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