1 #include <petsc/private/dmforestimpl.h> /*I petscdmforest.h I*/ 2 #include <petsc/private/dmimpl.h> /*I petscdm.h */ 3 #include <petscsf.h> 4 5 PetscBool DMForestPackageInitialized = PETSC_FALSE; 6 7 typedef struct _DMForestTypeLink *DMForestTypeLink; 8 9 struct _DMForestTypeLink 10 { 11 char *name; 12 DMForestTypeLink next; 13 }; 14 15 DMForestTypeLink DMForestTypeList; 16 17 #undef __FUNCT__ 18 #define __FUNCT__ "DMForestPackageFinalize" 19 static PetscErrorCode DMForestPackageFinalize(void) 20 { 21 DMForestTypeLink oldLink, link = DMForestTypeList; 22 PetscErrorCode ierr; 23 24 PetscFunctionBegin; 25 while (link) { 26 oldLink = link; 27 ierr = PetscFree(oldLink->name); 28 link = oldLink->next; 29 ierr = PetscFree(oldLink);CHKERRQ(ierr); 30 } 31 PetscFunctionReturn(0); 32 } 33 34 #undef __FUNCT__ 35 #define __FUNCT__ "DMForestPackageInitialize" 36 static PetscErrorCode DMForestPackageInitialize(void) 37 { 38 PetscErrorCode ierr; 39 40 PetscFunctionBegin; 41 if (DMForestPackageInitialized) PetscFunctionReturn(0); 42 DMForestPackageInitialized = PETSC_TRUE; 43 ierr = DMForestRegisterType(DMFOREST);CHKERRQ(ierr); 44 ierr = PetscRegisterFinalize(DMForestPackageFinalize);CHKERRQ(ierr); 45 PetscFunctionReturn(0); 46 } 47 48 #undef __FUNCT__ 49 #define __FUNCT__ "DMForestRegisterType" 50 PetscErrorCode DMForestRegisterType(DMType name) 51 { 52 DMForestTypeLink link; 53 PetscErrorCode ierr; 54 55 PetscFunctionBegin; 56 ierr = DMForestPackageInitialize();CHKERRQ(ierr); 57 ierr = PetscNew(&link);CHKERRQ(ierr); 58 ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr); 59 link->next = DMForestTypeList; 60 DMForestTypeList = link; 61 PetscFunctionReturn(0); 62 } 63 64 #undef __FUNCT__ 65 #define __FUNCT__ "DMIsForest" 66 PetscErrorCode DMIsForest(DM dm, PetscBool *isForest) 67 { 68 DMForestTypeLink link = DMForestTypeList; 69 PetscErrorCode ierr; 70 71 PetscFunctionBegin; 72 while (link) { 73 PetscBool sameType; 74 ierr = PetscObjectTypeCompare((PetscObject)dm,link->name,&sameType);CHKERRQ(ierr); 75 if (sameType) { 76 *isForest = PETSC_TRUE; 77 PetscFunctionReturn(0); 78 } 79 link = link->next; 80 } 81 *isForest = PETSC_FALSE; 82 PetscFunctionReturn(0); 83 } 84 85 #undef __FUNCT__ 86 #define __FUNCT__ "DMForestTemplate" 87 PETSC_EXTERN PetscErrorCode DMForestTemplate(DM dm, MPI_Comm comm, DM *tdm) 88 { 89 DM_Forest *forest = (DM_Forest *) dm->data; 90 DMType type; 91 DM base; 92 DMForestTopology topology; 93 PetscInt dim, overlap, ref, factor; 94 DMForestAdaptivityStrategy strat; 95 PetscDS ds; 96 void *ctx; 97 PetscErrorCode ierr; 98 99 PetscFunctionBegin; 100 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 101 ierr = DMCreate(PetscObjectComm((PetscObject)dm),tdm);CHKERRQ(ierr); 102 ierr = DMGetType(dm,&type);CHKERRQ(ierr); 103 ierr = DMSetType(*tdm,type);CHKERRQ(ierr); 104 ierr = DMForestGetBaseDM(dm,&base);CHKERRQ(ierr); 105 ierr = DMForestSetBaseDM(*tdm,base);CHKERRQ(ierr); 106 ierr = DMForestGetTopology(dm,&topology);CHKERRQ(ierr); 107 ierr = DMForestSetTopology(*tdm,topology);CHKERRQ(ierr); 108 ierr = DMForestGetAdjacencyDimension(dm,&dim);CHKERRQ(ierr); 109 ierr = DMForestSetAdjacencyDimension(*tdm,dim);CHKERRQ(ierr); 110 ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr); 111 ierr = DMForestSetPartitionOverlap(*tdm,overlap);CHKERRQ(ierr); 112 ierr = DMForestGetMinimumRefinement(dm,&ref);CHKERRQ(ierr); 113 ierr = DMForestSetMinimumRefinement(*tdm,ref);CHKERRQ(ierr); 114 ierr = DMForestGetMaximumRefinement(dm,&ref);CHKERRQ(ierr); 115 ierr = DMForestSetMaximumRefinement(*tdm,ref);CHKERRQ(ierr); 116 ierr = DMForestGetAdaptivityStrategy(dm,&strat);CHKERRQ(ierr); 117 ierr = DMForestSetAdaptivityStrategy(*tdm,strat);CHKERRQ(ierr); 118 ierr = DMForestGetGradeFactor(dm,&factor);CHKERRQ(ierr); 119 ierr = DMForestSetGradeFactor(*tdm,factor);CHKERRQ(ierr); 120 if (forest->ftemplate) { 121 ierr = (forest->ftemplate) (dm, *tdm);CHKERRQ(ierr); 122 } 123 ierr = DMForestSetAdaptivityForest(*tdm,dm);CHKERRQ(ierr); 124 ierr = DMGetDS(dm,&ds);CHKERRQ(ierr); 125 ierr = DMSetDS(*tdm,ds);CHKERRQ(ierr); 126 ierr = DMGetApplicationContext(dm,&ctx);CHKERRQ(ierr); 127 ierr = DMSetApplicationContext(*tdm,&ctx);CHKERRQ(ierr); 128 if (dm->maxCell) { 129 const PetscReal *maxCell, *L; 130 const DMBoundaryType *bd; 131 132 ierr = DMGetPeriodicity(dm,&maxCell,&L,&bd);CHKERRQ(ierr); 133 ierr = DMSetPeriodicity(*tdm,maxCell,L,bd);CHKERRQ(ierr); 134 } 135 PetscFunctionReturn(0); 136 } 137 138 static PetscErrorCode DMInitialize_Forest(DM dm); 139 140 #undef __FUNCT__ 141 #define __FUNCT__ "DMClone_Forest" 142 PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm) 143 { 144 DM_Forest *forest = (DM_Forest *) dm->data; 145 const char *type; 146 PetscErrorCode ierr; 147 148 PetscFunctionBegin; 149 forest->refct++; 150 (*newdm)->data = forest; 151 ierr = PetscObjectGetType((PetscObject) dm, &type);CHKERRQ(ierr); 152 ierr = PetscObjectChangeTypeName((PetscObject) *newdm, type);CHKERRQ(ierr); 153 ierr = DMInitialize_Forest(*newdm);CHKERRQ(ierr); 154 PetscFunctionReturn(0); 155 } 156 157 #undef __FUNCT__ 158 #define __FUNCT__ "DMDestroy_Forest" 159 static PetscErrorCode DMDestroy_Forest(DM dm) 160 { 161 DM_Forest *forest = (DM_Forest*) dm->data; 162 PetscErrorCode ierr; 163 164 PetscFunctionBegin; 165 if (--forest->refct > 0) PetscFunctionReturn(0); 166 if (forest->destroy) {ierr = forest->destroy(dm);CHKERRQ(ierr);} 167 ierr = PetscSFDestroy(&forest->cellSF);CHKERRQ(ierr); 168 ierr = PetscFree(forest->adaptLabel);CHKERRQ(ierr); 169 ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr); 170 ierr = DMDestroy(&forest->base);CHKERRQ(ierr); 171 ierr = DMDestroy(&forest->adapt);CHKERRQ(ierr); 172 ierr = PetscFree(forest->topology);CHKERRQ(ierr); 173 ierr = PetscFree(forest);CHKERRQ(ierr); 174 PetscFunctionReturn(0); 175 } 176 177 #undef __FUNCT__ 178 #define __FUNCT__ "DMForestSetTopology" 179 PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology) 180 { 181 DM_Forest *forest = (DM_Forest *) dm->data; 182 PetscErrorCode ierr; 183 184 PetscFunctionBegin; 185 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 186 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup"); 187 ierr = PetscFree(forest->topology);CHKERRQ(ierr); 188 ierr = PetscStrallocpy((const char *)topology,(char **) &forest->topology);CHKERRQ(ierr); 189 PetscFunctionReturn(0); 190 } 191 192 #undef __FUNCT__ 193 #define __FUNCT__ "DMForestGetTopology" 194 PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology) 195 { 196 DM_Forest *forest = (DM_Forest *) dm->data; 197 198 PetscFunctionBegin; 199 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 200 PetscValidPointer(topology,2); 201 *topology = forest->topology; 202 PetscFunctionReturn(0); 203 } 204 205 #undef __FUNCT__ 206 #define __FUNCT__ "DMForestSetBaseDM" 207 PetscErrorCode DMForestSetBaseDM(DM dm, DM base) 208 { 209 DM_Forest *forest = (DM_Forest *) dm->data; 210 PetscInt dim, dimEmbed; 211 PetscErrorCode ierr; 212 213 PetscFunctionBegin; 214 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 215 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup"); 216 ierr = PetscObjectReference((PetscObject)base);CHKERRQ(ierr); 217 ierr = DMDestroy(&forest->base);CHKERRQ(ierr); 218 forest->base = base; 219 if (base) { 220 PetscValidHeaderSpecific(base, DM_CLASSID, 2); 221 ierr = DMGetDimension(base,&dim);CHKERRQ(ierr); 222 ierr = DMSetDimension(dm,dim);CHKERRQ(ierr); 223 ierr = DMGetCoordinateDim(base,&dimEmbed);CHKERRQ(ierr); 224 ierr = DMSetCoordinateDim(dm,dimEmbed);CHKERRQ(ierr); 225 } 226 PetscFunctionReturn(0); 227 } 228 229 #undef __FUNCT__ 230 #define __FUNCT__ "DMForestGetBaseDM" 231 PetscErrorCode DMForestGetBaseDM(DM dm, DM *base) 232 { 233 DM_Forest *forest = (DM_Forest *) dm->data; 234 235 PetscFunctionBegin; 236 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 237 PetscValidPointer(base, 2); 238 *base = forest->base; 239 PetscFunctionReturn(0); 240 } 241 242 #undef __FUNCT__ 243 #define __FUNCT__ "DMForestSetAdaptivityForest" 244 PetscErrorCode DMForestSetAdaptivityForest(DM dm,DM adapt) 245 { 246 DM_Forest *forest; 247 PetscErrorCode ierr; 248 249 PetscFunctionBegin; 250 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 251 PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 252 forest = (DM_Forest *) dm->data; 253 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup"); 254 switch (forest->adaptPurpose) { 255 case DM_FOREST_KEEP: 256 ierr = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr); 257 ierr = DMDestroy(&(forest->adapt));CHKERRQ(ierr); 258 forest->adapt = adapt; 259 break; 260 case DM_FOREST_REFINE: 261 ierr = DMSetCoarseDM(dm,adapt);CHKERRQ(ierr); 262 break; 263 case DM_FOREST_COARSEN: 264 ierr = DMSetFineDM(dm,adapt);CHKERRQ(ierr); 265 break; 266 default: 267 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose"); 268 } 269 PetscFunctionReturn(0); 270 } 271 272 #undef __FUNCT__ 273 #define __FUNCT__ "DMForestGetAdaptivityForest" 274 PetscErrorCode DMForestGetAdaptivityForest(DM dm, DM *adapt) 275 { 276 DM_Forest *forest; 277 PetscErrorCode ierr; 278 279 PetscFunctionBegin; 280 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 281 forest = (DM_Forest *) dm->data; 282 switch (forest->adaptPurpose) { 283 case DM_FOREST_KEEP: 284 *adapt = forest->adapt; 285 break; 286 case DM_FOREST_REFINE: 287 ierr = DMGetCoarseDM(dm,adapt);CHKERRQ(ierr); 288 break; 289 case DM_FOREST_COARSEN: 290 ierr = DMGetFineDM(dm,adapt);CHKERRQ(ierr); 291 break; 292 default: 293 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose"); 294 } 295 PetscFunctionReturn(0); 296 } 297 298 #undef __FUNCT__ 299 #define __FUNCT__ "DMForestSetAdaptivityPurpose" 300 PetscErrorCode DMForestSetAdaptivityPurpose(DM dm, DMForestAdaptivityPurpose purpose) 301 { 302 DM_Forest *forest; 303 PetscErrorCode ierr; 304 305 PetscFunctionBegin; 306 forest = (DM_Forest *) dm->data; 307 if (purpose != forest->adaptPurpose) { 308 DM adapt; 309 310 ierr = DMForestGetAdaptivityForest(dm,&adapt);CHKERRQ(ierr); 311 ierr = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr); 312 ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr); 313 forest->adaptPurpose = purpose; 314 ierr = DMForestSetAdaptivityForest(dm,adapt);CHKERRQ(ierr); 315 ierr = DMDestroy(&adapt);CHKERRQ(ierr); 316 } 317 PetscFunctionReturn(0); 318 } 319 320 #undef __FUNCT__ 321 #define __FUNCT__ "DMForestSetAdjacencyDimension" 322 PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim) 323 { 324 PetscInt dim; 325 DM_Forest *forest = (DM_Forest *) dm->data; 326 PetscErrorCode ierr; 327 328 PetscFunctionBegin; 329 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 330 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup"); 331 if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim); 332 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 333 if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim); 334 forest->adjDim = adjDim; 335 PetscFunctionReturn(0); 336 } 337 338 #undef __FUNCT__ 339 #define __FUNCT__ "DMForestSetAdjacencyCodimension" 340 PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim) 341 { 342 PetscInt dim; 343 PetscErrorCode ierr; 344 345 PetscFunctionBegin; 346 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 347 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 348 ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr); 349 PetscFunctionReturn(0); 350 } 351 352 #undef __FUNCT__ 353 #define __FUNCT__ "DMForestGetAdjacencyDimension" 354 PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim) 355 { 356 DM_Forest *forest = (DM_Forest *) dm->data; 357 358 PetscFunctionBegin; 359 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 360 PetscValidIntPointer(adjDim,2); 361 *adjDim = forest->adjDim; 362 PetscFunctionReturn(0); 363 } 364 365 #undef __FUNCT__ 366 #define __FUNCT__ "DMForestGetAdjacencyCodimension" 367 PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim) 368 { 369 DM_Forest *forest = (DM_Forest *) dm->data; 370 PetscInt dim; 371 PetscErrorCode ierr; 372 373 PetscFunctionBegin; 374 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 375 PetscValidIntPointer(adjCodim,2); 376 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 377 *adjCodim = dim - forest->adjDim; 378 PetscFunctionReturn(0); 379 } 380 381 #undef __FUNCT__ 382 #define __FUNCT__ "DMForestSetPartitionOverlap" 383 PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap) 384 { 385 DM_Forest *forest = (DM_Forest *) dm->data; 386 387 PetscFunctionBegin; 388 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 389 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup"); 390 if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", overlap); 391 forest->overlap = overlap; 392 PetscFunctionReturn(0); 393 } 394 395 #undef __FUNCT__ 396 #define __FUNCT__ "DMForestGetPartitionOverlap" 397 PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap) 398 { 399 DM_Forest *forest = (DM_Forest *) dm->data; 400 401 PetscFunctionBegin; 402 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 403 PetscValidIntPointer(overlap,2); 404 *overlap = forest->overlap; 405 PetscFunctionReturn(0); 406 } 407 408 #undef __FUNCT__ 409 #define __FUNCT__ "DMForestSetMinimumRefinement" 410 PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement) 411 { 412 DM_Forest *forest = (DM_Forest *) dm->data; 413 414 PetscFunctionBegin; 415 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 416 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup"); 417 forest->minRefinement = minRefinement; 418 PetscFunctionReturn(0); 419 } 420 421 #undef __FUNCT__ 422 #define __FUNCT__ "DMForestGetMinimumRefinement" 423 PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement) 424 { 425 DM_Forest *forest = (DM_Forest *) dm->data; 426 427 PetscFunctionBegin; 428 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 429 PetscValidIntPointer(minRefinement,2); 430 *minRefinement = forest->minRefinement; 431 PetscFunctionReturn(0); 432 } 433 434 #undef __FUNCT__ 435 #define __FUNCT__ "DMForestSetInitialRefinement" 436 PetscErrorCode DMForestSetInitialRefinement(DM dm, PetscInt initRefinement) 437 { 438 DM_Forest *forest = (DM_Forest *) dm->data; 439 440 PetscFunctionBegin; 441 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 442 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the initial refinement after setup"); 443 forest->initRefinement = initRefinement; 444 PetscFunctionReturn(0); 445 } 446 447 #undef __FUNCT__ 448 #define __FUNCT__ "DMForestGetInitialRefinement" 449 PetscErrorCode DMForestGetInitialRefinement(DM dm, PetscInt *initRefinement) 450 { 451 DM_Forest *forest = (DM_Forest *) dm->data; 452 453 PetscFunctionBegin; 454 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 455 PetscValidIntPointer(initRefinement,2); 456 *initRefinement = forest->initRefinement; 457 PetscFunctionReturn(0); 458 } 459 460 #undef __FUNCT__ 461 #define __FUNCT__ "DMForestSetMaximumRefinement" 462 PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement) 463 { 464 DM_Forest *forest = (DM_Forest *) dm->data; 465 466 PetscFunctionBegin; 467 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 468 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the maximum refinement after setup"); 469 forest->maxRefinement = maxRefinement; 470 PetscFunctionReturn(0); 471 } 472 473 #undef __FUNCT__ 474 #define __FUNCT__ "DMForestGetMaximumRefinement" 475 PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement) 476 { 477 DM_Forest *forest = (DM_Forest *) dm->data; 478 479 PetscFunctionBegin; 480 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 481 PetscValidIntPointer(maxRefinement,2); 482 *maxRefinement = forest->maxRefinement; 483 PetscFunctionReturn(0); 484 } 485 486 #undef __FUNCT__ 487 #define __FUNCT__ "DMForestSetAdaptivityStrategy" 488 PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy) 489 { 490 DM_Forest *forest = (DM_Forest *) dm->data; 491 PetscErrorCode ierr; 492 493 PetscFunctionBegin; 494 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 495 ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr); 496 ierr = PetscStrallocpy((const char *) adaptStrategy,(char **)&forest->adaptStrategy);CHKERRQ(ierr); 497 PetscFunctionReturn(0); 498 } 499 500 #undef __FUNCT__ 501 #define __FUNCT__ "DMForestGetAdaptivityStrategy" 502 PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy) 503 { 504 DM_Forest *forest = (DM_Forest *) dm->data; 505 506 PetscFunctionBegin; 507 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 508 PetscValidPointer(adaptStrategy,2); 509 *adaptStrategy = forest->adaptStrategy; 510 PetscFunctionReturn(0); 511 } 512 513 #undef __FUNCT__ 514 #define __FUNCT__ "DMForestSetGradeFactor" 515 PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade) 516 { 517 DM_Forest *forest = (DM_Forest *) dm->data; 518 519 PetscFunctionBegin; 520 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 521 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup"); 522 forest->gradeFactor = grade; 523 PetscFunctionReturn(0); 524 } 525 526 #undef __FUNCT__ 527 #define __FUNCT__ "DMForestGetGradeFactor" 528 PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade) 529 { 530 DM_Forest *forest = (DM_Forest *) dm->data; 531 532 PetscFunctionBegin; 533 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 534 PetscValidIntPointer(grade,2); 535 *grade = forest->gradeFactor; 536 PetscFunctionReturn(0); 537 } 538 539 #undef __FUNCT__ 540 #define __FUNCT__ "DMForestSetCellWeightFactor" 541 PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor) 542 { 543 DM_Forest *forest = (DM_Forest *) dm->data; 544 545 PetscFunctionBegin; 546 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 547 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup"); 548 forest->weightsFactor = weightsFactor; 549 PetscFunctionReturn(0); 550 } 551 552 #undef __FUNCT__ 553 #define __FUNCT__ "DMForestGetCellWeightFactor" 554 PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor) 555 { 556 DM_Forest *forest = (DM_Forest *) dm->data; 557 558 PetscFunctionBegin; 559 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 560 PetscValidRealPointer(weightsFactor,2); 561 *weightsFactor = forest->weightsFactor; 562 PetscFunctionReturn(0); 563 } 564 565 #undef __FUNCT__ 566 #define __FUNCT__ "DMForestGetCellChart" 567 PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd) 568 { 569 DM_Forest *forest = (DM_Forest *) dm->data; 570 PetscErrorCode ierr; 571 572 PetscFunctionBegin; 573 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 574 PetscValidIntPointer(cStart,2); 575 PetscValidIntPointer(cEnd,2); 576 if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) { 577 ierr = forest->createcellchart(dm,&forest->cStart,&forest->cEnd);CHKERRQ(ierr); 578 } 579 *cStart = forest->cStart; 580 *cEnd = forest->cEnd; 581 PetscFunctionReturn(0); 582 } 583 584 #undef __FUNCT__ 585 #define __FUNCT__ "DMForestGetCellSF" 586 PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF) 587 { 588 DM_Forest *forest = (DM_Forest *) dm->data; 589 PetscErrorCode ierr; 590 591 PetscFunctionBegin; 592 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 593 PetscValidPointer(cellSF,2); 594 if ((!forest->cellSF) && forest->createcellsf) { 595 ierr = forest->createcellsf(dm,&forest->cellSF);CHKERRQ(ierr); 596 } 597 *cellSF = forest->cellSF; 598 PetscFunctionReturn(0); 599 } 600 601 #undef __FUNCT__ 602 #define __FUNCT__ "DMForestSetAdaptivityLabel" 603 PetscErrorCode DMForestSetAdaptivityLabel(DM dm, const char * adaptLabel) 604 { 605 DM_Forest *forest = (DM_Forest *) dm->data; 606 PetscErrorCode ierr; 607 608 PetscFunctionBegin; 609 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 610 ierr = PetscFree(forest->adaptLabel);CHKERRQ(ierr); 611 ierr = PetscStrallocpy(adaptLabel,&forest->adaptLabel);CHKERRQ(ierr); 612 PetscFunctionReturn(0); 613 } 614 615 #undef __FUNCT__ 616 #define __FUNCT__ "DMForestGetAdaptivityLabel" 617 PetscErrorCode DMForestGetAdaptivityLabel(DM dm, const char ** adaptLabel) 618 { 619 DM_Forest *forest = (DM_Forest *) dm->data; 620 621 PetscFunctionBegin; 622 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 623 *adaptLabel = forest->adaptLabel; 624 PetscFunctionReturn(0); 625 } 626 627 #undef __FUNCT__ 628 #define __FUNCT__ "DMForestSetCellWeights" 629 PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode) 630 { 631 DM_Forest *forest = (DM_Forest *) dm->data; 632 PetscInt cStart, cEnd; 633 PetscErrorCode ierr; 634 635 PetscFunctionBegin; 636 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 637 ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr); 638 if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd); 639 if (copyMode == PETSC_COPY_VALUES) { 640 if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) { 641 ierr = PetscMalloc1(cEnd-cStart,&forest->cellWeights);CHKERRQ(ierr); 642 } 643 ierr = PetscMemcpy(forest->cellWeights,weights,(cEnd-cStart)*sizeof(*weights));CHKERRQ(ierr); 644 forest->cellWeightsCopyMode = PETSC_OWN_POINTER; 645 PetscFunctionReturn(0); 646 } 647 if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) { 648 ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr); 649 } 650 forest->cellWeights = weights; 651 forest->cellWeightsCopyMode = copyMode; 652 PetscFunctionReturn(0); 653 } 654 655 #undef __FUNCT__ 656 #define __FUNCT__ "DMForestGetCellWeights" 657 PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights) 658 { 659 DM_Forest *forest = (DM_Forest *) dm->data; 660 661 PetscFunctionBegin; 662 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 663 PetscValidPointer(weights,2); 664 *weights = forest->cellWeights; 665 PetscFunctionReturn(0); 666 } 667 668 #undef __FUNCT__ 669 #define __FUNCT__ "DMForestSetWeightCapacity" 670 PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity) 671 { 672 DM_Forest *forest = (DM_Forest *) dm->data; 673 674 PetscFunctionBegin; 675 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 676 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup"); 677 if (capacity < 0.) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %f",capacity); 678 forest->weightCapacity = capacity; 679 PetscFunctionReturn(0); 680 } 681 682 #undef __FUNCT__ 683 #define __FUNCT__ "DMForestGetWeightCapacity" 684 PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity) 685 { 686 DM_Forest *forest = (DM_Forest *) dm->data; 687 688 PetscFunctionBegin; 689 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 690 PetscValidRealPointer(capacity,2); 691 *capacity = forest->weightCapacity; 692 PetscFunctionReturn(0); 693 } 694 695 #undef __FUNCT__ 696 #define __FUNCT__ "DMSetFromOptions_Forest" 697 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(PetscOptionItems *PetscOptionsObject,DM dm) 698 { 699 DM_Forest *forest = (DM_Forest *) dm->data; 700 PetscBool flg, flg1, flg2, flg3, flg4; 701 DMForestTopology oldTopo; 702 char stringBuffer[256]; 703 PetscViewer viewer; 704 PetscViewerFormat format; 705 PetscInt adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade; 706 PetscReal weightsFactor; 707 DMForestAdaptivityStrategy adaptStrategy; 708 PetscErrorCode ierr; 709 710 PetscFunctionBegin; 711 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 712 forest->setfromoptionscalled = PETSC_TRUE; 713 ierr = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr); 714 ierr = PetscOptionsHead(PetscOptionsObject,"DMForest Options");CHKERRQ(ierr); 715 ierr = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,256,&flg1);CHKERRQ(ierr); 716 ierr = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg2);CHKERRQ(ierr); 717 ierr = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg3);CHKERRQ(ierr); 718 ierr = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg4);CHKERRQ(ierr); 719 if ((PetscInt) flg1 + (PetscInt) flg2 + (PetscInt) flg3 + (PetscInt) flg4 > 1) { 720 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Specify only one of -dm_forest_{topology,base_dm,coarse_forest,fine_forest}"); 721 } 722 if (flg1) { 723 ierr = DMForestSetTopology(dm,(DMForestTopology)stringBuffer);CHKERRQ(ierr); 724 ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr); 725 ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr); 726 } 727 if (flg2) { 728 DM base; 729 730 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr); 731 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 732 ierr = DMLoad(base,viewer);CHKERRQ(ierr); 733 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 734 ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr); 735 ierr = DMDestroy(&base);CHKERRQ(ierr); 736 ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr); 737 ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr); 738 } 739 if (flg3) { 740 DM coarse; 741 742 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr); 743 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 744 ierr = DMLoad(coarse,viewer);CHKERRQ(ierr); 745 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 746 ierr = DMForestSetAdaptivityForest(dm,coarse);CHKERRQ(ierr); 747 ierr = DMDestroy(&coarse);CHKERRQ(ierr); 748 ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr); 749 ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr); 750 } 751 if (flg4) { 752 DM fine; 753 754 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr); 755 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 756 ierr = DMLoad(fine,viewer);CHKERRQ(ierr); 757 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 758 ierr = DMForestSetAdaptivityForest(dm,fine);CHKERRQ(ierr); 759 ierr = DMDestroy(&fine);CHKERRQ(ierr); 760 ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr); 761 ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr); 762 } 763 ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr); 764 ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr); 765 if (flg) { 766 ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr); 767 } 768 else { 769 ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr); 770 ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr); 771 if (flg) { 772 ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr); 773 } 774 } 775 ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr); 776 ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr); 777 if (flg) { 778 ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr); 779 } 780 #if 0 781 ierr = PetscOptionsInt("-dm_refine","equivalent to -dm_forest_set_minimum_refinement and -dm_forest_set_initial_refinement with the same value",NULL,minRefinement,&minRefinement,&flg);CHKERRQ(ierr); 782 if (flg) { 783 ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr); 784 ierr = DMForestSetInitialRefinement(dm,minRefinement);CHKERRQ(ierr); 785 } 786 ierr = PetscOptionsInt("-dm_refine_hierarchy","equivalent to -dm_forest_set_minimum_refinement 0 and -dm_forest_set_initial_refinement",NULL,initRefinement,&initRefinement,&flg);CHKERRQ(ierr); 787 if (flg) { 788 ierr = DMForestSetMinimumRefinement(dm,0);CHKERRQ(ierr); 789 ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr); 790 } 791 #endif 792 ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr); 793 ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr); 794 if (flg) { 795 ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr); 796 } 797 ierr = DMForestGetInitialRefinement(dm,&initRefinement);CHKERRQ(ierr); 798 ierr = PetscOptionsInt("-dm_forest_initial_refinement","set the initial level of refinement in the forest","DMForestSetInitialRefinement",initRefinement,&initRefinement,&flg);CHKERRQ(ierr); 799 if (flg) { 800 ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr); 801 } 802 ierr = DMForestGetMaximumRefinement(dm,&maxRefinement);CHKERRQ(ierr); 803 ierr = PetscOptionsInt("-dm_forest_maximum_refinement","set the maximum level of refinement in the forest","DMForestSetMaximumRefinement",maxRefinement,&maxRefinement,&flg);CHKERRQ(ierr); 804 if (flg) { 805 ierr = DMForestSetMaximumRefinement(dm,maxRefinement);CHKERRQ(ierr); 806 } 807 ierr = DMForestGetAdaptivityStrategy(dm,&adaptStrategy);CHKERRQ(ierr); 808 ierr = PetscOptionsString("-dm_forest_adaptivity_strategy","the forest's adaptivity-flag resolution strategy","DMForestSetAdaptivityStrategy",adaptStrategy,stringBuffer,256,&flg);CHKERRQ(ierr); 809 if (flg) { 810 ierr = DMForestSetAdaptivityStrategy(dm,(DMForestAdaptivityStrategy)stringBuffer);CHKERRQ(ierr); 811 } 812 ierr = DMForestGetGradeFactor(dm,&grade);CHKERRQ(ierr); 813 ierr = PetscOptionsInt("-dm_forest_grade_factor","grade factor between neighboring cells","DMForestSetGradeFactor",grade,&grade,&flg);CHKERRQ(ierr); 814 if (flg) { 815 ierr = DMForestSetGradeFactor(dm,grade);CHKERRQ(ierr); 816 } 817 ierr = DMForestGetCellWeightFactor(dm,&weightsFactor);CHKERRQ(ierr); 818 ierr = PetscOptionsReal("-dm_forest_cell_weight_factor","multiplying weight factor for cell refinement","DMForestSetCellWeightFactor",weightsFactor,&weightsFactor,&flg);CHKERRQ(ierr); 819 if (flg) { 820 ierr = DMForestSetCellWeightFactor(dm,weightsFactor);CHKERRQ(ierr); 821 } 822 ierr = PetscOptionsTail();CHKERRQ(ierr); 823 PetscFunctionReturn(0); 824 } 825 826 #undef __FUNCT__ 827 #define __FUNCT__ "DMCreateSubDM_Forest" 828 PetscErrorCode DMCreateSubDM_Forest(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) 829 { 830 PetscErrorCode ierr; 831 832 PetscFunctionBegin; 833 if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 834 ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 835 PetscFunctionReturn(0); 836 } 837 838 #undef __FUNCT__ 839 #define __FUNCT__ "DMRefine_Forest" 840 PetscErrorCode DMRefine_Forest(DM dm, MPI_Comm comm, DM *dmRefined) 841 { 842 DMLabel refine; 843 DM fineDM; 844 PetscErrorCode ierr; 845 846 PetscFunctionBegin; 847 ierr = DMGetFineDM(dm,&fineDM);CHKERRQ(ierr); 848 if (fineDM) { 849 ierr = PetscObjectReference((PetscObject)fineDM);CHKERRQ(ierr); 850 *dmRefined = fineDM; 851 PetscFunctionReturn(0); 852 } 853 ierr = DMForestTemplate(dm,comm,dmRefined);CHKERRQ(ierr); 854 ierr = DMGetLabel(dm,"refine",&refine);CHKERRQ(ierr); 855 if (!refine) { 856 ierr = DMCreateLabel(dm,"refine");CHKERRQ(ierr); 857 ierr = DMGetLabel(dm,"refine",&refine);CHKERRQ(ierr); 858 ierr = DMLabelSetDefaultValue(refine,DM_FOREST_REFINE);CHKERRQ(ierr); 859 } 860 ierr = DMForestSetAdaptivityLabel(*dmRefined,"refine");CHKERRQ(ierr); 861 PetscFunctionReturn(0); 862 } 863 864 #undef __FUNCT__ 865 #define __FUNCT__ "DMCoarsen_Forest" 866 PetscErrorCode DMCoarsen_Forest(DM dm, MPI_Comm comm, DM *dmCoarsened) 867 { 868 DMLabel coarsen; 869 DM coarseDM; 870 PetscErrorCode ierr; 871 872 PetscFunctionBegin; 873 ierr = DMGetCoarseDM(dm,&coarseDM);CHKERRQ(ierr); 874 if (coarseDM) { 875 ierr = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr); 876 *dmCoarsened = coarseDM; 877 PetscFunctionReturn(0); 878 } 879 ierr = DMForestTemplate(dm,comm,dmCoarsened);CHKERRQ(ierr); 880 ierr = DMGetLabel(dm,"coarsen",&coarsen);CHKERRQ(ierr); 881 if (!coarsen) { 882 ierr = DMCreateLabel(dm,"coarsen");CHKERRQ(ierr); 883 ierr = DMGetLabel(dm,"coarsen",&coarsen);CHKERRQ(ierr); 884 ierr = DMLabelSetDefaultValue(coarsen,DM_FOREST_COARSEN);CHKERRQ(ierr); 885 } 886 ierr = DMForestSetAdaptivityLabel(*dmCoarsened,"coarsen");CHKERRQ(ierr); 887 PetscFunctionReturn(0); 888 } 889 890 #undef __FUNCT__ 891 #define __FUNCT__ "DMInitialize_Forest" 892 static PetscErrorCode DMInitialize_Forest(DM dm) 893 { 894 PetscErrorCode ierr; 895 896 PetscFunctionBegin; 897 ierr = PetscMemzero(dm->ops,sizeof(*(dm->ops)));CHKERRQ(ierr); 898 899 dm->ops->clone = DMClone_Forest; 900 dm->ops->setfromoptions = DMSetFromOptions_Forest; 901 dm->ops->destroy = DMDestroy_Forest; 902 dm->ops->createsubdm = DMCreateSubDM_Forest; 903 dm->ops->refine = DMRefine_Forest; 904 dm->ops->coarsen = DMCoarsen_Forest; 905 PetscFunctionReturn(0); 906 } 907 908 #undef __FUNCT__ 909 #define __FUNCT__ "DMCreate_Forest" 910 PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm) 911 { 912 DM_Forest *forest; 913 PetscErrorCode ierr; 914 915 PetscFunctionBegin; 916 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 917 ierr = PetscNewLog(dm,&forest);CHKERRQ(ierr); 918 dm->dim = 0; 919 dm->data = forest; 920 forest->refct = 1; 921 forest->data = NULL; 922 forest->setfromoptionscalled = PETSC_FALSE; 923 forest->topology = NULL; 924 forest->base = NULL; 925 forest->adjDim = PETSC_DEFAULT; 926 forest->overlap = PETSC_DEFAULT; 927 forest->minRefinement = PETSC_DEFAULT; 928 forest->maxRefinement = PETSC_DEFAULT; 929 forest->initRefinement = PETSC_DEFAULT; 930 forest->cStart = PETSC_DETERMINE; 931 forest->cEnd = PETSC_DETERMINE; 932 forest->cellSF = 0; 933 forest->adaptLabel = NULL; 934 forest->gradeFactor = 2; 935 forest->cellWeights = NULL; 936 forest->cellWeightsCopyMode = PETSC_USE_POINTER; 937 forest->weightsFactor = 1.; 938 forest->weightCapacity = 1.; 939 ierr = DMForestSetAdaptivityStrategy(dm,DMFORESTADAPTALL);CHKERRQ(ierr); 940 ierr = DMInitialize_Forest(dm);CHKERRQ(ierr); 941 PetscFunctionReturn(0); 942 } 943 944