xref: /petsc/src/dm/impls/da/dacreate.c (revision dce8aeba1c9b69b19f651c53d8a6b674bd7e9cbd)
17d0a6c19SBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
347c6ae99SBarry Smith 
4d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFromOptions_DA(DM da, PetscOptionItems *PetscOptionsObject)
5d71ae5a4SJacob Faibussowitsch {
647c6ae99SBarry Smith   DM_DA    *dd     = (DM_DA *)da->data;
7c73cfb54SMatthew G. Knepley   PetscInt  refine = 0, dim = da->dim, maxnlevels = 100, refx[100], refy[100], refz[100], n, i;
8897f7067SBarry Smith   PetscBool flg;
947c6ae99SBarry Smith 
1047c6ae99SBarry Smith   PetscFunctionBegin;
1108401ef6SPierre Jolivet   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");
1208401ef6SPierre Jolivet   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");
1308401ef6SPierre Jolivet   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");
14235683edSBarry Smith 
15d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "DMDA Options");
169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-da_grid_x", "Number of grid points in x direction", "DMDASetSizes", dd->M, &dd->M, NULL, 1));
179566063dSJacob Faibussowitsch   if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_grid_y", "Number of grid points in y direction", "DMDASetSizes", dd->N, &dd->N, NULL, 1));
189566063dSJacob Faibussowitsch   if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_grid_z", "Number of grid points in z direction", "DMDASetSizes", dd->P, &dd->P, NULL, 1));
197ddda789SPeter Brune 
209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-da_overlap", "Decomposition overlap in all directions", "DMDASetOverlap", dd->xol, &dd->xol, &flg, 0));
219566063dSJacob Faibussowitsch   if (flg) PetscCall(DMDASetOverlap(da, dd->xol, dd->xol, dd->xol));
229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-da_overlap_x", "Decomposition overlap in x direction", "DMDASetOverlap", dd->xol, &dd->xol, NULL, 0));
239566063dSJacob Faibussowitsch   if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_overlap_y", "Decomposition overlap in y direction", "DMDASetOverlap", dd->yol, &dd->yol, NULL, 0));
249566063dSJacob Faibussowitsch   if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_overlap_z", "Decomposition overlap in z direction", "DMDASetOverlap", dd->zol, &dd->zol, NULL, 0));
253e7870d2SPeter Brune 
269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-da_local_subdomains", "", "DMDASetNumLocalSubdomains", dd->Nsub, &dd->Nsub, &flg, PETSC_DECIDE));
279566063dSJacob Faibussowitsch   if (flg) PetscCall(DMDASetNumLocalSubDomains(da, dd->Nsub));
283e7870d2SPeter Brune 
298d07fd27SPatrick Sanan   /* Handle DMDA parallel distribution */
309566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-da_processors_x", "Number of processors in x direction", "DMDASetNumProcs", dd->m, &dd->m, NULL, PETSC_DECIDE));
319566063dSJacob Faibussowitsch   if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_processors_y", "Number of processors in y direction", "DMDASetNumProcs", dd->n, &dd->n, NULL, PETSC_DECIDE));
329566063dSJacob Faibussowitsch   if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_processors_z", "Number of processors in z direction", "DMDASetNumProcs", dd->p, &dd->p, NULL, PETSC_DECIDE));
33aa219208SBarry Smith   /* Handle DMDA refinement */
349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-da_refine_x", "Refinement ratio in x direction", "DMDASetRefinementFactor", dd->refine_x, &dd->refine_x, NULL, 1));
359566063dSJacob Faibussowitsch   if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_refine_y", "Refinement ratio in y direction", "DMDASetRefinementFactor", dd->refine_y, &dd->refine_y, NULL, 1));
369566063dSJacob Faibussowitsch   if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_refine_z", "Refinement ratio in z direction", "DMDASetRefinementFactor", dd->refine_z, &dd->refine_z, NULL, 1));
379371c9d4SSatish Balay   dd->coarsen_x = dd->refine_x;
389371c9d4SSatish Balay   dd->coarsen_y = dd->refine_y;
399371c9d4SSatish Balay   dd->coarsen_z = dd->refine_z;
4047c6ae99SBarry Smith 
41397b6216SJed Brown   /* Get refinement factors, defaults taken from the coarse DMDA */
429566063dSJacob Faibussowitsch   PetscCall(DMDAGetRefinementFactor(da, &refx[0], &refy[0], &refz[0]));
43397b6216SJed Brown   for (i = 1; i < maxnlevels; i++) {
44397b6216SJed Brown     refx[i] = refx[0];
45397b6216SJed Brown     refy[i] = refy[0];
46397b6216SJed Brown     refz[i] = refz[0];
47397b6216SJed Brown   }
48397b6216SJed Brown   n = maxnlevels;
499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_x", "Refinement factor for each level", "None", refx, &n, &flg));
50897f7067SBarry Smith   if (flg) {
51897f7067SBarry Smith     dd->refine_x        = refx[0];
52897f7067SBarry Smith     dd->refine_x_hier_n = n;
539566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &dd->refine_x_hier));
549566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(dd->refine_x_hier, refx, n));
55897f7067SBarry Smith   }
56c73cfb54SMatthew G. Knepley   if (dim > 1) {
57397b6216SJed Brown     n = maxnlevels;
589566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_y", "Refinement factor for each level", "None", refy, &n, &flg));
59897f7067SBarry Smith     if (flg) {
60897f7067SBarry Smith       dd->refine_y        = refy[0];
61897f7067SBarry Smith       dd->refine_y_hier_n = n;
629566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(n, &dd->refine_y_hier));
639566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(dd->refine_y_hier, refy, n));
64897f7067SBarry Smith     }
65397b6216SJed Brown   }
66c73cfb54SMatthew G. Knepley   if (dim > 2) {
67397b6216SJed Brown     n = maxnlevels;
689566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_z", "Refinement factor for each level", "None", refz, &n, &flg));
69897f7067SBarry Smith     if (flg) {
70897f7067SBarry Smith       dd->refine_z        = refz[0];
71897f7067SBarry Smith       dd->refine_z_hier_n = n;
729566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(n, &dd->refine_z_hier));
739566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(dd->refine_z_hier, refz, n));
74897f7067SBarry Smith     }
75397b6216SJed Brown   }
76397b6216SJed Brown 
779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-da_refine", "Uniformly refine DA one or more times", "None", refine, &refine, NULL, 0));
78d0609cedSBarry Smith   PetscOptionsHeadEnd();
79235683edSBarry Smith 
80e0f5d30fSBarry Smith   while (refine--) {
81bff4a2f0SMatthew G. Knepley     if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
827a3b7fd5SBarry Smith       PetscCall(PetscIntMultError(dd->refine_x, dd->M, &dd->M));
83e0f5d30fSBarry Smith     } else {
847a3b7fd5SBarry Smith       PetscCall(PetscIntMultError(dd->refine_x, dd->M - 1, &dd->M));
857a3b7fd5SBarry Smith       dd->M += 1;
86e0f5d30fSBarry Smith     }
87bff4a2f0SMatthew G. Knepley     if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
887a3b7fd5SBarry Smith       PetscCall(PetscIntMultError(dd->refine_y, dd->N, &dd->N));
89e0f5d30fSBarry Smith     } else {
907a3b7fd5SBarry Smith       PetscCall(PetscIntMultError(dd->refine_y, dd->N - 1, &dd->N));
917a3b7fd5SBarry Smith       dd->N += 1;
92e0f5d30fSBarry Smith     }
93bff4a2f0SMatthew G. Knepley     if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
947a3b7fd5SBarry Smith       PetscCall(PetscIntMultError(dd->refine_z, dd->P, &dd->P));
95e0f5d30fSBarry Smith     } else {
967a3b7fd5SBarry Smith       PetscCall(PetscIntMultError(dd->refine_z, dd->P - 1, &dd->P));
977a3b7fd5SBarry Smith       dd->P += 1;
98e0f5d30fSBarry Smith     }
99e0f5d30fSBarry Smith     da->levelup++;
10085fc4b34SJed Brown     if (da->levelup - da->leveldown >= 0) {
10185fc4b34SJed Brown       dd->refine_x = refx[da->levelup - da->leveldown];
10285fc4b34SJed Brown       dd->refine_y = refy[da->levelup - da->leveldown];
10385fc4b34SJed Brown       dd->refine_z = refz[da->levelup - da->leveldown];
10485fc4b34SJed Brown     }
10585fc4b34SJed Brown     if (da->levelup - da->leveldown >= 1) {
10685fc4b34SJed Brown       dd->coarsen_x = refx[da->levelup - da->leveldown - 1];
10785fc4b34SJed Brown       dd->coarsen_y = refy[da->levelup - da->leveldown - 1];
10885fc4b34SJed Brown       dd->coarsen_z = refz[da->levelup - da->leveldown - 1];
10985fc4b34SJed Brown     }
110e0f5d30fSBarry Smith   }
11147c6ae99SBarry Smith   PetscFunctionReturn(0);
11247c6ae99SBarry Smith }
11347c6ae99SBarry Smith 
1147087cfbeSBarry Smith extern PetscErrorCode       DMCreateGlobalVector_DA(DM, Vec *);
1157087cfbeSBarry Smith extern PetscErrorCode       DMCreateLocalVector_DA(DM, Vec *);
1167087cfbeSBarry Smith extern PetscErrorCode       DMGlobalToLocalBegin_DA(DM, Vec, InsertMode, Vec);
1177087cfbeSBarry Smith extern PetscErrorCode       DMGlobalToLocalEnd_DA(DM, Vec, InsertMode, Vec);
1187087cfbeSBarry Smith extern PetscErrorCode       DMLocalToGlobalBegin_DA(DM, Vec, InsertMode, Vec);
1197087cfbeSBarry Smith extern PetscErrorCode       DMLocalToGlobalEnd_DA(DM, Vec, InsertMode, Vec);
120d78e899eSRichard Tran Mills extern PetscErrorCode       DMLocalToLocalBegin_DA(DM, Vec, InsertMode, Vec);
121d78e899eSRichard Tran Mills extern PetscErrorCode       DMLocalToLocalEnd_DA(DM, Vec, InsertMode, Vec);
122e727c939SJed Brown extern PetscErrorCode       DMCreateInterpolation_DA(DM, DM, Mat *, Vec *);
123b412c318SBarry Smith extern PetscErrorCode       DMCreateColoring_DA(DM, ISColoringType, ISColoring *);
124b412c318SBarry Smith extern PetscErrorCode       DMCreateMatrix_DA(DM, Mat *);
1256636e97aSMatthew G Knepley extern PetscErrorCode       DMCreateCoordinateDM_DA(DM, DM *);
1267087cfbeSBarry Smith extern PetscErrorCode       DMRefine_DA(DM, MPI_Comm, DM *);
1277087cfbeSBarry Smith extern PetscErrorCode       DMCoarsen_DA(DM, MPI_Comm, DM *);
1287087cfbeSBarry Smith extern PetscErrorCode       DMRefineHierarchy_DA(DM, PetscInt, DM[]);
1297087cfbeSBarry Smith extern PetscErrorCode       DMCoarsenHierarchy_DA(DM, PetscInt, DM[]);
1306dbf9973SLawrence Mitchell extern PetscErrorCode       DMCreateInjection_DA(DM, DM, Mat *);
1317087cfbeSBarry Smith extern PetscErrorCode       DMView_DA(DM, PetscViewer);
1327087cfbeSBarry Smith extern PetscErrorCode       DMSetUp_DA(DM);
1337087cfbeSBarry Smith extern PetscErrorCode       DMDestroy_DA(DM);
134e30e807fSPeter Brune extern PetscErrorCode       DMCreateDomainDecomposition_DA(DM, PetscInt *, char ***, IS **, IS **, DM **);
135e30e807fSPeter Brune extern PetscErrorCode       DMCreateDomainDecompositionScatters_DA(DM, PetscInt, DM *, VecScatter **, VecScatter **, VecScatter **);
1367c3cd84eSPatrick Sanan PETSC_INTERN PetscErrorCode DMGetCompatibility_DA(DM, DM, PetscBool *, PetscBool *);
1379a42bb27SBarry Smith 
138d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLoad_DA(DM da, PetscViewer viewer)
139d71ae5a4SJacob Faibussowitsch {
140060da220SMatthew G. Knepley   PetscInt        dim, m, n, p, dof, swidth;
141b859378eSBarry Smith   DMDAStencilType stencil;
142bff4a2f0SMatthew G. Knepley   DMBoundaryType  bx, by, bz;
143bc2bf880SBarry Smith   PetscBool       coors;
144bc2bf880SBarry Smith   DM              dac;
145bc2bf880SBarry Smith   Vec             c;
146b859378eSBarry Smith 
147b859378eSBarry Smith   PetscFunctionBegin;
1489566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &dim, 1, NULL, PETSC_INT));
1499566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &m, 1, NULL, PETSC_INT));
1509566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &n, 1, NULL, PETSC_INT));
1519566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &p, 1, NULL, PETSC_INT));
1529566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &dof, 1, NULL, PETSC_INT));
1539566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &swidth, 1, NULL, PETSC_INT));
1549566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &bx, 1, NULL, PETSC_ENUM));
1559566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &by, 1, NULL, PETSC_ENUM));
1569566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &bz, 1, NULL, PETSC_ENUM));
1579566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &stencil, 1, NULL, PETSC_ENUM));
158b859378eSBarry Smith 
1599566063dSJacob Faibussowitsch   PetscCall(DMSetDimension(da, dim));
1609566063dSJacob Faibussowitsch   PetscCall(DMDASetSizes(da, m, n, p));
1619566063dSJacob Faibussowitsch   PetscCall(DMDASetBoundaryType(da, bx, by, bz));
1629566063dSJacob Faibussowitsch   PetscCall(DMDASetDof(da, dof));
1639566063dSJacob Faibussowitsch   PetscCall(DMDASetStencilType(da, stencil));
1649566063dSJacob Faibussowitsch   PetscCall(DMDASetStencilWidth(da, swidth));
1659566063dSJacob Faibussowitsch   PetscCall(DMSetUp(da));
1669566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &coors, 1, NULL, PETSC_ENUM));
167bc2bf880SBarry Smith   if (coors) {
1689566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDM(da, &dac));
1699566063dSJacob Faibussowitsch     PetscCall(DMCreateGlobalVector(dac, &c));
1709566063dSJacob Faibussowitsch     PetscCall(VecLoad(c, viewer));
1719566063dSJacob Faibussowitsch     PetscCall(DMSetCoordinates(da, c));
1729566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&c));
173bc2bf880SBarry Smith   }
174b859378eSBarry Smith   PetscFunctionReturn(0);
175b859378eSBarry Smith }
176b859378eSBarry Smith 
177d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM_DA(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
178d71ae5a4SJacob Faibussowitsch {
179d724dfffSBarry Smith   DM_DA *da = (DM_DA *)dm->data;
180d724dfffSBarry Smith 
181d724dfffSBarry Smith   PetscFunctionBegin;
182d724dfffSBarry Smith   if (subdm) {
183c38c1269SMatthew G. Knepley     PetscSF sf;
184c38c1269SMatthew G. Knepley     Vec     coords;
185c38c1269SMatthew G. Knepley     void   *ctx;
186c38c1269SMatthew G. Knepley     /* Cannot use DMClone since the dof stuff is mixed in. Ugh
1879566063dSJacob Faibussowitsch     PetscCall(DMClone(dm, subdm)); */
1889566063dSJacob Faibussowitsch     PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), subdm));
1899566063dSJacob Faibussowitsch     PetscCall(DMGetPointSF(dm, &sf));
1909566063dSJacob Faibussowitsch     PetscCall(DMSetPointSF(*subdm, sf));
1919566063dSJacob Faibussowitsch     PetscCall(DMGetApplicationContext(dm, &ctx));
1929566063dSJacob Faibussowitsch     PetscCall(DMSetApplicationContext(*subdm, ctx));
1939566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinatesLocal(dm, &coords));
194c38c1269SMatthew G. Knepley     if (coords) {
1959566063dSJacob Faibussowitsch       PetscCall(DMSetCoordinatesLocal(*subdm, coords));
196c38c1269SMatthew G. Knepley     } else {
1979566063dSJacob Faibussowitsch       PetscCall(DMGetCoordinates(dm, &coords));
1989566063dSJacob Faibussowitsch       if (coords) PetscCall(DMSetCoordinates(*subdm, coords));
199c38c1269SMatthew G. Knepley     }
200c38c1269SMatthew G. Knepley 
2019566063dSJacob Faibussowitsch     PetscCall(DMSetType(*subdm, DMDA));
2029566063dSJacob Faibussowitsch     PetscCall(DMSetDimension(*subdm, dm->dim));
2039566063dSJacob Faibussowitsch     PetscCall(DMDASetSizes(*subdm, da->M, da->N, da->P));
2049566063dSJacob Faibussowitsch     PetscCall(DMDASetNumProcs(*subdm, da->m, da->n, da->p));
2059566063dSJacob Faibussowitsch     PetscCall(DMDASetBoundaryType(*subdm, da->bx, da->by, da->bz));
2069566063dSJacob Faibussowitsch     PetscCall(DMDASetDof(*subdm, numFields));
2079566063dSJacob Faibussowitsch     PetscCall(DMDASetStencilType(*subdm, da->stencil_type));
2089566063dSJacob Faibussowitsch     PetscCall(DMDASetStencilWidth(*subdm, da->s));
2099566063dSJacob Faibussowitsch     PetscCall(DMDASetOwnershipRanges(*subdm, da->lx, da->ly, da->lz));
210d724dfffSBarry Smith   }
211d724dfffSBarry Smith   if (is) {
212d724dfffSBarry Smith     PetscInt *indices, cnt = 0, dof = da->w, i, j;
21338221697SMatthew G. Knepley 
2149566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(da->Nlocal * numFields / dof, &indices));
21538221697SMatthew G. Knepley     for (i = da->base / dof; i < (da->base + da->Nlocal) / dof; ++i) {
216ad540459SPierre Jolivet       for (j = 0; j < numFields; ++j) indices[cnt++] = dof * i + fields[j];
217d724dfffSBarry Smith     }
21863a3b9bcSJacob Faibussowitsch     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);
2199566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), cnt, indices, PETSC_OWN_POINTER, is));
220d724dfffSBarry Smith   }
221d724dfffSBarry Smith   PetscFunctionReturn(0);
222d724dfffSBarry Smith }
223d724dfffSBarry Smith 
224d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldDecomposition_DA(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
225d71ae5a4SJacob Faibussowitsch {
2261c3fb106SBarry Smith   PetscInt i;
2271c3fb106SBarry Smith   DM_DA   *dd  = (DM_DA *)dm->data;
2281c3fb106SBarry Smith   PetscInt dof = dd->w;
2291c3fb106SBarry Smith 
2301c3fb106SBarry Smith   PetscFunctionBegin;
231731c8d9eSDmitry Karpeev   if (len) *len = dof;
2321c3fb106SBarry Smith   if (islist) {
2331c3fb106SBarry Smith     Vec      v;
2341c3fb106SBarry Smith     PetscInt rstart, n;
2351c3fb106SBarry Smith 
2369566063dSJacob Faibussowitsch     PetscCall(DMGetGlobalVector(dm, &v));
2379566063dSJacob Faibussowitsch     PetscCall(VecGetOwnershipRange(v, &rstart, NULL));
2389566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v, &n));
2399566063dSJacob Faibussowitsch     PetscCall(DMRestoreGlobalVector(dm, &v));
2409566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(dof, islist));
24148a46eb9SPierre Jolivet     for (i = 0; i < dof; i++) PetscCall(ISCreateStride(PetscObjectComm((PetscObject)dm), n / dof, rstart + i, dof, &(*islist)[i]));
2421c3fb106SBarry Smith   }
2431c3fb106SBarry Smith   if (namelist) {
2449566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(dof, namelist));
2451c3fb106SBarry Smith     if (dd->fieldname) {
24648a46eb9SPierre Jolivet       for (i = 0; i < dof; i++) PetscCall(PetscStrallocpy(dd->fieldname[i], &(*namelist)[i]));
2471c3fb106SBarry Smith     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Currently DMDA must have fieldnames");
2481c3fb106SBarry Smith   }
2491c3fb106SBarry Smith   if (dmlist) {
2501c3fb106SBarry Smith     DM da;
2511c3fb106SBarry Smith 
2529566063dSJacob Faibussowitsch     PetscCall(DMDACreate(PetscObjectComm((PetscObject)dm), &da));
2539566063dSJacob Faibussowitsch     PetscCall(DMSetDimension(da, dm->dim));
2549566063dSJacob Faibussowitsch     PetscCall(DMDASetSizes(da, dd->M, dd->N, dd->P));
2559566063dSJacob Faibussowitsch     PetscCall(DMDASetNumProcs(da, dd->m, dd->n, dd->p));
2569566063dSJacob Faibussowitsch     PetscCall(DMDASetBoundaryType(da, dd->bx, dd->by, dd->bz));
2579566063dSJacob Faibussowitsch     PetscCall(DMDASetDof(da, 1));
2589566063dSJacob Faibussowitsch     PetscCall(DMDASetStencilType(da, dd->stencil_type));
2599566063dSJacob Faibussowitsch     PetscCall(DMDASetStencilWidth(da, dd->s));
2609566063dSJacob Faibussowitsch     PetscCall(DMSetUp(da));
2619566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(dof, dmlist));
2629566063dSJacob Faibussowitsch     for (i = 0; i < dof - 1; i++) PetscCall(PetscObjectReference((PetscObject)da));
2631c3fb106SBarry Smith     for (i = 0; i < dof; i++) (*dmlist)[i] = da;
2641c3fb106SBarry Smith   }
2651c3fb106SBarry Smith   PetscFunctionReturn(0);
2661c3fb106SBarry Smith }
2671c3fb106SBarry Smith 
268d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClone_DA(DM dm, DM *newdm)
269d71ae5a4SJacob Faibussowitsch {
27038221697SMatthew G. Knepley   DM_DA *da = (DM_DA *)dm->data;
27138221697SMatthew G. Knepley 
27238221697SMatthew G. Knepley   PetscFunctionBegin;
2739566063dSJacob Faibussowitsch   PetscCall(DMSetType(*newdm, DMDA));
2749566063dSJacob Faibussowitsch   PetscCall(DMSetDimension(*newdm, dm->dim));
2759566063dSJacob Faibussowitsch   PetscCall(DMDASetSizes(*newdm, da->M, da->N, da->P));
2769566063dSJacob Faibussowitsch   PetscCall(DMDASetNumProcs(*newdm, da->m, da->n, da->p));
2779566063dSJacob Faibussowitsch   PetscCall(DMDASetBoundaryType(*newdm, da->bx, da->by, da->bz));
2789566063dSJacob Faibussowitsch   PetscCall(DMDASetDof(*newdm, da->w));
2799566063dSJacob Faibussowitsch   PetscCall(DMDASetStencilType(*newdm, da->stencil_type));
2809566063dSJacob Faibussowitsch   PetscCall(DMDASetStencilWidth(*newdm, da->s));
2819566063dSJacob Faibussowitsch   PetscCall(DMDASetOwnershipRanges(*newdm, da->lx, da->ly, da->lz));
2829566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*newdm));
28338221697SMatthew G. Knepley   PetscFunctionReturn(0);
28438221697SMatthew G. Knepley }
28538221697SMatthew G. Knepley 
286d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMHasCreateInjection_DA(DM dm, PetscBool *flg)
287d71ae5a4SJacob Faibussowitsch {
2884a7a4c06SLawrence Mitchell   DM_DA *da = (DM_DA *)dm->data;
2894a7a4c06SLawrence Mitchell 
2904a7a4c06SLawrence Mitchell   PetscFunctionBegin;
2914a7a4c06SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
292534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg, 2);
293131f56ebSLawrence Mitchell   *flg = da->interptype == DMDA_Q1 ? PETSC_TRUE : PETSC_FALSE;
2944a7a4c06SLawrence Mitchell   PetscFunctionReturn(0);
2954a7a4c06SLawrence Mitchell }
2964a7a4c06SLawrence Mitchell 
297d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMGetDimPoints_DA(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd)
298d71ae5a4SJacob Faibussowitsch {
299793f3fe5SMatthew G. Knepley   PetscFunctionBegin;
3009566063dSJacob Faibussowitsch   PetscCall(DMDAGetDepthStratum(dm, dim, pStart, pEnd));
301793f3fe5SMatthew G. Knepley   PetscFunctionReturn(0);
302793f3fe5SMatthew G. Knepley }
303793f3fe5SMatthew G. Knepley 
304d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMGetNeighbors_DA(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[])
305d71ae5a4SJacob Faibussowitsch {
306502a2867SDave May   PetscInt        dim;
307502a2867SDave May   DMDAStencilType st;
308502a2867SDave May 
309502a2867SDave May   PetscFunctionBegin;
3109566063dSJacob Faibussowitsch   PetscCall(DMDAGetNeighbors(dm, ranks));
3119566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(dm, &dim, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &st));
312502a2867SDave May 
313502a2867SDave May   switch (dim) {
314502a2867SDave May   case 1:
315502a2867SDave May     *nranks = 3;
316ad540459SPierre Jolivet     /* if (st == DMDA_STENCIL_STAR) *nranks = 3; */
317502a2867SDave May     break;
318502a2867SDave May   case 2:
319502a2867SDave May     *nranks = 9;
320ad540459SPierre Jolivet     /* if (st == DMDA_STENCIL_STAR) *nranks = 5; */
321502a2867SDave May     break;
322502a2867SDave May   case 3:
323502a2867SDave May     *nranks = 27;
324ad540459SPierre Jolivet     /* if (st == DMDA_STENCIL_STAR) *nranks = 7; */
325502a2867SDave May     break;
326d71ae5a4SJacob Faibussowitsch   default:
327d71ae5a4SJacob Faibussowitsch     break;
328502a2867SDave May   }
329502a2867SDave May   PetscFunctionReturn(0);
330502a2867SDave May }
331502a2867SDave May 
3323efe6655SBarry Smith /*MC
333*dce8aebaSBarry Smith    DMDA = "da" - A `DM` object that is used to manage data for a structured grid in 1, 2, or 3 dimensions.
3343efe6655SBarry Smith          In the global representation of the vector each process stores a non-overlapping rectangular (or slab in 3d) portion of the grid points.
3353efe6655SBarry Smith          In the local representation these rectangular regions (slabs) are extended in all directions by a stencil width.
3363efe6655SBarry Smith 
3373efe6655SBarry Smith          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*dce8aebaSBarry Smith          vertex centered; see the documentation for `DMSTAG`, a similar DM implementation which supports these staggered grids.
3393efe6655SBarry Smith 
3403efe6655SBarry Smith   Level: intermediate
3413efe6655SBarry Smith 
342db781477SPatrick Sanan .seealso: `DMType`, `DMCOMPOSITE`, `DMSTAG`, `DMDACreate()`, `DMCreate()`, `DMSetType()`
3433efe6655SBarry Smith M*/
3443efe6655SBarry Smith 
34505264a50SDave May extern PetscErrorCode       DMLocatePoints_DA_Regular(DM, Vec, DMPointLocationType, PetscSF);
3468135c375SStefano Zampini PETSC_INTERN PetscErrorCode DMSetUpGLVisViewer_DMDA(PetscObject, PetscViewer);
3471c3fb106SBarry Smith 
348d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreate_DA(DM da)
349d71ae5a4SJacob Faibussowitsch {
35047c6ae99SBarry Smith   DM_DA *dd;
35147c6ae99SBarry Smith 
35247c6ae99SBarry Smith   PetscFunctionBegin;
353a4121054SBarry Smith   PetscValidPointer(da, 1);
3544dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&dd));
355a4121054SBarry Smith   da->data = dd;
35647c6ae99SBarry Smith 
357c73cfb54SMatthew G. Knepley   da->dim        = -1;
358aa219208SBarry Smith   dd->interptype = DMDA_Q1;
35947c6ae99SBarry Smith   dd->refine_x   = 2;
36047c6ae99SBarry Smith   dd->refine_y   = 2;
36147c6ae99SBarry Smith   dd->refine_z   = 2;
36281c108dcSJed Brown   dd->coarsen_x  = 2;
36381c108dcSJed Brown   dd->coarsen_y  = 2;
36481c108dcSJed Brown   dd->coarsen_z  = 2;
3650298fd71SBarry Smith   dd->fieldname  = NULL;
36647c6ae99SBarry Smith   dd->nlocal     = -1;
36747c6ae99SBarry Smith   dd->Nlocal     = -1;
36847c6ae99SBarry Smith   dd->M          = -1;
36947c6ae99SBarry Smith   dd->N          = -1;
37047c6ae99SBarry Smith   dd->P          = -1;
37147c6ae99SBarry Smith   dd->m          = -1;
37247c6ae99SBarry Smith   dd->n          = -1;
37347c6ae99SBarry Smith   dd->p          = -1;
37447c6ae99SBarry Smith   dd->w          = -1;
37547c6ae99SBarry Smith   dd->s          = -1;
3768865f1eaSKarl Rupp 
3779371c9d4SSatish Balay   dd->xs = -1;
3789371c9d4SSatish Balay   dd->xe = -1;
3799371c9d4SSatish Balay   dd->ys = -1;
3809371c9d4SSatish Balay   dd->ye = -1;
3819371c9d4SSatish Balay   dd->zs = -1;
3829371c9d4SSatish Balay   dd->ze = -1;
3839371c9d4SSatish Balay   dd->Xs = -1;
3849371c9d4SSatish Balay   dd->Xe = -1;
3859371c9d4SSatish Balay   dd->Ys = -1;
3869371c9d4SSatish Balay   dd->Ye = -1;
3879371c9d4SSatish Balay   dd->Zs = -1;
3889371c9d4SSatish Balay   dd->Ze = -1;
38947c6ae99SBarry Smith 
3903e7870d2SPeter Brune   dd->Nsub = 1;
3917ddda789SPeter Brune   dd->xol  = 0;
3927ddda789SPeter Brune   dd->yol  = 0;
3937ddda789SPeter Brune   dd->zol  = 0;
394d886c4f4SPeter Brune   dd->xo   = 0;
395d886c4f4SPeter Brune   dd->yo   = 0;
396d886c4f4SPeter Brune   dd->zo   = 0;
397e30e807fSPeter Brune   dd->Mo   = -1;
398e30e807fSPeter Brune   dd->No   = -1;
399e30e807fSPeter Brune   dd->Po   = -1;
40088661749SPeter Brune 
4010298fd71SBarry Smith   dd->gtol = NULL;
4020298fd71SBarry Smith   dd->ltol = NULL;
4030298fd71SBarry Smith   dd->ao   = NULL;
4049db3d8bcSStefano Zampini   PetscStrallocpy(AOBASIC, (char **)&dd->aotype);
40547c6ae99SBarry Smith   dd->base         = -1;
406bff4a2f0SMatthew G. Knepley   dd->bx           = DM_BOUNDARY_NONE;
407bff4a2f0SMatthew G. Knepley   dd->by           = DM_BOUNDARY_NONE;
408bff4a2f0SMatthew G. Knepley   dd->bz           = DM_BOUNDARY_NONE;
409aa219208SBarry Smith   dd->stencil_type = DMDA_STENCIL_BOX;
410aa219208SBarry Smith   dd->interptype   = DMDA_Q1;
4110298fd71SBarry Smith   dd->lx           = NULL;
4120298fd71SBarry Smith   dd->ly           = NULL;
4130298fd71SBarry Smith   dd->lz           = NULL;
41447c6ae99SBarry Smith 
415454e267fSLisandro Dalcin   dd->elementtype = DMDA_ELEMENT_Q1;
416454e267fSLisandro Dalcin 
417a4121054SBarry Smith   da->ops->globaltolocalbegin        = DMGlobalToLocalBegin_DA;
418a4121054SBarry Smith   da->ops->globaltolocalend          = DMGlobalToLocalEnd_DA;
419a4121054SBarry Smith   da->ops->localtoglobalbegin        = DMLocalToGlobalBegin_DA;
420a4121054SBarry Smith   da->ops->localtoglobalend          = DMLocalToGlobalEnd_DA;
421d78e899eSRichard Tran Mills   da->ops->localtolocalbegin         = DMLocalToLocalBegin_DA;
422d78e899eSRichard Tran Mills   da->ops->localtolocalend           = DMLocalToLocalEnd_DA;
423a4121054SBarry Smith   da->ops->createglobalvector        = DMCreateGlobalVector_DA;
424a4121054SBarry Smith   da->ops->createlocalvector         = DMCreateLocalVector_DA;
42525296bd5SBarry Smith   da->ops->createinterpolation       = DMCreateInterpolation_DA;
426e727c939SJed Brown   da->ops->getcoloring               = DMCreateColoring_DA;
42725296bd5SBarry Smith   da->ops->creatematrix              = DMCreateMatrix_DA;
428a4121054SBarry Smith   da->ops->refine                    = DMRefine_DA;
429a4121054SBarry Smith   da->ops->coarsen                   = DMCoarsen_DA;
430a4121054SBarry Smith   da->ops->refinehierarchy           = DMRefineHierarchy_DA;
431a4121054SBarry Smith   da->ops->coarsenhierarchy          = DMCoarsenHierarchy_DA;
4325a84ad33SLisandro Dalcin   da->ops->createinjection           = DMCreateInjection_DA;
4334a7a4c06SLawrence Mitchell   da->ops->hascreateinjection        = DMHasCreateInjection_DA;
434a4121054SBarry Smith   da->ops->destroy                   = DMDestroy_DA;
435ea78f98cSLisandro Dalcin   da->ops->view                      = NULL;
436a4121054SBarry Smith   da->ops->setfromoptions            = DMSetFromOptions_DA;
437a4121054SBarry Smith   da->ops->setup                     = DMSetUp_DA;
43838221697SMatthew G. Knepley   da->ops->clone                     = DMClone_DA;
439b859378eSBarry Smith   da->ops->load                      = DMLoad_DA;
4406636e97aSMatthew G Knepley   da->ops->createcoordinatedm        = DMCreateCoordinateDM_DA;
441d724dfffSBarry Smith   da->ops->createsubdm               = DMCreateSubDM_DA;
44216621825SDmitry Karpeev   da->ops->createfielddecomposition  = DMCreateFieldDecomposition_DA;
443e30e807fSPeter Brune   da->ops->createdomaindecomposition = DMCreateDomainDecomposition_DA;
444e30e807fSPeter Brune   da->ops->createddscatters          = DMCreateDomainDecompositionScatters_DA;
445793f3fe5SMatthew G. Knepley   da->ops->getdimpoints              = DMGetDimPoints_DA;
446502a2867SDave May   da->ops->getneighbors              = DMGetNeighbors_DA;
44705264a50SDave May   da->ops->locatepoints              = DMLocatePoints_DA_Regular;
4487c3cd84eSPatrick Sanan   da->ops->getcompatibility          = DMGetCompatibility_DA;
4499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)da, "DMSetUpGLVisViewer_C", DMSetUpGLVisViewer_DMDA));
450a4121054SBarry Smith   PetscFunctionReturn(0);
451a4121054SBarry Smith }
45247c6ae99SBarry Smith 
453a4121054SBarry Smith /*@
454a4121054SBarry Smith   DMDACreate - Creates a DMDA object.
455a4121054SBarry Smith 
4565edebc4bSPatrick Sanan   Collective
457a4121054SBarry Smith 
458a4121054SBarry Smith   Input Parameter:
459a4121054SBarry Smith . comm - The communicator for the DMDA object
460a4121054SBarry Smith 
461a4121054SBarry Smith   Output Parameter:
462a4121054SBarry Smith . da  - The DMDA object
463a4121054SBarry Smith 
464e0f5d30fSBarry Smith   Level: advanced
465e0f5d30fSBarry Smith 
4665edebc4bSPatrick Sanan   Developers Note:
4675edebc4bSPatrick Sanan   Since there exists DMDACreate1/2/3d() should this routine even exist?
468a4121054SBarry Smith 
469db781477SPatrick Sanan .seealso: `DMDASetSizes()`, `DMClone()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`
470a4121054SBarry Smith @*/
471d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDACreate(MPI_Comm comm, DM *da)
472d71ae5a4SJacob Faibussowitsch {
473a4121054SBarry Smith   PetscFunctionBegin;
474a4121054SBarry Smith   PetscValidPointer(da, 2);
4759566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, da));
4769566063dSJacob Faibussowitsch   PetscCall(DMSetType(*da, DMDA));
47747c6ae99SBarry Smith   PetscFunctionReturn(0);
47847c6ae99SBarry Smith }
479