Actual source code: ts.c

  2: #include <private/tsimpl.h>        /*I "petscts.h"  I*/

  4: /* Logging support */
  5: PetscClassId  TS_CLASSID;
  6: PetscLogEvent  TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;

 10: /*
 11:   TSSetTypeFromOptions - Sets the type of ts from user options.

 13:   Collective on TS

 15:   Input Parameter:
 16: . ts - The ts

 18:   Level: intermediate

 20: .keywords: TS, set, options, database, type
 21: .seealso: TSSetFromOptions(), TSSetType()
 22: */
 23: static PetscErrorCode TSSetTypeFromOptions(TS ts)
 24: {
 25:   PetscBool      opt;
 26:   const char     *defaultType;
 27:   char           typeName[256];

 31:   if (((PetscObject)ts)->type_name) {
 32:     defaultType = ((PetscObject)ts)->type_name;
 33:   } else {
 34:     defaultType = TSEULER;
 35:   }

 37:   if (!TSRegisterAllCalled) {TSRegisterAll(PETSC_NULL);}
 38:   PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);
 39:   if (opt) {
 40:     TSSetType(ts, typeName);
 41:   } else {
 42:     TSSetType(ts, defaultType);
 43:   }
 44:   return(0);
 45: }

 49: /*@
 50:    TSSetFromOptions - Sets various TS parameters from user options.

 52:    Collective on TS

 54:    Input Parameter:
 55: .  ts - the TS context obtained from TSCreate()

 57:    Options Database Keys:
 58: +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP
 59: .  -ts_max_steps maxsteps - maximum number of time-steps to take
 60: .  -ts_max_time time - maximum time to compute to
 61: .  -ts_dt dt - initial time step
 62: .  -ts_monitor - print information at each timestep
 63: -  -ts_monitor_draw - plot information at each timestep

 65:    Level: beginner

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

 69: .seealso: TSGetType()
 70: @*/
 71: PetscErrorCode  TSSetFromOptions(TS ts)
 72: {
 73:   PetscBool      opt,flg;
 75:   PetscViewer    monviewer;
 76:   char           monfilename[PETSC_MAX_PATH_LEN];
 77:   SNES           snes;

 81:   PetscObjectOptionsBegin((PetscObject)ts);
 82:     /* Handle TS type options */
 83:     TSSetTypeFromOptions(ts);

 85:     /* Handle generic TS options */
 86:     PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,PETSC_NULL);
 87:     PetscOptionsReal("-ts_max_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,PETSC_NULL);
 88:     PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,PETSC_NULL);
 89:     PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&ts->time_step,PETSC_NULL);
 90:     opt = ts->exact_final_time == PETSC_DECIDE ? PETSC_FALSE : (PetscBool)ts->exact_final_time;
 91:     PetscOptionsBool("-ts_exact_final_time","Interpolate output to stop exactly at the final time","TSSetExactFinalTime",opt,&opt,&flg);
 92:     if (flg) {TSSetExactFinalTime(ts,opt);}
 93:     PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","",ts->max_snes_failures,&ts->max_snes_failures,PETSC_NULL);
 94:     PetscOptionsInt("-ts_max_reject","Maximum number of step rejections","",ts->max_reject,&ts->max_reject,PETSC_NULL);
 95:     PetscOptionsBool("-ts_error_if_step_failed","Error if no step succeeds","",ts->errorifstepfailed,&ts->errorifstepfailed,PETSC_NULL);

 97:     /* Monitor options */
 98:     PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
 99:     if (flg) {
100:       PetscViewerASCIIOpen(((PetscObject)ts)->comm,monfilename,&monviewer);
101:       TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
102:     }
103:     PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
104:     if (flg) {PetscPythonMonitorSet((PetscObject)ts,monfilename);}

106:     opt  = PETSC_FALSE;
107:     PetscOptionsBool("-ts_monitor_draw","Monitor timestep size graphically","TSMonitorLG",opt,&opt,PETSC_NULL);
108:     if (opt) {
109:       TSMonitorSet(ts,TSMonitorLG,PETSC_NULL,PETSC_NULL);
110:     }
111:     opt  = PETSC_FALSE;
112:     PetscOptionsBool("-ts_monitor_solution","Monitor solution graphically","TSMonitorSolution",opt,&opt,PETSC_NULL);
113:     if (opt) {
114:       void *ctx;
115:       TSMonitorSolutionCreate(ts,PETSC_NULL,&ctx);
116:       TSMonitorSet(ts,TSMonitorSolution,ctx,TSMonitorSolutionDestroy);
117:     }

119:     TSGetSNES(ts,&snes);
120:     if (ts->problem_type == TS_LINEAR) {SNESSetType(snes,SNESKSPONLY);}

122:     /* Handle specific TS options */
123:     if (ts->ops->setfromoptions) {
124:       (*ts->ops->setfromoptions)(ts);
125:     }

127:     /* process any options handlers added with PetscObjectAddOptionsHandler() */
128:     PetscObjectProcessOptionsHandlers((PetscObject)ts);
129:   PetscOptionsEnd();
130:   return(0);
131: }

136: /*@
137:    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
138:       set with TSSetRHSJacobian().

140:    Collective on TS and Vec

142:    Input Parameters:
143: +  ts - the TS context
144: .  t - current timestep
145: -  x - input vector

147:    Output Parameters:
148: +  A - Jacobian matrix
149: .  B - optional preconditioning matrix
150: -  flag - flag indicating matrix structure

152:    Notes:
153:    Most users should not need to explicitly call this routine, as it
154:    is used internally within the nonlinear solvers.

156:    See KSPSetOperators() for important information about setting the
157:    flag parameter.

159:    Level: developer

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

163: .seealso:  TSSetRHSJacobian(), KSPSetOperators()
164: @*/
165: PetscErrorCode  TSComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg)
166: {
168:   PetscInt Xstate;

174:   PetscObjectStateQuery((PetscObject)X,&Xstate);
175:   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == X && ts->rhsjacobian.Xstate == Xstate))) {
176:     *flg = ts->rhsjacobian.mstructure;
177:     return(0);
178:   }

180:   if (!ts->userops->rhsjacobian && !ts->userops->ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");

182:   if (ts->userops->rhsjacobian) {
183:     PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);
184:     *flg = DIFFERENT_NONZERO_PATTERN;
185:     PetscStackPush("TS user Jacobian function");
186:     (*ts->userops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);
187:     PetscStackPop;
188:     PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);
189:     /* make sure user returned a correct Jacobian and preconditioner */
192:   } else {
193:     MatZeroEntries(*A);
194:     if (*A != *B) {MatZeroEntries(*B);}
195:     *flg = SAME_NONZERO_PATTERN;
196:   }
197:   ts->rhsjacobian.time = t;
198:   ts->rhsjacobian.X = X;
199:   PetscObjectStateQuery((PetscObject)X,&ts->rhsjacobian.Xstate);
200:   ts->rhsjacobian.mstructure = *flg;
201:   return(0);
202: }

206: /*@
207:    TSComputeRHSFunction - Evaluates the right-hand-side function. 

209:    Collective on TS and Vec

211:    Input Parameters:
212: +  ts - the TS context
213: .  t - current time
214: -  x - state vector

216:    Output Parameter:
217: .  y - right hand side

219:    Note:
220:    Most users should not need to explicitly call this routine, as it
221:    is used internally within the nonlinear solvers.

223:    Level: developer

225: .keywords: TS, compute

227: .seealso: TSSetRHSFunction(), TSComputeIFunction()
228: @*/
229: PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec x,Vec y)
230: {


238:   if (!ts->userops->rhsfunction && !ts->userops->ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");

240:   PetscLogEventBegin(TS_FunctionEval,ts,x,y,0);
241:   if (ts->userops->rhsfunction) {
242:     PetscStackPush("TS user right-hand-side function");
243:     (*ts->userops->rhsfunction)(ts,t,x,y,ts->funP);
244:     PetscStackPop;
245:   } else {
246:     VecZeroEntries(y);
247:   }

249:   PetscLogEventEnd(TS_FunctionEval,ts,x,y,0);
250:   return(0);
251: }

255: static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs)
256: {
257:   Vec            F;

261:   *Frhs = PETSC_NULL;
262:   TSGetIFunction(ts,&F,PETSC_NULL,PETSC_NULL);
263:   if (!ts->Frhs) {
264:     VecDuplicate(F,&ts->Frhs);
265:   }
266:   *Frhs = ts->Frhs;
267:   return(0);
268: }

272: static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs)
273: {
274:   Mat            A,B;

278:   TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);
279:   if (Arhs) {
280:     if (!ts->Arhs) {
281:       MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);
282:     }
283:     *Arhs = ts->Arhs;
284:   }
285:   if (Brhs) {
286:     if (!ts->Brhs) {
287:       MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);
288:     }
289:     *Brhs = ts->Brhs;
290:   }
291:   return(0);
292: }

