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