1 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2 #include <petscdraw.h> 3 4 PetscLogEvent TS_AdjointStep, TS_ForwardStep; 5 6 /* ------------------------ Sensitivity Context ---------------------------*/ 7 8 /*@C 9 TSSetRHSJacobianP - Sets the function that computes the Jacobian of G w.r.t. the parameters p where y_t = G(y,p,t), as well as the location to store the matrix. 10 11 Logically Collective on TS 12 13 Input Parameters: 14 + ts - The TS context obtained from TSCreate() 15 - func - The function 16 17 Calling sequence of func: 18 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx); 19 + t - current timestep 20 . y - input vector (current ODE solution) 21 . A - output matrix 22 - ctx - [optional] user-defined function context 23 24 Level: intermediate 25 26 Notes: 27 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 28 29 .keywords: TS, sensitivity 30 .seealso: 31 @*/ 32 PetscErrorCode TSSetRHSJacobianP(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 33 { 34 PetscErrorCode ierr; 35 36 PetscFunctionBegin; 37 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 38 PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 39 40 ts->rhsjacobianp = func; 41 ts->rhsjacobianpctx = ctx; 42 if(Amat) { 43 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 44 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 45 ts->Jacp = Amat; 46 } 47 PetscFunctionReturn(0); 48 } 49 50 /*@C 51 TSComputeRHSJacobianP - Runs the user-defined JacobianP function. 52 53 Collective on TS 54 55 Input Parameters: 56 . ts - The TS context obtained from TSCreate() 57 58 Level: developer 59 60 .keywords: TS, sensitivity 61 .seealso: TSSetRHSJacobianP() 62 @*/ 63 PetscErrorCode TSComputeRHSJacobianP(TS ts,PetscReal t,Vec X,Mat Amat) 64 { 65 PetscErrorCode ierr; 66 67 PetscFunctionBegin; 68 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 69 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 70 PetscValidPointer(Amat,4); 71 72 PetscStackPush("TS user JacobianP function for sensitivity analysis"); 73 ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr); 74 PetscStackPop; 75 PetscFunctionReturn(0); 76 } 77 78 /*@C 79 TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions 80 81 Logically Collective on TS 82 83 Input Parameters: 84 + ts - the TS context obtained from TSCreate() 85 . numcost - number of gradients to be computed, this is the number of cost functions 86 . costintegral - vector that stores the integral values 87 . rf - routine for evaluating the integrand function 88 . drdyf - function that computes the gradients of the r's with respect to y 89 . 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) 90 . fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run 91 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 92 93 Calling sequence of rf: 94 $ PetscErrorCode rf(TS ts,PetscReal t,Vec y,Vec f,void *ctx); 95 96 Calling sequence of drdyf: 97 $ PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx); 98 99 Calling sequence of drdpf: 100 $ PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx); 101 102 Level: intermediate 103 104 Notes: 105 For optimization there is usually a single cost function (numcost = 1). For sensitivities there may be multiple cost functions 106 107 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function 108 109 .seealso: TSSetRHSJacobianP(), TSGetCostGradients(), TSSetCostGradients() 110 @*/ 111 PetscErrorCode TSSetCostIntegrand(TS ts,PetscInt numcost,Vec costintegral,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*), 112 PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*), 113 PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*), 114 PetscBool fwd,void *ctx) 115 { 116 PetscErrorCode ierr; 117 118 PetscFunctionBegin; 119 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 120 if (costintegral) PetscValidHeaderSpecific(costintegral,VEC_CLASSID,3); 121 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()"); 122 if (!ts->numcost) ts->numcost=numcost; 123 124 if (costintegral) { 125 ierr = PetscObjectReference((PetscObject)costintegral);CHKERRQ(ierr); 126 ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 127 ts->vec_costintegral = costintegral; 128 } else { 129 if (!ts->vec_costintegral) { /* Create a seq vec if user does not provide one */ 130 ierr = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr); 131 } else { 132 ierr = VecSet(ts->vec_costintegral,0.0);CHKERRQ(ierr); 133 } 134 } 135 if (!ts->vec_costintegrand) { 136 ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr); 137 } else { 138 ierr = VecSet(ts->vec_costintegrand,0.0);CHKERRQ(ierr); 139 } 140 ts->costintegralfwd = fwd; /* Evaluate the cost integral in forward run if fwd is true */ 141 ts->costintegrand = rf; 142 ts->costintegrandctx = ctx; 143 ts->drdyfunction = drdyf; 144 ts->drdpfunction = drdpf; 145 PetscFunctionReturn(0); 146 } 147 148 /*@ 149 TSGetCostIntegral - Returns the values of the integral term in the cost functions. 150 It is valid to call the routine after a backward run. 151 152 Not Collective 153 154 Input Parameter: 155 . ts - the TS context obtained from TSCreate() 156 157 Output Parameter: 158 . v - the vector containing the integrals for each cost function 159 160 Level: intermediate 161 162 .seealso: TSSetCostIntegrand() 163 164 .keywords: TS, sensitivity analysis 165 @*/ 166 PetscErrorCode TSGetCostIntegral(TS ts,Vec *v) 167 { 168 PetscFunctionBegin; 169 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 170 PetscValidPointer(v,2); 171 *v = ts->vec_costintegral; 172 PetscFunctionReturn(0); 173 } 174 175 /*@ 176 TSComputeCostIntegrand - Evaluates the integral function in the cost functions. 177 178 Input Parameters: 179 + ts - the TS context 180 . t - current time 181 - y - state vector, i.e. current solution 182 183 Output Parameter: 184 . q - vector of size numcost to hold the outputs 185 186 Note: 187 Most users should not need to explicitly call this routine, as it 188 is used internally within the sensitivity analysis context. 189 190 Level: developer 191 192 .keywords: TS, compute 193 194 .seealso: TSSetCostIntegrand() 195 @*/ 196 PetscErrorCode TSComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q) 197 { 198 PetscErrorCode ierr; 199 200 PetscFunctionBegin; 201 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 202 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 203 PetscValidHeaderSpecific(q,VEC_CLASSID,4); 204 205 ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 206 if (ts->costintegrand) { 207 PetscStackPush("TS user integrand in the cost function"); 208 ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr); 209 PetscStackPop; 210 } else { 211 ierr = VecZeroEntries(q);CHKERRQ(ierr); 212 } 213 214 ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 215 PetscFunctionReturn(0); 216 } 217 218 /*@ 219 TSComputeDRDYFunction - Runs the user-defined DRDY function. 220 221 Collective on TS 222 223 Input Parameters: 224 . ts - The TS context obtained from TSCreate() 225 226 Notes: 227 TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation, 228 so most users would not generally call this routine themselves. 229 230 Level: developer 231 232 .keywords: TS, sensitivity 233 .seealso: TSSetCostIntegrand() 234 @*/ 235 PetscErrorCode TSComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy) 236 { 237 PetscErrorCode ierr; 238 239 PetscFunctionBegin; 240 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 241 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 242 243 PetscStackPush("TS user DRDY function for sensitivity analysis"); 244 ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr); 245 PetscStackPop; 246 PetscFunctionReturn(0); 247 } 248 249 /*@ 250 TSComputeDRDPFunction - Runs the user-defined DRDP function. 251 252 Collective on TS 253 254 Input Parameters: 255 . ts - The TS context obtained from TSCreate() 256 257 Notes: 258 TSDRDPFunction() is typically used for sensitivity implementation, 259 so most users would not generally call this routine themselves. 260 261 Level: developer 262 263 .keywords: TS, sensitivity 264 .seealso: TSSetCostIntegrand() 265 @*/ 266 PetscErrorCode TSComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp) 267 { 268 PetscErrorCode ierr; 269 270 PetscFunctionBegin; 271 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 272 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 273 274 PetscStackPush("TS user DRDP function for sensitivity analysis"); 275 ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr); 276 PetscStackPop; 277 PetscFunctionReturn(0); 278 } 279 280 /* --------------------------- Adjoint sensitivity ---------------------------*/ 281 282 /*@ 283 TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial values and w.r.t. the problem parameters 284 for use by the TSAdjoint routines. 285 286 Logically Collective on TS and Vec 287 288 Input Parameters: 289 + ts - the TS context obtained from TSCreate() 290 . 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 291 - mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 292 293 Level: beginner 294 295 Notes: 296 the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime mu_i = df/dp|finaltime 297 298 After TSAdjointSolve() is called the lamba and the mu contain the computed sensitivities 299 300 .keywords: TS, timestep, set, sensitivity, initial values 301 @*/ 302 PetscErrorCode TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu) 303 { 304 PetscFunctionBegin; 305 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 306 PetscValidPointer(lambda,2); 307 ts->vecs_sensi = lambda; 308 ts->vecs_sensip = mu; 309 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"); 310 ts->numcost = numcost; 311 PetscFunctionReturn(0); 312 } 313 314 /*@ 315 TSGetCostGradients - Returns the gradients from the TSAdjointSolve() 316 317 Not Collective, but Vec returned is parallel if TS is parallel 318 319 Input Parameter: 320 . ts - the TS context obtained from TSCreate() 321 322 Output Parameter: 323 + lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 324 - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 325 326 Level: intermediate 327 328 .seealso: TSGetTimeStep() 329 330 .keywords: TS, timestep, get, sensitivity 331 @*/ 332 PetscErrorCode TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu) 333 { 334 PetscFunctionBegin; 335 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 336 if (numcost) *numcost = ts->numcost; 337 if (lambda) *lambda = ts->vecs_sensi; 338 if (mu) *mu = ts->vecs_sensip; 339 PetscFunctionReturn(0); 340 } 341 342 /*@ 343 TSAdjointSetUp - Sets up the internal data structures for the later use 344 of an adjoint solver 345 346 Collective on TS 347 348 Input Parameter: 349 . ts - the TS context obtained from TSCreate() 350 351 Level: advanced 352 353 .keywords: TS, timestep, setup 354 355 .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients() 356 @*/ 357 PetscErrorCode TSAdjointSetUp(TS ts) 358 { 359 PetscErrorCode ierr; 360 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 363 if (ts->adjointsetupcalled) PetscFunctionReturn(0); 364 if (!ts->vecs_sensi) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first"); 365 if (ts->vecs_sensip && !ts->Jacp) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"Must call TSAdjointSetRHSJacobian() first"); 366 367 if (ts->vec_costintegral) { /* if there is integral in the cost function */ 368 ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 369 if (ts->vecs_sensip){ 370 ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 371 } 372 } 373 374 if (ts->ops->adjointsetup) { 375 ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr); 376 } 377 ts->adjointsetupcalled = PETSC_TRUE; 378 PetscFunctionReturn(0); 379 } 380 381 /*@ 382 TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time 383 384 Logically Collective on TS 385 386 Input Parameters: 387 + ts - the TS context obtained from TSCreate() 388 . steps - number of steps to use 389 390 Level: intermediate 391 392 Notes: 393 Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this 394 so as to integrate back to less than the original timestep 395 396 .keywords: TS, timestep, set, maximum, iterations 397 398 .seealso: TSSetExactFinalTime() 399 @*/ 400 PetscErrorCode TSAdjointSetSteps(TS ts,PetscInt steps) 401 { 402 PetscFunctionBegin; 403 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 404 PetscValidLogicalCollectiveInt(ts,steps,2); 405 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps"); 406 if (steps > ts->steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps"); 407 ts->adjoint_max_steps = steps; 408 PetscFunctionReturn(0); 409 } 410 411 /*@C 412 TSAdjointSetRHSJacobian - Deprecated, use TSSetRHSJacobianP() 413 414 Level: deprecated 415 416 @*/ 417 PetscErrorCode TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 418 { 419 PetscErrorCode ierr; 420 421 PetscFunctionBegin; 422 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 423 PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 424 425 ts->rhsjacobianp = func; 426 ts->rhsjacobianpctx = ctx; 427 if(Amat) { 428 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 429 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 430 ts->Jacp = Amat; 431 } 432 PetscFunctionReturn(0); 433 } 434 435 /*@C 436 TSAdjointComputeRHSJacobian - Deprecated, use TSComputeRHSJacobianP() 437 438 Level: deprecated 439 440 @*/ 441 PetscErrorCode TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat) 442 { 443 PetscErrorCode ierr; 444 445 PetscFunctionBegin; 446 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 447 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 448 PetscValidPointer(Amat,4); 449 450 PetscStackPush("TS user JacobianP function for sensitivity analysis"); 451 ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr); 452 PetscStackPop; 453 PetscFunctionReturn(0); 454 } 455 456 /*@ 457 TSAdjointComputeDRDYFunction - Deprecated, use TSComputeDRDYFunction() 458 459 Level: deprecated 460 461 @*/ 462 PetscErrorCode TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy) 463 { 464 PetscErrorCode ierr; 465 466 PetscFunctionBegin; 467 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 468 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 469 470 PetscStackPush("TS user DRDY function for sensitivity analysis"); 471 ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr); 472 PetscStackPop; 473 PetscFunctionReturn(0); 474 } 475 476 /*@ 477 TSAdjointComputeDRDPFunction - Deprecated, use TSComputeDRDPFunction() 478 479 Level: deprecated 480 481 @*/ 482 PetscErrorCode TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp) 483 { 484 PetscErrorCode ierr; 485 486 PetscFunctionBegin; 487 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 488 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 489 490 PetscStackPush("TS user DRDP function for sensitivity analysis"); 491 ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr); 492 PetscStackPop; 493 PetscFunctionReturn(0); 494 } 495 496 /*@C 497 TSAdjointMonitorSensi - monitors the first lambda sensitivity 498 499 Level: intermediate 500 501 .keywords: TS, set, monitor 502 503 .seealso: TSAdjointMonitorSet() 504 @*/ 505 PetscErrorCode TSAdjointMonitorSensi(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf) 506 { 507 PetscErrorCode ierr; 508 PetscViewer viewer = vf->viewer; 509 510 PetscFunctionBegin; 511 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 512 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 513 ierr = VecView(lambda[0],viewer);CHKERRQ(ierr); 514 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 515 PetscFunctionReturn(0); 516 } 517 518 /*@C 519 TSAdjointMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 520 521 Collective on TS 522 523 Input Parameters: 524 + ts - TS object you wish to monitor 525 . name - the monitor type one is seeking 526 . help - message indicating what monitoring is done 527 . manual - manual page for the monitor 528 . monitor - the monitor function 529 - 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 530 531 Level: developer 532 533 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 534 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 535 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 536 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 537 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 538 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 539 PetscOptionsFList(), PetscOptionsEList() 540 @*/ 541 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*)) 542 { 543 PetscErrorCode ierr; 544 PetscViewer viewer; 545 PetscViewerFormat format; 546 PetscBool flg; 547 548 PetscFunctionBegin; 549 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 550 if (flg) { 551 PetscViewerAndFormat *vf; 552 ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 553 ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 554 if (monitorsetup) { 555 ierr = (*monitorsetup)(ts,vf);CHKERRQ(ierr); 556 } 557 ierr = TSAdjointMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 558 } 559 PetscFunctionReturn(0); 560 } 561 562 /*@C 563 TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every 564 timestep to display the iteration's progress. 565 566 Logically Collective on TS 567 568 Input Parameters: 569 + ts - the TS context obtained from TSCreate() 570 . adjointmonitor - monitoring routine 571 . adjointmctx - [optional] user-defined context for private data for the 572 monitor routine (use NULL if no context is desired) 573 - adjointmonitordestroy - [optional] routine that frees monitor context 574 (may be NULL) 575 576 Calling sequence of monitor: 577 $ int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx) 578 579 + ts - the TS context 580 . 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 581 been interpolated to) 582 . time - current time 583 . u - current iterate 584 . numcost - number of cost functionos 585 . lambda - sensitivities to initial conditions 586 . mu - sensitivities to parameters 587 - adjointmctx - [optional] adjoint monitoring context 588 589 Notes: 590 This routine adds an additional monitor to the list of monitors that 591 already has been loaded. 592 593 Fortran Notes: 594 Only a single monitor function can be set for each TS object 595 596 Level: intermediate 597 598 .keywords: TS, timestep, set, adjoint, monitor 599 600 .seealso: TSAdjointMonitorCancel() 601 @*/ 602 PetscErrorCode TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**)) 603 { 604 PetscErrorCode ierr; 605 PetscInt i; 606 PetscBool identical; 607 608 PetscFunctionBegin; 609 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 610 for (i=0; i<ts->numbermonitors;i++) { 611 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr); 612 if (identical) PetscFunctionReturn(0); 613 } 614 if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set"); 615 ts->adjointmonitor[ts->numberadjointmonitors] = adjointmonitor; 616 ts->adjointmonitordestroy[ts->numberadjointmonitors] = adjointmdestroy; 617 ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx; 618 PetscFunctionReturn(0); 619 } 620 621 /*@C 622 TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object. 623 624 Logically Collective on TS 625 626 Input Parameters: 627 . ts - the TS context obtained from TSCreate() 628 629 Notes: 630 There is no way to remove a single, specific monitor. 631 632 Level: intermediate 633 634 .keywords: TS, timestep, set, adjoint, monitor 635 636 .seealso: TSAdjointMonitorSet() 637 @*/ 638 PetscErrorCode TSAdjointMonitorCancel(TS ts) 639 { 640 PetscErrorCode ierr; 641 PetscInt i; 642 643 PetscFunctionBegin; 644 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 645 for (i=0; i<ts->numberadjointmonitors; i++) { 646 if (ts->adjointmonitordestroy[i]) { 647 ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 648 } 649 } 650 ts->numberadjointmonitors = 0; 651 PetscFunctionReturn(0); 652 } 653 654 /*@C 655 TSAdjointMonitorDefault - the default monitor of adjoint computations 656 657 Level: intermediate 658 659 .keywords: TS, set, monitor 660 661 .seealso: TSAdjointMonitorSet() 662 @*/ 663 PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf) 664 { 665 PetscErrorCode ierr; 666 PetscViewer viewer = vf->viewer; 667 668 PetscFunctionBegin; 669 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 670 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 671 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 672 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 673 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 674 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 675 PetscFunctionReturn(0); 676 } 677 678 /*@C 679 TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling 680 VecView() for the sensitivities to initial states at each timestep 681 682 Collective on TS 683 684 Input Parameters: 685 + ts - the TS context 686 . step - current time-step 687 . ptime - current time 688 . u - current state 689 . numcost - number of cost functions 690 . lambda - sensitivities to initial conditions 691 . mu - sensitivities to parameters 692 - dummy - either a viewer or NULL 693 694 Level: intermediate 695 696 .keywords: TS, vector, adjoint, monitor, view 697 698 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView() 699 @*/ 700 PetscErrorCode TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy) 701 { 702 PetscErrorCode ierr; 703 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 704 PetscDraw draw; 705 PetscReal xl,yl,xr,yr,h; 706 char time[32]; 707 708 PetscFunctionBegin; 709 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 710 711 ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr); 712 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 713 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 714 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 715 h = yl + .95*(yr - yl); 716 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 717 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 718 PetscFunctionReturn(0); 719 } 720 721 /* 722 TSAdjointSetFromOptions - Sets various TSAdjoint parameters from user options. 723 724 Collective on TSAdjoint 725 726 Input Parameter: 727 . ts - the TS context 728 729 Options Database Keys: 730 + -ts_adjoint_solve <yes,no> After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory) 731 . -ts_adjoint_monitor - print information at each adjoint time step 732 - -ts_adjoint_monitor_draw_sensi - monitor the sensitivity of the first cost function wrt initial conditions (lambda[0]) graphically 733 734 Level: developer 735 736 Notes: 737 This is not normally called directly by users 738 739 .keywords: TS, trajectory, timestep, set, options, database 740 741 .seealso: TSSetSaveTrajectory(), TSTrajectorySetUp() 742 */ 743 PetscErrorCode TSAdjointSetFromOptions(PetscOptionItems *PetscOptionsObject,TS ts) 744 { 745 PetscBool tflg,opt; 746 PetscErrorCode ierr; 747 748 PetscFunctionBegin; 749 PetscValidHeaderSpecific(ts,TS_CLASSID,2); 750 ierr = PetscOptionsHead(PetscOptionsObject,"TS Adjoint options");CHKERRQ(ierr); 751 tflg = ts->adjoint_solve ? PETSC_TRUE : PETSC_FALSE; 752 ierr = PetscOptionsBool("-ts_adjoint_solve","Solve the adjoint problem immediately after solving the forward problem","",tflg,&tflg,&opt);CHKERRQ(ierr); 753 if (opt) { 754 ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); 755 ts->adjoint_solve = tflg; 756 } 757 ierr = TSAdjointMonitorSetFromOptions(ts,"-ts_adjoint_monitor","Monitor adjoint timestep size","TSAdjointMonitorDefault",TSAdjointMonitorDefault,NULL);CHKERRQ(ierr); 758 ierr = TSAdjointMonitorSetFromOptions(ts,"-ts_adjoint_monitor_sensi","Monitor sensitivity in the adjoint computation","TSAdjointMonitorSensi",TSAdjointMonitorSensi,NULL);CHKERRQ(ierr); 759 opt = PETSC_FALSE; 760 ierr = PetscOptionsName("-ts_adjoint_monitor_draw_sensi","Monitor adjoint sensitivities (lambda only) graphically","TSAdjointMonitorDrawSensi",&opt);CHKERRQ(ierr); 761 if (opt) { 762 TSMonitorDrawCtx ctx; 763 PetscInt howoften = 1; 764 765 ierr = PetscOptionsInt("-ts_adjoint_monitor_draw_sensi","Monitor adjoint sensitivities (lambda only) graphically","TSAdjointMonitorDrawSensi",howoften,&howoften,NULL);CHKERRQ(ierr); 766 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 767 ierr = TSAdjointMonitorSet(ts,TSAdjointMonitorDrawSensi,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 768 } 769 PetscFunctionReturn(0); 770 } 771 772 /*@ 773 TSAdjointStep - Steps one time step backward in the adjoint run 774 775 Collective on TS 776 777 Input Parameter: 778 . ts - the TS context obtained from TSCreate() 779 780 Level: intermediate 781 782 .keywords: TS, adjoint, step 783 784 .seealso: TSAdjointSetUp(), TSAdjointSolve() 785 @*/ 786 PetscErrorCode TSAdjointStep(TS ts) 787 { 788 DM dm; 789 PetscErrorCode ierr; 790 791 PetscFunctionBegin; 792 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 793 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 794 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 795 796 ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr); 797 798 ts->reason = TS_CONVERGED_ITERATING; 799 ts->ptime_prev = ts->ptime; 800 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); 801 ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 802 ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr); 803 ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 804 ts->adjoint_steps++; ts->steps--; 805 806 if (ts->reason < 0) { 807 if (ts->errorifstepfailed) { 808 if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 809 else if (ts->reason == TS_DIVERGED_STEP_REJECTED) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_reject or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 810 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 811 } 812 } else if (!ts->reason) { 813 if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 814 } 815 PetscFunctionReturn(0); 816 } 817 818 /*@ 819 TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE 820 821 Collective on TS 822 823 Input Parameter: 824 . ts - the TS context obtained from TSCreate() 825 826 Options Database: 827 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial values 828 829 Level: intermediate 830 831 Notes: 832 This must be called after a call to TSSolve() that solves the forward problem 833 834 By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time 835 836 .keywords: TS, timestep, solve 837 838 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep() 839 @*/ 840 PetscErrorCode TSAdjointSolve(TS ts) 841 { 842 PetscErrorCode ierr; 843 844 PetscFunctionBegin; 845 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 846 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 847 848 /* reset time step and iteration counters */ 849 ts->adjoint_steps = 0; 850 ts->ksp_its = 0; 851 ts->snes_its = 0; 852 ts->num_snes_failures = 0; 853 ts->reject = 0; 854 ts->reason = TS_CONVERGED_ITERATING; 855 856 if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->steps; 857 if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 858 859 while (!ts->reason) { 860 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr); 861 ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 862 ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr); 863 ierr = TSAdjointStep(ts);CHKERRQ(ierr); 864 if (ts->vec_costintegral && !ts->costintegralfwd) { 865 ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr); 866 } 867 } 868 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr); 869 ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 870 ts->solvetime = ts->ptime; 871 ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr); 872 ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr); 873 ts->adjoint_max_steps = 0; 874 PetscFunctionReturn(0); 875 } 876 877 /*@C 878 TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet() 879 880 Collective on TS 881 882 Input Parameters: 883 + ts - time stepping context obtained from TSCreate() 884 . step - step number that has just completed 885 . ptime - model time of the state 886 . u - state at the current model time 887 . numcost - number of cost functions (dimension of lambda or mu) 888 . lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 889 - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 890 891 Notes: 892 TSAdjointMonitor() is typically used automatically within the time stepping implementations. 893 Users would almost never call this routine directly. 894 895 Level: developer 896 897 .keywords: TS, timestep 898 @*/ 899 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu) 900 { 901 PetscErrorCode ierr; 902 PetscInt i,n = ts->numberadjointmonitors; 903 904 PetscFunctionBegin; 905 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 906 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 907 ierr = VecLockReadPush(u);CHKERRQ(ierr); 908 for (i=0; i<n; i++) { 909 ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 910 } 911 ierr = VecLockReadPop(u);CHKERRQ(ierr); 912 PetscFunctionReturn(0); 913 } 914 915 /*@ 916 TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run. 917 918 Collective on TS 919 920 Input Arguments: 921 . ts - time stepping context 922 923 Level: advanced 924 925 Notes: 926 This function cannot be called until TSAdjointStep() has been completed. 927 928 .seealso: TSAdjointSolve(), TSAdjointStep 929 @*/ 930 PetscErrorCode TSAdjointCostIntegral(TS ts) 931 { 932 PetscErrorCode ierr; 933 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 934 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); 935 ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr); 936 PetscFunctionReturn(0); 937 } 938 939 /* ------------------ Forward (tangent linear) sensitivity ------------------*/ 940 941 /*@ 942 TSForwardSetUp - Sets up the internal data structures for the later use 943 of forward sensitivity analysis 944 945 Collective on TS 946 947 Input Parameter: 948 . ts - the TS context obtained from TSCreate() 949 950 Level: advanced 951 952 .keywords: TS, forward sensitivity, setup 953 954 .seealso: TSCreate(), TSDestroy(), TSSetUp() 955 @*/ 956 PetscErrorCode TSForwardSetUp(TS ts) 957 { 958 PetscErrorCode ierr; 959 960 PetscFunctionBegin; 961 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 962 if (ts->forwardsetupcalled) PetscFunctionReturn(0); 963 if (ts->vec_costintegral && !ts->vecs_integral_sensip ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSForwardSetIntegralGradients() before TSSetCostIntegrand()"); 964 if (ts->vecs_integral_sensip) { 965 ierr = VecDuplicateVecs(ts->vec_sol,ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 966 ierr = VecDuplicateVecs(ts->vecs_integral_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 967 } 968 969 if (ts->ops->forwardsetup) { 970 ierr = (*ts->ops->forwardsetup)(ts);CHKERRQ(ierr); 971 } 972 ts->forwardsetupcalled = PETSC_TRUE; 973 PetscFunctionReturn(0); 974 } 975 976 /*@ 977 TSForwardSetIntegralGradients - Set the vectors holding forward sensitivities of the integral term. 978 979 Input Parameter: 980 . ts- the TS context obtained from TSCreate() 981 . numfwdint- number of integrals 982 . vp = the vectors containing the gradients for each integral w.r.t. parameters 983 984 Level: intermediate 985 986 .keywords: TS, forward sensitivity 987 988 .seealso: TSForwardGetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardStep() 989 @*/ 990 PetscErrorCode TSForwardSetIntegralGradients(TS ts,PetscInt numfwdint,Vec *vp) 991 { 992 PetscFunctionBegin; 993 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 994 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()"); 995 if (!ts->numcost) ts->numcost = numfwdint; 996 997 ts->vecs_integral_sensip = vp; 998 PetscFunctionReturn(0); 999 } 1000 1001 /*@ 1002 TSForwardGetIntegralGradients - Returns the forward sensitivities ofthe integral term. 1003 1004 Input Parameter: 1005 . ts- the TS context obtained from TSCreate() 1006 1007 Output Parameter: 1008 . vp = the vectors containing the gradients for each integral w.r.t. parameters 1009 1010 Level: intermediate 1011 1012 .keywords: TS, forward sensitivity 1013 1014 .seealso: TSForwardSetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardStep() 1015 @*/ 1016 PetscErrorCode TSForwardGetIntegralGradients(TS ts,PetscInt *numfwdint,Vec **vp) 1017 { 1018 PetscFunctionBegin; 1019 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1020 PetscValidPointer(vp,3); 1021 if (numfwdint) *numfwdint = ts->numcost; 1022 if (vp) *vp = ts->vecs_integral_sensip; 1023 PetscFunctionReturn(0); 1024 } 1025 1026 /*@ 1027 TSForwardStep - Compute the forward sensitivity for one time step. 1028 1029 Collective on TS 1030 1031 Input Arguments: 1032 . ts - time stepping context 1033 1034 Level: advanced 1035 1036 Notes: 1037 This function cannot be called until TSStep() has been completed. 1038 1039 .keywords: TS, forward sensitivity 1040 1041 .seealso: TSForwardSetSensitivities(), TSForwardGetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardSetUp() 1042 @*/ 1043 PetscErrorCode TSForwardStep(TS ts) 1044 { 1045 PetscErrorCode ierr; 1046 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1047 if (!ts->ops->forwardstep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide forward sensitivity analysis",((PetscObject)ts)->type_name); 1048 ierr = PetscLogEventBegin(TS_ForwardStep,ts,0,0,0);CHKERRQ(ierr); 1049 ierr = (*ts->ops->forwardstep)(ts);CHKERRQ(ierr); 1050 ierr = PetscLogEventEnd(TS_ForwardStep,ts,0,0,0);CHKERRQ(ierr); 1051 PetscFunctionReturn(0); 1052 } 1053 1054 /*@ 1055 TSForwardSetSensitivities - Sets the initial value of the trajectory sensitivities of solution w.r.t. the problem parameters and initial values. 1056 1057 Logically Collective on TS and Vec 1058 1059 Input Parameters: 1060 + ts - the TS context obtained from TSCreate() 1061 . nump - number of parameters 1062 - Smat - sensitivities with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 1063 1064 Level: beginner 1065 1066 Notes: 1067 Forward sensitivity is also called 'trajectory sensitivity' in some fields such as power systems. 1068 This function turns on a flag to trigger TSSolve() to compute forward sensitivities automatically. 1069 You must call this function before TSSolve(). 1070 The entries in the sensitivity matrix must be correctly initialized with the values S = dy/dp|startingtime. 1071 1072 .keywords: TS, timestep, set, forward sensitivity, initial values 1073 1074 .seealso: TSForwardGetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardStep() 1075 @*/ 1076 PetscErrorCode TSForwardSetSensitivities(TS ts,PetscInt nump,Mat Smat) 1077 { 1078 PetscErrorCode ierr; 1079 1080 PetscFunctionBegin; 1081 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1082 PetscValidHeaderSpecific(Smat,MAT_CLASSID,3); 1083 ts->forward_solve = PETSC_TRUE; 1084 ts->num_parameters = nump; 1085 ierr = PetscObjectReference((PetscObject)Smat);CHKERRQ(ierr); 1086 ierr = MatDestroy(&ts->mat_sensip);CHKERRQ(ierr); 1087 ts->mat_sensip = Smat; 1088 PetscFunctionReturn(0); 1089 } 1090 1091 /*@ 1092 TSForwardGetSensitivities - Returns the trajectory sensitivities 1093 1094 Not Collective, but Vec returned is parallel if TS is parallel 1095 1096 Output Parameter: 1097 + ts - the TS context obtained from TSCreate() 1098 . nump - number of parameters 1099 - Smat - sensitivities with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 1100 1101 Level: intermediate 1102 1103 .keywords: TS, forward sensitivity 1104 1105 .seealso: TSForwardSetSensitivities(), TSForwardSetIntegralGradients(), TSForwardGetIntegralGradients(), TSForwardStep() 1106 @*/ 1107 PetscErrorCode TSForwardGetSensitivities(TS ts,PetscInt *nump,Mat *Smat) 1108 { 1109 PetscFunctionBegin; 1110 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1111 if (nump) *nump = ts->num_parameters; 1112 if (Smat) *Smat = ts->mat_sensip; 1113 PetscFunctionReturn(0); 1114 } 1115 1116 /*@ 1117 TSForwardCostIntegral - Evaluate the cost integral in the forward run. 1118 1119 Collective on TS 1120 1121 Input Arguments: 1122 . ts - time stepping context 1123 1124 Level: advanced 1125 1126 Notes: 1127 This function cannot be called until TSStep() has been completed. 1128 1129 .seealso: TSSolve(), TSAdjointCostIntegral() 1130 @*/ 1131 PetscErrorCode TSForwardCostIntegral(TS ts) 1132 { 1133 PetscErrorCode ierr; 1134 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1135 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); 1136 ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr); 1137 PetscFunctionReturn(0); 1138 } 1139