Actual source code: ts.c

petsc-3.7.3 2016-08-01
Report Typos and Errors
  2: #include <petsc/private/tsimpl.h>        /*I "petscts.h"  I*/
  3: #include <petscdmshell.h>
  4: #include <petscdmda.h>
  5: #include <petscviewer.h>
  6: #include <petscdraw.h>

  8: /* Logging support */
  9: PetscClassId  TS_CLASSID, DMTS_CLASSID;
 10: PetscLogEvent TS_AdjointStep, TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;

 12: const char *const TSExactFinalTimeOptions[] = {"UNSPECIFIED","STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",0};

 14: struct _n_TSMonitorDrawCtx {
 15:   PetscViewer   viewer;
 16:   Vec           initialsolution;
 17:   PetscBool     showinitial;
 18:   PetscInt      howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
 19:   PetscBool     showtimestepandtime;
 20: };

 24: /*@C
 25:    TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user

 27:    Collective on TS

 29:    Input Parameters:
 30: +  ts - TS object you wish to monitor
 31: .  name - the monitor type one is seeking
 32: .  help - message indicating what monitoring is done
 33: .  manual - manual page for the monitor
 34: .  monitor - the monitor function
 35: -  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

 37:    Level: developer

 39: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
 40:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
 41:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
 42:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
 43:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
 44:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
 45:           PetscOptionsFList(), PetscOptionsEList()
 46: @*/
 47: PetscErrorCode  TSMonitorSetFromOptions(TS ts,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(TS,PetscViewerAndFormat*))
 48: {
 49:   PetscErrorCode    ierr;
 50:   PetscViewer       viewer;
 51:   PetscViewerFormat format;
 52:   PetscBool         flg;

 55:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject)ts)->prefix,name,&viewer,&format,&flg);
 56:   if (flg) {
 57:     PetscViewerAndFormat *vf;
 58:     PetscViewerAndFormatCreate(viewer,format,&vf);
 59:     PetscObjectDereference((PetscObject)viewer);
 60:     if (monitorsetup) {
 61:       (*monitorsetup)(ts,vf);
 62:     }
 63:     TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
 64:   }
 65:   return(0);
 66: }

 70: /*@C
 71:    TSAdjointMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user

 73:    Collective on TS

 75:    Input Parameters:
 76: +  ts - TS object you wish to monitor
 77: .  name - the monitor type one is seeking
 78: .  help - message indicating what monitoring is done
 79: .  manual - manual page for the monitor
 80: .  monitor - the monitor function
 81: -  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

 83:    Level: developer

 85: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
 86:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
 87:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
 88:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
 89:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
 90:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
 91:           PetscOptionsFList(), PetscOptionsEList()
 92: @*/
 93: 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*))
 94: {
 95:   PetscErrorCode    ierr;
 96:   PetscViewer       viewer;
 97:   PetscViewerFormat format;
 98:   PetscBool         flg;

101:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject)ts)->prefix,name,&viewer,&format,&flg);
102:   if (flg) {
103:     PetscViewerAndFormat *vf;
104:     PetscViewerAndFormatCreate(viewer,format,&vf);
105:     PetscObjectDereference((PetscObject)viewer);
106:     if (monitorsetup) {
107:       (*monitorsetup)(ts,vf);
108:     }
109:     TSAdjointMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
110:   }
111:   return(0);
112: }

116: /*@
117:    TSSetFromOptions - Sets various TS parameters from user options.

119:    Collective on TS

121:    Input Parameter:
122: .  ts - the TS context obtained from TSCreate()

124:    Options Database Keys:
125: +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSALPHA, TSGL, TSSSP
126: .  -ts_save_trajectory - checkpoint the solution at each time-step
127: .  -ts_max_steps <maxsteps> - maximum number of time-steps to take
128: .  -ts_final_time <time> - maximum time to compute to
129: .  -ts_dt <dt> - initial time step
130: .  -ts_exact_final_time <stepover,interpolate,matchstep> whether to stop at the exact given final time and how to compute the solution at that ti,e
131: .  -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed
132: .  -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails
133: .  -ts_error_if_step_fails <true,false> - Error if no step succeeds
134: .  -ts_rtol <rtol> - relative tolerance for local truncation error
135: .  -ts_atol <atol> Absolute tolerance for local truncation error
136: .  -ts_adjoint_solve <yes,no> After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory)
137: .  -ts_fd_color - Use finite differences with coloring to compute IJacobian
138: .  -ts_monitor - print information at each timestep
139: .  -ts_monitor_lg_solution - Monitor solution graphically
140: .  -ts_monitor_lg_error - Monitor error graphically
141: .  -ts_monitor_lg_timestep - Monitor timestep size graphically
142: .  -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically
143: .  -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically
144: .  -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically
145: .  -ts_monitor_draw_solution - Monitor solution graphically
146: .  -ts_monitor_draw_solution_phase  <xleft,yleft,xright,yright> - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom
147: .  -ts_monitor_draw_error - Monitor error graphically, requires use to have provided TSSetSolutionFunction()
148: .  -ts_monitor_solution [ascii binary draw][:filename][:viewerformat] - monitors the solution at each timestep
149: .  -ts_monitor_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts
150: .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
151: .  -ts_adjoint_monitor - print information at each adjoint time step
152: -  -ts_adjoint_monitor_draw_sensi - monitor the sensitivity of the first cost function wrt initial conditions (lambda[0]) graphically

154:    Developer Note: We should unify all the -ts_monitor options in the way that -xxx_view has been unified

156:    Level: beginner

158: .keywords: TS, timestep, set, options, database

160: .seealso: TSGetType()
161: @*/
162: PetscErrorCode  TSSetFromOptions(TS ts)
163: {
164:   PetscBool              opt,flg,tflg;
165:   PetscErrorCode         ierr;
166:   char                   monfilename[PETSC_MAX_PATH_LEN];
167:   PetscReal              time_step;
168:   TSExactFinalTimeOption eftopt;
169:   char                   dir[16];
170:   TSIFunction            ifun;
171:   const char             *defaultType;
172:   char                   typeName[256];


177:   TSRegisterAll();
178:   TSGetIFunction(ts,NULL,&ifun,NULL);

180:   PetscObjectOptionsBegin((PetscObject)ts);
181:   if (((PetscObject)ts)->type_name)
182:     defaultType = ((PetscObject)ts)->type_name;
183:   else
184:     defaultType = ifun ? TSBEULER : TSEULER;
185:   PetscOptionsFList("-ts_type","TS method","TSSetType",TSList,defaultType,typeName,256,&opt);
186:   if (opt) {
187:     TSSetType(ts,typeName);
188:   } else {
189:     TSSetType(ts,defaultType);
190:   }

192:   /* Handle generic TS options */
193:   PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,NULL);
194:   PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,NULL);
195:   PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);
196:   PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);
197:   if (flg) {TSSetTimeStep(ts,time_step);}
198:   PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg);
199:   if (flg) {TSSetExactFinalTime(ts,eftopt);}
200:   PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);
201:   PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);
202:   PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);
203:   PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);
204:   PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);

206: #if defined(PETSC_HAVE_SAWS)
207:   {
208:   PetscBool set;
209:   flg  = PETSC_FALSE;
210:   PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set);
211:   if (set) {
212:     PetscObjectSAWsSetBlock((PetscObject)ts,flg);
213:   }
214:   }
215: #endif

217:   /* Monitor options */
218:   TSMonitorSetFromOptions(ts,"-ts_monitor","Monitor time and timestep size","TSMonitorDefault",TSMonitorDefault,NULL);
219:   TSMonitorSetFromOptions(ts,"-ts_monitor_solution","View the solution at each timestep","TSMonitorSolution",TSMonitorSolution,NULL);
220:   TSAdjointMonitorSetFromOptions(ts,"-ts_adjoint_monitor","Monitor adjoint timestep size","TSAdjointMonitorDefault",TSAdjointMonitorDefault,NULL);

222:   PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
223:   if (flg) {PetscPythonMonitorSet((PetscObject)ts,monfilename);}

225:   PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);
226:   if (opt) {
227:     TSMonitorLGCtx ctx;
228:     PetscInt       howoften = 1;

230:     PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);
231:     TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);
232:     TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);
233:   }

235:   PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);
236:   if (opt) {
237:     TSMonitorLGCtx ctx;
238:     PetscInt       howoften = 1;

240:     PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);
241:     TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);
242:     TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);
243:   }

245:   PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);
246:   if (opt) {
247:     TSMonitorLGCtx ctx;
248:     PetscInt       howoften = 1;

250:     PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);
251:     TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);
252:     TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);
253:   }
254:   PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);
255:   if (opt) {
256:     TSMonitorLGCtx ctx;
257:     PetscInt       howoften = 1;

259:     PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);
260:     TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);
261:     TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);
262:   }
263:   PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);
264:   if (opt) {
265:     TSMonitorLGCtx ctx;
266:     PetscInt       howoften = 1;

268:     PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);
269:     TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);
270:     TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);
271:   }
272:   PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);
273:   if (opt) {
274:     TSMonitorSPEigCtx ctx;
275:     PetscInt          howoften = 1;

277:     PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);
278:     TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);
279:     TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);
280:   }
281:   opt  = PETSC_FALSE;
282:   PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);
283:   if (opt) {
284:     TSMonitorDrawCtx ctx;
285:     PetscInt         howoften = 1;

287:     PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);
288:     TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);
289:     TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);
290:   }
291:   opt  = PETSC_FALSE;
292:   PetscOptionsName("-ts_adjoint_monitor_draw_sensi","Monitor adjoint sensitivities (lambda only) graphically","TSAdjointMonitorDrawSensi",&opt);
293:   if (opt) {
294:     TSMonitorDrawCtx ctx;
295:     PetscInt         howoften = 1;

297:     PetscOptionsInt("-ts_adjoint_monitor_draw_sensi","Monitor adjoint sensitivities (lambda only) graphically","TSAdjointMonitorDrawSensi",howoften,&howoften,NULL);
298:     TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);
299:     TSAdjointMonitorSet(ts,TSAdjointMonitorDrawSensi,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);
300:   }
301:   opt  = PETSC_FALSE;
302:   PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);
303:   if (opt) {
304:     TSMonitorDrawCtx ctx;
305:     PetscReal        bounds[4];
306:     PetscInt         n = 4;
307:     PetscDraw        draw;
308:     PetscDrawAxis    axis;

310:     PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);
311:     if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field");
312:     TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,1,&ctx);
313:     PetscViewerDrawGetDraw(ctx->viewer,0,&draw);
314:     PetscViewerDrawGetDrawAxis(ctx->viewer,0,&axis);
315:     PetscDrawAxisSetLimits(axis,bounds[0],bounds[2],bounds[1],bounds[3]);
316:     PetscDrawAxisSetLabels(axis,"Phase Diagram","Variable 1","Variable 2");
317:     TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);
318:   }
319:   opt  = PETSC_FALSE;
320:   PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);
321:   if (opt) {
322:     TSMonitorDrawCtx ctx;
323:     PetscInt         howoften = 1;

325:     PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);
326:     TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);
327:     TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);
328:   }

