Actual source code: ts.c

petsc-3.7.0 2016-04-25
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:       if (ijacobian) {
930:         TSGetRHSMats_Private(ts,&Arhs,&Brhs);
931:       } else {
932:         TSGetIJacobian(ts,&Arhs,&Brhs,NULL,NULL);
933:       }
934:       TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);
935:     }
936:     if (Arhs == A) {           /* No IJacobian, so we only have the RHS matrix */
937:       ts->rhsjacobian.scale = -1;
938:       ts->rhsjacobian.shift = shift;
939:       MatScale(A,-1);
940:       MatShift(A,shift);
941:       if (A != B) {
942:         MatScale(B,-1);
943:         MatShift(B,shift);
944:       }
945:     } else if (Arhs) {          /* Both IJacobian and RHSJacobian */
946:       MatStructure axpy = DIFFERENT_NONZERO_PATTERN;
947:       if (!ijacobian) {         /* No IJacobian provided, but we have a separate RHS matrix */
948:         MatZeroEntries(A);
949:         MatShift(A,shift);
950:         if (A != B) {
951:           MatZeroEntries(B);
952:           MatShift(B,shift);
953:         }
954:       }
955:       MatAXPY(A,-1,Arhs,axpy);
956:       if (A != B) {
957:         MatAXPY(B,-1,Brhs,axpy);
958:       }
959:     }
960:   }
961:   PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);
962:   return(0);
963: }

967: /*@C
968:     TSSetRHSFunction - Sets the routine for evaluating the function,
969:     where U_t = G(t,u).

971:     Logically Collective on TS

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

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

983: +   t - current timestep
984: .   u - input vector
985: .   F - function vector
986: -   ctx - [optional] user-defined function context

988:     Level: beginner

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

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

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


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

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

1024:     Logically Collective on TS

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

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

1035: +   t - current timestep
1036: .   u - output vector
1037: -   ctx - [optional] user-defined function context

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

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

1046:     Level: beginner

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

1050: .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction()
1051: @*/
1052: PetscErrorCode  TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
1053: {
1055:   DM             dm;

1059:   TSGetDM(ts,&dm);
1060:   DMTSSetSolutionFunction(dm,f,ctx);
1061:   return(0);
1062: }

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

1069:     Logically Collective on TS

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

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

1080: +   t - current timestep
1081: .   u - output vector
1082: -   ctx - [optional] user-defined function context

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

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

1090:     Level: beginner

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

1094: .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction()
1095: @*/
1096: PetscErrorCode  TSSetForcingFunction(TS ts,TSForcingFunction f,void *ctx)
1097: {
1099:   DM             dm;

1103:   TSGetDM(ts,&dm);
1104:   DMTSSetForcingFunction(dm,f,ctx);
1105:   return(0);
1106: }

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

1114:    Logically Collective on TS

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

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

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

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

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

1139:    Level: beginner

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

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

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


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


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

1190:    Logically Collective on TS

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

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

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

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

1210:    Level: beginner

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

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


1227:   TSGetDM(ts,&dm);
1228:   DMTSSetIFunction(dm,f,ctx);

1230:   TSGetSNES(ts,&snes);
1231:   if (!r && !ts->dm && ts->vec_sol) {
1232:     VecDuplicate(ts->vec_sol,&ralloc);
1233:     r  = ralloc;
1234:   }
1235:   SNESSetFunction(snes,r,SNESTSFormFunction,ts);
1236:   VecDestroy(&ralloc);
1237:   return(0);
1238: }

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

1245:    Not Collective

1247:    Input Parameter:
1248: .  ts - the TS context

1250:    Output Parameter:
1251: +  r - vector to hold residual (or NULL)
1252: .  func - the function to compute residual (or NULL)
1253: -  ctx - the function context (or NULL)

1255:    Level: advanced

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

1259: .seealso: TSSetIFunction(), SNESGetFunction()
1260: @*/
1261: PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx)
1262: {
1264:   SNES           snes;
1265:   DM             dm;

1269:   TSGetSNES(ts,&snes);
1270:   SNESGetFunction(snes,r,NULL,NULL);
1271:   TSGetDM(ts,&dm);
1272:   DMTSGetIFunction(dm,func,ctx);
1273:   return(0);
1274: }

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

1281:    Not Collective

1283:    Input Parameter:
1284: .  ts - the TS context

1286:    Output Parameter:
1287: +  r - vector to hold computed right hand side (or NULL)
1288: .  func - the function to compute right hand side (or NULL)
1289: -  ctx - the function context (or NULL)

