114d0ab18SJacob Faibussowitsch #include <petsc/private/tsimpl.h> /*I <petscts.h> I*/ 2814e85d6SHong Zhang #include <petscdraw.h> 3814e85d6SHong Zhang 433f72c5dSHong Zhang PetscLogEvent TS_AdjointStep, TS_ForwardStep, TS_JacobianPEval; 5814e85d6SHong Zhang 67f59fb53SHong Zhang /* #define TSADJOINT_STAGE */ 77f59fb53SHong Zhang 8814e85d6SHong Zhang /* ------------------------ Sensitivity Context ---------------------------*/ 9814e85d6SHong Zhang 10814e85d6SHong Zhang /*@C 11b5b4017aSHong Zhang TSSetRHSJacobianP - Sets the function that computes the Jacobian of G w.r.t. the parameters P where U_t = G(U,P,t), as well as the location to store the matrix. 12814e85d6SHong Zhang 13c3339decSBarry Smith Logically Collective 14814e85d6SHong Zhang 15814e85d6SHong Zhang Input Parameters: 16bcf0153eSBarry Smith + ts - `TS` context obtained from `TSCreate()` 17b5b4017aSHong Zhang . Amat - JacobianP matrix 18b5b4017aSHong Zhang . func - function 19b5b4017aSHong Zhang - ctx - [optional] user-defined function context 20814e85d6SHong Zhang 21814e85d6SHong Zhang Level: intermediate 22814e85d6SHong Zhang 23bcf0153eSBarry Smith Note: 2414d0ab18SJacob Faibussowitsch `Amat` has the same number of rows and the same row parallel layout as `u`, `Amat` has the same number of columns and parallel layout as `p` 25814e85d6SHong Zhang 268434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSRHSJacobianPFn`, `TSGetRHSJacobianP()` 27814e85d6SHong Zhang @*/ 288434afd1SBarry Smith PetscErrorCode TSSetRHSJacobianP(TS ts, Mat Amat, TSRHSJacobianPFn *func, void *ctx) 29d71ae5a4SJacob Faibussowitsch { 30814e85d6SHong Zhang PetscFunctionBegin; 31814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 32814e85d6SHong Zhang PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 33814e85d6SHong Zhang 34814e85d6SHong Zhang ts->rhsjacobianp = func; 35814e85d6SHong Zhang ts->rhsjacobianpctx = ctx; 36814e85d6SHong Zhang if (Amat) { 379566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&ts->Jacprhs)); 3933f72c5dSHong Zhang ts->Jacprhs = Amat; 40814e85d6SHong Zhang } 413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42814e85d6SHong Zhang } 43814e85d6SHong Zhang 44814e85d6SHong Zhang /*@C 45cd4cee2dSHong Zhang TSGetRHSJacobianP - Gets the function that computes the Jacobian of G w.r.t. the parameters P where U_t = G(U,P,t), as well as the location to store the matrix. 46cd4cee2dSHong Zhang 47c3339decSBarry Smith Logically Collective 48cd4cee2dSHong Zhang 49f899ff85SJose E. Roman Input Parameter: 50bcf0153eSBarry Smith . ts - `TS` context obtained from `TSCreate()` 51cd4cee2dSHong Zhang 52cd4cee2dSHong Zhang Output Parameters: 53cd4cee2dSHong Zhang + Amat - JacobianP matrix 54cd4cee2dSHong Zhang . func - function 55cd4cee2dSHong Zhang - ctx - [optional] user-defined function context 56cd4cee2dSHong Zhang 57cd4cee2dSHong Zhang Level: intermediate 58cd4cee2dSHong Zhang 59bcf0153eSBarry Smith Note: 6014d0ab18SJacob Faibussowitsch `Amat` has the same number of rows and the same row parallel layout as `u`, `Amat` has the same number of columns and parallel layout as `p` 61cd4cee2dSHong Zhang 628434afd1SBarry Smith .seealso: [](ch_ts), `TSSetRHSJacobianP()`, `TS`, `TSRHSJacobianPFn` 63cd4cee2dSHong Zhang @*/ 648434afd1SBarry Smith PetscErrorCode TSGetRHSJacobianP(TS ts, Mat *Amat, TSRHSJacobianPFn **func, void **ctx) 65d71ae5a4SJacob Faibussowitsch { 66cd4cee2dSHong Zhang PetscFunctionBegin; 67cd4cee2dSHong Zhang if (func) *func = ts->rhsjacobianp; 68cd4cee2dSHong Zhang if (ctx) *ctx = ts->rhsjacobianpctx; 69cd4cee2dSHong Zhang if (Amat) *Amat = ts->Jacprhs; 703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71cd4cee2dSHong Zhang } 72cd4cee2dSHong Zhang 73cd4cee2dSHong Zhang /*@C 74814e85d6SHong Zhang TSComputeRHSJacobianP - Runs the user-defined JacobianP function. 75814e85d6SHong Zhang 76c3339decSBarry Smith Collective 77814e85d6SHong Zhang 78814e85d6SHong Zhang Input Parameters: 792fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 802fe279fdSBarry Smith . t - the time 812fe279fdSBarry Smith - U - the solution at which to compute the Jacobian 822fe279fdSBarry Smith 832fe279fdSBarry Smith Output Parameter: 842fe279fdSBarry Smith . Amat - the computed Jacobian 85814e85d6SHong Zhang 86814e85d6SHong Zhang Level: developer 87814e85d6SHong Zhang 881cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetRHSJacobianP()`, `TS` 89814e85d6SHong Zhang @*/ 90d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSJacobianP(TS ts, PetscReal t, Vec U, Mat Amat) 91d71ae5a4SJacob Faibussowitsch { 92814e85d6SHong Zhang PetscFunctionBegin; 933ba16761SJacob Faibussowitsch if (!Amat) PetscFunctionReturn(PETSC_SUCCESS); 94814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 95c9ad9de0SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 96814e85d6SHong Zhang 9780ab5e31SHong Zhang if (ts->rhsjacobianp) PetscCallBack("TS callback JacobianP for sensitivity analysis", (*ts->rhsjacobianp)(ts, t, U, Amat, ts->rhsjacobianpctx)); 9880ab5e31SHong Zhang else { 9980ab5e31SHong Zhang PetscBool assembled; 10080ab5e31SHong Zhang PetscCall(MatZeroEntries(Amat)); 10180ab5e31SHong Zhang PetscCall(MatAssembled(Amat, &assembled)); 10280ab5e31SHong Zhang if (!assembled) { 10380ab5e31SHong Zhang PetscCall(MatAssemblyBegin(Amat, MAT_FINAL_ASSEMBLY)); 10480ab5e31SHong Zhang PetscCall(MatAssemblyEnd(Amat, MAT_FINAL_ASSEMBLY)); 10580ab5e31SHong Zhang } 10680ab5e31SHong Zhang } 1073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 108814e85d6SHong Zhang } 109814e85d6SHong Zhang 110814e85d6SHong Zhang /*@C 11133f72c5dSHong Zhang TSSetIJacobianP - Sets the function that computes the Jacobian of F w.r.t. the parameters P where F(Udot,U,t) = G(U,P,t), as well as the location to store the matrix. 11233f72c5dSHong Zhang 113c3339decSBarry Smith Logically Collective 11433f72c5dSHong Zhang 11533f72c5dSHong Zhang Input Parameters: 116bcf0153eSBarry Smith + ts - `TS` context obtained from `TSCreate()` 11733f72c5dSHong Zhang . Amat - JacobianP matrix 11833f72c5dSHong Zhang . func - function 11933f72c5dSHong Zhang - ctx - [optional] user-defined function context 12033f72c5dSHong Zhang 12120f4b53cSBarry Smith Calling sequence of `func`: 12214d0ab18SJacob Faibussowitsch + ts - the `TS` context 12314d0ab18SJacob Faibussowitsch . t - current timestep 12433f72c5dSHong Zhang . U - input vector (current ODE solution) 12533f72c5dSHong Zhang . Udot - time derivative of state vector 12633f72c5dSHong Zhang . shift - shift to apply, see note below 12733f72c5dSHong Zhang . A - output matrix 12833f72c5dSHong Zhang - ctx - [optional] user-defined function context 12933f72c5dSHong Zhang 13033f72c5dSHong Zhang Level: intermediate 13133f72c5dSHong Zhang 132bcf0153eSBarry Smith Note: 13333f72c5dSHong Zhang Amat has the same number of rows and the same row parallel layout as u, Amat has the same number of columns and parallel layout as p 13433f72c5dSHong Zhang 1351cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetRHSJacobianP()`, `TS` 13633f72c5dSHong Zhang @*/ 13714d0ab18SJacob Faibussowitsch PetscErrorCode TSSetIJacobianP(TS ts, Mat Amat, PetscErrorCode (*func)(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat A, void *ctx), void *ctx) 138d71ae5a4SJacob Faibussowitsch { 13933f72c5dSHong Zhang PetscFunctionBegin; 14033f72c5dSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 14133f72c5dSHong Zhang PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 14233f72c5dSHong Zhang 14333f72c5dSHong Zhang ts->ijacobianp = func; 14433f72c5dSHong Zhang ts->ijacobianpctx = ctx; 14533f72c5dSHong Zhang if (Amat) { 1469566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 1479566063dSJacob Faibussowitsch PetscCall(MatDestroy(&ts->Jacp)); 14833f72c5dSHong Zhang ts->Jacp = Amat; 14933f72c5dSHong Zhang } 1503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15133f72c5dSHong Zhang } 15233f72c5dSHong Zhang 153cc4c1da9SBarry Smith /*@ 15433f72c5dSHong Zhang TSComputeIJacobianP - Runs the user-defined IJacobianP function. 15533f72c5dSHong Zhang 156c3339decSBarry Smith Collective 15733f72c5dSHong Zhang 15833f72c5dSHong Zhang Input Parameters: 159bcf0153eSBarry Smith + ts - the `TS` context 16033f72c5dSHong Zhang . t - current timestep 16133f72c5dSHong Zhang . U - state vector 16233f72c5dSHong Zhang . Udot - time derivative of state vector 16333f72c5dSHong Zhang . shift - shift to apply, see note below 16480ab5e31SHong Zhang - imex - flag indicates if the method is IMEX so that the RHSJacobianP should be kept separate 16533f72c5dSHong Zhang 1662fe279fdSBarry Smith Output Parameter: 167b43aa488SJacob Faibussowitsch . Amat - Jacobian matrix 16833f72c5dSHong Zhang 16933f72c5dSHong Zhang Level: developer 17033f72c5dSHong Zhang 1711cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetIJacobianP()` 17233f72c5dSHong Zhang @*/ 173d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIJacobianP(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat Amat, PetscBool imex) 174d71ae5a4SJacob Faibussowitsch { 17533f72c5dSHong Zhang PetscFunctionBegin; 1763ba16761SJacob Faibussowitsch if (!Amat) PetscFunctionReturn(PETSC_SUCCESS); 17733f72c5dSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 17833f72c5dSHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 17933f72c5dSHong Zhang PetscValidHeaderSpecific(Udot, VEC_CLASSID, 4); 18033f72c5dSHong Zhang 1819566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TS_JacobianPEval, ts, U, Amat, 0)); 18248a46eb9SPierre Jolivet if (ts->ijacobianp) PetscCallBack("TS callback JacobianP for sensitivity analysis", (*ts->ijacobianp)(ts, t, U, Udot, shift, Amat, ts->ijacobianpctx)); 18333f72c5dSHong Zhang if (imex) { 18433f72c5dSHong Zhang if (!ts->ijacobianp) { /* system was written as Udot = G(t,U) */ 18533f72c5dSHong Zhang PetscBool assembled; 1869566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(Amat)); 1879566063dSJacob Faibussowitsch PetscCall(MatAssembled(Amat, &assembled)); 18833f72c5dSHong Zhang if (!assembled) { 1899566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(Amat, MAT_FINAL_ASSEMBLY)); 1909566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(Amat, MAT_FINAL_ASSEMBLY)); 19133f72c5dSHong Zhang } 19233f72c5dSHong Zhang } 19333f72c5dSHong Zhang } else { 1941baa6e33SBarry Smith if (ts->rhsjacobianp) PetscCall(TSComputeRHSJacobianP(ts, t, U, ts->Jacprhs)); 19533f72c5dSHong Zhang if (ts->Jacprhs == Amat) { /* No IJacobian, so we only have the RHS matrix */ 1969566063dSJacob Faibussowitsch PetscCall(MatScale(Amat, -1)); 19733f72c5dSHong Zhang } else if (ts->Jacprhs) { /* Both IJacobian and RHSJacobian */ 19833f72c5dSHong Zhang MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 19933f72c5dSHong Zhang if (!ts->ijacobianp) { /* No IJacobianp provided, but we have a separate RHS matrix */ 2009566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(Amat)); 20133f72c5dSHong Zhang } 2029566063dSJacob Faibussowitsch PetscCall(MatAXPY(Amat, -1, ts->Jacprhs, axpy)); 20333f72c5dSHong Zhang } 20433f72c5dSHong Zhang } 2059566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TS_JacobianPEval, ts, U, Amat, 0)); 2063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20733f72c5dSHong Zhang } 20833f72c5dSHong Zhang 20933f72c5dSHong Zhang /*@C 210814e85d6SHong Zhang TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions 211814e85d6SHong Zhang 212c3339decSBarry Smith Logically Collective 213814e85d6SHong Zhang 214814e85d6SHong Zhang Input Parameters: 215bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 216814e85d6SHong Zhang . numcost - number of gradients to be computed, this is the number of cost functions 217814e85d6SHong Zhang . costintegral - vector that stores the integral values 218814e85d6SHong Zhang . rf - routine for evaluating the integrand function 2198847d985SBarry Smith . drduf - function that computes the gradients of the r with respect to u 2208847d985SBarry Smith . drdpf - function that computes the gradients of the r with respect to p, can be `NULL` if parametric sensitivity is not desired (`mu` = `NULL`) 221814e85d6SHong Zhang . fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run 2222fe279fdSBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`) 223814e85d6SHong Zhang 22420f4b53cSBarry Smith Calling sequence of `rf`: 2258847d985SBarry Smith + ts - the integrator 2268847d985SBarry Smith . t - the time 2278847d985SBarry Smith . U - the solution 2288847d985SBarry Smith . F - the computed value of the function 2298847d985SBarry Smith - ctx - the user context 230814e85d6SHong Zhang 23120f4b53cSBarry Smith Calling sequence of `drduf`: 2328847d985SBarry Smith + ts - the integrator 2338847d985SBarry Smith . t - the time 2348847d985SBarry Smith . U - the solution 2358847d985SBarry Smith . dRdU - the computed gradients of the r with respect to u 2368847d985SBarry Smith - ctx - the user context 237814e85d6SHong Zhang 23820f4b53cSBarry Smith Calling sequence of `drdpf`: 2398847d985SBarry Smith + ts - the integrator 2408847d985SBarry Smith . t - the time 2418847d985SBarry Smith . U - the solution 2428847d985SBarry Smith . dRdP - the computed gradients of the r with respect to p 2438847d985SBarry Smith - ctx - the user context 244814e85d6SHong Zhang 245cd4cee2dSHong Zhang Level: deprecated 246814e85d6SHong Zhang 2478847d985SBarry Smith Notes: 248814e85d6SHong Zhang For optimization there is usually a single cost function (numcost = 1). For sensitivities there may be multiple cost functions 249814e85d6SHong Zhang 2508847d985SBarry Smith Use `TSCreateQuadratureTS()` and `TSForwardSetSensitivities()` instead 2518847d985SBarry Smith 2528847d985SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSJacobianP()`, `TSGetCostGradients()`, `TSSetCostGradients()`, 2538847d985SBarry Smith `TSCreateQuadratureTS()`, `TSForwardSetSensitivities()` 254814e85d6SHong Zhang @*/ 2558847d985SBarry Smith PetscErrorCode TSSetCostIntegrand(TS ts, PetscInt numcost, Vec costintegral, PetscErrorCode (*rf)(TS ts, PetscReal t, Vec U, Vec F, void *ctx), PetscErrorCode (*drduf)(TS ts, PetscReal t, Vec U, Vec *dRdU, void *ctx), PetscErrorCode (*drdpf)(TS ts, PetscReal t, Vec U, Vec *dRdP, void *ctx), PetscBool fwd, void *ctx) 256d71ae5a4SJacob Faibussowitsch { 257814e85d6SHong Zhang PetscFunctionBegin; 258814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 259814e85d6SHong Zhang if (costintegral) PetscValidHeaderSpecific(costintegral, VEC_CLASSID, 3); 2603c633725SBarry Smith PetscCheck(!ts->numcost || ts->numcost == numcost, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "The number of cost functions (2nd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostGradients() or TSForwardSetIntegralGradients()"); 261814e85d6SHong Zhang if (!ts->numcost) ts->numcost = numcost; 262814e85d6SHong Zhang 263814e85d6SHong Zhang if (costintegral) { 2649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)costintegral)); 2659566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ts->vec_costintegral)); 266814e85d6SHong Zhang ts->vec_costintegral = costintegral; 267814e85d6SHong Zhang } else { 268814e85d6SHong Zhang if (!ts->vec_costintegral) { /* Create a seq vec if user does not provide one */ 2699566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, numcost, &ts->vec_costintegral)); 270814e85d6SHong Zhang } else { 2719566063dSJacob Faibussowitsch PetscCall(VecSet(ts->vec_costintegral, 0.0)); 272814e85d6SHong Zhang } 273814e85d6SHong Zhang } 274814e85d6SHong Zhang if (!ts->vec_costintegrand) { 2759566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_costintegral, &ts->vec_costintegrand)); 276814e85d6SHong Zhang } else { 2779566063dSJacob Faibussowitsch PetscCall(VecSet(ts->vec_costintegrand, 0.0)); 278814e85d6SHong Zhang } 279814e85d6SHong Zhang ts->costintegralfwd = fwd; /* Evaluate the cost integral in forward run if fwd is true */ 280814e85d6SHong Zhang ts->costintegrand = rf; 281814e85d6SHong Zhang ts->costintegrandctx = ctx; 282c9ad9de0SHong Zhang ts->drdufunction = drduf; 283814e85d6SHong Zhang ts->drdpfunction = drdpf; 2843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 285814e85d6SHong Zhang } 286814e85d6SHong Zhang 287cc4c1da9SBarry Smith /*@ 288814e85d6SHong Zhang TSGetCostIntegral - Returns the values of the integral term in the cost functions. 289814e85d6SHong Zhang It is valid to call the routine after a backward run. 290814e85d6SHong Zhang 291814e85d6SHong Zhang Not Collective 292814e85d6SHong Zhang 293814e85d6SHong Zhang Input Parameter: 294bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 295814e85d6SHong Zhang 296814e85d6SHong Zhang Output Parameter: 297814e85d6SHong Zhang . v - the vector containing the integrals for each cost function 298814e85d6SHong Zhang 299814e85d6SHong Zhang Level: intermediate 300814e85d6SHong Zhang 301a94f484eSPierre Jolivet .seealso: [](ch_ts), `TS`, `TSAdjointSolve()`, `TSSetCostIntegrand()` 302814e85d6SHong Zhang @*/ 303d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetCostIntegral(TS ts, Vec *v) 304d71ae5a4SJacob Faibussowitsch { 305cd4cee2dSHong Zhang TS quadts; 306cd4cee2dSHong Zhang 307814e85d6SHong Zhang PetscFunctionBegin; 308814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3094f572ea9SToby Isaac PetscAssertPointer(v, 2); 3109566063dSJacob Faibussowitsch PetscCall(TSGetQuadratureTS(ts, NULL, &quadts)); 311cd4cee2dSHong Zhang *v = quadts->vec_sol; 3123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 313814e85d6SHong Zhang } 314814e85d6SHong Zhang 315cc4c1da9SBarry Smith /*@ 316814e85d6SHong Zhang TSComputeCostIntegrand - Evaluates the integral function in the cost functions. 317814e85d6SHong Zhang 318814e85d6SHong Zhang Input Parameters: 319bcf0153eSBarry Smith + ts - the `TS` context 320814e85d6SHong Zhang . t - current time 321c9ad9de0SHong Zhang - U - state vector, i.e. current solution 322814e85d6SHong Zhang 323814e85d6SHong Zhang Output Parameter: 324c9ad9de0SHong Zhang . Q - vector of size numcost to hold the outputs 325814e85d6SHong Zhang 326bcf0153eSBarry Smith Level: deprecated 327bcf0153eSBarry Smith 328bcf0153eSBarry Smith Note: 329814e85d6SHong Zhang Most users should not need to explicitly call this routine, as it 330814e85d6SHong Zhang is used internally within the sensitivity analysis context. 331814e85d6SHong Zhang 3321cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAdjointSolve()`, `TSSetCostIntegrand()` 333814e85d6SHong Zhang @*/ 334d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeCostIntegrand(TS ts, PetscReal t, Vec U, Vec Q) 335d71ae5a4SJacob Faibussowitsch { 336814e85d6SHong Zhang PetscFunctionBegin; 337814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 338c9ad9de0SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 339c9ad9de0SHong Zhang PetscValidHeaderSpecific(Q, VEC_CLASSID, 4); 340814e85d6SHong Zhang 3419566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TS_FunctionEval, ts, U, Q, 0)); 342792fecdfSBarry Smith if (ts->costintegrand) PetscCallBack("TS callback integrand in the cost function", (*ts->costintegrand)(ts, t, U, Q, ts->costintegrandctx)); 343ef1023bdSBarry Smith else PetscCall(VecZeroEntries(Q)); 3449566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TS_FunctionEval, ts, U, Q, 0)); 3453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 346814e85d6SHong Zhang } 347814e85d6SHong Zhang 34814d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-* 349cc4c1da9SBarry Smith /*@ 350bcf0153eSBarry Smith TSComputeDRDUFunction - Deprecated, use `TSGetQuadratureTS()` then `TSComputeRHSJacobian()` 351814e85d6SHong Zhang 352d76be551SHong Zhang Level: deprecated 353814e85d6SHong Zhang 354814e85d6SHong Zhang @*/ 355d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeDRDUFunction(TS ts, PetscReal t, Vec U, Vec *DRDU) 356d71ae5a4SJacob Faibussowitsch { 357814e85d6SHong Zhang PetscFunctionBegin; 3583ba16761SJacob Faibussowitsch if (!DRDU) PetscFunctionReturn(PETSC_SUCCESS); 359814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 360c9ad9de0SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 361814e85d6SHong Zhang 362792fecdfSBarry Smith PetscCallBack("TS callback DRDU for sensitivity analysis", (*ts->drdufunction)(ts, t, U, DRDU, ts->costintegrandctx)); 3633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 364814e85d6SHong Zhang } 365814e85d6SHong Zhang 36614d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-* 367cc4c1da9SBarry Smith /*@ 368bcf0153eSBarry Smith TSComputeDRDPFunction - Deprecated, use `TSGetQuadratureTS()` then `TSComputeRHSJacobianP()` 369814e85d6SHong Zhang 370d76be551SHong Zhang Level: deprecated 371814e85d6SHong Zhang 372814e85d6SHong Zhang @*/ 373d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeDRDPFunction(TS ts, PetscReal t, Vec U, Vec *DRDP) 374d71ae5a4SJacob Faibussowitsch { 375814e85d6SHong Zhang PetscFunctionBegin; 3763ba16761SJacob Faibussowitsch if (!DRDP) PetscFunctionReturn(PETSC_SUCCESS); 377814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 378c9ad9de0SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 379814e85d6SHong Zhang 380792fecdfSBarry Smith PetscCallBack("TS callback DRDP for sensitivity analysis", (*ts->drdpfunction)(ts, t, U, DRDP, ts->costintegrandctx)); 3813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 382814e85d6SHong Zhang } 383814e85d6SHong Zhang 38414d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation 38514d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-section-header-unknown 386b5b4017aSHong Zhang /*@C 387b5b4017aSHong Zhang TSSetIHessianProduct - Sets the function that computes the vector-Hessian-vector product. The Hessian is the second-order derivative of F (IFunction) w.r.t. the state variable. 388b5b4017aSHong Zhang 389c3339decSBarry Smith Logically Collective 390b5b4017aSHong Zhang 391b5b4017aSHong Zhang Input Parameters: 392bcf0153eSBarry Smith + ts - `TS` context obtained from `TSCreate()` 393b5b4017aSHong Zhang . ihp1 - an array of vectors storing the result of vector-Hessian-vector product for F_UU 394b5b4017aSHong Zhang . hessianproductfunc1 - vector-Hessian-vector product function for F_UU 395b5b4017aSHong Zhang . ihp2 - an array of vectors storing the result of vector-Hessian-vector product for F_UP 396b5b4017aSHong Zhang . hessianproductfunc2 - vector-Hessian-vector product function for F_UP 397b5b4017aSHong Zhang . ihp3 - an array of vectors storing the result of vector-Hessian-vector product for F_PU 398b5b4017aSHong Zhang . hessianproductfunc3 - vector-Hessian-vector product function for F_PU 399b5b4017aSHong Zhang . ihp4 - an array of vectors storing the result of vector-Hessian-vector product for F_PP 400f0fc11ceSJed Brown - hessianproductfunc4 - vector-Hessian-vector product function for F_PP 401b5b4017aSHong Zhang 40214d0ab18SJacob Faibussowitsch Calling sequence of `ihessianproductfunc1`: 40314d0ab18SJacob Faibussowitsch + ts - the `TS` context 404b5b4017aSHong Zhang + t - current timestep 405b5b4017aSHong Zhang . U - input vector (current ODE solution) 406369cf35fSHong Zhang . Vl - an array of input vectors to be left-multiplied with the Hessian 407b5b4017aSHong Zhang . Vr - input vector to be right-multiplied with the Hessian 408369cf35fSHong Zhang . VHV - an array of output vectors for vector-Hessian-vector product 409b5b4017aSHong Zhang - ctx - [optional] user-defined function context 410b5b4017aSHong Zhang 411b5b4017aSHong Zhang Level: intermediate 412b5b4017aSHong Zhang 413369cf35fSHong Zhang Notes: 41414d0ab18SJacob Faibussowitsch All other functions have the same calling sequence as `rhhessianproductfunc1`, so their 41514d0ab18SJacob Faibussowitsch descriptions are omitted for brevity. 41614d0ab18SJacob Faibussowitsch 417369cf35fSHong Zhang The first Hessian function and the working array are required. 418369cf35fSHong Zhang As an example to implement the callback functions, the second callback function calculates the vector-Hessian-vector product 419369cf35fSHong Zhang $ Vl_n^T*F_UP*Vr 420369cf35fSHong Zhang where the vector Vl_n (n-th element in the array Vl) and Vr are of size N and M respectively, and the Hessian F_UP is of size N x N x M. 421369cf35fSHong Zhang Each entry of F_UP corresponds to the derivative 422369cf35fSHong Zhang $ F_UP[i][j][k] = \frac{\partial^2 F[i]}{\partial U[j] \partial P[k]}. 423369cf35fSHong Zhang The result of the vector-Hessian-vector product for Vl_n needs to be stored in vector VHV_n with the j-th entry being 424369cf35fSHong Zhang $ VHV_n[j] = \sum_i \sum_k {Vl_n[i] * F_UP[i][j][k] * Vr[k]} 425369cf35fSHong Zhang If the cost function is a scalar, there will be only one vector in Vl and VHV. 426b5b4017aSHong Zhang 4271cc06b55SBarry Smith .seealso: [](ch_ts), `TS` 428b5b4017aSHong Zhang @*/ 42914d0ab18SJacob Faibussowitsch PetscErrorCode TSSetIHessianProduct(TS ts, Vec *ihp1, PetscErrorCode (*ihessianproductfunc1)(TS ts, PetscReal t, Vec U, Vec *Vl, Vec Vr, Vec *VHV, void *ctx), Vec *ihp2, PetscErrorCode (*ihessianproductfunc2)(TS, PetscReal, Vec, Vec *, Vec, Vec *, void *), Vec *ihp3, PetscErrorCode (*ihessianproductfunc3)(TS, PetscReal, Vec, Vec *, Vec, Vec *, void *), Vec *ihp4, PetscErrorCode (*ihessianproductfunc4)(TS, PetscReal, Vec, Vec *, Vec, Vec *, void *), void *ctx) 430d71ae5a4SJacob Faibussowitsch { 431b5b4017aSHong Zhang PetscFunctionBegin; 432b5b4017aSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 4334f572ea9SToby Isaac PetscAssertPointer(ihp1, 2); 434b5b4017aSHong Zhang 435b5b4017aSHong Zhang ts->ihessianproductctx = ctx; 436b5b4017aSHong Zhang if (ihp1) ts->vecs_fuu = ihp1; 437b5b4017aSHong Zhang if (ihp2) ts->vecs_fup = ihp2; 438b5b4017aSHong Zhang if (ihp3) ts->vecs_fpu = ihp3; 439b5b4017aSHong Zhang if (ihp4) ts->vecs_fpp = ihp4; 440b5b4017aSHong Zhang ts->ihessianproduct_fuu = ihessianproductfunc1; 441b5b4017aSHong Zhang ts->ihessianproduct_fup = ihessianproductfunc2; 442b5b4017aSHong Zhang ts->ihessianproduct_fpu = ihessianproductfunc3; 443b5b4017aSHong Zhang ts->ihessianproduct_fpp = ihessianproductfunc4; 4443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 445b5b4017aSHong Zhang } 446b5b4017aSHong Zhang 447cc4c1da9SBarry Smith /*@ 448b1e111ebSHong Zhang TSComputeIHessianProductFunctionUU - Runs the user-defined vector-Hessian-vector product function for Fuu. 449b5b4017aSHong Zhang 450c3339decSBarry Smith Collective 451b5b4017aSHong Zhang 452b5b4017aSHong Zhang Input Parameters: 4532fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 4542fe279fdSBarry Smith . t - the time 4552fe279fdSBarry Smith . U - the solution at which to compute the Hessian product 4562fe279fdSBarry Smith . Vl - the array of input vectors to be multiplied with the Hessian from the left 4572fe279fdSBarry Smith - Vr - the input vector to be multiplied with the Hessian from the right 4582fe279fdSBarry Smith 4592fe279fdSBarry Smith Output Parameter: 460b43aa488SJacob Faibussowitsch . VHV - the array of output vectors that store the Hessian product 461b5b4017aSHong Zhang 462b5b4017aSHong Zhang Level: developer 463b5b4017aSHong Zhang 464bcf0153eSBarry Smith Note: 465bcf0153eSBarry Smith `TSComputeIHessianProductFunctionUU()` is typically used for sensitivity implementation, 466bcf0153eSBarry Smith so most users would not generally call this routine themselves. 467bcf0153eSBarry Smith 4681cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetIHessianProduct()` 469b5b4017aSHong Zhang @*/ 470cc4c1da9SBarry Smith PetscErrorCode TSComputeIHessianProductFunctionUU(TS ts, PetscReal t, Vec U, Vec Vl[], Vec Vr, Vec VHV[]) 471d71ae5a4SJacob Faibussowitsch { 472b5b4017aSHong Zhang PetscFunctionBegin; 4733ba16761SJacob Faibussowitsch if (!VHV) PetscFunctionReturn(PETSC_SUCCESS); 474b5b4017aSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 475b5b4017aSHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 476b5b4017aSHong Zhang 477792fecdfSBarry Smith if (ts->ihessianproduct_fuu) PetscCallBack("TS callback IHessianProduct 1 for sensitivity analysis", (*ts->ihessianproduct_fuu)(ts, t, U, Vl, Vr, VHV, ts->ihessianproductctx)); 478ef1023bdSBarry Smith 47967633408SHong Zhang /* does not consider IMEX for now, so either IHessian or RHSHessian will be calculated, using the same output VHV */ 48067633408SHong Zhang if (ts->rhshessianproduct_guu) { 48167633408SHong Zhang PetscInt nadj; 4829566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUU(ts, t, U, Vl, Vr, VHV)); 48348a46eb9SPierre Jolivet for (nadj = 0; nadj < ts->numcost; nadj++) PetscCall(VecScale(VHV[nadj], -1)); 48467633408SHong Zhang } 4853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 486b5b4017aSHong Zhang } 487b5b4017aSHong Zhang 488cc4c1da9SBarry Smith /*@ 489b1e111ebSHong Zhang TSComputeIHessianProductFunctionUP - Runs the user-defined vector-Hessian-vector product function for Fup. 490b5b4017aSHong Zhang 491c3339decSBarry Smith Collective 492b5b4017aSHong Zhang 493b5b4017aSHong Zhang Input Parameters: 4942fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 4952fe279fdSBarry Smith . t - the time 4962fe279fdSBarry Smith . U - the solution at which to compute the Hessian product 4972fe279fdSBarry Smith . Vl - the array of input vectors to be multiplied with the Hessian from the left 4982fe279fdSBarry Smith - Vr - the input vector to be multiplied with the Hessian from the right 4992fe279fdSBarry Smith 5002fe279fdSBarry Smith Output Parameter: 501b43aa488SJacob Faibussowitsch . VHV - the array of output vectors that store the Hessian product 502b5b4017aSHong Zhang 503b5b4017aSHong Zhang Level: developer 504b5b4017aSHong Zhang 505bcf0153eSBarry Smith Note: 506bcf0153eSBarry Smith `TSComputeIHessianProductFunctionUP()` is typically used for sensitivity implementation, 507bcf0153eSBarry Smith so most users would not generally call this routine themselves. 508bcf0153eSBarry Smith 5091cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetIHessianProduct()` 510b5b4017aSHong Zhang @*/ 511cc4c1da9SBarry Smith PetscErrorCode TSComputeIHessianProductFunctionUP(TS ts, PetscReal t, Vec U, Vec Vl[], Vec Vr, Vec VHV[]) 512d71ae5a4SJacob Faibussowitsch { 513b5b4017aSHong Zhang PetscFunctionBegin; 5143ba16761SJacob Faibussowitsch if (!VHV) PetscFunctionReturn(PETSC_SUCCESS); 515b5b4017aSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 516b5b4017aSHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 517b5b4017aSHong Zhang 518792fecdfSBarry Smith if (ts->ihessianproduct_fup) PetscCallBack("TS callback IHessianProduct 2 for sensitivity analysis", (*ts->ihessianproduct_fup)(ts, t, U, Vl, Vr, VHV, ts->ihessianproductctx)); 519ef1023bdSBarry Smith 52067633408SHong Zhang /* does not consider IMEX for now, so either IHessian or RHSHessian will be calculated, using the same output VHV */ 52167633408SHong Zhang if (ts->rhshessianproduct_gup) { 52267633408SHong Zhang PetscInt nadj; 5239566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionUP(ts, t, U, Vl, Vr, VHV)); 52448a46eb9SPierre Jolivet for (nadj = 0; nadj < ts->numcost; nadj++) PetscCall(VecScale(VHV[nadj], -1)); 52567633408SHong Zhang } 5263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 527b5b4017aSHong Zhang } 528b5b4017aSHong Zhang 529cc4c1da9SBarry Smith /*@ 530b1e111ebSHong Zhang TSComputeIHessianProductFunctionPU - Runs the user-defined vector-Hessian-vector product function for Fpu. 531b5b4017aSHong Zhang 532c3339decSBarry Smith Collective 533b5b4017aSHong Zhang 534b5b4017aSHong Zhang Input Parameters: 5352fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 5362fe279fdSBarry Smith . t - the time 5372fe279fdSBarry Smith . U - the solution at which to compute the Hessian product 5382fe279fdSBarry Smith . Vl - the array of input vectors to be multiplied with the Hessian from the left 5392fe279fdSBarry Smith - Vr - the input vector to be multiplied with the Hessian from the right 5402fe279fdSBarry Smith 5412fe279fdSBarry Smith Output Parameter: 542b43aa488SJacob Faibussowitsch . VHV - the array of output vectors that store the Hessian product 543b5b4017aSHong Zhang 544b5b4017aSHong Zhang Level: developer 545b5b4017aSHong Zhang 546bcf0153eSBarry Smith Note: 547bcf0153eSBarry Smith `TSComputeIHessianProductFunctionPU()` is typically used for sensitivity implementation, 548bcf0153eSBarry Smith so most users would not generally call this routine themselves. 549bcf0153eSBarry Smith 5501cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetIHessianProduct()` 551b5b4017aSHong Zhang @*/ 552cc4c1da9SBarry Smith PetscErrorCode TSComputeIHessianProductFunctionPU(TS ts, PetscReal t, Vec U, Vec Vl[], Vec Vr, Vec VHV[]) 553d71ae5a4SJacob Faibussowitsch { 554b5b4017aSHong Zhang PetscFunctionBegin; 5553ba16761SJacob Faibussowitsch if (!VHV) PetscFunctionReturn(PETSC_SUCCESS); 556b5b4017aSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 557b5b4017aSHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 558b5b4017aSHong Zhang 559792fecdfSBarry Smith if (ts->ihessianproduct_fpu) PetscCallBack("TS callback IHessianProduct 3 for sensitivity analysis", (*ts->ihessianproduct_fpu)(ts, t, U, Vl, Vr, VHV, ts->ihessianproductctx)); 560ef1023bdSBarry Smith 56167633408SHong Zhang /* does not consider IMEX for now, so either IHessian or RHSHessian will be calculated, using the same output VHV */ 56267633408SHong Zhang if (ts->rhshessianproduct_gpu) { 56367633408SHong Zhang PetscInt nadj; 5649566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPU(ts, t, U, Vl, Vr, VHV)); 56548a46eb9SPierre Jolivet for (nadj = 0; nadj < ts->numcost; nadj++) PetscCall(VecScale(VHV[nadj], -1)); 56667633408SHong Zhang } 5673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 568b5b4017aSHong Zhang } 569b5b4017aSHong Zhang 570b5b4017aSHong Zhang /*@C 571b1e111ebSHong Zhang TSComputeIHessianProductFunctionPP - Runs the user-defined vector-Hessian-vector product function for Fpp. 572b5b4017aSHong Zhang 573c3339decSBarry Smith Collective 574b5b4017aSHong Zhang 575b5b4017aSHong Zhang Input Parameters: 5762fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 5772fe279fdSBarry Smith . t - the time 5782fe279fdSBarry Smith . U - the solution at which to compute the Hessian product 5792fe279fdSBarry Smith . Vl - the array of input vectors to be multiplied with the Hessian from the left 5802fe279fdSBarry Smith - Vr - the input vector to be multiplied with the Hessian from the right 5812fe279fdSBarry Smith 5822fe279fdSBarry Smith Output Parameter: 583b43aa488SJacob Faibussowitsch . VHV - the array of output vectors that store the Hessian product 584b5b4017aSHong Zhang 585b5b4017aSHong Zhang Level: developer 586b5b4017aSHong Zhang 587bcf0153eSBarry Smith Note: 588bcf0153eSBarry Smith `TSComputeIHessianProductFunctionPP()` is typically used for sensitivity implementation, 589bcf0153eSBarry Smith so most users would not generally call this routine themselves. 590bcf0153eSBarry Smith 5911cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetIHessianProduct()` 592b5b4017aSHong Zhang @*/ 593cc4c1da9SBarry Smith PetscErrorCode TSComputeIHessianProductFunctionPP(TS ts, PetscReal t, Vec U, Vec Vl[], Vec Vr, Vec VHV[]) 594d71ae5a4SJacob Faibussowitsch { 595b5b4017aSHong Zhang PetscFunctionBegin; 5963ba16761SJacob Faibussowitsch if (!VHV) PetscFunctionReturn(PETSC_SUCCESS); 597b5b4017aSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 598b5b4017aSHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 599b5b4017aSHong Zhang 600792fecdfSBarry Smith if (ts->ihessianproduct_fpp) PetscCallBack("TS callback IHessianProduct 3 for sensitivity analysis", (*ts->ihessianproduct_fpp)(ts, t, U, Vl, Vr, VHV, ts->ihessianproductctx)); 601ef1023bdSBarry Smith 60267633408SHong Zhang /* does not consider IMEX for now, so either IHessian or RHSHessian will be calculated, using the same output VHV */ 60367633408SHong Zhang if (ts->rhshessianproduct_gpp) { 60467633408SHong Zhang PetscInt nadj; 6059566063dSJacob Faibussowitsch PetscCall(TSComputeRHSHessianProductFunctionPP(ts, t, U, Vl, Vr, VHV)); 60648a46eb9SPierre Jolivet for (nadj = 0; nadj < ts->numcost; nadj++) PetscCall(VecScale(VHV[nadj], -1)); 60767633408SHong Zhang } 6083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 609b5b4017aSHong Zhang } 610b5b4017aSHong Zhang 61114d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation 61214d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-section-header-unknown 61313af1a74SHong Zhang /*@C 61414d0ab18SJacob Faibussowitsch TSSetRHSHessianProduct - Sets the function that computes the vector-Hessian-vector 61514d0ab18SJacob Faibussowitsch product. The Hessian is the second-order derivative of G (RHSFunction) w.r.t. the state 61614d0ab18SJacob Faibussowitsch variable. 61713af1a74SHong Zhang 618c3339decSBarry Smith Logically Collective 61913af1a74SHong Zhang 62013af1a74SHong Zhang Input Parameters: 621bcf0153eSBarry Smith + ts - `TS` context obtained from `TSCreate()` 62213af1a74SHong Zhang . rhshp1 - an array of vectors storing the result of vector-Hessian-vector product for G_UU 62313af1a74SHong Zhang . hessianproductfunc1 - vector-Hessian-vector product function for G_UU 62413af1a74SHong Zhang . rhshp2 - an array of vectors storing the result of vector-Hessian-vector product for G_UP 62513af1a74SHong Zhang . hessianproductfunc2 - vector-Hessian-vector product function for G_UP 62613af1a74SHong Zhang . rhshp3 - an array of vectors storing the result of vector-Hessian-vector product for G_PU 62713af1a74SHong Zhang . hessianproductfunc3 - vector-Hessian-vector product function for G_PU 62813af1a74SHong Zhang . rhshp4 - an array of vectors storing the result of vector-Hessian-vector product for G_PP 62914d0ab18SJacob Faibussowitsch . hessianproductfunc4 - vector-Hessian-vector product function for G_PP 63014d0ab18SJacob Faibussowitsch - ctx - [optional] user-defined function context 63113af1a74SHong Zhang 63214d0ab18SJacob Faibussowitsch Calling sequence of `rhshessianproductfunc1`: 63314d0ab18SJacob Faibussowitsch + ts - the `TS` context 63414d0ab18SJacob Faibussowitsch . t - current timestep 63513af1a74SHong Zhang . U - input vector (current ODE solution) 636369cf35fSHong Zhang . Vl - an array of input vectors to be left-multiplied with the Hessian 63713af1a74SHong Zhang . Vr - input vector to be right-multiplied with the Hessian 638369cf35fSHong Zhang . VHV - an array of output vectors for vector-Hessian-vector product 63913af1a74SHong Zhang - ctx - [optional] user-defined function context 64013af1a74SHong Zhang 64113af1a74SHong Zhang Level: intermediate 64213af1a74SHong Zhang 643369cf35fSHong Zhang Notes: 64414d0ab18SJacob Faibussowitsch All other functions have the same calling sequence as `rhhessianproductfunc1`, so their 64514d0ab18SJacob Faibussowitsch descriptions are omitted for brevity. 64614d0ab18SJacob Faibussowitsch 647369cf35fSHong Zhang The first Hessian function and the working array are required. 64814d0ab18SJacob Faibussowitsch 649369cf35fSHong Zhang As an example to implement the callback functions, the second callback function calculates the vector-Hessian-vector product 650369cf35fSHong Zhang $ Vl_n^T*G_UP*Vr 651369cf35fSHong Zhang where the vector Vl_n (n-th element in the array Vl) and Vr are of size N and M respectively, and the Hessian G_UP is of size N x N x M. 652369cf35fSHong Zhang Each entry of G_UP corresponds to the derivative 653369cf35fSHong Zhang $ G_UP[i][j][k] = \frac{\partial^2 G[i]}{\partial U[j] \partial P[k]}. 654369cf35fSHong Zhang The result of the vector-Hessian-vector product for Vl_n needs to be stored in vector VHV_n with j-th entry being 655369cf35fSHong Zhang $ VHV_n[j] = \sum_i \sum_k {Vl_n[i] * G_UP[i][j][k] * Vr[k]} 656369cf35fSHong Zhang If the cost function is a scalar, there will be only one vector in Vl and VHV. 65713af1a74SHong Zhang 6582fe279fdSBarry Smith .seealso: `TS`, `TSAdjoint` 65913af1a74SHong Zhang @*/ 66014d0ab18SJacob Faibussowitsch PetscErrorCode TSSetRHSHessianProduct(TS ts, Vec *rhshp1, PetscErrorCode (*rhshessianproductfunc1)(TS ts, PetscReal t, Vec U, Vec *Vl, Vec Vr, Vec *VHV, void *ctx), Vec *rhshp2, PetscErrorCode (*rhshessianproductfunc2)(TS, PetscReal, Vec, Vec *, Vec, Vec *, void *), Vec *rhshp3, PetscErrorCode (*rhshessianproductfunc3)(TS, PetscReal, Vec, Vec *, Vec, Vec *, void *), Vec *rhshp4, PetscErrorCode (*rhshessianproductfunc4)(TS, PetscReal, Vec, Vec *, Vec, Vec *, void *), void *ctx) 661d71ae5a4SJacob Faibussowitsch { 66213af1a74SHong Zhang PetscFunctionBegin; 66313af1a74SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 6644f572ea9SToby Isaac PetscAssertPointer(rhshp1, 2); 66513af1a74SHong Zhang 66613af1a74SHong Zhang ts->rhshessianproductctx = ctx; 66713af1a74SHong Zhang if (rhshp1) ts->vecs_guu = rhshp1; 66813af1a74SHong Zhang if (rhshp2) ts->vecs_gup = rhshp2; 66913af1a74SHong Zhang if (rhshp3) ts->vecs_gpu = rhshp3; 67013af1a74SHong Zhang if (rhshp4) ts->vecs_gpp = rhshp4; 67113af1a74SHong Zhang ts->rhshessianproduct_guu = rhshessianproductfunc1; 67213af1a74SHong Zhang ts->rhshessianproduct_gup = rhshessianproductfunc2; 67313af1a74SHong Zhang ts->rhshessianproduct_gpu = rhshessianproductfunc3; 67413af1a74SHong Zhang ts->rhshessianproduct_gpp = rhshessianproductfunc4; 6753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 67613af1a74SHong Zhang } 67713af1a74SHong Zhang 678cc4c1da9SBarry Smith /*@ 679b1e111ebSHong Zhang TSComputeRHSHessianProductFunctionUU - Runs the user-defined vector-Hessian-vector product function for Guu. 68013af1a74SHong Zhang 681c3339decSBarry Smith Collective 68213af1a74SHong Zhang 68313af1a74SHong Zhang Input Parameters: 6842fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 6852fe279fdSBarry Smith . t - the time 6862fe279fdSBarry Smith . U - the solution at which to compute the Hessian product 6872fe279fdSBarry Smith . Vl - the array of input vectors to be multiplied with the Hessian from the left 6882fe279fdSBarry Smith - Vr - the input vector to be multiplied with the Hessian from the right 6892fe279fdSBarry Smith 6902fe279fdSBarry Smith Output Parameter: 691b43aa488SJacob Faibussowitsch . VHV - the array of output vectors that store the Hessian product 69213af1a74SHong Zhang 69313af1a74SHong Zhang Level: developer 69413af1a74SHong Zhang 695bcf0153eSBarry Smith Note: 696bcf0153eSBarry Smith `TSComputeRHSHessianProductFunctionUU()` is typically used for sensitivity implementation, 697bcf0153eSBarry Smith so most users would not generally call this routine themselves. 698bcf0153eSBarry Smith 6991cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSHessianProduct()` 70013af1a74SHong Zhang @*/ 701cc4c1da9SBarry Smith PetscErrorCode TSComputeRHSHessianProductFunctionUU(TS ts, PetscReal t, Vec U, Vec Vl[], Vec Vr, Vec VHV[]) 702d71ae5a4SJacob Faibussowitsch { 70313af1a74SHong Zhang PetscFunctionBegin; 7043ba16761SJacob Faibussowitsch if (!VHV) PetscFunctionReturn(PETSC_SUCCESS); 70513af1a74SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 70613af1a74SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 70713af1a74SHong Zhang 708792fecdfSBarry Smith PetscCallBack("TS callback RHSHessianProduct 1 for sensitivity analysis", (*ts->rhshessianproduct_guu)(ts, t, U, Vl, Vr, VHV, ts->rhshessianproductctx)); 7093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71013af1a74SHong Zhang } 71113af1a74SHong Zhang 712cc4c1da9SBarry Smith /*@ 713b1e111ebSHong Zhang TSComputeRHSHessianProductFunctionUP - Runs the user-defined vector-Hessian-vector product function for Gup. 71413af1a74SHong Zhang 715c3339decSBarry Smith Collective 71613af1a74SHong Zhang 71713af1a74SHong Zhang Input Parameters: 7182fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 7192fe279fdSBarry Smith . t - the time 7202fe279fdSBarry Smith . U - the solution at which to compute the Hessian product 7212fe279fdSBarry Smith . Vl - the array of input vectors to be multiplied with the Hessian from the left 7222fe279fdSBarry Smith - Vr - the input vector to be multiplied with the Hessian from the right 7232fe279fdSBarry Smith 7242fe279fdSBarry Smith Output Parameter: 725b43aa488SJacob Faibussowitsch . VHV - the array of output vectors that store the Hessian product 72613af1a74SHong Zhang 72713af1a74SHong Zhang Level: developer 72813af1a74SHong Zhang 729bcf0153eSBarry Smith Note: 730bcf0153eSBarry Smith `TSComputeRHSHessianProductFunctionUP()` is typically used for sensitivity implementation, 731bcf0153eSBarry Smith so most users would not generally call this routine themselves. 732bcf0153eSBarry Smith 7331cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSHessianProduct()` 73413af1a74SHong Zhang @*/ 735cc4c1da9SBarry Smith PetscErrorCode TSComputeRHSHessianProductFunctionUP(TS ts, PetscReal t, Vec U, Vec Vl[], Vec Vr, Vec VHV[]) 736d71ae5a4SJacob Faibussowitsch { 73713af1a74SHong Zhang PetscFunctionBegin; 7383ba16761SJacob Faibussowitsch if (!VHV) PetscFunctionReturn(PETSC_SUCCESS); 73913af1a74SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 74013af1a74SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 74113af1a74SHong Zhang 742792fecdfSBarry Smith PetscCallBack("TS callback RHSHessianProduct 2 for sensitivity analysis", (*ts->rhshessianproduct_gup)(ts, t, U, Vl, Vr, VHV, ts->rhshessianproductctx)); 7433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74413af1a74SHong Zhang } 74513af1a74SHong Zhang 746cc4c1da9SBarry Smith /*@ 747b1e111ebSHong Zhang TSComputeRHSHessianProductFunctionPU - Runs the user-defined vector-Hessian-vector product function for Gpu. 74813af1a74SHong Zhang 749c3339decSBarry Smith Collective 75013af1a74SHong Zhang 75113af1a74SHong Zhang Input Parameters: 7522fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 7532fe279fdSBarry Smith . t - the time 7542fe279fdSBarry Smith . U - the solution at which to compute the Hessian product 7552fe279fdSBarry Smith . Vl - the array of input vectors to be multiplied with the Hessian from the left 7562fe279fdSBarry Smith - Vr - the input vector to be multiplied with the Hessian from the right 7572fe279fdSBarry Smith 7582fe279fdSBarry Smith Output Parameter: 759b43aa488SJacob Faibussowitsch . VHV - the array of output vectors that store the Hessian product 76013af1a74SHong Zhang 76113af1a74SHong Zhang Level: developer 76213af1a74SHong Zhang 763bcf0153eSBarry Smith Note: 764bcf0153eSBarry Smith `TSComputeRHSHessianProductFunctionPU()` is typically used for sensitivity implementation, 765bcf0153eSBarry Smith so most users would not generally call this routine themselves. 766bcf0153eSBarry Smith 7671cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetRHSHessianProduct()` 76813af1a74SHong Zhang @*/ 769cc4c1da9SBarry Smith PetscErrorCode TSComputeRHSHessianProductFunctionPU(TS ts, PetscReal t, Vec U, Vec Vl[], Vec Vr, Vec VHV[]) 770d71ae5a4SJacob Faibussowitsch { 77113af1a74SHong Zhang PetscFunctionBegin; 7723ba16761SJacob Faibussowitsch if (!VHV) PetscFunctionReturn(PETSC_SUCCESS); 77313af1a74SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 77413af1a74SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 77513af1a74SHong Zhang 776792fecdfSBarry Smith PetscCallBack("TS callback RHSHessianProduct 3 for sensitivity analysis", (*ts->rhshessianproduct_gpu)(ts, t, U, Vl, Vr, VHV, ts->rhshessianproductctx)); 7773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77813af1a74SHong Zhang } 77913af1a74SHong Zhang 780cc4c1da9SBarry Smith /*@ 781b1e111ebSHong Zhang TSComputeRHSHessianProductFunctionPP - Runs the user-defined vector-Hessian-vector product function for Gpp. 78213af1a74SHong Zhang 783c3339decSBarry Smith Collective 78413af1a74SHong Zhang 78513af1a74SHong Zhang Input Parameters: 7862fe279fdSBarry Smith + ts - The `TS` context obtained from `TSCreate()` 7872fe279fdSBarry Smith . t - the time 7882fe279fdSBarry Smith . U - the solution at which to compute the Hessian product 7892fe279fdSBarry Smith . Vl - the array of input vectors to be multiplied with the Hessian from the left 7902fe279fdSBarry Smith - Vr - the input vector to be multiplied with the Hessian from the right 7912fe279fdSBarry Smith 7922fe279fdSBarry Smith Output Parameter: 793b43aa488SJacob Faibussowitsch . VHV - the array of output vectors that store the Hessian product 79413af1a74SHong Zhang 79513af1a74SHong Zhang Level: developer 79613af1a74SHong Zhang 797bcf0153eSBarry Smith Note: 798bcf0153eSBarry Smith `TSComputeRHSHessianProductFunctionPP()` is typically used for sensitivity implementation, 799bcf0153eSBarry Smith so most users would not generally call this routine themselves. 800bcf0153eSBarry Smith 8011cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetRHSHessianProduct()` 80213af1a74SHong Zhang @*/ 803cc4c1da9SBarry Smith PetscErrorCode TSComputeRHSHessianProductFunctionPP(TS ts, PetscReal t, Vec U, Vec Vl[], Vec Vr, Vec VHV[]) 804d71ae5a4SJacob Faibussowitsch { 80513af1a74SHong Zhang PetscFunctionBegin; 8063ba16761SJacob Faibussowitsch if (!VHV) PetscFunctionReturn(PETSC_SUCCESS); 80713af1a74SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 80813af1a74SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 80913af1a74SHong Zhang 810792fecdfSBarry Smith PetscCallBack("TS callback RHSHessianProduct 3 for sensitivity analysis", (*ts->rhshessianproduct_gpp)(ts, t, U, Vl, Vr, VHV, ts->rhshessianproductctx)); 8113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81213af1a74SHong Zhang } 81313af1a74SHong Zhang 814814e85d6SHong Zhang /* --------------------------- Adjoint sensitivity ---------------------------*/ 815814e85d6SHong Zhang 816814e85d6SHong Zhang /*@ 817814e85d6SHong Zhang TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial values and w.r.t. the problem parameters 818bcf0153eSBarry Smith for use by the `TS` adjoint routines. 819814e85d6SHong Zhang 820c3339decSBarry Smith Logically Collective 821814e85d6SHong Zhang 822814e85d6SHong Zhang Input Parameters: 823bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 824d2fd7bfcSHong Zhang . numcost - number of gradients to be computed, this is the number of cost functions 825814e85d6SHong Zhang . lambda - gradients with respect to the initial condition variables, the dimension and parallel layout of these vectors is the same as the ODE solution vector 826814e85d6SHong Zhang - mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 827814e85d6SHong Zhang 828814e85d6SHong Zhang Level: beginner 829814e85d6SHong Zhang 830814e85d6SHong Zhang Notes: 83135cb6cd3SPierre Jolivet the entries in these vectors must be correctly initialized with the values lambda_i = df/dy|finaltime mu_i = df/dp|finaltime 832814e85d6SHong Zhang 83335cb6cd3SPierre Jolivet After `TSAdjointSolve()` is called the lambda and the mu contain the computed sensitivities 834814e85d6SHong Zhang 835bcf0153eSBarry Smith .seealso: `TS`, `TSAdjointSolve()`, `TSGetCostGradients()` 836814e85d6SHong Zhang @*/ 837d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetCostGradients(TS ts, PetscInt numcost, Vec *lambda, Vec *mu) 838d71ae5a4SJacob Faibussowitsch { 839814e85d6SHong Zhang PetscFunctionBegin; 840814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 8414f572ea9SToby Isaac PetscAssertPointer(lambda, 3); 842814e85d6SHong Zhang ts->vecs_sensi = lambda; 843814e85d6SHong Zhang ts->vecs_sensip = mu; 8443c633725SBarry Smith PetscCheck(!ts->numcost || ts->numcost == numcost, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "The number of cost functions (2nd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostIntegrand"); 845814e85d6SHong Zhang ts->numcost = numcost; 8463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 847814e85d6SHong Zhang } 848814e85d6SHong Zhang 849814e85d6SHong Zhang /*@ 850bcf0153eSBarry Smith TSGetCostGradients - Returns the gradients from the `TSAdjointSolve()` 851814e85d6SHong Zhang 852bcf0153eSBarry Smith Not Collective, but the vectors returned are parallel if `TS` is parallel 853814e85d6SHong Zhang 854814e85d6SHong Zhang Input Parameter: 855bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 856814e85d6SHong Zhang 857d8d19677SJose E. Roman Output Parameters: 8586b867d5aSJose E. Roman + numcost - size of returned arrays 8596b867d5aSJose E. Roman . lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 860814e85d6SHong Zhang - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 861814e85d6SHong Zhang 862814e85d6SHong Zhang Level: intermediate 863814e85d6SHong Zhang 8641cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAdjointSolve()`, `TSSetCostGradients()` 865814e85d6SHong Zhang @*/ 866d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetCostGradients(TS ts, PetscInt *numcost, Vec **lambda, Vec **mu) 867d71ae5a4SJacob Faibussowitsch { 868814e85d6SHong Zhang PetscFunctionBegin; 869814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 870814e85d6SHong Zhang if (numcost) *numcost = ts->numcost; 871814e85d6SHong Zhang if (lambda) *lambda = ts->vecs_sensi; 872814e85d6SHong Zhang if (mu) *mu = ts->vecs_sensip; 8733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 874814e85d6SHong Zhang } 875814e85d6SHong Zhang 876814e85d6SHong Zhang /*@ 877b5b4017aSHong Zhang TSSetCostHessianProducts - Sets the initial value of the Hessian-vector products of the cost function w.r.t. initial values and w.r.t. the problem parameters 878bcf0153eSBarry Smith for use by the `TS` adjoint routines. 879b5b4017aSHong Zhang 880c3339decSBarry Smith Logically Collective 881b5b4017aSHong Zhang 882b5b4017aSHong Zhang Input Parameters: 883bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 884b5b4017aSHong Zhang . numcost - number of cost functions 885b5b4017aSHong Zhang . lambda2 - Hessian-vector product with respect to the initial condition variables, the dimension and parallel layout of these vectors is the same as the ODE solution vector 886b5b4017aSHong Zhang . mu2 - Hessian-vector product with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 887b5b4017aSHong Zhang - dir - the direction vector that are multiplied with the Hessian of the cost functions 888b5b4017aSHong Zhang 889b5b4017aSHong Zhang Level: beginner 890b5b4017aSHong Zhang 891bcf0153eSBarry Smith Notes: 892bcf0153eSBarry Smith Hessian of the cost function is completely different from Hessian of the ODE/DAE system 893b5b4017aSHong Zhang 894bcf0153eSBarry Smith For second-order adjoint, one needs to call this function and then `TSAdjointSetForward()` before `TSSolve()`. 895b5b4017aSHong Zhang 89635cb6cd3SPierre Jolivet After `TSAdjointSolve()` is called, the lambda2 and the mu2 will contain the computed second-order adjoint sensitivities, and can be used to produce Hessian-vector product (not the full Hessian matrix). Users must provide a direction vector; it is usually generated by an optimization solver. 897b5b4017aSHong Zhang 8982fe279fdSBarry Smith Passing `NULL` for `lambda2` disables the second-order calculation. 899bcf0153eSBarry Smith 9001cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAdjointSolve()`, `TSAdjointSetForward()` 901b5b4017aSHong Zhang @*/ 902d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetCostHessianProducts(TS ts, PetscInt numcost, Vec *lambda2, Vec *mu2, Vec dir) 903d71ae5a4SJacob Faibussowitsch { 904b5b4017aSHong Zhang PetscFunctionBegin; 905b5b4017aSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 9063c633725SBarry Smith PetscCheck(!ts->numcost || ts->numcost == numcost, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "The number of cost functions (2nd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostIntegrand"); 907b5b4017aSHong Zhang ts->numcost = numcost; 908b5b4017aSHong Zhang ts->vecs_sensi2 = lambda2; 90933f72c5dSHong Zhang ts->vecs_sensi2p = mu2; 910b5b4017aSHong Zhang ts->vec_dir = dir; 9113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 912b5b4017aSHong Zhang } 913b5b4017aSHong Zhang 914b5b4017aSHong Zhang /*@ 915bcf0153eSBarry Smith TSGetCostHessianProducts - Returns the gradients from the `TSAdjointSolve()` 916b5b4017aSHong Zhang 917bcf0153eSBarry Smith Not Collective, but vectors returned are parallel if `TS` is parallel 918b5b4017aSHong Zhang 919b5b4017aSHong Zhang Input Parameter: 920bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 921b5b4017aSHong Zhang 922d8d19677SJose E. Roman Output Parameters: 923b5b4017aSHong Zhang + numcost - number of cost functions 924b5b4017aSHong Zhang . lambda2 - Hessian-vector product with respect to the initial condition variables, the dimension and parallel layout of these vectors is the same as the ODE solution vector 925b5b4017aSHong Zhang . mu2 - Hessian-vector product with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 926b5b4017aSHong Zhang - dir - the direction vector that are multiplied with the Hessian of the cost functions 927b5b4017aSHong Zhang 928b5b4017aSHong Zhang Level: intermediate 929b5b4017aSHong Zhang 9301cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdjointSolve()`, `TSSetCostHessianProducts()` 931b5b4017aSHong Zhang @*/ 932d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetCostHessianProducts(TS ts, PetscInt *numcost, Vec **lambda2, Vec **mu2, Vec *dir) 933d71ae5a4SJacob Faibussowitsch { 934b5b4017aSHong Zhang PetscFunctionBegin; 935b5b4017aSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 936b5b4017aSHong Zhang if (numcost) *numcost = ts->numcost; 937b5b4017aSHong Zhang if (lambda2) *lambda2 = ts->vecs_sensi2; 93833f72c5dSHong Zhang if (mu2) *mu2 = ts->vecs_sensi2p; 939b5b4017aSHong Zhang if (dir) *dir = ts->vec_dir; 9403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 941b5b4017aSHong Zhang } 942b5b4017aSHong Zhang 943b5b4017aSHong Zhang /*@ 944ecf68647SHong Zhang TSAdjointSetForward - Trigger the tangent linear solver and initialize the forward sensitivities 945b5b4017aSHong Zhang 946c3339decSBarry Smith Logically Collective 947b5b4017aSHong Zhang 948b5b4017aSHong Zhang Input Parameters: 949bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 950b5b4017aSHong Zhang - didp - the derivative of initial values w.r.t. parameters 951b5b4017aSHong Zhang 952b5b4017aSHong Zhang Level: intermediate 953b5b4017aSHong Zhang 954bcf0153eSBarry Smith Notes: 955baca6076SPierre Jolivet When computing sensitivities w.r.t. initial condition, set didp to `NULL` so that the solver will take it as an identity matrix mathematically. 9562fe279fdSBarry Smith `TSAdjoint` does not reset the tangent linear solver automatically, `TSAdjointResetForward()` should be called to reset the tangent linear solver. 957b5b4017aSHong Zhang 9581cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdjointSolve()`, `TSSetCostHessianProducts()`, `TSAdjointResetForward()` 959b5b4017aSHong Zhang @*/ 960d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointSetForward(TS ts, Mat didp) 961d71ae5a4SJacob Faibussowitsch { 96233f72c5dSHong Zhang Mat A; 96333f72c5dSHong Zhang Vec sp; 96433f72c5dSHong Zhang PetscScalar *xarr; 96533f72c5dSHong Zhang PetscInt lsize; 966b5b4017aSHong Zhang 967b5b4017aSHong Zhang PetscFunctionBegin; 968b5b4017aSHong Zhang ts->forward_solve = PETSC_TRUE; /* turn on tangent linear mode */ 9693c633725SBarry Smith PetscCheck(ts->vecs_sensi2, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetCostHessianProducts() first"); 9703c633725SBarry Smith PetscCheck(ts->vec_dir, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Directional vector is missing. Call TSSetCostHessianProducts() to set it."); 97133f72c5dSHong Zhang /* create a single-column dense matrix */ 9729566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(ts->vec_sol, &lsize)); 9739566063dSJacob Faibussowitsch PetscCall(MatCreateDense(PetscObjectComm((PetscObject)ts), lsize, PETSC_DECIDE, PETSC_DECIDE, 1, NULL, &A)); 97433f72c5dSHong Zhang 9759566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &sp)); 9769566063dSJacob Faibussowitsch PetscCall(MatDenseGetColumn(A, 0, &xarr)); 9779566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(sp, xarr)); 978ecf68647SHong Zhang if (ts->vecs_sensi2p) { /* tangent linear variable initialized as 2*dIdP*dir */ 97933f72c5dSHong Zhang if (didp) { 9809566063dSJacob Faibussowitsch PetscCall(MatMult(didp, ts->vec_dir, sp)); 9819566063dSJacob Faibussowitsch PetscCall(VecScale(sp, 2.)); 98233f72c5dSHong Zhang } else { 9839566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(sp)); 98433f72c5dSHong Zhang } 985ecf68647SHong Zhang } else { /* tangent linear variable initialized as dir */ 9869566063dSJacob Faibussowitsch PetscCall(VecCopy(ts->vec_dir, sp)); 98733f72c5dSHong Zhang } 9889566063dSJacob Faibussowitsch PetscCall(VecResetArray(sp)); 9899566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreColumn(A, &xarr)); 9909566063dSJacob Faibussowitsch PetscCall(VecDestroy(&sp)); 99133f72c5dSHong Zhang 9929566063dSJacob Faibussowitsch PetscCall(TSForwardSetInitialSensitivities(ts, A)); /* if didp is NULL, identity matrix is assumed */ 99333f72c5dSHong Zhang 9949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 9953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 996b5b4017aSHong Zhang } 997b5b4017aSHong Zhang 998b5b4017aSHong Zhang /*@ 999ecf68647SHong Zhang TSAdjointResetForward - Reset the tangent linear solver and destroy the tangent linear context 1000ecf68647SHong Zhang 1001c3339decSBarry Smith Logically Collective 1002ecf68647SHong Zhang 10032fe279fdSBarry Smith Input Parameter: 1004bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1005ecf68647SHong Zhang 1006ecf68647SHong Zhang Level: intermediate 1007ecf68647SHong Zhang 10081cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdjointSetForward()` 1009ecf68647SHong Zhang @*/ 1010d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointResetForward(TS ts) 1011d71ae5a4SJacob Faibussowitsch { 1012ecf68647SHong Zhang PetscFunctionBegin; 1013ecf68647SHong Zhang ts->forward_solve = PETSC_FALSE; /* turn off tangent linear mode */ 10149566063dSJacob Faibussowitsch PetscCall(TSForwardReset(ts)); 10153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1016ecf68647SHong Zhang } 1017ecf68647SHong Zhang 1018ecf68647SHong Zhang /*@ 1019814e85d6SHong Zhang TSAdjointSetUp - Sets up the internal data structures for the later use 1020814e85d6SHong Zhang of an adjoint solver 1021814e85d6SHong Zhang 1022c3339decSBarry Smith Collective 1023814e85d6SHong Zhang 1024814e85d6SHong Zhang Input Parameter: 1025bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1026814e85d6SHong Zhang 1027814e85d6SHong Zhang Level: advanced 1028814e85d6SHong Zhang 10291cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TSAdjointStep()`, `TSSetCostGradients()` 1030814e85d6SHong Zhang @*/ 1031d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointSetUp(TS ts) 1032d71ae5a4SJacob Faibussowitsch { 1033881c1a9bSHong Zhang TSTrajectory tj; 1034881c1a9bSHong Zhang PetscBool match; 1035814e85d6SHong Zhang 1036814e85d6SHong Zhang PetscFunctionBegin; 1037814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 10383ba16761SJacob Faibussowitsch if (ts->adjointsetupcalled) PetscFunctionReturn(PETSC_SUCCESS); 10393c633725SBarry Smith PetscCheck(ts->vecs_sensi, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "Must call TSSetCostGradients() first"); 10403c633725SBarry Smith PetscCheck(!ts->vecs_sensip || ts->Jacp || ts->Jacprhs, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "Must call TSSetRHSJacobianP() or TSSetIJacobianP() first"); 10419566063dSJacob Faibussowitsch PetscCall(TSGetTrajectory(ts, &tj)); 10429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)tj, TSTRAJECTORYBASIC, &match)); 1043881c1a9bSHong Zhang if (match) { 1044881c1a9bSHong Zhang PetscBool solution_only; 10459566063dSJacob Faibussowitsch PetscCall(TSTrajectoryGetSolutionOnly(tj, &solution_only)); 10463c633725SBarry Smith PetscCheck(!solution_only, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "TSAdjoint cannot use the solution-only mode when choosing the Basic TSTrajectory type. Turn it off with -ts_trajectory_solution_only 0"); 1047881c1a9bSHong Zhang } 10489566063dSJacob Faibussowitsch PetscCall(TSTrajectorySetUseHistory(tj, PETSC_FALSE)); /* not use TSHistory */ 104933f72c5dSHong Zhang 1050cd4cee2dSHong Zhang if (ts->quadraturets) { /* if there is integral in the cost function */ 10519566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vecs_sensi[0], &ts->vec_drdu_col)); 105248a46eb9SPierre Jolivet if (ts->vecs_sensip) PetscCall(VecDuplicate(ts->vecs_sensip[0], &ts->vec_drdp_col)); 1053814e85d6SHong Zhang } 1054814e85d6SHong Zhang 1055dbbe0bcdSBarry Smith PetscTryTypeMethod(ts, adjointsetup); 1056814e85d6SHong Zhang ts->adjointsetupcalled = PETSC_TRUE; 10573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1058814e85d6SHong Zhang } 1059814e85d6SHong Zhang 1060814e85d6SHong Zhang /*@ 1061bcf0153eSBarry Smith TSAdjointReset - Resets a `TS` adjoint context and removes any allocated `Vec`s and `Mat`s. 1062ece46509SHong Zhang 1063c3339decSBarry Smith Collective 1064ece46509SHong Zhang 1065ece46509SHong Zhang Input Parameter: 1066bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1067ece46509SHong Zhang 1068ece46509SHong Zhang Level: beginner 1069ece46509SHong Zhang 10701cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TSAdjointSetUp()`, `TSADestroy()` 1071ece46509SHong Zhang @*/ 1072d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointReset(TS ts) 1073d71ae5a4SJacob Faibussowitsch { 1074ece46509SHong Zhang PetscFunctionBegin; 1075ece46509SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1076dbbe0bcdSBarry Smith PetscTryTypeMethod(ts, adjointreset); 10777207e0fdSHong Zhang if (ts->quadraturets) { /* if there is integral in the cost function */ 10789566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ts->vec_drdu_col)); 107948a46eb9SPierre Jolivet if (ts->vecs_sensip) PetscCall(VecDestroy(&ts->vec_drdp_col)); 10807207e0fdSHong Zhang } 1081ece46509SHong Zhang ts->vecs_sensi = NULL; 1082ece46509SHong Zhang ts->vecs_sensip = NULL; 1083ece46509SHong Zhang ts->vecs_sensi2 = NULL; 108433f72c5dSHong Zhang ts->vecs_sensi2p = NULL; 1085ece46509SHong Zhang ts->vec_dir = NULL; 1086ece46509SHong Zhang ts->adjointsetupcalled = PETSC_FALSE; 10873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1088ece46509SHong Zhang } 1089ece46509SHong Zhang 1090ece46509SHong Zhang /*@ 1091814e85d6SHong Zhang TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time 1092814e85d6SHong Zhang 1093c3339decSBarry Smith Logically Collective 1094814e85d6SHong Zhang 1095814e85d6SHong Zhang Input Parameters: 1096bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 1097a2b725a8SWilliam Gropp - steps - number of steps to use 1098814e85d6SHong Zhang 1099814e85d6SHong Zhang Level: intermediate 1100814e85d6SHong Zhang 1101814e85d6SHong Zhang Notes: 1102bcf0153eSBarry Smith Normally one does not call this and `TSAdjointSolve()` integrates back to the original timestep. One can call this 1103814e85d6SHong Zhang so as to integrate back to less than the original timestep 1104814e85d6SHong Zhang 11051cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdjointSolve()`, `TS`, `TSSetExactFinalTime()` 1106814e85d6SHong Zhang @*/ 1107d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointSetSteps(TS ts, PetscInt steps) 1108d71ae5a4SJacob Faibussowitsch { 1109814e85d6SHong Zhang PetscFunctionBegin; 1110814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1111814e85d6SHong Zhang PetscValidLogicalCollectiveInt(ts, steps, 2); 11123c633725SBarry Smith PetscCheck(steps >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Cannot step back a negative number of steps"); 11133c633725SBarry Smith PetscCheck(steps <= ts->steps, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Cannot step back more than the total number of forward steps"); 1114814e85d6SHong Zhang ts->adjoint_max_steps = steps; 11153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1116814e85d6SHong Zhang } 1117814e85d6SHong Zhang 111814d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-* 1119814e85d6SHong Zhang /*@C 1120bcf0153eSBarry Smith TSAdjointSetRHSJacobian - Deprecated, use `TSSetRHSJacobianP()` 1121814e85d6SHong Zhang 1122814e85d6SHong Zhang Level: deprecated 1123814e85d6SHong Zhang @*/ 1124d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointSetRHSJacobian(TS ts, Mat Amat, PetscErrorCode (*func)(TS, PetscReal, Vec, Mat, void *), void *ctx) 1125d71ae5a4SJacob Faibussowitsch { 1126814e85d6SHong Zhang PetscFunctionBegin; 1127814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1128814e85d6SHong Zhang PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 1129814e85d6SHong Zhang 1130814e85d6SHong Zhang ts->rhsjacobianp = func; 1131814e85d6SHong Zhang ts->rhsjacobianpctx = ctx; 1132814e85d6SHong Zhang if (Amat) { 11339566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 11349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&ts->Jacp)); 1135814e85d6SHong Zhang ts->Jacp = Amat; 1136814e85d6SHong Zhang } 11373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1138814e85d6SHong Zhang } 1139814e85d6SHong Zhang 114014d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-* 1141814e85d6SHong Zhang /*@C 1142bcf0153eSBarry Smith TSAdjointComputeRHSJacobian - Deprecated, use `TSComputeRHSJacobianP()` 1143814e85d6SHong Zhang 1144814e85d6SHong Zhang Level: deprecated 1145814e85d6SHong Zhang @*/ 1146d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointComputeRHSJacobian(TS ts, PetscReal t, Vec U, Mat Amat) 1147d71ae5a4SJacob Faibussowitsch { 1148814e85d6SHong Zhang PetscFunctionBegin; 1149814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1150c9ad9de0SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 1151292bffcbSToby Isaac PetscValidHeaderSpecific(Amat, MAT_CLASSID, 4); 1152814e85d6SHong Zhang 1153792fecdfSBarry Smith PetscCallBack("TS callback JacobianP for sensitivity analysis", (*ts->rhsjacobianp)(ts, t, U, Amat, ts->rhsjacobianpctx)); 11543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1155814e85d6SHong Zhang } 1156814e85d6SHong Zhang 115714d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-* 1158814e85d6SHong Zhang /*@ 1159bcf0153eSBarry Smith TSAdjointComputeDRDYFunction - Deprecated, use `TSGetQuadratureTS()` then `TSComputeRHSJacobian()` 1160814e85d6SHong Zhang 1161814e85d6SHong Zhang Level: deprecated 1162814e85d6SHong Zhang @*/ 1163d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointComputeDRDYFunction(TS ts, PetscReal t, Vec U, Vec *DRDU) 1164d71ae5a4SJacob Faibussowitsch { 1165814e85d6SHong Zhang PetscFunctionBegin; 1166814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1167c9ad9de0SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 1168814e85d6SHong Zhang 1169792fecdfSBarry Smith PetscCallBack("TS callback DRDY for sensitivity analysis", (*ts->drdufunction)(ts, t, U, DRDU, ts->costintegrandctx)); 11703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1171814e85d6SHong Zhang } 1172814e85d6SHong Zhang 117314d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-* 1174814e85d6SHong Zhang /*@ 1175bcf0153eSBarry Smith TSAdjointComputeDRDPFunction - Deprecated, use `TSGetQuadratureTS()` then `TSComputeRHSJacobianP()` 1176814e85d6SHong Zhang 1177814e85d6SHong Zhang Level: deprecated 1178814e85d6SHong Zhang @*/ 1179d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointComputeDRDPFunction(TS ts, PetscReal t, Vec U, Vec *DRDP) 1180d71ae5a4SJacob Faibussowitsch { 1181814e85d6SHong Zhang PetscFunctionBegin; 1182814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1183c9ad9de0SHong Zhang PetscValidHeaderSpecific(U, VEC_CLASSID, 3); 1184814e85d6SHong Zhang 1185792fecdfSBarry Smith PetscCallBack("TS callback DRDP for sensitivity analysis", (*ts->drdpfunction)(ts, t, U, DRDP, ts->costintegrandctx)); 11863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1187814e85d6SHong Zhang } 1188814e85d6SHong Zhang 118914d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation 1190814e85d6SHong Zhang /*@C 1191814e85d6SHong Zhang TSAdjointMonitorSensi - monitors the first lambda sensitivity 1192814e85d6SHong Zhang 1193814e85d6SHong Zhang Level: intermediate 1194814e85d6SHong Zhang 11951cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdjointMonitorSet()` 1196814e85d6SHong Zhang @*/ 1197ba38deedSJacob Faibussowitsch static PetscErrorCode TSAdjointMonitorSensi(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscInt numcost, Vec *lambda, Vec *mu, PetscViewerAndFormat *vf) 1198d71ae5a4SJacob Faibussowitsch { 1199814e85d6SHong Zhang PetscViewer viewer = vf->viewer; 1200814e85d6SHong Zhang 1201814e85d6SHong Zhang PetscFunctionBegin; 1202064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 8); 12039566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 12049566063dSJacob Faibussowitsch PetscCall(VecView(lambda[0], viewer)); 12059566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 12063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1207814e85d6SHong Zhang } 1208814e85d6SHong Zhang 1209814e85d6SHong Zhang /*@C 1210814e85d6SHong Zhang TSAdjointMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 1211814e85d6SHong Zhang 1212c3339decSBarry Smith Collective 1213814e85d6SHong Zhang 1214814e85d6SHong Zhang Input Parameters: 1215bcf0153eSBarry Smith + ts - `TS` object you wish to monitor 1216814e85d6SHong Zhang . name - the monitor type one is seeking 1217814e85d6SHong Zhang . help - message indicating what monitoring is done 1218814e85d6SHong Zhang . manual - manual page for the monitor 1219*49abdd8aSBarry Smith . monitor - the monitor function, its context must be a `PetscViewerAndFormat` 1220bcf0153eSBarry Smith - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the `TS` or `PetscViewer` objects 1221814e85d6SHong Zhang 1222814e85d6SHong Zhang Level: developer 1223814e85d6SHong Zhang 1224648c30bcSBarry Smith .seealso: [](ch_ts), `PetscOptionsCreateViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 1225db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 1226b43aa488SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 1227db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 1228c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 1229db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 1230*49abdd8aSBarry Smith `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscViewerAndFormat` 1231814e85d6SHong Zhang @*/ 1232d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointMonitorSetFromOptions(TS ts, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, PetscInt, Vec *, Vec *, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(TS, PetscViewerAndFormat *)) 1233d71ae5a4SJacob Faibussowitsch { 1234814e85d6SHong Zhang PetscViewer viewer; 1235814e85d6SHong Zhang PetscViewerFormat format; 1236814e85d6SHong Zhang PetscBool flg; 1237814e85d6SHong Zhang 1238814e85d6SHong Zhang PetscFunctionBegin; 1239648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)ts), ((PetscObject)ts)->options, ((PetscObject)ts)->prefix, name, &viewer, &format, &flg)); 1240814e85d6SHong Zhang if (flg) { 1241814e85d6SHong Zhang PetscViewerAndFormat *vf; 12429566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 1243648c30bcSBarry Smith PetscCall(PetscViewerDestroy(&viewer)); 12441baa6e33SBarry Smith if (monitorsetup) PetscCall((*monitorsetup)(ts, vf)); 1245*49abdd8aSBarry Smith PetscCall(TSAdjointMonitorSet(ts, (PetscErrorCode (*)(TS, PetscInt, PetscReal, Vec, PetscInt, Vec *, Vec *, void *))monitor, vf, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy)); 1246814e85d6SHong Zhang } 12473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1248814e85d6SHong Zhang } 1249814e85d6SHong Zhang 1250814e85d6SHong Zhang /*@C 1251814e85d6SHong Zhang TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every 1252814e85d6SHong Zhang timestep to display the iteration's progress. 1253814e85d6SHong Zhang 1254c3339decSBarry Smith Logically Collective 1255814e85d6SHong Zhang 1256814e85d6SHong Zhang Input Parameters: 1257bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 1258814e85d6SHong Zhang . adjointmonitor - monitoring routine 125914d0ab18SJacob Faibussowitsch . adjointmctx - [optional] user-defined context for private data for the monitor routine 126014d0ab18SJacob Faibussowitsch (use `NULL` if no context is desired) 1261*49abdd8aSBarry Smith - adjointmdestroy - [optional] routine that frees monitor context (may be `NULL`), see `PetscCtxDestroyFn` for its calling sequence 1262814e85d6SHong Zhang 126320f4b53cSBarry Smith Calling sequence of `adjointmonitor`: 1264bcf0153eSBarry Smith + ts - the `TS` context 126514d0ab18SJacob Faibussowitsch . steps - iteration number (after the final time step the monitor routine is called with 126614d0ab18SJacob Faibussowitsch a step of -1, this is at the final time which may have been interpolated to) 1267814e85d6SHong Zhang . time - current time 1268814e85d6SHong Zhang . u - current iterate 1269814e85d6SHong Zhang . numcost - number of cost functionos 1270814e85d6SHong Zhang . lambda - sensitivities to initial conditions 1271814e85d6SHong Zhang . mu - sensitivities to parameters 1272814e85d6SHong Zhang - adjointmctx - [optional] adjoint monitoring context 1273814e85d6SHong Zhang 1274bcf0153eSBarry Smith Level: intermediate 1275bcf0153eSBarry Smith 1276bcf0153eSBarry Smith Note: 1277814e85d6SHong Zhang This routine adds an additional monitor to the list of monitors that 1278814e85d6SHong Zhang already has been loaded. 1279814e85d6SHong Zhang 1280b43aa488SJacob Faibussowitsch Fortran Notes: 128120f4b53cSBarry Smith Only a single monitor function can be set for each `TS` object 1282814e85d6SHong Zhang 1283*49abdd8aSBarry Smith .seealso: [](ch_ts), `TS`, `TSAdjointSolve()`, `TSAdjointMonitorCancel()`, `PetscCtxDestroyFn` 1284814e85d6SHong Zhang @*/ 1285*49abdd8aSBarry Smith PetscErrorCode TSAdjointMonitorSet(TS ts, PetscErrorCode (*adjointmonitor)(TS ts, PetscInt steps, PetscReal time, Vec u, PetscInt numcost, Vec *lambda, Vec *mu, void *adjointmctx), void *adjointmctx, PetscCtxDestroyFn *adjointmdestroy) 1286d71ae5a4SJacob Faibussowitsch { 1287814e85d6SHong Zhang PetscInt i; 1288814e85d6SHong Zhang PetscBool identical; 1289814e85d6SHong Zhang 1290814e85d6SHong Zhang PetscFunctionBegin; 1291814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1292814e85d6SHong Zhang for (i = 0; i < ts->numbermonitors; i++) { 12939566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor, adjointmctx, adjointmdestroy, (PetscErrorCode (*)(void))ts->adjointmonitor[i], ts->adjointmonitorcontext[i], ts->adjointmonitordestroy[i], &identical)); 12943ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 1295814e85d6SHong Zhang } 12963c633725SBarry Smith PetscCheck(ts->numberadjointmonitors < MAXTSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many adjoint monitors set"); 1297814e85d6SHong Zhang ts->adjointmonitor[ts->numberadjointmonitors] = adjointmonitor; 1298814e85d6SHong Zhang ts->adjointmonitordestroy[ts->numberadjointmonitors] = adjointmdestroy; 1299814e85d6SHong Zhang ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void *)adjointmctx; 13003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1301814e85d6SHong Zhang } 1302814e85d6SHong Zhang 1303814e85d6SHong Zhang /*@C 1304814e85d6SHong Zhang TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object. 1305814e85d6SHong Zhang 1306c3339decSBarry Smith Logically Collective 1307814e85d6SHong Zhang 13082fe279fdSBarry Smith Input Parameter: 1309bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1310814e85d6SHong Zhang 1311814e85d6SHong Zhang Notes: 1312814e85d6SHong Zhang There is no way to remove a single, specific monitor. 1313814e85d6SHong Zhang 1314814e85d6SHong Zhang Level: intermediate 1315814e85d6SHong Zhang 13161cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAdjointSolve()`, `TSAdjointMonitorSet()` 1317814e85d6SHong Zhang @*/ 1318d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointMonitorCancel(TS ts) 1319d71ae5a4SJacob Faibussowitsch { 1320814e85d6SHong Zhang PetscInt i; 1321814e85d6SHong Zhang 1322814e85d6SHong Zhang PetscFunctionBegin; 1323814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1324814e85d6SHong Zhang for (i = 0; i < ts->numberadjointmonitors; i++) { 132548a46eb9SPierre Jolivet if (ts->adjointmonitordestroy[i]) PetscCall((*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i])); 1326814e85d6SHong Zhang } 1327814e85d6SHong Zhang ts->numberadjointmonitors = 0; 13283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1329814e85d6SHong Zhang } 1330814e85d6SHong Zhang 1331814e85d6SHong Zhang /*@C 1332814e85d6SHong Zhang TSAdjointMonitorDefault - the default monitor of adjoint computations 1333814e85d6SHong Zhang 133414d0ab18SJacob Faibussowitsch Input Parameters: 133514d0ab18SJacob Faibussowitsch + ts - the `TS` context 133614d0ab18SJacob Faibussowitsch . step - iteration number (after the final time step the monitor routine is called with a 133714d0ab18SJacob Faibussowitsch step of -1, this is at the final time which may have been interpolated to) 133814d0ab18SJacob Faibussowitsch . time - current time 133914d0ab18SJacob Faibussowitsch . v - current iterate 134014d0ab18SJacob Faibussowitsch . numcost - number of cost functionos 134114d0ab18SJacob Faibussowitsch . lambda - sensitivities to initial conditions 134214d0ab18SJacob Faibussowitsch . mu - sensitivities to parameters 134314d0ab18SJacob Faibussowitsch - vf - the viewer and format 134414d0ab18SJacob Faibussowitsch 1345814e85d6SHong Zhang Level: intermediate 1346814e85d6SHong Zhang 13471cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAdjointSolve()`, `TSAdjointMonitorSet()` 1348814e85d6SHong Zhang @*/ 134914d0ab18SJacob Faibussowitsch PetscErrorCode TSAdjointMonitorDefault(TS ts, PetscInt step, PetscReal time, Vec v, PetscInt numcost, Vec *lambda, Vec *mu, PetscViewerAndFormat *vf) 1350d71ae5a4SJacob Faibussowitsch { 1351814e85d6SHong Zhang PetscViewer viewer = vf->viewer; 1352814e85d6SHong Zhang 1353814e85d6SHong Zhang PetscFunctionBegin; 135414d0ab18SJacob Faibussowitsch (void)v; 135514d0ab18SJacob Faibussowitsch (void)numcost; 135614d0ab18SJacob Faibussowitsch (void)lambda; 135714d0ab18SJacob Faibussowitsch (void)mu; 1358064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 8); 13599566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 13609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel)); 136114d0ab18SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " TS dt %g time %g%s", step, (double)ts->time_step, (double)time, ts->steprollback ? " (r)\n" : "\n")); 13629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel)); 13639566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 13643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1365814e85d6SHong Zhang } 1366814e85d6SHong Zhang 1367814e85d6SHong Zhang /*@C 1368bcf0153eSBarry Smith TSAdjointMonitorDrawSensi - Monitors progress of the adjoint `TS` solvers by calling 1369bcf0153eSBarry Smith `VecView()` for the sensitivities to initial states at each timestep 1370814e85d6SHong Zhang 1371c3339decSBarry Smith Collective 1372814e85d6SHong Zhang 1373814e85d6SHong Zhang Input Parameters: 1374bcf0153eSBarry Smith + ts - the `TS` context 1375814e85d6SHong Zhang . step - current time-step 1376814e85d6SHong Zhang . ptime - current time 1377814e85d6SHong Zhang . u - current state 1378814e85d6SHong Zhang . numcost - number of cost functions 1379814e85d6SHong Zhang . lambda - sensitivities to initial conditions 1380814e85d6SHong Zhang . mu - sensitivities to parameters 13812fe279fdSBarry Smith - dummy - either a viewer or `NULL` 1382814e85d6SHong Zhang 1383814e85d6SHong Zhang Level: intermediate 1384814e85d6SHong Zhang 13851cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdjointSolve()`, `TSAdjointMonitorSet()`, `TSAdjointMonitorDefault()`, `VecView()` 1386814e85d6SHong Zhang @*/ 1387d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointMonitorDrawSensi(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscInt numcost, Vec *lambda, Vec *mu, void *dummy) 1388d71ae5a4SJacob Faibussowitsch { 1389814e85d6SHong Zhang TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 1390814e85d6SHong Zhang PetscDraw draw; 1391814e85d6SHong Zhang PetscReal xl, yl, xr, yr, h; 1392814e85d6SHong Zhang char time[32]; 1393814e85d6SHong Zhang 1394814e85d6SHong Zhang PetscFunctionBegin; 13953ba16761SJacob Faibussowitsch if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(PETSC_SUCCESS); 1396814e85d6SHong Zhang 13979566063dSJacob Faibussowitsch PetscCall(VecView(lambda[0], ictx->viewer)); 13989566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw)); 13999566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime)); 14009566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1401814e85d6SHong Zhang h = yl + .95 * (yr - yl); 14029566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time)); 14039566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 14043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1405814e85d6SHong Zhang } 1406814e85d6SHong Zhang 140714d0ab18SJacob Faibussowitsch /*@C 140814d0ab18SJacob Faibussowitsch TSAdjointSetFromOptions - Sets various `TS` adjoint parameters from options database. 1409814e85d6SHong Zhang 1410c3339decSBarry Smith Collective 1411814e85d6SHong Zhang 141214d0ab18SJacob Faibussowitsch Input Parameters: 141314d0ab18SJacob Faibussowitsch + ts - the `TS` context 141414d0ab18SJacob Faibussowitsch - PetscOptionsObject - the options context 1415814e85d6SHong Zhang 1416814e85d6SHong Zhang Options Database Keys: 141714d0ab18SJacob Faibussowitsch + -ts_adjoint_solve <yes,no> - After solving the ODE/DAE solve the adjoint problem (requires `-ts_save_trajectory`) 1418814e85d6SHong Zhang . -ts_adjoint_monitor - print information at each adjoint time step 1419814e85d6SHong Zhang - -ts_adjoint_monitor_draw_sensi - monitor the sensitivity of the first cost function wrt initial conditions (lambda[0]) graphically 1420814e85d6SHong Zhang 1421814e85d6SHong Zhang Level: developer 1422814e85d6SHong Zhang 1423bcf0153eSBarry Smith Note: 1424814e85d6SHong Zhang This is not normally called directly by users 1425814e85d6SHong Zhang 14261cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetSaveTrajectory()`, `TSTrajectorySetUp()` 142714d0ab18SJacob Faibussowitsch @*/ 1428d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointSetFromOptions(TS ts, PetscOptionItems *PetscOptionsObject) 1429d71ae5a4SJacob Faibussowitsch { 1430814e85d6SHong Zhang PetscBool tflg, opt; 1431814e85d6SHong Zhang 1432814e85d6SHong Zhang PetscFunctionBegin; 1433dbbe0bcdSBarry Smith PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1434d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "TS Adjoint options"); 1435814e85d6SHong Zhang tflg = ts->adjoint_solve ? PETSC_TRUE : PETSC_FALSE; 14369566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_adjoint_solve", "Solve the adjoint problem immediately after solving the forward problem", "", tflg, &tflg, &opt)); 1437814e85d6SHong Zhang if (opt) { 14389566063dSJacob Faibussowitsch PetscCall(TSSetSaveTrajectory(ts)); 1439814e85d6SHong Zhang ts->adjoint_solve = tflg; 1440814e85d6SHong Zhang } 14419566063dSJacob Faibussowitsch PetscCall(TSAdjointMonitorSetFromOptions(ts, "-ts_adjoint_monitor", "Monitor adjoint timestep size", "TSAdjointMonitorDefault", TSAdjointMonitorDefault, NULL)); 14429566063dSJacob Faibussowitsch PetscCall(TSAdjointMonitorSetFromOptions(ts, "-ts_adjoint_monitor_sensi", "Monitor sensitivity in the adjoint computation", "TSAdjointMonitorSensi", TSAdjointMonitorSensi, NULL)); 1443814e85d6SHong Zhang opt = PETSC_FALSE; 14449566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-ts_adjoint_monitor_draw_sensi", "Monitor adjoint sensitivities (lambda only) graphically", "TSAdjointMonitorDrawSensi", &opt)); 1445814e85d6SHong Zhang if (opt) { 1446814e85d6SHong Zhang TSMonitorDrawCtx ctx; 1447814e85d6SHong Zhang PetscInt howoften = 1; 1448814e85d6SHong Zhang 14499566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_adjoint_monitor_draw_sensi", "Monitor adjoint sensitivities (lambda only) graphically", "TSAdjointMonitorDrawSensi", howoften, &howoften, NULL)); 14509566063dSJacob Faibussowitsch PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx)); 1451*49abdd8aSBarry Smith PetscCall(TSAdjointMonitorSet(ts, TSAdjointMonitorDrawSensi, ctx, (PetscCtxDestroyFn *)TSMonitorDrawCtxDestroy)); 1452814e85d6SHong Zhang } 14533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1454814e85d6SHong Zhang } 1455814e85d6SHong Zhang 1456814e85d6SHong Zhang /*@ 1457814e85d6SHong Zhang TSAdjointStep - Steps one time step backward in the adjoint run 1458814e85d6SHong Zhang 1459c3339decSBarry Smith Collective 1460814e85d6SHong Zhang 1461814e85d6SHong Zhang Input Parameter: 1462bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1463814e85d6SHong Zhang 1464814e85d6SHong Zhang Level: intermediate 1465814e85d6SHong Zhang 14661cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdjointSetUp()`, `TSAdjointSolve()` 1467814e85d6SHong Zhang @*/ 1468d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointStep(TS ts) 1469d71ae5a4SJacob Faibussowitsch { 1470814e85d6SHong Zhang DM dm; 1471814e85d6SHong Zhang 1472814e85d6SHong Zhang PetscFunctionBegin; 1473814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 14749566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 14759566063dSJacob Faibussowitsch PetscCall(TSAdjointSetUp(ts)); 14767b0e2f17SHong Zhang ts->steps--; /* must decrease the step index before the adjoint step is taken. */ 1477814e85d6SHong Zhang 1478814e85d6SHong Zhang ts->reason = TS_CONVERGED_ITERATING; 1479814e85d6SHong Zhang ts->ptime_prev = ts->ptime; 14809566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TS_AdjointStep, ts, 0, 0, 0)); 1481dbbe0bcdSBarry Smith PetscUseTypeMethod(ts, adjointstep); 14829566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TS_AdjointStep, ts, 0, 0, 0)); 14837b0e2f17SHong Zhang ts->adjoint_steps++; 1484814e85d6SHong Zhang 1485814e85d6SHong Zhang if (ts->reason < 0) { 14863c633725SBarry Smith PetscCheck(!ts->errorifstepfailed, PetscObjectComm((PetscObject)ts), PETSC_ERR_NOT_CONVERGED, "TSAdjointStep has failed due to %s", TSConvergedReasons[ts->reason]); 1487814e85d6SHong Zhang } else if (!ts->reason) { 1488814e85d6SHong Zhang if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 1489814e85d6SHong Zhang } 14903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1491814e85d6SHong Zhang } 1492814e85d6SHong Zhang 1493814e85d6SHong Zhang /*@ 1494814e85d6SHong Zhang TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE 1495814e85d6SHong Zhang 1496c3339decSBarry Smith Collective 1497bcf0153eSBarry Smith ` 1498b43aa488SJacob Faibussowitsch 1499814e85d6SHong Zhang Input Parameter: 1500bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1501814e85d6SHong Zhang 1502bcf0153eSBarry Smith Options Database Key: 1503814e85d6SHong Zhang . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial values 1504814e85d6SHong Zhang 1505814e85d6SHong Zhang Level: intermediate 1506814e85d6SHong Zhang 1507814e85d6SHong Zhang Notes: 1508bcf0153eSBarry Smith This must be called after a call to `TSSolve()` that solves the forward problem 1509814e85d6SHong Zhang 1510bcf0153eSBarry Smith By default this will integrate back to the initial time, one can use `TSAdjointSetSteps()` to step back to a later time 1511814e85d6SHong Zhang 151242747ad1SJacob Faibussowitsch .seealso: [](ch_ts), `TSCreate()`, `TSSetCostGradients()`, `TSSetSolution()`, `TSAdjointStep()` 1513814e85d6SHong Zhang @*/ 1514d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointSolve(TS ts) 1515d71ae5a4SJacob Faibussowitsch { 1516f1d62c27SHong Zhang static PetscBool cite = PETSC_FALSE; 15177f59fb53SHong Zhang #if defined(TSADJOINT_STAGE) 15187f59fb53SHong Zhang PetscLogStage adjoint_stage; 15197f59fb53SHong Zhang #endif 1520814e85d6SHong Zhang 1521814e85d6SHong Zhang PetscFunctionBegin; 1522814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1523421b783aSHong Zhang PetscCall(PetscCitationsRegister("@article{Zhang2022tsadjoint,\n" 1524421b783aSHong Zhang " title = {{PETSc TSAdjoint: A Discrete Adjoint ODE Solver for First-Order and Second-Order Sensitivity Analysis}},\n" 1525f1d62c27SHong Zhang " author = {Zhang, Hong and Constantinescu, Emil M. and Smith, Barry F.},\n" 1526421b783aSHong Zhang " journal = {SIAM Journal on Scientific Computing},\n" 1527421b783aSHong Zhang " volume = {44},\n" 1528421b783aSHong Zhang " number = {1},\n" 1529421b783aSHong Zhang " pages = {C1-C24},\n" 1530421b783aSHong Zhang " doi = {10.1137/21M140078X},\n" 15319371c9d4SSatish Balay " year = {2022}\n}\n", 15329371c9d4SSatish Balay &cite)); 15337f59fb53SHong Zhang #if defined(TSADJOINT_STAGE) 15349566063dSJacob Faibussowitsch PetscCall(PetscLogStageRegister("TSAdjoint", &adjoint_stage)); 15359566063dSJacob Faibussowitsch PetscCall(PetscLogStagePush(adjoint_stage)); 15367f59fb53SHong Zhang #endif 15379566063dSJacob Faibussowitsch PetscCall(TSAdjointSetUp(ts)); 1538814e85d6SHong Zhang 1539814e85d6SHong Zhang /* reset time step and iteration counters */ 1540814e85d6SHong Zhang ts->adjoint_steps = 0; 1541814e85d6SHong Zhang ts->ksp_its = 0; 1542814e85d6SHong Zhang ts->snes_its = 0; 1543814e85d6SHong Zhang ts->num_snes_failures = 0; 1544814e85d6SHong Zhang ts->reject = 0; 1545814e85d6SHong Zhang ts->reason = TS_CONVERGED_ITERATING; 1546814e85d6SHong Zhang 1547814e85d6SHong Zhang if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->steps; 1548814e85d6SHong Zhang if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 1549814e85d6SHong Zhang 1550814e85d6SHong Zhang while (!ts->reason) { 15519566063dSJacob Faibussowitsch PetscCall(TSTrajectoryGet(ts->trajectory, ts, ts->steps, &ts->ptime)); 15529566063dSJacob Faibussowitsch PetscCall(TSAdjointMonitor(ts, ts->steps, ts->ptime, ts->vec_sol, ts->numcost, ts->vecs_sensi, ts->vecs_sensip)); 15539566063dSJacob Faibussowitsch PetscCall(TSAdjointEventHandler(ts)); 15549566063dSJacob Faibussowitsch PetscCall(TSAdjointStep(ts)); 155548a46eb9SPierre Jolivet if ((ts->vec_costintegral || ts->quadraturets) && !ts->costintegralfwd) PetscCall(TSAdjointCostIntegral(ts)); 1556814e85d6SHong Zhang } 1557bdbff044SHong Zhang if (!ts->steps) { 15589566063dSJacob Faibussowitsch PetscCall(TSTrajectoryGet(ts->trajectory, ts, ts->steps, &ts->ptime)); 15599566063dSJacob Faibussowitsch PetscCall(TSAdjointMonitor(ts, ts->steps, ts->ptime, ts->vec_sol, ts->numcost, ts->vecs_sensi, ts->vecs_sensip)); 1560bdbff044SHong Zhang } 1561814e85d6SHong Zhang ts->solvetime = ts->ptime; 15629566063dSJacob Faibussowitsch PetscCall(TSTrajectoryViewFromOptions(ts->trajectory, NULL, "-ts_trajectory_view")); 15639566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(ts->vecs_sensi[0], (PetscObject)ts, "-ts_adjoint_view_solution")); 1564814e85d6SHong Zhang ts->adjoint_max_steps = 0; 15657f59fb53SHong Zhang #if defined(TSADJOINT_STAGE) 15669566063dSJacob Faibussowitsch PetscCall(PetscLogStagePop()); 15677f59fb53SHong Zhang #endif 15683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1569814e85d6SHong Zhang } 1570814e85d6SHong Zhang 1571814e85d6SHong Zhang /*@C 1572bcf0153eSBarry Smith TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using `TSAdjointMonitorSet()` 1573814e85d6SHong Zhang 1574c3339decSBarry Smith Collective 1575814e85d6SHong Zhang 1576814e85d6SHong Zhang Input Parameters: 1577bcf0153eSBarry Smith + ts - time stepping context obtained from `TSCreate()` 1578814e85d6SHong Zhang . step - step number that has just completed 1579814e85d6SHong Zhang . ptime - model time of the state 1580814e85d6SHong Zhang . u - state at the current model time 1581814e85d6SHong Zhang . numcost - number of cost functions (dimension of lambda or mu) 1582814e85d6SHong Zhang . lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 1583814e85d6SHong Zhang - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 1584814e85d6SHong Zhang 1585814e85d6SHong Zhang Level: developer 1586814e85d6SHong Zhang 1587bcf0153eSBarry Smith Note: 1588bcf0153eSBarry Smith `TSAdjointMonitor()` is typically used automatically within the time stepping implementations. 1589bcf0153eSBarry Smith Users would almost never call this routine directly. 1590bcf0153eSBarry Smith 1591bcf0153eSBarry Smith .seealso: `TSAdjointMonitorSet()`, `TSAdjointSolve()` 1592814e85d6SHong Zhang @*/ 1593d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointMonitor(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscInt numcost, Vec *lambda, Vec *mu) 1594d71ae5a4SJacob Faibussowitsch { 1595814e85d6SHong Zhang PetscInt i, n = ts->numberadjointmonitors; 1596814e85d6SHong Zhang 1597814e85d6SHong Zhang PetscFunctionBegin; 1598814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1599814e85d6SHong Zhang PetscValidHeaderSpecific(u, VEC_CLASSID, 4); 16009566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(u)); 160148a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*ts->adjointmonitor[i])(ts, step, ptime, u, numcost, lambda, mu, ts->adjointmonitorcontext[i])); 16029566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(u)); 16033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1604814e85d6SHong Zhang } 1605814e85d6SHong Zhang 1606814e85d6SHong Zhang /*@ 1607814e85d6SHong Zhang TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run. 1608814e85d6SHong Zhang 1609c3339decSBarry Smith Collective 1610814e85d6SHong Zhang 16114165533cSJose E. Roman Input Parameter: 1612814e85d6SHong Zhang . ts - time stepping context 1613814e85d6SHong Zhang 1614814e85d6SHong Zhang Level: advanced 1615814e85d6SHong Zhang 1616814e85d6SHong Zhang Notes: 1617bcf0153eSBarry Smith This function cannot be called until `TSAdjointStep()` has been completed. 1618814e85d6SHong Zhang 16191cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdjointSolve()`, `TSAdjointStep()` 1620814e85d6SHong Zhang @*/ 1621d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdjointCostIntegral(TS ts) 1622d71ae5a4SJacob Faibussowitsch { 1623362febeeSStefano Zampini PetscFunctionBegin; 1624814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1625dbbe0bcdSBarry Smith PetscUseTypeMethod(ts, adjointintegral); 16263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1627814e85d6SHong Zhang } 1628814e85d6SHong Zhang 1629814e85d6SHong Zhang /* ------------------ Forward (tangent linear) sensitivity ------------------*/ 1630814e85d6SHong Zhang 1631814e85d6SHong Zhang /*@ 1632814e85d6SHong Zhang TSForwardSetUp - Sets up the internal data structures for the later use 1633814e85d6SHong Zhang of forward sensitivity analysis 1634814e85d6SHong Zhang 1635c3339decSBarry Smith Collective 1636814e85d6SHong Zhang 1637814e85d6SHong Zhang Input Parameter: 1638bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1639814e85d6SHong Zhang 1640814e85d6SHong Zhang Level: advanced 1641814e85d6SHong Zhang 16421cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSCreate()`, `TSDestroy()`, `TSSetUp()` 1643814e85d6SHong Zhang @*/ 1644d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardSetUp(TS ts) 1645d71ae5a4SJacob Faibussowitsch { 1646814e85d6SHong Zhang PetscFunctionBegin; 1647814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 16483ba16761SJacob Faibussowitsch if (ts->forwardsetupcalled) PetscFunctionReturn(PETSC_SUCCESS); 1649dbbe0bcdSBarry Smith PetscTryTypeMethod(ts, forwardsetup); 16509566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &ts->vec_sensip_col)); 1651814e85d6SHong Zhang ts->forwardsetupcalled = PETSC_TRUE; 16523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1653814e85d6SHong Zhang } 1654814e85d6SHong Zhang 1655814e85d6SHong Zhang /*@ 16567adebddeSHong Zhang TSForwardReset - Reset the internal data structures used by forward sensitivity analysis 16577adebddeSHong Zhang 1658c3339decSBarry Smith Collective 16597adebddeSHong Zhang 16607adebddeSHong Zhang Input Parameter: 1661bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 16627adebddeSHong Zhang 16637adebddeSHong Zhang Level: advanced 16647adebddeSHong Zhang 16651cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TSDestroy()`, `TSForwardSetUp()` 16667adebddeSHong Zhang @*/ 1667d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardReset(TS ts) 1668d71ae5a4SJacob Faibussowitsch { 16697207e0fdSHong Zhang TS quadts = ts->quadraturets; 16707adebddeSHong Zhang 16717adebddeSHong Zhang PetscFunctionBegin; 16727adebddeSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1673dbbe0bcdSBarry Smith PetscTryTypeMethod(ts, forwardreset); 16749566063dSJacob Faibussowitsch PetscCall(MatDestroy(&ts->mat_sensip)); 167548a46eb9SPierre Jolivet if (quadts) PetscCall(MatDestroy(&quadts->mat_sensip)); 16769566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ts->vec_sensip_col)); 16777adebddeSHong Zhang ts->forward_solve = PETSC_FALSE; 16787adebddeSHong Zhang ts->forwardsetupcalled = PETSC_FALSE; 16793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16807adebddeSHong Zhang } 16817adebddeSHong Zhang 16827adebddeSHong Zhang /*@ 1683814e85d6SHong Zhang TSForwardSetIntegralGradients - Set the vectors holding forward sensitivities of the integral term. 1684814e85d6SHong Zhang 1685d8d19677SJose E. Roman Input Parameters: 1686bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 1687814e85d6SHong Zhang . numfwdint - number of integrals 168867b8a455SSatish Balay - vp - the vectors containing the gradients for each integral w.r.t. parameters 1689814e85d6SHong Zhang 16907207e0fdSHong Zhang Level: deprecated 1691814e85d6SHong Zhang 169242747ad1SJacob Faibussowitsch .seealso: [](ch_ts), `TSForwardGetSensitivities()`, `TSForwardGetIntegralGradients()`, `TSForwardStep()` 1693814e85d6SHong Zhang @*/ 1694d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardSetIntegralGradients(TS ts, PetscInt numfwdint, Vec *vp) 1695d71ae5a4SJacob Faibussowitsch { 1696814e85d6SHong Zhang PetscFunctionBegin; 1697814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 16983c633725SBarry Smith PetscCheck(!ts->numcost || ts->numcost == numfwdint, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "The number of cost functions (2nd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostIntegrand()"); 1699814e85d6SHong Zhang if (!ts->numcost) ts->numcost = numfwdint; 1700814e85d6SHong Zhang 1701814e85d6SHong Zhang ts->vecs_integral_sensip = vp; 17023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1703814e85d6SHong Zhang } 1704814e85d6SHong Zhang 1705814e85d6SHong Zhang /*@ 1706814e85d6SHong Zhang TSForwardGetIntegralGradients - Returns the forward sensitivities of the integral term. 1707814e85d6SHong Zhang 1708814e85d6SHong Zhang Input Parameter: 1709bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1710814e85d6SHong Zhang 171114d0ab18SJacob Faibussowitsch Output Parameters: 171214d0ab18SJacob Faibussowitsch + numfwdint - number of integrals 171314d0ab18SJacob Faibussowitsch - vp - the vectors containing the gradients for each integral w.r.t. parameters 1714814e85d6SHong Zhang 17157207e0fdSHong Zhang Level: deprecated 1716814e85d6SHong Zhang 171742747ad1SJacob Faibussowitsch .seealso: [](ch_ts), `TSForwardSetSensitivities()`, `TSForwardSetIntegralGradients()`, `TSForwardStep()` 1718814e85d6SHong Zhang @*/ 1719d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardGetIntegralGradients(TS ts, PetscInt *numfwdint, Vec **vp) 1720d71ae5a4SJacob Faibussowitsch { 1721814e85d6SHong Zhang PetscFunctionBegin; 1722814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 17234f572ea9SToby Isaac PetscAssertPointer(vp, 3); 1724814e85d6SHong Zhang if (numfwdint) *numfwdint = ts->numcost; 1725814e85d6SHong Zhang if (vp) *vp = ts->vecs_integral_sensip; 17263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1727814e85d6SHong Zhang } 1728814e85d6SHong Zhang 1729814e85d6SHong Zhang /*@ 1730814e85d6SHong Zhang TSForwardStep - Compute the forward sensitivity for one time step. 1731814e85d6SHong Zhang 1732c3339decSBarry Smith Collective 1733814e85d6SHong Zhang 17344165533cSJose E. Roman Input Parameter: 1735814e85d6SHong Zhang . ts - time stepping context 1736814e85d6SHong Zhang 1737814e85d6SHong Zhang Level: advanced 1738814e85d6SHong Zhang 1739814e85d6SHong Zhang Notes: 1740bcf0153eSBarry Smith This function cannot be called until `TSStep()` has been completed. 1741814e85d6SHong Zhang 17421cc06b55SBarry Smith .seealso: [](ch_ts), `TSForwardSetSensitivities()`, `TSForwardGetSensitivities()`, `TSForwardSetIntegralGradients()`, `TSForwardGetIntegralGradients()`, `TSForwardSetUp()` 1743814e85d6SHong Zhang @*/ 1744d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardStep(TS ts) 1745d71ae5a4SJacob Faibussowitsch { 1746362febeeSStefano Zampini PetscFunctionBegin; 1747814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 17489566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TS_ForwardStep, ts, 0, 0, 0)); 1749dbbe0bcdSBarry Smith PetscUseTypeMethod(ts, forwardstep); 17509566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TS_ForwardStep, ts, 0, 0, 0)); 17513c633725SBarry Smith PetscCheck(ts->reason >= 0 || !ts->errorifstepfailed, PetscObjectComm((PetscObject)ts), PETSC_ERR_NOT_CONVERGED, "TSFowardStep has failed due to %s", TSConvergedReasons[ts->reason]); 17523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1753814e85d6SHong Zhang } 1754814e85d6SHong Zhang 1755814e85d6SHong Zhang /*@ 1756814e85d6SHong Zhang TSForwardSetSensitivities - Sets the initial value of the trajectory sensitivities of solution w.r.t. the problem parameters and initial values. 1757814e85d6SHong Zhang 1758c3339decSBarry Smith Logically Collective 1759814e85d6SHong Zhang 1760814e85d6SHong Zhang Input Parameters: 1761bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 1762814e85d6SHong Zhang . nump - number of parameters 1763814e85d6SHong Zhang - Smat - sensitivities with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 1764814e85d6SHong Zhang 1765814e85d6SHong Zhang Level: beginner 1766814e85d6SHong Zhang 1767814e85d6SHong Zhang Notes: 176809cb0f53SBarry Smith Use `PETSC_DETERMINE` to use the number of columns of `Smat` for `nump` 176909cb0f53SBarry Smith 1770814e85d6SHong Zhang Forward sensitivity is also called 'trajectory sensitivity' in some fields such as power systems. 1771bcf0153eSBarry Smith This function turns on a flag to trigger `TSSolve()` to compute forward sensitivities automatically. 1772bcf0153eSBarry Smith You must call this function before `TSSolve()`. 1773814e85d6SHong Zhang The entries in the sensitivity matrix must be correctly initialized with the values S = dy/dp|startingtime. 1774814e85d6SHong Zhang 17751cc06b55SBarry Smith .seealso: [](ch_ts), `TSForwardGetSensitivities()`, `TSForwardSetIntegralGradients()`, `TSForwardGetIntegralGradients()`, `TSForwardStep()` 1776814e85d6SHong Zhang @*/ 1777d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardSetSensitivities(TS ts, PetscInt nump, Mat Smat) 1778d71ae5a4SJacob Faibussowitsch { 1779814e85d6SHong Zhang PetscFunctionBegin; 1780814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1781814e85d6SHong Zhang PetscValidHeaderSpecific(Smat, MAT_CLASSID, 3); 1782814e85d6SHong Zhang ts->forward_solve = PETSC_TRUE; 178309cb0f53SBarry Smith if (nump == PETSC_DEFAULT || nump == PETSC_DETERMINE) { 17849566063dSJacob Faibussowitsch PetscCall(MatGetSize(Smat, NULL, &ts->num_parameters)); 1785b5b4017aSHong Zhang } else ts->num_parameters = nump; 17869566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Smat)); 17879566063dSJacob Faibussowitsch PetscCall(MatDestroy(&ts->mat_sensip)); 1788814e85d6SHong Zhang ts->mat_sensip = Smat; 17893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1790814e85d6SHong Zhang } 1791814e85d6SHong Zhang 1792814e85d6SHong Zhang /*@ 1793814e85d6SHong Zhang TSForwardGetSensitivities - Returns the trajectory sensitivities 1794814e85d6SHong Zhang 1795bcf0153eSBarry Smith Not Collective, but Smat returned is parallel if ts is parallel 1796814e85d6SHong Zhang 1797d8d19677SJose E. Roman Output Parameters: 1798bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 1799814e85d6SHong Zhang . nump - number of parameters 1800814e85d6SHong Zhang - Smat - sensitivities with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 1801814e85d6SHong Zhang 1802814e85d6SHong Zhang Level: intermediate 1803814e85d6SHong Zhang 18041cc06b55SBarry Smith .seealso: [](ch_ts), `TSForwardSetSensitivities()`, `TSForwardSetIntegralGradients()`, `TSForwardGetIntegralGradients()`, `TSForwardStep()` 1805814e85d6SHong Zhang @*/ 1806d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardGetSensitivities(TS ts, PetscInt *nump, Mat *Smat) 1807d71ae5a4SJacob Faibussowitsch { 1808814e85d6SHong Zhang PetscFunctionBegin; 1809814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1810814e85d6SHong Zhang if (nump) *nump = ts->num_parameters; 1811814e85d6SHong Zhang if (Smat) *Smat = ts->mat_sensip; 18123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1813814e85d6SHong Zhang } 1814814e85d6SHong Zhang 1815814e85d6SHong Zhang /*@ 1816814e85d6SHong Zhang TSForwardCostIntegral - Evaluate the cost integral in the forward run. 1817814e85d6SHong Zhang 1818c3339decSBarry Smith Collective 1819814e85d6SHong Zhang 18204165533cSJose E. Roman Input Parameter: 1821814e85d6SHong Zhang . ts - time stepping context 1822814e85d6SHong Zhang 1823814e85d6SHong Zhang Level: advanced 1824814e85d6SHong Zhang 1825bcf0153eSBarry Smith Note: 1826bcf0153eSBarry Smith This function cannot be called until `TSStep()` has been completed. 1827814e85d6SHong Zhang 18281cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSolve()`, `TSAdjointCostIntegral()` 1829814e85d6SHong Zhang @*/ 1830d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardCostIntegral(TS ts) 1831d71ae5a4SJacob Faibussowitsch { 1832362febeeSStefano Zampini PetscFunctionBegin; 1833814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1834dbbe0bcdSBarry Smith PetscUseTypeMethod(ts, forwardintegral); 18353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1836814e85d6SHong Zhang } 1837b5b4017aSHong Zhang 1838b5b4017aSHong Zhang /*@ 1839b5b4017aSHong Zhang TSForwardSetInitialSensitivities - Set initial values for tangent linear sensitivities 1840b5b4017aSHong Zhang 1841c3339decSBarry Smith Collective 1842b5b4017aSHong Zhang 1843d8d19677SJose E. Roman Input Parameters: 1844bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 1845b5b4017aSHong Zhang - didp - parametric sensitivities of the initial condition 1846b5b4017aSHong Zhang 1847b5b4017aSHong Zhang Level: intermediate 1848b5b4017aSHong Zhang 1849bcf0153eSBarry Smith Notes: 1850bcf0153eSBarry Smith `TSSolve()` allows users to pass the initial solution directly to `TS`. But the tangent linear variables cannot be initialized in this way. 1851bcf0153eSBarry Smith This function is used to set initial values for tangent linear variables. 1852b5b4017aSHong Zhang 18531cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSForwardSetSensitivities()` 1854b5b4017aSHong Zhang @*/ 1855d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardSetInitialSensitivities(TS ts, Mat didp) 1856d71ae5a4SJacob Faibussowitsch { 1857362febeeSStefano Zampini PetscFunctionBegin; 1858b5b4017aSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1859b5b4017aSHong Zhang PetscValidHeaderSpecific(didp, MAT_CLASSID, 2); 186009cb0f53SBarry Smith if (!ts->mat_sensip) PetscCall(TSForwardSetSensitivities(ts, PETSC_DETERMINE, didp)); 18613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1862b5b4017aSHong Zhang } 18636affb6f8SHong Zhang 18646affb6f8SHong Zhang /*@ 18656affb6f8SHong Zhang TSForwardGetStages - Get the number of stages and the tangent linear sensitivities at the intermediate stages 18666affb6f8SHong Zhang 18676affb6f8SHong Zhang Input Parameter: 1868bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 18696affb6f8SHong Zhang 18706affb6f8SHong Zhang Output Parameters: 1871cd4cee2dSHong Zhang + ns - number of stages 18726affb6f8SHong Zhang - S - tangent linear sensitivities at the intermediate stages 18736affb6f8SHong Zhang 18746affb6f8SHong Zhang Level: advanced 18756affb6f8SHong Zhang 1876bcf0153eSBarry Smith .seealso: `TS` 18776affb6f8SHong Zhang @*/ 1878d71ae5a4SJacob Faibussowitsch PetscErrorCode TSForwardGetStages(TS ts, PetscInt *ns, Mat **S) 1879d71ae5a4SJacob Faibussowitsch { 18806affb6f8SHong Zhang PetscFunctionBegin; 18816affb6f8SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 18826affb6f8SHong Zhang 18836affb6f8SHong Zhang if (!ts->ops->getstages) *S = NULL; 1884dbbe0bcdSBarry Smith else PetscUseTypeMethod(ts, forwardgetstages, ns, S); 18853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18866affb6f8SHong Zhang } 1887cd4cee2dSHong Zhang 1888cd4cee2dSHong Zhang /*@ 1889bcf0153eSBarry Smith TSCreateQuadratureTS - Create a sub-`TS` that evaluates integrals over time 1890cd4cee2dSHong Zhang 1891d8d19677SJose E. Roman Input Parameters: 1892bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 1893cd4cee2dSHong Zhang - fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run 1894cd4cee2dSHong Zhang 18952fe279fdSBarry Smith Output Parameter: 1896bcf0153eSBarry Smith . quadts - the child `TS` context 1897cd4cee2dSHong Zhang 1898cd4cee2dSHong Zhang Level: intermediate 1899cd4cee2dSHong Zhang 19001cc06b55SBarry Smith .seealso: [](ch_ts), `TSGetQuadratureTS()` 1901cd4cee2dSHong Zhang @*/ 1902d71ae5a4SJacob Faibussowitsch PetscErrorCode TSCreateQuadratureTS(TS ts, PetscBool fwd, TS *quadts) 1903d71ae5a4SJacob Faibussowitsch { 1904cd4cee2dSHong Zhang char prefix[128]; 1905cd4cee2dSHong Zhang 1906cd4cee2dSHong Zhang PetscFunctionBegin; 1907cd4cee2dSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 19084f572ea9SToby Isaac PetscAssertPointer(quadts, 3); 19099566063dSJacob Faibussowitsch PetscCall(TSDestroy(&ts->quadraturets)); 19109566063dSJacob Faibussowitsch PetscCall(TSCreate(PetscObjectComm((PetscObject)ts), &ts->quadraturets)); 19119566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->quadraturets, (PetscObject)ts, 1)); 19129566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(prefix, sizeof(prefix), "%squad_", ((PetscObject)ts)->prefix ? ((PetscObject)ts)->prefix : "")); 19139566063dSJacob Faibussowitsch PetscCall(TSSetOptionsPrefix(ts->quadraturets, prefix)); 1914cd4cee2dSHong Zhang *quadts = ts->quadraturets; 1915cd4cee2dSHong Zhang 1916cd4cee2dSHong Zhang if (ts->numcost) { 19179566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, ts->numcost, &(*quadts)->vec_sol)); 1918cd4cee2dSHong Zhang } else { 19199566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, 1, &(*quadts)->vec_sol)); 1920cd4cee2dSHong Zhang } 1921cd4cee2dSHong Zhang ts->costintegralfwd = fwd; 19223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1923cd4cee2dSHong Zhang } 1924cd4cee2dSHong Zhang 1925cd4cee2dSHong Zhang /*@ 1926bcf0153eSBarry Smith TSGetQuadratureTS - Return the sub-`TS` that evaluates integrals over time 1927cd4cee2dSHong Zhang 1928cd4cee2dSHong Zhang Input Parameter: 1929bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 1930cd4cee2dSHong Zhang 1931cd4cee2dSHong Zhang Output Parameters: 1932cd4cee2dSHong Zhang + fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run 1933bcf0153eSBarry Smith - quadts - the child `TS` context 1934cd4cee2dSHong Zhang 1935cd4cee2dSHong Zhang Level: intermediate 1936cd4cee2dSHong Zhang 19371cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreateQuadratureTS()` 1938cd4cee2dSHong Zhang @*/ 1939d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetQuadratureTS(TS ts, PetscBool *fwd, TS *quadts) 1940d71ae5a4SJacob Faibussowitsch { 1941cd4cee2dSHong Zhang PetscFunctionBegin; 1942cd4cee2dSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 1943cd4cee2dSHong Zhang if (fwd) *fwd = ts->costintegralfwd; 1944cd4cee2dSHong Zhang if (quadts) *quadts = ts->quadraturets; 19453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1946cd4cee2dSHong Zhang } 1947ba0675f6SHong Zhang 1948ba0675f6SHong Zhang /*@ 1949bcf0153eSBarry Smith TSComputeSNESJacobian - Compute the Jacobian needed for the `SNESSolve()` in `TS` 1950bcf0153eSBarry Smith 1951c3339decSBarry Smith Collective 1952ba0675f6SHong Zhang 1953ba0675f6SHong Zhang Input Parameters: 1954bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 1955ba0675f6SHong Zhang - x - state vector 1956ba0675f6SHong Zhang 1957ba0675f6SHong Zhang Output Parameters: 1958ba0675f6SHong Zhang + J - Jacobian matrix 1959ba0675f6SHong Zhang - Jpre - preconditioning matrix for J (may be same as J) 1960ba0675f6SHong Zhang 1961ba0675f6SHong Zhang Level: developer 1962ba0675f6SHong Zhang 1963bcf0153eSBarry Smith Note: 1964bcf0153eSBarry Smith Uses finite differencing when `TS` Jacobian is not available. 1965bcf0153eSBarry Smith 1966b43aa488SJacob Faibussowitsch .seealso: `SNES`, `TS`, `SNESSetJacobian()`, `TSSetRHSJacobian()`, `TSSetIJacobian()` 1967ba0675f6SHong Zhang @*/ 1968d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeSNESJacobian(TS ts, Vec x, Mat J, Mat Jpre) 1969d71ae5a4SJacob Faibussowitsch { 1970ba0675f6SHong Zhang SNES snes = ts->snes; 1971ba0675f6SHong Zhang PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *) = NULL; 1972ba0675f6SHong Zhang 1973ba0675f6SHong Zhang PetscFunctionBegin; 1974ba0675f6SHong Zhang /* 1975ba0675f6SHong Zhang Unlike implicit methods, explicit methods do not have SNESMatFDColoring in the snes object 1976ba0675f6SHong Zhang because SNESSolve() has not been called yet; so querying SNESMatFDColoring does not work for 1977da81f932SPierre Jolivet explicit methods. Instead, we check the Jacobian compute function directly to determine if FD 1978ba0675f6SHong Zhang coloring is used. 1979ba0675f6SHong Zhang */ 19809566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, NULL, &jac, NULL)); 1981ba0675f6SHong Zhang if (jac == SNESComputeJacobianDefaultColor) { 1982ba0675f6SHong Zhang Vec f; 19839566063dSJacob Faibussowitsch PetscCall(SNESSetSolution(snes, x)); 19849566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &f, NULL, NULL)); 1985ba0675f6SHong Zhang /* Force MatFDColoringApply to evaluate the SNES residual function for the base vector */ 19869566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, x, f)); 1987ba0675f6SHong Zhang } 19889566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, x, J, Jpre)); 19893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1990ba0675f6SHong Zhang } 1991