330:   opt  = PETSC_FALSE;
331:   PetscOptionsString("-ts_monitor_solution_vtk","Save each time step to a binary file, use filename-%%03D.vts","TSMonitorSolutionVTK",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
332:   if (flg) {
333:     const char *ptr,*ptr2;
334:     char       *filetemplate;
335:     if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts");
336:     /* Do some cursory validation of the input. */
337:     PetscStrstr(monfilename,"%",(char**)&ptr);
338:     if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts");
339:     for (ptr++; ptr && *ptr; ptr++) {
340:       PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);
341:       if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts");
342:       if (ptr2) break;
343:     }
344:     PetscStrallocpy(monfilename,&filetemplate);
345:     TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);
346:   }

348:   PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,16,&flg);
349:   if (flg) {
350:     TSMonitorDMDARayCtx *rayctx;
351:     int                  ray = 0;
352:     DMDADirection        ddir;
353:     DM                   da;
354:     PetscMPIInt          rank;

356:     if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir);
357:     if (dir[0] == 'x') ddir = DMDA_X;
358:     else if (dir[0] == 'y') ddir = DMDA_Y;
359:     else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir);
360:     sscanf(dir+2,"%d",&ray);

362:     PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %D\n",dir[0],ray);
363:     PetscNew(&rayctx);
364:     TSGetDM(ts,&da);
365:     DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);
366:     MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);
367:     if (!rank) {
368:       PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,600,300,&rayctx->viewer);
369:     }
370:     rayctx->lgctx = NULL;
371:     TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);
372:   }
373:   PetscOptionsString("-ts_monitor_lg_dmda_ray","Display a ray of the solution","None","x=0",dir,16,&flg);
374:   if (flg) {
375:     TSMonitorDMDARayCtx *rayctx;
376:     int                 ray = 0;
377:     DMDADirection       ddir;
378:     DM                  da;
379:     PetscInt            howoften = 1;

381:     if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir);
382:     if      (dir[0] == 'x') ddir = DMDA_X;
383:     else if (dir[0] == 'y') ddir = DMDA_Y;
384:     else SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir);
385:     sscanf(dir+2, "%d", &ray);

387:     PetscInfo2(((PetscObject) ts),"Displaying LG DMDA ray %c = %D\n", dir[0], ray);
388:     PetscNew(&rayctx);
389:     TSGetDM(ts, &da);
390:     DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter);
391:     TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&rayctx->lgctx);
392:     TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy);
393:   }

395:   PetscOptionsName("-ts_monitor_envelope","Monitor maximum and minimum value of each component of the solution","TSMonitorEnvelope",&opt);
396:   if (opt) {
397:     TSMonitorEnvelopeCtx ctx;

399:     TSMonitorEnvelopeCtxCreate(ts,&ctx);
400:     TSMonitorSet(ts,TSMonitorEnvelope,ctx,(PetscErrorCode (*)(void**))TSMonitorEnvelopeCtxDestroy);
401:   }

403:   flg  = PETSC_FALSE;
404:   PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL);
405:   if (flg) {
406:     DM   dm;
407:     DMTS tdm;

409:     TSGetDM(ts, &dm);
410:     DMGetDMTS(dm, &tdm);
411:     tdm->ijacobianctx = NULL;
412:     TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, 0);
413:     PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n");
414:   }

416:   if (ts->adapt) {
417:     TSAdaptSetFromOptions(PetscOptionsObject,ts->adapt);
418:   }

420:   /* Handle specific TS options */
421:   if (ts->ops->setfromoptions) {
422:     (*ts->ops->setfromoptions)(PetscOptionsObject,ts);
423:   }

425:   /* TS trajectory must be set after TS, since it may use some TS options above */
426:   tflg = ts->trajectory ? PETSC_TRUE : PETSC_FALSE;
427:   PetscOptionsBool("-ts_save_trajectory","Save the solution at each timestep","TSSetSaveTrajectory",tflg,&tflg,NULL);
428:   if (tflg) {
429:     TSSetSaveTrajectory(ts);
430:   }
431:   tflg = ts->adjoint_solve ? PETSC_TRUE : PETSC_FALSE;
432:   PetscOptionsBool("-ts_adjoint_solve","Solve the adjoint problem immediately after solving the forward problem","",tflg,&tflg,&flg);
433:   if (flg) {
434:     TSSetSaveTrajectory(ts);
435:     ts->adjoint_solve = tflg;
436:   }

438:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
439:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ts);
440:   PetscOptionsEnd();

442:   if (ts->trajectory) {
443:     TSTrajectorySetFromOptions(ts->trajectory,ts);
444:   }

446:   TSGetSNES(ts,&ts->snes);
447:   if (ts->problem_type == TS_LINEAR) {SNESSetType(ts->snes,SNESKSPONLY);}
448:   SNESSetFromOptions(ts->snes);
449:   return(0);
450: }

454: /*@
455:    TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object

457:    Collective on TS

459:    Input Parameters:
460: .  ts - the TS context obtained from TSCreate()

462: Note: This routine should be called after all TS options have been set

464:    Level: intermediate

466: .seealso: TSGetTrajectory(), TSAdjointSolve()

468: .keywords: TS, set, checkpoint,
469: @*/
470: PetscErrorCode  TSSetSaveTrajectory(TS ts)
471: {

476:   if (!ts->trajectory) {
477:     TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);
478:     TSTrajectorySetFromOptions(ts->trajectory,ts);
479:   }
480:   return(0);
481: }

485: /*@
486:    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
487:       set with TSSetRHSJacobian().

489:    Collective on TS and Vec

491:    Input Parameters:
492: +  ts - the TS context
493: .  t - current timestep
494: -  U - input vector

496:    Output Parameters:
497: +  A - Jacobian matrix
498: .  B - optional preconditioning matrix
499: -  flag - flag indicating matrix structure

501:    Notes:
502:    Most users should not need to explicitly call this routine, as it
503:    is used internally within the nonlinear solvers.

505:    See KSPSetOperators() for important information about setting the
506:    flag parameter.

508:    Level: developer

510: .keywords: SNES, compute, Jacobian, matrix

512: .seealso:  TSSetRHSJacobian(), KSPSetOperators()
513: @*/
514: PetscErrorCode  TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat B)
515: {
517:   PetscObjectState Ustate;
518:   DM             dm;
519:   DMTS           tsdm;
520:   TSRHSJacobian  rhsjacobianfunc;
521:   void           *ctx;
522:   TSIJacobian    ijacobianfunc;
523:   TSRHSFunction  rhsfunction;

529:   TSGetDM(ts,&dm);
530:   DMGetDMTS(dm,&tsdm);
531:   DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);
532:   DMTSGetIJacobian(dm,&ijacobianfunc,NULL);
533:   DMTSGetRHSFunction(dm,&rhsfunction,&ctx);
534:   PetscObjectStateGet((PetscObject)U,&Ustate);
535:   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) {
536:     return(0);
537:   }

539:   if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");

541:   if (ts->rhsjacobian.reuse) {
542:     MatShift(A,-ts->rhsjacobian.shift);
543:     MatScale(A,1./ts->rhsjacobian.scale);
544:     if (A != B) {
545:       MatShift(B,-ts->rhsjacobian.shift);
546:       MatScale(B,1./ts->rhsjacobian.scale);
547:     }
548:     ts->rhsjacobian.shift = 0;
549:     ts->rhsjacobian.scale = 1.;
550:   }

552:   if (rhsjacobianfunc) {
553:     PetscBool missing;
554:     PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);
555:     PetscStackPush("TS user Jacobian function");
556:     (*rhsjacobianfunc)(ts,t,U,A,B,ctx);
557:     PetscStackPop;
558:     PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);
559:     if (A) {
560:       MatMissingDiagonal(A,&missing,NULL);
561:       if (missing) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Amat passed to TSSetRHSJacobian() must have all diagonal entries set, if they are zero you must still set them with a zero value");
562:     }
563:     if (B && B != A) {
564:       MatMissingDiagonal(B,&missing,NULL);
565:       if (missing) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Bmat passed to TSSetRHSJacobian() must have all diagonal entries set, if they are zero you must still set them with a zero value");
566:     }
567:   } else {
568:     MatZeroEntries(A);
569:     if (A != B) {MatZeroEntries(B);}
570:   }
571:   ts->rhsjacobian.time       = t;
572:   ts->rhsjacobian.X          = U;
573:   PetscObjectStateGet((PetscObject)U,&ts->rhsjacobian.Xstate);
574:   return(0);
575: }

579: /*@
580:    TSComputeRHSFunction - Evaluates the right-hand-side function.

582:    Collective on TS and Vec

584:    Input Parameters:
585: +  ts - the TS context
586: .  t - current time
587: -  U - state vector

589:    Output Parameter:
590: .  y - right hand side

592:    Note:
593:    Most users should not need to explicitly call this routine, as it
594:    is used internally within the nonlinear solvers.

596:    Level: developer

598: .keywords: TS, compute

600: .seealso: TSSetRHSFunction(), TSComputeIFunction()
601: @*/
602: PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y)
603: {
605:   TSRHSFunction  rhsfunction;
606:   TSIFunction    ifunction;
607:   void           *ctx;
608:   DM             dm;

614:   TSGetDM(ts,&dm);
615:   DMTSGetRHSFunction(dm,&rhsfunction,&ctx);
616:   DMTSGetIFunction(dm,&ifunction,NULL);

618:   if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");

620:   PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);
621:   if (rhsfunction) {
622:     PetscStackPush("TS user right-hand-side function");
623:     (*rhsfunction)(ts,t,U,y,ctx);
624:     PetscStackPop;
625:   } else {
626:     VecZeroEntries(y);
627:   }