1291:    Level: advanced

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

1295: .seealso: TSSetRHSFunction(), SNESGetFunction()
1296: @*/
1297: PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx)
1298: {
1300:   SNES           snes;
1301:   DM             dm;

1305:   TSGetSNES(ts,&snes);
1306:   SNESGetFunction(snes,r,NULL,NULL);
1307:   TSGetDM(ts,&dm);
1308:   DMTSGetRHSFunction(dm,func,ctx);
1309:   return(0);
1310: }

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

1318:    Logically Collective on TS

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

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

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

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

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

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

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

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

1356:    Level: beginner

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

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

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


1376:   TSGetDM(ts,&dm);
1377:   DMTSSetIJacobian(dm,f,ctx);

1379:   TSGetSNES(ts,&snes);
1380:   SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);
1381:   return(0);
1382: }

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

1392:    Logically Collective

1394:    Input Arguments:
1395: +  ts - TS context obtained from TSCreate()
1396: -  reuse - PETSC_TRUE if the RHS Jacobian

1398:    Level: intermediate

1400: .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
1401: @*/
1402: PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse)
1403: {
1405:   ts->rhsjacobian.reuse = reuse;
1406:   return(0);
1407: }

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

1414:    Logically Collective on TS

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

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

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

1432:    Level: beginner

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

1436: .seealso: TSSetI2Jacobian()
1437: @*/
1438: PetscErrorCode TSSetI2Function(TS ts,Vec F,TSI2Function fun,void *ctx)
1439: {
1440:   DM             dm;

1446:   TSSetIFunction(ts,F,NULL,NULL);
1447:   TSGetDM(ts,&dm);
1448:   DMTSSetI2Function(dm,fun,ctx);
1449:   return(0);
1450: }

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

1457:   Not Collective

1459:   Input Parameter:
1460: . ts - the TS context

1462:   Output Parameter:
1463: + r - vector to hold residual (or NULL)
1464: . fun - the function to compute residual (or NULL)
1465: - ctx - the function context (or NULL)

1467:   Level: advanced

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

1471: .seealso: TSSetI2Function(), SNESGetFunction()
1472: @*/
1473: PetscErrorCode TSGetI2Function(TS ts,Vec *r,TSI2Function *fun,void **ctx)
1474: {
1476:   SNES           snes;
1477:   DM             dm;

1481:   TSGetSNES(ts,&snes);
1482:   SNESGetFunction(snes,r,NULL,NULL);
1483:   TSGetDM(ts,&dm);
1484:   DMTSGetI2Function(dm,fun,ctx);
1485:   return(0);
1486: }

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

1494:    Logically Collective on TS

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

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

1506: +  t    - time at step/stage being solved
1507: .  U    - state vector
1508: .  U_t  - time derivative of state vector
1509: .  U_tt - second time derivative of state vector
1510: .  v    - shift for U_t
1511: .  a    - shift for U_tt
1512: .  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
1513: .  P    - preconditioning matrix for J, may be same as J
1514: .  m    - flag indicating information about the preconditioner matrix
1515:           structure (same as flag in KSPSetOperators())
1516: -  ctx  - [optional] user-defined context for matrix evaluation routine

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

1521:    The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be
1522:    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.
1523:    The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U  where the positive "shift"
1524:    parameters 'a' and 'b' and vectors W, W' depend on the integration method, step size, and past states.

1526:    Level: beginner

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

1530: .seealso: TSSetI2Function()
1531: @*/
1532: PetscErrorCode TSSetI2Jacobian(TS ts,Mat J,Mat P,TSI2Jacobian jac,void *ctx)
1533: {
1534:   DM             dm;

1541:   TSSetIJacobian(ts,J,P,NULL,NULL);
1542:   TSGetDM(ts,&dm);
1543:   DMTSSetI2Jacobian(dm,jac,ctx);
1544:   return(0);
1545: }

1549: /*@C
1550:   TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep.

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

1554:   Input Parameter:
1555: . ts  - The TS context obtained from TSCreate()

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

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

1565:   Level: advanced

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

1569: .keywords: TS, timestep, get, matrix, Jacobian
1570: @*/
1571: PetscErrorCode  TSGetI2Jacobian(TS ts,Mat *J,Mat *P,TSI2Jacobian *jac,void **ctx)
1572: {
1574:   SNES           snes;
1575:   DM             dm;

1578:   TSGetSNES(ts,&snes);
1579:   SNESSetUpMatrices(snes);
1580:   SNESGetJacobian(snes,J,P,NULL,NULL);
1581:   TSGetDM(ts,&dm);
1582:   DMTSGetI2Jacobian(dm,jac,ctx);
1583:   return(0);
1584: }

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

