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