629:   PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);
630:   return(0);
631: }

635: /*@
636:    TSComputeSolutionFunction - Evaluates the solution function.

638:    Collective on TS and Vec

640:    Input Parameters:
641: +  ts - the TS context
642: -  t - current time

644:    Output Parameter:
645: .  U - the solution

647:    Note:
648:    Most users should not need to explicitly call this routine, as it
649:    is used internally within the nonlinear solvers.

651:    Level: developer

653: .keywords: TS, compute

655: .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction()
656: @*/
657: PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U)
658: {
659:   PetscErrorCode     ierr;
660:   TSSolutionFunction solutionfunction;
661:   void               *ctx;
662:   DM                 dm;

667:   TSGetDM(ts,&dm);
668:   DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);

670:   if (solutionfunction) {
671:     PetscStackPush("TS user solution function");
672:     (*solutionfunction)(ts,t,U,ctx);
673:     PetscStackPop;
674:   }
675:   return(0);
676: }
679: /*@
680:    TSComputeForcingFunction - Evaluates the forcing function.

682:    Collective on TS and Vec

684:    Input Parameters:
685: +  ts - the TS context
686: -  t - current time

688:    Output Parameter:
689: .  U - the function value

691:    Note:
692:    Most users should not need to explicitly call this routine, as it
693:    is used internally within the nonlinear solvers.

695:    Level: developer

697: .keywords: TS, compute

699: .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction()
700: @*/
701: PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U)
702: {
703:   PetscErrorCode     ierr, (*forcing)(TS,PetscReal,Vec,void*);
704:   void               *ctx;
705:   DM                 dm;

710:   TSGetDM(ts,&dm);
711:   DMTSGetForcingFunction(dm,&forcing,&ctx);

713:   if (forcing) {
714:     PetscStackPush("TS user forcing function");
715:     (*forcing)(ts,t,U,ctx);
716:     PetscStackPop;
717:   }
718:   return(0);
719: }

723: static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs)
724: {
725:   Vec            F;

729:   *Frhs = NULL;
730:   TSGetIFunction(ts,&F,NULL,NULL);
731:   if (!ts->Frhs) {
732:     VecDuplicate(F,&ts->Frhs);
733:   }
734:   *Frhs = ts->Frhs;
735:   return(0);
736: }

740: static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs)
741: {
742:   Mat            A,B;

746:   if (Arhs) *Arhs = NULL;
747:   if (Brhs) *Brhs = NULL;
748:   TSGetIJacobian(ts,&A,&B,NULL,NULL);
749:   if (Arhs) {
750:     if (!ts->Arhs) {
751:       MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);
752:     }
753:     *Arhs = ts->Arhs;
754:   }
755:   if (Brhs) {
756:     if (!ts->Brhs) {
757:       if (A != B) {
758:         MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);
759:       } else {
760:         PetscObjectReference((PetscObject)ts->Arhs);
761:         ts->Brhs = ts->Arhs;
762:       }
763:     }
764:     *Brhs = ts->Brhs;
765:   }
766:   return(0);
767: }

771: /*@
772:    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0

774:    Collective on TS and Vec

776:    Input Parameters:
777: +  ts - the TS context
778: .  t - current time
779: .  U - state vector
780: .  Udot - time derivative of state vector
781: -  imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate

783:    Output Parameter:
784: .  Y - right hand side

786:    Note:
787:    Most users should not need to explicitly call this routine, as it
788:    is used internally within the nonlinear solvers.

790:    If the user did did not write their equations in implicit form, this
791:    function recasts them in implicit form.

793:    Level: developer

795: .keywords: TS, compute

797: .seealso: TSSetIFunction(), TSComputeRHSFunction()
798: @*/
799: PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex)
800: {
802:   TSIFunction    ifunction;
803:   TSRHSFunction  rhsfunction;
804:   void           *ctx;
805:   DM             dm;


813:   TSGetDM(ts,&dm);
814:   DMTSGetIFunction(dm,&ifunction,&ctx);
815:   DMTSGetRHSFunction(dm,&rhsfunction,NULL);

817:   if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");

819:   PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);
820:   if (ifunction) {
821:     PetscStackPush("TS user implicit function");
822:     (*ifunction)(ts,t,U,Udot,Y,ctx);
823:     PetscStackPop;
824:   }
825:   if (imex) {
826:     if (!ifunction) {
827:       VecCopy(Udot,Y);
828:     }
829:   } else if (rhsfunction) {
830:     if (ifunction) {
831:       Vec Frhs;
832:       TSGetRHSVec_Private(ts,&Frhs);
833:       TSComputeRHSFunction(ts,t,U,Frhs);
834:       VecAXPY(Y,-1,Frhs);
835:     } else {
836:       TSComputeRHSFunction(ts,t,U,Y);
837:       VecAYPX(Y,-1,Udot);
838:     }
839:   }
840:   PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);
841:   return(0);
842: }

846: /*@
847:    TSComputeIJacobian - Evaluates the Jacobian of the DAE

849:    Collective on TS and Vec

851:    Input
852:       Input Parameters:
853: +  ts - the TS context
854: .  t - current timestep
855: .  U - state vector
856: .  Udot - time derivative of state vector
857: .  shift - shift to apply, see note below
858: -  imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate

860:    Output Parameters:
861: +  A - Jacobian matrix
862: .  B - optional preconditioning matrix
863: -  flag - flag indicating matrix structure

865:    Notes:
866:    If F(t,U,Udot)=0 is the DAE, the required Jacobian is

868:    dF/dU + shift*dF/dUdot

870:    Most users should not need to explicitly call this routine, as it
871:    is used internally within the nonlinear solvers.

873:    Level: developer

875: .keywords: TS, compute, Jacobian, matrix

877: .seealso:  TSSetIJacobian()
878: @*/
879: PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,PetscBool imex)
880: {
882:   TSIJacobian    ijacobian;
883:   TSRHSJacobian  rhsjacobian;
884:   DM             dm;
885:   void           *ctx;


896:   TSGetDM(ts,&dm);
897:   DMTSGetIJacobian(dm,&ijacobian,&ctx);
898:   DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);

900:   if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");

902:   PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);
903:   if (ijacobian) {
904:     PetscBool missing;
905:     PetscStackPush("TS user implicit Jacobian");
906:     (*ijacobian)(ts,t,U,Udot,shift,A,B,ctx);
907:     PetscStackPop;
908:     if (A) {
909:       MatMissingDiagonal(A,&missing,NULL);
910:       if (missing) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Amat passed to TSSetIJacobian() must have all diagonal entries set, if they are zero you must still set them with a zero value");
911:     }
912:     if (B && B != A) {
913:       MatMissingDiagonal(B,&missing,NULL);
914:       if (missing) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Bmat passed to TSSetIJacobian() must have all diagonal entries set, if they are zero you must still set them with a zero value");
915:     }
916:   }
917:   if (imex) {
918:     if (!ijacobian) {  /* system was written as Udot = G(t,U) */
919:       MatZeroEntries(A);
920:       MatShift(A,shift);
921:       if (A != B) {
922:         MatZeroEntries(B);
923:         MatShift(B,shift);
924:       }
925:     }
926:   } else {
927:     Mat Arhs = NULL,Brhs = NULL;
928:     if (rhsjacobian) {
929:       TSGetRHSMats_Private(ts,&Arhs,&Brhs);
930:       TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);
931:     }
932:     if (Arhs == A) {           /* No IJacobian, so we only have the RHS matrix */
933:       ts->rhsjacobian.scale = -1;
934:       ts->rhsjacobian.shift = shift;
935:       MatScale(A,-1);
936:       MatShift(A,shift);
937:       if (A != B) {
938:         MatScale(B,-1);
939:         MatShift(B,shift);
940:       }
941:     } else if (Arhs) {          /* Both IJacobian and RHSJacobian */
942:       MatStructure axpy = DIFFERENT_NONZERO_PATTERN;
943:       if (!ijacobian) {         /* No IJacobian provided, but we have a separate RHS matrix */
944:         MatZeroEntries(A);
945:         MatShift(A,shift);
946:         if (A != B) {
947:           MatZeroEntries(B);
948:           MatShift(B,shift);
949:         }
950:       }
951:       MatAXPY(A,-1,Arhs,axpy);
952:       if (A != B) {
953:         MatAXPY(B,-1,Brhs,axpy);
954:       }
955:     }
956:   }
957:   PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);
958:   return(0);
959: }

963: /*@C
964:     TSSetRHSFunction - Sets the routine for evaluating the function,
965:     where U_t = G(t,u).

967:     Logically Collective on TS

969:     Input Parameters:
970: +   ts - the TS context obtained from TSCreate()
971: .   r - vector to put the computed right hand side (or NULL to have it created)
972: .   f - routine for evaluating the right-hand-side function
973: -   ctx - [optional] user-defined context for private data for the
974:           function evaluation routine (may be NULL)

976:     Calling sequence of func:
977: $     func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);

979: +   t - current timestep
980: .   u - input vector
981: .   F - function vector
982: -   ctx - [optional] user-defined function context

984:     Level: beginner

986:     Notes: You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE.

988: .keywords: TS, timestep, set, right-hand-side, function

990: .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSSetIFunction()
991: @*/
992: PetscErrorCode  TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
993: {
995:   SNES           snes;
996:   Vec            ralloc = NULL;
997:   DM             dm;


1003:   TSGetDM(ts,&dm);
1004:   DMTSSetRHSFunction(dm,f,ctx);
1005:   TSGetSNES(ts,&snes);
1006:   if (!r && !ts->dm && ts->vec_sol) {
1007:     VecDuplicate(ts->vec_sol,&ralloc);
1008:     r = ralloc;
1009:   }
1010:   SNESSetFunction(snes,r,SNESTSFormFunction,ts);
1011:   VecDestroy(&ralloc);
1012:   return(0);
1013: }

