Actual source code: dageometry.c

  1: #include <petscsf.h>
  2: #include <petsc/private/dmdaimpl.h>

  4: /*@
  5:   DMDAConvertToCell - Convert (i,j,k) to local cell number

  7:   Not Collective

  9:   Input Parameters:
 10: + da - the distributed array
 11: - s - A MatStencil giving (i,j,k)

 13:   Output Parameter:
 14: . cell - the local cell number

 16:   Level: developer
 17: @*/
 18: PetscErrorCode DMDAConvertToCell(DM dm, MatStencil s, PetscInt *cell)
 19: {
 20:   DM_DA         *da  = (DM_DA *)dm->data;
 21:   const PetscInt dim = dm->dim;
 22:   const PetscInt mx = (da->Xe - da->Xs) / da->w, my = da->Ye - da->Ys /*, mz = da->Ze - da->Zs*/;
 23:   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;

 25:   *cell = -1;
 29:   *cell = (kl * my + jl) * mx + il;
 30:   return 0;
 31: }

 33: PetscErrorCode private_DMDALocatePointsIS_2D_Regular(DM dmregular, Vec pos, IS *iscell)
 34: {
 35:   PetscInt           n, bs, p, npoints;
 36:   PetscInt           xs, xe, Xs, Xe, mxlocal;
 37:   PetscInt           ys, ye, Ys, Ye, mylocal;
 38:   PetscInt           d, c0, c1;
 39:   PetscReal          gmin_l[2], gmax_l[2], dx[2];
 40:   PetscReal          gmin[2], gmax[2];
 41:   PetscInt          *cellidx;
 42:   Vec                coor;
 43:   const PetscScalar *_coor;

 45:   DMDAGetCorners(dmregular, &xs, &ys, NULL, &xe, &ye, NULL);
 46:   DMDAGetGhostCorners(dmregular, &Xs, &Ys, NULL, &Xe, &Ye, NULL);
 47:   xe += xs;
 48:   Xe += Xs;
 49:   if (xs != Xs) xs -= 1;
 50:   ye += ys;
 51:   Ye += Ys;
 52:   if (ys != Ys) ys -= 1;

 54:   mxlocal = xe - xs - 1;
 55:   mylocal = ye - ys - 1;

 57:   DMGetCoordinatesLocal(dmregular, &coor);
 58:   VecGetArrayRead(coor, &_coor);
 59:   c0 = (xs - Xs) + (ys - Ys) * (Xe - Xs);
 60:   c1 = (xe - 2 - Xs + 1) + (ye - 2 - Ys + 1) * (Xe - Xs);

 62:   gmin_l[0] = PetscRealPart(_coor[2 * c0 + 0]);
 63:   gmin_l[1] = PetscRealPart(_coor[2 * c0 + 1]);

 65:   gmax_l[0] = PetscRealPart(_coor[2 * c1 + 0]);
 66:   gmax_l[1] = PetscRealPart(_coor[2 * c1 + 1]);

 68:   dx[0] = (gmax_l[0] - gmin_l[0]) / ((PetscReal)mxlocal);
 69:   dx[1] = (gmax_l[1] - gmin_l[1]) / ((PetscReal)mylocal);

 71:   VecRestoreArrayRead(coor, &_coor);

 73:   DMGetBoundingBox(dmregular, gmin, gmax);

 75:   VecGetLocalSize(pos, &n);
 76:   VecGetBlockSize(pos, &bs);
 77:   npoints = n / bs;

 79:   PetscMalloc1(npoints, &cellidx);
 80:   VecGetArrayRead(pos, &_coor);
 81:   for (p = 0; p < npoints; p++) {
 82:     PetscReal coor_p[2];
 83:     PetscInt  mi[2];

 85:     coor_p[0] = PetscRealPart(_coor[2 * p]);
 86:     coor_p[1] = PetscRealPart(_coor[2 * p + 1]);

 88:     cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND;

 90:     if (coor_p[0] < gmin_l[0]) continue;
 91:     if (coor_p[0] > gmax_l[0]) continue;
 92:     if (coor_p[1] < gmin_l[1]) continue;
 93:     if (coor_p[1] > gmax_l[1]) continue;

 95:     for (d = 0; d < 2; d++) mi[d] = (PetscInt)((coor_p[d] - gmin[d]) / dx[d]);

 97:     if (mi[0] < xs) continue;
 98:     if (mi[0] > (xe - 1)) continue;
 99:     if (mi[1] < ys) continue;
100:     if (mi[1] > (ye - 1)) continue;

102:     if (mi[0] == (xe - 1)) mi[0]--;
103:     if (mi[1] == (ye - 1)) mi[1]--;

105:     cellidx[p] = (mi[0] - xs) + (mi[1] - ys) * mxlocal;
106:   }
107:   VecRestoreArrayRead(pos, &_coor);
108:   ISCreateGeneral(PETSC_COMM_SELF, npoints, cellidx, PETSC_OWN_POINTER, iscell);
109:   return 0;
110: }

