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