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