1ae2316d0SEmil Constantinescu #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2ae2316d0SEmil Constantinescu 3ae2316d0SEmil Constantinescu typedef struct { 4*1917a363SLisandro Dalcin Vec E,Y; 5726095e4SEmil Constantinescu } TSAdapt_GLEE; 6ae2316d0SEmil Constantinescu 75e4ed32fSEmil Constantinescu static PetscErrorCode TSAdaptChoose_GLEE(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept,PetscReal *wlte,PetscReal *wltea,PetscReal *wlter) 8ae2316d0SEmil Constantinescu { 9657c1e31SEmil Constantinescu TSAdapt_GLEE *glee = (TSAdapt_GLEE*)adapt->data; 100a01e1b2SEmil Constantinescu TSType time_scheme; /* Type of time-integration scheme */ 11ae2316d0SEmil Constantinescu PetscErrorCode ierr; 128a175baeSEmil Constantinescu Vec X,Y,E; 13df3bac28SEmil Constantinescu PetscReal enorm,enorma,enormr,hfac_lte,hfac_ltea,hfac_lter,h_lte,safety; 145e4ed32fSEmil Constantinescu PetscInt order,stepno; 15df3bac28SEmil Constantinescu PetscBool bGTEMethod=PETSC_FALSE; 16ae2316d0SEmil Constantinescu 17ae2316d0SEmil Constantinescu PetscFunctionBegin; 18df3bac28SEmil Constantinescu 195e4ed32fSEmil Constantinescu *next_sc = 0; /* Reuse the same order scheme */ 20*1917a363SLisandro Dalcin safety = adapt->safety; 21df3bac28SEmil Constantinescu ierr = TSGetTimeStepNumber(ts,&stepno);CHKERRQ(ierr); 220a01e1b2SEmil Constantinescu ierr = TSGetType(ts,&time_scheme);CHKERRQ(ierr); 23df3bac28SEmil Constantinescu if (!strcmp(time_scheme,TSGLEE)) bGTEMethod=PETSC_TRUE; 24df3bac28SEmil Constantinescu order = adapt->candidates.order[0]; 25df3bac28SEmil Constantinescu 26df3bac28SEmil Constantinescu if (bGTEMethod){/* the method is of GLEE type */ 278a175baeSEmil Constantinescu ierr = TSGetSolution(ts,&X);CHKERRQ(ierr); 288a175baeSEmil Constantinescu if (!glee->E) {ierr = VecDuplicate(X,&glee->E);CHKERRQ(ierr);} 298a175baeSEmil Constantinescu E = glee->E; 308a175baeSEmil Constantinescu ierr = TSGetTimeError(ts,0,&E);CHKERRQ(ierr); 31df3bac28SEmil Constantinescu /* this should be called with Y (the solution at the beginning of the step)*/ 328a175baeSEmil Constantinescu ierr = TSErrorWeightedENorm(ts,E,X,X,adapt->wnormtype,&enorm,&enorma,&enormr);CHKERRQ(ierr); 330a01e1b2SEmil Constantinescu } else { 34df3bac28SEmil Constantinescu /* the method is NOT of GLEE type; use the stantard basic augmented by separate atol and rtol */ 35ae2316d0SEmil Constantinescu ierr = TSGetSolution(ts,&X);CHKERRQ(ierr); 36657c1e31SEmil Constantinescu if (!glee->Y) {ierr = VecDuplicate(X,&glee->Y);CHKERRQ(ierr);} 37657c1e31SEmil Constantinescu Y = glee->Y; 38ae2316d0SEmil Constantinescu ierr = TSEvaluateStep(ts,order-1,Y,NULL);CHKERRQ(ierr); 397453f775SEmil Constantinescu ierr = TSErrorWeightedNorm(ts,X,Y,adapt->wnormtype,&enorm,&enorma,&enormr);CHKERRQ(ierr); 400a01e1b2SEmil Constantinescu } 415e4ed32fSEmil Constantinescu 425e4ed32fSEmil Constantinescu if (enorm < 0) { 435e4ed32fSEmil Constantinescu *accept = PETSC_TRUE; 445e4ed32fSEmil Constantinescu *next_h = h; /* Reuse the old step */ 45df3bac28SEmil Constantinescu *wlte = -1; /* Weighted error was not evaluated */ 46df3bac28SEmil Constantinescu *wltea = -1; /* Weighted absolute error was not evaluated */ 47df3bac28SEmil Constantinescu *wlter = -1; /* Weighted relative error was not evaluated */ 485e4ed32fSEmil Constantinescu PetscFunctionReturn(0); 495e4ed32fSEmil Constantinescu } 505e4ed32fSEmil Constantinescu 51df3bac28SEmil Constantinescu if (enorm > 1. || enorma > 1. || enormr > 1.) { 52*1917a363SLisandro Dalcin if (!*accept) safety *= adapt->reject_safety; /* The last attempt also failed, shorten more aggressively */ 53ae2316d0SEmil Constantinescu if (h < (1 + PETSC_SQRT_MACHINE_EPSILON)*adapt->dt_min) { 54df3bac28SEmil Constantinescu ierr = PetscInfo4(adapt,"Estimated scaled truncation error [combined, absolute, relative]] [%g, %g, %g], accepting because step size %g is at minimum\n",(double)enorm,(double)enorma,(double)enormr,(double)h);CHKERRQ(ierr); 55ae2316d0SEmil Constantinescu *accept = PETSC_TRUE; 56bf997491SLisandro Dalcin } else if (adapt->always_accept) { 57df3bac28SEmil Constantinescu ierr = PetscInfo4(adapt,"Estimated scaled truncation error [combined, absolute, relative]] [%g, %g, %g], accepting step of size %g because always_accept is set\n",(double)enorm,(double)enorma,(double)enormr,(double)h);CHKERRQ(ierr); 58ae2316d0SEmil Constantinescu *accept = PETSC_TRUE; 59ae2316d0SEmil Constantinescu } else { 60df3bac28SEmil Constantinescu ierr = PetscInfo4(adapt,"Estimated scaled truncation error [combined, absolute, relative]] [%g, %g, %g], rejecting step of size %g\n",(double)enorm,(double)enorma,(double)enormr,(double)h);CHKERRQ(ierr); 61ae2316d0SEmil Constantinescu *accept = PETSC_FALSE; 62ae2316d0SEmil Constantinescu } 63ae2316d0SEmil Constantinescu } else { 64df3bac28SEmil Constantinescu ierr = PetscInfo4(adapt,"Estimated scaled truncation error [combined, absolute, relative] [%g, %g, %g], accepting step of size %g\n",(double)enorm,(double)enorma,(double)enormr,(double)h);CHKERRQ(ierr); 65ae2316d0SEmil Constantinescu *accept = PETSC_TRUE; 66ae2316d0SEmil Constantinescu } 67ae2316d0SEmil Constantinescu 68df3bac28SEmil Constantinescu if (bGTEMethod){ 69df3bac28SEmil Constantinescu /* The optimal new step based on the current global truncation error. */ 70df3bac28SEmil Constantinescu if (enorm > 0) { 71df3bac28SEmil Constantinescu /* factor based on the absolute tolerance */ 72df3bac28SEmil Constantinescu hfac_ltea = safety * PetscPowReal(1./enorma,((PetscReal)1)/order); 73df3bac28SEmil Constantinescu /* factor based on the relative tolerance */ 74df3bac28SEmil Constantinescu hfac_lter = safety * PetscPowReal(1./enormr,((PetscReal)1)/order); 75df3bac28SEmil Constantinescu /* pick the minimum time step among the relative and absolute tolerances */ 76df3bac28SEmil Constantinescu hfac_lte = PetscMin(hfac_ltea,hfac_lter); 77df3bac28SEmil Constantinescu } else { 78ae2316d0SEmil Constantinescu hfac_lte = safety * PETSC_INFINITY; 79df3bac28SEmil Constantinescu } 80*1917a363SLisandro Dalcin h_lte = h * PetscClipInterval(hfac_lte,adapt->clip[0],adapt->clip[1]); 81ae2316d0SEmil Constantinescu *next_h = PetscClipInterval(h_lte,adapt->dt_min,adapt->dt_max); 82df3bac28SEmil Constantinescu } else { 83df3bac28SEmil Constantinescu /* The optimal new step based purely on local truncation error for this step. */ 84df3bac28SEmil Constantinescu if (enorm > 0) { 85df3bac28SEmil Constantinescu /* factor based on the absolute tolerance */ 86df3bac28SEmil Constantinescu hfac_ltea = safety * PetscPowReal(enorma,((PetscReal)-1)/order); 87df3bac28SEmil Constantinescu /* factor based on the relative tolerance */ 88df3bac28SEmil Constantinescu hfac_lter = safety * PetscPowReal(enormr,((PetscReal)-1)/order); 89df3bac28SEmil Constantinescu /* pick the minimum time step among the relative and absolute tolerances */ 90df3bac28SEmil Constantinescu hfac_lte = PetscMin(hfac_ltea,hfac_lter); 91df3bac28SEmil Constantinescu } else { 92df3bac28SEmil Constantinescu hfac_lte = safety * PETSC_INFINITY; 93df3bac28SEmil Constantinescu } 94*1917a363SLisandro Dalcin h_lte = h * PetscClipInterval(hfac_lte,adapt->clip[0],adapt->clip[1]); 95df3bac28SEmil Constantinescu *next_h = PetscClipInterval(h_lte,adapt->dt_min,adapt->dt_max); 96df3bac28SEmil Constantinescu } 97ae2316d0SEmil Constantinescu *wlte = enorm; 985e4ed32fSEmil Constantinescu *wltea = enorma; 995e4ed32fSEmil Constantinescu *wlter = enormr; 100ae2316d0SEmil Constantinescu PetscFunctionReturn(0); 101ae2316d0SEmil Constantinescu } 102ae2316d0SEmil Constantinescu 103726095e4SEmil Constantinescu static PetscErrorCode TSAdaptReset_GLEE(TSAdapt adapt) 104ae2316d0SEmil Constantinescu { 105657c1e31SEmil Constantinescu TSAdapt_GLEE *glee = (TSAdapt_GLEE*)adapt->data; 106ae2316d0SEmil Constantinescu PetscErrorCode ierr; 107ae2316d0SEmil Constantinescu 108ae2316d0SEmil Constantinescu PetscFunctionBegin; 109657c1e31SEmil Constantinescu ierr = VecDestroy(&glee->Y);CHKERRQ(ierr); 110*1917a363SLisandro Dalcin ierr = VecDestroy(&glee->E);CHKERRQ(ierr); 111ae2316d0SEmil Constantinescu PetscFunctionReturn(0); 112ae2316d0SEmil Constantinescu } 113ae2316d0SEmil Constantinescu 114726095e4SEmil Constantinescu static PetscErrorCode TSAdaptDestroy_GLEE(TSAdapt adapt) 115ae2316d0SEmil Constantinescu { 116ae2316d0SEmil Constantinescu PetscErrorCode ierr; 117ae2316d0SEmil Constantinescu 118ae2316d0SEmil Constantinescu PetscFunctionBegin; 119726095e4SEmil Constantinescu ierr = TSAdaptReset_GLEE(adapt);CHKERRQ(ierr); 120ae2316d0SEmil Constantinescu ierr = PetscFree(adapt->data);CHKERRQ(ierr); 121ae2316d0SEmil Constantinescu PetscFunctionReturn(0); 122ae2316d0SEmil Constantinescu } 123ae2316d0SEmil Constantinescu 124ae2316d0SEmil Constantinescu /*MC 125657c1e31SEmil Constantinescu TSADAPTGLEE - GLEE adaptive controller for time stepping 126ae2316d0SEmil Constantinescu 127ae2316d0SEmil Constantinescu Level: intermediate 128ae2316d0SEmil Constantinescu 129ae2316d0SEmil Constantinescu .seealso: TS, TSAdapt, TSSetAdapt() 130ae2316d0SEmil Constantinescu M*/ 131726095e4SEmil Constantinescu PETSC_EXTERN PetscErrorCode TSAdaptCreate_GLEE(TSAdapt adapt) 132ae2316d0SEmil Constantinescu { 133ae2316d0SEmil Constantinescu PetscErrorCode ierr; 134*1917a363SLisandro Dalcin TSAdapt_GLEE *glee; 135ae2316d0SEmil Constantinescu 136ae2316d0SEmil Constantinescu PetscFunctionBegin; 137*1917a363SLisandro Dalcin ierr = PetscNewLog(adapt,&glee);CHKERRQ(ierr); 138*1917a363SLisandro Dalcin adapt->data = (void*)glee; 139726095e4SEmil Constantinescu adapt->ops->choose = TSAdaptChoose_GLEE; 140*1917a363SLisandro Dalcin adapt->ops->reset = TSAdaptReset_GLEE; 141726095e4SEmil Constantinescu adapt->ops->destroy = TSAdaptDestroy_GLEE; 142ae2316d0SEmil Constantinescu PetscFunctionReturn(0); 143ae2316d0SEmil Constantinescu } 144