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 ierr = PetscFree(forest->adaptLabel);CHKERRQ(ierr); 152 ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr); 153 ierr = DMDestroy(&forest->base);CHKERRQ(ierr); 154 ierr = PetscFree(forest->topology);CHKERRQ(ierr); 155 ierr = PetscFree(forest);CHKERRQ(ierr); 156 PetscFunctionReturn(0); 157 } 158 159 #undef __FUNCT__ 160 #define __FUNCT__ "DMForestSetTopology" 161 PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology) 162 { 163 DM_Forest *forest = (DM_Forest *) dm->data; 164 PetscErrorCode ierr; 165 166 PetscFunctionBegin; 167 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 168 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup"); 169 ierr = PetscFree(forest->topology);CHKERRQ(ierr); 170 ierr = PetscStrallocpy((const char *)topology,(char **) &forest->topology);CHKERRQ(ierr); 171 PetscFunctionReturn(0); 172 } 173 174 #undef __FUNCT__ 175 #define __FUNCT__ "DMForestGetTopology" 176 PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology) 177 { 178 DM_Forest *forest = (DM_Forest *) dm->data; 179 180 PetscFunctionBegin; 181 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 182 PetscValidPointer(topology,2); 183 *topology = forest->topology; 184 PetscFunctionReturn(0); 185 } 186 187 #undef __FUNCT__ 188 #define __FUNCT__ "DMForestSetBaseDM" 189 PetscErrorCode DMForestSetBaseDM(DM dm, DM base) 190 { 191 DM_Forest *forest = (DM_Forest *) dm->data; 192 PetscInt dim, dimEmbed; 193 PetscErrorCode ierr; 194 195 PetscFunctionBegin; 196 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 197 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup"); 198 ierr = PetscObjectReference((PetscObject)base);CHKERRQ(ierr); 199 ierr = DMDestroy(&forest->base);CHKERRQ(ierr); 200 forest->base = base; 201 if (base) { 202 PetscValidHeaderSpecific(base, DM_CLASSID, 2); 203 ierr = DMGetDimension(base,&dim);CHKERRQ(ierr); 204 ierr = DMSetDimension(dm,dim);CHKERRQ(ierr); 205 ierr = DMGetCoordinateDim(base,&dimEmbed);CHKERRQ(ierr); 206 ierr = DMSetCoordinateDim(dm,dimEmbed);CHKERRQ(ierr); 207 } 208 PetscFunctionReturn(0); 209 } 210 211 #undef __FUNCT__ 212 #define __FUNCT__ "DMForestGetBaseDM" 213 PetscErrorCode DMForestGetBaseDM(DM dm, DM *base) 214 { 215 DM_Forest *forest = (DM_Forest *) dm->data; 216 217 PetscFunctionBegin; 218 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 219 PetscValidPointer(base, 2); 220 *base = forest->base; 221 PetscFunctionReturn(0); 222 } 223 224 #undef __FUNCT__ 225 #define __FUNCT__ "DMForestSetCoarseForest" 226 PetscErrorCode DMForestSetCoarseForest(DM dm,DM coarse) 227 { 228 PetscErrorCode ierr; 229 230 PetscFunctionBegin; 231 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 232 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the coarse forest after setup"); 233 ierr = DMSetCoarseDM(dm,coarse);CHKERRQ(ierr); 234 if (coarse) { 235 PetscValidHeaderSpecific(coarse, DM_CLASSID, 2); 236 ierr = DMForestTemplate(coarse,dm);CHKERRQ(ierr); 237 } 238 PetscFunctionReturn(0); 239 } 240 241 #undef __FUNCT__ 242 #define __FUNCT__ "DMForestGetCoarseForest" 243 PetscErrorCode DMForestGetCoarseForest(DM dm, DM *coarse) 244 { 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 ierr = DMGetCoarseDM(dm,coarse);CHKERRQ(ierr); 249 PetscFunctionReturn(0); 250 } 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "DMForestSetFineForest" 254 PetscErrorCode DMForestSetFineForest(DM dm,DM fine) 255 { 256 PetscErrorCode ierr; 257 258 PetscFunctionBegin; 259 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 260 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the fine forest after setup"); 261 ierr = DMSetFineDM(dm,fine);CHKERRQ(ierr); 262 if (fine) { 263 PetscValidHeaderSpecific(fine, DM_CLASSID, 2); 264 ierr = DMForestTemplate(fine,dm);CHKERRQ(ierr); 265 } 266 PetscFunctionReturn(0); 267 } 268 269 #undef __FUNCT__ 270 #define __FUNCT__ "DMForestGetFineForest" 271 PetscErrorCode DMForestGetFineForest(DM dm, DM *fine) 272 { 273 PetscErrorCode ierr; 274 275 PetscFunctionBegin; 276 ierr = DMGetFineDM(dm,fine);CHKERRQ(ierr); 277 PetscFunctionReturn(0); 278 } 279 280 #undef __FUNCT__ 281 #define __FUNCT__ "DMForestSetAdjacencyDimension" 282 PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim) 283 { 284 PetscInt dim; 285 DM_Forest *forest = (DM_Forest *) dm->data; 286 PetscErrorCode ierr; 287 288 PetscFunctionBegin; 289 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 290 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup"); 291 if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim); 292 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 293 if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim); 294 forest->adjDim = adjDim; 295 PetscFunctionReturn(0); 296 } 297 298 #undef __FUNCT__ 299 #define __FUNCT__ "DMForestSetAdjacencyCodimension" 300 PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim) 301 { 302 PetscInt dim; 303 PetscErrorCode ierr; 304 305 PetscFunctionBegin; 306 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 307 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 308 ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr); 309 PetscFunctionReturn(0); 310 } 311 312 #undef __FUNCT__ 313 #define __FUNCT__ "DMForestGetAdjacencyDimension" 314 PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim) 315 { 316 DM_Forest *forest = (DM_Forest *) dm->data; 317 318 PetscFunctionBegin; 319 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 320 PetscValidIntPointer(adjDim,2); 321 *adjDim = forest->adjDim; 322 PetscFunctionReturn(0); 323 } 324 325 #undef __FUNCT__ 326 #define __FUNCT__ "DMForestGetAdjacencyCodimension" 327 PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim) 328 { 329 DM_Forest *forest = (DM_Forest *) dm->data; 330 PetscInt dim; 331 PetscErrorCode ierr; 332 333 PetscFunctionBegin; 334 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 335 PetscValidIntPointer(adjCodim,2); 336 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 337 *adjCodim = dim - forest->adjDim; 338 PetscFunctionReturn(0); 339 } 340 341 #undef __FUNCT__ 342 #define __FUNCT__ "DMForestSetPartitionOverlap" 343 PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap) 344 { 345 DM_Forest *forest = (DM_Forest *) dm->data; 346 347 PetscFunctionBegin; 348 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 349 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup"); 350 if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", overlap); 351 forest->overlap = overlap; 352 PetscFunctionReturn(0); 353 } 354 355 #undef __FUNCT__ 356 #define __FUNCT__ "DMForestGetPartitionOverlap" 357 PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap) 358 { 359 DM_Forest *forest = (DM_Forest *) dm->data; 360 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 363 PetscValidIntPointer(overlap,2); 364 *overlap = forest->overlap; 365 PetscFunctionReturn(0); 366 } 367 368 #undef __FUNCT__ 369 #define __FUNCT__ "DMForestSetMinimumRefinement" 370 PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement) 371 { 372 DM_Forest *forest = (DM_Forest *) dm->data; 373 374 PetscFunctionBegin; 375 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 376 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup"); 377 forest->minRefinement = minRefinement; 378 PetscFunctionReturn(0); 379 } 380 381 #undef __FUNCT__ 382 #define __FUNCT__ "DMForestGetMinimumRefinement" 383 PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement) 384 { 385 DM_Forest *forest = (DM_Forest *) dm->data; 386 387 PetscFunctionBegin; 388 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 389 PetscValidIntPointer(minRefinement,2); 390 *minRefinement = forest->minRefinement; 391 PetscFunctionReturn(0); 392 } 393 394 #undef __FUNCT__ 395 #define __FUNCT__ "DMForestSetInitialRefinement" 396 PetscErrorCode DMForestSetInitialRefinement(DM dm, PetscInt initRefinement) 397 { 398 DM_Forest *forest = (DM_Forest *) dm->data; 399 400 PetscFunctionBegin; 401 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 402 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the initial refinement after setup"); 403 forest->initRefinement = initRefinement; 404 PetscFunctionReturn(0); 405 } 406 407 #undef __FUNCT__ 408 #define __FUNCT__ "DMForestGetInitialRefinement" 409 PetscErrorCode DMForestGetInitialRefinement(DM dm, PetscInt *initRefinement) 410 { 411 DM_Forest *forest = (DM_Forest *) dm->data; 412 413 PetscFunctionBegin; 414 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 415 PetscValidIntPointer(initRefinement,2); 416 *initRefinement = forest->initRefinement; 417 PetscFunctionReturn(0); 418 } 419 420 #undef __FUNCT__ 421 #define __FUNCT__ "DMForestSetMaximumRefinement" 422 PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement) 423 { 424 DM_Forest *forest = (DM_Forest *) dm->data; 425 426 PetscFunctionBegin; 427 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 428 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the maximum refinement after setup"); 429 forest->maxRefinement = maxRefinement; 430 PetscFunctionReturn(0); 431 } 432 433 #undef __FUNCT__ 434 #define __FUNCT__ "DMForestGetMaximumRefinement" 435 PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement) 436 { 437 DM_Forest *forest = (DM_Forest *) dm->data; 438 439 PetscFunctionBegin; 440 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 441 PetscValidIntPointer(maxRefinement,2); 442 *maxRefinement = forest->maxRefinement; 443 PetscFunctionReturn(0); 444 } 445 446 #undef __FUNCT__ 447 #define __FUNCT__ "DMForestSetAdaptivityStrategy" 448 PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy) 449 { 450 DM_Forest *forest = (DM_Forest *) dm->data; 451 PetscErrorCode ierr; 452 453 PetscFunctionBegin; 454 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 455 ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr); 456 ierr = PetscStrallocpy((const char *) adaptStrategy,(char **)&forest->adaptStrategy);CHKERRQ(ierr); 457 PetscFunctionReturn(0); 458 } 459 460 #undef __FUNCT__ 461 #define __FUNCT__ "DMForestGetAdaptivityStrategy" 462 PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy) 463 { 464 DM_Forest *forest = (DM_Forest *) dm->data; 465 466 PetscFunctionBegin; 467 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 468 PetscValidPointer(adaptStrategy,2); 469 *adaptStrategy = forest->adaptStrategy; 470 PetscFunctionReturn(0); 471 } 472 473 #undef __FUNCT__ 474 #define __FUNCT__ "DMForestSetGradeFactor" 475 PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade) 476 { 477 DM_Forest *forest = (DM_Forest *) dm->data; 478 479 PetscFunctionBegin; 480 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 481 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup"); 482 forest->gradeFactor = grade; 483 PetscFunctionReturn(0); 484 } 485 486 #undef __FUNCT__ 487 #define __FUNCT__ "DMForestGetGradeFactor" 488 PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade) 489 { 490 DM_Forest *forest = (DM_Forest *) dm->data; 491 492 PetscFunctionBegin; 493 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 494 PetscValidIntPointer(grade,2); 495 *grade = forest->gradeFactor; 496 PetscFunctionReturn(0); 497 } 498 499 #undef __FUNCT__ 500 #define __FUNCT__ "DMForestSetCellWeightFactor" 501 PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor) 502 { 503 DM_Forest *forest = (DM_Forest *) dm->data; 504 505 PetscFunctionBegin; 506 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 507 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup"); 508 forest->weightsFactor = weightsFactor; 509 PetscFunctionReturn(0); 510 } 511 512 #undef __FUNCT__ 513 #define __FUNCT__ "DMForestGetCellWeightFactor" 514 PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor) 515 { 516 DM_Forest *forest = (DM_Forest *) dm->data; 517 518 PetscFunctionBegin; 519 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 520 PetscValidRealPointer(weightsFactor,2); 521 *weightsFactor = forest->weightsFactor; 522 PetscFunctionReturn(0); 523 } 524 525 #undef __FUNCT__ 526 #define __FUNCT__ "DMForestGetCellChart" 527 PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd) 528 { 529 DM_Forest *forest = (DM_Forest *) dm->data; 530 PetscErrorCode ierr; 531 532 PetscFunctionBegin; 533 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 534 PetscValidIntPointer(cStart,2); 535 PetscValidIntPointer(cEnd,2); 536 if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) { 537 ierr = forest->createcellchart(dm,&forest->cStart,&forest->cEnd);CHKERRQ(ierr); 538 } 539 *cStart = forest->cStart; 540 *cEnd = forest->cEnd; 541 PetscFunctionReturn(0); 542 } 543 544 #undef __FUNCT__ 545 #define __FUNCT__ "DMForestGetCellSF" 546 PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF) 547 { 548 DM_Forest *forest = (DM_Forest *) dm->data; 549 PetscErrorCode ierr; 550 551 PetscFunctionBegin; 552 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 553 PetscValidPointer(cellSF,2); 554 if ((!forest->cellSF) && forest->createcellsf) { 555 ierr = forest->createcellsf(dm,&forest->cellSF);CHKERRQ(ierr); 556 } 557 *cellSF = forest->cellSF; 558 PetscFunctionReturn(0); 559 } 560 561 #undef __FUNCT__ 562 #define __FUNCT__ "DMForestSetAdaptivityLabel" 563 PetscErrorCode DMForestSetAdaptivityLabel(DM dm, const char * adaptLabel) 564 { 565 DM_Forest *forest = (DM_Forest *) dm->data; 566 PetscErrorCode ierr; 567 568 PetscFunctionBegin; 569 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 570 ierr = PetscFree(forest->adaptLabel);CHKERRQ(ierr); 571 ierr = PetscStrallocpy(adaptLabel,&forest->adaptLabel);CHKERRQ(ierr); 572 PetscFunctionReturn(0); 573 } 574 575 #undef __FUNCT__ 576 #define __FUNCT__ "DMForestGetAdaptivityLabel" 577 PetscErrorCode DMForestGetAdaptivityLabel(DM dm, DMLabel *label) 578 { 579 DM_Forest *forest = (DM_Forest *) dm->data; 580 PetscErrorCode ierr; 581 582 PetscFunctionBegin; 583 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 584 if (forest->adaptLabel) { 585 ierr = DMGetLabel(dm,forest->adaptLabel,label);CHKERRQ(ierr); 586 } 587 else { 588 *label = NULL; 589 } 590 PetscFunctionReturn(0); 591 } 592 593 #undef __FUNCT__ 594 #define __FUNCT__ "DMForestSetCellWeights" 595 PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode) 596 { 597 DM_Forest *forest = (DM_Forest *) dm->data; 598 PetscInt cStart, cEnd; 599 PetscErrorCode ierr; 600 601 PetscFunctionBegin; 602 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 603 ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr); 604 if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd); 605 if (copyMode == PETSC_COPY_VALUES) { 606 if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) { 607 ierr = PetscMalloc1(cEnd-cStart,&forest->cellWeights);CHKERRQ(ierr); 608 } 609 ierr = PetscMemcpy(forest->cellWeights,weights,(cEnd-cStart)*sizeof(*weights));CHKERRQ(ierr); 610 forest->cellWeightsCopyMode = PETSC_OWN_POINTER; 611 PetscFunctionReturn(0); 612 } 613 if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) { 614 ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr); 615 } 616 forest->cellWeights = weights; 617 forest->cellWeightsCopyMode = copyMode; 618 PetscFunctionReturn(0); 619 } 620 621 #undef __FUNCT__ 622 #define __FUNCT__ "DMForestGetCellWeights" 623 PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights) 624 { 625 DM_Forest *forest = (DM_Forest *) dm->data; 626 627 PetscFunctionBegin; 628 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 629 PetscValidPointer(weights,2); 630 *weights = forest->cellWeights; 631 PetscFunctionReturn(0); 632 } 633 634 #undef __FUNCT__ 635 #define __FUNCT__ "DMForestSetWeightCapacity" 636 PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity) 637 { 638 DM_Forest *forest = (DM_Forest *) dm->data; 639 640 PetscFunctionBegin; 641 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 642 if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup"); 643 if (capacity < 0.) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %f",capacity); 644 forest->weightCapacity = capacity; 645 PetscFunctionReturn(0); 646 } 647 648 #undef __FUNCT__ 649 #define __FUNCT__ "DMForestGetWeightCapacity" 650 PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity) 651 { 652 DM_Forest *forest = (DM_Forest *) dm->data; 653 654 PetscFunctionBegin; 655 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 656 PetscValidRealPointer(capacity,2); 657 *capacity = forest->weightCapacity; 658 PetscFunctionReturn(0); 659 } 660 661 #undef __FUNCT__ 662 #define __FUNCT__ "DMSetFromOptions_Forest" 663 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(PetscOptionItems *PetscOptionsObject,DM dm) 664 { 665 DM_Forest *forest = (DM_Forest *) dm->data; 666 PetscBool flg, flg1, flg2, flg3, flg4; 667 DMForestTopology oldTopo; 668 char stringBuffer[256]; 669 PetscViewer viewer; 670 PetscViewerFormat format; 671 PetscInt adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade; 672 PetscReal weightsFactor; 673 DMForestAdaptivityStrategy adaptStrategy; 674 PetscErrorCode ierr; 675 676 PetscFunctionBegin; 677 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 678 forest->setFromOptions = PETSC_TRUE; 679 ierr = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr); 680 ierr = PetscOptionsHead(PetscOptionsObject,"DMForest Options");CHKERRQ(ierr); 681 ierr = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,256,&flg1);CHKERRQ(ierr); 682 ierr = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg2);CHKERRQ(ierr); 683 ierr = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg3);CHKERRQ(ierr); 684 ierr = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg4);CHKERRQ(ierr); 685 if ((PetscInt) flg1 + (PetscInt) flg2 + (PetscInt) flg3 + (PetscInt) flg4 > 1) { 686 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Specify only one of -dm_forest_{topology,base_dm,coarse_forest,fine_forest}"); 687 } 688 if (flg1) { 689 ierr = DMForestSetTopology(dm,(DMForestTopology)stringBuffer);CHKERRQ(ierr); 690 ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr); 691 ierr = DMForestSetCoarseForest(dm,NULL);CHKERRQ(ierr); 692 ierr = DMForestSetFineForest(dm,NULL);CHKERRQ(ierr); 693 } 694 if (flg2) { 695 DM base; 696 697 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr); 698 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 699 ierr = DMLoad(base,viewer);CHKERRQ(ierr); 700 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 701 ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr); 702 ierr = DMDestroy(&base);CHKERRQ(ierr); 703 ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr); 704 ierr = DMForestSetCoarseForest(dm,NULL);CHKERRQ(ierr); 705 ierr = DMForestSetFineForest(dm,NULL);CHKERRQ(ierr); 706 } 707 if (flg3) { 708 DM coarse; 709 710 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr); 711 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 712 ierr = DMLoad(coarse,viewer);CHKERRQ(ierr); 713 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 714 ierr = DMForestSetCoarseForest(dm,coarse);CHKERRQ(ierr); 715 ierr = DMDestroy(&coarse);CHKERRQ(ierr); 716 ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr); 717 ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr); 718 ierr = DMForestSetFineForest(dm,NULL);CHKERRQ(ierr); 719 } 720 if (flg4) { 721 DM fine; 722 723 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr); 724 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 725 ierr = DMLoad(fine,viewer);CHKERRQ(ierr); 726 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 727 ierr = DMForestSetFineForest(dm,fine);CHKERRQ(ierr); 728 ierr = DMDestroy(&fine);CHKERRQ(ierr); 729 ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr); 730 ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr); 731 ierr = DMForestSetCoarseForest(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__ "DMInitialize_Forest" 810 static PetscErrorCode DMInitialize_Forest(DM dm) 811 { 812 PetscErrorCode ierr; 813 814 PetscFunctionBegin; 815 ierr = PetscMemzero(dm->ops,sizeof(*(dm->ops)));CHKERRQ(ierr); 816 817 dm->ops->clone = DMClone_Forest; 818 dm->ops->setfromoptions = DMSetFromOptions_Forest; 819 dm->ops->destroy = DMDestroy_Forest; 820 dm->ops->createsubdm = DMCreateSubDM_Forest; 821 PetscFunctionReturn(0); 822 } 823 824 #undef __FUNCT__ 825 #define __FUNCT__ "DMCreate_Forest" 826 PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm) 827 { 828 DM_Forest *forest; 829 PetscErrorCode ierr; 830 831 PetscFunctionBegin; 832 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 833 ierr = PetscNewLog(dm,&forest);CHKERRQ(ierr); 834 dm->dim = 0; 835 dm->data = forest; 836 forest->refct = 1; 837 forest->data = NULL; 838 forest->setFromOptions = PETSC_FALSE; 839 forest->topology = NULL; 840 forest->base = NULL; 841 forest->adjDim = PETSC_DEFAULT; 842 forest->overlap = PETSC_DEFAULT; 843 forest->minRefinement = PETSC_DEFAULT; 844 forest->maxRefinement = PETSC_DEFAULT; 845 forest->initRefinement = PETSC_DEFAULT; 846 forest->cStart = PETSC_DETERMINE; 847 forest->cEnd = PETSC_DETERMINE; 848 forest->cellSF = 0; 849 forest->adaptLabel = NULL; 850 forest->gradeFactor = 2; 851 forest->cellWeights = NULL; 852 forest->cellWeightsCopyMode = PETSC_USE_POINTER; 853 forest->weightsFactor = 1.; 854 forest->weightCapacity = 1.; 855 ierr = DMForestSetAdaptivityStrategy(dm,DMFORESTADAPTALL);CHKERRQ(ierr); 856 ierr = DMInitialize_Forest(dm);CHKERRQ(ierr); 857 PetscFunctionReturn(0); 858 } 859 860