1 static char help[] = "Linear elasticity in 2d and 3d with finite elements.\n\ 2 We solve the elasticity problem in a rectangular\n\ 3 domain, using a parallel unstructured mesh (DMPLEX) to discretize it.\n\ 4 This example supports automatic convergence estimation\n\ 5 and eventually adaptivity.\n\n\n"; 6 7 /* 8 https://en.wikipedia.org/wiki/Linear_elasticity 9 10 Converting elastic constants: 11 lambda = E nu / ((1 + nu) (1 - 2 nu)) 12 mu = E / (2 (1 + nu)) 13 */ 14 15 #include <petscdmplex.h> 16 #include <petscsnes.h> 17 #include <petscds.h> 18 #include <petscbag.h> 19 #include <petscconvest.h> 20 21 typedef enum { 22 SOL_VLAP_QUADRATIC, 23 SOL_ELAS_QUADRATIC, 24 SOL_VLAP_TRIG, 25 SOL_ELAS_TRIG, 26 SOL_ELAS_AXIAL_DISP, 27 SOL_ELAS_UNIFORM_STRAIN, 28 SOL_ELAS_GE, 29 SOL_MASS_QUADRATIC, 30 NUM_SOLUTION_TYPES 31 } SolutionType; 32 const char *solutionTypes[NUM_SOLUTION_TYPES + 1] = {"vlap_quad", "elas_quad", "vlap_trig", "elas_trig", "elas_axial_disp", "elas_uniform_strain", "elas_ge", "mass_quad", "unknown"}; 33 34 typedef enum { 35 DEFORM_NONE, 36 DEFORM_SHEAR, 37 DEFORM_STEP, 38 NUM_DEFORM_TYPES 39 } DeformType; 40 const char *deformTypes[NUM_DEFORM_TYPES + 1] = {"none", "shear", "step", "unknown"}; 41 42 typedef struct { 43 PetscScalar mu; /* shear modulus */ 44 PetscScalar lambda; /* Lame's first parameter */ 45 PetscScalar N; /* Tension force on right wall */ 46 } Parameter; 47 48 typedef struct { 49 /* Domain and mesh definition */ 50 char dmType[256]; /* DM type for the solve */ 51 DeformType deform; /* Domain deformation type */ 52 /* Problem definition */ 53 SolutionType solType; /* Type of exact solution */ 54 PetscBag bag; /* Problem parameters */ 55 /* Solver definition */ 56 PetscBool useNearNullspace; /* Use the rigid body modes as a near nullspace for AMG */ 57 } AppCtx; 58 59 static PetscErrorCode zero(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 60 { 61 PetscInt d; 62 for (d = 0; d < dim; ++d) u[d] = 0.0; 63 return PETSC_SUCCESS; 64 } 65 66 static PetscErrorCode ge_shift(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 67 { 68 PetscInt d; 69 u[0] = 0.1; 70 for (d = 1; d < dim; ++d) u[d] = 0.0; 71 return PETSC_SUCCESS; 72 } 73 74 static PetscErrorCode quadratic_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 75 { 76 u[0] = x[0] * x[0]; 77 u[1] = x[1] * x[1] - 2.0 * x[0] * x[1]; 78 return PETSC_SUCCESS; 79 } 80 81 static PetscErrorCode quadratic_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 82 { 83 u[0] = x[0] * x[0]; 84 u[1] = x[1] * x[1] - 2.0 * x[0] * x[1]; 85 u[2] = x[2] * x[2] - 2.0 * x[1] * x[2]; 86 return PETSC_SUCCESS; 87 } 88 89 /* 90 u = x^2 91 v = y^2 - 2xy 92 Delta <u,v> - f = <2, 2> - <2, 2> 93 94 u = x^2 95 v = y^2 - 2xy 96 w = z^2 - 2yz 97 Delta <u,v,w> - f = <2, 2, 2> - <2, 2, 2> 98 */ 99 static void f0_vlap_quadratic_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 100 { 101 PetscInt d; 102 for (d = 0; d < dim; ++d) f0[d] += 2.0; 103 } 104 105 /* 106 u = x^2 107 v = y^2 - 2xy 108 \varepsilon = / 2x -y \ 109 \ -y 2y - 2x / 110 Tr(\varepsilon) = div u = 2y 111 div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij} 112 = \lambda \partial_j (2y) + 2\mu < 2-1, 2 > 113 = \lambda < 0, 2 > + \mu < 2, 4 > 114 115 u = x^2 116 v = y^2 - 2xy 117 w = z^2 - 2yz 118 \varepsilon = / 2x -y 0 \ 119 | -y 2y - 2x -z | 120 \ 0 -z 2z - 2y/ 121 Tr(\varepsilon) = div u = 2z 122 div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij} 123 = \lambda \partial_j (2z) + 2\mu < 2-1, 2-1, 2 > 124 = \lambda < 0, 0, 2 > + \mu < 2, 2, 4 > 125 */ 126 static void f0_elas_quadratic_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 127 { 128 const PetscReal mu = PetscRealPart(constants[0]); 129 const PetscReal lambda = PetscRealPart(constants[1]); 130 131 for (PetscInt d = 0; d < dim - 1; ++d) f0[d] += 2.0 * mu; 132 f0[dim - 1] += 2.0 * lambda + 4.0 * mu; 133 } 134 135 static void f0_mass_quadratic_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 136 { 137 if (dim == 2) { 138 f0[0] -= x[0] * x[0]; 139 f0[1] -= x[1] * x[1] - 2.0 * x[0] * x[1]; 140 } else { 141 f0[0] -= x[0] * x[0]; 142 f0[1] -= x[1] * x[1] - 2.0 * x[0] * x[1]; 143 f0[2] -= x[2] * x[2] - 2.0 * x[1] * x[2]; 144 } 145 } 146 147 static PetscErrorCode trig_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 148 { 149 u[0] = PetscSinReal(2.0 * PETSC_PI * x[0]); 150 u[1] = PetscSinReal(2.0 * PETSC_PI * x[1]) - 2.0 * x[0] * x[1]; 151 return PETSC_SUCCESS; 152 } 153 154 static PetscErrorCode trig_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 155 { 156 u[0] = PetscSinReal(2.0 * PETSC_PI * x[0]); 157 u[1] = PetscSinReal(2.0 * PETSC_PI * x[1]) - 2.0 * x[0] * x[1]; 158 u[2] = PetscSinReal(2.0 * PETSC_PI * x[2]) - 2.0 * x[1] * x[2]; 159 return PETSC_SUCCESS; 160 } 161 162 /* 163 u = sin(2 pi x) 164 v = sin(2 pi y) - 2xy 165 Delta <u,v> - f = <-4 pi^2 u, -4 pi^2 v> - <-4 pi^2 sin(2 pi x), -4 pi^2 sin(2 pi y)> 166 167 u = sin(2 pi x) 168 v = sin(2 pi y) - 2xy 169 w = sin(2 pi z) - 2yz 170 Delta <u,v,2> - f = <-4 pi^2 u, -4 pi^2 v, -4 pi^2 w> - <-4 pi^2 sin(2 pi x), -4 pi^2 sin(2 pi y), -4 pi^2 sin(2 pi z)> 171 */ 172 static void f0_vlap_trig_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 173 { 174 PetscInt d; 175 for (d = 0; d < dim; ++d) f0[d] += -4.0 * PetscSqr(PETSC_PI) * PetscSinReal(2.0 * PETSC_PI * x[d]); 176 } 177 178 /* 179 u = sin(2 pi x) 180 v = sin(2 pi y) - 2xy 181 \varepsilon = / 2 pi cos(2 pi x) -y \ 182 \ -y 2 pi cos(2 pi y) - 2x / 183 Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x 184 div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij} 185 = \lambda \partial_j 2 pi (cos(2 pi x) + cos(2 pi y)) + 2\mu < -4 pi^2 sin(2 pi x) - 1, -4 pi^2 sin(2 pi y) > 186 = \lambda < -4 pi^2 sin(2 pi x) - 2, -4 pi^2 sin(2 pi y) > + \mu < -8 pi^2 sin(2 pi x) - 2, -8 pi^2 sin(2 pi y) > 187 188 u = sin(2 pi x) 189 v = sin(2 pi y) - 2xy 190 w = sin(2 pi z) - 2yz 191 \varepsilon = / 2 pi cos(2 pi x) -y 0 \ 192 | -y 2 pi cos(2 pi y) - 2x -z | 193 \ 0 -z 2 pi cos(2 pi z) - 2y / 194 Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2 y 195 div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij} 196 = \lambda \partial_j (2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2 y) + 2\mu < -4 pi^2 sin(2 pi x) - 1, -4 pi^2 sin(2 pi y) - 1, -4 pi^2 sin(2 pi z) > 197 = \lambda < -4 pi^2 sin(2 pi x) - 2, -4 pi^2 sin(2 pi y) - 2, -4 pi^2 sin(2 pi z) > + 2\mu < -4 pi^2 sin(2 pi x) - 1, -4 pi^2 sin(2 pi y) - 1, -4 pi^2 sin(2 pi z) > 198 */ 199 static void f0_elas_trig_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 200 { 201 const PetscReal mu = PetscRealPart(constants[0]); 202 const PetscReal lambda = PetscRealPart(constants[1]); 203 const PetscReal fact = 4.0 * PetscSqr(PETSC_PI); 204 205 for (PetscInt d = 0; d < dim; ++d) f0[d] += -(2.0 * mu + lambda) * fact * PetscSinReal(2.0 * PETSC_PI * x[d]) - (d < dim - 1 ? 2.0 * (mu + lambda) : 0.0); 206 } 207 208 static PetscErrorCode axial_disp_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 209 { 210 AppCtx *user = (AppCtx *)ctx; 211 Parameter *param; 212 213 PetscCall(PetscBagGetData(user->bag, (void **)¶m)); 214 { 215 const PetscReal mu = PetscRealPart(param->mu); 216 const PetscReal lambda = PetscRealPart(param->lambda); 217 const PetscReal N = PetscRealPart(param->N); 218 219 u[0] = (3. * lambda * lambda + 8. * lambda * mu + 4 * mu * mu) / (4 * mu * (3 * lambda * lambda + 5. * lambda * mu + 2 * mu * mu)) * N * x[0]; 220 u[1] = 0.25 * lambda / mu / (lambda + mu) * N * x[1]; 221 for (PetscInt d = 2; d < dim; ++d) u[d] = 0.0; 222 } 223 return PETSC_SUCCESS; 224 } 225 226 /* 227 We will pull/push on the right side of a block of linearly elastic material. The uniform traction conditions on the 228 right side of the box will result in a uniform strain along x and y. The Neumann BC is given by 229 230 n_i \sigma_{ij} = t_i 231 232 u = (1/(2\mu) - 1) x 233 v = -y 234 f = 0 235 t = <4\mu/\lambda (\lambda + \mu), 0> 236 \varepsilon = / 1/(2\mu) - 1 0 \ 237 \ 0 -1 / 238 Tr(\varepsilon) = div u = 1/(2\mu) - 2 239 div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij} 240 = \lambda \partial_j (1/(2\mu) - 2) + 2\mu < 0, 0 > 241 = \lambda < 0, 0 > + \mu < 0, 0 > = 0 242 NBC = <1,0> . <4\mu/\lambda (\lambda + \mu), 0> = 4\mu/\lambda (\lambda + \mu) 243 244 u = x - 1/2 245 v = 0 246 w = 0 247 \varepsilon = / x 0 0 \ 248 | 0 0 0 | 249 \ 0 0 0 / 250 Tr(\varepsilon) = div u = x 251 div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij} 252 = \lambda \partial_j x + 2\mu < 1, 0, 0 > 253 = \lambda < 1, 0, 0 > + \mu < 2, 0, 0 > 254 */ 255 static void f0_elas_axial_disp_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 256 { 257 const PetscReal N = PetscRealPart(constants[2]); 258 259 f0[0] = N; 260 } 261 262 static PetscErrorCode uniform_strain_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 263 { 264 const PetscReal eps_xx = 0.1; 265 const PetscReal eps_xy = 0.3; 266 const PetscReal eps_yy = 0.25; 267 PetscInt d; 268 269 u[0] = eps_xx * x[0] + eps_xy * x[1]; 270 u[1] = eps_xy * x[0] + eps_yy * x[1]; 271 for (d = 2; d < dim; ++d) u[d] = 0.0; 272 return PETSC_SUCCESS; 273 } 274 275 static void f0_mass_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 276 { 277 const PetscInt Nc = dim; 278 PetscInt c; 279 280 for (c = 0; c < Nc; ++c) f0[c] = u[c]; 281 } 282 283 static void f1_vlap_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]) 284 { 285 const PetscInt Nc = dim; 286 PetscInt c, d; 287 288 for (c = 0; c < Nc; ++c) 289 for (d = 0; d < dim; ++d) f1[c * dim + d] += u_x[c * dim + d]; 290 } 291 292 static void f1_elas_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]) 293 { 294 const PetscReal mu = PetscRealPart(constants[0]); 295 const PetscReal lambda = PetscRealPart(constants[1]); 296 const PetscInt Nc = dim; 297 298 for (PetscInt c = 0; c < Nc; ++c) { 299 for (PetscInt d = 0; d < dim; ++d) { 300 f1[c * dim + d] += mu * (u_x[c * dim + d] + u_x[d * dim + c]); 301 f1[c * dim + c] += lambda * u_x[d * dim + d]; 302 } 303 } 304 } 305 306 static void g0_mass_uu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 307 { 308 const PetscInt Nc = dim; 309 PetscInt c; 310 311 for (c = 0; c < Nc; ++c) g0[c * Nc + c] = 1.0; 312 } 313 314 static void g3_vlap_uu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]) 315 { 316 const PetscInt Nc = dim; 317 PetscInt c, d; 318 319 for (c = 0; c < Nc; ++c) { 320 for (d = 0; d < dim; ++d) g3[((c * Nc + c) * dim + d) * dim + d] = 1.0; 321 } 322 } 323 324 /* 325 \partial_df \phi_fc g_{fc,gc,df,dg} \partial_dg \phi_gc 326 327 \partial_df \phi_fc \lambda \delta_{fc,df} \sum_gc \partial_dg \phi_gc \delta_{gc,dg} 328 = \partial_fc \phi_fc \sum_gc \partial_gc \phi_gc 329 */ 330 static void g3_elas_uu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]) 331 { 332 const PetscReal mu = PetscRealPart(constants[0]); 333 const PetscReal lambda = PetscRealPart(constants[1]); 334 const PetscInt Nc = dim; 335 336 for (PetscInt c = 0; c < Nc; ++c) { 337 for (PetscInt d = 0; d < dim; ++d) { 338 g3[((c * Nc + c) * dim + d) * dim + d] += mu; 339 g3[((c * Nc + d) * dim + d) * dim + c] += mu; 340 g3[((c * Nc + d) * dim + c) * dim + d] += lambda; 341 } 342 } 343 } 344 345 static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 346 { 347 PetscInt sol = 0, def = 0; 348 349 PetscFunctionBeginUser; 350 options->deform = DEFORM_NONE; 351 options->solType = SOL_VLAP_QUADRATIC; 352 options->useNearNullspace = PETSC_TRUE; 353 PetscCall(PetscStrncpy(options->dmType, DMPLEX, 256)); 354 355 PetscOptionsBegin(comm, "", "Linear Elasticity Problem Options", "DMPLEX"); 356 PetscCall(PetscOptionsEList("-deform_type", "Type of domain deformation", "ex17.c", deformTypes, NUM_DEFORM_TYPES, deformTypes[options->deform], &def, NULL)); 357 options->deform = (DeformType)def; 358 PetscCall(PetscOptionsEList("-sol_type", "Type of exact solution", "ex17.c", solutionTypes, NUM_SOLUTION_TYPES, solutionTypes[options->solType], &sol, NULL)); 359 options->solType = (SolutionType)sol; 360 PetscCall(PetscOptionsBool("-near_nullspace", "Use the rigid body modes as an AMG near nullspace", "ex17.c", options->useNearNullspace, &options->useNearNullspace, NULL)); 361 PetscCall(PetscOptionsFList("-dm_type", "Convert DMPlex to another format", "ex17.c", DMList, options->dmType, options->dmType, 256, NULL)); 362 PetscOptionsEnd(); 363 PetscFunctionReturn(PETSC_SUCCESS); 364 } 365 366 static PetscErrorCode SetupParameters(MPI_Comm comm, AppCtx *ctx) 367 { 368 PetscBag bag; 369 Parameter *p; 370 371 PetscFunctionBeginUser; 372 /* setup PETSc parameter bag */ 373 PetscCall(PetscBagGetData(ctx->bag, (void **)&p)); 374 PetscCall(PetscBagSetName(ctx->bag, "par", "Elastic Parameters")); 375 bag = ctx->bag; 376 PetscCall(PetscBagRegisterScalar(bag, &p->mu, 1.0, "mu", "Shear Modulus, Pa")); 377 PetscCall(PetscBagRegisterScalar(bag, &p->lambda, 1.0, "lambda", "Lame's first parameter, Pa")); 378 PetscCall(PetscBagRegisterScalar(bag, &p->N, -1.0, "N", "Tension on right wall, Pa")); 379 PetscCall(PetscBagSetFromOptions(bag)); 380 { 381 PetscViewer viewer; 382 PetscViewerFormat format; 383 PetscBool flg; 384 385 PetscCall(PetscOptionsGetViewer(comm, NULL, NULL, "-param_view", &viewer, &format, &flg)); 386 if (flg) { 387 PetscCall(PetscViewerPushFormat(viewer, format)); 388 PetscCall(PetscBagView(bag, viewer)); 389 PetscCall(PetscViewerFlush(viewer)); 390 PetscCall(PetscViewerPopFormat(viewer)); 391 PetscCall(PetscViewerDestroy(&viewer)); 392 } 393 } 394 PetscFunctionReturn(PETSC_SUCCESS); 395 } 396 397 static PetscErrorCode DMPlexDistortGeometry(DM dm) 398 { 399 DM cdm; 400 DMLabel label; 401 Vec coordinates; 402 PetscScalar *coords; 403 PetscReal mid = 0.5; 404 PetscInt cdim, d, vStart, vEnd, v; 405 406 PetscFunctionBeginUser; 407 PetscCall(DMGetCoordinateDM(dm, &cdm)); 408 PetscCall(DMGetCoordinateDim(dm, &cdim)); 409 PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 410 PetscCall(DMGetLabel(dm, "marker", &label)); 411 PetscCall(DMGetCoordinatesLocal(dm, &coordinates)); 412 PetscCall(VecGetArrayWrite(coordinates, &coords)); 413 for (v = vStart; v < vEnd; ++v) { 414 PetscScalar *pcoords, shift; 415 PetscInt val; 416 417 PetscCall(DMLabelGetValue(label, v, &val)); 418 if (val >= 0) continue; 419 PetscCall(DMPlexPointLocalRef(cdm, v, coords, &pcoords)); 420 shift = 0.2 * PetscAbsScalar(pcoords[0] - mid); 421 shift = PetscRealPart(pcoords[0]) > mid ? shift : -shift; 422 for (d = 1; d < cdim; ++d) pcoords[d] += shift; 423 } 424 PetscCall(VecRestoreArrayWrite(coordinates, &coords)); 425 PetscFunctionReturn(PETSC_SUCCESS); 426 } 427 428 static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 429 { 430 PetscFunctionBeginUser; 431 PetscCall(DMCreate(comm, dm)); 432 PetscCall(DMSetType(*dm, DMPLEX)); 433 PetscCall(DMSetFromOptions(*dm)); 434 switch (user->deform) { 435 case DEFORM_NONE: 436 break; 437 case DEFORM_SHEAR: 438 PetscCall(DMPlexShearGeometry(*dm, DM_X, NULL)); 439 break; 440 case DEFORM_STEP: 441 PetscCall(DMPlexDistortGeometry(*dm)); 442 break; 443 default: 444 SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid deformation type: %s (%d)", deformTypes[PetscMin(user->deform, NUM_DEFORM_TYPES)], user->deform); 445 } 446 PetscCall(DMSetApplicationContext(*dm, user)); 447 PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 448 PetscFunctionReturn(PETSC_SUCCESS); 449 } 450 451 static PetscErrorCode SetupPrimalProblem(DM dm, AppCtx *user) 452 { 453 PetscErrorCode (*exact)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *); 454 Parameter *param; 455 PetscDS ds; 456 PetscWeakForm wf; 457 DMLabel label; 458 PetscInt id, bd; 459 PetscInt dim; 460 461 PetscFunctionBeginUser; 462 PetscCall(DMGetDS(dm, &ds)); 463 PetscCall(PetscDSGetWeakForm(ds, &wf)); 464 PetscCall(PetscDSGetSpatialDimension(ds, &dim)); 465 PetscCall(PetscBagGetData(user->bag, (void **)¶m)); 466 switch (user->solType) { 467 case SOL_MASS_QUADRATIC: 468 PetscCall(PetscDSSetResidual(ds, 0, f0_mass_u, NULL)); 469 PetscCall(PetscDSSetJacobian(ds, 0, 0, g0_mass_uu, NULL, NULL, NULL)); 470 PetscCall(PetscWeakFormSetIndexResidual(wf, NULL, 0, 0, 0, 1, f0_mass_quadratic_u, 0, NULL)); 471 switch (dim) { 472 case 2: 473 exact = quadratic_2d_u; 474 break; 475 case 3: 476 exact = quadratic_3d_u; 477 break; 478 default: 479 SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %" PetscInt_FMT, dim); 480 } 481 break; 482 case SOL_VLAP_QUADRATIC: 483 PetscCall(PetscDSSetResidual(ds, 0, f0_vlap_quadratic_u, f1_vlap_u)); 484 PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_vlap_uu)); 485 switch (dim) { 486 case 2: 487 exact = quadratic_2d_u; 488 break; 489 case 3: 490 exact = quadratic_3d_u; 491 break; 492 default: 493 SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %" PetscInt_FMT, dim); 494 } 495 break; 496 case SOL_ELAS_QUADRATIC: 497 PetscCall(PetscDSSetResidual(ds, 0, f0_elas_quadratic_u, f1_elas_u)); 498 PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu)); 499 switch (dim) { 500 case 2: 501 exact = quadratic_2d_u; 502 break; 503 case 3: 504 exact = quadratic_3d_u; 505 break; 506 default: 507 SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %" PetscInt_FMT, dim); 508 } 509 break; 510 case SOL_VLAP_TRIG: 511 PetscCall(PetscDSSetResidual(ds, 0, f0_vlap_trig_u, f1_vlap_u)); 512 PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_vlap_uu)); 513 switch (dim) { 514 case 2: 515 exact = trig_2d_u; 516 break; 517 case 3: 518 exact = trig_3d_u; 519 break; 520 default: 521 SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %" PetscInt_FMT, dim); 522 } 523 break; 524 case SOL_ELAS_TRIG: 525 PetscCall(PetscDSSetResidual(ds, 0, f0_elas_trig_u, f1_elas_u)); 526 PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu)); 527 switch (dim) { 528 case 2: 529 exact = trig_2d_u; 530 break; 531 case 3: 532 exact = trig_3d_u; 533 break; 534 default: 535 SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %" PetscInt_FMT, dim); 536 } 537 break; 538 case SOL_ELAS_AXIAL_DISP: 539 PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_elas_u)); 540 PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu)); 541 id = dim == 3 ? 5 : 2; 542 PetscCall(DMGetLabel(dm, "marker", &label)); 543 PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "right", label, 1, &id, 0, 0, NULL, (void (*)(void))NULL, NULL, user, &bd)); 544 PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); 545 PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, 0, f0_elas_axial_disp_bd_u, 0, NULL)); 546 exact = axial_disp_u; 547 break; 548 case SOL_ELAS_UNIFORM_STRAIN: 549 PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_elas_u)); 550 PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu)); 551 exact = uniform_strain_u; 552 break; 553 case SOL_ELAS_GE: 554 PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_elas_u)); 555 PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu)); 556 exact = zero; /* No exact solution available */ 557 break; 558 default: 559 SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%d)", solutionTypes[PetscMin(user->solType, NUM_SOLUTION_TYPES)], user->solType); 560 } 561 PetscCall(PetscDSSetExactSolution(ds, 0, exact, user)); 562 PetscCall(DMGetLabel(dm, "marker", &label)); 563 if (user->solType == SOL_ELAS_AXIAL_DISP) { 564 PetscInt cmp; 565 566 id = dim == 3 ? 6 : 4; 567 cmp = 0; 568 PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "left", label, 1, &id, 0, 1, &cmp, (void (*)(void))zero, NULL, user, NULL)); 569 cmp = dim == 3 ? 2 : 1; 570 id = dim == 3 ? 1 : 1; 571 PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "bottom", label, 1, &id, 0, 1, &cmp, (void (*)(void))zero, NULL, user, NULL)); 572 if (dim == 3) { 573 cmp = 1; 574 id = 3; 575 PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "front", label, 1, &id, 0, 1, &cmp, (void (*)(void))zero, NULL, user, NULL)); 576 } 577 } else if (user->solType == SOL_ELAS_GE) { 578 PetscInt cmp; 579 580 id = dim == 3 ? 6 : 4; 581 PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "left", label, 1, &id, 0, 0, NULL, (void (*)(void))zero, NULL, user, NULL)); 582 id = dim == 3 ? 5 : 2; 583 cmp = 0; 584 PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "right", label, 1, &id, 0, 1, &cmp, (void (*)(void))ge_shift, NULL, user, NULL)); 585 } else { 586 id = 1; 587 PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall", label, 1, &id, 0, 0, NULL, (void (*)(void))exact, NULL, user, NULL)); 588 } 589 /* Setup constants */ 590 { 591 PetscScalar constants[3]; 592 593 constants[0] = param->mu; /* shear modulus, Pa */ 594 constants[1] = param->lambda; /* Lame's first parameter, Pa */ 595 constants[2] = param->N; /* Tension on right wall, Pa */ 596 PetscCall(PetscDSSetConstants(ds, 3, constants)); 597 } 598 PetscFunctionReturn(PETSC_SUCCESS); 599 } 600 601 static PetscErrorCode CreateElasticityNullSpace(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullspace) 602 { 603 PetscFunctionBegin; 604 PetscCall(DMPlexCreateRigidBody(dm, origField, nullspace)); 605 PetscFunctionReturn(PETSC_SUCCESS); 606 } 607 608 PetscErrorCode SetupFE(DM dm, const char name[], PetscErrorCode (*setup)(DM, AppCtx *), void *ctx) 609 { 610 AppCtx *user = (AppCtx *)ctx; 611 DM cdm = dm; 612 PetscFE fe; 613 char prefix[PETSC_MAX_PATH_LEN]; 614 DMPolytopeType ct; 615 PetscInt dim, cStart; 616 617 PetscFunctionBegin; 618 /* Create finite element */ 619 PetscCall(DMGetDimension(dm, &dim)); 620 PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 621 PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 622 PetscCall(PetscSNPrintf(prefix, PETSC_MAX_PATH_LEN, "%s_", name)); 623 PetscCall(PetscFECreateByCell(PETSC_COMM_SELF, dim, dim, ct, name ? prefix : NULL, -1, &fe)); 624 PetscCall(PetscObjectSetName((PetscObject)fe, name)); 625 /* Set discretization and boundary conditions for each mesh */ 626 PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fe)); 627 PetscCall(DMCreateDS(dm)); 628 PetscCall((*setup)(dm, user)); 629 while (cdm) { 630 PetscCall(DMCopyDisc(dm, cdm)); 631 if (user->useNearNullspace) PetscCall(DMSetNearNullSpaceConstructor(cdm, 0, CreateElasticityNullSpace)); 632 PetscCall(DMGetCoarseDM(cdm, &cdm)); 633 } 634 PetscCall(PetscFEDestroy(&fe)); 635 PetscFunctionReturn(PETSC_SUCCESS); 636 } 637 638 int main(int argc, char **argv) 639 { 640 DM dm; /* Problem specification */ 641 SNES snes; /* Nonlinear solver */ 642 Vec u; /* Solutions */ 643 AppCtx user; /* User-defined work context */ 644 645 PetscFunctionBeginUser; 646 PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 647 PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 648 PetscCall(PetscBagCreate(PETSC_COMM_SELF, sizeof(Parameter), &user.bag)); 649 PetscCall(SetupParameters(PETSC_COMM_WORLD, &user)); 650 /* Primal system */ 651 PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes)); 652 PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 653 PetscCall(SNESSetDM(snes, dm)); 654 PetscCall(SetupFE(dm, "displacement", SetupPrimalProblem, &user)); 655 PetscCall(DMCreateGlobalVector(dm, &u)); 656 PetscCall(VecSet(u, 0.0)); 657 PetscCall(PetscObjectSetName((PetscObject)u, "displacement")); 658 PetscCall(DMPlexSetSNESLocalFEM(dm, &user, &user, &user)); 659 PetscCall(SNESSetFromOptions(snes)); 660 PetscCall(DMSNESCheckFromOptions(snes, u)); 661 PetscCall(SNESSolve(snes, NULL, u)); 662 PetscCall(SNESGetSolution(snes, &u)); 663 PetscCall(VecViewFromOptions(u, NULL, "-displacement_view")); 664 /* Cleanup */ 665 PetscCall(VecDestroy(&u)); 666 PetscCall(SNESDestroy(&snes)); 667 PetscCall(DMDestroy(&dm)); 668 PetscCall(PetscBagDestroy(&user.bag)); 669 PetscCall(PetscFinalize()); 670 return 0; 671 } 672 673 /*TEST 674 675 testset: 676 args: -dm_plex_box_faces 1,1,1 677 678 test: 679 suffix: 2d_p1_quad_vlap 680 requires: triangle 681 args: -displacement_petscspace_degree 1 -dm_refine 2 -convest_num_refine 3 -snes_convergence_estimate 682 test: 683 suffix: 2d_p2_quad_vlap 684 requires: triangle 685 args: -displacement_petscspace_degree 2 -dm_refine 2 -dmsnes_check .0001 686 test: 687 suffix: 2d_p3_quad_vlap 688 requires: triangle 689 args: -displacement_petscspace_degree 3 -dm_refine 2 -dmsnes_check .0001 690 test: 691 suffix: 2d_q1_quad_vlap 692 args: -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 2 -convest_num_refine 3 -snes_convergence_estimate 693 test: 694 suffix: 2d_q2_quad_vlap 695 args: -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 2 -dmsnes_check .0001 696 test: 697 suffix: 2d_q3_quad_vlap 698 requires: !single 699 args: -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 2 -dmsnes_check .0001 700 test: 701 suffix: 2d_p1_quad_elas 702 requires: triangle 703 args: -sol_type elas_quad -displacement_petscspace_degree 1 -dm_refine 2 -convest_num_refine 3 -snes_convergence_estimate 704 test: 705 suffix: 2d_p2_quad_elas 706 requires: triangle 707 args: -sol_type elas_quad -displacement_petscspace_degree 2 -dmsnes_check .0001 708 test: 709 suffix: 2d_p3_quad_elas 710 requires: triangle 711 args: -sol_type elas_quad -displacement_petscspace_degree 3 -dmsnes_check .0001 712 test: 713 suffix: 2d_q1_quad_elas 714 args: -sol_type elas_quad -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 715 test: 716 suffix: 2d_q1_quad_elas_shear 717 args: -sol_type elas_quad -dm_plex_simplex 0 -deform_type shear -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 718 test: 719 suffix: 2d_q2_quad_elas 720 args: -sol_type elas_quad -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dmsnes_check .0001 721 test: 722 suffix: 2d_q2_quad_elas_shear 723 args: -sol_type elas_quad -dm_plex_simplex 0 -deform_type shear -displacement_petscspace_degree 2 -dmsnes_check 724 test: 725 suffix: 2d_q3_quad_elas 726 args: -sol_type elas_quad -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dmsnes_check .0001 727 test: 728 suffix: 2d_q3_quad_elas_shear 729 requires: !single 730 args: -sol_type elas_quad -dm_plex_simplex 0 -deform_type shear -displacement_petscspace_degree 3 -dmsnes_check 731 732 test: 733 suffix: 3d_p1_quad_vlap 734 requires: ctetgen 735 args: -dm_plex_dim 3 -dm_refine 1 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate 736 test: 737 suffix: 3d_p2_quad_vlap 738 requires: ctetgen 739 args: -dm_plex_dim 3 -displacement_petscspace_degree 2 -dm_refine 1 -dmsnes_check .0001 740 test: 741 suffix: 3d_p3_quad_vlap 742 requires: ctetgen 743 args: -dm_plex_dim 3 -displacement_petscspace_degree 3 -dm_refine 0 -dmsnes_check .0001 744 test: 745 suffix: 3d_q1_quad_vlap 746 args: -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_simplex 0 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate 747 test: 748 suffix: 3d_q2_quad_vlap 749 args: -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 1 -dmsnes_check .0001 750 test: 751 suffix: 3d_q3_quad_vlap 752 args: -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 0 -dmsnes_check .0001 753 test: 754 suffix: 3d_p1_quad_elas 755 requires: ctetgen 756 args: -sol_type elas_quad -dm_plex_dim 3 -dm_refine 1 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate 757 test: 758 suffix: 3d_p2_quad_elas 759 requires: ctetgen 760 args: -sol_type elas_quad -dm_plex_dim 3 -displacement_petscspace_degree 2 -dm_refine 1 -dmsnes_check .0001 761 test: 762 suffix: 3d_p3_quad_elas 763 requires: ctetgen 764 args: -sol_type elas_quad -dm_plex_dim 3 -displacement_petscspace_degree 3 -dm_refine 0 -dmsnes_check .0001 765 test: 766 suffix: 3d_q1_quad_elas 767 args: -sol_type elas_quad -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_simplex 0 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate 768 test: 769 suffix: 3d_q2_quad_elas 770 args: -sol_type elas_quad -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 1 -dmsnes_check .0001 771 test: 772 suffix: 3d_q3_quad_elas 773 requires: !single 774 args: -sol_type elas_quad -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 0 -dmsnes_check .0001 775 776 test: 777 suffix: 2d_p1_trig_vlap 778 requires: triangle 779 args: -sol_type vlap_trig -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 780 test: 781 suffix: 2d_p2_trig_vlap 782 requires: triangle 783 args: -sol_type vlap_trig -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 784 test: 785 suffix: 2d_p3_trig_vlap 786 requires: triangle 787 args: -sol_type vlap_trig -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 788 test: 789 suffix: 2d_q1_trig_vlap 790 args: -sol_type vlap_trig -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 791 test: 792 suffix: 2d_q2_trig_vlap 793 args: -sol_type vlap_trig -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 794 test: 795 suffix: 2d_q3_trig_vlap 796 args: -sol_type vlap_trig -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 797 test: 798 suffix: 2d_p1_trig_elas 799 requires: triangle 800 args: -sol_type elas_trig -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 801 test: 802 suffix: 2d_p2_trig_elas 803 requires: triangle 804 args: -sol_type elas_trig -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 805 test: 806 suffix: 2d_p3_trig_elas 807 requires: triangle 808 args: -sol_type elas_trig -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 809 test: 810 suffix: 2d_q1_trig_elas 811 args: -sol_type elas_trig -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 812 test: 813 suffix: 2d_q1_trig_elas_shear 814 args: -sol_type elas_trig -dm_plex_simplex 0 -deform_type shear -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 815 test: 816 suffix: 2d_q2_trig_elas 817 args: -sol_type elas_trig -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 818 test: 819 suffix: 2d_q2_trig_elas_shear 820 args: -sol_type elas_trig -dm_plex_simplex 0 -deform_type shear -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 821 test: 822 suffix: 2d_q3_trig_elas 823 args: -sol_type elas_trig -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 824 test: 825 suffix: 2d_q3_trig_elas_shear 826 args: -sol_type elas_trig -dm_plex_simplex 0 -deform_type shear -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate 827 828 test: 829 suffix: 3d_p1_trig_vlap 830 requires: ctetgen 831 args: -sol_type vlap_trig -dm_plex_dim 3 -dm_refine 1 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate 832 test: 833 suffix: 3d_p2_trig_vlap 834 requires: ctetgen 835 args: -sol_type vlap_trig -dm_plex_dim 3 -displacement_petscspace_degree 2 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate 836 test: 837 suffix: 3d_p3_trig_vlap 838 requires: ctetgen 839 args: -sol_type vlap_trig -dm_plex_dim 3 -displacement_petscspace_degree 3 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate 840 test: 841 suffix: 3d_q1_trig_vlap 842 args: -sol_type vlap_trig -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_simplex 0 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate 843 test: 844 suffix: 3d_q2_trig_vlap 845 args: -sol_type vlap_trig -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate 846 test: 847 suffix: 3d_q3_trig_vlap 848 requires: !__float128 849 args: -sol_type vlap_trig -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate 850 test: 851 suffix: 3d_p1_trig_elas 852 requires: ctetgen 853 args: -sol_type elas_trig -dm_plex_dim 3 -dm_refine 1 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate 854 test: 855 suffix: 3d_p2_trig_elas 856 requires: ctetgen 857 args: -sol_type elas_trig -dm_plex_dim 3 -displacement_petscspace_degree 2 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate 858 test: 859 suffix: 3d_p3_trig_elas 860 requires: ctetgen 861 args: -sol_type elas_trig -dm_plex_dim 3 -displacement_petscspace_degree 3 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate 862 test: 863 suffix: 3d_q1_trig_elas 864 args: -sol_type elas_trig -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_simplex 0 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate 865 test: 866 suffix: 3d_q2_trig_elas 867 args: -sol_type elas_trig -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate 868 test: 869 suffix: 3d_q3_trig_elas 870 requires: !__float128 871 args: -sol_type elas_trig -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate 872 873 test: 874 suffix: 2d_p1_axial_elas 875 requires: triangle 876 args: -sol_type elas_axial_disp -displacement_petscspace_degree 1 -dm_plex_separate_marker -dm_refine 2 -dmsnes_check .0001 -pc_type lu 877 test: 878 suffix: 2d_p2_axial_elas 879 requires: triangle 880 args: -sol_type elas_axial_disp -displacement_petscspace_degree 2 -dm_plex_separate_marker -dmsnes_check .0001 -pc_type lu 881 test: 882 suffix: 2d_p3_axial_elas 883 requires: triangle 884 args: -sol_type elas_axial_disp -displacement_petscspace_degree 3 -dm_plex_separate_marker -dmsnes_check .0001 -pc_type lu 885 test: 886 suffix: 2d_q1_axial_elas 887 args: -sol_type elas_axial_disp -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_plex_separate_marker -dm_refine 1 -dmsnes_check .0001 -pc_type lu 888 test: 889 suffix: 2d_q2_axial_elas 890 args: -sol_type elas_axial_disp -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_plex_separate_marker -dmsnes_check .0001 -pc_type lu 891 test: 892 suffix: 2d_q3_axial_elas 893 args: -sol_type elas_axial_disp -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_plex_separate_marker -dmsnes_check .0001 -pc_type lu 894 895 test: 896 suffix: 2d_p1_uniform_elas 897 requires: triangle 898 args: -sol_type elas_uniform_strain -displacement_petscspace_degree 1 -dm_refine 2 -dmsnes_check .0001 -pc_type lu 899 test: 900 suffix: 2d_p2_uniform_elas 901 requires: triangle 902 args: -sol_type elas_uniform_strain -displacement_petscspace_degree 2 -dm_refine 2 -dmsnes_check .0001 -pc_type lu 903 test: 904 suffix: 2d_p3_uniform_elas 905 requires: triangle 906 args: -sol_type elas_uniform_strain -displacement_petscspace_degree 3 -dm_refine 2 -dmsnes_check .0001 -pc_type lu 907 test: 908 suffix: 2d_q1_uniform_elas 909 args: -sol_type elas_uniform_strain -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 2 -dmsnes_check .0001 -pc_type lu 910 test: 911 suffix: 2d_q2_uniform_elas 912 requires: !single 913 args: -sol_type elas_uniform_strain -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 2 -dmsnes_check .0001 -pc_type lu 914 test: 915 suffix: 2d_q3_uniform_elas 916 requires: !single 917 args: -sol_type elas_uniform_strain -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 2 -dmsnes_check .0001 -pc_type lu 918 test: 919 suffix: 2d_p1_uniform_elas_step 920 requires: triangle 921 args: -sol_type elas_uniform_strain -deform_type step -displacement_petscspace_degree 1 -dm_refine 2 -dmsnes_check .0001 -pc_type lu 922 923 testset: 924 args: -dm_plex_simplex 0 -dm_plex_box_faces 3,3 -deform_type step -displacement_petscspace_degree 1 -dmsnes_check .0001 -pc_type lu 925 926 test: 927 suffix: 2d_q1_uniform_elas_step 928 args: -sol_type elas_uniform_strain -dm_refine 2 929 test: 930 suffix: 2d_q1_quad_vlap_step 931 args: 932 test: 933 suffix: 2d_q2_quad_vlap_step 934 args: -displacement_petscspace_degree 2 935 test: 936 suffix: 2d_q1_quad_mass_step 937 args: -sol_type mass_quad 938 939 testset: 940 filter: grep -v "variant HERMITIAN" 941 args: -dm_plex_dim 3 -dm_plex_simplex 0 -dm_plex_box_lower -5,-5,-0.25 -dm_plex_box_upper 5,5,0.25 \ 942 -dm_plex_box_faces 5,5,2 -dm_plex_separate_marker -dm_refine 0 -petscpartitioner_type simple \ 943 -sol_type elas_ge 944 945 test: 946 suffix: ge_q1_0 947 args: -displacement_petscspace_degree 1 \ 948 -snes_max_it 2 -snes_rtol 1.e-10 \ 949 -ksp_type cg -ksp_rtol 1.e-10 -ksp_max_it 100 -ksp_norm_type unpreconditioned \ 950 -pc_type gamg -pc_gamg_type agg -pc_gamg_agg_nsmooths 1 \ 951 -pc_gamg_coarse_eq_limit 10 -pc_gamg_reuse_interpolation true \ 952 -pc_gamg_threshold 0.05 -pc_gamg_threshold_scale .0 \ 953 -mg_levels_ksp_max_it 2 -mg_levels_ksp_type chebyshev -mg_levels_ksp_chebyshev_esteig 0,0.05,0,1.1 -mg_levels_pc_type jacobi \ 954 -matptap_via scalable 955 test: 956 suffix: ge_q1_gmg 957 args: -displacement_petscspace_degree 1 \ 958 -dm_plex_box_faces 2,2 -dm_refine_hierarchy 3 \ 959 -snes_max_it 2 -snes_rtol 1.e-10 \ 960 -ksp_type cg -ksp_rtol 1.e-10 -ksp_max_it 100 -ksp_norm_type unpreconditioned \ 961 -pc_type mg -pc_mg_type full \ 962 -mg_levels_ksp_max_it 4 -mg_levels_esteig_ksp_type cg \ 963 -mg_levels_esteig_ksp_max_it 10 -mg_levels_ksp_chebyshev_esteig 0,0.1,0,1.1 \ 964 -mg_levels_pc_type jacobi 965 test: 966 nsize: 5 967 suffix: ge_q1_gdsw 968 args: -snes_max_it 1 -ksp_type cg -ksp_norm_type natural -displacement_petscspace_degree 1 -snes_monitor_short -ksp_monitor_short -pc_type mg -pc_mg_adapt_interp_coarse_space gdsw -pc_mg_levels 2 -pc_mg_galerkin -mg_levels_pc_type bjacobi -mg_levels_esteig_ksp_type cg -mg_levels_sub_pc_type icc -mg_coarse_redundant_pc_type cholesky -ksp_view 969 970 TEST*/ 971