1591:   Collective on TS and Vec

1593:   Input Parameters:
1594: + ts - the TS context
1595: . t - current time
1596: . U - state vector
1597: . V - time derivative of state vector (U_t)
1598: - A - second time derivative of state vector (U_tt)

1600:   Output Parameter:
1601: . F - the residual vector

1603:   Note:
1604:   Most users should not need to explicitly call this routine, as it
1605:   is used internally within the nonlinear solvers.

1607:   Level: developer

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

1611: .seealso: TSSetI2Function()
1612: @*/
1613: PetscErrorCode TSComputeI2Function(TS ts,PetscReal t,Vec U,Vec V,Vec A,Vec F)
1614: {
1615:   DM             dm;
1616:   TSI2Function   I2Function;
1617:   void           *ctx;
1618:   TSRHSFunction  rhsfunction;


1628:   TSGetDM(ts,&dm);
1629:   DMTSGetI2Function(dm,&I2Function,&ctx);
1630:   DMTSGetRHSFunction(dm,&rhsfunction,NULL);

1632:   if (!I2Function) {
1633:     TSComputeIFunction(ts,t,U,A,F,PETSC_FALSE);
1634:     return(0);
1635:   }

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

1639:   PetscStackPush("TS user implicit function");
1640:   I2Function(ts,t,U,V,A,F,ctx);
1641:   PetscStackPop;

1643:   if (rhsfunction) {
1644:     Vec Frhs;
1645:     TSGetRHSVec_Private(ts,&Frhs);
1646:     TSComputeRHSFunction(ts,t,U,Frhs);
1647:     VecAXPY(F,-1,Frhs);
1648:   }

1650:   PetscLogEventEnd(TS_FunctionEval,ts,U,V,F);
1651:   return(0);
1652: }

1656: /*@
1657:   TSComputeI2Jacobian - Evaluates the Jacobian of the DAE

1659:   Collective on TS and Vec

1661:   Input Parameters:
1662: + ts - the TS context
1663: . t - current timestep
1664: . U - state vector
1665: . V - time derivative of state vector
1666: . A - second time derivative of state vector
1667: . shiftV - shift to apply, see note below
1668: - shiftA - shift to apply, see note below

1670:   Output Parameters:
1671: + J - Jacobian matrix
1672: - P - optional preconditioning matrix

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

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

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

1682:   Level: developer

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

1686: .seealso:  TSSetI2Jacobian()
1687: @*/
1688: PetscErrorCode TSComputeI2Jacobian(TS ts,PetscReal t,Vec U,Vec V,Vec A,PetscReal shiftV,PetscReal shiftA,Mat J,Mat P)
1689: {
1690:   DM             dm;
1691:   TSI2Jacobian   I2Jacobian;
1692:   void           *ctx;
1693:   TSRHSJacobian  rhsjacobian;


1704:   TSGetDM(ts,&dm);
1705:   DMTSGetI2Jacobian(dm,&I2Jacobian,&ctx);
1706:   DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);

1708:   if (!I2Jacobian) {
1709:     TSComputeIJacobian(ts,t,U,A,shiftA,J,P,PETSC_FALSE);
1710:     return(0);
1711:   }

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

1715:   PetscStackPush("TS user implicit Jacobian");
1716:   I2Jacobian(ts,t,U,V,A,shiftV,shiftA,J,P,ctx);
1717:   PetscStackPop;

1719:   if (rhsjacobian) {
1720:     Mat Jrhs,Prhs; MatStructure axpy = DIFFERENT_NONZERO_PATTERN;
1721:     TSGetRHSMats_Private(ts,&Jrhs,&Prhs);
1722:     TSComputeRHSJacobian(ts,t,U,Jrhs,Prhs);
1723:     MatAXPY(J,-1,Jrhs,axpy);
1724:     if (P != J) {MatAXPY(P,-1,Prhs,axpy);}
1725:   }

1727:   PetscLogEventEnd(TS_JacobianEval,ts,U,J,P);
1728:   return(0);
1729: }

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

1737:    Logically Collective on TS and Vec

1739:    Input Parameters:
1740: +  ts - the TS context obtained from TSCreate()
1741: .  u - the solution vector
1742: -  v - the time derivative vector

1744:    Level: beginner