1017: /*@C
1018:     TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE

1020:     Logically Collective on TS

1022:     Input Parameters:
1023: +   ts - the TS context obtained from TSCreate()
1024: .   f - routine for evaluating the solution
1025: -   ctx - [optional] user-defined context for private data for the
1026:           function evaluation routine (may be NULL)

1028:     Calling sequence of func:
1029: $     func (TS ts,PetscReal t,Vec u,void *ctx);

1031: +   t - current timestep
1032: .   u - output vector
1033: -   ctx - [optional] user-defined function context

1035:     Notes:
1036:     This routine is used for testing accuracy of time integration schemes when you already know the solution.
1037:     If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
1038:     create closed-form solutions with non-physical forcing terms.

1040:     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.

1042:     Level: beginner

1044: .keywords: TS, timestep, set, right-hand-side, function

1046: .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction()
1047: @*/
1048: PetscErrorCode  TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
1049: {
1051:   DM             dm;

1055:   TSGetDM(ts,&dm);
1056:   DMTSSetSolutionFunction(dm,f,ctx);
1057:   return(0);
1058: }

1062: /*@C
1063:     TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE

1065:     Logically Collective on TS

1067:     Input Parameters:
1068: +   ts - the TS context obtained from TSCreate()
1069: .   f - routine for evaluating the forcing function
1070: -   ctx - [optional] user-defined context for private data for the
1071:           function evaluation routine (may be NULL)

1073:     Calling sequence of func:
1074: $     func (TS ts,PetscReal t,Vec u,void *ctx);

1076: +   t - current timestep
1077: .   u - output vector
1078: -   ctx - [optional] user-defined function context

1080:     Notes:
1081:     This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to
1082:     create closed-form solutions with a non-physical forcing term.

1084:     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.

1086:     Level: beginner

1088: .keywords: TS, timestep, set, right-hand-side, function

1090: .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction()
1091: @*/
1092: PetscErrorCode  TSSetForcingFunction(TS ts,TSForcingFunction f,void *ctx)
1093: {
1095:   DM             dm;

1099:   TSGetDM(ts,&dm);
1100:   DMTSSetForcingFunction(dm,f,ctx);
1101:   return(0);
1102: }

1106: /*@C
1107:    TSSetRHSJacobian - Sets the function to compute the Jacobian of G,
1108:    where U_t = G(U,t), as well as the location to store the matrix.

1110:    Logically Collective on TS

1112:    Input Parameters:
1113: +  ts  - the TS context obtained from TSCreate()
1114: .  Amat - (approximate) Jacobian matrix
1115: .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1116: .  f   - the Jacobian evaluation routine
1117: -  ctx - [optional] user-defined context for private data for the
1118:          Jacobian evaluation routine (may be NULL)

1120:    Calling sequence of f:
1121: $     func (TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);

1123: +  t - current timestep
1124: .  u - input vector
1125: .  Amat - (approximate) Jacobian matrix
1126: .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1127: -  ctx - [optional] user-defined context for matrix evaluation routine

1129:    Notes:
1130:    You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value

1132:    The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f()
1133:    You should not assume the values are the same in the next call to f() as you set them in the previous call.

1135:    Level: beginner

1137: .keywords: TS, timestep, set, right-hand-side, Jacobian

1139: .seealso: SNESComputeJacobianDefaultColor(), TSSetRHSFunction(), TSRHSJacobianSetReuse(), TSSetIJacobian()

1141: @*/
1142: PetscErrorCode  TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx)
1143: {
1145:   SNES           snes;
1146:   DM             dm;
1147:   TSIJacobian    ijacobian;


1156:   TSGetDM(ts,&dm);
1157:   DMTSSetRHSJacobian(dm,f,ctx);
1158:   if (f == TSComputeRHSJacobianConstant) {
1159:     /* Handle this case automatically for the user; otherwise user should call themselves. */
1160:     TSRHSJacobianSetReuse(ts,PETSC_TRUE);
1161:   }
1162:   DMTSGetIJacobian(dm,&ijacobian,NULL);
1163:   TSGetSNES(ts,&snes);
1164:   if (!ijacobian) {
1165:     SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);
1166:   }
1167:   if (Amat) {
1168:     PetscObjectReference((PetscObject)Amat);
1169:     MatDestroy(&ts->Arhs);
1170:     ts->Arhs = Amat;
1171:   }
1172:   if (Pmat) {
1173:     PetscObjectReference((PetscObject)Pmat);
1174:     MatDestroy(&ts->Brhs);
1175:     ts->Brhs = Pmat;
1176:   }
1177:   return(0);
1178: }


1183: /*@C
1184:    TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.

1186:    Logically Collective on TS

1188:    Input Parameters:
1189: +  ts  - the TS context obtained from TSCreate()
1190: .  r   - vector to hold the residual (or NULL to have it created internally)
1191: .  f   - the function evaluation routine
1192: -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)

1194:    Calling sequence of f:
1195: $  f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);

1197: +  t   - time at step/stage being solved
1198: .  u   - state vector
1199: .  u_t - time derivative of state vector
1200: .  F   - function vector
1201: -  ctx - [optional] user-defined context for matrix evaluation routine

1203:    Important:
1204:    The user MUST call either this routine or TSSetRHSFunction() to define the ODE.  When solving DAEs you must use this function.

1206:    Level: beginner

1208: .keywords: TS, timestep, set, DAE, Jacobian

1210: .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian()
1211: @*/
1212: PetscErrorCode  TSSetIFunction(TS ts,Vec r,TSIFunction f,void *ctx)
1213: {
1215:   SNES           snes;
1216:   Vec            ralloc = NULL;
1217:   DM             dm;


1223:   TSGetDM(ts,&dm);
1224:   DMTSSetIFunction(dm,f,ctx);

1226:   TSGetSNES(ts,&snes);
1227:   if (!r && !ts->dm && ts->vec_sol) {
1228:     VecDuplicate(ts->vec_sol,&ralloc);
1229:     r  = ralloc;
1230:   }
1231:   SNESSetFunction(snes,r,SNESTSFormFunction,ts);
1232:   VecDestroy(&ralloc);
1233:   return(0);
1234: }

1238: /*@C
1239:    TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it.

1241:    Not Collective

1243:    Input Parameter:
1244: .  ts - the TS context

1246:    Output Parameter:
1247: +  r - vector to hold residual (or NULL)
1248: .  func - the function to compute residual (or NULL)
1249: -  ctx - the function context (or NULL)

1251:    Level: advanced

1253: .keywords: TS, nonlinear, get, function

1255: .seealso: TSSetIFunction(), SNESGetFunction()
1256: @*/
1257: PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx)
1258: {
1260:   SNES           snes;
1261:   DM             dm;

1265:   TSGetSNES(ts,&snes);
1266:   SNESGetFunction(snes,r,NULL,NULL);
1267:   TSGetDM(ts,&dm);
1268:   DMTSGetIFunction(dm,func,ctx);
1269:   return(0);
1270: }

1274: /*@C
1275:    TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it.

1277:    Not Collective

1279:    Input Parameter:
1280: .  ts - the TS context

1282:    Output Parameter:
1283: +  r - vector to hold computed right hand side (or NULL)
1284: .  func - the function to compute right hand side (or NULL)
1285: -  ctx - the function context (or NULL)

1287:    Level: advanced

1289: .keywords: TS, nonlinear, get, function

1291: .seealso: TSSetRHSFunction(), SNESGetFunction()
1292: @*/
1293: PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx)
1294: {
1296:   SNES           snes;
1297:   DM             dm;

1301:   TSGetSNES(ts,&snes);
1302:   SNESGetFunction(snes,r,NULL,NULL);
1303:   TSGetDM(ts,&dm);
1304:   DMTSGetRHSFunction(dm,func,ctx);
1305:   return(0);
1306: }

1310: /*@C
1311:    TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
1312:         provided with TSSetIFunction().

1314:    Logically Collective on TS

1316:    Input Parameters:
1317: +  ts  - the TS context obtained from TSCreate()
1318: .  Amat - (approximate) Jacobian matrix
1319: .  Pmat - matrix used to compute preconditioner (usually the same as Amat)
1320: .  f   - the Jacobian evaluation routine
1321: -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)

1323:    Calling sequence of f:
1324: $  f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);

1326: +  t    - time at step/stage being solved
1327: .  U    - state vector
1328: .  U_t  - time derivative of state vector
1329: .  a    - shift
1330: .  Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1331: .  Pmat - matrix used for constructing preconditioner, usually the same as Amat
1332: -  ctx  - [optional] user-defined context for matrix evaluation routine

1334:    Notes:
1335:    The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve.

1337:    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
1338:    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.

1340:    The matrix dF/dU + a*dF/dU_t you provide turns out to be
1341:    the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1342:    The time integrator internally approximates U_t by W+a*U where the positive "shift"
1343:    a and vector W depend on the integration method, step size, and past states. For example with
1344:    the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1345:    W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt

1347:    You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value

1349:    The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f()
1350:    You should not assume the values are the same in the next call to f() as you set them in the previous call.

1352:    Level: beginner

1354: .keywords: TS, timestep, DAE, Jacobian

1356: .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESComputeJacobianDefaultColor(), SNESComputeJacobianDefault(), TSSetRHSFunction()

1358: @*/
1359: PetscErrorCode  TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx)
1360: {
1362:   SNES           snes;
1363:   DM             dm;


1372:   TSGetDM(ts,&dm);
1373:   DMTSSetIJacobian(dm,f,ctx);

1375:   TSGetSNES(ts,&snes);
1376:   SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);
1377:   return(0);
1378: }

1382: /*@
1383:    TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating.  Without this flag, TS will change the sign and
1384:    shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute
1385:    the entire Jacobian.  The reuse flag must be set if the evaluation function will assume that the matrix entries have
1386:    not been changed by the TS.

1388:    Logically Collective

1390:    Input Arguments:
1391: +  ts - TS context obtained from TSCreate()
1392: -  reuse - PETSC_TRUE if the RHS Jacobian

1394:    Level: intermediate

1396: .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
1397: @*/
1398: PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse)
1399: {
1401:   ts->rhsjacobian.reuse = reuse;
1402:   return(0);
1403: }

