xref: /petsc/src/dm/impls/da/dacorn.c (revision 320964c43e5835503d2bb93f219e28335f8c67fc)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6b45d2f2cSJed Brown #include <petsc-private/daimpl.h>    /*I   "petscdmda.h"   I*/
747c6ae99SBarry Smith 
847c6ae99SBarry Smith #undef __FUNCT__
9aa219208SBarry Smith #define __FUNCT__ "DMDASetCoordinates"
1047c6ae99SBarry Smith /*@
11aa219208SBarry Smith    DMDASetCoordinates - Sets into the DMDA a vector that indicates the
1247c6ae99SBarry Smith       coordinates of the local nodes (NOT including ghost nodes).
1347c6ae99SBarry Smith 
14aa219208SBarry Smith    Collective on DMDA
1547c6ae99SBarry Smith 
1647c6ae99SBarry Smith    Input Parameter:
1747c6ae99SBarry Smith +  da - the distributed array
1847c6ae99SBarry Smith -  c - coordinate vector
1947c6ae99SBarry Smith 
2047c6ae99SBarry Smith    Note:
2147c6ae99SBarry Smith     The coordinates should NOT include those for all ghost points
2247c6ae99SBarry Smith 
2347c6ae99SBarry Smith   Level: intermediate
2447c6ae99SBarry Smith 
2547c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
2647c6ae99SBarry Smith 
27ce00eea3SSatish Balay .seealso: DMDASetGhostCoordinates(), DMDAGetGhostCorners(), DMDAGetCoordinates(), DMDASetUniformCoordinates(). DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA()
2847c6ae99SBarry Smith @*/
297087cfbeSBarry Smith PetscErrorCode  DMDASetCoordinates(DM da,Vec c)
3047c6ae99SBarry Smith {
3147c6ae99SBarry Smith   PetscErrorCode ierr;
3247c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
33401ddaa8SBarry Smith   PetscInt       bs;
3447c6ae99SBarry Smith 
3547c6ae99SBarry Smith   PetscFunctionBegin;
3647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
3747c6ae99SBarry Smith   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
38401ddaa8SBarry Smith   ierr = VecGetBlockSize(c,&bs);CHKERRQ(ierr);
39401ddaa8SBarry Smith   if (bs != dd->dim) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_INCOMP,"Block size of vector must match dimension of DMDA");
4047c6ae99SBarry Smith   ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr);
4196e147daSBarry Smith   ierr = VecDestroy(&dd->coordinates);CHKERRQ(ierr);
4247c6ae99SBarry Smith   dd->coordinates = c;
43fcfd50ebSBarry Smith   ierr = VecDestroy(&dd->ghosted_coordinates);CHKERRQ(ierr);
4447c6ae99SBarry Smith   PetscFunctionReturn(0);
4547c6ae99SBarry Smith }
4647c6ae99SBarry Smith 
4747c6ae99SBarry Smith #undef __FUNCT__
48ce00eea3SSatish Balay #define __FUNCT__ "DMDASetGhostedCoordinates"
49ce00eea3SSatish Balay /*@
50ce00eea3SSatish Balay    DMDASetGhostedCoordinates - Sets into the DMDA a vector that indicates the
51ce00eea3SSatish Balay       coordinates of the local nodes, including ghost nodes.
52ce00eea3SSatish Balay 
53ce00eea3SSatish Balay    Collective on DMDA
54ce00eea3SSatish Balay 
55ce00eea3SSatish Balay    Input Parameter:
56ce00eea3SSatish Balay +  da - the distributed array
57ce00eea3SSatish Balay -  c - coordinate vector
58ce00eea3SSatish Balay 
59ce00eea3SSatish Balay    Note:
60ce00eea3SSatish Balay     The coordinates of interior ghost points can be set using DMDASetCoordinates()
61ce00eea3SSatish Balay     followed by DMDAGetGhostedCoordinates().  This is intended to enable the setting
62ce00eea3SSatish Balay     of ghost coordinates outside of the domain.
63ce00eea3SSatish Balay 
64ce00eea3SSatish Balay     Non-ghosted coordinates, if set, are assumed still valid.
65ce00eea3SSatish Balay 
66ce00eea3SSatish Balay   Level: intermediate
67ce00eea3SSatish Balay 
68ce00eea3SSatish Balay .keywords: distributed array, get, corners, nodes, local indices, coordinates
69ce00eea3SSatish Balay 
70ce00eea3SSatish Balay .seealso: DMDASetCoordinates(), DMDAGetGhostCorners(), DMDAGetCoordinates(), DMDASetUniformCoordinates(). DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA()
71ce00eea3SSatish Balay @*/
72ce00eea3SSatish Balay PetscErrorCode  DMDASetGhostedCoordinates(DM da,Vec c)
73ce00eea3SSatish Balay {
74ce00eea3SSatish Balay   PetscErrorCode ierr;
75ce00eea3SSatish Balay   DM_DA          *dd = (DM_DA*)da->data;
76401ddaa8SBarry Smith   PetscInt       bs;
77ce00eea3SSatish Balay 
78ce00eea3SSatish Balay   PetscFunctionBegin;
79ce00eea3SSatish Balay   PetscValidHeaderSpecific(da,DM_CLASSID,1);
80ce00eea3SSatish Balay   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
81401ddaa8SBarry Smith   ierr = VecGetBlockSize(c,&bs);CHKERRQ(ierr);
82401ddaa8SBarry Smith   if (bs != dd->dim) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_INCOMP,"Block size of vector must match dimension of DMDA");
83ce00eea3SSatish Balay   ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr);
8496e147daSBarry Smith   ierr = VecDestroy(&dd->ghosted_coordinates);CHKERRQ(ierr);
85ce00eea3SSatish Balay   dd->ghosted_coordinates = c;
86ce00eea3SSatish Balay   PetscFunctionReturn(0);
87ce00eea3SSatish Balay }
88ce00eea3SSatish Balay 
89ce00eea3SSatish Balay #undef __FUNCT__
90aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinates"
9147c6ae99SBarry Smith /*@
92aa219208SBarry Smith    DMDAGetCoordinates - Gets the node coordinates associated with a DMDA.
9347c6ae99SBarry Smith 
9447c6ae99SBarry Smith    Not Collective
9547c6ae99SBarry Smith 
9647c6ae99SBarry Smith    Input Parameter:
9747c6ae99SBarry Smith .  da - the distributed array
9847c6ae99SBarry Smith 
9947c6ae99SBarry Smith    Output Parameter:
10047c6ae99SBarry Smith .  c - coordinate vector
10147c6ae99SBarry Smith 
10247c6ae99SBarry Smith    Note:
10347c6ae99SBarry Smith     Each process has only the coordinates for its local nodes (does NOT have the
10447c6ae99SBarry Smith   coordinates for the ghost nodes).
10547c6ae99SBarry Smith 
10647c6ae99SBarry Smith     For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
10747c6ae99SBarry Smith     and (x_0,y_0,z_0,x_1,y_1,z_1...)
10847c6ae99SBarry Smith 
10947c6ae99SBarry Smith   Level: intermediate
11047c6ae99SBarry Smith 
11147c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
11247c6ae99SBarry Smith 
113aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA()
11447c6ae99SBarry Smith @*/
1157087cfbeSBarry Smith PetscErrorCode  DMDAGetCoordinates(DM da,Vec *c)
11647c6ae99SBarry Smith {
11747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
11847c6ae99SBarry Smith   PetscFunctionBegin;
11947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
12047c6ae99SBarry Smith   PetscValidPointer(c,2);
12147c6ae99SBarry Smith   *c = dd->coordinates;
12247c6ae99SBarry Smith   PetscFunctionReturn(0);
12347c6ae99SBarry Smith }
12447c6ae99SBarry Smith 
12547c6ae99SBarry Smith #undef __FUNCT__
126aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinateDA"
12747c6ae99SBarry Smith /*@
128aa219208SBarry Smith    DMDAGetCoordinateDA - Gets the DMDA that scatters between global and local DMDA coordinates
12947c6ae99SBarry Smith 
130aa219208SBarry Smith    Collective on DMDA
13147c6ae99SBarry Smith 
13247c6ae99SBarry Smith    Input Parameter:
13347c6ae99SBarry Smith .  da - the distributed array
13447c6ae99SBarry Smith 
13547c6ae99SBarry Smith    Output Parameter:
136aa219208SBarry Smith .  dac - coordinate DMDA
13747c6ae99SBarry Smith 
13847c6ae99SBarry Smith   Level: intermediate
13947c6ae99SBarry Smith 
14047c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
14147c6ae99SBarry Smith 
142aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetGhostedCoordinates()
14347c6ae99SBarry Smith @*/
1447087cfbeSBarry Smith PetscErrorCode  DMDAGetCoordinateDA(DM da,DM *cda)
14547c6ae99SBarry Smith {
14647c6ae99SBarry Smith   PetscMPIInt    size;
14747c6ae99SBarry Smith   PetscErrorCode ierr;
14847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
14947c6ae99SBarry Smith 
15047c6ae99SBarry Smith   PetscFunctionBegin;
15147c6ae99SBarry Smith   if (!dd->da_coordinates) {
15247c6ae99SBarry Smith     ierr = MPI_Comm_size(((PetscObject)da)->comm,&size);CHKERRQ(ierr);
15347c6ae99SBarry Smith     if (dd->dim == 1) {
15447c6ae99SBarry Smith       PetscInt         s,m,*lc,l;
1551321219cSEthan Coon       DMDABoundaryType bx;
1561321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,0,0,0,0,0,0,&s,&bx,0,0,0);CHKERRQ(ierr);
157aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,0,0);CHKERRQ(ierr);
15847c6ae99SBarry Smith       ierr = PetscMalloc(size*sizeof(PetscInt),&lc);CHKERRQ(ierr);
15947c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
1601321219cSEthan Coon       ierr = DMDACreate1d(((PetscObject)da)->comm,bx,m,1,s,lc,&dd->da_coordinates);CHKERRQ(ierr);
16147c6ae99SBarry Smith       ierr = PetscFree(lc);CHKERRQ(ierr);
16247c6ae99SBarry Smith     } else if (dd->dim == 2) {
16347c6ae99SBarry Smith       PetscInt         i,s,m,*lc,*ld,l,k,n,M,N;
1641321219cSEthan Coon       DMDABoundaryType bx,by;
1651321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,&n,0,&M,&N,0,0,&s,&bx,&by,0,0);CHKERRQ(ierr);
166aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,&k,0);CHKERRQ(ierr);
16747c6ae99SBarry Smith       ierr = PetscMalloc2(size,PetscInt,&lc,size,PetscInt,&ld);CHKERRQ(ierr);
16847c6ae99SBarry Smith       /* only first M values in lc matter */
16947c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
17047c6ae99SBarry Smith       /* every Mth value in ld matters */
17147c6ae99SBarry Smith       ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
17247c6ae99SBarry Smith       for ( i=0; i<N; i++) {
17347c6ae99SBarry Smith         ld[i] = ld[M*i];
17447c6ae99SBarry Smith       }
1751321219cSEthan Coon       ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,DMDA_STENCIL_BOX,m,n,M,N,2,s,lc,ld,&dd->da_coordinates);CHKERRQ(ierr);
17647c6ae99SBarry Smith       ierr = PetscFree2(lc,ld);CHKERRQ(ierr);
17747c6ae99SBarry Smith     } else if (dd->dim == 3) {
17847c6ae99SBarry Smith       PetscInt         i,s,m,*lc,*ld,*le,l,k,q,n,M,N,P,p;
1791321219cSEthan Coon       DMDABoundaryType bx,by,bz;
1801321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,&n,&p,&M,&N,&P,0,&s,&bx,&by,&bz,0);CHKERRQ(ierr);
181aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,&k,&q);CHKERRQ(ierr);
18247c6ae99SBarry Smith       ierr = PetscMalloc3(size,PetscInt,&lc,size,PetscInt,&ld,size,PetscInt,&le);CHKERRQ(ierr);
18347c6ae99SBarry Smith       /* only first M values in lc matter */
18447c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
18547c6ae99SBarry Smith       /* every Mth value in ld matters */
18647c6ae99SBarry Smith       ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
18747c6ae99SBarry Smith       for ( i=0; i<N; i++) {
18847c6ae99SBarry Smith         ld[i] = ld[M*i];
18947c6ae99SBarry Smith       }
19047c6ae99SBarry Smith       ierr = MPI_Allgather(&q,1,MPIU_INT,le,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
19147c6ae99SBarry Smith       for ( i=0; i<P; i++) {
19247c6ae99SBarry Smith         le[i] = le[M*N*i];
19347c6ae99SBarry Smith       }
1941321219cSEthan Coon       ierr = DMDACreate3d(((PetscObject)da)->comm,bx,by,bz,DMDA_STENCIL_BOX,m,n,p,M,N,P,3,s,lc,ld,le,&dd->da_coordinates);CHKERRQ(ierr);
19547c6ae99SBarry Smith       ierr = PetscFree3(lc,ld,le);CHKERRQ(ierr);
19647c6ae99SBarry Smith     }
19747c6ae99SBarry Smith   }
19847c6ae99SBarry Smith   *cda = dd->da_coordinates;
19947c6ae99SBarry Smith   PetscFunctionReturn(0);
20047c6ae99SBarry Smith }
20147c6ae99SBarry Smith 
20247c6ae99SBarry Smith 
20347c6ae99SBarry Smith #undef __FUNCT__
204aa219208SBarry Smith #define __FUNCT__ "DMDAGetGhostedCoordinates"
20547c6ae99SBarry Smith /*@
206aa219208SBarry Smith    DMDAGetGhostedCoordinates - Gets the node coordinates associated with a DMDA.
20747c6ae99SBarry Smith 
208aa219208SBarry Smith    Collective on DMDA
20947c6ae99SBarry Smith 
21047c6ae99SBarry Smith    Input Parameter:
21147c6ae99SBarry Smith .  da - the distributed array
21247c6ae99SBarry Smith 
21347c6ae99SBarry Smith    Output Parameter:
21447c6ae99SBarry Smith .  c - coordinate vector
21547c6ae99SBarry Smith 
21647c6ae99SBarry Smith    Note:
21747c6ae99SBarry Smith     Each process has only the coordinates for its local AND ghost nodes
21847c6ae99SBarry Smith 
21947c6ae99SBarry Smith     For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
22047c6ae99SBarry Smith     and (x_0,y_0,z_0,x_1,y_1,z_1...)
22147c6ae99SBarry Smith 
22247c6ae99SBarry Smith   Level: intermediate
22347c6ae99SBarry Smith 
22447c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
22547c6ae99SBarry Smith 
226aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetCoordinateDA()
22747c6ae99SBarry Smith @*/
2287087cfbeSBarry Smith PetscErrorCode  DMDAGetGhostedCoordinates(DM da,Vec *c)
22947c6ae99SBarry Smith {
23047c6ae99SBarry Smith   PetscErrorCode ierr;
23147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
23247c6ae99SBarry Smith 
23347c6ae99SBarry Smith   PetscFunctionBegin;
23447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
23547c6ae99SBarry Smith   PetscValidPointer(c,2);
236aa219208SBarry Smith   if (!dd->coordinates) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call DMDASetCoordinates() before this call");
23747c6ae99SBarry Smith   if (!dd->ghosted_coordinates) {
2389a42bb27SBarry Smith     DM dac;
239aa219208SBarry Smith     ierr = DMDAGetCoordinateDA(da,&dac);CHKERRQ(ierr);
240564755cdSBarry Smith     ierr = DMCreateLocalVector(dac,&dd->ghosted_coordinates);CHKERRQ(ierr);
2419a42bb27SBarry Smith     ierr = DMGlobalToLocalBegin(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr);
2429a42bb27SBarry Smith     ierr = DMGlobalToLocalEnd(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr);
24347c6ae99SBarry Smith   }
24447c6ae99SBarry Smith   *c = dd->ghosted_coordinates;
24547c6ae99SBarry Smith   PetscFunctionReturn(0);
24647c6ae99SBarry Smith }
24747c6ae99SBarry Smith 
24847c6ae99SBarry Smith #undef __FUNCT__
249aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName"
25047c6ae99SBarry Smith /*@C
251aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
252aa219208SBarry Smith    vectors associated with a DMDA.
25347c6ae99SBarry Smith 
25447c6ae99SBarry Smith    Not Collective
25547c6ae99SBarry Smith 
25647c6ae99SBarry Smith    Input Parameters:
25747c6ae99SBarry Smith +  da - the distributed array
258aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
259aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
26047c6ae99SBarry Smith -  names - the name of the field (component)
26147c6ae99SBarry Smith 
26247c6ae99SBarry Smith   Level: intermediate
26347c6ae99SBarry Smith 
26447c6ae99SBarry Smith .keywords: distributed array, get, component name
26547c6ae99SBarry Smith 
266aa219208SBarry Smith .seealso: DMDAGetFieldName()
26747c6ae99SBarry Smith @*/
2687087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
26947c6ae99SBarry Smith {
27047c6ae99SBarry Smith   PetscErrorCode ierr;
27147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
27247c6ae99SBarry Smith 
27347c6ae99SBarry Smith   PetscFunctionBegin;
27447c6ae99SBarry Smith    PetscValidHeaderSpecific(da,DM_CLASSID,1);
27547c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
276c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
27747c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
27847c6ae99SBarry Smith   PetscFunctionReturn(0);
27947c6ae99SBarry Smith }
28047c6ae99SBarry Smith 
28147c6ae99SBarry Smith #undef __FUNCT__
282aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName"
28347c6ae99SBarry Smith /*@C
284aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
285aa219208SBarry Smith    vectors associated with a DMDA.
28647c6ae99SBarry Smith 
28747c6ae99SBarry Smith    Not Collective
28847c6ae99SBarry Smith 
28947c6ae99SBarry Smith    Input Parameter:
29047c6ae99SBarry Smith +  da - the distributed array
291aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
292aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
29347c6ae99SBarry Smith 
29447c6ae99SBarry Smith    Output Parameter:
29547c6ae99SBarry Smith .  names - the name of the field (component)
29647c6ae99SBarry Smith 
29747c6ae99SBarry Smith   Level: intermediate
29847c6ae99SBarry Smith 
29947c6ae99SBarry Smith .keywords: distributed array, get, component name
30047c6ae99SBarry Smith 
301aa219208SBarry Smith .seealso: DMDASetFieldName()
30247c6ae99SBarry Smith @*/
3037087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
30447c6ae99SBarry Smith {
30547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
30647c6ae99SBarry Smith 
30747c6ae99SBarry Smith   PetscFunctionBegin;
30847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
30947c6ae99SBarry Smith   PetscValidPointer(name,3);
31047c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
31147c6ae99SBarry Smith   *name = dd->fieldname[nf];
31247c6ae99SBarry Smith   PetscFunctionReturn(0);
31347c6ae99SBarry Smith }
31447c6ae99SBarry Smith 
31547c6ae99SBarry Smith #undef __FUNCT__
316aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners"
31747c6ae99SBarry Smith /*@
318aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
31947c6ae99SBarry Smith    corner of the local region, excluding ghost points.
32047c6ae99SBarry Smith 
32147c6ae99SBarry Smith    Not Collective
32247c6ae99SBarry Smith 
32347c6ae99SBarry Smith    Input Parameter:
32447c6ae99SBarry Smith .  da - the distributed array
32547c6ae99SBarry Smith 
32647c6ae99SBarry Smith    Output Parameters:
32747c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
32847c6ae99SBarry Smith            for 2D and 3D problems)
32947c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
33047c6ae99SBarry Smith            these are used for 2D and 3D problems)
33147c6ae99SBarry Smith 
33247c6ae99SBarry Smith    Note:
33347c6ae99SBarry Smith    The corner information is independent of the number of degrees of
334aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
33547c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
33647c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
33747c6ae99SBarry Smith    Any of y, z, n, and p can be passed in as PETSC_NULL if not needed.
33847c6ae99SBarry Smith 
33947c6ae99SBarry Smith   Level: beginner
34047c6ae99SBarry Smith 
34147c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
34247c6ae99SBarry Smith 
343aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
34447c6ae99SBarry Smith @*/
3457087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
34647c6ae99SBarry Smith {
34747c6ae99SBarry Smith   PetscInt w;
34847c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
34947c6ae99SBarry Smith 
35047c6ae99SBarry Smith   PetscFunctionBegin;
35147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
35247c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
35347c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
35447c6ae99SBarry Smith   w = dd->w;
35547c6ae99SBarry Smith   if (x) *x = dd->xs/w; if(m) *m = (dd->xe - dd->xs)/w;
35647c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
35747c6ae99SBarry Smith   if (y) *y = dd->ys;   if (n) *n = (dd->ye - dd->ys);
35847c6ae99SBarry Smith   if (z) *z = dd->zs;   if (p) *p = (dd->ze - dd->zs);
35947c6ae99SBarry Smith   PetscFunctionReturn(0);
36047c6ae99SBarry Smith }
36147c6ae99SBarry Smith 
36247c6ae99SBarry Smith #undef __FUNCT__
363aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox"
36447c6ae99SBarry Smith /*@
365aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
36647c6ae99SBarry Smith 
36747c6ae99SBarry Smith    Not Collective
36847c6ae99SBarry Smith 
36947c6ae99SBarry Smith    Input Parameter:
37047c6ae99SBarry Smith .  da - the distributed array
37147c6ae99SBarry Smith 
37247c6ae99SBarry Smith    Output Parameters:
37347c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
37447c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
37547c6ae99SBarry Smith 
37647c6ae99SBarry Smith   Level: beginner
37747c6ae99SBarry Smith 
37847c6ae99SBarry Smith .keywords: distributed array, get, coordinates
37947c6ae99SBarry Smith 
380aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetBoundingBox()
38147c6ae99SBarry Smith @*/
3827087cfbeSBarry Smith PetscErrorCode  DMDAGetLocalBoundingBox(DM da,PetscReal lmin[],PetscReal lmax[])
38347c6ae99SBarry Smith {
38447c6ae99SBarry Smith   PetscErrorCode    ierr;
38547c6ae99SBarry Smith   Vec               coords  = PETSC_NULL;
38647c6ae99SBarry Smith   PetscInt          dim,i,j;
38747c6ae99SBarry Smith   const PetscScalar *local_coords;
388ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
38947c6ae99SBarry Smith   PetscInt          N,Ni;
39047c6ae99SBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
39147c6ae99SBarry Smith 
39247c6ae99SBarry Smith   PetscFunctionBegin;
39347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
39447c6ae99SBarry Smith   dim = dd->dim;
395aa219208SBarry Smith   ierr = DMDAGetCoordinates(da,&coords);CHKERRQ(ierr);
3967324c66bSJed Brown   if (coords) {
39747c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
39847c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
39947c6ae99SBarry Smith     Ni = N/dim;
40047c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
4017324c66bSJed Brown       for (j=0; j<3; j++) {
4027324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
4037324c66bSJed Brown         max[j] = j < dim ? PetscMax(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
40447c6ae99SBarry Smith       }
40547c6ae99SBarry Smith     }
40647c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
4077324c66bSJed Brown   } else {                      /* Just use grid indices */
4087324c66bSJed Brown     DMDALocalInfo info;
4097324c66bSJed Brown     ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
4107324c66bSJed Brown     min[0] = info.xs;
4117324c66bSJed Brown     min[1] = info.ys;
4127324c66bSJed Brown     min[2] = info.zs;
4137324c66bSJed Brown     max[0] = info.xs + info.xm-1;
4147324c66bSJed Brown     max[1] = info.ys + info.ym-1;
4157324c66bSJed Brown     max[2] = info.zs + info.zm-1;
4167324c66bSJed Brown   }
41747c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
41847c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
41947c6ae99SBarry Smith   PetscFunctionReturn(0);
42047c6ae99SBarry Smith }
42147c6ae99SBarry Smith 
42247c6ae99SBarry Smith #undef __FUNCT__
423aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox"
42447c6ae99SBarry Smith /*@
425aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
42647c6ae99SBarry Smith 
427aa219208SBarry Smith    Collective on DMDA
42847c6ae99SBarry Smith 
42947c6ae99SBarry Smith    Input Parameter:
43047c6ae99SBarry Smith .  da - the distributed array
43147c6ae99SBarry Smith 
43247c6ae99SBarry Smith    Output Parameters:
43347c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
43447c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
43547c6ae99SBarry Smith 
43647c6ae99SBarry Smith   Level: beginner
43747c6ae99SBarry Smith 
43847c6ae99SBarry Smith .keywords: distributed array, get, coordinates
43947c6ae99SBarry Smith 
440aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetLocalBoundingBox()
44147c6ae99SBarry Smith @*/
4427087cfbeSBarry Smith PetscErrorCode  DMDAGetBoundingBox(DM da,PetscReal gmin[],PetscReal gmax[])
44347c6ae99SBarry Smith {
44447c6ae99SBarry Smith   PetscErrorCode ierr;
44547c6ae99SBarry Smith   PetscMPIInt    count;
44647c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
44747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
44847c6ae99SBarry Smith 
44947c6ae99SBarry Smith   PetscFunctionBegin;
45047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
45147c6ae99SBarry Smith   count = PetscMPIIntCast(dd->dim);
452aa219208SBarry Smith   ierr = DMDAGetLocalBoundingBox(da,lmin,lmax);CHKERRQ(ierr);
453d9822059SBarry Smith   if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,((PetscObject)da)->comm);CHKERRQ(ierr);}
454d9822059SBarry Smith   if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,((PetscObject)da)->comm);CHKERRQ(ierr);}
45547c6ae99SBarry Smith   PetscFunctionReturn(0);
45647c6ae99SBarry Smith }
457bc2bf880SBarry Smith 
458bc2bf880SBarry Smith #undef __FUNCT__
459bc2bf880SBarry Smith #define __FUNCT__ "DMDAGetReducedDA"
460bc2bf880SBarry Smith /*@
461bc2bf880SBarry Smith    DMDAGetReducedDA - Gets the DMDA with the same layout but with fewer or more fields
462bc2bf880SBarry Smith 
463bc2bf880SBarry Smith    Collective on DMDA
464bc2bf880SBarry Smith 
465bc2bf880SBarry Smith    Input Parameter:
466bc2bf880SBarry Smith +  da - the distributed array
467bc2bf880SBarry Smith .  nfields - number of fields in new DMDA
468bc2bf880SBarry Smith 
469bc2bf880SBarry Smith    Output Parameter:
470bc2bf880SBarry Smith .  nda - the new DMDA
471bc2bf880SBarry Smith 
472bc2bf880SBarry Smith   Level: intermediate
473bc2bf880SBarry Smith 
474bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
475bc2bf880SBarry Smith 
476bc2bf880SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetGhostedCoordinates()
477bc2bf880SBarry Smith @*/
478bc2bf880SBarry Smith PetscErrorCode  DMDAGetReducedDA(DM da,PetscInt nfields,DM *nda)
479bc2bf880SBarry Smith {
480bc2bf880SBarry Smith   PetscErrorCode ierr;
481bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
482bc2bf880SBarry Smith 
483*320964c4SBlaise Bourdin   PetscInt          s,m,n,p,M,N,P,dim;
484*320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
485bc2bf880SBarry Smith   DMDABoundaryType  bx,by,bz;
486*320964c4SBlaise Bourdin   DMDAStencilType   stencil_type;
487*320964c4SBlaise Bourdin 
488*320964c4SBlaise Bourdin   PetscFunctionBegin;
489*320964c4SBlaise Bourdin   ierr = DMDAGetInfo(da,&dim,&M,&N,&P,&m,&n,&p,0,&s,&bx,&by,&bz,&stencil_type);CHKERRQ(ierr);
490*320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
491*320964c4SBlaise Bourdin   if (dim == 1) {
492*320964c4SBlaise Bourdin     ierr = DMDACreate1d(((PetscObject)da)->comm,bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
493*320964c4SBlaise Bourdin   } else if (dim == 2) {
494*320964c4SBlaise Bourdin     ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
495*320964c4SBlaise Bourdin   } else if (dim == 3) {
496*320964c4SBlaise Bourdin     ierr = DMDACreate3d(((PetscObject)da)->comm,bx,by,bz,stencil_type,M,N,P,m,n,p,nfields,s,lx,ly,lz,nda);CHKERRQ(ierr);
497bc2bf880SBarry Smith   }
498bc2bf880SBarry Smith   if (dd->coordinates) {
499bc2bf880SBarry Smith     DM_DA *ndd = (DM_DA*)(*nda)->data;
500bc2bf880SBarry Smith     ierr        = PetscObjectReference((PetscObject)dd->coordinates);CHKERRQ(ierr);
501bc2bf880SBarry Smith     ndd->coordinates = dd->coordinates;
502bc2bf880SBarry Smith   }
503bc2bf880SBarry Smith   PetscFunctionReturn(0);
504bc2bf880SBarry Smith }
505bc2bf880SBarry Smith 
506