xref: /petsc/src/ts/adapt/impls/basic/adaptbasic.c (revision e91eccc2778f456fc991f5a9b142a3a67738bfd5)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/
284df9cb4SJed Brown 
384df9cb4SJed Brown typedef struct {
41c3436cfSJed Brown   Vec Y;
584df9cb4SJed Brown } TSAdapt_Basic;
684df9cb4SJed Brown 
75e4ed32fSEmil Constantinescu static PetscErrorCode TSAdaptChoose_Basic(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept,PetscReal *wlte,PetscReal *wltea,PetscReal *wlter)
884df9cb4SJed Brown {
91c3436cfSJed Brown   TSAdapt_Basic  *basic = (TSAdapt_Basic*)adapt->data;
10b1f5bccaSLisandro Dalcin   PetscInt       order  = PETSC_DECIDE;
11b1f5bccaSLisandro Dalcin   PetscReal      enorm  = -1;
127453f775SEmil Constantinescu   PetscReal      enorma,enormr;
131917a363SLisandro Dalcin   PetscReal      safety = adapt->safety;
14b1f5bccaSLisandro Dalcin   PetscReal      hfac_lte,h_lte;
151c3436cfSJed Brown   PetscErrorCode ierr;
1684df9cb4SJed Brown 
1784df9cb4SJed Brown   PetscFunctionBegin;
181566a47fSLisandro Dalcin   *next_sc = 0;   /* Reuse the same order scheme */
19bf997491SLisandro Dalcin   *wltea   = -1;  /* Weighted absolute local truncation error is not used */
20bf997491SLisandro Dalcin   *wlter   = -1;  /* Weighted relative local truncation error is not used */
211566a47fSLisandro Dalcin 
221ebf93c6SLisandro Dalcin   if (ts->ops->evaluatewlte) {
231566a47fSLisandro Dalcin     ierr = TSEvaluateWLTE(ts,adapt->wnormtype,&order,&enorm);CHKERRQ(ierr);
241566a47fSLisandro Dalcin     if (enorm >= 0 && order < 1) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_OUTOFRANGE,"Computed error order %D must be positive",order);
251566a47fSLisandro Dalcin   } else if (ts->ops->evaluatestep) {
261566a47fSLisandro Dalcin     if (adapt->candidates.n < 1) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_WRONGSTATE,"No candidate has been registered");
271566a47fSLisandro Dalcin     if (!adapt->candidates.inuse_set) SETERRQ1(PetscObjectComm((PetscObject)adapt),PETSC_ERR_ARG_WRONGSTATE,"The current in-use scheme is not among the %D candidates",adapt->candidates.n);
281566a47fSLisandro Dalcin     if (!basic->Y) {ierr = VecDuplicate(ts->vec_sol,&basic->Y);CHKERRQ(ierr);}
291566a47fSLisandro Dalcin     order = adapt->candidates.order[0];
301ebf93c6SLisandro Dalcin     ierr = TSEvaluateStep(ts,order-1,basic->Y,NULL);CHKERRQ(ierr);
317453f775SEmil Constantinescu     ierr = TSErrorWeightedNorm(ts,ts->vec_sol,basic->Y,adapt->wnormtype,&enorm,&enorma,&enormr);CHKERRQ(ierr);
321ebf93c6SLisandro Dalcin   }
331c3436cfSJed Brown 
341566a47fSLisandro Dalcin   if (enorm < 0) {
351566a47fSLisandro Dalcin     *accept  = PETSC_TRUE;
361566a47fSLisandro Dalcin     *next_h  = h;            /* Reuse the old step */
371566a47fSLisandro Dalcin     *wlte    = -1;           /* Weighted local truncation error was not evaluated */
381566a47fSLisandro Dalcin     PetscFunctionReturn(0);
391566a47fSLisandro Dalcin   }
401566a47fSLisandro Dalcin 
411566a47fSLisandro Dalcin   /* Determine whether the step is accepted of rejected */
421566a47fSLisandro Dalcin   if (enorm > 1) {
431917a363SLisandro Dalcin     if (!*accept) safety *= adapt->reject_safety; /* The last attempt also failed, shorten more aggressively */
44fd94acc0SJed Brown     if (h < (1 + PETSC_SQRT_MACHINE_EPSILON)*adapt->dt_min) {
4557622a8eSBarry Smith       ierr = PetscInfo2(adapt,"Estimated scaled local truncation error %g, accepting because step size %g is at minimum\n",(double)enorm,(double)h);CHKERRQ(ierr);
46fd94acc0SJed Brown       *accept = PETSC_TRUE;
47bf997491SLisandro Dalcin     } else if (adapt->always_accept) {
4857622a8eSBarry Smith       ierr = PetscInfo2(adapt,"Estimated scaled local truncation error %g, accepting step of size %g because always_accept is set\n",(double)enorm,(double)h);CHKERRQ(ierr);
497e1ba4dcSJed Brown       *accept = PETSC_TRUE;
501c3436cfSJed Brown     } else {
5157622a8eSBarry Smith       ierr = PetscInfo2(adapt,"Estimated scaled local truncation error %g, rejecting step of size %g\n",(double)enorm,(double)h);CHKERRQ(ierr);
52fd94acc0SJed Brown       *accept = PETSC_FALSE;
53fd94acc0SJed Brown     }
54fd94acc0SJed Brown   } else {
5557622a8eSBarry Smith     ierr = PetscInfo2(adapt,"Estimated scaled local truncation error %g, accepting step of size %g\n",(double)enorm,(double)h);CHKERRQ(ierr);
56fd94acc0SJed Brown     *accept = PETSC_TRUE;
571c3436cfSJed Brown   }
581c3436cfSJed Brown 
591c3436cfSJed Brown   /* The optimal new step based purely on local truncation error for this step. */
601566a47fSLisandro Dalcin   if (enorm > 0)
611566a47fSLisandro Dalcin     hfac_lte = safety * PetscPowReal(enorm,((PetscReal)-1)/order);
621566a47fSLisandro Dalcin   else
63bf0c4ff7SBarry Smith     hfac_lte = safety * PETSC_INFINITY;
64a191cbb8SBarry Smith   if (adapt->timestepjustincreased){
65a191cbb8SBarry Smith     hfac_lte = PetscMin(hfac_lte,1.0);
66a191cbb8SBarry Smith     adapt->timestepjustincreased--;
67a191cbb8SBarry Smith   }
681917a363SLisandro Dalcin   h_lte = h * PetscClipInterval(hfac_lte,adapt->clip[0],adapt->clip[1]);
691c3436cfSJed Brown 
701c3436cfSJed Brown   *next_h = PetscClipInterval(h_lte,adapt->dt_min,adapt->dt_max);
710b99f514SJed Brown   *wlte   = enorm;
7284df9cb4SJed Brown   PetscFunctionReturn(0);
7384df9cb4SJed Brown }
7484df9cb4SJed Brown 
75099af0a3SLisandro Dalcin static PetscErrorCode TSAdaptReset_Basic(TSAdapt adapt)
7684df9cb4SJed Brown {
771c3436cfSJed Brown   TSAdapt_Basic  *basic = (TSAdapt_Basic*)adapt->data;
7884df9cb4SJed Brown   PetscErrorCode ierr;
7984df9cb4SJed Brown 
8084df9cb4SJed Brown   PetscFunctionBegin;
811c3436cfSJed Brown   ierr = VecDestroy(&basic->Y);CHKERRQ(ierr);
82099af0a3SLisandro Dalcin   PetscFunctionReturn(0);
83099af0a3SLisandro Dalcin }
84099af0a3SLisandro Dalcin 
85099af0a3SLisandro Dalcin static PetscErrorCode TSAdaptDestroy_Basic(TSAdapt adapt)
86099af0a3SLisandro Dalcin {
87099af0a3SLisandro Dalcin   PetscErrorCode ierr;
88099af0a3SLisandro Dalcin 
89099af0a3SLisandro Dalcin   PetscFunctionBegin;
90099af0a3SLisandro Dalcin   ierr = TSAdaptReset_Basic(adapt);CHKERRQ(ierr);
9184df9cb4SJed Brown   ierr = PetscFree(adapt->data);CHKERRQ(ierr);
9284df9cb4SJed Brown   PetscFunctionReturn(0);
9384df9cb4SJed Brown }
9484df9cb4SJed Brown 
9584df9cb4SJed Brown /*MC
9684df9cb4SJed Brown    TSADAPTBASIC - Basic adaptive controller for time stepping
9784df9cb4SJed Brown 
9884df9cb4SJed Brown    Level: intermediate
9984df9cb4SJed Brown 
100*e91eccc2SStefano Zampini .seealso: TS, TSAdapt, TSGetAdapt()
10184df9cb4SJed Brown M*/
1028cc058d9SJed Brown PETSC_EXTERN PetscErrorCode TSAdaptCreate_Basic(TSAdapt adapt)
10384df9cb4SJed Brown {
10484df9cb4SJed Brown   PetscErrorCode ierr;
1051917a363SLisandro Dalcin   TSAdapt_Basic  *basic;
10684df9cb4SJed Brown 
10784df9cb4SJed Brown   PetscFunctionBegin;
1081917a363SLisandro Dalcin   ierr= PetscNewLog(adapt,&basic);CHKERRQ(ierr);
1091917a363SLisandro Dalcin   adapt->data         = (void*)basic;
1101c3436cfSJed Brown   adapt->ops->choose  = TSAdaptChoose_Basic;
1111917a363SLisandro Dalcin   adapt->ops->reset   = TSAdaptReset_Basic;
11284df9cb4SJed Brown   adapt->ops->destroy = TSAdaptDestroy_Basic;
1131b9b13dfSLisandro Dalcin   PetscFunctionReturn(0);
1141b9b13dfSLisandro Dalcin }
115