1407: /*@C
1408:    TSSetI2Function - Set the function to compute F(t,U,U_t,U_tt) where F = 0 is the DAE to be solved.

1410:    Logically Collective on TS

1412:    Input Parameters:
1413: +  ts  - the TS context obtained from TSCreate()
1414: .  F   - vector to hold the residual (or NULL to have it created internally)
1415: .  fun - the function evaluation routine
1416: -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)

1418:    Calling sequence of fun:
1419: $  fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);

1421: +  t    - time at step/stage being solved
1422: .  U    - state vector
1423: .  U_t  - time derivative of state vector
1424: .  U_tt - second time derivative of state vector
1425: .  F    - function vector
1426: -  ctx  - [optional] user-defined context for matrix evaluation routine (may be NULL)

1428:    Level: beginner

1430: .keywords: TS, timestep, set, ODE, DAE, Function

1432: .seealso: TSSetI2Jacobian()
1433: @*/
1434: PetscErrorCode TSSetI2Function(TS ts,Vec F,TSI2Function fun,void *ctx)
1435: {
1436:   DM             dm;

1442:   TSSetIFunction(ts,F,NULL,NULL);
1443:   TSGetDM(ts,&dm);
1444:   DMTSSetI2Function(dm,fun,ctx);
1445:   return(0);
1446: }

1450: /*@C
1451:   TSGetI2Function - Returns the vector where the implicit residual is stored and the function/contex to compute it.

1453:   Not Collective

1455:   Input Parameter:
1456: . ts - the TS context

1458:   Output Parameter:
1459: + r - vector to hold residual (or NULL)
1460: . fun - the function to compute residual (or NULL)
1461: - ctx - the function context (or NULL)

1463:   Level: advanced

1465: .keywords: TS, nonlinear, get, function

1467: .seealso: TSSetI2Function(), SNESGetFunction()
1468: @*/
1469: PetscErrorCode TSGetI2Function(TS ts,Vec *r,TSI2Function *fun,void **ctx)
1470: {
1472:   SNES           snes;
1473:   DM             dm;

1477:   TSGetSNES(ts,&snes);
1478:   SNESGetFunction(snes,r,NULL,NULL);
1479:   TSGetDM(ts,&dm);
1480:   DMTSGetI2Function(dm,fun,ctx);
1481:   return(0);
1482: }

1486: /*@C
1487:    TSSetI2Jacobian - Set the function to compute the matrix dF/dU + v*dF/dU_t  + a*dF/dU_tt
1488:         where F(t,U,U_t,U_tt) is the function you provided with TSSetI2Function().

1490:    Logically Collective on TS

1492:    Input Parameters:
1493: +  ts  - the TS context obtained from TSCreate()
1494: .  J   - Jacobian matrix
1495: .  P   - preconditioning matrix for J (may be same as J)
1496: .  jac - the Jacobian evaluation routine
1497: -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)

1499:    Calling sequence of jac:
1500: $  jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx);

1502: +  t    - time at step/stage being solved
1503: .  U    - state vector
1504: .  U_t  - time derivative of state vector
1505: .  U_tt - second time derivative of state vector
1506: .  v    - shift for U_t
1507: .  a    - shift for U_tt
1508: .  J    - Jacobian of G(U) = F(t,U,W+v*U,W'+a*U), equivalent to dF/dU + v*dF/dU_t  + a*dF/dU_tt
1509: .  P    - preconditioning matrix for J, may be same as J
1510: -  ctx  - [optional] user-defined context for matrix evaluation routine

1512:    Notes:
1513:    The matrices J and P are exactly the matrices that are used by SNES for the nonlinear solve.

1515:    The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be
1516:    the Jacobian of G(U) = F(t,U,W+v*U,W'+a*U) where F(t,U,U_t,U_tt) = 0 is the DAE to be solved.
1517:    The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U  where the positive "shift"
1518:    parameters 'v' and 'a' and vectors W, W' depend on the integration method, step size, and past states.

1520:    Level: beginner

1522: .keywords: TS, timestep, set, ODE, DAE, Jacobian

1524: .seealso: TSSetI2Function()
1525: @*/
1526: PetscErrorCode TSSetI2Jacobian(TS ts,Mat J,Mat P,TSI2Jacobian jac,void *ctx)
1527: {
1528:   DM             dm;

1535:   TSSetIJacobian(ts,J,P,NULL,NULL);
1536:   TSGetDM(ts,&dm);
1537:   DMTSSetI2Jacobian(dm,jac,ctx);
1538:   return(0);
1539: }

1543: /*@C
1544:   TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep.

1546:   Not Collective, but parallel objects are returned if TS is parallel

1548:   Input Parameter:
1549: . ts  - The TS context obtained from TSCreate()

1551:   Output Parameters:
1552: + J  - The (approximate) Jacobian of F(t,U,U_t,U_tt)
1553: . P - The matrix from which the preconditioner is constructed, often the same as J
1554: . jac - The function to compute the Jacobian matrices
1555: - ctx - User-defined context for Jacobian evaluation routine

1557:   Notes: You can pass in NULL for any return argument you do not need.

1559:   Level: advanced

1561: .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()

1563: .keywords: TS, timestep, get, matrix, Jacobian
1564: @*/
1565: PetscErrorCode  TSGetI2Jacobian(TS ts,Mat *J,Mat *P,TSI2Jacobian *jac,void **ctx)
1566: {
1568:   SNES           snes;
1569:   DM             dm;

1572:   TSGetSNES(ts,&snes);
1573:   SNESSetUpMatrices(snes);
1574:   SNESGetJacobian(snes,J,P,NULL,NULL);
1575:   TSGetDM(ts,&dm);
1576:   DMTSGetI2Jacobian(dm,jac,ctx);
1577:   return(0);
1578: }

1582: /*@
1583:   TSComputeI2Function - Evaluates the DAE residual written in implicit form F(t,U,U_t,U_tt) = 0

1585:   Collective on TS and Vec

1587:   Input Parameters:
1588: + ts - the TS context
1589: . t - current time
1590: . U - state vector
1591: . V - time derivative of state vector (U_t)
1592: - A - second time derivative of state vector (U_tt)

1594:   Output Parameter:
1595: . F - the residual vector

1597:   Note:
1598:   Most users should not need to explicitly call this routine, as it
1599:   is used internally within the nonlinear solvers.

1601:   Level: developer

1603: .keywords: TS, compute, function, vector

1605: .seealso: TSSetI2Function()
1606: @*/
1607: PetscErrorCode TSComputeI2Function(TS ts,PetscReal t,Vec U,Vec V,Vec A,Vec F)
1608: {
1609:   DM             dm;
1610:   TSI2Function   I2Function;
1611:   void           *ctx;
1612:   TSRHSFunction  rhsfunction;


1622:   TSGetDM(ts,&dm);
1623:   DMTSGetI2Function(dm,&I2Function,&ctx);
1624:   DMTSGetRHSFunction(dm,&rhsfunction,NULL);

1626:   if (!I2Function) {
1627:     TSComputeIFunction(ts,t,U,A,F,PETSC_FALSE);
1628:     return(0);
1629:   }

1631:   PetscLogEventBegin(TS_FunctionEval,ts,U,V,F);

1633:   PetscStackPush("TS user implicit function");
1634:   I2Function(ts,t,U,V,A,F,ctx);
1635:   PetscStackPop;

1637:   if (rhsfunction) {
1638:     Vec Frhs;
1639:     TSGetRHSVec_Private(ts,&Frhs);
1640:     TSComputeRHSFunction(ts,t,U,Frhs);
1641:     VecAXPY(F,-1,Frhs);
1642:   }

1644:   PetscLogEventEnd(TS_FunctionEval,ts,U,V,F);
1645:   return(0);
1646: }

1650: /*@
1651:   TSComputeI2Jacobian - Evaluates the Jacobian of the DAE

1653:   Collective on TS and Vec

1655:   Input Parameters:
1656: + ts - the TS context
1657: . t - current timestep
1658: . U - state vector
1659: . V - time derivative of state vector
1660: . A - second time derivative of state vector
1661: . shiftV - shift to apply, see note below
1662: - shiftA - shift to apply, see note below

1664:   Output Parameters:
1665: + J - Jacobian matrix
1666: - P - optional preconditioning matrix

1668:   Notes:
1669:   If F(t,U,V,A)=0 is the DAE, the required Jacobian is

1671:   dF/dU + shiftV*dF/dV + shiftA*dF/dA

1673:   Most users should not need to explicitly call this routine, as it
1674:   is used internally within the nonlinear solvers.

1676:   Level: developer

1678: .keywords: TS, compute, Jacobian, matrix

1680: .seealso:  TSSetI2Jacobian()
1681: @*/
1682: PetscErrorCode TSComputeI2Jacobian(TS ts,PetscReal t,Vec U,Vec V,Vec A,PetscReal shiftV,PetscReal shiftA,Mat J,Mat P)
1683: {
1684:   DM             dm;
1685:   TSI2Jacobian   I2Jacobian;
1686:   void           *ctx;
1687:   TSRHSJacobian  rhsjacobian;


1698:   TSGetDM(ts,&dm);
1699:   DMTSGetI2Jacobian(dm,&I2Jacobian,&ctx);
1700:   DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);

1702:   if (!I2Jacobian) {
1703:     TSComputeIJacobian(ts,t,U,A,shiftA,J,P,PETSC_FALSE);
1704:     return(0);
1705:   }

1707:   PetscLogEventBegin(TS_JacobianEval,ts,U,J,P);

1709:   PetscStackPush("TS user implicit Jacobian");
1710:   I2Jacobian(ts,t,U,V,A,shiftV,shiftA,J,P,ctx);
1711:   PetscStackPop;

1713:   if (rhsjacobian) {
1714:     Mat Jrhs,Prhs; MatStructure axpy = DIFFERENT_NONZERO_PATTERN;
1715:     TSGetRHSMats_Private(ts,&Jrhs,&Prhs);
1716:     TSComputeRHSJacobian(ts,t,U,Jrhs,Prhs);
1717:     MatAXPY(J,-1,Jrhs,axpy);
1718:     if (P != J) {MatAXPY(P,-1,Prhs,axpy);}
1719:   }

1721:   PetscLogEventEnd(TS_JacobianEval,ts,U,J,P);
1722:   return(0);
1723: }

1727: /*@
1728:    TS2SetSolution - Sets the initial solution and time derivative vectors
1729:    for use by the TS routines handling second order equations.

1731:    Logically Collective on TS and Vec

1733:    Input Parameters:
1734: +  ts - the TS context obtained from TSCreate()
1735: .  u - the solution vector
1736: -  v - the time derivative vector

1738:    Level: beginner

1740: .keywords: TS, timestep, set, solution, initial conditions
1741: @*/
1742: PetscErrorCode  TS2SetSolution(TS ts,Vec u,Vec v)
1743: {

1750:   TSSetSolution(ts,u);
1751:   PetscObjectReference((PetscObject)v);
1752:   VecDestroy(&ts->vec_dot);
1753:   ts->vec_dot = v;
1754:   return(0);
1755: }

