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