xref: /petsc/src/dm/impls/da/dacreate.c (revision 8cc058d9cd56c1ccb3be12a47760ddfc446aaffc)
1 
2 #include <petsc-private/dmdaimpl.h>    /*I   "petscdmda.h"   I*/
3 
4 #undef __FUNCT__
5 #define __FUNCT__ "DMSetFromOptions_DA"
6 PetscErrorCode  DMSetFromOptions_DA(DM da)
7 {
8   PetscErrorCode ierr;
9   DM_DA          *dd         = (DM_DA*)da->data;
10   PetscInt       refine      = 0,maxnlevels = 100,*refx,*refy,*refz,n,i;
11   PetscBool      negativeMNP = PETSC_FALSE,bM = PETSC_FALSE,bN = PETSC_FALSE, bP = PETSC_FALSE,flg;
12 
13   PetscFunctionBegin;
14   PetscValidHeaderSpecific(da,DM_CLASSID,1);
15 
16   if (dd->M < 0) {
17     dd->M       = -dd->M;
18     bM          = PETSC_TRUE;
19     negativeMNP = PETSC_TRUE;
20   }
21   if (dd->dim > 1 && dd->N < 0) {
22     dd->N       = -dd->N;
23     bN          = PETSC_TRUE;
24     negativeMNP = PETSC_TRUE;
25   }
26   if (dd->dim > 2 && dd->P < 0) {
27     dd->P       = -dd->P;
28     bP          = PETSC_TRUE;
29     negativeMNP = PETSC_TRUE;
30   }
31 
32   ierr = PetscOptionsHead("DMDA Options");CHKERRQ(ierr);
33   if (bM) {ierr = PetscOptionsInt("-da_grid_x","Number of grid points in x direction","DMDASetSizes",dd->M,&dd->M,NULL);CHKERRQ(ierr);}
34   if (bN) {ierr = PetscOptionsInt("-da_grid_y","Number of grid points in y direction","DMDASetSizes",dd->N,&dd->N,NULL);CHKERRQ(ierr);}
35   if (bP) {ierr = PetscOptionsInt("-da_grid_z","Number of grid points in z direction","DMDASetSizes",dd->P,&dd->P,NULL);CHKERRQ(ierr);}
36 
37   ierr = PetscOptionsInt("-da_overlap","Decomposition overlap in all directions","DMDASetOverlap",dd->xol,&dd->xol,&flg);CHKERRQ(ierr);
38   if (flg) {ierr = DMDASetOverlap(da,dd->xol,dd->xol,dd->xol);CHKERRQ(ierr);}
39 
40   ierr = PetscOptionsInt("-da_overlap_x","Decomposition overlap in x direction","DMDASetOverlap",dd->xol,&dd->xol,NULL);CHKERRQ(ierr);
41   if (dd->dim > 1) {ierr = PetscOptionsInt("-da_overlap_y","Decomposition overlap in y direction","DMDASetOverlap",dd->yol,&dd->yol,NULL);CHKERRQ(ierr);}
42   if (dd->dim > 2) {ierr = PetscOptionsInt("-da_overlap_z","Decomposition overlap in z direction","DMDASetOverlap",dd->zol,&dd->zol,NULL);CHKERRQ(ierr);}
43   /* Handle DMDA parallel distibution */
44   ierr = PetscOptionsInt("-da_processors_x","Number of processors in x direction","DMDASetNumProcs",dd->m,&dd->m,NULL);CHKERRQ(ierr);
45   if (dd->dim > 1) {ierr = PetscOptionsInt("-da_processors_y","Number of processors in y direction","DMDASetNumProcs",dd->n,&dd->n,NULL);CHKERRQ(ierr);}
46   if (dd->dim > 2) {ierr = PetscOptionsInt("-da_processors_z","Number of processors in z direction","DMDASetNumProcs",dd->p,&dd->p,NULL);CHKERRQ(ierr);}
47   /* Handle DMDA refinement */
48   ierr = PetscOptionsInt("-da_refine_x","Refinement ratio in x direction","DMDASetRefinementFactor",dd->refine_x,&dd->refine_x,NULL);CHKERRQ(ierr);
49   if (dd->dim > 1) {ierr = PetscOptionsInt("-da_refine_y","Refinement ratio in y direction","DMDASetRefinementFactor",dd->refine_y,&dd->refine_y,NULL);CHKERRQ(ierr);}
50   if (dd->dim > 2) {ierr = PetscOptionsInt("-da_refine_z","Refinement ratio in z direction","DMDASetRefinementFactor",dd->refine_z,&dd->refine_z,NULL);CHKERRQ(ierr);}
51   dd->coarsen_x = dd->refine_x; dd->coarsen_y = dd->refine_y; dd->coarsen_z = dd->refine_z;
52 
53   /* Get refinement factors, defaults taken from the coarse DMDA */
54   ierr = PetscMalloc3(maxnlevels,PetscInt,&refx,maxnlevels,PetscInt,&refy,maxnlevels,PetscInt,&refz);CHKERRQ(ierr);
55   ierr = DMDAGetRefinementFactor(da,&refx[0],&refy[0],&refz[0]);CHKERRQ(ierr);
56   for (i=1; i<maxnlevels; i++) {
57     refx[i] = refx[0];
58     refy[i] = refy[0];
59     refz[i] = refz[0];
60   }
61   n    = maxnlevels;
62   ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_x",refx,&n,NULL);CHKERRQ(ierr);
63   if (da->levelup - da->leveldown >= 0) dd->refine_x = refx[da->levelup - da->leveldown];
64   if (da->levelup - da->leveldown >= 1) dd->coarsen_x = refx[da->levelup - da->leveldown - 1];
65   if (dd->dim > 1) {
66     n    = maxnlevels;
67     ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_y",refy,&n,NULL);CHKERRQ(ierr);
68     if (da->levelup - da->leveldown >= 0) dd->refine_y = refy[da->levelup - da->leveldown];
69     if (da->levelup - da->leveldown >= 1) dd->coarsen_y = refy[da->levelup - da->leveldown - 1];
70   }
71   if (dd->dim > 2) {
72     n    = maxnlevels;
73     ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_z",refz,&n,NULL);CHKERRQ(ierr);
74     if (da->levelup - da->leveldown >= 0) dd->refine_z = refz[da->levelup - da->leveldown];
75     if (da->levelup - da->leveldown >= 1) dd->coarsen_z = refz[da->levelup - da->leveldown - 1];
76   }
77 
78   if (negativeMNP) {ierr = PetscOptionsInt("-da_refine","Uniformly refine DA one or more times","None",refine,&refine,NULL);CHKERRQ(ierr);}
79   ierr = PetscOptionsTail();CHKERRQ(ierr);
80 
81   while (refine--) {
82     if (dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
83       dd->M = dd->refine_x*dd->M;
84     } else {
85       dd->M = 1 + dd->refine_x*(dd->M - 1);
86     }
87     if (dd->by == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
88       dd->N = dd->refine_y*dd->N;
89     } else {
90       dd->N = 1 + dd->refine_y*(dd->N - 1);
91     }
92     if (dd->bz == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
93       dd->P = dd->refine_z*dd->P;
94     } else {
95       dd->P = 1 + dd->refine_z*(dd->P - 1);
96     }
97     da->levelup++;
98     if (da->levelup - da->leveldown >= 0) {
99       dd->refine_x = refx[da->levelup - da->leveldown];
100       dd->refine_y = refy[da->levelup - da->leveldown];
101       dd->refine_z = refz[da->levelup - da->leveldown];
102     }
103     if (da->levelup - da->leveldown >= 1) {
104       dd->coarsen_x = refx[da->levelup - da->leveldown - 1];
105       dd->coarsen_y = refy[da->levelup - da->leveldown - 1];
106       dd->coarsen_z = refz[da->levelup - da->leveldown - 1];
107     }
108   }
109   ierr = PetscFree3(refx,refy,refz);CHKERRQ(ierr);
110   PetscFunctionReturn(0);
111 }
112 
113 extern PetscErrorCode  DMCreateGlobalVector_DA(DM,Vec*);
114 extern PetscErrorCode  DMCreateLocalVector_DA(DM,Vec*);
115 extern PetscErrorCode  DMGlobalToLocalBegin_DA(DM,Vec,InsertMode,Vec);
116 extern PetscErrorCode  DMGlobalToLocalEnd_DA(DM,Vec,InsertMode,Vec);
117 extern PetscErrorCode  DMLocalToGlobalBegin_DA(DM,Vec,InsertMode,Vec);
118 extern PetscErrorCode  DMLocalToGlobalEnd_DA(DM,Vec,InsertMode,Vec);
119 extern PetscErrorCode  DMCreateInterpolation_DA(DM,DM,Mat*,Vec*);
120 extern PetscErrorCode  DMCreateColoring_DA(DM,ISColoringType,MatType,ISColoring*);
121 extern PetscErrorCode  DMCreateMatrix_DA(DM,MatType,Mat*);
122 extern PetscErrorCode  DMCreateCoordinateDM_DA(DM,DM*);
123 extern PetscErrorCode  DMRefine_DA(DM,MPI_Comm,DM*);
124 extern PetscErrorCode  DMCoarsen_DA(DM,MPI_Comm,DM*);
125 extern PetscErrorCode  DMRefineHierarchy_DA(DM,PetscInt,DM[]);
126 extern PetscErrorCode  DMCoarsenHierarchy_DA(DM,PetscInt,DM[]);
127 extern PetscErrorCode  DMCreateInjection_DA(DM,DM,VecScatter*);
128 extern PetscErrorCode  DMCreateAggregates_DA(DM,DM,Mat*);
129 extern PetscErrorCode  DMView_DA(DM,PetscViewer);
130 extern PetscErrorCode  DMSetUp_DA(DM);
131 extern PetscErrorCode  DMDestroy_DA(DM);
132 extern PetscErrorCode  DMCreateDomainDecomposition_DA(DM,PetscInt*,char***,IS**,IS**,DM**);
133 extern PetscErrorCode  DMCreateDomainDecompositionScatters_DA(DM,PetscInt,DM*,VecScatter**,VecScatter**,VecScatter**);
134 
135 #undef __FUNCT__
136 #define __FUNCT__ "DMLoad_DA"
137 PetscErrorCode DMLoad_DA(DM da,PetscViewer viewer)
138 {
139   PetscErrorCode   ierr;
140   PetscInt         dim,m,n,p,dof,swidth;
141   DMDAStencilType  stencil;
142   DMDABoundaryType bx,by,bz;
143   PetscBool        coors;
144   DM               dac;
145   Vec              c;
146 
147   PetscFunctionBegin;
148   ierr = PetscViewerBinaryRead(viewer,&dim,1,PETSC_INT);CHKERRQ(ierr);
149   ierr = PetscViewerBinaryRead(viewer,&m,1,PETSC_INT);CHKERRQ(ierr);
150   ierr = PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);CHKERRQ(ierr);
151   ierr = PetscViewerBinaryRead(viewer,&p,1,PETSC_INT);CHKERRQ(ierr);
152   ierr = PetscViewerBinaryRead(viewer,&dof,1,PETSC_INT);CHKERRQ(ierr);
153   ierr = PetscViewerBinaryRead(viewer,&swidth,1,PETSC_INT);CHKERRQ(ierr);
154   ierr = PetscViewerBinaryRead(viewer,&bx,1,PETSC_ENUM);CHKERRQ(ierr);
155   ierr = PetscViewerBinaryRead(viewer,&by,1,PETSC_ENUM);CHKERRQ(ierr);
156   ierr = PetscViewerBinaryRead(viewer,&bz,1,PETSC_ENUM);CHKERRQ(ierr);
157   ierr = PetscViewerBinaryRead(viewer,&stencil,1,PETSC_ENUM);CHKERRQ(ierr);
158 
159   ierr = DMDASetDim(da, dim);CHKERRQ(ierr);
160   ierr = DMDASetSizes(da, m,n,p);CHKERRQ(ierr);
161   ierr = DMDASetBoundaryType(da, bx, by, bz);CHKERRQ(ierr);
162   ierr = DMDASetDof(da, dof);CHKERRQ(ierr);
163   ierr = DMDASetStencilType(da, stencil);CHKERRQ(ierr);
164   ierr = DMDASetStencilWidth(da, swidth);CHKERRQ(ierr);
165   ierr = DMSetUp(da);CHKERRQ(ierr);
166   ierr = PetscViewerBinaryRead(viewer,&coors,1,PETSC_ENUM);CHKERRQ(ierr);
167   if (coors) {
168     ierr = DMGetCoordinateDM(da,&dac);CHKERRQ(ierr);
169     ierr = DMCreateGlobalVector(dac,&c);CHKERRQ(ierr);
170     ierr = VecLoad(c,viewer);CHKERRQ(ierr);
171     ierr = DMSetCoordinates(da,c);CHKERRQ(ierr);
172     ierr = VecDestroy(&c);CHKERRQ(ierr);
173   }
174   PetscFunctionReturn(0);
175 }
176 
177 #undef __FUNCT__
178 #define __FUNCT__ "DMCreateSubDM_DA"
179 PetscErrorCode DMCreateSubDM_DA(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
180 {
181   PetscErrorCode ierr;
182   DM_DA          *da = (DM_DA*)dm->data;
183 
184   PetscFunctionBegin;
185   if (da->dim != 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Support only implemented for 2d");
186   if (subdm) {
187     ierr = DMDACreate2d(PetscObjectComm((PetscObject)dm),da->bx,da->by,da->stencil_type,da->M,da->N,da->m,da->n,numFields,da->s,da->lx,da->ly,subdm);CHKERRQ(ierr);
188   }
189   if (is) {
190     PetscInt *indices,cnt = 0, dof = da->w,i,j;
191     ierr = PetscMalloc(sizeof(PetscInt)*da->Nlocal*numFields/dof,&indices);CHKERRQ(ierr);
192     for (i=da->base/dof; i<(da->base+da->Nlocal)/dof; i++) {
193       for (j=0; j<numFields; j++) {
194         indices[cnt++] = dof*i + fields[j];
195       }
196     }
197     if (cnt != da->Nlocal*numFields/dof) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Count does not equal expected value");
198     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm),da->Nlocal*numFields/dof,indices,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
199   }
200   PetscFunctionReturn(0);
201 }
202 
203 #undef __FUNCT__
204 #define __FUNCT__ "DMCreateFieldDecomposition_DA"
205 PetscErrorCode DMCreateFieldDecomposition_DA(DM dm, PetscInt *len,char ***namelist, IS **islist, DM **dmlist)
206 {
207   PetscInt       i;
208   PetscErrorCode ierr;
209   DM_DA          *dd = (DM_DA*)dm->data;
210   PetscInt       dof = dd->w;
211 
212   PetscFunctionBegin;
213   if (len) *len = dof;
214   if (islist) {
215     Vec      v;
216     PetscInt rstart,n;
217 
218     ierr = DMGetGlobalVector(dm,&v);CHKERRQ(ierr);
219     ierr = VecGetOwnershipRange(v,&rstart,NULL);CHKERRQ(ierr);
220     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
221     ierr = DMRestoreGlobalVector(dm,&v);CHKERRQ(ierr);
222     ierr = PetscMalloc(dof*sizeof(IS),islist);CHKERRQ(ierr);
223     for (i=0; i<dof; i++) {
224       ierr = ISCreateStride(PetscObjectComm((PetscObject)dm),n/dof,rstart+i,dof,&(*islist)[i]);CHKERRQ(ierr);
225     }
226   }
227   if (namelist) {
228     ierr = PetscMalloc(dof*sizeof(const char*), namelist);CHKERRQ(ierr);
229     if (dd->fieldname) {
230       for (i=0; i<dof; i++) {
231         ierr = PetscStrallocpy(dd->fieldname[i],&(*namelist)[i]);CHKERRQ(ierr);
232       }
233     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently DMDA must have fieldnames");
234   }
235   if (dmlist) {
236     DM da;
237 
238     ierr = DMDACreate(PetscObjectComm((PetscObject)dm), &da);CHKERRQ(ierr);
239     ierr = DMDASetDim(da, dd->dim);CHKERRQ(ierr);
240     ierr = DMDASetSizes(da, dd->M, dd->N, dd->P);CHKERRQ(ierr);
241     ierr = DMDASetNumProcs(da, dd->m, dd->n, dd->p);CHKERRQ(ierr);
242     ierr = DMDASetBoundaryType(da, dd->bx, dd->by, dd->bz);CHKERRQ(ierr);
243     ierr = DMDASetDof(da, 1);CHKERRQ(ierr);
244     ierr = DMDASetStencilType(da, dd->stencil_type);CHKERRQ(ierr);
245     ierr = DMDASetStencilWidth(da, dd->s);CHKERRQ(ierr);
246     ierr = DMSetUp(da);CHKERRQ(ierr);
247     ierr = PetscMalloc(dof*sizeof(DM),dmlist);CHKERRQ(ierr);
248     for (i=0; i<dof-1; i++) {ierr = PetscObjectReference((PetscObject)da);CHKERRQ(ierr);}
249     for (i=0; i<dof; i++) (*dmlist)[i] = da;
250   }
251   PetscFunctionReturn(0);
252 }
253 
254 /*MC
255    DMDA = "da" - A DM object that is used to manage data for a structured grid in 1, 2, or 3 dimensions.
256          In the global representation of the vector each process stores a non-overlapping rectangular (or slab in 3d) portion of the grid points.
257          In the local representation these rectangular regions (slabs) are extended in all directions by a stencil width.
258 
259          The vectors can be thought of as either cell centered or vertex centered on the mesh. But some variables cannot be cell centered and others
260          vertex centered.
261 
262 
263   Level: intermediate
264 
265 .seealso: DMType, DMCOMPOSITE, DMDACreate(), DMCreate(), DMSetType()
266 M*/
267 
268 
269 #undef __FUNCT__
270 #define __FUNCT__ "DMCreate_DA"
271 PETSC_EXTERN PetscErrorCode DMCreate_DA(DM da)
272 {
273   PetscErrorCode ierr;
274   DM_DA          *dd;
275 
276   PetscFunctionBegin;
277   PetscValidPointer(da,1);
278   ierr     = PetscNewLog(da,DM_DA,&dd);CHKERRQ(ierr);
279   da->data = dd;
280 
281   dd->dim        = -1;
282   dd->interptype = DMDA_Q1;
283   dd->refine_x   = 2;
284   dd->refine_y   = 2;
285   dd->refine_z   = 2;
286   dd->coarsen_x  = 2;
287   dd->coarsen_y  = 2;
288   dd->coarsen_z  = 2;
289   dd->fieldname  = NULL;
290   dd->nlocal     = -1;
291   dd->Nlocal     = -1;
292   dd->M          = -1;
293   dd->N          = -1;
294   dd->P          = -1;
295   dd->m          = -1;
296   dd->n          = -1;
297   dd->p          = -1;
298   dd->w          = -1;
299   dd->s          = -1;
300 
301   dd->xs = -1; dd->xe = -1; dd->ys = -1; dd->ye = -1; dd->zs = -1; dd->ze = -1;
302   dd->Xs = -1; dd->Xe = -1; dd->Ys = -1; dd->Ye = -1; dd->Zs = -1; dd->Ze = -1;
303 
304   dd->xol             = 0;
305   dd->yol             = 0;
306   dd->zol             = 0;
307   dd->xo              = 0;
308   dd->yo              = 0;
309   dd->zo              = 0;
310   dd->Mo              = -1;
311   dd->No              = -1;
312   dd->Po              = -1;
313 
314   dd->gtol         = NULL;
315   dd->ltog         = NULL;
316   dd->ltol         = NULL;
317   dd->ao           = NULL;
318   dd->base         = -1;
319   dd->bx           = DMDA_BOUNDARY_NONE;
320   dd->by           = DMDA_BOUNDARY_NONE;
321   dd->bz           = DMDA_BOUNDARY_NONE;
322   dd->stencil_type = DMDA_STENCIL_BOX;
323   dd->interptype   = DMDA_Q1;
324   dd->idx          = NULL;
325   dd->Nl           = -1;
326   dd->lx           = NULL;
327   dd->ly           = NULL;
328   dd->lz           = NULL;
329 
330   dd->elementtype = DMDA_ELEMENT_Q1;
331 
332   ierr = PetscStrallocpy(VECSTANDARD,(char**)&da->vectype);CHKERRQ(ierr);
333 
334   da->ops->globaltolocalbegin          = DMGlobalToLocalBegin_DA;
335   da->ops->globaltolocalend            = DMGlobalToLocalEnd_DA;
336   da->ops->localtoglobalbegin          = DMLocalToGlobalBegin_DA;
337   da->ops->localtoglobalend            = DMLocalToGlobalEnd_DA;
338   da->ops->createglobalvector          = DMCreateGlobalVector_DA;
339   da->ops->createlocalvector           = DMCreateLocalVector_DA;
340   da->ops->createinterpolation         = DMCreateInterpolation_DA;
341   da->ops->getcoloring                 = DMCreateColoring_DA;
342   da->ops->creatematrix                = DMCreateMatrix_DA;
343   da->ops->refine                      = DMRefine_DA;
344   da->ops->coarsen                     = DMCoarsen_DA;
345   da->ops->refinehierarchy             = DMRefineHierarchy_DA;
346   da->ops->coarsenhierarchy            = DMCoarsenHierarchy_DA;
347   da->ops->getinjection                = DMCreateInjection_DA;
348   da->ops->getaggregates               = DMCreateAggregates_DA;
349   da->ops->destroy                     = DMDestroy_DA;
350   da->ops->view                        = 0;
351   da->ops->setfromoptions              = DMSetFromOptions_DA;
352   da->ops->setup                       = DMSetUp_DA;
353   da->ops->load                        = DMLoad_DA;
354   da->ops->createcoordinatedm          = DMCreateCoordinateDM_DA;
355   da->ops->createsubdm                 = DMCreateSubDM_DA;
356   da->ops->createfielddecomposition    = DMCreateFieldDecomposition_DA;
357   da->ops->createdomaindecomposition   = DMCreateDomainDecomposition_DA;
358   da->ops->createddscatters            = DMCreateDomainDecompositionScatters_DA;
359   PetscFunctionReturn(0);
360 }
361 
362 #undef __FUNCT__
363 #define __FUNCT__ "DMDACreate"
364 /*@
365   DMDACreate - Creates a DMDA object.
366 
367   Collective on MPI_Comm
368 
369   Input Parameter:
370 . comm - The communicator for the DMDA object
371 
372   Output Parameter:
373 . da  - The DMDA object
374 
375   Level: advanced
376 
377   Developers Note: Since there exists DMDACreate1/2/3d() should this routine even exist?
378 
379 .keywords: DMDA, create
380 .seealso:  DMDASetSizes(), DMDADuplicate(),  DMDACreate1d(), DMDACreate2d(), DMDACreate3d()
381 @*/
382 PetscErrorCode  DMDACreate(MPI_Comm comm, DM *da)
383 {
384   PetscErrorCode ierr;
385 
386   PetscFunctionBegin;
387   PetscValidPointer(da,2);
388   ierr = DMCreate(comm,da);CHKERRQ(ierr);
389   ierr = DMSetType(*da,DMDA);CHKERRQ(ierr);
390   PetscFunctionReturn(0);
391 }
392 
393 
394