1746: .keywords: TS, timestep, set, solution, initial conditions
1747: @*/
1748: PetscErrorCode  TS2SetSolution(TS ts,Vec u,Vec v)
1749: {

1756:   TSSetSolution(ts,u);
1757:   PetscObjectReference((PetscObject)v);
1758:   VecDestroy(&ts->vec_dot);
1759:   ts->vec_dot = v;
1760:   return(0);
1761: }

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

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

1773:    Input Parameter:
1774: .  ts - the TS context obtained from TSCreate()

1776:    Output Parameter:
1777: +  u - the vector containing the solution
1778: -  v - the vector containing the time derivative

1780:    Level: intermediate

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

1784: .keywords: TS, timestep, get, solution
1785: @*/
1786: PetscErrorCode  TS2GetSolution(TS ts,Vec *u,Vec *v)
1787: {
1792:   if (u) *u = ts->vec_sol;
1793:   if (v) *v = ts->vec_dot;
1794:   return(0);
1795: }

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

1802:   Collective on PetscViewer

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

1809:    Level: intermediate

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

1814:   Notes for advanced users:
1815:   Most users should not need to know the details of the binary storage
1816:   format, since TSLoad() and TSView() completely hide these details.
1817:   But for anyone who's interested, the standard binary matrix storage
1818:   format is
1819: .vb
1820:      has not yet been determined
1821: .ve

1823: .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad()
1824: @*/
1825: PetscErrorCode  TSLoad(TS ts, PetscViewer viewer)
1826: {
1828:   PetscBool      isbinary;
1829:   PetscInt       classid;
1830:   char           type[256];
1831:   DMTS           sdm;
1832:   DM             dm;

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

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

1857: #include <petscdraw.h>
1858: #if defined(PETSC_HAVE_SAWS)
1859: #include <petscviewersaws.h>
1860: #endif
1863: /*@C
1864:     TSView - Prints the TS data structure.

1866:     Collective on TS

1868:     Input Parameters:
1869: +   ts - the TS context obtained from TSCreate()
1870: -   viewer - visualization context

1872:     Options Database Key:
1873: .   -ts_view - calls TSView() at end of TSStep()

1875:     Notes:
1876:     The available visualization contexts include
1877: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1878: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1879:          output where only the first processor opens
1880:          the file.  All other processors send their
1881:          data to the first processor to print.

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

1886:     Level: beginner

1888: .keywords: TS, timestep, view

1890: .seealso: PetscViewerASCIIOpen()
1891: @*/
1892: PetscErrorCode  TSView(TS ts,PetscViewer viewer)
1893: {
1895:   TSType         type;
1896:   PetscBool      iascii,isstring,isundials,isbinary,isdraw;
1897:   DMTS           sdm;
1898: #if defined(PETSC_HAVE_SAWS)
1899:   PetscBool      issaws;
1900: #endif

1904:   if (!viewer) {
1905:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);
1906:   }

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

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

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

1978:     PetscObjectGetName((PetscObject)ts,&name);
1979:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
1980:     if (!((PetscObject)ts)->amsmem && !rank) {
1981:       char       dir[1024];

1983:       PetscObjectViewSAWs((PetscObject)ts,viewer);
1984:       PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);
1985:       PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT));
1986:       PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);
1987:       PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE));
1988:     }
1989:     if (ts->ops->view) {
1990:       (*ts->ops->view)(ts,viewer);
1991:     }
1992: #endif
1993:   }

1995:   PetscViewerASCIIPushTab(viewer);
1996:   PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);
1997:   PetscViewerASCIIPopTab(viewer);
1998:   return(0);
1999: }


2004: /*@
2005:    TSSetApplicationContext - Sets an optional user-defined context for
2006:    the timesteppers.

2008:    Logically Collective on TS

2010:    Input Parameters:
2011: +  ts - the TS context obtained from TSCreate()
2012: -  usrP - optional user context

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

2017:    Level: intermediate

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

2021: .seealso: TSGetApplicationContext()
2022: @*/
2023: PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
2024: {
2027:   ts->user = usrP;
2028:   return(0);
2029: }

2033: /*@
2034:     TSGetApplicationContext - Gets the user-defined context for the
2035:     timestepper.

2037:     Not Collective

2039:     Input Parameter:
2040: .   ts - the TS context obtained from TSCreate()

2042:     Output Parameter:
2043: .   usrP - user context

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

2048:     Level: intermediate

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

2052: .seealso: TSSetApplicationContext()
2053: @*/
2054: PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
2055: {
2058:   *(void**)usrP = ts->user;
2059:   return(0);
2060: }

