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