xref: /petsc/src/dm/impls/da/dageometry.c (revision dce8aeba1c9b69b19f651c53d8a6b674bd7e9cbd)
105264a50SDave May #include <petscsf.h>
2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I  "petscdmda.h"   I*/
357459e9aSMatthew G Knepley 
4ed4e918cSMatthew G Knepley /*@
5f0e3914cSSatish Balay   DMDAConvertToCell - Convert (i,j,k) to local cell number
6341c9bdaSMatthew G Knepley 
7ed4e918cSMatthew G Knepley   Not Collective
8ed4e918cSMatthew G Knepley 
9d8d19677SJose E. Roman   Input Parameters:
10ed4e918cSMatthew G Knepley + da - the distributed array
11*dce8aebaSBarry Smith - s - A `MatStencil` giving (i,j,k)
12ed4e918cSMatthew G Knepley 
13ed4e918cSMatthew G Knepley   Output Parameter:
14ed4e918cSMatthew G Knepley . cell - the local cell number
15ed4e918cSMatthew G Knepley 
16ed4e918cSMatthew G Knepley   Level: developer
17*dce8aebaSBarry Smith 
18*dce8aebaSBarry Smith .seealso:  `DM`, `DMDA`
19ed4e918cSMatthew G Knepley @*/
20d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAConvertToCell(DM dm, MatStencil s, PetscInt *cell)
21d71ae5a4SJacob Faibussowitsch {
22341c9bdaSMatthew G Knepley   DM_DA         *da  = (DM_DA *)dm->data;
23c73cfb54SMatthew G. Knepley   const PetscInt dim = dm->dim;
244e846693SMatthew G Knepley   const PetscInt mx = (da->Xe - da->Xs) / da->w, my = da->Ye - da->Ys /*, mz = da->Ze - da->Zs*/;
25ed4e918cSMatthew G Knepley   const PetscInt il = s.i - da->Xs / da->w, jl = dim > 1 ? s.j - da->Ys : 0, kl = dim > 2 ? s.k - da->Zs : 0;
26341c9bdaSMatthew G Knepley 
27341c9bdaSMatthew G Knepley   PetscFunctionBegin;
28ed4e918cSMatthew G Knepley   *cell = -1;
2963a3b9bcSJacob Faibussowitsch   PetscCheck(!(s.i < da->Xs / da->w) && !(s.i >= da->Xe / da->w), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Stencil i %" PetscInt_FMT " should be in [%" PetscInt_FMT ", %" PetscInt_FMT ")", s.i, da->Xs / da->w, da->Xe / da->w);
301dca8a05SBarry Smith   PetscCheck(dim <= 1 || (s.j >= da->Ys && s.j < da->Ye), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Stencil j %" PetscInt_FMT " should be in [%" PetscInt_FMT ", %" PetscInt_FMT ")", s.j, da->Ys, da->Ye);
311dca8a05SBarry Smith   PetscCheck(dim <= 2 || (s.k >= da->Zs && s.k < da->Ze), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Stencil k %" PetscInt_FMT " should be in [%" PetscInt_FMT ", %" PetscInt_FMT ")", s.k, da->Zs, da->Ze);
32ed4e918cSMatthew G Knepley   *cell = (kl * my + jl) * mx + il;
33ed4e918cSMatthew G Knepley   PetscFunctionReturn(0);
34341c9bdaSMatthew G Knepley }
35341c9bdaSMatthew G Knepley 
36d71ae5a4SJacob Faibussowitsch PetscErrorCode private_DMDALocatePointsIS_2D_Regular(DM dmregular, Vec pos, IS *iscell)
37d71ae5a4SJacob Faibussowitsch {
3805264a50SDave May   PetscInt           n, bs, p, npoints;
3905264a50SDave May   PetscInt           xs, xe, Xs, Xe, mxlocal;
4005264a50SDave May   PetscInt           ys, ye, Ys, Ye, mylocal;
41aab5bcd8SJed Brown   PetscInt           d, c0, c1;
4205264a50SDave May   PetscReal          gmin_l[2], gmax_l[2], dx[2];
4305264a50SDave May   PetscReal          gmin[2], gmax[2];
4405264a50SDave May   PetscInt          *cellidx;
4505264a50SDave May   Vec                coor;
4605264a50SDave May   const PetscScalar *_coor;
4705264a50SDave May 
48aab5bcd8SJed Brown   PetscFunctionBegin;
499566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(dmregular, &xs, &ys, NULL, &xe, &ye, NULL));
509566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(dmregular, &Xs, &Ys, NULL, &Xe, &Ye, NULL));
519371c9d4SSatish Balay   xe += xs;
529371c9d4SSatish Balay   Xe += Xs;
539371c9d4SSatish Balay   ye += ys;
549371c9d4SSatish Balay   Ye += Ys;
5551c42ae6SMatthew G. Knepley   if (xs != Xs && Xs >= 0) xs -= 1;
5651c42ae6SMatthew G. Knepley   if (ys != Ys && Ys >= 0) ys -= 1;
5705264a50SDave May 
589566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinatesLocal(dmregular, &coor));
599566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(coor, &_coor));
6005264a50SDave May   c0 = (xs - Xs) + (ys - Ys) * (Xe - Xs);
6105264a50SDave May   c1 = (xe - 2 - Xs + 1) + (ye - 2 - Ys + 1) * (Xe - Xs);
6205264a50SDave May 
63a5f152d1SDave May   gmin_l[0] = PetscRealPart(_coor[2 * c0 + 0]);
64a5f152d1SDave May   gmin_l[1] = PetscRealPart(_coor[2 * c0 + 1]);
6505264a50SDave May 
66a5f152d1SDave May   gmax_l[0] = PetscRealPart(_coor[2 * c1 + 0]);
67a5f152d1SDave May   gmax_l[1] = PetscRealPart(_coor[2 * c1 + 1]);
6851c42ae6SMatthew G. Knepley   PetscCall(VecRestoreArrayRead(coor, &_coor));
6951c42ae6SMatthew G. Knepley 
7051c42ae6SMatthew G. Knepley   mxlocal = xe - xs - 1;
7151c42ae6SMatthew G. Knepley   mylocal = ye - ys - 1;
7205264a50SDave May 
7305264a50SDave May   dx[0] = (gmax_l[0] - gmin_l[0]) / ((PetscReal)mxlocal);
7405264a50SDave May   dx[1] = (gmax_l[1] - gmin_l[1]) / ((PetscReal)mylocal);
7505264a50SDave May 
769566063dSJacob Faibussowitsch   PetscCall(DMGetBoundingBox(dmregular, gmin, gmax));
7705264a50SDave May 
789566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(pos, &n));
799566063dSJacob Faibussowitsch   PetscCall(VecGetBlockSize(pos, &bs));
8005264a50SDave May   npoints = n / bs;
8105264a50SDave May 
829566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(npoints, &cellidx));
839566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(pos, &_coor));
8405264a50SDave May   for (p = 0; p < npoints; p++) {
850ca99263SDave May     PetscReal coor_p[2];
8605264a50SDave May     PetscInt  mi[2];
8705264a50SDave May 
880ca99263SDave May     coor_p[0] = PetscRealPart(_coor[2 * p]);
890ca99263SDave May     coor_p[1] = PetscRealPart(_coor[2 * p + 1]);
9005264a50SDave May 
9105264a50SDave May     cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND;
9205264a50SDave May 
93ad540459SPierre Jolivet     if (coor_p[0] < gmin_l[0]) continue;
94ad540459SPierre Jolivet     if (coor_p[0] > gmax_l[0]) continue;
95ad540459SPierre Jolivet     if (coor_p[1] < gmin_l[1]) continue;
96ad540459SPierre Jolivet     if (coor_p[1] > gmax_l[1]) continue;
9705264a50SDave May 
98ad540459SPierre Jolivet     for (d = 0; d < 2; d++) mi[d] = (PetscInt)((coor_p[d] - gmin[d]) / dx[d]);
9905264a50SDave May 
100ad540459SPierre Jolivet     if (mi[0] < xs) continue;
101ad540459SPierre Jolivet     if (mi[0] > (xe - 1)) continue;
102ad540459SPierre Jolivet     if (mi[1] < ys) continue;
103ad540459SPierre Jolivet     if (mi[1] > (ye - 1)) continue;
10405264a50SDave May 
105ad540459SPierre Jolivet     if (mi[0] == (xe - 1)) mi[0]--;
106ad540459SPierre Jolivet     if (mi[1] == (ye - 1)) mi[1]--;
10705264a50SDave May 
10805264a50SDave May     cellidx[p] = (mi[0] - xs) + (mi[1] - ys) * mxlocal;
10905264a50SDave May   }
1109566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(pos, &_coor));
1119566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, npoints, cellidx, PETSC_OWN_POINTER, iscell));
11205264a50SDave May   PetscFunctionReturn(0);
11305264a50SDave May }
11405264a50SDave May 
115d71ae5a4SJacob Faibussowitsch PetscErrorCode private_DMDALocatePointsIS_3D_Regular(DM dmregular, Vec pos, IS *iscell)
116d71ae5a4SJacob Faibussowitsch {
11705264a50SDave May   PetscInt           n, bs, p, npoints;
11805264a50SDave May   PetscInt           xs, xe, Xs, Xe, mxlocal;
11905264a50SDave May   PetscInt           ys, ye, Ys, Ye, mylocal;
12005264a50SDave May   PetscInt           zs, ze, Zs, Ze, mzlocal;
121aab5bcd8SJed Brown   PetscInt           d, c0, c1;
12205264a50SDave May   PetscReal          gmin_l[3], gmax_l[3], dx[3];
12305264a50SDave May   PetscReal          gmin[3], gmax[3];
12405264a50SDave May   PetscInt          *cellidx;
12505264a50SDave May   Vec                coor;
12605264a50SDave May   const PetscScalar *_coor;
12705264a50SDave May 
128aab5bcd8SJed Brown   PetscFunctionBegin;
1299566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(dmregular, &xs, &ys, &zs, &xe, &ye, &ze));
1309566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(dmregular, &Xs, &Ys, &Zs, &Xe, &Ye, &Ze));
1319371c9d4SSatish Balay   xe += xs;
1329371c9d4SSatish Balay   Xe += Xs;
1339371c9d4SSatish Balay   ye += ys;
1349371c9d4SSatish Balay   Ye += Ys;
1359371c9d4SSatish Balay   ze += zs;
1369371c9d4SSatish Balay   Ze += Zs;
13751c42ae6SMatthew G. Knepley   if (xs != Xs && Xs >= 0) xs -= 1;
13851c42ae6SMatthew G. Knepley   if (ys != Ys && Ys >= 0) ys -= 1;
13951c42ae6SMatthew G. Knepley   if (zs != Zs && Zs >= 0) zs -= 1;
14005264a50SDave May 
1419566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinatesLocal(dmregular, &coor));
1429566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(coor, &_coor));
14305264a50SDave May   c0 = (xs - Xs) + (ys - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
14405264a50SDave May   c1 = (xe - 2 - Xs + 1) + (ye - 2 - Ys + 1) * (Xe - Xs) + (ze - 2 - Zs + 1) * (Xe - Xs) * (Ye - Ys);
14505264a50SDave May 
146a5f152d1SDave May   gmin_l[0] = PetscRealPart(_coor[3 * c0 + 0]);
147a5f152d1SDave May   gmin_l[1] = PetscRealPart(_coor[3 * c0 + 1]);
148a5f152d1SDave May   gmin_l[2] = PetscRealPart(_coor[3 * c0 + 2]);
14905264a50SDave May 
150a5f152d1SDave May   gmax_l[0] = PetscRealPart(_coor[3 * c1 + 0]);
151a5f152d1SDave May   gmax_l[1] = PetscRealPart(_coor[3 * c1 + 1]);
152a5f152d1SDave May   gmax_l[2] = PetscRealPart(_coor[3 * c1 + 2]);
15351c42ae6SMatthew G. Knepley   PetscCall(VecRestoreArrayRead(coor, &_coor));
15451c42ae6SMatthew G. Knepley 
15551c42ae6SMatthew G. Knepley   if (xs != Xs) xs -= 1;
15651c42ae6SMatthew G. Knepley   if (ys != Ys) ys -= 1;
15751c42ae6SMatthew G. Knepley   if (zs != Zs) zs -= 1;
15851c42ae6SMatthew G. Knepley 
15951c42ae6SMatthew G. Knepley   mxlocal = xe - xs - 1;
16051c42ae6SMatthew G. Knepley   mylocal = ye - ys - 1;
16151c42ae6SMatthew G. Knepley   mzlocal = ze - zs - 1;
16205264a50SDave May 
16305264a50SDave May   dx[0] = (gmax_l[0] - gmin_l[0]) / ((PetscReal)mxlocal);
16405264a50SDave May   dx[1] = (gmax_l[1] - gmin_l[1]) / ((PetscReal)mylocal);
16505264a50SDave May   dx[2] = (gmax_l[2] - gmin_l[2]) / ((PetscReal)mzlocal);
16605264a50SDave May 
1679566063dSJacob Faibussowitsch   PetscCall(DMGetBoundingBox(dmregular, gmin, gmax));
16805264a50SDave May 
1699566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(pos, &n));
1709566063dSJacob Faibussowitsch   PetscCall(VecGetBlockSize(pos, &bs));
17105264a50SDave May   npoints = n / bs;
17205264a50SDave May 
1739566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(npoints, &cellidx));
1749566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(pos, &_coor));
17505264a50SDave May   for (p = 0; p < npoints; p++) {
1760ca99263SDave May     PetscReal coor_p[3];
17705264a50SDave May     PetscInt  mi[3];
17805264a50SDave May 
1790ca99263SDave May     coor_p[0] = PetscRealPart(_coor[3 * p]);
1800ca99263SDave May     coor_p[1] = PetscRealPart(_coor[3 * p + 1]);
1810ca99263SDave May     coor_p[2] = PetscRealPart(_coor[3 * p + 2]);
18205264a50SDave May 
18305264a50SDave May     cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND;
18405264a50SDave May 
185ad540459SPierre Jolivet     if (coor_p[0] < gmin_l[0]) continue;
186ad540459SPierre Jolivet     if (coor_p[0] > gmax_l[0]) continue;
187ad540459SPierre Jolivet     if (coor_p[1] < gmin_l[1]) continue;
188ad540459SPierre Jolivet     if (coor_p[1] > gmax_l[1]) continue;
189ad540459SPierre Jolivet     if (coor_p[2] < gmin_l[2]) continue;
190ad540459SPierre Jolivet     if (coor_p[2] > gmax_l[2]) continue;
19105264a50SDave May 
192ad540459SPierre Jolivet     for (d = 0; d < 3; d++) mi[d] = (PetscInt)((coor_p[d] - gmin[d]) / dx[d]);
19305264a50SDave May 
194ad540459SPierre Jolivet     if (mi[0] < xs) continue;
195ad540459SPierre Jolivet     if (mi[0] > (xe - 1)) continue;
196ad540459SPierre Jolivet     if (mi[1] < ys) continue;
197ad540459SPierre Jolivet     if (mi[1] > (ye - 1)) continue;
198ad540459SPierre Jolivet     if (mi[2] < zs) continue;
199ad540459SPierre Jolivet     if (mi[2] > (ze - 1)) continue;
20005264a50SDave May 
201ad540459SPierre Jolivet     if (mi[0] == (xe - 1)) mi[0]--;
202ad540459SPierre Jolivet     if (mi[1] == (ye - 1)) mi[1]--;
203ad540459SPierre Jolivet     if (mi[2] == (ze - 1)) mi[2]--;
20405264a50SDave May 
20505264a50SDave May     cellidx[p] = (mi[0] - xs) + (mi[1] - ys) * mxlocal + (mi[2] - zs) * mxlocal * mylocal;
20605264a50SDave May   }
2079566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(pos, &_coor));
2089566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, npoints, cellidx, PETSC_OWN_POINTER, iscell));
20905264a50SDave May   PetscFunctionReturn(0);
21005264a50SDave May }
21105264a50SDave May 
212d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocatePoints_DA_Regular(DM dm, Vec pos, DMPointLocationType ltype, PetscSF cellSF)
213d71ae5a4SJacob Faibussowitsch {
21405264a50SDave May   IS              iscell;
21505264a50SDave May   PetscSFNode    *cells;
21605264a50SDave May   PetscInt        p, bs, dim, npoints, nfound;
21705264a50SDave May   const PetscInt *boxCells;
21805264a50SDave May 
21905264a50SDave May   PetscFunctionBegin;
2209566063dSJacob Faibussowitsch   PetscCall(VecGetBlockSize(pos, &dim));
22105264a50SDave May   switch (dim) {
222d71ae5a4SJacob Faibussowitsch   case 1:
223d71ae5a4SJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Support not provided for 1D");
224d71ae5a4SJacob Faibussowitsch   case 2:
225d71ae5a4SJacob Faibussowitsch     PetscCall(private_DMDALocatePointsIS_2D_Regular(dm, pos, &iscell));
226d71ae5a4SJacob Faibussowitsch     break;
227d71ae5a4SJacob Faibussowitsch   case 3:
228d71ae5a4SJacob Faibussowitsch     PetscCall(private_DMDALocatePointsIS_3D_Regular(dm, pos, &iscell));
229d71ae5a4SJacob Faibussowitsch     break;
230d71ae5a4SJacob Faibussowitsch   default:
231d71ae5a4SJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupport spatial dimension");
23205264a50SDave May   }
23305264a50SDave May 
2349566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(pos, &npoints));
2359566063dSJacob Faibussowitsch   PetscCall(VecGetBlockSize(pos, &bs));
23605264a50SDave May   npoints = npoints / bs;
23705264a50SDave May 
2389566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(npoints, &cells));
2399566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscell, &boxCells));
24005264a50SDave May 
24105264a50SDave May   for (p = 0; p < npoints; p++) {
24205264a50SDave May     cells[p].rank  = 0;
24305264a50SDave May     cells[p].index = boxCells[p];
24405264a50SDave May   }
2459566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscell, &boxCells));
24605264a50SDave May 
24705264a50SDave May   nfound = npoints;
2489566063dSJacob Faibussowitsch   PetscCall(PetscSFSetGraph(cellSF, npoints, nfound, NULL, PETSC_OWN_POINTER, cells, PETSC_OWN_POINTER));
2499566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&iscell));
25005264a50SDave May   PetscFunctionReturn(0);
25105264a50SDave May }
252