1759: /*@
1760:    TS2GetSolution - Returns the solution and time derivative at the present timestep
1761:    for second order equations. It is valid to call this routine inside the function
1762:    that you are evaluating in order to move to the new timestep. This vector not
1763:    changed until the solution at the next timestep has been calculated.

1765:    Not Collective, but Vec returned is parallel if TS is parallel

1767:    Input Parameter:
1768: .  ts - the TS context obtained from TSCreate()

1770:    Output Parameter:
1771: +  u - the vector containing the solution
1772: -  v - the vector containing the time derivative

1774:    Level: intermediate

1776: .seealso: TS2SetSolution(), TSGetTimeStep(), TSGetTime()

1778: .keywords: TS, timestep, get, solution
1779: @*/
1780: PetscErrorCode  TS2GetSolution(TS ts,Vec *u,Vec *v)
1781: {
1786:   if (u) *u = ts->vec_sol;
1787:   if (v) *v = ts->vec_dot;
1788:   return(0);
1789: }

1793: /*@C
1794:   TSLoad - Loads a KSP that has been stored in binary  with KSPView().

1796:   Collective on PetscViewer

1798:   Input Parameters:
1799: + newdm - the newly loaded TS, this needs to have been created with TSCreate() or
1800:            some related function before a call to TSLoad().
1801: - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()

1803:    Level: intermediate

1805:   Notes:
1806:    The type is determined by the data in the file, any type set into the TS before this call is ignored.

1808:   Notes for advanced users:
1809:   Most users should not need to know the details of the binary storage
1810:   format, since TSLoad() and TSView() completely hide these details.
1811:   But for anyone who's interested, the standard binary matrix storage
1812:   format is
1813: .vb
1814:      has not yet been determined
1815: .ve

1817: .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad()
1818: @*/
1819: PetscErrorCode  TSLoad(TS ts, PetscViewer viewer)
1820: {
1822:   PetscBool      isbinary;
1823:   PetscInt       classid;
1824:   char           type[256];
1825:   DMTS           sdm;
1826:   DM             dm;

1831:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
1832:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");

1834:   PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);
1835:   if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file");
1836:   PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);
1837:   TSSetType(ts, type);
1838:   if (ts->ops->load) {
1839:     (*ts->ops->load)(ts,viewer);
1840:   }
1841:   DMCreate(PetscObjectComm((PetscObject)ts),&dm);
1842:   DMLoad(dm,viewer);
1843:   TSSetDM(ts,dm);
1844:   DMCreateGlobalVector(ts->dm,&ts->vec_sol);
1845:   VecLoad(ts->vec_sol,viewer);
1846:   DMGetDMTS(ts->dm,&sdm);
1847:   DMTSLoad(sdm,viewer);
1848:   return(0);
1849: }

1851: #include <petscdraw.h>
1852: #if defined(PETSC_HAVE_SAWS)
1853: #include <petscviewersaws.h>
1854: #endif
1857: /*@C
1858:     TSView - Prints the TS data structure.

1860:     Collective on TS

1862:     Input Parameters:
1863: +   ts - the TS context obtained from TSCreate()
1864: -   viewer - visualization context

1866:     Options Database Key:
1867: .   -ts_view - calls TSView() at end of TSStep()

1869:     Notes:
1870:     The available visualization contexts include
1871: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1872: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1873:          output where only the first processor opens
1874:          the file.  All other processors send their
1875:          data to the first processor to print.

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

1880:     Level: beginner

1882: .keywords: TS, timestep, view

1884: .seealso: PetscViewerASCIIOpen()
1885: @*/
1886: PetscErrorCode  TSView(TS ts,PetscViewer viewer)
1887: {
1889:   TSType         type;
1890:   PetscBool      iascii,isstring,isundials,isbinary,isdraw;
1891:   DMTS           sdm;
1892: #if defined(PETSC_HAVE_SAWS)
1893:   PetscBool      issaws;
1894: #endif

1898:   if (!viewer) {
1899:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);
1900:   }

1904:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
1905:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
1906:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
1907:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
1908: #if defined(PETSC_HAVE_SAWS)
1909:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
1910: #endif
1911:   if (iascii) {
1912:     PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);
1913:     PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);
1914:     PetscViewerASCIIPrintf(viewer,"  maximum time=%g\n",(double)ts->max_time);
1915:     if (ts->problem_type == TS_NONLINEAR) {
1916:       PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->snes_its);
1917:       PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solve failures=%D\n",ts->num_snes_failures);
1918:     }
1919:     PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->ksp_its);
1920:     PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);
1921:     DMGetDMTS(ts->dm,&sdm);
1922:     DMTSView(sdm,viewer);
1923:     if (ts->ops->view) {
1924:       PetscViewerASCIIPushTab(viewer);
1925:       (*ts->ops->view)(ts,viewer);
1926:       PetscViewerASCIIPopTab(viewer);
1927:     }
1928:   } else if (isstring) {
1929:     TSGetType(ts,&type);
1930:     PetscViewerStringSPrintf(viewer," %-7.7s",type);
1931:   } else if (isbinary) {
1932:     PetscInt    classid = TS_FILE_CLASSID;
1933:     MPI_Comm    comm;
1934:     PetscMPIInt rank;
1935:     char        type[256];

1937:     PetscObjectGetComm((PetscObject)ts,&comm);
1938:     MPI_Comm_rank(comm,&rank);
1939:     if (!rank) {
1940:       PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);
1941:       PetscStrncpy(type,((PetscObject)ts)->type_name,256);
1942:       PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);
1943:     }
1944:     if (ts->ops->view) {
1945:       (*ts->ops->view)(ts,viewer);
1946:     }
1947:     DMView(ts->dm,viewer);
1948:     VecView(ts->vec_sol,viewer);
1949:     DMGetDMTS(ts->dm,&sdm);
1950:     DMTSView(sdm,viewer);
1951:   } else if (isdraw) {
1952:     PetscDraw draw;
1953:     char      str[36];
1954:     PetscReal x,y,bottom,h;

1956:     PetscViewerDrawGetDraw(viewer,0,&draw);
1957:     PetscDrawGetCurrentPoint(draw,&x,&y);
1958:     PetscStrcpy(str,"TS: ");
1959:     PetscStrcat(str,((PetscObject)ts)->type_name);
1960:     PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);
1961:     bottom = y - h;
1962:     PetscDrawPushCurrentPoint(draw,x,bottom);
1963:     if (ts->ops->view) {
1964:       (*ts->ops->view)(ts,viewer);
1965:     }
1966:     PetscDrawPopCurrentPoint(draw);
1967: #if defined(PETSC_HAVE_SAWS)
1968:   } else if (issaws) {
1969:     PetscMPIInt rank;
1970:     const char  *name;

1972:     PetscObjectGetName((PetscObject)ts,&name);
1973:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
1974:     if (!((PetscObject)ts)->amsmem && !rank) {
1975:       char       dir[1024];

1977:       PetscObjectViewSAWs((PetscObject)ts,viewer);
1978:       PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);
1979:       PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT));
1980:       PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);
1981:       PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE));
1982:     }
1983:     if (ts->ops->view) {
1984:       (*ts->ops->view)(ts,viewer);
1985:     }
1986: #endif
1987:   }

1989:   PetscViewerASCIIPushTab(viewer);
1990:   PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);
1991:   PetscViewerASCIIPopTab(viewer);
1992:   return(0);
1993: }


1998: /*@
1999:    TSSetApplicationContext - Sets an optional user-defined context for
2000:    the timesteppers.

2002:    Logically Collective on TS

2004:    Input Parameters:
2005: +  ts - the TS context obtained from TSCreate()
2006: -  usrP - optional user context

2008:    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
2009:     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.

2011:    Level: intermediate

2013: .keywords: TS, timestep, set, application, context

2015: .seealso: TSGetApplicationContext()
2016: @*/
2017: PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
2018: {
2021:   ts->user = usrP;
2022:   return(0);
2023: }

2027: /*@
2028:     TSGetApplicationContext - Gets the user-defined context for the
2029:     timestepper.

2031:     Not Collective

2033:     Input Parameter:
2034: .   ts - the TS context obtained from TSCreate()

2036:     Output Parameter:
2037: .   usrP - user context

2039:    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
2040:     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.

2042:     Level: intermediate

2044: .keywords: TS, timestep, get, application, context

2046: .seealso: TSSetApplicationContext()
2047: @*/
2048: PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
2049: {
2052:   *(void**)usrP = ts->user;
2053:   return(0);
2054: }

2058: /*@
2059:    TSGetTimeStepNumber - Gets the number of time steps completed.

2061:    Not Collective

2063:    Input Parameter:
2064: .  ts - the TS context obtained from TSCreate()

2066:    Output Parameter:
2067: .  iter - number of steps completed so far

2069:    Level: intermediate

2071: .keywords: TS, timestep, get, iteration, number
2072: .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep()
2073: @*/
2074: PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt *iter)
2075: {
2079:   *iter = ts->steps;
2080:   return(0);
2081: }

2085: /*@
2086:    TSSetInitialTimeStep - Sets the initial timestep to be used,
2087:    as well as the initial time.

2089:    Logically Collective on TS

2091:    Input Parameters:
2092: +  ts - the TS context obtained from TSCreate()
2093: .  initial_time - the initial time
2094: -  time_step - the size of the timestep

2096:    Level: intermediate

2098: .seealso: TSSetTimeStep(), TSGetTimeStep()

2100: .keywords: TS, set, initial, timestep
2101: @*/
2102: PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
2103: {

2108:   TSSetTimeStep(ts,time_step);
2109:   TSSetTime(ts,initial_time);
2110:   return(0);
2111: }

2115: /*@
2116:    TSSetTimeStep - Allows one to reset the timestep at any time,
2117:    useful for simple pseudo-timestepping codes.

2119:    Logically Collective on TS

2121:    Input Parameters:
2122: +  ts - the TS context obtained from TSCreate()
2123: -  time_step - the size of the timestep

2125:    Level: intermediate

2127: .seealso: TSSetInitialTimeStep(), TSGetTimeStep()

2129: .keywords: TS, set, timestep
2130: @*/
2131: PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
2132: {
2136:   ts->time_step = time_step;
2137:   return(0);
2138: }

