xref: /petsc/src/dm/impls/da/daindex.c (revision 8b8307b2cbff7ae63ec0459e534a4a6ccda2943f)
1 #define PETSCDM_DLL
2 
3 /*
4   Code for manipulating distributed regular arrays in parallel.
5 */
6 
7 #include "private/daimpl.h"    /*I   "petscdm.h"   I*/
8 
9 #undef __FUNCT__
10 #define __FUNCT__ "DMDAGetGlobalIndices"
11 /*@C
12    DMDAGetGlobalIndices - Returns the global node number of all local nodes,
13    including ghost nodes.
14 
15    Not Collective
16 
17    Input Parameter:
18 .  da - the distributed array
19 
20    Output Parameters:
21 +  n - the number of local elements, including ghost nodes (or PETSC_NULL)
22 -  idx - the global indices
23 
24    Level: intermediate
25 
26    Note:
27    For DMDA_STENCIL_STAR stencils the inactive corner ghost nodes are also included
28    in the list of local indices (even though those nodes are not updated
29    during calls to DMDAXXXToXXX().
30 
31    Essentially the same data is returned in the form of a local-to-global mapping
32    with the routine DMDAGetISLocalToGlobalMapping();
33 
34    Fortran Note:
35    This routine is used differently from Fortran
36 .vb
37         DM          da
38         integer     n,da_array(1)
39         PetscOffset i_da
40         integer     ierr
41         call DMDAGetGlobalIndices(da,n,da_array,i_da,ierr)
42 
43    C Access first local entry in list
44         value = da_array(i_da + 1)
45 .ve
46 
47    See the <A href="../../docs/manual.pdf#nameddest=ch_fortran">Fortran chapter</A> of the users manual for details.
48 
49 .keywords: distributed array, get, global, indices, local-to-global
50 
51 .seealso: DMDACreate2d(), DMDAGetGhostCorners(), DMDAGetCorners(), DMLocalToGlobalBegin()
52           DMGlobalToLocalBegin(), DMGlobalToLocalEnd(), DMDALocalToLocalBegin(), DMDAGetAO(), DMDAGetGlobalIndicesF90()
53           DMDAGetISLocalToGlobalMapping(), DMDACreate3d(), DMDACreate1d(), DMDALocalToLocalEnd(), DMDAGetOwnershipRanges()
54 @*/
55 PetscErrorCode PETSCDM_DLLEXPORT DMDAGetGlobalIndices(DM da,PetscInt *n,PetscInt **idx)
56 {
57   DM_DA          *dd = (DM_DA*)da->data;
58 
59   PetscFunctionBegin;
60   PetscValidHeaderSpecific(da,DM_CLASSID,1);
61   if (n)   *n   = dd->Nl;
62   if (idx) *idx = dd->idx;
63   PetscFunctionReturn(0);
64 }
65 
66 #undef __FUNCT__
67 #define __FUNCT__ "DMDAGetNatural_Private"
68 /*
69    Gets the natural number for each global number on the process.
70 
71    Used by DMDAGetAO() and DMDAGlobalToNatural_Create()
72 */
73 PetscErrorCode DMDAGetNatural_Private(DM da,PetscInt *outNlocal,IS *isnatural)
74 {
75   PetscErrorCode ierr;
76   PetscInt       Nlocal,i,j,k,*lidx,lict = 0;
77   DM_DA          *dd = (DM_DA*)da->data;
78 
79   PetscFunctionBegin;
80   Nlocal = (dd->xe-dd->xs);
81   if (dd->dim > 1) {
82     Nlocal *= (dd->ye-dd->ys);
83   }
84   if (dd->dim > 2) {
85     Nlocal *= (dd->ze-dd->zs);
86   }
87 
88   ierr = PetscMalloc(Nlocal*sizeof(PetscInt),&lidx);CHKERRQ(ierr);
89 
90   if (dd->dim == 1) {
91     for (i=dd->xs; i<dd->xe; i++) {
92       /*  global number in natural ordering */
93       lidx[lict++] = i;
94     }
95   } else if (dd->dim == 2) {
96     for (j=dd->ys; j<dd->ye; j++) {
97       for (i=dd->xs; i<dd->xe; i++) {
98 	/*  global number in natural ordering */
99 	lidx[lict++] = i + j*dd->M*dd->w;
100       }
101     }
102   } else if (dd->dim == 3) {
103     for (k=dd->zs; k<dd->ze; k++) {
104       for (j=dd->ys; j<dd->ye; j++) {
105 	for (i=dd->xs; i<dd->xe; i++) {
106 	  lidx[lict++] = i + j*dd->M*dd->w + k*dd->M*dd->N*dd->w;
107 	}
108       }
109     }
110   }
111   *outNlocal = Nlocal;
112   ierr = ISCreateGeneral(((PetscObject)da)->comm,Nlocal,lidx,PETSC_OWN_POINTER,isnatural);CHKERRQ(ierr);
113   PetscFunctionReturn(0);
114 }
115 
116 #undef __FUNCT__
117 #define __FUNCT__ "DMDAGetAO"
118 /*@
119    DMDAGetAO - Gets the application ordering context for a distributed array.
120 
121    Collective on DMDA
122 
123    Input Parameter:
124 .  da - the distributed array
125 
126    Output Parameters:
127 .  ao - the application ordering context for DMDAs
128 
129    Level: intermediate
130 
131    Notes:
132    In this case, the AO maps to the natural grid ordering that would be used
133    for the DMDA if only 1 processor were employed (ordering most rapidly in the
134    x-direction, then y, then z).  Multiple degrees of freedom are numbered
135    for each node (rather than 1 component for the whole grid, then the next
136    component, etc.)
137 
138 .keywords: distributed array, get, global, indices, local-to-global
139 
140 .seealso: DMDACreate2d(), DMDAGetGhostCorners(), DMDAGetCorners(), DMDALocalToGlocal()
141           DMGlobalToLocalBegin(), DMGlobalToLocalEnd(), DMDALocalToLocalBegin(), DMDALocalToLocalEnd(), DMDAGetGlobalIndices(), DMDAGetOwnershipRanges(),
142           AO, AOPetscToApplication(), AOApplicationToPetsc()
143 @*/
144 PetscErrorCode PETSCDM_DLLEXPORT DMDAGetAO(DM da,AO *ao)
145 {
146   DM_DA *dd = (DM_DA*)da->data;
147 
148   PetscFunctionBegin;
149   PetscValidHeaderSpecific(da,DM_CLASSID,1);
150   PetscValidPointer(ao,2);
151 
152   /*
153      Build the natural ordering to PETSc ordering mappings.
154   */
155   if (!dd->ao) {
156     IS             ispetsc,isnatural;
157     PetscErrorCode ierr;
158     PetscInt       Nlocal;
159 
160     ierr = DMDAGetNatural_Private(da,&Nlocal,&isnatural);CHKERRQ(ierr);
161     ierr = ISCreateStride(((PetscObject)da)->comm,Nlocal,dd->base,1,&ispetsc);CHKERRQ(ierr);
162     ierr = AOCreateBasicIS(isnatural,ispetsc,&dd->ao);CHKERRQ(ierr);
163     ierr = PetscLogObjectParent(da,dd->ao);CHKERRQ(ierr);
164     ierr = ISDestroy(ispetsc);CHKERRQ(ierr);
165     ierr = ISDestroy(isnatural);CHKERRQ(ierr);
166   }
167   *ao = dd->ao;
168   PetscFunctionReturn(0);
169 }
170 
171 /*MC
172     DMDAGetGlobalIndicesF90 - Returns a Fortran90 pointer to the list of
173     global indices (global node number of all local nodes, including
174     ghost nodes).
175 
176     Synopsis:
177     DMDAGetGlobalIndicesF90(DM da,integer n,{integer, pointer :: idx(:)},integer ierr)
178 
179     Not Collective
180 
181     Input Parameter:
182 .   da - the distributed array
183 
184     Output Parameters:
185 +   n - the number of local elements, including ghost nodes (or PETSC_NULL)
186 .   idx - the Fortran90 pointer to the global indices
187 -   ierr - error code
188 
189     Level: intermediate
190 
191     Notes:
192      Not yet supported for all F90 compilers
193 
194 .keywords: distributed array, get, global, indices, local-to-global, f90
195 
196 .seealso: DMDAGetGlobalIndices()
197 M*/
198