296: /*@
297:    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,X,Xdot)=0

299:    Collective on TS and Vec

301:    Input Parameters:
302: +  ts - the TS context
303: .  t - current time
304: .  X - state vector
305: .  Xdot - time derivative of state vector
306: -  imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate

308:    Output Parameter:
309: .  Y - right hand side

311:    Note:
312:    Most users should not need to explicitly call this routine, as it
313:    is used internally within the nonlinear solvers.

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

318:    Level: developer

320: .keywords: TS, compute

322: .seealso: TSSetIFunction(), TSComputeRHSFunction()
323: @*/
324: PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec Y,PetscBool imex)
325: {


334:   if (!ts->userops->rhsfunction && !ts->userops->ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");

336:   PetscLogEventBegin(TS_FunctionEval,ts,X,Xdot,Y);
337:   if (ts->userops->ifunction) {
338:     PetscStackPush("TS user implicit function");
339:     (*ts->userops->ifunction)(ts,t,X,Xdot,Y,ts->funP);
340:     PetscStackPop;
341:   }
342:   if (imex) {
343:     if (!ts->userops->ifunction) {
344:       VecCopy(Xdot,Y);
345:     }
346:   } else if (ts->userops->rhsfunction) {
347:     if (ts->userops->ifunction) {
348:       Vec Frhs;
349:       TSGetRHSVec_Private(ts,&Frhs);
350:       TSComputeRHSFunction(ts,t,X,Frhs);
351:       VecAXPY(Y,-1,Frhs);
352:     } else {
353:       TSComputeRHSFunction(ts,t,X,Y);
354:       VecAYPX(Y,-1,Xdot);
355:     }
356:   }
357:   PetscLogEventEnd(TS_FunctionEval,ts,X,Xdot,Y);
358:   return(0);
359: }

363: /*@
364:    TSComputeIJacobian - Evaluates the Jacobian of the DAE

366:    Collective on TS and Vec

368:    Input
369:       Input Parameters:
370: +  ts - the TS context
371: .  t - current timestep
372: .  X - state vector
373: .  Xdot - time derivative of state vector
374: .  shift - shift to apply, see note below
375: -  imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate

377:    Output Parameters:
378: +  A - Jacobian matrix
379: .  B - optional preconditioning matrix
380: -  flag - flag indicating matrix structure

382:    Notes:
383:    If F(t,X,Xdot)=0 is the DAE, the required Jacobian is

385:    dF/dX + shift*dF/dXdot

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

390:    Level: developer

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

394: .seealso:  TSSetIJacobian()
395: @*/
396: PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex)
397: {
398:   PetscInt Xstate, Xdotstate;

410:   PetscObjectStateQuery((PetscObject)X,&Xstate);
411:   PetscObjectStateQuery((PetscObject)Xdot,&Xdotstate);
412:   if (ts->ijacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->ijacobian.X == X && ts->ijacobian.Xstate == Xstate && ts->ijacobian.Xdot == Xdot && ts->ijacobian.Xdotstate == Xdotstate && ts->ijacobian.imex == imex))) {
413:     *flg = ts->ijacobian.mstructure;
414:     MatScale(*A, shift / ts->ijacobian.shift);
415:     return(0);
416:   }

418:   if (!ts->userops->rhsjacobian && !ts->userops->ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");

420:   *flg = SAME_NONZERO_PATTERN;  /* In case we're solving a linear problem in which case it wouldn't get initialized below. */
421:   PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);
422:   if (ts->userops->ijacobian) {
423:     *flg = DIFFERENT_NONZERO_PATTERN;
424:     PetscStackPush("TS user implicit Jacobian");
425:     (*ts->userops->ijacobian)(ts,t,X,Xdot,shift,A,B,flg,ts->jacP);
426:     PetscStackPop;
427:     /* make sure user returned a correct Jacobian and preconditioner */
430:   }
431:   if (imex) {
432:     if (!ts->userops->ijacobian) {  /* system was written as Xdot = F(t,X) */
433:       MatZeroEntries(*A);
434:       MatShift(*A,shift);
435:       if (*A != *B) {
436:         MatZeroEntries(*B);
437:         MatShift(*B,shift);
438:       }
439:       *flg = SAME_PRECONDITIONER;
440:     }
441:   } else {
442:     if (!ts->userops->ijacobian) {
443:       TSComputeRHSJacobian(ts,t,X,A,B,flg);
444:       MatScale(*A,-1);
445:       MatShift(*A,shift);
446:       if (*A != *B) {
447:         MatScale(*B,-1);
448:         MatShift(*B,shift);
449:       }
450:     } else if (ts->userops->rhsjacobian) {
451:       Mat Arhs,Brhs;
452:       MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN;
453:       TSGetRHSMats_Private(ts,&Arhs,&Brhs);
454:       TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);
455:       axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN;
456:       MatAXPY(*A,-1,Arhs,axpy);
457:       if (*A != *B) {
458:         MatAXPY(*B,-1,Brhs,axpy);
459:       }
460:       *flg = PetscMin(*flg,flg2);
461:     }
462:   }

464:   ts->ijacobian.time = t;
465:   ts->ijacobian.X = X;
466:   ts->ijacobian.Xdot = Xdot;
467:   PetscObjectStateQuery((PetscObject)X,&ts->ijacobian.Xstate);
468:   PetscObjectStateQuery((PetscObject)Xdot,&ts->ijacobian.Xdotstate);
469:   ts->ijacobian.shift = shift;
470:   ts->ijacobian.imex = imex;
471:   ts->ijacobian.mstructure = *flg;
472:   PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);
473:   return(0);
474: }

478: /*@C
479:     TSSetRHSFunction - Sets the routine for evaluating the function,
480:     F(t,u), where U_t = F(t,u).

482:     Logically Collective on TS

484:     Input Parameters:
485: +   ts - the TS context obtained from TSCreate()
486: .   r - vector to put the computed right hand side (or PETSC_NULL to have it created)
487: .   f - routine for evaluating the right-hand-side function
488: -   ctx - [optional] user-defined context for private data for the 
489:           function evaluation routine (may be PETSC_NULL)

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

494: +   t - current timestep
495: .   u - input vector
496: .   F - function vector
497: -   ctx - [optional] user-defined function context 

499:     Important: 
500:     The user MUST call either this routine or TSSetMatrices().

502:     Level: beginner

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

506: .seealso: TSSetMatrices()
507: @*/
508: PetscErrorCode  TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
509: {
511:   SNES           snes;

516:   if (f)   ts->userops->rhsfunction = f;
517:   if (ctx) ts->funP                 = ctx;
518:   TSGetSNES(ts,&snes);
519:   SNESSetFunction(snes,r,SNESTSFormFunction,ts);
520:   return(0);
521: }

525: /*@C
526:    TSSetRHSJacobian - Sets the function to compute the Jacobian of F,
527:    where U_t = F(U,t), as well as the location to store the matrix.
528:    Use TSSetMatrices() for linear problems.

530:    Logically Collective on TS

532:    Input Parameters:
533: +  ts  - the TS context obtained from TSCreate()
534: .  A   - Jacobian matrix
535: .  B   - preconditioner matrix (usually same as A)
536: .  f   - the Jacobian evaluation routine
537: -  ctx - [optional] user-defined context for private data for the 
538:          Jacobian evaluation routine (may be PETSC_NULL)

540:    Calling sequence of func:
541: $     func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx);

543: +  t - current timestep
544: .  u - input vector
545: .  A - matrix A, where U_t = A(t)u
546: .  B - preconditioner matrix, usually the same as A
547: .  flag - flag indicating information about the preconditioner matrix
548:           structure (same as flag in KSPSetOperators())
549: -  ctx - [optional] user-defined context for matrix evaluation routine

551:    Notes: 
552:    See KSPSetOperators() for important information about setting the flag
553:    output parameter in the routine func().  Be sure to read this information!

555:    The routine func() takes Mat * as the matrix arguments rather than Mat.  
556:    This allows the matrix evaluation routine to replace A and/or B with a 
557:    completely new matrix structure (not just different matrix elements)
558:    when appropriate, for instance, if the nonzero structure is changing
559:    throughout the global iterations.

561:    Level: beginner
562:    
563: .keywords: TS, timestep, set, right-hand-side, Jacobian

565: .seealso: TSDefaultComputeJacobianColor(),
566:           SNESDefaultComputeJacobianColor(), TSSetRHSFunction(), TSSetMatrices()

568: @*/
569: PetscErrorCode  TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx)
570: {
572:   SNES           snes;


581:   if (f)   ts->userops->rhsjacobian = f;
582:   if (ctx) ts->jacP                 = ctx;
583:   TSGetSNES(ts,&snes);
584:   if (!ts->userops->ijacobian) {
585:     SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);
586:   }
587:   if (A) {
588:     PetscObjectReference((PetscObject)A);
589:     MatDestroy(&ts->Arhs);
590:     ts->Arhs = A;
591:   }
592:   if (B) {
593:     PetscObjectReference((PetscObject)B);
594:     MatDestroy(&ts->Brhs);
595:     ts->Brhs = B;
596:   }
597:   return(0);
598: }


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

606:    Logically Collective on TS

608:    Input Parameters:
609: +  ts  - the TS context obtained from TSCreate()
610: .  r   - vector to hold the residual (or PETSC_NULL to have it created internally)
611: .  f   - the function evaluation routine
612: -  ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL)

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

617: +  t   - time at step/stage being solved
618: .  u   - state vector
619: .  u_t - time derivative of state vector
620: .  F   - function vector
621: -  ctx - [optional] user-defined context for matrix evaluation routine

623:    Important:
624:    The user MUST call either this routine, TSSetRHSFunction(), or TSSetMatrices().  This routine must be used when not solving an ODE.

626:    Level: beginner

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

630: .seealso: TSSetMatrices(), TSSetRHSFunction(), TSSetIJacobian()
631: @*/
632: PetscErrorCode  TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx)
633: {
635:   SNES           snes;

640:   if (f)   ts->userops->ifunction = f;
641:   if (ctx) ts->funP           = ctx;
642:   TSGetSNES(ts,&snes);
643:   SNESSetFunction(snes,res,SNESTSFormFunction,ts);
644:   return(0);
645: }

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