2064: /*@
2065:    TSGetTimeStepNumber - Gets the number of time steps completed.

2067:    Not Collective

2069:    Input Parameter:
2070: .  ts - the TS context obtained from TSCreate()

2072:    Output Parameter:
2073: .  iter - number of steps completed so far

2075:    Level: intermediate

2077: .keywords: TS, timestep, get, iteration, number
2078: .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep()
2079: @*/
2080: PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt *iter)
2081: {
2085:   *iter = ts->steps;
2086:   return(0);
2087: }

2091: /*@
2092:    TSSetInitialTimeStep - Sets the initial timestep to be used,
2093:    as well as the initial time.

2095:    Logically Collective on TS

2097:    Input Parameters:
2098: +  ts - the TS context obtained from TSCreate()
2099: .  initial_time - the initial time
2100: -  time_step - the size of the timestep

2102:    Level: intermediate

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

2106: .keywords: TS, set, initial, timestep
2107: @*/
2108: PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
2109: {

2114:   TSSetTimeStep(ts,time_step);
2115:   TSSetTime(ts,initial_time);
2116:   return(0);
2117: }

2121: /*@
2122:    TSSetTimeStep - Allows one to reset the timestep at any time,
2123:    useful for simple pseudo-timestepping codes.

2125:    Logically Collective on TS

2127:    Input Parameters:
2128: +  ts - the TS context obtained from TSCreate()
2129: -  time_step - the size of the timestep

2131:    Level: intermediate

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

2135: .keywords: TS, set, timestep
2136: @*/
2137: PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
2138: {
2142:   ts->time_step = time_step;
2143:   return(0);
2144: }

2148: /*@
2149:    TSSetExactFinalTime - Determines whether to adapt the final time step to
2150:      match the exact final time, interpolate solution to the exact final time,
2151:      or just return at the final time TS computed.

2153:   Logically Collective on TS

2155:    Input Parameter:
2156: +   ts - the time-step context
2157: -   eftopt - exact final time option

2159: $  TS_EXACTFINALTIME_STEPOVER    - Don't do anything if final time is exceeded
2160: $  TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time
2161: $  TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time

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

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

2169:    Level: beginner

2171: .seealso: TSExactFinalTimeOption
2172: @*/
2173: PetscErrorCode  TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
2174: {
2178:   ts->exact_final_time = eftopt;
2179:   return(0);
2180: }

2184: /*@
2185:    TSGetTimeStep - Gets the current timestep size.

2187:    Not Collective

2189:    Input Parameter:
2190: .  ts - the TS context obtained from TSCreate()

2192:    Output Parameter:
2193: .  dt - the current timestep size

2195:    Level: intermediate

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

2199: .keywords: TS, get, timestep
2200: @*/
2201: PetscErrorCode  TSGetTimeStep(TS ts,PetscReal *dt)
2202: {
2206:   *dt = ts->time_step;
2207:   return(0);
2208: }

2212: /*@
2213:    TSGetSolution - Returns the solution at the present timestep. It
2214:    is valid to call this routine inside the function that you are evaluating
2215:    in order to move to the new timestep. This vector not changed until
2216:    the solution at the next timestep has been calculated.

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

2220:    Input Parameter:
2221: .  ts - the TS context obtained from TSCreate()

2223:    Output Parameter:
2224: .  v - the vector containing the solution

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

2229:    Level: intermediate

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

2233: .keywords: TS, timestep, get, solution
2234: @*/
2235: PetscErrorCode  TSGetSolution(TS ts,Vec *v)
2236: {
2240:   *v = ts->vec_sol;
2241:   return(0);
2242: }

2246: /*@
2247:    TSGetCostGradients - Returns the gradients from the TSAdjointSolve()

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

2251:    Input Parameter:
2252: .  ts - the TS context obtained from TSCreate()

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

2258:    Level: intermediate

2260: .seealso: TSGetTimeStep()

2262: .keywords: TS, timestep, get, sensitivity
2263: @*/
2264: PetscErrorCode  TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu)
2265: {
2268:   if (numcost) *numcost = ts->numcost;
2269:   if (lambda)  *lambda  = ts->vecs_sensi;
2270:   if (mu)      *mu      = ts->vecs_sensip;
2271:   return(0);
2272: }

