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 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, (char *)0, 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 200 test: 201 suffix: 2 202 nsize: 3 203 args: -distribute -m 1 -n 1 -p 3 -NZ 20 204 205 TEST*/ 206