652:    Not Collective

654:    Input Parameter:
655: .  ts - the TS context

657:    Output Parameter:
658: +  r - vector to hold residual (or PETSC_NULL)
659: .  func - the function to compute residual (or PETSC_NULL)
660: -  ctx - the function context (or PETSC_NULL)

662:    Level: advanced

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

666: .seealso: TSSetIFunction(), SNESGetFunction()
667: @*/
668: PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx)
669: {
671:   SNES snes;

675:   TSGetSNES(ts,&snes);
676:   SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);
677:   if (func) *func = ts->userops->ifunction;
678:   if (ctx)  *ctx  = ts->funP;
679:   return(0);
680: }

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

687:    Not Collective

689:    Input Parameter:
690: .  ts - the TS context

692:    Output Parameter:
693: +  r - vector to hold computed right hand side (or PETSC_NULL)
694: .  func - the function to compute right hand side (or PETSC_NULL)
695: -  ctx - the function context (or PETSC_NULL)

697:    Level: advanced

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

701: .seealso: TSSetRhsfunction(), SNESGetFunction()
702: @*/
703: PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx)
704: {
706:   SNES snes;

710:   TSGetSNES(ts,&snes);
711:   SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);
712:   if (func) *func = ts->userops->rhsfunction;
713:   if (ctx)  *ctx  = ts->funP;
714:   return(0);
715: }

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

723:    Logically Collective on TS

725:    Input Parameters:
726: +  ts  - the TS context obtained from TSCreate()
727: .  A   - Jacobian matrix
728: .  B   - preconditioning matrix for A (may be same as A)
729: .  f   - the Jacobian evaluation routine
730: -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL)

732:    Calling sequence of f:
733: $  f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx);

735: +  t    - time at step/stage being solved
736: .  U    - state vector
737: .  U_t  - time derivative of state vector
738: .  a    - shift
739: .  A    - Jacobian of G(U) = F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
740: .  B    - preconditioning matrix for A, may be same as A
741: .  flag - flag indicating information about the preconditioner matrix
742:           structure (same as flag in KSPSetOperators())
743: -  ctx  - [optional] user-defined context for matrix evaluation routine

745:    Notes:
746:    The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve.

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

755:    Level: beginner

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

759: .seealso: TSSetIFunction(), TSSetRHSJacobian()

761: @*/
762: PetscErrorCode  TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx)
763: {
765:   SNES           snes;

773:   if (f)   ts->userops->ijacobian = f;
774:   if (ctx) ts->jacP           = ctx;
775:   TSGetSNES(ts,&snes);
776:   SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);
777:   return(0);
778: }

782: /*@C
783:     TSView - Prints the TS data structure.

785:     Collective on TS

787:     Input Parameters:
788: +   ts - the TS context obtained from TSCreate()
789: -   viewer - visualization context

791:     Options Database Key:
792: .   -ts_view - calls TSView() at end of TSStep()

794:     Notes:
795:     The available visualization contexts include
796: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
797: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
798:          output where only the first processor opens
799:          the file.  All other processors send their
800:          data to the first processor to print.

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

805:     Level: beginner

807: .keywords: TS, timestep, view

809: .seealso: PetscViewerASCIIOpen()
810: @*/
811: PetscErrorCode  TSView(TS ts,PetscViewer viewer)
812: {
814:   const TSType   type;
815:   PetscBool      iascii,isstring,isundials;

819:   if (!viewer) {
820:     PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);
821:   }

825:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
826:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
827:   if (iascii) {
828:     PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");
829:     PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);
830:     PetscViewerASCIIPrintf(viewer,"  maximum time=%G\n",ts->max_time);
831:     if (ts->problem_type == TS_NONLINEAR) {
832:       PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->nonlinear_its);
833:       PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solve failures=%D\n",ts->num_snes_failures);
834:     }
835:     PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->linear_its);
836:     PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);
837:     if (ts->ops->view) {
838:       PetscViewerASCIIPushTab(viewer);
839:       (*ts->ops->view)(ts,viewer);
840:       PetscViewerASCIIPopTab(viewer);
841:     }
842:   } else if (isstring) {
843:     TSGetType(ts,&type);
844:     PetscViewerStringSPrintf(viewer," %-7.7s",type);
845:   }
846:   PetscViewerASCIIPushTab(viewer);
847:   PetscTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);
848:   PetscViewerASCIIPopTab(viewer);
849:   return(0);
850: }


855: /*@
856:    TSSetApplicationContext - Sets an optional user-defined context for
857:    the timesteppers.

859:    Logically Collective on TS

861:    Input Parameters:
862: +  ts - the TS context obtained from TSCreate()
863: -  usrP - optional user context

865:    Level: intermediate

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

869: .seealso: TSGetApplicationContext()
870: @*/
871: PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
872: {
875:   ts->user = usrP;
876:   return(0);
877: }

881: /*@
882:     TSGetApplicationContext - Gets the user-defined context for the 
883:     timestepper.

885:     Not Collective

887:     Input Parameter:
888: .   ts - the TS context obtained from TSCreate()

890:     Output Parameter:
891: .   usrP - user context

893:     Level: intermediate

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

897: .seealso: TSSetApplicationContext()
898: @*/
899: PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
900: {
903:   *(void**)usrP = ts->user;
904:   return(0);
905: }

909: /*@
910:    TSGetTimeStepNumber - Gets the current number of timesteps.

912:    Not Collective

914:    Input Parameter:
915: .  ts - the TS context obtained from TSCreate()

917:    Output Parameter:
918: .  iter - number steps so far

920:    Level: intermediate

922: .keywords: TS, timestep, get, iteration, number
923: @*/
924: PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt* iter)
925: {
929:   *iter = ts->steps;
930:   return(0);
931: }

935: /*@
936:    TSSetInitialTimeStep - Sets the initial timestep to be used,
937:    as well as the initial time.

939:    Logically Collective on TS

941:    Input Parameters:
942: +  ts - the TS context obtained from TSCreate()
943: .  initial_time - the initial time
944: -  time_step - the size of the timestep

946:    Level: intermediate

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

950: .keywords: TS, set, initial, timestep
951: @*/
952: PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
953: {

958:   TSSetTimeStep(ts,time_step);
959:   TSSetTime(ts,initial_time);
960:   return(0);
961: }

965: /*@
966:    TSSetTimeStep - Allows one to reset the timestep at any time,
967:    useful for simple pseudo-timestepping codes.

969:    Logically Collective on TS

971:    Input Parameters:
972: +  ts - the TS context obtained from TSCreate()
973: -  time_step - the size of the timestep

975:    Level: intermediate

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

979: .keywords: TS, set, timestep
980: @*/
981: PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
982: {
986:   ts->time_step = time_step;
987:   return(0);
988: }

992: /*@
993:    TSSetExactFinalTime - Determines whether to interpolate solution to the
994:       exact final time requested by the user or just returns it at the final time
995:       it computed.

997:   Logically Collective on TS

999:    Input Parameter:
1000: +   ts - the time-step context
1001: -   ft - PETSC_TRUE if interpolates, else PETSC_FALSE

1003:    Level: beginner

1005: .seealso: TSSetDuration()
1006: @*/
1007: PetscErrorCode  TSSetExactFinalTime(TS ts,PetscBool flg)
1008: {

1013:   ts->exact_final_time = flg;
1014:   return(0);
1015: }

1019: /*@
1020:    TSGetTimeStep - Gets the current timestep size.

1022:    Not Collective

1024:    Input Parameter:
1025: .  ts - the TS context obtained from TSCreate()

1027:    Output Parameter:
1028: .  dt - the current timestep size

1030:    Level: intermediate

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

1034: .keywords: TS, get, timestep
1035: @*/
1036: PetscErrorCode  TSGetTimeStep(TS ts,PetscReal* dt)
1037: {
1041:   *dt = ts->time_step;
1042:   return(0);
1043: }

1047: /*@
1048:    TSGetSolution - Returns the solution at the present timestep. It
1049:    is valid to call this routine inside the function that you are evaluating
1050:    in order to move to the new timestep. This vector not changed until
1051:    the solution at the next timestep has been calculated.

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

1055:    Input Parameter:
1056: .  ts - the TS context obtained from TSCreate()

1058:    Output Parameter:
1059: .  v - the vector containing the solution

1061:    Level: intermediate

1063: .seealso: TSGetTimeStep()

1065: .keywords: TS, timestep, get, solution
1066: @*/
1067: PetscErrorCode  TSGetSolution(TS ts,Vec *v)
1068: {
1072:   *v = ts->vec_sol;
1073:   return(0);
1074: }

1076: /* ----- Routines to initialize and destroy a timestepper ---- */
1079: /*@
1080:   TSSetProblemType - Sets the type of problem to be solved.

1082:   Not collective

1084:   Input Parameters:
1085: + ts   - The TS
1086: - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1087: .vb
1088:          U_t = A U    
1089:          U_t = A(t) U 
1090:          U_t = F(t,U) 
1091: .ve

1093:    Level: beginner

1095: .keywords: TS, problem type
1096: .seealso: TSSetUp(), TSProblemType, TS
1097: @*/
1098: PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
1099: {

1104:   ts->problem_type = type;
1105:   if (type == TS_LINEAR) {
1106:     SNES snes;
1107:     TSGetSNES(ts,&snes);
1108:     SNESSetType(snes,SNESKSPONLY);
1109:   }
1110:   return(0);
1111: }

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