2274: /* ----- Routines to initialize and destroy a timestepper ---- */
2277: /*@
2278:   TSSetProblemType - Sets the type of problem to be solved.

2280:   Not collective

2282:   Input Parameters:
2283: + ts   - The TS
2284: - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2285: .vb
2286:          U_t - A U = 0      (linear)
2287:          U_t - A(t) U = 0   (linear)
2288:          F(t,U,U_t) = 0     (nonlinear)
2289: .ve

2291:    Level: beginner

2293: .keywords: TS, problem type
2294: .seealso: TSSetUp(), TSProblemType, TS
2295: @*/
2296: PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
2297: {

2302:   ts->problem_type = type;
2303:   if (type == TS_LINEAR) {
2304:     SNES snes;
2305:     TSGetSNES(ts,&snes);
2306:     SNESSetType(snes,SNESKSPONLY);
2307:   }
2308:   return(0);
2309: }

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

2316:   Not collective

2318:   Input Parameter:
2319: . ts   - The TS

2321:   Output Parameter:
2322: . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2323: .vb
2324:          M U_t = A U
2325:          M(t) U_t = A(t) U
2326:          F(t,U,U_t)
2327: .ve

2329:    Level: beginner

2331: .keywords: TS, problem type
2332: .seealso: TSSetUp(), TSProblemType, TS
2333: @*/
2334: PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
2335: {
2339:   *type = ts->problem_type;
2340:   return(0);
2341: }

2345: /*@
2346:    TSSetUp - Sets up the internal data structures for the later use
2347:    of a timestepper.

2349:    Collective on TS

2351:    Input Parameter:
2352: .  ts - the TS context obtained from TSCreate()

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

2361:    Level: advanced

2363: .keywords: TS, timestep, setup

2365: .seealso: TSCreate(), TSStep(), TSDestroy()
2366: @*/
2367: PetscErrorCode  TSSetUp(TS ts)
2368: {
2370:   DM             dm;
2371:   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2372:   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
2373:   TSIFunction    ifun;
2374:   TSIJacobian    ijac;
2375:   TSI2Jacobian   i2jac;
2376:   TSRHSJacobian  rhsjac;

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

2382:   ts->total_steps = 0;
2383:   if (!((PetscObject)ts)->type_name) {
2384:     TSGetIFunction(ts,NULL,&ifun,NULL);
2385:     TSSetType(ts,ifun ? TSBEULER : TSEULER);
2386:   }

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

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

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

2436: /*@
2437:    TSAdjointSetUp - Sets up the internal data structures for the later use
2438:    of an adjoint solver

2440:    Collective on TS

2442:    Input Parameter:
2443: .  ts - the TS context obtained from TSCreate()

2445:    Level: advanced

2447: .keywords: TS, timestep, setup

2449: .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients()
2450: @*/
2451: PetscErrorCode  TSAdjointSetUp(TS ts)
2452: {

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

2460:   if (ts->vec_costintegral) { /* if there is integral in the cost function*/
2461:     VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);
2462:     if (ts->vecs_sensip){
2463:       VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);
2464:     }
2465:   }

2467:   if (ts->ops->adjointsetup) {
2468:     (*ts->ops->adjointsetup)(ts);
2469:   }
2470:   ts->adjointsetupcalled = PETSC_TRUE;
2471:   return(0);
2472: }

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

2479:    Collective on TS

2481:    Input Parameter:
2482: .  ts - the TS context obtained from TSCreate()

2484:    Level: beginner

2486: .keywords: TS, timestep, reset

2488: .seealso: TSCreate(), TSSetup(), TSDestroy()
2489: @*/
2490: PetscErrorCode  TSReset(TS ts)
2491: {


2497:   if (ts->ops->reset) {
2498:     (*ts->ops->reset)(ts);
2499:   }
2500:   if (ts->snes) {SNESReset(ts->snes);}
2501:   if (ts->adapt) {TSAdaptReset(ts->adapt);}

2503:   MatDestroy(&ts->Arhs);
2504:   MatDestroy(&ts->Brhs);
2505:   VecDestroy(&ts->Frhs);
2506:   VecDestroy(&ts->vec_sol);
2507:   VecDestroy(&ts->vec_dot);
2508:   VecDestroy(&ts->vatol);
2509:   VecDestroy(&ts->vrtol);
2510:   VecDestroyVecs(ts->nwork,&ts->work);

2512:  if (ts->vec_costintegral) {
2513:     VecDestroyVecs(ts->numcost,&ts->vecs_drdy);
2514:     if (ts->vecs_drdp){
2515:       VecDestroyVecs(ts->numcost,&ts->vecs_drdp);
2516:     }
2517:   }
2518:   ts->vecs_sensi  = NULL;
2519:   ts->vecs_sensip = NULL;
2520:   MatDestroy(&ts->Jacp);
2521:   VecDestroy(&ts->vec_costintegral);
2522:   VecDestroy(&ts->vec_costintegrand);
2523:   ts->setupcalled = PETSC_FALSE;
2524:   return(0);
2525: }

