Actual source code: ex17.c
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";
7: /*
8: https://en.wikipedia.org/wiki/Linear_elasticity
9: */
11: #include <petscdmplex.h>
12: #include <petscsnes.h>
13: #include <petscds.h>
14: #include <petscconvest.h>
16: typedef enum {SOL_VLAP_QUADRATIC, SOL_ELAS_QUADRATIC, SOL_VLAP_TRIG, SOL_ELAS_TRIG, SOL_ELAS_AXIAL_DISP, SOL_ELAS_UNIFORM_STRAIN, SOL_MASS_QUADRATIC, NUM_SOLUTION_TYPES} SolutionType;
17: const char *solutionTypes[NUM_SOLUTION_TYPES+1] = {"vlap_quad", "elas_quad", "vlap_trig", "elas_trig", "elas_axial_disp", "elas_uniform_strain", "mass_quad", "unknown"};
19: typedef enum {DEFORM_NONE, DEFORM_SHEAR, DEFORM_STEP, NUM_DEFORM_TYPES} DeformType;
20: const char *deformTypes[NUM_DEFORM_TYPES+1] = {"none", "shear", "step", "unknown"};
22: typedef struct {
23: /* Domain and mesh definition */
24: char dmType[256]; /* DM type for the solve */
25: DeformType deform; /* Domain deformation type */
26: /* Problem definition */
27: SolutionType solType; /* Type of exact solution */
28: /* Solver definition */
29: PetscBool useNearNullspace; /* Use the rigid body modes as a near nullspace for AMG */
30: } AppCtx;
32: static PetscErrorCode zero(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
33: {
34: PetscInt d;
35: for (d = 0; d < dim; ++d) u[d] = 0.0;
36: return 0;
37: }
39: static PetscErrorCode quadratic_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
40: {
41: u[0] = x[0]*x[0];
42: u[1] = x[1]*x[1] - 2.0*x[0]*x[1];
43: return 0;
44: }
46: static PetscErrorCode quadratic_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
47: {
48: u[0] = x[0]*x[0];
49: u[1] = x[1]*x[1] - 2.0*x[0]*x[1];
50: u[2] = x[2]*x[2] - 2.0*x[1]*x[2];
51: return 0;
52: }
54: /*
55: u = x^2
56: v = y^2 - 2xy
57: Delta <u,v> - f = <2, 2> - <2, 2>
59: u = x^2
60: v = y^2 - 2xy
61: w = z^2 - 2yz
62: Delta <u,v,w> - f = <2, 2, 2> - <2, 2, 2>
63: */
64: static void f0_vlap_quadratic_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
65: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
66: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
67: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
68: {
69: PetscInt d;
70: for (d = 0; d < dim; ++d) f0[d] += 2.0;
71: }
73: /*
74: u = x^2
75: v = y^2 - 2xy
76: \varepsilon = / 2x -y \
77: \ -y 2y - 2x /
78: Tr(\varepsilon) = div u = 2y
79: div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
80: = \lambda \partial_j (2y) + 2\mu < 2-1, 2 >
81: = \lambda < 0, 2 > + \mu < 2, 4 >
83: u = x^2
84: v = y^2 - 2xy
85: w = z^2 - 2yz
86: \varepsilon = / 2x -y 0 \
87: | -y 2y - 2x -z |
88: \ 0 -z 2z - 2y/
89: Tr(\varepsilon) = div u = 2z
90: div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
91: = \lambda \partial_j (2z) + 2\mu < 2-1, 2-1, 2 >
92: = \lambda < 0, 0, 2 > + \mu < 2, 2, 4 >
93: */
94: static void f0_elas_quadratic_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
95: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
96: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
97: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
98: {
99: const PetscReal mu = 1.0;
100: const PetscReal lambda = 1.0;
101: PetscInt d;
103: for (d = 0; d < dim-1; ++d) f0[d] += 2.0*mu;
104: f0[dim-1] += 2.0*lambda + 4.0*mu;
105: }
107: static void f0_mass_quadratic_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
108: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
109: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
110: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
111: {
112: if (dim == 2) {
113: f0[0] -= x[0]*x[0];
114: f0[1] -= x[1]*x[1] - 2.0*x[0]*x[1];
115: } else {
116: f0[0] -= x[0]*x[0];
117: f0[1] -= x[1]*x[1] - 2.0*x[0]*x[1];
118: f0[2] -= x[2]*x[2] - 2.0*x[1]*x[2];
119: }
120: }
122: static PetscErrorCode trig_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
123: {
124: u[0] = PetscSinReal(2.0*PETSC_PI*x[0]);
125: u[1] = PetscSinReal(2.0*PETSC_PI*x[1]) - 2.0*x[0]*x[1];
126: return 0;
127: }
129: static PetscErrorCode trig_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
130: {
131: u[0] = PetscSinReal(2.0*PETSC_PI*x[0]);
132: u[1] = PetscSinReal(2.0*PETSC_PI*x[1]) - 2.0*x[0]*x[1];
133: u[2] = PetscSinReal(2.0*PETSC_PI*x[2]) - 2.0*x[1]*x[2];
134: return 0;
135: }
137: /*
138: u = sin(2 pi x)
139: v = sin(2 pi y) - 2xy
140: 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)>
142: u = sin(2 pi x)
143: v = sin(2 pi y) - 2xy
144: w = sin(2 pi z) - 2yz
145: 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)>
146: */
147: static void f0_vlap_trig_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
148: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
149: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
150: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
151: {
152: PetscInt d;
153: for (d = 0; d < dim; ++d) f0[d] += -4.0*PetscSqr(PETSC_PI)*PetscSinReal(2.0*PETSC_PI*x[d]);
154: }
156: /*
157: u = sin(2 pi x)
158: v = sin(2 pi y) - 2xy
159: \varepsilon = / 2 pi cos(2 pi x) -y \
160: \ -y 2 pi cos(2 pi y) - 2x /
161: Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
162: div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
163: = \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) >
164: = \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) >
166: u = sin(2 pi x)
167: v = sin(2 pi y) - 2xy
168: w = sin(2 pi z) - 2yz
169: \varepsilon = / 2 pi cos(2 pi x) -y 0 \
170: | -y 2 pi cos(2 pi y) - 2x -z |
171: \ 0 -z 2 pi cos(2 pi z) - 2y /
172: Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2 y
173: div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
174: = \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) >
175: = \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) >
176: */
177: static void f0_elas_trig_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
178: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
179: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
180: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
181: {
182: const PetscReal mu = 1.0;
183: const PetscReal lambda = 1.0;
184: const PetscReal fact = 4.0*PetscSqr(PETSC_PI);
185: PetscInt d;
187: for (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);
188: }
190: static PetscErrorCode axial_disp_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
191: {
192: const PetscReal mu = 1.0;
193: const PetscReal lambda = 1.0;
194: const PetscReal N = 1.0;
195: PetscInt d;
197: 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];
198: u[1] = -0.25*lambda/mu/(lambda+mu)*N*x[1];
199: for (d = 2; d < dim; ++d) u[d] = 0.0;
200: return 0;
201: }
203: /*
204: We will pull/push on the right side of a block of linearly elastic material. The uniform traction conditions on the
205: right side of the box will result in a uniform strain along x and y. The Neumann BC is given by
207: n_i \sigma_{ij} = t_i
209: u = (1/(2\mu) - 1) x
210: v = -y
211: f = 0
212: t = <4\mu/\lambda (\lambda + \mu), 0>
213: \varepsilon = / 1/(2\mu) - 1 0 \
214: \ 0 -1 /
215: Tr(\varepsilon) = div u = 1/(2\mu) - 2
216: div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
217: = \lambda \partial_j (1/(2\mu) - 2) + 2\mu < 0, 0 >
218: = \lambda < 0, 0 > + \mu < 0, 0 > = 0
219: NBC = <1,0> . <4\mu/\lambda (\lambda + \mu), 0> = 4\mu/\lambda (\lambda + \mu)
221: u = x - 1/2
222: v = 0
223: w = 0
224: \varepsilon = / x 0 0 \
225: | 0 0 0 |
226: \ 0 0 0 /
227: Tr(\varepsilon) = div u = x
228: div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
229: = \lambda \partial_j x + 2\mu < 1, 0, 0 >
230: = \lambda < 1, 0, 0 > + \mu < 2, 0, 0 >
231: */
232: static void f0_elas_axial_disp_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
233: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
234: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
235: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
236: {
237: const PetscReal N = -1.0;
239: f0[0] = N;
240: }
242: static PetscErrorCode uniform_strain_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
243: {
244: const PetscReal eps_xx = 0.1;
245: const PetscReal eps_xy = 0.3;
246: const PetscReal eps_yy = 0.25;
247: PetscInt d;
249: u[0] = eps_xx*x[0] + eps_xy*x[1];
250: u[1] = eps_xy*x[0] + eps_yy*x[1];
251: for (d = 2; d < dim; ++d) u[d] = 0.0;
252: return 0;
253: }
255: static void f0_mass_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
256: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
257: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
258: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
259: {
260: const PetscInt Nc = dim;
261: PetscInt c;
263: for (c = 0; c < Nc; ++c) f0[c] = u[c];
264: }
266: static void f1_vlap_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
267: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
268: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
269: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])
270: {
271: const PetscInt Nc = dim;
272: PetscInt c, d;
274: for (c = 0; c < Nc; ++c) for (d = 0; d < dim; ++d) f1[c*dim+d] += u_x[c*dim+d];
275: }
277: static void f1_elas_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
278: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
279: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
280: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])
281: {
282: const PetscInt Nc = dim;
283: const PetscReal mu = 1.0;
284: const PetscReal lambda = 1.0;
285: PetscInt c, d;
287: for (c = 0; c < Nc; ++c) {
288: for (d = 0; d < dim; ++d) {
289: f1[c*dim+d] += mu*(u_x[c*dim+d] + u_x[d*dim+c]);
290: f1[c*dim+c] += lambda*u_x[d*dim+d];
291: }
292: }
293: }
295: static void g0_mass_uu(PetscInt dim, PetscInt Nf, PetscInt NfAux,
296: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
297: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
298: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
299: {
300: const PetscInt Nc = dim;
301: PetscInt c;
303: for (c = 0; c < Nc; ++c) g0[c*Nc + c] = 1.0;
304: }
306: static void g3_vlap_uu(PetscInt dim, PetscInt Nf, PetscInt NfAux,
307: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
308: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
309: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])
310: {
311: const PetscInt Nc = dim;
312: PetscInt c, d;
314: for (c = 0; c < Nc; ++c) {
315: for (d = 0; d < dim; ++d) {
316: g3[((c*Nc + c)*dim + d)*dim + d] = 1.0;
317: }
318: }
319: }
321: /*
322: \partial_df \phi_fc g_{fc,gc,df,dg} \partial_dg \phi_gc
324: \partial_df \phi_fc \lambda \delta_{fc,df} \sum_gc \partial_dg \phi_gc \delta_{gc,dg}
325: = \partial_fc \phi_fc \sum_gc \partial_gc \phi_gc
326: */
327: static void g3_elas_uu(PetscInt dim, PetscInt Nf, PetscInt NfAux,
328: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
329: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
330: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])
331: {
332: const PetscInt Nc = dim;
333: const PetscReal mu = 1.0;
334: const PetscReal lambda = 1.0;
335: PetscInt c, d;
337: for (c = 0; c < Nc; ++c) {
338: for (d = 0; d < dim; ++d) {
339: g3[((c*Nc + c)*dim + d)*dim + d] += mu;
340: g3[((c*Nc + d)*dim + d)*dim + c] += mu;
341: g3[((c*Nc + d)*dim + c)*dim + d] += lambda;
342: }
343: }
344: }
346: static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
347: {
348: PetscInt sol = 0, def = 0;
352: options->deform = DEFORM_NONE;
353: options->solType = SOL_VLAP_QUADRATIC;
354: options->useNearNullspace = PETSC_TRUE;
355: PetscStrncpy(options->dmType, DMPLEX, 256);
357: PetscOptionsBegin(comm, "", "Linear Elasticity Problem Options", "DMPLEX");
358: PetscOptionsEList("-deform_type", "Type of domain deformation", "ex17.c", deformTypes, NUM_DEFORM_TYPES, deformTypes[options->deform], &def, NULL);
359: options->deform = (DeformType) def;
360: PetscOptionsEList("-sol_type", "Type of exact solution", "ex17.c", solutionTypes, NUM_SOLUTION_TYPES, solutionTypes[options->solType], &sol, NULL);
361: options->solType = (SolutionType) sol;
362: PetscOptionsBool("-near_nullspace", "Use the rigid body modes as an AMG near nullspace", "ex17.c", options->useNearNullspace, &options->useNearNullspace, NULL);
363: PetscOptionsFList("-dm_type", "Convert DMPlex to another format", "ex17.c", DMList, options->dmType, options->dmType, 256, NULL);
364: PetscOptionsEnd();
365: return(0);
366: }
368: static PetscErrorCode DMPlexDistortGeometry(DM dm)
369: {
370: DM cdm;
371: DMLabel label;
372: Vec coordinates;
373: PetscScalar *coords;
374: PetscReal mid = 0.5;
375: PetscInt cdim, d, vStart, vEnd, v;
379: DMGetCoordinateDM(dm, &cdm);
380: DMGetCoordinateDim(dm, &cdim);
381: DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);
382: DMGetLabel(dm, "marker", &label);
383: DMGetCoordinatesLocal(dm, &coordinates);
384: VecGetArrayWrite(coordinates, &coords);
385: for (v = vStart; v < vEnd; ++v) {
386: PetscScalar *pcoords, shift;
387: PetscInt val;
389: DMLabelGetValue(label, v, &val);
390: if (val >= 0) continue;
391: DMPlexPointLocalRef(cdm, v, coords, &pcoords);
392: shift = 0.2 * PetscAbsScalar(pcoords[0] - mid);
393: shift = PetscRealPart(pcoords[0]) > mid ? shift : -shift;
394: for (d = 1; d < cdim; ++d) pcoords[d] += shift;
395: }
396: VecRestoreArrayWrite(coordinates, &coords);
397: return(0);
398: }
400: static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
401: {
405: DMCreate(comm, dm);
406: DMSetType(*dm, DMPLEX);
407: DMSetFromOptions(*dm);
408: switch (user->deform) {
409: case DEFORM_NONE: break;
410: case DEFORM_SHEAR: DMPlexShearGeometry(*dm, DM_X, NULL);break;
411: case DEFORM_STEP: DMPlexDistortGeometry(*dm);break;
412: default: SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid deformation type: %s (%D)", deformTypes[PetscMin(user->deform, NUM_DEFORM_TYPES)], user->deform);
413: }
414: DMSetApplicationContext(*dm, user);
415: DMViewFromOptions(*dm, NULL, "-dm_view");
416: return(0);
417: }
419: static PetscErrorCode SetupPrimalProblem(DM dm, AppCtx *user)
420: {
421: PetscErrorCode (*exact)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
422: PetscDS ds;
423: PetscWeakForm wf;
424: DMLabel label;
425: PetscInt id, bd;
426: PetscInt dim;
430: DMGetDS(dm, &ds);
431: PetscDSGetWeakForm(ds, &wf);
432: PetscDSGetSpatialDimension(ds, &dim);
433: switch (user->solType) {
434: case SOL_MASS_QUADRATIC:
435: PetscDSSetResidual(ds, 0, f0_mass_u, NULL);
436: PetscDSSetJacobian(ds, 0, 0, g0_mass_uu, NULL, NULL, NULL);
437: PetscWeakFormSetIndexResidual(wf, NULL, 0, 0, 0, 1, f0_mass_quadratic_u, 0, NULL);
438: switch (dim) {
439: case 2: exact = quadratic_2d_u;break;
440: case 3: exact = quadratic_3d_u;break;
441: default: SETERRQ1(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %D", dim);
442: }
443: break;
444: case SOL_VLAP_QUADRATIC:
445: PetscDSSetResidual(ds, 0, f0_vlap_quadratic_u, f1_vlap_u);
446: PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_vlap_uu);
447: switch (dim) {
448: case 2: exact = quadratic_2d_u;break;
449: case 3: exact = quadratic_3d_u;break;
450: default: SETERRQ1(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %D", dim);
451: }
452: break;
453: case SOL_ELAS_QUADRATIC:
454: PetscDSSetResidual(ds, 0, f0_elas_quadratic_u, f1_elas_u);
455: PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu);
456: switch (dim) {
457: case 2: exact = quadratic_2d_u;break;
458: case 3: exact = quadratic_3d_u;break;
459: default: SETERRQ1(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %D", dim);
460: }
461: break;
462: case SOL_VLAP_TRIG:
463: PetscDSSetResidual(ds, 0, f0_vlap_trig_u, f1_vlap_u);
464: PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_vlap_uu);
465: switch (dim) {
466: case 2: exact = trig_2d_u;break;
467: case 3: exact = trig_3d_u;break;
468: default: SETERRQ1(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %D", dim);
469: }
470: break;
471: case SOL_ELAS_TRIG:
472: PetscDSSetResidual(ds, 0, f0_elas_trig_u, f1_elas_u);
473: PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu);
474: switch (dim) {
475: case 2: exact = trig_2d_u;break;
476: case 3: exact = trig_3d_u;break;
477: default: SETERRQ1(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Invalid dimension: %D", dim);
478: }
479: break;
480: case SOL_ELAS_AXIAL_DISP:
481: PetscDSSetResidual(ds, 0, NULL, f1_elas_u);
482: PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu);
483: id = dim == 3 ? 5 : 2;
484: DMGetLabel(dm, "marker", &label);
485: DMAddBoundary(dm, DM_BC_NATURAL, "right", label, 1, &id, 0, 0, NULL, (void (*)(void)) NULL, NULL, user, &bd);
486: PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
487: PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, 0, f0_elas_axial_disp_bd_u, 0, NULL);
488: exact = axial_disp_u;
489: break;
490: case SOL_ELAS_UNIFORM_STRAIN:
491: PetscDSSetResidual(ds, 0, NULL, f1_elas_u);
492: PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_elas_uu);
493: exact = uniform_strain_u;
494: break;
495: default: SETERRQ2(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%D)", solutionTypes[PetscMin(user->solType, NUM_SOLUTION_TYPES)], user->solType);
496: }
497: PetscDSSetExactSolution(ds, 0, exact, user);
498: DMGetLabel(dm, "marker", &label);
499: if (user->solType == SOL_ELAS_AXIAL_DISP) {
500: PetscInt cmp;
502: id = dim == 3 ? 6 : 4;
503: cmp = 0;
504: DMAddBoundary(dm, DM_BC_ESSENTIAL, "left", label, 1, &id, 0, 1, &cmp, (void (*)(void)) zero, NULL, user, NULL);
505: cmp = dim == 3 ? 2 : 1;
506: id = dim == 3 ? 1 : 1;
507: DMAddBoundary(dm, DM_BC_ESSENTIAL, "bottom", label, 1, &id, 0, 1, &cmp, (void (*)(void)) zero, NULL, user, NULL);
508: if (dim == 3) {
509: cmp = 1;
510: id = 3;
511: DMAddBoundary(dm, DM_BC_ESSENTIAL, "front", label, 1, &id, 0, 1, &cmp, (void (*)(void)) zero, NULL, user, NULL);
512: }
513: } else {
514: id = 1;
515: DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall", label, 1, &id, 0, 0, NULL, (void (*)(void)) exact, NULL, user, NULL);
516: }
517: return(0);
518: }
520: static PetscErrorCode CreateElasticityNullSpace(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullspace)
521: {
525: DMPlexCreateRigidBody(dm, origField, nullspace);
526: return(0);
527: }
529: PetscErrorCode SetupFE(DM dm, const char name[], PetscErrorCode (*setup)(DM, AppCtx *), void *ctx)
530: {
531: AppCtx *user = (AppCtx *) ctx;
532: DM cdm = dm;
533: PetscFE fe;
534: char prefix[PETSC_MAX_PATH_LEN];
535: DMPolytopeType ct;
536: PetscBool simplex;
537: PetscInt dim, cStart;
541: /* Create finite element */
542: DMGetDimension(dm, &dim);
543: DMPlexGetHeightStratum(dm, 0, &cStart, NULL);
544: DMPlexGetCellType(dm, cStart, &ct);
545: simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE;
546: PetscSNPrintf(prefix, PETSC_MAX_PATH_LEN, "%s_", name);
547: PetscFECreateDefault(PetscObjectComm((PetscObject) dm), dim, dim, simplex, name ? prefix : NULL, -1, &fe);
548: PetscObjectSetName((PetscObject) fe, name);
549: /* Set discretization and boundary conditions for each mesh */
550: DMSetField(dm, 0, NULL, (PetscObject) fe);
551: DMCreateDS(dm);
552: (*setup)(dm, user);
553: while (cdm) {
554: DMCopyDisc(dm, cdm);
555: if (user->useNearNullspace) {DMSetNearNullSpaceConstructor(cdm, 0, CreateElasticityNullSpace);}
556: /* TODO: Check whether the boundary of coarse meshes is marked */
557: DMGetCoarseDM(cdm, &cdm);
558: }
559: PetscFEDestroy(&fe);
560: return(0);
561: }
563: int main(int argc, char **argv)
564: {
565: DM dm; /* Problem specification */
566: SNES snes; /* Nonlinear solver */
567: Vec u; /* Solutions */
568: AppCtx user; /* User-defined work context */
571: PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr;
572: ProcessOptions(PETSC_COMM_WORLD, &user);
573: /* Primal system */
574: SNESCreate(PETSC_COMM_WORLD, &snes);
575: CreateMesh(PETSC_COMM_WORLD, &user, &dm);
576: SNESSetDM(snes, dm);
577: SetupFE(dm, "displacement", SetupPrimalProblem, &user);
578: DMCreateGlobalVector(dm, &u);
579: VecSet(u, 0.0);
580: PetscObjectSetName((PetscObject) u, "displacement");
581: DMPlexSetSNESLocalFEM(dm, &user, &user, &user);
582: SNESSetFromOptions(snes);
583: DMSNESCheckFromOptions(snes, u);
584: SNESSolve(snes, NULL, u);
585: SNESGetSolution(snes, &u);
586: VecViewFromOptions(u, NULL, "-displacement_view");
587: /* Cleanup */
588: VecDestroy(&u);
589: SNESDestroy(&snes);
590: DMDestroy(&dm);
591: PetscFinalize();
592: return ierr;
593: }
595: /*TEST
597: testset:
598: args: -dm_plex_box_faces 1,1,1
600: test:
601: suffix: 2d_p1_quad_vlap
602: requires: triangle
603: args: -displacement_petscspace_degree 1 -dm_refine 2 -convest_num_refine 3 -snes_convergence_estimate
604: test:
605: suffix: 2d_p2_quad_vlap
606: requires: triangle
607: args: -displacement_petscspace_degree 2 -dm_refine 2 -dmsnes_check .0001
608: test:
609: suffix: 2d_p3_quad_vlap
610: requires: triangle
611: args: -displacement_petscspace_degree 3 -dm_refine 2 -dmsnes_check .0001
612: test:
613: suffix: 2d_q1_quad_vlap
614: args: -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 2 -convest_num_refine 3 -snes_convergence_estimate
615: test:
616: suffix: 2d_q2_quad_vlap
617: args: -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 2 -dmsnes_check .0001
618: test:
619: suffix: 2d_q3_quad_vlap
620: requires: !single
621: args: -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 2 -dmsnes_check .0001
622: test:
623: suffix: 2d_p1_quad_elas
624: requires: triangle
625: args: -sol_type elas_quad -displacement_petscspace_degree 1 -dm_refine 2 -convest_num_refine 3 -snes_convergence_estimate
626: test:
627: suffix: 2d_p2_quad_elas
628: requires: triangle
629: args: -sol_type elas_quad -displacement_petscspace_degree 2 -dmsnes_check .0001
630: test:
631: suffix: 2d_p3_quad_elas
632: requires: triangle
633: args: -sol_type elas_quad -displacement_petscspace_degree 3 -dmsnes_check .0001
634: test:
635: suffix: 2d_q1_quad_elas
636: args: -sol_type elas_quad -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
637: test:
638: suffix: 2d_q1_quad_elas_shear
639: 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
640: test:
641: suffix: 2d_q2_quad_elas
642: args: -sol_type elas_quad -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dmsnes_check .0001
643: test:
644: suffix: 2d_q2_quad_elas_shear
645: args: -sol_type elas_quad -dm_plex_simplex 0 -deform_type shear -displacement_petscspace_degree 2 -dmsnes_check
646: test:
647: suffix: 2d_q3_quad_elas
648: args: -sol_type elas_quad -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dmsnes_check .0001
649: test:
650: suffix: 2d_q3_quad_elas_shear
651: requires: !single
652: args: -sol_type elas_quad -dm_plex_simplex 0 -deform_type shear -displacement_petscspace_degree 3 -dmsnes_check
654: test:
655: suffix: 3d_p1_quad_vlap
656: requires: ctetgen
657: args: -dm_plex_dim 3 -dm_refine 1 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate
658: test:
659: suffix: 3d_p2_quad_vlap
660: requires: ctetgen
661: args: -dm_plex_dim 3 -displacement_petscspace_degree 2 -dm_refine 1 -dmsnes_check .0001
662: test:
663: suffix: 3d_p3_quad_vlap
664: requires: ctetgen
665: args: -dm_plex_dim 3 -displacement_petscspace_degree 3 -dm_refine 0 -dmsnes_check .0001
666: test:
667: suffix: 3d_q1_quad_vlap
668: 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
669: test:
670: suffix: 3d_q2_quad_vlap
671: args: -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 1 -dmsnes_check .0001
672: test:
673: suffix: 3d_q3_quad_vlap
674: args: -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 0 -dmsnes_check .0001
675: test:
676: suffix: 3d_p1_quad_elas
677: requires: ctetgen
678: args: -sol_type elas_quad -dm_plex_dim 3 -dm_refine 1 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate
679: test:
680: suffix: 3d_p2_quad_elas
681: requires: ctetgen
682: args: -sol_type elas_quad -dm_plex_dim 3 -displacement_petscspace_degree 2 -dm_refine 1 -dmsnes_check .0001
683: test:
684: suffix: 3d_p3_quad_elas
685: requires: ctetgen
686: args: -sol_type elas_quad -dm_plex_dim 3 -displacement_petscspace_degree 3 -dm_refine 0 -dmsnes_check .0001
687: test:
688: suffix: 3d_q1_quad_elas
689: 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
690: test:
691: suffix: 3d_q2_quad_elas
692: args: -sol_type elas_quad -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 1 -dmsnes_check .0001
693: test:
694: suffix: 3d_q3_quad_elas
695: requires: !single
696: args: -sol_type elas_quad -dm_plex_dim 3 -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 0 -dmsnes_check .0001
698: test:
699: suffix: 2d_p1_trig_vlap
700: requires: triangle
701: args: -sol_type vlap_trig -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
702: test:
703: suffix: 2d_p2_trig_vlap
704: requires: triangle
705: args: -sol_type vlap_trig -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
706: test:
707: suffix: 2d_p3_trig_vlap
708: requires: triangle
709: args: -sol_type vlap_trig -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
710: test:
711: suffix: 2d_q1_trig_vlap
712: args: -sol_type vlap_trig -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
713: test:
714: suffix: 2d_q2_trig_vlap
715: args: -sol_type vlap_trig -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
716: test:
717: suffix: 2d_q3_trig_vlap
718: args: -sol_type vlap_trig -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
719: test:
720: suffix: 2d_p1_trig_elas
721: requires: triangle
722: args: -sol_type elas_trig -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
723: test:
724: suffix: 2d_p2_trig_elas
725: requires: triangle
726: args: -sol_type elas_trig -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
727: test:
728: suffix: 2d_p3_trig_elas
729: requires: triangle
730: args: -sol_type elas_trig -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
731: test:
732: suffix: 2d_q1_trig_elas
733: args: -sol_type elas_trig -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
734: test:
735: suffix: 2d_q1_trig_elas_shear
736: 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
737: test:
738: suffix: 2d_q2_trig_elas
739: args: -sol_type elas_trig -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
740: test:
741: suffix: 2d_q2_trig_elas_shear
742: 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
743: test:
744: suffix: 2d_q3_trig_elas
745: args: -sol_type elas_trig -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 1 -convest_num_refine 3 -snes_convergence_estimate
746: test:
747: suffix: 2d_q3_trig_elas_shear
748: 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
750: test:
751: suffix: 3d_p1_trig_vlap
752: requires: ctetgen
753: args: -sol_type vlap_trig -dm_plex_dim 3 -dm_refine 1 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate
754: test:
755: suffix: 3d_p2_trig_vlap
756: requires: ctetgen
757: args: -sol_type vlap_trig -dm_plex_dim 3 -displacement_petscspace_degree 2 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate
758: test:
759: suffix: 3d_p3_trig_vlap
760: requires: ctetgen
761: args: -sol_type vlap_trig -dm_plex_dim 3 -displacement_petscspace_degree 3 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate
762: test:
763: suffix: 3d_q1_trig_vlap
764: 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
765: test:
766: suffix: 3d_q2_trig_vlap
767: 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
768: test:
769: suffix: 3d_q3_trig_vlap
770: requires: !__float128
771: 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
772: test:
773: suffix: 3d_p1_trig_elas
774: requires: ctetgen
775: args: -sol_type elas_trig -dm_plex_dim 3 -dm_refine 1 -displacement_petscspace_degree 1 -convest_num_refine 2 -snes_convergence_estimate
776: test:
777: suffix: 3d_p2_trig_elas
778: requires: ctetgen
779: args: -sol_type elas_trig -dm_plex_dim 3 -displacement_petscspace_degree 2 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate
780: test:
781: suffix: 3d_p3_trig_elas
782: requires: ctetgen
783: args: -sol_type elas_trig -dm_plex_dim 3 -displacement_petscspace_degree 3 -dm_refine 0 -convest_num_refine 1 -snes_convergence_estimate
784: test:
785: suffix: 3d_q1_trig_elas
786: 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
787: test:
788: suffix: 3d_q2_trig_elas
789: 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
790: test:
791: suffix: 3d_q3_trig_elas
792: requires: !__float128
793: 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
795: test:
796: suffix: 2d_p1_axial_elas
797: requires: triangle
798: args: -sol_type elas_axial_disp -displacement_petscspace_degree 1 -dm_plex_separate_marker -dm_refine 2 -dmsnes_check .0001 -pc_type lu
799: test:
800: suffix: 2d_p2_axial_elas
801: requires: triangle
802: args: -sol_type elas_axial_disp -displacement_petscspace_degree 2 -dm_plex_separate_marker -dmsnes_check .0001 -pc_type lu
803: test:
804: suffix: 2d_p3_axial_elas
805: requires: triangle
806: args: -sol_type elas_axial_disp -displacement_petscspace_degree 3 -dm_plex_separate_marker -dmsnes_check .0001 -pc_type lu
807: test:
808: suffix: 2d_q1_axial_elas
809: 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
810: test:
811: suffix: 2d_q2_axial_elas
812: args: -sol_type elas_axial_disp -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_plex_separate_marker -dmsnes_check .0001 -pc_type lu
813: test:
814: suffix: 2d_q3_axial_elas
815: args: -sol_type elas_axial_disp -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_plex_separate_marker -dmsnes_check .0001 -pc_type lu
817: test:
818: suffix: 2d_p1_uniform_elas
819: requires: triangle
820: args: -sol_type elas_uniform_strain -displacement_petscspace_degree 1 -dm_refine 2 -dmsnes_check .0001 -pc_type lu
821: test:
822: suffix: 2d_p2_uniform_elas
823: requires: triangle
824: args: -sol_type elas_uniform_strain -displacement_petscspace_degree 2 -dm_refine 2 -dmsnes_check .0001 -pc_type lu
825: test:
826: suffix: 2d_p3_uniform_elas
827: requires: triangle
828: args: -sol_type elas_uniform_strain -displacement_petscspace_degree 3 -dm_refine 2 -dmsnes_check .0001 -pc_type lu
829: test:
830: suffix: 2d_q1_uniform_elas
831: args: -sol_type elas_uniform_strain -dm_plex_simplex 0 -displacement_petscspace_degree 1 -dm_refine 2 -dmsnes_check .0001 -pc_type lu
832: test:
833: suffix: 2d_q2_uniform_elas
834: requires: !single
835: args: -sol_type elas_uniform_strain -dm_plex_simplex 0 -displacement_petscspace_degree 2 -dm_refine 2 -dmsnes_check .0001 -pc_type lu
836: test:
837: suffix: 2d_q3_uniform_elas
838: requires: !single
839: args: -sol_type elas_uniform_strain -dm_plex_simplex 0 -displacement_petscspace_degree 3 -dm_refine 2 -dmsnes_check .0001 -pc_type lu
840: test:
841: suffix: 2d_p1_uniform_elas_step
842: requires: triangle
843: args: -sol_type elas_uniform_strain -deform_type step -displacement_petscspace_degree 1 -dm_refine 2 -dmsnes_check .0001 -pc_type lu
845: testset:
846: args: -dm_plex_simplex 0 -dm_plex_box_faces 3,3 -deform_type step -displacement_petscspace_degree 1 -dmsnes_check .0001 -pc_type lu
848: test:
849: suffix: 2d_q1_uniform_elas_step
850: args: -sol_type elas_uniform_strain -dm_refine 2
851: test:
852: suffix: 2d_q1_quad_vlap_step
853: args:
854: test:
855: suffix: 2d_q2_quad_vlap_step
856: args: -displacement_petscspace_degree 2
857: test:
858: suffix: 2d_q1_quad_mass_step
859: args: -sol_type mass_quad
861: TEST*/