1 2 #include <private/tsimpl.h> /*I "petscts.h" I*/ 3 4 static PetscFList TSAdaptList; 5 static PetscBool TSAdaptPackageInitialized; 6 static PetscBool TSAdaptRegisterAllCalled; 7 static PetscClassId TSADAPT_CLASSID; 8 9 EXTERN_C_BEGIN 10 PetscErrorCode TSAdaptCreate_Basic(TSAdapt); 11 EXTERN_C_END 12 13 #undef __FUNCT__ 14 #define __FUNCT__ "TSAdaptRegister" 15 /*@C 16 TSAdaptRegister - see TSAdaptRegisterDynamic() 17 18 Level: advanced 19 @*/ 20 PetscErrorCode TSAdaptRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(TSAdapt)) 21 { 22 PetscErrorCode ierr; 23 char fullname[PETSC_MAX_PATH_LEN]; 24 25 PetscFunctionBegin; 26 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 27 ierr = PetscFListAdd(&TSAdaptList,sname,fullname,(void(*)(void))function);CHKERRQ(ierr); 28 PetscFunctionReturn(0); 29 } 30 31 #undef __FUNCT__ 32 #define __FUNCT__ "TSAdaptRegisterAll" 33 /*@C 34 TSAdaptRegisterAll - Registers all of the adaptivity schemes in TSAdapt 35 36 Not Collective 37 38 Level: advanced 39 40 .keywords: TSAdapt, register, all 41 42 .seealso: TSAdaptRegisterDestroy() 43 @*/ 44 PetscErrorCode TSAdaptRegisterAll(const char path[]) 45 { 46 PetscErrorCode ierr; 47 48 PetscFunctionBegin; 49 ierr = TSAdaptRegisterDynamic(TSADAPTBASIC,path,"TSAdaptCreate_Basic",TSAdaptCreate_Basic);CHKERRQ(ierr); 50 PetscFunctionReturn(0); 51 } 52 53 #undef __FUNCT__ 54 #define __FUNCT__ "TSAdaptFinalizePackage" 55 /*@C 56 TSFinalizePackage - This function destroys everything in the TS package. It is 57 called from PetscFinalize(). 58 59 Level: developer 60 61 .keywords: Petsc, destroy, package 62 .seealso: PetscFinalize() 63 @*/ 64 PetscErrorCode TSAdaptFinalizePackage(void) 65 { 66 PetscFunctionBegin; 67 TSAdaptPackageInitialized = PETSC_FALSE; 68 TSAdaptRegisterAllCalled = PETSC_FALSE; 69 TSAdaptList = PETSC_NULL; 70 PetscFunctionReturn(0); 71 } 72 73 #undef __FUNCT__ 74 #define __FUNCT__ "TSAdaptInitializePackage" 75 /*@C 76 TSAdaptInitializePackage - This function initializes everything in the TSAdapt package. It is 77 called from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to 78 TSCreate_GL() when using static libraries. 79 80 Input Parameter: 81 path - The dynamic library path, or PETSC_NULL 82 83 Level: developer 84 85 .keywords: TSAdapt, initialize, package 86 .seealso: PetscInitialize() 87 @*/ 88 PetscErrorCode TSAdaptInitializePackage(const char path[]) 89 { 90 PetscErrorCode ierr; 91 92 PetscFunctionBegin; 93 if (TSAdaptPackageInitialized) PetscFunctionReturn(0); 94 TSAdaptPackageInitialized = PETSC_TRUE; 95 ierr = PetscClassIdRegister("TSAdapt",&TSADAPT_CLASSID);CHKERRQ(ierr); 96 ierr = TSAdaptRegisterAll(path);CHKERRQ(ierr); 97 ierr = PetscRegisterFinalize(TSAdaptFinalizePackage);CHKERRQ(ierr); 98 PetscFunctionReturn(0); 99 } 100 101 #undef __FUNCT__ 102 #define __FUNCT__ "TSAdaptRegisterDestroy" 103 /*@C 104 TSAdaptRegisterDestroy - Frees the list of adaptivity schemes that were registered by TSAdaptRegister()/TSAdaptRegisterDynamic(). 105 106 Not Collective 107 108 Level: advanced 109 110 .keywords: TSAdapt, register, destroy 111 .seealso: TSAdaptRegister(), TSAdaptRegisterAll(), TSAdaptRegisterDynamic() 112 @*/ 113 PetscErrorCode TSAdaptRegisterDestroy(void) 114 { 115 PetscErrorCode ierr; 116 117 PetscFunctionBegin; 118 ierr = PetscFListDestroy(&TSAdaptList);CHKERRQ(ierr); 119 TSAdaptRegisterAllCalled = PETSC_FALSE; 120 PetscFunctionReturn(0); 121 } 122 123 124 #undef __FUNCT__ 125 #define __FUNCT__ "TSAdaptSetType" 126 PetscErrorCode TSAdaptSetType(TSAdapt adapt,const TSAdaptType type) 127 { 128 PetscErrorCode ierr,(*r)(TSAdapt); 129 130 PetscFunctionBegin; 131 ierr = PetscFListFind(TSAdaptList,((PetscObject)adapt)->comm,type,PETSC_TRUE,(void(**)(void))&r);CHKERRQ(ierr); 132 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TSAdapt type \"%s\" given",type); 133 if (((PetscObject)adapt)->type_name) {ierr = (*adapt->ops->destroy)(adapt);CHKERRQ(ierr);} 134 ierr = (*r)(adapt);CHKERRQ(ierr); 135 ierr = PetscObjectChangeTypeName((PetscObject)adapt,type);CHKERRQ(ierr); 136 PetscFunctionReturn(0); 137 } 138 139 #undef __FUNCT__ 140 #define __FUNCT__ "TSAdaptSetOptionsPrefix" 141 PetscErrorCode TSAdaptSetOptionsPrefix(TSAdapt adapt,const char prefix[]) 142 { 143 PetscErrorCode ierr; 144 145 PetscFunctionBegin; 146 ierr = PetscObjectSetOptionsPrefix((PetscObject)adapt,prefix);CHKERRQ(ierr); 147 PetscFunctionReturn(0); 148 } 149 150 #undef __FUNCT__ 151 #define __FUNCT__ "TSAdaptView" 152 PetscErrorCode TSAdaptView(TSAdapt adapt,PetscViewer viewer) 153 { 154 PetscErrorCode ierr; 155 PetscBool iascii; 156 157 PetscFunctionBegin; 158 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 159 if (iascii) { 160 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)adapt,viewer,"TSAdapt Object");CHKERRQ(ierr); 161 ierr = PetscViewerASCIIPrintf(viewer,"number of candidates %D\n",adapt->candidates.n);CHKERRQ(ierr); 162 if (adapt->ops->view) { 163 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 164 ierr = (*adapt->ops->view)(adapt,viewer);CHKERRQ(ierr); 165 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 166 } 167 } else { 168 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name); 169 } 170 PetscFunctionReturn(0); 171 } 172 173 #undef __FUNCT__ 174 #define __FUNCT__ "TSAdaptDestroy" 175 PetscErrorCode TSAdaptDestroy(TSAdapt *adapt) 176 { 177 PetscErrorCode ierr; 178 179 PetscFunctionBegin; 180 if (!*adapt) PetscFunctionReturn(0); 181 PetscValidHeaderSpecific(*adapt,TSADAPT_CLASSID,1); 182 if (--((PetscObject)(*adapt))->refct > 0) {*adapt = 0; PetscFunctionReturn(0);} 183 if ((*adapt)->ops->destroy) {ierr = (*(*adapt)->ops->destroy)(*adapt);CHKERRQ(ierr);} 184 ierr = PetscHeaderDestroy(adapt);CHKERRQ(ierr); 185 PetscFunctionReturn(0); 186 } 187 188 #undef __FUNCT__ 189 #define __FUNCT__ "TSAdaptSetFromOptions" 190 /*@ 191 TSAdaptSetFromOptions - Sets various TSAdapt parameters from user options. 192 193 Collective on TSAdapt 194 195 Input Parameter: 196 . adapt - the TSAdapt context 197 198 Options Database Keys: 199 . -ts_adapt_type <type> - basic 200 201 Level: advanced 202 203 Notes: 204 This function is automatically called by TSSetFromOptions() 205 206 .keywords: TS, TSGetAdapt(), TSAdaptSetType() 207 208 .seealso: TSGetType() 209 @*/ 210 PetscErrorCode TSAdaptSetFromOptions(TSAdapt adapt) 211 { 212 PetscErrorCode ierr; 213 char type[256] = TSADAPTBASIC; 214 PetscBool flg; 215 216 PetscFunctionBegin; 217 /* This should use PetscOptionsBegin() if/when this becomes an object used outside of TS, but currently this 218 * function can only be called from inside TSSetFromOptions_GL() */ 219 ierr = PetscOptionsHead("TS Adaptivity options");CHKERRQ(ierr); 220 ierr = PetscOptionsList("-ts_adapt_type","Algorithm to use for adaptivity","TSAdaptSetType",TSAdaptList, 221 ((PetscObject)adapt)->type_name?((PetscObject)adapt)->type_name:type,type,sizeof type,&flg);CHKERRQ(ierr); 222 if (flg || !((PetscObject)adapt)->type_name) { 223 ierr = TSAdaptSetType(adapt,type);CHKERRQ(ierr); 224 } 225 if (adapt->ops->setfromoptions) {ierr = (*adapt->ops->setfromoptions)(adapt);CHKERRQ(ierr);} 226 ierr = PetscOptionsTail();CHKERRQ(ierr); 227 PetscFunctionReturn(0); 228 } 229 230 #undef __FUNCT__ 231 #define __FUNCT__ "TSAdaptCandidatesClear" 232 /*@ 233 TSAdaptCandidatesClear - clear any previously set candidate schemes 234 235 Logically Collective 236 237 Input Argument: 238 . adapt - adaptive controller 239 240 Level: developer 241 242 .seealso: TSAdapt, TSAdaptCreate(), TSAdaptCandidateAdd(), TSAdaptChoose() 243 @*/ 244 PetscErrorCode TSAdaptCandidatesClear(TSAdapt adapt) 245 { 246 PetscErrorCode ierr; 247 248 PetscFunctionBegin; 249 ierr = PetscMemzero(&adapt->candidates,sizeof(adapt->candidates));CHKERRQ(ierr); 250 PetscFunctionReturn(0); 251 } 252 253 #undef __FUNCT__ 254 #define __FUNCT__ "TSAdaptCandidateAdd" 255 /*@C 256 TSAdaptCandidateAdd - add a candidate scheme for the adaptive controller to select from 257 258 Logically Collective 259 260 Input Arguments: 261 + adapt - time step adaptivity context, obtained with TSGetAdapt() or TSAdaptCreate() 262 . name - name of the candidate scheme to add 263 . order - order of the candidate scheme 264 . stageorder - stage order of the candidate scheme 265 . leadingerror - leading error coefficient of the candidate scheme 266 . cost - relative measure of the amount of work required for the candidate scheme 267 - inuse - indicates that this scheme is the one currently in use, this flag can only be set for one scheme 268 269 Note: 270 This routine is not available in Fortran. 271 272 Level: developer 273 274 .seealso: TSAdaptCandidatesClear(), TSAdaptChoose() 275 @*/ 276 PetscErrorCode TSAdaptCandidateAdd(TSAdapt adapt,const char name[],PetscInt order,PetscInt stageorder,PetscReal leadingerror,PetscReal cost,PetscBool inuse) 277 { 278 PetscInt c; 279 280 PetscFunctionBegin; 281 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 282 if (order < 1) SETERRQ1(((PetscObject)adapt)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Classical order %D must be a positive integer",order); 283 if (inuse) { 284 if (adapt->candidates.inuse_set) SETERRQ(((PetscObject)adapt)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set the inuse method twice, maybe forgot to call TSAdaptCandidatesClear()"); 285 adapt->candidates.inuse_set = PETSC_TRUE; 286 } 287 c = !adapt->candidates.order[0] + adapt->candidates.n; 288 adapt->candidates.name[c] = name; 289 adapt->candidates.order[c] = order; 290 adapt->candidates.stageorder[c] = stageorder; 291 adapt->candidates.leadingerror[c] = leadingerror; 292 adapt->candidates.cost[c] = cost; 293 adapt->candidates.n++; 294 PetscFunctionReturn(0); 295 } 296 297 #undef __FUNCT__ 298 #define __FUNCT__ "TSAdaptChoose" 299 /*@C 300 TSAdaptChoose - choose which method and step size to use for the next step 301 302 Logically Collective 303 304 Input Arguments: 305 + adapt - adaptive contoller 306 - h - current step size 307 308 Output Arguments: 309 + next_sc - scheme to use for the next step 310 . next_h - step size to use for the next step 311 - accept - PETSC_TRUE to accept the current step, PETSC_FALSE to repeat the current step with the new step size 312 313 Level: developer 314 315 .seealso: TSAdapt, TSAdaptCandidatesClear(), TSAdaptCandidateAdd() 316 @*/ 317 PetscErrorCode TSAdaptChoose(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept) 318 { 319 PetscErrorCode ierr; 320 321 PetscFunctionBegin; 322 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 323 PetscValidHeaderSpecific(ts,TS_CLASSID,2); 324 PetscValidIntPointer(next_sc,4); 325 PetscValidPointer(next_h,5); 326 PetscValidIntPointer(accept,6); 327 if (adapt->candidates.n < 1) SETERRQ1(((PetscObject)adapt)->comm,PETSC_ERR_ARG_WRONGSTATE,"%D candidates have been registered",adapt->candidates.n); 328 if (!adapt->candidates.inuse_set) SETERRQ1(((PetscObject)adapt)->comm,PETSC_ERR_ARG_WRONGSTATE,"The current in-use scheme is not among the %D candidates",adapt->candidates.n); 329 ierr = (*adapt->ops->choose)(adapt,ts,h,next_sc,next_h,accept);CHKERRQ(ierr); 330 PetscFunctionReturn(0); 331 } 332 333 #undef __FUNCT__ 334 #define __FUNCT__ "TSAdaptCreate" 335 /*@ 336 TSAdaptCreate - create an adaptive controller context for time stepping 337 338 Collective on MPI_Comm 339 340 Input Parameter: 341 . comm - The communicator 342 343 Output Parameter: 344 . adapt - new TSAdapt object 345 346 Level: developer 347 348 Notes: 349 TSAdapt creation is handled by TS, so users should not need to call this function. 350 351 .keywords: TSAdapt, create 352 .seealso: TSGetAdapt(), TSAdaptSetType(), TSAdaptDestroy() 353 @*/ 354 PetscErrorCode TSAdaptCreate(MPI_Comm comm,TSAdapt *inadapt) 355 { 356 PetscErrorCode ierr; 357 TSAdapt adapt; 358 359 PetscFunctionBegin; 360 *inadapt = 0; 361 ierr = PetscHeaderCreate(adapt,_p_TSAdapt,struct _TSAdaptOps,TSADAPT_CLASSID,0,"TSAdapt","General Linear adaptivity","TS",comm,TSAdaptDestroy,TSAdaptView);CHKERRQ(ierr); 362 *inadapt = adapt; 363 PetscFunctionReturn(0); 364 } 365