xref: /petsc/src/dm/impls/da/dagetelem.c (revision f4d061e980d13bc62f06124c58b76593bdf99e72)
1454e267fSLisandro Dalcin 
2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I  "petscdmda.h"   I*/
3454e267fSLisandro Dalcin 
49371c9d4SSatish Balay static PetscErrorCode DMDAGetElements_1D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[]) {
5454e267fSLisandro Dalcin   DM_DA   *da = (DM_DA *)dm->data;
6454e267fSLisandro Dalcin   PetscInt i, xs, xe, Xs, Xe;
7454e267fSLisandro Dalcin   PetscInt cnt = 0;
85fd66863SKarl Rupp 
9454e267fSLisandro Dalcin   PetscFunctionBegin;
10454e267fSLisandro Dalcin   if (!da->e) {
11f951a8fcSStefano Zampini     PetscInt corners[2];
12f951a8fcSStefano Zampini 
137a8be351SBarry Smith     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");
149566063dSJacob Faibussowitsch     PetscCall(DMDAGetCorners(dm, &xs, NULL, NULL, &xe, NULL, NULL));
159566063dSJacob Faibussowitsch     PetscCall(DMDAGetGhostCorners(dm, &Xs, NULL, NULL, &Xe, NULL, NULL));
169371c9d4SSatish Balay     xe += xs;
179371c9d4SSatish Balay     Xe += Xs;
189371c9d4SSatish Balay     if (xs != Xs) xs -= 1;
19454e267fSLisandro Dalcin     da->ne = 1 * (xe - xs - 1);
209566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1 + 2 * da->ne, &da->e));
21454e267fSLisandro Dalcin     for (i = xs; i < xe - 1; i++) {
22454e267fSLisandro Dalcin       da->e[cnt++] = (i - Xs);
23454e267fSLisandro Dalcin       da->e[cnt++] = (i - Xs + 1);
24454e267fSLisandro Dalcin     }
25cfbed8a3SStefano Zampini     da->nen = 2;
26cfbed8a3SStefano Zampini 
27f951a8fcSStefano Zampini     corners[0] = (xs - Xs);
28f951a8fcSStefano Zampini     corners[1] = (xe - 1 - Xs);
299566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 2, corners, PETSC_COPY_VALUES, &da->ecorners));
30454e267fSLisandro Dalcin   }
31454e267fSLisandro Dalcin   *nel = da->ne;
32cfbed8a3SStefano Zampini   *nen = da->nen;
33454e267fSLisandro Dalcin   *e   = da->e;
34454e267fSLisandro Dalcin   PetscFunctionReturn(0);
35454e267fSLisandro Dalcin }
36454e267fSLisandro Dalcin 
379371c9d4SSatish Balay static PetscErrorCode DMDAGetElements_2D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[]) {
38454e267fSLisandro Dalcin   DM_DA   *da = (DM_DA *)dm->data;
39454e267fSLisandro Dalcin   PetscInt i, xs, xe, Xs, Xe;
40454e267fSLisandro Dalcin   PetscInt j, ys, ye, Ys, Ye;
41cfbed8a3SStefano Zampini   PetscInt cnt = 0, cell[4], ns = 2;
429371c9d4SSatish Balay   PetscInt c, split[] = {0, 1, 3, 2, 3, 1};
435fd66863SKarl Rupp 
44454e267fSLisandro Dalcin   PetscFunctionBegin;
45454e267fSLisandro Dalcin   if (!da->e) {
46cfbed8a3SStefano Zampini     PetscInt corners[4], nn = 0;
47f951a8fcSStefano Zampini 
487a8be351SBarry Smith     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");
49cfbed8a3SStefano Zampini 
50cfbed8a3SStefano Zampini     switch (da->elementtype) {
519371c9d4SSatish Balay     case DMDA_ELEMENT_Q1: da->nen = 4; break;
529371c9d4SSatish Balay     case DMDA_ELEMENT_P1: da->nen = 3; break;
539371c9d4SSatish Balay     default: SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown element type %d", da->elementtype);
54cfbed8a3SStefano Zampini     }
55cfbed8a3SStefano Zampini     nn = da->nen;
56cfbed8a3SStefano Zampini 
57ad540459SPierre Jolivet     if (da->elementtype == DMDA_ELEMENT_P1) ns = 2;
58ad540459SPierre Jolivet     if (da->elementtype == DMDA_ELEMENT_Q1) ns = 1;
599566063dSJacob Faibussowitsch     PetscCall(DMDAGetCorners(dm, &xs, &ys, NULL, &xe, &ye, NULL));
609566063dSJacob Faibussowitsch     PetscCall(DMDAGetGhostCorners(dm, &Xs, &Ys, NULL, &Xe, &Ye, NULL));
619371c9d4SSatish Balay     xe += xs;
629371c9d4SSatish Balay     Xe += Xs;
639371c9d4SSatish Balay     if (xs != Xs) xs -= 1;
649371c9d4SSatish Balay     ye += ys;
659371c9d4SSatish Balay     Ye += Ys;
669371c9d4SSatish Balay     if (ys != Ys) ys -= 1;
67454e267fSLisandro Dalcin     da->ne = ns * (xe - xs - 1) * (ye - ys - 1);
689566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1 + nn * da->ne, &da->e));
69454e267fSLisandro Dalcin     for (j = ys; j < ye - 1; j++) {
70454e267fSLisandro Dalcin       for (i = xs; i < xe - 1; i++) {
71454e267fSLisandro Dalcin         cell[0] = (i - Xs) + (j - Ys) * (Xe - Xs);
72454e267fSLisandro Dalcin         cell[1] = (i - Xs + 1) + (j - Ys) * (Xe - Xs);
73454e267fSLisandro Dalcin         cell[2] = (i - Xs + 1) + (j - Ys + 1) * (Xe - Xs);
74454e267fSLisandro Dalcin         cell[3] = (i - Xs) + (j - Ys + 1) * (Xe - Xs);
75454e267fSLisandro Dalcin         if (da->elementtype == DMDA_ELEMENT_P1) {
768865f1eaSKarl Rupp           for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[split[c]];
77454e267fSLisandro Dalcin         }
78454e267fSLisandro Dalcin         if (da->elementtype == DMDA_ELEMENT_Q1) {
798865f1eaSKarl Rupp           for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[c];
80454e267fSLisandro Dalcin         }
81454e267fSLisandro Dalcin       }
82454e267fSLisandro Dalcin     }
83cfbed8a3SStefano Zampini 
84f951a8fcSStefano Zampini     corners[0] = (xs - Xs) + (ys - Ys) * (Xe - Xs);
85f951a8fcSStefano Zampini     corners[1] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs);
86f951a8fcSStefano Zampini     corners[2] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs);
87f951a8fcSStefano Zampini     corners[3] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs);
889566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 4, corners, PETSC_COPY_VALUES, &da->ecorners));
89454e267fSLisandro Dalcin   }
90454e267fSLisandro Dalcin   *nel = da->ne;
91cfbed8a3SStefano Zampini   *nen = da->nen;
92454e267fSLisandro Dalcin   *e   = da->e;
93454e267fSLisandro Dalcin   PetscFunctionReturn(0);
94454e267fSLisandro Dalcin }
95454e267fSLisandro Dalcin 
969371c9d4SSatish Balay static PetscErrorCode DMDAGetElements_3D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[]) {
97454e267fSLisandro Dalcin   DM_DA   *da = (DM_DA *)dm->data;
98454e267fSLisandro Dalcin   PetscInt i, xs, xe, Xs, Xe;
99454e267fSLisandro Dalcin   PetscInt j, ys, ye, Ys, Ye;
100454e267fSLisandro Dalcin   PetscInt k, zs, ze, Zs, Ze;
101cfbed8a3SStefano Zampini   PetscInt cnt = 0, cell[8], ns = 6;
1029371c9d4SSatish 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};
1035fd66863SKarl Rupp 
104454e267fSLisandro Dalcin   PetscFunctionBegin;
105454e267fSLisandro Dalcin   if (!da->e) {
106cfbed8a3SStefano Zampini     PetscInt corners[8], nn = 0;
107f951a8fcSStefano Zampini 
1087a8be351SBarry Smith     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");
109cfbed8a3SStefano Zampini 
110cfbed8a3SStefano Zampini     switch (da->elementtype) {
1119371c9d4SSatish Balay     case DMDA_ELEMENT_Q1: da->nen = 8; break;
1129371c9d4SSatish Balay     case DMDA_ELEMENT_P1: da->nen = 4; break;
1139371c9d4SSatish Balay     default: SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown element type %d", da->elementtype);
114cfbed8a3SStefano Zampini     }
115cfbed8a3SStefano Zampini     nn = da->nen;
116cfbed8a3SStefano Zampini 
117ad540459SPierre Jolivet     if (da->elementtype == DMDA_ELEMENT_P1) ns = 6;
118ad540459SPierre Jolivet     if (da->elementtype == DMDA_ELEMENT_Q1) ns = 1;
1199566063dSJacob Faibussowitsch     PetscCall(DMDAGetCorners(dm, &xs, &ys, &zs, &xe, &ye, &ze));
1209566063dSJacob Faibussowitsch     PetscCall(DMDAGetGhostCorners(dm, &Xs, &Ys, &Zs, &Xe, &Ye, &Ze));
1219371c9d4SSatish Balay     xe += xs;
1229371c9d4SSatish Balay     Xe += Xs;
1239371c9d4SSatish Balay     if (xs != Xs) xs -= 1;
1249371c9d4SSatish Balay     ye += ys;
1259371c9d4SSatish Balay     Ye += Ys;
1269371c9d4SSatish Balay     if (ys != Ys) ys -= 1;
1279371c9d4SSatish Balay     ze += zs;
1289371c9d4SSatish Balay     Ze += Zs;
1299371c9d4SSatish Balay     if (zs != Zs) zs -= 1;
130454e267fSLisandro Dalcin     da->ne = ns * (xe - xs - 1) * (ye - ys - 1) * (ze - zs - 1);
1319566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1 + nn * da->ne, &da->e));
132454e267fSLisandro Dalcin     for (k = zs; k < ze - 1; k++) {
133454e267fSLisandro Dalcin       for (j = ys; j < ye - 1; j++) {
134454e267fSLisandro Dalcin         for (i = xs; i < xe - 1; i++) {
135454e267fSLisandro Dalcin           cell[0] = (i - Xs) + (j - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
1362da392ccSBarry Smith           cell[1] = (i + 1 - Xs) + (j - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
1372da392ccSBarry Smith           cell[2] = (i + 1 - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
1382da392ccSBarry Smith           cell[3] = (i - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
1392da392ccSBarry Smith           cell[4] = (i - Xs) + (j - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
1402da392ccSBarry Smith           cell[5] = (i + 1 - Xs) + (j - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
1412da392ccSBarry Smith           cell[6] = (i + 1 - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
1422da392ccSBarry Smith           cell[7] = (i - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
143454e267fSLisandro Dalcin           if (da->elementtype == DMDA_ELEMENT_P1) {
1448865f1eaSKarl Rupp             for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[split[c]];
145454e267fSLisandro Dalcin           }
146454e267fSLisandro Dalcin           if (da->elementtype == DMDA_ELEMENT_Q1) {
1478865f1eaSKarl Rupp             for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[c];
148454e267fSLisandro Dalcin           }
149454e267fSLisandro Dalcin         }
150454e267fSLisandro Dalcin       }
151454e267fSLisandro Dalcin     }
152cfbed8a3SStefano Zampini 
153f951a8fcSStefano Zampini     corners[0] = (xs - Xs) + (ys - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
154f951a8fcSStefano Zampini     corners[1] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
155f951a8fcSStefano Zampini     corners[2] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
156f951a8fcSStefano Zampini     corners[3] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
157f951a8fcSStefano Zampini     corners[4] = (xs - Xs) + (ys - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
158f951a8fcSStefano Zampini     corners[5] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
159f951a8fcSStefano Zampini     corners[6] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
160f951a8fcSStefano Zampini     corners[7] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
1619566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 8, corners, PETSC_COPY_VALUES, &da->ecorners));
162454e267fSLisandro Dalcin   }
163454e267fSLisandro Dalcin   *nel = da->ne;
164cfbed8a3SStefano Zampini   *nen = da->nen;
165454e267fSLisandro Dalcin   *e   = da->e;
166454e267fSLisandro Dalcin   PetscFunctionReturn(0);
167454e267fSLisandro Dalcin }
168454e267fSLisandro Dalcin 
169f5f57ec0SBarry Smith /*@
170d4a6ed37SStefano Zampini    DMDAGetElementsCorners - Returns the global (x,y,z) indices of the lower left
171d4a6ed37SStefano Zampini    corner of the non-overlapping decomposition identified by DMDAGetElements()
172d4a6ed37SStefano Zampini 
173d4a6ed37SStefano Zampini     Not Collective
174d4a6ed37SStefano Zampini 
175d4a6ed37SStefano Zampini    Input Parameter:
176d4a6ed37SStefano Zampini .     da - the DM object
177d4a6ed37SStefano Zampini 
178d4a6ed37SStefano Zampini    Output Parameters:
179d4a6ed37SStefano Zampini +     gx - the x index
180d4a6ed37SStefano Zampini .     gy - the y index
181d4a6ed37SStefano Zampini -     gz - the z index
182d4a6ed37SStefano Zampini 
183d4a6ed37SStefano Zampini    Level: intermediate
184d4a6ed37SStefano Zampini 
185d4a6ed37SStefano Zampini    Notes:
186d4a6ed37SStefano Zampini 
187db781477SPatrick Sanan .seealso: `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`
188d4a6ed37SStefano Zampini @*/
1899371c9d4SSatish Balay PetscErrorCode DMDAGetElementsCorners(DM da, PetscInt *gx, PetscInt *gy, PetscInt *gz) {
190d4a6ed37SStefano Zampini   PetscInt  xs, Xs;
191d4a6ed37SStefano Zampini   PetscInt  ys, Ys;
192d4a6ed37SStefano Zampini   PetscInt  zs, Zs;
193d4a6ed37SStefano Zampini   PetscBool isda;
194d4a6ed37SStefano Zampini 
195d4a6ed37SStefano Zampini   PetscFunctionBegin;
196a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
197d4a6ed37SStefano Zampini   if (gx) PetscValidIntPointer(gx, 2);
198d4a6ed37SStefano Zampini   if (gy) PetscValidIntPointer(gy, 3);
199d4a6ed37SStefano Zampini   if (gz) PetscValidIntPointer(gz, 4);
2009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
2017a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
2029566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, NULL, NULL, NULL));
2039566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &Xs, &Ys, &Zs, NULL, NULL, NULL));
204d4a6ed37SStefano Zampini   if (xs != Xs) xs -= 1;
205d4a6ed37SStefano Zampini   if (ys != Ys) ys -= 1;
206d4a6ed37SStefano Zampini   if (zs != Zs) zs -= 1;
207d4a6ed37SStefano Zampini   if (gx) *gx = xs;
208d4a6ed37SStefano Zampini   if (gy) *gy = ys;
209d4a6ed37SStefano Zampini   if (gz) *gz = zs;
210d4a6ed37SStefano Zampini   PetscFunctionReturn(0);
211d4a6ed37SStefano Zampini }
212d4a6ed37SStefano Zampini 
213d4a6ed37SStefano Zampini /*@
214d4a6ed37SStefano Zampini       DMDAGetElementsSizes - Gets the local number of elements per direction for the non-overlapping decomposition identified by DMDAGetElements()
215d4a6ed37SStefano Zampini 
216d4a6ed37SStefano Zampini     Not Collective
217d4a6ed37SStefano Zampini 
218d4a6ed37SStefano Zampini    Input Parameter:
219d4a6ed37SStefano Zampini .     da - the DM object
220d4a6ed37SStefano Zampini 
221d4a6ed37SStefano Zampini    Output Parameters:
222d4a6ed37SStefano Zampini +     mx - number of local elements in x-direction
223d4a6ed37SStefano Zampini .     my - number of local elements in y-direction
224d4a6ed37SStefano Zampini -     mz - number of local elements in z-direction
225d4a6ed37SStefano Zampini 
226d4a6ed37SStefano Zampini    Level: intermediate
227d4a6ed37SStefano Zampini 
22895452b02SPatrick Sanan    Notes:
22995452b02SPatrick Sanan     It returns the same number of elements, irrespective of the DMDAElementType
230d4a6ed37SStefano Zampini 
231db781477SPatrick Sanan .seealso: `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements`
232d4a6ed37SStefano Zampini @*/
2339371c9d4SSatish Balay PetscErrorCode DMDAGetElementsSizes(DM da, PetscInt *mx, PetscInt *my, PetscInt *mz) {
234d4a6ed37SStefano Zampini   PetscInt  xs, xe, Xs;
235d4a6ed37SStefano Zampini   PetscInt  ys, ye, Ys;
236d4a6ed37SStefano Zampini   PetscInt  zs, ze, Zs;
237d4a6ed37SStefano Zampini   PetscInt  dim;
238d4a6ed37SStefano Zampini   PetscBool isda;
239d4a6ed37SStefano Zampini 
240d4a6ed37SStefano Zampini   PetscFunctionBegin;
241a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
242d4a6ed37SStefano Zampini   if (mx) PetscValidIntPointer(mx, 2);
243d4a6ed37SStefano Zampini   if (my) PetscValidIntPointer(my, 3);
244d4a6ed37SStefano Zampini   if (mz) PetscValidIntPointer(mz, 4);
2459566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
2467a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
2479566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xe, &ye, &ze));
2489566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &Xs, &Ys, &Zs, NULL, NULL, NULL));
2499371c9d4SSatish Balay   xe += xs;
2509371c9d4SSatish Balay   if (xs != Xs) xs -= 1;
2519371c9d4SSatish Balay   ye += ys;
2529371c9d4SSatish Balay   if (ys != Ys) ys -= 1;
2539371c9d4SSatish Balay   ze += zs;
2549371c9d4SSatish Balay   if (zs != Zs) zs -= 1;
255d4a6ed37SStefano Zampini   if (mx) *mx = 0;
256d4a6ed37SStefano Zampini   if (my) *my = 0;
257d4a6ed37SStefano Zampini   if (mz) *mz = 0;
2589566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(da, &dim));
259d4a6ed37SStefano Zampini   switch (dim) {
260d4a6ed37SStefano Zampini   case 3:
261*f4d061e9SPierre Jolivet     if (mz) *mz = ze - zs - 1; /* fall through */
262d4a6ed37SStefano Zampini   case 2:
263*f4d061e9SPierre Jolivet     if (my) *my = ye - ys - 1; /* fall through */
264d4a6ed37SStefano Zampini   case 1:
265d4a6ed37SStefano Zampini     if (mx) *mx = xe - xs - 1;
266d4a6ed37SStefano Zampini     break;
267d4a6ed37SStefano Zampini   }
268d4a6ed37SStefano Zampini   PetscFunctionReturn(0);
269d4a6ed37SStefano Zampini }
270d4a6ed37SStefano Zampini 
271d4a6ed37SStefano Zampini /*@
2722dde6fd4SLisandro Dalcin       DMDASetElementType - Sets the element type to be returned by DMDAGetElements()
2732dde6fd4SLisandro Dalcin 
2742dde6fd4SLisandro Dalcin     Not Collective
2752dde6fd4SLisandro Dalcin 
2762dde6fd4SLisandro Dalcin    Input Parameter:
2772dde6fd4SLisandro Dalcin .     da - the DMDA object
2782dde6fd4SLisandro Dalcin 
2792dde6fd4SLisandro Dalcin    Output Parameters:
2806420f107SDave May .     etype - the element type, currently either DMDA_ELEMENT_P1 or DMDA_ELEMENT_Q1
2812dde6fd4SLisandro Dalcin 
2822dde6fd4SLisandro Dalcin    Level: intermediate
2832dde6fd4SLisandro Dalcin 
284db781477SPatrick Sanan .seealso: `DMDAElementType`, `DMDAGetElementType()`, `DMDAGetElements()`, `DMDARestoreElements()`
2852dde6fd4SLisandro Dalcin @*/
2869371c9d4SSatish Balay PetscErrorCode DMDASetElementType(DM da, DMDAElementType etype) {
2872dde6fd4SLisandro Dalcin   DM_DA    *dd = (DM_DA *)da->data;
288f951a8fcSStefano Zampini   PetscBool isda;
2892dde6fd4SLisandro Dalcin 
2902dde6fd4SLisandro Dalcin   PetscFunctionBegin;
291a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
2922dde6fd4SLisandro Dalcin   PetscValidLogicalCollectiveEnum(da, etype, 2);
2939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
294f951a8fcSStefano Zampini   if (!isda) PetscFunctionReturn(0);
2952dde6fd4SLisandro Dalcin   if (dd->elementtype != etype) {
2969566063dSJacob Faibussowitsch     PetscCall(PetscFree(dd->e));
2979566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&dd->ecorners));
2988865f1eaSKarl Rupp 
2992dde6fd4SLisandro Dalcin     dd->elementtype = etype;
3002dde6fd4SLisandro Dalcin     dd->ne          = 0;
301cfbed8a3SStefano Zampini     dd->nen         = 0;
3020298fd71SBarry Smith     dd->e           = NULL;
3032dde6fd4SLisandro Dalcin   }
3042dde6fd4SLisandro Dalcin   PetscFunctionReturn(0);
3052dde6fd4SLisandro Dalcin }
3062dde6fd4SLisandro Dalcin 
307f5f57ec0SBarry Smith /*@
3082dde6fd4SLisandro Dalcin       DMDAGetElementType - Gets the element type to be returned by DMDAGetElements()
3092dde6fd4SLisandro Dalcin 
3102dde6fd4SLisandro Dalcin     Not Collective
3112dde6fd4SLisandro Dalcin 
3122dde6fd4SLisandro Dalcin    Input Parameter:
3132dde6fd4SLisandro Dalcin .     da - the DMDA object
3142dde6fd4SLisandro Dalcin 
3152dde6fd4SLisandro Dalcin    Output Parameters:
3166420f107SDave May .     etype - the element type, currently either DMDA_ELEMENT_P1 or DMDA_ELEMENT_Q1
3172dde6fd4SLisandro Dalcin 
3182dde6fd4SLisandro Dalcin    Level: intermediate
3192dde6fd4SLisandro Dalcin 
320db781477SPatrick Sanan .seealso: `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`, `DMDARestoreElements()`
3212dde6fd4SLisandro Dalcin @*/
3229371c9d4SSatish Balay PetscErrorCode DMDAGetElementType(DM da, DMDAElementType *etype) {
3232dde6fd4SLisandro Dalcin   DM_DA    *dd = (DM_DA *)da->data;
324f951a8fcSStefano Zampini   PetscBool isda;
3255fd66863SKarl Rupp 
3262dde6fd4SLisandro Dalcin   PetscFunctionBegin;
327a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
3282dde6fd4SLisandro Dalcin   PetscValidPointer(etype, 2);
3299566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
3307a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
3312dde6fd4SLisandro Dalcin   *etype = dd->elementtype;
3322dde6fd4SLisandro Dalcin   PetscFunctionReturn(0);
3332dde6fd4SLisandro Dalcin }
3342dde6fd4SLisandro Dalcin 
3352dde6fd4SLisandro Dalcin /*@C
3362dde6fd4SLisandro Dalcin       DMDAGetElements - Gets an array containing the indices (in local coordinates)
3372dde6fd4SLisandro Dalcin                  of all the local elements
3382dde6fd4SLisandro Dalcin 
3392dde6fd4SLisandro Dalcin     Not Collective
3402dde6fd4SLisandro Dalcin 
3412dde6fd4SLisandro Dalcin    Input Parameter:
3422dde6fd4SLisandro Dalcin .     dm - the DM object
3432dde6fd4SLisandro Dalcin 
3442dde6fd4SLisandro Dalcin    Output Parameters:
3452dde6fd4SLisandro Dalcin +     nel - number of local elements
3462dde6fd4SLisandro Dalcin .     nen - number of element nodes
347c2cd2aa3SJed Brown -     e - the local indices of the elements' vertices
3482dde6fd4SLisandro Dalcin 
3492dde6fd4SLisandro Dalcin    Level: intermediate
3502dde6fd4SLisandro Dalcin 
35193386343SJed Brown    Notes:
35293386343SJed Brown      Call DMDARestoreElements() once you have finished accessing the elements.
35393386343SJed Brown 
35445950774SSatish Balay      Each process uniquely owns a subset of the elements. That is no element is owned by two or more processes.
355009f0576SBarry Smith 
356009f0576SBarry 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.
357009f0576SBarry Smith 
358f5f57ec0SBarry Smith      Not supported in Fortran
359f5f57ec0SBarry Smith 
360db781477SPatrick Sanan .seealso: `DMDAElementType`, `DMDASetElementType()`, `VecSetValuesLocal()`, `MatSetValuesLocal()`, `DMGlobalToLocalBegin()`, `DMLocalToGlobalBegin()`
3612dde6fd4SLisandro Dalcin @*/
3629371c9d4SSatish Balay PetscErrorCode DMDAGetElements(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[]) {
363c73cfb54SMatthew G. Knepley   PetscInt  dim;
36499c57625SBarry Smith   DM_DA    *dd = (DM_DA *)dm->data;
365f951a8fcSStefano Zampini   PetscBool isda;
3665fd66863SKarl Rupp 
367454e267fSLisandro Dalcin   PetscFunctionBegin;
368a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
369f951a8fcSStefano Zampini   PetscValidIntPointer(nel, 2);
370f951a8fcSStefano Zampini   PetscValidIntPointer(nen, 3);
371f951a8fcSStefano Zampini   PetscValidPointer(e, 4);
3729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda));
3737a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)dm)->type_name);
37408401ef6SPierre 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");
3759566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
376cfbed8a3SStefano Zampini   if (dd->e) {
377cfbed8a3SStefano Zampini     *nel = dd->ne;
378cfbed8a3SStefano Zampini     *nen = dd->nen;
379cfbed8a3SStefano Zampini     *e   = dd->e;
380cfbed8a3SStefano Zampini     PetscFunctionReturn(0);
381cfbed8a3SStefano Zampini   }
382c73cfb54SMatthew G. Knepley   if (dim == -1) {
3839371c9d4SSatish Balay     *nel = 0;
3849371c9d4SSatish Balay     *nen = 0;
3859371c9d4SSatish Balay     *e   = NULL;
386c73cfb54SMatthew G. Knepley   } else if (dim == 1) {
3879566063dSJacob Faibussowitsch     PetscCall(DMDAGetElements_1D(dm, nel, nen, e));
388c73cfb54SMatthew G. Knepley   } else if (dim == 2) {
3899566063dSJacob Faibussowitsch     PetscCall(DMDAGetElements_2D(dm, nel, nen, e));
390c73cfb54SMatthew G. Knepley   } else if (dim == 3) {
3919566063dSJacob Faibussowitsch     PetscCall(DMDAGetElements_3D(dm, nel, nen, e));
39263a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
393454e267fSLisandro Dalcin   PetscFunctionReturn(0);
394454e267fSLisandro Dalcin }
3952dde6fd4SLisandro Dalcin 
396f951a8fcSStefano Zampini /*@
397d4a6ed37SStefano Zampini       DMDAGetSubdomainCornersIS - Gets an index set containing the corner indices (in local coordinates)
398f951a8fcSStefano Zampini                                  of the non-overlapping decomposition identified by DMDAGetElements
399f951a8fcSStefano Zampini 
400f951a8fcSStefano Zampini     Not Collective
401f951a8fcSStefano Zampini 
402f951a8fcSStefano Zampini    Input Parameter:
403f951a8fcSStefano Zampini .     dm - the DM object
404f951a8fcSStefano Zampini 
405f951a8fcSStefano Zampini    Output Parameters:
406f951a8fcSStefano Zampini .     is - the index set
407f951a8fcSStefano Zampini 
408f951a8fcSStefano Zampini    Level: intermediate
409f951a8fcSStefano Zampini 
41095452b02SPatrick Sanan    Notes:
41195452b02SPatrick Sanan     Call DMDARestoreSubdomainCornersIS() once you have finished accessing the index set.
412f951a8fcSStefano Zampini 
413db781477SPatrick Sanan .seealso: `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`, `DMDARestoreElementsCornersIS()`
414f951a8fcSStefano Zampini @*/
4159371c9d4SSatish Balay PetscErrorCode DMDAGetSubdomainCornersIS(DM dm, IS *is) {
416f951a8fcSStefano Zampini   DM_DA    *dd = (DM_DA *)dm->data;
417f951a8fcSStefano Zampini   PetscBool isda;
418f951a8fcSStefano Zampini 
419f951a8fcSStefano Zampini   PetscFunctionBegin;
420a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
421f951a8fcSStefano Zampini   PetscValidPointer(is, 2);
4229566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda));
4237a8be351SBarry Smith   PetscCheck(isda, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)dm)->type_name);
42408401ef6SPierre 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");
425f951a8fcSStefano Zampini   if (!dd->ecorners) { /* compute elements if not yet done */
426f951a8fcSStefano Zampini     const PetscInt *e;
427f951a8fcSStefano Zampini     PetscInt        nel, nen;
428f951a8fcSStefano Zampini 
4299566063dSJacob Faibussowitsch     PetscCall(DMDAGetElements(dm, &nel, &nen, &e));
4309566063dSJacob Faibussowitsch     PetscCall(DMDARestoreElements(dm, &nel, &nen, &e));
431f951a8fcSStefano Zampini   }
432f951a8fcSStefano Zampini   *is = dd->ecorners;
433f951a8fcSStefano Zampini   PetscFunctionReturn(0);
434f951a8fcSStefano Zampini }
435f951a8fcSStefano Zampini 
4362dde6fd4SLisandro Dalcin /*@C
437009f0576SBarry Smith       DMDARestoreElements - Restores the array obtained with DMDAGetElements()
4382dde6fd4SLisandro Dalcin 
4392dde6fd4SLisandro Dalcin     Not Collective
4402dde6fd4SLisandro Dalcin 
441d8d19677SJose E. Roman    Input Parameters:
4422dde6fd4SLisandro Dalcin +     dm - the DM object
4432dde6fd4SLisandro Dalcin .     nel - number of local elements
4442dde6fd4SLisandro Dalcin .     nen - number of element nodes
445c2cd2aa3SJed Brown -     e - the local indices of the elements' vertices
4462dde6fd4SLisandro Dalcin 
4472dde6fd4SLisandro Dalcin    Level: intermediate
4482dde6fd4SLisandro Dalcin 
449009f0576SBarry Smith    Note: You should not access these values after you have called this routine.
450009f0576SBarry Smith 
451c67aec63SBarry Smith          This restore signals the DMDA object that you no longer need access to the array information.
452009f0576SBarry Smith 
453f5f57ec0SBarry Smith          Not supported in Fortran
454f5f57ec0SBarry Smith 
455db781477SPatrick Sanan .seealso: `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`
4562dde6fd4SLisandro Dalcin @*/
4579371c9d4SSatish Balay PetscErrorCode DMDARestoreElements(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[]) {
4582dde6fd4SLisandro Dalcin   PetscFunctionBegin;
459a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
4602dde6fd4SLisandro Dalcin   PetscValidIntPointer(nel, 2);
4612dde6fd4SLisandro Dalcin   PetscValidIntPointer(nen, 3);
4622dde6fd4SLisandro Dalcin   PetscValidPointer(e, 4);
4639cc8bc54SJed Brown   *nel = 0;
4649cc8bc54SJed Brown   *nen = -1;
4659cc8bc54SJed Brown   *e   = NULL;
4662dde6fd4SLisandro Dalcin   PetscFunctionReturn(0);
4672dde6fd4SLisandro Dalcin }
468f951a8fcSStefano Zampini 
469f951a8fcSStefano Zampini /*@
470d4a6ed37SStefano Zampini       DMDARestoreSubdomainCornersIS - Restores the IS obtained with DMDAGetSubdomainCornersIS()
471f951a8fcSStefano Zampini 
472f951a8fcSStefano Zampini     Not Collective
473f951a8fcSStefano Zampini 
474d8d19677SJose E. Roman    Input Parameters:
475f951a8fcSStefano Zampini +     dm - the DM object
476f951a8fcSStefano Zampini -     is - the index set
477f951a8fcSStefano Zampini 
478f951a8fcSStefano Zampini    Level: intermediate
479f951a8fcSStefano Zampini 
480f951a8fcSStefano Zampini    Note:
481f951a8fcSStefano Zampini 
482db781477SPatrick Sanan .seealso: `DMDAElementType`, `DMDASetElementType()`, `DMDAGetSubdomainCornersIS()`
483f951a8fcSStefano Zampini @*/
4849371c9d4SSatish Balay PetscErrorCode DMDARestoreSubdomainCornersIS(DM dm, IS *is) {
485f951a8fcSStefano Zampini   PetscFunctionBegin;
486a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
487f951a8fcSStefano Zampini   PetscValidHeaderSpecific(*is, IS_CLASSID, 2);
488f951a8fcSStefano Zampini   *is = NULL;
489f951a8fcSStefano Zampini   PetscFunctionReturn(0);
490f951a8fcSStefano Zampini }
491