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