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