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