xref: /petsc/src/dm/impls/da/dacorn.c (revision b45d2f2cb7e031d9c0de5873eca80614ca7b863b)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6*b45d2f2cSJed 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;
3347c6ae99SBarry Smith 
3447c6ae99SBarry Smith   PetscFunctionBegin;
3547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
3647c6ae99SBarry Smith   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
3747c6ae99SBarry Smith   ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr);
3896e147daSBarry Smith   ierr = VecDestroy(&dd->coordinates);CHKERRQ(ierr);
3947c6ae99SBarry Smith   dd->coordinates = c;
4047c6ae99SBarry Smith   ierr = VecSetBlockSize(c,dd->dim);CHKERRQ(ierr);
41fcfd50ebSBarry Smith   ierr = VecDestroy(&dd->ghosted_coordinates);CHKERRQ(ierr);
4247c6ae99SBarry Smith   PetscFunctionReturn(0);
4347c6ae99SBarry Smith }
4447c6ae99SBarry Smith 
4547c6ae99SBarry Smith #undef __FUNCT__
46ce00eea3SSatish Balay #define __FUNCT__ "DMDASetGhostedCoordinates"
47ce00eea3SSatish Balay /*@
48ce00eea3SSatish Balay    DMDASetGhostedCoordinates - Sets into the DMDA a vector that indicates the
49ce00eea3SSatish Balay       coordinates of the local nodes, including ghost nodes.
50ce00eea3SSatish Balay 
51ce00eea3SSatish Balay    Collective on DMDA
52ce00eea3SSatish Balay 
53ce00eea3SSatish Balay    Input Parameter:
54ce00eea3SSatish Balay +  da - the distributed array
55ce00eea3SSatish Balay -  c - coordinate vector
56ce00eea3SSatish Balay 
57ce00eea3SSatish Balay    Note:
58ce00eea3SSatish Balay     The coordinates of interior ghost points can be set using DMDASetCoordinates()
59ce00eea3SSatish Balay     followed by DMDAGetGhostedCoordinates().  This is intended to enable the setting
60ce00eea3SSatish Balay     of ghost coordinates outside of the domain.
61ce00eea3SSatish Balay 
62ce00eea3SSatish Balay     Non-ghosted coordinates, if set, are assumed still valid.
63ce00eea3SSatish Balay 
64ce00eea3SSatish Balay   Level: intermediate
65ce00eea3SSatish Balay 
66ce00eea3SSatish Balay .keywords: distributed array, get, corners, nodes, local indices, coordinates
67ce00eea3SSatish Balay 
68ce00eea3SSatish Balay .seealso: DMDASetCoordinates(), DMDAGetGhostCorners(), DMDAGetCoordinates(), DMDASetUniformCoordinates(). DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA()
69ce00eea3SSatish Balay @*/
70ce00eea3SSatish Balay PetscErrorCode  DMDASetGhostedCoordinates(DM da,Vec c)
71ce00eea3SSatish Balay {
72ce00eea3SSatish Balay   PetscErrorCode ierr;
73ce00eea3SSatish Balay   DM_DA          *dd = (DM_DA*)da->data;
74ce00eea3SSatish Balay 
75ce00eea3SSatish Balay   PetscFunctionBegin;
76ce00eea3SSatish Balay   PetscValidHeaderSpecific(da,DM_CLASSID,1);
77ce00eea3SSatish Balay   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
78ce00eea3SSatish Balay   ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr);
7996e147daSBarry Smith   ierr = VecDestroy(&dd->ghosted_coordinates);CHKERRQ(ierr);
80ce00eea3SSatish Balay   dd->ghosted_coordinates = c;
81ce00eea3SSatish Balay   ierr = VecSetBlockSize(c,dd->dim);CHKERRQ(ierr);
82ce00eea3SSatish Balay   PetscFunctionReturn(0);
83ce00eea3SSatish Balay }
84ce00eea3SSatish Balay 
85ce00eea3SSatish Balay #undef __FUNCT__
86aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinates"
8747c6ae99SBarry Smith /*@
88aa219208SBarry Smith    DMDAGetCoordinates - Gets the node coordinates associated with a DMDA.
8947c6ae99SBarry Smith 
9047c6ae99SBarry Smith    Not Collective
9147c6ae99SBarry Smith 
9247c6ae99SBarry Smith    Input Parameter:
9347c6ae99SBarry Smith .  da - the distributed array
9447c6ae99SBarry Smith 
9547c6ae99SBarry Smith    Output Parameter:
9647c6ae99SBarry Smith .  c - coordinate vector
9747c6ae99SBarry Smith 
9847c6ae99SBarry Smith    Note:
9947c6ae99SBarry Smith     Each process has only the coordinates for its local nodes (does NOT have the
10047c6ae99SBarry Smith   coordinates for the ghost nodes).
10147c6ae99SBarry Smith 
10247c6ae99SBarry Smith     For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
10347c6ae99SBarry Smith     and (x_0,y_0,z_0,x_1,y_1,z_1...)
10447c6ae99SBarry Smith 
10547c6ae99SBarry Smith   Level: intermediate
10647c6ae99SBarry Smith 
10747c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
10847c6ae99SBarry Smith 
109aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA()
11047c6ae99SBarry Smith @*/
1117087cfbeSBarry Smith PetscErrorCode  DMDAGetCoordinates(DM da,Vec *c)
11247c6ae99SBarry Smith {
11347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
11447c6ae99SBarry Smith   PetscFunctionBegin;
11547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
11647c6ae99SBarry Smith   PetscValidPointer(c,2);
11747c6ae99SBarry Smith   *c = dd->coordinates;
11847c6ae99SBarry Smith   PetscFunctionReturn(0);
11947c6ae99SBarry Smith }
12047c6ae99SBarry Smith 
12147c6ae99SBarry Smith #undef __FUNCT__
122aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinateDA"
12347c6ae99SBarry Smith /*@
124aa219208SBarry Smith    DMDAGetCoordinateDA - Gets the DMDA that scatters between global and local DMDA coordinates
12547c6ae99SBarry Smith 
126aa219208SBarry Smith    Collective on DMDA
12747c6ae99SBarry Smith 
12847c6ae99SBarry Smith    Input Parameter:
12947c6ae99SBarry Smith .  da - the distributed array
13047c6ae99SBarry Smith 
13147c6ae99SBarry Smith    Output Parameter:
132aa219208SBarry Smith .  dac - coordinate DMDA
13347c6ae99SBarry Smith 
13447c6ae99SBarry Smith   Level: intermediate
13547c6ae99SBarry Smith 
13647c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
13747c6ae99SBarry Smith 
138aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetGhostedCoordinates()
13947c6ae99SBarry Smith @*/
1407087cfbeSBarry Smith PetscErrorCode  DMDAGetCoordinateDA(DM da,DM *cda)
14147c6ae99SBarry Smith {
14247c6ae99SBarry Smith   PetscMPIInt    size;
14347c6ae99SBarry Smith   PetscErrorCode ierr;
14447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
14547c6ae99SBarry Smith 
14647c6ae99SBarry Smith   PetscFunctionBegin;
14747c6ae99SBarry Smith   if (!dd->da_coordinates) {
14847c6ae99SBarry Smith     ierr = MPI_Comm_size(((PetscObject)da)->comm,&size);CHKERRQ(ierr);
14947c6ae99SBarry Smith     if (dd->dim == 1) {
15047c6ae99SBarry Smith       PetscInt         s,m,*lc,l;
1511321219cSEthan Coon       DMDABoundaryType bx;
1521321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,0,0,0,0,0,0,&s,&bx,0,0,0);CHKERRQ(ierr);
153aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,0,0);CHKERRQ(ierr);
15447c6ae99SBarry Smith       ierr = PetscMalloc(size*sizeof(PetscInt),&lc);CHKERRQ(ierr);
15547c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
1561321219cSEthan Coon       ierr = DMDACreate1d(((PetscObject)da)->comm,bx,m,1,s,lc,&dd->da_coordinates);CHKERRQ(ierr);
15747c6ae99SBarry Smith       ierr = PetscFree(lc);CHKERRQ(ierr);
15847c6ae99SBarry Smith     } else if (dd->dim == 2) {
15947c6ae99SBarry Smith       PetscInt         i,s,m,*lc,*ld,l,k,n,M,N;
1601321219cSEthan Coon       DMDABoundaryType bx,by;
1611321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,&n,0,&M,&N,0,0,&s,&bx,&by,0,0);CHKERRQ(ierr);
162aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,&k,0);CHKERRQ(ierr);
16347c6ae99SBarry Smith       ierr = PetscMalloc2(size,PetscInt,&lc,size,PetscInt,&ld);CHKERRQ(ierr);
16447c6ae99SBarry Smith       /* only first M values in lc matter */
16547c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
16647c6ae99SBarry Smith       /* every Mth value in ld matters */
16747c6ae99SBarry Smith       ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
16847c6ae99SBarry Smith       for ( i=0; i<N; i++) {
16947c6ae99SBarry Smith         ld[i] = ld[M*i];
17047c6ae99SBarry Smith       }
1711321219cSEthan Coon       ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,DMDA_STENCIL_BOX,m,n,M,N,2,s,lc,ld,&dd->da_coordinates);CHKERRQ(ierr);
17247c6ae99SBarry Smith       ierr = PetscFree2(lc,ld);CHKERRQ(ierr);
17347c6ae99SBarry Smith     } else if (dd->dim == 3) {
17447c6ae99SBarry Smith       PetscInt         i,s,m,*lc,*ld,*le,l,k,q,n,M,N,P,p;
1751321219cSEthan Coon       DMDABoundaryType bx,by,bz;
1761321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,&n,&p,&M,&N,&P,0,&s,&bx,&by,&bz,0);CHKERRQ(ierr);
177aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,&k,&q);CHKERRQ(ierr);
17847c6ae99SBarry Smith       ierr = PetscMalloc3(size,PetscInt,&lc,size,PetscInt,&ld,size,PetscInt,&le);CHKERRQ(ierr);
17947c6ae99SBarry Smith       /* only first M values in lc matter */
18047c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
18147c6ae99SBarry Smith       /* every Mth value in ld matters */
18247c6ae99SBarry Smith       ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
18347c6ae99SBarry Smith       for ( i=0; i<N; i++) {
18447c6ae99SBarry Smith         ld[i] = ld[M*i];
18547c6ae99SBarry Smith       }
18647c6ae99SBarry Smith       ierr = MPI_Allgather(&q,1,MPIU_INT,le,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
18747c6ae99SBarry Smith       for ( i=0; i<P; i++) {
18847c6ae99SBarry Smith         le[i] = le[M*N*i];
18947c6ae99SBarry Smith       }
1901321219cSEthan 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);
19147c6ae99SBarry Smith       ierr = PetscFree3(lc,ld,le);CHKERRQ(ierr);
19247c6ae99SBarry Smith     }
19347c6ae99SBarry Smith   }
19447c6ae99SBarry Smith   *cda = dd->da_coordinates;
19547c6ae99SBarry Smith   PetscFunctionReturn(0);
19647c6ae99SBarry Smith }
19747c6ae99SBarry Smith 
19847c6ae99SBarry Smith 
19947c6ae99SBarry Smith #undef __FUNCT__
200aa219208SBarry Smith #define __FUNCT__ "DMDAGetGhostedCoordinates"
20147c6ae99SBarry Smith /*@
202aa219208SBarry Smith    DMDAGetGhostedCoordinates - Gets the node coordinates associated with a DMDA.
20347c6ae99SBarry Smith 
204aa219208SBarry Smith    Collective on DMDA
20547c6ae99SBarry Smith 
20647c6ae99SBarry Smith    Input Parameter:
20747c6ae99SBarry Smith .  da - the distributed array
20847c6ae99SBarry Smith 
20947c6ae99SBarry Smith    Output Parameter:
21047c6ae99SBarry Smith .  c - coordinate vector
21147c6ae99SBarry Smith 
21247c6ae99SBarry Smith    Note:
21347c6ae99SBarry Smith     Each process has only the coordinates for its local AND ghost nodes
21447c6ae99SBarry Smith 
21547c6ae99SBarry Smith     For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
21647c6ae99SBarry Smith     and (x_0,y_0,z_0,x_1,y_1,z_1...)
21747c6ae99SBarry Smith 
21847c6ae99SBarry Smith   Level: intermediate
21947c6ae99SBarry Smith 
22047c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
22147c6ae99SBarry Smith 
222aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetCoordinateDA()
22347c6ae99SBarry Smith @*/
2247087cfbeSBarry Smith PetscErrorCode  DMDAGetGhostedCoordinates(DM da,Vec *c)
22547c6ae99SBarry Smith {
22647c6ae99SBarry Smith   PetscErrorCode ierr;
22747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
22847c6ae99SBarry Smith 
22947c6ae99SBarry Smith   PetscFunctionBegin;
23047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
23147c6ae99SBarry Smith   PetscValidPointer(c,2);
232aa219208SBarry Smith   if (!dd->coordinates) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call DMDASetCoordinates() before this call");
23347c6ae99SBarry Smith   if (!dd->ghosted_coordinates) {
2349a42bb27SBarry Smith     DM dac;
235aa219208SBarry Smith     ierr = DMDAGetCoordinateDA(da,&dac);CHKERRQ(ierr);
236564755cdSBarry Smith     ierr = DMCreateLocalVector(dac,&dd->ghosted_coordinates);CHKERRQ(ierr);
2379a42bb27SBarry Smith     ierr = DMGlobalToLocalBegin(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr);
2389a42bb27SBarry Smith     ierr = DMGlobalToLocalEnd(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr);
23947c6ae99SBarry Smith   }
24047c6ae99SBarry Smith   *c = dd->ghosted_coordinates;
24147c6ae99SBarry Smith   PetscFunctionReturn(0);
24247c6ae99SBarry Smith }
24347c6ae99SBarry Smith 
24447c6ae99SBarry Smith #undef __FUNCT__
245aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName"
24647c6ae99SBarry Smith /*@C
247aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
248aa219208SBarry Smith    vectors associated with a DMDA.
24947c6ae99SBarry Smith 
25047c6ae99SBarry Smith    Not Collective
25147c6ae99SBarry Smith 
25247c6ae99SBarry Smith    Input Parameters:
25347c6ae99SBarry Smith +  da - the distributed array
254aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
255aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
25647c6ae99SBarry Smith -  names - the name of the field (component)
25747c6ae99SBarry Smith 
25847c6ae99SBarry Smith   Level: intermediate
25947c6ae99SBarry Smith 
26047c6ae99SBarry Smith .keywords: distributed array, get, component name
26147c6ae99SBarry Smith 
262aa219208SBarry Smith .seealso: DMDAGetFieldName()
26347c6ae99SBarry Smith @*/
2647087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
26547c6ae99SBarry Smith {
26647c6ae99SBarry Smith   PetscErrorCode ierr;
26747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
26847c6ae99SBarry Smith 
26947c6ae99SBarry Smith   PetscFunctionBegin;
27047c6ae99SBarry Smith    PetscValidHeaderSpecific(da,DM_CLASSID,1);
27147c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
272c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
27347c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
27447c6ae99SBarry Smith   PetscFunctionReturn(0);
27547c6ae99SBarry Smith }
27647c6ae99SBarry Smith 
27747c6ae99SBarry Smith #undef __FUNCT__
278aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName"
27947c6ae99SBarry Smith /*@C
280aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
281aa219208SBarry Smith    vectors associated with a DMDA.
28247c6ae99SBarry Smith 
28347c6ae99SBarry Smith    Not Collective
28447c6ae99SBarry Smith 
28547c6ae99SBarry Smith    Input Parameter:
28647c6ae99SBarry Smith +  da - the distributed array
287aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
288aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
28947c6ae99SBarry Smith 
29047c6ae99SBarry Smith    Output Parameter:
29147c6ae99SBarry Smith .  names - the name of the field (component)
29247c6ae99SBarry Smith 
29347c6ae99SBarry Smith   Level: intermediate
29447c6ae99SBarry Smith 
29547c6ae99SBarry Smith .keywords: distributed array, get, component name
29647c6ae99SBarry Smith 
297aa219208SBarry Smith .seealso: DMDASetFieldName()
29847c6ae99SBarry Smith @*/
2997087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
30047c6ae99SBarry Smith {
30147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
30247c6ae99SBarry Smith 
30347c6ae99SBarry Smith   PetscFunctionBegin;
30447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
30547c6ae99SBarry Smith   PetscValidPointer(name,3);
30647c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
30747c6ae99SBarry Smith   *name = dd->fieldname[nf];
30847c6ae99SBarry Smith   PetscFunctionReturn(0);
30947c6ae99SBarry Smith }
31047c6ae99SBarry Smith 
31147c6ae99SBarry Smith #undef __FUNCT__
312aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners"
31347c6ae99SBarry Smith /*@
314aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
31547c6ae99SBarry Smith    corner of the local region, excluding ghost points.
31647c6ae99SBarry Smith 
31747c6ae99SBarry Smith    Not Collective
31847c6ae99SBarry Smith 
31947c6ae99SBarry Smith    Input Parameter:
32047c6ae99SBarry Smith .  da - the distributed array
32147c6ae99SBarry Smith 
32247c6ae99SBarry Smith    Output Parameters:
32347c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
32447c6ae99SBarry Smith            for 2D and 3D problems)
32547c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
32647c6ae99SBarry Smith            these are used for 2D and 3D problems)
32747c6ae99SBarry Smith 
32847c6ae99SBarry Smith    Note:
32947c6ae99SBarry Smith    The corner information is independent of the number of degrees of
330aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
33147c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
33247c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
33347c6ae99SBarry Smith    Any of y, z, n, and p can be passed in as PETSC_NULL if not needed.
33447c6ae99SBarry Smith 
33547c6ae99SBarry Smith   Level: beginner
33647c6ae99SBarry Smith 
33747c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
33847c6ae99SBarry Smith 
339aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
34047c6ae99SBarry Smith @*/
3417087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
34247c6ae99SBarry Smith {
34347c6ae99SBarry Smith   PetscInt w;
34447c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
34547c6ae99SBarry Smith 
34647c6ae99SBarry Smith   PetscFunctionBegin;
34747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
34847c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
34947c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
35047c6ae99SBarry Smith   w = dd->w;
35147c6ae99SBarry Smith   if (x) *x = dd->xs/w; if(m) *m = (dd->xe - dd->xs)/w;
35247c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
35347c6ae99SBarry Smith   if (y) *y = dd->ys;   if (n) *n = (dd->ye - dd->ys);
35447c6ae99SBarry Smith   if (z) *z = dd->zs;   if (p) *p = (dd->ze - dd->zs);
35547c6ae99SBarry Smith   PetscFunctionReturn(0);
35647c6ae99SBarry Smith }
35747c6ae99SBarry Smith 
35847c6ae99SBarry Smith #undef __FUNCT__
359aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox"
36047c6ae99SBarry Smith /*@
361aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
36247c6ae99SBarry Smith 
36347c6ae99SBarry Smith    Not Collective
36447c6ae99SBarry Smith 
36547c6ae99SBarry Smith    Input Parameter:
36647c6ae99SBarry Smith .  da - the distributed array
36747c6ae99SBarry Smith 
36847c6ae99SBarry Smith    Output Parameters:
36947c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
37047c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
37147c6ae99SBarry Smith 
37247c6ae99SBarry Smith   Level: beginner
37347c6ae99SBarry Smith 
37447c6ae99SBarry Smith .keywords: distributed array, get, coordinates
37547c6ae99SBarry Smith 
376aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetBoundingBox()
37747c6ae99SBarry Smith @*/
3787087cfbeSBarry Smith PetscErrorCode  DMDAGetLocalBoundingBox(DM da,PetscReal lmin[],PetscReal lmax[])
37947c6ae99SBarry Smith {
38047c6ae99SBarry Smith   PetscErrorCode    ierr;
38147c6ae99SBarry Smith   Vec               coords  = PETSC_NULL;
38247c6ae99SBarry Smith   PetscInt          dim,i,j;
38347c6ae99SBarry Smith   const PetscScalar *local_coords;
384ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
38547c6ae99SBarry Smith   PetscInt          N,Ni;
38647c6ae99SBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
38747c6ae99SBarry Smith 
38847c6ae99SBarry Smith   PetscFunctionBegin;
38947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
39047c6ae99SBarry Smith   dim = dd->dim;
391aa219208SBarry Smith   ierr = DMDAGetCoordinates(da,&coords);CHKERRQ(ierr);
3927324c66bSJed Brown   if (coords) {
39347c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
39447c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
39547c6ae99SBarry Smith     Ni = N/dim;
39647c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
3977324c66bSJed Brown       for (j=0; j<3; j++) {
3987324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
3997324c66bSJed Brown         max[j] = j < dim ? PetscMax(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
40047c6ae99SBarry Smith       }
40147c6ae99SBarry Smith     }
40247c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
4037324c66bSJed Brown   } else {                      /* Just use grid indices */
4047324c66bSJed Brown     DMDALocalInfo info;
4057324c66bSJed Brown     ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
4067324c66bSJed Brown     min[0] = info.xs;
4077324c66bSJed Brown     min[1] = info.ys;
4087324c66bSJed Brown     min[2] = info.zs;
4097324c66bSJed Brown     max[0] = info.xs + info.xm-1;
4107324c66bSJed Brown     max[1] = info.ys + info.ym-1;
4117324c66bSJed Brown     max[2] = info.zs + info.zm-1;
4127324c66bSJed Brown   }
41347c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
41447c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
41547c6ae99SBarry Smith   PetscFunctionReturn(0);
41647c6ae99SBarry Smith }
41747c6ae99SBarry Smith 
41847c6ae99SBarry Smith #undef __FUNCT__
419aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox"
42047c6ae99SBarry Smith /*@
421aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
42247c6ae99SBarry Smith 
423aa219208SBarry Smith    Collective on DMDA
42447c6ae99SBarry Smith 
42547c6ae99SBarry Smith    Input Parameter:
42647c6ae99SBarry Smith .  da - the distributed array
42747c6ae99SBarry Smith 
42847c6ae99SBarry Smith    Output Parameters:
42947c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
43047c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
43147c6ae99SBarry Smith 
43247c6ae99SBarry Smith   Level: beginner
43347c6ae99SBarry Smith 
43447c6ae99SBarry Smith .keywords: distributed array, get, coordinates
43547c6ae99SBarry Smith 
436aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetLocalBoundingBox()
43747c6ae99SBarry Smith @*/
4387087cfbeSBarry Smith PetscErrorCode  DMDAGetBoundingBox(DM da,PetscReal gmin[],PetscReal gmax[])
43947c6ae99SBarry Smith {
44047c6ae99SBarry Smith   PetscErrorCode ierr;
44147c6ae99SBarry Smith   PetscMPIInt    count;
44247c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
44347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
44447c6ae99SBarry Smith 
44547c6ae99SBarry Smith   PetscFunctionBegin;
44647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
44747c6ae99SBarry Smith   count = PetscMPIIntCast(dd->dim);
448aa219208SBarry Smith   ierr = DMDAGetLocalBoundingBox(da,lmin,lmax);CHKERRQ(ierr);
449d9822059SBarry Smith   if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,((PetscObject)da)->comm);CHKERRQ(ierr);}
450d9822059SBarry Smith   if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,((PetscObject)da)->comm);CHKERRQ(ierr);}
45147c6ae99SBarry Smith   PetscFunctionReturn(0);
45247c6ae99SBarry Smith }
453bc2bf880SBarry Smith 
454bc2bf880SBarry Smith #undef __FUNCT__
455bc2bf880SBarry Smith #define __FUNCT__ "DMDAGetReducedDA"
456bc2bf880SBarry Smith /*@
457bc2bf880SBarry Smith    DMDAGetReducedDA - Gets the DMDA with the same layout but with fewer or more fields
458bc2bf880SBarry Smith 
459bc2bf880SBarry Smith    Collective on DMDA
460bc2bf880SBarry Smith 
461bc2bf880SBarry Smith    Input Parameter:
462bc2bf880SBarry Smith +  da - the distributed array
463bc2bf880SBarry Smith .  nfields - number of fields in new DMDA
464bc2bf880SBarry Smith 
465bc2bf880SBarry Smith    Output Parameter:
466bc2bf880SBarry Smith .  nda - the new DMDA
467bc2bf880SBarry Smith 
468bc2bf880SBarry Smith   Level: intermediate
469bc2bf880SBarry Smith 
470bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
471bc2bf880SBarry Smith 
472bc2bf880SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetGhostedCoordinates()
473bc2bf880SBarry Smith @*/
474bc2bf880SBarry Smith PetscErrorCode  DMDAGetReducedDA(DM da,PetscInt nfields,DM *nda)
475bc2bf880SBarry Smith {
476bc2bf880SBarry Smith   PetscErrorCode ierr;
477bc2bf880SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
478bc2bf880SBarry Smith 
479bc2bf880SBarry Smith   PetscFunctionBegin;
480bc2bf880SBarry Smith   if (dd->dim == 1) {
481bc2bf880SBarry Smith     PetscInt         s,m,l;
482bc2bf880SBarry Smith     DMDABoundaryType bx;
483bc2bf880SBarry Smith     ierr = DMDAGetInfo(da,0,&m,0,0,0,0,0,0,&s,&bx,0,0,0);CHKERRQ(ierr);
484bc2bf880SBarry Smith     ierr = DMDAGetCorners(da,0,0,0,&l,0,0);CHKERRQ(ierr);
485bc2bf880SBarry Smith     ierr = DMDACreate1d(((PetscObject)da)->comm,bx,m,nfields,s,dd->lx,nda);CHKERRQ(ierr);
486bc2bf880SBarry Smith   } else if (dd->dim == 2) {
487bc2bf880SBarry Smith     PetscInt         s,m,l,k,n,M,N;
488bc2bf880SBarry Smith     DMDABoundaryType bx,by;
489bc2bf880SBarry Smith     ierr = DMDAGetInfo(da,0,&m,&n,0,&M,&N,0,0,&s,&bx,&by,0,0);CHKERRQ(ierr);
490bc2bf880SBarry Smith     ierr = DMDAGetCorners(da,0,0,0,&l,&k,0);CHKERRQ(ierr);
491bc2bf880SBarry Smith     ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,DMDA_STENCIL_BOX,m,n,M,N,nfields,s,dd->lx,dd->ly,nda);CHKERRQ(ierr);
492bc2bf880SBarry Smith   } else if (dd->dim == 3) {
493bc2bf880SBarry Smith     PetscInt         s,m,l,k,q,n,M,N,P,p;
494bc2bf880SBarry Smith     DMDABoundaryType bx,by,bz;
495bc2bf880SBarry Smith     ierr = DMDAGetInfo(da,0,&m,&n,&p,&M,&N,&P,0,&s,&bx,&by,&bz,0);CHKERRQ(ierr);
496bc2bf880SBarry Smith     ierr = DMDAGetCorners(da,0,0,0,&l,&k,&q);CHKERRQ(ierr);
497bc2bf880SBarry Smith     ierr = DMDACreate3d(((PetscObject)da)->comm,bx,by,bz,DMDA_STENCIL_BOX,m,n,p,M,N,P,nfields,s,dd->lx,dd->ly,dd->lz,&dd->da_coordinates);CHKERRQ(ierr);
498bc2bf880SBarry Smith   }
499bc2bf880SBarry Smith   if (dd->coordinates) {
500bc2bf880SBarry Smith     DM_DA *ndd = (DM_DA*)(*nda)->data;
501bc2bf880SBarry Smith     ierr        = PetscObjectReference((PetscObject)dd->coordinates);CHKERRQ(ierr);
502bc2bf880SBarry Smith     ndd->coordinates = dd->coordinates;
503bc2bf880SBarry Smith   }
504bc2bf880SBarry Smith   PetscFunctionReturn(0);
505bc2bf880SBarry Smith }
506bc2bf880SBarry Smith 
507