xref: /petsc/src/dm/impls/da/dagetelem.c (revision 20f4b53cbb5e9bd9ef12b76a8697d60d197cda17)
1454e267fSLisandro Dalcin 
2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I  "petscdmda.h"   I*/
3454e267fSLisandro Dalcin 
4d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDAGetElements_1D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
5d71ae5a4SJacob Faibussowitsch {
6454e267fSLisandro Dalcin   DM_DA   *da = (DM_DA *)dm->data;
7454e267fSLisandro Dalcin   PetscInt i, xs, xe, Xs, Xe;
8454e267fSLisandro Dalcin   PetscInt cnt = 0;
95fd66863SKarl Rupp 
10454e267fSLisandro Dalcin   PetscFunctionBegin;
11454e267fSLisandro Dalcin   if (!da->e) {
12f951a8fcSStefano Zampini     PetscInt corners[2];
13f951a8fcSStefano Zampini 
147a8be351SBarry Smith     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");
159566063dSJacob Faibussowitsch     PetscCall(DMDAGetCorners(dm, &xs, NULL, NULL, &xe, NULL, NULL));
169566063dSJacob Faibussowitsch     PetscCall(DMDAGetGhostCorners(dm, &Xs, NULL, NULL, &Xe, NULL, NULL));
179371c9d4SSatish Balay     xe += xs;
189371c9d4SSatish Balay     Xe += Xs;
199371c9d4SSatish Balay     if (xs != Xs) xs -= 1;
20454e267fSLisandro Dalcin     da->ne = 1 * (xe - xs - 1);
219566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1 + 2 * da->ne, &da->e));
22454e267fSLisandro Dalcin     for (i = xs; i < xe - 1; i++) {
23454e267fSLisandro Dalcin       da->e[cnt++] = (i - Xs);
24454e267fSLisandro Dalcin       da->e[cnt++] = (i - Xs + 1);
25454e267fSLisandro Dalcin     }
26cfbed8a3SStefano Zampini     da->nen = 2;
27cfbed8a3SStefano Zampini 
28f951a8fcSStefano Zampini     corners[0] = (xs - Xs);
29f951a8fcSStefano Zampini     corners[1] = (xe - 1 - Xs);
309566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 2, corners, PETSC_COPY_VALUES, &da->ecorners));
31454e267fSLisandro Dalcin   }
32454e267fSLisandro Dalcin   *nel = da->ne;
33cfbed8a3SStefano Zampini   *nen = da->nen;
34454e267fSLisandro Dalcin   *e   = da->e;
353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
36454e267fSLisandro Dalcin }
37454e267fSLisandro Dalcin 
38d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDAGetElements_2D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
39d71ae5a4SJacob Faibussowitsch {
40454e267fSLisandro Dalcin   DM_DA   *da = (DM_DA *)dm->data;
41454e267fSLisandro Dalcin   PetscInt i, xs, xe, Xs, Xe;
42454e267fSLisandro Dalcin   PetscInt j, ys, ye, Ys, Ye;
43cfbed8a3SStefano Zampini   PetscInt cnt = 0, cell[4], ns = 2;
449371c9d4SSatish Balay   PetscInt c, split[] = {0, 1, 3, 2, 3, 1};
455fd66863SKarl Rupp 
46454e267fSLisandro Dalcin   PetscFunctionBegin;
47454e267fSLisandro Dalcin   if (!da->e) {
48cfbed8a3SStefano Zampini     PetscInt corners[4], nn = 0;
49f951a8fcSStefano Zampini 
507a8be351SBarry Smith     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");
51cfbed8a3SStefano Zampini 
52cfbed8a3SStefano Zampini     switch (da->elementtype) {
53d71ae5a4SJacob Faibussowitsch     case DMDA_ELEMENT_Q1:
54d71ae5a4SJacob Faibussowitsch       da->nen = 4;
55d71ae5a4SJacob Faibussowitsch       break;
56d71ae5a4SJacob Faibussowitsch     case DMDA_ELEMENT_P1:
57d71ae5a4SJacob Faibussowitsch       da->nen = 3;
58d71ae5a4SJacob Faibussowitsch       break;
59d71ae5a4SJacob Faibussowitsch     default:
60d71ae5a4SJacob Faibussowitsch       SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown element type %d", da->elementtype);
61cfbed8a3SStefano Zampini     }
62cfbed8a3SStefano Zampini     nn = da->nen;
63cfbed8a3SStefano Zampini 
64ad540459SPierre Jolivet     if (da->elementtype == DMDA_ELEMENT_P1) ns = 2;
65ad540459SPierre Jolivet     if (da->elementtype == DMDA_ELEMENT_Q1) ns = 1;
669566063dSJacob Faibussowitsch     PetscCall(DMDAGetCorners(dm, &xs, &ys, NULL, &xe, &ye, NULL));
679566063dSJacob Faibussowitsch     PetscCall(DMDAGetGhostCorners(dm, &Xs, &Ys, NULL, &Xe, &Ye, NULL));
689371c9d4SSatish Balay     xe += xs;
699371c9d4SSatish Balay     Xe += Xs;
709371c9d4SSatish Balay     if (xs != Xs) xs -= 1;
719371c9d4SSatish Balay     ye += ys;
729371c9d4SSatish Balay     Ye += Ys;
739371c9d4SSatish Balay     if (ys != Ys) ys -= 1;
74454e267fSLisandro Dalcin     da->ne = ns * (xe - xs - 1) * (ye - ys - 1);
759566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1 + nn * da->ne, &da->e));
76454e267fSLisandro Dalcin     for (j = ys; j < ye - 1; j++) {
77454e267fSLisandro Dalcin       for (i = xs; i < xe - 1; i++) {
78454e267fSLisandro Dalcin         cell[0] = (i - Xs) + (j - Ys) * (Xe - Xs);
79454e267fSLisandro Dalcin         cell[1] = (i - Xs + 1) + (j - Ys) * (Xe - Xs);
80454e267fSLisandro Dalcin         cell[2] = (i - Xs + 1) + (j - Ys + 1) * (Xe - Xs);
81454e267fSLisandro Dalcin         cell[3] = (i - Xs) + (j - Ys + 1) * (Xe - Xs);
82454e267fSLisandro Dalcin         if (da->elementtype == DMDA_ELEMENT_P1) {
838865f1eaSKarl Rupp           for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[split[c]];
84454e267fSLisandro Dalcin         }
85454e267fSLisandro Dalcin         if (da->elementtype == DMDA_ELEMENT_Q1) {
868865f1eaSKarl Rupp           for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[c];
87454e267fSLisandro Dalcin         }
88454e267fSLisandro Dalcin       }
89454e267fSLisandro Dalcin     }
90cfbed8a3SStefano Zampini 
91f951a8fcSStefano Zampini     corners[0] = (xs - Xs) + (ys - Ys) * (Xe - Xs);
92f951a8fcSStefano Zampini     corners[1] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs);
93f951a8fcSStefano Zampini     corners[2] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs);
94f951a8fcSStefano Zampini     corners[3] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs);
959566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 4, corners, PETSC_COPY_VALUES, &da->ecorners));
96454e267fSLisandro Dalcin   }
97454e267fSLisandro Dalcin   *nel = da->ne;
98cfbed8a3SStefano Zampini   *nen = da->nen;
99454e267fSLisandro Dalcin   *e   = da->e;
1003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
101454e267fSLisandro Dalcin }
102454e267fSLisandro Dalcin 
103d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDAGetElements_3D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
104d71ae5a4SJacob Faibussowitsch {
105454e267fSLisandro Dalcin   DM_DA   *da = (DM_DA *)dm->data;
106454e267fSLisandro Dalcin   PetscInt i, xs, xe, Xs, Xe;
107454e267fSLisandro Dalcin   PetscInt j, ys, ye, Ys, Ye;
108454e267fSLisandro Dalcin   PetscInt k, zs, ze, Zs, Ze;
109cfbed8a3SStefano Zampini   PetscInt cnt = 0, cell[8], ns = 6;
1109371c9d4SSatish Balay   PetscInt c, split[] = {0, 1, 3, 7, 0, 1, 7, 4, 1, 2, 3, 7, 1, 2, 7, 6, 1, 4, 5, 7, 1, 5, 6, 7};
1115fd66863SKarl Rupp 
112454e267fSLisandro Dalcin   PetscFunctionBegin;
113454e267fSLisandro Dalcin   if (!da->e) {
114cfbed8a3SStefano Zampini     PetscInt corners[8], nn = 0;
115f951a8fcSStefano Zampini 
1167a8be351SBarry Smith     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");
117cfbed8a3SStefano Zampini 
118cfbed8a3SStefano Zampini     switch (da->elementtype) {
119d71ae5a4SJacob Faibussowitsch     case DMDA_ELEMENT_Q1:
120d71ae5a4SJacob Faibussowitsch       da->nen = 8;
121d71ae5a4SJacob Faibussowitsch       break;
122d71ae5a4SJacob Faibussowitsch     case DMDA_ELEMENT_P1:
123d71ae5a4SJacob Faibussowitsch       da->nen = 4;
124d71ae5a4SJacob Faibussowitsch       break;
125d71ae5a4SJacob Faibussowitsch     default:
126d71ae5a4SJacob Faibussowitsch       SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown element type %d", da->elementtype);
127cfbed8a3SStefano Zampini     }
128cfbed8a3SStefano Zampini     nn = da->nen;
129cfbed8a3SStefano Zampini 
130ad540459SPierre Jolivet     if (da->elementtype == DMDA_ELEMENT_P1) ns = 6;
131ad540459SPierre Jolivet     if (da->elementtype == DMDA_ELEMENT_Q1) ns = 1;
1329566063dSJacob Faibussowitsch     PetscCall(DMDAGetCorners(dm, &xs, &ys, &zs, &xe, &ye, &ze));
1339566063dSJacob Faibussowitsch     PetscCall(DMDAGetGhostCorners(dm, &Xs, &Ys, &Zs, &Xe, &Ye, &Ze));
1349371c9d4SSatish Balay     xe += xs;
1359371c9d4SSatish Balay     Xe += Xs;
1369371c9d4SSatish Balay     if (xs != Xs) xs -= 1;
1379371c9d4SSatish Balay     ye += ys;
1389371c9d4SSatish Balay     Ye += Ys;
1399371c9d4SSatish Balay     if (ys != Ys) ys -= 1;
1409371c9d4SSatish Balay     ze += zs;
1419371c9d4SSatish Balay     Ze += Zs;
1429371c9d4SSatish Balay     if (zs != Zs) zs -= 1;
143454e267fSLisandro Dalcin     da->ne = ns * (xe - xs - 1) * (ye - ys - 1) * (ze - zs - 1);
1449566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1 + nn * da->ne, &da->e));
145454e267fSLisandro Dalcin     for (k = zs; k < ze - 1; k++) {
146454e267fSLisandro Dalcin       for (j = ys; j < ye - 1; j++) {
147454e267fSLisandro Dalcin         for (i = xs; i < xe - 1; i++) {
148454e267fSLisandro Dalcin           cell[0] = (i - Xs) + (j - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
1492da392ccSBarry Smith           cell[1] = (i + 1 - Xs) + (j - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
1502da392ccSBarry Smith           cell[2] = (i + 1 - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
1512da392ccSBarry Smith           cell[3] = (i - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
1522da392ccSBarry Smith           cell[4] = (i - Xs) + (j - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
1532da392ccSBarry Smith           cell[5] = (i + 1 - Xs) + (j - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
1542da392ccSBarry Smith           cell[6] = (i + 1 - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
1552da392ccSBarry Smith           cell[7] = (i - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
156454e267fSLisandro Dalcin           if (da->elementtype == DMDA_ELEMENT_P1) {
1578865f1eaSKarl Rupp             for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[split[c]];
158454e267fSLisandro Dalcin           }
159454e267fSLisandro Dalcin           if (da->elementtype == DMDA_ELEMENT_Q1) {
1608865f1eaSKarl Rupp             for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[c];
161454e267fSLisandro Dalcin           }
162454e267fSLisandro Dalcin         }
163454e267fSLisandro Dalcin       }
164454e267fSLisandro Dalcin     }
165cfbed8a3SStefano Zampini 
166f951a8fcSStefano Zampini     corners[0] = (xs - Xs) + (ys - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
167f951a8fcSStefano Zampini     corners[1] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
168f951a8fcSStefano Zampini     corners[2] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
169f951a8fcSStefano Zampini     corners[3] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
170f951a8fcSStefano Zampini     corners[4] = (xs - Xs) + (ys - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
171f951a8fcSStefano Zampini     corners[5] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
172f951a8fcSStefano Zampini     corners[6] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
173f951a8fcSStefano Zampini     corners[7] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
1749566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 8, corners, PETSC_COPY_VALUES, &da->ecorners));
175454e267fSLisandro Dalcin   }
176454e267fSLisandro Dalcin   *nel = da->ne;
177cfbed8a3SStefano Zampini   *nen = da->nen;
178454e267fSLisandro Dalcin   *e   = da->e;
1793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
180454e267fSLisandro Dalcin }
181454e267fSLisandro Dalcin 
182f5f57ec0SBarry Smith /*@
183d4a6ed37SStefano Zampini    DMDAGetElementsCorners - Returns the global (x,y,z) indices of the lower left
184dce8aebaSBarry Smith    corner of the non-overlapping decomposition identified by `DMDAGetElements()`
185d4a6ed37SStefano Zampini 
186d4a6ed37SStefano Zampini     Not Collective
187d4a6ed37SStefano Zampini 
188d4a6ed37SStefano Zampini    Input Parameter:
189dce8aebaSBarry Smith .     da - the `DMDA` object
190d4a6ed37SStefano Zampini 
191d4a6ed37SStefano Zampini    Output Parameters:
192d4a6ed37SStefano Zampini +     gx - the x index
193d4a6ed37SStefano Zampini .     gy - the y index
194d4a6ed37SStefano Zampini -     gz - the z index
195d4a6ed37SStefano Zampini 
196d4a6ed37SStefano Zampini    Level: intermediate
197d4a6ed37SStefano Zampini 
198dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`
199d4a6ed37SStefano Zampini @*/
200d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetElementsCorners(DM da, PetscInt *gx, PetscInt *gy, PetscInt *gz)
201d71ae5a4SJacob Faibussowitsch {
202d4a6ed37SStefano Zampini   PetscInt  xs, Xs;
203d4a6ed37SStefano Zampini   PetscInt  ys, Ys;
204d4a6ed37SStefano Zampini   PetscInt  zs, Zs;
205d4a6ed37SStefano Zampini   PetscBool isda;
206d4a6ed37SStefano Zampini 
207d4a6ed37SStefano Zampini   PetscFunctionBegin;
208a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
209d4a6ed37SStefano Zampini   if (gx) PetscValidIntPointer(gx, 2);
210d4a6ed37SStefano Zampini   if (gy) PetscValidIntPointer(gy, 3);
211d4a6ed37SStefano Zampini   if (gz) PetscValidIntPointer(gz, 4);
2129566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
2137a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
2149566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, NULL, NULL, NULL));
2159566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &Xs, &Ys, &Zs, NULL, NULL, NULL));
216d4a6ed37SStefano Zampini   if (xs != Xs) xs -= 1;
217d4a6ed37SStefano Zampini   if (ys != Ys) ys -= 1;
218d4a6ed37SStefano Zampini   if (zs != Zs) zs -= 1;
219d4a6ed37SStefano Zampini   if (gx) *gx = xs;
220d4a6ed37SStefano Zampini   if (gy) *gy = ys;
221d4a6ed37SStefano Zampini   if (gz) *gz = zs;
2223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
223d4a6ed37SStefano Zampini }
224d4a6ed37SStefano Zampini 
225d4a6ed37SStefano Zampini /*@
226dce8aebaSBarry Smith       DMDAGetElementsSizes - Gets the local number of elements per direction for the non-overlapping decomposition identified by `DMDAGetElements()`
227d4a6ed37SStefano Zampini 
228d4a6ed37SStefano Zampini     Not Collective
229d4a6ed37SStefano Zampini 
230d4a6ed37SStefano Zampini    Input Parameter:
231dce8aebaSBarry Smith .     da - the `DMDA` object
232d4a6ed37SStefano Zampini 
233d4a6ed37SStefano Zampini    Output Parameters:
234d4a6ed37SStefano Zampini +     mx - number of local elements in x-direction
235d4a6ed37SStefano Zampini .     my - number of local elements in y-direction
236d4a6ed37SStefano Zampini -     mz - number of local elements in z-direction
237d4a6ed37SStefano Zampini 
238d4a6ed37SStefano Zampini    Level: intermediate
239d4a6ed37SStefano Zampini 
240dce8aebaSBarry Smith    Note:
241dce8aebaSBarry Smith     It returns the same number of elements, irrespective of the `DMDAElementType`
242d4a6ed37SStefano Zampini 
243dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements`
244d4a6ed37SStefano Zampini @*/
245d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetElementsSizes(DM da, PetscInt *mx, PetscInt *my, PetscInt *mz)
246d71ae5a4SJacob Faibussowitsch {
247d4a6ed37SStefano Zampini   PetscInt  xs, xe, Xs;
248d4a6ed37SStefano Zampini   PetscInt  ys, ye, Ys;
249d4a6ed37SStefano Zampini   PetscInt  zs, ze, Zs;
250d4a6ed37SStefano Zampini   PetscInt  dim;
251d4a6ed37SStefano Zampini   PetscBool isda;
252d4a6ed37SStefano Zampini 
253d4a6ed37SStefano Zampini   PetscFunctionBegin;
254a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
255d4a6ed37SStefano Zampini   if (mx) PetscValidIntPointer(mx, 2);
256d4a6ed37SStefano Zampini   if (my) PetscValidIntPointer(my, 3);
257d4a6ed37SStefano Zampini   if (mz) PetscValidIntPointer(mz, 4);
2589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
2597a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
2609566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xe, &ye, &ze));
2619566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &Xs, &Ys, &Zs, NULL, NULL, NULL));
2629371c9d4SSatish Balay   xe += xs;
2639371c9d4SSatish Balay   if (xs != Xs) xs -= 1;
2649371c9d4SSatish Balay   ye += ys;
2659371c9d4SSatish Balay   if (ys != Ys) ys -= 1;
2669371c9d4SSatish Balay   ze += zs;
2679371c9d4SSatish Balay   if (zs != Zs) zs -= 1;
268d4a6ed37SStefano Zampini   if (mx) *mx = 0;
269d4a6ed37SStefano Zampini   if (my) *my = 0;
270d4a6ed37SStefano Zampini   if (mz) *mz = 0;
2719566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(da, &dim));
272d4a6ed37SStefano Zampini   switch (dim) {
273d4a6ed37SStefano Zampini   case 3:
274f4d061e9SPierre Jolivet     if (mz) *mz = ze - zs - 1; /* fall through */
275d4a6ed37SStefano Zampini   case 2:
276f4d061e9SPierre Jolivet     if (my) *my = ye - ys - 1; /* fall through */
277d4a6ed37SStefano Zampini   case 1:
278d4a6ed37SStefano Zampini     if (mx) *mx = xe - xs - 1;
279d4a6ed37SStefano Zampini     break;
280d4a6ed37SStefano Zampini   }
2813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
282d4a6ed37SStefano Zampini }
283d4a6ed37SStefano Zampini 
284d4a6ed37SStefano Zampini /*@
285dce8aebaSBarry Smith       DMDASetElementType - Sets the element type to be returned by `DMDAGetElements()`
2862dde6fd4SLisandro Dalcin 
2872dde6fd4SLisandro Dalcin     Not Collective
2882dde6fd4SLisandro Dalcin 
2892dde6fd4SLisandro Dalcin    Input Parameter:
290dce8aebaSBarry Smith .     da - the `DMDA` object
2912dde6fd4SLisandro Dalcin 
2922dde6fd4SLisandro Dalcin    Output Parameters:
293dce8aebaSBarry Smith .     etype - the element type, currently either `DMDA_ELEMENT_P1` or `DMDA_ELEMENT_Q1`
2942dde6fd4SLisandro Dalcin 
2952dde6fd4SLisandro Dalcin    Level: intermediate
2962dde6fd4SLisandro Dalcin 
297dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAElementType`, `DMDAGetElementType()`, `DMDAGetElements()`, `DMDARestoreElements()`
2982dde6fd4SLisandro Dalcin @*/
299d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetElementType(DM da, DMDAElementType etype)
300d71ae5a4SJacob Faibussowitsch {
3012dde6fd4SLisandro Dalcin   DM_DA    *dd = (DM_DA *)da->data;
302f951a8fcSStefano Zampini   PetscBool isda;
3032dde6fd4SLisandro Dalcin 
3042dde6fd4SLisandro Dalcin   PetscFunctionBegin;
305a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
3062dde6fd4SLisandro Dalcin   PetscValidLogicalCollectiveEnum(da, etype, 2);
3079566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
3083ba16761SJacob Faibussowitsch   if (!isda) PetscFunctionReturn(PETSC_SUCCESS);
3092dde6fd4SLisandro Dalcin   if (dd->elementtype != etype) {
3109566063dSJacob Faibussowitsch     PetscCall(PetscFree(dd->e));
3119566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&dd->ecorners));
3128865f1eaSKarl Rupp 
3132dde6fd4SLisandro Dalcin     dd->elementtype = etype;
3142dde6fd4SLisandro Dalcin     dd->ne          = 0;
315cfbed8a3SStefano Zampini     dd->nen         = 0;
3160298fd71SBarry Smith     dd->e           = NULL;
3172dde6fd4SLisandro Dalcin   }
3183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3192dde6fd4SLisandro Dalcin }
3202dde6fd4SLisandro Dalcin 
321f5f57ec0SBarry Smith /*@
322dce8aebaSBarry Smith       DMDAGetElementType - Gets the element type to be returned by `DMDAGetElements()`
3232dde6fd4SLisandro Dalcin 
3242dde6fd4SLisandro Dalcin     Not Collective
3252dde6fd4SLisandro Dalcin 
3262dde6fd4SLisandro Dalcin    Input Parameter:
327dce8aebaSBarry Smith .     da - the `DMDA` object
3282dde6fd4SLisandro Dalcin 
3292dde6fd4SLisandro Dalcin    Output Parameters:
330dce8aebaSBarry Smith .     etype - the element type, currently either `DMDA_ELEMENT_P1` or `DMDA_ELEMENT_Q1`
3312dde6fd4SLisandro Dalcin 
3322dde6fd4SLisandro Dalcin    Level: intermediate
3332dde6fd4SLisandro Dalcin 
334dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`, `DMDARestoreElements()`
3352dde6fd4SLisandro Dalcin @*/
336d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetElementType(DM da, DMDAElementType *etype)
337d71ae5a4SJacob Faibussowitsch {
3382dde6fd4SLisandro Dalcin   DM_DA    *dd = (DM_DA *)da->data;
339f951a8fcSStefano Zampini   PetscBool isda;
3405fd66863SKarl Rupp 
3412dde6fd4SLisandro Dalcin   PetscFunctionBegin;
342a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
3432dde6fd4SLisandro Dalcin   PetscValidPointer(etype, 2);
3449566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
3457a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
3462dde6fd4SLisandro Dalcin   *etype = dd->elementtype;
3473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3482dde6fd4SLisandro Dalcin }
3492dde6fd4SLisandro Dalcin 
3502dde6fd4SLisandro Dalcin /*@C
3512dde6fd4SLisandro Dalcin       DMDAGetElements - Gets an array containing the indices (in local coordinates)
3522dde6fd4SLisandro Dalcin                  of all the local elements
3532dde6fd4SLisandro Dalcin 
354*20f4b53cSBarry Smith     Not Collective; No Fortran Support
3552dde6fd4SLisandro Dalcin 
3562dde6fd4SLisandro Dalcin    Input Parameter:
357dce8aebaSBarry Smith .     dm - the `DMDA` object
3582dde6fd4SLisandro Dalcin 
3592dde6fd4SLisandro Dalcin    Output Parameters:
3602dde6fd4SLisandro Dalcin +     nel - number of local elements
3612dde6fd4SLisandro Dalcin .     nen - number of element nodes
362c2cd2aa3SJed Brown -     e - the local indices of the elements' vertices
3632dde6fd4SLisandro Dalcin 
3642dde6fd4SLisandro Dalcin    Level: intermediate
3652dde6fd4SLisandro Dalcin 
36693386343SJed Brown    Notes:
367dce8aebaSBarry Smith      Call `DMDARestoreElements()` once you have finished accessing the elements.
36893386343SJed Brown 
36945950774SSatish Balay      Each process uniquely owns a subset of the elements. That is no element is owned by two or more processes.
370009f0576SBarry Smith 
371dce8aebaSBarry Smith      If on each process you integrate over its owned elements and use `ADD_VALUES` in `Vec`/`MatSetValuesLocal()` then you'll obtain the correct result.
372009f0576SBarry Smith 
373dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `VecSetValuesLocal()`, `MatSetValuesLocal()`, `DMGlobalToLocalBegin()`, `DMLocalToGlobalBegin()`
3742dde6fd4SLisandro Dalcin @*/
375d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetElements(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
376d71ae5a4SJacob Faibussowitsch {
377c73cfb54SMatthew G. Knepley   PetscInt  dim;
37899c57625SBarry Smith   DM_DA    *dd = (DM_DA *)dm->data;
379f951a8fcSStefano Zampini   PetscBool isda;
3805fd66863SKarl Rupp 
381454e267fSLisandro Dalcin   PetscFunctionBegin;
382a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
383f951a8fcSStefano Zampini   PetscValidIntPointer(nel, 2);
384f951a8fcSStefano Zampini   PetscValidIntPointer(nen, 3);
385f951a8fcSStefano Zampini   PetscValidPointer(e, 4);
3869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda));
3877a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)dm)->type_name);
38808401ef6SPierre Jolivet   PetscCheck(dd->stencil_type != DMDA_STENCIL_STAR, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DMDAGetElements() requires you use a stencil type of DMDA_STENCIL_BOX");
3899566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
390cfbed8a3SStefano Zampini   if (dd->e) {
391cfbed8a3SStefano Zampini     *nel = dd->ne;
392cfbed8a3SStefano Zampini     *nen = dd->nen;
393cfbed8a3SStefano Zampini     *e   = dd->e;
3943ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
395cfbed8a3SStefano Zampini   }
396c73cfb54SMatthew G. Knepley   if (dim == -1) {
3979371c9d4SSatish Balay     *nel = 0;
3989371c9d4SSatish Balay     *nen = 0;
3999371c9d4SSatish Balay     *e   = NULL;
400c73cfb54SMatthew G. Knepley   } else if (dim == 1) {
4019566063dSJacob Faibussowitsch     PetscCall(DMDAGetElements_1D(dm, nel, nen, e));
402c73cfb54SMatthew G. Knepley   } else if (dim == 2) {
4039566063dSJacob Faibussowitsch     PetscCall(DMDAGetElements_2D(dm, nel, nen, e));
404c73cfb54SMatthew G. Knepley   } else if (dim == 3) {
4059566063dSJacob Faibussowitsch     PetscCall(DMDAGetElements_3D(dm, nel, nen, e));
40663a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
4073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
408454e267fSLisandro Dalcin }
4092dde6fd4SLisandro Dalcin 
410f951a8fcSStefano Zampini /*@
411d4a6ed37SStefano Zampini       DMDAGetSubdomainCornersIS - Gets an index set containing the corner indices (in local coordinates)
412dce8aebaSBarry Smith                                  of the non-overlapping decomposition identified by `DMDAGetElements()`
413f951a8fcSStefano Zampini 
414f951a8fcSStefano Zampini     Not Collective
415f951a8fcSStefano Zampini 
416f951a8fcSStefano Zampini    Input Parameter:
417dce8aebaSBarry Smith .     dm - the `DMDA` object
418f951a8fcSStefano Zampini 
419f951a8fcSStefano Zampini    Output Parameters:
420f951a8fcSStefano Zampini .     is - the index set
421f951a8fcSStefano Zampini 
422f951a8fcSStefano Zampini    Level: intermediate
423f951a8fcSStefano Zampini 
424dce8aebaSBarry Smith    Note:
425dce8aebaSBarry Smith     Call `DMDARestoreSubdomainCornersIS()` once you have finished accessing the index set.
426f951a8fcSStefano Zampini 
427dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`, `DMDARestoreElementsCornersIS()`
428f951a8fcSStefano Zampini @*/
429d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetSubdomainCornersIS(DM dm, IS *is)
430d71ae5a4SJacob Faibussowitsch {
431f951a8fcSStefano Zampini   DM_DA    *dd = (DM_DA *)dm->data;
432f951a8fcSStefano Zampini   PetscBool isda;
433f951a8fcSStefano Zampini 
434f951a8fcSStefano Zampini   PetscFunctionBegin;
435a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
436f951a8fcSStefano Zampini   PetscValidPointer(is, 2);
4379566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda));
4387a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)dm)->type_name);
43908401ef6SPierre Jolivet   PetscCheck(dd->stencil_type != DMDA_STENCIL_STAR, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DMDAGetElement() requires you use a stencil type of DMDA_STENCIL_BOX");
440f951a8fcSStefano Zampini   if (!dd->ecorners) { /* compute elements if not yet done */
441f951a8fcSStefano Zampini     const PetscInt *e;
442f951a8fcSStefano Zampini     PetscInt        nel, nen;
443f951a8fcSStefano Zampini 
4449566063dSJacob Faibussowitsch     PetscCall(DMDAGetElements(dm, &nel, &nen, &e));
4459566063dSJacob Faibussowitsch     PetscCall(DMDARestoreElements(dm, &nel, &nen, &e));
446f951a8fcSStefano Zampini   }
447f951a8fcSStefano Zampini   *is = dd->ecorners;
4483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
449f951a8fcSStefano Zampini }
450f951a8fcSStefano Zampini 
4512dde6fd4SLisandro Dalcin /*@C
452dce8aebaSBarry Smith       DMDARestoreElements - Restores the array obtained with `DMDAGetElements()`
4532dde6fd4SLisandro Dalcin 
454*20f4b53cSBarry Smith     Not Collective; No Fortran Support
4552dde6fd4SLisandro Dalcin 
456d8d19677SJose E. Roman    Input Parameters:
457*20f4b53cSBarry Smith +     dm - the `DM` object
4582dde6fd4SLisandro Dalcin .     nel - number of local elements
4592dde6fd4SLisandro Dalcin .     nen - number of element nodes
460c2cd2aa3SJed Brown -     e - the local indices of the elements' vertices
4612dde6fd4SLisandro Dalcin 
4622dde6fd4SLisandro Dalcin    Level: intermediate
4632dde6fd4SLisandro Dalcin 
464dce8aebaSBarry Smith    Note:
465dce8aebaSBarry Smith    This restore signals the `DMDA` object that you no longer need access to the array information.
466009f0576SBarry Smith 
467dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`
4682dde6fd4SLisandro Dalcin @*/
469d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDARestoreElements(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
470d71ae5a4SJacob Faibussowitsch {
4712dde6fd4SLisandro Dalcin   PetscFunctionBegin;
472a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
4732dde6fd4SLisandro Dalcin   PetscValidIntPointer(nel, 2);
4742dde6fd4SLisandro Dalcin   PetscValidIntPointer(nen, 3);
4752dde6fd4SLisandro Dalcin   PetscValidPointer(e, 4);
4769cc8bc54SJed Brown   *nel = 0;
4779cc8bc54SJed Brown   *nen = -1;
4789cc8bc54SJed Brown   *e   = NULL;
4793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4802dde6fd4SLisandro Dalcin }
481f951a8fcSStefano Zampini 
482f951a8fcSStefano Zampini /*@
483dce8aebaSBarry Smith       DMDARestoreSubdomainCornersIS - Restores the `IS` obtained with `DMDAGetSubdomainCornersIS()`
484f951a8fcSStefano Zampini 
485f951a8fcSStefano Zampini     Not Collective
486f951a8fcSStefano Zampini 
487d8d19677SJose E. Roman    Input Parameters:
488dce8aebaSBarry Smith +     dm - the `DM` object
489f951a8fcSStefano Zampini -     is - the index set
490f951a8fcSStefano Zampini 
491f951a8fcSStefano Zampini    Level: intermediate
492f951a8fcSStefano Zampini 
493dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetSubdomainCornersIS()`
494f951a8fcSStefano Zampini @*/
495d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDARestoreSubdomainCornersIS(DM dm, IS *is)
496d71ae5a4SJacob Faibussowitsch {
497f951a8fcSStefano Zampini   PetscFunctionBegin;
498a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
499f951a8fcSStefano Zampini   PetscValidHeaderSpecific(*is, IS_CLASSID, 2);
500f951a8fcSStefano Zampini   *is = NULL;
5013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
502f951a8fcSStefano Zampini }
503