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