xref: /petsc/src/dm/impls/da/dageometry.c (revision ea78f98c112368f404cd6d4fff6d4dfe73e5a1e7)
105264a50SDave May #include <petscsf.h>
2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h>     /*I  "petscdmda.h"   I*/
357459e9aSMatthew G Knepley 
457459e9aSMatthew G Knepley 
5ed4e918cSMatthew G Knepley /*@
6f0e3914cSSatish Balay   DMDAConvertToCell - Convert (i,j,k) to local cell number
7341c9bdaSMatthew G Knepley 
8ed4e918cSMatthew G Knepley   Not Collective
9ed4e918cSMatthew G Knepley 
10ed4e918cSMatthew G Knepley   Input Parameter:
11ed4e918cSMatthew G Knepley + da - the distributed array
12907376e6SBarry Smith - s - A MatStencil giving (i,j,k)
13ed4e918cSMatthew G Knepley 
14ed4e918cSMatthew G Knepley   Output Parameter:
15ed4e918cSMatthew G Knepley . cell - the local cell number
16ed4e918cSMatthew G Knepley 
17ed4e918cSMatthew G Knepley   Level: developer
18ed4e918cSMatthew G Knepley 
19ed4e918cSMatthew G Knepley .seealso: DMDAVecGetClosure()
20ed4e918cSMatthew G Knepley @*/
21ed4e918cSMatthew G Knepley PetscErrorCode DMDAConvertToCell(DM dm, MatStencil s, PetscInt *cell)
22341c9bdaSMatthew G Knepley {
23341c9bdaSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
24c73cfb54SMatthew G. Knepley   const PetscInt dim = dm->dim;
254e846693SMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys /*, mz = da->Ze - da->Zs*/;
26ed4e918cSMatthew 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;
27341c9bdaSMatthew G Knepley 
28341c9bdaSMatthew G Knepley   PetscFunctionBegin;
29ed4e918cSMatthew G Knepley   *cell = -1;
30cb004a26SBarry Smith   if ((s.i < da->Xs/da->w) || (s.i >= da->Xe/da->w))    SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Stencil i %D should be in [%D, %D)", s.i, da->Xs/da->w, da->Xe/da->w);
31cb004a26SBarry Smith   if ((dim > 1) && ((s.j < da->Ys) || (s.j >= da->Ye))) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Stencil j %D should be in [%D, %D)", s.j, da->Ys, da->Ye);
32cb004a26SBarry Smith   if ((dim > 2) && ((s.k < da->Zs) || (s.k >= da->Ze))) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Stencil k %D should be in [%D, %D)", s.k, da->Zs, da->Ze);
33ed4e918cSMatthew G Knepley   *cell = (kl*my + jl)*mx + il;
34ed4e918cSMatthew G Knepley   PetscFunctionReturn(0);
35341c9bdaSMatthew G Knepley }
36341c9bdaSMatthew G Knepley 
3705264a50SDave May PetscErrorCode private_DMDALocatePointsIS_2D_Regular(DM dmregular,Vec pos,IS *iscell)
3805264a50SDave May {
3905264a50SDave May   PetscInt          n,bs,p,npoints;
4005264a50SDave May   PetscInt          xs,xe,Xs,Xe,mxlocal;
4105264a50SDave May   PetscInt          ys,ye,Ys,Ye,mylocal;
42aab5bcd8SJed Brown   PetscInt          d,c0,c1;
4305264a50SDave May   PetscReal         gmin_l[2],gmax_l[2],dx[2];
4405264a50SDave May   PetscReal         gmin[2],gmax[2];
4505264a50SDave May   PetscInt          *cellidx;
4605264a50SDave May   Vec               coor;
4705264a50SDave May   const PetscScalar *_coor;
4805264a50SDave May   PetscErrorCode    ierr;
4905264a50SDave May 
50aab5bcd8SJed Brown   PetscFunctionBegin;
51*ea78f98cSLisandro Dalcin   ierr = DMDAGetCorners(dmregular,&xs,&ys,NULL,&xe,&ye,NULL);CHKERRQ(ierr);
52*ea78f98cSLisandro Dalcin   ierr = DMDAGetGhostCorners(dmregular,&Xs,&Ys,NULL,&Xe,&Ye,NULL);CHKERRQ(ierr);
5305264a50SDave May   xe += xs; Xe += Xs; if (xs != Xs) xs -= 1;
5405264a50SDave May   ye += ys; Ye += Ys; if (ys != Ys) ys -= 1;
5505264a50SDave May 
5605264a50SDave May   mxlocal = xe - xs - 1;
5705264a50SDave May   mylocal = ye - ys - 1;
5805264a50SDave May 
5905264a50SDave May   ierr = DMGetCoordinatesLocal(dmregular,&coor);CHKERRQ(ierr);
6005264a50SDave May   ierr = VecGetArrayRead(coor,&_coor);CHKERRQ(ierr);
6105264a50SDave May   c0 = (xs-Xs) + (ys-Ys)*(Xe-Xs);
6205264a50SDave May   c1 = (xe-2-Xs+1) + (ye-2-Ys+1)*(Xe-Xs);
6305264a50SDave May 
64a5f152d1SDave May   gmin_l[0] = PetscRealPart(_coor[2*c0+0]);
65a5f152d1SDave May   gmin_l[1] = PetscRealPart(_coor[2*c0+1]);
6605264a50SDave May 
67a5f152d1SDave May   gmax_l[0] = PetscRealPart(_coor[2*c1+0]);
68a5f152d1SDave May   gmax_l[1] = PetscRealPart(_coor[2*c1+1]);
6905264a50SDave May 
7005264a50SDave May   dx[0] = (gmax_l[0]-gmin_l[0])/((PetscReal)mxlocal);
7105264a50SDave May   dx[1] = (gmax_l[1]-gmin_l[1])/((PetscReal)mylocal);
7205264a50SDave May 
7305264a50SDave May   ierr = VecRestoreArrayRead(coor,&_coor);CHKERRQ(ierr);
7405264a50SDave May 
75c5daea06SMatthew G. Knepley   ierr = DMGetBoundingBox(dmregular,gmin,gmax);CHKERRQ(ierr);
7605264a50SDave May 
7705264a50SDave May   ierr = VecGetLocalSize(pos,&n);CHKERRQ(ierr);
7805264a50SDave May   ierr = VecGetBlockSize(pos,&bs);CHKERRQ(ierr);
7905264a50SDave May   npoints = n/bs;
8005264a50SDave May 
8105264a50SDave May   ierr = PetscMalloc1(npoints,&cellidx);CHKERRQ(ierr);
8205264a50SDave May   ierr = VecGetArrayRead(pos,&_coor);CHKERRQ(ierr);
8305264a50SDave May   for (p=0; p<npoints; p++) {
840ca99263SDave May     PetscReal coor_p[2];
8505264a50SDave May     PetscInt  mi[2];
8605264a50SDave May 
870ca99263SDave May     coor_p[0] = PetscRealPart(_coor[2*p]);
880ca99263SDave May     coor_p[1] = PetscRealPart(_coor[2*p+1]);
8905264a50SDave May 
9005264a50SDave May     cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND;
9105264a50SDave May 
920ca99263SDave May     if (coor_p[0] < gmin_l[0]) { continue; }
930ca99263SDave May     if (coor_p[0] > gmax_l[0]) { continue; }
940ca99263SDave May     if (coor_p[1] < gmin_l[1]) { continue; }
950ca99263SDave May     if (coor_p[1] > gmax_l[1]) { continue; }
9605264a50SDave May 
97aab5bcd8SJed Brown     for (d=0; d<2; d++) {
9805264a50SDave May       mi[d] = (PetscInt)( (coor_p[d] - gmin[d])/dx[d] );
9905264a50SDave May     }
10005264a50SDave May 
10105264a50SDave May     if (mi[0] < xs)     { continue; }
10205264a50SDave May     if (mi[0] > (xe-1)) { continue; }
10305264a50SDave May     if (mi[1] < ys)     { continue; }
10405264a50SDave May     if (mi[1] > (ye-1)) { continue; }
10505264a50SDave May 
10605264a50SDave May     if (mi[0] == (xe-1)) { mi[0]--; }
10705264a50SDave May     if (mi[1] == (ye-1)) { mi[1]--; }
10805264a50SDave May 
10905264a50SDave May     cellidx[p] = (mi[0]-xs) + (mi[1]-ys) * mxlocal;
11005264a50SDave May   }
11105264a50SDave May   ierr = VecRestoreArrayRead(pos,&_coor);CHKERRQ(ierr);
11205264a50SDave May   ierr = ISCreateGeneral(PETSC_COMM_SELF,npoints,cellidx,PETSC_OWN_POINTER,iscell);CHKERRQ(ierr);
11305264a50SDave May   PetscFunctionReturn(0);
11405264a50SDave May }
11505264a50SDave May 
11605264a50SDave May PetscErrorCode private_DMDALocatePointsIS_3D_Regular(DM dmregular,Vec pos,IS *iscell)
11705264a50SDave May {
11805264a50SDave May   PetscInt          n,bs,p,npoints;
11905264a50SDave May   PetscInt          xs,xe,Xs,Xe,mxlocal;
12005264a50SDave May   PetscInt          ys,ye,Ys,Ye,mylocal;
12105264a50SDave May   PetscInt          zs,ze,Zs,Ze,mzlocal;
122aab5bcd8SJed Brown   PetscInt          d,c0,c1;
12305264a50SDave May   PetscReal         gmin_l[3],gmax_l[3],dx[3];
12405264a50SDave May   PetscReal         gmin[3],gmax[3];
12505264a50SDave May   PetscInt          *cellidx;
12605264a50SDave May   Vec               coor;
12705264a50SDave May   const PetscScalar *_coor;
12805264a50SDave May   PetscErrorCode    ierr;
12905264a50SDave May 
130aab5bcd8SJed Brown   PetscFunctionBegin;
13105264a50SDave May   ierr = DMDAGetCorners(dmregular,&xs,&ys,&zs,&xe,&ye,&ze);CHKERRQ(ierr);
13205264a50SDave May   ierr = DMDAGetGhostCorners(dmregular,&Xs,&Ys,&Zs,&Xe,&Ye,&Ze);CHKERRQ(ierr);
13305264a50SDave May   xe += xs; Xe += Xs; if (xs != Xs) xs -= 1;
13405264a50SDave May   ye += ys; Ye += Ys; if (ys != Ys) ys -= 1;
13505264a50SDave May   ze += zs; Ze += Zs; if (zs != Zs) zs -= 1;
13605264a50SDave May 
13705264a50SDave May   mxlocal = xe - xs - 1;
13805264a50SDave May   mylocal = ye - ys - 1;
13905264a50SDave May   mzlocal = ze - zs - 1;
14005264a50SDave May 
14105264a50SDave May   ierr = DMGetCoordinatesLocal(dmregular,&coor);CHKERRQ(ierr);
14205264a50SDave May   ierr = VecGetArrayRead(coor,&_coor);CHKERRQ(ierr);
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]);
15305264a50SDave May 
15405264a50SDave May   dx[0] = (gmax_l[0]-gmin_l[0])/((PetscReal)mxlocal);
15505264a50SDave May   dx[1] = (gmax_l[1]-gmin_l[1])/((PetscReal)mylocal);
15605264a50SDave May   dx[2] = (gmax_l[2]-gmin_l[2])/((PetscReal)mzlocal);
15705264a50SDave May 
15805264a50SDave May   ierr = VecRestoreArrayRead(coor,&_coor);CHKERRQ(ierr);
15905264a50SDave May 
160c5daea06SMatthew G. Knepley   ierr = DMGetBoundingBox(dmregular,gmin,gmax);CHKERRQ(ierr);
16105264a50SDave May 
16205264a50SDave May   ierr = VecGetLocalSize(pos,&n);CHKERRQ(ierr);
16305264a50SDave May   ierr = VecGetBlockSize(pos,&bs);CHKERRQ(ierr);
16405264a50SDave May   npoints = n/bs;
16505264a50SDave May 
16605264a50SDave May   ierr = PetscMalloc1(npoints,&cellidx);CHKERRQ(ierr);
16705264a50SDave May   ierr = VecGetArrayRead(pos,&_coor);CHKERRQ(ierr);
16805264a50SDave May   for (p=0; p<npoints; p++) {
1690ca99263SDave May     PetscReal coor_p[3];
17005264a50SDave May     PetscInt  mi[3];
17105264a50SDave May 
1720ca99263SDave May     coor_p[0] = PetscRealPart(_coor[3*p]);
1730ca99263SDave May     coor_p[1] = PetscRealPart(_coor[3*p+1]);
1740ca99263SDave May     coor_p[2] = PetscRealPart(_coor[3*p+2]);
17505264a50SDave May 
17605264a50SDave May     cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND;
17705264a50SDave May 
1780ca99263SDave May     if (coor_p[0] < gmin_l[0]) { continue; }
1790ca99263SDave May     if (coor_p[0] > gmax_l[0]) { continue; }
1800ca99263SDave May     if (coor_p[1] < gmin_l[1]) { continue; }
1810ca99263SDave May     if (coor_p[1] > gmax_l[1]) { continue; }
1820ca99263SDave May     if (coor_p[2] < gmin_l[2]) { continue; }
1830ca99263SDave May     if (coor_p[2] > gmax_l[2]) { continue; }
18405264a50SDave May 
185aab5bcd8SJed Brown     for (d=0; d<3; d++) {
18605264a50SDave May       mi[d] = (PetscInt)( (coor_p[d] - gmin[d])/dx[d] );
18705264a50SDave May     }
18805264a50SDave May 
18905264a50SDave May     if (mi[0] < xs)     { continue; }
19005264a50SDave May     if (mi[0] > (xe-1)) { continue; }
19105264a50SDave May     if (mi[1] < ys)     { continue; }
19205264a50SDave May     if (mi[1] > (ye-1)) { continue; }
19305264a50SDave May     if (mi[2] < zs)     { continue; }
19405264a50SDave May     if (mi[2] > (ze-1)) { continue; }
19505264a50SDave May 
19605264a50SDave May     if (mi[0] == (xe-1)) { mi[0]--; }
19705264a50SDave May     if (mi[1] == (ye-1)) { mi[1]--; }
19805264a50SDave May     if (mi[2] == (ze-1)) { mi[2]--; }
19905264a50SDave May 
20005264a50SDave May     cellidx[p] = (mi[0]-xs) + (mi[1]-ys) * mxlocal + (mi[2]-zs) * mxlocal * mylocal;
20105264a50SDave May   }
20205264a50SDave May   ierr = VecRestoreArrayRead(pos,&_coor);CHKERRQ(ierr);
20305264a50SDave May   ierr = ISCreateGeneral(PETSC_COMM_SELF,npoints,cellidx,PETSC_OWN_POINTER,iscell);CHKERRQ(ierr);
20405264a50SDave May   PetscFunctionReturn(0);
20505264a50SDave May }
20605264a50SDave May 
20705264a50SDave May PetscErrorCode DMLocatePoints_DA_Regular(DM dm,Vec pos,DMPointLocationType ltype,PetscSF cellSF)
20805264a50SDave May {
20905264a50SDave May   IS             iscell;
21005264a50SDave May   PetscSFNode    *cells;
21105264a50SDave May   PetscInt       p,bs,dim,npoints,nfound;
21205264a50SDave May   const PetscInt *boxCells;
21305264a50SDave May   PetscErrorCode ierr;
21405264a50SDave May 
21505264a50SDave May   PetscFunctionBegin;
21605264a50SDave May   ierr = VecGetBlockSize(pos,&dim);CHKERRQ(ierr);
21705264a50SDave May   switch (dim) {
21805264a50SDave May     case 1:
21905264a50SDave May       SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Support not provided for 1D");
22005264a50SDave May       break;
22105264a50SDave May     case 2:
22205264a50SDave May       ierr = private_DMDALocatePointsIS_2D_Regular(dm,pos,&iscell);CHKERRQ(ierr);
22305264a50SDave May       break;
22405264a50SDave May     case 3:
22505264a50SDave May       ierr = private_DMDALocatePointsIS_3D_Regular(dm,pos,&iscell);CHKERRQ(ierr);
22605264a50SDave May       break;
22705264a50SDave May     default:
22805264a50SDave May       SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Unsupport spatial dimension");
22905264a50SDave May       break;
23005264a50SDave May   }
23105264a50SDave May 
23205264a50SDave May   ierr = VecGetLocalSize(pos,&npoints);CHKERRQ(ierr);
23305264a50SDave May   ierr = VecGetBlockSize(pos,&bs);CHKERRQ(ierr);
23405264a50SDave May   npoints = npoints / bs;
23505264a50SDave May 
23605264a50SDave May   ierr = PetscMalloc1(npoints, &cells);CHKERRQ(ierr);
23705264a50SDave May   ierr = ISGetIndices(iscell, &boxCells);CHKERRQ(ierr);
23805264a50SDave May 
23905264a50SDave May   for (p=0; p<npoints; p++) {
24005264a50SDave May     cells[p].rank  = 0;
24105264a50SDave May     cells[p].index = boxCells[p];
24205264a50SDave May   }
24305264a50SDave May   ierr = ISRestoreIndices(iscell, &boxCells);CHKERRQ(ierr);
24405264a50SDave May 
24505264a50SDave May   nfound = npoints;
24605264a50SDave May   ierr = PetscSFSetGraph(cellSF, npoints, nfound, NULL, PETSC_OWN_POINTER, cells, PETSC_OWN_POINTER);CHKERRQ(ierr);
24705264a50SDave May   ierr = ISDestroy(&iscell);CHKERRQ(ierr);
24805264a50SDave May   PetscFunctionReturn(0);
24905264a50SDave May }
250