112: PetscErrorCode private_DMDALocatePointsIS_3D_Regular(DM dmregular, Vec pos, IS *iscell)
113: {
114:   PetscInt           n, bs, p, npoints;
115:   PetscInt           xs, xe, Xs, Xe, mxlocal;
116:   PetscInt           ys, ye, Ys, Ye, mylocal;
117:   PetscInt           zs, ze, Zs, Ze, mzlocal;
118:   PetscInt           d, c0, c1;
119:   PetscReal          gmin_l[3], gmax_l[3], dx[3];
120:   PetscReal          gmin[3], gmax[3];
121:   PetscInt          *cellidx;
122:   Vec                coor;
123:   const PetscScalar *_coor;

125:   DMDAGetCorners(dmregular, &xs, &ys, &zs, &xe, &ye, &ze);
126:   DMDAGetGhostCorners(dmregular, &Xs, &Ys, &Zs, &Xe, &Ye, &Ze);
127:   xe += xs;
128:   Xe += Xs;
129:   if (xs != Xs) xs -= 1;
130:   ye += ys;
131:   Ye += Ys;
132:   if (ys != Ys) ys -= 1;
133:   ze += zs;
134:   Ze += Zs;
135:   if (zs != Zs) zs -= 1;

137:   mxlocal = xe - xs - 1;
138:   mylocal = ye - ys - 1;
139:   mzlocal = ze - zs - 1;

141:   DMGetCoordinatesLocal(dmregular, &coor);
142:   VecGetArrayRead(coor, &_coor);
143:   c0 = (xs - Xs) + (ys - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
144:   c1 = (xe - 2 - Xs + 1) + (ye - 2 - Ys + 1) * (Xe - Xs) + (ze - 2 - Zs + 1) * (Xe - Xs) * (Ye - Ys);

146:   gmin_l[0] = PetscRealPart(_coor[3 * c0 + 0]);
147:   gmin_l[1] = PetscRealPart(_coor[3 * c0 + 1]);
148:   gmin_l[2] = PetscRealPart(_coor[3 * c0 + 2]);

150:   gmax_l[0] = PetscRealPart(_coor[3 * c1 + 0]);
151:   gmax_l[1] = PetscRealPart(_coor[3 * c1 + 1]);
152:   gmax_l[2] = PetscRealPart(_coor[3 * c1 + 2]);

154:   dx[0] = (gmax_l[0] - gmin_l[0]) / ((PetscReal)mxlocal);
155:   dx[1] = (gmax_l[1] - gmin_l[1]) / ((PetscReal)mylocal);
156:   dx[2] = (gmax_l[2] - gmin_l[2]) / ((PetscReal)mzlocal);

158:   VecRestoreArrayRead(coor, &_coor);

160:   DMGetBoundingBox(dmregular, gmin, gmax);

162:   VecGetLocalSize(pos, &n);
163:   VecGetBlockSize(pos, &bs);
164:   npoints = n / bs;

166:   PetscMalloc1(npoints, &cellidx);
167:   VecGetArrayRead(pos, &_coor);
168:   for (p = 0; p < npoints; p++) {
169:     PetscReal coor_p[3];
170:     PetscInt  mi[3];

172:     coor_p[0] = PetscRealPart(_coor[3 * p]);
173:     coor_p[1] = PetscRealPart(_coor[3 * p + 1]);
174:     coor_p[2] = PetscRealPart(_coor[3 * p + 2]);

176:     cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND;

178:     if (coor_p[0] < gmin_l[0]) continue;
179:     if (coor_p[0] > gmax_l[0]) continue;
180:     if (coor_p[1] < gmin_l[1]) continue;
181:     if (coor_p[1] > gmax_l[1]) continue;
182:     if (coor_p[2] < gmin_l[2]) continue;
183:     if (coor_p[2] > gmax_l[2]) continue;

185:     for (d = 0; d < 3; d++) mi[d] = (PetscInt)((coor_p[d] - gmin[d]) / dx[d]);

187:     if (mi[0] < xs) continue;
188:     if (mi[0] > (xe - 1)) continue;
189:     if (mi[1] < ys) continue;
190:     if (mi[1] > (ye - 1)) continue;
191:     if (mi[2] < zs) continue;
192:     if (mi[2] > (ze - 1)) continue;

194:     if (mi[0] == (xe - 1)) mi[0]--;
195:     if (mi[1] == (ye - 1)) mi[1]--;
196:     if (mi[2] == (ze - 1)) mi[2]--;

198:     cellidx[p] = (mi[0] - xs) + (mi[1] - ys) * mxlocal + (mi[2] - zs) * mxlocal * mylocal;
199:   }
200:   VecRestoreArrayRead(pos, &_coor);
201:   ISCreateGeneral(PETSC_COMM_SELF, npoints, cellidx, PETSC_OWN_POINTER, iscell);
202:   return 0;
203: }

205: PetscErrorCode DMLocatePoints_DA_Regular(DM dm, Vec pos, DMPointLocationType ltype, PetscSF cellSF)
206: {
207:   IS              iscell;
208:   PetscSFNode    *cells;
209:   PetscInt        p, bs, dim, npoints, nfound;
210:   const PetscInt *boxCells;

212:   VecGetBlockSize(pos, &dim);
213:   switch (dim) {
214:   case 1:
215:     SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Support not provided for 1D");
216:   case 2:
217:     private_DMDALocatePointsIS_2D_Regular(dm, pos, &iscell);
218:     break;
219:   case 3:
220:     private_DMDALocatePointsIS_3D_Regular(dm, pos, &iscell);
221:     break;
222:   default:
223:     SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupport spatial dimension");
224:   }

226:   VecGetLocalSize(pos, &npoints);
227:   VecGetBlockSize(pos, &bs);
228:   npoints = npoints / bs;

230:   PetscMalloc1(npoints, &cells);
231:   ISGetIndices(iscell, &boxCells);

233:   for (p = 0; p < npoints; p++) {
234:     cells[p].rank  = 0;
235:     cells[p].index = boxCells[p];
236:   }
237:   ISRestoreIndices(iscell, &boxCells);

239:   nfound = npoints;
240:   PetscSFSetGraph(cellSF, npoints, nfound, NULL, PETSC_OWN_POINTER, cells, PETSC_OWN_POINTER);
241:   ISDestroy(&iscell);
242:   return 0;
243: }