xref: /petsc/src/dm/tutorials/ex3.c (revision f97672e55eacc8688507b9471cd7ec2664d7f203)
1 
2 static char help[] = "Tests DMCreateInterpolation() for nonuniform DMDA coordinates.\n\n";
3 
4 #include <petscdm.h>
5 #include <petscdmda.h>
6 
7 PetscErrorCode SetCoordinates1d(DM da)
8 {
9   PetscInt       i,start,m;
10   Vec            local,global;
11   PetscScalar    *coors,*coorslocal;
12   DM             cda;
13 
14   PetscFunctionBeginUser;
15   PetscCall(DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0));
16   PetscCall(DMGetCoordinateDM(da,&cda));
17   PetscCall(DMGetCoordinates(da,&global));
18   PetscCall(DMGetCoordinatesLocal(da,&local));
19   PetscCall(DMDAVecGetArray(cda,global,&coors));
20   PetscCall(DMDAVecGetArrayRead(cda,local,&coorslocal));
21   PetscCall(DMDAGetCorners(cda,&start,0,0,&m,0,0));
22   for (i=start; i<start+m; i++) {
23     if (i % 2) {
24       coors[i] = coorslocal[i-1] + .1*(coorslocal[i+1] - coorslocal[i-1]);
25     }
26   }
27   PetscCall(DMDAVecRestoreArray(cda,global,&coors));
28   PetscCall(DMDAVecRestoreArrayRead(cda,local,&coorslocal));
29   PetscCall(DMGlobalToLocalBegin(cda,global,INSERT_VALUES,local));
30   PetscCall(DMGlobalToLocalEnd(cda,global,INSERT_VALUES,local));
31   PetscFunctionReturn(0);
32 }
33 
34 PetscErrorCode SetCoordinates2d(DM da)
35 {
36   PetscInt       i,j,mstart,m,nstart,n;
37   Vec            local,global;
38   DMDACoor2d     **coors,**coorslocal;
39   DM             cda;
40 
41   PetscFunctionBeginUser;
42   PetscCall(DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0));
43   PetscCall(DMGetCoordinateDM(da,&cda));
44   PetscCall(DMGetCoordinates(da,&global));
45   PetscCall(DMGetCoordinatesLocal(da,&local));
46   PetscCall(DMDAVecGetArray(cda,global,&coors));
47   PetscCall(DMDAVecGetArrayRead(cda,local,&coorslocal));
48   PetscCall(DMDAGetCorners(cda,&mstart,&nstart,0,&m,&n,0));
49   for (i=mstart; i<mstart+m; i++) {
50     for (j=nstart; j<nstart+n; j++) {
51       if (i % 2) {
52         coors[j][i].x = coorslocal[j][i-1].x + .1*(coorslocal[j][i+1].x - coorslocal[j][i-1].x);
53       }
54       if (j % 2) {
55         coors[j][i].y = coorslocal[j-1][i].y + .3*(coorslocal[j+1][i].y - coorslocal[j-1][i].y);
56       }
57     }
58   }
59   PetscCall(DMDAVecRestoreArray(cda,global,&coors));
60   PetscCall(DMDAVecRestoreArrayRead(cda,local,&coorslocal));
61 
62   PetscCall(DMGlobalToLocalBegin(cda,global,INSERT_VALUES,local));
63   PetscCall(DMGlobalToLocalEnd(cda,global,INSERT_VALUES,local));
64   PetscFunctionReturn(0);
65 }
66 
67 PetscErrorCode SetCoordinates3d(DM da)
68 {
69   PetscInt       i,j,mstart,m,nstart,n,pstart,p,k;
70   Vec            local,global;
71   DMDACoor3d     ***coors,***coorslocal;
72   DM             cda;
73 
74   PetscFunctionBeginUser;
75   PetscCall(DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0));
76   PetscCall(DMGetCoordinateDM(da,&cda));
77   PetscCall(DMGetCoordinates(da,&global));
78   PetscCall(DMGetCoordinatesLocal(da,&local));
79   PetscCall(DMDAVecGetArray(cda,global,&coors));
80   PetscCall(DMDAVecGetArrayRead(cda,local,&coorslocal));
81   PetscCall(DMDAGetCorners(cda,&mstart,&nstart,&pstart,&m,&n,&p));
82   for (i=mstart; i<mstart+m; i++) {
83     for (j=nstart; j<nstart+n; j++) {
84       for (k=pstart; k<pstart+p; k++) {
85         if (i % 2) {
86           coors[k][j][i].x = coorslocal[k][j][i-1].x + .1*(coorslocal[k][j][i+1].x - coorslocal[k][j][i-1].x);
87         }
88         if (j % 2) {
89           coors[k][j][i].y = coorslocal[k][j-1][i].y + .3*(coorslocal[k][j+1][i].y - coorslocal[k][j-1][i].y);
90         }
91         if (k % 2) {
92           coors[k][j][i].z = coorslocal[k-1][j][i].z + .4*(coorslocal[k+1][j][i].z - coorslocal[k-1][j][i].z);
93         }
94       }
95     }
96   }
97   PetscCall(DMDAVecRestoreArray(cda,global,&coors));
98   PetscCall(DMDAVecRestoreArrayRead(cda,local,&coorslocal));
99   PetscCall(DMGlobalToLocalBegin(cda,global,INSERT_VALUES,local));
100   PetscCall(DMGlobalToLocalEnd(cda,global,INSERT_VALUES,local));
101   PetscFunctionReturn(0);
102 }
103 
104 int main(int argc,char **argv)
105 {
106   PetscInt         M = 5,N = 4,P = 3, m = PETSC_DECIDE,n = PETSC_DECIDE,p = PETSC_DECIDE,dim = 1;
107   DM               dac,daf;
108   DMBoundaryType   bx    = DM_BOUNDARY_NONE,by=DM_BOUNDARY_NONE,bz=DM_BOUNDARY_NONE;
109   DMDAStencilType  stype = DMDA_STENCIL_BOX;
110   Mat              A;
111 
112   PetscCall(PetscInitialize(&argc,&argv,(char*)0,help));
113   PetscCall(PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL));
114   PetscCall(PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL));
115   PetscCall(PetscOptionsGetInt(NULL,NULL,"-P",&P,NULL));
116   PetscCall(PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL));
117   PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
118   PetscCall(PetscOptionsGetInt(NULL,NULL,"-p",&p,NULL));
119   PetscCall(PetscOptionsGetInt(NULL,NULL,"-dim",&dim,NULL));
120 
121   /* Create distributed array and get vectors */
122   if (dim == 1) {
123     PetscCall(DMDACreate1d(PETSC_COMM_WORLD,bx,M,1,1,NULL,&dac));
124   } else if (dim == 2) {
125     PetscCall(DMDACreate2d(PETSC_COMM_WORLD,bx,by,stype,M,N,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&dac));
126   } else if (dim == 3) {
127     PetscCall(DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,stype,M,N,P,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,NULL,&dac));
128   } else SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"dim must be 1,2, or 3");
129   PetscCall(DMSetFromOptions(dac));
130   PetscCall(DMSetUp(dac));
131 
132   PetscCall(DMRefine(dac,PETSC_COMM_WORLD,&daf));
133 
134   PetscCall(DMDASetUniformCoordinates(dac,0.0,1.0,0.0,1.0,0.0,1.0));
135   if (dim == 1) {
136     PetscCall(SetCoordinates1d(daf));
137   } else if (dim == 2) {
138     PetscCall(SetCoordinates2d(daf));
139   } else if (dim == 3) {
140     PetscCall(SetCoordinates3d(daf));
141   }
142   PetscCall(DMCreateInterpolation(dac,daf,&A,0));
143 
144   /* Free memory */
145   PetscCall(DMDestroy(&dac));
146   PetscCall(DMDestroy(&daf));
147   PetscCall(MatDestroy(&A));
148   PetscCall(PetscFinalize());
149   return 0;
150 }
151 
152 /*TEST
153 
154    test:
155       nsize: 3
156       args: -mat_view
157 
158    test:
159       suffix: 2
160       nsize: 3
161       args: -mat_view -dim 2
162 
163    test:
164       suffix: 3
165       nsize: 3
166       args: -mat_view -dim 3
167 
168 TEST*/
169