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