xref: /petsc/src/ts/adapt/interface/tsadapt.c (revision ffeef943c8ee50edff320d8a3135bb0c94853e4c)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I  "petscts.h" I*/
284df9cb4SJed Brown 
31b9b13dfSLisandro Dalcin PetscClassId TSADAPT_CLASSID;
41b9b13dfSLisandro Dalcin 
5140e18c1SBarry Smith static PetscFunctionList TSAdaptList;
684df9cb4SJed Brown static PetscBool         TSAdaptPackageInitialized;
784df9cb4SJed Brown static PetscBool         TSAdaptRegisterAllCalled;
884df9cb4SJed Brown 
98cc058d9SJed Brown PETSC_EXTERN PetscErrorCode TSAdaptCreate_None(TSAdapt);
101566a47fSLisandro Dalcin PETSC_EXTERN PetscErrorCode TSAdaptCreate_Basic(TSAdapt);
11cb7ab186SLisandro Dalcin PETSC_EXTERN PetscErrorCode TSAdaptCreate_DSP(TSAdapt);
128cc058d9SJed Brown PETSC_EXTERN PetscErrorCode TSAdaptCreate_CFL(TSAdapt);
131917a363SLisandro Dalcin PETSC_EXTERN PetscErrorCode TSAdaptCreate_GLEE(TSAdapt);
14d949e4a4SStefano Zampini PETSC_EXTERN PetscErrorCode TSAdaptCreate_History(TSAdapt);
1584df9cb4SJed Brown 
1684df9cb4SJed Brown /*@C
171c84c290SBarry Smith   TSAdaptRegister -  adds a TSAdapt implementation
181c84c290SBarry Smith 
19cc4c1da9SBarry Smith   Not Collective, No Fortran Support
201c84c290SBarry Smith 
211c84c290SBarry Smith   Input Parameters:
222fe279fdSBarry Smith + sname    - name of user-defined adaptivity scheme
232fe279fdSBarry Smith - function - routine to create method context
241c84c290SBarry Smith 
25bcf0153eSBarry Smith   Level: advanced
26bcf0153eSBarry Smith 
271c84c290SBarry Smith   Notes:
28bcf0153eSBarry Smith   `TSAdaptRegister()` may be called multiple times to add several user-defined families.
291c84c290SBarry Smith 
30b43aa488SJacob Faibussowitsch   Example Usage:
311c84c290SBarry Smith .vb
32bdf89e91SBarry Smith    TSAdaptRegister("my_scheme", MySchemeCreate);
331c84c290SBarry Smith .ve
341c84c290SBarry Smith 
351c84c290SBarry Smith   Then, your scheme can be chosen with the procedural interface via
361c84c290SBarry Smith $     TSAdaptSetType(ts, "my_scheme")
371c84c290SBarry Smith   or at runtime via the option
381c84c290SBarry Smith $     -ts_adapt_type my_scheme
3984df9cb4SJed Brown 
401cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdaptRegisterAll()`
4184df9cb4SJed Brown @*/
42d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptRegister(const char sname[], PetscErrorCode (*function)(TSAdapt))
43d71ae5a4SJacob Faibussowitsch {
4484df9cb4SJed Brown   PetscFunctionBegin;
459566063dSJacob Faibussowitsch   PetscCall(TSAdaptInitializePackage());
469566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&TSAdaptList, sname, function));
473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4884df9cb4SJed Brown }
4984df9cb4SJed Brown 
5084df9cb4SJed Brown /*@C
512fe279fdSBarry Smith   TSAdaptRegisterAll - Registers all of the adaptivity schemes in `TSAdapt`
5284df9cb4SJed Brown 
5384df9cb4SJed Brown   Not Collective
5484df9cb4SJed Brown 
5584df9cb4SJed Brown   Level: advanced
5684df9cb4SJed Brown 
571cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdaptRegisterDestroy()`
5884df9cb4SJed Brown @*/
59d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptRegisterAll(void)
60d71ae5a4SJacob Faibussowitsch {
6184df9cb4SJed Brown   PetscFunctionBegin;
623ba16761SJacob Faibussowitsch   if (TSAdaptRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
630f51fdf8SToby Isaac   TSAdaptRegisterAllCalled = PETSC_TRUE;
649566063dSJacob Faibussowitsch   PetscCall(TSAdaptRegister(TSADAPTNONE, TSAdaptCreate_None));
659566063dSJacob Faibussowitsch   PetscCall(TSAdaptRegister(TSADAPTBASIC, TSAdaptCreate_Basic));
669566063dSJacob Faibussowitsch   PetscCall(TSAdaptRegister(TSADAPTDSP, TSAdaptCreate_DSP));
679566063dSJacob Faibussowitsch   PetscCall(TSAdaptRegister(TSADAPTCFL, TSAdaptCreate_CFL));
689566063dSJacob Faibussowitsch   PetscCall(TSAdaptRegister(TSADAPTGLEE, TSAdaptCreate_GLEE));
699566063dSJacob Faibussowitsch   PetscCall(TSAdaptRegister(TSADAPTHISTORY, TSAdaptCreate_History));
703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7184df9cb4SJed Brown }
7284df9cb4SJed Brown 
7384df9cb4SJed Brown /*@C
742fe279fdSBarry Smith   TSAdaptFinalizePackage - This function destroys everything in the `TS` package. It is
752fe279fdSBarry Smith   called from `PetscFinalize()`.
7684df9cb4SJed Brown 
7784df9cb4SJed Brown   Level: developer
7884df9cb4SJed Brown 
791cc06b55SBarry Smith .seealso: [](ch_ts), `PetscFinalize()`
8084df9cb4SJed Brown @*/
81d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptFinalizePackage(void)
82d71ae5a4SJacob Faibussowitsch {
8384df9cb4SJed Brown   PetscFunctionBegin;
849566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListDestroy(&TSAdaptList));
8584df9cb4SJed Brown   TSAdaptPackageInitialized = PETSC_FALSE;
8684df9cb4SJed Brown   TSAdaptRegisterAllCalled  = PETSC_FALSE;
873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8884df9cb4SJed Brown }
8984df9cb4SJed Brown 
9084df9cb4SJed Brown /*@C
912fe279fdSBarry Smith   TSAdaptInitializePackage - This function initializes everything in the `TSAdapt` package. It is
922fe279fdSBarry Smith   called from `TSInitializePackage()`.
9384df9cb4SJed Brown 
9484df9cb4SJed Brown   Level: developer
9584df9cb4SJed Brown 
961cc06b55SBarry Smith .seealso: [](ch_ts), `PetscInitialize()`
9784df9cb4SJed Brown @*/
98d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptInitializePackage(void)
99d71ae5a4SJacob Faibussowitsch {
10084df9cb4SJed Brown   PetscFunctionBegin;
1013ba16761SJacob Faibussowitsch   if (TSAdaptPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
10284df9cb4SJed Brown   TSAdaptPackageInitialized = PETSC_TRUE;
1039566063dSJacob Faibussowitsch   PetscCall(PetscClassIdRegister("TSAdapt", &TSADAPT_CLASSID));
1049566063dSJacob Faibussowitsch   PetscCall(TSAdaptRegisterAll());
1059566063dSJacob Faibussowitsch   PetscCall(PetscRegisterFinalize(TSAdaptFinalizePackage));
1063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10784df9cb4SJed Brown }
10884df9cb4SJed Brown 
109cc4c1da9SBarry Smith /*@
110bcf0153eSBarry Smith   TSAdaptSetType - sets the approach used for the error adapter
1117eef6055SBarry Smith 
11220f4b53cSBarry Smith   Logicially Collective
1137eef6055SBarry Smith 
114d8d19677SJose E. Roman   Input Parameters:
11558b119d1SBarry Smith + adapt - the `TS` adapter, most likely obtained with `TSGetAdapt()`
116bcf0153eSBarry Smith - type  - one of the `TSAdaptType`
1177eef6055SBarry Smith 
118bcf0153eSBarry Smith   Options Database Key:
119ec18b7bcSLisandro Dalcin . -ts_adapt_type <basic or dsp or none> - to set the adapter type
1207eef6055SBarry Smith 
1217eef6055SBarry Smith   Level: intermediate
1227eef6055SBarry Smith 
123b43aa488SJacob Faibussowitsch .seealso: [](ch_ts), `TSGetAdapt()`, `TSAdaptDestroy()`, `TSAdaptType`, `TSAdaptGetType()`
1247eef6055SBarry Smith @*/
125d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetType(TSAdapt adapt, TSAdaptType type)
126d71ae5a4SJacob Faibussowitsch {
127ef749922SLisandro Dalcin   PetscBool match;
1285f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(TSAdapt);
12984df9cb4SJed Brown 
13084df9cb4SJed Brown   PetscFunctionBegin;
1314782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
1324f572ea9SToby Isaac   PetscAssertPointer(type, 2);
1339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)adapt, type, &match));
1343ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
1359566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(TSAdaptList, type, &r));
1366adde796SStefano Zampini   PetscCheck(r, PetscObjectComm((PetscObject)adapt), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown TSAdapt type \"%s\" given", type);
137dbbe0bcdSBarry Smith   PetscTryTypeMethod(adapt, destroy);
1389566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(adapt->ops, sizeof(struct _TSAdaptOps)));
1399566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)adapt, type));
1409566063dSJacob Faibussowitsch   PetscCall((*r)(adapt));
1413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14284df9cb4SJed Brown }
14384df9cb4SJed Brown 
144cc4c1da9SBarry Smith /*@
145a1cb98faSBarry Smith   TSAdaptGetType - gets the `TS` adapter method type (as a string).
146d0288e4fSLisandro Dalcin 
147d0288e4fSLisandro Dalcin   Not Collective
148d0288e4fSLisandro Dalcin 
149d0288e4fSLisandro Dalcin   Input Parameter:
150a1cb98faSBarry Smith . adapt - The `TS` adapter, most likely obtained with `TSGetAdapt()`
151d0288e4fSLisandro Dalcin 
152d0288e4fSLisandro Dalcin   Output Parameter:
153a1cb98faSBarry Smith . type - The name of `TS` adapter method
154d0288e4fSLisandro Dalcin 
155d0288e4fSLisandro Dalcin   Level: intermediate
156d0288e4fSLisandro Dalcin 
157a1cb98faSBarry Smith .seealso: `TSAdapt`, `TSAdaptType`, `TSAdaptSetType()`
158d0288e4fSLisandro Dalcin @*/
159d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptGetType(TSAdapt adapt, TSAdaptType *type)
160d71ae5a4SJacob Faibussowitsch {
161d0288e4fSLisandro Dalcin   PetscFunctionBegin;
162d0288e4fSLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
1634f572ea9SToby Isaac   PetscAssertPointer(type, 2);
164d0288e4fSLisandro Dalcin   *type = ((PetscObject)adapt)->type_name;
1653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
166d0288e4fSLisandro Dalcin }
167d0288e4fSLisandro Dalcin 
168d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetOptionsPrefix(TSAdapt adapt, const char prefix[])
169d71ae5a4SJacob Faibussowitsch {
17084df9cb4SJed Brown   PetscFunctionBegin;
1714782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
1729566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)adapt, prefix));
1733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17484df9cb4SJed Brown }
17584df9cb4SJed Brown 
176*ffeef943SBarry Smith /*@
1772fe279fdSBarry Smith   TSAdaptLoad - Loads a TSAdapt that has been stored in binary with `TSAdaptView()`.
178ad6bc421SBarry Smith 
179c3339decSBarry Smith   Collective
180ad6bc421SBarry Smith 
181ad6bc421SBarry Smith   Input Parameters:
182b43aa488SJacob Faibussowitsch + adapt  - the newly loaded `TSAdapt`, this needs to have been created with `TSAdaptCreate()` or
183bcf0153eSBarry Smith            some related function before a call to `TSAdaptLoad()`.
184bcf0153eSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or
185bcf0153eSBarry Smith            HDF5 file viewer, obtained from `PetscViewerHDF5Open()`
186ad6bc421SBarry Smith 
187ad6bc421SBarry Smith   Level: intermediate
188ad6bc421SBarry Smith 
189bcf0153eSBarry Smith   Note:
190bcf0153eSBarry Smith   The type is determined by the data in the file, any type set into the `TSAdapt` before this call is ignored.
191ad6bc421SBarry Smith 
1921cc06b55SBarry Smith .seealso: [](ch_ts), `PetscViewerBinaryOpen()`, `TSAdaptView()`, `MatLoad()`, `VecLoad()`, `TSAdapt`
193ad6bc421SBarry Smith @*/
194d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptLoad(TSAdapt adapt, PetscViewer viewer)
195d71ae5a4SJacob Faibussowitsch {
196ad6bc421SBarry Smith   PetscBool isbinary;
197ad6bc421SBarry Smith   char      type[256];
198ad6bc421SBarry Smith 
199ad6bc421SBarry Smith   PetscFunctionBegin;
2004782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
201ad6bc421SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
2029566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
2033c633725SBarry Smith   PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");
204ad6bc421SBarry Smith 
2059566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR));
2069566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetType(adapt, type));
207dbbe0bcdSBarry Smith   PetscTryTypeMethod(adapt, load, viewer);
2083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
209ad6bc421SBarry Smith }
210ad6bc421SBarry Smith 
211d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptView(TSAdapt adapt, PetscViewer viewer)
212d71ae5a4SJacob Faibussowitsch {
2131c167fc2SEmil Constantinescu   PetscBool iascii, isbinary, isnone, isglee;
21484df9cb4SJed Brown 
21584df9cb4SJed Brown   PetscFunctionBegin;
2164782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
2179566063dSJacob Faibussowitsch   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)adapt), &viewer));
2184782b174SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
2194782b174SLisandro Dalcin   PetscCheckSameComm(adapt, 1, viewer, 2);
2209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
2219566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
22284df9cb4SJed Brown   if (iascii) {
2239566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)adapt, viewer));
2249566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)adapt, TSADAPTNONE, &isnone));
2259566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)adapt, TSADAPTGLEE, &isglee));
2261917a363SLisandro Dalcin     if (!isnone) {
2279566063dSJacob Faibussowitsch       if (adapt->always_accept) PetscCall(PetscViewerASCIIPrintf(viewer, "  always accepting steps\n"));
2289566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  safety factor %g\n", (double)adapt->safety));
2299566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  extra safety factor after step rejection %g\n", (double)adapt->reject_safety));
2309566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  clip fastest increase %g\n", (double)adapt->clip[1]));
2319566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  clip fastest decrease %g\n", (double)adapt->clip[0]));
2329566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum allowed timestep %g\n", (double)adapt->dt_max));
2339566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  minimum allowed timestep %g\n", (double)adapt->dt_min));
2349566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum solution absolute value to be ignored %g\n", (double)adapt->ignore_max));
2351c167fc2SEmil Constantinescu     }
2361c167fc2SEmil Constantinescu     if (isglee) {
2371c167fc2SEmil Constantinescu       if (adapt->glee_use_local) {
2389566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  GLEE uses local error control\n"));
2391c167fc2SEmil Constantinescu       } else {
2409566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  GLEE uses global error control\n"));
2411c167fc2SEmil Constantinescu       }
2421917a363SLisandro Dalcin     }
2439566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
244dbbe0bcdSBarry Smith     PetscTryTypeMethod(adapt, view, viewer);
2459566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
246ad6bc421SBarry Smith   } else if (isbinary) {
247ad6bc421SBarry Smith     char type[256];
248ad6bc421SBarry Smith 
249ad6bc421SBarry Smith     /* need to save FILE_CLASS_ID for adapt class */
2509566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(type, ((PetscObject)adapt)->type_name, 256));
2519566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, type, 256, PETSC_CHAR));
252dbbe0bcdSBarry Smith   } else PetscTryTypeMethod(adapt, view, viewer);
2533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25484df9cb4SJed Brown }
25584df9cb4SJed Brown 
256099af0a3SLisandro Dalcin /*@
257bcf0153eSBarry Smith   TSAdaptReset - Resets a `TSAdapt` context to its defaults
258099af0a3SLisandro Dalcin 
259c3339decSBarry Smith   Collective
260099af0a3SLisandro Dalcin 
261099af0a3SLisandro Dalcin   Input Parameter:
262bcf0153eSBarry Smith . adapt - the `TSAdapt` context obtained from `TSGetAdapt()` or `TSAdaptCreate()`
263099af0a3SLisandro Dalcin 
264099af0a3SLisandro Dalcin   Level: developer
265099af0a3SLisandro Dalcin 
2661cc06b55SBarry Smith .seealso: [](ch_ts), `TSGetAdapt()`, `TSAdapt`, `TSAdaptCreate()`, `TSAdaptDestroy()`
267099af0a3SLisandro Dalcin @*/
268d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptReset(TSAdapt adapt)
269d71ae5a4SJacob Faibussowitsch {
270099af0a3SLisandro Dalcin   PetscFunctionBegin;
271099af0a3SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
272dbbe0bcdSBarry Smith   PetscTryTypeMethod(adapt, reset);
2733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
274099af0a3SLisandro Dalcin }
275099af0a3SLisandro Dalcin 
276d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptDestroy(TSAdapt *adapt)
277d71ae5a4SJacob Faibussowitsch {
27884df9cb4SJed Brown   PetscFunctionBegin;
2793ba16761SJacob Faibussowitsch   if (!*adapt) PetscFunctionReturn(PETSC_SUCCESS);
28084df9cb4SJed Brown   PetscValidHeaderSpecific(*adapt, TSADAPT_CLASSID, 1);
281f4f49eeaSPierre Jolivet   if (--((PetscObject)*adapt)->refct > 0) {
2829371c9d4SSatish Balay     *adapt = NULL;
2833ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
2849371c9d4SSatish Balay   }
285099af0a3SLisandro Dalcin 
2869566063dSJacob Faibussowitsch   PetscCall(TSAdaptReset(*adapt));
287099af0a3SLisandro Dalcin 
288f4f49eeaSPierre Jolivet   PetscTryTypeMethod(*adapt, destroy);
2899566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*adapt)->monitor));
2909566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(adapt));
2913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29284df9cb4SJed Brown }
29384df9cb4SJed Brown 
2941c3436cfSJed Brown /*@
2951c3436cfSJed Brown   TSAdaptSetMonitor - Monitor the choices made by the adaptive controller
2961c3436cfSJed Brown 
297c3339decSBarry Smith   Collective
2981c3436cfSJed Brown 
2994165533cSJose E. Roman   Input Parameters:
3001c3436cfSJed Brown + adapt - adaptive controller context
301bcf0153eSBarry Smith - flg   - `PETSC_TRUE` to active a monitor, `PETSC_FALSE` to disable
3021c3436cfSJed Brown 
303bcf0153eSBarry Smith   Options Database Key:
304ec18b7bcSLisandro Dalcin . -ts_adapt_monitor - to turn on monitoring
305bf997491SLisandro Dalcin 
3061c3436cfSJed Brown   Level: intermediate
3071c3436cfSJed Brown 
3081cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSGetAdapt()`, `TSAdaptChoose()`
3091c3436cfSJed Brown @*/
310d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetMonitor(TSAdapt adapt, PetscBool flg)
311d71ae5a4SJacob Faibussowitsch {
3121c3436cfSJed Brown   PetscFunctionBegin;
3134782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
3144782b174SLisandro Dalcin   PetscValidLogicalCollectiveBool(adapt, flg, 2);
3151c3436cfSJed Brown   if (flg) {
3169566063dSJacob Faibussowitsch     if (!adapt->monitor) PetscCall(PetscViewerASCIIOpen(PetscObjectComm((PetscObject)adapt), "stdout", &adapt->monitor));
3171c3436cfSJed Brown   } else {
3189566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&adapt->monitor));
3191c3436cfSJed Brown   }
3203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3211c3436cfSJed Brown }
3221c3436cfSJed Brown 
3230873808bSJed Brown /*@C
324bf997491SLisandro Dalcin   TSAdaptSetCheckStage - Set a callback to check convergence for a stage
3250873808bSJed Brown 
3262fe279fdSBarry Smith   Logically Collective
3270873808bSJed Brown 
3284165533cSJose E. Roman   Input Parameters:
3290873808bSJed Brown + adapt - adaptive controller context
3300873808bSJed Brown - func  - stage check function
3310873808bSJed Brown 
332b43aa488SJacob Faibussowitsch   Calling sequence:
3330873808bSJed Brown + adapt  - adaptive controller context
3340873808bSJed Brown . ts     - time stepping context
33514d0ab18SJacob Faibussowitsch . t      - current time
33614d0ab18SJacob Faibussowitsch . Y      - current solution vector
3370873808bSJed Brown - accept - pending choice of whether to accept, can be modified by this routine
3380873808bSJed Brown 
3390873808bSJed Brown   Level: advanced
3400873808bSJed Brown 
3411cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSGetAdapt()`, `TSAdaptChoose()`
3420873808bSJed Brown @*/
34314d0ab18SJacob Faibussowitsch PetscErrorCode TSAdaptSetCheckStage(TSAdapt adapt, PetscErrorCode (*func)(TSAdapt adapt, TS ts, PetscReal t, Vec Y, PetscBool *accept))
344d71ae5a4SJacob Faibussowitsch {
3450873808bSJed Brown   PetscFunctionBegin;
3460873808bSJed Brown   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
34768ae941aSLisandro Dalcin   adapt->checkstage = func;
3483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3490873808bSJed Brown }
3500873808bSJed Brown 
3511c3436cfSJed Brown /*@
352bf997491SLisandro Dalcin   TSAdaptSetAlwaysAccept - Set whether to always accept steps regardless of
353bf997491SLisandro Dalcin   any error or stability condition not meeting the prescribed goal.
354bf997491SLisandro Dalcin 
3552fe279fdSBarry Smith   Logically Collective
356bf997491SLisandro Dalcin 
3574165533cSJose E. Roman   Input Parameters:
358bcf0153eSBarry Smith + adapt - time step adaptivity context, usually gotten with `TSGetAdapt()`
359bf997491SLisandro Dalcin - flag  - whether to always accept steps
360bf997491SLisandro Dalcin 
361bcf0153eSBarry Smith   Options Database Key:
362ec18b7bcSLisandro Dalcin . -ts_adapt_always_accept - to always accept steps
363bf997491SLisandro Dalcin 
364bf997491SLisandro Dalcin   Level: intermediate
365bf997491SLisandro Dalcin 
3661cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSGetAdapt()`, `TSAdaptChoose()`
367bf997491SLisandro Dalcin @*/
368d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetAlwaysAccept(TSAdapt adapt, PetscBool flag)
369d71ae5a4SJacob Faibussowitsch {
370bf997491SLisandro Dalcin   PetscFunctionBegin;
371bf997491SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
372bf997491SLisandro Dalcin   PetscValidLogicalCollectiveBool(adapt, flag, 2);
373bf997491SLisandro Dalcin   adapt->always_accept = flag;
3743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
375bf997491SLisandro Dalcin }
376bf997491SLisandro Dalcin 
377bf997491SLisandro Dalcin /*@
378bcf0153eSBarry Smith   TSAdaptSetSafety - Set safety factors for time step adaptor
3791c3436cfSJed Brown 
3802fe279fdSBarry Smith   Logically Collective
3811917a363SLisandro Dalcin 
3824165533cSJose E. Roman   Input Parameters:
3831917a363SLisandro Dalcin + adapt         - adaptive controller context
3841917a363SLisandro Dalcin . safety        - safety factor relative to target error/stability goal
385ec18b7bcSLisandro Dalcin - reject_safety - extra safety factor to apply if the last step was rejected
3861917a363SLisandro Dalcin 
3871917a363SLisandro Dalcin   Options Database Keys:
388ec18b7bcSLisandro Dalcin + -ts_adapt_safety <safety>               - to set safety factor
389ec18b7bcSLisandro Dalcin - -ts_adapt_reject_safety <reject_safety> - to set reject safety factor
3901917a363SLisandro Dalcin 
3911917a363SLisandro Dalcin   Level: intermediate
3921917a363SLisandro Dalcin 
3931cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptGetSafety()`, `TSAdaptChoose()`
3941917a363SLisandro Dalcin @*/
395d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetSafety(TSAdapt adapt, PetscReal safety, PetscReal reject_safety)
396d71ae5a4SJacob Faibussowitsch {
3971917a363SLisandro Dalcin   PetscFunctionBegin;
3981917a363SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
3991917a363SLisandro Dalcin   PetscValidLogicalCollectiveReal(adapt, safety, 2);
4001917a363SLisandro Dalcin   PetscValidLogicalCollectiveReal(adapt, reject_safety, 3);
40113bcc0bdSJacob Faibussowitsch   PetscCheck(safety == (PetscReal)PETSC_DEFAULT || safety >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Safety factor %g must be non negative", (double)safety);
40213bcc0bdSJacob Faibussowitsch   PetscCheck(safety == (PetscReal)PETSC_DEFAULT || safety <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Safety factor %g must be less than one", (double)safety);
40313bcc0bdSJacob Faibussowitsch   PetscCheck(reject_safety == (PetscReal)PETSC_DEFAULT || reject_safety >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Reject safety factor %g must be non negative", (double)reject_safety);
40413bcc0bdSJacob Faibussowitsch   PetscCheck(reject_safety == (PetscReal)PETSC_DEFAULT || reject_safety <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Reject safety factor %g must be less than one", (double)reject_safety);
40513bcc0bdSJacob Faibussowitsch   if (safety != (PetscReal)PETSC_DEFAULT) adapt->safety = safety;
40613bcc0bdSJacob Faibussowitsch   if (reject_safety != (PetscReal)PETSC_DEFAULT) adapt->reject_safety = reject_safety;
4073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4081917a363SLisandro Dalcin }
4091917a363SLisandro Dalcin 
4101917a363SLisandro Dalcin /*@
411bcf0153eSBarry Smith   TSAdaptGetSafety - Get safety factors for time step adapter
4121917a363SLisandro Dalcin 
4131917a363SLisandro Dalcin   Not Collective
4141917a363SLisandro Dalcin 
4154165533cSJose E. Roman   Input Parameter:
4161917a363SLisandro Dalcin . adapt - adaptive controller context
4171917a363SLisandro Dalcin 
4184165533cSJose E. Roman   Output Parameters:
419b43aa488SJacob Faibussowitsch + safety        - safety factor relative to target error/stability goal
420b43aa488SJacob Faibussowitsch - reject_safety - extra safety factor to apply if the last step was rejected
4211917a363SLisandro Dalcin 
4221917a363SLisandro Dalcin   Level: intermediate
4231917a363SLisandro Dalcin 
4241cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptSetSafety()`, `TSAdaptChoose()`
4251917a363SLisandro Dalcin @*/
426d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptGetSafety(TSAdapt adapt, PetscReal *safety, PetscReal *reject_safety)
427d71ae5a4SJacob Faibussowitsch {
4281917a363SLisandro Dalcin   PetscFunctionBegin;
4291917a363SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
4304f572ea9SToby Isaac   if (safety) PetscAssertPointer(safety, 2);
4314f572ea9SToby Isaac   if (reject_safety) PetscAssertPointer(reject_safety, 3);
4321917a363SLisandro Dalcin   if (safety) *safety = adapt->safety;
4331917a363SLisandro Dalcin   if (reject_safety) *reject_safety = adapt->reject_safety;
4343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4351917a363SLisandro Dalcin }
4361917a363SLisandro Dalcin 
4371917a363SLisandro Dalcin /*@
438bcf0153eSBarry Smith   TSAdaptSetMaxIgnore - Set error estimation threshold. Solution components below this threshold value will not be considered when computing error norms
439bcf0153eSBarry Smith   for time step adaptivity (in absolute value). A negative value (default) of the threshold leads to considering all solution components.
44076cddca1SEmil Constantinescu 
4412fe279fdSBarry Smith   Logically Collective
44276cddca1SEmil Constantinescu 
4434165533cSJose E. Roman   Input Parameters:
44476cddca1SEmil Constantinescu + adapt      - adaptive controller context
44576cddca1SEmil Constantinescu - max_ignore - threshold for solution components that are ignored during error estimation
44676cddca1SEmil Constantinescu 
447bcf0153eSBarry Smith   Options Database Key:
44876cddca1SEmil Constantinescu . -ts_adapt_max_ignore <max_ignore> - to set the threshold
44976cddca1SEmil Constantinescu 
45076cddca1SEmil Constantinescu   Level: intermediate
45176cddca1SEmil Constantinescu 
4521cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptGetMaxIgnore()`, `TSAdaptChoose()`
45376cddca1SEmil Constantinescu @*/
454d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetMaxIgnore(TSAdapt adapt, PetscReal max_ignore)
455d71ae5a4SJacob Faibussowitsch {
45676cddca1SEmil Constantinescu   PetscFunctionBegin;
45776cddca1SEmil Constantinescu   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
45876cddca1SEmil Constantinescu   PetscValidLogicalCollectiveReal(adapt, max_ignore, 2);
45976cddca1SEmil Constantinescu   adapt->ignore_max = max_ignore;
4603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
46176cddca1SEmil Constantinescu }
46276cddca1SEmil Constantinescu 
46376cddca1SEmil Constantinescu /*@
464bcf0153eSBarry Smith   TSAdaptGetMaxIgnore - Get error estimation threshold. Solution components below this threshold value will not be considered when computing error norms
465bcf0153eSBarry Smith   for time step adaptivity (in absolute value).
46676cddca1SEmil Constantinescu 
46776cddca1SEmil Constantinescu   Not Collective
46876cddca1SEmil Constantinescu 
4694165533cSJose E. Roman   Input Parameter:
47076cddca1SEmil Constantinescu . adapt - adaptive controller context
47176cddca1SEmil Constantinescu 
4724165533cSJose E. Roman   Output Parameter:
47376cddca1SEmil Constantinescu . max_ignore - threshold for solution components that are ignored during error estimation
47476cddca1SEmil Constantinescu 
47576cddca1SEmil Constantinescu   Level: intermediate
47676cddca1SEmil Constantinescu 
4771cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptSetMaxIgnore()`, `TSAdaptChoose()`
47876cddca1SEmil Constantinescu @*/
479d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptGetMaxIgnore(TSAdapt adapt, PetscReal *max_ignore)
480d71ae5a4SJacob Faibussowitsch {
48176cddca1SEmil Constantinescu   PetscFunctionBegin;
48276cddca1SEmil Constantinescu   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
4834f572ea9SToby Isaac   PetscAssertPointer(max_ignore, 2);
48476cddca1SEmil Constantinescu   *max_ignore = adapt->ignore_max;
4853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
48676cddca1SEmil Constantinescu }
48776cddca1SEmil Constantinescu 
48876cddca1SEmil Constantinescu /*@
489bcf0153eSBarry Smith   TSAdaptSetClip - Sets the admissible decrease/increase factor in step size in the time step adapter
4901917a363SLisandro Dalcin 
491c3339decSBarry Smith   Logically collective
4921917a363SLisandro Dalcin 
4934165533cSJose E. Roman   Input Parameters:
4941917a363SLisandro Dalcin + adapt - adaptive controller context
4951917a363SLisandro Dalcin . low   - admissible decrease factor
496ec18b7bcSLisandro Dalcin - high  - admissible increase factor
4971917a363SLisandro Dalcin 
498bcf0153eSBarry Smith   Options Database Key:
499ec18b7bcSLisandro Dalcin . -ts_adapt_clip <low>,<high> - to set admissible time step decrease and increase factors
5001917a363SLisandro Dalcin 
5011917a363SLisandro Dalcin   Level: intermediate
5021917a363SLisandro Dalcin 
5031cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptChoose()`, `TSAdaptGetClip()`, `TSAdaptSetScaleSolveFailed()`
5041917a363SLisandro Dalcin @*/
505d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetClip(TSAdapt adapt, PetscReal low, PetscReal high)
506d71ae5a4SJacob Faibussowitsch {
5071917a363SLisandro Dalcin   PetscFunctionBegin;
5081917a363SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
5091917a363SLisandro Dalcin   PetscValidLogicalCollectiveReal(adapt, low, 2);
5101917a363SLisandro Dalcin   PetscValidLogicalCollectiveReal(adapt, high, 3);
51113bcc0bdSJacob Faibussowitsch   PetscCheck(low == (PetscReal)PETSC_DEFAULT || low >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Decrease factor %g must be non negative", (double)low);
51213bcc0bdSJacob Faibussowitsch   PetscCheck(low == (PetscReal)PETSC_DEFAULT || low <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Decrease factor %g must be less than one", (double)low);
51313bcc0bdSJacob Faibussowitsch   PetscCheck(high == (PetscReal)PETSC_DEFAULT || high >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Increase factor %g must be greater than one", (double)high);
51413bcc0bdSJacob Faibussowitsch   if (low != (PetscReal)PETSC_DEFAULT) adapt->clip[0] = low;
51513bcc0bdSJacob Faibussowitsch   if (high != (PetscReal)PETSC_DEFAULT) adapt->clip[1] = high;
5163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5171917a363SLisandro Dalcin }
5181917a363SLisandro Dalcin 
5191917a363SLisandro Dalcin /*@
520bcf0153eSBarry Smith   TSAdaptGetClip - Gets the admissible decrease/increase factor in step size in the time step adapter
5211917a363SLisandro Dalcin 
5221917a363SLisandro Dalcin   Not Collective
5231917a363SLisandro Dalcin 
5244165533cSJose E. Roman   Input Parameter:
5251917a363SLisandro Dalcin . adapt - adaptive controller context
5261917a363SLisandro Dalcin 
5274165533cSJose E. Roman   Output Parameters:
5281917a363SLisandro Dalcin + low  - optional, admissible decrease factor
5291917a363SLisandro Dalcin - high - optional, admissible increase factor
5301917a363SLisandro Dalcin 
5311917a363SLisandro Dalcin   Level: intermediate
5321917a363SLisandro Dalcin 
5331cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptChoose()`, `TSAdaptSetClip()`, `TSAdaptSetScaleSolveFailed()`
5341917a363SLisandro Dalcin @*/
535d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptGetClip(TSAdapt adapt, PetscReal *low, PetscReal *high)
536d71ae5a4SJacob Faibussowitsch {
5371917a363SLisandro Dalcin   PetscFunctionBegin;
5381917a363SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
5394f572ea9SToby Isaac   if (low) PetscAssertPointer(low, 2);
5404f572ea9SToby Isaac   if (high) PetscAssertPointer(high, 3);
5411917a363SLisandro Dalcin   if (low) *low = adapt->clip[0];
5421917a363SLisandro Dalcin   if (high) *high = adapt->clip[1];
5433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5441917a363SLisandro Dalcin }
5451917a363SLisandro Dalcin 
5461917a363SLisandro Dalcin /*@
547bcf0153eSBarry Smith   TSAdaptSetScaleSolveFailed - Scale step size by this factor if solve fails
54862c23b28SMark 
54920f4b53cSBarry Smith   Logically Collective
55062c23b28SMark 
5514165533cSJose E. Roman   Input Parameters:
55262c23b28SMark + adapt - adaptive controller context
553ee300463SSatish Balay - scale - scale
55462c23b28SMark 
555bcf0153eSBarry Smith   Options Database Key:
55662c23b28SMark . -ts_adapt_scale_solve_failed <scale> - to set scale step by this factor if solve fails
55762c23b28SMark 
55862c23b28SMark   Level: intermediate
55962c23b28SMark 
5601cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptChoose()`, `TSAdaptGetScaleSolveFailed()`, `TSAdaptGetClip()`
56162c23b28SMark @*/
562d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetScaleSolveFailed(TSAdapt adapt, PetscReal scale)
563d71ae5a4SJacob Faibussowitsch {
56462c23b28SMark   PetscFunctionBegin;
56562c23b28SMark   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
56662c23b28SMark   PetscValidLogicalCollectiveReal(adapt, scale, 2);
56713bcc0bdSJacob Faibussowitsch   PetscCheck(scale == (PetscReal)PETSC_DEFAULT || scale > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Scale factor %g must be positive", (double)scale);
56813bcc0bdSJacob Faibussowitsch   PetscCheck(scale == (PetscReal)PETSC_DEFAULT || scale <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Scale factor %g must be less than one", (double)scale);
56913bcc0bdSJacob Faibussowitsch   if (scale != (PetscReal)PETSC_DEFAULT) adapt->scale_solve_failed = scale;
5703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
57162c23b28SMark }
57262c23b28SMark 
57362c23b28SMark /*@
57462c23b28SMark   TSAdaptGetScaleSolveFailed - Gets the admissible decrease/increase factor in step size
57562c23b28SMark 
57662c23b28SMark   Not Collective
57762c23b28SMark 
5784165533cSJose E. Roman   Input Parameter:
57962c23b28SMark . adapt - adaptive controller context
58062c23b28SMark 
5814165533cSJose E. Roman   Output Parameter:
582ee300463SSatish Balay . scale - scale factor
58362c23b28SMark 
58462c23b28SMark   Level: intermediate
58562c23b28SMark 
5861cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptChoose()`, `TSAdaptSetScaleSolveFailed()`, `TSAdaptSetClip()`
58762c23b28SMark @*/
588d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptGetScaleSolveFailed(TSAdapt adapt, PetscReal *scale)
589d71ae5a4SJacob Faibussowitsch {
59062c23b28SMark   PetscFunctionBegin;
59162c23b28SMark   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
5924f572ea9SToby Isaac   if (scale) PetscAssertPointer(scale, 2);
59362c23b28SMark   if (scale) *scale = adapt->scale_solve_failed;
5943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
59562c23b28SMark }
59662c23b28SMark 
59762c23b28SMark /*@
598bcf0153eSBarry Smith   TSAdaptSetStepLimits - Set the minimum and maximum step sizes to be considered by the time step controller
5991917a363SLisandro Dalcin 
60020f4b53cSBarry Smith   Logically Collective
6011c3436cfSJed Brown 
6024165533cSJose E. Roman   Input Parameters:
603bcf0153eSBarry Smith + adapt - time step adaptivity context, usually gotten with `TSGetAdapt()`
6041c3436cfSJed Brown . hmin  - minimum time step
6051c3436cfSJed Brown - hmax  - maximum time step
6061c3436cfSJed Brown 
6071c3436cfSJed Brown   Options Database Keys:
608ec18b7bcSLisandro Dalcin + -ts_adapt_dt_min <min> - to set minimum time step
609ec18b7bcSLisandro Dalcin - -ts_adapt_dt_max <max> - to set maximum time step
6101c3436cfSJed Brown 
6111c3436cfSJed Brown   Level: intermediate
6121c3436cfSJed Brown 
6131cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptGetStepLimits()`, `TSAdaptChoose()`
6141c3436cfSJed Brown @*/
615d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetStepLimits(TSAdapt adapt, PetscReal hmin, PetscReal hmax)
616d71ae5a4SJacob Faibussowitsch {
6171c3436cfSJed Brown   PetscFunctionBegin;
6184782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
619b1f5bccaSLisandro Dalcin   PetscValidLogicalCollectiveReal(adapt, hmin, 2);
620b1f5bccaSLisandro Dalcin   PetscValidLogicalCollectiveReal(adapt, hmax, 3);
62113bcc0bdSJacob Faibussowitsch   PetscCheck(hmin == (PetscReal)PETSC_DEFAULT || hmin >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Minimum time step %g must be non negative", (double)hmin);
62213bcc0bdSJacob Faibussowitsch   PetscCheck(hmax == (PetscReal)PETSC_DEFAULT || hmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Minimum time step %g must be non negative", (double)hmax);
62313bcc0bdSJacob Faibussowitsch   if (hmin != (PetscReal)PETSC_DEFAULT) adapt->dt_min = hmin;
62413bcc0bdSJacob Faibussowitsch   if (hmax != (PetscReal)PETSC_DEFAULT) adapt->dt_max = hmax;
625b1f5bccaSLisandro Dalcin   hmin = adapt->dt_min;
626b1f5bccaSLisandro Dalcin   hmax = adapt->dt_max;
6273c633725SBarry Smith   PetscCheck(hmax > hmin, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Maximum time step %g must greater than minimum time step %g", (double)hmax, (double)hmin);
6283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6291917a363SLisandro Dalcin }
6301917a363SLisandro Dalcin 
6311917a363SLisandro Dalcin /*@
632bcf0153eSBarry Smith   TSAdaptGetStepLimits - Get the minimum and maximum step sizes to be considered by the time step controller
6331917a363SLisandro Dalcin 
6341917a363SLisandro Dalcin   Not Collective
6351917a363SLisandro Dalcin 
6364165533cSJose E. Roman   Input Parameter:
637bcf0153eSBarry Smith . adapt - time step adaptivity context, usually gotten with `TSGetAdapt()`
6381917a363SLisandro Dalcin 
6394165533cSJose E. Roman   Output Parameters:
6401917a363SLisandro Dalcin + hmin - minimum time step
6411917a363SLisandro Dalcin - hmax - maximum time step
6421917a363SLisandro Dalcin 
6431917a363SLisandro Dalcin   Level: intermediate
6441917a363SLisandro Dalcin 
6451cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptSetStepLimits()`, `TSAdaptChoose()`
6461917a363SLisandro Dalcin @*/
647d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptGetStepLimits(TSAdapt adapt, PetscReal *hmin, PetscReal *hmax)
648d71ae5a4SJacob Faibussowitsch {
6491917a363SLisandro Dalcin   PetscFunctionBegin;
6501917a363SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
6514f572ea9SToby Isaac   if (hmin) PetscAssertPointer(hmin, 2);
6524f572ea9SToby Isaac   if (hmax) PetscAssertPointer(hmax, 3);
6531917a363SLisandro Dalcin   if (hmin) *hmin = adapt->dt_min;
6541917a363SLisandro Dalcin   if (hmax) *hmax = adapt->dt_max;
6553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6561c3436cfSJed Brown }
6571c3436cfSJed Brown 
65814d0ab18SJacob Faibussowitsch /*@C
659bcf0153eSBarry Smith   TSAdaptSetFromOptions - Sets various `TSAdapt` parameters from user options.
66084df9cb4SJed Brown 
661c3339decSBarry Smith   Collective
66284df9cb4SJed Brown 
66314d0ab18SJacob Faibussowitsch   Input Parameters:
6642fe279fdSBarry Smith + adapt              - the `TSAdapt` context
6652fe279fdSBarry Smith - PetscOptionsObject - object created by `PetscOptionsBegin()`
66684df9cb4SJed Brown 
66784df9cb4SJed Brown   Options Database Keys:
6681917a363SLisandro Dalcin + -ts_adapt_type <type>                - algorithm to use for adaptivity
669bf997491SLisandro Dalcin . -ts_adapt_always_accept              - always accept steps regardless of error/stability goals
6701917a363SLisandro Dalcin . -ts_adapt_safety <safety>            - safety factor relative to target error/stability goal
6711917a363SLisandro Dalcin . -ts_adapt_reject_safety <safety>     - extra safety factor to apply if the last step was rejected
6721917a363SLisandro Dalcin . -ts_adapt_clip <low,high>            - admissible time step decrease and increase factors
67323de1d84SBarry Smith . -ts_adapt_dt_min <min>               - minimum timestep to use
67423de1d84SBarry Smith . -ts_adapt_dt_max <max>               - maximum timestep to use
67523de1d84SBarry Smith . -ts_adapt_scale_solve_failed <scale> - scale timestep by this factor if a solve fails
676de50f1caSBarry Smith . -ts_adapt_wnormtype <2 or infinity>  - type of norm for computing error estimates
677de50f1caSBarry Smith - -ts_adapt_time_step_increase_delay   - number of timesteps to delay increasing the time step after it has been decreased due to failed solver
67884df9cb4SJed Brown 
67984df9cb4SJed Brown   Level: advanced
68084df9cb4SJed Brown 
681bcf0153eSBarry Smith   Note:
682bcf0153eSBarry Smith   This function is automatically called by `TSSetFromOptions()`
68384df9cb4SJed Brown 
6841cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSGetAdapt()`, `TSAdaptSetType()`, `TSAdaptSetAlwaysAccept()`, `TSAdaptSetSafety()`,
685db781477SPatrick Sanan           `TSAdaptSetClip()`, `TSAdaptSetScaleSolveFailed()`, `TSAdaptSetStepLimits()`, `TSAdaptSetMonitor()`
68614d0ab18SJacob Faibussowitsch @*/
687d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetFromOptions(TSAdapt adapt, PetscOptionItems *PetscOptionsObject)
688d71ae5a4SJacob Faibussowitsch {
68984df9cb4SJed Brown   char      type[256] = TSADAPTBASIC;
69062c23b28SMark   PetscReal safety, reject_safety, clip[2], scale, hmin, hmax;
6911c3436cfSJed Brown   PetscBool set, flg;
6921917a363SLisandro Dalcin   PetscInt  two;
69384df9cb4SJed Brown 
69484df9cb4SJed Brown   PetscFunctionBegin;
695dbbe0bcdSBarry Smith   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
69684df9cb4SJed Brown   /* This should use PetscOptionsBegin() if/when this becomes an object used outside of TS, but currently this
6971566a47fSLisandro Dalcin    * function can only be called from inside TSSetFromOptions()  */
698d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "TS Adaptivity options");
6999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-ts_adapt_type", "Algorithm to use for adaptivity", "TSAdaptSetType", TSAdaptList, ((PetscObject)adapt)->type_name ? ((PetscObject)adapt)->type_name : type, type, sizeof(type), &flg));
70048a46eb9SPierre Jolivet   if (flg || !((PetscObject)adapt)->type_name) PetscCall(TSAdaptSetType(adapt, type));
7011917a363SLisandro Dalcin 
7029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_adapt_always_accept", "Always accept the step", "TSAdaptSetAlwaysAccept", adapt->always_accept, &flg, &set));
7039566063dSJacob Faibussowitsch   if (set) PetscCall(TSAdaptSetAlwaysAccept(adapt, flg));
7041917a363SLisandro Dalcin 
7059371c9d4SSatish Balay   safety        = adapt->safety;
7069371c9d4SSatish Balay   reject_safety = adapt->reject_safety;
7079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_adapt_safety", "Safety factor relative to target error/stability goal", "TSAdaptSetSafety", safety, &safety, &set));
7089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_adapt_reject_safety", "Extra safety factor to apply if the last step was rejected", "TSAdaptSetSafety", reject_safety, &reject_safety, &flg));
7099566063dSJacob Faibussowitsch   if (set || flg) PetscCall(TSAdaptSetSafety(adapt, safety, reject_safety));
7101917a363SLisandro Dalcin 
7119371c9d4SSatish Balay   two     = 2;
7129371c9d4SSatish Balay   clip[0] = adapt->clip[0];
7139371c9d4SSatish Balay   clip[1] = adapt->clip[1];
7149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsRealArray("-ts_adapt_clip", "Admissible decrease/increase factor in step size", "TSAdaptSetClip", clip, &two, &set));
7153c633725SBarry Smith   PetscCheck(!set || (two == 2), PetscObjectComm((PetscObject)adapt), PETSC_ERR_ARG_OUTOFRANGE, "Must give exactly two values to -ts_adapt_clip");
7169566063dSJacob Faibussowitsch   if (set) PetscCall(TSAdaptSetClip(adapt, clip[0], clip[1]));
7171917a363SLisandro Dalcin 
7189371c9d4SSatish Balay   hmin = adapt->dt_min;
7199371c9d4SSatish Balay   hmax = adapt->dt_max;
7209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_adapt_dt_min", "Minimum time step considered", "TSAdaptSetStepLimits", hmin, &hmin, &set));
7219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_adapt_dt_max", "Maximum time step considered", "TSAdaptSetStepLimits", hmax, &hmax, &flg));
7229566063dSJacob Faibussowitsch   if (set || flg) PetscCall(TSAdaptSetStepLimits(adapt, hmin, hmax));
7231917a363SLisandro Dalcin 
7249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_adapt_max_ignore", "Adaptor ignores (absolute) solution values smaller than this value", "", adapt->ignore_max, &adapt->ignore_max, &set));
7259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_adapt_glee_use_local", "GLEE adaptor uses local error estimation for step control", "", adapt->glee_use_local, &adapt->glee_use_local, &set));
726d580f011SEmil Constantinescu 
7279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_adapt_scale_solve_failed", "Scale step by this factor if solve fails", "TSAdaptSetScaleSolveFailed", adapt->scale_solve_failed, &scale, &set));
7289566063dSJacob Faibussowitsch   if (set) PetscCall(TSAdaptSetScaleSolveFailed(adapt, scale));
7291917a363SLisandro Dalcin 
7309566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-ts_adapt_wnormtype", "Type of norm computed for error estimation", "", NormTypes, (PetscEnum)adapt->wnormtype, (PetscEnum *)&adapt->wnormtype, NULL));
7313c633725SBarry Smith   PetscCheck(adapt->wnormtype == NORM_2 || adapt->wnormtype == NORM_INFINITY, PetscObjectComm((PetscObject)adapt), PETSC_ERR_SUP, "Only 2-norm and infinite norm supported");
7321917a363SLisandro Dalcin 
7339566063dSJacob Faibussowitsch   PetscCall(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));
734de50f1caSBarry Smith 
7359566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_adapt_monitor", "Print choices made by adaptive controller", "TSAdaptSetMonitor", adapt->monitor ? PETSC_TRUE : PETSC_FALSE, &flg, &set));
7369566063dSJacob Faibussowitsch   if (set) PetscCall(TSAdaptSetMonitor(adapt, flg));
7371917a363SLisandro Dalcin 
738dbbe0bcdSBarry Smith   PetscTryTypeMethod(adapt, setfromoptions, PetscOptionsObject);
739d0609cedSBarry Smith   PetscOptionsHeadEnd();
7403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
74184df9cb4SJed Brown }
74284df9cb4SJed Brown 
74384df9cb4SJed Brown /*@
74484df9cb4SJed Brown   TSAdaptCandidatesClear - clear any previously set candidate schemes
74584df9cb4SJed Brown 
74620f4b53cSBarry Smith   Logically Collective
74784df9cb4SJed Brown 
7484165533cSJose E. Roman   Input Parameter:
74984df9cb4SJed Brown . adapt - adaptive controller
75084df9cb4SJed Brown 
75184df9cb4SJed Brown   Level: developer
75284df9cb4SJed Brown 
7531cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptCreate()`, `TSAdaptCandidateAdd()`, `TSAdaptChoose()`
75484df9cb4SJed Brown @*/
755d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptCandidatesClear(TSAdapt adapt)
756d71ae5a4SJacob Faibussowitsch {
75784df9cb4SJed Brown   PetscFunctionBegin;
7584782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
7599566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(&adapt->candidates, sizeof(adapt->candidates)));
7603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
76184df9cb4SJed Brown }
76284df9cb4SJed Brown 
76384df9cb4SJed Brown /*@C
76484df9cb4SJed Brown   TSAdaptCandidateAdd - add a candidate scheme for the adaptive controller to select from
76584df9cb4SJed Brown 
76620f4b53cSBarry Smith   Logically Collective; No Fortran Support
76784df9cb4SJed Brown 
7684165533cSJose E. Roman   Input Parameters:
769bcf0153eSBarry Smith + adapt      - time step adaptivity context, obtained with `TSGetAdapt()` or `TSAdaptCreate()`
77084df9cb4SJed Brown . name       - name of the candidate scheme to add
77184df9cb4SJed Brown . order      - order of the candidate scheme
77284df9cb4SJed Brown . stageorder - stage order of the candidate scheme
7738d59e960SJed Brown . ccfl       - stability coefficient relative to explicit Euler, used for CFL constraints
77484df9cb4SJed Brown . cost       - relative measure of the amount of work required for the candidate scheme
77584df9cb4SJed Brown - inuse      - indicates that this scheme is the one currently in use, this flag can only be set for one scheme
77684df9cb4SJed Brown 
77784df9cb4SJed Brown   Level: developer
77884df9cb4SJed Brown 
7791cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptCandidatesClear()`, `TSAdaptChoose()`
78084df9cb4SJed Brown @*/
781d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptCandidateAdd(TSAdapt adapt, const char name[], PetscInt order, PetscInt stageorder, PetscReal ccfl, PetscReal cost, PetscBool inuse)
782d71ae5a4SJacob Faibussowitsch {
78384df9cb4SJed Brown   PetscInt c;
78484df9cb4SJed Brown 
78584df9cb4SJed Brown   PetscFunctionBegin;
78684df9cb4SJed Brown   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
78763a3b9bcSJacob Faibussowitsch   PetscCheck(order >= 1, PetscObjectComm((PetscObject)adapt), PETSC_ERR_ARG_OUTOFRANGE, "Classical order %" PetscInt_FMT " must be a positive integer", order);
78884df9cb4SJed Brown   if (inuse) {
7893c633725SBarry Smith     PetscCheck(!adapt->candidates.inuse_set, PetscObjectComm((PetscObject)adapt), PETSC_ERR_ARG_WRONGSTATE, "Cannot set the inuse method twice, maybe forgot to call TSAdaptCandidatesClear()");
79084df9cb4SJed Brown     adapt->candidates.inuse_set = PETSC_TRUE;
79184df9cb4SJed Brown   }
7921c3436cfSJed Brown   /* first slot if this is the current scheme, otherwise the next available slot */
7931c3436cfSJed Brown   c = inuse ? 0 : !adapt->candidates.inuse_set + adapt->candidates.n;
794bbd56ea5SKarl Rupp 
79584df9cb4SJed Brown   adapt->candidates.name[c]       = name;
79684df9cb4SJed Brown   adapt->candidates.order[c]      = order;
79784df9cb4SJed Brown   adapt->candidates.stageorder[c] = stageorder;
7988d59e960SJed Brown   adapt->candidates.ccfl[c]       = ccfl;
79984df9cb4SJed Brown   adapt->candidates.cost[c]       = cost;
80084df9cb4SJed Brown   adapt->candidates.n++;
8013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
80284df9cb4SJed Brown }
80384df9cb4SJed Brown 
8048d59e960SJed Brown /*@C
8058d59e960SJed Brown   TSAdaptCandidatesGet - Get the list of candidate orders of accuracy and cost
8068d59e960SJed Brown 
8078d59e960SJed Brown   Not Collective
8088d59e960SJed Brown 
8094165533cSJose E. Roman   Input Parameter:
8108d59e960SJed Brown . adapt - time step adaptivity context
8118d59e960SJed Brown 
8124165533cSJose E. Roman   Output Parameters:
8138d59e960SJed Brown + n          - number of candidate schemes, always at least 1
8148d59e960SJed Brown . order      - the order of each candidate scheme
8158d59e960SJed Brown . stageorder - the stage order of each candidate scheme
8168d59e960SJed Brown . ccfl       - the CFL coefficient of each scheme
8178d59e960SJed Brown - cost       - the relative cost of each scheme
8188d59e960SJed Brown 
8198d59e960SJed Brown   Level: developer
8208d59e960SJed Brown 
8218d59e960SJed Brown   Note:
8228d59e960SJed Brown   The current scheme is always returned in the first slot
8238d59e960SJed Brown 
8241cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptCandidatesClear()`, `TSAdaptCandidateAdd()`, `TSAdaptChoose()`
8258d59e960SJed Brown @*/
826d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptCandidatesGet(TSAdapt adapt, PetscInt *n, const PetscInt **order, const PetscInt **stageorder, const PetscReal **ccfl, const PetscReal **cost)
827d71ae5a4SJacob Faibussowitsch {
8288d59e960SJed Brown   PetscFunctionBegin;
8298d59e960SJed Brown   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
8308d59e960SJed Brown   if (n) *n = adapt->candidates.n;
8318d59e960SJed Brown   if (order) *order = adapt->candidates.order;
8328d59e960SJed Brown   if (stageorder) *stageorder = adapt->candidates.stageorder;
8338d59e960SJed Brown   if (ccfl) *ccfl = adapt->candidates.ccfl;
8348d59e960SJed Brown   if (cost) *cost = adapt->candidates.cost;
8353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8368d59e960SJed Brown }
8378d59e960SJed Brown 
83884df9cb4SJed Brown /*@C
83984df9cb4SJed Brown   TSAdaptChoose - choose which method and step size to use for the next step
84084df9cb4SJed Brown 
841c3339decSBarry Smith   Collective
84284df9cb4SJed Brown 
8434165533cSJose E. Roman   Input Parameters:
844da81f932SPierre Jolivet + adapt - adaptive controller
84597bb3fdcSJose E. Roman . ts    - time stepper
84684df9cb4SJed Brown - h     - current step size
84784df9cb4SJed Brown 
8484165533cSJose E. Roman   Output Parameters:
8491566a47fSLisandro Dalcin + next_sc - optional, scheme to use for the next step
85084df9cb4SJed Brown . next_h  - step size to use for the next step
851bcf0153eSBarry Smith - accept  - `PETSC_TRUE` to accept the current step, `PETSC_FALSE` to repeat the current step with the new step size
8521c3436cfSJed Brown 
85384df9cb4SJed Brown   Level: developer
85484df9cb4SJed Brown 
855bcf0153eSBarry Smith   Note:
856bcf0153eSBarry Smith   The input value of parameter accept is retained from the last time step, so it will be `PETSC_FALSE` if the step is
857bcf0153eSBarry Smith   being retried after an initial rejection.
858bcf0153eSBarry Smith 
8591cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSAdaptCandidatesClear()`, `TSAdaptCandidateAdd()`
86084df9cb4SJed Brown @*/
861d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptChoose(TSAdapt adapt, TS ts, PetscReal h, PetscInt *next_sc, PetscReal *next_h, PetscBool *accept)
862d71ae5a4SJacob Faibussowitsch {
8631566a47fSLisandro Dalcin   PetscInt  ncandidates = adapt->candidates.n;
8641566a47fSLisandro Dalcin   PetscInt  scheme      = 0;
8650b99f514SJed Brown   PetscReal wlte        = -1.0;
8665e4ed32fSEmil Constantinescu   PetscReal wltea       = -1.0;
8675e4ed32fSEmil Constantinescu   PetscReal wlter       = -1.0;
86884df9cb4SJed Brown 
86984df9cb4SJed Brown   PetscFunctionBegin;
87084df9cb4SJed Brown   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
87184df9cb4SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 2);
8724f572ea9SToby Isaac   if (next_sc) PetscAssertPointer(next_sc, 4);
8734f572ea9SToby Isaac   PetscAssertPointer(next_h, 5);
8744f572ea9SToby Isaac   PetscAssertPointer(accept, 6);
8751566a47fSLisandro Dalcin   if (next_sc) *next_sc = 0;
8761566a47fSLisandro Dalcin 
8771566a47fSLisandro Dalcin   /* Do not mess with adaptivity while handling events */
878ca4445c7SIlya Fursov   if (ts->event && ts->event->processing) {
8791566a47fSLisandro Dalcin     *next_h = h;
8801566a47fSLisandro Dalcin     *accept = PETSC_TRUE;
881fe4ad979SIlya Fursov     if (adapt->monitor) {
882fe4ad979SIlya Fursov       PetscCall(PetscViewerASCIIAddTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
883fe4ad979SIlya Fursov 
884fe4ad979SIlya Fursov       if (ts->event->iterctr == 0) {
885fe4ad979SIlya Fursov         /*
886fe4ad979SIlya Fursov           An event has been found, now finalising the event processing: performing the 1st and 2nd post-event steps.
887fe4ad979SIlya Fursov           Entering this if-branch means both these steps (set to either PETSC_DECIDE or numerical value) are managed
888fe4ad979SIlya Fursov           by the event handler. In this case the 1st post-event step is always accepted, without interference of TSAdapt.
889fe4ad979SIlya Fursov           Note: if the 2nd post-event step is not managed by the event handler (e.g. given 1st = numerical, 2nd = PETSC_DECIDE),
890fe4ad979SIlya Fursov           this if-branch is not entered, and TSAdapt may reject/adjust the proposed 1st post-event step.
891fe4ad979SIlya Fursov         */
892fe4ad979SIlya Fursov         PetscCall(PetscViewerASCIIPrintf(adapt->monitor, "    TSAdapt does not interfere, step %3" PetscInt_FMT " accepted. Processing post-event steps: 1-st accepted just now, 2-nd yet to come\n", ts->steps));
893fe4ad979SIlya Fursov       } else PetscCall(PetscViewerASCIIPrintf(adapt->monitor, "    TSAdapt does not interfere, step %3" PetscInt_FMT " accepted. Event handling in progress\n", ts->steps));
894fe4ad979SIlya Fursov 
895fe4ad979SIlya Fursov       PetscCall(PetscViewerASCIISubtractTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
896fe4ad979SIlya Fursov     }
8973ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
8981566a47fSLisandro Dalcin   }
8991566a47fSLisandro Dalcin 
900dbbe0bcdSBarry Smith   PetscUseTypeMethod(adapt, choose, ts, h, &scheme, next_h, accept, &wlte, &wltea, &wlter);
90163a3b9bcSJacob Faibussowitsch   PetscCheck(scheme >= 0 && (ncandidates <= 0 || scheme < ncandidates), PetscObjectComm((PetscObject)adapt), PETSC_ERR_ARG_OUTOFRANGE, "Chosen scheme %" PetscInt_FMT " not in valid range 0..%" PetscInt_FMT, scheme, ncandidates - 1);
9023c633725SBarry Smith   PetscCheck(*next_h >= 0, PetscObjectComm((PetscObject)adapt), PETSC_ERR_ARG_OUTOFRANGE, "Computed step size %g must be positive", (double)*next_h);
9031566a47fSLisandro Dalcin   if (next_sc) *next_sc = scheme;
9041566a47fSLisandro Dalcin 
90549354f04SShri Abhyankar   if (*accept && ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) {
90636b54a69SLisandro Dalcin     /* Increase/reduce step size if end time of next step is close to or overshoots max time */
907ca4445c7SIlya Fursov     PetscReal t   = ts->ptime + ts->time_step, tend, tmax, h1, hmax;
908fe7350e0SStefano Zampini     PetscReal a   = (PetscReal)(1.0 + adapt->matchstepfac[0]);
909fe7350e0SStefano Zampini     PetscReal b   = adapt->matchstepfac[1];
910ca4445c7SIlya Fursov     PetscReal eps = 10 * PETSC_MACHINE_EPSILON;
9114a658b32SHong Zhang 
912fe4ad979SIlya Fursov     /*
913fe4ad979SIlya Fursov       Logic in using 'dt_span_cached':
914fe4ad979SIlya Fursov       1. It always overrides *next_h, except (any of):
915fe4ad979SIlya Fursov          a) the current step was rejected,
916fe4ad979SIlya Fursov          b) the adaptor proposed to decrease the next step,
917fe4ad979SIlya Fursov          c) the adaptor proposed *next_h > dt_span_cached.
918fe4ad979SIlya Fursov       2. If *next_h was adjusted by tspan points (or the final point):
919fe4ad979SIlya Fursov            -- when dt_span_cached is filled (>0), it keeps its value,
920fe4ad979SIlya Fursov            -- when dt_span_cached is clear (==0), it gets the unadjusted version of *next_h.
921fe4ad979SIlya Fursov       3. If *next_h was not adjusted as in (2), dt_span_cached is cleared.
922fe4ad979SIlya Fursov       Note, if a combination (1.b || 1.c) && (3) takes place, this means that
923fe4ad979SIlya Fursov       dt_span_cached remains unused at the moment of clearing.
924fe4ad979SIlya Fursov       If (1.a) takes place, dt_span_cached keeps its value.
925fe4ad979SIlya Fursov       Also, dt_span_cached can be updated by the event handler, see tsevent.c.
926fe4ad979SIlya Fursov     */
927ca4445c7SIlya Fursov     if (h <= *next_h && *next_h <= adapt->dt_span_cached) *next_h = adapt->dt_span_cached; /* try employing the cache */
928ca4445c7SIlya Fursov     h1   = *next_h;
929ca4445c7SIlya Fursov     tend = t + h1;
930ca4445c7SIlya Fursov 
931ca4445c7SIlya Fursov     if (ts->tspan && ts->tspan->spanctr < ts->tspan->num_span_times) {
932ca4445c7SIlya Fursov       PetscCheck(ts->tspan->worktol == 0, PetscObjectComm((PetscObject)adapt), PETSC_ERR_PLIB, "Unexpected state (tspan->worktol != 0) in TSAdaptChoose()");
933ca4445c7SIlya Fursov       ts->tspan->worktol = ts->tspan->reltol * h1 + ts->tspan->abstol;
934ca4445c7SIlya Fursov       if (PetscIsCloseAtTol(t, ts->tspan->span_times[ts->tspan->spanctr], ts->tspan->worktol, 0)) /* hit a span time point */
9354a658b32SHong Zhang         if (ts->tspan->spanctr + 1 < ts->tspan->num_span_times) tmax = ts->tspan->span_times[ts->tspan->spanctr + 1];
9364a658b32SHong Zhang         else tmax = ts->max_time; /* hit the last span time point */
9374a658b32SHong Zhang       else tmax = ts->tspan->span_times[ts->tspan->spanctr];
9384a658b32SHong Zhang     } else tmax = ts->max_time;
939ca4445c7SIlya Fursov     tmax = PetscMin(tmax, ts->max_time);
9404a658b32SHong Zhang     hmax = tmax - t;
941ca4445c7SIlya Fursov     PetscCheck((hmax > eps) || (PetscAbsReal(hmax) <= eps && PetscIsCloseAtTol(t, ts->max_time, eps, 0)), PetscObjectComm((PetscObject)adapt), PETSC_ERR_PLIB, "Unexpected state: bad hmax in TSAdaptChoose()");
942ca4445c7SIlya Fursov 
94336b54a69SLisandro Dalcin     if (t < tmax && tend > tmax) *next_h = hmax;
944ca4445c7SIlya Fursov     if (t < tmax && tend < tmax && h1 * b > hmax) *next_h = hmax / 2;
945ca4445c7SIlya Fursov     if (t < tmax && tend < tmax && h1 * a > hmax) *next_h = hmax;
946ca4445c7SIlya Fursov     if (ts->tspan && h1 != *next_h && !adapt->dt_span_cached) adapt->dt_span_cached = h1; /* cache the step size if it is to be changed    */
947ca4445c7SIlya Fursov     if (ts->tspan && h1 == *next_h && adapt->dt_span_cached) adapt->dt_span_cached = 0;   /* clear the cache if the step size is unchanged */
948e1db57b0SHong Zhang   }
9491c3436cfSJed Brown   if (adapt->monitor) {
9501566a47fSLisandro Dalcin     const char *sc_name = (scheme < ncandidates) ? adapt->candidates.name[scheme] : "";
9519566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
9520b99f514SJed Brown     if (wlte < 0) {
9539371c9d4SSatish Balay       PetscCall(PetscViewerASCIIPrintf(adapt->monitor, "    TSAdapt %s %s %" PetscInt_FMT ":%s step %3" PetscInt_FMT " %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",
9549371c9d4SSatish Balay                                        (double)ts->ptime, (double)h, (double)*next_h));
9550b99f514SJed Brown     } else {
9569371c9d4SSatish Balay       PetscCall(PetscViewerASCIIPrintf(adapt->monitor, "    TSAdapt %s %s %" PetscInt_FMT ":%s step %3" PetscInt_FMT " %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",
9579371c9d4SSatish Balay                                        (double)ts->ptime, (double)h, (double)*next_h, (double)wlte, (double)wltea, (double)wlter));
9580b99f514SJed Brown     }
9599566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
9601c3436cfSJed Brown   }
9613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
96284df9cb4SJed Brown }
96384df9cb4SJed Brown 
96497335746SJed Brown /*@
965de50f1caSBarry Smith   TSAdaptSetTimeStepIncreaseDelay - The number of timesteps to wait after a decrease in the timestep due to failed solver
966de50f1caSBarry Smith   before increasing the time step.
967de50f1caSBarry Smith 
968c3339decSBarry Smith   Logicially Collective
969de50f1caSBarry Smith 
9704165533cSJose E. Roman   Input Parameters:
971de50f1caSBarry Smith + adapt - adaptive controller context
972de50f1caSBarry Smith - cnt   - the number of timesteps
973de50f1caSBarry Smith 
974de50f1caSBarry Smith   Options Database Key:
975de50f1caSBarry Smith . -ts_adapt_time_step_increase_delay cnt - number of steps to delay the increase
976de50f1caSBarry Smith 
977de50f1caSBarry Smith   Level: advanced
978de50f1caSBarry Smith 
979bcf0153eSBarry Smith   Notes:
980bcf0153eSBarry Smith   This is to prevent an adaptor from bouncing back and forth between two nearby timesteps. The default is 0.
981bcf0153eSBarry Smith 
982bcf0153eSBarry Smith   The successful use of this option is problem dependent
983bcf0153eSBarry Smith 
984b43aa488SJacob Faibussowitsch   Developer Notes:
985bcf0153eSBarry Smith   There is no theory to support this option
986bcf0153eSBarry Smith 
9871cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`
988de50f1caSBarry Smith @*/
989d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptSetTimeStepIncreaseDelay(TSAdapt adapt, PetscInt cnt)
990d71ae5a4SJacob Faibussowitsch {
991de50f1caSBarry Smith   PetscFunctionBegin;
992de50f1caSBarry Smith   adapt->timestepjustdecreased_delay = cnt;
9933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
994de50f1caSBarry Smith }
995de50f1caSBarry Smith 
996de50f1caSBarry Smith /*@
9976bc98fa9SBarry Smith   TSAdaptCheckStage - checks whether to accept a stage, (e.g. reject and change time step size if nonlinear solve fails or solution vector is infeasible)
99897335746SJed Brown 
999c3339decSBarry Smith   Collective
100097335746SJed Brown 
10014165533cSJose E. Roman   Input Parameters:
100297335746SJed Brown + adapt - adaptive controller context
1003b295832fSPierre Barbier de Reuille . ts    - time stepper
1004b295832fSPierre Barbier de Reuille . t     - Current simulation time
1005b295832fSPierre Barbier de Reuille - Y     - Current solution vector
100697335746SJed Brown 
10074165533cSJose E. Roman   Output Parameter:
1008bcf0153eSBarry Smith . accept - `PETSC_TRUE` to accept the stage, `PETSC_FALSE` to reject
100997335746SJed Brown 
101097335746SJed Brown   Level: developer
101197335746SJed Brown 
10121cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`
101397335746SJed Brown @*/
1014d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptCheckStage(TSAdapt adapt, TS ts, PetscReal t, Vec Y, PetscBool *accept)
1015d71ae5a4SJacob Faibussowitsch {
10161566a47fSLisandro Dalcin   SNESConvergedReason snesreason = SNES_CONVERGED_ITERATING;
10176c6709e3SStefano Zampini   PetscBool           func_accept, snes_div_func;
101897335746SJed Brown 
101997335746SJed Brown   PetscFunctionBegin;
10204782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
10214782b174SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 2);
10224f572ea9SToby Isaac   PetscAssertPointer(accept, 5);
10231566a47fSLisandro Dalcin 
10246c6709e3SStefano Zampini   PetscCall(TSFunctionDomainError(ts, t, Y, &func_accept));
10259566063dSJacob Faibussowitsch   if (ts->snes) PetscCall(SNESGetConvergedReason(ts->snes, &snesreason));
10266c6709e3SStefano Zampini   snes_div_func = (PetscBool)(snesreason == SNES_DIVERGED_FUNCTION_DOMAIN);
10276c6709e3SStefano Zampini   if (func_accept && snesreason < 0 && !snes_div_func) {
102897335746SJed Brown     *accept = PETSC_FALSE;
10296c6709e3SStefano Zampini     PetscCall(PetscInfo(ts, "Step=%" PetscInt_FMT ", nonlinear solve failure: %s\n", ts->steps, SNESConvergedReasons[snesreason]));
10306de24e2aSJed Brown     if (++ts->num_snes_failures >= ts->max_snes_failures && ts->max_snes_failures > 0) {
103197335746SJed Brown       ts->reason = TS_DIVERGED_NONLINEAR_SOLVE;
103263a3b9bcSJacob Faibussowitsch       PetscCall(PetscInfo(ts, "Step=%" PetscInt_FMT ", nonlinear solve failures %" PetscInt_FMT " greater than current TS allowed, stopping solve\n", ts->steps, ts->num_snes_failures));
103397335746SJed Brown       if (adapt->monitor) {
10349566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIAddTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
10359371c9d4SSatish Balay         PetscCall(PetscViewerASCIIPrintf(adapt->monitor, "    TSAdapt %s step %3" PetscInt_FMT " stage rejected t=%-11g+%10.3e, nonlinear solve failures %" PetscInt_FMT " greater than current TS allowed\n", ((PetscObject)adapt)->type_name, ts->steps,
10369371c9d4SSatish Balay                                          (double)ts->ptime, (double)ts->time_step, ts->num_snes_failures));
10379566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISubtractTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
103897335746SJed Brown       }
1039cb9d8021SPierre Barbier de Reuille     }
1040cb9d8021SPierre Barbier de Reuille   } else {
10416c6709e3SStefano Zampini     *accept = (PetscBool)(func_accept && !snes_div_func);
10426c6709e3SStefano Zampini     if (*accept && adapt->checkstage) PetscCall((*adapt->checkstage)(adapt, ts, t, Y, accept));
10436bc98fa9SBarry Smith     if (!*accept) {
10446c6709e3SStefano Zampini       const char *user_func = !func_accept ? "TSSetFunctionDomainError()" : "TSAdaptSetCheckStage";
10456c6709e3SStefano Zampini       const char *snes_err  = "SNES invalid function domain";
10466c6709e3SStefano Zampini       const char *err_msg   = snes_div_func && func_accept ? snes_err : user_func;
10476c6709e3SStefano Zampini       PetscCall(PetscInfo(ts, "Step=%" PetscInt_FMT ", solution rejected by %s\n", ts->steps, err_msg));
10486bc98fa9SBarry Smith       if (adapt->monitor) {
10499566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIAddTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
10506c6709e3SStefano Zampini         PetscCall(PetscViewerASCIIPrintf(adapt->monitor, "    TSAdapt %s step %3" PetscInt_FMT " stage rejected by %s\n", ((PetscObject)adapt)->type_name, ts->steps, err_msg));
10519566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISubtractTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
10526bc98fa9SBarry Smith       }
10536bc98fa9SBarry Smith     }
1054cb9d8021SPierre Barbier de Reuille   }
1055cb9d8021SPierre Barbier de Reuille 
10561566a47fSLisandro Dalcin   if (!(*accept) && !ts->reason) {
10571566a47fSLisandro Dalcin     PetscReal dt, new_dt;
10589566063dSJacob Faibussowitsch     PetscCall(TSGetTimeStep(ts, &dt));
1059cb9d8021SPierre Barbier de Reuille     new_dt = dt * adapt->scale_solve_failed;
10609566063dSJacob Faibussowitsch     PetscCall(TSSetTimeStep(ts, new_dt));
1061de50f1caSBarry Smith     adapt->timestepjustdecreased += adapt->timestepjustdecreased_delay;
106297335746SJed Brown     if (adapt->monitor) {
10639566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIAddTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
10646c6709e3SStefano Zampini       PetscCall(PetscViewerASCIIPrintf(adapt->monitor, "    TSAdapt %s step %3" PetscInt_FMT " stage rejected (SNES reason %s) t=%-11g+%10.3e retrying with dt=%-10.3e\n", ((PetscObject)adapt)->type_name, ts->steps, SNESConvergedReasons[snesreason],
10656c6709e3SStefano Zampini                                        (double)ts->ptime, (double)dt, (double)new_dt));
10669566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISubtractTab(adapt->monitor, ((PetscObject)adapt)->tablevel));
106797335746SJed Brown     }
106897335746SJed Brown   }
10693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
107097335746SJed Brown }
107197335746SJed Brown 
107284df9cb4SJed Brown /*@
107384df9cb4SJed Brown   TSAdaptCreate - create an adaptive controller context for time stepping
107484df9cb4SJed Brown 
1075d083f849SBarry Smith   Collective
107684df9cb4SJed Brown 
107784df9cb4SJed Brown   Input Parameter:
107884df9cb4SJed Brown . comm - The communicator
107984df9cb4SJed Brown 
108084df9cb4SJed Brown   Output Parameter:
1081b43aa488SJacob Faibussowitsch . inadapt - new `TSAdapt` object
108284df9cb4SJed Brown 
108384df9cb4SJed Brown   Level: developer
108484df9cb4SJed Brown 
1085bcf0153eSBarry Smith   Note:
1086bcf0153eSBarry Smith   `TSAdapt` creation is handled by `TS`, so users should not need to call this function.
108784df9cb4SJed Brown 
10881cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdapt`, `TSGetAdapt()`, `TSAdaptSetType()`, `TSAdaptDestroy()`
108984df9cb4SJed Brown @*/
1090d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAdaptCreate(MPI_Comm comm, TSAdapt *inadapt)
1091d71ae5a4SJacob Faibussowitsch {
109284df9cb4SJed Brown   TSAdapt adapt;
109384df9cb4SJed Brown 
109484df9cb4SJed Brown   PetscFunctionBegin;
10954f572ea9SToby Isaac   PetscAssertPointer(inadapt, 2);
10963b3bcf4cSLisandro Dalcin   *inadapt = NULL;
10979566063dSJacob Faibussowitsch   PetscCall(TSAdaptInitializePackage());
10983b3bcf4cSLisandro Dalcin 
10999566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(adapt, TSADAPT_CLASSID, "TSAdapt", "Time stepping adaptivity", "TS", comm, TSAdaptDestroy, TSAdaptView));
11001c3436cfSJed Brown 
1101bf997491SLisandro Dalcin   adapt->always_accept      = PETSC_FALSE;
11021917a363SLisandro Dalcin   adapt->safety             = 0.9;
11031917a363SLisandro Dalcin   adapt->reject_safety      = 0.5;
11041917a363SLisandro Dalcin   adapt->clip[0]            = 0.1;
11051917a363SLisandro Dalcin   adapt->clip[1]            = 10.;
11061c3436cfSJed Brown   adapt->dt_min             = 1e-20;
11071917a363SLisandro Dalcin   adapt->dt_max             = 1e+20;
11081c167fc2SEmil Constantinescu   adapt->ignore_max         = -1.0;
1109d580f011SEmil Constantinescu   adapt->glee_use_local     = PETSC_TRUE;
111097335746SJed Brown   adapt->scale_solve_failed = 0.25;
1111fe7350e0SStefano Zampini   /* these two safety factors are not public, and they are used only in the TS_EXACTFINALTIME_MATCHSTEP case
1112fe7350e0SStefano Zampini      to prevent from situations were unreasonably small time steps are taken in order to match the final time */
1113fe7350e0SStefano Zampini   adapt->matchstepfac[0]             = 0.01; /* allow 1% step size increase in the last step */
1114fe7350e0SStefano Zampini   adapt->matchstepfac[1]             = 2.0;  /* halve last step if it is greater than what remains divided this factor */
11157619abb3SShri   adapt->wnormtype                   = NORM_2;
1116de50f1caSBarry Smith   adapt->timestepjustdecreased_delay = 0;
11171917a363SLisandro Dalcin 
111884df9cb4SJed Brown   *inadapt = adapt;
11193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
112084df9cb4SJed Brown }
1121