xref: /petsc/src/ts/adapt/interface/tsadapt.c (revision d580f011359fe1d8ed722591c352a429e8371af2)
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_max_ignore","Adaptor ignores (absolute) solution values smaller than this value","",adapt->ignore_max,&adapt->ignore_max,&set);CHKERRQ(ierr);
657   ierr = PetscOptionsBool("-ts_adapt_glee_use_local","GLEE adaptor uses local error estimation for step control","",adapt->glee_use_local,&adapt->glee_use_local,&set);CHKERRQ(ierr);
658 
659   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);
660 
661   ierr = PetscOptionsEnum("-ts_adapt_wnormtype","Type of norm computed for error estimation","",NormTypes,(PetscEnum)adapt->wnormtype,(PetscEnum*)&adapt->wnormtype,NULL);CHKERRQ(ierr);
662   if (adapt->wnormtype != NORM_2 && adapt->wnormtype != NORM_INFINITY) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_SUP,"Only 2-norm and infinite norm supported");
663 
664   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);
665 
666   ierr = PetscOptionsBool("-ts_adapt_monitor","Print choices made by adaptive controller","TSAdaptSetMonitor",adapt->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
667   if (set) {ierr = TSAdaptSetMonitor(adapt,flg);CHKERRQ(ierr);}
668 
669   if (adapt->ops->setfromoptions) {ierr = (*adapt->ops->setfromoptions)(PetscOptionsObject,adapt);CHKERRQ(ierr);}
670   ierr = PetscOptionsTail();CHKERRQ(ierr);
671   PetscFunctionReturn(0);
672 }
673 
674 /*@
675    TSAdaptCandidatesClear - clear any previously set candidate schemes
676 
677    Logically collective on TSAdapt
678 
679    Input Argument:
680 .  adapt - adaptive controller
681 
682    Level: developer
683 
684 .seealso: TSAdapt, TSAdaptCreate(), TSAdaptCandidateAdd(), TSAdaptChoose()
685 @*/
686 PetscErrorCode TSAdaptCandidatesClear(TSAdapt adapt)
687 {
688   PetscErrorCode ierr;
689 
690   PetscFunctionBegin;
691   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
692   ierr = PetscMemzero(&adapt->candidates,sizeof(adapt->candidates));CHKERRQ(ierr);
693   PetscFunctionReturn(0);
694 }
695 
696 /*@C
697    TSAdaptCandidateAdd - add a candidate scheme for the adaptive controller to select from
698 
699    Logically collective on TSAdapt
700 
701    Input Arguments:
702 +  adapt - time step adaptivity context, obtained with TSGetAdapt() or TSAdaptCreate()
703 .  name - name of the candidate scheme to add
704 .  order - order of the candidate scheme
705 .  stageorder - stage order of the candidate scheme
706 .  ccfl - stability coefficient relative to explicit Euler, used for CFL constraints
707 .  cost - relative measure of the amount of work required for the candidate scheme
708 -  inuse - indicates that this scheme is the one currently in use, this flag can only be set for one scheme
709 
710    Note:
711    This routine is not available in Fortran.
712 
713    Level: developer
714 
715 .seealso: TSAdaptCandidatesClear(), TSAdaptChoose()
716 @*/
717 PetscErrorCode TSAdaptCandidateAdd(TSAdapt adapt,const char name[],PetscInt order,PetscInt stageorder,PetscReal ccfl,PetscReal cost,PetscBool inuse)
718 {
719   PetscInt c;
720 
721   PetscFunctionBegin;
722   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
723   if (order < 1) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Classical order %D must be a positive integer",order);
724   if (inuse) {
725     if (adapt->candidates.inuse_set) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_WRONGSTATE,"Cannot set the inuse method twice, maybe forgot to call TSAdaptCandidatesClear()");
726     adapt->candidates.inuse_set = PETSC_TRUE;
727   }
728   /* first slot if this is the current scheme, otherwise the next available slot */
729   c = inuse ? 0 : !adapt->candidates.inuse_set + adapt->candidates.n;
730 
731   adapt->candidates.name[c]       = name;
732   adapt->candidates.order[c]      = order;
733   adapt->candidates.stageorder[c] = stageorder;
734   adapt->candidates.ccfl[c]       = ccfl;
735   adapt->candidates.cost[c]       = cost;
736   adapt->candidates.n++;
737   PetscFunctionReturn(0);
738 }
739 
740 /*@C
741    TSAdaptCandidatesGet - Get the list of candidate orders of accuracy and cost
742 
743    Not Collective
744 
745    Input Arguments:
746 .  adapt - time step adaptivity context
747 
748    Output Arguments:
749 +  n - number of candidate schemes, always at least 1
750 .  order - the order of each candidate scheme
751 .  stageorder - the stage order of each candidate scheme
752 .  ccfl - the CFL coefficient of each scheme
753 -  cost - the relative cost of each scheme
754 
755    Level: developer
756 
757    Note:
758    The current scheme is always returned in the first slot
759 
760 .seealso: TSAdaptCandidatesClear(), TSAdaptCandidateAdd(), TSAdaptChoose()
761 @*/
762 PetscErrorCode TSAdaptCandidatesGet(TSAdapt adapt,PetscInt *n,const PetscInt **order,const PetscInt **stageorder,const PetscReal **ccfl,const PetscReal **cost)
763 {
764   PetscFunctionBegin;
765   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
766   if (n) *n = adapt->candidates.n;
767   if (order) *order = adapt->candidates.order;
768   if (stageorder) *stageorder = adapt->candidates.stageorder;
769   if (ccfl) *ccfl = adapt->candidates.ccfl;
770   if (cost) *cost = adapt->candidates.cost;
771   PetscFunctionReturn(0);
772 }
773 
774 /*@C
775    TSAdaptChoose - choose which method and step size to use for the next step
776 
777    Collective on TSAdapt
778 
779    Input Arguments:
780 +  adapt - adaptive contoller
781 -  h - current step size
782 
783    Output Arguments:
784 +  next_sc - optional, scheme to use for the next step
785 .  next_h - step size to use for the next step
786 -  accept - PETSC_TRUE to accept the current step, PETSC_FALSE to repeat the current step with the new step size
787 
788    Note:
789    The input value of parameter accept is retained from the last time step, so it will be PETSC_FALSE if the step is
790    being retried after an initial rejection.
791 
792    Level: developer
793 
794 .seealso: TSAdapt, TSAdaptCandidatesClear(), TSAdaptCandidateAdd()
795 @*/
796 PetscErrorCode TSAdaptChoose(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept)
797 {
798   PetscErrorCode ierr;
799   PetscInt       ncandidates = adapt->candidates.n;
800   PetscInt       scheme = 0;
801   PetscReal      wlte = -1.0;
802   PetscReal      wltea = -1.0;
803   PetscReal      wlter = -1.0;
804 
805   PetscFunctionBegin;
806   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
807   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
808   if (next_sc) PetscValidIntPointer(next_sc,4);
809   PetscValidPointer(next_h,5);
810   PetscValidIntPointer(accept,6);
811   if (next_sc) *next_sc = 0;
812 
813   /* Do not mess with adaptivity while handling events*/
814   if (ts->event && ts->event->status != TSEVENT_NONE) {
815     *next_h = h;
816     *accept = PETSC_TRUE;
817     PetscFunctionReturn(0);
818   }
819 
820   ierr = (*adapt->ops->choose)(adapt,ts,h,&scheme,next_h,accept,&wlte,&wltea,&wlter);CHKERRQ(ierr);
821   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);
822   if (*next_h < 0) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Computed step size %g must be positive",(double)*next_h);
823   if (next_sc) *next_sc = scheme;
824 
825   if (*accept && ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) {
826     /* Increase/reduce step size if end time of next step is close to or overshoots max time */
827     PetscReal t = ts->ptime + ts->time_step, h = *next_h;
828     PetscReal tend = t + h, tmax = ts->max_time, hmax = tmax - t;
829     PetscReal a = (PetscReal)(1.0 + adapt->matchstepfac[0]);
830     PetscReal b = adapt->matchstepfac[1];
831     if (t < tmax && tend > tmax) *next_h = hmax;
832     if (t < tmax && tend < tmax && h*b > hmax) *next_h = hmax/2;
833     if (t < tmax && tend < tmax && h*a > hmax) *next_h = hmax;
834   }
835 
836   if (adapt->monitor) {
837     const char *sc_name = (scheme < ncandidates) ? adapt->candidates.name[scheme] : "";
838     ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
839     if (wlte < 0) {
840       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);
841     } else {
842       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);
843     }
844     ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
845   }
846   PetscFunctionReturn(0);
847 }
848 
849 /*@
850    TSAdaptSetTimeStepIncreaseDelay - The number of timesteps to wait after a decrease in the timestep due to failed solver
851                                      before increasing the time step.
852 
853    Logicially Collective on TSAdapt
854 
855    Input Arguments:
856 +  adapt - adaptive controller context
857 -  cnt - the number of timesteps
858 
859    Options Database Key:
860 .  -ts_adapt_time_step_increase_delay cnt - number of steps to delay the increase
861 
862    Notes: This is to prevent an adaptor from bouncing back and forth between two nearby timesteps. The default is 0.
863           The successful use of this option is problem dependent
864 
865    Developer Note: there is no theory to support this option
866 
867    Level: advanced
868 
869 .seealso:
870 @*/
871 PetscErrorCode TSAdaptSetTimeStepIncreaseDelay(TSAdapt adapt,PetscInt cnt)
872 {
873   PetscFunctionBegin;
874   adapt->timestepjustdecreased_delay = cnt;
875   PetscFunctionReturn(0);
876 }
877 
878 
879 /*@
880    TSAdaptCheckStage - checks whether to accept a stage, (e.g. reject and change time step size if nonlinear solve fails)
881 
882    Collective on TSAdapt
883 
884    Input Arguments:
885 +  adapt - adaptive controller context
886 .  ts - time stepper
887 .  t - Current simulation time
888 -  Y - Current solution vector
889 
890    Output Arguments:
891 .  accept - PETSC_TRUE to accept the stage, PETSC_FALSE to reject
892 
893    Level: developer
894 
895 .seealso:
896 @*/
897 PetscErrorCode TSAdaptCheckStage(TSAdapt adapt,TS ts,PetscReal t,Vec Y,PetscBool *accept)
898 {
899   PetscErrorCode      ierr;
900   SNESConvergedReason snesreason = SNES_CONVERGED_ITERATING;
901 
902   PetscFunctionBegin;
903   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
904   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
905   PetscValidIntPointer(accept,3);
906 
907   if (ts->snes) {ierr = SNESGetConvergedReason(ts->snes,&snesreason);CHKERRQ(ierr);}
908   if (snesreason < 0) {
909     *accept = PETSC_FALSE;
910     if (++ts->num_snes_failures >= ts->max_snes_failures && ts->max_snes_failures > 0) {
911       ts->reason = TS_DIVERGED_NONLINEAR_SOLVE;
912       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);
913       if (adapt->monitor) {
914         ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
915         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);
916         ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
917       }
918     }
919   } else {
920     *accept = PETSC_TRUE;
921     ierr = TSFunctionDomainError(ts,t,Y,accept);CHKERRQ(ierr);
922     if(*accept && adapt->checkstage) {
923       ierr = (*adapt->checkstage)(adapt,ts,t,Y,accept);CHKERRQ(ierr);
924     }
925   }
926 
927   if(!(*accept) && !ts->reason) {
928     PetscReal dt,new_dt;
929     ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr);
930     new_dt = dt * adapt->scale_solve_failed;
931     ierr = TSSetTimeStep(ts,new_dt);CHKERRQ(ierr);
932     adapt->timestepjustdecreased += adapt->timestepjustdecreased_delay;
933     if (adapt->monitor) {
934       ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
935       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);
936       ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
937     }
938   }
939   PetscFunctionReturn(0);
940 }
941 
942 /*@
943   TSAdaptCreate - create an adaptive controller context for time stepping
944 
945   Collective on MPI_Comm
946 
947   Input Parameter:
948 . comm - The communicator
949 
950   Output Parameter:
951 . adapt - new TSAdapt object
952 
953   Level: developer
954 
955   Notes:
956   TSAdapt creation is handled by TS, so users should not need to call this function.
957 
958 .keywords: TSAdapt, create
959 .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptDestroy()
960 @*/
961 PetscErrorCode  TSAdaptCreate(MPI_Comm comm,TSAdapt *inadapt)
962 {
963   PetscErrorCode ierr;
964   TSAdapt        adapt;
965 
966   PetscFunctionBegin;
967   PetscValidPointer(inadapt,1);
968   *inadapt = NULL;
969   ierr = TSAdaptInitializePackage();CHKERRQ(ierr);
970 
971   ierr = PetscHeaderCreate(adapt,TSADAPT_CLASSID,"TSAdapt","Time stepping adaptivity","TS",comm,TSAdaptDestroy,TSAdaptView);CHKERRQ(ierr);
972 
973   adapt->always_accept      = PETSC_FALSE;
974   adapt->safety             = 0.9;
975   adapt->reject_safety      = 0.5;
976   adapt->clip[0]            = 0.1;
977   adapt->clip[1]            = 10.;
978   adapt->dt_min             = 1e-20;
979   adapt->dt_max             = 1e+20;
980   adapt->ignore_max         = -PETSC_INFINITY;
981   adapt->glee_use_local     = PETSC_TRUE;
982   adapt->scale_solve_failed = 0.25;
983   /* these two safety factors are not public, and they are used only in the TS_EXACTFINALTIME_MATCHSTEP case
984      to prevent from situations were unreasonably small time steps are taken in order to match the final time */
985   adapt->matchstepfac[0]    = 0.01; /* allow 1% step size increase in the last step */
986   adapt->matchstepfac[1]    = 2.0;  /* halve last step if it is greater than what remains divided this factor */
987   adapt->wnormtype          = NORM_2;
988   adapt->timestepjustdecreased_delay = 0;
989 
990   *inadapt = adapt;
991   PetscFunctionReturn(0);
992 }
993