xref: /petsc/src/dm/tests/ex6.c (revision ffc4695bcb29f4b022f59a5fd6bc99fc280ff6d8)
1c4762a1bSJed Brown static char help[] = "Tests various 3-dimensional DMDA routines.\n\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown #include <petscdm.h>
4c4762a1bSJed Brown #include <petscdmda.h>
5c4762a1bSJed Brown #include <petscao.h>
6c4762a1bSJed Brown 
7c4762a1bSJed Brown int main(int argc,char **argv)
8c4762a1bSJed Brown {
9c4762a1bSJed Brown   PetscMPIInt      rank;
10c4762a1bSJed Brown   PetscInt         M = 3,N = 5,P=3,s=1,w=2,nloc,l,i,j,k,kk,m = PETSC_DECIDE,n = PETSC_DECIDE,p = PETSC_DECIDE;
11c4762a1bSJed Brown   PetscErrorCode   ierr;
12c4762a1bSJed Brown   PetscInt         Xs,Xm,Ys,Ym,Zs,Zm,iloc,*iglobal;
13c4762a1bSJed Brown   const PetscInt   *ltog;
14c4762a1bSJed Brown   PetscInt         *lx        = NULL,*ly = NULL,*lz = NULL;
15c4762a1bSJed Brown   PetscBool        test_order = PETSC_FALSE;
16c4762a1bSJed Brown   DM               da;
17c4762a1bSJed Brown   PetscViewer      viewer;
18c4762a1bSJed Brown   Vec              local,global;
19c4762a1bSJed Brown   PetscScalar      value;
20c4762a1bSJed Brown   DMBoundaryType   bx           = DM_BOUNDARY_NONE,by = DM_BOUNDARY_NONE,bz = DM_BOUNDARY_NONE;
21c4762a1bSJed Brown   DMDAStencilType  stencil_type = DMDA_STENCIL_BOX;
22c4762a1bSJed Brown   AO               ao;
23c4762a1bSJed Brown   PetscBool        flg = PETSC_FALSE;
24c4762a1bSJed Brown 
25c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
26c4762a1bSJed Brown   ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",300,0,400,300,&viewer);CHKERRQ(ierr);
27c4762a1bSJed Brown 
28c4762a1bSJed Brown   /* Read options */
29c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-NX",&M,NULL);CHKERRQ(ierr);
30c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-NY",&N,NULL);CHKERRQ(ierr);
31c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-NZ",&P,NULL);CHKERRQ(ierr);
32c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr);
33c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr);
34c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-p",&p,NULL);CHKERRQ(ierr);
35c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-s",&s,NULL);CHKERRQ(ierr);
36c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-w",&w,NULL);CHKERRQ(ierr);
37c4762a1bSJed Brown   flg  = PETSC_FALSE;
38c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-star",&flg,NULL);CHKERRQ(ierr);
39c4762a1bSJed Brown   if (flg) stencil_type =  DMDA_STENCIL_STAR;
40c4762a1bSJed Brown   flg  = PETSC_FALSE;
41c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-box",&flg,NULL);CHKERRQ(ierr);
42c4762a1bSJed Brown   if (flg) stencil_type =  DMDA_STENCIL_BOX;
43c4762a1bSJed Brown 
44c4762a1bSJed Brown   flg  = PETSC_FALSE;
45c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-xperiodic",&flg,NULL);CHKERRQ(ierr);
46c4762a1bSJed Brown   if (flg) bx = DM_BOUNDARY_PERIODIC;
47c4762a1bSJed Brown   flg  = PETSC_FALSE;
48c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-xghosted",&flg,NULL);CHKERRQ(ierr);
49c4762a1bSJed Brown   if (flg) bx = DM_BOUNDARY_GHOSTED;
50c4762a1bSJed Brown   flg  = PETSC_FALSE;
51c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-xnonghosted",&flg,NULL);CHKERRQ(ierr);
52c4762a1bSJed Brown 
53c4762a1bSJed Brown   flg  = PETSC_FALSE;
54c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-yperiodic",&flg,NULL);CHKERRQ(ierr);
55c4762a1bSJed Brown   if (flg) by = DM_BOUNDARY_PERIODIC;
56c4762a1bSJed Brown   flg  = PETSC_FALSE;
57c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-yghosted",&flg,NULL);CHKERRQ(ierr);
58c4762a1bSJed Brown   if (flg) by = DM_BOUNDARY_GHOSTED;
59c4762a1bSJed Brown   flg  = PETSC_FALSE;
60c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-ynonghosted",&flg,NULL);CHKERRQ(ierr);
61c4762a1bSJed Brown 
62c4762a1bSJed Brown   flg  = PETSC_FALSE;
63c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-zperiodic",&flg,NULL);CHKERRQ(ierr);
64c4762a1bSJed Brown   if (flg) bz = DM_BOUNDARY_PERIODIC;
65c4762a1bSJed Brown   flg  = PETSC_FALSE;
66c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-zghosted",&flg,NULL);CHKERRQ(ierr);
67c4762a1bSJed Brown   if (flg) bz = DM_BOUNDARY_GHOSTED;
68c4762a1bSJed Brown   flg  = PETSC_FALSE;
69c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-znonghosted",&flg,NULL);CHKERRQ(ierr);
70c4762a1bSJed Brown 
71c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-testorder",&test_order,NULL);CHKERRQ(ierr);
72c4762a1bSJed Brown 
73c4762a1bSJed Brown   flg  = PETSC_FALSE;
74c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-distribute",&flg,NULL);CHKERRQ(ierr);
75c4762a1bSJed Brown   if (flg) {
76c4762a1bSJed Brown     if (m == PETSC_DECIDE) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Must set -m option with -distribute option");
77c4762a1bSJed Brown     ierr = PetscMalloc1(m,&lx);CHKERRQ(ierr);
78c4762a1bSJed Brown     for (i=0; i<m-1; i++) lx[i] = 4;
79c4762a1bSJed Brown     lx[m-1] = M - 4*(m-1);
80c4762a1bSJed Brown     if (n == PETSC_DECIDE) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Must set -n option with -distribute option");
81c4762a1bSJed Brown     ierr = PetscMalloc1(n,&ly);CHKERRQ(ierr);
82c4762a1bSJed Brown     for (i=0; i<n-1; i++) ly[i] = 2;
83c4762a1bSJed Brown     ly[n-1] = N - 2*(n-1);
84c4762a1bSJed Brown     if (p == PETSC_DECIDE) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Must set -p option with -distribute option");
85c4762a1bSJed Brown     ierr = PetscMalloc1(p,&lz);CHKERRQ(ierr);
86c4762a1bSJed Brown     for (i=0; i<p-1; i++) lz[i] = 2;
87c4762a1bSJed Brown     lz[p-1] = P - 2*(p-1);
88c4762a1bSJed Brown   }
89c4762a1bSJed Brown 
90c4762a1bSJed Brown   /* Create distributed array and get vectors */
91c4762a1bSJed Brown   ierr = DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,stencil_type,M,N,P,m,n,p,w,s,lx,ly,lz,&da);CHKERRQ(ierr);
92c4762a1bSJed Brown   ierr = DMSetFromOptions(da);CHKERRQ(ierr);
93c4762a1bSJed Brown   ierr = DMSetUp(da);CHKERRQ(ierr);
94c4762a1bSJed Brown   ierr = PetscFree(lx);CHKERRQ(ierr);
95c4762a1bSJed Brown   ierr = PetscFree(ly);CHKERRQ(ierr);
96c4762a1bSJed Brown   ierr = PetscFree(lz);CHKERRQ(ierr);
97c4762a1bSJed Brown   ierr = DMView(da,viewer);CHKERRQ(ierr);
98c4762a1bSJed Brown   ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr);
99c4762a1bSJed Brown   ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr);
100c4762a1bSJed Brown 
101c4762a1bSJed Brown   /* Set global vector; send ghost points to local vectors */
102c4762a1bSJed Brown   value = 1;
103c4762a1bSJed Brown   ierr = VecSet(global,value);CHKERRQ(ierr);
104c4762a1bSJed Brown   ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
105c4762a1bSJed Brown   ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
106c4762a1bSJed Brown 
107c4762a1bSJed Brown   /* Scale local vectors according to processor rank; pass to global vector */
108*ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr);
109c4762a1bSJed Brown   value = rank;
110c4762a1bSJed Brown   ierr = VecScale(local,value);CHKERRQ(ierr);
111c4762a1bSJed Brown   ierr = DMLocalToGlobalBegin(da,local,INSERT_VALUES,global);CHKERRQ(ierr);
112c4762a1bSJed Brown   ierr = DMLocalToGlobalEnd(da,local,INSERT_VALUES,global);CHKERRQ(ierr);
113c4762a1bSJed Brown 
114c4762a1bSJed Brown   if (!test_order) { /* turn off printing when testing ordering mappings */
115c4762a1bSJed Brown     if (M*N*P<40) {
116c4762a1bSJed Brown       ierr = PetscPrintf(PETSC_COMM_WORLD,"\nGlobal Vector:\n");CHKERRQ(ierr);
117c4762a1bSJed Brown       ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
118c4762a1bSJed Brown       ierr = PetscPrintf(PETSC_COMM_WORLD,"\n");CHKERRQ(ierr);
119c4762a1bSJed Brown     }
120c4762a1bSJed Brown   }
121c4762a1bSJed Brown 
122c4762a1bSJed Brown   /* Send ghost points to local vectors */
123c4762a1bSJed Brown   ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
124c4762a1bSJed Brown   ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
125c4762a1bSJed Brown 
126c4762a1bSJed Brown   flg  = PETSC_FALSE;
127c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-local_print",&flg,NULL);CHKERRQ(ierr);
128c4762a1bSJed Brown   if (flg) {
129c4762a1bSJed Brown     PetscViewer sviewer;
130c4762a1bSJed Brown     ierr = PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
131c4762a1bSJed Brown     ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"\nLocal Vector: processor %d\n",rank);CHKERRQ(ierr);
132c4762a1bSJed Brown     ierr = PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr);
133c4762a1bSJed Brown     ierr = VecView(local,sviewer);CHKERRQ(ierr);
134c4762a1bSJed Brown     ierr = PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr);
135c4762a1bSJed Brown     ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD,PETSC_STDOUT);CHKERRQ(ierr);
136c4762a1bSJed Brown     ierr = PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
137c4762a1bSJed Brown   }
138c4762a1bSJed Brown 
139c4762a1bSJed Brown   /* Tests mappings betweeen application/PETSc orderings */
140c4762a1bSJed Brown   if (test_order) {
141c4762a1bSJed Brown     ISLocalToGlobalMapping ltogm;
142c4762a1bSJed Brown 
143c4762a1bSJed Brown     ierr = DMGetLocalToGlobalMapping(da,&ltogm);CHKERRQ(ierr);
144c4762a1bSJed Brown     ierr = ISLocalToGlobalMappingGetSize(ltogm,&nloc);CHKERRQ(ierr);
145c4762a1bSJed Brown     ierr = ISLocalToGlobalMappingGetIndices(ltogm,&ltog);CHKERRQ(ierr);
146c4762a1bSJed Brown 
147c4762a1bSJed Brown     ierr = DMDAGetGhostCorners(da,&Xs,&Ys,&Zs,&Xm,&Ym,&Zm);CHKERRQ(ierr);
148c4762a1bSJed Brown     ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr);
149c4762a1bSJed Brown     /* ierr = AOView(ao,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */
150c4762a1bSJed Brown     ierr = PetscMalloc1(nloc,&iglobal);CHKERRQ(ierr);
151c4762a1bSJed Brown 
152c4762a1bSJed Brown     /* Set iglobal to be global indices for each processor's local and ghost nodes,
153c4762a1bSJed Brown        using the DMDA ordering of grid points */
154c4762a1bSJed Brown     kk = 0;
155c4762a1bSJed Brown     for (k=Zs; k<Zs+Zm; k++) {
156c4762a1bSJed Brown       for (j=Ys; j<Ys+Ym; j++) {
157c4762a1bSJed Brown         for (i=Xs; i<Xs+Xm; i++) {
158c4762a1bSJed Brown           iloc = w*((k-Zs)*Xm*Ym + (j-Ys)*Xm + i-Xs);
159c4762a1bSJed Brown           for (l=0; l<w; l++) {
160c4762a1bSJed Brown             iglobal[kk++] = ltog[iloc+l];
161c4762a1bSJed Brown           }
162c4762a1bSJed Brown         }
163c4762a1bSJed Brown       }
164c4762a1bSJed Brown     }
165c4762a1bSJed Brown 
166c4762a1bSJed Brown     /* Map this to the application ordering (which for DMDAs is just the natural ordering
167c4762a1bSJed Brown        that would be used for 1 processor, numbering most rapidly by x, then y, then z) */
168c4762a1bSJed Brown     ierr = AOPetscToApplication(ao,nloc,iglobal);CHKERRQ(ierr);
169c4762a1bSJed Brown 
170c4762a1bSJed Brown     /* Then map the application ordering back to the PETSc DMDA ordering */
171c4762a1bSJed Brown     ierr = AOApplicationToPetsc(ao,nloc,iglobal);CHKERRQ(ierr);
172c4762a1bSJed Brown 
173c4762a1bSJed Brown     /* Verify the mappings */
174c4762a1bSJed Brown     kk=0;
175c4762a1bSJed Brown     for (k=Zs; k<Zs+Zm; k++) {
176c4762a1bSJed Brown       for (j=Ys; j<Ys+Ym; j++) {
177c4762a1bSJed Brown         for (i=Xs; i<Xs+Xm; i++) {
178c4762a1bSJed Brown           iloc = w*((k-Zs)*Xm*Ym + (j-Ys)*Xm + i-Xs);
179c4762a1bSJed Brown           for (l=0; l<w; l++) {
180c4762a1bSJed Brown             if (iglobal[kk] != ltog[iloc+l]) {
181c4762a1bSJed Brown               ierr = PetscPrintf(MPI_COMM_WORLD,"[%D] Problem with mapping: z=%D, j=%D, i=%D, l=%D, petsc1=%D, petsc2=%D\n",rank,k,j,i,l,ltog[iloc+l],iglobal[kk]);CHKERRQ(ierr);
182c4762a1bSJed Brown             }
183c4762a1bSJed Brown             kk++;
184c4762a1bSJed Brown           }
185c4762a1bSJed Brown         }
186c4762a1bSJed Brown       }
187c4762a1bSJed Brown     }
188c4762a1bSJed Brown     ierr = PetscFree(iglobal);CHKERRQ(ierr);
189c4762a1bSJed Brown     ierr = ISLocalToGlobalMappingRestoreIndices(ltogm,&ltog);CHKERRQ(ierr);
190c4762a1bSJed Brown   }
191c4762a1bSJed Brown 
192c4762a1bSJed Brown   /* Free memory */
193c4762a1bSJed Brown   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
194c4762a1bSJed Brown   ierr = VecDestroy(&local);CHKERRQ(ierr);
195c4762a1bSJed Brown   ierr = VecDestroy(&global);CHKERRQ(ierr);
196c4762a1bSJed Brown   ierr = DMDestroy(&da);CHKERRQ(ierr);
197c4762a1bSJed Brown   ierr = PetscFinalize();
198c4762a1bSJed Brown   return ierr;
199c4762a1bSJed Brown }
200c4762a1bSJed Brown 
201c4762a1bSJed Brown /*TEST
202c4762a1bSJed Brown 
203c4762a1bSJed Brown     test:
204c4762a1bSJed Brown       args:  -testorder -nox
205c4762a1bSJed Brown 
206c4762a1bSJed Brown  TEST*/
207c4762a1bSJed Brown 
208c4762a1bSJed Brown 
209c4762a1bSJed Brown 
210c4762a1bSJed Brown 
211c4762a1bSJed Brown 
212c4762a1bSJed Brown 
213c4762a1bSJed Brown 
214c4762a1bSJed Brown 
215c4762a1bSJed Brown 
216c4762a1bSJed Brown 
217c4762a1bSJed Brown 
218c4762a1bSJed Brown 
219c4762a1bSJed Brown 
220c4762a1bSJed Brown 
221c4762a1bSJed Brown 
222c4762a1bSJed Brown 
223c4762a1bSJed Brown 
224c4762a1bSJed Brown 
225c4762a1bSJed Brown 
226