2142: /*@
2143:    TSSetExactFinalTime - Determines whether to adapt the final time step to
2144:      match the exact final time, interpolate solution to the exact final time,
2145:      or just return at the final time TS computed.

2147:   Logically Collective on TS

2149:    Input Parameter:
2150: +   ts - the time-step context
2151: -   eftopt - exact final time option

2153: $  TS_EXACTFINALTIME_STEPOVER    - Don't do anything if final time is exceeded
2154: $  TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time
2155: $  TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time

2157:    Options Database:
2158: .   -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime

2160:    Warning: If you use the option TS_EXACTFINALTIME_STEPOVER the solution may be at a very different time
2161:     then the final time you selected.

2163:    Level: beginner

2165: .seealso: TSExactFinalTimeOption
2166: @*/
2167: PetscErrorCode  TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
2168: {
2172:   ts->exact_final_time = eftopt;
2173:   return(0);
2174: }

2178: /*@
2179:    TSGetTimeStep - Gets the current timestep size.

2181:    Not Collective

2183:    Input Parameter:
2184: .  ts - the TS context obtained from TSCreate()

2186:    Output Parameter:
2187: .  dt - the current timestep size

2189:    Level: intermediate

2191: .seealso: TSSetInitialTimeStep(), TSGetTimeStep()

2193: .keywords: TS, get, timestep
2194: @*/
2195: PetscErrorCode  TSGetTimeStep(TS ts,PetscReal *dt)
2196: {
2200:   *dt = ts->time_step;
2201:   return(0);
2202: }

2206: /*@
2207:    TSGetSolution - Returns the solution at the present timestep. It
2208:    is valid to call this routine inside the function that you are evaluating
2209:    in order to move to the new timestep. This vector not changed until
2210:    the solution at the next timestep has been calculated.

2212:    Not Collective, but Vec returned is parallel if TS is parallel

2214:    Input Parameter:
2215: .  ts - the TS context obtained from TSCreate()

2217:    Output Parameter:
2218: .  v - the vector containing the solution

2220:    Note: If you used TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); this does not return the solution at the requested
2221:    final time. It returns the solution at the next timestep.

2223:    Level: intermediate

2225: .seealso: TSGetTimeStep(), TSGetTime(), TSGetSolveTime()

2227: .keywords: TS, timestep, get, solution
2228: @*/
2229: PetscErrorCode  TSGetSolution(TS ts,Vec *v)
2230: {
2234:   *v = ts->vec_sol;
2235:   return(0);
2236: }

2240: /*@
2241:    TSGetCostGradients - Returns the gradients from the TSAdjointSolve()

2243:    Not Collective, but Vec returned is parallel if TS is parallel

2245:    Input Parameter:
2246: .  ts - the TS context obtained from TSCreate()

2248:    Output Parameter:
2249: +  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
2250: -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters

2252:    Level: intermediate

2254: .seealso: TSGetTimeStep()

2256: .keywords: TS, timestep, get, sensitivity
2257: @*/
2258: PetscErrorCode  TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu)
2259: {
2262:   if (numcost) *numcost = ts->numcost;
2263:   if (lambda)  *lambda  = ts->vecs_sensi;
2264:   if (mu)      *mu      = ts->vecs_sensip;
2265:   return(0);
2266: }

2268: /* ----- Routines to initialize and destroy a timestepper ---- */
2271: /*@
2272:   TSSetProblemType - Sets the type of problem to be solved.

2274:   Not collective

2276:   Input Parameters:
2277: + ts   - The TS
2278: - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2279: .vb
2280:          U_t - A U = 0      (linear)
2281:          U_t - A(t) U = 0   (linear)
2282:          F(t,U,U_t) = 0     (nonlinear)
2283: .ve

2285:    Level: beginner

2287: .keywords: TS, problem type
2288: .seealso: TSSetUp(), TSProblemType, TS
2289: @*/
2290: PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
2291: {

2296:   ts->problem_type = type;
2297:   if (type == TS_LINEAR) {
2298:     SNES snes;
2299:     TSGetSNES(ts,&snes);
2300:     SNESSetType(snes,SNESKSPONLY);
2301:   }
2302:   return(0);
2303: }

2307: /*@C
2308:   TSGetProblemType - Gets the type of problem to be solved.

2310:   Not collective

2312:   Input Parameter:
2313: . ts   - The TS

2315:   Output Parameter:
2316: . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2317: .vb
2318:          M U_t = A U
2319:          M(t) U_t = A(t) U
2320:          F(t,U,U_t)
2321: .ve

2323:    Level: beginner

2325: .keywords: TS, problem type
2326: .seealso: TSSetUp(), TSProblemType, TS
2327: @*/
2328: PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
2329: {
2333:   *type = ts->problem_type;
2334:   return(0);
2335: }

2339: /*@
2340:    TSSetUp - Sets up the internal data structures for the later use
2341:    of a timestepper.

2343:    Collective on TS

2345:    Input Parameter:
2346: .  ts - the TS context obtained from TSCreate()

2348:    Notes:
2349:    For basic use of the TS solvers the user need not explicitly call
2350:    TSSetUp(), since these actions will automatically occur during
2351:    the call to TSStep().  However, if one wishes to control this
2352:    phase separately, TSSetUp() should be called after TSCreate()
2353:    and optional routines of the form TSSetXXX(), but before TSStep().

2355:    Level: advanced

2357: .keywords: TS, timestep, setup

2359: .seealso: TSCreate(), TSStep(), TSDestroy()
2360: @*/
2361: PetscErrorCode  TSSetUp(TS ts)
2362: {
2364:   DM             dm;
2365:   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2366:   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
2367:   TSIFunction    ifun;
2368:   TSIJacobian    ijac;
2369:   TSI2Jacobian   i2jac;
2370:   TSRHSJacobian  rhsjac;

2374:   if (ts->setupcalled) return(0);

2376:   ts->total_steps = 0;
2377:   if (!((PetscObject)ts)->type_name) {
2378:     TSGetIFunction(ts,NULL,&ifun,NULL);
2379:     TSSetType(ts,ifun ? TSBEULER : TSEULER);
2380:   }

2382:   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");

2384:   if (ts->rhsjacobian.reuse) {
2385:     Mat Amat,Pmat;
2386:     SNES snes;
2387:     TSGetSNES(ts,&snes);
2388:     SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);
2389:     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
2390:      * have displaced the RHS matrix */
2391:     if (Amat == ts->Arhs) {
2392:       MatDuplicate(ts->Arhs,MAT_DO_NOT_COPY_VALUES,&Amat);
2393:       SNESSetJacobian(snes,Amat,NULL,NULL,NULL);
2394:       MatDestroy(&Amat);
2395:     }
2396:     if (Pmat == ts->Brhs) {
2397:       MatDuplicate(ts->Brhs,MAT_DO_NOT_COPY_VALUES,&Pmat);
2398:       SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);
2399:       MatDestroy(&Pmat);
2400:     }
2401:   }
2402:   if (ts->ops->setup) {
2403:     (*ts->ops->setup)(ts);
2404:   }

2406:   /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
2407:      to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
2408:    */
2409:   TSGetDM(ts,&dm);
2410:   DMSNESGetFunction(dm,&func,NULL);
2411:   if (!func) {
2412:     DMSNESSetFunction(dm,SNESTSFormFunction,ts);
2413:   }
2414:   /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
2415:      Otherwise, the SNES will use coloring internally to form the Jacobian.
2416:    */
2417:   DMSNESGetJacobian(dm,&jac,NULL);
2418:   DMTSGetIJacobian(dm,&ijac,NULL);
2419:   DMTSGetI2Jacobian(dm,&i2jac,NULL);
2420:   DMTSGetRHSJacobian(dm,&rhsjac,NULL);
2421:   if (!jac && (ijac || i2jac || rhsjac)) {
2422:     DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);
2423:   }
2424:   ts->setupcalled = PETSC_TRUE;
2425:   return(0);
2426: }

2430: /*@
2431:    TSAdjointSetUp - Sets up the internal data structures for the later use
2432:    of an adjoint solver

2434:    Collective on TS

2436:    Input Parameter:
2437: .  ts - the TS context obtained from TSCreate()

2439:    Level: advanced

2441: .keywords: TS, timestep, setup

2443: .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients()
2444: @*/
2445: PetscErrorCode  TSAdjointSetUp(TS ts)
2446: {

2451:   if (ts->adjointsetupcalled) return(0);
2452:   if (!ts->vecs_sensi) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first");

2454:   if (ts->vec_costintegral) { /* if there is integral in the cost function*/
2455:     VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);
2456:     if (ts->vecs_sensip){
2457:       VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);
2458:     }
2459:   }

2461:   if (ts->ops->adjointsetup) {
2462:     (*ts->ops->adjointsetup)(ts);
2463:   }
2464:   ts->adjointsetupcalled = PETSC_TRUE;
2465:   return(0);
2466: }

2470: /*@
2471:    TSReset - Resets a TS context and removes any allocated Vecs and Mats.

2473:    Collective on TS

2475:    Input Parameter:
2476: .  ts - the TS context obtained from TSCreate()

2478:    Level: beginner

2480: .keywords: TS, timestep, reset

2482: .seealso: TSCreate(), TSSetup(), TSDestroy()
2483: @*/
2484: PetscErrorCode  TSReset(TS ts)
2485: {


2491:   if (ts->ops->reset) {
2492:     (*ts->ops->reset)(ts);
2493:   }
2494:   if (ts->snes) {SNESReset(ts->snes);}
2495:   if (ts->adapt) {TSAdaptReset(ts->adapt);}

2497:   MatDestroy(&ts->Arhs);
2498:   MatDestroy(&ts->Brhs);
2499:   VecDestroy(&ts->Frhs);
2500:   VecDestroy(&ts->vec_sol);
2501:   VecDestroy(&ts->vec_dot);
2502:   VecDestroy(&ts->vatol);
2503:   VecDestroy(&ts->vrtol);
2504:   VecDestroyVecs(ts->nwork,&ts->work);

2506:  if (ts->vec_costintegral) {
2507:     VecDestroyVecs(ts->numcost,&ts->vecs_drdy);
2508:     if (ts->vecs_drdp){
2509:       VecDestroyVecs(ts->numcost,&ts->vecs_drdp);
2510:     }
2511:   }
2512:   ts->vecs_sensi  = NULL;
2513:   ts->vecs_sensip = NULL;
2514:   MatDestroy(&ts->Jacp);
2515:   VecDestroy(&ts->vec_costintegral);
2516:   VecDestroy(&ts->vec_costintegrand);
2517:   ts->setupcalled = PETSC_FALSE;
2518:   return(0);
2519: }