1118:   Not collective

1120:   Input Parameter:
1121: . ts   - The TS

1123:   Output Parameter:
1124: . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1125: .vb
1126:          M U_t = A U
1127:          M(t) U_t = A(t) U
1128:          U_t = F(t,U)
1129: .ve

1131:    Level: beginner

1133: .keywords: TS, problem type
1134: .seealso: TSSetUp(), TSProblemType, TS
1135: @*/
1136: PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
1137: {
1141:   *type = ts->problem_type;
1142:   return(0);
1143: }

1147: /*@
1148:    TSSetUp - Sets up the internal data structures for the later use
1149:    of a timestepper.  

1151:    Collective on TS

1153:    Input Parameter:
1154: .  ts - the TS context obtained from TSCreate()

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

1163:    Level: advanced

1165: .keywords: TS, timestep, setup

1167: .seealso: TSCreate(), TSStep(), TSDestroy()
1168: @*/
1169: PetscErrorCode  TSSetUp(TS ts)
1170: {

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

1177:   if (!((PetscObject)ts)->type_name) {
1178:     TSSetType(ts,TSEULER);
1179:   }
1180:   if (ts->exact_final_time == PETSC_DECIDE) ts->exact_final_time = PETSC_FALSE;

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

1184:   if (ts->ops->setup) {
1185:     (*ts->ops->setup)(ts);
1186:   }

1188:   ts->setupcalled = PETSC_TRUE;
1189:   return(0);
1190: }

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

1197:    Collective on TS

1199:    Input Parameter:
1200: .  ts - the TS context obtained from TSCreate()

1202:    Level: beginner

1204: .keywords: TS, timestep, reset

1206: .seealso: TSCreate(), TSSetup(), TSDestroy()
1207: @*/
1208: PetscErrorCode  TSReset(TS ts)
1209: {

1214:   if (ts->ops->reset) {
1215:     (*ts->ops->reset)(ts);
1216:   }
1217:   if (ts->snes) {SNESReset(ts->snes);}
1218:   MatDestroy(&ts->Arhs);
1219:   MatDestroy(&ts->Brhs);
1220:   VecDestroy(&ts->Frhs);
1221:   VecDestroy(&ts->vec_sol);
1222:   VecDestroyVecs(ts->nwork,&ts->work);
1223:   ts->setupcalled = PETSC_FALSE;
1224:   return(0);
1225: }

1229: /*@
1230:    TSDestroy - Destroys the timestepper context that was created
1231:    with TSCreate().

1233:    Collective on TS

1235:    Input Parameter:
1236: .  ts - the TS context obtained from TSCreate()

1238:    Level: beginner

1240: .keywords: TS, timestepper, destroy

1242: .seealso: TSCreate(), TSSetUp(), TSSolve()
1243: @*/
1244: PetscErrorCode  TSDestroy(TS *ts)
1245: {

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

1253:   TSReset((*ts));

1255:   /* if memory was published with AMS then destroy it */
1256:   PetscObjectDepublish((*ts));
1257:   if ((*ts)->ops->destroy) {(*(*ts)->ops->destroy)((*ts));}

1259:   SNESDestroy(&(*ts)->snes);
1260:   DMDestroy(&(*ts)->dm);
1261:   TSMonitorCancel((*ts));

1263:   PetscFree((*ts)->userops);

1265:   PetscHeaderDestroy(ts);
1266:   return(0);
1267: }

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

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

1277:    Input Parameter:
1278: .  ts - the TS context obtained from TSCreate()

1280:    Output Parameter:
1281: .  snes - the nonlinear solver context

1283:    Notes:
1284:    The user can then directly manipulate the SNES context to set various
1285:    options, etc.  Likewise, the user can then extract and manipulate the
1286:    KSP, KSP, and PC contexts as well.

1288:    TSGetSNES() does not work for integrators that do not use SNES; in
1289:    this case TSGetSNES() returns PETSC_NULL in snes.

1291:    Level: beginner

1293: .keywords: timestep, get, SNES
1294: @*/
1295: PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
1296: {

1302:   if (!ts->snes) {
1303:     SNESCreate(((PetscObject)ts)->comm,&ts->snes);
1304:     PetscLogObjectParent(ts,ts->snes);
1305:     PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);
1306:     if (ts->problem_type == TS_LINEAR) {
1307:       SNESSetType(ts->snes,SNESKSPONLY);
1308:     }
1309:   }
1310:   *snes = ts->snes;
1311:   return(0);
1312: }

1316: /*@
1317:    TSGetKSP - Returns the KSP (linear solver) associated with
1318:    a TS (timestepper) context.

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

1322:    Input Parameter:
1323: .  ts - the TS context obtained from TSCreate()

1325:    Output Parameter:
1326: .  ksp - the nonlinear solver context

1328:    Notes:
1329:    The user can then directly manipulate the KSP context to set various
1330:    options, etc.  Likewise, the user can then extract and manipulate the
1331:    KSP and PC contexts as well.

1333:    TSGetKSP() does not work for integrators that do not use KSP;
1334:    in this case TSGetKSP() returns PETSC_NULL in ksp.

1336:    Level: beginner

1338: .keywords: timestep, get, KSP
1339: @*/
1340: PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
1341: {
1343:   SNES           snes;

1348:   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1349:   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1350:   TSGetSNES(ts,&snes);
1351:   SNESGetKSP(snes,ksp);
1352:   return(0);
1353: }

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

1359: /*@
1360:    TSGetDuration - Gets the maximum number of timesteps to use and
1361:    maximum time for iteration.

1363:    Not Collective

1365:    Input Parameters:
1366: +  ts       - the TS context obtained from TSCreate()
1367: .  maxsteps - maximum number of iterations to use, or PETSC_NULL
1368: -  maxtime  - final time to iterate to, or PETSC_NULL

1370:    Level: intermediate

1372: .keywords: TS, timestep, get, maximum, iterations, time
1373: @*/
1374: PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1375: {
1378:   if (maxsteps) {
1380:     *maxsteps = ts->max_steps;
1381:   }
1382:   if (maxtime) {
1384:     *maxtime  = ts->max_time;
1385:   }
1386:   return(0);
1387: }

1391: /*@
1392:    TSSetDuration - Sets the maximum number of timesteps to use and
1393:    maximum time for iteration.

1395:    Logically Collective on TS

1397:    Input Parameters:
1398: +  ts - the TS context obtained from TSCreate()
1399: .  maxsteps - maximum number of iterations to use
1400: -  maxtime - final time to iterate to

1402:    Options Database Keys:
1403: .  -ts_max_steps <maxsteps> - Sets maxsteps
1404: .  -ts_max_time <maxtime> - Sets maxtime

1406:    Notes:
1407:    The default maximum number of iterations is 5000. Default time is 5.0

1409:    Level: intermediate

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

1413: .seealso: TSSetExactFinalTime()
1414: @*/
1415: PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1416: {
1421:   if (maxsteps >= 0) ts->max_steps = maxsteps;
1422:   if (maxtime != PETSC_DEFAULT) ts->max_time  = maxtime;
1423:   return(0);
1424: }

1428: /*@
1429:    TSSetSolution - Sets the initial solution vector
1430:    for use by the TS routines.

1432:    Logically Collective on TS and Vec

1434:    Input Parameters:
1435: +  ts - the TS context obtained from TSCreate()
1436: -  x - the solution vector

1438:    Level: beginner

1440: .keywords: TS, timestep, set, solution, initial conditions
1441: @*/
1442: PetscErrorCode  TSSetSolution(TS ts,Vec x)
1443: {

1449:   PetscObjectReference((PetscObject)x);
1450:   VecDestroy(&ts->vec_sol);
1451:   ts->vec_sol = x;
1452:   return(0);
1453: }

1457: /*@C
1458:   TSSetPreStep - Sets the general-purpose function
1459:   called once at the beginning of each time step.

1461:   Logically Collective on TS

1463:   Input Parameters:
1464: + ts   - The TS context obtained from TSCreate()
1465: - func - The function

1467:   Calling sequence of func:
1468: . func (TS ts);

1470:   Level: intermediate

1472: .keywords: TS, timestep
1473: @*/
1474: PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
1475: {
1478:   ts->ops->prestep = func;
1479:   return(0);
1480: }

1484: /*@
1485:   TSPreStep - Runs the user-defined pre-step function.

1487:   Collective on TS

1489:   Input Parameters:
1490: . ts   - The TS context obtained from TSCreate()

1492:   Notes:
1493:   TSPreStep() is typically used within time stepping implementations,
1494:   so most users would not generally call this routine themselves.

1496:   Level: developer

1498: .keywords: TS, timestep
1499: @*/
1500: PetscErrorCode  TSPreStep(TS ts)
1501: {

1506:   if (ts->ops->prestep) {
1507:     PetscStackPush("TS PreStep function");
1508:     (*ts->ops->prestep)(ts);
1509:     PetscStackPop;
1510:   }
1511:   return(0);
1512: }

1516: /*@C
1517:   TSSetPostStep - Sets the general-purpose function
1518:   called once at the end of each time step.

1520:   Logically Collective on TS

1522:   Input Parameters:
1523: + ts   - The TS context obtained from TSCreate()
1524: - func - The function

1526:   Calling sequence of func:
1527: . func (TS ts);

1529:   Level: intermediate

1531: .keywords: TS, timestep
1532: @*/
1533: PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
1534: {
1537:   ts->ops->poststep = func;
1538:   return(0);
1539: }

