13d177a5cSEmil Constantinescu 23d177a5cSEmil Constantinescu #include <../src/ts/impls/implicit/glle/glle.h> /*I "petscts.h" I*/ 33d177a5cSEmil Constantinescu 43d177a5cSEmil Constantinescu static PetscFunctionList TSGLLEAdaptList; 53d177a5cSEmil Constantinescu static PetscBool TSGLLEAdaptPackageInitialized; 63d177a5cSEmil Constantinescu static PetscBool TSGLLEAdaptRegisterAllCalled; 73d177a5cSEmil Constantinescu static PetscClassId TSGLLEADAPT_CLASSID; 83d177a5cSEmil Constantinescu 93d177a5cSEmil Constantinescu struct _TSGLLEAdaptOps { 103d177a5cSEmil Constantinescu PetscErrorCode (*choose)(TSGLLEAdapt,PetscInt,const PetscInt[],const PetscReal[],const PetscReal[],PetscInt,PetscReal,PetscReal,PetscInt*,PetscReal*,PetscBool*); 113d177a5cSEmil Constantinescu PetscErrorCode (*destroy)(TSGLLEAdapt); 123d177a5cSEmil Constantinescu PetscErrorCode (*view)(TSGLLEAdapt,PetscViewer); 133d177a5cSEmil Constantinescu PetscErrorCode (*setfromoptions)(PetscOptionItems*,TSGLLEAdapt); 143d177a5cSEmil Constantinescu }; 153d177a5cSEmil Constantinescu 163d177a5cSEmil Constantinescu struct _p_TSGLLEAdapt { 173d177a5cSEmil Constantinescu PETSCHEADER(struct _TSGLLEAdaptOps); 183d177a5cSEmil Constantinescu void *data; 193d177a5cSEmil Constantinescu }; 203d177a5cSEmil Constantinescu 213d177a5cSEmil Constantinescu PETSC_EXTERN PetscErrorCode TSGLLEAdaptCreate_None(TSGLLEAdapt); 223d177a5cSEmil Constantinescu PETSC_EXTERN PetscErrorCode TSGLLEAdaptCreate_Size(TSGLLEAdapt); 233d177a5cSEmil Constantinescu PETSC_EXTERN PetscErrorCode TSGLLEAdaptCreate_Both(TSGLLEAdapt); 243d177a5cSEmil Constantinescu 253d177a5cSEmil Constantinescu /*@C 263d177a5cSEmil Constantinescu TSGLLEAdaptRegister - adds a TSGLLEAdapt implementation 273d177a5cSEmil Constantinescu 283d177a5cSEmil Constantinescu Not Collective 293d177a5cSEmil Constantinescu 303d177a5cSEmil Constantinescu Input Parameters: 313d177a5cSEmil Constantinescu + name_scheme - name of user-defined adaptivity scheme 323d177a5cSEmil Constantinescu - routine_create - routine to create method context 333d177a5cSEmil Constantinescu 343d177a5cSEmil Constantinescu Notes: 353d177a5cSEmil Constantinescu TSGLLEAdaptRegister() may be called multiple times to add several user-defined families. 363d177a5cSEmil Constantinescu 373d177a5cSEmil Constantinescu Sample usage: 383d177a5cSEmil Constantinescu .vb 393d177a5cSEmil Constantinescu TSGLLEAdaptRegister("my_scheme",MySchemeCreate); 403d177a5cSEmil Constantinescu .ve 413d177a5cSEmil Constantinescu 423d177a5cSEmil Constantinescu Then, your scheme can be chosen with the procedural interface via 433d177a5cSEmil Constantinescu $ TSGLLEAdaptSetType(ts,"my_scheme") 443d177a5cSEmil Constantinescu or at runtime via the option 453d177a5cSEmil Constantinescu $ -ts_adapt_type my_scheme 463d177a5cSEmil Constantinescu 473d177a5cSEmil Constantinescu Level: advanced 483d177a5cSEmil Constantinescu 493d177a5cSEmil Constantinescu .keywords: TSGLLEAdapt, register 503d177a5cSEmil Constantinescu 513d177a5cSEmil Constantinescu .seealso: TSGLLEAdaptRegisterAll() 523d177a5cSEmil Constantinescu @*/ 533d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptRegister(const char sname[],PetscErrorCode (*function)(TSGLLEAdapt)) 543d177a5cSEmil Constantinescu { 553d177a5cSEmil Constantinescu PetscErrorCode ierr; 563d177a5cSEmil Constantinescu 573d177a5cSEmil Constantinescu PetscFunctionBegin; 581d36bdfdSBarry Smith ierr = TSGLLEAdaptInitializePackage();CHKERRQ(ierr); 593d177a5cSEmil Constantinescu ierr = PetscFunctionListAdd(&TSGLLEAdaptList,sname,function);CHKERRQ(ierr); 603d177a5cSEmil Constantinescu PetscFunctionReturn(0); 613d177a5cSEmil Constantinescu } 623d177a5cSEmil Constantinescu 633d177a5cSEmil Constantinescu /*@C 643d177a5cSEmil Constantinescu TSGLLEAdaptRegisterAll - Registers all of the adaptivity schemes in TSGLLEAdapt 653d177a5cSEmil Constantinescu 663d177a5cSEmil Constantinescu Not Collective 673d177a5cSEmil Constantinescu 683d177a5cSEmil Constantinescu Level: advanced 693d177a5cSEmil Constantinescu 703d177a5cSEmil Constantinescu .keywords: TSGLLEAdapt, register, all 713d177a5cSEmil Constantinescu 723d177a5cSEmil Constantinescu .seealso: TSGLLEAdaptRegisterDestroy() 733d177a5cSEmil Constantinescu @*/ 743d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptRegisterAll(void) 753d177a5cSEmil Constantinescu { 763d177a5cSEmil Constantinescu PetscErrorCode ierr; 773d177a5cSEmil Constantinescu 783d177a5cSEmil Constantinescu PetscFunctionBegin; 793d177a5cSEmil Constantinescu if (TSGLLEAdaptRegisterAllCalled) PetscFunctionReturn(0); 803d177a5cSEmil Constantinescu TSGLLEAdaptRegisterAllCalled = PETSC_TRUE; 813d177a5cSEmil Constantinescu ierr = TSGLLEAdaptRegister(TSGLLEADAPT_NONE,TSGLLEAdaptCreate_None);CHKERRQ(ierr); 823d177a5cSEmil Constantinescu ierr = TSGLLEAdaptRegister(TSGLLEADAPT_SIZE,TSGLLEAdaptCreate_Size);CHKERRQ(ierr); 833d177a5cSEmil Constantinescu ierr = TSGLLEAdaptRegister(TSGLLEADAPT_BOTH,TSGLLEAdaptCreate_Both);CHKERRQ(ierr); 843d177a5cSEmil Constantinescu PetscFunctionReturn(0); 853d177a5cSEmil Constantinescu } 863d177a5cSEmil Constantinescu 873d177a5cSEmil Constantinescu /*@C 883d177a5cSEmil Constantinescu TSGLLEFinalizePackage - This function destroys everything in the TSGLLE package. It is 893d177a5cSEmil Constantinescu called from PetscFinalize(). 903d177a5cSEmil Constantinescu 913d177a5cSEmil Constantinescu Level: developer 923d177a5cSEmil Constantinescu 933d177a5cSEmil Constantinescu .keywords: Petsc, destroy, package 943d177a5cSEmil Constantinescu .seealso: PetscFinalize() 953d177a5cSEmil Constantinescu @*/ 963d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptFinalizePackage(void) 973d177a5cSEmil Constantinescu { 983d177a5cSEmil Constantinescu PetscErrorCode ierr; 993d177a5cSEmil Constantinescu 1003d177a5cSEmil Constantinescu PetscFunctionBegin; 1013d177a5cSEmil Constantinescu ierr = PetscFunctionListDestroy(&TSGLLEAdaptList);CHKERRQ(ierr); 1023d177a5cSEmil Constantinescu TSGLLEAdaptPackageInitialized = PETSC_FALSE; 1033d177a5cSEmil Constantinescu TSGLLEAdaptRegisterAllCalled = PETSC_FALSE; 1043d177a5cSEmil Constantinescu PetscFunctionReturn(0); 1053d177a5cSEmil Constantinescu } 1063d177a5cSEmil Constantinescu 1073d177a5cSEmil Constantinescu /*@C 1083d177a5cSEmil Constantinescu TSGLLEAdaptInitializePackage - This function initializes everything in the TSGLLEAdapt package. It is 109*8a690491SBarry Smith called from TSInitializePackage(). 1103d177a5cSEmil Constantinescu 1113d177a5cSEmil Constantinescu Level: developer 1123d177a5cSEmil Constantinescu 1133d177a5cSEmil Constantinescu .keywords: TSGLLEAdapt, initialize, package 1143d177a5cSEmil Constantinescu .seealso: PetscInitialize() 1153d177a5cSEmil Constantinescu @*/ 1163d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptInitializePackage(void) 1173d177a5cSEmil Constantinescu { 1183d177a5cSEmil Constantinescu PetscErrorCode ierr; 1193d177a5cSEmil Constantinescu 1203d177a5cSEmil Constantinescu PetscFunctionBegin; 1213d177a5cSEmil Constantinescu if (TSGLLEAdaptPackageInitialized) PetscFunctionReturn(0); 1223d177a5cSEmil Constantinescu TSGLLEAdaptPackageInitialized = PETSC_TRUE; 1233d177a5cSEmil Constantinescu ierr = PetscClassIdRegister("TSGLLEAdapt",&TSGLLEADAPT_CLASSID);CHKERRQ(ierr); 1243d177a5cSEmil Constantinescu ierr = TSGLLEAdaptRegisterAll();CHKERRQ(ierr); 1253d177a5cSEmil Constantinescu ierr = PetscRegisterFinalize(TSGLLEAdaptFinalizePackage);CHKERRQ(ierr); 1263d177a5cSEmil Constantinescu PetscFunctionReturn(0); 1273d177a5cSEmil Constantinescu } 1283d177a5cSEmil Constantinescu 1293d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptSetType(TSGLLEAdapt adapt,TSGLLEAdaptType type) 1303d177a5cSEmil Constantinescu { 1313d177a5cSEmil Constantinescu PetscErrorCode ierr,(*r)(TSGLLEAdapt); 1323d177a5cSEmil Constantinescu 1333d177a5cSEmil Constantinescu PetscFunctionBegin; 1343d177a5cSEmil Constantinescu ierr = PetscFunctionListFind(TSGLLEAdaptList,type,&r);CHKERRQ(ierr); 1353d177a5cSEmil Constantinescu if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TSGLLEAdapt type \"%s\" given",type); 1363d177a5cSEmil Constantinescu if (((PetscObject)adapt)->type_name) {ierr = (*adapt->ops->destroy)(adapt);CHKERRQ(ierr);} 1373d177a5cSEmil Constantinescu ierr = (*r)(adapt);CHKERRQ(ierr); 1383d177a5cSEmil Constantinescu ierr = PetscObjectChangeTypeName((PetscObject)adapt,type);CHKERRQ(ierr); 1393d177a5cSEmil Constantinescu PetscFunctionReturn(0); 1403d177a5cSEmil Constantinescu } 1413d177a5cSEmil Constantinescu 1423d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptSetOptionsPrefix(TSGLLEAdapt adapt,const char prefix[]) 1433d177a5cSEmil Constantinescu { 1443d177a5cSEmil Constantinescu PetscErrorCode ierr; 1453d177a5cSEmil Constantinescu 1463d177a5cSEmil Constantinescu PetscFunctionBegin; 1473d177a5cSEmil Constantinescu ierr = PetscObjectSetOptionsPrefix((PetscObject)adapt,prefix);CHKERRQ(ierr); 1483d177a5cSEmil Constantinescu PetscFunctionReturn(0); 1493d177a5cSEmil Constantinescu } 1503d177a5cSEmil Constantinescu 1513d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptView(TSGLLEAdapt adapt,PetscViewer viewer) 1523d177a5cSEmil Constantinescu { 1533d177a5cSEmil Constantinescu PetscErrorCode ierr; 1543d177a5cSEmil Constantinescu PetscBool iascii; 1553d177a5cSEmil Constantinescu 1563d177a5cSEmil Constantinescu PetscFunctionBegin; 1573d177a5cSEmil Constantinescu ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1583d177a5cSEmil Constantinescu if (iascii) { 1593d177a5cSEmil Constantinescu ierr = PetscObjectPrintClassNamePrefixType((PetscObject)adapt,viewer);CHKERRQ(ierr); 1603d177a5cSEmil Constantinescu if (adapt->ops->view) { 1613d177a5cSEmil Constantinescu ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1623d177a5cSEmil Constantinescu ierr = (*adapt->ops->view)(adapt,viewer);CHKERRQ(ierr); 1633d177a5cSEmil Constantinescu ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1643d177a5cSEmil Constantinescu } 1653d177a5cSEmil Constantinescu } 1663d177a5cSEmil Constantinescu PetscFunctionReturn(0); 1673d177a5cSEmil Constantinescu } 1683d177a5cSEmil Constantinescu 1693d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptDestroy(TSGLLEAdapt *adapt) 1703d177a5cSEmil Constantinescu { 1713d177a5cSEmil Constantinescu PetscErrorCode ierr; 1723d177a5cSEmil Constantinescu 1733d177a5cSEmil Constantinescu PetscFunctionBegin; 1743d177a5cSEmil Constantinescu if (!*adapt) PetscFunctionReturn(0); 1753d177a5cSEmil Constantinescu PetscValidHeaderSpecific(*adapt,TSGLLEADAPT_CLASSID,1); 1763d177a5cSEmil Constantinescu if (--((PetscObject)(*adapt))->refct > 0) {*adapt = 0; PetscFunctionReturn(0);} 1773d177a5cSEmil Constantinescu if ((*adapt)->ops->destroy) {ierr = (*(*adapt)->ops->destroy)(*adapt);CHKERRQ(ierr);} 1783d177a5cSEmil Constantinescu ierr = PetscHeaderDestroy(adapt);CHKERRQ(ierr); 1793d177a5cSEmil Constantinescu PetscFunctionReturn(0); 1803d177a5cSEmil Constantinescu } 1813d177a5cSEmil Constantinescu 1823d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptSetFromOptions(PetscOptionItems *PetscOptionsObject,TSGLLEAdapt adapt) 1833d177a5cSEmil Constantinescu { 1843d177a5cSEmil Constantinescu PetscErrorCode ierr; 1853d177a5cSEmil Constantinescu char type[256] = TSGLLEADAPT_BOTH; 1863d177a5cSEmil Constantinescu PetscBool flg; 1873d177a5cSEmil Constantinescu 1883d177a5cSEmil Constantinescu PetscFunctionBegin; 1893d177a5cSEmil Constantinescu /* This should use PetscOptionsBegin() if/when this becomes an object used outside of TSGLLE, but currently this 1903d177a5cSEmil Constantinescu * function can only be called from inside TSSetFromOptions_GLLE() */ 1913d177a5cSEmil Constantinescu ierr = PetscOptionsHead(PetscOptionsObject,"TSGLLE Adaptivity options");CHKERRQ(ierr); 1923d177a5cSEmil Constantinescu ierr = PetscOptionsFList("-ts_adapt_type","Algorithm to use for adaptivity","TSGLLEAdaptSetType",TSGLLEAdaptList, 1933d177a5cSEmil Constantinescu ((PetscObject)adapt)->type_name ? ((PetscObject)adapt)->type_name : type,type,sizeof(type),&flg);CHKERRQ(ierr); 1943d177a5cSEmil Constantinescu if (flg || !((PetscObject)adapt)->type_name) { 1953d177a5cSEmil Constantinescu ierr = TSGLLEAdaptSetType(adapt,type);CHKERRQ(ierr); 1963d177a5cSEmil Constantinescu } 1973d177a5cSEmil Constantinescu if (adapt->ops->setfromoptions) {ierr = (*adapt->ops->setfromoptions)(PetscOptionsObject,adapt);CHKERRQ(ierr);} 1983d177a5cSEmil Constantinescu ierr = PetscOptionsTail();CHKERRQ(ierr); 1993d177a5cSEmil Constantinescu PetscFunctionReturn(0); 2003d177a5cSEmil Constantinescu } 2013d177a5cSEmil Constantinescu 2023d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptChoose(TSGLLEAdapt adapt,PetscInt n,const PetscInt orders[],const PetscReal errors[],const PetscReal cost[],PetscInt cur,PetscReal h,PetscReal tleft,PetscInt *next_sc,PetscReal *next_h,PetscBool *finish) 2033d177a5cSEmil Constantinescu { 2043d177a5cSEmil Constantinescu PetscErrorCode ierr; 2053d177a5cSEmil Constantinescu 2063d177a5cSEmil Constantinescu PetscFunctionBegin; 2073d177a5cSEmil Constantinescu PetscValidHeaderSpecific(adapt,TSGLLEADAPT_CLASSID,1); 2083d177a5cSEmil Constantinescu PetscValidIntPointer(orders,3); 2093d177a5cSEmil Constantinescu PetscValidPointer(errors,4); 2103d177a5cSEmil Constantinescu PetscValidPointer(cost,5); 2113d177a5cSEmil Constantinescu PetscValidIntPointer(next_sc,9); 2123d177a5cSEmil Constantinescu PetscValidPointer(next_h,10); 2133d177a5cSEmil Constantinescu PetscValidIntPointer(finish,11); 2143d177a5cSEmil Constantinescu ierr = (*adapt->ops->choose)(adapt,n,orders,errors,cost,cur,h,tleft,next_sc,next_h,finish);CHKERRQ(ierr); 2153d177a5cSEmil Constantinescu PetscFunctionReturn(0); 2163d177a5cSEmil Constantinescu } 2173d177a5cSEmil Constantinescu 2183d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptCreate(MPI_Comm comm,TSGLLEAdapt *inadapt) 2193d177a5cSEmil Constantinescu { 2203d177a5cSEmil Constantinescu PetscErrorCode ierr; 2213d177a5cSEmil Constantinescu TSGLLEAdapt adapt; 2223d177a5cSEmil Constantinescu 2233d177a5cSEmil Constantinescu PetscFunctionBegin; 2243d177a5cSEmil Constantinescu *inadapt = NULL; 2253d177a5cSEmil Constantinescu ierr = PetscHeaderCreate(adapt,TSGLLEADAPT_CLASSID,"TSGLLEAdapt","General Linear adaptivity","TS",comm,TSGLLEAdaptDestroy,TSGLLEAdaptView);CHKERRQ(ierr); 2263d177a5cSEmil Constantinescu *inadapt = adapt; 2273d177a5cSEmil Constantinescu PetscFunctionReturn(0); 2283d177a5cSEmil Constantinescu } 2293d177a5cSEmil Constantinescu 2303d177a5cSEmil Constantinescu 2313d177a5cSEmil Constantinescu /* 2323d177a5cSEmil Constantinescu * Implementations 2333d177a5cSEmil Constantinescu */ 2343d177a5cSEmil Constantinescu 2353d177a5cSEmil Constantinescu static PetscErrorCode TSGLLEAdaptDestroy_JustFree(TSGLLEAdapt adapt) 2363d177a5cSEmil Constantinescu { 2373d177a5cSEmil Constantinescu PetscErrorCode ierr; 2383d177a5cSEmil Constantinescu 2393d177a5cSEmil Constantinescu PetscFunctionBegin; 2403d177a5cSEmil Constantinescu ierr = PetscFree(adapt->data);CHKERRQ(ierr); 2413d177a5cSEmil Constantinescu PetscFunctionReturn(0); 2423d177a5cSEmil Constantinescu } 2433d177a5cSEmil Constantinescu 2443d177a5cSEmil Constantinescu /* -------------------------------- None ----------------------------------- */ 2453d177a5cSEmil Constantinescu typedef struct { 2463d177a5cSEmil Constantinescu PetscInt scheme; 2473d177a5cSEmil Constantinescu PetscReal h; 2483d177a5cSEmil Constantinescu } TSGLLEAdapt_None; 2493d177a5cSEmil Constantinescu 2503d177a5cSEmil Constantinescu static PetscErrorCode TSGLLEAdaptChoose_None(TSGLLEAdapt adapt,PetscInt n,const PetscInt orders[],const PetscReal errors[],const PetscReal cost[],PetscInt cur,PetscReal h,PetscReal tleft,PetscInt *next_sc,PetscReal *next_h,PetscBool *finish) 2513d177a5cSEmil Constantinescu { 2523d177a5cSEmil Constantinescu 2533d177a5cSEmil Constantinescu PetscFunctionBegin; 2543d177a5cSEmil Constantinescu *next_sc = cur; 2553d177a5cSEmil Constantinescu *next_h = h; 2563d177a5cSEmil Constantinescu if (*next_h > tleft) { 2573d177a5cSEmil Constantinescu *finish = PETSC_TRUE; 2583d177a5cSEmil Constantinescu *next_h = tleft; 2593d177a5cSEmil Constantinescu } else *finish = PETSC_FALSE; 2603d177a5cSEmil Constantinescu PetscFunctionReturn(0); 2613d177a5cSEmil Constantinescu } 2623d177a5cSEmil Constantinescu 2633d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptCreate_None(TSGLLEAdapt adapt) 2643d177a5cSEmil Constantinescu { 2653d177a5cSEmil Constantinescu PetscErrorCode ierr; 2663d177a5cSEmil Constantinescu TSGLLEAdapt_None *a; 2673d177a5cSEmil Constantinescu 2683d177a5cSEmil Constantinescu PetscFunctionBegin; 2693d177a5cSEmil Constantinescu ierr = PetscNewLog(adapt,&a);CHKERRQ(ierr); 2703d177a5cSEmil Constantinescu adapt->data = (void*)a; 2713d177a5cSEmil Constantinescu adapt->ops->choose = TSGLLEAdaptChoose_None; 2723d177a5cSEmil Constantinescu adapt->ops->destroy = TSGLLEAdaptDestroy_JustFree; 2733d177a5cSEmil Constantinescu PetscFunctionReturn(0); 2743d177a5cSEmil Constantinescu } 2753d177a5cSEmil Constantinescu 2763d177a5cSEmil Constantinescu /* -------------------------------- Size ----------------------------------- */ 2773d177a5cSEmil Constantinescu typedef struct { 2783d177a5cSEmil Constantinescu PetscReal desired_h; 2793d177a5cSEmil Constantinescu } TSGLLEAdapt_Size; 2803d177a5cSEmil Constantinescu 2813d177a5cSEmil Constantinescu 2823d177a5cSEmil Constantinescu static PetscErrorCode TSGLLEAdaptChoose_Size(TSGLLEAdapt adapt,PetscInt n,const PetscInt orders[],const PetscReal errors[],const PetscReal cost[],PetscInt cur,PetscReal h,PetscReal tleft,PetscInt *next_sc,PetscReal *next_h,PetscBool *finish) 2833d177a5cSEmil Constantinescu { 2843d177a5cSEmil Constantinescu TSGLLEAdapt_Size *sz = (TSGLLEAdapt_Size*)adapt->data; 2853d177a5cSEmil Constantinescu PetscReal dec = 0.2,inc = 5.0,safe = 0.9,optimal,last_desired_h; 2863d177a5cSEmil Constantinescu 2873d177a5cSEmil Constantinescu PetscFunctionBegin; 2883d177a5cSEmil Constantinescu *next_sc = cur; 2893d177a5cSEmil Constantinescu optimal = PetscPowReal((PetscReal)errors[cur],(PetscReal)-1./(safe*orders[cur])); 2903d177a5cSEmil Constantinescu /* Step sizes oscillate when there is no smoothing. Here we use a geometric mean of the current step size and the 2913d177a5cSEmil Constantinescu * one that would have been taken (without smoothing) on the last step. */ 2923d177a5cSEmil Constantinescu last_desired_h = sz->desired_h; 2933d177a5cSEmil Constantinescu sz->desired_h = h*PetscMax(dec,PetscMin(inc,optimal)); /* Trim to [dec,inc] */ 2943d177a5cSEmil Constantinescu 2953d177a5cSEmil Constantinescu /* Normally only happens on the first step */ 2963d177a5cSEmil Constantinescu if (last_desired_h > 1e-14) *next_h = PetscSqrtReal(last_desired_h * sz->desired_h); 2973d177a5cSEmil Constantinescu else *next_h = sz->desired_h; 2983d177a5cSEmil Constantinescu 2993d177a5cSEmil Constantinescu if (*next_h > tleft) { 3003d177a5cSEmil Constantinescu *finish = PETSC_TRUE; 3013d177a5cSEmil Constantinescu *next_h = tleft; 3023d177a5cSEmil Constantinescu } else *finish = PETSC_FALSE; 3033d177a5cSEmil Constantinescu PetscFunctionReturn(0); 3043d177a5cSEmil Constantinescu } 3053d177a5cSEmil Constantinescu 3063d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptCreate_Size(TSGLLEAdapt adapt) 3073d177a5cSEmil Constantinescu { 3083d177a5cSEmil Constantinescu PetscErrorCode ierr; 3093d177a5cSEmil Constantinescu TSGLLEAdapt_Size *a; 3103d177a5cSEmil Constantinescu 3113d177a5cSEmil Constantinescu PetscFunctionBegin; 3123d177a5cSEmil Constantinescu ierr = PetscNewLog(adapt,&a);CHKERRQ(ierr); 3133d177a5cSEmil Constantinescu adapt->data = (void*)a; 3143d177a5cSEmil Constantinescu adapt->ops->choose = TSGLLEAdaptChoose_Size; 3153d177a5cSEmil Constantinescu adapt->ops->destroy = TSGLLEAdaptDestroy_JustFree; 3163d177a5cSEmil Constantinescu PetscFunctionReturn(0); 3173d177a5cSEmil Constantinescu } 3183d177a5cSEmil Constantinescu 3193d177a5cSEmil Constantinescu /* -------------------------------- Both ----------------------------------- */ 3203d177a5cSEmil Constantinescu typedef struct { 3213d177a5cSEmil Constantinescu PetscInt count_at_order; 3223d177a5cSEmil Constantinescu PetscReal desired_h; 3233d177a5cSEmil Constantinescu } TSGLLEAdapt_Both; 3243d177a5cSEmil Constantinescu 3253d177a5cSEmil Constantinescu 3263d177a5cSEmil Constantinescu static PetscErrorCode TSGLLEAdaptChoose_Both(TSGLLEAdapt adapt,PetscInt n,const PetscInt orders[],const PetscReal errors[],const PetscReal cost[],PetscInt cur,PetscReal h,PetscReal tleft,PetscInt *next_sc,PetscReal *next_h,PetscBool *finish) 3273d177a5cSEmil Constantinescu { 3283d177a5cSEmil Constantinescu TSGLLEAdapt_Both *both = (TSGLLEAdapt_Both*)adapt->data; 3293d177a5cSEmil Constantinescu PetscErrorCode ierr; 3303d177a5cSEmil Constantinescu PetscReal dec = 0.2,inc = 5.0,safe = 0.9; 3313d177a5cSEmil Constantinescu struct {PetscInt id; PetscReal h,eff;} best={-1,0,0},trial={-1,0,0},current={-1,0,0}; 3323d177a5cSEmil Constantinescu PetscInt i; 3333d177a5cSEmil Constantinescu 3343d177a5cSEmil Constantinescu PetscFunctionBegin; 3353d177a5cSEmil Constantinescu for (i=0; i<n; i++) { 3363d177a5cSEmil Constantinescu PetscReal optimal; 3373d177a5cSEmil Constantinescu trial.id = i; 3383d177a5cSEmil Constantinescu optimal = PetscPowReal((PetscReal)errors[i],(PetscReal)-1./(safe*orders[i])); 3393d177a5cSEmil Constantinescu trial.h = h*optimal; 3403d177a5cSEmil Constantinescu trial.eff = trial.h/cost[i]; 3413d177a5cSEmil Constantinescu if (trial.eff > best.eff) {ierr = PetscMemcpy(&best,&trial,sizeof(trial));CHKERRQ(ierr);} 3423d177a5cSEmil Constantinescu if (i == cur) {ierr = PetscMemcpy(¤t,&trial,sizeof(trial));CHKERRQ(ierr);} 3433d177a5cSEmil Constantinescu } 3443d177a5cSEmil Constantinescu /* Only switch orders if the scheme offers significant benefits over the current one. 3453d177a5cSEmil Constantinescu When the scheme is not changing, only change step size if it offers significant benefits. */ 3463d177a5cSEmil Constantinescu if (best.eff < 1.2*current.eff || both->count_at_order < orders[cur]+2) { 3473d177a5cSEmil Constantinescu PetscReal last_desired_h; 3483d177a5cSEmil Constantinescu *next_sc = current.id; 3493d177a5cSEmil Constantinescu last_desired_h = both->desired_h; 3503d177a5cSEmil Constantinescu both->desired_h = PetscMax(h*dec,PetscMin(h*inc,current.h)); 3513d177a5cSEmil Constantinescu *next_h = (both->count_at_order > 0) 3523d177a5cSEmil Constantinescu ? PetscSqrtReal(last_desired_h * both->desired_h) 3533d177a5cSEmil Constantinescu : both->desired_h; 3543d177a5cSEmil Constantinescu both->count_at_order++; 3553d177a5cSEmil Constantinescu } else { 3563d177a5cSEmil Constantinescu PetscReal rat = cost[best.id]/cost[cur]; 3573d177a5cSEmil Constantinescu *next_sc = best.id; 3583d177a5cSEmil Constantinescu *next_h = PetscMax(h*rat*dec,PetscMin(h*rat*inc,best.h)); 3593d177a5cSEmil Constantinescu both->count_at_order = 0; 3603d177a5cSEmil Constantinescu both->desired_h = best.h; 3613d177a5cSEmil Constantinescu } 3623d177a5cSEmil Constantinescu 3633d177a5cSEmil Constantinescu if (*next_h > tleft) { 3643d177a5cSEmil Constantinescu *finish = PETSC_TRUE; 3653d177a5cSEmil Constantinescu *next_h = tleft; 3663d177a5cSEmil Constantinescu } else *finish = PETSC_FALSE; 3673d177a5cSEmil Constantinescu PetscFunctionReturn(0); 3683d177a5cSEmil Constantinescu } 3693d177a5cSEmil Constantinescu 3703d177a5cSEmil Constantinescu PetscErrorCode TSGLLEAdaptCreate_Both(TSGLLEAdapt adapt) 3713d177a5cSEmil Constantinescu { 3723d177a5cSEmil Constantinescu PetscErrorCode ierr; 3733d177a5cSEmil Constantinescu TSGLLEAdapt_Both *a; 3743d177a5cSEmil Constantinescu 3753d177a5cSEmil Constantinescu PetscFunctionBegin; 3763d177a5cSEmil Constantinescu ierr = PetscNewLog(adapt,&a);CHKERRQ(ierr); 3773d177a5cSEmil Constantinescu adapt->data = (void*)a; 3783d177a5cSEmil Constantinescu adapt->ops->choose = TSGLLEAdaptChoose_Both; 3793d177a5cSEmil Constantinescu adapt->ops->destroy = TSGLLEAdaptDestroy_JustFree; 3803d177a5cSEmil Constantinescu PetscFunctionReturn(0); 3813d177a5cSEmil Constantinescu } 382