1 2 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 3 4 PetscErrorCode DMSetFromOptions_DA(DM da, PetscOptionItems *PetscOptionsObject) 5 { 6 DM_DA *dd = (DM_DA *)da->data; 7 PetscInt refine = 0, dim = da->dim, maxnlevels = 100, refx[100], refy[100], refz[100], n, i; 8 PetscBool flg; 9 10 PetscFunctionBegin; 11 PetscCheck(dd->M >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_OUTOFRANGE, "Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime"); 12 PetscCheck(dd->N >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_OUTOFRANGE, "Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime"); 13 PetscCheck(dd->P >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_OUTOFRANGE, "Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime"); 14 15 PetscOptionsHeadBegin(PetscOptionsObject, "DMDA Options"); 16 PetscCall(PetscOptionsBoundedInt("-da_grid_x", "Number of grid points in x direction", "DMDASetSizes", dd->M, &dd->M, NULL, 1)); 17 if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_grid_y", "Number of grid points in y direction", "DMDASetSizes", dd->N, &dd->N, NULL, 1)); 18 if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_grid_z", "Number of grid points in z direction", "DMDASetSizes", dd->P, &dd->P, NULL, 1)); 19 20 PetscCall(PetscOptionsBoundedInt("-da_overlap", "Decomposition overlap in all directions", "DMDASetOverlap", dd->xol, &dd->xol, &flg, 0)); 21 if (flg) PetscCall(DMDASetOverlap(da, dd->xol, dd->xol, dd->xol)); 22 PetscCall(PetscOptionsBoundedInt("-da_overlap_x", "Decomposition overlap in x direction", "DMDASetOverlap", dd->xol, &dd->xol, NULL, 0)); 23 if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_overlap_y", "Decomposition overlap in y direction", "DMDASetOverlap", dd->yol, &dd->yol, NULL, 0)); 24 if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_overlap_z", "Decomposition overlap in z direction", "DMDASetOverlap", dd->zol, &dd->zol, NULL, 0)); 25 26 PetscCall(PetscOptionsBoundedInt("-da_local_subdomains", "", "DMDASetNumLocalSubdomains", dd->Nsub, &dd->Nsub, &flg, PETSC_DECIDE)); 27 if (flg) PetscCall(DMDASetNumLocalSubDomains(da, dd->Nsub)); 28 29 /* Handle DMDA parallel distribution */ 30 PetscCall(PetscOptionsBoundedInt("-da_processors_x", "Number of processors in x direction", "DMDASetNumProcs", dd->m, &dd->m, NULL, PETSC_DECIDE)); 31 if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_processors_y", "Number of processors in y direction", "DMDASetNumProcs", dd->n, &dd->n, NULL, PETSC_DECIDE)); 32 if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_processors_z", "Number of processors in z direction", "DMDASetNumProcs", dd->p, &dd->p, NULL, PETSC_DECIDE)); 33 /* Handle DMDA refinement */ 34 PetscCall(PetscOptionsBoundedInt("-da_refine_x", "Refinement ratio in x direction", "DMDASetRefinementFactor", dd->refine_x, &dd->refine_x, NULL, 1)); 35 if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_refine_y", "Refinement ratio in y direction", "DMDASetRefinementFactor", dd->refine_y, &dd->refine_y, NULL, 1)); 36 if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_refine_z", "Refinement ratio in z direction", "DMDASetRefinementFactor", dd->refine_z, &dd->refine_z, NULL, 1)); 37 dd->coarsen_x = dd->refine_x; 38 dd->coarsen_y = dd->refine_y; 39 dd->coarsen_z = dd->refine_z; 40 41 /* Get refinement factors, defaults taken from the coarse DMDA */ 42 PetscCall(DMDAGetRefinementFactor(da, &refx[0], &refy[0], &refz[0])); 43 for (i = 1; i < maxnlevels; i++) { 44 refx[i] = refx[0]; 45 refy[i] = refy[0]; 46 refz[i] = refz[0]; 47 } 48 n = maxnlevels; 49 PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_x", "Refinement factor for each level", "None", refx, &n, &flg)); 50 if (flg) { 51 dd->refine_x = refx[0]; 52 dd->refine_x_hier_n = n; 53 PetscCall(PetscMalloc1(n, &dd->refine_x_hier)); 54 PetscCall(PetscArraycpy(dd->refine_x_hier, refx, n)); 55 } 56 if (dim > 1) { 57 n = maxnlevels; 58 PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_y", "Refinement factor for each level", "None", refy, &n, &flg)); 59 if (flg) { 60 dd->refine_y = refy[0]; 61 dd->refine_y_hier_n = n; 62 PetscCall(PetscMalloc1(n, &dd->refine_y_hier)); 63 PetscCall(PetscArraycpy(dd->refine_y_hier, refy, n)); 64 } 65 } 66 if (dim > 2) { 67 n = maxnlevels; 68 PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_z", "Refinement factor for each level", "None", refz, &n, &flg)); 69 if (flg) { 70 dd->refine_z = refz[0]; 71 dd->refine_z_hier_n = n; 72 PetscCall(PetscMalloc1(n, &dd->refine_z_hier)); 73 PetscCall(PetscArraycpy(dd->refine_z_hier, refz, n)); 74 } 75 } 76 77 PetscCall(PetscOptionsBoundedInt("-da_refine", "Uniformly refine DA one or more times", "None", refine, &refine, NULL, 0)); 78 PetscOptionsHeadEnd(); 79 80 while (refine--) { 81 if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 82 PetscCall(PetscIntMultError(dd->refine_x, dd->M, &dd->M)); 83 } else { 84 PetscCall(PetscIntMultError(dd->refine_x, dd->M - 1, &dd->M)); 85 dd->M += 1; 86 } 87 if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 88 PetscCall(PetscIntMultError(dd->refine_y, dd->N, &dd->N)); 89 } else { 90 PetscCall(PetscIntMultError(dd->refine_y, dd->N - 1, &dd->N)); 91 dd->N += 1; 92 } 93 if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 94 PetscCall(PetscIntMultError(dd->refine_z, dd->P, &dd->P)); 95 } else { 96 PetscCall(PetscIntMultError(dd->refine_z, dd->P - 1, &dd->P)); 97 dd->P += 1; 98 } 99 da->levelup++; 100 if (da->levelup - da->leveldown >= 0) { 101 dd->refine_x = refx[da->levelup - da->leveldown]; 102 dd->refine_y = refy[da->levelup - da->leveldown]; 103 dd->refine_z = refz[da->levelup - da->leveldown]; 104 } 105 if (da->levelup - da->leveldown >= 1) { 106 dd->coarsen_x = refx[da->levelup - da->leveldown - 1]; 107 dd->coarsen_y = refy[da->levelup - da->leveldown - 1]; 108 dd->coarsen_z = refz[da->levelup - da->leveldown - 1]; 109 } 110 } 111 PetscFunctionReturn(PETSC_SUCCESS); 112 } 113 114 extern PetscErrorCode DMCreateGlobalVector_DA(DM, Vec *); 115 extern PetscErrorCode DMCreateLocalVector_DA(DM, Vec *); 116 extern PetscErrorCode DMGlobalToLocalBegin_DA(DM, Vec, InsertMode, Vec); 117 extern PetscErrorCode DMGlobalToLocalEnd_DA(DM, Vec, InsertMode, Vec); 118 extern PetscErrorCode DMLocalToGlobalBegin_DA(DM, Vec, InsertMode, Vec); 119 extern PetscErrorCode DMLocalToGlobalEnd_DA(DM, Vec, InsertMode, Vec); 120 extern PetscErrorCode DMLocalToLocalBegin_DA(DM, Vec, InsertMode, Vec); 121 extern PetscErrorCode DMLocalToLocalEnd_DA(DM, Vec, InsertMode, Vec); 122 extern PetscErrorCode DMCreateInterpolation_DA(DM, DM, Mat *, Vec *); 123 extern PetscErrorCode DMCreateColoring_DA(DM, ISColoringType, ISColoring *); 124 extern PetscErrorCode DMCreateMatrix_DA(DM, Mat *); 125 extern PetscErrorCode DMCreateCoordinateDM_DA(DM, DM *); 126 extern PetscErrorCode DMRefine_DA(DM, MPI_Comm, DM *); 127 extern PetscErrorCode DMCoarsen_DA(DM, MPI_Comm, DM *); 128 extern PetscErrorCode DMRefineHierarchy_DA(DM, PetscInt, DM[]); 129 extern PetscErrorCode DMCoarsenHierarchy_DA(DM, PetscInt, DM[]); 130 extern PetscErrorCode DMCreateInjection_DA(DM, DM, Mat *); 131 extern PetscErrorCode DMView_DA(DM, PetscViewer); 132 extern PetscErrorCode DMSetUp_DA(DM); 133 extern PetscErrorCode DMDestroy_DA(DM); 134 extern PetscErrorCode DMCreateDomainDecomposition_DA(DM, PetscInt *, char ***, IS **, IS **, DM **); 135 extern PetscErrorCode DMCreateDomainDecompositionScatters_DA(DM, PetscInt, DM *, VecScatter **, VecScatter **, VecScatter **); 136 PETSC_INTERN PetscErrorCode DMGetCompatibility_DA(DM, DM, PetscBool *, PetscBool *); 137 138 PetscErrorCode DMLoad_DA(DM da, PetscViewer viewer) 139 { 140 PetscInt dim, m, n, p, dof, swidth; 141 DMDAStencilType stencil; 142 DMBoundaryType bx, by, bz; 143 PetscBool coors; 144 DM dac; 145 Vec c; 146 147 PetscFunctionBegin; 148 PetscCall(PetscViewerBinaryRead(viewer, &dim, 1, NULL, PETSC_INT)); 149 PetscCall(PetscViewerBinaryRead(viewer, &m, 1, NULL, PETSC_INT)); 150 PetscCall(PetscViewerBinaryRead(viewer, &n, 1, NULL, PETSC_INT)); 151 PetscCall(PetscViewerBinaryRead(viewer, &p, 1, NULL, PETSC_INT)); 152 PetscCall(PetscViewerBinaryRead(viewer, &dof, 1, NULL, PETSC_INT)); 153 PetscCall(PetscViewerBinaryRead(viewer, &swidth, 1, NULL, PETSC_INT)); 154 PetscCall(PetscViewerBinaryRead(viewer, &bx, 1, NULL, PETSC_ENUM)); 155 PetscCall(PetscViewerBinaryRead(viewer, &by, 1, NULL, PETSC_ENUM)); 156 PetscCall(PetscViewerBinaryRead(viewer, &bz, 1, NULL, PETSC_ENUM)); 157 PetscCall(PetscViewerBinaryRead(viewer, &stencil, 1, NULL, PETSC_ENUM)); 158 159 PetscCall(DMSetDimension(da, dim)); 160 PetscCall(DMDASetSizes(da, m, n, p)); 161 PetscCall(DMDASetBoundaryType(da, bx, by, bz)); 162 PetscCall(DMDASetDof(da, dof)); 163 PetscCall(DMDASetStencilType(da, stencil)); 164 PetscCall(DMDASetStencilWidth(da, swidth)); 165 PetscCall(DMSetUp(da)); 166 PetscCall(PetscViewerBinaryRead(viewer, &coors, 1, NULL, PETSC_ENUM)); 167 if (coors) { 168 PetscCall(DMGetCoordinateDM(da, &dac)); 169 PetscCall(DMCreateGlobalVector(dac, &c)); 170 PetscCall(VecLoad(c, viewer)); 171 PetscCall(DMSetCoordinates(da, c)); 172 PetscCall(VecDestroy(&c)); 173 } 174 PetscFunctionReturn(PETSC_SUCCESS); 175 } 176 177 PetscErrorCode DMCreateSubDM_DA(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 178 { 179 DM_DA *da = (DM_DA *)dm->data; 180 181 PetscFunctionBegin; 182 if (subdm) { 183 PetscSF sf; 184 Vec coords; 185 void *ctx; 186 /* Cannot use DMClone since the dof stuff is mixed in. Ugh 187 PetscCall(DMClone(dm, subdm)); */ 188 PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), subdm)); 189 PetscCall(DMGetPointSF(dm, &sf)); 190 PetscCall(DMSetPointSF(*subdm, sf)); 191 PetscCall(DMGetApplicationContext(dm, &ctx)); 192 PetscCall(DMSetApplicationContext(*subdm, ctx)); 193 PetscCall(DMGetCoordinatesLocal(dm, &coords)); 194 if (coords) { 195 PetscCall(DMSetCoordinatesLocal(*subdm, coords)); 196 } else { 197 PetscCall(DMGetCoordinates(dm, &coords)); 198 if (coords) PetscCall(DMSetCoordinates(*subdm, coords)); 199 } 200 201 PetscCall(DMSetType(*subdm, DMDA)); 202 PetscCall(DMSetDimension(*subdm, dm->dim)); 203 PetscCall(DMDASetSizes(*subdm, da->M, da->N, da->P)); 204 PetscCall(DMDASetNumProcs(*subdm, da->m, da->n, da->p)); 205 PetscCall(DMDASetBoundaryType(*subdm, da->bx, da->by, da->bz)); 206 PetscCall(DMDASetDof(*subdm, numFields)); 207 PetscCall(DMDASetStencilType(*subdm, da->stencil_type)); 208 PetscCall(DMDASetStencilWidth(*subdm, da->s)); 209 PetscCall(DMDASetOwnershipRanges(*subdm, da->lx, da->ly, da->lz)); 210 } 211 if (is) { 212 PetscInt *indices, cnt = 0, dof = da->w, i, j; 213 214 PetscCall(PetscMalloc1(da->Nlocal * numFields / dof, &indices)); 215 for (i = da->base / dof; i < (da->base + da->Nlocal) / dof; ++i) { 216 for (j = 0; j < numFields; ++j) indices[cnt++] = dof * i + fields[j]; 217 } 218 PetscCheck(cnt == da->Nlocal * numFields / dof, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count %" PetscInt_FMT " does not equal expected value %" PetscInt_FMT, cnt, da->Nlocal * numFields / dof); 219 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), cnt, indices, PETSC_OWN_POINTER, is)); 220 } 221 PetscFunctionReturn(PETSC_SUCCESS); 222 } 223 224 PetscErrorCode DMCreateFieldDecomposition_DA(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 225 { 226 PetscInt i; 227 DM_DA *dd = (DM_DA *)dm->data; 228 PetscInt dof = dd->w; 229 230 PetscFunctionBegin; 231 if (len) *len = dof; 232 if (islist) { 233 Vec v; 234 PetscInt rstart, n; 235 236 PetscCall(DMGetGlobalVector(dm, &v)); 237 PetscCall(VecGetOwnershipRange(v, &rstart, NULL)); 238 PetscCall(VecGetLocalSize(v, &n)); 239 PetscCall(DMRestoreGlobalVector(dm, &v)); 240 PetscCall(PetscMalloc1(dof, islist)); 241 for (i = 0; i < dof; i++) PetscCall(ISCreateStride(PetscObjectComm((PetscObject)dm), n / dof, rstart + i, dof, &(*islist)[i])); 242 } 243 if (namelist) { 244 PetscCall(PetscMalloc1(dof, namelist)); 245 if (dd->fieldname) { 246 for (i = 0; i < dof; i++) PetscCall(PetscStrallocpy(dd->fieldname[i], &(*namelist)[i])); 247 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Currently DMDA must have fieldnames"); 248 } 249 if (dmlist) { 250 DM da; 251 252 PetscCall(DMDACreate(PetscObjectComm((PetscObject)dm), &da)); 253 PetscCall(DMSetDimension(da, dm->dim)); 254 PetscCall(DMDASetSizes(da, dd->M, dd->N, dd->P)); 255 PetscCall(DMDASetNumProcs(da, dd->m, dd->n, dd->p)); 256 PetscCall(DMDASetBoundaryType(da, dd->bx, dd->by, dd->bz)); 257 PetscCall(DMDASetDof(da, 1)); 258 PetscCall(DMDASetStencilType(da, dd->stencil_type)); 259 PetscCall(DMDASetStencilWidth(da, dd->s)); 260 PetscCall(DMSetUp(da)); 261 PetscCall(PetscMalloc1(dof, dmlist)); 262 for (i = 0; i < dof - 1; i++) PetscCall(PetscObjectReference((PetscObject)da)); 263 for (i = 0; i < dof; i++) (*dmlist)[i] = da; 264 } 265 PetscFunctionReturn(PETSC_SUCCESS); 266 } 267 268 PetscErrorCode DMClone_DA(DM dm, DM *newdm) 269 { 270 DM_DA *da = (DM_DA *)dm->data; 271 272 PetscFunctionBegin; 273 PetscCall(DMSetType(*newdm, DMDA)); 274 PetscCall(DMSetDimension(*newdm, dm->dim)); 275 PetscCall(DMDASetSizes(*newdm, da->M, da->N, da->P)); 276 PetscCall(DMDASetNumProcs(*newdm, da->m, da->n, da->p)); 277 PetscCall(DMDASetBoundaryType(*newdm, da->bx, da->by, da->bz)); 278 PetscCall(DMDASetDof(*newdm, da->w)); 279 PetscCall(DMDASetStencilType(*newdm, da->stencil_type)); 280 PetscCall(DMDASetStencilWidth(*newdm, da->s)); 281 PetscCall(DMDASetOwnershipRanges(*newdm, da->lx, da->ly, da->lz)); 282 PetscCall(DMSetUp(*newdm)); 283 PetscFunctionReturn(PETSC_SUCCESS); 284 } 285 286 static PetscErrorCode DMHasCreateInjection_DA(DM dm, PetscBool *flg) 287 { 288 DM_DA *da = (DM_DA *)dm->data; 289 290 PetscFunctionBegin; 291 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 292 PetscValidBoolPointer(flg, 2); 293 *flg = da->interptype == DMDA_Q1 ? PETSC_TRUE : PETSC_FALSE; 294 PetscFunctionReturn(PETSC_SUCCESS); 295 } 296 297 static PetscErrorCode DMGetDimPoints_DA(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 298 { 299 PetscFunctionBegin; 300 PetscCall(DMDAGetDepthStratum(dm, dim, pStart, pEnd)); 301 PetscFunctionReturn(PETSC_SUCCESS); 302 } 303 304 static PetscErrorCode DMGetNeighbors_DA(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 305 { 306 PetscInt dim; 307 DMDAStencilType st; 308 309 PetscFunctionBegin; 310 PetscCall(DMDAGetNeighbors(dm, ranks)); 311 PetscCall(DMDAGetInfo(dm, &dim, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &st)); 312 313 switch (dim) { 314 case 1: 315 *nranks = 3; 316 /* if (st == DMDA_STENCIL_STAR) *nranks = 3; */ 317 break; 318 case 2: 319 *nranks = 9; 320 /* if (st == DMDA_STENCIL_STAR) *nranks = 5; */ 321 break; 322 case 3: 323 *nranks = 27; 324 /* if (st == DMDA_STENCIL_STAR) *nranks = 7; */ 325 break; 326 default: 327 break; 328 } 329 PetscFunctionReturn(PETSC_SUCCESS); 330 } 331 332 /*MC 333 DMDA = "da" - A `DM` object that is used to manage data for a structured grid in 1, 2, or 3 dimensions. 334 In the global representation of the vector each process stores a non-overlapping rectangular (or slab in 3d) portion of the grid points. 335 In the local representation these rectangular regions (slabs) are extended in all directions by a stencil width. 336 337 The vectors can be thought of as either cell centered or vertex centered on the mesh. But some variables cannot be cell centered and others 338 vertex centered; see the documentation for `DMSTAG`, a similar DM implementation which supports these staggered grids. 339 340 Level: intermediate 341 342 .seealso: `DMType`, `DMCOMPOSITE`, `DMSTAG`, `DMDACreate()`, `DMCreate()`, `DMSetType()` 343 M*/ 344 345 extern PetscErrorCode DMLocatePoints_DA_Regular(DM, Vec, DMPointLocationType, PetscSF); 346 PETSC_INTERN PetscErrorCode DMSetUpGLVisViewer_DMDA(PetscObject, PetscViewer); 347 348 PETSC_EXTERN PetscErrorCode DMCreate_DA(DM da) 349 { 350 DM_DA *dd; 351 352 PetscFunctionBegin; 353 PetscValidPointer(da, 1); 354 PetscCall(PetscNew(&dd)); 355 da->data = dd; 356 357 da->dim = -1; 358 dd->interptype = DMDA_Q1; 359 dd->refine_x = 2; 360 dd->refine_y = 2; 361 dd->refine_z = 2; 362 dd->coarsen_x = 2; 363 dd->coarsen_y = 2; 364 dd->coarsen_z = 2; 365 dd->fieldname = NULL; 366 dd->nlocal = -1; 367 dd->Nlocal = -1; 368 dd->M = -1; 369 dd->N = -1; 370 dd->P = -1; 371 dd->m = -1; 372 dd->n = -1; 373 dd->p = -1; 374 dd->w = -1; 375 dd->s = -1; 376 377 dd->xs = -1; 378 dd->xe = -1; 379 dd->ys = -1; 380 dd->ye = -1; 381 dd->zs = -1; 382 dd->ze = -1; 383 dd->Xs = -1; 384 dd->Xe = -1; 385 dd->Ys = -1; 386 dd->Ye = -1; 387 dd->Zs = -1; 388 dd->Ze = -1; 389 390 dd->Nsub = 1; 391 dd->xol = 0; 392 dd->yol = 0; 393 dd->zol = 0; 394 dd->xo = 0; 395 dd->yo = 0; 396 dd->zo = 0; 397 dd->Mo = -1; 398 dd->No = -1; 399 dd->Po = -1; 400 401 dd->gtol = NULL; 402 dd->ltol = NULL; 403 dd->ao = NULL; 404 PetscCall(PetscStrallocpy(AOBASIC, (char **)&dd->aotype)); 405 dd->base = -1; 406 dd->bx = DM_BOUNDARY_NONE; 407 dd->by = DM_BOUNDARY_NONE; 408 dd->bz = DM_BOUNDARY_NONE; 409 dd->stencil_type = DMDA_STENCIL_BOX; 410 dd->interptype = DMDA_Q1; 411 dd->lx = NULL; 412 dd->ly = NULL; 413 dd->lz = NULL; 414 415 dd->elementtype = DMDA_ELEMENT_Q1; 416 417 da->ops->globaltolocalbegin = DMGlobalToLocalBegin_DA; 418 da->ops->globaltolocalend = DMGlobalToLocalEnd_DA; 419 da->ops->localtoglobalbegin = DMLocalToGlobalBegin_DA; 420 da->ops->localtoglobalend = DMLocalToGlobalEnd_DA; 421 da->ops->localtolocalbegin = DMLocalToLocalBegin_DA; 422 da->ops->localtolocalend = DMLocalToLocalEnd_DA; 423 da->ops->createglobalvector = DMCreateGlobalVector_DA; 424 da->ops->createlocalvector = DMCreateLocalVector_DA; 425 da->ops->createinterpolation = DMCreateInterpolation_DA; 426 da->ops->getcoloring = DMCreateColoring_DA; 427 da->ops->creatematrix = DMCreateMatrix_DA; 428 da->ops->refine = DMRefine_DA; 429 da->ops->coarsen = DMCoarsen_DA; 430 da->ops->refinehierarchy = DMRefineHierarchy_DA; 431 da->ops->coarsenhierarchy = DMCoarsenHierarchy_DA; 432 da->ops->createinjection = DMCreateInjection_DA; 433 da->ops->hascreateinjection = DMHasCreateInjection_DA; 434 da->ops->destroy = DMDestroy_DA; 435 da->ops->view = NULL; 436 da->ops->setfromoptions = DMSetFromOptions_DA; 437 da->ops->setup = DMSetUp_DA; 438 da->ops->clone = DMClone_DA; 439 da->ops->load = DMLoad_DA; 440 da->ops->createcoordinatedm = DMCreateCoordinateDM_DA; 441 da->ops->createsubdm = DMCreateSubDM_DA; 442 da->ops->createfielddecomposition = DMCreateFieldDecomposition_DA; 443 da->ops->createdomaindecomposition = DMCreateDomainDecomposition_DA; 444 da->ops->createddscatters = DMCreateDomainDecompositionScatters_DA; 445 da->ops->getdimpoints = DMGetDimPoints_DA; 446 da->ops->getneighbors = DMGetNeighbors_DA; 447 da->ops->locatepoints = DMLocatePoints_DA_Regular; 448 da->ops->getcompatibility = DMGetCompatibility_DA; 449 PetscCall(PetscObjectComposeFunction((PetscObject)da, "DMSetUpGLVisViewer_C", DMSetUpGLVisViewer_DMDA)); 450 PetscFunctionReturn(PETSC_SUCCESS); 451 } 452 453 /*@ 454 DMDACreate - Creates a DMDA object. 455 456 Collective 457 458 Input Parameter: 459 . comm - The communicator for the DMDA object 460 461 Output Parameter: 462 . da - The DMDA object 463 464 Level: advanced 465 466 Developers Note: 467 Since there exists DMDACreate1/2/3d() should this routine even exist? 468 469 .seealso: `DMDASetSizes()`, `DMClone()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()` 470 @*/ 471 PetscErrorCode DMDACreate(MPI_Comm comm, DM *da) 472 { 473 PetscFunctionBegin; 474 PetscValidPointer(da, 2); 475 PetscCall(DMCreate(comm, da)); 476 PetscCall(DMSetType(*da, DMDA)); 477 PetscFunctionReturn(PETSC_SUCCESS); 478 } 479