xref: /petsc/src/ts/adapt/interface/tsadapt.c (revision 5e4ed32f0140df3e357a2244cf5f0301f2d2ad78)
184df9cb4SJed Brown 
2af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I  "petscts.h" I*/
384df9cb4SJed Brown 
41b9b13dfSLisandro Dalcin PetscClassId TSADAPT_CLASSID;
51b9b13dfSLisandro Dalcin 
6140e18c1SBarry Smith static PetscFunctionList TSAdaptList;
784df9cb4SJed Brown static PetscBool         TSAdaptPackageInitialized;
884df9cb4SJed Brown static PetscBool         TSAdaptRegisterAllCalled;
984df9cb4SJed Brown 
10726095e4SEmil Constantinescu PETSC_EXTERN PetscErrorCode TSAdaptCreate_GLEE(TSAdapt);
118cc058d9SJed Brown PETSC_EXTERN PetscErrorCode TSAdaptCreate_None(TSAdapt);
121566a47fSLisandro Dalcin PETSC_EXTERN PetscErrorCode TSAdaptCreate_Basic(TSAdapt);
138cc058d9SJed Brown PETSC_EXTERN PetscErrorCode TSAdaptCreate_CFL(TSAdapt);
1484df9cb4SJed Brown 
1584df9cb4SJed Brown #undef __FUNCT__
1684df9cb4SJed Brown #define __FUNCT__ "TSAdaptRegister"
1784df9cb4SJed Brown /*@C
181c84c290SBarry Smith    TSAdaptRegister -  adds a TSAdapt implementation
191c84c290SBarry Smith 
201c84c290SBarry Smith    Not Collective
211c84c290SBarry Smith 
221c84c290SBarry Smith    Input Parameters:
231c84c290SBarry Smith +  name_scheme - name of user-defined adaptivity scheme
241c84c290SBarry Smith -  routine_create - routine to create method context
251c84c290SBarry Smith 
261c84c290SBarry Smith    Notes:
271c84c290SBarry Smith    TSAdaptRegister() may be called multiple times to add several user-defined families.
281c84c290SBarry Smith 
291c84c290SBarry Smith    Sample usage:
301c84c290SBarry Smith .vb
31bdf89e91SBarry Smith    TSAdaptRegister("my_scheme",MySchemeCreate);
321c84c290SBarry Smith .ve
331c84c290SBarry Smith 
341c84c290SBarry Smith    Then, your scheme can be chosen with the procedural interface via
351c84c290SBarry Smith $     TSAdaptSetType(ts,"my_scheme")
361c84c290SBarry Smith    or at runtime via the option
371c84c290SBarry Smith $     -ts_adapt_type my_scheme
3884df9cb4SJed Brown 
3984df9cb4SJed Brown    Level: advanced
401c84c290SBarry Smith 
411c84c290SBarry Smith .keywords: TSAdapt, register
421c84c290SBarry Smith 
431c84c290SBarry Smith .seealso: TSAdaptRegisterAll()
4484df9cb4SJed Brown @*/
45bdf89e91SBarry Smith PetscErrorCode  TSAdaptRegister(const char sname[],PetscErrorCode (*function)(TSAdapt))
4684df9cb4SJed Brown {
4784df9cb4SJed Brown   PetscErrorCode ierr;
4884df9cb4SJed Brown 
4984df9cb4SJed Brown   PetscFunctionBegin;
50a240a19fSJed Brown   ierr = PetscFunctionListAdd(&TSAdaptList,sname,function);CHKERRQ(ierr);
5184df9cb4SJed Brown   PetscFunctionReturn(0);
5284df9cb4SJed Brown }
5384df9cb4SJed Brown 
5484df9cb4SJed Brown #undef __FUNCT__
5584df9cb4SJed Brown #define __FUNCT__ "TSAdaptRegisterAll"
5684df9cb4SJed Brown /*@C
5784df9cb4SJed Brown   TSAdaptRegisterAll - Registers all of the adaptivity schemes in TSAdapt
5884df9cb4SJed Brown 
5984df9cb4SJed Brown   Not Collective
6084df9cb4SJed Brown 
6184df9cb4SJed Brown   Level: advanced
6284df9cb4SJed Brown 
6384df9cb4SJed Brown .keywords: TSAdapt, register, all
6484df9cb4SJed Brown 
6584df9cb4SJed Brown .seealso: TSAdaptRegisterDestroy()
6684df9cb4SJed Brown @*/
67607a6623SBarry Smith PetscErrorCode  TSAdaptRegisterAll(void)
6884df9cb4SJed Brown {
6984df9cb4SJed Brown   PetscErrorCode ierr;
7084df9cb4SJed Brown 
7184df9cb4SJed Brown   PetscFunctionBegin;
720f51fdf8SToby Isaac   if (TSAdaptRegisterAllCalled) PetscFunctionReturn(0);
730f51fdf8SToby Isaac   TSAdaptRegisterAllCalled = PETSC_TRUE;
74726095e4SEmil Constantinescu   ierr = TSAdaptRegister(TSADAPTGLEE ,TSAdaptCreate_GLEE);CHKERRQ(ierr);
75bdf89e91SBarry Smith   ierr = TSAdaptRegister(TSADAPTNONE, TSAdaptCreate_None);CHKERRQ(ierr);
761566a47fSLisandro Dalcin   ierr = TSAdaptRegister(TSADAPTBASIC,TSAdaptCreate_Basic);CHKERRQ(ierr);
77bdf89e91SBarry Smith   ierr = TSAdaptRegister(TSADAPTCFL,  TSAdaptCreate_CFL);CHKERRQ(ierr);
7884df9cb4SJed Brown   PetscFunctionReturn(0);
7984df9cb4SJed Brown }
8084df9cb4SJed Brown 
8184df9cb4SJed Brown #undef __FUNCT__
8284df9cb4SJed Brown #define __FUNCT__ "TSAdaptFinalizePackage"
8384df9cb4SJed Brown /*@C
84560360afSLisandro Dalcin   TSAdaptFinalizePackage - This function destroys everything in the TS package. It is
8584df9cb4SJed Brown   called from PetscFinalize().
8684df9cb4SJed Brown 
8784df9cb4SJed Brown   Level: developer
8884df9cb4SJed Brown 
8984df9cb4SJed Brown .keywords: Petsc, destroy, package
9084df9cb4SJed Brown .seealso: PetscFinalize()
9184df9cb4SJed Brown @*/
9284df9cb4SJed Brown PetscErrorCode  TSAdaptFinalizePackage(void)
9384df9cb4SJed Brown {
9437e93019SBarry Smith   PetscErrorCode ierr;
9537e93019SBarry Smith 
9684df9cb4SJed Brown   PetscFunctionBegin;
9737e93019SBarry Smith   ierr = PetscFunctionListDestroy(&TSAdaptList);CHKERRQ(ierr);
9884df9cb4SJed Brown   TSAdaptPackageInitialized = PETSC_FALSE;
9984df9cb4SJed Brown   TSAdaptRegisterAllCalled  = PETSC_FALSE;
10084df9cb4SJed Brown   PetscFunctionReturn(0);
10184df9cb4SJed Brown }
10284df9cb4SJed Brown 
10384df9cb4SJed Brown #undef __FUNCT__
10484df9cb4SJed Brown #define __FUNCT__ "TSAdaptInitializePackage"
10584df9cb4SJed Brown /*@C
10684df9cb4SJed Brown   TSAdaptInitializePackage - This function initializes everything in the TSAdapt package. It is
10784df9cb4SJed Brown   called from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to
10826d28e4eSEmil Constantinescu   TSCreate_GLLE() when using static libraries.
10984df9cb4SJed Brown 
11084df9cb4SJed Brown   Level: developer
11184df9cb4SJed Brown 
11284df9cb4SJed Brown .keywords: TSAdapt, initialize, package
11384df9cb4SJed Brown .seealso: PetscInitialize()
11484df9cb4SJed Brown @*/
115607a6623SBarry Smith PetscErrorCode  TSAdaptInitializePackage(void)
11684df9cb4SJed Brown {
11784df9cb4SJed Brown   PetscErrorCode ierr;
11884df9cb4SJed Brown 
11984df9cb4SJed Brown   PetscFunctionBegin;
12084df9cb4SJed Brown   if (TSAdaptPackageInitialized) PetscFunctionReturn(0);
12184df9cb4SJed Brown   TSAdaptPackageInitialized = PETSC_TRUE;
12284df9cb4SJed Brown   ierr = PetscClassIdRegister("TSAdapt",&TSADAPT_CLASSID);CHKERRQ(ierr);
123607a6623SBarry Smith   ierr = TSAdaptRegisterAll();CHKERRQ(ierr);
12484df9cb4SJed Brown   ierr = PetscRegisterFinalize(TSAdaptFinalizePackage);CHKERRQ(ierr);
12584df9cb4SJed Brown   PetscFunctionReturn(0);
12684df9cb4SJed Brown }
12784df9cb4SJed Brown 
12884df9cb4SJed Brown #undef __FUNCT__
12984df9cb4SJed Brown #define __FUNCT__ "TSAdaptSetType"
1307eef6055SBarry Smith /*@C
1317eef6055SBarry Smith   TSAdaptSetType - sets the approach used for the error adapter, currently there is only TSADAPTBASIC and TSADAPTNONE
1327eef6055SBarry Smith 
1337eef6055SBarry Smith   Logicially Collective on TSAdapt
1347eef6055SBarry Smith 
1357eef6055SBarry Smith   Input Parameter:
1367eef6055SBarry Smith + adapt - the TS error adapter, most likely obtained with TSGetAdapt()
1377eef6055SBarry Smith - type - either  TSADAPTBASIC or TSADAPTNONE
1387eef6055SBarry Smith 
1397eef6055SBarry Smith   Options Database:
1407eef6055SBarry Smith .  -ts_adapt_type basic or none - to setting the adapter type
1417eef6055SBarry Smith 
1427eef6055SBarry Smith   Level: intermediate
1437eef6055SBarry Smith 
1447eef6055SBarry Smith .keywords: TSAdapt, create
1457eef6055SBarry Smith 
1467eef6055SBarry Smith .seealso: TSGetAdapt(), TSAdaptDestroy(), TSAdaptType, TSAdaptGetType()
1477eef6055SBarry Smith @*/
14819fd82e9SBarry Smith PetscErrorCode  TSAdaptSetType(TSAdapt adapt,TSAdaptType type)
14984df9cb4SJed Brown {
150ef749922SLisandro Dalcin   PetscBool      match;
15184df9cb4SJed Brown   PetscErrorCode ierr,(*r)(TSAdapt);
15284df9cb4SJed Brown 
15384df9cb4SJed Brown   PetscFunctionBegin;
1544782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
155ef749922SLisandro Dalcin   ierr = PetscObjectTypeCompare((PetscObject)adapt,type,&match);CHKERRQ(ierr);
156ef749922SLisandro Dalcin   if (match) PetscFunctionReturn(0);
1571c9cd337SJed Brown   ierr = PetscFunctionListFind(TSAdaptList,type,&r);CHKERRQ(ierr);
15884df9cb4SJed Brown   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TSAdapt type \"%s\" given",type);
159ef749922SLisandro Dalcin   if (adapt->ops->destroy) {ierr = (*adapt->ops->destroy)(adapt);CHKERRQ(ierr);}
1604cefc2ffSBarry Smith   ierr = PetscMemzero(adapt->ops,sizeof(struct _TSAdaptOps));CHKERRQ(ierr);
16184df9cb4SJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)adapt,type);CHKERRQ(ierr);
16268ae941aSLisandro Dalcin   ierr = (*r)(adapt);CHKERRQ(ierr);
16384df9cb4SJed Brown   PetscFunctionReturn(0);
16484df9cb4SJed Brown }
16584df9cb4SJed Brown 
16684df9cb4SJed Brown #undef __FUNCT__
16784df9cb4SJed Brown #define __FUNCT__ "TSAdaptSetOptionsPrefix"
16884df9cb4SJed Brown PetscErrorCode  TSAdaptSetOptionsPrefix(TSAdapt adapt,const char prefix[])
16984df9cb4SJed Brown {
17084df9cb4SJed Brown   PetscErrorCode ierr;
17184df9cb4SJed Brown 
17284df9cb4SJed Brown   PetscFunctionBegin;
1734782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
17484df9cb4SJed Brown   ierr = PetscObjectSetOptionsPrefix((PetscObject)adapt,prefix);CHKERRQ(ierr);
17584df9cb4SJed Brown   PetscFunctionReturn(0);
17684df9cb4SJed Brown }
17784df9cb4SJed Brown 
17884df9cb4SJed Brown #undef __FUNCT__
179ad6bc421SBarry Smith #define __FUNCT__ "TSAdaptLoad"
180ad6bc421SBarry Smith /*@C
181ad6bc421SBarry Smith   TSAdaptLoad - Loads a TSAdapt that has been stored in binary  with TSAdaptView().
182ad6bc421SBarry Smith 
183ad6bc421SBarry Smith   Collective on PetscViewer
184ad6bc421SBarry Smith 
185ad6bc421SBarry Smith   Input Parameters:
186ad6bc421SBarry Smith + newdm - the newly loaded TSAdapt, this needs to have been created with TSAdaptCreate() or
187ad6bc421SBarry Smith            some related function before a call to TSAdaptLoad().
188ad6bc421SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
189ad6bc421SBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
190ad6bc421SBarry Smith 
191ad6bc421SBarry Smith    Level: intermediate
192ad6bc421SBarry Smith 
193ad6bc421SBarry Smith   Notes:
194ad6bc421SBarry Smith    The type is determined by the data in the file, any type set into the TSAdapt before this call is ignored.
195ad6bc421SBarry Smith 
196ad6bc421SBarry Smith   Notes for advanced users:
197ad6bc421SBarry Smith   Most users should not need to know the details of the binary storage
198ad6bc421SBarry Smith   format, since TSAdaptLoad() and TSAdaptView() completely hide these details.
199ad6bc421SBarry Smith   But for anyone who's interested, the standard binary matrix storage
200ad6bc421SBarry Smith   format is
201ad6bc421SBarry Smith .vb
202ad6bc421SBarry Smith      has not yet been determined
203ad6bc421SBarry Smith .ve
204ad6bc421SBarry Smith 
205ad6bc421SBarry Smith .seealso: PetscViewerBinaryOpen(), TSAdaptView(), MatLoad(), VecLoad()
206ad6bc421SBarry Smith @*/
2074782b174SLisandro Dalcin PetscErrorCode  TSAdaptLoad(TSAdapt adapt,PetscViewer viewer)
208ad6bc421SBarry Smith {
209ad6bc421SBarry Smith   PetscErrorCode ierr;
210ad6bc421SBarry Smith   PetscBool      isbinary;
211ad6bc421SBarry Smith   char           type[256];
212ad6bc421SBarry Smith 
213ad6bc421SBarry Smith   PetscFunctionBegin;
2144782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
215ad6bc421SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
216ad6bc421SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
217ad6bc421SBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
218ad6bc421SBarry Smith 
219060da220SMatthew G. Knepley   ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
2204782b174SLisandro Dalcin   ierr = TSAdaptSetType(adapt,type);CHKERRQ(ierr);
2214782b174SLisandro Dalcin   if (adapt->ops->load) {
2224782b174SLisandro Dalcin     ierr = (*adapt->ops->load)(adapt,viewer);CHKERRQ(ierr);
223ad6bc421SBarry Smith   }
224ad6bc421SBarry Smith   PetscFunctionReturn(0);
225ad6bc421SBarry Smith }
226ad6bc421SBarry Smith 
227ad6bc421SBarry Smith #undef __FUNCT__
22884df9cb4SJed Brown #define __FUNCT__ "TSAdaptView"
22984df9cb4SJed Brown PetscErrorCode  TSAdaptView(TSAdapt adapt,PetscViewer viewer)
23084df9cb4SJed Brown {
23184df9cb4SJed Brown   PetscErrorCode ierr;
232ad6bc421SBarry Smith   PetscBool      iascii,isbinary;
23384df9cb4SJed Brown 
23484df9cb4SJed Brown   PetscFunctionBegin;
2354782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
2364782b174SLisandro Dalcin   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)adapt),&viewer);CHKERRQ(ierr);}
2374782b174SLisandro Dalcin   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
2384782b174SLisandro Dalcin   PetscCheckSameComm(adapt,1,viewer,2);
239251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
240ad6bc421SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
24184df9cb4SJed Brown   if (iascii) {
242dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)adapt,viewer);CHKERRQ(ierr);
24384df9cb4SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  number of candidates %D\n",adapt->candidates.n);CHKERRQ(ierr);
24484df9cb4SJed Brown     if (adapt->ops->view) {
24584df9cb4SJed Brown       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
24684df9cb4SJed Brown       ierr = (*adapt->ops->view)(adapt,viewer);CHKERRQ(ierr);
24784df9cb4SJed Brown       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
24884df9cb4SJed Brown     }
249ad6bc421SBarry Smith   } else if (isbinary) {
250ad6bc421SBarry Smith     char type[256];
251ad6bc421SBarry Smith 
252ad6bc421SBarry Smith     /* need to save FILE_CLASS_ID for adapt class */
253ad6bc421SBarry Smith     ierr = PetscStrncpy(type,((PetscObject)adapt)->type_name,256);CHKERRQ(ierr);
254ad6bc421SBarry Smith     ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
255bbd56ea5SKarl Rupp   } else if (adapt->ops->view) {
256f2c2a1b9SBarry Smith     ierr = (*adapt->ops->view)(adapt,viewer);CHKERRQ(ierr);
257f2c2a1b9SBarry Smith   }
25884df9cb4SJed Brown   PetscFunctionReturn(0);
25984df9cb4SJed Brown }
26084df9cb4SJed Brown 
26184df9cb4SJed Brown #undef __FUNCT__
262099af0a3SLisandro Dalcin #define __FUNCT__ "TSAdaptReset"
263099af0a3SLisandro Dalcin /*@
264099af0a3SLisandro Dalcin    TSAdaptReset - Resets a TSAdapt context.
265099af0a3SLisandro Dalcin 
266099af0a3SLisandro Dalcin    Collective on TS
267099af0a3SLisandro Dalcin 
268099af0a3SLisandro Dalcin    Input Parameter:
269099af0a3SLisandro Dalcin .  adapt - the TSAdapt context obtained from TSAdaptCreate()
270099af0a3SLisandro Dalcin 
271099af0a3SLisandro Dalcin    Level: developer
272099af0a3SLisandro Dalcin 
273099af0a3SLisandro Dalcin .seealso: TSAdaptCreate(), TSAdaptDestroy()
274099af0a3SLisandro Dalcin @*/
275099af0a3SLisandro Dalcin PetscErrorCode  TSAdaptReset(TSAdapt adapt)
276099af0a3SLisandro Dalcin {
277099af0a3SLisandro Dalcin   PetscErrorCode ierr;
278099af0a3SLisandro Dalcin 
279099af0a3SLisandro Dalcin   PetscFunctionBegin;
280099af0a3SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
281099af0a3SLisandro Dalcin   if (adapt->ops->reset) {ierr = (*adapt->ops->reset)(adapt);CHKERRQ(ierr);}
282099af0a3SLisandro Dalcin   PetscFunctionReturn(0);
283099af0a3SLisandro Dalcin }
284099af0a3SLisandro Dalcin 
285099af0a3SLisandro Dalcin #undef __FUNCT__
28684df9cb4SJed Brown #define __FUNCT__ "TSAdaptDestroy"
28784df9cb4SJed Brown PetscErrorCode  TSAdaptDestroy(TSAdapt *adapt)
28884df9cb4SJed Brown {
28984df9cb4SJed Brown   PetscErrorCode ierr;
29084df9cb4SJed Brown 
29184df9cb4SJed Brown   PetscFunctionBegin;
29284df9cb4SJed Brown   if (!*adapt) PetscFunctionReturn(0);
29384df9cb4SJed Brown   PetscValidHeaderSpecific(*adapt,TSADAPT_CLASSID,1);
2944782b174SLisandro Dalcin   if (--((PetscObject)(*adapt))->refct > 0) {*adapt = NULL; PetscFunctionReturn(0);}
295099af0a3SLisandro Dalcin 
296099af0a3SLisandro Dalcin   ierr = TSAdaptReset(*adapt);CHKERRQ(ierr);
297099af0a3SLisandro Dalcin 
29884df9cb4SJed Brown   if ((*adapt)->ops->destroy) {ierr = (*(*adapt)->ops->destroy)(*adapt);CHKERRQ(ierr);}
2991c3436cfSJed Brown   ierr = PetscViewerDestroy(&(*adapt)->monitor);CHKERRQ(ierr);
30084df9cb4SJed Brown   ierr = PetscHeaderDestroy(adapt);CHKERRQ(ierr);
30184df9cb4SJed Brown   PetscFunctionReturn(0);
30284df9cb4SJed Brown }
30384df9cb4SJed Brown 
30484df9cb4SJed Brown #undef __FUNCT__
3051c3436cfSJed Brown #define __FUNCT__ "TSAdaptSetMonitor"
3061c3436cfSJed Brown /*@
3071c3436cfSJed Brown    TSAdaptSetMonitor - Monitor the choices made by the adaptive controller
3081c3436cfSJed Brown 
3091c3436cfSJed Brown    Collective on TSAdapt
3101c3436cfSJed Brown 
3111c3436cfSJed Brown    Input Arguments:
3121c3436cfSJed Brown +  adapt - adaptive controller context
3131c3436cfSJed Brown -  flg - PETSC_TRUE to active a monitor, PETSC_FALSE to disable
3141c3436cfSJed Brown 
3151c3436cfSJed Brown    Level: intermediate
3161c3436cfSJed Brown 
3171c3436cfSJed Brown .seealso: TSAdaptChoose()
3181c3436cfSJed Brown @*/
3191c3436cfSJed Brown PetscErrorCode TSAdaptSetMonitor(TSAdapt adapt,PetscBool flg)
3201c3436cfSJed Brown {
3211c3436cfSJed Brown   PetscErrorCode ierr;
3221c3436cfSJed Brown 
3231c3436cfSJed Brown   PetscFunctionBegin;
3244782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
3254782b174SLisandro Dalcin   PetscValidLogicalCollectiveBool(adapt,flg,2);
3261c3436cfSJed Brown   if (flg) {
327ce94432eSBarry Smith     if (!adapt->monitor) {ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)adapt),"stdout",&adapt->monitor);CHKERRQ(ierr);}
3281c3436cfSJed Brown   } else {
3291c3436cfSJed Brown     ierr = PetscViewerDestroy(&adapt->monitor);CHKERRQ(ierr);
3301c3436cfSJed Brown   }
3311c3436cfSJed Brown   PetscFunctionReturn(0);
3321c3436cfSJed Brown }
3331c3436cfSJed Brown 
3341c3436cfSJed Brown #undef __FUNCT__
3350873808bSJed Brown #define __FUNCT__ "TSAdaptSetCheckStage"
3360873808bSJed Brown /*@C
3370873808bSJed Brown    TSAdaptSetCheckStage - set a callback to check convergence for a stage
3380873808bSJed Brown 
3390873808bSJed Brown    Logically collective on TSAdapt
3400873808bSJed Brown 
3410873808bSJed Brown    Input Arguments:
3420873808bSJed Brown +  adapt - adaptive controller context
3430873808bSJed Brown -  func - stage check function
3440873808bSJed Brown 
3450873808bSJed Brown    Arguments of func:
3460873808bSJed Brown $  PetscErrorCode func(TSAdapt adapt,TS ts,PetscBool *accept)
3470873808bSJed Brown 
3480873808bSJed Brown +  adapt - adaptive controller context
3490873808bSJed Brown .  ts - time stepping context
3500873808bSJed Brown -  accept - pending choice of whether to accept, can be modified by this routine
3510873808bSJed Brown 
3520873808bSJed Brown    Level: advanced
3530873808bSJed Brown 
3540873808bSJed Brown .seealso: TSAdaptChoose()
3550873808bSJed Brown @*/
356b295832fSPierre Barbier de Reuille PetscErrorCode TSAdaptSetCheckStage(TSAdapt adapt,PetscErrorCode (*func)(TSAdapt,TS,PetscReal,Vec,PetscBool*))
3570873808bSJed Brown {
3580873808bSJed Brown 
3590873808bSJed Brown   PetscFunctionBegin;
3600873808bSJed Brown   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
36168ae941aSLisandro Dalcin   adapt->checkstage = func;
3620873808bSJed Brown   PetscFunctionReturn(0);
3630873808bSJed Brown }
3640873808bSJed Brown 
3650873808bSJed Brown #undef __FUNCT__
3661c3436cfSJed Brown #define __FUNCT__ "TSAdaptSetStepLimits"
3671c3436cfSJed Brown /*@
3681c3436cfSJed Brown    TSAdaptSetStepLimits - Set minimum and maximum step sizes to be considered by the controller
3691c3436cfSJed Brown 
3701c3436cfSJed Brown    Logically Collective
3711c3436cfSJed Brown 
3721c3436cfSJed Brown    Input Arguments:
373552698daSJed Brown +  adapt - time step adaptivity context, usually gotten with TSGetAdapt()
3741c3436cfSJed Brown .  hmin - minimum time step
3751c3436cfSJed Brown -  hmax - maximum time step
3761c3436cfSJed Brown 
3771c3436cfSJed Brown    Options Database Keys:
3781c3436cfSJed Brown +  -ts_adapt_dt_min - minimum time step
3791c3436cfSJed Brown -  -ts_adapt_dt_max - maximum time step
3801c3436cfSJed Brown 
3811c3436cfSJed Brown    Level: intermediate
3821c3436cfSJed Brown 
3831c3436cfSJed Brown .seealso: TSAdapt
3841c3436cfSJed Brown @*/
3851c3436cfSJed Brown PetscErrorCode TSAdaptSetStepLimits(TSAdapt adapt,PetscReal hmin,PetscReal hmax)
3861c3436cfSJed Brown {
3871c3436cfSJed Brown 
3881c3436cfSJed Brown   PetscFunctionBegin;
3894782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
390b1f5bccaSLisandro Dalcin   PetscValidLogicalCollectiveReal(adapt,hmin,2);
391b1f5bccaSLisandro Dalcin   PetscValidLogicalCollectiveReal(adapt,hmax,3);
392b1f5bccaSLisandro Dalcin   if (hmin != PETSC_DEFAULT && hmin < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Minimum time step %g must be non negative",(double)hmin);
393b1f5bccaSLisandro Dalcin   if (hmax != PETSC_DEFAULT && hmax < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Minimum time step %g must be non negative",(double)hmax);
394b1f5bccaSLisandro Dalcin   if (hmin != PETSC_DEFAULT) adapt->dt_min = hmin;
395b1f5bccaSLisandro Dalcin   if (hmax != PETSC_DEFAULT) adapt->dt_max = hmax;
396b1f5bccaSLisandro Dalcin #if defined(PETSC_USE_DEBUG)
397b1f5bccaSLisandro Dalcin   hmin = adapt->dt_min;
398b1f5bccaSLisandro Dalcin   hmax = adapt->dt_max;
399b1f5bccaSLisandro Dalcin   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);
400b1f5bccaSLisandro Dalcin #endif
4011c3436cfSJed Brown   PetscFunctionReturn(0);
4021c3436cfSJed Brown }
4031c3436cfSJed Brown 
4041c3436cfSJed Brown #undef __FUNCT__
40584df9cb4SJed Brown #define __FUNCT__ "TSAdaptSetFromOptions"
406e55864a3SBarry Smith /*
40784df9cb4SJed Brown    TSAdaptSetFromOptions - Sets various TSAdapt parameters from user options.
40884df9cb4SJed Brown 
40984df9cb4SJed Brown    Collective on TSAdapt
41084df9cb4SJed Brown 
41184df9cb4SJed Brown    Input Parameter:
41284df9cb4SJed Brown .  adapt - the TSAdapt context
41384df9cb4SJed Brown 
41484df9cb4SJed Brown    Options Database Keys:
41584df9cb4SJed Brown .  -ts_adapt_type <type> - basic
41684df9cb4SJed Brown 
41784df9cb4SJed Brown    Level: advanced
41884df9cb4SJed Brown 
41984df9cb4SJed Brown    Notes:
42084df9cb4SJed Brown    This function is automatically called by TSSetFromOptions()
42184df9cb4SJed Brown 
422552698daSJed Brown .keywords: TS, TSGetAdapt(), TSAdaptSetType()
42384df9cb4SJed Brown 
42484df9cb4SJed Brown .seealso: TSGetType()
425e55864a3SBarry Smith */
4264416b707SBarry Smith PetscErrorCode  TSAdaptSetFromOptions(PetscOptionItems *PetscOptionsObject,TSAdapt adapt)
42784df9cb4SJed Brown {
42884df9cb4SJed Brown   PetscErrorCode ierr;
42984df9cb4SJed Brown   char           type[256] = TSADAPTBASIC;
4301c3436cfSJed Brown   PetscBool      set,flg;
43184df9cb4SJed Brown 
43284df9cb4SJed Brown   PetscFunctionBegin;
4334782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
43484df9cb4SJed Brown   /* This should use PetscOptionsBegin() if/when this becomes an object used outside of TS, but currently this
4351566a47fSLisandro Dalcin    * function can only be called from inside TSSetFromOptions()  */
436e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"TS Adaptivity options");CHKERRQ(ierr);
437a264d7a6SBarry Smith   ierr = PetscOptionsFList("-ts_adapt_type","Algorithm to use for adaptivity","TSAdaptSetType",TSAdaptList,
4388caf3d72SBarry Smith                           ((PetscObject)adapt)->type_name ? ((PetscObject)adapt)->type_name : type,type,sizeof(type),&flg);CHKERRQ(ierr);
43984df9cb4SJed Brown   if (flg || !((PetscObject)adapt)->type_name) {
44084df9cb4SJed Brown     ierr = TSAdaptSetType(adapt,type);CHKERRQ(ierr);
44184df9cb4SJed Brown   }
4420298fd71SBarry Smith   ierr = PetscOptionsReal("-ts_adapt_dt_min","Minimum time step considered","TSAdaptSetStepLimits",adapt->dt_min,&adapt->dt_min,NULL);CHKERRQ(ierr);
4430298fd71SBarry Smith   ierr = PetscOptionsReal("-ts_adapt_dt_max","Maximum time step considered","TSAdaptSetStepLimits",adapt->dt_max,&adapt->dt_max,NULL);CHKERRQ(ierr);
4440298fd71SBarry Smith   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);
4451c3436cfSJed Brown   ierr = PetscOptionsBool("-ts_adapt_monitor","Print choices made by adaptive controller","TSAdaptSetMonitor",adapt->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
4467619abb3SShri   ierr = PetscOptionsEnum("-ts_adapt_wnormtype","Type of norm computed for error estimation","",NormTypes,(PetscEnum)adapt->wnormtype,(PetscEnum*)&adapt->wnormtype,NULL);CHKERRQ(ierr);
4477619abb3SShri   if (adapt->wnormtype != NORM_2 && adapt->wnormtype != NORM_INFINITY) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_SUP,"Only 2-norm and infinite norm supported");
4481c3436cfSJed Brown   if (set) {ierr = TSAdaptSetMonitor(adapt,flg);CHKERRQ(ierr);}
449e55864a3SBarry Smith   if (adapt->ops->setfromoptions) {ierr = (*adapt->ops->setfromoptions)(PetscOptionsObject,adapt);CHKERRQ(ierr);}
45084df9cb4SJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
45184df9cb4SJed Brown   PetscFunctionReturn(0);
45284df9cb4SJed Brown }
45384df9cb4SJed Brown 
45484df9cb4SJed Brown #undef __FUNCT__
45584df9cb4SJed Brown #define __FUNCT__ "TSAdaptCandidatesClear"
45684df9cb4SJed Brown /*@
45784df9cb4SJed Brown    TSAdaptCandidatesClear - clear any previously set candidate schemes
45884df9cb4SJed Brown 
45984df9cb4SJed Brown    Logically Collective
46084df9cb4SJed Brown 
46184df9cb4SJed Brown    Input Argument:
46284df9cb4SJed Brown .  adapt - adaptive controller
46384df9cb4SJed Brown 
46484df9cb4SJed Brown    Level: developer
46584df9cb4SJed Brown 
46684df9cb4SJed Brown .seealso: TSAdapt, TSAdaptCreate(), TSAdaptCandidateAdd(), TSAdaptChoose()
46784df9cb4SJed Brown @*/
46884df9cb4SJed Brown PetscErrorCode TSAdaptCandidatesClear(TSAdapt adapt)
46984df9cb4SJed Brown {
47084df9cb4SJed Brown   PetscErrorCode ierr;
47184df9cb4SJed Brown 
47284df9cb4SJed Brown   PetscFunctionBegin;
4734782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
47484df9cb4SJed Brown   ierr = PetscMemzero(&adapt->candidates,sizeof(adapt->candidates));CHKERRQ(ierr);
47584df9cb4SJed Brown   PetscFunctionReturn(0);
47684df9cb4SJed Brown }
47784df9cb4SJed Brown 
47884df9cb4SJed Brown #undef __FUNCT__
47984df9cb4SJed Brown #define __FUNCT__ "TSAdaptCandidateAdd"
48084df9cb4SJed Brown /*@C
48184df9cb4SJed Brown    TSAdaptCandidateAdd - add a candidate scheme for the adaptive controller to select from
48284df9cb4SJed Brown 
48384df9cb4SJed Brown    Logically Collective
48484df9cb4SJed Brown 
48584df9cb4SJed Brown    Input Arguments:
486552698daSJed Brown +  adapt - time step adaptivity context, obtained with TSGetAdapt() or TSAdaptCreate()
48784df9cb4SJed Brown .  name - name of the candidate scheme to add
48884df9cb4SJed Brown .  order - order of the candidate scheme
48984df9cb4SJed Brown .  stageorder - stage order of the candidate scheme
4908d59e960SJed Brown .  ccfl - stability coefficient relative to explicit Euler, used for CFL constraints
49184df9cb4SJed Brown .  cost - relative measure of the amount of work required for the candidate scheme
49284df9cb4SJed Brown -  inuse - indicates that this scheme is the one currently in use, this flag can only be set for one scheme
49384df9cb4SJed Brown 
49484df9cb4SJed Brown    Note:
49584df9cb4SJed Brown    This routine is not available in Fortran.
49684df9cb4SJed Brown 
49784df9cb4SJed Brown    Level: developer
49884df9cb4SJed Brown 
49984df9cb4SJed Brown .seealso: TSAdaptCandidatesClear(), TSAdaptChoose()
50084df9cb4SJed Brown @*/
5018d59e960SJed Brown PetscErrorCode TSAdaptCandidateAdd(TSAdapt adapt,const char name[],PetscInt order,PetscInt stageorder,PetscReal ccfl,PetscReal cost,PetscBool inuse)
50284df9cb4SJed Brown {
50384df9cb4SJed Brown   PetscInt c;
50484df9cb4SJed Brown 
50584df9cb4SJed Brown   PetscFunctionBegin;
50684df9cb4SJed Brown   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
507ce94432eSBarry Smith   if (order < 1) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Classical order %D must be a positive integer",order);
50884df9cb4SJed Brown   if (inuse) {
509ce94432eSBarry Smith     if (adapt->candidates.inuse_set) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_WRONGSTATE,"Cannot set the inuse method twice, maybe forgot to call TSAdaptCandidatesClear()");
51084df9cb4SJed Brown     adapt->candidates.inuse_set = PETSC_TRUE;
51184df9cb4SJed Brown   }
5121c3436cfSJed Brown   /* first slot if this is the current scheme, otherwise the next available slot */
5131c3436cfSJed Brown   c = inuse ? 0 : !adapt->candidates.inuse_set + adapt->candidates.n;
514bbd56ea5SKarl Rupp 
51584df9cb4SJed Brown   adapt->candidates.name[c]       = name;
51684df9cb4SJed Brown   adapt->candidates.order[c]      = order;
51784df9cb4SJed Brown   adapt->candidates.stageorder[c] = stageorder;
5188d59e960SJed Brown   adapt->candidates.ccfl[c]       = ccfl;
51984df9cb4SJed Brown   adapt->candidates.cost[c]       = cost;
52084df9cb4SJed Brown   adapt->candidates.n++;
52184df9cb4SJed Brown   PetscFunctionReturn(0);
52284df9cb4SJed Brown }
52384df9cb4SJed Brown 
52484df9cb4SJed Brown #undef __FUNCT__
5258d59e960SJed Brown #define __FUNCT__ "TSAdaptCandidatesGet"
5268d59e960SJed Brown /*@C
5278d59e960SJed Brown    TSAdaptCandidatesGet - Get the list of candidate orders of accuracy and cost
5288d59e960SJed Brown 
5298d59e960SJed Brown    Not Collective
5308d59e960SJed Brown 
5318d59e960SJed Brown    Input Arguments:
5328d59e960SJed Brown .  adapt - time step adaptivity context
5338d59e960SJed Brown 
5348d59e960SJed Brown    Output Arguments:
5358d59e960SJed Brown +  n - number of candidate schemes, always at least 1
5368d59e960SJed Brown .  order - the order of each candidate scheme
5378d59e960SJed Brown .  stageorder - the stage order of each candidate scheme
5388d59e960SJed Brown .  ccfl - the CFL coefficient of each scheme
5398d59e960SJed Brown -  cost - the relative cost of each scheme
5408d59e960SJed Brown 
5418d59e960SJed Brown    Level: developer
5428d59e960SJed Brown 
5438d59e960SJed Brown    Note:
5448d59e960SJed Brown    The current scheme is always returned in the first slot
5458d59e960SJed Brown 
5468d59e960SJed Brown .seealso: TSAdaptCandidatesClear(), TSAdaptCandidateAdd(), TSAdaptChoose()
5478d59e960SJed Brown @*/
5488d59e960SJed Brown PetscErrorCode TSAdaptCandidatesGet(TSAdapt adapt,PetscInt *n,const PetscInt **order,const PetscInt **stageorder,const PetscReal **ccfl,const PetscReal **cost)
5498d59e960SJed Brown {
5508d59e960SJed Brown   PetscFunctionBegin;
5518d59e960SJed Brown   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
5528d59e960SJed Brown   if (n) *n = adapt->candidates.n;
5538d59e960SJed Brown   if (order) *order = adapt->candidates.order;
5548d59e960SJed Brown   if (stageorder) *stageorder = adapt->candidates.stageorder;
5558d59e960SJed Brown   if (ccfl) *ccfl = adapt->candidates.ccfl;
5568d59e960SJed Brown   if (cost) *cost = adapt->candidates.cost;
5578d59e960SJed Brown   PetscFunctionReturn(0);
5588d59e960SJed Brown }
5598d59e960SJed Brown 
5608d59e960SJed Brown #undef __FUNCT__
56184df9cb4SJed Brown #define __FUNCT__ "TSAdaptChoose"
56284df9cb4SJed Brown /*@C
56384df9cb4SJed Brown    TSAdaptChoose - choose which method and step size to use for the next step
56484df9cb4SJed Brown 
56584df9cb4SJed Brown    Logically Collective
56684df9cb4SJed Brown 
56784df9cb4SJed Brown    Input Arguments:
56884df9cb4SJed Brown +  adapt - adaptive contoller
56984df9cb4SJed Brown -  h - current step size
57084df9cb4SJed Brown 
57184df9cb4SJed Brown    Output Arguments:
5721566a47fSLisandro Dalcin +  next_sc - optional, scheme to use for the next step
57384df9cb4SJed Brown .  next_h - step size to use for the next step
57484df9cb4SJed Brown -  accept - PETSC_TRUE to accept the current step, PETSC_FALSE to repeat the current step with the new step size
57584df9cb4SJed Brown 
5761c3436cfSJed Brown    Note:
5771c3436cfSJed Brown    The input value of parameter accept is retained from the last time step, so it will be PETSC_FALSE if the step is
5781c3436cfSJed Brown    being retried after an initial rejection.
5791c3436cfSJed Brown 
58084df9cb4SJed Brown    Level: developer
58184df9cb4SJed Brown 
58284df9cb4SJed Brown .seealso: TSAdapt, TSAdaptCandidatesClear(), TSAdaptCandidateAdd()
58384df9cb4SJed Brown @*/
58484df9cb4SJed Brown PetscErrorCode TSAdaptChoose(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept)
58584df9cb4SJed Brown {
58684df9cb4SJed Brown   PetscErrorCode ierr;
5871566a47fSLisandro Dalcin   PetscInt       ncandidates = adapt->candidates.n;
5881566a47fSLisandro Dalcin   PetscInt       scheme = 0;
5890b99f514SJed Brown   PetscReal      wlte = -1.0;
590*5e4ed32fSEmil Constantinescu   PetscReal      wltea = -1.0;
591*5e4ed32fSEmil Constantinescu   PetscReal      wlter = -1.0;
59284df9cb4SJed Brown 
59384df9cb4SJed Brown   PetscFunctionBegin;
59484df9cb4SJed Brown   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
59584df9cb4SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
5961566a47fSLisandro Dalcin   if (next_sc) PetscValidIntPointer(next_sc,4);
59784df9cb4SJed Brown   PetscValidPointer(next_h,5);
59884df9cb4SJed Brown   PetscValidIntPointer(accept,6);
5991566a47fSLisandro Dalcin   if (next_sc) *next_sc = 0;
6001566a47fSLisandro Dalcin 
6011566a47fSLisandro Dalcin   /* Do not mess with adaptivity while handling events*/
6021566a47fSLisandro Dalcin   if (ts->event && ts->event->status != TSEVENT_NONE) {
6031566a47fSLisandro Dalcin     *next_h = h;
6041566a47fSLisandro Dalcin     *accept = PETSC_TRUE;
6051566a47fSLisandro Dalcin     PetscFunctionReturn(0);
6061566a47fSLisandro Dalcin   }
6071566a47fSLisandro Dalcin 
608*5e4ed32fSEmil Constantinescu   ierr = (*adapt->ops->choose)(adapt,ts,h,&scheme,next_h,accept,&wlte,&wltea,&wlter);CHKERRQ(ierr);
6091566a47fSLisandro Dalcin   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);
6101566a47fSLisandro Dalcin   if (*next_h < 0) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Computed step size %g must be positive",(double)*next_h);
6111566a47fSLisandro Dalcin   if (next_sc) *next_sc = scheme;
6121566a47fSLisandro Dalcin 
61349354f04SShri Abhyankar   if (*accept && ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) {
61449354f04SShri Abhyankar     /* Reduce time step if it overshoots max time */
6151566a47fSLisandro Dalcin     if (ts->ptime + ts->time_step + *next_h >= ts->max_time) {
6161566a47fSLisandro Dalcin       PetscReal next_dt = ts->max_time - (ts->ptime + ts->time_step);
6178709b12bSShri Abhyankar       if (next_dt > PETSC_SMALL) *next_h = next_dt;
61849354f04SShri Abhyankar       else ts->reason = TS_CONVERGED_TIME;
61949354f04SShri Abhyankar     }
62049354f04SShri Abhyankar   }
6211c3436cfSJed Brown 
6221c3436cfSJed Brown   if (adapt->monitor) {
6231566a47fSLisandro Dalcin     const char *sc_name = (scheme < ncandidates) ? adapt->candidates.name[scheme] : "";
6241c3436cfSJed Brown     ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
6250b99f514SJed Brown     if (wlte < 0) {
6261566a47fSLisandro Dalcin       ierr = PetscViewerASCIIPrintf(adapt->monitor,"    TSAdapt '%s': step %3D %s t=%-11g+%10.3e family='%s' scheme=%D:'%s' dt=%-10.3e\n",((PetscObject)adapt)->type_name,ts->steps,*accept ? "accepted" : "rejected",(double)ts->ptime,(double)h,((PetscObject)ts)->type_name,scheme,sc_name,(double)*next_h);CHKERRQ(ierr);
6270b99f514SJed Brown     } else {
6281566a47fSLisandro Dalcin       ierr = PetscViewerASCIIPrintf(adapt->monitor,"    TSAdapt '%s': step %3D %s t=%-11g+%10.3e wlte=%5.3g family='%s' scheme=%D:'%s' dt=%-10.3e\n",((PetscObject)adapt)->type_name,ts->steps,*accept ? "accepted" : "rejected",(double)ts->ptime,(double)h,(double)wlte,((PetscObject)ts)->type_name,scheme,sc_name,(double)*next_h);CHKERRQ(ierr);
6290b99f514SJed Brown     }
6301c3436cfSJed Brown     ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
6311c3436cfSJed Brown   }
63284df9cb4SJed Brown   PetscFunctionReturn(0);
63384df9cb4SJed Brown }
63484df9cb4SJed Brown 
63584df9cb4SJed Brown #undef __FUNCT__
63697335746SJed Brown #define __FUNCT__ "TSAdaptCheckStage"
63797335746SJed Brown /*@
63897335746SJed Brown    TSAdaptCheckStage - checks whether to accept a stage, (e.g. reject and change time step size if nonlinear solve fails)
63997335746SJed Brown 
64097335746SJed Brown    Collective
64197335746SJed Brown 
64297335746SJed Brown    Input Arguments:
64397335746SJed Brown +  adapt - adaptive controller context
644b295832fSPierre Barbier de Reuille .  ts - time stepper
645b295832fSPierre Barbier de Reuille .  t - Current simulation time
646b295832fSPierre Barbier de Reuille -  Y - Current solution vector
64797335746SJed Brown 
64897335746SJed Brown    Output Arguments:
64997335746SJed Brown .  accept - PETSC_TRUE to accept the stage, PETSC_FALSE to reject
65097335746SJed Brown 
65197335746SJed Brown    Level: developer
65297335746SJed Brown 
65397335746SJed Brown .seealso:
65497335746SJed Brown @*/
655b295832fSPierre Barbier de Reuille PetscErrorCode TSAdaptCheckStage(TSAdapt adapt,TS ts,PetscReal t,Vec Y,PetscBool *accept)
65697335746SJed Brown {
65797335746SJed Brown   PetscErrorCode      ierr;
6581566a47fSLisandro Dalcin   SNESConvergedReason snesreason = SNES_CONVERGED_ITERATING;
65997335746SJed Brown 
66097335746SJed Brown   PetscFunctionBegin;
6614782b174SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
6624782b174SLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
6634782b174SLisandro Dalcin   PetscValidIntPointer(accept,3);
6641566a47fSLisandro Dalcin 
6651566a47fSLisandro Dalcin   if (ts->snes) {ierr = SNESGetConvergedReason(ts->snes,&snesreason);CHKERRQ(ierr);}
66697335746SJed Brown   if (snesreason < 0) {
66797335746SJed Brown     *accept = PETSC_FALSE;
6686de24e2aSJed Brown     if (++ts->num_snes_failures >= ts->max_snes_failures && ts->max_snes_failures > 0) {
66997335746SJed Brown       ts->reason = TS_DIVERGED_NONLINEAR_SOLVE;
67048c19aefSLisandro Dalcin       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);
67197335746SJed Brown       if (adapt->monitor) {
67297335746SJed Brown         ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
6731566a47fSLisandro Dalcin         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);
67497335746SJed Brown         ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
67597335746SJed Brown       }
676cb9d8021SPierre Barbier de Reuille     }
677cb9d8021SPierre Barbier de Reuille   } else {
6781566a47fSLisandro Dalcin     *accept = PETSC_TRUE;
679b295832fSPierre Barbier de Reuille     ierr = TSFunctionDomainError(ts,t,Y,accept);CHKERRQ(ierr);
680cb9d8021SPierre Barbier de Reuille     if(*accept && adapt->checkstage) {
681b295832fSPierre Barbier de Reuille       ierr = (*adapt->checkstage)(adapt,ts,t,Y,accept);CHKERRQ(ierr);
682cb9d8021SPierre Barbier de Reuille     }
683cb9d8021SPierre Barbier de Reuille   }
684cb9d8021SPierre Barbier de Reuille 
6851566a47fSLisandro Dalcin   if(!(*accept) && !ts->reason) {
6861566a47fSLisandro Dalcin     PetscReal dt,new_dt;
6871566a47fSLisandro Dalcin     ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr);
688cb9d8021SPierre Barbier de Reuille     new_dt = dt * adapt->scale_solve_failed;
68997335746SJed Brown     ierr = TSSetTimeStep(ts,new_dt);CHKERRQ(ierr);
69097335746SJed Brown     if (adapt->monitor) {
69197335746SJed Brown       ierr = PetscViewerASCIIAddTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
69297335746SJed Brown       ierr = PetscViewerASCIIPrintf(adapt->monitor,"    TSAdapt '%s': step %3D stage rejected t=%-11g+%10.3e retrying with dt=%-10.3e\n",((PetscObject)adapt)->type_name,ts->steps,(double)ts->ptime,(double)dt,(double)new_dt);CHKERRQ(ierr);
69397335746SJed Brown       ierr = PetscViewerASCIISubtractTab(adapt->monitor,((PetscObject)adapt)->tablevel);CHKERRQ(ierr);
69497335746SJed Brown     }
69597335746SJed Brown   }
69697335746SJed Brown   PetscFunctionReturn(0);
69797335746SJed Brown }
69897335746SJed Brown 
69997335746SJed Brown #undef __FUNCT__
70084df9cb4SJed Brown #define __FUNCT__ "TSAdaptCreate"
70184df9cb4SJed Brown /*@
70284df9cb4SJed Brown   TSAdaptCreate - create an adaptive controller context for time stepping
70384df9cb4SJed Brown 
70484df9cb4SJed Brown   Collective on MPI_Comm
70584df9cb4SJed Brown 
70684df9cb4SJed Brown   Input Parameter:
70784df9cb4SJed Brown . comm - The communicator
70884df9cb4SJed Brown 
70984df9cb4SJed Brown   Output Parameter:
71084df9cb4SJed Brown . adapt - new TSAdapt object
71184df9cb4SJed Brown 
71284df9cb4SJed Brown   Level: developer
71384df9cb4SJed Brown 
71484df9cb4SJed Brown   Notes:
71584df9cb4SJed Brown   TSAdapt creation is handled by TS, so users should not need to call this function.
71684df9cb4SJed Brown 
71784df9cb4SJed Brown .keywords: TSAdapt, create
718552698daSJed Brown .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptDestroy()
71984df9cb4SJed Brown @*/
72084df9cb4SJed Brown PetscErrorCode  TSAdaptCreate(MPI_Comm comm,TSAdapt *inadapt)
72184df9cb4SJed Brown {
72284df9cb4SJed Brown   PetscErrorCode ierr;
72384df9cb4SJed Brown   TSAdapt        adapt;
72484df9cb4SJed Brown 
72584df9cb4SJed Brown   PetscFunctionBegin;
7263b3bcf4cSLisandro Dalcin   PetscValidPointer(inadapt,1);
7273b3bcf4cSLisandro Dalcin   *inadapt = NULL;
7283b3bcf4cSLisandro Dalcin   ierr = TSAdaptInitializePackage();CHKERRQ(ierr);
7293b3bcf4cSLisandro Dalcin 
73073107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(adapt,TSADAPT_CLASSID,"TSAdapt","Time stepping adaptivity","TS",comm,TSAdaptDestroy,TSAdaptView);CHKERRQ(ierr);
7311c3436cfSJed Brown 
7321c3436cfSJed Brown   adapt->dt_min             = 1e-20;
7331c3436cfSJed Brown   adapt->dt_max             = 1e50;
73497335746SJed Brown   adapt->scale_solve_failed = 0.25;
7357619abb3SShri   adapt->wnormtype          = NORM_2;
7367eef6055SBarry Smith   ierr = TSAdaptSetType(adapt,TSADAPTBASIC);CHKERRQ(ierr);
7371c3436cfSJed Brown 
73884df9cb4SJed Brown   *inadapt = adapt;
73984df9cb4SJed Brown   PetscFunctionReturn(0);
74084df9cb4SJed Brown }
741