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