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