Date: 2022-08-02T03:14:59+00:00

Actual source code: traj.c

      1: #include <petsc/private/tsimpl.h>
      2: #include <petsc/private/tshistoryimpl.h>
      3: #include <petscdm.h>

      5: PetscFunctionList TSTrajectoryList              = NULL;
      6: PetscBool         TSTrajectoryRegisterAllCalled = PETSC_FALSE;
      7: PetscClassId      TSTRAJECTORY_CLASSID;
      8: PetscLogEvent     TSTrajectory_Set, TSTrajectory_Get, TSTrajectory_GetVecs, TSTrajectory_SetUp;

     10: /*@C
     11:   TSTrajectoryRegister - Adds a way of storing trajectories to the TS package

     13:   Not Collective

     15:   Input Parameters:
     16: + name        - the name of a new user-defined creation routine
     17: - create_func - the creation routine itself

     19:   Notes:
     20:   TSTrajectoryRegister() may be called multiple times to add several user-defined tses.

     22:   Level: developer

     24: .seealso: TSTrajectoryRegisterAll()
     25: @*/
     26: PetscErrorCode TSTrajectoryRegister(const char sname[],PetscErrorCode (*function)(TSTrajectory,TS))
     27: {
     28:   PetscFunctionListAdd(&TSTrajectoryList,sname,function);
     29:   return 0;
     30: }

     32: /*@
     33:   TSTrajectorySet - Sets a vector of state in the trajectory object

     35:   Collective on TSTrajectory

     37:   Input Parameters:
     38: + tj      - the trajectory object
     39: . ts      - the time stepper object (optional)
     40: . stepnum - the step number
     41: . time    - the current time
     42: - X       - the current solution

     44:   Level: developer

     46:   Notes: Usually one does not call this routine, it is called automatically during TSSolve()

     48: .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectoryGet(), TSTrajectoryGetVecs()
     49: @*/
     50: PetscErrorCode TSTrajectorySet(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal time,Vec X)
     51: {
     52:   if (!tj) return 0;
     60:   if (tj->monitor) {
     61:     PetscViewerASCIIPrintf(tj->monitor,"TSTrajectorySet: stepnum %D, time %g (stages %D)\n",stepnum,(double)time,(PetscInt)!tj->solution_only);
     62:   }
     63:   PetscLogEventBegin(TSTrajectory_Set,tj,ts,0,0);
     64:   (*tj->ops->set)(tj,ts,stepnum,time,X);
     65:   PetscLogEventEnd(TSTrajectory_Set,tj,ts,0,0);
     66:   if (tj->usehistory) {
     67:     TSHistoryUpdate(tj->tsh,stepnum,time);
     68:   }
     69:   if (tj->lag.caching) tj->lag.Udotcached.time = PETSC_MIN_REAL;
     70:   return 0;
     71: }

     73: /*@
     74:   TSTrajectoryGetNumSteps - Return the number of steps registered in the TSTrajectory via TSTrajectorySet().

     76:   Not collective.

     78:   Input Parameters:
     79: . tj - the trajectory object

     81:   Output Parameter:
     82: . steps - the number of steps

     84:   Level: developer

     86: .seealso: TSTrajectorySet()
     87: @*/
     88: PetscErrorCode TSTrajectoryGetNumSteps(TSTrajectory tj, PetscInt *steps)
     89: {
     92:   TSHistoryGetNumSteps(tj->tsh,steps);
     93:   return 0;
     94: }

     96: /*@
     97:   TSTrajectoryGet - Updates the solution vector of a time stepper object by inquiring the TSTrajectory

     99:   Collective on TS

    101:   Input Parameters:
    102: + tj      - the trajectory object
    103: . ts      - the time stepper object
    104: - stepnum - the step number

    106:   Output Parameter:
    107: . time    - the time associated with the step number

    109:   Level: developer

    111:   Notes: Usually one does not call this routine, it is called automatically during TSSolve()

    113: .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectorySet(), TSTrajectoryGetVecs(), TSGetSolution()
    114: @*/
    115: PetscErrorCode TSTrajectoryGet(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal *time)
    116: {
    125:   if (tj->monitor) {
    126:     PetscViewerASCIIPrintf(tj->monitor,"TSTrajectoryGet: stepnum %D, stages %D\n",stepnum,(PetscInt)!tj->solution_only);
    127:     PetscViewerFlush(tj->monitor);
    128:   }
    129:   PetscLogEventBegin(TSTrajectory_Get,tj,ts,0,0);
    130:   (*tj->ops->get)(tj,ts,stepnum,time);
    131:   PetscLogEventEnd(TSTrajectory_Get,tj,ts,0,0);
    132:   return 0;
    133: }

    135: /*@
    136:   TSTrajectoryGetVecs - Reconstructs the vector of state and its time derivative using information from the TSTrajectory and, possibly, from the TS

    138:   Collective on TS

    140:   Input Parameters:
    141: + tj      - the trajectory object
    142: . ts      - the time stepper object (optional)
    143: - stepnum - the requested step number

    145:   Input/Output Parameter:

    147:   Output Parameters:
    148: + time - On input time for the step if step number is PETSC_DECIDE, on output the time associated with the step number
    149: . U    - state vector (can be NULL)
    150: - Udot - time derivative of state vector (can be NULL)

    152:   Level: developer

    154:   Notes: If the step number is PETSC_DECIDE, the time argument is used to inquire the trajectory.
    155:          If the requested time does not match any in the trajectory, Lagrangian interpolations are returned.

    157: .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectorySet(), TSTrajectoryGet()
    158: @*/
    159: PetscErrorCode TSTrajectoryGetVecs(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal *time,Vec U,Vec Udot)
    160: {
    168:   if (!U && !Udot) return 0;
    170:   PetscLogEventBegin(TSTrajectory_GetVecs,tj,ts,0,0);
    171:   if (tj->monitor) {
    172:     PetscInt pU,pUdot;
    173:     pU    = U ? 1 : 0;
    174:     pUdot = Udot ? 1 : 0;
    175:     PetscViewerASCIIPrintf(tj->monitor,"Requested by GetVecs %D %D: stepnum %D, time %g\n",pU,pUdot,stepnum,(double)*time);
    176:     PetscViewerFlush(tj->monitor);
    177:   }
    178:   if (U && tj->lag.caching) {
    179:     PetscObjectId    id;
    180:     PetscObjectState state;

    182:     PetscObjectStateGet((PetscObject)U,&state);
    183:     PetscObjectGetId((PetscObject)U,&id);
    184:     if (stepnum == PETSC_DECIDE) {
    185:       if (id == tj->lag.Ucached.id && *time == tj->lag.Ucached.time && state == tj->lag.Ucached.state) U = NULL;
    186:     } else {
    187:       if (id == tj->lag.Ucached.id && stepnum == tj->lag.Ucached.step && state == tj->lag.Ucached.state) U = NULL;
    188:     }
    189:     if (tj->monitor && !U) {
    190:       PetscViewerASCIIPushTab(tj->monitor);
    191:       PetscViewerASCIIPrintf(tj->monitor,"State vector cached\n");
    192:       PetscViewerASCIIPopTab(tj->monitor);
    193:       PetscViewerFlush(tj->monitor);
    194:     }
    195:   }
    196:   if (Udot && tj->lag.caching) {
    197:     PetscObjectId    id;
    198:     PetscObjectState state;

    200:     PetscObjectStateGet((PetscObject)Udot,&state);
    201:     PetscObjectGetId((PetscObject)Udot,&id);
    202:     if (stepnum == PETSC_DECIDE) {
    203:       if (id == tj->lag.Udotcached.id && *time == tj->lag.Udotcached.time && state == tj->lag.Udotcached.state) Udot = NULL;
    204:     } else {
    205:       if (id == tj->lag.Udotcached.id && stepnum == tj->lag.Udotcached.step && state == tj->lag.Udotcached.state) Udot = NULL;
    206:     }
    207:     if (tj->monitor && !Udot) {
    208:       PetscViewerASCIIPushTab(tj->monitor);
    209:       PetscViewerASCIIPrintf(tj->monitor,"Derivative vector cached\n");
    210:       PetscViewerASCIIPopTab(tj->monitor);
    211:       PetscViewerFlush(tj->monitor);
    212:     }
    213:   }
    214:   if (!U && !Udot) {
    215:     PetscLogEventEnd(TSTrajectory_GetVecs,tj,ts,0,0);
    216:     return 0;
    217:   }

    219:   if (stepnum == PETSC_DECIDE || Udot) { /* reverse search for requested time in TSHistory */
    220:     if (tj->monitor) {
    221:       PetscViewerASCIIPushTab(tj->monitor);
    222:     }
    223:     /* cached states will be updated in the function */
    224:     TSTrajectoryReconstruct_Private(tj,ts,*time,U,Udot);
    225:     if (tj->monitor) {
    226:       PetscViewerASCIIPopTab(tj->monitor);
    227:       PetscViewerFlush(tj->monitor);
    228:     }
    229:   } else if (U) { /* we were asked to load from stepnum, use TSTrajectoryGet */
    230:     TS  fakets = ts;
    231:     Vec U2;

    233:     /* use a fake TS if ts is missing */
    234:     if (!ts) {
    235:       PetscObjectQuery((PetscObject)tj,"__fake_ts",(PetscObject*)&fakets);
    236:       if (!fakets) {
    237:         TSCreate(PetscObjectComm((PetscObject)tj),&fakets);
    238:         PetscObjectCompose((PetscObject)tj,"__fake_ts",(PetscObject)fakets);
    239:         PetscObjectDereference((PetscObject)fakets);
    240:         VecDuplicate(U,&U2);
    241:         TSSetSolution(fakets,U2);
    242:         PetscObjectDereference((PetscObject)U2);
    243:       }
    244:     }
    245:     TSTrajectoryGet(tj,fakets,stepnum,time);
    246:     TSGetSolution(fakets,&U2);
    247:     VecCopy(U2,U);
    248:     PetscObjectStateGet((PetscObject)U,&tj->lag.Ucached.state);
    249:     PetscObjectGetId((PetscObject)U,&tj->lag.Ucached.id);
    250:     tj->lag.Ucached.time = *time;
    251:     tj->lag.Ucached.step = stepnum;
    252:   }
    253:   PetscLogEventEnd(TSTrajectory_GetVecs,tj,ts,0,0);
    254:   return 0;
    255: }

    257: /*@C
    258:    TSTrajectoryViewFromOptions - View from Options

    260:    Collective on TSTrajectory

    262:    Input Parameters:
    263: +  A - the TSTrajectory context
    264: .  obj - Optional object
    265: -  name - command line option

    267:    Level: intermediate
    268: .seealso:  TSTrajectory, TSTrajectoryView, PetscObjectViewFromOptions(), TSTrajectoryCreate()
    269: @*/
    270: PetscErrorCode  TSTrajectoryViewFromOptions(TSTrajectory A,PetscObject obj,const char name[])
    271: {
    273:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
    274:   return 0;
    275: }

    277: /*@C
    278:     TSTrajectoryView - Prints information about the trajectory object

    280:     Collective on TSTrajectory

    282:     Input Parameters:
    283: +   tj - the TSTrajectory context obtained from TSTrajectoryCreate()
    284: -   viewer - visualization context

    286:     Options Database Key:
    287: .   -ts_trajectory_view - calls TSTrajectoryView() at end of TSAdjointStep()

    289:     Notes:
    290:     The available visualization contexts include
    291: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    292: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    293:          output where only the first processor opens
    294:          the file.  All other processors send their
    295:          data to the first processor to print.

    297:     The user can open an alternative visualization context with
    298:     PetscViewerASCIIOpen() - output to a specified file.

    300:     Level: developer

    302: .seealso: PetscViewerASCIIOpen()
    303: @*/
    304: PetscErrorCode  TSTrajectoryView(TSTrajectory tj,PetscViewer viewer)
    305: {
    306:   PetscBool      iascii;

    309:   if (!viewer) {
    310:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)tj),&viewer);
    311:   }

    315:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    316:   if (iascii) {
    317:     PetscObjectPrintClassNamePrefixType((PetscObject)tj,viewer);
    318:     PetscViewerASCIIPrintf(viewer,"  total number of recomputations for adjoint calculation = %D\n",tj->recomps);
    319:     PetscViewerASCIIPrintf(viewer,"  disk checkpoint reads = %D\n",tj->diskreads);
    320:     PetscViewerASCIIPrintf(viewer,"  disk checkpoint writes = %D\n",tj->diskwrites);
    321:     if (tj->ops->view) {
    322:       PetscViewerASCIIPushTab(viewer);
    323:       (*tj->ops->view)(tj,viewer);
    324:       PetscViewerASCIIPopTab(viewer);
    325:     }
    326:   }
    327:   return 0;
    328: }

    330: /*@C
    331:    TSTrajectorySetVariableNames - Sets the name of each component in the solution vector so that it may be saved with the trajectory

    333:    Collective on TSTrajectory

    335:    Input Parameters:
    336: +  tr - the trajectory context
    337: -  names - the names of the components, final string must be NULL

    339:    Level: intermediate

    341:    Note: Fortran interface is not possible because of the string array argument

    343: .seealso: TSTrajectory, TSGetTrajectory()
    344: @*/
    345: PetscErrorCode  TSTrajectorySetVariableNames(TSTrajectory ctx,const char * const *names)
    346: {
    349:   PetscStrArrayDestroy(&ctx->names);
    350:   PetscStrArrayallocpy(names,&ctx->names);
    351:   return 0;
    352: }

    354: /*@C
    355:    TSTrajectorySetTransform - Solution vector will be transformed by provided function before being saved to disk

    357:    Collective on TSLGCtx

    359:    Input Parameters:
    360: +  tj - the TSTrajectory context
    361: .  transform - the transform function
    362: .  destroy - function to destroy the optional context
    363: -  ctx - optional context used by transform function

    365:    Level: intermediate

    367: .seealso:  TSTrajectorySetVariableNames(), TSTrajectory, TSMonitorLGSetTransform()
    368: @*/
    369: PetscErrorCode  TSTrajectorySetTransform(TSTrajectory tj,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
    370: {
    372:   tj->transform        = transform;
    373:   tj->transformdestroy = destroy;
    374:   tj->transformctx     = tctx;
    375:   return 0;
    376: }

    378: /*@
    379:   TSTrajectoryCreate - This function creates an empty trajectory object used to store the time dependent solution of an ODE/DAE

    381:   Collective

    383:   Input Parameter:
    384: . comm - the communicator

    386:   Output Parameter:
    387: . tj   - the trajectory object

    389:   Level: developer

    391:   Notes:
    392:     Usually one does not call this routine, it is called automatically when one calls TSSetSaveTrajectory().

    394: .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectorySetKeepFiles()
    395: @*/
    396: PetscErrorCode  TSTrajectoryCreate(MPI_Comm comm,TSTrajectory *tj)
    397: {
    398:   TSTrajectory   t;

    401:   *tj = NULL;
    402:   TSInitializePackage();

    404:   PetscHeaderCreate(t,TSTRAJECTORY_CLASSID,"TSTrajectory","Time stepping","TS",comm,TSTrajectoryDestroy,TSTrajectoryView);
    405:   t->setupcalled = PETSC_FALSE;
    406:   TSHistoryCreate(comm,&t->tsh);

    408:   t->lag.order            = 1;
    409:   t->lag.L                = NULL;
    410:   t->lag.T                = NULL;
    411:   t->lag.W                = NULL;
    412:   t->lag.WW               = NULL;
    413:   t->lag.TW               = NULL;
    414:   t->lag.TT               = NULL;
    415:   t->lag.caching          = PETSC_TRUE;
    416:   t->lag.Ucached.id       = 0;
    417:   t->lag.Ucached.state    = -1;
    418:   t->lag.Ucached.time     = PETSC_MIN_REAL;
    419:   t->lag.Ucached.step     = PETSC_MAX_INT;
    420:   t->lag.Udotcached.id    = 0;
    421:   t->lag.Udotcached.state = -1;
    422:   t->lag.Udotcached.time  = PETSC_MIN_REAL;
    423:   t->lag.Udotcached.step  = PETSC_MAX_INT;
    424:   t->adjoint_solve_mode   = PETSC_TRUE;
    425:   t->solution_only        = PETSC_FALSE;
    426:   t->keepfiles            = PETSC_FALSE;
    427:   t->usehistory           = PETSC_TRUE;
    428:   *tj  = t;
    429:   TSTrajectorySetFiletemplate(t,"TS-%06D.bin");
    430:   return 0;
    431: }

    433: /*@C
    434:   TSTrajectorySetType - Sets the storage method to be used as in a trajectory

    436:   Collective on TS

    438:   Input Parameters:
    439: + tj   - the TSTrajectory context
    440: . ts   - the TS context
    441: - type - a known method

    443:   Options Database Command:
    444: . -ts_trajectory_type <type> - Sets the method; use -help for a list of available methods (for instance, basic)

    446:    Level: developer

    448: .seealso: TS, TSTrajectoryCreate(), TSTrajectorySetFromOptions(), TSTrajectoryDestroy(), TSTrajectoryGetType()

    450: @*/
    451: PetscErrorCode  TSTrajectorySetType(TSTrajectory tj,TS ts,TSTrajectoryType type)
    452: {
    453:   PetscErrorCode (*r)(TSTrajectory,TS);
    454:   PetscBool      match;

    457:   PetscObjectTypeCompare((PetscObject)tj,type,&match);
    458:   if (match) return 0;

    460:   PetscFunctionListFind(TSTrajectoryList,type,&r);
    462:   if (tj->ops->destroy) {
    463:     (*(tj)->ops->destroy)(tj);

    465:     tj->ops->destroy = NULL;
    466:   }
    467:   PetscMemzero(tj->ops,sizeof(*tj->ops));

    469:   PetscObjectChangeTypeName((PetscObject)tj,type);
    470:   (*r)(tj,ts);
    471:   return 0;
    472: }

    474: /*@C
    475:   TSTrajectoryGetType - Gets the trajectory type

    477:   Collective on TS

    479:   Input Parameters:
    480: + tj   - the TSTrajectory context
    481: - ts   - the TS context

    483:   Output Parameters:
    484: . type - a known method

    486:   Level: developer

    488: .seealso: TS, TSTrajectoryCreate(), TSTrajectorySetFromOptions(), TSTrajectoryDestroy(), TSTrajectorySetType()

    490: @*/
    491: PetscErrorCode TSTrajectoryGetType(TSTrajectory tj,TS ts,TSTrajectoryType *type)
    492: {
    494:   if (type) *type = ((PetscObject)tj)->type_name;
    495:   return 0;
    496: }

    498: PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Basic(TSTrajectory,TS);
    499: PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Singlefile(TSTrajectory,TS);
    500: PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Memory(TSTrajectory,TS);
    501: PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Visualization(TSTrajectory,TS);

    503: /*@C
    504:   TSTrajectoryRegisterAll - Registers all of the trajectory storage schecmes in the TS package.

    506:   Not Collective

    508:   Level: developer

    510: .seealso: TSTrajectoryRegister()
    511: @*/
    512: PetscErrorCode  TSTrajectoryRegisterAll(void)
    513: {
    514:   if (TSTrajectoryRegisterAllCalled) return 0;
    515:   TSTrajectoryRegisterAllCalled = PETSC_TRUE;

    517:   TSTrajectoryRegister(TSTRAJECTORYBASIC,TSTrajectoryCreate_Basic);
    518:   TSTrajectoryRegister(TSTRAJECTORYSINGLEFILE,TSTrajectoryCreate_Singlefile);
    519:   TSTrajectoryRegister(TSTRAJECTORYMEMORY,TSTrajectoryCreate_Memory);
    520:   TSTrajectoryRegister(TSTRAJECTORYVISUALIZATION,TSTrajectoryCreate_Visualization);
    521:   return 0;
    522: }

    524: /*@
    525:    TSTrajectoryReset - Resets a trajectory context

    527:    Collective on TSTrajectory

    529:    Input Parameter:
    530: .  tj - the TSTrajectory context obtained from TSTrajectoryCreate()

    532:    Level: developer

    534: .seealso: TSTrajectoryCreate(), TSTrajectorySetUp()
    535: @*/
    536: PetscErrorCode TSTrajectoryReset(TSTrajectory tj)
    537: {
    538:   if (!tj) return 0;
    540:   if (tj->ops->reset) {
    541:     (*tj->ops->reset)(tj);
    542:   }
    543:   PetscFree(tj->dirfiletemplate);
    544:   TSHistoryDestroy(&tj->tsh);
    545:   TSHistoryCreate(PetscObjectComm((PetscObject)tj),&tj->tsh);
    546:   tj->setupcalled = PETSC_FALSE;
    547:   return 0;
    548: }

    550: /*@
    551:    TSTrajectoryDestroy - Destroys a trajectory context

    553:    Collective on TSTrajectory

    555:    Input Parameter:
    556: .  tj - the TSTrajectory context obtained from TSTrajectoryCreate()

    558:    Level: developer

    560: .seealso: TSTrajectoryCreate(), TSTrajectorySetUp()
    561: @*/
    562: PetscErrorCode TSTrajectoryDestroy(TSTrajectory *tj)
    563: {
    564:   if (!*tj) return 0;
    566:   if (--((PetscObject)(*tj))->refct > 0) {*tj = NULL; return 0;}

    568:   TSTrajectoryReset(*tj);
    569:   TSHistoryDestroy(&(*tj)->tsh);
    570:   VecDestroyVecs((*tj)->lag.order+1,&(*tj)->lag.W);
    571:   PetscFree5((*tj)->lag.L,(*tj)->lag.T,(*tj)->lag.WW,(*tj)->lag.TT,(*tj)->lag.TW);
    572:   VecDestroy(&(*tj)->U);
    573:   VecDestroy(&(*tj)->Udot);

    575:   if ((*tj)->transformdestroy) (*(*tj)->transformdestroy)((*tj)->transformctx);
    576:   if ((*tj)->ops->destroy) (*(*tj)->ops->destroy)((*tj));
    577:   if (!((*tj)->keepfiles)) {
    578:     PetscMPIInt rank;
    579:     MPI_Comm    comm;

    581:     PetscObjectGetComm((PetscObject)(*tj),&comm);
    582:     MPI_Comm_rank(comm,&rank);
    583:     if (rank == 0 && (*tj)->dirname) { /* we own the directory, so we run PetscRMTree on it */
    584:       PetscRMTree((*tj)->dirname);
    585:     }
    586:   }
    587:   PetscStrArrayDestroy(&(*tj)->names);
    588:   PetscFree((*tj)->dirname);
    589:   PetscFree((*tj)->filetemplate);
    590:   PetscHeaderDestroy(tj);
    591:   return 0;
    592: }

    594: /*
    595:   TSTrajectorySetTypeFromOptions_Private - Sets the type of ts from user options.

    597:   Collective on TSTrajectory

    599:   Input Parameter:
    600: + tj - the TSTrajectory context
    601: - ts - the TS context

    603:   Options Database Keys:
    604: . -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION

    606:   Level: developer

    608: .seealso: TSTrajectorySetFromOptions(), TSTrajectorySetType()
    609: */
    610: static PetscErrorCode TSTrajectorySetTypeFromOptions_Private(PetscOptionItems *PetscOptionsObject,TSTrajectory tj,TS ts)
    611: {
    612:   PetscBool      opt;
    613:   const char     *defaultType;
    614:   char           typeName[256];

    616:   if (((PetscObject)tj)->type_name) defaultType = ((PetscObject)tj)->type_name;
    617:   else defaultType = TSTRAJECTORYBASIC;

    619:   TSTrajectoryRegisterAll();
    620:   PetscOptionsFList("-ts_trajectory_type","TSTrajectory method","TSTrajectorySetType",TSTrajectoryList,defaultType,typeName,256,&opt);
    621:   if (opt) {
    622:     TSTrajectorySetType(tj,ts,typeName);
    623:   } else {
    624:     TSTrajectorySetType(tj,ts,defaultType);
    625:   }
    626:   return 0;
    627: }

    629: /*@
    630:    TSTrajectorySetUseHistory - Use TSHistory in TSTrajectory

    632:    Collective on TSTrajectory

    634:    Input Parameters:
    635: +  tj - the TSTrajectory context
    636: -  flg - PETSC_TRUE to save, PETSC_FALSE to disable

    638:    Options Database Keys:
    639: .  -ts_trajectory_use_history - have it use TSHistory

    641:    Level: advanced

    643: .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp()
    644: @*/
    645: PetscErrorCode TSTrajectorySetUseHistory(TSTrajectory tj,PetscBool flg)
    646: {
    649:   tj->usehistory = flg;
    650:   return 0;
    651: }

    653: /*@
    654:    TSTrajectorySetMonitor - Monitor the schedules generated by the checkpointing controller

    656:    Collective on TSTrajectory

    658:    Input Parameters:
    659: +  tj - the TSTrajectory context
    660: -  flg - PETSC_TRUE to active a monitor, PETSC_FALSE to disable

    662:    Options Database Keys:
    663: .  -ts_trajectory_monitor - print TSTrajectory information

    665:    Level: developer

    667: .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp()
    668: @*/
    669: PetscErrorCode TSTrajectorySetMonitor(TSTrajectory tj,PetscBool flg)
    670: {
    673:   if (flg) tj->monitor = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)tj));
    674:   else tj->monitor = NULL;
    675:   return 0;
    676: }

    678: /*@
    679:    TSTrajectorySetKeepFiles - Keep the files generated by the TSTrajectory

    681:    Collective on TSTrajectory

    683:    Input Parameters:
    684: +  tj - the TSTrajectory context
    685: -  flg - PETSC_TRUE to save, PETSC_FALSE to disable

    687:    Options Database Keys:
    688: .  -ts_trajectory_keep_files - have it keep the files

    690:    Notes:
    691:     By default the TSTrajectory used for adjoint computations, TSTRAJECTORYBASIC, removes the files it generates at the end of the run. This causes the files to be kept.

    693:    Level: advanced

    695: .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp(), TSTrajectorySetMonitor()
    696: @*/
    697: PetscErrorCode TSTrajectorySetKeepFiles(TSTrajectory tj,PetscBool flg)
    698: {
    701:   tj->keepfiles = flg;
    702:   return 0;
    703: }

    705: /*@C
    706:    TSTrajectorySetDirname - Specify the name of the directory where disk checkpoints are stored.

    708:    Collective on TSTrajectory

    710:    Input Parameters:
    711: +  tj      - the TSTrajectory context
    712: -  dirname - the directory name

    714:    Options Database Keys:
    715: .  -ts_trajectory_dirname - set the directory name

    717:    Notes:
    718:     The final location of the files is determined by dirname/filetemplate where filetemplate was provided by TSTrajectorySetFiletemplate()

    720:    Level: developer

    722: .seealso: TSTrajectorySetFiletemplate(),TSTrajectorySetUp()
    723: @*/
    724: PetscErrorCode TSTrajectorySetDirname(TSTrajectory tj,const char dirname[])
    725: {
    726:   PetscBool      flg;

    729:   PetscStrcmp(tj->dirname,dirname,&flg);
    730:   if (!flg && tj->dirfiletemplate) {
    731:     SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ARG_WRONGSTATE,"Cannot set directoryname after TSTrajectory has been setup");
    732:   }
    733:   PetscFree(tj->dirname);
    734:   PetscStrallocpy(dirname,&tj->dirname);
    735:   return 0;
    736: }

    738: /*@C
    739:    TSTrajectorySetFiletemplate - Specify the name template for the files storing checkpoints.

    741:    Collective on TSTrajectory

    743:    Input Parameters:
    744: +  tj      - the TSTrajectory context
    745: -  filetemplate - the template

    747:    Options Database Keys:
    748: .  -ts_trajectory_file_template - set the file name template

    750:    Notes:
    751:     The name template should be of the form, for example filename-%06D.bin It should not begin with a leading /

    753:    The final location of the files is determined by dirname/filetemplate where dirname was provided by TSTrajectorySetDirname(). The %06D is replaced by the
    754:    timestep counter

    756:    Level: developer

    758: .seealso: TSTrajectorySetDirname(),TSTrajectorySetUp()
    759: @*/
    760: PetscErrorCode TSTrajectorySetFiletemplate(TSTrajectory tj,const char filetemplate[])
    761: {
    762:   const char     *ptr,*ptr2;

    768:   /* Do some cursory validation of the input. */
    769:   PetscStrstr(filetemplate,"%",(char**)&ptr);
    771:   for (ptr++; ptr && *ptr; ptr++) {
    772:     PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);
    774:     if (ptr2) break;
    775:   }
    776:   PetscFree(tj->filetemplate);
    777:   PetscStrallocpy(filetemplate,&tj->filetemplate);
    778:   return 0;
    779: }

    781: /*@
    782:    TSTrajectorySetFromOptions - Sets various TSTrajectory parameters from user options.

    784:    Collective on TSTrajectory

    786:    Input Parameters:
    787: +  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
    788: -  ts - the TS context

    790:    Options Database Keys:
    791: +  -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
    792: .  -ts_trajectory_keep_files <true,false> - keep the files generated by the code after the program ends. This is true by default for TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
    793: -  -ts_trajectory_monitor - print TSTrajectory information

    795:    Level: developer

    797:    Notes:
    798:     This is not normally called directly by users

    800: .seealso: TSSetSaveTrajectory(), TSTrajectorySetUp()
    801: @*/
    802: PetscErrorCode  TSTrajectorySetFromOptions(TSTrajectory tj,TS ts)
    803: {
    804:   PetscBool      set,flg;
    805:   char           dirname[PETSC_MAX_PATH_LEN],filetemplate[PETSC_MAX_PATH_LEN];

    810:   PetscObjectOptionsBegin((PetscObject)tj);
    811:   TSTrajectorySetTypeFromOptions_Private(PetscOptionsObject,tj,ts);
    812:   PetscOptionsBool("-ts_trajectory_use_history","Turn on/off usage of TSHistory",NULL,tj->usehistory,&tj->usehistory,NULL);
    813:   PetscOptionsBool("-ts_trajectory_monitor","Print checkpointing schedules","TSTrajectorySetMonitor",tj->monitor ? PETSC_TRUE:PETSC_FALSE,&flg,&set);
    814:   if (set) TSTrajectorySetMonitor(tj,flg);
    815:   PetscOptionsInt("-ts_trajectory_reconstruction_order","Interpolation order for reconstruction",NULL,tj->lag.order,&tj->lag.order,NULL);
    816:   PetscOptionsBool("-ts_trajectory_reconstruction_caching","Turn on/off caching of TSTrajectoryGetVecs input",NULL,tj->lag.caching,&tj->lag.caching,NULL);
    817:   PetscOptionsBool("-ts_trajectory_adjointmode","Instruct the trajectory that will be used in a TSAdjointSolve()",NULL,tj->adjoint_solve_mode,&tj->adjoint_solve_mode,NULL);
    818:   PetscOptionsBool("-ts_trajectory_solution_only","Checkpoint solution only","TSTrajectorySetSolutionOnly",tj->solution_only,&tj->solution_only,NULL);
    819:   PetscOptionsBool("-ts_trajectory_keep_files","Keep any trajectory files generated during the run","TSTrajectorySetKeepFiles",tj->keepfiles,&flg,&set);
    820:   if (set) TSTrajectorySetKeepFiles(tj,flg);

    822:   PetscOptionsString("-ts_trajectory_dirname","Directory name for TSTrajectory file","TSTrajectorySetDirname",NULL,dirname,sizeof(dirname)-14,&set);
    823:   if (set) {
    824:     TSTrajectorySetDirname(tj,dirname);
    825:   }

    827:   PetscOptionsString("-ts_trajectory_file_template","Template for TSTrajectory file name, use filename-%06D.bin","TSTrajectorySetFiletemplate",NULL,filetemplate,sizeof(filetemplate),&set);
    828:   if (set) {
    829:     TSTrajectorySetFiletemplate(tj,filetemplate);
    830:   }

    832:   /* Handle specific TSTrajectory options */
    833:   if (tj->ops->setfromoptions) {
    834:     (*tj->ops->setfromoptions)(PetscOptionsObject,tj);
    835:   }
    836:   PetscOptionsEnd();
    837:   return 0;
    838: }

    840: /*@
    841:    TSTrajectorySetUp - Sets up the internal data structures, e.g. stacks, for the later use
    842:    of a TS trajectory.

    844:    Collective on TS

    846:    Input Parameters:
    847: +  ts - the TS context obtained from TSCreate()
    848: -  tj - the TS trajectory context

    850:    Level: developer

    852: .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy()
    853: @*/
    854: PetscErrorCode  TSTrajectorySetUp(TSTrajectory tj,TS ts)
    855: {
    856:   size_t         s1,s2;

    858:   if (!tj) return 0;
    861:   if (tj->setupcalled) return 0;

    863:   PetscLogEventBegin(TSTrajectory_SetUp,tj,ts,0,0);
    864:   if (!((PetscObject)tj)->type_name) {
    865:     TSTrajectorySetType(tj,ts,TSTRAJECTORYBASIC);
    866:   }
    867:   if (tj->ops->setup) {
    868:     (*tj->ops->setup)(tj,ts);
    869:   }

    871:   tj->setupcalled = PETSC_TRUE;

    873:   /* Set the counters to zero */
    874:   tj->recomps    = 0;
    875:   tj->diskreads  = 0;
    876:   tj->diskwrites = 0;
    877:   PetscStrlen(tj->dirname,&s1);
    878:   PetscStrlen(tj->filetemplate,&s2);
    879:   PetscFree(tj->dirfiletemplate);
    880:   PetscMalloc((s1 + s2 + 10)*sizeof(char),&tj->dirfiletemplate);
    881:   PetscSNPrintf(tj->dirfiletemplate,s1+s2+10,"%s/%s",tj->dirname,tj->filetemplate);
    882:   PetscLogEventEnd(TSTrajectory_SetUp,tj,ts,0,0);
    883:   return 0;
    884: }

    886: /*@
    887:    TSTrajectorySetSolutionOnly - Tells the trajectory to store just the solution, and not any intermediate stage also.

    889:    Collective on TSTrajectory

    891:    Input Parameters:
    892: +  tj  - the TS trajectory context
    893: -  flg - the boolean flag

    895:    Level: developer

    897: .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectoryGetSolutionOnly()
    898: @*/
    899: PetscErrorCode TSTrajectorySetSolutionOnly(TSTrajectory tj,PetscBool solution_only)
    900: {
    903:   tj->solution_only = solution_only;
    904:   return 0;
    905: }

    907: /*@
    908:    TSTrajectoryGetSolutionOnly - Gets the value set with TSTrajectorySetSolutionOnly.

    910:    Logically collective on TSTrajectory

    912:    Input Parameter:
    913: .  tj  - the TS trajectory context

    915:    Output Parameter:
    916: .  flg - the boolean flag

    918:    Level: developer

    920: .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetSolutionOnly()
    921: @*/
    922: PetscErrorCode TSTrajectoryGetSolutionOnly(TSTrajectory tj,PetscBool *solution_only)
    923: {
    926:   *solution_only = tj->solution_only;
    927:   return 0;
    928: }

    930: /*@
    931:    TSTrajectoryGetUpdatedHistoryVecs - Get updated state and time-derivative history vectors.

    933:    Collective on TSTrajectory

    935:    Input Parameters:
    936: +  tj   - the TS trajectory context
    937: .  ts   - the TS solver context
    938: -  time - the requested time

    940:    Output Parameters:
    941: +  U    - state vector at given time (can be interpolated)
    942: -  Udot - time-derivative vector at given time (can be interpolated)

    944:    Level: developer

    946:    Notes: The vectors are interpolated if time does not match any time step stored in the TSTrajectory(). Pass NULL to not request a vector.
    947:           This function differs from TSTrajectoryGetVecs since the vectors obtained cannot be modified, and they need to be returned by
    948:           calling TSTrajectoryRestoreUpdatedHistoryVecs().

    950: .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectoryRestoreUpdatedHistoryVecs(), TSTrajectoryGetVecs()
    951: @*/
    952: PetscErrorCode TSTrajectoryGetUpdatedHistoryVecs(TSTrajectory tj, TS ts, PetscReal time, Vec *U, Vec *Udot)
    953: {
    959:   if (U && !tj->U) {
    960:     DM dm;

    962:     TSGetDM(ts,&dm);
    963:     DMCreateGlobalVector(dm,&tj->U);
    964:   }
    965:   if (Udot && !tj->Udot) {
    966:     DM dm;

    968:     TSGetDM(ts,&dm);
    969:     DMCreateGlobalVector(dm,&tj->Udot);
    970:   }
    971:   TSTrajectoryGetVecs(tj,ts,PETSC_DECIDE,&time,U ? tj->U : NULL,Udot ? tj->Udot : NULL);
    972:   if (U) {
    973:     VecLockReadPush(tj->U);
    974:     *U   = tj->U;
    975:   }
    976:   if (Udot) {
    977:     VecLockReadPush(tj->Udot);
    978:     *Udot = tj->Udot;
    979:   }
    980:   return 0;
    981: }

    983: /*@
    984:    TSTrajectoryRestoreUpdatedHistoryVecs - Restores updated state and time-derivative history vectors obtained with TSTrajectoryGetUpdatedHistoryVecs().

    986:    Collective on TSTrajectory

    988:    Input Parameters:
    989: +  tj   - the TS trajectory context
    990: .  U    - state vector at given time (can be interpolated)
    991: -  Udot - time-derivative vector at given time (can be interpolated)

    993:    Level: developer

    995: .seealso: TSTrajectoryGetUpdatedHistoryVecs()
    996: @*/
    997: PetscErrorCode TSTrajectoryRestoreUpdatedHistoryVecs(TSTrajectory tj, Vec *U, Vec *Udot)
    998: {
    1004:   if (U) {
    1005:     VecLockReadPop(tj->U);
    1006:     *U   = NULL;
    1007:   }
    1008:   if (Udot) {
    1009:     VecLockReadPop(tj->Udot);
    1010:     *Udot = NULL;
    1011:   }
    1012:   return 0;
    1013: }