xref: /petsc/src/dm/tests/ex46.c (revision 609caa7c8c030312b00807b4f015fd827bb80932)
1 static char help[] = "Tests DMGetCompatibility() with a 3D DMDA.\n\n";
2 
3 #include <petscdm.h>
4 #include <petscdmda.h>
5 #include <petscdmstag.h>
6 
main(int argc,char ** argv)7 int main(int argc, char **argv)
8 {
9   PetscInt        M = 3, N = 5, P = 3, s = 1, w = 2, i, m = PETSC_DECIDE, n = PETSC_DECIDE, p = PETSC_DECIDE;
10   PetscInt       *lx = NULL, *ly = NULL, *lz = NULL;
11   PetscBool       test_order = PETSC_FALSE;
12   DM              da;
13   DMBoundaryType  bx = DM_BOUNDARY_NONE, by = DM_BOUNDARY_NONE, bz = DM_BOUNDARY_NONE;
14   DMDAStencilType stencil_type = DMDA_STENCIL_BOX;
15   PetscBool       flg = PETSC_FALSE, distribute = PETSC_FALSE;
16 
17   PetscFunctionBeginUser;
18   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
19 
20   /* Read options */
21   PetscCall(PetscOptionsGetInt(NULL, NULL, "-NX", &M, NULL));
22   PetscCall(PetscOptionsGetInt(NULL, NULL, "-NY", &N, NULL));
23   PetscCall(PetscOptionsGetInt(NULL, NULL, "-NZ", &P, NULL));
24   PetscCall(PetscOptionsGetInt(NULL, NULL, "-m", &m, NULL));
25   PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL));
26   PetscCall(PetscOptionsGetInt(NULL, NULL, "-p", &p, NULL));
27   PetscCall(PetscOptionsGetInt(NULL, NULL, "-s", &s, NULL));
28   PetscCall(PetscOptionsGetInt(NULL, NULL, "-w", &w, NULL));
29   flg = PETSC_FALSE;
30   PetscCall(PetscOptionsGetBool(NULL, NULL, "-star", &flg, NULL));
31   if (flg) stencil_type = DMDA_STENCIL_STAR;
32   flg = PETSC_FALSE;
33   PetscCall(PetscOptionsGetBool(NULL, NULL, "-box", &flg, NULL));
34   if (flg) stencil_type = DMDA_STENCIL_BOX;
35 
36   flg = PETSC_FALSE;
37   PetscCall(PetscOptionsGetBool(NULL, NULL, "-xperiodic", &flg, NULL));
38   if (flg) bx = DM_BOUNDARY_PERIODIC;
39   flg = PETSC_FALSE;
40   PetscCall(PetscOptionsGetBool(NULL, NULL, "-xghosted", &flg, NULL));
41   if (flg) bx = DM_BOUNDARY_GHOSTED;
42   flg = PETSC_FALSE;
43   PetscCall(PetscOptionsGetBool(NULL, NULL, "-xnonghosted", &flg, NULL));
44 
45   flg = PETSC_FALSE;
46   PetscCall(PetscOptionsGetBool(NULL, NULL, "-yperiodic", &flg, NULL));
47   if (flg) by = DM_BOUNDARY_PERIODIC;
48   flg = PETSC_FALSE;
49   PetscCall(PetscOptionsGetBool(NULL, NULL, "-yghosted", &flg, NULL));
50   if (flg) by = DM_BOUNDARY_GHOSTED;
51   flg = PETSC_FALSE;
52   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ynonghosted", &flg, NULL));
53 
54   flg = PETSC_FALSE;
55   PetscCall(PetscOptionsGetBool(NULL, NULL, "-zperiodic", &flg, NULL));
56   if (flg) bz = DM_BOUNDARY_PERIODIC;
57   flg = PETSC_FALSE;
58   PetscCall(PetscOptionsGetBool(NULL, NULL, "-zghosted", &flg, NULL));
59   if (flg) bz = DM_BOUNDARY_GHOSTED;
60   flg = PETSC_FALSE;
61   PetscCall(PetscOptionsGetBool(NULL, NULL, "-znonghosted", &flg, NULL));
62 
63   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testorder", &test_order, NULL));
64 
65   flg = PETSC_FALSE;
66   PetscCall(PetscOptionsGetBool(NULL, NULL, "-distribute", &distribute, NULL));
67   if (distribute) {
68     PetscCheck(m != PETSC_DECIDE, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Must set -m option with -distribute option");
69     PetscCall(PetscMalloc1(m, &lx));
70     for (i = 0; i < m - 1; i++) lx[i] = 4;
71     lx[m - 1] = M - 4 * (m - 1);
72     PetscCheck(n != PETSC_DECIDE, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Must set -n option with -distribute option");
73     PetscCall(PetscMalloc1(n, &ly));
74     for (i = 0; i < n - 1; i++) ly[i] = 2;
75     ly[n - 1] = N - 2 * (n - 1);
76     PetscCheck(p != PETSC_DECIDE, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Must set -p option with -distribute option");
77     PetscCall(PetscMalloc1(p, &lz));
78     for (i = 0; i < p - 1; i++) lz[i] = 2;
79     lz[p - 1] = P - 2 * (p - 1);
80   }
81 
82   PetscCall(DMDACreate3d(PETSC_COMM_WORLD, bx, by, bz, stencil_type, M, N, P, m, n, p, w, s, lx, ly, lz, &da));
83   PetscCall(DMSetFromOptions(da));
84   PetscCall(DMSetUp(da));
85 
86   /* Check self-compatibility */
87   {
88     PetscBool compatible, set;
89     PetscCall(DMGetCompatibility(da, da, &compatible, &set));
90     if (!set || !compatible) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da), "Error: DM not compatible with itself\n"));
91   }
92 
93   /* Check compatibility with the same DM on a dup'd communicator */
94   {
95     DM        da2;
96     PetscBool compatible, set;
97     MPI_Comm  comm2;
98     PetscCallMPI(MPI_Comm_dup(PETSC_COMM_WORLD, &comm2));
99     PetscCall(DMDACreate3d(comm2, bx, by, bz, stencil_type, M, N, P, m, n, p, w, s, lx, ly, lz, &da2));
100     PetscCall(DMSetFromOptions(da2));
101     PetscCall(DMSetUp(da2));
102     PetscCall(DMGetCompatibility(da, da2, &compatible, &set));
103     if (!set || !compatible) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da), "Error: DM not compatible with DMDA on dup'd comm\n"));
104     PetscCall(DMDestroy(&da2));
105     PetscCallMPI(MPI_Comm_free(&comm2));
106   }
107 
108   /* Check compatibility with a derived DMDA */
109   {
110     DM        da2;
111     PetscBool compatible, set;
112     PetscCall(DMDACreateCompatibleDMDA(da, w * 2, &da2));
113     PetscCall(DMGetCompatibility(da, da2, &compatible, &set));
114     if (!set || !compatible) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da), "Error: DM not compatible with DMDA created with DMDACreateCompatibleDMDA()\n"));
115     PetscCall(DMDestroy(&da2));
116   }
117 
118   /* Confirm incompatibility with different stencil width */
119   {
120     DM        da2;
121     PetscBool compatible, set;
122     PetscCall(DMDACreate3d(PETSC_COMM_WORLD, bx, by, bz, stencil_type, M, N, P, m, n, p, w, 0, lx, ly, lz, &da2));
123     PetscCall(DMSetUp(da2));
124     PetscCall(DMGetCompatibility(da, da2, &compatible, &set));
125     if (!set || compatible) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da), "Error: DM not determined incompatible with known-incompatible DMDA (different stencil width)\n"));
126     PetscCall(DMDestroy(&da2));
127   }
128 
129   /* Confirm incompatibility with different boundary types */
130   {
131     DM             da2;
132     PetscBool      compatible, set;
133     DMBoundaryType bz2;
134     bz2 = bz == DM_BOUNDARY_NONE ? DM_BOUNDARY_GHOSTED : DM_BOUNDARY_NONE;
135     PetscCall(DMDACreate3d(PETSC_COMM_WORLD, bx, by, bz2, stencil_type, M, N, P, m, n, p, w, s, lx, ly, lz, &da2));
136     PetscCall(DMSetUp(da2));
137     PetscCall(DMGetCompatibility(da, da2, &compatible, &set));
138     if (!set || compatible) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da), "Error: DM not determined incompatible with known-incompatible DMDA (different boundary type)\n"));
139     PetscCall(DMDestroy(&da2));
140   }
141 
142   if (!distribute) {
143     /* Confirm incompatibility with different global sizes */
144     {
145       DM        da2;
146       PetscBool compatible, set;
147       PetscCall(DMDACreate3d(PETSC_COMM_WORLD, bx, by, bz, stencil_type, M, N, P * 2, m, n, p, w, s, lx, ly, lz, &da2));
148       PetscCall(DMSetUp(da2));
149       PetscCall(DMGetCompatibility(da, da2, &compatible, &set));
150       if (!set || compatible) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da), "Error: DM not determined incompatible with known-incompatible DMDA (different global sizes)\n"));
151       PetscCall(DMDestroy(&da2));
152     }
153   }
154 
155   if (distribute && p > 1) {
156     /* Confirm incompatibility with different local size */
157     {
158       DM          da2;
159       PetscBool   compatible, set;
160       PetscMPIInt rank;
161       PetscInt   *lz2;
162       PetscCall(PetscMalloc1(p, &lz2));
163       for (i = 0; i < p - 1; i++) lz2[i] = 1; /* One point per rank instead of 2 */
164       lz2[p - 1] = P - (p - 1);
165       PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
166       PetscCall(DMDACreate3d(PETSC_COMM_WORLD, bx, by, bz, stencil_type, M, N, P, m, n, p, w, s, lx, ly, lz2, &da2));
167       PetscCall(DMSetUp(da2));
168       PetscCall(DMGetCompatibility(da, da2, &compatible, &set));
169       if (!set || compatible) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da), "Error: DM not determined incompatible with known-incompatible DMDA (different local sizes) \n"));
170       PetscCall(DMDestroy(&da2));
171       PetscCall(PetscFree(lz2));
172     }
173   }
174 
175   /* Check compatibility with a DM of different type (DMStag) */
176   {
177     DM        dm2;
178     PetscBool compatible, set;
179     PetscCall(DMStagCreate3d(PETSC_COMM_WORLD, bx, by, bz, M, N, P, m, n, p, 1, 1, 1, 1, DMSTAG_STENCIL_STAR, w, lx, ly, lz, &dm2));
180     PetscCall(DMSetUp(dm2));
181     PetscCall(DMGetCompatibility(da, dm2, &compatible, &set));
182     /* Don't interpret the result, but note that one can run with -info */
183     PetscCall(DMDestroy(&dm2));
184   }
185 
186   /* Free memory */
187   PetscCall(PetscFree(lx));
188   PetscCall(PetscFree(ly));
189   PetscCall(PetscFree(lz));
190   PetscCall(DMDestroy(&da));
191   PetscCall(PetscFinalize());
192   return 0;
193 }
194 
195 /*TEST
196 
197    test:
198       suffix: 1
199       output_file: output/empty.out
200 
201    test:
202       suffix: 2
203       nsize: 3
204       args: -distribute -m 1 -n 1 -p 3 -NZ 20
205       output_file: output/empty.out
206 
207  TEST*/
208