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