1543: /*@
1544:   TSPostStep - Runs the user-defined post-step function.

1546:   Collective on TS

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

1551:   Notes:
1552:   TSPostStep() is typically used within time stepping implementations,
1553:   so most users would not generally call this routine themselves.

1555:   Level: developer

1557: .keywords: TS, timestep
1558: @*/
1559: PetscErrorCode  TSPostStep(TS ts)
1560: {

1565:   if (ts->ops->poststep) {
1566:     PetscStackPush("TS PostStep function");
1567:     (*ts->ops->poststep)(ts);
1568:     PetscStackPop;
1569:   }
1570:   return(0);
1571: }

1573: /* ------------ Routines to set performance monitoring options ----------- */

1577: /*@C
1578:    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
1579:    timestep to display the iteration's  progress.

1581:    Logically Collective on TS

1583:    Input Parameters:
1584: +  ts - the TS context obtained from TSCreate()
1585: .  monitor - monitoring routine
1586: .  mctx - [optional] user-defined context for private data for the 
1587:              monitor routine (use PETSC_NULL if no context is desired)
1588: -  monitordestroy - [optional] routine that frees monitor context
1589:           (may be PETSC_NULL)

1591:    Calling sequence of monitor:
1592: $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx)

1594: +    ts - the TS context
1595: .    steps - iteration number
1596: .    time - current time
1597: .    x - current iterate
1598: -    mctx - [optional] monitoring context

1600:    Notes:
1601:    This routine adds an additional monitor to the list of monitors that 
1602:    already has been loaded.

1604:    Fortran notes: Only a single monitor function can be set for each TS object

1606:    Level: intermediate

1608: .keywords: TS, timestep, set, monitor

1610: .seealso: TSMonitorDefault(), TSMonitorCancel()
1611: @*/
1612: PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
1613: {
1616:   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1617:   ts->monitor[ts->numbermonitors]           = monitor;
1618:   ts->mdestroy[ts->numbermonitors]          = mdestroy;
1619:   ts->monitorcontext[ts->numbermonitors++]  = (void*)mctx;
1620:   return(0);
1621: }

1625: /*@C
1626:    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.

1628:    Logically Collective on TS

1630:    Input Parameters:
1631: .  ts - the TS context obtained from TSCreate()

1633:    Notes:
1634:    There is no way to remove a single, specific monitor.

1636:    Level: intermediate

1638: .keywords: TS, timestep, set, monitor

1640: .seealso: TSMonitorDefault(), TSMonitorSet()
1641: @*/
1642: PetscErrorCode  TSMonitorCancel(TS ts)
1643: {
1645:   PetscInt       i;

1649:   for (i=0; i<ts->numbermonitors; i++) {
1650:     if (ts->mdestroy[i]) {
1651:       (*ts->mdestroy[i])(&ts->monitorcontext[i]);
1652:     }
1653:   }
1654:   ts->numbermonitors = 0;
1655:   return(0);
1656: }

1660: /*@
1661:    TSMonitorDefault - Sets the Default monitor

1663:    Level: intermediate

1665: .keywords: TS, set, monitor

1667: .seealso: TSMonitorDefault(), TSMonitorSet()
1668: @*/
1669: PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy)
1670: {
1672:   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ts)->comm);

1675:   PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);
1676:   PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);
1677:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);
1678:   return(0);
1679: }

1683: /*@
1684:    TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available.

1686:    Logically Collective on TS

1688:    Input Argument:
1689: .  ts - time stepping context

1691:    Output Argument:
1692: .  flg - PETSC_TRUE or PETSC_FALSE

1694:    Level: intermediate

1696: .keywords: TS, set

1698: .seealso: TSInterpolate(), TSSetPostStep()
1699: @*/
1700: PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg)
1701: {

1705:   ts->retain_stages = flg;
1706:   return(0);
1707: }

1711: /*@
1712:    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval

1714:    Collective on TS

1716:    Input Argument:
1717: +  ts - time stepping context
1718: -  t - time to interpolate to

1720:    Output Argument:
1721: .  X - state at given time

1723:    Notes:
1724:    The user should call TSSetRetainStages() before taking a step in which interpolation will be requested.

1726:    Level: intermediate

1728:    Developer Notes:
1729:    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.

1731: .keywords: TS, set

1733: .seealso: TSSetRetainStages(), TSSetPostStep()
1734: @*/
1735: PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec X)
1736: {

1741:   if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(((PetscObject)ts)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Requested time %G not in last time steps [%G,%G]",t,ts->ptime-ts->time_step_prev,ts->ptime);
1742:   if (!ts->ops->interpolate) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
1743:   (*ts->ops->interpolate)(ts,t,X);
1744:   return(0);
1745: }

1749: /*@
1750:    TSStep - Steps one time step

1752:    Collective on TS

1754:    Input Parameter:
1755: .  ts - the TS context obtained from TSCreate()

1757:    Level: intermediate

1759: .keywords: TS, timestep, solve

1761: .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve()
1762: @*/
1763: PetscErrorCode  TSStep(TS ts)
1764: {
1765:   PetscReal      ptime_prev;

1770:   TSSetUp(ts);

1772:   ts->reason = TS_CONVERGED_ITERATING;

1774:   ptime_prev = ts->ptime;
1775:   PetscLogEventBegin(TS_Step,ts,0,0,0);
1776:   (*ts->ops->step)(ts);
1777:   PetscLogEventEnd(TS_Step,ts,0,0,0);
1778:   ts->time_step_prev = ts->ptime - ptime_prev;

1780:   if (ts->reason < 0) {
1781:     if (ts->errorifstepfailed) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed");
1782:   } else if (!ts->reason) {
1783:     if (ts->steps >= ts->max_steps)
1784:       ts->reason = TS_CONVERGED_ITS;
1785:     else if (ts->ptime >= ts->max_time)
1786:       ts->reason = TS_CONVERGED_TIME;
1787:   }

1789:   return(0);
1790: }

1794: /*@
1795:    TSSolve - Steps the requested number of timesteps.

1797:    Collective on TS

1799:    Input Parameter:
1800: +  ts - the TS context obtained from TSCreate()
1801: -  x - the solution vector

1803:    Output Parameter:
1804: .  ftime - time of the state vector x upon completion

1806:    Level: beginner

1808:    Notes:
1809:    The final time returned by this function may be different from the time of the internally
1810:    held state accessible by TSGetSolution() and TSGetTime() because the method may have
1811:    stepped over the final time.

1813: .keywords: TS, timestep, solve

1815: .seealso: TSCreate(), TSSetSolution(), TSStep()
1816: @*/
1817: PetscErrorCode TSSolve(TS ts,Vec x,PetscReal *ftime)
1818: {
1819:   PetscBool      flg;
1820:   char           filename[PETSC_MAX_PATH_LEN];
1821:   PetscViewer    viewer;

1827:   if (ts->exact_final_time) {   /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */
1828:     if (!ts->vec_sol || x == ts->vec_sol) {
1829:       Vec y;
1830:       VecDuplicate(x,&y);
1831:       TSSetSolution(ts,y);
1832:       VecDestroy(&y); /* grant ownership */
1833:     }
1834:     VecCopy(x,ts->vec_sol);
1835:   } else {
1836:     TSSetSolution(ts,x);
1837:   }
1838:   TSSetUp(ts);
1839:   /* reset time step and iteration counters */
1840:   ts->steps = 0;
1841:   ts->linear_its = 0;
1842:   ts->nonlinear_its = 0;
1843:   ts->num_snes_failures = 0;
1844:   ts->reject = 0;
1845:   ts->reason = TS_CONVERGED_ITERATING;

1847:   if (ts->ops->solve) {         /* This private interface is transitional and should be removed when all implementations are updated. */
1848:     (*ts->ops->solve)(ts);
1849:     VecCopy(ts->vec_sol,x);
1850:     if (ftime) *ftime = ts->ptime;
1851:   } else {
1852:     /* steps the requested number of timesteps. */
1853:     TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);
1854:     if (ts->steps >= ts->max_steps)
1855:       ts->reason = TS_CONVERGED_ITS;
1856:     else if (ts->ptime >= ts->max_time)
1857:       ts->reason = TS_CONVERGED_TIME;
1858:     while (!ts->reason) {
1859:       TSPreStep(ts);
1860:       TSStep(ts);
1861:       TSPostStep(ts);
1862:       TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);
1863:     }
1864:     if (ts->exact_final_time && ts->ptime > ts->max_time) {
1865:       TSInterpolate(ts,ts->max_time,x);
1866:       if (ftime) *ftime = ts->max_time;
1867:     } else {
1868:       VecCopy(ts->vec_sol,x);
1869:       if (ftime) *ftime = ts->ptime;
1870:     }
1871:   }
1872:   PetscOptionsGetString(((PetscObject)ts)->prefix,"-ts_view",filename,PETSC_MAX_PATH_LEN,&flg);
1873:   if (flg && !PetscPreLoadingOn) {
1874:     PetscViewerASCIIOpen(((PetscObject)ts)->comm,filename,&viewer);
1875:     TSView(ts,viewer);
1876:     PetscViewerDestroy(&viewer);
1877:   }
1878:   return(0);
1879: }

