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) { 90 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da),"Error: DM not compatible with itself\n")); 91 } 92 } 93 94 /* Check compatibility with the same DM on a dup'd communicator */ 95 { 96 DM da2; 97 PetscBool compatible,set; 98 MPI_Comm comm2; 99 PetscCallMPI(MPI_Comm_dup(PETSC_COMM_WORLD,&comm2)); 100 PetscCall(DMDACreate3d(comm2,bx,by,bz,stencil_type,M,N,P,m,n,p,w,s,lx,ly,lz,&da2)); 101 PetscCall(DMSetFromOptions(da2)); 102 PetscCall(DMSetUp(da2)); 103 PetscCall(DMGetCompatibility(da,da2,&compatible,&set)); 104 if (!set || !compatible) { 105 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da),"Error: DM not compatible with DMDA on dup'd comm\n")); 106 } 107 PetscCall(DMDestroy(&da2)); 108 PetscCallMPI(MPI_Comm_free(&comm2)); 109 } 110 111 /* Check compatibility with a derived DMDA */ 112 { 113 DM da2; 114 PetscBool compatible,set; 115 PetscCall(DMDACreateCompatibleDMDA(da,w*2,&da2)); 116 PetscCall(DMGetCompatibility(da,da2,&compatible,&set)); 117 if (!set || !compatible) { 118 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da),"Error: DM not compatible with DMDA created with DMDACreateCompatibleDMDA()\n")); 119 } 120 PetscCall(DMDestroy(&da2)); 121 } 122 123 /* Confirm incompatibility with different stencil width */ 124 { 125 DM da2; 126 PetscBool compatible,set; 127 PetscCall(DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,stencil_type,M,N,P,m,n,p,w,0,lx,ly,lz,&da2)); 128 PetscCall(DMSetUp(da2)); 129 PetscCall(DMGetCompatibility(da,da2,&compatible,&set)); 130 if (!set || compatible) { 131 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da),"Error: DM not determined incompatible with known-incompatible DMDA (different stencil width)\n")); 132 } 133 PetscCall(DMDestroy(&da2)); 134 } 135 136 /* Confirm incompatibility with different boundary types */ 137 { 138 DM da2; 139 PetscBool compatible,set; 140 DMBoundaryType bz2; 141 bz2 = bz == DM_BOUNDARY_NONE ? DM_BOUNDARY_GHOSTED : DM_BOUNDARY_NONE; 142 PetscCall(DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz2,stencil_type,M,N,P,m,n,p,w,s,lx,ly,lz,&da2)); 143 PetscCall(DMSetUp(da2)); 144 PetscCall(DMGetCompatibility(da,da2,&compatible,&set)); 145 if (!set || compatible) { 146 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da),"Error: DM not determined incompatible with known-incompatible DMDA (different boundary type)\n")); 147 } 148 PetscCall(DMDestroy(&da2)); 149 } 150 151 if (!distribute) { 152 /* Confirm incompatibility with different global sizes */ 153 { 154 DM da2; 155 PetscBool compatible,set; 156 PetscCall(DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,stencil_type,M,N,P*2,m,n,p,w,s,lx,ly,lz,&da2)); 157 PetscCall(DMSetUp(da2)); 158 PetscCall(DMGetCompatibility(da,da2,&compatible,&set)); 159 if (!set || compatible) { 160 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da),"Error: DM not determined incompatible with known-incompatible DMDA (different global sizes)\n")); 161 } 162 PetscCall(DMDestroy(&da2)); 163 } 164 } 165 166 if (distribute && p > 1) { 167 /* Confirm incompatibility with different local size */ 168 { 169 DM da2; 170 PetscBool compatible,set; 171 PetscMPIInt rank; 172 PetscInt *lz2; 173 PetscCall(PetscMalloc1(p,&lz2)); 174 for (i=0; i<p-1; i++) lz2[i] = 1; /* One point per rank instead of 2 */ 175 lz2[p-1] = P - (p-1); 176 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 177 PetscCall(DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,stencil_type,M,N,P,m,n,p,w,s,lx,ly,lz2,&da2)); 178 PetscCall(DMSetUp(da2)); 179 PetscCall(DMGetCompatibility(da,da2,&compatible,&set)); 180 if (!set || compatible) { 181 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)da),"Error: DM not determined incompatible with known-incompatible DMDA (different local sizes) \n")); 182 } 183 PetscCall(DMDestroy(&da2)); 184 PetscCall(PetscFree(lz2)); 185 } 186 } 187 188 /* Check compatibility with a DM of different type (DMStag) */ 189 { 190 DM dm2; 191 PetscBool compatible,set; 192 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)); 193 PetscCall(DMSetUp(dm2)); 194 PetscCall(DMGetCompatibility(da,dm2,&compatible,&set)); 195 /* Don't interpret the result, but note that one can run with -info */ 196 PetscCall(DMDestroy(&dm2)); 197 } 198 199 /* Free memory */ 200 PetscCall(PetscFree(lx)); 201 PetscCall(PetscFree(ly)); 202 PetscCall(PetscFree(lz)); 203 PetscCall(DMDestroy(&da)); 204 PetscCall(PetscFinalize()); 205 return 0; 206 } 207 208 /*TEST 209 210 test: 211 suffix: 1 212 213 test: 214 suffix: 2 215 nsize: 3 216 args: -distribute -m 1 -n 1 -p 3 -NZ 20 217 218 TEST*/ 219