1 #include <petsc-private/dmforestimpl.h> 2 #include <petsc-private/dmimpl.h> 3 #include <petscsf.h> /*I "petscsf.h" */ 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "DMClone_Forest" 7 PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm) 8 { 9 DM_Forest *forest = (DM_Forest *) dm->data; 10 const char *type; 11 PetscErrorCode ierr; 12 13 PetscFunctionBegin; 14 forest->refct++; 15 (*newdm)->data = forest; 16 ierr = PetscObjectGetType((PetscObject) dm, &type);CHKERRQ(ierr); 17 ierr = PetscObjectChangeTypeName((PetscObject) *newdm, type);CHKERRQ(ierr); 18 PetscFunctionReturn(0); 19 } 20 21 #undef __FUNCT__ 22 #define __FUNCT__ "DMDestroy_Forest" 23 PetscErrorCode DMDestroy_Forest(DM dm) 24 { 25 DM_Forest *forest = (DM_Forest*) dm->data; 26 PetscErrorCode ierr; 27 28 PetscFunctionBegin; 29 if (--forest->refct > 0) PetscFunctionReturn(0); 30 ierr = PetscSFDestroy(&forest->cellSF);CHKERRQ(ierr); 31 if (forest->adaptCopyMode == PETSC_OWN_POINTER) { 32 ierr = PetscFree(forest->adaptMarkers);CHKERRQ(ierr); 33 } 34 if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) { 35 ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr); 36 } 37 PetscFunctionReturn(0); 38 } 39 40 #undef __FUNCT__ 41 #define __FUNCT__ "DMForestSetTopology" 42 PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology) 43 { 44 DM_Forest *forest = (DM_Forest *) dm->data; 45 PetscErrorCode ierr; 46 47 PetscFunctionBegin; 48 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup"); 50 ierr = PetscFree(forest->topology);CHKERRQ(ierr); 51 ierr = PetscStrallocpy((const char *)topology,(char **) &forest->topology);CHKERRQ(ierr); 52 PetscFunctionReturn(0); 53 } 54 55 #undef __FUNCT__ 56 #define __FUNCT__ "DMForestGetTopology" 57 PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology) 58 { 59 DM_Forest *forest = (DM_Forest *) dm->data; 60 61 PetscFunctionBegin; 62 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63 PetscValidPointer(topology,2); 64 *topology = forest->topology; 65 PetscFunctionReturn(0); 66 } 67 68 #undef __FUNCT__ 69 #define __FUNCT__ "DMForestSetBaseDM" 70 PetscErrorCode DMForestSetBaseDM(DM dm, DM base) 71 { 72 DM_Forest *forest = (DM_Forest *) dm->data; 73 PetscInt dim, dimEmbed; 74 PetscErrorCode ierr; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 78 PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 79 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup"); 80 ierr = PetscObjectReference((PetscObject)base);CHKERRQ(ierr); 81 ierr = DMDestroy(&forest->base);CHKERRQ(ierr); 82 forest->base = base; 83 ierr = DMGetDimension(base,&dim);CHKERRQ(ierr); 84 ierr = DMSetDimension(dm,dim);CHKERRQ(ierr); 85 ierr = DMGetCoordinateDim(base,&dimEmbed);CHKERRQ(ierr); 86 ierr = DMSetCoordinateDim(dm,dimEmbed);CHKERRQ(ierr); 87 PetscFunctionReturn(0); 88 } 89 90 #undef __FUNCT__ 91 #define __FUNCT__ "DMForestGetBaseDM" 92 PetscErrorCode DMForestGetBaseDM(DM dm, DM *base) 93 { 94 DM_Forest *forest = (DM_Forest *) dm->data; 95 96 PetscFunctionBegin; 97 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 98 PetscValidPointer(base, 2); 99 *base = forest->base; 100 PetscFunctionReturn(0); 101 } 102 103 #undef __FUNCT__ 104 #define __FUNCT__ "DMForestSetCoarseForest" 105 PetscErrorCode DMForestSetCoarseForest(DM dm,DM coarse) 106 { 107 DM_Forest *forest = (DM_Forest *) dm->data; 108 DM base; 109 PetscErrorCode ierr; 110 111 PetscFunctionBegin; 112 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 113 PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 114 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the coarse forest after setup"); 115 ierr = PetscObjectReference((PetscObject)coarse);CHKERRQ(ierr); 116 ierr = DMDestroy(&forest->coarse);CHKERRQ(ierr); 117 ierr = DMForestGetBaseDM(coarse,&base);CHKERRQ(ierr); 118 ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr); 119 forest->coarse = coarse; 120 PetscFunctionReturn(0); 121 } 122 123 #undef __FUNCT__ 124 #define __FUNCT__ "DMForestGetCoarseForest" 125 PetscErrorCode DMForestGetCoarseForest(DM dm, DM *coarse) 126 { 127 DM_Forest *forest = (DM_Forest *) dm->data; 128 129 PetscFunctionBegin; 130 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 131 PetscValidPointer(coarse, 2); 132 *coarse = forest->coarse; 133 PetscFunctionReturn(0); 134 } 135 136 #undef __FUNCT__ 137 #define __FUNCT__ "DMForestSetFineForest" 138 PetscErrorCode DMForestSetFineForest(DM dm,DM fine) 139 { 140 DM_Forest *forest = (DM_Forest *) dm->data; 141 DM base; 142 PetscErrorCode ierr; 143 144 PetscFunctionBegin; 145 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 146 PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 147 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the fine forest after setup"); 148 ierr = PetscObjectReference((PetscObject)fine);CHKERRQ(ierr); 149 ierr = DMDestroy(&forest->fine);CHKERRQ(ierr); 150 ierr = DMForestGetBaseDM(fine,&base);CHKERRQ(ierr); 151 ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr); 152 forest->fine = fine; 153 PetscFunctionReturn(0); 154 } 155 156 #undef __FUNCT__ 157 #define __FUNCT__ "DMForestGetFineForest_Forest" 158 PetscErrorCode DMForestGetFineForest(DM dm, DM *fine) 159 { 160 DM_Forest *forest = (DM_Forest *) dm->data; 161 162 PetscFunctionBegin; 163 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 164 PetscValidPointer(fine, 2); 165 *fine = forest->fine; 166 PetscFunctionReturn(0); 167 } 168 169 #undef __FUNCT__ 170 #define __FUNCT__ "DMForestSetAdjacencyDimension" 171 PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim) 172 { 173 PetscInt dim; 174 DM_Forest *forest = (DM_Forest *) dm->data; 175 PetscErrorCode ierr; 176 177 PetscFunctionBegin; 178 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 179 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup"); 180 if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim); 181 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 182 if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim); 183 forest->adjDim = adjDim; 184 PetscFunctionReturn(0); 185 } 186 187 #undef __FUNCT__ 188 #define __FUNCT__ "DMForestSetAdjacencyCodimension" 189 PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim) 190 { 191 PetscInt dim; 192 PetscErrorCode ierr; 193 194 PetscFunctionBegin; 195 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 196 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 197 ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr); 198 PetscFunctionReturn(0); 199 } 200 201 #undef __FUNCT__ 202 #define __FUNCT__ "DMForestGetAdjacencyDimension" 203 PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim) 204 { 205 DM_Forest *forest = (DM_Forest *) dm->data; 206 207 PetscFunctionBegin; 208 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 209 PetscValidIntPointer(adjDim,2); 210 *adjDim = forest->adjDim; 211 PetscFunctionReturn(0); 212 } 213 214 #undef __FUNCT__ 215 #define __FUNCT__ "DMForestGetAdjacencyCodimension" 216 PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim) 217 { 218 DM_Forest *forest = (DM_Forest *) dm->data; 219 PetscInt dim; 220 PetscErrorCode ierr; 221 222 PetscFunctionBegin; 223 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 224 PetscValidIntPointer(adjCodim,2); 225 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 226 *adjCodim = dim - forest->adjDim; 227 PetscFunctionReturn(0); 228 } 229 230 #undef __FUNCT__ 231 #define __FUNCT__ "DMForestSetParititionOverlap" 232 PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap) 233 { 234 DM_Forest *forest = (DM_Forest *) dm->data; 235 236 PetscFunctionBegin; 237 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 238 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup"); 239 if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", overlap); 240 forest->overlap = overlap; 241 PetscFunctionReturn(0); 242 } 243 244 #undef __FUNCT__ 245 #define __FUNCT__ "DMForestGetPartitionOverlap" 246 PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap) 247 { 248 DM_Forest *forest = (DM_Forest *) dm->data; 249 250 PetscFunctionBegin; 251 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 252 PetscValidIntPointer(overlap,2); 253 *overlap = forest->overlap; 254 PetscFunctionReturn(0); 255 } 256 257 #undef __FUNCT__ 258 #define __FUNCT__ "DMForestSetMinimumRefinement" 259 PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement) 260 { 261 DM_Forest *forest = (DM_Forest *) dm->data; 262 263 PetscFunctionBegin; 264 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 265 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup"); 266 forest->minRefinement = minRefinement; 267 PetscFunctionReturn(0); 268 } 269 270 #undef __FUNCT__ 271 #define __FUNCT__ "DMForestGetMinimumRefinement" 272 PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement) 273 { 274 DM_Forest *forest = (DM_Forest *) dm->data; 275 276 PetscFunctionBegin; 277 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 278 PetscValidIntPointer(minRefinement,2); 279 *minRefinement = forest->minRefinement; 280 PetscFunctionReturn(0); 281 } 282 283 #undef __FUNCT__ 284 #define __FUNCT__ "DMForestSetMaximumRefinement" 285 PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement) 286 { 287 DM_Forest *forest = (DM_Forest *) dm->data; 288 289 PetscFunctionBegin; 290 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 291 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the maximum refinement after setup"); 292 forest->maxRefinement = maxRefinement; 293 PetscFunctionReturn(0); 294 } 295 296 #undef __FUNCT__ 297 #define __FUNCT__ "DMForestGetMaximumRefinement" 298 PetscErrorCode DMForestGetMaximumRefinement (DM dm, PetscInt *maxRefinement) 299 { 300 DM_Forest *forest = (DM_Forest *) dm->data; 301 302 PetscFunctionBegin; 303 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 304 PetscValidIntPointer(maxRefinement,2); 305 *maxRefinement = forest->maxRefinement; 306 PetscFunctionReturn(0); 307 } 308 309 #undef __FUNCT__ 310 #define __FUNCT__ "DMForestSetAdaptivityStrategy" 311 PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy) 312 { 313 DM_Forest *forest = (DM_Forest *) dm->data; 314 PetscErrorCode ierr; 315 316 PetscFunctionBegin; 317 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 318 ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr); 319 ierr = PetscStrallocpy((const char *)adaptStrategy,(char **)adaptStrategy);CHKERRQ(ierr); 320 PetscFunctionReturn(0); 321 } 322 323 #undef __FUNCT__ 324 #define __FUNCT__ "DMForestGetAdaptivityStrategy" 325 PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy) 326 { 327 DM_Forest *forest = (DM_Forest *) dm->data; 328 329 PetscFunctionBegin; 330 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 331 PetscValidPointer(adaptStrategy,2); 332 *adaptStrategy = forest->adaptStrategy; 333 PetscFunctionReturn(0); 334 } 335 336 #undef __FUNCT__ 337 #define __FUNCT__ "DMForestSetGradeFactor" 338 PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade) 339 { 340 DM_Forest *forest = (DM_Forest *) dm->data; 341 342 PetscFunctionBegin; 343 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 344 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup"); 345 forest->gradeFactor = grade; 346 PetscFunctionReturn(0); 347 } 348 349 #undef __FUNCT__ 350 #define __FUNCT__ "DMForestGetGradeFactor" 351 PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade) 352 { 353 DM_Forest *forest = (DM_Forest *) dm->data; 354 355 PetscFunctionBegin; 356 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 357 PetscValidIntPointer(grade,2); 358 *grade = forest->gradeFactor; 359 PetscFunctionReturn(0); 360 } 361 362 #undef __FUNCT__ 363 #define __FUNCT__ "DMForestSetCellWeightsFactor" 364 PetscErrorCode DMForestSetCellWeightsFactor(DM dm, PetscReal weightsFactor) 365 { 366 DM_Forest *forest = (DM_Forest *) dm->data; 367 368 PetscFunctionBegin; 369 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 370 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup"); 371 forest->weightsFactor = weightsFactor; 372 PetscFunctionReturn(0); 373 } 374 375 #undef __FUNCT__ 376 #define __FUNCT__ "DMForestGetCellWeightsFactor" 377 PetscErrorCode DMForestGetCellWeightsFactor(DM dm, PetscReal *weightsFactor) 378 { 379 DM_Forest *forest = (DM_Forest *) dm->data; 380 381 PetscFunctionBegin; 382 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 383 PetscValidRealPointer(weightsFactor,2); 384 *weightsFactor = forest->weightsFactor; 385 PetscFunctionReturn(0); 386 } 387 388 #undef __FUNCT__ 389 #define __FUNCT__ "DMForestGetCellChart" 390 PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd) 391 { 392 DM_Forest *forest = (DM_Forest *) dm->data; 393 PetscErrorCode ierr; 394 395 PetscFunctionBegin; 396 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 397 PetscValidIntPointer(cStart,2); 398 PetscValidIntPointer(cEnd,2); 399 if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) { 400 ierr = forest->createcellchart(dm,&forest->cStart,&forest->cEnd);CHKERRQ(ierr); 401 } 402 *cStart = forest->cStart; 403 *cEnd = forest->cEnd; 404 PetscFunctionReturn(0); 405 } 406 407 #undef __FUNCT__ 408 #define __FUNCT__ "DMForestGetCellSF" 409 PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF) 410 { 411 DM_Forest *forest = (DM_Forest *) dm->data; 412 PetscErrorCode ierr; 413 414 PetscFunctionBegin; 415 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 416 PetscValidPointer(cellSF,2); 417 if ((!forest->cellSF) && forest->createcellsf) { 418 ierr = forest->createcellsf(dm,&forest->cellSF);CHKERRQ(ierr); 419 } 420 *cellSF = forest->cellSF; 421 PetscFunctionReturn(0); 422 } 423 424 #undef __FUNCT__ 425 #define __FUNCT__ "DMForestSetAdaptivityMarkers" 426 PetscErrorCode DMForestSetAdaptivityMarkers(DM dm, PetscInt markers[], PetscCopyMode copyMode) 427 { 428 DM_Forest *forest = (DM_Forest *) dm->data; 429 PetscInt cStart, cEnd; 430 PetscErrorCode ierr; 431 432 PetscFunctionBegin; 433 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 434 ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr); 435 if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd); 436 if (copyMode == PETSC_COPY_VALUES) { 437 if (forest->adaptCopyMode != PETSC_OWN_POINTER || forest->adaptMarkers == markers) { 438 ierr = PetscMalloc1(cEnd-cStart,&forest->adaptMarkers);CHKERRQ(ierr); 439 } 440 ierr = PetscMemcpy(forest->adaptMarkers,markers,(cEnd-cStart)*sizeof(*markers));CHKERRQ(ierr); 441 forest->adaptCopyMode = PETSC_OWN_POINTER; 442 PetscFunctionReturn(0); 443 } 444 if (forest->adaptCopyMode == PETSC_OWN_POINTER) { 445 ierr = PetscFree(forest->adaptMarkers);CHKERRQ(ierr); 446 } 447 forest->adaptMarkers = markers; 448 forest->adaptCopyMode = copyMode; 449 PetscFunctionReturn(0); 450 } 451 452 #undef __FUNCT__ 453 #define __FUNCT__ "DMForestGetAdaptivityMarkers" 454 PetscErrorCode DMForestGetAdaptivityMarkers(DM dm, PetscInt **markers) 455 { 456 DM_Forest *forest = (DM_Forest *) dm->data; 457 458 PetscFunctionBegin; 459 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 460 PetscValidPointer(markers,2); 461 *markers = forest->adaptMarkers; 462 PetscFunctionReturn(0); 463 } 464 465 #undef __FUNCT__ 466 #define __FUNCT__ "DMForestSetCellWeights" 467 PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode) 468 { 469 DM_Forest *forest = (DM_Forest *) dm->data; 470 PetscInt cStart, cEnd; 471 PetscErrorCode ierr; 472 473 PetscFunctionBegin; 474 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 475 ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr); 476 if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd); 477 if (copyMode == PETSC_COPY_VALUES) { 478 if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) { 479 ierr = PetscMalloc1(cEnd-cStart,&forest->cellWeights);CHKERRQ(ierr); 480 } 481 ierr = PetscMemcpy(forest->cellWeights,weights,(cEnd-cStart)*sizeof(*weights));CHKERRQ(ierr); 482 forest->cellWeightsCopyMode = PETSC_OWN_POINTER; 483 PetscFunctionReturn(0); 484 } 485 if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) { 486 ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr); 487 } 488 forest->cellWeights = weights; 489 forest->cellWeightsCopyMode = copyMode; 490 PetscFunctionReturn(0); 491 } 492 493 #undef __FUNCT__ 494 #define __FUNCT__ "DMForestGetCellWeights" 495 PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights) 496 { 497 DM_Forest *forest = (DM_Forest *) dm->data; 498 499 PetscFunctionBegin; 500 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 501 PetscValidPointer(weights,2); 502 *weights = forest->cellWeights; 503 PetscFunctionReturn(0); 504 } 505 506 #undef __FUNCT__ 507 #define __FUNCT__ "DMForestSetWeightCapacity" 508 PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity) 509 { 510 DM_Forest *forest = (DM_Forest *) dm->data; 511 512 PetscFunctionBegin; 513 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 514 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup"); 515 if (capacity < 0.) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %f",capacity); 516 forest->weightCapacity = capacity; 517 PetscFunctionReturn(0); 518 } 519 520 #undef __FUNCT__ 521 #define __FUNCT__ "DMForestGetWeightCapacity" 522 PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity) 523 { 524 DM_Forest *forest = (DM_Forest *) dm->data; 525 526 PetscFunctionBegin; 527 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 528 PetscValidRealPointer(capacity,2); 529 *capacity = forest->weightCapacity; 530 PetscFunctionReturn(0); 531 } 532 533 #undef __FUNCT__ 534 #define __FUNCT__ "DMSetFromOptions_Forest" 535 PetscErrorCode DMSetFromFromOptions_Forest(DM dm) 536 { 537 DM_Forest *forest = (DM_Forest *) dm->data; 538 PetscBool flg; 539 DMForestTopology oldTopo; 540 char stringBuffer[256]; 541 PetscViewer viewer; 542 PetscViewerFormat format; 543 PetscInt adjDim, adjCodim, overlap, minRefinement, maxRefinement, grade; 544 PetscReal weightsFactor; 545 DMForestAdaptivityStrategy adaptStrategy; 546 PetscErrorCode ierr; 547 548 PetscFunctionBegin; 549 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 550 forest->setFromOptions = PETSC_TRUE; 551 ierr = PetscOptionsHead("DMForest Options");CHKERRQ(ierr); 552 ierr = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr); 553 ierr = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,256,&flg);CHKERRQ(ierr); 554 if (flg) { 555 ierr = DMForestSetTopology(dm,(DMForestTopology)stringBuffer);CHKERRQ(ierr); 556 } 557 ierr = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg);CHKERRQ(ierr); 558 if (flg) { 559 DM base; 560 561 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr); 562 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 563 ierr = DMLoad(base,viewer);CHKERRQ(ierr); 564 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 565 ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr); 566 ierr = DMDestroy(&base);CHKERRQ(ierr); 567 } 568 ierr = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg);CHKERRQ(ierr); 569 if (flg) { 570 DM coarse; 571 572 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr); 573 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 574 ierr = DMLoad(coarse,viewer);CHKERRQ(ierr); 575 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 576 ierr = DMForestSetCoarseForest(dm,coarse);CHKERRQ(ierr); 577 ierr = DMDestroy(&coarse);CHKERRQ(ierr); 578 } 579 ierr = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg);CHKERRQ(ierr); 580 if (flg) { 581 DM fine; 582 583 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr); 584 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 585 ierr = DMLoad(fine,viewer);CHKERRQ(ierr); 586 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 587 ierr = DMForestSetFineForest(dm,fine);CHKERRQ(ierr); 588 ierr = DMDestroy(&fine);CHKERRQ(ierr); 589 } 590 ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr); 591 ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr); 592 if (flg) { 593 ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr); 594 } 595 else { 596 ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr); 597 ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr); 598 if (flg) { 599 ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr); 600 } 601 } 602 ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr); 603 ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr); 604 if (flg) { 605 ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr); 606 } 607 ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr); 608 ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr); 609 if (flg) { 610 ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr); 611 } 612 ierr = DMForestGetMaximumRefinement(dm,&maxRefinement);CHKERRQ(ierr); 613 ierr = PetscOptionsInt("-dm_forest_maximum_refinement","set the maximum level of refinement in the forest","DMForestSetMaximumRefinement",maxRefinement,&maxRefinement,&flg);CHKERRQ(ierr); 614 if (flg) { 615 ierr = DMForestSetMaximumRefinement(dm,maxRefinement);CHKERRQ(ierr); 616 } 617 ierr = DMForestGetAdaptivityStrategy(dm,&adaptStrategy);CHKERRQ(ierr); 618 ierr = PetscOptionsString("-dm_forest_adaptivity_strategy","the forest's adaptivity-flag resolution strategy","DMForestSetAdaptivityStrategy",adaptStrategy,stringBuffer,256,&flg);CHKERRQ(ierr); 619 if (flg) { 620 ierr = DMForestSetAdaptivityStrategy(dm,(DMForestAdaptivityStrategy)stringBuffer);CHKERRQ(ierr); 621 } 622 ierr = DMForestGetGradeFactor(dm,&grade);CHKERRQ(ierr); 623 ierr = PetscOptionsInt("-dm_forest_grade_factor","grade factor between neighboring cells","DMForestSetGradeFactor",grade,&grade,&flg);CHKERRQ(ierr); 624 if (flg) { 625 ierr = DMForestSetGradeFactor(dm,grade);CHKERRQ(ierr); 626 } 627 ierr = DMForestGetCellWeightFactor(dm,&weightsFactor);CHKERRQ(ierr); 628 ierr = PetscOptionsReal("-dm_forest_cell_weight_factor","multiplying weight factor for cell refinement","DMForestSetCellWeightFactor",weightsFactor,&weightsFactor,&flg);CHKERRQ(ierr); 629 if (flg) { 630 ierr = DMForestSetCellWeightFactor(dm,weightsFactor);CHKERRQ(ierr); 631 } 632 ierr = PetscOptionsTail();CHKERRQ(ierr); 633 PetscFunctionReturn(0); 634 } 635 636 #undef __FUNCT__ 637 #define __FUNCT__ "DMCreate_Forest" 638 PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm) 639 { 640 DM_Forest *forest; 641 PetscErrorCode ierr; 642 643 PetscFunctionBegin; 644 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 645 ierr = PetscNewLog(dm,&forest);CHKERRQ(ierr); 646 dm->dim = 0; 647 dm->data = forest; 648 forest->refct = 1; 649 forest->data = NULL; 650 forest->setup = 0; 651 forest->setFromOptions = PETSC_FALSE; 652 forest->topology = NULL; 653 forest->base = NULL; 654 forest->coarse = NULL; 655 forest->fine = NULL; 656 forest->adjDim = PETSC_DEFAULT; 657 forest->overlap = PETSC_DEFAULT; 658 forest->minRefinement = PETSC_DEFAULT; 659 forest->maxRefinement = PETSC_DEFAULT; 660 forest->cStart = PETSC_DETERMINE; 661 forest->cEnd = PETSC_DETERMINE; 662 forest->cellSF = 0; 663 forest->adaptMarkers = NULL; 664 forest->adaptCopyMode = PETSC_USE_POINTER; 665 forest->adaptStrategy = DMFORESTADAPTALL; 666 forest->gradeFactor = 2; 667 forest->cellWeights = NULL; 668 forest->cellWeightsCopyMode = PETSC_USE_POINTER; 669 forest->weightsFactor = 1.; 670 forest->weightCapacity = 1.; 671 PetscFunctionReturn(0); 672 } 673 674