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