1814e85d6SHong Zhang #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 6814e85d6SHong Zhang /* ------------------------ Sensitivity Context ---------------------------*/ 7814e85d6SHong Zhang 8814e85d6SHong Zhang /*@C 9b5b4017aSHong 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. 10814e85d6SHong Zhang 11814e85d6SHong Zhang Logically Collective on TS 12814e85d6SHong Zhang 13814e85d6SHong Zhang Input Parameters: 14b5b4017aSHong Zhang + ts - TS context obtained from TSCreate() 15b5b4017aSHong Zhang . Amat - JacobianP matrix 16b5b4017aSHong Zhang . func - function 17b5b4017aSHong Zhang - ctx - [optional] user-defined function context 18814e85d6SHong Zhang 19814e85d6SHong Zhang Calling sequence of func: 20814e85d6SHong Zhang $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx); 21814e85d6SHong Zhang + t - current timestep 22c9ad9de0SHong Zhang . U - input vector (current ODE solution) 23814e85d6SHong Zhang . A - output matrix 24814e85d6SHong Zhang - ctx - [optional] user-defined function context 25814e85d6SHong Zhang 26814e85d6SHong Zhang Level: intermediate 27814e85d6SHong Zhang 28814e85d6SHong Zhang Notes: 29814e85d6SHong 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 30814e85d6SHong Zhang 31814e85d6SHong Zhang .keywords: TS, sensitivity 32814e85d6SHong Zhang .seealso: 33814e85d6SHong Zhang @*/ 34814e85d6SHong Zhang PetscErrorCode TSSetRHSJacobianP(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 35814e85d6SHong Zhang { 36814e85d6SHong Zhang PetscErrorCode ierr; 37814e85d6SHong Zhang 38814e85d6SHong Zhang PetscFunctionBegin; 39814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID,1); 40814e85d6SHong Zhang PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 41814e85d6SHong Zhang 42814e85d6SHong Zhang ts->rhsjacobianp = func; 43814e85d6SHong Zhang ts->rhsjacobianpctx = ctx; 44814e85d6SHong Zhang if(Amat) { 45814e85d6SHong Zhang ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 4633f72c5dSHong Zhang ierr = MatDestroy(&ts->Jacprhs);CHKERRQ(ierr); 4733f72c5dSHong Zhang ts->Jacprhs = Amat; 48814e85d6SHong Zhang } 49814e85d6SHong Zhang PetscFunctionReturn(0); 50814e85d6SHong Zhang } 51814e85d6SHong Zhang 52814e85d6SHong Zhang /*@C 53814e85d6SHong Zhang TSComputeRHSJacobianP - Runs the user-defined JacobianP function. 54814e85d6SHong Zhang 55814e85d6SHong Zhang Collective on TS 56814e85d6SHong Zhang 57814e85d6SHong Zhang Input Parameters: 58814e85d6SHong Zhang . ts - The TS context obtained from TSCreate() 59814e85d6SHong Zhang 60814e85d6SHong Zhang Level: developer 61814e85d6SHong Zhang 62814e85d6SHong Zhang .keywords: TS, sensitivity 63814e85d6SHong Zhang .seealso: TSSetRHSJacobianP() 64814e85d6SHong Zhang @*/ 65c9ad9de0SHong Zhang PetscErrorCode TSComputeRHSJacobianP(TS ts,PetscReal t,Vec U,Mat Amat) 66814e85d6SHong Zhang { 67814e85d6SHong Zhang PetscErrorCode ierr; 68814e85d6SHong Zhang 69814e85d6SHong Zhang PetscFunctionBegin; 7033f72c5dSHong Zhang if (!Amat) PetscFunctionReturn(0); 71814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 72c9ad9de0SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 73814e85d6SHong Zhang 74814e85d6SHong Zhang PetscStackPush("TS user JacobianP function for sensitivity analysis"); 75c9ad9de0SHong Zhang ierr = (*ts->rhsjacobianp)(ts,t,U,Amat,ts->rhsjacobianpctx);CHKERRQ(ierr); 76814e85d6SHong Zhang PetscStackPop; 77814e85d6SHong Zhang PetscFunctionReturn(0); 78814e85d6SHong Zhang } 79814e85d6SHong Zhang 80814e85d6SHong Zhang /*@C 8133f72c5dSHong 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. 8233f72c5dSHong Zhang 8333f72c5dSHong Zhang Logically Collective on TS 8433f72c5dSHong Zhang 8533f72c5dSHong Zhang Input Parameters: 8633f72c5dSHong Zhang + ts - TS context obtained from TSCreate() 8733f72c5dSHong Zhang . Amat - JacobianP matrix 8833f72c5dSHong Zhang . func - function 8933f72c5dSHong Zhang - ctx - [optional] user-defined function context 9033f72c5dSHong Zhang 9133f72c5dSHong Zhang Calling sequence of func: 9233f72c5dSHong Zhang $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx); 9333f72c5dSHong Zhang + t - current timestep 9433f72c5dSHong Zhang . U - input vector (current ODE solution) 9533f72c5dSHong Zhang . Udot - time derivative of state vector 9633f72c5dSHong Zhang . shift - shift to apply, see note below 9733f72c5dSHong Zhang . A - output matrix 9833f72c5dSHong Zhang - ctx - [optional] user-defined function context 9933f72c5dSHong Zhang 10033f72c5dSHong Zhang Level: intermediate 10133f72c5dSHong Zhang 10233f72c5dSHong Zhang Notes: 10333f72c5dSHong 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 10433f72c5dSHong Zhang 10533f72c5dSHong Zhang .keywords: TS, sensitivity 10633f72c5dSHong Zhang .seealso: 10733f72c5dSHong Zhang @*/ 10833f72c5dSHong Zhang PetscErrorCode TSSetIJacobianP(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Vec,PetscReal,Mat,void*),void *ctx) 10933f72c5dSHong Zhang { 11033f72c5dSHong Zhang PetscErrorCode ierr; 11133f72c5dSHong Zhang 11233f72c5dSHong Zhang PetscFunctionBegin; 11333f72c5dSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID,1); 11433f72c5dSHong Zhang PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 11533f72c5dSHong Zhang 11633f72c5dSHong Zhang ts->ijacobianp = func; 11733f72c5dSHong Zhang ts->ijacobianpctx = ctx; 11833f72c5dSHong Zhang if(Amat) { 11933f72c5dSHong Zhang ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 12033f72c5dSHong Zhang ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 12133f72c5dSHong Zhang ts->Jacp = Amat; 12233f72c5dSHong Zhang } 12333f72c5dSHong Zhang PetscFunctionReturn(0); 12433f72c5dSHong Zhang } 12533f72c5dSHong Zhang 12633f72c5dSHong Zhang /*@C 12733f72c5dSHong Zhang TSComputeIJacobianP - Runs the user-defined IJacobianP function. 12833f72c5dSHong Zhang 12933f72c5dSHong Zhang Collective on TS 13033f72c5dSHong Zhang 13133f72c5dSHong Zhang Input Parameters: 13233f72c5dSHong Zhang + ts - the TS context 13333f72c5dSHong Zhang . t - current timestep 13433f72c5dSHong Zhang . U - state vector 13533f72c5dSHong Zhang . Udot - time derivative of state vector 13633f72c5dSHong Zhang . shift - shift to apply, see note below 13733f72c5dSHong Zhang - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 13833f72c5dSHong Zhang 13933f72c5dSHong Zhang Output Parameters: 14033f72c5dSHong Zhang . A - Jacobian matrix 14133f72c5dSHong Zhang 14233f72c5dSHong Zhang Level: developer 14333f72c5dSHong Zhang 14433f72c5dSHong Zhang .keywords: TS, sensitivity 14533f72c5dSHong Zhang .seealso: TSSetIJacobianP() 14633f72c5dSHong Zhang @*/ 14733f72c5dSHong Zhang PetscErrorCode TSComputeIJacobianP(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat Amat,PetscBool imex) 14833f72c5dSHong Zhang { 14933f72c5dSHong Zhang PetscErrorCode ierr; 15033f72c5dSHong Zhang 15133f72c5dSHong Zhang PetscFunctionBegin; 15233f72c5dSHong Zhang if (!Amat) PetscFunctionReturn(0); 15333f72c5dSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 15433f72c5dSHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 15533f72c5dSHong Zhang PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 15633f72c5dSHong Zhang 15733f72c5dSHong Zhang ierr = PetscLogEventBegin(TS_JacobianPEval,ts,U,Amat,0);CHKERRQ(ierr); 15833f72c5dSHong Zhang if (ts->ijacobianp) { 15933f72c5dSHong Zhang PetscStackPush("TS user JacobianP function for sensitivity analysis"); 16033f72c5dSHong Zhang ierr = (*ts->ijacobianp)(ts,t,U,Udot,shift,Amat,ts->ijacobianpctx);CHKERRQ(ierr); 16133f72c5dSHong Zhang PetscStackPop; 16233f72c5dSHong Zhang } 16333f72c5dSHong Zhang if (imex) { 16433f72c5dSHong Zhang if (!ts->ijacobianp) { /* system was written as Udot = G(t,U) */ 16533f72c5dSHong Zhang PetscBool assembled; 16633f72c5dSHong Zhang ierr = MatZeroEntries(Amat);CHKERRQ(ierr); 16733f72c5dSHong Zhang ierr = MatAssembled(Amat,&assembled);CHKERRQ(ierr); 16833f72c5dSHong Zhang if (!assembled) { 16933f72c5dSHong Zhang ierr = MatAssemblyBegin(Amat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17033f72c5dSHong Zhang ierr = MatAssemblyEnd(Amat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17133f72c5dSHong Zhang } 17233f72c5dSHong Zhang } 17333f72c5dSHong Zhang } else { 17433f72c5dSHong Zhang if (ts->rhsjacobianp) { 17533f72c5dSHong Zhang ierr = TSComputeRHSJacobianP(ts,t,U,ts->Jacprhs);CHKERRQ(ierr); 17633f72c5dSHong Zhang } 17733f72c5dSHong Zhang if (ts->Jacprhs == Amat) { /* No IJacobian, so we only have the RHS matrix */ 17833f72c5dSHong Zhang ierr = MatScale(Amat,-1);CHKERRQ(ierr); 17933f72c5dSHong Zhang } else if (ts->Jacprhs) { /* Both IJacobian and RHSJacobian */ 18033f72c5dSHong Zhang MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 18133f72c5dSHong Zhang if (!ts->ijacobianp) { /* No IJacobianp provided, but we have a separate RHS matrix */ 18233f72c5dSHong Zhang ierr = MatZeroEntries(Amat);CHKERRQ(ierr); 18333f72c5dSHong Zhang } 18433f72c5dSHong Zhang ierr = MatAXPY(Amat,-1,ts->Jacprhs,axpy);CHKERRQ(ierr); 18533f72c5dSHong Zhang } 18633f72c5dSHong Zhang } 18733f72c5dSHong Zhang ierr = PetscLogEventEnd(TS_JacobianPEval,ts,U,Amat,0);CHKERRQ(ierr); 18833f72c5dSHong Zhang PetscFunctionReturn(0); 18933f72c5dSHong Zhang } 19033f72c5dSHong Zhang 19133f72c5dSHong Zhang /*@C 192814e85d6SHong Zhang TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions 193814e85d6SHong Zhang 194814e85d6SHong Zhang Logically Collective on TS 195814e85d6SHong Zhang 196814e85d6SHong Zhang Input Parameters: 197814e85d6SHong Zhang + ts - the TS context obtained from TSCreate() 198814e85d6SHong Zhang . numcost - number of gradients to be computed, this is the number of cost functions 199814e85d6SHong Zhang . costintegral - vector that stores the integral values 200814e85d6SHong Zhang . rf - routine for evaluating the integrand function 201c9ad9de0SHong Zhang . drduf - function that computes the gradients of the r's with respect to u 202814e85d6SHong Zhang . drdpf - function that computes the gradients of the r's with respect to p, can be NULL if parametric sensitivity is not desired (mu=NULL) 203814e85d6SHong Zhang . fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run 204814e85d6SHong Zhang - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 205814e85d6SHong Zhang 206814e85d6SHong Zhang Calling sequence of rf: 207c9ad9de0SHong Zhang $ PetscErrorCode rf(TS ts,PetscReal t,Vec U,Vec F,void *ctx); 208814e85d6SHong Zhang 209c9ad9de0SHong Zhang Calling sequence of drduf: 210c9ad9de0SHong Zhang $ PetscErroCode drduf(TS ts,PetscReal t,Vec U,Vec *dRdU,void *ctx); 211814e85d6SHong Zhang 212814e85d6SHong Zhang Calling sequence of drdpf: 213c9ad9de0SHong Zhang $ PetscErroCode drdpf(TS ts,PetscReal t,Vec U,Vec *dRdP,void *ctx); 214814e85d6SHong Zhang 215814e85d6SHong Zhang Level: intermediate 216814e85d6SHong Zhang 217814e85d6SHong Zhang Notes: 218814e85d6SHong Zhang For optimization there is usually a single cost function (numcost = 1). For sensitivities there may be multiple cost functions 219814e85d6SHong Zhang 220814e85d6SHong Zhang .keywords: TS, sensitivity analysis, timestep, set, quadrature, function 221814e85d6SHong Zhang 222814e85d6SHong Zhang .seealso: TSSetRHSJacobianP(), TSGetCostGradients(), TSSetCostGradients() 223814e85d6SHong Zhang @*/ 224814e85d6SHong Zhang PetscErrorCode TSSetCostIntegrand(TS ts,PetscInt numcost,Vec costintegral,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*), 225c9ad9de0SHong Zhang PetscErrorCode (*drduf)(TS,PetscReal,Vec,Vec*,void*), 226814e85d6SHong Zhang PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*), 227814e85d6SHong Zhang PetscBool fwd,void *ctx) 228814e85d6SHong Zhang { 229814e85d6SHong Zhang PetscErrorCode ierr; 230814e85d6SHong Zhang 231814e85d6SHong Zhang PetscFunctionBegin; 232814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 233814e85d6SHong Zhang if (costintegral) PetscValidHeaderSpecific(costintegral,VEC_CLASSID,3); 234814e85d6SHong Zhang if (ts->numcost && ts->numcost!=numcost) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostGradients() or TSForwardSetIntegralGradients()"); 235814e85d6SHong Zhang if (!ts->numcost) ts->numcost=numcost; 236814e85d6SHong Zhang 237814e85d6SHong Zhang if (costintegral) { 238814e85d6SHong Zhang ierr = PetscObjectReference((PetscObject)costintegral);CHKERRQ(ierr); 239814e85d6SHong Zhang ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 240814e85d6SHong Zhang ts->vec_costintegral = costintegral; 241814e85d6SHong Zhang } else { 242814e85d6SHong Zhang if (!ts->vec_costintegral) { /* Create a seq vec if user does not provide one */ 243814e85d6SHong Zhang ierr = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr); 244814e85d6SHong Zhang } else { 245814e85d6SHong Zhang ierr = VecSet(ts->vec_costintegral,0.0);CHKERRQ(ierr); 246814e85d6SHong Zhang } 247814e85d6SHong Zhang } 248814e85d6SHong Zhang if (!ts->vec_costintegrand) { 249814e85d6SHong Zhang ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr); 250814e85d6SHong Zhang } else { 251814e85d6SHong Zhang ierr = VecSet(ts->vec_costintegrand,0.0);CHKERRQ(ierr); 252814e85d6SHong Zhang } 253814e85d6SHong Zhang ts->costintegralfwd = fwd; /* Evaluate the cost integral in forward run if fwd is true */ 254814e85d6SHong Zhang ts->costintegrand = rf; 255814e85d6SHong Zhang ts->costintegrandctx = ctx; 256c9ad9de0SHong Zhang ts->drdufunction = drduf; 257814e85d6SHong Zhang ts->drdpfunction = drdpf; 258814e85d6SHong Zhang PetscFunctionReturn(0); 259814e85d6SHong Zhang } 260814e85d6SHong Zhang 261b5b4017aSHong Zhang /*@C 262814e85d6SHong Zhang TSGetCostIntegral - Returns the values of the integral term in the cost functions. 263814e85d6SHong Zhang It is valid to call the routine after a backward run. 264814e85d6SHong Zhang 265814e85d6SHong Zhang Not Collective 266814e85d6SHong Zhang 267814e85d6SHong Zhang Input Parameter: 268814e85d6SHong Zhang . ts - the TS context obtained from TSCreate() 269814e85d6SHong Zhang 270814e85d6SHong Zhang Output Parameter: 271814e85d6SHong Zhang . v - the vector containing the integrals for each cost function 272814e85d6SHong Zhang 273814e85d6SHong Zhang Level: intermediate 274814e85d6SHong Zhang 275814e85d6SHong Zhang .seealso: TSSetCostIntegrand() 276814e85d6SHong Zhang 277814e85d6SHong Zhang .keywords: TS, sensitivity analysis 278814e85d6SHong Zhang @*/ 279814e85d6SHong Zhang PetscErrorCode TSGetCostIntegral(TS ts,Vec *v) 280814e85d6SHong Zhang { 281814e85d6SHong Zhang PetscFunctionBegin; 282814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 283814e85d6SHong Zhang PetscValidPointer(v,2); 284814e85d6SHong Zhang *v = ts->vec_costintegral; 285814e85d6SHong Zhang PetscFunctionReturn(0); 286814e85d6SHong Zhang } 287814e85d6SHong Zhang 288b5b4017aSHong Zhang /*@C 289814e85d6SHong Zhang TSComputeCostIntegrand - Evaluates the integral function in the cost functions. 290814e85d6SHong Zhang 291814e85d6SHong Zhang Input Parameters: 292814e85d6SHong Zhang + ts - the TS context 293814e85d6SHong Zhang . t - current time 294c9ad9de0SHong Zhang - U - state vector, i.e. current solution 295814e85d6SHong Zhang 296814e85d6SHong Zhang Output Parameter: 297c9ad9de0SHong Zhang . Q - vector of size numcost to hold the outputs 298814e85d6SHong Zhang 299814e85d6SHong Zhang Note: 300814e85d6SHong Zhang Most users should not need to explicitly call this routine, as it 301814e85d6SHong Zhang is used internally within the sensitivity analysis context. 302814e85d6SHong Zhang 303814e85d6SHong Zhang Level: developer 304814e85d6SHong Zhang 305814e85d6SHong Zhang .keywords: TS, compute 306814e85d6SHong Zhang 307814e85d6SHong Zhang .seealso: TSSetCostIntegrand() 308814e85d6SHong Zhang @*/ 309c9ad9de0SHong Zhang PetscErrorCode TSComputeCostIntegrand(TS ts,PetscReal t,Vec U,Vec Q) 310814e85d6SHong Zhang { 311814e85d6SHong Zhang PetscErrorCode ierr; 312814e85d6SHong Zhang 313814e85d6SHong Zhang PetscFunctionBegin; 314814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 315c9ad9de0SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 316c9ad9de0SHong Zhang PetscValidHeaderSpecific(Q,VEC_CLASSID,4); 317814e85d6SHong Zhang 318c9ad9de0SHong Zhang ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Q,0);CHKERRQ(ierr); 319814e85d6SHong Zhang if (ts->costintegrand) { 320814e85d6SHong Zhang PetscStackPush("TS user integrand in the cost function"); 321c9ad9de0SHong Zhang ierr = (*ts->costintegrand)(ts,t,U,Q,ts->costintegrandctx);CHKERRQ(ierr); 322814e85d6SHong Zhang PetscStackPop; 323814e85d6SHong Zhang } else { 324c9ad9de0SHong Zhang ierr = VecZeroEntries(Q);CHKERRQ(ierr); 325814e85d6SHong Zhang } 326814e85d6SHong Zhang 327c9ad9de0SHong Zhang ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Q,0);CHKERRQ(ierr); 328814e85d6SHong Zhang PetscFunctionReturn(0); 329814e85d6SHong Zhang } 330814e85d6SHong Zhang 331b5b4017aSHong Zhang /*@C 332c9ad9de0SHong Zhang TSComputeDRDUFunction - Runs the user-defined DRDU function. 333814e85d6SHong Zhang 334814e85d6SHong Zhang Collective on TS 335814e85d6SHong Zhang 336814e85d6SHong Zhang Input Parameters: 337c9ad9de0SHong Zhang + ts - the TS context obtained from TSCreate() 338c9ad9de0SHong Zhang . t - current time 339c9ad9de0SHong Zhang - U - stata vector 340c9ad9de0SHong Zhang 341c9ad9de0SHong Zhang Output Parameters: 342b5b4017aSHong Zhang . DRDU - vector array to hold the outputs 343814e85d6SHong Zhang 344814e85d6SHong Zhang Notes: 345c9ad9de0SHong Zhang TSComputeDRDUFunction() is typically used for sensitivity implementation, 346814e85d6SHong Zhang so most users would not generally call this routine themselves. 347814e85d6SHong Zhang 348814e85d6SHong Zhang Level: developer 349814e85d6SHong Zhang 350814e85d6SHong Zhang .keywords: TS, sensitivity 351814e85d6SHong Zhang .seealso: TSSetCostIntegrand() 352814e85d6SHong Zhang @*/ 353c9ad9de0SHong Zhang PetscErrorCode TSComputeDRDUFunction(TS ts,PetscReal t,Vec U,Vec *DRDU) 354814e85d6SHong Zhang { 355814e85d6SHong Zhang PetscErrorCode ierr; 356814e85d6SHong Zhang 357814e85d6SHong Zhang PetscFunctionBegin; 35833f72c5dSHong Zhang if (!DRDU) PetscFunctionReturn(0); 359814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 360c9ad9de0SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 361814e85d6SHong Zhang 362c9ad9de0SHong Zhang PetscStackPush("TS user DRDU function for sensitivity analysis"); 363c9ad9de0SHong Zhang ierr = (*ts->drdufunction)(ts,t,U,DRDU,ts->costintegrandctx); CHKERRQ(ierr); 364814e85d6SHong Zhang PetscStackPop; 365814e85d6SHong Zhang PetscFunctionReturn(0); 366814e85d6SHong Zhang } 367814e85d6SHong Zhang 368b5b4017aSHong Zhang /*@C 369814e85d6SHong Zhang TSComputeDRDPFunction - Runs the user-defined DRDP function. 370814e85d6SHong Zhang 371814e85d6SHong Zhang Collective on TS 372814e85d6SHong Zhang 373814e85d6SHong Zhang Input Parameters: 374c9ad9de0SHong Zhang + ts - the TS context obtained from TSCreate() 375c9ad9de0SHong Zhang . t - current time 376c9ad9de0SHong Zhang - U - stata vector 377c9ad9de0SHong Zhang 378c9ad9de0SHong Zhang Output Parameters: 379b5b4017aSHong Zhang . DRDP - vector array to hold the outputs 380814e85d6SHong Zhang 381814e85d6SHong Zhang Notes: 382c9ad9de0SHong Zhang TSComputeDRDPFunction() is typically used for sensitivity implementation, 383814e85d6SHong Zhang so most users would not generally call this routine themselves. 384814e85d6SHong Zhang 385814e85d6SHong Zhang Level: developer 386814e85d6SHong Zhang 387814e85d6SHong Zhang .keywords: TS, sensitivity 388814e85d6SHong Zhang .seealso: TSSetCostIntegrand() 389814e85d6SHong Zhang @*/ 390c9ad9de0SHong Zhang PetscErrorCode TSComputeDRDPFunction(TS ts,PetscReal t,Vec U,Vec *DRDP) 391814e85d6SHong Zhang { 392814e85d6SHong Zhang PetscErrorCode ierr; 393814e85d6SHong Zhang 394814e85d6SHong Zhang PetscFunctionBegin; 39533f72c5dSHong Zhang if (!DRDP) PetscFunctionReturn(0); 396814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 397c9ad9de0SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 398814e85d6SHong Zhang 399814e85d6SHong Zhang PetscStackPush("TS user DRDP function for sensitivity analysis"); 400c9ad9de0SHong Zhang ierr = (*ts->drdpfunction)(ts,t,U,DRDP,ts->costintegrandctx); CHKERRQ(ierr); 401814e85d6SHong Zhang PetscStackPop; 402814e85d6SHong Zhang PetscFunctionReturn(0); 403814e85d6SHong Zhang } 404814e85d6SHong Zhang 405b5b4017aSHong Zhang /*@C 406b5b4017aSHong 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. 407b5b4017aSHong Zhang 408b5b4017aSHong Zhang Logically Collective on TS 409b5b4017aSHong Zhang 410b5b4017aSHong Zhang Input Parameters: 411b5b4017aSHong Zhang + ts - TS context obtained from TSCreate() 412b5b4017aSHong Zhang . ihp1 - an array of vectors storing the result of vector-Hessian-vector product for F_UU 413b5b4017aSHong Zhang . hessianproductfunc1 - vector-Hessian-vector product function for F_UU 414b5b4017aSHong Zhang . ihp2 - an array of vectors storing the result of vector-Hessian-vector product for F_UP 415b5b4017aSHong Zhang . hessianproductfunc2 - vector-Hessian-vector product function for F_UP 416b5b4017aSHong Zhang . ihp3 - an array of vectors storing the result of vector-Hessian-vector product for F_PU 417b5b4017aSHong Zhang . hessianproductfunc3 - vector-Hessian-vector product function for F_PU 418b5b4017aSHong Zhang . ihp4 - an array of vectors storing the result of vector-Hessian-vector product for F_PP 419b5b4017aSHong Zhang . hessianproductfunc4 - vector-Hessian-vector product function for F_PP 420b5b4017aSHong Zhang 421b5b4017aSHong Zhang Calling sequence of ihessianproductfunc: 422b5b4017aSHong Zhang $ ihessianproductfunc (TS ts,PetscReal t,Vec U,Vec Vl,Vec Vr,Vec VHV,void *ctx); 423b5b4017aSHong Zhang + t - current timestep 424b5b4017aSHong Zhang . U - input vector (current ODE solution) 425b5b4017aSHong Zhang . Vl - input vector to be left-multiplied with the Hessian 426b5b4017aSHong Zhang . Vr - input vector to be right-multiplied with the Hessian 427b5b4017aSHong Zhang . VHV - output vector for vector-Hessian-vector product 428b5b4017aSHong Zhang - ctx - [optional] user-defined function context 429b5b4017aSHong Zhang 430b5b4017aSHong Zhang Level: intermediate 431b5b4017aSHong Zhang 432b5b4017aSHong Zhang Note: The first Hessian function and the working array are required. 433b5b4017aSHong Zhang 434b5b4017aSHong Zhang .keywords: TS, sensitivity 435b5b4017aSHong Zhang 436b5b4017aSHong Zhang .seealso: 437b5b4017aSHong Zhang @*/ 438b5b4017aSHong Zhang PetscErrorCode TSSetIHessianProduct(TS ts,Vec *ihp1,PetscErrorCode (*ihessianproductfunc1)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*), 439b5b4017aSHong Zhang Vec *ihp2,PetscErrorCode (*ihessianproductfunc2)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*), 440b5b4017aSHong Zhang Vec *ihp3,PetscErrorCode (*ihessianproductfunc3)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*), 441b5b4017aSHong Zhang Vec *ihp4,PetscErrorCode (*ihessianproductfunc4)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*), 442b5b4017aSHong Zhang void *ctx) 443b5b4017aSHong Zhang { 444b5b4017aSHong Zhang PetscFunctionBegin; 445b5b4017aSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 446b5b4017aSHong Zhang PetscValidPointer(ihp1,2); 447b5b4017aSHong Zhang 448b5b4017aSHong Zhang ts->ihessianproductctx = ctx; 449b5b4017aSHong Zhang if (ihp1) ts->vecs_fuu = ihp1; 450b5b4017aSHong Zhang if (ihp2) ts->vecs_fup = ihp2; 451b5b4017aSHong Zhang if (ihp3) ts->vecs_fpu = ihp3; 452b5b4017aSHong Zhang if (ihp4) ts->vecs_fpp = ihp4; 453b5b4017aSHong Zhang ts->ihessianproduct_fuu = ihessianproductfunc1; 454b5b4017aSHong Zhang ts->ihessianproduct_fup = ihessianproductfunc2; 455b5b4017aSHong Zhang ts->ihessianproduct_fpu = ihessianproductfunc3; 456b5b4017aSHong Zhang ts->ihessianproduct_fpp = ihessianproductfunc4; 457b5b4017aSHong Zhang PetscFunctionReturn(0); 458b5b4017aSHong Zhang } 459b5b4017aSHong Zhang 460b5b4017aSHong Zhang /*@C 461b5b4017aSHong Zhang TSComputeIHessianProductFunction1 - Runs the user-defined vector-Hessian-vector product function for Fuu. 462b5b4017aSHong Zhang 463b5b4017aSHong Zhang Collective on TS 464b5b4017aSHong Zhang 465b5b4017aSHong Zhang Input Parameters: 466b5b4017aSHong Zhang . ts - The TS context obtained from TSCreate() 467b5b4017aSHong Zhang 468b5b4017aSHong Zhang Notes: 469b5b4017aSHong Zhang TSComputeIHessianProductFunction1() is typically used for sensitivity implementation, 470b5b4017aSHong Zhang so most users would not generally call this routine themselves. 471b5b4017aSHong Zhang 472b5b4017aSHong Zhang Level: developer 473b5b4017aSHong Zhang 474b5b4017aSHong Zhang .keywords: TS, sensitivity 475b5b4017aSHong Zhang 476b5b4017aSHong Zhang .seealso: TSSetIHessianProduct() 477b5b4017aSHong Zhang @*/ 478b5b4017aSHong Zhang PetscErrorCode TSComputeIHessianProductFunction1(TS ts,PetscReal t,Vec U,Vec *Vl,Vec Vr,Vec *VHV) 479b5b4017aSHong Zhang { 480b5b4017aSHong Zhang PetscErrorCode ierr; 481b5b4017aSHong Zhang 482b5b4017aSHong Zhang PetscFunctionBegin; 48333f72c5dSHong Zhang if (!VHV) PetscFunctionReturn(0); 484b5b4017aSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 485b5b4017aSHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 486b5b4017aSHong Zhang 48767633408SHong Zhang if (ts->ihessianproduct_fuu) { 488b5b4017aSHong Zhang PetscStackPush("TS user IHessianProduct function 1 for sensitivity analysis"); 489b5b4017aSHong Zhang ierr = (*ts->ihessianproduct_fuu)(ts,t,U,Vl,Vr,VHV,ts->ihessianproductctx);CHKERRQ(ierr); 490b5b4017aSHong Zhang PetscStackPop; 49167633408SHong Zhang } 49267633408SHong Zhang /* does not consider IMEX for now, so either IHessian or RHSHessian will be calculated, using the same output VHV */ 49367633408SHong Zhang if (ts->rhshessianproduct_guu) { 49467633408SHong Zhang PetscInt nadj; 49567633408SHong Zhang ierr = TSComputeRHSHessianProductFunction1(ts,t,U,Vl,Vr,VHV);CHKERRQ(ierr); 49667633408SHong Zhang for (nadj=0; nadj<ts->numcost; nadj++) { 49767633408SHong Zhang ierr = VecScale(VHV[nadj],-1);CHKERRQ(ierr); 49867633408SHong Zhang } 49967633408SHong Zhang } 500b5b4017aSHong Zhang PetscFunctionReturn(0); 501b5b4017aSHong Zhang } 502b5b4017aSHong Zhang 503b5b4017aSHong Zhang /*@C 504b5b4017aSHong Zhang TSComputeIHessianProductFunction2 - Runs the user-defined vector-Hessian-vector product function for Fup. 505b5b4017aSHong Zhang 506b5b4017aSHong Zhang Collective on TS 507b5b4017aSHong Zhang 508b5b4017aSHong Zhang Input Parameters: 509b5b4017aSHong Zhang . ts - The TS context obtained from TSCreate() 510b5b4017aSHong Zhang 511b5b4017aSHong Zhang Notes: 512b5b4017aSHong Zhang TSComputeIHessianProductFunction2() is typically used for sensitivity implementation, 513b5b4017aSHong Zhang so most users would not generally call this routine themselves. 514b5b4017aSHong Zhang 515b5b4017aSHong Zhang Level: developer 516b5b4017aSHong Zhang 517b5b4017aSHong Zhang .keywords: TS, sensitivity 518b5b4017aSHong Zhang 519b5b4017aSHong Zhang .seealso: TSSetIHessianProduct() 520b5b4017aSHong Zhang @*/ 521b5b4017aSHong Zhang PetscErrorCode TSComputeIHessianProductFunction2(TS ts,PetscReal t,Vec U,Vec *Vl,Vec Vr,Vec *VHV) 522b5b4017aSHong Zhang { 523b5b4017aSHong Zhang PetscErrorCode ierr; 524b5b4017aSHong Zhang 525b5b4017aSHong Zhang PetscFunctionBegin; 52633f72c5dSHong Zhang if (!VHV) PetscFunctionReturn(0); 527b5b4017aSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 528b5b4017aSHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 529b5b4017aSHong Zhang 53067633408SHong Zhang if (ts->ihessianproduct_fup) { 531b5b4017aSHong Zhang PetscStackPush("TS user IHessianProduct function 2 for sensitivity analysis"); 532b5b4017aSHong Zhang ierr = (*ts->ihessianproduct_fup)(ts,t,U,Vl,Vr,VHV,ts->ihessianproductctx);CHKERRQ(ierr); 533b5b4017aSHong Zhang PetscStackPop; 53467633408SHong Zhang } 53567633408SHong Zhang /* does not consider IMEX for now, so either IHessian or RHSHessian will be calculated, using the same output VHV */ 53667633408SHong Zhang if (ts->rhshessianproduct_gup) { 53767633408SHong Zhang PetscInt nadj; 53867633408SHong Zhang ierr = TSComputeRHSHessianProductFunction2(ts,t,U,Vl,Vr,VHV);CHKERRQ(ierr); 53967633408SHong Zhang for (nadj=0; nadj<ts->numcost; nadj++) { 54067633408SHong Zhang ierr = VecScale(VHV[nadj],-1);CHKERRQ(ierr); 54167633408SHong Zhang } 54267633408SHong Zhang } 543b5b4017aSHong Zhang PetscFunctionReturn(0); 544b5b4017aSHong Zhang } 545b5b4017aSHong Zhang 546b5b4017aSHong Zhang /*@C 547b5b4017aSHong Zhang TSComputeIHessianProductFunction3 - Runs the user-defined vector-Hessian-vector product function for Fpu. 548b5b4017aSHong Zhang 549b5b4017aSHong Zhang Collective on TS 550b5b4017aSHong Zhang 551b5b4017aSHong Zhang Input Parameters: 552b5b4017aSHong Zhang . ts - The TS context obtained from TSCreate() 553b5b4017aSHong Zhang 554b5b4017aSHong Zhang Notes: 555b5b4017aSHong Zhang TSComputeIHessianProductFunction3() is typically used for sensitivity implementation, 556b5b4017aSHong Zhang so most users would not generally call this routine themselves. 557b5b4017aSHong Zhang 558b5b4017aSHong Zhang Level: developer 559b5b4017aSHong Zhang 560b5b4017aSHong Zhang .keywords: TS, sensitivity 561b5b4017aSHong Zhang 562b5b4017aSHong Zhang .seealso: TSSetIHessianProduct() 563b5b4017aSHong Zhang @*/ 564b5b4017aSHong Zhang PetscErrorCode TSComputeIHessianProductFunction3(TS ts,PetscReal t,Vec U,Vec *Vl,Vec Vr,Vec *VHV) 565b5b4017aSHong Zhang { 566b5b4017aSHong Zhang PetscErrorCode ierr; 567b5b4017aSHong Zhang 568b5b4017aSHong Zhang PetscFunctionBegin; 56933f72c5dSHong Zhang if (!VHV) PetscFunctionReturn(0); 570b5b4017aSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 571b5b4017aSHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 572b5b4017aSHong Zhang 57367633408SHong Zhang if (ts->ihessianproduct_fpu) { 574b5b4017aSHong Zhang PetscStackPush("TS user IHessianProduct function 3 for sensitivity analysis"); 575b5b4017aSHong Zhang ierr = (*ts->ihessianproduct_fpu)(ts,t,U,Vl,Vr,VHV,ts->ihessianproductctx);CHKERRQ(ierr); 576b5b4017aSHong Zhang PetscStackPop; 57767633408SHong Zhang } 57867633408SHong Zhang /* does not consider IMEX for now, so either IHessian or RHSHessian will be calculated, using the same output VHV */ 57967633408SHong Zhang if (ts->rhshessianproduct_gpu) { 58067633408SHong Zhang PetscInt nadj; 58167633408SHong Zhang ierr = TSComputeRHSHessianProductFunction3(ts,t,U,Vl,Vr,VHV);CHKERRQ(ierr); 58267633408SHong Zhang for (nadj=0; nadj<ts->numcost; nadj++) { 58367633408SHong Zhang ierr = VecScale(VHV[nadj],-1);CHKERRQ(ierr); 58467633408SHong Zhang } 58567633408SHong Zhang } 586b5b4017aSHong Zhang PetscFunctionReturn(0); 587b5b4017aSHong Zhang } 588b5b4017aSHong Zhang 589b5b4017aSHong Zhang /*@C 590b5b4017aSHong Zhang TSComputeIHessianProductFunction4 - Runs the user-defined vector-Hessian-vector product function for Fpp. 591b5b4017aSHong Zhang 592b5b4017aSHong Zhang Collective on TS 593b5b4017aSHong Zhang 594b5b4017aSHong Zhang Input Parameters: 595b5b4017aSHong Zhang . ts - The TS context obtained from TSCreate() 596b5b4017aSHong Zhang 597b5b4017aSHong Zhang Notes: 598b5b4017aSHong Zhang TSComputeIHessianProductFunction4() is typically used for sensitivity implementation, 599b5b4017aSHong Zhang so most users would not generally call this routine themselves. 600b5b4017aSHong Zhang 601b5b4017aSHong Zhang Level: developer 602b5b4017aSHong Zhang 603b5b4017aSHong Zhang .keywords: TS, sensitivity 604b5b4017aSHong Zhang 605b5b4017aSHong Zhang .seealso: TSSetIHessianProduct() 606b5b4017aSHong Zhang @*/ 607b5b4017aSHong Zhang PetscErrorCode TSComputeIHessianProductFunction4(TS ts,PetscReal t,Vec U,Vec *Vl,Vec Vr,Vec *VHV) 608b5b4017aSHong Zhang { 609b5b4017aSHong Zhang PetscErrorCode ierr; 610b5b4017aSHong Zhang 611b5b4017aSHong Zhang PetscFunctionBegin; 61233f72c5dSHong Zhang if (!VHV) PetscFunctionReturn(0); 613b5b4017aSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 614b5b4017aSHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 615b5b4017aSHong Zhang 61667633408SHong Zhang if (ts->ihessianproduct_fpp) { 617b5b4017aSHong Zhang PetscStackPush("TS user IHessianProduct function 3 for sensitivity analysis"); 618b5b4017aSHong Zhang ierr = (*ts->ihessianproduct_fpp)(ts,t,U,Vl,Vr,VHV,ts->ihessianproductctx);CHKERRQ(ierr); 619b5b4017aSHong Zhang PetscStackPop; 62067633408SHong Zhang } 62167633408SHong Zhang /* does not consider IMEX for now, so either IHessian or RHSHessian will be calculated, using the same output VHV */ 62267633408SHong Zhang if (ts->rhshessianproduct_gpp) { 62367633408SHong Zhang PetscInt nadj; 62467633408SHong Zhang ierr = TSComputeRHSHessianProductFunction4(ts,t,U,Vl,Vr,VHV);CHKERRQ(ierr); 62567633408SHong Zhang for (nadj=0; nadj<ts->numcost; nadj++) { 62667633408SHong Zhang ierr = VecScale(VHV[nadj],-1);CHKERRQ(ierr); 62767633408SHong Zhang } 62867633408SHong Zhang } 629b5b4017aSHong Zhang PetscFunctionReturn(0); 630b5b4017aSHong Zhang } 631b5b4017aSHong Zhang 632*13af1a74SHong Zhang /*@C 633*13af1a74SHong Zhang TSSetRHSHessianProduct - Sets the function that computes the vecotr-Hessian-vector product. The Hessian is the second-order derivative of G (RHSFunction) w.r.t. the state variable. 634*13af1a74SHong Zhang 635*13af1a74SHong Zhang Logically Collective on TS 636*13af1a74SHong Zhang 637*13af1a74SHong Zhang Input Parameters: 638*13af1a74SHong Zhang + ts - TS context obtained from TSCreate() 639*13af1a74SHong Zhang . rhshp1 - an array of vectors storing the result of vector-Hessian-vector product for G_UU 640*13af1a74SHong Zhang . hessianproductfunc1 - vector-Hessian-vector product function for G_UU 641*13af1a74SHong Zhang . rhshp2 - an array of vectors storing the result of vector-Hessian-vector product for G_UP 642*13af1a74SHong Zhang . hessianproductfunc2 - vector-Hessian-vector product function for G_UP 643*13af1a74SHong Zhang . rhshp3 - an array of vectors storing the result of vector-Hessian-vector product for G_PU 644*13af1a74SHong Zhang . hessianproductfunc3 - vector-Hessian-vector product function for G_PU 645*13af1a74SHong Zhang . rhshp4 - an array of vectors storing the result of vector-Hessian-vector product for G_PP 646*13af1a74SHong Zhang . hessianproductfunc4 - vector-Hessian-vector product function for G_PP 647*13af1a74SHong Zhang 648*13af1a74SHong Zhang Calling sequence of ihessianproductfunc: 649*13af1a74SHong Zhang $ rhshessianproductfunc (TS ts,PetscReal t,Vec U,Vec Vl,Vec Vr,Vec VHV,void *ctx); 650*13af1a74SHong Zhang + t - current timestep 651*13af1a74SHong Zhang . U - input vector (current ODE solution) 652*13af1a74SHong Zhang . Vl - input vector to be left-multiplied with the Hessian 653*13af1a74SHong Zhang . Vr - input vector to be right-multiplied with the Hessian 654*13af1a74SHong Zhang . VHV - output vector for vector-Hessian-vector product 655*13af1a74SHong Zhang - ctx - [optional] user-defined function context 656*13af1a74SHong Zhang 657*13af1a74SHong Zhang Level: intermediate 658*13af1a74SHong Zhang 659*13af1a74SHong Zhang Note: The first Hessian function and the working array are required. 660*13af1a74SHong Zhang 661*13af1a74SHong Zhang .keywords: TS, sensitivity 662*13af1a74SHong Zhang 663*13af1a74SHong Zhang .seealso: 664*13af1a74SHong Zhang @*/ 665*13af1a74SHong Zhang PetscErrorCode TSSetRHSHessianProduct(TS ts,Vec *rhshp1,PetscErrorCode (*rhshessianproductfunc1)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*), 666*13af1a74SHong Zhang Vec *rhshp2,PetscErrorCode (*rhshessianproductfunc2)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*), 667*13af1a74SHong Zhang Vec *rhshp3,PetscErrorCode (*rhshessianproductfunc3)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*), 668*13af1a74SHong Zhang Vec *rhshp4,PetscErrorCode (*rhshessianproductfunc4)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*), 669*13af1a74SHong Zhang void *ctx) 670*13af1a74SHong Zhang { 671*13af1a74SHong Zhang PetscFunctionBegin; 672*13af1a74SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 673*13af1a74SHong Zhang PetscValidPointer(rhshp1,2); 674*13af1a74SHong Zhang 675*13af1a74SHong Zhang ts->rhshessianproductctx = ctx; 676*13af1a74SHong Zhang if (rhshp1) ts->vecs_guu = rhshp1; 677*13af1a74SHong Zhang if (rhshp2) ts->vecs_gup = rhshp2; 678*13af1a74SHong Zhang if (rhshp3) ts->vecs_gpu = rhshp3; 679*13af1a74SHong Zhang if (rhshp4) ts->vecs_gpp = rhshp4; 680*13af1a74SHong Zhang ts->rhshessianproduct_guu = rhshessianproductfunc1; 681*13af1a74SHong Zhang ts->rhshessianproduct_gup = rhshessianproductfunc2; 682*13af1a74SHong Zhang ts->rhshessianproduct_gpu = rhshessianproductfunc3; 683*13af1a74SHong Zhang ts->rhshessianproduct_gpp = rhshessianproductfunc4; 684*13af1a74SHong Zhang PetscFunctionReturn(0); 685*13af1a74SHong Zhang } 686*13af1a74SHong Zhang 687*13af1a74SHong Zhang /*@C 688*13af1a74SHong Zhang TSComputeRHSHessianProductFunction1 - Runs the user-defined vector-Hessian-vector product function for Guu. 689*13af1a74SHong Zhang 690*13af1a74SHong Zhang Collective on TS 691*13af1a74SHong Zhang 692*13af1a74SHong Zhang Input Parameters: 693*13af1a74SHong Zhang . ts - The TS context obtained from TSCreate() 694*13af1a74SHong Zhang 695*13af1a74SHong Zhang Notes: 696*13af1a74SHong Zhang TSComputeRHSHessianProductFunction1() is typically used for sensitivity implementation, 697*13af1a74SHong Zhang so most users would not generally call this routine themselves. 698*13af1a74SHong Zhang 699*13af1a74SHong Zhang Level: developer 700*13af1a74SHong Zhang 701*13af1a74SHong Zhang .keywords: TS, sensitivity 702*13af1a74SHong Zhang 703*13af1a74SHong Zhang .seealso: TSSetRHSHessianProduct() 704*13af1a74SHong Zhang @*/ 705*13af1a74SHong Zhang PetscErrorCode TSComputeRHSHessianProductFunction1(TS ts,PetscReal t,Vec U,Vec *Vl,Vec Vr,Vec *VHV) 706*13af1a74SHong Zhang { 707*13af1a74SHong Zhang PetscErrorCode ierr; 708*13af1a74SHong Zhang 709*13af1a74SHong Zhang PetscFunctionBegin; 710*13af1a74SHong Zhang if (!VHV) PetscFunctionReturn(0); 711*13af1a74SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 712*13af1a74SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 713*13af1a74SHong Zhang 714*13af1a74SHong Zhang PetscStackPush("TS user RHSHessianProduct function 1 for sensitivity analysis"); 715*13af1a74SHong Zhang ierr = (*ts->rhshessianproduct_guu)(ts,t,U,Vl,Vr,VHV,ts->rhshessianproductctx);CHKERRQ(ierr); 716*13af1a74SHong Zhang PetscStackPop; 717*13af1a74SHong Zhang PetscFunctionReturn(0); 718*13af1a74SHong Zhang } 719*13af1a74SHong Zhang 720*13af1a74SHong Zhang /*@C 721*13af1a74SHong Zhang TSComputeRHSHessianProductFunction2 - Runs the user-defined vector-Hessian-vector product function for Gup. 722*13af1a74SHong Zhang 723*13af1a74SHong Zhang Collective on TS 724*13af1a74SHong Zhang 725*13af1a74SHong Zhang Input Parameters: 726*13af1a74SHong Zhang . ts - The TS context obtained from TSCreate() 727*13af1a74SHong Zhang 728*13af1a74SHong Zhang Notes: 729*13af1a74SHong Zhang TSComputeRHSHessianProductFunction2() is typically used for sensitivity implementation, 730*13af1a74SHong Zhang so most users would not generally call this routine themselves. 731*13af1a74SHong Zhang 732*13af1a74SHong Zhang Level: developer 733*13af1a74SHong Zhang 734*13af1a74SHong Zhang .keywords: TS, sensitivity 735*13af1a74SHong Zhang 736*13af1a74SHong Zhang .seealso: TSSetRHSHessianProduct() 737*13af1a74SHong Zhang @*/ 738*13af1a74SHong Zhang PetscErrorCode TSComputeRHSHessianProductFunction2(TS ts,PetscReal t,Vec U,Vec *Vl,Vec Vr,Vec *VHV) 739*13af1a74SHong Zhang { 740*13af1a74SHong Zhang PetscErrorCode ierr; 741*13af1a74SHong Zhang 742*13af1a74SHong Zhang PetscFunctionBegin; 743*13af1a74SHong Zhang if (!VHV) PetscFunctionReturn(0); 744*13af1a74SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 745*13af1a74SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 746*13af1a74SHong Zhang 747*13af1a74SHong Zhang PetscStackPush("TS user RHSHessianProduct function 2 for sensitivity analysis"); 748*13af1a74SHong Zhang ierr = (*ts->rhshessianproduct_gup)(ts,t,U,Vl,Vr,VHV,ts->rhshessianproductctx);CHKERRQ(ierr); 749*13af1a74SHong Zhang PetscStackPop; 750*13af1a74SHong Zhang PetscFunctionReturn(0); 751*13af1a74SHong Zhang } 752*13af1a74SHong Zhang 753*13af1a74SHong Zhang /*@C 754*13af1a74SHong Zhang TSComputeRHSHessianProductFunction3 - Runs the user-defined vector-Hessian-vector product function for Gpu. 755*13af1a74SHong Zhang 756*13af1a74SHong Zhang Collective on TS 757*13af1a74SHong Zhang 758*13af1a74SHong Zhang Input Parameters: 759*13af1a74SHong Zhang . ts - The TS context obtained from TSCreate() 760*13af1a74SHong Zhang 761*13af1a74SHong Zhang Notes: 762*13af1a74SHong Zhang TSComputeRHSHessianProductFunction3() is typically used for sensitivity implementation, 763*13af1a74SHong Zhang so most users would not generally call this routine themselves. 764*13af1a74SHong Zhang 765*13af1a74SHong Zhang Level: developer 766*13af1a74SHong Zhang 767*13af1a74SHong Zhang .keywords: TS, sensitivity 768*13af1a74SHong Zhang 769*13af1a74SHong Zhang .seealso: TSSetRHSHessianProduct() 770*13af1a74SHong Zhang @*/ 771*13af1a74SHong Zhang PetscErrorCode TSComputeRHSHessianProductFunction3(TS ts,PetscReal t,Vec U,Vec *Vl,Vec Vr,Vec *VHV) 772*13af1a74SHong Zhang { 773*13af1a74SHong Zhang PetscErrorCode ierr; 774*13af1a74SHong Zhang 775*13af1a74SHong Zhang PetscFunctionBegin; 776*13af1a74SHong Zhang if (!VHV) PetscFunctionReturn(0); 777*13af1a74SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 778*13af1a74SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 779*13af1a74SHong Zhang 780*13af1a74SHong Zhang PetscStackPush("TS user RHSHessianProduct function 3 for sensitivity analysis"); 781*13af1a74SHong Zhang ierr = (*ts->rhshessianproduct_gpu)(ts,t,U,Vl,Vr,VHV,ts->rhshessianproductctx);CHKERRQ(ierr); 782*13af1a74SHong Zhang PetscStackPop; 783*13af1a74SHong Zhang PetscFunctionReturn(0); 784*13af1a74SHong Zhang } 785*13af1a74SHong Zhang 786*13af1a74SHong Zhang /*@C 787*13af1a74SHong Zhang TSComputeRHSHessianProductFunction4 - Runs the user-defined vector-Hessian-vector product function for Gpp. 788*13af1a74SHong Zhang 789*13af1a74SHong Zhang Collective on TS 790*13af1a74SHong Zhang 791*13af1a74SHong Zhang Input Parameters: 792*13af1a74SHong Zhang . ts - The TS context obtained from TSCreate() 793*13af1a74SHong Zhang 794*13af1a74SHong Zhang Notes: 795*13af1a74SHong Zhang TSComputeRHSHessianProductFunction4() is typically used for sensitivity implementation, 796*13af1a74SHong Zhang so most users would not generally call this routine themselves. 797*13af1a74SHong Zhang 798*13af1a74SHong Zhang Level: developer 799*13af1a74SHong Zhang 800*13af1a74SHong Zhang .keywords: TS, sensitivity 801*13af1a74SHong Zhang 802*13af1a74SHong Zhang .seealso: TSSetRHSHessianProduct() 803*13af1a74SHong Zhang @*/ 804*13af1a74SHong Zhang PetscErrorCode TSComputeRHSHessianProductFunction4(TS ts,PetscReal t,Vec U,Vec *Vl,Vec Vr,Vec *VHV) 805*13af1a74SHong Zhang { 806*13af1a74SHong Zhang PetscErrorCode ierr; 807*13af1a74SHong Zhang 808*13af1a74SHong Zhang PetscFunctionBegin; 809*13af1a74SHong Zhang if (!VHV) PetscFunctionReturn(0); 810*13af1a74SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 811*13af1a74SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 812*13af1a74SHong Zhang 813*13af1a74SHong Zhang PetscStackPush("TS user RHSHessianProduct function 3 for sensitivity analysis"); 814*13af1a74SHong Zhang ierr = (*ts->rhshessianproduct_gpp)(ts,t,U,Vl,Vr,VHV,ts->rhshessianproductctx);CHKERRQ(ierr); 815*13af1a74SHong Zhang PetscStackPop; 816*13af1a74SHong Zhang PetscFunctionReturn(0); 817*13af1a74SHong Zhang } 818*13af1a74SHong Zhang 819814e85d6SHong Zhang /* --------------------------- Adjoint sensitivity ---------------------------*/ 820814e85d6SHong Zhang 821814e85d6SHong Zhang /*@ 822814e85d6SHong 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 823814e85d6SHong Zhang for use by the TSAdjoint routines. 824814e85d6SHong Zhang 825814e85d6SHong Zhang Logically Collective on TS and Vec 826814e85d6SHong Zhang 827814e85d6SHong Zhang Input Parameters: 828814e85d6SHong Zhang + ts - the TS context obtained from TSCreate() 829814e85d6SHong 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 830814e85d6SHong Zhang - mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 831814e85d6SHong Zhang 832814e85d6SHong Zhang Level: beginner 833814e85d6SHong Zhang 834814e85d6SHong Zhang Notes: 835814e85d6SHong Zhang the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime mu_i = df/dp|finaltime 836814e85d6SHong Zhang 837814e85d6SHong Zhang After TSAdjointSolve() is called the lamba and the mu contain the computed sensitivities 838814e85d6SHong Zhang 839814e85d6SHong Zhang .keywords: TS, timestep, set, sensitivity, initial values 840b5b4017aSHong Zhang 841b5b4017aSHong Zhang .seealso TSGetCostGradients() 842814e85d6SHong Zhang @*/ 843814e85d6SHong Zhang PetscErrorCode TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu) 844814e85d6SHong Zhang { 845814e85d6SHong Zhang PetscFunctionBegin; 846814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 847814e85d6SHong Zhang PetscValidPointer(lambda,2); 848814e85d6SHong Zhang ts->vecs_sensi = lambda; 849814e85d6SHong Zhang ts->vecs_sensip = mu; 850814e85d6SHong Zhang if (ts->numcost && ts->numcost!=numcost) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostIntegrand"); 851814e85d6SHong Zhang ts->numcost = numcost; 852814e85d6SHong Zhang PetscFunctionReturn(0); 853814e85d6SHong Zhang } 854814e85d6SHong Zhang 855814e85d6SHong Zhang /*@ 856814e85d6SHong Zhang TSGetCostGradients - Returns the gradients from the TSAdjointSolve() 857814e85d6SHong Zhang 858814e85d6SHong Zhang Not Collective, but Vec returned is parallel if TS is parallel 859814e85d6SHong Zhang 860814e85d6SHong Zhang Input Parameter: 861814e85d6SHong Zhang . ts - the TS context obtained from TSCreate() 862814e85d6SHong Zhang 863814e85d6SHong Zhang Output Parameter: 864814e85d6SHong Zhang + lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 865814e85d6SHong Zhang - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 866814e85d6SHong Zhang 867814e85d6SHong Zhang Level: intermediate 868814e85d6SHong Zhang 869814e85d6SHong Zhang .keywords: TS, timestep, get, sensitivity 870b5b4017aSHong Zhang 871b5b4017aSHong Zhang .seealso: TSSetCostGradients() 872814e85d6SHong Zhang @*/ 873814e85d6SHong Zhang PetscErrorCode TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu) 874814e85d6SHong Zhang { 875814e85d6SHong Zhang PetscFunctionBegin; 876814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 877814e85d6SHong Zhang if (numcost) *numcost = ts->numcost; 878814e85d6SHong Zhang if (lambda) *lambda = ts->vecs_sensi; 879814e85d6SHong Zhang if (mu) *mu = ts->vecs_sensip; 880814e85d6SHong Zhang PetscFunctionReturn(0); 881814e85d6SHong Zhang } 882814e85d6SHong Zhang 883814e85d6SHong Zhang /*@ 884b5b4017aSHong 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 885b5b4017aSHong Zhang for use by the TSAdjoint routines. 886b5b4017aSHong Zhang 887b5b4017aSHong Zhang Logically Collective on TS and Vec 888b5b4017aSHong Zhang 889b5b4017aSHong Zhang Input Parameters: 890b5b4017aSHong Zhang + ts - the TS context obtained from TSCreate() 891b5b4017aSHong Zhang . numcost - number of cost functions 892b5b4017aSHong 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 893b5b4017aSHong 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 894b5b4017aSHong Zhang - dir - the direction vector that are multiplied with the Hessian of the cost functions 895b5b4017aSHong Zhang 896b5b4017aSHong Zhang Level: beginner 897b5b4017aSHong Zhang 898b5b4017aSHong Zhang Notes: Hessian of the cost function is completely different from Hessian of the ODE/DAE system 899b5b4017aSHong Zhang 900b5b4017aSHong Zhang For second-order adjoint, one needs to call this function and then TSAdjointInitializeForward() before TSSolve(). 901b5b4017aSHong Zhang 902b5b4017aSHong Zhang After TSAdjointSolve() is called, the lamba2 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. 903b5b4017aSHong Zhang 9043fca9621SHong Zhang Passing NULL for lambda2 disables the second-order calculation. 905b5b4017aSHong Zhang .keywords: TS, sensitivity, second-order adjoint 906b5b4017aSHong Zhang 907b5b4017aSHong Zhang .seealso: TSAdjointInitializeForward() 908b5b4017aSHong Zhang @*/ 909b5b4017aSHong Zhang PetscErrorCode TSSetCostHessianProducts(TS ts,PetscInt numcost,Vec *lambda2,Vec *mu2,Vec dir) 910b5b4017aSHong Zhang { 911b5b4017aSHong Zhang PetscFunctionBegin; 912b5b4017aSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 913b5b4017aSHong Zhang if (ts->numcost && ts->numcost!=numcost) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostIntegrand"); 914b5b4017aSHong Zhang ts->numcost = numcost; 915b5b4017aSHong Zhang ts->vecs_sensi2 = lambda2; 91633f72c5dSHong Zhang ts->vecs_sensi2p = mu2; 917b5b4017aSHong Zhang ts->vec_dir = dir; 918b5b4017aSHong Zhang PetscFunctionReturn(0); 919b5b4017aSHong Zhang } 920b5b4017aSHong Zhang 921b5b4017aSHong Zhang /*@ 922b5b4017aSHong Zhang TSGetCostHessianProducts - Returns the gradients from the TSAdjointSolve() 923b5b4017aSHong Zhang 924b5b4017aSHong Zhang Not Collective, but Vec returned is parallel if TS is parallel 925b5b4017aSHong Zhang 926b5b4017aSHong Zhang Input Parameter: 927b5b4017aSHong Zhang . ts - the TS context obtained from TSCreate() 928b5b4017aSHong Zhang 929b5b4017aSHong Zhang Output Parameter: 930b5b4017aSHong Zhang + numcost - number of cost functions 931b5b4017aSHong 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 932b5b4017aSHong 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 933b5b4017aSHong Zhang - dir - the direction vector that are multiplied with the Hessian of the cost functions 934b5b4017aSHong Zhang 935b5b4017aSHong Zhang Level: intermediate 936b5b4017aSHong Zhang 937b5b4017aSHong Zhang .keywords: TS, sensitivity, second-order adjoint 938b5b4017aSHong Zhang 939b5b4017aSHong Zhang .seealso: TSSetCostHessianProducts() 940b5b4017aSHong Zhang @*/ 941b5b4017aSHong Zhang PetscErrorCode TSGetCostHessianProducts(TS ts,PetscInt *numcost,Vec **lambda2,Vec **mu2, Vec *dir) 942b5b4017aSHong Zhang { 943b5b4017aSHong Zhang PetscFunctionBegin; 944b5b4017aSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 945b5b4017aSHong Zhang if (numcost) *numcost = ts->numcost; 946b5b4017aSHong Zhang if (lambda2) *lambda2 = ts->vecs_sensi2; 94733f72c5dSHong Zhang if (mu2) *mu2 = ts->vecs_sensi2p; 948b5b4017aSHong Zhang if (dir) *dir = ts->vec_dir; 949b5b4017aSHong Zhang PetscFunctionReturn(0); 950b5b4017aSHong Zhang } 951b5b4017aSHong Zhang 952b5b4017aSHong Zhang /*@ 953b5b4017aSHong Zhang TSAdjointInitializeForward - Trigger the tangent linear solver and initialize the forward sensitivities 954b5b4017aSHong Zhang 955b5b4017aSHong Zhang Logically Collective on TS and Mat 956b5b4017aSHong Zhang 957b5b4017aSHong Zhang Input Parameters: 958b5b4017aSHong Zhang + ts - the TS context obtained from TSCreate() 959b5b4017aSHong Zhang - didp - the derivative of initial values w.r.t. parameters 960b5b4017aSHong Zhang 961b5b4017aSHong Zhang Level: intermediate 962b5b4017aSHong Zhang 963b5b4017aSHong Zhang Notes: When computing sensitivies w.r.t. initial condition, set didp to NULL so that the solver will take it as an identity matrix mathematically. 964b5b4017aSHong Zhang 965b5b4017aSHong Zhang .keywords: TS, sensitivity, second-order adjoint 966b5b4017aSHong Zhang 967b5b4017aSHong Zhang .seealso: TSSetCostHessianProducts() 968b5b4017aSHong Zhang @*/ 969b5b4017aSHong Zhang PetscErrorCode TSAdjointInitializeForward(TS ts,Mat didp) 970b5b4017aSHong Zhang { 97133f72c5dSHong Zhang Mat A; 97233f72c5dSHong Zhang Vec sp; 97333f72c5dSHong Zhang PetscScalar *xarr; 97433f72c5dSHong Zhang PetscInt lsize; 975b5b4017aSHong Zhang PetscErrorCode ierr; 976b5b4017aSHong Zhang 977b5b4017aSHong Zhang PetscFunctionBegin; 978b5b4017aSHong Zhang ts->forward_solve = PETSC_TRUE; /* turn on tangent linear mode */ 979b5b4017aSHong Zhang if (!ts->vecs_sensi2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetCostHessianProducts() first"); 98033f72c5dSHong Zhang if (!ts->vec_dir) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Directional vector is missing. Call TSSetCostHessianProducts() to set it."); 98133f72c5dSHong Zhang /* create a single-column dense matrix */ 98233f72c5dSHong Zhang ierr = VecGetLocalSize(ts->vec_sol,&lsize);CHKERRQ(ierr); 98333f72c5dSHong Zhang ierr = MatCreateDense(PETSC_COMM_WORLD,lsize,PETSC_DECIDE,PETSC_DECIDE,1,NULL,&A);CHKERRQ(ierr); 98433f72c5dSHong Zhang 98533f72c5dSHong Zhang ierr = VecDuplicate(ts->vec_sol,&sp);CHKERRQ(ierr); 98633f72c5dSHong Zhang ierr = MatDenseGetColumn(A,0,&xarr);CHKERRQ(ierr); 98733f72c5dSHong Zhang ierr = VecPlaceArray(sp,xarr);CHKERRQ(ierr); 98833f72c5dSHong Zhang if (ts->vecs_sensi2p) { /* TLM variable initialized as 2*dIdP*dir */ 98933f72c5dSHong Zhang if (didp) { 99033f72c5dSHong Zhang ierr = MatMult(didp,ts->vec_dir,sp);CHKERRQ(ierr); 99133f72c5dSHong Zhang ierr = VecScale(sp,2.);CHKERRQ(ierr); 99233f72c5dSHong Zhang } else { 99333f72c5dSHong Zhang ierr = VecZeroEntries(sp);CHKERRQ(ierr); 99433f72c5dSHong Zhang } 99533f72c5dSHong Zhang } else { /* TLM variable initialized as dir */ 99633f72c5dSHong Zhang ierr = VecCopy(ts->vec_dir,sp);CHKERRQ(ierr); 99733f72c5dSHong Zhang } 99833f72c5dSHong Zhang ierr = VecResetArray(sp);CHKERRQ(ierr); 99933f72c5dSHong Zhang ierr = MatDenseRestoreColumn(A,&xarr);CHKERRQ(ierr); 100033f72c5dSHong Zhang ierr = VecDestroy(&sp);CHKERRQ(ierr); 100133f72c5dSHong Zhang 100233f72c5dSHong Zhang ierr = TSForwardSetInitialSensitivities(ts,A);CHKERRQ(ierr); /* if didp is NULL, identity matrix is assumed */ 100333f72c5dSHong Zhang 100433f72c5dSHong Zhang ierr = MatDestroy(&A);CHKERRQ(ierr); 1005b5b4017aSHong Zhang PetscFunctionReturn(0); 1006b5b4017aSHong Zhang } 1007b5b4017aSHong Zhang 1008b5b4017aSHong Zhang /*@ 1009814e85d6SHong Zhang TSAdjointSetUp - Sets up the internal data structures for the later use 1010814e85d6SHong Zhang of an adjoint solver 1011814e85d6SHong Zhang 1012814e85d6SHong Zhang Collective on TS 1013814e85d6SHong Zhang 1014814e85d6SHong Zhang Input Parameter: 1015814e85d6SHong Zhang . ts - the TS context obtained from TSCreate() 1016814e85d6SHong Zhang 1017814e85d6SHong Zhang Level: advanced 1018814e85d6SHong Zhang 1019814e85d6SHong Zhang .keywords: TS, timestep, setup 1020814e85d6SHong Zhang 1021814e85d6SHong Zhang .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients() 1022814e85d6SHong Zhang @*/ 1023814e85d6SHong Zhang PetscErrorCode TSAdjointSetUp(TS ts) 1024814e85d6SHong Zhang { 1025814e85d6SHong Zhang PetscErrorCode ierr; 1026814e85d6SHong Zhang 1027814e85d6SHong Zhang PetscFunctionBegin; 1028814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1029814e85d6SHong Zhang if (ts->adjointsetupcalled) PetscFunctionReturn(0); 1030814e85d6SHong Zhang if (!ts->vecs_sensi) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first"); 103133f72c5dSHong Zhang if (ts->vecs_sensip && !ts->Jacp && !ts->Jacprhs) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetRHSJacobianP() or TSSetIJacobianP() first"); 103233f72c5dSHong Zhang 103333f72c5dSHong Zhang if (!ts->Jacp && ts->Jacprhs) ts->Jacp = ts->Jacprhs; 1034814e85d6SHong Zhang 1035814e85d6SHong Zhang if (ts->vec_costintegral) { /* if there is integral in the cost function */ 1036c9ad9de0SHong Zhang ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdu);CHKERRQ(ierr); 1037814e85d6SHong Zhang if (ts->vecs_sensip){ 1038814e85d6SHong Zhang ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 1039814e85d6SHong Zhang } 1040814e85d6SHong Zhang } 1041814e85d6SHong Zhang 1042814e85d6SHong Zhang if (ts->ops->adjointsetup) { 1043814e85d6SHong Zhang ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr); 1044814e85d6SHong Zhang } 1045814e85d6SHong Zhang ts->adjointsetupcalled = PETSC_TRUE; 1046814e85d6SHong Zhang PetscFunctionReturn(0); 1047814e85d6SHong Zhang } 1048814e85d6SHong Zhang 1049814e85d6SHong Zhang /*@ 1050ece46509SHong Zhang TSAdjointReset - Resets a TSAdjoint context and removes any allocated Vecs and Mats. 1051ece46509SHong Zhang 1052ece46509SHong Zhang Collective on TS 1053ece46509SHong Zhang 1054ece46509SHong Zhang Input Parameter: 1055ece46509SHong Zhang . ts - the TS context obtained from TSCreate() 1056ece46509SHong Zhang 1057ece46509SHong Zhang Level: beginner 1058ece46509SHong Zhang 1059ece46509SHong Zhang .keywords: TS, timestep, reset 1060ece46509SHong Zhang 1061ece46509SHong Zhang .seealso: TSCreate(), TSAdjointSetup(), TSADestroy() 1062ece46509SHong Zhang @*/ 1063ece46509SHong Zhang PetscErrorCode TSAdjointReset(TS ts) 1064ece46509SHong Zhang { 1065ece46509SHong Zhang PetscErrorCode ierr; 1066ece46509SHong Zhang 1067ece46509SHong Zhang PetscFunctionBegin; 1068ece46509SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1069ece46509SHong Zhang if (ts->ops->adjointreset) { 1070ece46509SHong Zhang ierr = (*ts->ops->adjointreset)(ts);CHKERRQ(ierr); 1071ece46509SHong Zhang } 1072cda2db4bSHong Zhang if (ts->vec_dir) { /* second-order adjoint */ 1073cda2db4bSHong Zhang ierr = TSForwardReset(ts);CHKERRQ(ierr); 1074cda2db4bSHong Zhang } 1075ece46509SHong Zhang ts->vecs_sensi = NULL; 1076ece46509SHong Zhang ts->vecs_sensip = NULL; 1077ece46509SHong Zhang ts->vecs_sensi2 = NULL; 107833f72c5dSHong Zhang ts->vecs_sensi2p = NULL; 1079ece46509SHong Zhang ts->vec_dir = NULL; 1080ece46509SHong Zhang ts->adjointsetupcalled = PETSC_FALSE; 1081ece46509SHong Zhang PetscFunctionReturn(0); 1082ece46509SHong Zhang } 1083ece46509SHong Zhang 1084ece46509SHong Zhang /*@ 1085814e85d6SHong Zhang TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time 1086814e85d6SHong Zhang 1087814e85d6SHong Zhang Logically Collective on TS 1088814e85d6SHong Zhang 1089814e85d6SHong Zhang Input Parameters: 1090814e85d6SHong Zhang + ts - the TS context obtained from TSCreate() 1091814e85d6SHong Zhang . steps - number of steps to use 1092814e85d6SHong Zhang 1093814e85d6SHong Zhang Level: intermediate 1094814e85d6SHong Zhang 1095814e85d6SHong Zhang Notes: 1096814e85d6SHong Zhang Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this 1097814e85d6SHong Zhang so as to integrate back to less than the original timestep 1098814e85d6SHong Zhang 1099814e85d6SHong Zhang .keywords: TS, timestep, set, maximum, iterations 1100814e85d6SHong Zhang 1101814e85d6SHong Zhang .seealso: TSSetExactFinalTime() 1102814e85d6SHong Zhang @*/ 1103814e85d6SHong Zhang PetscErrorCode TSAdjointSetSteps(TS ts,PetscInt steps) 1104814e85d6SHong Zhang { 1105814e85d6SHong Zhang PetscFunctionBegin; 1106814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1107814e85d6SHong Zhang PetscValidLogicalCollectiveInt(ts,steps,2); 1108814e85d6SHong Zhang if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps"); 1109814e85d6SHong Zhang if (steps > ts->steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps"); 1110814e85d6SHong Zhang ts->adjoint_max_steps = steps; 1111814e85d6SHong Zhang PetscFunctionReturn(0); 1112814e85d6SHong Zhang } 1113814e85d6SHong Zhang 1114814e85d6SHong Zhang /*@C 1115814e85d6SHong Zhang TSAdjointSetRHSJacobian - Deprecated, use TSSetRHSJacobianP() 1116814e85d6SHong Zhang 1117814e85d6SHong Zhang Level: deprecated 1118814e85d6SHong Zhang 1119814e85d6SHong Zhang @*/ 1120814e85d6SHong Zhang PetscErrorCode TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 1121814e85d6SHong Zhang { 1122814e85d6SHong Zhang PetscErrorCode ierr; 1123814e85d6SHong Zhang 1124814e85d6SHong Zhang PetscFunctionBegin; 1125814e85d6SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1126814e85d6SHong Zhang PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1127814e85d6SHong Zhang 1128814e85d6SHong Zhang ts->rhsjacobianp = func; 1129814e85d6SHong Zhang ts->rhsjacobianpctx = ctx; 1130814e85d6SHong Zhang if(Amat) { 1131814e85d6SHong Zhang ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 1132814e85d6SHong Zhang ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 1133814e85d6SHong Zhang ts->Jacp = Amat; 1134814e85d6SHong Zhang } 1135814e85d6SHong Zhang PetscFunctionReturn(0); 1136814e85d6SHong Zhang } 1137814e85d6SHong Zhang 1138814e85d6SHong Zhang /*@C 1139814e85d6SHong Zhang TSAdjointComputeRHSJacobian - Deprecated, use TSComputeRHSJacobianP() 1140814e85d6SHong Zhang 1141814e85d6SHong Zhang Level: deprecated 1142814e85d6SHong Zhang 1143814e85d6SHong Zhang @*/ 1144c9ad9de0SHong Zhang PetscErrorCode TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat Amat) 1145814e85d6SHong Zhang { 1146814e85d6SHong Zhang PetscErrorCode ierr; 1147814e85d6SHong Zhang 1148814e85d6SHong Zhang PetscFunctionBegin; 1149814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1150c9ad9de0SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1151814e85d6SHong Zhang PetscValidPointer(Amat,4); 1152814e85d6SHong Zhang 1153814e85d6SHong Zhang PetscStackPush("TS user JacobianP function for sensitivity analysis"); 1154c9ad9de0SHong Zhang ierr = (*ts->rhsjacobianp)(ts,t,U,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr); 1155814e85d6SHong Zhang PetscStackPop; 1156814e85d6SHong Zhang PetscFunctionReturn(0); 1157814e85d6SHong Zhang } 1158814e85d6SHong Zhang 1159814e85d6SHong Zhang /*@ 1160c9ad9de0SHong Zhang TSAdjointComputeDRDYFunction - Deprecated, use TSComputeDRDUFunction() 1161814e85d6SHong Zhang 1162814e85d6SHong Zhang Level: deprecated 1163814e85d6SHong Zhang 1164814e85d6SHong Zhang @*/ 1165c9ad9de0SHong Zhang PetscErrorCode TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec U,Vec *DRDU) 1166814e85d6SHong Zhang { 1167814e85d6SHong Zhang PetscErrorCode ierr; 1168814e85d6SHong Zhang 1169814e85d6SHong Zhang PetscFunctionBegin; 1170814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1171c9ad9de0SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1172814e85d6SHong Zhang 1173814e85d6SHong Zhang PetscStackPush("TS user DRDY function for sensitivity analysis"); 1174c9ad9de0SHong Zhang ierr = (*ts->drdufunction)(ts,t,U,DRDU,ts->costintegrandctx); CHKERRQ(ierr); 1175814e85d6SHong Zhang PetscStackPop; 1176814e85d6SHong Zhang PetscFunctionReturn(0); 1177814e85d6SHong Zhang } 1178814e85d6SHong Zhang 1179814e85d6SHong Zhang /*@ 1180814e85d6SHong Zhang TSAdjointComputeDRDPFunction - Deprecated, use TSComputeDRDPFunction() 1181814e85d6SHong Zhang 1182814e85d6SHong Zhang Level: deprecated 1183814e85d6SHong Zhang 1184814e85d6SHong Zhang @*/ 1185c9ad9de0SHong Zhang PetscErrorCode TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec U,Vec *DRDP) 1186814e85d6SHong Zhang { 1187814e85d6SHong Zhang PetscErrorCode ierr; 1188814e85d6SHong Zhang 1189814e85d6SHong Zhang PetscFunctionBegin; 1190814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1191c9ad9de0SHong Zhang PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1192814e85d6SHong Zhang 1193814e85d6SHong Zhang PetscStackPush("TS user DRDP function for sensitivity analysis"); 1194c9ad9de0SHong Zhang ierr = (*ts->drdpfunction)(ts,t,U,DRDP,ts->costintegrandctx); CHKERRQ(ierr); 1195814e85d6SHong Zhang PetscStackPop; 1196814e85d6SHong Zhang PetscFunctionReturn(0); 1197814e85d6SHong Zhang } 1198814e85d6SHong Zhang 1199814e85d6SHong Zhang /*@C 1200814e85d6SHong Zhang TSAdjointMonitorSensi - monitors the first lambda sensitivity 1201814e85d6SHong Zhang 1202814e85d6SHong Zhang Level: intermediate 1203814e85d6SHong Zhang 1204814e85d6SHong Zhang .keywords: TS, set, monitor 1205814e85d6SHong Zhang 1206814e85d6SHong Zhang .seealso: TSAdjointMonitorSet() 1207814e85d6SHong Zhang @*/ 1208814e85d6SHong Zhang PetscErrorCode TSAdjointMonitorSensi(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf) 1209814e85d6SHong Zhang { 1210814e85d6SHong Zhang PetscErrorCode ierr; 1211814e85d6SHong Zhang PetscViewer viewer = vf->viewer; 1212814e85d6SHong Zhang 1213814e85d6SHong Zhang PetscFunctionBegin; 1214814e85d6SHong Zhang PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 1215814e85d6SHong Zhang ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 1216814e85d6SHong Zhang ierr = VecView(lambda[0],viewer);CHKERRQ(ierr); 1217814e85d6SHong Zhang ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 1218814e85d6SHong Zhang PetscFunctionReturn(0); 1219814e85d6SHong Zhang } 1220814e85d6SHong Zhang 1221814e85d6SHong Zhang /*@C 1222814e85d6SHong Zhang TSAdjointMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 1223814e85d6SHong Zhang 1224814e85d6SHong Zhang Collective on TS 1225814e85d6SHong Zhang 1226814e85d6SHong Zhang Input Parameters: 1227814e85d6SHong Zhang + ts - TS object you wish to monitor 1228814e85d6SHong Zhang . name - the monitor type one is seeking 1229814e85d6SHong Zhang . help - message indicating what monitoring is done 1230814e85d6SHong Zhang . manual - manual page for the monitor 1231814e85d6SHong Zhang . monitor - the monitor function 1232814e85d6SHong Zhang - 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 1233814e85d6SHong Zhang 1234814e85d6SHong Zhang Level: developer 1235814e85d6SHong Zhang 1236814e85d6SHong Zhang .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 1237814e85d6SHong Zhang PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 1238814e85d6SHong Zhang PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 1239814e85d6SHong Zhang PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 1240814e85d6SHong Zhang PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 1241814e85d6SHong Zhang PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 1242814e85d6SHong Zhang PetscOptionsFList(), PetscOptionsEList() 1243814e85d6SHong Zhang @*/ 1244814e85d6SHong Zhang 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*)) 1245814e85d6SHong Zhang { 1246814e85d6SHong Zhang PetscErrorCode ierr; 1247814e85d6SHong Zhang PetscViewer viewer; 1248814e85d6SHong Zhang PetscViewerFormat format; 1249814e85d6SHong Zhang PetscBool flg; 1250814e85d6SHong Zhang 1251814e85d6SHong Zhang PetscFunctionBegin; 125216413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 1253814e85d6SHong Zhang if (flg) { 1254814e85d6SHong Zhang PetscViewerAndFormat *vf; 1255814e85d6SHong Zhang ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 1256814e85d6SHong Zhang ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 1257814e85d6SHong Zhang if (monitorsetup) { 1258814e85d6SHong Zhang ierr = (*monitorsetup)(ts,vf);CHKERRQ(ierr); 1259814e85d6SHong Zhang } 1260814e85d6SHong Zhang ierr = TSAdjointMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 1261814e85d6SHong Zhang } 1262814e85d6SHong Zhang PetscFunctionReturn(0); 1263814e85d6SHong Zhang } 1264814e85d6SHong Zhang 1265814e85d6SHong Zhang /*@C 1266814e85d6SHong Zhang TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every 1267814e85d6SHong Zhang timestep to display the iteration's progress. 1268814e85d6SHong Zhang 1269814e85d6SHong Zhang Logically Collective on TS 1270814e85d6SHong Zhang 1271814e85d6SHong Zhang Input Parameters: 1272814e85d6SHong Zhang + ts - the TS context obtained from TSCreate() 1273814e85d6SHong Zhang . adjointmonitor - monitoring routine 1274814e85d6SHong Zhang . adjointmctx - [optional] user-defined context for private data for the 1275814e85d6SHong Zhang monitor routine (use NULL if no context is desired) 1276814e85d6SHong Zhang - adjointmonitordestroy - [optional] routine that frees monitor context 1277814e85d6SHong Zhang (may be NULL) 1278814e85d6SHong Zhang 1279814e85d6SHong Zhang Calling sequence of monitor: 1280814e85d6SHong Zhang $ int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx) 1281814e85d6SHong Zhang 1282814e85d6SHong Zhang + ts - the TS context 1283814e85d6SHong Zhang . steps - iteration number (after the final time step the monitor routine is called with a step of -1, this is at the final time which may have 1284814e85d6SHong Zhang been interpolated to) 1285814e85d6SHong Zhang . time - current time 1286814e85d6SHong Zhang . u - current iterate 1287814e85d6SHong Zhang . numcost - number of cost functionos 1288814e85d6SHong Zhang . lambda - sensitivities to initial conditions 1289814e85d6SHong Zhang . mu - sensitivities to parameters 1290814e85d6SHong Zhang - adjointmctx - [optional] adjoint monitoring context 1291814e85d6SHong Zhang 1292814e85d6SHong Zhang Notes: 1293814e85d6SHong Zhang This routine adds an additional monitor to the list of monitors that 1294814e85d6SHong Zhang already has been loaded. 1295814e85d6SHong Zhang 1296814e85d6SHong Zhang Fortran Notes: 1297814e85d6SHong Zhang Only a single monitor function can be set for each TS object 1298814e85d6SHong Zhang 1299814e85d6SHong Zhang Level: intermediate 1300814e85d6SHong Zhang 1301814e85d6SHong Zhang .keywords: TS, timestep, set, adjoint, monitor 1302814e85d6SHong Zhang 1303814e85d6SHong Zhang .seealso: TSAdjointMonitorCancel() 1304814e85d6SHong Zhang @*/ 1305814e85d6SHong Zhang PetscErrorCode TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**)) 1306814e85d6SHong Zhang { 1307814e85d6SHong Zhang PetscErrorCode ierr; 1308814e85d6SHong Zhang PetscInt i; 1309814e85d6SHong Zhang PetscBool identical; 1310814e85d6SHong Zhang 1311814e85d6SHong Zhang PetscFunctionBegin; 1312814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1313814e85d6SHong Zhang for (i=0; i<ts->numbermonitors;i++) { 1314814e85d6SHong Zhang ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr); 1315814e85d6SHong Zhang if (identical) PetscFunctionReturn(0); 1316814e85d6SHong Zhang } 1317814e85d6SHong Zhang if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set"); 1318814e85d6SHong Zhang ts->adjointmonitor[ts->numberadjointmonitors] = adjointmonitor; 1319814e85d6SHong Zhang ts->adjointmonitordestroy[ts->numberadjointmonitors] = adjointmdestroy; 1320814e85d6SHong Zhang ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx; 1321814e85d6SHong Zhang PetscFunctionReturn(0); 1322814e85d6SHong Zhang } 1323814e85d6SHong Zhang 1324814e85d6SHong Zhang /*@C 1325814e85d6SHong Zhang TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object. 1326814e85d6SHong Zhang 1327814e85d6SHong Zhang Logically Collective on TS 1328814e85d6SHong Zhang 1329814e85d6SHong Zhang Input Parameters: 1330814e85d6SHong Zhang . ts - the TS context obtained from TSCreate() 1331814e85d6SHong Zhang 1332814e85d6SHong Zhang Notes: 1333814e85d6SHong Zhang There is no way to remove a single, specific monitor. 1334814e85d6SHong Zhang 1335814e85d6SHong Zhang Level: intermediate 1336814e85d6SHong Zhang 1337814e85d6SHong Zhang .keywords: TS, timestep, set, adjoint, monitor 1338814e85d6SHong Zhang 1339814e85d6SHong Zhang .seealso: TSAdjointMonitorSet() 1340814e85d6SHong Zhang @*/ 1341814e85d6SHong Zhang PetscErrorCode TSAdjointMonitorCancel(TS ts) 1342814e85d6SHong Zhang { 1343814e85d6SHong Zhang PetscErrorCode ierr; 1344814e85d6SHong Zhang PetscInt i; 1345814e85d6SHong Zhang 1346814e85d6SHong Zhang PetscFunctionBegin; 1347814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1348814e85d6SHong Zhang for (i=0; i<ts->numberadjointmonitors; i++) { 1349814e85d6SHong Zhang if (ts->adjointmonitordestroy[i]) { 1350814e85d6SHong Zhang ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 1351814e85d6SHong Zhang } 1352814e85d6SHong Zhang } 1353814e85d6SHong Zhang ts->numberadjointmonitors = 0; 1354814e85d6SHong Zhang PetscFunctionReturn(0); 1355814e85d6SHong Zhang } 1356814e85d6SHong Zhang 1357814e85d6SHong Zhang /*@C 1358814e85d6SHong Zhang TSAdjointMonitorDefault - the default monitor of adjoint computations 1359814e85d6SHong Zhang 1360814e85d6SHong Zhang Level: intermediate 1361814e85d6SHong Zhang 1362814e85d6SHong Zhang .keywords: TS, set, monitor 1363814e85d6SHong Zhang 1364814e85d6SHong Zhang .seealso: TSAdjointMonitorSet() 1365814e85d6SHong Zhang @*/ 1366814e85d6SHong Zhang PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf) 1367814e85d6SHong Zhang { 1368814e85d6SHong Zhang PetscErrorCode ierr; 1369814e85d6SHong Zhang PetscViewer viewer = vf->viewer; 1370814e85d6SHong Zhang 1371814e85d6SHong Zhang PetscFunctionBegin; 1372814e85d6SHong Zhang PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 1373814e85d6SHong Zhang ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 1374814e85d6SHong Zhang ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1375814e85d6SHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 1376814e85d6SHong Zhang ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1377814e85d6SHong Zhang ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 1378814e85d6SHong Zhang PetscFunctionReturn(0); 1379814e85d6SHong Zhang } 1380814e85d6SHong Zhang 1381814e85d6SHong Zhang /*@C 1382814e85d6SHong Zhang TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling 1383814e85d6SHong Zhang VecView() for the sensitivities to initial states at each timestep 1384814e85d6SHong Zhang 1385814e85d6SHong Zhang Collective on TS 1386814e85d6SHong Zhang 1387814e85d6SHong Zhang Input Parameters: 1388814e85d6SHong Zhang + ts - the TS context 1389814e85d6SHong Zhang . step - current time-step 1390814e85d6SHong Zhang . ptime - current time 1391814e85d6SHong Zhang . u - current state 1392814e85d6SHong Zhang . numcost - number of cost functions 1393814e85d6SHong Zhang . lambda - sensitivities to initial conditions 1394814e85d6SHong Zhang . mu - sensitivities to parameters 1395814e85d6SHong Zhang - dummy - either a viewer or NULL 1396814e85d6SHong Zhang 1397814e85d6SHong Zhang Level: intermediate 1398814e85d6SHong Zhang 1399814e85d6SHong Zhang .keywords: TS, vector, adjoint, monitor, view 1400814e85d6SHong Zhang 1401814e85d6SHong Zhang .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView() 1402814e85d6SHong Zhang @*/ 1403814e85d6SHong Zhang PetscErrorCode TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy) 1404814e85d6SHong Zhang { 1405814e85d6SHong Zhang PetscErrorCode ierr; 1406814e85d6SHong Zhang TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 1407814e85d6SHong Zhang PetscDraw draw; 1408814e85d6SHong Zhang PetscReal xl,yl,xr,yr,h; 1409814e85d6SHong Zhang char time[32]; 1410814e85d6SHong Zhang 1411814e85d6SHong Zhang PetscFunctionBegin; 1412814e85d6SHong Zhang if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 1413814e85d6SHong Zhang 1414814e85d6SHong Zhang ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr); 1415814e85d6SHong Zhang ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 1416814e85d6SHong Zhang ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 1417814e85d6SHong Zhang ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1418814e85d6SHong Zhang h = yl + .95*(yr - yl); 1419814e85d6SHong Zhang ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 1420814e85d6SHong Zhang ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1421814e85d6SHong Zhang PetscFunctionReturn(0); 1422814e85d6SHong Zhang } 1423814e85d6SHong Zhang 1424814e85d6SHong Zhang /* 1425814e85d6SHong Zhang TSAdjointSetFromOptions - Sets various TSAdjoint parameters from user options. 1426814e85d6SHong Zhang 1427814e85d6SHong Zhang Collective on TSAdjoint 1428814e85d6SHong Zhang 1429814e85d6SHong Zhang Input Parameter: 1430814e85d6SHong Zhang . ts - the TS context 1431814e85d6SHong Zhang 1432814e85d6SHong Zhang Options Database Keys: 1433814e85d6SHong Zhang + -ts_adjoint_solve <yes,no> After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory) 1434814e85d6SHong Zhang . -ts_adjoint_monitor - print information at each adjoint time step 1435814e85d6SHong Zhang - -ts_adjoint_monitor_draw_sensi - monitor the sensitivity of the first cost function wrt initial conditions (lambda[0]) graphically 1436814e85d6SHong Zhang 1437814e85d6SHong Zhang Level: developer 1438814e85d6SHong Zhang 1439814e85d6SHong Zhang Notes: 1440814e85d6SHong Zhang This is not normally called directly by users 1441814e85d6SHong Zhang 1442814e85d6SHong Zhang .keywords: TS, trajectory, timestep, set, options, database 1443814e85d6SHong Zhang 1444814e85d6SHong Zhang .seealso: TSSetSaveTrajectory(), TSTrajectorySetUp() 1445814e85d6SHong Zhang */ 1446814e85d6SHong Zhang PetscErrorCode TSAdjointSetFromOptions(PetscOptionItems *PetscOptionsObject,TS ts) 1447814e85d6SHong Zhang { 1448814e85d6SHong Zhang PetscBool tflg,opt; 1449814e85d6SHong Zhang PetscErrorCode ierr; 1450814e85d6SHong Zhang 1451814e85d6SHong Zhang PetscFunctionBegin; 1452814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,2); 1453814e85d6SHong Zhang ierr = PetscOptionsHead(PetscOptionsObject,"TS Adjoint options");CHKERRQ(ierr); 1454814e85d6SHong Zhang tflg = ts->adjoint_solve ? PETSC_TRUE : PETSC_FALSE; 1455814e85d6SHong Zhang ierr = PetscOptionsBool("-ts_adjoint_solve","Solve the adjoint problem immediately after solving the forward problem","",tflg,&tflg,&opt);CHKERRQ(ierr); 1456814e85d6SHong Zhang if (opt) { 1457814e85d6SHong Zhang ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); 1458814e85d6SHong Zhang ts->adjoint_solve = tflg; 1459814e85d6SHong Zhang } 1460814e85d6SHong Zhang ierr = TSAdjointMonitorSetFromOptions(ts,"-ts_adjoint_monitor","Monitor adjoint timestep size","TSAdjointMonitorDefault",TSAdjointMonitorDefault,NULL);CHKERRQ(ierr); 1461814e85d6SHong Zhang ierr = TSAdjointMonitorSetFromOptions(ts,"-ts_adjoint_monitor_sensi","Monitor sensitivity in the adjoint computation","TSAdjointMonitorSensi",TSAdjointMonitorSensi,NULL);CHKERRQ(ierr); 1462814e85d6SHong Zhang opt = PETSC_FALSE; 1463814e85d6SHong Zhang ierr = PetscOptionsName("-ts_adjoint_monitor_draw_sensi","Monitor adjoint sensitivities (lambda only) graphically","TSAdjointMonitorDrawSensi",&opt);CHKERRQ(ierr); 1464814e85d6SHong Zhang if (opt) { 1465814e85d6SHong Zhang TSMonitorDrawCtx ctx; 1466814e85d6SHong Zhang PetscInt howoften = 1; 1467814e85d6SHong Zhang 1468814e85d6SHong Zhang ierr = PetscOptionsInt("-ts_adjoint_monitor_draw_sensi","Monitor adjoint sensitivities (lambda only) graphically","TSAdjointMonitorDrawSensi",howoften,&howoften,NULL);CHKERRQ(ierr); 1469814e85d6SHong Zhang ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 1470814e85d6SHong Zhang ierr = TSAdjointMonitorSet(ts,TSAdjointMonitorDrawSensi,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 1471814e85d6SHong Zhang } 1472814e85d6SHong Zhang PetscFunctionReturn(0); 1473814e85d6SHong Zhang } 1474814e85d6SHong Zhang 1475814e85d6SHong Zhang /*@ 1476814e85d6SHong Zhang TSAdjointStep - Steps one time step backward in the adjoint run 1477814e85d6SHong Zhang 1478814e85d6SHong Zhang Collective on TS 1479814e85d6SHong Zhang 1480814e85d6SHong Zhang Input Parameter: 1481814e85d6SHong Zhang . ts - the TS context obtained from TSCreate() 1482814e85d6SHong Zhang 1483814e85d6SHong Zhang Level: intermediate 1484814e85d6SHong Zhang 1485814e85d6SHong Zhang .keywords: TS, adjoint, step 1486814e85d6SHong Zhang 1487814e85d6SHong Zhang .seealso: TSAdjointSetUp(), TSAdjointSolve() 1488814e85d6SHong Zhang @*/ 1489814e85d6SHong Zhang PetscErrorCode TSAdjointStep(TS ts) 1490814e85d6SHong Zhang { 1491814e85d6SHong Zhang DM dm; 1492814e85d6SHong Zhang PetscErrorCode ierr; 1493814e85d6SHong Zhang 1494814e85d6SHong Zhang PetscFunctionBegin; 1495814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1496814e85d6SHong Zhang ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1497814e85d6SHong Zhang ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 1498814e85d6SHong Zhang 1499814e85d6SHong Zhang ts->reason = TS_CONVERGED_ITERATING; 1500814e85d6SHong Zhang ts->ptime_prev = ts->ptime; 1501814e85d6SHong Zhang if (!ts->ops->adjointstep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed because the adjoint of %s has not been implemented, try other time stepping methods for adjoint sensitivity analysis",((PetscObject)ts)->type_name); 1502814e85d6SHong Zhang ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 1503814e85d6SHong Zhang ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr); 1504814e85d6SHong Zhang ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 1505814e85d6SHong Zhang ts->adjoint_steps++; ts->steps--; 1506814e85d6SHong Zhang 1507814e85d6SHong Zhang if (ts->reason < 0) { 1508814e85d6SHong Zhang if (ts->errorifstepfailed) { 150905c9950eSHong Zhang if (ts->reason == TSADJOINT_DIVERGED_LINEAR_SOLVE) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSAdjointStep has failed due to %s",TSConvergedReasons[ts->reason]); 151005c9950eSHong Zhang else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSAdjointStep has failed due to %s",TSConvergedReasons[ts->reason]); 1511814e85d6SHong Zhang } 1512814e85d6SHong Zhang } else if (!ts->reason) { 1513814e85d6SHong Zhang if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 1514814e85d6SHong Zhang } 1515814e85d6SHong Zhang PetscFunctionReturn(0); 1516814e85d6SHong Zhang } 1517814e85d6SHong Zhang 1518814e85d6SHong Zhang /*@ 1519814e85d6SHong Zhang TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE 1520814e85d6SHong Zhang 1521814e85d6SHong Zhang Collective on TS 1522814e85d6SHong Zhang 1523814e85d6SHong Zhang Input Parameter: 1524814e85d6SHong Zhang . ts - the TS context obtained from TSCreate() 1525814e85d6SHong Zhang 1526814e85d6SHong Zhang Options Database: 1527814e85d6SHong Zhang . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial values 1528814e85d6SHong Zhang 1529814e85d6SHong Zhang Level: intermediate 1530814e85d6SHong Zhang 1531814e85d6SHong Zhang Notes: 1532814e85d6SHong Zhang This must be called after a call to TSSolve() that solves the forward problem 1533814e85d6SHong Zhang 1534814e85d6SHong Zhang By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time 1535814e85d6SHong Zhang 1536814e85d6SHong Zhang .keywords: TS, timestep, solve 1537814e85d6SHong Zhang 1538814e85d6SHong Zhang .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep() 1539814e85d6SHong Zhang @*/ 1540814e85d6SHong Zhang PetscErrorCode TSAdjointSolve(TS ts) 1541814e85d6SHong Zhang { 1542814e85d6SHong Zhang PetscErrorCode ierr; 1543814e85d6SHong Zhang 1544814e85d6SHong Zhang PetscFunctionBegin; 1545814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1546814e85d6SHong Zhang ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 1547814e85d6SHong Zhang 1548814e85d6SHong Zhang /* reset time step and iteration counters */ 1549814e85d6SHong Zhang ts->adjoint_steps = 0; 1550814e85d6SHong Zhang ts->ksp_its = 0; 1551814e85d6SHong Zhang ts->snes_its = 0; 1552814e85d6SHong Zhang ts->num_snes_failures = 0; 1553814e85d6SHong Zhang ts->reject = 0; 1554814e85d6SHong Zhang ts->reason = TS_CONVERGED_ITERATING; 1555814e85d6SHong Zhang 1556814e85d6SHong Zhang if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->steps; 1557814e85d6SHong Zhang if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 1558814e85d6SHong Zhang 1559814e85d6SHong Zhang while (!ts->reason) { 1560814e85d6SHong Zhang ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr); 1561814e85d6SHong Zhang ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 1562814e85d6SHong Zhang ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr); 1563814e85d6SHong Zhang ierr = TSAdjointStep(ts);CHKERRQ(ierr); 1564814e85d6SHong Zhang if (ts->vec_costintegral && !ts->costintegralfwd) { 1565814e85d6SHong Zhang ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr); 1566814e85d6SHong Zhang } 1567814e85d6SHong Zhang } 1568814e85d6SHong Zhang ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr); 1569814e85d6SHong Zhang ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 1570814e85d6SHong Zhang ts->solvetime = ts->ptime; 1571814e85d6SHong Zhang ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr); 1572814e85d6SHong Zhang ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr); 1573814e85d6SHong Zhang ts->adjoint_max_steps = 0; 1574814e85d6SHong Zhang PetscFunctionReturn(0); 1575814e85d6SHong Zhang } 1576814e85d6SHong Zhang 1577814e85d6SHong Zhang /*@C 1578814e85d6SHong Zhang TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet() 1579814e85d6SHong Zhang 1580814e85d6SHong Zhang Collective on TS 1581814e85d6SHong Zhang 1582814e85d6SHong Zhang Input Parameters: 1583814e85d6SHong Zhang + ts - time stepping context obtained from TSCreate() 1584814e85d6SHong Zhang . step - step number that has just completed 1585814e85d6SHong Zhang . ptime - model time of the state 1586814e85d6SHong Zhang . u - state at the current model time 1587814e85d6SHong Zhang . numcost - number of cost functions (dimension of lambda or mu) 1588814e85d6SHong Zhang . lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 1589814e85d6SHong Zhang - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 1590814e85d6SHong Zhang 1591814e85d6SHong Zhang Notes: 1592814e85d6SHong Zhang TSAdjointMonitor() is typically used automatically within the time stepping implementations. 1593814e85d6SHong Zhang Users would almost never call this routine directly. 1594814e85d6SHong Zhang 1595814e85d6SHong Zhang Level: developer 1596814e85d6SHong Zhang 1597814e85d6SHong Zhang .keywords: TS, timestep 1598814e85d6SHong Zhang @*/ 1599814e85d6SHong Zhang PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu) 1600814e85d6SHong Zhang { 1601814e85d6SHong Zhang PetscErrorCode ierr; 1602814e85d6SHong Zhang PetscInt i,n = ts->numberadjointmonitors; 1603814e85d6SHong Zhang 1604814e85d6SHong Zhang PetscFunctionBegin; 1605814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1606814e85d6SHong Zhang PetscValidHeaderSpecific(u,VEC_CLASSID,4); 16078860a134SJunchao Zhang ierr = VecLockReadPush(u);CHKERRQ(ierr); 1608814e85d6SHong Zhang for (i=0; i<n; i++) { 1609814e85d6SHong Zhang ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 1610814e85d6SHong Zhang } 16118860a134SJunchao Zhang ierr = VecLockReadPop(u);CHKERRQ(ierr); 1612814e85d6SHong Zhang PetscFunctionReturn(0); 1613814e85d6SHong Zhang } 1614814e85d6SHong Zhang 1615814e85d6SHong Zhang /*@ 1616814e85d6SHong Zhang TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run. 1617814e85d6SHong Zhang 1618814e85d6SHong Zhang Collective on TS 1619814e85d6SHong Zhang 1620814e85d6SHong Zhang Input Arguments: 1621814e85d6SHong Zhang . ts - time stepping context 1622814e85d6SHong Zhang 1623814e85d6SHong Zhang Level: advanced 1624814e85d6SHong Zhang 1625814e85d6SHong Zhang Notes: 1626814e85d6SHong Zhang This function cannot be called until TSAdjointStep() has been completed. 1627814e85d6SHong Zhang 1628814e85d6SHong Zhang .seealso: TSAdjointSolve(), TSAdjointStep 1629814e85d6SHong Zhang @*/ 1630814e85d6SHong Zhang PetscErrorCode TSAdjointCostIntegral(TS ts) 1631814e85d6SHong Zhang { 1632814e85d6SHong Zhang PetscErrorCode ierr; 1633814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1634814e85d6SHong Zhang if (!ts->ops->adjointintegral) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide integral evaluation in the adjoint run",((PetscObject)ts)->type_name); 1635814e85d6SHong Zhang ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr); 1636814e85d6SHong Zhang PetscFunctionReturn(0); 1637814e85d6SHong Zhang } 1638814e85d6SHong Zhang 1639814e85d6SHong Zhang /* ------------------ Forward (tangent linear) sensitivity ------------------*/ 1640814e85d6SHong Zhang 1641814e85d6SHong Zhang /*@ 1642814e85d6SHong Zhang TSForwardSetUp - Sets up the internal data structures for the later use 1643814e85d6SHong Zhang of forward sensitivity analysis 1644814e85d6SHong Zhang 1645814e85d6SHong Zhang Collective on TS 1646814e85d6SHong Zhang 1647814e85d6SHong Zhang Input Parameter: 1648814e85d6SHong Zhang . ts - the TS context obtained from TSCreate() 1649814e85d6SHong Zhang 1650814e85d6SHong Zhang Level: advanced 1651814e85d6SHong Zhang 1652814e85d6SHong Zhang .keywords: TS, forward sensitivity, setup 1653814e85d6SHong Zhang 1654814e85d6SHong Zhang .seealso: TSCreate(), TSDestroy(), TSSetUp() 1655814e85d6SHong Zhang @*/ 1656814e85d6SHong Zhang PetscErrorCode TSForwardSetUp(TS ts) 1657814e85d6SHong Zhang { 1658814e85d6SHong Zhang PetscErrorCode ierr; 1659814e85d6SHong Zhang 1660814e85d6SHong Zhang PetscFunctionBegin; 1661814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1662814e85d6SHong Zhang if (ts->forwardsetupcalled) PetscFunctionReturn(0); 1663814e85d6SHong Zhang if (ts->vec_costintegral && !ts->vecs_integral_sensip ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSForwardSetIntegralGradients() before TSSetCostIntegrand()"); 1664814e85d6SHong Zhang if (ts->vecs_integral_sensip) { 1665c9ad9de0SHong Zhang ierr = VecDuplicateVecs(ts->vec_sol,ts->numcost,&ts->vecs_drdu);CHKERRQ(ierr); 1666814e85d6SHong Zhang ierr = VecDuplicateVecs(ts->vecs_integral_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 1667814e85d6SHong Zhang } 166833f72c5dSHong Zhang if (!ts->Jacp && ts->Jacprhs) ts->Jacp = ts->Jacprhs; 1669814e85d6SHong Zhang 1670814e85d6SHong Zhang if (ts->ops->forwardsetup) { 1671814e85d6SHong Zhang ierr = (*ts->ops->forwardsetup)(ts);CHKERRQ(ierr); 1672814e85d6SHong Zhang } 1673814e85d6SHong Zhang ts->forwardsetupcalled = PETSC_TRUE; 1674814e85d6SHong Zhang PetscFunctionReturn(0); 1675814e85d6SHong Zhang } 1676814e85d6SHong Zhang 1677814e85d6SHong Zhang /*@ 16787adebddeSHong Zhang TSForwardReset - Reset the internal data structures used by forward sensitivity analysis 16797adebddeSHong Zhang 16807adebddeSHong Zhang Collective on TS 16817adebddeSHong Zhang 16827adebddeSHong Zhang Input Parameter: 16837adebddeSHong Zhang . ts - the TS context obtained from TSCreate() 16847adebddeSHong Zhang 16857adebddeSHong Zhang Level: advanced 16867adebddeSHong Zhang 16877adebddeSHong Zhang .keywords: TS, forward sensitivity, reset 16887adebddeSHong Zhang 16897adebddeSHong Zhang .seealso: TSCreate(), TSDestroy(), TSForwardSetUp() 16907adebddeSHong Zhang @*/ 16917adebddeSHong Zhang PetscErrorCode TSForwardReset(TS ts) 16927adebddeSHong Zhang { 16937adebddeSHong Zhang PetscErrorCode ierr; 16947adebddeSHong Zhang 16957adebddeSHong Zhang PetscFunctionBegin; 16967adebddeSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 16977adebddeSHong Zhang if (ts->ops->forwardreset) { 16987adebddeSHong Zhang ierr = (*ts->ops->forwardreset)(ts);CHKERRQ(ierr); 16997adebddeSHong Zhang } 17007adebddeSHong Zhang ierr = MatDestroy(&ts->mat_sensip);CHKERRQ(ierr); 17017adebddeSHong Zhang ts->vecs_integral_sensip = NULL; 17027adebddeSHong Zhang ts->forward_solve = PETSC_FALSE; 17037adebddeSHong Zhang ts->forwardsetupcalled = PETSC_FALSE; 17047adebddeSHong Zhang PetscFunctionReturn(0); 17057adebddeSHong Zhang } 17067adebddeSHong Zhang 17077adebddeSHong Zhang /*@ 1708814e85d6SHong Zhang TSForwardSetIntegralGradients - Set the vectors holding forward sensitivities of the integral term. 1709814e85d6SHong Zhang 1710814e85d6SHong Zhang Input Parameter: 1711814e85d6SHong Zhang . ts- the TS context obtained from TSCreate() 1712814e85d6SHong Zhang . numfwdint- number of integrals 1713814e85d6SHong Zhang . vp = the vectors containing the gradients for each integral w.r.t. parameters 1714814e85d6SHong Zhang 1715814e85d6SHong Zhang Level: intermediate 1716814e85d6SHong Zhang 1717814e85d6SHong Zhang .keywords: TS, forward sensitivity 1718814e85d6SHong Zhang 1719814e85d6SHong Zhang .seealso: TSForwardGetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardStep() 1720814e85d6SHong Zhang @*/ 1721814e85d6SHong Zhang PetscErrorCode TSForwardSetIntegralGradients(TS ts,PetscInt numfwdint,Vec *vp) 1722814e85d6SHong Zhang { 1723814e85d6SHong Zhang PetscFunctionBegin; 1724814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1725814e85d6SHong Zhang if (ts->numcost && ts->numcost!=numfwdint) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostIntegrand()"); 1726814e85d6SHong Zhang if (!ts->numcost) ts->numcost = numfwdint; 1727814e85d6SHong Zhang 1728814e85d6SHong Zhang ts->vecs_integral_sensip = vp; 1729814e85d6SHong Zhang PetscFunctionReturn(0); 1730814e85d6SHong Zhang } 1731814e85d6SHong Zhang 1732814e85d6SHong Zhang /*@ 1733814e85d6SHong Zhang TSForwardGetIntegralGradients - Returns the forward sensitivities ofthe integral term. 1734814e85d6SHong Zhang 1735814e85d6SHong Zhang Input Parameter: 1736814e85d6SHong Zhang . ts- the TS context obtained from TSCreate() 1737814e85d6SHong Zhang 1738814e85d6SHong Zhang Output Parameter: 1739814e85d6SHong Zhang . vp = the vectors containing the gradients for each integral w.r.t. parameters 1740814e85d6SHong Zhang 1741814e85d6SHong Zhang Level: intermediate 1742814e85d6SHong Zhang 1743814e85d6SHong Zhang .keywords: TS, forward sensitivity 1744814e85d6SHong Zhang 1745814e85d6SHong Zhang .seealso: TSForwardSetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardStep() 1746814e85d6SHong Zhang @*/ 1747814e85d6SHong Zhang PetscErrorCode TSForwardGetIntegralGradients(TS ts,PetscInt *numfwdint,Vec **vp) 1748814e85d6SHong Zhang { 1749814e85d6SHong Zhang PetscFunctionBegin; 1750814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1751814e85d6SHong Zhang PetscValidPointer(vp,3); 1752814e85d6SHong Zhang if (numfwdint) *numfwdint = ts->numcost; 1753814e85d6SHong Zhang if (vp) *vp = ts->vecs_integral_sensip; 1754814e85d6SHong Zhang PetscFunctionReturn(0); 1755814e85d6SHong Zhang } 1756814e85d6SHong Zhang 1757814e85d6SHong Zhang /*@ 1758814e85d6SHong Zhang TSForwardStep - Compute the forward sensitivity for one time step. 1759814e85d6SHong Zhang 1760814e85d6SHong Zhang Collective on TS 1761814e85d6SHong Zhang 1762814e85d6SHong Zhang Input Arguments: 1763814e85d6SHong Zhang . ts - time stepping context 1764814e85d6SHong Zhang 1765814e85d6SHong Zhang Level: advanced 1766814e85d6SHong Zhang 1767814e85d6SHong Zhang Notes: 1768814e85d6SHong Zhang This function cannot be called until TSStep() has been completed. 1769814e85d6SHong Zhang 1770814e85d6SHong Zhang .keywords: TS, forward sensitivity 1771814e85d6SHong Zhang 1772814e85d6SHong Zhang .seealso: TSForwardSetSensitivities(), TSForwardGetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardSetUp() 1773814e85d6SHong Zhang @*/ 1774814e85d6SHong Zhang PetscErrorCode TSForwardStep(TS ts) 1775814e85d6SHong Zhang { 1776814e85d6SHong Zhang PetscErrorCode ierr; 1777814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1778814e85d6SHong Zhang if (!ts->ops->forwardstep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide forward sensitivity analysis",((PetscObject)ts)->type_name); 1779814e85d6SHong Zhang ierr = PetscLogEventBegin(TS_ForwardStep,ts,0,0,0);CHKERRQ(ierr); 1780814e85d6SHong Zhang ierr = (*ts->ops->forwardstep)(ts);CHKERRQ(ierr); 1781814e85d6SHong Zhang ierr = PetscLogEventEnd(TS_ForwardStep,ts,0,0,0);CHKERRQ(ierr); 1782814e85d6SHong Zhang PetscFunctionReturn(0); 1783814e85d6SHong Zhang } 1784814e85d6SHong Zhang 1785814e85d6SHong Zhang /*@ 1786814e85d6SHong Zhang TSForwardSetSensitivities - Sets the initial value of the trajectory sensitivities of solution w.r.t. the problem parameters and initial values. 1787814e85d6SHong Zhang 1788814e85d6SHong Zhang Logically Collective on TS and Vec 1789814e85d6SHong Zhang 1790814e85d6SHong Zhang Input Parameters: 1791814e85d6SHong Zhang + ts - the TS context obtained from TSCreate() 1792814e85d6SHong Zhang . nump - number of parameters 1793814e85d6SHong Zhang - Smat - sensitivities with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 1794814e85d6SHong Zhang 1795814e85d6SHong Zhang Level: beginner 1796814e85d6SHong Zhang 1797814e85d6SHong Zhang Notes: 1798814e85d6SHong Zhang Forward sensitivity is also called 'trajectory sensitivity' in some fields such as power systems. 1799814e85d6SHong Zhang This function turns on a flag to trigger TSSolve() to compute forward sensitivities automatically. 1800814e85d6SHong Zhang You must call this function before TSSolve(). 1801814e85d6SHong Zhang The entries in the sensitivity matrix must be correctly initialized with the values S = dy/dp|startingtime. 1802814e85d6SHong Zhang 1803814e85d6SHong Zhang .keywords: TS, timestep, set, forward sensitivity, initial values 1804814e85d6SHong Zhang 1805814e85d6SHong Zhang .seealso: TSForwardGetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardStep() 1806814e85d6SHong Zhang @*/ 1807814e85d6SHong Zhang PetscErrorCode TSForwardSetSensitivities(TS ts,PetscInt nump,Mat Smat) 1808814e85d6SHong Zhang { 1809814e85d6SHong Zhang PetscErrorCode ierr; 1810814e85d6SHong Zhang 1811814e85d6SHong Zhang PetscFunctionBegin; 1812814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1813814e85d6SHong Zhang PetscValidHeaderSpecific(Smat,MAT_CLASSID,3); 1814814e85d6SHong Zhang ts->forward_solve = PETSC_TRUE; 1815b5b4017aSHong Zhang if (nump == PETSC_DEFAULT) { 1816b5b4017aSHong Zhang ierr = MatGetSize(Smat,NULL,&ts->num_parameters);CHKERRQ(ierr); 1817b5b4017aSHong Zhang } else ts->num_parameters = nump; 1818814e85d6SHong Zhang ierr = PetscObjectReference((PetscObject)Smat);CHKERRQ(ierr); 1819814e85d6SHong Zhang ierr = MatDestroy(&ts->mat_sensip);CHKERRQ(ierr); 1820814e85d6SHong Zhang ts->mat_sensip = Smat; 1821814e85d6SHong Zhang PetscFunctionReturn(0); 1822814e85d6SHong Zhang } 1823814e85d6SHong Zhang 1824814e85d6SHong Zhang /*@ 1825814e85d6SHong Zhang TSForwardGetSensitivities - Returns the trajectory sensitivities 1826814e85d6SHong Zhang 1827814e85d6SHong Zhang Not Collective, but Vec returned is parallel if TS is parallel 1828814e85d6SHong Zhang 1829814e85d6SHong Zhang Output Parameter: 1830814e85d6SHong Zhang + ts - the TS context obtained from TSCreate() 1831814e85d6SHong Zhang . nump - number of parameters 1832814e85d6SHong Zhang - Smat - sensitivities with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 1833814e85d6SHong Zhang 1834814e85d6SHong Zhang Level: intermediate 1835814e85d6SHong Zhang 1836814e85d6SHong Zhang .keywords: TS, forward sensitivity 1837814e85d6SHong Zhang 1838814e85d6SHong Zhang .seealso: TSForwardSetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardStep() 1839814e85d6SHong Zhang @*/ 1840814e85d6SHong Zhang PetscErrorCode TSForwardGetSensitivities(TS ts,PetscInt *nump,Mat *Smat) 1841814e85d6SHong Zhang { 1842814e85d6SHong Zhang PetscFunctionBegin; 1843814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1844814e85d6SHong Zhang if (nump) *nump = ts->num_parameters; 1845814e85d6SHong Zhang if (Smat) *Smat = ts->mat_sensip; 1846814e85d6SHong Zhang PetscFunctionReturn(0); 1847814e85d6SHong Zhang } 1848814e85d6SHong Zhang 1849814e85d6SHong Zhang /*@ 1850814e85d6SHong Zhang TSForwardCostIntegral - Evaluate the cost integral in the forward run. 1851814e85d6SHong Zhang 1852814e85d6SHong Zhang Collective on TS 1853814e85d6SHong Zhang 1854814e85d6SHong Zhang Input Arguments: 1855814e85d6SHong Zhang . ts - time stepping context 1856814e85d6SHong Zhang 1857814e85d6SHong Zhang Level: advanced 1858814e85d6SHong Zhang 1859814e85d6SHong Zhang Notes: 1860814e85d6SHong Zhang This function cannot be called until TSStep() has been completed. 1861814e85d6SHong Zhang 1862814e85d6SHong Zhang .seealso: TSSolve(), TSAdjointCostIntegral() 1863814e85d6SHong Zhang @*/ 1864814e85d6SHong Zhang PetscErrorCode TSForwardCostIntegral(TS ts) 1865814e85d6SHong Zhang { 1866814e85d6SHong Zhang PetscErrorCode ierr; 1867814e85d6SHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1868814e85d6SHong Zhang if (!ts->ops->forwardintegral) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide integral evaluation in the forward run",((PetscObject)ts)->type_name); 1869814e85d6SHong Zhang ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr); 1870814e85d6SHong Zhang PetscFunctionReturn(0); 1871814e85d6SHong Zhang } 1872b5b4017aSHong Zhang 1873b5b4017aSHong Zhang /*@ 1874b5b4017aSHong Zhang TSForwardSetInitialSensitivities - Set initial values for tangent linear sensitivities 1875b5b4017aSHong Zhang 1876b5b4017aSHong Zhang Collective on TS and Mat 1877b5b4017aSHong Zhang 1878b5b4017aSHong Zhang Input Parameter 1879b5b4017aSHong Zhang + ts - the TS context obtained from TSCreate() 1880b5b4017aSHong Zhang - didp - parametric sensitivities of the initial condition 1881b5b4017aSHong Zhang 1882b5b4017aSHong Zhang Level: intermediate 1883b5b4017aSHong Zhang 1884b5b4017aSHong Zhang Notes: TSSolve() allows users to pass the initial solution directly to TS. But the tangent linear variables cannot be initialized in this way. This function is used to set initial values for tangent linear variables. 1885b5b4017aSHong Zhang 1886b5b4017aSHong Zhang .seealso: TSForwardSetSensitivities() 1887b5b4017aSHong Zhang @*/ 1888b5b4017aSHong Zhang PetscErrorCode TSForwardSetInitialSensitivities(TS ts,Mat didp) 1889b5b4017aSHong Zhang { 1890b5b4017aSHong Zhang PetscErrorCode ierr; 1891b5b4017aSHong Zhang 1892b5b4017aSHong Zhang PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1893b5b4017aSHong Zhang PetscValidHeaderSpecific(didp,MAT_CLASSID,2); 1894b5b4017aSHong Zhang if (!ts->mat_sensip) { 1895b5b4017aSHong Zhang ierr = TSForwardSetSensitivities(ts,PETSC_DEFAULT,didp);CHKERRQ(ierr); 1896b5b4017aSHong Zhang } 1897b5b4017aSHong Zhang PetscFunctionReturn(0); 1898b5b4017aSHong Zhang } 18996affb6f8SHong Zhang 19006affb6f8SHong Zhang /*@ 19016affb6f8SHong Zhang TSForwardGetStages - Get the number of stages and the tangent linear sensitivities at the intermediate stages 19026affb6f8SHong Zhang 19036affb6f8SHong Zhang Input Parameter: 19046affb6f8SHong Zhang . ts - the TS context obtained from TSCreate() 19056affb6f8SHong Zhang 19066affb6f8SHong Zhang Output Parameters: 19076affb6f8SHong Zhang + ns - nu 19086affb6f8SHong Zhang - S - tangent linear sensitivities at the intermediate stages 19096affb6f8SHong Zhang 19106affb6f8SHong Zhang Level: advanced 19116affb6f8SHong Zhang 19126affb6f8SHong Zhang .keywords: TS, second-order adjoint, forward sensitivity 19136affb6f8SHong Zhang @*/ 19146affb6f8SHong Zhang PetscErrorCode TSForwardGetStages(TS ts,PetscInt *ns,Mat **S) 19156affb6f8SHong Zhang { 19166affb6f8SHong Zhang PetscErrorCode ierr; 19176affb6f8SHong Zhang 19186affb6f8SHong Zhang PetscFunctionBegin; 19196affb6f8SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID,1); 19206affb6f8SHong Zhang 19216affb6f8SHong Zhang if (!ts->ops->getstages) *S=NULL; 19226affb6f8SHong Zhang else { 19236affb6f8SHong Zhang ierr = (*ts->ops->forwardgetstages)(ts,ns,S);CHKERRQ(ierr); 19246affb6f8SHong Zhang } 19256affb6f8SHong Zhang PetscFunctionReturn(0); 19266affb6f8SHong Zhang } 1927