1 #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/ 2 3 /*@C 4 TaoSetHessian - Sets the function to compute the Hessian as well as the location to store the matrix. 5 6 Logically collective on tao 7 8 Input Parameters: 9 + tao - the Tao context 10 . H - Matrix used for the hessian 11 . Hpre - Matrix that will be used operated on by preconditioner, can be same as H 12 . func - Hessian evaluation routine 13 - ctx - [optional] user-defined context for private data for the 14 Hessian evaluation routine (may be NULL) 15 16 Calling sequence of func: 17 $ func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx); 18 19 + tao - the Tao context 20 . x - input vector 21 . H - Hessian matrix 22 . Hpre - preconditioner matrix, usually the same as H 23 - ctx - [optional] user-defined Hessian context 24 25 Level: beginner 26 27 .seealso: `Tao`, `TaoTypes`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetObjectiveAndGradient()`, `TaoGetHessian()` 28 @*/ 29 PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) 30 { 31 PetscFunctionBegin; 32 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 33 if (H) { 34 PetscValidHeaderSpecific(H, MAT_CLASSID, 2); 35 PetscCheckSameComm(tao, 1, H, 2); 36 } 37 if (Hpre) { 38 PetscValidHeaderSpecific(Hpre, MAT_CLASSID, 3); 39 PetscCheckSameComm(tao, 1, Hpre, 3); 40 } 41 if (ctx) tao->user_hessP = ctx; 42 if (func) tao->ops->computehessian = func; 43 if (H) { 44 PetscCall(PetscObjectReference((PetscObject)H)); 45 PetscCall(MatDestroy(&tao->hessian)); 46 tao->hessian = H; 47 } 48 if (Hpre) { 49 PetscCall(PetscObjectReference((PetscObject)Hpre)); 50 PetscCall(MatDestroy(&tao->hessian_pre)); 51 tao->hessian_pre = Hpre; 52 } 53 PetscFunctionReturn(0); 54 } 55 56 /*@C 57 TaoGetHessian - Gets the function to compute the Hessian as well as the location to store the matrix. 58 59 Not collective 60 61 Input Parameter: 62 . tao - the Tao context 63 64 OutputParameters: 65 + H - Matrix used for the hessian 66 . Hpre - Matrix that will be used operated on by preconditioner, can be the same as H 67 . func - Hessian evaluation routine 68 - ctx - user-defined context for private data for the Hessian evaluation routine 69 70 Calling sequence of func: 71 $ func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx); 72 73 + tao - the Tao context 74 . x - input vector 75 . H - Hessian matrix 76 . Hpre - preconditioner matrix, usually the same as H 77 - ctx - [optional] user-defined Hessian context 78 79 Level: beginner 80 81 .seealso: `Tao`, TaoType`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()` 82 @*/ 83 PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void *), void **ctx) 84 { 85 PetscFunctionBegin; 86 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 87 if (H) *H = tao->hessian; 88 if (Hpre) *Hpre = tao->hessian_pre; 89 if (ctx) *ctx = tao->user_hessP; 90 if (func) *func = tao->ops->computehessian; 91 PetscFunctionReturn(0); 92 } 93 94 PetscErrorCode TaoTestHessian(Tao tao) 95 { 96 Mat A, B, C, D, hessian; 97 Vec x = tao->solution; 98 PetscReal nrm, gnorm; 99 PetscReal threshold = 1.e-5; 100 PetscInt m, n, M, N; 101 PetscBool complete_print = PETSC_FALSE, test = PETSC_FALSE, flg; 102 PetscViewer viewer, mviewer; 103 MPI_Comm comm; 104 PetscInt tabs; 105 static PetscBool directionsprinted = PETSC_FALSE; 106 PetscViewerFormat format; 107 108 PetscFunctionBegin; 109 PetscObjectOptionsBegin((PetscObject)tao); 110 PetscCall(PetscOptionsName("-tao_test_hessian", "Compare hand-coded and finite difference Hessians", "None", &test)); 111 PetscCall(PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL)); 112 PetscCall(PetscOptionsViewer("-tao_test_hessian_view", "View difference between hand-coded and finite difference Hessians element entries", "None", &mviewer, &format, &complete_print)); 113 PetscOptionsEnd(); 114 if (!test) PetscFunctionReturn(0); 115 116 PetscCall(PetscObjectGetComm((PetscObject)tao, &comm)); 117 PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 118 PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 119 PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel)); 120 PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Hessian -------------\n")); 121 if (!complete_print && !directionsprinted) { 122 PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n")); 123 PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Hessian entries greater than <threshold>.\n")); 124 } 125 if (!directionsprinted) { 126 PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 127 PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Hessian is probably correct.\n")); 128 directionsprinted = PETSC_TRUE; 129 } 130 if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 131 132 PetscCall(PetscObjectTypeCompare((PetscObject)tao->hessian, MATMFFD, &flg)); 133 if (!flg) hessian = tao->hessian; 134 else hessian = tao->hessian_pre; 135 136 while (hessian) { 137 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)hessian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "")); 138 if (flg) { 139 A = hessian; 140 PetscCall(PetscObjectReference((PetscObject)A)); 141 } else { 142 PetscCall(MatComputeOperator(hessian, MATAIJ, &A)); 143 } 144 145 PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 146 PetscCall(MatGetSize(A, &M, &N)); 147 PetscCall(MatGetLocalSize(A, &m, &n)); 148 PetscCall(MatSetSizes(B, m, n, M, N)); 149 PetscCall(MatSetType(B, ((PetscObject)A)->type_name)); 150 PetscCall(MatSetUp(B)); 151 PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 152 153 PetscCall(TaoDefaultComputeHessian(tao, x, B, B, NULL)); 154 155 PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D)); 156 PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 157 PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm)); 158 PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm)); 159 PetscCall(MatDestroy(&D)); 160 if (!gnorm) gnorm = 1; /* just in case */ 161 PetscCall(PetscViewerASCIIPrintf(viewer, " ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm)); 162 163 if (complete_print) { 164 PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Hessian ----------\n")); 165 PetscCall(MatView(A, mviewer)); 166 PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Hessian ----------\n")); 167 PetscCall(MatView(B, mviewer)); 168 } 169 170 if (complete_print) { 171 PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 172 PetscScalar *cvals; 173 const PetscInt *bcols; 174 const PetscScalar *bvals; 175 176 PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 177 PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C)); 178 PetscCall(MatSetSizes(C, m, n, M, N)); 179 PetscCall(MatSetType(C, ((PetscObject)A)->type_name)); 180 PetscCall(MatSetUp(C)); 181 PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 182 PetscCall(MatGetOwnershipRange(B, &Istart, &Iend)); 183 184 for (row = Istart; row < Iend; row++) { 185 PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals)); 186 PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals)); 187 for (j = 0, cncols = 0; j < bncols; j++) { 188 if (PetscAbsScalar(bvals[j]) > threshold) { 189 ccols[cncols] = bcols[j]; 190 cvals[cncols] = bvals[j]; 191 cncols += 1; 192 } 193 } 194 if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES)); 195 PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals)); 196 PetscCall(PetscFree2(ccols, cvals)); 197 } 198 PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 199 PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 200 PetscCall(PetscViewerASCIIPrintf(viewer, " Finite-difference minus hand-coded Hessian with tolerance %g ----------\n", (double)threshold)); 201 PetscCall(MatView(C, mviewer)); 202 PetscCall(MatDestroy(&C)); 203 } 204 PetscCall(MatDestroy(&A)); 205 PetscCall(MatDestroy(&B)); 206 207 if (hessian != tao->hessian_pre) { 208 hessian = tao->hessian_pre; 209 PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Hessian for preconditioner -------------\n")); 210 } else hessian = NULL; 211 } 212 if (complete_print) { 213 PetscCall(PetscViewerPopFormat(mviewer)); 214 PetscCall(PetscViewerDestroy(&mviewer)); 215 } 216 PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 217 PetscFunctionReturn(0); 218 } 219 220 /*@C 221 TaoComputeHessian - Computes the Hessian matrix that has been 222 set with `TaoSetHessian()`. 223 224 Collective on tao 225 226 Input Parameters: 227 + tao - the Tao solver context 228 - X - input vector 229 230 Output Parameters: 231 + H - Hessian matrix 232 - Hpre - Preconditioning matrix 233 234 Options Database Keys: 235 + -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors 236 . -tao_test_hessian <numerical value> - display entries in the difference between the user provided Hessian and finite difference Hessian that are greater than a certain value to help users detect errors 237 - -tao_test_hessian_view - display the user provided Hessian, the finite difference Hessian and the difference between them to help users detect the location of errors in the user provided Hessian 238 239 Notes: 240 Most users should not need to explicitly call this routine, as it 241 is used internally within the minimization solvers. 242 243 `TaoComputeHessian()` is typically used within optimization algorithms, 244 so most users would not generally call this routine 245 themselves. 246 247 Developer Note: 248 The Hessian test mechanism follows `SNESTestJacobian()`. 249 250 Level: developer 251 252 .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()` 253 @*/ 254 PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre) 255 { 256 PetscFunctionBegin; 257 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 258 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 259 PetscCheckSameComm(tao, 1, X, 2); 260 ++tao->nhess; 261 PetscCall(VecLockReadPush(X)); 262 PetscCall(PetscLogEventBegin(TAO_HessianEval, tao, X, H, Hpre)); 263 PetscCallBack("Tao callback Hessian", (*tao->ops->computehessian)(tao, X, H, Hpre, tao->user_hessP)); 264 PetscCall(PetscLogEventEnd(TAO_HessianEval, tao, X, H, Hpre)); 265 PetscCall(VecLockReadPop(X)); 266 267 PetscCall(TaoTestHessian(tao)); 268 PetscFunctionReturn(0); 269 } 270 271 /*@C 272 TaoComputeJacobian - Computes the Jacobian matrix that has been 273 set with TaoSetJacobianRoutine(). 274 275 Collective on tao 276 277 Input Parameters: 278 + tao - the Tao solver context 279 - X - input vector 280 281 Output Parameters: 282 + J - Jacobian matrix 283 - Jpre - Preconditioning matrix 284 285 Notes: 286 Most users should not need to explicitly call this routine, as it 287 is used internally within the minimization solvers. 288 289 `TaoComputeJacobian()` is typically used within minimization 290 implementations, so most users would not generally call this routine 291 themselves. 292 293 Level: developer 294 295 .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()` 296 @*/ 297 PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre) 298 { 299 PetscFunctionBegin; 300 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 301 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 302 PetscCheckSameComm(tao, 1, X, 2); 303 ++tao->njac; 304 PetscCall(VecLockReadPush(X)); 305 PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre)); 306 PetscCallBack("Tao callback Jacobian", (*tao->ops->computejacobian)(tao, X, J, Jpre, tao->user_jacP)); 307 PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre)); 308 PetscCall(VecLockReadPop(X)); 309 PetscFunctionReturn(0); 310 } 311 312 /*@C 313 TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been 314 set with `TaoSetJacobianResidual()`. 315 316 Collective on tao 317 318 Input Parameters: 319 + tao - the Tao solver context 320 - X - input vector 321 322 Output Parameters: 323 + J - Jacobian matrix 324 - Jpre - Preconditioning matrix 325 326 Notes: 327 Most users should not need to explicitly call this routine, as it 328 is used internally within the minimization solvers. 329 330 `TaoComputeResidualJacobian()` is typically used within least-squares 331 implementations, so most users would not generally call this routine 332 themselves. 333 334 Level: developer 335 336 .seealso: `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()` 337 @*/ 338 PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre) 339 { 340 PetscFunctionBegin; 341 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 342 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 343 PetscCheckSameComm(tao, 1, X, 2); 344 ++tao->njac; 345 PetscCall(VecLockReadPush(X)); 346 PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre)); 347 PetscCallBack("Tao callback least-squares residual Jacobian", (*tao->ops->computeresidualjacobian)(tao, X, J, Jpre, tao->user_lsjacP)); 348 PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre)); 349 PetscCall(VecLockReadPop(X)); 350 PetscFunctionReturn(0); 351 } 352 353 /*@C 354 TaoComputeJacobianState - Computes the Jacobian matrix that has been 355 set with `TaoSetJacobianStateRoutine()`. 356 357 Collective on tao 358 359 Input Parameters: 360 + tao - the Tao solver context 361 - X - input vector 362 363 Output Parameters: 364 + J - Jacobian matrix 365 . Jpre - Preconditioning matrix 366 - Jinv - unknown 367 368 Notes: 369 Most users should not need to explicitly call this routine, as it 370 is used internally within the optimization algorithms. 371 372 Level: developer 373 374 .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()` 375 @*/ 376 PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv) 377 { 378 PetscFunctionBegin; 379 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 380 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 381 PetscCheckSameComm(tao, 1, X, 2); 382 ++tao->njac_state; 383 PetscCall(VecLockReadPush(X)); 384 PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre)); 385 PetscCallBack("Tao callback Jacobian(state)", (*tao->ops->computejacobianstate)(tao, X, J, Jpre, Jinv, tao->user_jac_stateP)); 386 PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre)); 387 PetscCall(VecLockReadPop(X)); 388 PetscFunctionReturn(0); 389 } 390 391 /*@C 392 TaoComputeJacobianDesign - Computes the Jacobian matrix that has been 393 set with `TaoSetJacobianDesignRoutine()`. 394 395 Collective on tao 396 397 Input Parameters: 398 + tao - the Tao solver context 399 - X - input vector 400 401 Output Parameters: 402 . J - Jacobian matrix 403 404 Notes: 405 Most users should not need to explicitly call this routine, as it 406 is used internally within the optimization algorithms. 407 408 Level: developer 409 410 .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()` 411 @*/ 412 PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J) 413 { 414 PetscFunctionBegin; 415 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 416 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 417 PetscCheckSameComm(tao, 1, X, 2); 418 ++tao->njac_design; 419 PetscCall(VecLockReadPush(X)); 420 PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, NULL)); 421 PetscCallBack("Tao callback Jacobian(design)", (*tao->ops->computejacobiandesign)(tao, X, J, tao->user_jac_designP)); 422 PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, NULL)); 423 PetscCall(VecLockReadPop(X)); 424 PetscFunctionReturn(0); 425 } 426 427 /*@C 428 TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix. 429 430 Logically collective on tao 431 432 Input Parameters: 433 + tao - the Tao context 434 . J - Matrix used for the jacobian 435 . Jpre - Matrix that will be used operated on by preconditioner, can be same as J 436 . func - Jacobian evaluation routine 437 - ctx - [optional] user-defined context for private data for the 438 Jacobian evaluation routine (may be NULL) 439 440 Calling sequence of func: 441 $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx); 442 443 + tao - the Tao context 444 . x - input vector 445 . J - Jacobian matrix 446 . Jpre - preconditioning matrix, usually the same as J 447 - ctx - [optional] user-defined Jacobian context 448 449 Level: intermediate 450 451 .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()` 452 @*/ 453 PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) 454 { 455 PetscFunctionBegin; 456 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 457 if (J) { 458 PetscValidHeaderSpecific(J, MAT_CLASSID, 2); 459 PetscCheckSameComm(tao, 1, J, 2); 460 } 461 if (Jpre) { 462 PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3); 463 PetscCheckSameComm(tao, 1, Jpre, 3); 464 } 465 if (ctx) tao->user_jacP = ctx; 466 if (func) tao->ops->computejacobian = func; 467 if (J) { 468 PetscCall(PetscObjectReference((PetscObject)J)); 469 PetscCall(MatDestroy(&tao->jacobian)); 470 tao->jacobian = J; 471 } 472 if (Jpre) { 473 PetscCall(PetscObjectReference((PetscObject)Jpre)); 474 PetscCall(MatDestroy(&tao->jacobian_pre)); 475 tao->jacobian_pre = Jpre; 476 } 477 PetscFunctionReturn(0); 478 } 479 480 /*@C 481 TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the 482 location to store the matrix. 483 484 Logically collective on tao 485 486 Input Parameters: 487 + tao - the Tao context 488 . J - Matrix used for the jacobian 489 . Jpre - Matrix that will be used operated on by preconditioner, can be same as J 490 . func - Jacobian evaluation routine 491 - ctx - [optional] user-defined context for private data for the 492 Jacobian evaluation routine (may be NULL) 493 494 Calling sequence of func: 495 $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx); 496 497 + tao - the Tao context 498 . x - input vector 499 . J - Jacobian matrix 500 . Jpre - preconditioning matrix, usually the same as J 501 - ctx - [optional] user-defined Jacobian context 502 503 Level: intermediate 504 505 .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()` 506 @*/ 507 PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) 508 { 509 PetscFunctionBegin; 510 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 511 if (J) { 512 PetscValidHeaderSpecific(J, MAT_CLASSID, 2); 513 PetscCheckSameComm(tao, 1, J, 2); 514 } 515 if (Jpre) { 516 PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3); 517 PetscCheckSameComm(tao, 1, Jpre, 3); 518 } 519 if (ctx) tao->user_lsjacP = ctx; 520 if (func) tao->ops->computeresidualjacobian = func; 521 if (J) { 522 PetscCall(PetscObjectReference((PetscObject)J)); 523 PetscCall(MatDestroy(&tao->ls_jac)); 524 tao->ls_jac = J; 525 } 526 if (Jpre) { 527 PetscCall(PetscObjectReference((PetscObject)Jpre)); 528 PetscCall(MatDestroy(&tao->ls_jac_pre)); 529 tao->ls_jac_pre = Jpre; 530 } 531 PetscFunctionReturn(0); 532 } 533 534 /*@C 535 TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian 536 (and its inverse) of the constraint function with respect to the state variables. 537 Used only for PDE-constrained optimization. 538 539 Logically collective on tao 540 541 Input Parameters: 542 + tao - the Tao context 543 . J - Matrix used for the jacobian 544 . Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J. Only used if Jinv is NULL 545 . Jinv - [optional] Matrix used to apply the inverse of the state jacobian. Use NULL to default to PETSc KSP solvers to apply the inverse. 546 . func - Jacobian evaluation routine 547 - ctx - [optional] user-defined context for private data for the 548 Jacobian evaluation routine (may be NULL) 549 550 Calling sequence of func: 551 $ func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx); 552 553 + tao - the Tao context 554 . x - input vector 555 . J - Jacobian matrix 556 . Jpre - preconditioner matrix, usually the same as J 557 . Jinv - inverse of J 558 - ctx - [optional] user-defined Jacobian context 559 560 Level: intermediate 561 562 .seealso: `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()` 563 @*/ 564 PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void *), void *ctx) 565 { 566 PetscFunctionBegin; 567 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 568 if (J) { 569 PetscValidHeaderSpecific(J, MAT_CLASSID, 2); 570 PetscCheckSameComm(tao, 1, J, 2); 571 } 572 if (Jpre) { 573 PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3); 574 PetscCheckSameComm(tao, 1, Jpre, 3); 575 } 576 if (Jinv) { 577 PetscValidHeaderSpecific(Jinv, MAT_CLASSID, 4); 578 PetscCheckSameComm(tao, 1, Jinv, 4); 579 } 580 if (ctx) tao->user_jac_stateP = ctx; 581 if (func) tao->ops->computejacobianstate = func; 582 if (J) { 583 PetscCall(PetscObjectReference((PetscObject)J)); 584 PetscCall(MatDestroy(&tao->jacobian_state)); 585 tao->jacobian_state = J; 586 } 587 if (Jpre) { 588 PetscCall(PetscObjectReference((PetscObject)Jpre)); 589 PetscCall(MatDestroy(&tao->jacobian_state_pre)); 590 tao->jacobian_state_pre = Jpre; 591 } 592 if (Jinv) { 593 PetscCall(PetscObjectReference((PetscObject)Jinv)); 594 PetscCall(MatDestroy(&tao->jacobian_state_inv)); 595 tao->jacobian_state_inv = Jinv; 596 } 597 PetscFunctionReturn(0); 598 } 599 600 /*@C 601 TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of 602 the constraint function with respect to the design variables. Used only for 603 PDE-constrained optimization. 604 605 Logically collective on tao 606 607 Input Parameters: 608 + tao - the Tao context 609 . J - Matrix used for the jacobian 610 . func - Jacobian evaluation routine 611 - ctx - [optional] user-defined context for private data for the 612 Jacobian evaluation routine (may be NULL) 613 614 Calling sequence of func: 615 $ func(Tao tao,Vec x,Mat J,void *ctx); 616 617 + tao - the Tao context 618 . x - input vector 619 . J - Jacobian matrix 620 - ctx - [optional] user-defined Jacobian context 621 622 Level: intermediate 623 624 .seealso: `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()` 625 @*/ 626 PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void *), void *ctx) 627 { 628 PetscFunctionBegin; 629 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 630 if (J) { 631 PetscValidHeaderSpecific(J, MAT_CLASSID, 2); 632 PetscCheckSameComm(tao, 1, J, 2); 633 } 634 if (ctx) tao->user_jac_designP = ctx; 635 if (func) tao->ops->computejacobiandesign = func; 636 if (J) { 637 PetscCall(PetscObjectReference((PetscObject)J)); 638 PetscCall(MatDestroy(&tao->jacobian_design)); 639 tao->jacobian_design = J; 640 } 641 PetscFunctionReturn(0); 642 } 643 644 /*@ 645 TaoSetStateDesignIS - Indicate to the Tao which variables in the 646 solution vector are state variables and which are design. Only applies to 647 PDE-constrained optimization. 648 649 Logically Collective on Tao 650 651 Input Parameters: 652 + tao - The Tao context 653 . s_is - the index set corresponding to the state variables 654 - d_is - the index set corresponding to the design variables 655 656 Level: intermediate 657 658 .seealso: `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()` 659 @*/ 660 PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is) 661 { 662 PetscFunctionBegin; 663 PetscCall(PetscObjectReference((PetscObject)s_is)); 664 PetscCall(ISDestroy(&tao->state_is)); 665 tao->state_is = s_is; 666 PetscCall(PetscObjectReference((PetscObject)(d_is))); 667 PetscCall(ISDestroy(&tao->design_is)); 668 tao->design_is = d_is; 669 PetscFunctionReturn(0); 670 } 671 672 /*@C 673 TaoComputeJacobianEquality - Computes the Jacobian matrix that has been 674 set with `TaoSetJacobianEqualityRoutine()`. 675 676 Collective on tao 677 678 Input Parameters: 679 + tao - the Tao solver context 680 - X - input vector 681 682 Output Parameters: 683 + J - Jacobian matrix 684 - Jpre - Preconditioning matrix 685 686 Notes: 687 Most users should not need to explicitly call this routine, as it 688 is used internally within the optimization algorithms. 689 690 Level: developer 691 692 .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()` 693 @*/ 694 PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre) 695 { 696 PetscFunctionBegin; 697 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 698 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 699 PetscCheckSameComm(tao, 1, X, 2); 700 ++tao->njac_equality; 701 PetscCall(VecLockReadPush(X)); 702 PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre)); 703 PetscCallBack("Tao callback Jacobian(equality)", (*tao->ops->computejacobianequality)(tao, X, J, Jpre, tao->user_jac_equalityP)); 704 PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre)); 705 PetscCall(VecLockReadPop(X)); 706 PetscFunctionReturn(0); 707 } 708 709 /*@C 710 TaoComputeJacobianInequality - Computes the Jacobian matrix that has been 711 set with `TaoSetJacobianInequalityRoutine()`. 712 713 Collective on tao 714 715 Input Parameters: 716 + tao - the Tao solver context 717 - X - input vector 718 719 Output Parameters: 720 + J - Jacobian matrix 721 - Jpre - Preconditioning matrix 722 723 Notes: 724 Most users should not need to explicitly call this routine, as it 725 is used internally within the minimization solvers. 726 727 Level: developer 728 729 .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()` 730 @*/ 731 PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre) 732 { 733 PetscFunctionBegin; 734 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 735 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 736 PetscCheckSameComm(tao, 1, X, 2); 737 ++tao->njac_inequality; 738 PetscCall(VecLockReadPush(X)); 739 PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre)); 740 PetscCallBack("Tao callback Jacobian (inequality)", (*tao->ops->computejacobianinequality)(tao, X, J, Jpre, tao->user_jac_inequalityP)); 741 PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre)); 742 PetscCall(VecLockReadPop(X)); 743 PetscFunctionReturn(0); 744 } 745 746 /*@C 747 TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian 748 (and its inverse) of the constraint function with respect to the equality variables. 749 Used only for PDE-constrained optimization. 750 751 Logically collective on tao 752 753 Input Parameters: 754 + tao - the Tao context 755 . J - Matrix used for the jacobian 756 . Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J. 757 . func - Jacobian evaluation routine 758 - ctx - [optional] user-defined context for private data for the 759 Jacobian evaluation routine (may be NULL) 760 761 Calling sequence of func: 762 $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx); 763 764 + tao - the Tao context 765 . x - input vector 766 . J - Jacobian matrix 767 . Jpre - preconditioner matrix, usually the same as J 768 - ctx - [optional] user-defined Jacobian context 769 770 Level: intermediate 771 772 .seealso: `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()` 773 @*/ 774 PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) 775 { 776 PetscFunctionBegin; 777 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 778 if (J) { 779 PetscValidHeaderSpecific(J, MAT_CLASSID, 2); 780 PetscCheckSameComm(tao, 1, J, 2); 781 } 782 if (Jpre) { 783 PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3); 784 PetscCheckSameComm(tao, 1, Jpre, 3); 785 } 786 if (ctx) tao->user_jac_equalityP = ctx; 787 if (func) tao->ops->computejacobianequality = func; 788 if (J) { 789 PetscCall(PetscObjectReference((PetscObject)J)); 790 PetscCall(MatDestroy(&tao->jacobian_equality)); 791 tao->jacobian_equality = J; 792 } 793 if (Jpre) { 794 PetscCall(PetscObjectReference((PetscObject)Jpre)); 795 PetscCall(MatDestroy(&tao->jacobian_equality_pre)); 796 tao->jacobian_equality_pre = Jpre; 797 } 798 PetscFunctionReturn(0); 799 } 800 801 /*@C 802 TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian 803 (and its inverse) of the constraint function with respect to the inequality variables. 804 Used only for PDE-constrained optimization. 805 806 Logically collective on tao 807 808 Input Parameters: 809 + tao - the Tao context 810 . J - Matrix used for the jacobian 811 . Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J. 812 . func - Jacobian evaluation routine 813 - ctx - [optional] user-defined context for private data for the 814 Jacobian evaluation routine (may be NULL) 815 816 Calling sequence of func: 817 $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx); 818 819 + tao - the Tao context 820 . x - input vector 821 . J - Jacobian matrix 822 . Jpre - preconditioner matrix, usually the same as J 823 - ctx - [optional] user-defined Jacobian context 824 825 Level: intermediate 826 827 .seealso: `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()` 828 @*/ 829 PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) 830 { 831 PetscFunctionBegin; 832 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 833 if (J) { 834 PetscValidHeaderSpecific(J, MAT_CLASSID, 2); 835 PetscCheckSameComm(tao, 1, J, 2); 836 } 837 if (Jpre) { 838 PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3); 839 PetscCheckSameComm(tao, 1, Jpre, 3); 840 } 841 if (ctx) tao->user_jac_inequalityP = ctx; 842 if (func) tao->ops->computejacobianinequality = func; 843 if (J) { 844 PetscCall(PetscObjectReference((PetscObject)J)); 845 PetscCall(MatDestroy(&tao->jacobian_inequality)); 846 tao->jacobian_inequality = J; 847 } 848 if (Jpre) { 849 PetscCall(PetscObjectReference((PetscObject)Jpre)); 850 PetscCall(MatDestroy(&tao->jacobian_inequality_pre)); 851 tao->jacobian_inequality_pre = Jpre; 852 } 853 PetscFunctionReturn(0); 854 } 855