2529: /*@
2530:    TSDestroy - Destroys the timestepper context that was created
2531:    with TSCreate().

2533:    Collective on TS

2535:    Input Parameter:
2536: .  ts - the TS context obtained from TSCreate()

2538:    Level: beginner

2540: .keywords: TS, timestepper, destroy

2542: .seealso: TSCreate(), TSSetUp(), TSSolve()
2543: @*/
2544: PetscErrorCode  TSDestroy(TS *ts)
2545: {

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

2553:   TSReset((*ts));

2555:   /* if memory was published with SAWs then destroy it */
2556:   PetscObjectSAWsViewOff((PetscObject)*ts);
2557:   if ((*ts)->ops->destroy) {(*(*ts)->ops->destroy)((*ts));}

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

2561:   TSAdaptDestroy(&(*ts)->adapt);
2562:   TSEventDestroy(&(*ts)->event);

2564:   SNESDestroy(&(*ts)->snes);
2565:   DMDestroy(&(*ts)->dm);
2566:   TSMonitorCancel((*ts));
2567:   TSAdjointMonitorCancel((*ts));

2569:   PetscHeaderDestroy(ts);
2570:   return(0);
2571: }

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

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

2581:    Input Parameter:
2582: .  ts - the TS context obtained from TSCreate()

2584:    Output Parameter:
2585: .  snes - the nonlinear solver context

2587:    Notes:
2588:    The user can then directly manipulate the SNES context to set various
2589:    options, etc.  Likewise, the user can then extract and manipulate the
2590:    KSP, KSP, and PC contexts as well.

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

2595:    Level: beginner

2597: .keywords: timestep, get, SNES
2598: @*/
2599: PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
2600: {

2606:   if (!ts->snes) {
2607:     SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);
2608:     SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);
2609:     PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);
2610:     PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);
2611:     if (ts->dm) {SNESSetDM(ts->snes,ts->dm);}
2612:     if (ts->problem_type == TS_LINEAR) {
2613:       SNESSetType(ts->snes,SNESKSPONLY);
2614:     }
2615:   }
2616:   *snes = ts->snes;
2617:   return(0);
2618: }

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

2625:    Collective

2627:    Input Parameter:
2628: +  ts - the TS context obtained from TSCreate()
2629: -  snes - the nonlinear solver context

2631:    Notes:
2632:    Most users should have the TS created by calling TSGetSNES()

2634:    Level: developer

2636: .keywords: timestep, set, SNES
2637: @*/
2638: PetscErrorCode TSSetSNES(TS ts,SNES snes)
2639: {
2641:   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);

2646:   PetscObjectReference((PetscObject)snes);
2647:   SNESDestroy(&ts->snes);

2649:   ts->snes = snes;

2651:   SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);
2652:   SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);
2653:   if (func == SNESTSFormJacobian) {
2654:     SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);
2655:   }
2656:   return(0);
2657: }

2661: /*@
2662:    TSGetKSP - Returns the KSP (linear solver) associated with
2663:    a TS (timestepper) context.

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

2667:    Input Parameter:
2668: .  ts - the TS context obtained from TSCreate()

2670:    Output Parameter:
2671: .  ksp - the nonlinear solver context

2673:    Notes:
2674:    The user can then directly manipulate the KSP context to set various
2675:    options, etc.  Likewise, the user can then extract and manipulate the
2676:    KSP and PC contexts as well.

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

2681:    Level: beginner

2683: .keywords: timestep, get, KSP
2684: @*/
2685: PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
2686: {
2688:   SNES           snes;

2693:   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
2694:   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
2695:   TSGetSNES(ts,&snes);
2696:   SNESGetKSP(snes,ksp);
2697:   return(0);
2698: }

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