2523: /*@
2524:    TSDestroy - Destroys the timestepper context that was created
2525:    with TSCreate().

2527:    Collective on TS

2529:    Input Parameter:
2530: .  ts - the TS context obtained from TSCreate()

2532:    Level: beginner

2534: .keywords: TS, timestepper, destroy

2536: .seealso: TSCreate(), TSSetUp(), TSSolve()
2537: @*/
2538: PetscErrorCode  TSDestroy(TS *ts)
2539: {

2543:   if (!*ts) return(0);
2545:   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; return(0);}

2547:   TSReset((*ts));

2549:   /* if memory was published with SAWs then destroy it */
2550:   PetscObjectSAWsViewOff((PetscObject)*ts);
2551:   if ((*ts)->ops->destroy) {(*(*ts)->ops->destroy)((*ts));}

2553:   TSTrajectoryDestroy(&(*ts)->trajectory);

2555:   TSAdaptDestroy(&(*ts)->adapt);
2556:   TSEventDestroy(&(*ts)->event);

2558:   SNESDestroy(&(*ts)->snes);
2559:   DMDestroy(&(*ts)->dm);
2560:   TSMonitorCancel((*ts));
2561:   TSAdjointMonitorCancel((*ts));

2563:   PetscHeaderDestroy(ts);
2564:   return(0);
2565: }

2569: /*@
2570:    TSGetSNES - Returns the SNES (nonlinear solver) associated with
2571:    a TS (timestepper) context. Valid only for nonlinear problems.

2573:    Not Collective, but SNES is parallel if TS is parallel

2575:    Input Parameter:
2576: .  ts - the TS context obtained from TSCreate()

2578:    Output Parameter:
2579: .  snes - the nonlinear solver context

2581:    Notes:
2582:    The user can then directly manipulate the SNES context to set various
2583:    options, etc.  Likewise, the user can then extract and manipulate the
2584:    KSP, KSP, and PC contexts as well.

2586:    TSGetSNES() does not work for integrators that do not use SNES; in
2587:    this case TSGetSNES() returns NULL in snes.

2589:    Level: beginner

2591: .keywords: timestep, get, SNES
2592: @*/
2593: PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
2594: {

2600:   if (!ts->snes) {
2601:     SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);
2602:     SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);
2603:     PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);
2604:     PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);
2605:     if (ts->dm) {SNESSetDM(ts->snes,ts->dm);}
2606:     if (ts->problem_type == TS_LINEAR) {
2607:       SNESSetType(ts->snes,SNESKSPONLY);
2608:     }
2609:   }
2610:   *snes = ts->snes;
2611:   return(0);
2612: }

2616: /*@
2617:    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context

2619:    Collective

2621:    Input Parameter:
2622: +  ts - the TS context obtained from TSCreate()
2623: -  snes - the nonlinear solver context

2625:    Notes:
2626:    Most users should have the TS created by calling TSGetSNES()

2628:    Level: developer

2630: .keywords: timestep, set, SNES
2631: @*/
2632: PetscErrorCode TSSetSNES(TS ts,SNES snes)
2633: {
2635:   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);

2640:   PetscObjectReference((PetscObject)snes);
2641:   SNESDestroy(&ts->snes);

2643:   ts->snes = snes;

2645:   SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);
2646:   SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);
2647:   if (func == SNESTSFormJacobian) {
2648:     SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);
2649:   }
2650:   return(0);
2651: }

2655: /*@
2656:    TSGetKSP - Returns the KSP (linear solver) associated with
2657:    a TS (timestepper) context.

2659:    Not Collective, but KSP is parallel if TS is parallel

2661:    Input Parameter:
2662: .  ts - the TS context obtained from TSCreate()

2664:    Output Parameter:
2665: .  ksp - the nonlinear solver context

2667:    Notes:
2668:    The user can then directly manipulate the KSP context to set various
2669:    options, etc.  Likewise, the user can then extract and manipulate the
2670:    KSP and PC contexts as well.

2672:    TSGetKSP() does not work for integrators that do not use KSP;
2673:    in this case TSGetKSP() returns NULL in ksp.

2675:    Level: beginner

2677: .keywords: timestep, get, KSP
2678: @*/
2679: PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
2680: {
2682:   SNES           snes;

2687:   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
2688:   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
2689:   TSGetSNES(ts,&snes);
2690:   SNESGetKSP(snes,ksp);
2691:   return(0);
2692: }

2694: /* ----------- Routines to set solver parameters ---------- */

2698: /*@
2699:    TSGetDuration - Gets the maximum number of timesteps to use and
2700:    maximum time for iteration.

2702:    Not Collective

2704:    Input Parameters:
2705: +  ts       - the TS context obtained from TSCreate()
2706: .  maxsteps - maximum number of iterations to use, or NULL
2707: -  maxtime  - final time to iterate to, or NULL

2709:    Level: intermediate

2711: .keywords: TS, timestep, get, maximum, iterations, time
2712: @*/
2713: PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
2714: {
2717:   if (maxsteps) {
2719:     *maxsteps = ts->max_steps;
2720:   }
2721:   if (maxtime) {
2723:     *maxtime = ts->max_time;
2724:   }
2725:   return(0);
2726: }

2730: /*@
2731:    TSSetDuration - Sets the maximum number of timesteps to use and
2732:    maximum time for iteration.

2734:    Logically Collective on TS

2736:    Input Parameters:
2737: +  ts - the TS context obtained from TSCreate()
2738: .  maxsteps - maximum number of iterations to use
2739: -  maxtime - final time to iterate to

2741:    Options Database Keys:
2742: .  -ts_max_steps <maxsteps> - Sets maxsteps
2743: .  -ts_final_time <maxtime> - Sets maxtime

2745:    Notes:
2746:    The default maximum number of iterations is 5000. Default time is 5.0

2748:    Level: intermediate

2750: .keywords: TS, timestep, set, maximum, iterations

2752: .seealso: TSSetExactFinalTime()
2753: @*/
2754: PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
2755: {
2760:   if (maxsteps >= 0) ts->max_steps = maxsteps;
2761:   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
2762:   return(0);
2763: }

2767: /*@
2768:    TSSetSolution - Sets the initial solution vector
2769:    for use by the TS routines.

2771:    Logically Collective on TS and Vec

2773:    Input Parameters:
2774: +  ts - the TS context obtained from TSCreate()
2775: -  u - the solution vector

2777:    Level: beginner

2779: .keywords: TS, timestep, set, solution, initial conditions
2780: @*/
2781: PetscErrorCode  TSSetSolution(TS ts,Vec u)
2782: {
2784:   DM             dm;

2789:   PetscObjectReference((PetscObject)u);
2790:   VecDestroy(&ts->vec_sol);
2791:   ts->vec_sol = u;

2793:   TSGetDM(ts,&dm);
2794:   DMShellSetGlobalVector(dm,u);
2795:   return(0);
2796: }

2800: /*@
2801:    TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time

2803:    Logically Collective on TS

2805:    Input Parameters:
2806: +  ts - the TS context obtained from TSCreate()
2807: .  steps - number of steps to use

2809:    Level: intermediate

2811:    Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this
2812:           so as to integrate back to less than the original timestep

2814: .keywords: TS, timestep, set, maximum, iterations

2816: .seealso: TSSetExactFinalTime()
2817: @*/
2818: PetscErrorCode  TSAdjointSetSteps(TS ts,PetscInt steps)
2819: {
2823:   if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps");
2824:   if (steps > ts->total_steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps");
2825:   ts->adjoint_max_steps = steps;
2826:   return(0);
2827: }

2831: /*@
2832:    TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial conditions and w.r.t. the problem parameters 
2833:       for use by the TSAdjoint routines.

2835:    Logically Collective on TS and Vec

2837:    Input Parameters:
2838: +  ts - the TS context obtained from TSCreate()
2839: .  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
2840: -  mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters

2842:    Level: beginner

2844:    Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime  mu_i = df/dp|finaltime

2846: .keywords: TS, timestep, set, sensitivity, initial conditions
2847: @*/
2848: PetscErrorCode  TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu)
2849: {
2853:   ts->vecs_sensi  = lambda;
2854:   ts->vecs_sensip = mu;
2855:   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");
2856:   ts->numcost  = numcost;
2857:   return(0);
2858: }

2862: /*@C
2863:   TSAdjointSetRHSJacobian - 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.

2865:   Logically Collective on TS

2867:   Input Parameters:
2868: + ts   - The TS context obtained from TSCreate()
2869: - func - The function

2871:   Calling sequence of func:
2872: $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx);
2873: +   t - current timestep
2874: .   y - input vector (current ODE solution)
2875: .   A - output matrix
2876: -   ctx - [optional] user-defined function context

2878:   Level: intermediate

2880:   Notes: 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

2882: .keywords: TS, sensitivity
2883: .seealso:
2884: @*/
2885: PetscErrorCode  TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx)
2886: {


2893:   ts->rhsjacobianp    = func;
2894:   ts->rhsjacobianpctx = ctx;
2895:   if(Amat) {
2896:     PetscObjectReference((PetscObject)Amat);
2897:     MatDestroy(&ts->Jacp);
2898:     ts->Jacp = Amat;
2899:   }
2900:   return(0);
2901: }

2905: /*@C
2906:   TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function.

2908:   Collective on TS

2910:   Input Parameters:
2911: . ts   - The TS context obtained from TSCreate()

2913:   Level: developer

2915: .keywords: TS, sensitivity
2916: .seealso: TSAdjointSetRHSJacobian()
2917: @*/
2918: PetscErrorCode  TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat)
2919: {


2927:   PetscStackPush("TS user JacobianP function for sensitivity analysis");
2928:   (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx);
2929:   PetscStackPop;
2930:   return(0);
2931: }

2935: /*@C
2936:     TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions

2938:     Logically Collective on TS

2940:     Input Parameters:
2941: +   ts - the TS context obtained from TSCreate()
2942: .   numcost - number of gradients to be computed, this is the number of cost functions
2943: .   rf - routine for evaluating the integrand function
2944: .   drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y
2945: .   drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p
Binary file (standard input) matches