Actual source code: adaptcfl.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      1: #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/

      3: typedef struct {
      4:   PetscReal safety;         /* safety factor relative to target CFL constraint */
      5:   PetscBool always_accept;
      6: } TSAdapt_CFL;

     10: static PetscErrorCode TSAdaptChoose_CFL(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept,PetscReal *wlte)
     11: {
     12:   TSAdapt_CFL     *cfl = (TSAdapt_CFL*)adapt->data;
     13:   PetscErrorCode  ierr;
     14:   PetscReal       hcfl,cfltimestep,ccfl;
     15:   PetscInt        ncandidates;
     16:   const PetscReal *ccflarray;

     19:   TSGetCFLTime(ts,&cfltimestep);
     20:   TSAdaptCandidatesGet(adapt,&ncandidates,NULL,NULL,&ccflarray,NULL);
     21:   ccfl = (ncandidates > 0) ? ccflarray[0] : 1.0;

     23:   /* Determine whether the step is accepted of rejected */
     24:   *accept = PETSC_TRUE;
     25:   if (h > cfltimestep * ccfl) {
     26:     if (cfl->always_accept) {
     27:       PetscInfo3(adapt,"Step length %g with scheme of CFL coefficient %g did not satisfy user-provided CFL constraint %g, proceeding anyway\n",(double)h,(double)ccfl,(double)cfltimestep);
     28:     } else {
     29:       PetscInfo3(adapt,"Step length %g with scheme of CFL coefficient %g did not satisfy user-provided CFL constraint %g, step REJECTED\n",(double)h,(double)ccfl,(double)cfltimestep);
     30:       *accept  = PETSC_FALSE;
     31:     }
     32:   }

     34:   /* The optimal new step based purely on CFL constraint for this step. */
     35:   hcfl = cfl->safety * cfltimestep * ccfl;
     36:   if (hcfl < adapt->dt_min) {
     37:     PetscInfo4(adapt,"Cannot satisfy CFL constraint %g (with %g safety) at minimum time step %g with method coefficient %g, proceding anyway\n",(double)cfltimestep,(double)cfl->safety,(double)adapt->dt_min,(double)ccfl);
     38:   }

     40:   *next_sc = 0;
     41:   *next_h  = PetscClipInterval(hcfl,adapt->dt_min,adapt->dt_max);
     42:   *wlte    = -1;  /* Weighted local truncation error was not evaluated */
     43:   return(0);
     44: }

     48: static PetscErrorCode TSAdaptDestroy_CFL(TSAdapt adapt)
     49: {

     53:   PetscFree(adapt->data);
     54:   return(0);
     55: }

     59: static PetscErrorCode TSAdaptSetFromOptions_CFL(PetscOptionItems *PetscOptionsObject,TSAdapt adapt)
     60: {
     61:   TSAdapt_CFL    *cfl = (TSAdapt_CFL*)adapt->data;

     65:   PetscOptionsHead(PetscOptionsObject,"CFL adaptive controller options");
     66:   PetscOptionsReal("-ts_adapt_cfl_safety","Safety factor relative to target CFL constraint","",cfl->safety,&cfl->safety,NULL);
     67:   PetscOptionsBool("-ts_adapt_cfl_always_accept","Always accept the step regardless of whether CFL constraint meets goal","",cfl->always_accept,&cfl->always_accept,NULL);
     68:   /* The TS implementations do not currently communicate CFL information to the controller.  There is a placeholder, but
     69:    * we do not believe it to provide sufficiently rich information.  That means the CFL adaptor is incomplete and
     70:    * unusable.  Do not delete the guard below unless you have finished the implementation. */
     71:   if (!cfl->always_accept) SETERRQ(PetscObjectComm((PetscObject)adapt),PETSC_ERR_SUP,"Step rejection not implemented. The CFL implementation is incomplete/unusable");
     72:   PetscOptionsTail();
     73:   return(0);
     74: }

     78: /*MC
     79:    TSADAPTCFL - CFL adaptive controller for time stepping

     81:    Level: intermediate

     83: .seealso: TS, TSAdapt, TSSetAdapt()
     84: M*/
     85: PETSC_EXTERN PetscErrorCode TSAdaptCreate_CFL(TSAdapt adapt)
     86: {
     88:   TSAdapt_CFL    *a;

     91:   PetscNewLog(adapt,&a);
     92:   adapt->data = (void*)a;

     94:   adapt->ops->choose         = TSAdaptChoose_CFL;
     95:   adapt->ops->setfromoptions = TSAdaptSetFromOptions_CFL;
     96:   adapt->ops->destroy        = TSAdaptDestroy_CFL;

     98:   a->safety        = 0.9;
     99:   a->always_accept = PETSC_FALSE;
    100:   return(0);
    101: }