1883: /*@
1884:    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()

1886:    Collective on TS

1888:    Input Parameters:
1889: +  ts - time stepping context obtained from TSCreate()
1890: .  step - step number that has just completed
1891: .  ptime - model time of the state
1892: -  x - state at the current model time

1894:    Notes:
1895:    TSMonitor() is typically used within the time stepping implementations.
1896:    Users might call this function when using the TSStep() interface instead of TSSolve().

1898:    Level: advanced

1900: .keywords: TS, timestep
1901: @*/
1902: PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x)
1903: {
1905:   PetscInt       i,n = ts->numbermonitors;

1908:   for (i=0; i<n; i++) {
1909:     (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);
1910:   }
1911:   return(0);
1912: }

1914: /* ------------------------------------------------------------------------*/

1918: /*@C
1919:    TSMonitorLGCreate - Creates a line graph context for use with 
1920:    TS to monitor convergence of preconditioned residual norms.

1922:    Collective on TS

1924:    Input Parameters:
1925: +  host - the X display to open, or null for the local machine
1926: .  label - the title to put in the title bar
1927: .  x, y - the screen coordinates of the upper left coordinate of the window
1928: -  m, n - the screen width and height in pixels

1930:    Output Parameter:
1931: .  draw - the drawing context

1933:    Options Database Key:
1934: .  -ts_monitor_draw - automatically sets line graph monitor

1936:    Notes: 
1937:    Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy().

1939:    Level: intermediate

1941: .keywords: TS, monitor, line graph, residual, seealso

1943: .seealso: TSMonitorLGDestroy(), TSMonitorSet()

1945: @*/
1946: PetscErrorCode  TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1947: {
1948:   PetscDraw      win;

1952:   PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);
1953:   PetscDrawSetType(win,PETSC_DRAW_X);
1954:   PetscDrawLGCreate(win,1,draw);
1955:   PetscDrawLGIndicateDataPoints(*draw);

1957:   PetscLogObjectParent(*draw,win);
1958:   return(0);
1959: }

1963: PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1964: {
1965:   PetscDrawLG    lg = (PetscDrawLG) monctx;
1966:   PetscReal      x,y = ptime;

1970:   if (!monctx) {
1971:     MPI_Comm    comm;
1972:     PetscViewer viewer;

1974:     PetscObjectGetComm((PetscObject)ts,&comm);
1975:     viewer = PETSC_VIEWER_DRAW_(comm);
1976:     PetscViewerDrawGetDrawLG(viewer,0,&lg);
1977:   }

1979:   if (!n) {PetscDrawLGReset(lg);}
1980:   x = (PetscReal)n;
1981:   PetscDrawLGAddPoint(lg,&x,&y);
1982:   if (n < 20 || (n % 5)) {
1983:     PetscDrawLGDraw(lg);
1984:   }
1985:   return(0);
1986: }

1990: /*@C
1991:    TSMonitorLGDestroy - Destroys a line graph context that was created 
1992:    with TSMonitorLGCreate().

1994:    Collective on PetscDrawLG

1996:    Input Parameter:
1997: .  draw - the drawing context

1999:    Level: intermediate

2001: .keywords: TS, monitor, line graph, destroy

2003: .seealso: TSMonitorLGCreate(),  TSMonitorSet(), TSMonitorLG();
2004: @*/
2005: PetscErrorCode  TSMonitorLGDestroy(PetscDrawLG *drawlg)
2006: {
2007:   PetscDraw      draw;

2011:   PetscDrawLGGetDraw(*drawlg,&draw);
2012:   PetscDrawDestroy(&draw);
2013:   PetscDrawLGDestroy(drawlg);
2014:   return(0);
2015: }

2019: /*@
2020:    TSGetTime - Gets the current time.

2022:    Not Collective

2024:    Input Parameter:
2025: .  ts - the TS context obtained from TSCreate()

2027:    Output Parameter:
2028: .  t  - the current time

2030:    Level: beginner

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

2034: .keywords: TS, get, time
2035: @*/
2036: PetscErrorCode  TSGetTime(TS ts,PetscReal* t)
2037: {
2041:   *t = ts->ptime;
2042:   return(0);
2043: }

2047: /*@
2048:    TSSetTime - Allows one to reset the time.

2050:    Logically Collective on TS

2052:    Input Parameters:
2053: +  ts - the TS context obtained from TSCreate()
2054: -  time - the time

2056:    Level: intermediate

2058: .seealso: TSGetTime(), TSSetDuration()

2060: .keywords: TS, set, time
2061: @*/
2062: PetscErrorCode  TSSetTime(TS ts, PetscReal t)
2063: {
2067:   ts->ptime = t;
2068:   return(0);
2069: }

2073: /*@C
2074:    TSSetOptionsPrefix - Sets the prefix used for searching for all
2075:    TS options in the database.

2077:    Logically Collective on TS

2079:    Input Parameter:
2080: +  ts     - The TS context
2081: -  prefix - The prefix to prepend to all option names

2083:    Notes:
2084:    A hyphen (-) must NOT be given at the beginning of the prefix name.
2085:    The first character of all runtime options is AUTOMATICALLY the
2086:    hyphen.

2088:    Level: advanced

2090: .keywords: TS, set, options, prefix, database

2092: .seealso: TSSetFromOptions()

2094: @*/
2095: PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
2096: {
2098:   SNES           snes;

2102:   PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);
2103:   TSGetSNES(ts,&snes);
2104:   SNESSetOptionsPrefix(snes,prefix);
2105:   return(0);
2106: }


2111: /*@C
2112:    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
2113:    TS options in the database.

2115:    Logically Collective on TS

2117:    Input Parameter:
2118: +  ts     - The TS context
2119: -  prefix - The prefix to prepend to all option names

2121:    Notes:
2122:    A hyphen (-) must NOT be given at the beginning of the prefix name.
2123:    The first character of all runtime options is AUTOMATICALLY the
2124:    hyphen.

2126:    Level: advanced

2128: .keywords: TS, append, options, prefix, database

2130: .seealso: TSGetOptionsPrefix()

2132: @*/
2133: PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
2134: {
2136:   SNES           snes;

2140:   PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);
2141:   TSGetSNES(ts,&snes);
2142:   SNESAppendOptionsPrefix(snes,prefix);
2143:   return(0);
2144: }

2148: /*@C
2149:    TSGetOptionsPrefix - Sets the prefix used for searching for all
2150:    TS options in the database.

2152:    Not Collective

2154:    Input Parameter:
2155: .  ts - The TS context

2157:    Output Parameter:
2158: .  prefix - A pointer to the prefix string used

2160:    Notes: On the fortran side, the user should pass in a string 'prifix' of
2161:    sufficient length to hold the prefix.

2163:    Level: intermediate

2165: .keywords: TS, get, options, prefix, database

2167: .seealso: TSAppendOptionsPrefix()
2168: @*/
2169: PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
2170: {

2176:   PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);
2177:   return(0);
2178: }

2182: /*@C
2183:    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.

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

2187:    Input Parameter:
2188: .  ts  - The TS context obtained from TSCreate()

2190:    Output Parameters:
2191: +  J   - The Jacobian J of F, where U_t = F(U,t)
2192: .  M   - The preconditioner matrix, usually the same as J
2193: .  func - Function to compute the Jacobian of the RHS
2194: -  ctx - User-defined context for Jacobian evaluation routine

2196:    Notes: You can pass in PETSC_NULL for any return argument you do not need.

2198:    Level: intermediate

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

2202: .keywords: TS, timestep, get, matrix, Jacobian
2203: @*/
2204: PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx)
2205: {
2207:   SNES           snes;

2210:   TSGetSNES(ts,&snes);
2211:   SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);
2212:   if (func) *func = ts->userops->rhsjacobian;
2213:   if (ctx) *ctx = ts->jacP;
2214:   return(0);
2215: }

2219: /*@C
2220:    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.

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

2224:    Input Parameter:
2225: .  ts  - The TS context obtained from TSCreate()

2227:    Output Parameters:
2228: +  A   - The Jacobian of F(t,U,U_t)
2229: .  B   - The preconditioner matrix, often the same as A
2230: .  f   - The function to compute the matrices
2231: - ctx - User-defined context for Jacobian evaluation routine

2233:    Notes: You can pass in PETSC_NULL for any return argument you do not need.

2235:    Level: advanced

2237: .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()

2239: .keywords: TS, timestep, get, matrix, Jacobian
2240: @*/
2241: PetscErrorCode  TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2242: {
2244:   SNES           snes;

2247:   TSGetSNES(ts,&snes);
2248:   SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);
2249:   if (f) *f = ts->userops->ijacobian;
2250:   if (ctx) *ctx = ts->jacP;
2251:   return(0);
2252: }

2254: typedef struct {
2255:   PetscViewer viewer;
2256:   Vec         initialsolution;
2257:   PetscBool   showinitial;
2258: } TSMonitorSolutionCtx;

2262: /*@C
2263:    TSMonitorSolution - Monitors progress of the TS solvers by calling 
2264:    VecView() for the solution at each timestep

2266:    Collective on TS

2268:    Input Parameters:
2269: +  ts - the TS context
2270: .  step - current time-step
2271: .  ptime - current time
2272: -  dummy - either a viewer or PETSC_NULL

2274:    Level: intermediate

2276: .keywords: TS,  vector, monitor, view

2278: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2279: @*/
2280: PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy)
2281: {
2282:   PetscErrorCode       ierr;
2283:   TSMonitorSolutionCtx *ictx = (TSMonitorSolutionCtx*)dummy;

2286:   if (!step && ictx->showinitial) {
2287:     if (!ictx->initialsolution) {
2288:       VecDuplicate(x,&ictx->initialsolution);
2289:     }
2290:     VecCopy(x,ictx->initialsolution);
2291:   }
2292:   if (ictx->showinitial) {
2293:     PetscReal pause;
2294:     PetscViewerDrawGetPause(ictx->viewer,&pause);
2295:     PetscViewerDrawSetPause(ictx->viewer,0.0);
2296:     VecView(ictx->initialsolution,ictx->viewer);
2297:     PetscViewerDrawSetPause(ictx->viewer,pause);
2298:     PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);
2299:   }
2300:   VecView(x,ictx->viewer);
2301:   if (ictx->showinitial) {
2302:     PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);
2303:   }
2304:   return(0);
2305: }


