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