2704: /*@
2705:    TSGetDuration - Gets the maximum number of timesteps to use and
2706:    maximum time for iteration.

2708:    Not Collective

2710:    Input Parameters:
2711: +  ts       - the TS context obtained from TSCreate()
2712: .  maxsteps - maximum number of iterations to use, or NULL
2713: -  maxtime  - final time to iterate to, or NULL

2715:    Level: intermediate

2717: .keywords: TS, timestep, get, maximum, iterations, time
2718: @*/
2719: PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
2720: {
2723:   if (maxsteps) {
2725:     *maxsteps = ts->max_steps;
2726:   }
2727:   if (maxtime) {
2729:     *maxtime = ts->max_time;
2730:   }
2731:   return(0);
2732: }

2736: /*@
2737:    TSSetDuration - Sets the maximum number of timesteps to use and
2738:    maximum time for iteration.

2740:    Logically Collective on TS

2742:    Input Parameters:
2743: +  ts - the TS context obtained from TSCreate()
2744: .  maxsteps - maximum number of iterations to use
2745: -  maxtime - final time to iterate to

2747:    Options Database Keys:
2748: .  -ts_max_steps <maxsteps> - Sets maxsteps
2749: .  -ts_final_time <maxtime> - Sets maxtime

2751:    Notes:
2752:    The default maximum number of iterations is 5000. Default time is 5.0

2754:    Level: intermediate

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

2758: .seealso: TSSetExactFinalTime()
2759: @*/
2760: PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
2761: {
2766:   if (maxsteps >= 0) ts->max_steps = maxsteps;
2767:   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
2768:   return(0);
2769: }

2773: /*@
2774:    TSSetSolution - Sets the initial solution vector
2775:    for use by the TS routines.

2777:    Logically Collective on TS and Vec

2779:    Input Parameters:
2780: +  ts - the TS context obtained from TSCreate()
2781: -  u - the solution vector

2783:    Level: beginner

2785: .keywords: TS, timestep, set, solution, initial conditions
2786: @*/
2787: PetscErrorCode  TSSetSolution(TS ts,Vec u)
2788: {
2790:   DM             dm;

2795:   PetscObjectReference((PetscObject)u);
2796:   VecDestroy(&ts->vec_sol);
2797:   ts->vec_sol = u;

2799:   TSGetDM(ts,&dm);
2800:   DMShellSetGlobalVector(dm,u);
2801:   return(0);
2802: }

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

2809:    Logically Collective on TS

2811:    Input Parameters:
2812: +  ts - the TS context obtained from TSCreate()
2813: .  steps - number of steps to use

2815:    Level: intermediate

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

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

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

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

2841:    Logically Collective on TS and Vec

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

2848:    Level: beginner

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

2852: .keywords: TS, timestep, set, sensitivity, initial conditions
2853: @*/
2854: PetscErrorCode  TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu)
2855: {
2859:   ts->vecs_sensi  = lambda;
2860:   ts->vecs_sensip = mu;
2861:   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");
2862:   ts->numcost  = numcost;
2863:   return(0);
2864: }

2868: /*@C
2869:   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.

2871:   Logically Collective on TS

2873:   Input Parameters:
2874: + ts   - The TS context obtained from TSCreate()
2875: - func - The function

2877:   Calling sequence of func:
2878: $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx);
2879: +   t - current timestep
2880: .   y - input vector (current ODE solution)
2881: .   A - output matrix
2882: -   ctx - [optional] user-defined function context

2884:   Level: intermediate

2886:   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

2888: .keywords: TS, sensitivity
2889: .seealso:
2890: @*/
2891: PetscErrorCode  TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx)
2892: {


2899:   ts->rhsjacobianp    = func;
2900:   ts->rhsjacobianpctx = ctx;
2901:   if(Amat) {
2902:     PetscObjectReference((PetscObject)Amat);
2903:     MatDestroy(&ts->Jacp);
2904:     ts->Jacp = Amat;
2905:   }
2906:   return(0);
2907: }

2911: /*@C
2912:   TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function.

2914:   Collective on TS

2916:   Input Parameters:
2917: . ts   - The TS context obtained from TSCreate()

2919:   Level: developer

2921: .keywords: TS, sensitivity
2922: .seealso: TSAdjointSetRHSJacobian()
2923: @*/
2924: PetscErrorCode  TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat)
2925: {


2933:   PetscStackPush("TS user JacobianP function for sensitivity analysis");
2934:   (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx);
2935:   PetscStackPop;
2936:   return(0);
2937: }

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

2944:     Logically Collective on TS

2946:     Input Parameters:
2947: +   ts - the TS context obtained from TSCreate()
2948: .   numcost - number of gradients to be computed, this is the number of cost functions
2949: .   rf - routine for evaluating the integrand function
2950: .   drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y
2951: .   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