2310: /*@C
2311:    TSMonitorSolutionDestroy - Destroys the monitor context for TSMonitorSolution

2313:    Collective on TS

2315:    Input Parameters:
2316: .    ctx - the monitor context

2318:    Level: intermediate

2320: .keywords: TS,  vector, monitor, view

2322: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolution()
2323: @*/
2324: PetscErrorCode  TSMonitorSolutionDestroy(void **ctx)
2325: {
2326:   PetscErrorCode       ierr;
2327:   TSMonitorSolutionCtx *ictx = *(TSMonitorSolutionCtx**)ctx;
2328: 
2330:   PetscViewerDestroy(&ictx->viewer);
2331:   VecDestroy(&ictx->initialsolution);
2332:   PetscFree(ictx);
2333:   return(0);
2334: }

2338: /*@C
2339:    TSMonitorSolutionCreate - Creates the monitor context for TSMonitorSolution

2341:    Collective on TS

2343:    Input Parameter:
2344: .    ts - time-step context

2346:    Output Patameter:
2347: .    ctx - the monitor context

2349:    Level: intermediate

2351: .keywords: TS,  vector, monitor, view

2353: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolution()
2354: @*/
2355: PetscErrorCode  TSMonitorSolutionCreate(TS ts,PetscViewer viewer,void **ctx)
2356: {
2357:   PetscErrorCode       ierr;
2358:   TSMonitorSolutionCtx *ictx;
2359: 
2361:   PetscNew(TSMonitorSolutionCtx,&ictx);
2362:   *ctx = (void*)ictx;
2363:   if (!viewer) {
2364:     viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm);
2365:   }
2366:   PetscObjectReference((PetscObject)viewer);
2367:   ictx->viewer      = viewer;
2368:   ictx->showinitial = PETSC_FALSE;
2369:   PetscOptionsGetBool(((PetscObject)ts)->prefix,"-ts_monitor_solution_initial",&ictx->showinitial,PETSC_NULL);
2370:   return(0);
2371: }

2375: /*@
2376:    TSSetDM - Sets the DM that may be used by some preconditioners

2378:    Logically Collective on TS and DM

2380:    Input Parameters:
2381: +  ts - the preconditioner context
2382: -  dm - the dm

2384:    Level: intermediate


2387: .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
2388: @*/
2389: PetscErrorCode  TSSetDM(TS ts,DM dm)
2390: {
2392:   SNES           snes;

2396:   PetscObjectReference((PetscObject)dm);
2397:   DMDestroy(&ts->dm);
2398:   ts->dm = dm;
2399:   TSGetSNES(ts,&snes);
2400:   SNESSetDM(snes,dm);
2401:   return(0);
2402: }

2406: /*@
2407:    TSGetDM - Gets the DM that may be used by some preconditioners

2409:    Not Collective

2411:    Input Parameter:
2412: . ts - the preconditioner context

2414:    Output Parameter:
2415: .  dm - the dm

2417:    Level: intermediate


2420: .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
2421: @*/
2422: PetscErrorCode  TSGetDM(TS ts,DM *dm)
2423: {
2426:   *dm = ts->dm;
2427:   return(0);
2428: }

2432: /*@
2433:    SNESTSFormFunction - Function to evaluate nonlinear residual

2435:    Logically Collective on SNES

2437:    Input Parameter:
2438: + snes - nonlinear solver
2439: . X - the current state at which to evaluate the residual
2440: - ctx - user context, must be a TS

2442:    Output Parameter:
2443: . F - the nonlinear residual

2445:    Notes:
2446:    This function is not normally called by users and is automatically registered with the SNES used by TS.
2447:    It is most frequently passed to MatFDColoringSetFunction().

2449:    Level: advanced

2451: .seealso: SNESSetFunction(), MatFDColoringSetFunction()
2452: @*/
2453: PetscErrorCode  SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx)
2454: {
2455:   TS ts = (TS)ctx;

2463:   (ts->ops->snesfunction)(snes,X,F,ts);
2464:   return(0);
2465: }

2469: /*@
2470:    SNESTSFormJacobian - Function to evaluate the Jacobian

2472:    Collective on SNES

2474:    Input Parameter:
2475: + snes - nonlinear solver
2476: . X - the current state at which to evaluate the residual
2477: - ctx - user context, must be a TS

2479:    Output Parameter:
2480: + A - the Jacobian
2481: . B - the preconditioning matrix (may be the same as A)
2482: - flag - indicates any structure change in the matrix

2484:    Notes:
2485:    This function is not normally called by users and is automatically registered with the SNES used by TS.

2487:    Level: developer

2489: .seealso: SNESSetJacobian()
2490: @*/
2491: PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx)
2492: {
2493:   TS ts = (TS)ctx;

2505:   (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);
2506:   return(0);
2507: }

2511: /*@C
2512:    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only

2514:    Collective on TS

2516:    Input Arguments:
2517: +  ts - time stepping context
2518: .  t - time at which to evaluate
2519: .  X - state at which to evaluate
2520: -  ctx - context

2522:    Output Arguments:
2523: .  F - right hand side

2525:    Level: intermediate

2527:    Notes:
2528:    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
2529:    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().

2531: .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
2532: @*/
2533: PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec X,Vec F,void *ctx)
2534: {
2536:   Mat Arhs,Brhs;
2537:   MatStructure flg2;

2540:   TSGetRHSMats_Private(ts,&Arhs,&Brhs);
2541:   TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);
2542:   MatMult(Arhs,X,F);
2543:   return(0);
2544: }

2548: /*@C
2549:    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.

2551:    Collective on TS

2553:    Input Arguments:
2554: +  ts - time stepping context
2555: .  t - time at which to evaluate
2556: .  X - state at which to evaluate
2557: -  ctx - context

2559:    Output Arguments:
2560: +  A - pointer to operator
2561: .  B - pointer to preconditioning matrix
2562: -  flg - matrix structure flag

2564:    Level: intermediate

2566:    Notes:
2567:    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.

2569: .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
2570: @*/
2571: PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg,void *ctx)
2572: {

2575:   *flg = SAME_PRECONDITIONER;
2576:   return(0);
2577: }

2581: /*@C
2582:    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only

2584:    Collective on TS

2586:    Input Arguments:
2587: +  ts - time stepping context
2588: .  t - time at which to evaluate
2589: .  X - state at which to evaluate
2590: .  Xdot - time derivative of state vector
2591: -  ctx - context

2593:    Output Arguments:
2594: .  F - left hand side

2596:    Level: intermediate

2598:    Notes:
2599:    The assumption here is that the left hand side is of the form A*Xdot (and not A*Xdot + B*X). For other cases, the
2600:    user is required to write their own TSComputeIFunction.
2601:    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
2602:    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().

2604: .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
2605: @*/
2606: PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx)
2607: {
2609:   Mat A,B;
2610:   MatStructure flg2;

2613:   TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);
2614:   TSComputeIJacobian(ts,t,X,Xdot,1.0,&A,&B,&flg2,PETSC_TRUE);
2615:   MatMult(A,Xdot,F);
2616:   return(0);
2617: }

2621: /*@C
2622:    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.

2624:    Collective on TS

2626:    Input Arguments:
2627: +  ts - time stepping context
2628: .  t - time at which to evaluate
2629: .  X - state at which to evaluate
2630: .  Xdot - time derivative of state vector
2631: .  shift - shift to apply
2632: -  ctx - context

2634:    Output Arguments:
2635: +  A - pointer to operator
2636: .  B - pointer to preconditioning matrix
2637: -  flg - matrix structure flag

2639:    Level: intermediate

2641:    Notes:
2642:    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.

2644: .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
2645: @*/
2646: PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx)
2647: {

2650:   *flg = SAME_PRECONDITIONER;
2651:   return(0);
2652: }


2657: /*@
2658:    TSGetConvergedReason - Gets the reason the TS iteration was stopped.

2660:    Not Collective

2662:    Input Parameter:
2663: .  ts - the TS context

2665:    Output Parameter:
2666: .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 
2667:             manual pages for the individual convergence tests for complete lists

2669:    Level: intermediate

2671:    Notes:
2672:    Can only be called after the call to TSSolve() is complete.

2674: .keywords: TS, nonlinear, set, convergence, test

2676: .seealso: TSSetConvergenceTest(), TSConvergedReason
2677: @*/
2678: PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
2679: {
2683:   *reason = ts->reason;
2684:   return(0);
2685: }


2690: /*@
2691:    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu

2693:    Input Parameters:
2694: .  ts   - the TS context.
2695: .  xl   - lower bound.
2696: .  xu   - upper bound.

2698:    Notes:
2699:    If this routine is not called then the lower and upper bounds are set to 
2700:    SNES_VI_INF and SNES_VI_NINF respectively during SNESSetUp().

2702:    Level: advanced

2704: @*/
2705: PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
2706: {
2708:   SNES           snes;

2711:   TSGetSNES(ts,&snes);
2712:   SNESVISetVariableBounds(snes,xl,xu);
2713:   return(0);
2714: }

