1 #include <petsc-private/dmforestimpl.h> 2 #include <petsc-private/dmimpl.h> 3 #include <petscsf.h> /*I "petscsf.h" */ 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "DMClone_Forest" 7 PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm) 8 { 9 DM_Forest *forest = (DM_Forest *) dm->data; 10 const char *type; 11 PetscErrorCode ierr; 12 13 PetscFunctionBegin; 14 forest->refct++; 15 (*newdm)->data = forest; 16 ierr = PetscObjectGetType((PetscObject) dm, &type);CHKERRQ(ierr); 17 ierr = PetscObjectChangeTypeName((PetscObject) *newdm, type);CHKERRQ(ierr); 18 PetscFunctionReturn(0); 19 } 20 21 #undef __FUNCT__ 22 #define __FUNCT__ "DMDestroy_Forest" 23 PetscErrorCode DMDestroy_Forest(DM dm) 24 { 25 DM_Forest *forest = (DM_Forest*) dm->data; 26 PetscErrorCode ierr; 27 28 PetscFunctionBegin; 29 if (--forest->refct > 0) PetscFunctionReturn(0); 30 ierr = PetscSFDestroy(&forest->cellSF);CHKERRQ(ierr); 31 if (forest->adaptCopyMode == PETSC_OWN_POINTER) { 32 ierr = PetscFree(forest->adaptMarkers);CHKERRQ(ierr); 33 } 34 if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) { 35 ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr); 36 } 37 PetscFunctionReturn(0); 38 } 39 40 #undef __FUNCT__ 41 #define __FUNCT__ "DMForestSetTopology" 42 PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology) 43 { 44 DM_Forest *forest = (DM_Forest *) dm->data; 45 PetscErrorCode ierr; 46 47 PetscFunctionBegin; 48 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup"); 50 ierr = PetscFree(forest->topology);CHKERRQ(ierr); 51 ierr = PetscStrallocpy((const char *)topology,(char **) &forest->topology);CHKERRQ(ierr); 52 PetscFunctionReturn(0); 53 } 54 55 #undef __FUNCT__ 56 #define __FUNCT__ "DMForestGetTopology" 57 PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology) 58 { 59 DM_Forest *forest = (DM_Forest *) dm->data; 60 61 PetscFunctionBegin; 62 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63 PetscValidPointer(topology,2); 64 *topology = forest->topology; 65 PetscFunctionReturn(0); 66 } 67 68 #undef __FUNCT__ 69 #define __FUNCT__ "DMForestSetBaseDM" 70 PetscErrorCode DMForestSetBaseDM(DM dm, DM base) 71 { 72 DM_Forest *forest = (DM_Forest *) dm->data; 73 PetscInt dim, dimEmbed; 74 PetscErrorCode ierr; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 78 PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 79 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup"); 80 ierr = PetscObjectReference((PetscObject)base);CHKERRQ(ierr); 81 ierr = DMDestroy(&forest->base);CHKERRQ(ierr); 82 forest->base = base; 83 ierr = DMGetDimension(base,&dim);CHKERRQ(ierr); 84 ierr = DMSetDimension(dm,dim);CHKERRQ(ierr); 85 ierr = DMGetCoordinateDim(base,&dimEmbed);CHKERRQ(ierr); 86 ierr = DMSetCoordinateDim(dm,dimEmbed);CHKERRQ(ierr); 87 PetscFunctionReturn(0); 88 } 89 90 #undef __FUNCT__ 91 #define __FUNCT__ "DMForestGetBaseDM" 92 PetscErrorCode DMForestGetBaseDM(DM dm, DM *base) 93 { 94 DM_Forest *forest = (DM_Forest *) dm->data; 95 96 PetscFunctionBegin; 97 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 98 PetscValidPointer(base, 2); 99 *base = forest->base; 100 PetscFunctionReturn(0); 101 } 102 103 #undef __FUNCT__ 104 #define __FUNCT__ "DMForestSetCoarseForest" 105 PetscErrorCode DMForestSetCoarseForest(DM dm,DM coarse) 106 { 107 DM_Forest *forest = (DM_Forest *) dm->data; 108 DM base; 109 PetscErrorCode ierr; 110 111 PetscFunctionBegin; 112 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 113 PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 114 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the coarse forest after setup"); 115 ierr = PetscObjectReference((PetscObject)coarse);CHKERRQ(ierr); 116 ierr = DMDestroy(&forest->coarse);CHKERRQ(ierr); 117 ierr = DMForestGetBaseDM(coarse,&base);CHKERRQ(ierr); 118 ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr); 119 forest->coarse = coarse; 120 PetscFunctionReturn(0); 121 } 122 123 #undef __FUNCT__ 124 #define __FUNCT__ "DMForestGetCoarseForest" 125 PetscErrorCode DMForestGetCoarseForest(DM dm, DM *coarse) 126 { 127 DM_Forest *forest = (DM_Forest *) dm->data; 128 129 PetscFunctionBegin; 130 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 131 PetscValidPointer(coarse, 2); 132 *coarse = forest->coarse; 133 PetscFunctionReturn(0); 134 } 135 136 #undef __FUNCT__ 137 #define __FUNCT__ "DMForestSetFineForest" 138 PetscErrorCode DMForestSetFineForest(DM dm,DM fine) 139 { 140 DM_Forest *forest = (DM_Forest *) dm->data; 141 DM base; 142 PetscErrorCode ierr; 143 144 PetscFunctionBegin; 145 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 146 PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 147 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the fine forest after setup"); 148 ierr = PetscObjectReference((PetscObject)fine);CHKERRQ(ierr); 149 ierr = DMDestroy(&forest->fine);CHKERRQ(ierr); 150 ierr = DMForestGetBaseDM(fine,&base);CHKERRQ(ierr); 151 ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr); 152 forest->fine = fine; 153 PetscFunctionReturn(0); 154 } 155 156 #undef __FUNCT__ 157 #define __FUNCT__ "DMForestGetFineForest_Forest" 158 PetscErrorCode DMForestGetFineForest(DM dm, DM *fine) 159 { 160 DM_Forest *forest = (DM_Forest *) dm->data; 161 162 PetscFunctionBegin; 163 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 164 PetscValidPointer(fine, 2); 165 *fine = forest->fine; 166 PetscFunctionReturn(0); 167 } 168 169 #undef __FUNCT__ 170 #define __FUNCT__ "DMForestSetAdjacencyDimension" 171 PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim) 172 { 173 PetscInt dim; 174 DM_Forest *forest = (DM_Forest *) dm->data; 175 PetscErrorCode ierr; 176 177 PetscFunctionBegin; 178 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 179 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup"); 180 if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim); 181 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 182 if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim); 183 forest->adjDim = adjDim; 184 PetscFunctionReturn(0); 185 } 186 187 #undef __FUNCT__ 188 #define __FUNCT__ "DMForestSetAdjacencyCodimension" 189 PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim) 190 { 191 PetscInt dim; 192 PetscErrorCode ierr; 193 194 PetscFunctionBegin; 195 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 196 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 197 ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr); 198 PetscFunctionReturn(0); 199 } 200 201 #undef __FUNCT__ 202 #define __FUNCT__ "DMForestGetAdjacencyDimension" 203 PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim) 204 { 205 DM_Forest *forest = (DM_Forest *) dm->data; 206 207 PetscFunctionBegin; 208 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 209 PetscValidIntPointer(adjDim,2); 210 *adjDim = forest->adjDim; 211 PetscFunctionReturn(0); 212 } 213 214 #undef __FUNCT__ 215 #define __FUNCT__ "DMForestGetAdjacencyCodimension" 216 PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim) 217 { 218 DM_Forest *forest = (DM_Forest *) dm->data; 219 PetscInt dim; 220 PetscErrorCode ierr; 221 222 PetscFunctionBegin; 223 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 224 PetscValidIntPointer(adjCodim,2); 225 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 226 *adjCodim = dim - forest->adjDim; 227 PetscFunctionReturn(0); 228 } 229 230 #undef __FUNCT__ 231 #define __FUNCT__ "DMForestSetParititionOverlap" 232 PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap) 233 { 234 DM_Forest *forest = (DM_Forest *) dm->data; 235 236 PetscFunctionBegin; 237 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 238 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup"); 239 if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", overlap); 240 forest->overlap = overlap; 241 PetscFunctionReturn(0); 242 } 243 244 #undef __FUNCT__ 245 #define __FUNCT__ "DMForestGetPartitionOverlap" 246 PetscErrorCode DMForestGetPartitionOverlap (DM dm, PetscInt *overlap) 247 { 248 DM_Forest *forest = (DM_Forest *) dm->data; 249 250 PetscFunctionBegin; 251 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 252 PetscValidIntPointer(overlap,2); 253 *overlap = forest->overlap; 254 PetscFunctionReturn(0); 255 } 256 257 #undef __FUNCT__ 258 #define __FUNCT__ "DMForestSetMinimumRefinement" 259 PetscErrorCode DMForestSetMinimumRefinement (DM dm, PetscInt minRefinement) 260 { 261 DM_Forest *forest = (DM_Forest *) dm->data; 262 263 PetscFunctionBegin; 264 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 265 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup"); 266 forest->minRefinement = minRefinement; 267 PetscFunctionReturn(0); 268 } 269 270 #undef __FUNCT__ 271 #define __FUNCT__ "DMForestGetMinimumRefinement" 272 PetscErrorCode DMForestGetMinimumRefinement (DM dm, PetscInt *minRefinement) 273 { 274 DM_Forest *forest = (DM_Forest *) dm->data; 275 276 PetscFunctionBegin; 277 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 278 PetscValidIntPointer(minRefinement,2); 279 *minRefinement = forest->minRefinement; 280 PetscFunctionReturn(0); 281 } 282 283 #undef __FUNCT__ 284 #define __FUNCT__ "DMForestSetMinimumRefinement" 285 PetscErrorCode DMForestSetMinimumRefinement (DM dm, PetscInt minRefinement) 286 { 287 DM_Forest *forest = (DM_Forest *) dm->data; 288 289 PetscFunctionBegin; 290 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 291 if (forest->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup"); 292 forest->minRefinement = minRefinement; 293 PetscFunctionReturn(0); 294 } 295 296 #undef __FUNCT__ 297 #define __FUNCT__ "DMForestGetMinimumRefinement" 298 PetscErrorCode DMForestGetMinimumRefinement (DM dm, PetscInt *minRefinement) 299 { 300 DM_Forest *forest = (DM_Forest *) dm->data; 301 302 PetscFunctionBegin; 303 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 304 PetscValidIntPointer(minRefinement,2); 305 *minRefinement = forest->minRefinement; 306 PetscFunctionReturn(0); 307 } 308 #undef __FUNCT__ 309 #define __FUNCT__ "DMSetFromOptions_Forest" 310 PetscErrorCode DMSetFromFromOptions_Forest(DM dm) 311 { 312 DM_Forest *forest = (DM_Forest *) dm->data; 313 PetscBool flg; 314 DMForestTopology oldTopo; 315 char topology[256]; 316 PetscViewer viewer; 317 PetscViewerFormat format; 318 PetscInt adjDim, adjCodim, overlap, minRefinement; 319 PetscErrorCode ierr; 320 321 PetscFunctionBegin; 322 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 323 forest->setFromOptions = PETSC_TRUE; 324 ierr = PetscOptionsHead("DMForest Options");CHKERRQ(ierr); 325 ierr = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr); 326 ierr = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,topology,256,&flg);CHKERRQ(ierr); 327 if (flg) { 328 ierr = DMForestSetTopology(dm,(DMForestTopology)topology);CHKERRQ(ierr); 329 } 330 ierr = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg);CHKERRQ(ierr); 331 if (flg) { 332 DM base; 333 334 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr); 335 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 336 ierr = DMLoad(base,viewer);CHKERRQ(ierr); 337 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 338 ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr); 339 ierr = DMDestroy(&base);CHKERRQ(ierr); 340 } 341 ierr = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg);CHKERRQ(ierr); 342 if (flg) { 343 DM coarse; 344 345 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr); 346 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 347 ierr = DMLoad(coarse,viewer);CHKERRQ(ierr); 348 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 349 ierr = DMForestSetCoarseForest(dm,coarse);CHKERRQ(ierr); 350 ierr = DMDestroy(&coarse);CHKERRQ(ierr); 351 } 352 ierr = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg);CHKERRQ(ierr); 353 if (flg) { 354 DM fine; 355 356 ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr); 357 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 358 ierr = DMLoad(fine,viewer);CHKERRQ(ierr); 359 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 360 ierr = DMForestSetFineForest(dm,fine);CHKERRQ(ierr); 361 ierr = DMDestroy(&fine);CHKERRQ(ierr); 362 } 363 ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr); 364 ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr); 365 if (flg) { 366 ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr); 367 } 368 else { 369 ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr); 370 ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr); 371 if (flg) { 372 ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr); 373 } 374 } 375 ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr); 376 ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr); 377 if (flg) { 378 ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr); 379 } 380 ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr); 381 ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr); 382 if (flg) { 383 ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr); 384 } 385 ierr = PetscOptionsTail();CHKERRQ(ierr); 386 PetscFunctionReturn(0); 387 } 388 389 #undef __FUNCT__ 390 #define __FUNCT__ "DMCreate_Forest" 391 PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm) 392 { 393 DM_Forest *forest; 394 PetscErrorCode ierr; 395 396 PetscFunctionBegin; 397 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 398 ierr = PetscNewLog(dm,&forest);CHKERRQ(ierr); 399 dm->dim = 0; 400 dm->data = forest; 401 forest->refct = 1; 402 forest->data = NULL; 403 forest->setup = 0; 404 forest->setFromOptions = PETSC_FALSE; 405 forest->topology = NULL; 406 forest->base = NULL; 407 forest->coarse = NULL; 408 forest->fine = NULL; 409 forest->adjDim = PETSC_DEFAULT; 410 forest->overlap = PETSC_DEFAULT; 411 forest->minRefinement = PETSC_DEFAULT; 412 forest->maxRefinement = PETSC_DEFAULT; 413 forest->cStart = 0; 414 forest->cEnd = 0; 415 forest->cellSF = 0; 416 forest->adaptMarkers = NULL; 417 forest->adaptCopyMode = PETSC_USE_POINTER; 418 forest->adaptStrategy = DMFORESTADAPTALL; 419 forest->gradeFactor = 2; 420 forest->cellWeights = NULL; 421 forest->cellWeightsCopyMode = PETSC_USE_POINTER; 422 forest->weightsFactor = 1.; 423 forest->weightCapacity = 1.; 424 PetscFunctionReturn(0); 425 } 426 427