xref: /petsc/src/dm/impls/da/dacorn.c (revision d9822059a04b3bd78629edfbf3ebfea74b8f6e57)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6c6db04a5SJed Brown #include <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);
3847c6ae99SBarry Smith   if (dd->coordinates) {ierr = VecDestroy(dd->coordinates);CHKERRQ(ierr);}
3947c6ae99SBarry Smith   dd->coordinates = c;
4047c6ae99SBarry Smith   ierr = VecSetBlockSize(c,dd->dim);CHKERRQ(ierr);
4147c6ae99SBarry Smith   if (dd->ghosted_coordinates) { /* The ghosted coordinates are no longer valid */
4247c6ae99SBarry Smith     ierr = VecDestroy(dd->ghosted_coordinates);CHKERRQ(ierr);
4347c6ae99SBarry Smith     dd->ghosted_coordinates = PETSC_NULL;
4447c6ae99SBarry Smith   }
4547c6ae99SBarry Smith   PetscFunctionReturn(0);
4647c6ae99SBarry Smith }
4747c6ae99SBarry Smith 
4847c6ae99SBarry Smith #undef __FUNCT__
49ce00eea3SSatish Balay #define __FUNCT__ "DMDASetGhostedCoordinates"
50ce00eea3SSatish Balay /*@
51ce00eea3SSatish Balay    DMDASetGhostedCoordinates - Sets into the DMDA a vector that indicates the
52ce00eea3SSatish Balay       coordinates of the local nodes, including ghost nodes.
53ce00eea3SSatish Balay 
54ce00eea3SSatish Balay    Collective on DMDA
55ce00eea3SSatish Balay 
56ce00eea3SSatish Balay    Input Parameter:
57ce00eea3SSatish Balay +  da - the distributed array
58ce00eea3SSatish Balay -  c - coordinate vector
59ce00eea3SSatish Balay 
60ce00eea3SSatish Balay    Note:
61ce00eea3SSatish Balay     The coordinates of interior ghost points can be set using DMDASetCoordinates()
62ce00eea3SSatish Balay     followed by DMDAGetGhostedCoordinates().  This is intended to enable the setting
63ce00eea3SSatish Balay     of ghost coordinates outside of the domain.
64ce00eea3SSatish Balay 
65ce00eea3SSatish Balay     Non-ghosted coordinates, if set, are assumed still valid.
66ce00eea3SSatish Balay 
67ce00eea3SSatish Balay   Level: intermediate
68ce00eea3SSatish Balay 
69ce00eea3SSatish Balay .keywords: distributed array, get, corners, nodes, local indices, coordinates
70ce00eea3SSatish Balay 
71ce00eea3SSatish Balay .seealso: DMDASetCoordinates(), DMDAGetGhostCorners(), DMDAGetCoordinates(), DMDASetUniformCoordinates(). DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA()
72ce00eea3SSatish Balay @*/
73ce00eea3SSatish Balay PetscErrorCode  DMDASetGhostedCoordinates(DM da,Vec c)
74ce00eea3SSatish Balay {
75ce00eea3SSatish Balay   PetscErrorCode ierr;
76ce00eea3SSatish Balay   DM_DA          *dd = (DM_DA*)da->data;
77ce00eea3SSatish Balay 
78ce00eea3SSatish Balay   PetscFunctionBegin;
79ce00eea3SSatish Balay   PetscValidHeaderSpecific(da,DM_CLASSID,1);
80ce00eea3SSatish Balay   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
81ce00eea3SSatish Balay   ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr);
82ce00eea3SSatish Balay   if (dd->ghosted_coordinates) {ierr = VecDestroy(dd->ghosted_coordinates);CHKERRQ(ierr);}
83ce00eea3SSatish Balay   dd->ghosted_coordinates = c;
84ce00eea3SSatish Balay   ierr = VecSetBlockSize(c,dd->dim);CHKERRQ(ierr);
85ce00eea3SSatish Balay   PetscFunctionReturn(0);
86ce00eea3SSatish Balay }
87ce00eea3SSatish Balay 
88ce00eea3SSatish Balay #undef __FUNCT__
89aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinates"
9047c6ae99SBarry Smith /*@
91aa219208SBarry Smith    DMDAGetCoordinates - Gets the node coordinates associated with a DMDA.
9247c6ae99SBarry Smith 
9347c6ae99SBarry Smith    Not Collective
9447c6ae99SBarry Smith 
9547c6ae99SBarry Smith    Input Parameter:
9647c6ae99SBarry Smith .  da - the distributed array
9747c6ae99SBarry Smith 
9847c6ae99SBarry Smith    Output Parameter:
9947c6ae99SBarry Smith .  c - coordinate vector
10047c6ae99SBarry Smith 
10147c6ae99SBarry Smith    Note:
10247c6ae99SBarry Smith     Each process has only the coordinates for its local nodes (does NOT have the
10347c6ae99SBarry Smith   coordinates for the ghost nodes).
10447c6ae99SBarry Smith 
10547c6ae99SBarry Smith     For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
10647c6ae99SBarry Smith     and (x_0,y_0,z_0,x_1,y_1,z_1...)
10747c6ae99SBarry Smith 
10847c6ae99SBarry Smith   Level: intermediate
10947c6ae99SBarry Smith 
11047c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
11147c6ae99SBarry Smith 
112aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA()
11347c6ae99SBarry Smith @*/
1147087cfbeSBarry Smith PetscErrorCode  DMDAGetCoordinates(DM da,Vec *c)
11547c6ae99SBarry Smith {
11647c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
11747c6ae99SBarry Smith   PetscFunctionBegin;
11847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
11947c6ae99SBarry Smith   PetscValidPointer(c,2);
12047c6ae99SBarry Smith   *c = dd->coordinates;
12147c6ae99SBarry Smith   PetscFunctionReturn(0);
12247c6ae99SBarry Smith }
12347c6ae99SBarry Smith 
12447c6ae99SBarry Smith #undef __FUNCT__
125aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinateDA"
12647c6ae99SBarry Smith /*@
127aa219208SBarry Smith    DMDAGetCoordinateDA - Gets the DMDA that scatters between global and local DMDA coordinates
12847c6ae99SBarry Smith 
129aa219208SBarry Smith    Collective on DMDA
13047c6ae99SBarry Smith 
13147c6ae99SBarry Smith    Input Parameter:
13247c6ae99SBarry Smith .  da - the distributed array
13347c6ae99SBarry Smith 
13447c6ae99SBarry Smith    Output Parameter:
135aa219208SBarry Smith .  dac - coordinate DMDA
13647c6ae99SBarry Smith 
13747c6ae99SBarry Smith   Level: intermediate
13847c6ae99SBarry Smith 
13947c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
14047c6ae99SBarry Smith 
141aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetGhostedCoordinates()
14247c6ae99SBarry Smith @*/
1437087cfbeSBarry Smith PetscErrorCode  DMDAGetCoordinateDA(DM da,DM *cda)
14447c6ae99SBarry Smith {
14547c6ae99SBarry Smith   PetscMPIInt    size;
14647c6ae99SBarry Smith   PetscErrorCode ierr;
14747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
14847c6ae99SBarry Smith 
14947c6ae99SBarry Smith   PetscFunctionBegin;
15047c6ae99SBarry Smith   if (!dd->da_coordinates) {
15147c6ae99SBarry Smith     ierr = MPI_Comm_size(((PetscObject)da)->comm,&size);CHKERRQ(ierr);
15247c6ae99SBarry Smith     if (dd->dim == 1) {
15347c6ae99SBarry Smith       PetscInt            s,m,*lc,l;
1541321219cSEthan Coon       DMDABoundaryType bx;
1551321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,0,0,0,0,0,0,&s,&bx,0,0,0);CHKERRQ(ierr);
156aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,0,0);CHKERRQ(ierr);
15747c6ae99SBarry Smith       ierr = PetscMalloc(size*sizeof(PetscInt),&lc);CHKERRQ(ierr);
15847c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
1591321219cSEthan Coon       ierr = DMDACreate1d(((PetscObject)da)->comm,bx,m,1,s,lc,&dd->da_coordinates);CHKERRQ(ierr);
16047c6ae99SBarry Smith       ierr = PetscFree(lc);CHKERRQ(ierr);
16147c6ae99SBarry Smith     } else if (dd->dim == 2) {
16247c6ae99SBarry Smith       PetscInt            i,s,m,*lc,*ld,l,k,n,M,N;
1631321219cSEthan Coon       DMDABoundaryType bx,by;
1641321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,&n,0,&M,&N,0,0,&s,&bx,&by,0,0);CHKERRQ(ierr);
165aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,&k,0);CHKERRQ(ierr);
16647c6ae99SBarry Smith       ierr = PetscMalloc2(size,PetscInt,&lc,size,PetscInt,&ld);CHKERRQ(ierr);
16747c6ae99SBarry Smith       /* only first M values in lc matter */
16847c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
16947c6ae99SBarry Smith       /* every Mth value in ld matters */
17047c6ae99SBarry Smith       ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
17147c6ae99SBarry Smith       for ( i=0; i<N; i++) {
17247c6ae99SBarry Smith         ld[i] = ld[M*i];
17347c6ae99SBarry Smith       }
1741321219cSEthan Coon       ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,DMDA_STENCIL_BOX,m,n,M,N,2,s,lc,ld,&dd->da_coordinates);CHKERRQ(ierr);
17547c6ae99SBarry Smith       ierr = PetscFree2(lc,ld);CHKERRQ(ierr);
17647c6ae99SBarry Smith     } else if (dd->dim == 3) {
17747c6ae99SBarry Smith       PetscInt            i,s,m,*lc,*ld,*le,l,k,q,n,M,N,P,p;
1781321219cSEthan Coon       DMDABoundaryType bx,by,bz;
1791321219cSEthan Coon       ierr = DMDAGetInfo(da,0,&m,&n,&p,&M,&N,&P,0,&s,&bx,&by,&bz,0);CHKERRQ(ierr);
180aa219208SBarry Smith       ierr = DMDAGetCorners(da,0,0,0,&l,&k,&q);CHKERRQ(ierr);
18147c6ae99SBarry Smith       ierr = PetscMalloc3(size,PetscInt,&lc,size,PetscInt,&ld,size,PetscInt,&le);CHKERRQ(ierr);
18247c6ae99SBarry Smith       /* only first M values in lc matter */
18347c6ae99SBarry Smith       ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
18447c6ae99SBarry Smith       /* every Mth value in ld matters */
18547c6ae99SBarry Smith       ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
18647c6ae99SBarry Smith       for ( i=0; i<N; i++) {
18747c6ae99SBarry Smith         ld[i] = ld[M*i];
18847c6ae99SBarry Smith       }
18947c6ae99SBarry Smith       ierr = MPI_Allgather(&q,1,MPIU_INT,le,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr);
19047c6ae99SBarry Smith       for ( i=0; i<P; i++) {
19147c6ae99SBarry Smith         le[i] = le[M*N*i];
19247c6ae99SBarry Smith       }
1931321219cSEthan 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);
19447c6ae99SBarry Smith       ierr = PetscFree3(lc,ld,le);CHKERRQ(ierr);
19547c6ae99SBarry Smith     }
19647c6ae99SBarry Smith   }
19747c6ae99SBarry Smith   *cda = dd->da_coordinates;
19847c6ae99SBarry Smith   PetscFunctionReturn(0);
19947c6ae99SBarry Smith }
20047c6ae99SBarry Smith 
20147c6ae99SBarry Smith 
20247c6ae99SBarry Smith #undef __FUNCT__
203aa219208SBarry Smith #define __FUNCT__ "DMDAGetGhostedCoordinates"
20447c6ae99SBarry Smith /*@
205aa219208SBarry Smith    DMDAGetGhostedCoordinates - Gets the node coordinates associated with a DMDA.
20647c6ae99SBarry Smith 
207aa219208SBarry Smith    Collective on DMDA
20847c6ae99SBarry Smith 
20947c6ae99SBarry Smith    Input Parameter:
21047c6ae99SBarry Smith .  da - the distributed array
21147c6ae99SBarry Smith 
21247c6ae99SBarry Smith    Output Parameter:
21347c6ae99SBarry Smith .  c - coordinate vector
21447c6ae99SBarry Smith 
21547c6ae99SBarry Smith    Note:
21647c6ae99SBarry Smith     Each process has only the coordinates for its local AND ghost nodes
21747c6ae99SBarry Smith 
21847c6ae99SBarry Smith     For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
21947c6ae99SBarry Smith     and (x_0,y_0,z_0,x_1,y_1,z_1...)
22047c6ae99SBarry Smith 
22147c6ae99SBarry Smith   Level: intermediate
22247c6ae99SBarry Smith 
22347c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
22447c6ae99SBarry Smith 
225aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetCoordinateDA()
22647c6ae99SBarry Smith @*/
2277087cfbeSBarry Smith PetscErrorCode  DMDAGetGhostedCoordinates(DM da,Vec *c)
22847c6ae99SBarry Smith {
22947c6ae99SBarry Smith   PetscErrorCode ierr;
23047c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
23147c6ae99SBarry Smith 
23247c6ae99SBarry Smith   PetscFunctionBegin;
23347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
23447c6ae99SBarry Smith   PetscValidPointer(c,2);
235aa219208SBarry Smith   if (!dd->coordinates) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call DMDASetCoordinates() before this call");
23647c6ae99SBarry Smith   if (!dd->ghosted_coordinates) {
2379a42bb27SBarry Smith     DM dac;
238aa219208SBarry Smith     ierr = DMDAGetCoordinateDA(da,&dac);CHKERRQ(ierr);
239564755cdSBarry Smith     ierr = DMCreateLocalVector(dac,&dd->ghosted_coordinates);CHKERRQ(ierr);
2409a42bb27SBarry Smith     ierr = DMGlobalToLocalBegin(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr);
2419a42bb27SBarry Smith     ierr = DMGlobalToLocalEnd(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr);
24247c6ae99SBarry Smith   }
24347c6ae99SBarry Smith   *c = dd->ghosted_coordinates;
24447c6ae99SBarry Smith   PetscFunctionReturn(0);
24547c6ae99SBarry Smith }
24647c6ae99SBarry Smith 
24747c6ae99SBarry Smith #undef __FUNCT__
248aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName"
24947c6ae99SBarry Smith /*@C
250aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
251aa219208SBarry Smith    vectors associated with a DMDA.
25247c6ae99SBarry Smith 
25347c6ae99SBarry Smith    Not Collective
25447c6ae99SBarry Smith 
25547c6ae99SBarry Smith    Input Parameters:
25647c6ae99SBarry Smith +  da - the distributed array
257aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
258aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
25947c6ae99SBarry Smith -  names - the name of the field (component)
26047c6ae99SBarry Smith 
26147c6ae99SBarry Smith   Level: intermediate
26247c6ae99SBarry Smith 
26347c6ae99SBarry Smith .keywords: distributed array, get, component name
26447c6ae99SBarry Smith 
265aa219208SBarry Smith .seealso: DMDAGetFieldName()
26647c6ae99SBarry Smith @*/
2677087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
26847c6ae99SBarry Smith {
26947c6ae99SBarry Smith   PetscErrorCode ierr;
27047c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
27147c6ae99SBarry Smith 
27247c6ae99SBarry Smith   PetscFunctionBegin;
27347c6ae99SBarry Smith    PetscValidHeaderSpecific(da,DM_CLASSID,1);
27447c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
275c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
27647c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
27747c6ae99SBarry Smith   PetscFunctionReturn(0);
27847c6ae99SBarry Smith }
27947c6ae99SBarry Smith 
28047c6ae99SBarry Smith #undef __FUNCT__
281aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName"
28247c6ae99SBarry Smith /*@C
283aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
284aa219208SBarry Smith    vectors associated with a DMDA.
28547c6ae99SBarry Smith 
28647c6ae99SBarry Smith    Not Collective
28747c6ae99SBarry Smith 
28847c6ae99SBarry Smith    Input Parameter:
28947c6ae99SBarry Smith +  da - the distributed array
290aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
291aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
29247c6ae99SBarry Smith 
29347c6ae99SBarry Smith    Output Parameter:
29447c6ae99SBarry Smith .  names - the name of the field (component)
29547c6ae99SBarry Smith 
29647c6ae99SBarry Smith   Level: intermediate
29747c6ae99SBarry Smith 
29847c6ae99SBarry Smith .keywords: distributed array, get, component name
29947c6ae99SBarry Smith 
300aa219208SBarry Smith .seealso: DMDASetFieldName()
30147c6ae99SBarry Smith @*/
3027087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
30347c6ae99SBarry Smith {
30447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
30547c6ae99SBarry Smith 
30647c6ae99SBarry Smith   PetscFunctionBegin;
30747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
30847c6ae99SBarry Smith   PetscValidPointer(name,3);
30947c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
31047c6ae99SBarry Smith   *name = dd->fieldname[nf];
31147c6ae99SBarry Smith   PetscFunctionReturn(0);
31247c6ae99SBarry Smith }
31347c6ae99SBarry Smith 
31447c6ae99SBarry Smith #undef __FUNCT__
315aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners"
31647c6ae99SBarry Smith /*@
317aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
31847c6ae99SBarry Smith    corner of the local region, excluding ghost points.
31947c6ae99SBarry Smith 
32047c6ae99SBarry Smith    Not Collective
32147c6ae99SBarry Smith 
32247c6ae99SBarry Smith    Input Parameter:
32347c6ae99SBarry Smith .  da - the distributed array
32447c6ae99SBarry Smith 
32547c6ae99SBarry Smith    Output Parameters:
32647c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
32747c6ae99SBarry Smith            for 2D and 3D problems)
32847c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
32947c6ae99SBarry Smith            these are used for 2D and 3D problems)
33047c6ae99SBarry Smith 
33147c6ae99SBarry Smith    Note:
33247c6ae99SBarry Smith    The corner information is independent of the number of degrees of
333aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
33447c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
33547c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
33647c6ae99SBarry Smith    Any of y, z, n, and p can be passed in as PETSC_NULL if not needed.
33747c6ae99SBarry Smith 
33847c6ae99SBarry Smith   Level: beginner
33947c6ae99SBarry Smith 
34047c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
34147c6ae99SBarry Smith 
342aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
34347c6ae99SBarry Smith @*/
3447087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
34547c6ae99SBarry Smith {
34647c6ae99SBarry Smith   PetscInt w;
34747c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
34847c6ae99SBarry Smith 
34947c6ae99SBarry Smith   PetscFunctionBegin;
35047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
35147c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
35247c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
35347c6ae99SBarry Smith   w = dd->w;
35447c6ae99SBarry Smith   if (x) *x = dd->xs/w; if(m) *m = (dd->xe - dd->xs)/w;
35547c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
35647c6ae99SBarry Smith   if (y) *y = dd->ys;   if (n) *n = (dd->ye - dd->ys);
35747c6ae99SBarry Smith   if (z) *z = dd->zs;   if (p) *p = (dd->ze - dd->zs);
35847c6ae99SBarry Smith   PetscFunctionReturn(0);
35947c6ae99SBarry Smith }
36047c6ae99SBarry Smith 
36147c6ae99SBarry Smith #undef __FUNCT__
362aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox"
36347c6ae99SBarry Smith /*@
364aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
36547c6ae99SBarry Smith 
36647c6ae99SBarry Smith    Not Collective
36747c6ae99SBarry Smith 
36847c6ae99SBarry Smith    Input Parameter:
36947c6ae99SBarry Smith .  da - the distributed array
37047c6ae99SBarry Smith 
37147c6ae99SBarry Smith    Output Parameters:
37247c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
37347c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
37447c6ae99SBarry Smith 
37547c6ae99SBarry Smith   Level: beginner
37647c6ae99SBarry Smith 
37747c6ae99SBarry Smith .keywords: distributed array, get, coordinates
37847c6ae99SBarry Smith 
379aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetBoundingBox()
38047c6ae99SBarry Smith @*/
3817087cfbeSBarry Smith PetscErrorCode  DMDAGetLocalBoundingBox(DM da,PetscReal lmin[],PetscReal lmax[])
38247c6ae99SBarry Smith {
38347c6ae99SBarry Smith   PetscErrorCode    ierr;
38447c6ae99SBarry Smith   Vec               coords  = PETSC_NULL;
38547c6ae99SBarry Smith   PetscInt          dim,i,j;
38647c6ae99SBarry Smith   const PetscScalar *local_coords;
38747c6ae99SBarry Smith   PetscReal         min[3]={PETSC_MAX,PETSC_MAX,PETSC_MAX},max[3]={PETSC_MIN,PETSC_MIN,PETSC_MIN};
38847c6ae99SBarry Smith   PetscInt          N,Ni;
38947c6ae99SBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
39047c6ae99SBarry Smith 
39147c6ae99SBarry Smith   PetscFunctionBegin;
39247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
39347c6ae99SBarry Smith   dim = dd->dim;
394aa219208SBarry Smith   ierr = DMDAGetCoordinates(da,&coords);CHKERRQ(ierr);
39547c6ae99SBarry Smith   ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
39647c6ae99SBarry Smith   ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
39747c6ae99SBarry Smith   Ni = N/dim;
39847c6ae99SBarry Smith   for (i=0; i<Ni; i++) {
39947c6ae99SBarry Smith     for (j=0; j<dim; j++) {
40047c6ae99SBarry Smith       min[j] = PetscMin(min[j],PetscRealPart(local_coords[i*dim+j]));CHKERRQ(ierr);
40147c6ae99SBarry Smith       max[j] = PetscMax(min[j],PetscRealPart(local_coords[i*dim+j]));CHKERRQ(ierr);
40247c6ae99SBarry Smith     }
40347c6ae99SBarry Smith   }
40447c6ae99SBarry Smith   ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
40547c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
40647c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
40747c6ae99SBarry Smith   PetscFunctionReturn(0);
40847c6ae99SBarry Smith }
40947c6ae99SBarry Smith 
41047c6ae99SBarry Smith #undef __FUNCT__
411aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox"
41247c6ae99SBarry Smith /*@
413aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
41447c6ae99SBarry Smith 
415aa219208SBarry Smith    Collective on DMDA
41647c6ae99SBarry Smith 
41747c6ae99SBarry Smith    Input Parameter:
41847c6ae99SBarry Smith .  da - the distributed array
41947c6ae99SBarry Smith 
42047c6ae99SBarry Smith    Output Parameters:
42147c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
42247c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
42347c6ae99SBarry Smith 
42447c6ae99SBarry Smith   Level: beginner
42547c6ae99SBarry Smith 
42647c6ae99SBarry Smith .keywords: distributed array, get, coordinates
42747c6ae99SBarry Smith 
428aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetLocalBoundingBox()
42947c6ae99SBarry Smith @*/
4307087cfbeSBarry Smith PetscErrorCode  DMDAGetBoundingBox(DM da,PetscReal gmin[],PetscReal gmax[])
43147c6ae99SBarry Smith {
43247c6ae99SBarry Smith   PetscErrorCode ierr;
43347c6ae99SBarry Smith   PetscMPIInt    count;
43447c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
43547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
43647c6ae99SBarry Smith 
43747c6ae99SBarry Smith   PetscFunctionBegin;
43847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
43947c6ae99SBarry Smith   count = PetscMPIIntCast(dd->dim);
440aa219208SBarry Smith   ierr = DMDAGetLocalBoundingBox(da,lmin,lmax);CHKERRQ(ierr);
441*d9822059SBarry Smith   if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,((PetscObject)da)->comm);CHKERRQ(ierr);}
442*d9822059SBarry Smith   if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,((PetscObject)da)->comm);CHKERRQ(ierr);}
44347c6ae99SBarry Smith   PetscFunctionReturn(0);
44447c6ae99SBarry Smith }
445