2716: #if defined(PETSC_HAVE_MATLAB_ENGINE)
2717: #include <mex.h>

2719: typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;

2723: /*
2724:    TSComputeFunction_Matlab - Calls the function that has been set with
2725:                          TSSetFunctionMatlab().

2727:    Collective on TS

2729:    Input Parameters:
2730: +  snes - the TS context
2731: -  x - input vector

2733:    Output Parameter:
2734: .  y - function vector, as set by TSSetFunction()

2736:    Notes:
2737:    TSComputeFunction() is typically used within nonlinear solvers
2738:    implementations, so most users would not generally call this routine
2739:    themselves.

2741:    Level: developer

2743: .keywords: TS, nonlinear, compute, function

2745: .seealso: TSSetFunction(), TSGetFunction()
2746: */
2747: PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,Vec y, void *ctx)
2748: {
2749:   PetscErrorCode   ierr;
2750:   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
2751:   int              nlhs = 1,nrhs = 7;
2752:   mxArray          *plhs[1],*prhs[7];
2753:   long long int    lx = 0,lxdot = 0,ly = 0,ls = 0;


2763:   PetscMemcpy(&ls,&snes,sizeof(snes));
2764:   PetscMemcpy(&lx,&x,sizeof(x));
2765:   PetscMemcpy(&lxdot,&xdot,sizeof(xdot));
2766:   PetscMemcpy(&ly,&y,sizeof(x));
2767:   prhs[0] =  mxCreateDoubleScalar((double)ls);
2768:   prhs[1] =  mxCreateDoubleScalar(time);
2769:   prhs[2] =  mxCreateDoubleScalar((double)lx);
2770:   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
2771:   prhs[4] =  mxCreateDoubleScalar((double)ly);
2772:   prhs[5] =  mxCreateString(sctx->funcname);
2773:   prhs[6] =  sctx->ctx;
2774:    mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");
2775:    mxGetScalar(plhs[0]);
2776:   mxDestroyArray(prhs[0]);
2777:   mxDestroyArray(prhs[1]);
2778:   mxDestroyArray(prhs[2]);
2779:   mxDestroyArray(prhs[3]);
2780:   mxDestroyArray(prhs[4]);
2781:   mxDestroyArray(prhs[5]);
2782:   mxDestroyArray(plhs[0]);
2783:   return(0);
2784: }


2789: /*
2790:    TSSetFunctionMatlab - Sets the function evaluation routine and function
2791:    vector for use by the TS routines in solving ODEs
2792:    equations from MATLAB. Here the function is a string containing the name of a MATLAB function

2794:    Logically Collective on TS

2796:    Input Parameters:
2797: +  ts - the TS context
2798: -  func - function evaluation routine

2800:    Calling sequence of func:
2801: $    func (TS ts,PetscReal time,Vec x,Vec xdot,Vec f,void *ctx);

2803:    Level: beginner

2805: .keywords: TS, nonlinear, set, function

2807: .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
2808: */
2809: PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
2810: {
2811:   PetscErrorCode  ierr;
2812:   TSMatlabContext *sctx;

2815:   /* currently sctx is memory bleed */
2816:   PetscMalloc(sizeof(TSMatlabContext),&sctx);
2817:   PetscStrallocpy(func,&sctx->funcname);
2818:   /*
2819:      This should work, but it doesn't
2820:   sctx->ctx = ctx;
2821:   mexMakeArrayPersistent(sctx->ctx);
2822:   */
2823:   sctx->ctx = mxDuplicateArray(ctx);
2824:   TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);
2825:   return(0);
2826: }

2830: /*
2831:    TSComputeJacobian_Matlab - Calls the function that has been set with
2832:                          TSSetJacobianMatlab().

2834:    Collective on TS

2836:    Input Parameters:
2837: +  ts - the TS context
2838: .  x - input vector
2839: .  A, B - the matrices
2840: -  ctx - user context

2842:    Output Parameter:
2843: .  flag - structure of the matrix

2845:    Level: developer

2847: .keywords: TS, nonlinear, compute, function

2849: .seealso: TSSetFunction(), TSGetFunction()
2850: @*/
2851: PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec x,Vec xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx)
2852: {
2853:   PetscErrorCode  ierr;
2854:   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
2855:   int             nlhs = 2,nrhs = 9;
2856:   mxArray         *plhs[2],*prhs[9];
2857:   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;


2863:   /* call Matlab function in ctx with arguments x and y */

2865:   PetscMemcpy(&ls,&ts,sizeof(ts));
2866:   PetscMemcpy(&lx,&x,sizeof(x));
2867:   PetscMemcpy(&lxdot,&xdot,sizeof(x));
2868:   PetscMemcpy(&lA,A,sizeof(x));
2869:   PetscMemcpy(&lB,B,sizeof(x));
2870:   prhs[0] =  mxCreateDoubleScalar((double)ls);
2871:   prhs[1] =  mxCreateDoubleScalar((double)time);
2872:   prhs[2] =  mxCreateDoubleScalar((double)lx);
2873:   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
2874:   prhs[4] =  mxCreateDoubleScalar((double)shift);
2875:   prhs[5] =  mxCreateDoubleScalar((double)lA);
2876:   prhs[6] =  mxCreateDoubleScalar((double)lB);
2877:   prhs[7] =  mxCreateString(sctx->funcname);
2878:   prhs[8] =  sctx->ctx;
2879:    mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");
2880:    mxGetScalar(plhs[0]);
2881:   *flag   =  (MatStructure) mxGetScalar(plhs[1]);
2882:   mxDestroyArray(prhs[0]);
2883:   mxDestroyArray(prhs[1]);
2884:   mxDestroyArray(prhs[2]);
2885:   mxDestroyArray(prhs[3]);
2886:   mxDestroyArray(prhs[4]);
2887:   mxDestroyArray(prhs[5]);
2888:   mxDestroyArray(prhs[6]);
2889:   mxDestroyArray(prhs[7]);
2890:   mxDestroyArray(plhs[0]);
2891:   mxDestroyArray(plhs[1]);
2892:   return(0);
2893: }


2898: /*
2899:    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
2900:    vector for use by the TS routines in solving ODEs from MATLAB. Here the function is a string containing the name of a MATLAB function

2902:    Logically Collective on TS

2904:    Input Parameters:
2905: +  ts - the TS context
2906: .  A,B - Jacobian matrices
2907: .  func - function evaluation routine
2908: -  ctx - user context

2910:    Calling sequence of func:
2911: $    flag = func (TS ts,PetscReal time,Vec x,Vec xdot,Mat A,Mat B,void *ctx);


2914:    Level: developer

2916: .keywords: TS, nonlinear, set, function

2918: .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
2919: */
2920: PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
2921: {
2922:   PetscErrorCode    ierr;
2923:   TSMatlabContext *sctx;

2926:   /* currently sctx is memory bleed */
2927:   PetscMalloc(sizeof(TSMatlabContext),&sctx);
2928:   PetscStrallocpy(func,&sctx->funcname);
2929:   /*
2930:      This should work, but it doesn't
2931:   sctx->ctx = ctx;
2932:   mexMakeArrayPersistent(sctx->ctx);
2933:   */
2934:   sctx->ctx = mxDuplicateArray(ctx);
2935:   TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);
2936:   return(0);
2937: }

2941: /*
2942:    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().

2944:    Collective on TS

2946: .seealso: TSSetFunction(), TSGetFunction()
2947: @*/
2948: PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec x, void *ctx)
2949: {
2950:   PetscErrorCode  ierr;
2951:   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
2952:   int             nlhs = 1,nrhs = 6;
2953:   mxArray         *plhs[1],*prhs[6];
2954:   long long int   lx = 0,ls = 0;


2960:   PetscMemcpy(&ls,&ts,sizeof(ts));
2961:   PetscMemcpy(&lx,&x,sizeof(x));
2962:   prhs[0] =  mxCreateDoubleScalar((double)ls);
2963:   prhs[1] =  mxCreateDoubleScalar((double)it);
2964:   prhs[2] =  mxCreateDoubleScalar((double)time);
2965:   prhs[3] =  mxCreateDoubleScalar((double)lx);
2966:   prhs[4] =  mxCreateString(sctx->funcname);
2967:   prhs[5] =  sctx->ctx;
2968:    mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");
2969:    mxGetScalar(plhs[0]);
2970:   mxDestroyArray(prhs[0]);
2971:   mxDestroyArray(prhs[1]);
2972:   mxDestroyArray(prhs[2]);
2973:   mxDestroyArray(prhs[3]);
2974:   mxDestroyArray(prhs[4]);
2975:   mxDestroyArray(plhs[0]);
2976:   return(0);
2977: }


2982: /*
2983:    TSMonitorSetMatlab - Sets the monitor function from Matlab

2985:    Level: developer

2987: .keywords: TS, nonlinear, set, function

2989: .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
2990: */
2991: PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
2992: {
2993:   PetscErrorCode    ierr;
2994:   TSMatlabContext *sctx;

2997:   /* currently sctx is memory bleed */
2998:   PetscMalloc(sizeof(TSMatlabContext),&sctx);
2999:   PetscStrallocpy(func,&sctx->funcname);
3000:   /*
3001:      This should work, but it doesn't
3002:   sctx->ctx = ctx;
3003:   mexMakeArrayPersistent(sctx->ctx);
3004:   */
3005:   sctx->ctx = mxDuplicateArray(ctx);
3006:   TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);
3007:   return(0);
3008: }
3009: #endif