xref: /petsc/src/ts/adapt/interface/tsadapt.c (revision 87050cfd2c0579ea516b8fcfef1cf8502bc01bdc)
1 
2 #include <petsc/private/tsimpl.h> /*I  "petscts.h" I*/
3 
4 PetscClassId TSADAPT_CLASSID;
5 
6 static PetscFunctionList TSAdaptList;
7 static PetscBool         TSAdaptPackageInitialized;
8 static PetscBool         TSAdaptRegisterAllCalled;
9 
10 PETSC_EXTERN PetscErrorCode TSAdaptCreate_None(TSAdapt);
11 PETSC_EXTERN PetscErrorCode TSAdaptCreate_Basic(TSAdapt);
12 PETSC_EXTERN PetscErrorCode TSAdaptCreate_DSP(TSAdapt);
13 PETSC_EXTERN PetscErrorCode TSAdaptCreate_CFL(TSAdapt);
14 PETSC_EXTERN PetscErrorCode TSAdaptCreate_GLEE(TSAdapt);
15 PETSC_EXTERN PetscErrorCode TSAdaptCreate_History(TSAdapt);
16 
17 /*@C
18    TSAdaptRegister -  adds a TSAdapt implementation
19 
20    Not Collective
21 
22    Input Parameters:
23 +  name_scheme - name of user-defined adaptivity scheme
24 -  routine_create - routine to create method context
25 
26    Notes:
27    TSAdaptRegister() may be called multiple times to add several user-defined families.
28 
29    Sample usage:
30 .vb
31    TSAdaptRegister("my_scheme",MySchemeCreate);
32 .ve
33 
34    Then, your scheme can be chosen with the procedural interface via
35 $     TSAdaptSetType(ts,"my_scheme")
36    or at runtime via the option
37 $     -ts_adapt_type my_scheme
38 
39    Level: advanced
40 
41 .keywords: TSAdapt, register
42 
43 .seealso: TSAdaptRegisterAll()
44 @*/
45 PetscErrorCode  TSAdaptRegister(const char sname[],PetscErrorCode (*function)(TSAdapt))
46 {
47   PetscErrorCode ierr;
48 
49   PetscFunctionBegin;
50   ierr = TSAdaptInitializePackage();CHKERRQ(ierr);
51   ierr = PetscFunctionListAdd(&TSAdaptList,sname,function);CHKERRQ(ierr);
52   PetscFunctionReturn(0);
53 }
54 
55 /*@C
56   TSAdaptRegisterAll - Registers all of the adaptivity schemes in TSAdapt
57 
58   Not Collective
59 
60   Level: advanced
61 
62 .keywords: TSAdapt, register, all
63 
64 .seealso: TSAdaptRegisterDestroy()
65 @*/
66 PetscErrorCode  TSAdaptRegisterAll(void)
67 {
68   PetscErrorCode ierr;
69 
70   PetscFunctionBegin;
71   if (TSAdaptRegisterAllCalled) PetscFunctionReturn(0);
72   TSAdaptRegisterAllCalled = PETSC_TRUE;
73   ierr = TSAdaptRegister(TSADAPTNONE,   TSAdaptCreate_None);CHKERRQ(ierr);
74   ierr = TSAdaptRegister(TSADAPTBASIC,  TSAdaptCreate_Basic);CHKERRQ(ierr);
75   ierr = TSAdaptRegister(TSADAPTDSP,    TSAdaptCreate_DSP);CHKERRQ(ierr);
76   ierr = TSAdaptRegister(TSADAPTCFL,    TSAdaptCreate_CFL);CHKERRQ(ierr);
77   ierr = TSAdaptRegister(TSADAPTGLEE,   TSAdaptCreate_GLEE);CHKERRQ(ierr);
78   ierr = TSAdaptRegister(TSADAPTHISTORY,TSAdaptCreate_History);CHKERRQ(ierr);
79   PetscFunctionReturn(0);
80 }
81 
82 /*@C
83   TSAdaptFinalizePackage - This function destroys everything in the TS package. It is
84   called from PetscFinalize().
85 
86   Level: developer
87 
88 .keywords: Petsc, destroy, package
89 .seealso: PetscFinalize()
90 @*/
91 PetscErrorCode  TSAdaptFinalizePackage(void)
92 {
93   PetscErrorCode ierr;
94 
95   PetscFunctionBegin;
96   ierr = PetscFunctionListDestroy(&TSAdaptList);CHKERRQ(ierr);
97   TSAdaptPackageInitialized = PETSC_FALSE;
98   TSAdaptRegisterAllCalled  = PETSC_FALSE;
99   PetscFunctionReturn(0);
100 }
101 
102 /*@C
103   TSAdaptInitializePackage - This function initializes everything in the TSAdapt package. It is
104   called from TSInitializePackage().
105 
106   Level: developer
107 
108 .keywords: TSAdapt, initialize, package
109 .seealso: PetscInitialize()
110 @*/
111 PetscErrorCode  TSAdaptInitializePackage(void)
112 {
113   PetscErrorCode ierr;
114 
115   PetscFunctionBegin;
116   if (TSAdaptPackageInitialized) PetscFunctionReturn(0);
117   TSAdaptPackageInitialized = PETSC_TRUE;
118   ierr = PetscClassIdRegister("TSAdapt",&TSADAPT_CLASSID);CHKERRQ(ierr);
119   ierr = TSAdaptRegisterAll();CHKERRQ(ierr);
120   ierr = PetscRegisterFinalize(TSAdaptFinalizePackage);CHKERRQ(ierr);
121   PetscFunctionReturn(0);
122 }
123 
124 /*@C
125   TSAdaptSetType - sets the approach used for the error adapter, currently there is only TSADAPTBASIC and TSADAPTNONE
126 
127   Logicially Collective on TSAdapt
128 
129   Input Parameter:
130 + adapt - the TS adapter, most likely obtained with TSGetAdapt()
131 - type - either  TSADAPTBASIC or TSADAPTNONE
132 
133   Options Database:
134 . -ts_adapt_type <basic or dsp or none> - to set the adapter type
135 
136   Level: intermediate
137 
138 .keywords: TSAdapt, create
139 
140 .seealso: TSGetAdapt(), TSAdaptDestroy(), TSAdaptType, TSAdaptGetType()
141 @*/
142 PetscErrorCode  TSAdaptSetType(TSAdapt adapt,TSAdaptType type)
143 {
144   PetscBool      match;
145   PetscErrorCode ierr,(*r)(TSAdapt);
146 
147   PetscFunctionBegin;
148   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
149   PetscValidCharPointer(type,2);
150   ierr = PetscObjectTypeCompare((PetscObject)adapt,type,&match);CHKERRQ(ierr);
151   if (match) PetscFunctionReturn(0);
152   ierr = PetscFunctionListFind(TSAdaptList,type,&r);CHKERRQ(ierr);
153   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TSAdapt type \"%s\" given",type);
154   if (adapt->ops->destroy) {ierr = (*adapt->ops->destroy)(adapt);CHKERRQ(ierr);}
155   ierr = PetscMemzero(adapt->ops,sizeof(struct _TSAdaptOps));CHKERRQ(ierr);
156   ierr = PetscObjectChangeTypeName((PetscObject)adapt,type);CHKERRQ(ierr);
157   ierr = (*r)(adapt);CHKERRQ(ierr);
158   PetscFunctionReturn(0);
159 }
160 
161 /*@C
162   TSAdaptGetType - gets the TS adapter method type (as a string).
163 
164   Not Collective
165 
166   Input Parameter:
167 . adapt - The TS adapter, most likely obtained with TSGetAdapt()
168 
169   Output Parameter:
170 . type - The name of TS adapter method
171 
172   Level: intermediate
173 
174 .keywords: TSAdapt, get, type
175 .seealso TSAdaptSetType()
176 @*/
177 PetscErrorCode TSAdaptGetType(TSAdapt adapt,TSAdaptType *type)
178 {
179   PetscFunctionBegin;
180   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
181   PetscValidPointer(type,2);
182   *type = ((PetscObject)adapt)->type_name;
183   PetscFunctionReturn(0);
184 }
185 
186 PetscErrorCode  TSAdaptSetOptionsPrefix(TSAdapt adapt,const char prefix[])
187 {
188   PetscErrorCode ierr;
189 
190   PetscFunctionBegin;
191   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
192   ierr = PetscObjectSetOptionsPrefix((PetscObject)adapt,prefix);CHKERRQ(ierr);
193   PetscFunctionReturn(0);
194 }
195 
196 /*@C
197   TSAdaptLoad - Loads a TSAdapt that has been stored in binary  with TSAdaptView().
198 
199   Collective on PetscViewer
200 
201   Input Parameters:
202 + newdm - the newly loaded TSAdapt, this needs to have been created with TSAdaptCreate() or
203            some related function before a call to TSAdaptLoad().
204 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
205            HDF5 file viewer, obtained from PetscViewerHDF5Open()
206 
207    Level: intermediate
208 
209   Notes:
210    The type is determined by the data in the file, any type set into the TSAdapt before this call is ignored.
211 
212   Notes for advanced users:
213   Most users should not need to know the details of the binary storage
214   format, since TSAdaptLoad() and TSAdaptView() completely hide these details.
215   But for anyone who's interested, the standard binary matrix storage
216   format is
217 .vb
218      has not yet been determined
219 .ve
220 
221 .seealso: PetscViewerBinaryOpen(), TSAdaptView(), MatLoad(), VecLoad()
222 @*/
223 PetscErrorCode  TSAdaptLoad(TSAdapt adapt,PetscViewer viewer)
224 {
225   PetscErrorCode ierr;
226   PetscBool      isbinary;
227   char           type[256];
228 
229   PetscFunctionBegin;
230   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
231   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
232   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
233   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
234 
235   ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
236   ierr = TSAdaptSetType(adapt,type);CHKERRQ(ierr);
237   if (adapt->ops->load) {
238     ierr = (*adapt->ops->load)(adapt,viewer);CHKERRQ(ierr);
239   }
240   PetscFunctionReturn(0);
241 }
242 
243 PetscErrorCode  TSAdaptView(TSAdapt adapt,PetscViewer viewer)
244 {
245   PetscErrorCode ierr;
246   PetscBool      iascii,isbinary,isnone;
247 
248   PetscFunctionBegin;
249   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
250   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)adapt),&viewer);CHKERRQ(ierr);}
251   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
252   PetscCheckSameComm(adapt,1,viewer,2);
253   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
254   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
255   if (iascii) {
256     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)adapt,viewer);CHKERRQ(ierr);
257     ierr = PetscObjectTypeCompare((PetscObject)adapt,TSADAPTNONE,&isnone);CHKERRQ(ierr);
258     if (!isnone) {
259       if (adapt->always_accept) {ierr = PetscViewerASCIIPrintf(viewer,"  always accepting steps\n");CHKERRQ(ierr);}
260       ierr = PetscViewerASCIIPrintf(viewer,"  safety factor %g\n",(double)adapt->safety);CHKERRQ(ierr);
261       ierr = PetscViewerASCIIPrintf(viewer,"  extra safety factor after step rejection %g\n",(double)adapt->reject_safety);CHKERRQ(ierr);
262       ierr = PetscViewerASCIIPrintf(viewer,"  clip fastest increase %g\n",(double)adapt->clip[1]);CHKERRQ(ierr);
263       ierr = PetscViewerASCIIPrintf(viewer,"  clip fastest decrease %g\n",(double)adapt->clip[0]);CHKERRQ(ierr);
264       ierr = PetscViewerASCIIPrintf(viewer,"  maximum allowed timestep %g\n",(double)adapt->dt_max);CHKERRQ(ierr);
265       ierr = PetscViewerASCIIPrintf(viewer,"  minimum allowed timestep %g\n",(double)adapt->dt_min);CHKERRQ(ierr);
266     }
267     if (adapt->ops->view) {
268       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
269       ierr = (*adapt->ops->view)(adapt,viewer);CHKERRQ(ierr);
270       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
271     }
272   } else if (isbinary) {
273     char type[256];
274 
275     /* need to save FILE_CLASS_ID for adapt class */
276     ierr = PetscStrncpy(type,((PetscObject)adapt)->type_name,256);CHKERRQ(ierr);
277     ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
278   } else if (adapt->ops->view) {
279     ierr = (*adapt->ops->view)(adapt,viewer);CHKERRQ(ierr);
280   }
281   PetscFunctionReturn(0);
282 }
283 
284 /*@
285    TSAdaptReset - Resets a TSAdapt context.
286 
287    Collective on TS
288 
289    Input Parameter:
290 .  adapt - the TSAdapt context obtained from TSAdaptCreate()
291 
292    Level: developer
293 
294 .seealso: TSAdaptCreate(), TSAdaptDestroy()
295 @*/
296 PetscErrorCode  TSAdaptReset(TSAdapt adapt)
297 {
298   PetscErrorCode ierr;
299 
300   PetscFunctionBegin;
301   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
302   if (adapt->ops->reset) {ierr = (*adapt->ops->reset)(adapt);CHKERRQ(ierr);}
303   PetscFunctionReturn(0);
304 }
305 
306 PetscErrorCode  TSAdaptDestroy(TSAdapt *adapt)
307 {
308   PetscErrorCode ierr;
309 
310   PetscFunctionBegin;
311   if (!*adapt) PetscFunctionReturn(0);
312   PetscValidHeaderSpecific(*adapt,TSADAPT_CLASSID,1);
313   if (--((PetscObject)(*adapt))->refct > 0) {*adapt = NULL; PetscFunctionReturn(0);}
314 
315   ierr = TSAdaptReset(*adapt);CHKERRQ(ierr);
316 
317   if ((*adapt)->ops->destroy) {ierr = (*(*adapt)->ops->destroy)(*adapt);CHKERRQ(ierr);}
318   ierr = PetscViewerDestroy(&(*adapt)->monitor);CHKERRQ(ierr);
319   ierr = PetscHeaderDestroy(adapt);CHKERRQ(ierr);
320   PetscFunctionReturn(0);
321 }
322 
323 /*@
324    TSAdaptSetMonitor - Monitor the choices made by the adaptive controller
325 
326    Collective on TSAdapt
327 
328    Input Arguments:
329 +  adapt - adaptive controller context
330 -  flg - PETSC_TRUE to active a monitor, PETSC_FALSE to disable
331 
332    Options Database Keys:
333 .  -ts_adapt_monitor - to turn on monitoring
334 
335    Level: intermediate
336 
337 .seealso: TSAdaptChoose()
338 @*/
339 PetscErrorCode TSAdaptSetMonitor(TSAdapt adapt,PetscBool flg)
340 {
341   PetscErrorCode ierr;
342 
343   PetscFunctionBegin;
344   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
345   PetscValidLogicalCollectiveBool(adapt,flg,2);
346   if (flg) {
347     if (!adapt->monitor) {ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)adapt),"stdout",&adapt->monitor);CHKERRQ(ierr);}
348   } else {
349     ierr = PetscViewerDestroy(&adapt->monitor);CHKERRQ(ierr);
350   }
351   PetscFunctionReturn(0);
352 }
353 
354 /*@C
355    TSAdaptSetCheckStage - Set a callback to check convergence for a stage
356 
357    Logically collective on TSAdapt
358 
359    Input Arguments:
360 +  adapt - adaptive controller context
361 -  func - stage check function
362 
363    Arguments of func:
364 $  PetscErrorCode func(TSAdapt adapt,TS ts,PetscBool *accept)
365 
366 +  adapt - adaptive controller context
367 .  ts - time stepping context
368 -  accept - pending choice of whether to accept, can be modified by this routine
369 
370    Level: advanced
371 
372 .seealso: TSAdaptChoose()
373 @*/
374 PetscErrorCode TSAdaptSetCheckStage(TSAdapt adapt,PetscErrorCode (*func)(TSAdapt,TS,PetscReal,Vec,PetscBool*))
375 {
376 
377   PetscFunctionBegin;
378   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
379   adapt->checkstage = func;
380   PetscFunctionReturn(0);
381 }
382 
383 /*@
384    TSAdaptSetAlwaysAccept - Set whether to always accept steps regardless of
385    any error or stability condition not meeting the prescribed goal.
386 
387    Logically collective on TSAdapt
388 
389    Input Arguments:
390 +  adapt - time step adaptivity context, usually gotten with TSGetAdapt()
391 -  flag - whether to always accept steps
392 
393    Options Database Keys:
394 .  -ts_adapt_always_accept - to always accept steps
395 
396    Level: intermediate
397 
398 .seealso: TSAdapt, TSAdaptChoose()
399 @*/
400 PetscErrorCode TSAdaptSetAlwaysAccept(TSAdapt adapt,PetscBool flag)
401 {
402   PetscFunctionBegin;
403   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
404   PetscValidLogicalCollectiveBool(adapt,flag,2);
405   adapt->always_accept = flag;
406   PetscFunctionReturn(0);
407 }
408 
409 /*@
410    TSAdaptSetSafety - Set safety factors
411 
412    Logically collective on TSAdapt
413 
414    Input Arguments:
415 +  adapt - adaptive controller context
416 .  safety - safety factor relative to target error/stability goal
417 -  reject_safety - extra safety factor to apply if the last step was rejected
418 
419    Options Database Keys:
420 +  -ts_adapt_safety <safety> - to set safety factor
421 -  -ts_adapt_reject_safety <reject_safety> - to set reject safety factor
422 
423    Level: intermediate
424 
425 .seealso: TSAdapt, TSAdaptGetSafety(), TSAdaptChoose()
426 @*/
427 PetscErrorCode TSAdaptSetSafety(TSAdapt adapt,PetscReal safety,PetscReal reject_safety)
428 {
429   PetscFunctionBegin;
430   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
431   PetscValidLogicalCollectiveReal(adapt,safety,2);
432   PetscValidLogicalCollectiveReal(adapt,reject_safety,3);
433   if (safety != PETSC_DEFAULT && safety < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Safety factor %g must be non negative",(double)safety);
434   if (safety != PETSC_DEFAULT && safety > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Safety factor %g must be less than one",(double)safety);
435   if (reject_safety != PETSC_DEFAULT && reject_safety < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Reject safety factor %g must be non negative",(double)reject_safety);
436   if (reject_safety != PETSC_DEFAULT && reject_safety > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Reject safety factor %g must be less than one",(double)reject_safety);
437   if (safety != PETSC_DEFAULT) adapt->safety = safety;
438   if (reject_safety != PETSC_DEFAULT) adapt->reject_safety = reject_safety;
439   PetscFunctionReturn(0);
440 }
441 
442 /*@
443    TSAdaptGetSafety - Get safety factors
444 
445    Not Collective
446 
447    Input Arguments:
448 .  adapt - adaptive controller context
449 
450    Ouput Arguments:
451 .  safety - safety factor relative to target error/stability goal
452 +  reject_safety - extra safety factor to apply if the last step was rejected
453 
454    Level: intermediate
455 
456 .seealso: TSAdapt, TSAdaptSetSafety(), TSAdaptChoose()
457 @*/
458 PetscErrorCode TSAdaptGetSafety(TSAdapt adapt,PetscReal *safety,PetscReal *reject_safety)
459 {
460   PetscFunctionBegin;
461   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
462   if (safety)        PetscValidRealPointer(safety,2);
463   if (reject_safety) PetscValidRealPointer(reject_safety,3);
464   if (safety)        *safety        = adapt->safety;
465   if (reject_safety) *reject_safety = adapt->reject_safety;
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    TSAdaptSetClip - Sets the admissible decrease/increase factor in step size
471 
472    Logically collective on TSAdapt
473 
474    Input Arguments:
475 +  adapt - adaptive controller context
476 .  low - admissible decrease factor
477 -  high - admissible increase factor
478 
479    Options Database Keys:
480 .  -ts_adapt_clip <low>,<high> - to set admissible time step decrease and increase factors
481 
482    Level: intermediate
483 
484 .seealso: TSAdaptChoose(), TSAdaptGetClip()
485 @*/
486 PetscErrorCode TSAdaptSetClip(TSAdapt adapt,PetscReal low,PetscReal high)
487 {
488   PetscFunctionBegin;
489   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
490   PetscValidLogicalCollectiveReal(adapt,low,2);
491   PetscValidLogicalCollectiveReal(adapt,high,3);
492   if (low  != PETSC_DEFAULT && low  < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Decrease factor %g must be non negative",(double)low);
493   if (low  != PETSC_DEFAULT && low  > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Decrease factor %g must be less than one",(double)low);
494   if (high != PETSC_DEFAULT && high < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Increase factor %g must be geather than one",(double)high);
495   if (low  != PETSC_DEFAULT) adapt->clip[0] = low;
496   if (high != PETSC_DEFAULT) adapt->clip[1] = high;
497   PetscFunctionReturn(0);
498 }
499 
500 /*@
501    TSAdaptGetClip - Gets the admissible decrease/increase factor in step size
502 
503    Not Collective
504 
505    Input Arguments:
506 .  adapt - adaptive controller context
507 
508    Ouput Arguments:
509 +  low - optional, admissible decrease factor
510 -  high - optional, admissible increase factor
511 
512    Level: intermediate
513 
514 .seealso: TSAdaptChoose(), TSAdaptSetClip()
515 @*/
516 PetscErrorCode TSAdaptGetClip(TSAdapt adapt,PetscReal *low,PetscReal *high)
517 {
518   PetscFunctionBegin;
519   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
520   if (low)  PetscValidRealPointer(low,2);
521   if (high) PetscValidRealPointer(high,3);
522   if (low)  *low  = adapt->clip[0];
523   if (high) *high = adapt->clip[1];
524   PetscFunctionReturn(0);
525 }
526 
527 /*@
528    TSAdaptSetStepLimits - Set the minimum and maximum step sizes to be considered by the controller
529 
530    Logically collective on TSAdapt
531 
532    Input Arguments:
533 +  adapt - time step adaptivity context, usually gotten with TSGetAdapt()
534 .  hmin - minimum time step
535 -  hmax - maximum time step
536 
537    Options Database Keys:
538 +  -ts_adapt_dt_min <min> - to set minimum time step
539 -  -ts_adapt_dt_max <max> - to set maximum time step
540 
541    Level: intermediate
542 
543 .seealso: TSAdapt, TSAdaptGetStepLimits(), TSAdaptChoose()
544 @*/
545 PetscErrorCode TSAdaptSetStepLimits(TSAdapt adapt,PetscReal hmin,PetscReal hmax)
546 {
547 
548   PetscFunctionBegin;
549   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
550   PetscValidLogicalCollectiveReal(adapt,hmin,2);
551   PetscValidLogicalCollectiveReal(adapt,hmax,3);
552   if (hmin != PETSC_DEFAULT && hmin < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Minimum time step %g must be non negative",(double)hmin);
553   if (hmax != PETSC_DEFAULT && hmax < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Minimum time step %g must be non negative",(double)hmax);
554   if (hmin != PETSC_DEFAULT) adapt->dt_min = hmin;
555   if (hmax != PETSC_DEFAULT) adapt->dt_max = hmax;
556   hmin = adapt->dt_min;
557   hmax = adapt->dt_max;
558   if (hmax <= hmin) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Maximum time step %g must geather than minimum time step %g",(double)hmax,(double)hmin);
559   PetscFunctionReturn(0);
560 }
561 
562 /*@
563    TSAdaptGetStepLimits - Get the minimum and maximum step sizes to be considered by the controller
564 
565    Not Collective
566 
567    Input Arguments:
568 .  adapt - time step adaptivity context, usually gotten with TSGetAdapt()
569 
570    Output Arguments:
571 +  hmin - minimum time step
572 -  hmax - maximum time step
573 
574    Level: intermediate
575 
576 .seealso: TSAdapt, TSAdaptSetStepLimits(), TSAdaptChoose()
577 @*/
578 PetscErrorCode TSAdaptGetStepLimits(TSAdapt adapt,PetscReal *hmin,PetscReal *hmax)
579 {
580 
581   PetscFunctionBegin;
582   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
583   if (hmin) PetscValidRealPointer(hmin,2);
584   if (hmax) PetscValidRealPointer(hmax,3);
585   if (hmin) *hmin = adapt->dt_min;
586   if (hmax) *hmax = adapt->dt_max;
587   PetscFunctionReturn(0);
588 }
589 
590 /*
591    TSAdaptSetFromOptions - Sets various TSAdapt parameters from user options.
592 
593    Collective on TSAdapt
594 
595    Input Parameter:
596 .  adapt - the TSAdapt context
597 
598    Options Database Keys:
599 +  -ts_adapt_type <type> - algorithm to use for adaptivity
600 .  -ts_adapt_always_accept - always accept steps regardless of error/stability goals
601 .  -ts_adapt_safety <safety> - safety factor relative to target error/stability goal
602 .  -ts_adapt_reject_safety <safety> - extra safety factor to apply if the last step was rejected
603 .  -ts_adapt_clip <low,high> - admissible time step decrease and increase factors
604 .  -ts_adapt_dt_min <min> - minimum timestep to use
605 .  -ts_adapt_dt_max <max> - maximum timestep to use
606 .  -ts_adapt_scale_solve_failed <scale> - scale timestep by this factor if a solve fails
607 .  -ts_adapt_wnormtype <2 or infinity> - type of norm for computing error estimates
608 -  -ts_adapt_time_step_increase_delay - number of timesteps to delay increasing the time step after it has been decreased due to failed solver
609 
610    Level: advanced
611 
612    Notes:
613    This function is automatically called by TSSetFromOptions()
614 
615 .keywords: TS, TSGetAdapt(), TSAdaptSetType(), TSAdaptSetStepLimits()
616 
617 .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptSetAlwaysAccept(), TSAdaptSetSafety(),
618           TSAdaptSetClip(), TSAdaptSetStepLimits(), TSAdaptSetMonitor()
619 */
620 PetscErrorCode  TSAdaptSetFromOptions(PetscOptionItems *PetscOptionsObject,TSAdapt adapt)
621 {
622   PetscErrorCode ierr;
623   char           type[256] = TSADAPTBASIC;
624   PetscReal      safety,reject_safety,clip[2],hmin,hmax;
625   PetscBool      set,flg;
626   PetscInt       two;
627 
628   PetscFunctionBegin;
629   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
630   /* This should use PetscOptionsBegin() if/when this becomes an object used outside of TS, but currently this
631    * function can only be called from inside TSSetFromOptions()  */
632   ierr = PetscOptionsHead(PetscOptionsObject,"TS Adaptivity options");CHKERRQ(ierr);
633   ierr = PetscOptionsFList("-ts_adapt_type","Algorithm to use for adaptivity","TSAdaptSetType",TSAdaptList,((PetscObject)adapt)->type_name ? ((PetscObject)adapt)->type_name : type,type,sizeof(type),&flg);CHKERRQ(ierr);
634   if (flg || !((PetscObject)adapt)->type_name) {
635     ierr = TSAdaptSetType(adapt,type);CHKERRQ(ierr);
636   }
637 
638   ierr = PetscOptionsBool("-ts_adapt_always_accept","Always accept the step","TSAdaptSetAlwaysAccept",adapt->always_accept,&flg,&set);CHKERRQ(ierr);
639   if (set) {ierr = TSAdaptSetAlwaysAccept(adapt,flg);CHKERRQ(ierr);}
640 
641   safety = adapt->safety; reject_safety = adapt->reject_safety;
642   ierr = PetscOptionsReal("-ts_adapt_safety","Safety factor relative to target error/stability goal","TSAdaptSetSafety",safety,&safety,&set);CHKERRQ(ierr);
643   ierr = PetscOptionsReal("-ts_adapt_reject_safety","Extra safety factor to apply if the last step was rejected","TSAdaptSetSafety",reject_safety,&reject_safety,&flg);CHKERRQ(ierr);
644   if (set || flg) {ierr = TSAdaptSetSafety(adapt,safety,reject_safety);CHKERRQ(ierr);}
645 
646   two = 2; clip[0] = adapt->clip[0]; clip[1] = adapt->clip[1];
647   ierr = PetscOptionsRealArray("-ts_adapt_clip","Admissible decrease/increase factor in step size","TSAdaptSetClip",clip,&two,&set);CHKERRQ(ierr);
648   if (set && (two != 2)) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Must give exactly two values to -ts_adapt_clip");
649   if (set) {ierr = TSAdaptSetClip(adapt,clip[0],clip[1]);CHKERRQ(ierr);}
650 
651   hmin = adapt->dt_min; hmax = adapt->dt_max;
652   ierr = PetscOptionsReal("-ts_adapt_dt_min","Minimum time step considered","TSAdaptSetStepLimits",hmin,&hmin,&set);CHKERRQ(ierr);
653   ierr = PetscOptionsReal("-ts_adapt_dt_max","Maximum time step considered","TSAdaptSetStepLimits",hmax,&hmax,&flg);CHKERRQ(ierr);
654   if (set || flg) {ierr = TSAdaptSetStepLimits(adapt,hmin,hmax);CHKERRQ(ierr);}
655 
656   ierr = PetscOptionsReal("-ts_adapt_scale_solve_failed","Scale step by this factor if solve fails","",adapt->scale_solve_failed,&adapt->scale_solve_failed,NULL);CHKERRQ(ierr);
657 
658   ierr = PetscOptionsEnum("-ts_adapt_wnormtype","Type of norm computed for error estimation","",NormTypes,(PetscEnum)adapt->wnormtype,(PetscEnum*)&adapt->wnormtype,NULL);CHKERRQ(ierr);
659   if (adapt->wnormtype != NORM_2 && adapt->wnormtype != NORM_INFINITY) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_SUP,"Only 2-norm and infinite norm supported");
660 
661   ierr = PetscOptionsInt("-ts_adapt_time_step_increase_delay","Number of timesteps to delay increasing the time step after it has been decreased due to failed solver","TSAdaptSetTimeStepIncreaseDelay",adapt->timestepjustdecreased_delay,&adapt->timestepjustdecreased_delay,NULL);CHKERRQ(ierr);
662 
663   ierr = PetscOptionsBool("-ts_adapt_monitor","Print choices made by adaptive controller","TSAdaptSetMonitor",adapt->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
664   if (set) {ierr = TSAdaptSetMonitor(adapt,flg);CHKERRQ(ierr);}
665 
666   if (adapt->ops->setfromoptions) {ierr = (*adapt->ops->setfromoptions)(PetscOptionsObject,adapt);CHKERRQ(ierr);}
667   ierr = PetscOptionsTail();CHKERRQ(ierr);
668   PetscFunctionReturn(0);
669 }
670 
671 /*@
672    TSAdaptCandidatesClear - clear any previously set candidate schemes
673 
674    Logically collective on TSAdapt
675 
676    Input Argument:
677 .  adapt - adaptive controller
678 
679    Level: developer
680 
681 .seealso: TSAdapt, TSAdaptCreate(), TSAdaptCandidateAdd(), TSAdaptChoose()
682 @*/
683 PetscErrorCode TSAdaptCandidatesClear(TSAdapt adapt)
684 {
685   PetscErrorCode ierr;
686 
687   PetscFunctionBegin;
688   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
689   ierr = PetscMemzero(&adapt->candidates,sizeof(adapt->candidates));CHKERRQ(ierr);
690   PetscFunctionReturn(0);
691 }
692 
693 /*@C
694    TSAdaptCandidateAdd - add a candidate scheme for the adaptive controller to select from
695 
696    Logically collective on TSAdapt
697 
698    Input Arguments:
699 +  adapt - time step adaptivity context, obtained with TSGetAdapt() or TSAdaptCreate()
700 .  name - name of the candidate scheme to add
701 .  order - order of the candidate scheme
702 .  stageorder - stage order of the candidate scheme
703 .  ccfl - stability coefficient relative to explicit Euler, used for CFL constraints
704 .  cost - relative measure of the amount of work required for the candidate scheme
705 -  inuse - indicates that this scheme is the one currently in use, this flag can only be set for one scheme
706 
707    Note:
708    This routine is not available in Fortran.
709 
710    Level: developer
711 
712 .seealso: TSAdaptCandidatesClear(), TSAdaptChoose()
713 @*/
714 PetscErrorCode TSAdaptCandidateAdd(TSAdapt adapt,const char name[],PetscInt order,PetscInt stageorder,PetscReal ccfl,PetscReal cost,PetscBool inuse)
715 {
716   PetscInt c;
717 
718   PetscFunctionBegin;
719   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
720   if (order < 1) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Classical order %D must be a positive integer",order);
721   if (inuse) {
722     if (adapt->candidates.inuse_set) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_WRONGSTATE,"Cannot set the inuse method twice, maybe forgot to call TSAdaptCandidatesClear()");
723     adapt->candidates.inuse_set = PETSC_TRUE;
724   }
725   /* first slot if this is the current scheme, otherwise the next available slot */
726   c = inuse ? 0 : !adapt->candidates.inuse_set + adapt->candidates.n;
727 
728   adapt->candidates.name[c]       = name;
729   adapt->candidates.order[c]      = order;
730   adapt->candidates.stageorder[c] = stageorder;
731   adapt->candidates.ccfl[c]       = ccfl;
732   adapt->candidates.cost[c]       = cost;
733   adapt->candidates.n++;
734   PetscFunctionReturn(0);
735 }
736 
737 /*@C
738    TSAdaptCandidatesGet - Get the list of candidate orders of accuracy and cost
739 
740    Not Collective
741 
742    Input Arguments:
743 .  adapt - time step adaptivity context
744 
745    Output Arguments:
746 +  n - number of candidate schemes, always at least 1
747 .  order - the order of each candidate scheme
748 .  stageorder - the stage order of each candidate scheme
749 .  ccfl - the CFL coefficient of each scheme
750 -  cost - the relative cost of each scheme
751 
752    Level: developer
753 
754    Note:
755    The current scheme is always returned in the first slot
756 
757 .seealso: TSAdaptCandidatesClear(), TSAdaptCandidateAdd(), TSAdaptChoose()
758 @*/
759 PetscErrorCode TSAdaptCandidatesGet(TSAdapt adapt,PetscInt *n,const PetscInt **order,const PetscInt **stageorder,const PetscReal **ccfl,const PetscReal **cost)
760 {
761   PetscFunctionBegin;
762   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
763   if (n) *n = adapt->candidates.n;
764   if (order) *order = adapt->candidates.order;
765   if (stageorder) *stageorder = adapt->candidates.stageorder;
766   if (ccfl) *ccfl = adapt->candidates.ccfl;
767   if (cost) *cost = adapt->candidates.cost;
768   PetscFunctionReturn(0);
769 }
770 
771 /*@C
772    TSAdaptChoose - choose which method and step size to use for the next step
773 
774    Collective on TSAdapt
775 
776    Input Arguments:
777 +  adapt - adaptive contoller
778 -  h - current step size
779 
780    Output Arguments:
781 +  next_sc - optional, scheme to use for the next step
782 .  next_h - step size to use for the next step
783 -  accept - PETSC_TRUE to accept the current step, PETSC_FALSE to repeat the current step with the new step size
784 
785    Note:
786    The input value of parameter accept is retained from the last time step, so it will be PETSC_FALSE if the step is
787    being retried after an initial rejection.
788 
789    Level: developer
790 
791 .seealso: TSAdapt, TSAdaptCandidatesClear(), TSAdaptCandidateAdd()
792 @*/
793 PetscErrorCode TSAdaptChoose(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept)
794 {
795   PetscErrorCode ierr;
796   PetscInt       ncandidates = adapt->candidates.n;
797   PetscInt       scheme = 0;
798   PetscReal      wlte = -1.0;
799   PetscReal      wltea = -1.0;
800   PetscReal      wlter = -1.0;
801 
802   PetscFunctionBegin;
803   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
804   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
805   if (next_sc) PetscValidIntPointer(next_sc,4);
806   PetscValidPointer(next_h,5);
807   PetscValidIntPointer(accept,6);
808   if (next_sc) *next_sc = 0;
809 
810   /* Do not mess with adaptivity while handling events*/
811   if (ts->event && ts->event->status != TSEVENT_NONE) {
812     *next_h = h;
813     *accept = PETSC_TRUE;
814     PetscFunctionReturn(0);
815   }
816 
817   ierr = (*adapt->ops->choose)(adapt,ts,h,&scheme,next_h,accept,&wlte,&wltea,&wlter);CHKERRQ(ierr);
818   if (scheme < 0 || (ncandidates > 0 && scheme >= ncandidates)) SETERRQ2(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Chosen scheme %D not in valid range 0..%D",scheme,ncandidates-1);
819   if (*next_h < 0) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Computed step size %g must be positive",(double)*next_h);
820   if (next_sc) *next_sc = scheme;
821 
822   if (*accept && ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) {
823     /* Increase/reduce step size if end time of next step is close to or overshoots max time */
824     PetscReal t = ts->ptime + ts->time_step, h = *next_h;
825     PetscReal tend = t + h, tmax = ts->max_time, hmax = tmax - t;
826     PetscReal a = (PetscReal)(1.0 + adapt->matchstepfac[0]);
827     PetscReal b = adapt->matchstepfac[1];
828     if (t < tmax && tend > tmax) *next_h = hmax;
829     if (t < tmax && tend < tmax && h*b > hmax) *next_h = hmax/2;
830     if (t < tmax && tend < tmax && h*a > hmax) *next_h = hmax;
831   }
832 
833   if (adapt->monitor) {
834     const char *sc_name = (scheme < ncandidates) ? adapt->candidates.name[scheme] : "";
835     ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
836     if (wlte < 0) {
837       ierr = PetscViewerASCIIPrintf(adapt->monitor,"    TSAdapt %s %s %D:%s step %3D %s t=%-11g+%10.3e dt=%-10.3e\n",((PetscObject)adapt)->type_name,((PetscObject)ts)->type_name,scheme,sc_name,ts->steps,*accept ? "accepted" : "rejected",(double)ts->ptime,(double)h,(double)*next_h);CHKERRQ(ierr);
838     } else {
839       ierr = PetscViewerASCIIPrintf(adapt->monitor,"    TSAdapt %s %s %D:%s step %3D %s t=%-11g+%10.3e dt=%-10.3e wlte=%5.3g  wltea=%5.3g wlter=%5.3g\n",((PetscObject)adapt)->type_name,((PetscObject)ts)->type_name,scheme,sc_name,ts->steps,*accept ? "accepted" : "rejected",(double)ts->ptime,(double)h,(double)*next_h,(double)wlte,(double)wltea,(double)wlter);CHKERRQ(ierr);
840     }
841     ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
842   }
843   PetscFunctionReturn(0);
844 }
845 
846 /*@
847    TSAdaptSetTimeStepIncreaseDelay - The number of timesteps to wait after a decrease in the timestep due to failed solver
848                                      before increasing the time step.
849 
850    Logicially Collective on TSAdapt
851 
852    Input Arguments:
853 +  adapt - adaptive controller context
854 -  cnt - the number of timesteps
855 
856    Options Database Key:
857 .  -ts_adapt_time_step_increase_delay cnt - number of steps to delay the increase
858 
859    Notes: This is to prevent an adaptor from bouncing back and forth between two nearby timesteps. The default is 0.
860           The successful use of this option is problem dependent
861 
862    Developer Note: there is no theory to support this option
863 
864    Level: advanced
865 
866 .seealso:
867 @*/
868 PetscErrorCode TSAdaptSetTimeStepIncreaseDelay(TSAdapt adapt,PetscInt cnt)
869 {
870   PetscFunctionBegin;
871   adapt->timestepjustdecreased_delay = cnt;
872   PetscFunctionReturn(0);
873 }
874 
875 
876 /*@
877    TSAdaptCheckStage - checks whether to accept a stage, (e.g. reject and change time step size if nonlinear solve fails)
878 
879    Collective on TSAdapt
880 
881    Input Arguments:
882 +  adapt - adaptive controller context
883 .  ts - time stepper
884 .  t - Current simulation time
885 -  Y - Current solution vector
886 
887    Output Arguments:
888 .  accept - PETSC_TRUE to accept the stage, PETSC_FALSE to reject
889 
890    Level: developer
891 
892 .seealso:
893 @*/
894 PetscErrorCode TSAdaptCheckStage(TSAdapt adapt,TS ts,PetscReal t,Vec Y,PetscBool *accept)
895 {
896   PetscErrorCode      ierr;
897   SNESConvergedReason snesreason = SNES_CONVERGED_ITERATING;
898 
899   PetscFunctionBegin;
900   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
901   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
902   PetscValidIntPointer(accept,3);
903 
904   if (ts->snes) {ierr = SNESGetConvergedReason(ts->snes,&snesreason);CHKERRQ(ierr);}
905   if (snesreason < 0) {
906     *accept = PETSC_FALSE;
907     if (++ts->num_snes_failures >= ts->max_snes_failures && ts->max_snes_failures > 0) {
908       ts->reason = TS_DIVERGED_NONLINEAR_SOLVE;
909       ierr = PetscInfo2(ts,"Step=%D, nonlinear solve failures %D greater than current TS allowed, stopping solve\n",ts->steps,ts->num_snes_failures);CHKERRQ(ierr);
910       if (adapt->monitor) {
911         ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
912         ierr = PetscViewerASCIIPrintf(adapt->monitor,"    TSAdapt %s step %3D stage rejected t=%-11g+%10.3e, nonlinear solve failures %D greater than current TS allowed\n",((PetscObject)adapt)->type_name,ts->steps,(double)ts->ptime,(double)ts->time_step,ts->num_snes_failures);CHKERRQ(ierr);
913         ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
914       }
915     }
916   } else {
917     *accept = PETSC_TRUE;
918     ierr = TSFunctionDomainError(ts,t,Y,accept);CHKERRQ(ierr);
919     if(*accept && adapt->checkstage) {
920       ierr = (*adapt->checkstage)(adapt,ts,t,Y,accept);CHKERRQ(ierr);
921     }
922   }
923 
924   if(!(*accept) && !ts->reason) {
925     PetscReal dt,new_dt;
926     ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr);
927     new_dt = dt * adapt->scale_solve_failed;
928     ierr = TSSetTimeStep(ts,new_dt);CHKERRQ(ierr);
929     adapt->timestepjustdecreased += adapt->timestepjustdecreased_delay;
930     if (adapt->monitor) {
931       ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
932       ierr = PetscViewerASCIIPrintf(adapt->monitor,"    TSAdapt %s step %3D stage rejected (%s) t=%-11g+%10.3e retrying with dt=%-10.3e\n",((PetscObject)adapt)->type_name,ts->steps,SNESConvergedReasons[snesreason],(double)ts->ptime,(double)dt,(double)new_dt);CHKERRQ(ierr);
933       ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
934     }
935   }
936   PetscFunctionReturn(0);
937 }
938 
939 /*@
940   TSAdaptCreate - create an adaptive controller context for time stepping
941 
942   Collective on MPI_Comm
943 
944   Input Parameter:
945 . comm - The communicator
946 
947   Output Parameter:
948 . adapt - new TSAdapt object
949 
950   Level: developer
951 
952   Notes:
953   TSAdapt creation is handled by TS, so users should not need to call this function.
954 
955 .keywords: TSAdapt, create
956 .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptDestroy()
957 @*/
958 PetscErrorCode  TSAdaptCreate(MPI_Comm comm,TSAdapt *inadapt)
959 {
960   PetscErrorCode ierr;
961   TSAdapt        adapt;
962 
963   PetscFunctionBegin;
964   PetscValidPointer(inadapt,1);
965   *inadapt = NULL;
966   ierr = TSAdaptInitializePackage();CHKERRQ(ierr);
967 
968   ierr = PetscHeaderCreate(adapt,TSADAPT_CLASSID,"TSAdapt","Time stepping adaptivity","TS",comm,TSAdaptDestroy,TSAdaptView);CHKERRQ(ierr);
969 
970   adapt->always_accept      = PETSC_FALSE;
971   adapt->safety             = 0.9;
972   adapt->reject_safety      = 0.5;
973   adapt->clip[0]            = 0.1;
974   adapt->clip[1]            = 10.;
975   adapt->dt_min             = 1e-20;
976   adapt->dt_max             = 1e+20;
977   adapt->scale_solve_failed = 0.25;
978   /* these two safety factors are not public, and they are used only in the TS_EXACTFINALTIME_MATCHSTEP case
979      to prevent from situations were unreasonably small time steps are taken in order to match the final time */
980   adapt->matchstepfac[0]    = 0.01; /* allow 1% step size increase in the last step */
981   adapt->matchstepfac[1]    = 2.0;  /* halve last step if it is greater than what remains divided this factor */
982   adapt->wnormtype          = NORM_2;
983   adapt->timestepjustdecreased_delay = 0;
984 
985   *inadapt = adapt;
986   PetscFunctionReturn(0);
987 }
988