xref: /petsc/src/ts/tutorials/ex53.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
165876a83SMatthew G. Knepley static char help[] = "Time dependent Biot Poroelasticity problem with finite elements.\n\
265876a83SMatthew G. Knepley We solve three field, quasi-static poroelasticity in a rectangular\n\
365876a83SMatthew G. Knepley domain, using a parallel unstructured mesh (DMPLEX) to discretize it.\n\
465876a83SMatthew G. Knepley Contributed by: Robert Walker <rwalker6@buffalo.edu>\n\n\n";
565876a83SMatthew G. Knepley 
665876a83SMatthew G. Knepley #include <petscdmplex.h>
765876a83SMatthew G. Knepley #include <petscsnes.h>
865876a83SMatthew G. Knepley #include <petscts.h>
965876a83SMatthew G. Knepley #include <petscds.h>
1065876a83SMatthew G. Knepley #include <petscbag.h>
1165876a83SMatthew G. Knepley 
1265876a83SMatthew G. Knepley #include <petsc/private/tsimpl.h>
1365876a83SMatthew G. Knepley 
1465876a83SMatthew G. Knepley /* This presentation of poroelasticity is taken from
1565876a83SMatthew G. Knepley 
1665876a83SMatthew G. Knepley @book{Cheng2016,
1765876a83SMatthew G. Knepley   title={Poroelasticity},
1865876a83SMatthew G. Knepley   author={Cheng, Alexander H-D},
1965876a83SMatthew G. Knepley   volume={27},
2065876a83SMatthew G. Knepley   year={2016},
2165876a83SMatthew G. Knepley   publisher={Springer}
2265876a83SMatthew G. Knepley }
2365876a83SMatthew G. Knepley 
2465876a83SMatthew G. Knepley For visualization, use
2565876a83SMatthew G. Knepley 
2665876a83SMatthew G. Knepley   -dm_view hdf5:${PETSC_DIR}/sol.h5 -monitor_solution hdf5:${PETSC_DIR}/sol.h5::append
2765876a83SMatthew G. Knepley 
2865876a83SMatthew G. Knepley The weak form would then be, using test function $(v, q, \tau)$,
2965876a83SMatthew G. Knepley 
3065876a83SMatthew G. Knepley             (q, \frac{1}{M} \frac{dp}{dt}) + (q, \alpha \frac{d\varepsilon}{dt}) + (\nabla q, \kappa \nabla p) = (q, g)
3165876a83SMatthew G. Knepley  -(\nabla v, 2 G \epsilon) - (\nabla\cdot v, \frac{2 G \nu}{1 - 2\nu} \varepsilon) + \alpha (\nabla\cdot v, p) = (v, f)
3265876a83SMatthew G. Knepley                                                                           (\tau, \nabla \cdot u - \varepsilon) = 0
3365876a83SMatthew G. Knepley */
3465876a83SMatthew G. Knepley 
35*9371c9d4SSatish Balay typedef enum {
36*9371c9d4SSatish Balay   SOL_QUADRATIC_LINEAR,
37*9371c9d4SSatish Balay   SOL_QUADRATIC_TRIG,
38*9371c9d4SSatish Balay   SOL_TRIG_LINEAR,
39*9371c9d4SSatish Balay   SOL_TERZAGHI,
40*9371c9d4SSatish Balay   SOL_MANDEL,
41*9371c9d4SSatish Balay   SOL_CRYER,
42*9371c9d4SSatish Balay   NUM_SOLUTION_TYPES
43*9371c9d4SSatish Balay } SolutionType;
4465876a83SMatthew G. Knepley const char *solutionTypes[NUM_SOLUTION_TYPES + 1] = {"quadratic_linear", "quadratic_trig", "trig_linear", "terzaghi", "mandel", "cryer", "unknown"};
4565876a83SMatthew G. Knepley 
4665876a83SMatthew G. Knepley typedef struct {
4765876a83SMatthew G. Knepley   PetscScalar mu;    /* shear modulus */
4865876a83SMatthew G. Knepley   PetscScalar K_u;   /* undrained bulk modulus */
4965876a83SMatthew G. Knepley   PetscScalar alpha; /* Biot effective stress coefficient */
5065876a83SMatthew G. Knepley   PetscScalar M;     /* Biot modulus */
5165876a83SMatthew G. Knepley   PetscScalar k;     /* (isotropic) permeability */
5265876a83SMatthew G. Knepley   PetscScalar mu_f;  /* fluid dynamic viscosity */
5365876a83SMatthew G. Knepley   PetscScalar P_0;   /* magnitude of vertical stress */
5465876a83SMatthew G. Knepley } Parameter;
5565876a83SMatthew G. Knepley 
5665876a83SMatthew G. Knepley typedef struct {
5765876a83SMatthew G. Knepley   /* Domain and mesh definition */
5830602db0SMatthew G. Knepley   PetscReal    xmin[3]; /* Lower left bottom corner of bounding box */
5930602db0SMatthew G. Knepley   PetscReal    xmax[3]; /* Upper right top corner of bounding box */
6065876a83SMatthew G. Knepley   /* Problem definition */
6165876a83SMatthew G. Knepley   SolutionType solType;   /* Type of exact solution */
6265876a83SMatthew G. Knepley   PetscBag     bag;       /* Problem parameters */
6365876a83SMatthew G. Knepley   PetscReal    t_r;       /* Relaxation time: 4 L^2 / c */
6424b15d09SMatthew G. Knepley   PetscReal    dtInitial; /* Override the choice for first timestep */
6565876a83SMatthew G. Knepley   /* Exact solution terms */
6665876a83SMatthew G. Knepley   PetscInt     niter;     /* Number of series term iterations in exact solutions */
6765876a83SMatthew G. Knepley   PetscReal    eps;       /* Precision value for root finding */
6865876a83SMatthew G. Knepley   PetscReal   *zeroArray; /* Array of root locations */
6965876a83SMatthew G. Knepley } AppCtx;
7065876a83SMatthew G. Knepley 
71*9371c9d4SSatish Balay static PetscErrorCode zero(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
7265876a83SMatthew G. Knepley   PetscInt c;
7365876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) u[c] = 0.0;
7465876a83SMatthew G. Knepley   return 0;
7565876a83SMatthew G. Knepley }
7665876a83SMatthew G. Knepley 
7765876a83SMatthew G. Knepley /* Quadratic space and linear time solution
7865876a83SMatthew G. Knepley 
7965876a83SMatthew G. Knepley   2D:
8065876a83SMatthew G. Knepley   u = x^2
8165876a83SMatthew G. Knepley   v = y^2 - 2xy
8265876a83SMatthew G. Knepley   p = (x + y) t
8365876a83SMatthew G. Knepley   e = 2y
8465876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha t, alpha t>
8565876a83SMatthew G. Knepley   g = 0
8665876a83SMatthew G. Knepley   \epsilon = / 2x     -y    \
8765876a83SMatthew G. Knepley              \ -y   2y - 2x /
8865876a83SMatthew G. Knepley   Tr(\epsilon) = e = div u = 2y
8965876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
9065876a83SMatthew G. Knepley     = 2 G < 2-1, 2 > + \lambda <0, 2> - alpha <t, t>
9165876a83SMatthew G. Knepley     = <2 G, 4 G + 2 \lambda> - <alpha t, alpha t>
9265876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
9365876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
9465876a83SMatthew G. Knepley     = (x + y)/M
9565876a83SMatthew G. Knepley 
9665876a83SMatthew G. Knepley   3D:
9765876a83SMatthew G. Knepley   u = x^2
9865876a83SMatthew G. Knepley   v = y^2 - 2xy
9965876a83SMatthew G. Knepley   w = z^2 - 2yz
10065876a83SMatthew G. Knepley   p = (x + y + z) t
10165876a83SMatthew G. Knepley   e = 2z
10265876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha t, alpha t, alpha t>
10365876a83SMatthew G. Knepley   g = 0
10465876a83SMatthew G. Knepley   \varepsilon = / 2x     -y       0   \
10565876a83SMatthew G. Knepley                 | -y   2y - 2x   -z   |
10665876a83SMatthew G. Knepley                 \  0     -z    2z - 2y/
10765876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2z
10865876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
10965876a83SMatthew G. Knepley     = 2 G < 2-1, 2-1, 2 > + \lambda <0, 0, 2> - alpha <t, t, t>
11065876a83SMatthew G. Knepley     = <2 G, 2G, 4 G + 2 \lambda> - <alpha t, alpha t, alpha t>
11165876a83SMatthew G. Knepley */
112*9371c9d4SSatish Balay static PetscErrorCode quadratic_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
11365876a83SMatthew G. Knepley   PetscInt d;
11465876a83SMatthew G. Knepley 
115*9371c9d4SSatish Balay   for (d = 0; d < dim; ++d) { u[d] = PetscSqr(x[d]) - (d > 0 ? 2.0 * x[d - 1] * x[d] : 0.0); }
11665876a83SMatthew G. Knepley   return 0;
11765876a83SMatthew G. Knepley }
11865876a83SMatthew G. Knepley 
119*9371c9d4SSatish Balay static PetscErrorCode linear_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
12065876a83SMatthew G. Knepley   u[0] = 2.0 * x[dim - 1];
12165876a83SMatthew G. Knepley   return 0;
12265876a83SMatthew G. Knepley }
12365876a83SMatthew G. Knepley 
124*9371c9d4SSatish Balay static PetscErrorCode linear_linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
12565876a83SMatthew G. Knepley   PetscReal sum = 0.0;
12665876a83SMatthew G. Knepley   PetscInt  d;
12765876a83SMatthew G. Knepley 
12865876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
12965876a83SMatthew G. Knepley   u[0] = sum * time;
13065876a83SMatthew G. Knepley   return 0;
13165876a83SMatthew G. Knepley }
13265876a83SMatthew G. Knepley 
133*9371c9d4SSatish Balay static PetscErrorCode linear_linear_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
13465876a83SMatthew G. Knepley   PetscReal sum = 0.0;
13565876a83SMatthew G. Knepley   PetscInt  d;
13665876a83SMatthew G. Knepley 
13765876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
13865876a83SMatthew G. Knepley   u[0] = sum;
13965876a83SMatthew G. Knepley   return 0;
14065876a83SMatthew G. Knepley }
14165876a83SMatthew G. Knepley 
142*9371c9d4SSatish Balay static void f0_quadratic_linear_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[]) {
14365876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
14465876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
14565876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
14665876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
14765876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
14865876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
14965876a83SMatthew G. Knepley   PetscInt        d;
15065876a83SMatthew G. Knepley 
151*9371c9d4SSatish Balay   for (d = 0; d < dim - 1; ++d) { f0[d] -= 2.0 * G - alpha * t; }
15265876a83SMatthew G. Knepley   f0[dim - 1] -= 2.0 * lambda + 4.0 * G - alpha * t;
15365876a83SMatthew G. Knepley }
15465876a83SMatthew G. Knepley 
155*9371c9d4SSatish Balay static void f0_quadratic_linear_p(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[]) {
15665876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
15765876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
15865876a83SMatthew G. Knepley   PetscReal       sum   = 0.0;
15965876a83SMatthew G. Knepley   PetscInt        d;
16065876a83SMatthew G. Knepley 
16165876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
16265876a83SMatthew G. Knepley   f0[0] += u_t ? alpha * u_t[uOff[1]] : 0.0;
16365876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]] / M : 0.0;
16465876a83SMatthew G. Knepley   f0[0] -= sum / M;
16565876a83SMatthew G. Knepley }
16665876a83SMatthew G. Knepley 
16765876a83SMatthew G. Knepley /* Quadratic space and trigonometric time solution
16865876a83SMatthew G. Knepley 
16965876a83SMatthew G. Knepley   2D:
17065876a83SMatthew G. Knepley   u = x^2
17165876a83SMatthew G. Knepley   v = y^2 - 2xy
17265876a83SMatthew G. Knepley   p = (x + y) cos(t)
17365876a83SMatthew G. Knepley   e = 2y
17465876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha cos(t), alpha cos(t)>
17565876a83SMatthew G. Knepley   g = 0
17665876a83SMatthew G. Knepley   \epsilon = / 2x     -y    \
17765876a83SMatthew G. Knepley              \ -y   2y - 2x /
17865876a83SMatthew G. Knepley   Tr(\epsilon) = e = div u = 2y
17965876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
18065876a83SMatthew G. Knepley     = 2 G < 2-1, 2 > + \lambda <0, 2> - alpha <cos(t), cos(t)>
18165876a83SMatthew G. Knepley     = <2 G, 4 G + 2 \lambda> - <alpha cos(t), alpha cos(t)>
18265876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
18365876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
18465876a83SMatthew G. Knepley     = -(x + y)/M sin(t)
18565876a83SMatthew G. Knepley 
18665876a83SMatthew G. Knepley   3D:
18765876a83SMatthew G. Knepley   u = x^2
18865876a83SMatthew G. Knepley   v = y^2 - 2xy
18965876a83SMatthew G. Knepley   w = z^2 - 2yz
19065876a83SMatthew G. Knepley   p = (x + y + z) cos(t)
19165876a83SMatthew G. Knepley   e = 2z
19265876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha cos(t), alpha cos(t), alpha cos(t)>
19365876a83SMatthew G. Knepley   g = 0
19465876a83SMatthew G. Knepley   \varepsilon = / 2x     -y       0   \
19565876a83SMatthew G. Knepley                 | -y   2y - 2x   -z   |
19665876a83SMatthew G. Knepley                 \  0     -z    2z - 2y/
19765876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2z
19865876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
19965876a83SMatthew G. Knepley     = 2 G < 2-1, 2-1, 2 > + \lambda <0, 0, 2> - alpha <cos(t), cos(t), cos(t)>
20065876a83SMatthew G. Knepley     = <2 G, 2G, 4 G + 2 \lambda> - <alpha cos(t), alpha cos(t), alpha cos(t)>
20165876a83SMatthew G. Knepley */
202*9371c9d4SSatish Balay static PetscErrorCode linear_trig_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
20365876a83SMatthew G. Knepley   PetscReal sum = 0.0;
20465876a83SMatthew G. Knepley   PetscInt  d;
20565876a83SMatthew G. Knepley 
20665876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
20765876a83SMatthew G. Knepley   u[0] = sum * PetscCosReal(time);
20865876a83SMatthew G. Knepley   return 0;
20965876a83SMatthew G. Knepley }
21065876a83SMatthew G. Knepley 
211*9371c9d4SSatish Balay static PetscErrorCode linear_trig_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
21265876a83SMatthew G. Knepley   PetscReal sum = 0.0;
21365876a83SMatthew G. Knepley   PetscInt  d;
21465876a83SMatthew G. Knepley 
21565876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
21665876a83SMatthew G. Knepley   u[0] = -sum * PetscSinReal(time);
21765876a83SMatthew G. Knepley   return 0;
21865876a83SMatthew G. Knepley }
21965876a83SMatthew G. Knepley 
220*9371c9d4SSatish Balay static void f0_quadratic_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[]) {
22165876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
22265876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
22365876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
22465876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
22565876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
22665876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
22765876a83SMatthew G. Knepley   PetscInt        d;
22865876a83SMatthew G. Knepley 
229*9371c9d4SSatish Balay   for (d = 0; d < dim - 1; ++d) { f0[d] -= 2.0 * G - alpha * PetscCosReal(t); }
23065876a83SMatthew G. Knepley   f0[dim - 1] -= 2.0 * lambda + 4.0 * G - alpha * PetscCosReal(t);
23165876a83SMatthew G. Knepley }
23265876a83SMatthew G. Knepley 
233*9371c9d4SSatish Balay static void f0_quadratic_trig_p(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[]) {
23465876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
23565876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
23665876a83SMatthew G. Knepley   PetscReal       sum   = 0.0;
23765876a83SMatthew G. Knepley   PetscInt        d;
23865876a83SMatthew G. Knepley 
23965876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
24065876a83SMatthew G. Knepley 
24165876a83SMatthew G. Knepley   f0[0] += u_t ? alpha * u_t[uOff[1]] : 0.0;
24265876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]] / M : 0.0;
24365876a83SMatthew G. Knepley   f0[0] += PetscSinReal(t) * sum / M;
24465876a83SMatthew G. Knepley }
24565876a83SMatthew G. Knepley 
24665876a83SMatthew G. Knepley /* Trigonometric space and linear time solution
24765876a83SMatthew G. Knepley 
24865876a83SMatthew G. Knepley u = sin(2 pi x)
24965876a83SMatthew G. Knepley v = sin(2 pi y) - 2xy
25065876a83SMatthew G. Knepley \varepsilon = / 2 pi cos(2 pi x)             -y        \
25165876a83SMatthew G. Knepley               \      -y          2 pi cos(2 pi y) - 2x /
25265876a83SMatthew G. Knepley Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
25365876a83SMatthew G. Knepley div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
25465876a83SMatthew G. Knepley   = \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) >
25565876a83SMatthew G. Knepley   = \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) >
25665876a83SMatthew G. Knepley 
25765876a83SMatthew G. Knepley   2D:
25865876a83SMatthew G. Knepley   u = sin(2 pi x)
25965876a83SMatthew G. Knepley   v = sin(2 pi y) - 2xy
26065876a83SMatthew G. Knepley   p = (cos(2 pi x) + cos(2 pi y)) t
26165876a83SMatthew G. Knepley   e = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
26265876a83SMatthew G. Knepley   f = < -4 pi^2 sin(2 pi x) (2 G + lambda) - (2 G - 2 lambda), -4 pi^2 sin(2 pi y) (2G + lambda) > + 2 pi alpha t <sin(2 pi x), sin(2 pi y)>
26365876a83SMatthew G. Knepley   g = 0
26465876a83SMatthew G. Knepley   \varepsilon = / 2 pi cos(2 pi x)             -y        \
26565876a83SMatthew G. Knepley                 \      -y          2 pi cos(2 pi y) - 2x /
26665876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
26765876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
26865876a83SMatthew G. Knepley     = 2 G < -4 pi^2 sin(2 pi x) - 1, -4 pi^2 sin(2 pi y) > + \lambda <-4 pi^2 sin(2 pi x) - 2, -4 pi^2 sin(2 pi y)> - alpha <-2 pi sin(2 pi x) t, -2 pi sin(2 pi y) t>
26965876a83SMatthew G. Knepley     = < -4 pi^2 sin(2 pi x) (2 G + lambda) - (2 G + 2 lambda), -4 pi^2 sin(2 pi y) (2G + lambda) > + 2 pi alpha t <sin(2 pi x), sin(2 pi y)>
27065876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
27165876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
27265876a83SMatthew G. Knepley     = (cos(2 pi x) + cos(2 pi y))/M - 4 pi^2 \kappa (cos(2 pi x) + cos(2 pi y)) t
27365876a83SMatthew G. Knepley 
27465876a83SMatthew G. Knepley   3D:
27565876a83SMatthew G. Knepley   u = sin(2 pi x)
27665876a83SMatthew G. Knepley   v = sin(2 pi y) - 2xy
27765876a83SMatthew G. Knepley   v = sin(2 pi y) - 2yz
27865876a83SMatthew G. Knepley   p = (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) t
27965876a83SMatthew G. Knepley   e = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2y
28065876a83SMatthew G. Knepley   f = < -4 pi^2 sin(2 pi x) (2 G + lambda) - (2 G + 2 lambda),  -4 pi^2 sin(2 pi y) (2 G + lambda) - (2 G + 2 lambda), -4 pi^2 sin(2 pi z) (2G + lambda) > + 2 pi alpha t <sin(2 pi x), sin(2 pi y), , sin(2 pi z)>
28165876a83SMatthew G. Knepley   g = 0
28265876a83SMatthew G. Knepley   \varepsilon = / 2 pi cos(2 pi x)            -y                     0         \
28365876a83SMatthew G. Knepley                 |         -y       2 pi cos(2 pi y) - 2x            -z         |
28465876a83SMatthew G. Knepley                 \          0                  -z         2 pi cos(2 pi z) - 2y /
28565876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2 y
28665876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
28765876a83SMatthew G. Knepley     = 2 G < -4 pi^2 sin(2 pi x) - 1, -4 pi^2 sin(2 pi y) - 1, -4 pi^2 sin(2 pi z) > + \lambda <-4 pi^2 sin(2 pi x) - 2, 4 pi^2 sin(2 pi y) - 2, -4 pi^2 sin(2 pi y)> - alpha <-2 pi sin(2 pi x) t, -2 pi sin(2 pi y) t, -2 pi sin(2 pi z) t>
28865876a83SMatthew G. Knepley     = < -4 pi^2 sin(2 pi x) (2 G + lambda) - (2 G + 2 lambda),  -4 pi^2 sin(2 pi y) (2 G + lambda) - (2 G + 2 lambda), -4 pi^2 sin(2 pi z) (2G + lambda) > + 2 pi alpha t <sin(2 pi x), sin(2 pi y), , sin(2 pi z)>
28965876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
29065876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
29165876a83SMatthew G. Knepley     = (cos(2 pi x) + cos(2 pi y) + cos(2 pi z))/M - 4 pi^2 \kappa (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) t
29265876a83SMatthew G. Knepley */
293*9371c9d4SSatish Balay static PetscErrorCode trig_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
29465876a83SMatthew G. Knepley   PetscInt d;
29565876a83SMatthew G. Knepley 
296*9371c9d4SSatish Balay   for (d = 0; d < dim; ++d) { u[d] = PetscSinReal(2. * PETSC_PI * x[d]) - (d > 0 ? 2.0 * x[d - 1] * x[d] : 0.0); }
29765876a83SMatthew G. Knepley   return 0;
29865876a83SMatthew G. Knepley }
29965876a83SMatthew G. Knepley 
300*9371c9d4SSatish Balay static PetscErrorCode trig_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
30165876a83SMatthew G. Knepley   PetscReal sum = 0.0;
30265876a83SMatthew G. Knepley   PetscInt  d;
30365876a83SMatthew G. Knepley 
30465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += 2. * PETSC_PI * PetscCosReal(2. * PETSC_PI * x[d]) - (d < dim - 1 ? 2. * x[d] : 0.0);
30565876a83SMatthew G. Knepley   u[0] = sum;
30665876a83SMatthew G. Knepley   return 0;
30765876a83SMatthew G. Knepley }
30865876a83SMatthew G. Knepley 
309*9371c9d4SSatish Balay static PetscErrorCode trig_linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
31065876a83SMatthew G. Knepley   PetscReal sum = 0.0;
31165876a83SMatthew G. Knepley   PetscInt  d;
31265876a83SMatthew G. Knepley 
31365876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2. * PETSC_PI * x[d]);
31465876a83SMatthew G. Knepley   u[0] = sum * time;
31565876a83SMatthew G. Knepley   return 0;
31665876a83SMatthew G. Knepley }
31765876a83SMatthew G. Knepley 
318*9371c9d4SSatish Balay static PetscErrorCode trig_linear_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
31965876a83SMatthew G. Knepley   PetscReal sum = 0.0;
32065876a83SMatthew G. Knepley   PetscInt  d;
32165876a83SMatthew G. Knepley 
32265876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2. * PETSC_PI * x[d]);
32365876a83SMatthew G. Knepley   u[0] = sum;
32465876a83SMatthew G. Knepley   return 0;
32565876a83SMatthew G. Knepley }
32665876a83SMatthew G. Knepley 
327*9371c9d4SSatish Balay static void f0_trig_linear_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[]) {
32865876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
32965876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
33065876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
33165876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
33265876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
33365876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
33465876a83SMatthew G. Knepley   PetscInt        d;
33565876a83SMatthew G. Knepley 
336*9371c9d4SSatish Balay   for (d = 0; d < dim - 1; ++d) { f0[d] += PetscSqr(2. * PETSC_PI) * PetscSinReal(2. * PETSC_PI * x[d]) * (2. * G + lambda) + 2.0 * (G + lambda) - 2. * PETSC_PI * alpha * PetscSinReal(2. * PETSC_PI * x[d]) * t; }
33765876a83SMatthew G. Knepley   f0[dim - 1] += PetscSqr(2. * PETSC_PI) * PetscSinReal(2. * PETSC_PI * x[dim - 1]) * (2. * G + lambda) - 2. * PETSC_PI * alpha * PetscSinReal(2. * PETSC_PI * x[dim - 1]) * t;
33865876a83SMatthew G. Knepley }
33965876a83SMatthew G. Knepley 
340*9371c9d4SSatish Balay static void f0_trig_linear_p(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[]) {
34165876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
34265876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
34365876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
34465876a83SMatthew G. Knepley   PetscReal       sum   = 0.0;
34565876a83SMatthew G. Knepley   PetscInt        d;
34665876a83SMatthew G. Knepley 
34765876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2. * PETSC_PI * x[d]);
34865876a83SMatthew G. Knepley   f0[0] += u_t ? alpha * u_t[uOff[1]] : 0.0;
34965876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]] / M : 0.0;
35065876a83SMatthew G. Knepley   f0[0] -= sum / M - 4 * PetscSqr(PETSC_PI) * kappa * sum * t;
35165876a83SMatthew G. Knepley }
35265876a83SMatthew G. Knepley 
35365876a83SMatthew G. Knepley /* Terzaghi Solutions */
35465876a83SMatthew G. Knepley /* The analytical solutions given here are drawn from chapter 7, section 3, */
35565876a83SMatthew G. Knepley /* "One-Dimensional Consolidation Problem," from Poroelasticity, by Cheng.  */
356*9371c9d4SSatish Balay static PetscErrorCode terzaghi_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
35765876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
35865876a83SMatthew G. Knepley   Parameter *param;
35965876a83SMatthew G. Knepley 
3609566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
36165876a83SMatthew G. Knepley   if (time <= 0.0) {
36265876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                                        /* -  */
36365876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                                          /* Pa */
36465876a83SMatthew G. Knepley     PetscScalar M     = param->M;                                            /* Pa */
36565876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                                           /* Pa */
36665876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                                          /* Pa */
36765876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
36865876a83SMatthew G. Knepley     PetscScalar eta   = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
36965876a83SMatthew G. Knepley     PetscScalar S     = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
37065876a83SMatthew G. Knepley 
37165876a83SMatthew G. Knepley     u[0] = ((P_0 * eta) / (G * S));
37265876a83SMatthew G. Knepley   } else {
37365876a83SMatthew G. Knepley     u[0] = 0.0;
37465876a83SMatthew G. Knepley   }
37565876a83SMatthew G. Knepley   return 0;
37665876a83SMatthew G. Knepley }
37765876a83SMatthew G. Knepley 
378*9371c9d4SSatish Balay static PetscErrorCode terzaghi_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
37965876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
38065876a83SMatthew G. Knepley   Parameter *param;
38165876a83SMatthew G. Knepley 
3829566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
38365876a83SMatthew G. Knepley   {
38465876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                                      /* Pa */
38565876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                                       /* Pa */
38665876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                                      /* Pa */
38730602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1];                   /* m */
38865876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
38965876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                        /* - */
39065876a83SMatthew G. Knepley 
39165876a83SMatthew G. Knepley     u[0] = 0.0;
39265876a83SMatthew G. Knepley     u[1] = ((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - zstar);
39365876a83SMatthew G. Knepley   }
39465876a83SMatthew G. Knepley   return 0;
39565876a83SMatthew G. Knepley }
39665876a83SMatthew G. Knepley 
397*9371c9d4SSatish Balay static PetscErrorCode terzaghi_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
39865876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
39965876a83SMatthew G. Knepley   Parameter *param;
40065876a83SMatthew G. Knepley 
4019566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
40265876a83SMatthew G. Knepley   {
40365876a83SMatthew G. Knepley     PetscScalar K_u  = param->K_u;                                      /* Pa */
40465876a83SMatthew G. Knepley     PetscScalar G    = param->mu;                                       /* Pa */
40565876a83SMatthew G. Knepley     PetscScalar P_0  = param->P_0;                                      /* Pa */
40665876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
40765876a83SMatthew G. Knepley 
40865876a83SMatthew G. Knepley     u[0] = -(P_0 * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u));
40965876a83SMatthew G. Knepley   }
41065876a83SMatthew G. Knepley   return 0;
41165876a83SMatthew G. Knepley }
41265876a83SMatthew G. Knepley 
413*9371c9d4SSatish Balay static PetscErrorCode terzaghi_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
41465876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
41565876a83SMatthew G. Knepley   Parameter *param;
41665876a83SMatthew G. Knepley 
4179566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
41865876a83SMatthew G. Knepley   if (time < 0.0) {
4199566063dSJacob Faibussowitsch     PetscCall(terzaghi_initial_u(dim, time, x, Nc, u, ctx));
42065876a83SMatthew G. Knepley   } else {
42165876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
42265876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
42365876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
42465876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
42565876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
42665876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
42730602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
42865876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
42965876a83SMatthew G. Knepley 
43065876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
43165876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
43265876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
43365876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
43465876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
43565876a83SMatthew G. Knepley 
43665876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
43765876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
43865876a83SMatthew G. Knepley     PetscScalar F2    = 0.0;
43965876a83SMatthew G. Knepley 
44065876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
441*9371c9d4SSatish Balay       if (m % 2 == 1) { F2 += (8.0 / PetscSqr(m * PETSC_PI)) * PetscCosReal(0.5 * m * PETSC_PI * zstar) * (1.0 - PetscExpReal(-PetscSqr(m * PETSC_PI) * tstar)); }
44265876a83SMatthew G. Knepley     }
44365876a83SMatthew G. Knepley     u[0] = 0.0;
44465876a83SMatthew G. Knepley     u[1] = ((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - zstar) + ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * F2; /* m */
44565876a83SMatthew G. Knepley   }
44665876a83SMatthew G. Knepley   return 0;
44765876a83SMatthew G. Knepley }
44865876a83SMatthew G. Knepley 
449*9371c9d4SSatish Balay static PetscErrorCode terzaghi_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
45065876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
45165876a83SMatthew G. Knepley   Parameter *param;
45265876a83SMatthew G. Knepley 
4539566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
45465876a83SMatthew G. Knepley   if (time < 0.0) {
4559566063dSJacob Faibussowitsch     PetscCall(terzaghi_initial_eps(dim, time, x, Nc, u, ctx));
45665876a83SMatthew G. Knepley   } else {
45765876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
45865876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
45965876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
46065876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
46165876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
46265876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
46330602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
46465876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
46565876a83SMatthew G. Knepley 
46665876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
46765876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
46865876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
46965876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
47065876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
47165876a83SMatthew G. Knepley 
47265876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
47365876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
47465876a83SMatthew G. Knepley     PetscScalar F2_z  = 0.0;
47565876a83SMatthew G. Knepley 
47665876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
477*9371c9d4SSatish Balay       if (m % 2 == 1) { F2_z += (-4.0 / (m * PETSC_PI * L)) * PetscSinReal(0.5 * m * PETSC_PI * zstar) * (1.0 - PetscExpReal(-PetscSqr(m * PETSC_PI) * tstar)); }
47865876a83SMatthew G. Knepley     }
47965876a83SMatthew G. Knepley     u[0] = -((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u) * L)) + ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * F2_z; /* - */
48065876a83SMatthew G. Knepley   }
48165876a83SMatthew G. Knepley   return 0;
48265876a83SMatthew G. Knepley }
48365876a83SMatthew G. Knepley 
48465876a83SMatthew G. Knepley // Pressure
485*9371c9d4SSatish Balay static PetscErrorCode terzaghi_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
48665876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
48765876a83SMatthew G. Knepley   Parameter *param;
48865876a83SMatthew G. Knepley 
4899566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
49065876a83SMatthew G. Knepley   if (time <= 0.0) {
4919566063dSJacob Faibussowitsch     PetscCall(terzaghi_drainage_pressure(dim, time, x, Nc, u, ctx));
49265876a83SMatthew G. Knepley   } else {
49365876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
49465876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
49565876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
49665876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
49765876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
49865876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
49930602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
50065876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
50165876a83SMatthew G. Knepley 
50265876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
50365876a83SMatthew G. Knepley     PetscScalar eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
50465876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
50565876a83SMatthew G. Knepley     PetscScalar c   = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
50665876a83SMatthew G. Knepley 
50765876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
50865876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
50965876a83SMatthew G. Knepley     PetscScalar F1    = 0.0;
51065876a83SMatthew G. Knepley 
51163a3b9bcSJacob Faibussowitsch     PetscCheck(PetscAbsScalar((1 / M + (alpha * eta) / G) - S) <= 1.0e-10, PETSC_COMM_SELF, PETSC_ERR_PLIB, "S %g != check %g", (double)PetscAbsScalar(S), (double)PetscAbsScalar(1 / M + (alpha * eta) / G));
51265876a83SMatthew G. Knepley 
51365876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
514*9371c9d4SSatish Balay       if (m % 2 == 1) { F1 += (4.0 / (m * PETSC_PI)) * PetscSinReal(0.5 * m * PETSC_PI * zstar) * PetscExpReal(-PetscSqr(m * PETSC_PI) * tstar); }
51565876a83SMatthew G. Knepley     }
51665876a83SMatthew G. Knepley     u[0] = ((P_0 * eta) / (G * S)) * F1; /* Pa */
51765876a83SMatthew G. Knepley   }
51865876a83SMatthew G. Knepley   return 0;
51965876a83SMatthew G. Knepley }
52065876a83SMatthew G. Knepley 
521*9371c9d4SSatish Balay static PetscErrorCode terzaghi_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
52265876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
52365876a83SMatthew G. Knepley   Parameter *param;
52465876a83SMatthew G. Knepley 
5259566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
52665876a83SMatthew G. Knepley   if (time <= 0.0) {
52765876a83SMatthew G. Knepley     u[0] = 0.0;
52865876a83SMatthew G. Knepley     u[1] = 0.0;
52965876a83SMatthew G. Knepley   } else {
53065876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
53165876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
53265876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
53365876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
53465876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
53565876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
53630602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
53765876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
53865876a83SMatthew G. Knepley 
53965876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
54065876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
54165876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
54265876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
54365876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
54465876a83SMatthew G. Knepley 
54565876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
54665876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
54765876a83SMatthew G. Knepley     PetscScalar F2_t  = 0.0;
54865876a83SMatthew G. Knepley 
54965876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
550*9371c9d4SSatish Balay       if (m % 2 == 1) { F2_t += (2.0 * c / PetscSqr(L)) * PetscCosReal(0.5 * m * PETSC_PI * zstar) * PetscExpReal(-PetscSqr(m * PETSC_PI) * tstar); }
55165876a83SMatthew G. Knepley     }
55265876a83SMatthew G. Knepley     u[0] = 0.0;
55365876a83SMatthew G. Knepley     u[1] = ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * F2_t; /* m / s */
55465876a83SMatthew G. Knepley   }
55565876a83SMatthew G. Knepley   return 0;
55665876a83SMatthew G. Knepley }
55765876a83SMatthew G. Knepley 
558*9371c9d4SSatish Balay static PetscErrorCode terzaghi_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
55965876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
56065876a83SMatthew G. Knepley   Parameter *param;
56165876a83SMatthew G. Knepley 
5629566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
56365876a83SMatthew G. Knepley   if (time <= 0.0) {
56465876a83SMatthew G. Knepley     u[0] = 0.0;
56565876a83SMatthew G. Knepley   } else {
56665876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
56765876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
56865876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
56965876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
57065876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
57165876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
57230602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
57365876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
57465876a83SMatthew G. Knepley 
57565876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
57665876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
57765876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
57865876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
57965876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
58065876a83SMatthew G. Knepley 
58165876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
58265876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
58365876a83SMatthew G. Knepley     PetscScalar F2_zt = 0.0;
58465876a83SMatthew G. Knepley 
58565876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
586*9371c9d4SSatish Balay       if (m % 2 == 1) { F2_zt += ((-m * PETSC_PI * c) / (L * L * L)) * PetscSinReal(0.5 * m * PETSC_PI * zstar) * PetscExpReal(-PetscSqr(m * PETSC_PI) * tstar); }
58765876a83SMatthew G. Knepley     }
58865876a83SMatthew G. Knepley     u[0] = ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * F2_zt; /* 1 / s */
58965876a83SMatthew G. Knepley   }
59065876a83SMatthew G. Knepley   return 0;
59165876a83SMatthew G. Knepley }
59265876a83SMatthew G. Knepley 
593*9371c9d4SSatish Balay static PetscErrorCode terzaghi_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
59465876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
59565876a83SMatthew G. Knepley   Parameter *param;
59665876a83SMatthew G. Knepley 
5979566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
59865876a83SMatthew G. Knepley   if (time <= 0.0) {
59965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
60065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
60165876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
60265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
60365876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
60465876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
60530602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
60665876a83SMatthew G. Knepley 
60765876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
60865876a83SMatthew G. Knepley     PetscScalar eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
60965876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
61065876a83SMatthew G. Knepley     PetscScalar c   = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
61165876a83SMatthew G. Knepley 
61265876a83SMatthew G. Knepley     u[0] = -((P_0 * eta) / (G * S)) * PetscSqr(0 * PETSC_PI) * c / PetscSqr(2.0 * L); /* Pa / s */
61365876a83SMatthew G. Knepley   } else {
61465876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
61565876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
61665876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
61765876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
61865876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
61965876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
62030602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
62165876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
62265876a83SMatthew G. Knepley 
62365876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
62465876a83SMatthew G. Knepley     PetscScalar eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
62565876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
62665876a83SMatthew G. Knepley     PetscScalar c   = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
62765876a83SMatthew G. Knepley 
62865876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
62965876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
63065876a83SMatthew G. Knepley     PetscScalar F1_t  = 0.0;
63165876a83SMatthew G. Knepley 
63263a3b9bcSJacob Faibussowitsch     PetscCheck(PetscAbsScalar((1 / M + (alpha * eta) / G) - S) <= 1.0e-10, PETSC_COMM_SELF, PETSC_ERR_PLIB, "S %g != check %g", (double)PetscAbsScalar(S), (double)PetscAbsScalar(1 / M + (alpha * eta) / G));
63365876a83SMatthew G. Knepley 
63465876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
635*9371c9d4SSatish Balay       if (m % 2 == 1) { F1_t += ((-m * PETSC_PI * c) / PetscSqr(L)) * PetscSinReal(0.5 * m * PETSC_PI * zstar) * PetscExpReal(-PetscSqr(m * PETSC_PI) * tstar); }
63665876a83SMatthew G. Knepley     }
63765876a83SMatthew G. Knepley     u[0] = ((P_0 * eta) / (G * S)) * F1_t; /* Pa / s */
63865876a83SMatthew G. Knepley   }
63965876a83SMatthew G. Knepley   return 0;
64065876a83SMatthew G. Knepley }
64165876a83SMatthew G. Knepley 
64265876a83SMatthew G. Knepley /* Mandel Solutions */
643*9371c9d4SSatish Balay static PetscErrorCode mandel_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
64465876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
64565876a83SMatthew G. Knepley   Parameter *param;
64665876a83SMatthew G. Knepley 
6479566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
64865876a83SMatthew G. Knepley   if (time <= 0.0) {
64965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                          /* -  */
65065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                            /* Pa */
65165876a83SMatthew G. Knepley     PetscScalar M     = param->M;                              /* Pa */
65265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                             /* Pa */
65365876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                            /* Pa */
65465876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;                /* m^2 / (Pa s) */
65530602db0SMatthew G. Knepley     PetscReal   a     = 0.5 * (user->xmax[0] - user->xmin[0]); /* m */
65665876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
65765876a83SMatthew G. Knepley 
65865876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
65965876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
66065876a83SMatthew G. Knepley     PetscScalar B    = alpha * M / K_u;                                     /* -,       Cheng (B.12) */
66165876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
66265876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
66365876a83SMatthew G. Knepley 
66465876a83SMatthew G. Knepley     PetscScalar A1   = 3.0 / (B * (1.0 + nu_u));
66565876a83SMatthew G. Knepley     PetscReal   aa   = 0.0;
66665876a83SMatthew G. Knepley     PetscReal   p    = 0.0;
66765876a83SMatthew G. Knepley     PetscReal   time = 0.0;
66865876a83SMatthew G. Knepley 
66965876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
67065876a83SMatthew G. Knepley       aa = user->zeroArray[n - 1];
67165876a83SMatthew G. Knepley       p += (PetscSinReal(aa) / (aa - PetscSinReal(aa) * PetscCosReal(aa))) * (PetscCosReal((aa * x[0]) / a) - PetscCosReal(aa)) * PetscExpReal(-1.0 * (aa * aa * PetscRealPart(c) * time) / (a * a));
67265876a83SMatthew G. Knepley     }
67365876a83SMatthew G. Knepley     u[0] = ((2.0 * P_0) / (a * A1)) * p;
67465876a83SMatthew G. Knepley   } else {
67565876a83SMatthew G. Knepley     u[0] = 0.0;
67665876a83SMatthew G. Knepley   }
67765876a83SMatthew G. Knepley   return 0;
67865876a83SMatthew G. Knepley }
67965876a83SMatthew G. Knepley 
680*9371c9d4SSatish Balay static PetscErrorCode mandel_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
68165876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
68265876a83SMatthew G. Knepley   Parameter *param;
68365876a83SMatthew G. Knepley 
6849566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
68565876a83SMatthew G. Knepley   {
68665876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                          /* -  */
68765876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                            /* Pa */
68865876a83SMatthew G. Knepley     PetscScalar M     = param->M;                              /* Pa */
68965876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                             /* Pa */
69065876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                            /* Pa */
69165876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;                /* m^2 / (Pa s) */
69230602db0SMatthew G. Knepley     PetscScalar a     = 0.5 * (user->xmax[0] - user->xmin[0]); /* m */
69365876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
69465876a83SMatthew G. Knepley 
69565876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
69665876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
69765876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
69865876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
69965876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
70065876a83SMatthew G. Knepley 
70165876a83SMatthew G. Knepley     PetscScalar A_s     = 0.0;
70265876a83SMatthew G. Knepley     PetscScalar B_s     = 0.0;
70365876a83SMatthew G. Knepley     PetscScalar time    = 0.0;
70465876a83SMatthew G. Knepley     PetscScalar alpha_n = 0.0;
70565876a83SMatthew G. Knepley 
70665876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
70765876a83SMatthew G. Knepley       alpha_n = user->zeroArray[n - 1];
70865876a83SMatthew G. Knepley       A_s += ((PetscSinReal(alpha_n) * PetscCosReal(alpha_n)) / (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n))) * PetscExpReal(-1 * (alpha_n * alpha_n * c * time) / (a * a));
70965876a83SMatthew G. Knepley       B_s += (PetscCosReal(alpha_n) / (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n))) * PetscSinReal((alpha_n * x[0]) / a) * PetscExpReal(-1 * (alpha_n * alpha_n * c * time) / (a * a));
71065876a83SMatthew G. Knepley     }
71165876a83SMatthew G. Knepley     u[0] = ((P_0 * nu) / (2.0 * G * a) - (P_0 * nu_u) / (G * a) * A_s) * x[0] + P_0 / G * B_s;
71265876a83SMatthew G. Knepley     u[1] = (-1 * (P_0 * (1.0 - nu)) / (2 * G * a) + (P_0 * (1 - nu_u)) / (G * a) * A_s) * x[1];
71365876a83SMatthew G. Knepley   }
71465876a83SMatthew G. Knepley   return 0;
71565876a83SMatthew G. Knepley }
71665876a83SMatthew G. Knepley 
717*9371c9d4SSatish Balay static PetscErrorCode mandel_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
71865876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
71965876a83SMatthew G. Knepley   Parameter *param;
72065876a83SMatthew G. Knepley 
7219566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
72265876a83SMatthew G. Knepley   {
72365876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                          /* -  */
72465876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                            /* Pa */
72565876a83SMatthew G. Knepley     PetscScalar M     = param->M;                              /* Pa */
72665876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                             /* Pa */
72765876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                            /* Pa */
72865876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;                /* m^2 / (Pa s) */
72930602db0SMatthew G. Knepley     PetscReal   a     = 0.5 * (user->xmax[0] - user->xmin[0]); /* m */
73065876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
73165876a83SMatthew G. Knepley 
73265876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
73365876a83SMatthew G. Knepley     PetscScalar nu  = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
73465876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
73565876a83SMatthew G. Knepley     PetscReal   c   = PetscRealPart(kappa / S);                            /* m^2 / s, Cheng (B.16) */
73665876a83SMatthew G. Knepley 
73765876a83SMatthew G. Knepley     PetscReal aa    = 0.0;
73865876a83SMatthew G. Knepley     PetscReal eps_A = 0.0;
73965876a83SMatthew G. Knepley     PetscReal eps_B = 0.0;
74065876a83SMatthew G. Knepley     PetscReal eps_C = 0.0;
74165876a83SMatthew G. Knepley     PetscReal time  = 0.0;
74265876a83SMatthew G. Knepley 
74365876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
74465876a83SMatthew G. Knepley       aa = user->zeroArray[n - 1];
74565876a83SMatthew G. Knepley       eps_A += (aa * PetscExpReal((-1.0 * aa * aa * c * time) / (a * a)) * PetscCosReal(aa) * PetscCosReal((aa * x[0]) / a)) / (a * (aa - PetscSinReal(aa) * PetscCosReal(aa)));
74665876a83SMatthew G. Knepley       eps_B += (PetscExpReal((-1.0 * aa * aa * c * time) / (a * a)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
74765876a83SMatthew G. Knepley       eps_C += (PetscExpReal((-1.0 * aa * aa * c * time) / (aa * aa)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
74865876a83SMatthew G. Knepley     }
74965876a83SMatthew G. Knepley     u[0] = (P_0 / G) * eps_A + ((P_0 * nu) / (2.0 * G * a)) - eps_B / (G * a) - (P_0 * (1 - nu)) / (2 * G * a) + eps_C / (G * a);
75065876a83SMatthew G. Knepley   }
75165876a83SMatthew G. Knepley   return 0;
75265876a83SMatthew G. Knepley }
75365876a83SMatthew G. Knepley 
75465876a83SMatthew G. Knepley // Displacement
755*9371c9d4SSatish Balay static PetscErrorCode mandel_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
75665876a83SMatthew G. Knepley   Parameter *param;
75765876a83SMatthew G. Knepley 
75865876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
75965876a83SMatthew G. Knepley 
7609566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
76165876a83SMatthew G. Knepley   if (time <= 0.0) {
7629566063dSJacob Faibussowitsch     PetscCall(mandel_initial_u(dim, time, x, Nc, u, ctx));
76365876a83SMatthew G. Knepley   } else {
76465876a83SMatthew G. Knepley     PetscInt    NITER = user->niter;
76565876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
76665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
76765876a83SMatthew G. Knepley     PetscScalar M     = param->M;
76865876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
76965876a83SMatthew G. Knepley     PetscScalar k     = param->k;
77065876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
77165876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
77265876a83SMatthew G. Knepley 
77365876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
77465876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
77565876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
77665876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
77730602db0SMatthew G. Knepley     PetscReal   a     = (user->xmax[0] - user->xmin[0]) / 2.0;
77865876a83SMatthew G. Knepley     PetscReal   c     = PetscRealPart(((2.0 * kappa * G) * (1.0 - nu) * (nu_u - nu)) / (alpha * alpha * (1.0 - 2.0 * nu) * (1.0 - nu_u)));
77965876a83SMatthew G. Knepley 
78065876a83SMatthew G. Knepley     // Series term
78165876a83SMatthew G. Knepley     PetscScalar A_x = 0.0;
78265876a83SMatthew G. Knepley     PetscScalar B_x = 0.0;
78365876a83SMatthew G. Knepley 
78465876a83SMatthew G. Knepley     for (PetscInt n = 1; n < NITER + 1; n++) {
78565876a83SMatthew G. Knepley       PetscReal alpha_n = user->zeroArray[n - 1];
78665876a83SMatthew G. Knepley 
78765876a83SMatthew G. Knepley       A_x += ((PetscSinReal(alpha_n) * PetscCosReal(alpha_n)) / (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n))) * PetscExpReal(-1 * (alpha_n * alpha_n * c * time) / (a * a));
78865876a83SMatthew G. Knepley       B_x += (PetscCosReal(alpha_n) / (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n))) * PetscSinReal((alpha_n * x[0]) / a) * PetscExpReal(-1 * (alpha_n * alpha_n * c * time) / (a * a));
78965876a83SMatthew G. Knepley     }
79065876a83SMatthew G. Knepley     u[0] = ((F * nu) / (2.0 * G * a) - (F * nu_u) / (G * a) * A_x) * x[0] + F / G * B_x;
79165876a83SMatthew G. Knepley     u[1] = (-1 * (F * (1.0 - nu)) / (2 * G * a) + (F * (1 - nu_u)) / (G * a) * A_x) * x[1];
79265876a83SMatthew G. Knepley   }
79365876a83SMatthew G. Knepley   return 0;
79465876a83SMatthew G. Knepley }
79565876a83SMatthew G. Knepley 
79665876a83SMatthew G. Knepley // Trace strain
797*9371c9d4SSatish Balay static PetscErrorCode mandel_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
79865876a83SMatthew G. Knepley   Parameter *param;
79965876a83SMatthew G. Knepley 
80065876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
80165876a83SMatthew G. Knepley 
8029566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
80365876a83SMatthew G. Knepley   if (time <= 0.0) {
8049566063dSJacob Faibussowitsch     PetscCall(mandel_initial_eps(dim, time, x, Nc, u, ctx));
80565876a83SMatthew G. Knepley   } else {
80665876a83SMatthew G. Knepley     PetscInt    NITER = user->niter;
80765876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
80865876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
80965876a83SMatthew G. Knepley     PetscScalar M     = param->M;
81065876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
81165876a83SMatthew G. Knepley     PetscScalar k     = param->k;
81265876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
81365876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
81465876a83SMatthew G. Knepley 
81565876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
81665876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
81765876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
81865876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
81965876a83SMatthew G. Knepley     //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
82065876a83SMatthew G. Knepley 
82165876a83SMatthew G. Knepley     //const PetscScalar b = (YMAX - YMIN) / 2.0;
82230602db0SMatthew G. Knepley     PetscScalar a = (user->xmax[0] - user->xmin[0]) / 2.0;
82365876a83SMatthew G. Knepley     PetscReal   c = PetscRealPart(((2.0 * kappa * G) * (1.0 - nu) * (nu_u - nu)) / (alpha * alpha * (1.0 - 2.0 * nu) * (1.0 - nu_u)));
82465876a83SMatthew G. Knepley 
82565876a83SMatthew G. Knepley     // Series term
82665876a83SMatthew G. Knepley     PetscScalar eps_A = 0.0;
82765876a83SMatthew G. Knepley     PetscScalar eps_B = 0.0;
82865876a83SMatthew G. Knepley     PetscScalar eps_C = 0.0;
82965876a83SMatthew G. Knepley 
830*9371c9d4SSatish Balay     for (PetscInt n = 1; n < NITER + 1; n++) {
83165876a83SMatthew G. Knepley       PetscReal aa = user->zeroArray[n - 1];
83265876a83SMatthew G. Knepley 
83365876a83SMatthew G. Knepley       eps_A += (aa * PetscExpReal((-1.0 * aa * aa * c * time) / (a * a)) * PetscCosReal(aa) * PetscCosReal((aa * x[0]) / a)) / (a * (aa - PetscSinReal(aa) * PetscCosReal(aa)));
83465876a83SMatthew G. Knepley 
83565876a83SMatthew G. Knepley       eps_B += (PetscExpReal((-1.0 * aa * aa * c * time) / (a * a)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
83665876a83SMatthew G. Knepley 
83765876a83SMatthew G. Knepley       eps_C += (PetscExpReal((-1.0 * aa * aa * c * time) / (aa * aa)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
83865876a83SMatthew G. Knepley     }
83965876a83SMatthew G. Knepley 
84065876a83SMatthew G. Knepley     u[0] = (F / G) * eps_A + ((F * nu) / (2.0 * G * a)) - eps_B / (G * a) - (F * (1 - nu)) / (2 * G * a) + eps_C / (G * a);
84165876a83SMatthew G. Knepley   }
84265876a83SMatthew G. Knepley   return 0;
84365876a83SMatthew G. Knepley }
84465876a83SMatthew G. Knepley 
84565876a83SMatthew G. Knepley // Pressure
846*9371c9d4SSatish Balay static PetscErrorCode mandel_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
84765876a83SMatthew G. Knepley   Parameter *param;
84865876a83SMatthew G. Knepley 
84965876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
85065876a83SMatthew G. Knepley 
8519566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
85265876a83SMatthew G. Knepley   if (time <= 0.0) {
8539566063dSJacob Faibussowitsch     PetscCall(mandel_drainage_pressure(dim, time, x, Nc, u, ctx));
85465876a83SMatthew G. Knepley   } else {
85565876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
85665876a83SMatthew G. Knepley 
85765876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
85865876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
85965876a83SMatthew G. Knepley     PetscScalar M     = param->M;
86065876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
86165876a83SMatthew G. Knepley     PetscScalar k     = param->k;
86265876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
86365876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
86465876a83SMatthew G. Knepley 
86565876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
86665876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
86765876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
86865876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
86965876a83SMatthew G. Knepley     PetscScalar B     = (alpha * M) / (K_d + alpha * alpha * M);
87065876a83SMatthew G. Knepley 
87130602db0SMatthew G. Knepley     PetscReal   a  = (user->xmax[0] - user->xmin[0]) / 2.0;
87265876a83SMatthew G. Knepley     PetscReal   c  = PetscRealPart(((2.0 * kappa * G) * (1.0 - nu) * (nu_u - nu)) / (alpha * alpha * (1.0 - 2.0 * nu) * (1.0 - nu_u)));
87365876a83SMatthew G. Knepley     PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
87465876a83SMatthew G. Knepley     //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
87565876a83SMatthew G. Knepley 
87665876a83SMatthew G. Knepley     // Series term
87765876a83SMatthew G. Knepley     PetscScalar aa = 0.0;
87865876a83SMatthew G. Knepley     PetscScalar p  = 0.0;
87965876a83SMatthew G. Knepley 
880*9371c9d4SSatish Balay     for (PetscInt n = 1; n < NITER + 1; n++) {
88165876a83SMatthew G. Knepley       aa = user->zeroArray[n - 1];
88265876a83SMatthew G. Knepley       p += (PetscSinReal(aa) / (aa - PetscSinReal(aa) * PetscCosReal(aa))) * (PetscCosReal((aa * x[0]) / a) - PetscCosReal(aa)) * PetscExpReal(-1.0 * (aa * aa * c * time) / (a * a));
88365876a83SMatthew G. Knepley     }
88465876a83SMatthew G. Knepley     u[0] = ((2.0 * F) / (a * A1)) * p;
88565876a83SMatthew G. Knepley   }
88665876a83SMatthew G. Knepley   return 0;
88765876a83SMatthew G. Knepley }
88865876a83SMatthew G. Knepley 
88965876a83SMatthew G. Knepley // Time derivative of displacement
890*9371c9d4SSatish Balay static PetscErrorCode mandel_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
89165876a83SMatthew G. Knepley   Parameter *param;
89265876a83SMatthew G. Knepley 
89365876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
89465876a83SMatthew G. Knepley 
8959566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
89665876a83SMatthew G. Knepley 
89765876a83SMatthew G. Knepley   PetscInt    NITER = user->niter;
89865876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
89965876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
90065876a83SMatthew G. Knepley   PetscScalar M     = param->M;
90165876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
90265876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
90365876a83SMatthew G. Knepley 
90465876a83SMatthew G. Knepley   PetscScalar K_d   = K_u - alpha * alpha * M;
90565876a83SMatthew G. Knepley   PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
90665876a83SMatthew G. Knepley   PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
90765876a83SMatthew G. Knepley   PetscScalar kappa = param->k / param->mu_f;
90830602db0SMatthew G. Knepley   PetscReal   a     = (user->xmax[0] - user->xmin[0]) / 2.0;
90965876a83SMatthew G. Knepley   PetscReal   c     = PetscRealPart(((2.0 * kappa * G) * (1.0 - nu) * (nu_u - nu)) / (alpha * alpha * (1.0 - 2.0 * nu) * (1.0 - nu_u)));
91065876a83SMatthew G. Knepley 
91165876a83SMatthew G. Knepley   // Series term
91265876a83SMatthew G. Knepley   PetscScalar A_s_t = 0.0;
91365876a83SMatthew G. Knepley   PetscScalar B_s_t = 0.0;
91465876a83SMatthew G. Knepley 
915*9371c9d4SSatish Balay   for (PetscInt n = 1; n < NITER + 1; n++) {
91665876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n - 1];
91765876a83SMatthew G. Knepley 
91865876a83SMatthew G. Knepley     A_s_t += (-1.0 * alpha_n * alpha_n * c * PetscExpReal((-1.0 * alpha_n * alpha_n * time) / (a * a)) * PetscSinReal((alpha_n * x[0]) / a) * PetscCosReal(alpha_n)) / (a * a * (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n)));
91965876a83SMatthew G. Knepley     B_s_t += (-1.0 * alpha_n * alpha_n * c * PetscExpReal((-1.0 * alpha_n * alpha_n * time) / (a * a)) * PetscSinReal(alpha_n) * PetscCosReal(alpha_n)) / (a * a * (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n)));
92065876a83SMatthew G. Knepley   }
92165876a83SMatthew G. Knepley 
92265876a83SMatthew G. Knepley   u[0] = (F / G) * A_s_t - ((F * nu_u * x[0]) / (G * a)) * B_s_t;
92365876a83SMatthew G. Knepley   u[1] = ((F * x[1] * (1 - nu_u)) / (G * a)) * B_s_t;
92465876a83SMatthew G. Knepley 
92565876a83SMatthew G. Knepley   return 0;
92665876a83SMatthew G. Knepley }
92765876a83SMatthew G. Knepley 
92865876a83SMatthew G. Knepley // Time derivative of trace strain
929*9371c9d4SSatish Balay static PetscErrorCode mandel_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
93065876a83SMatthew G. Knepley   Parameter *param;
93165876a83SMatthew G. Knepley 
93265876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
93365876a83SMatthew G. Knepley 
9349566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
93565876a83SMatthew G. Knepley 
93665876a83SMatthew G. Knepley   PetscInt    NITER = user->niter;
93765876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
93865876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
93965876a83SMatthew G. Knepley   PetscScalar M     = param->M;
94065876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
94165876a83SMatthew G. Knepley   PetscScalar k     = param->k;
94265876a83SMatthew G. Knepley   PetscScalar mu_f  = param->mu_f;
94365876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
94465876a83SMatthew G. Knepley 
94565876a83SMatthew G. Knepley   PetscScalar K_d   = K_u - alpha * alpha * M;
94665876a83SMatthew G. Knepley   PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
94765876a83SMatthew G. Knepley   PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
94865876a83SMatthew G. Knepley   PetscScalar kappa = k / mu_f;
94965876a83SMatthew G. Knepley   //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
95065876a83SMatthew G. Knepley 
95165876a83SMatthew G. Knepley   //const PetscScalar b = (YMAX - YMIN) / 2.0;
95230602db0SMatthew G. Knepley   PetscReal a = (user->xmax[0] - user->xmin[0]) / 2.0;
95365876a83SMatthew G. Knepley   PetscReal c = PetscRealPart(((2.0 * kappa * G) * (1.0 - nu) * (nu_u - nu)) / (alpha * alpha * (1.0 - 2.0 * nu) * (1.0 - nu_u)));
95465876a83SMatthew G. Knepley 
95565876a83SMatthew G. Knepley   // Series term
95665876a83SMatthew G. Knepley   PetscScalar eps_As = 0.0;
95765876a83SMatthew G. Knepley   PetscScalar eps_Bs = 0.0;
95865876a83SMatthew G. Knepley   PetscScalar eps_Cs = 0.0;
95965876a83SMatthew G. Knepley 
960*9371c9d4SSatish Balay   for (PetscInt n = 1; n < NITER + 1; n++) {
96165876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n - 1];
96265876a83SMatthew G. Knepley 
96365876a83SMatthew G. Knepley     eps_As += (-1.0 * alpha_n * alpha_n * alpha_n * c * PetscExpReal((-1.0 * alpha_n * alpha_n * c * time) / (a * a)) * PetscCosReal(alpha_n) * PetscCosReal((alpha_n * x[0]) / a)) / (alpha_n * alpha_n * alpha_n * (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n)));
96465876a83SMatthew G. Knepley     eps_Bs += (-1.0 * alpha_n * alpha_n * c * PetscExpReal((-1.0 * alpha_n * alpha_n * c * time) / (a * a)) * PetscSinReal(alpha_n) * PetscCosReal(alpha_n)) / (alpha_n * alpha_n * (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n)));
96565876a83SMatthew G. Knepley     eps_Cs += (-1.0 * alpha_n * alpha_n * c * PetscExpReal((-1.0 * alpha_n * alpha_n * c * time) / (a * a)) * PetscSinReal(alpha_n) * PetscCosReal(alpha_n)) / (alpha_n * alpha_n * (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n)));
96665876a83SMatthew G. Knepley   }
96765876a83SMatthew G. Knepley 
96865876a83SMatthew G. Knepley   u[0] = (F / G) * eps_As - ((F * nu_u) / (G * a)) * eps_Bs + ((F * (1 - nu_u)) / (G * a)) * eps_Cs;
96965876a83SMatthew G. Knepley   return 0;
97065876a83SMatthew G. Knepley }
97165876a83SMatthew G. Knepley 
97265876a83SMatthew G. Knepley // Time derivative of pressure
973*9371c9d4SSatish Balay static PetscErrorCode mandel_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
97465876a83SMatthew G. Knepley   Parameter *param;
97565876a83SMatthew G. Knepley 
97665876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
97765876a83SMatthew G. Knepley 
9789566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
97965876a83SMatthew G. Knepley 
98065876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
98165876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
98265876a83SMatthew G. Knepley   PetscScalar M     = param->M;
98365876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
98465876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
98565876a83SMatthew G. Knepley 
98665876a83SMatthew G. Knepley   PetscScalar K_d  = K_u - alpha * alpha * M;
98765876a83SMatthew G. Knepley   PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
98865876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
98965876a83SMatthew G. Knepley 
99030602db0SMatthew G. Knepley   PetscReal a = (user->xmax[0] - user->xmin[0]) / 2.0;
99165876a83SMatthew G. Knepley   //PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
99265876a83SMatthew G. Knepley   //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
99365876a83SMatthew G. Knepley 
99465876a83SMatthew G. Knepley   u[0] = ((2.0 * F * (-2.0 * nu + 3.0 * nu_u)) / (3.0 * a * alpha * (1.0 - 2.0 * nu)));
99565876a83SMatthew G. Knepley 
99665876a83SMatthew G. Knepley   return 0;
99765876a83SMatthew G. Knepley }
99865876a83SMatthew G. Knepley 
99965876a83SMatthew G. Knepley /* Cryer Solutions */
1000*9371c9d4SSatish Balay static PetscErrorCode cryer_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
100165876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
100265876a83SMatthew G. Knepley   Parameter *param;
100365876a83SMatthew G. Knepley 
10049566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
100565876a83SMatthew G. Knepley   if (time <= 0.0) {
100665876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;    /* -  */
100765876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;      /* Pa */
100865876a83SMatthew G. Knepley     PetscScalar M     = param->M;        /* Pa */
100965876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;      /* Pa */
101065876a83SMatthew G. Knepley     PetscScalar B     = alpha * M / K_u; /* -, Cheng (B.12) */
101165876a83SMatthew G. Knepley 
101265876a83SMatthew G. Knepley     u[0] = P_0 * B;
101365876a83SMatthew G. Knepley   } else {
101465876a83SMatthew G. Knepley     u[0] = 0.0;
101565876a83SMatthew G. Knepley   }
101665876a83SMatthew G. Knepley   return 0;
101765876a83SMatthew G. Knepley }
101865876a83SMatthew G. Knepley 
1019*9371c9d4SSatish Balay static PetscErrorCode cryer_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
102065876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
102165876a83SMatthew G. Knepley   Parameter *param;
102265876a83SMatthew G. Knepley 
10239566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
102465876a83SMatthew G. Knepley   {
102565876a83SMatthew G. Knepley     PetscScalar K_u  = param->K_u;                                      /* Pa */
102665876a83SMatthew G. Knepley     PetscScalar G    = param->mu;                                       /* Pa */
102765876a83SMatthew G. Knepley     PetscScalar P_0  = param->P_0;                                      /* Pa */
102830602db0SMatthew G. Knepley     PetscReal   R_0  = user->xmax[1];                                   /* m */
102965876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
103065876a83SMatthew G. Knepley 
103165876a83SMatthew G. Knepley     PetscScalar u_0  = -P_0 * R_0 * (1. - 2. * nu_u) / (2. * G * (1. + nu_u)); /* Cheng (7.407) */
103265876a83SMatthew G. Knepley     PetscReal   u_sc = PetscRealPart(u_0) / R_0;
103365876a83SMatthew G. Knepley 
103465876a83SMatthew G. Knepley     u[0] = u_sc * x[0];
103565876a83SMatthew G. Knepley     u[1] = u_sc * x[1];
103665876a83SMatthew G. Knepley     u[2] = u_sc * x[2];
103765876a83SMatthew G. Knepley   }
103865876a83SMatthew G. Knepley   return 0;
103965876a83SMatthew G. Knepley }
104065876a83SMatthew G. Knepley 
1041*9371c9d4SSatish Balay static PetscErrorCode cryer_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
104265876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
104365876a83SMatthew G. Knepley   Parameter *param;
104465876a83SMatthew G. Knepley 
10459566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
104665876a83SMatthew G. Knepley   {
104765876a83SMatthew G. Knepley     PetscScalar K_u  = param->K_u;                                      /* Pa */
104865876a83SMatthew G. Knepley     PetscScalar G    = param->mu;                                       /* Pa */
104965876a83SMatthew G. Knepley     PetscScalar P_0  = param->P_0;                                      /* Pa */
105030602db0SMatthew G. Knepley     PetscReal   R_0  = user->xmax[1];                                   /* m */
105165876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
105265876a83SMatthew G. Knepley 
105365876a83SMatthew G. Knepley     PetscScalar u_0  = -P_0 * R_0 * (1. - 2. * nu_u) / (2. * G * (1. + nu_u)); /* Cheng (7.407) */
105465876a83SMatthew G. Knepley     PetscReal   u_sc = PetscRealPart(u_0) / R_0;
105565876a83SMatthew G. Knepley 
105665876a83SMatthew G. Knepley     /* div R = 1/R^2 d/dR R^2 R = 3 */
105765876a83SMatthew G. Knepley     u[0] = 3. * u_sc;
105865876a83SMatthew G. Knepley     u[1] = 3. * u_sc;
105965876a83SMatthew G. Knepley     u[2] = 3. * u_sc;
106065876a83SMatthew G. Knepley   }
106165876a83SMatthew G. Knepley   return 0;
106265876a83SMatthew G. Knepley }
106365876a83SMatthew G. Knepley 
106465876a83SMatthew G. Knepley // Displacement
1065*9371c9d4SSatish Balay static PetscErrorCode cryer_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
106665876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
106765876a83SMatthew G. Knepley   Parameter *param;
106865876a83SMatthew G. Knepley 
10699566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
107065876a83SMatthew G. Knepley   if (time <= 0.0) {
10719566063dSJacob Faibussowitsch     PetscCall(cryer_initial_u(dim, time, x, Nc, u, ctx));
107265876a83SMatthew G. Knepley   } else {
107365876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
107465876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
107565876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
107665876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
107765876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
107865876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
107930602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
108065876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
108165876a83SMatthew G. Knepley 
108265876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
108365876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
108465876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
108565876a83SMatthew G. Knepley     PetscScalar S     = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
108665876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
108765876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0 * R_0 * (1. - 2. * nu) / (2. * G * (1. + nu));  /* m,       Cheng (7.388) */
108865876a83SMatthew G. Knepley 
108965876a83SMatthew G. Knepley     PetscReal   R      = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
109065876a83SMatthew G. Knepley     PetscReal   R_star = R / R_0;
109165876a83SMatthew G. Knepley     PetscReal   tstar  = PetscRealPart(c * time) / PetscSqr(R_0); /* - */
109265876a83SMatthew G. Knepley     PetscReal   A_n    = 0.0;
109365876a83SMatthew G. Knepley     PetscScalar u_sc;
109465876a83SMatthew G. Knepley 
109565876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
109665876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n - 1];
109765876a83SMatthew G. Knepley       const PetscReal E_n = PetscRealPart(PetscSqr(1 - nu) * PetscSqr(1 + nu_u) * x_n - 18.0 * (1 + nu) * (nu_u - nu) * (1 - nu_u));
109865876a83SMatthew G. Knepley 
109965876a83SMatthew G. Knepley       /* m , Cheng (7.404) */
1100*9371c9d4SSatish Balay       A_n += PetscRealPart((12.0 * (1.0 + nu) * (nu_u - nu)) / ((1.0 - 2.0 * nu) * E_n * PetscSqr(R_star) * x_n * PetscSinReal(PetscSqrtReal(x_n))) * (3.0 * (nu_u - nu) * (PetscSinReal(R_star * PetscSqrtReal(x_n)) - R_star * PetscSqrtReal(x_n) * PetscCosReal(R_star * PetscSqrtReal(x_n))) + (1.0 - nu) * (1.0 - 2.0 * nu) * PetscPowRealInt(R_star, 3) * x_n * PetscSinReal(PetscSqrtReal(x_n))) * PetscExpReal(-x_n * tstar));
110165876a83SMatthew G. Knepley     }
110265876a83SMatthew G. Knepley     u_sc = PetscRealPart(u_inf) * (R_star - A_n);
110365876a83SMatthew G. Knepley     u[0] = u_sc * x[0] / R;
110465876a83SMatthew G. Knepley     u[1] = u_sc * x[1] / R;
110565876a83SMatthew G. Knepley     u[2] = u_sc * x[2] / R;
110665876a83SMatthew G. Knepley   }
110765876a83SMatthew G. Knepley   return 0;
110865876a83SMatthew G. Knepley }
110965876a83SMatthew G. Knepley 
111065876a83SMatthew G. Knepley // Volumetric Strain
1111*9371c9d4SSatish Balay static PetscErrorCode cryer_3d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
111265876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
111365876a83SMatthew G. Knepley   Parameter *param;
111465876a83SMatthew G. Knepley 
11159566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
111665876a83SMatthew G. Knepley   if (time <= 0.0) {
11179566063dSJacob Faibussowitsch     PetscCall(cryer_initial_eps(dim, time, x, Nc, u, ctx));
111865876a83SMatthew G. Knepley   } else {
111965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
112065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
112165876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
112265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
112365876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
112465876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
112530602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
112665876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
112765876a83SMatthew G. Knepley 
112865876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
112965876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
113065876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
113165876a83SMatthew G. Knepley     PetscScalar S     = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
113265876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
113365876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0 * R_0 * (1. - 2. * nu) / (2. * G * (1. + nu));  /* m,       Cheng (7.388) */
113465876a83SMatthew G. Knepley 
113565876a83SMatthew G. Knepley     PetscReal R      = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
113665876a83SMatthew G. Knepley     PetscReal R_star = R / R_0;
113765876a83SMatthew G. Knepley     PetscReal tstar  = PetscRealPart(c * time) / PetscSqr(R_0); /* - */
113865876a83SMatthew G. Knepley     PetscReal divA_n = 0.0;
113965876a83SMatthew G. Knepley 
114065876a83SMatthew G. Knepley     if (R_star < PETSC_SMALL) {
114165876a83SMatthew G. Knepley       for (n = 1; n < N + 1; ++n) {
114265876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n - 1];
114365876a83SMatthew G. Knepley         const PetscReal E_n = PetscRealPart(PetscSqr(1 - nu) * PetscSqr(1 + nu_u) * x_n - 18.0 * (1 + nu) * (nu_u - nu) * (1 - nu_u));
114465876a83SMatthew G. Knepley 
1145*9371c9d4SSatish Balay         divA_n += PetscRealPart((12.0 * (1.0 + nu) * (nu_u - nu)) / ((1.0 - 2.0 * nu) * E_n * PetscSqr(R_star) * x_n * PetscSinReal(PetscSqrtReal(x_n))) * (3.0 * (nu_u - nu) * PetscSqrtReal(x_n) * ((2.0 + PetscSqr(R_star * PetscSqrtReal(x_n))) - 2.0 * PetscCosReal(R_star * PetscSqrtReal(x_n))) + 5.0 * (1.0 - nu) * (1.0 - 2.0 * nu) * PetscPowRealInt(R_star, 2) * x_n * PetscSinReal(PetscSqrtReal(x_n))) * PetscExpReal(-x_n * tstar));
114665876a83SMatthew G. Knepley       }
114765876a83SMatthew G. Knepley     } else {
114865876a83SMatthew G. Knepley       for (n = 1; n < N + 1; ++n) {
114965876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n - 1];
115065876a83SMatthew G. Knepley         const PetscReal E_n = PetscRealPart(PetscSqr(1 - nu) * PetscSqr(1 + nu_u) * x_n - 18.0 * (1 + nu) * (nu_u - nu) * (1 - nu_u));
115165876a83SMatthew G. Knepley 
1152*9371c9d4SSatish Balay         divA_n += PetscRealPart((12.0 * (1.0 + nu) * (nu_u - nu)) / ((1.0 - 2.0 * nu) * E_n * PetscSqr(R_star) * x_n * PetscSinReal(PetscSqrtReal(x_n))) * (3.0 * (nu_u - nu) * PetscSqrtReal(x_n) * ((2.0 / (R_star * PetscSqrtReal(x_n)) + R_star * PetscSqrtReal(x_n)) * PetscSinReal(R_star * PetscSqrtReal(x_n)) - 2.0 * PetscCosReal(R_star * PetscSqrtReal(x_n))) + 5.0 * (1.0 - nu) * (1.0 - 2.0 * nu) * PetscPowRealInt(R_star, 2) * x_n * PetscSinReal(PetscSqrtReal(x_n))) * PetscExpReal(-x_n * tstar));
115365876a83SMatthew G. Knepley       }
115465876a83SMatthew G. Knepley     }
115563a3b9bcSJacob Faibussowitsch     if (PetscAbsReal(divA_n) > 1e3) PetscPrintf(PETSC_COMM_SELF, "(%g, %g, %g) divA_n: %g\n", (double)x[0], (double)x[1], (double)x[2], (double)divA_n);
115665876a83SMatthew G. Knepley     u[0] = PetscRealPart(u_inf) / R_0 * (3.0 - divA_n);
115765876a83SMatthew G. Knepley   }
115865876a83SMatthew G. Knepley   return 0;
115965876a83SMatthew G. Knepley }
116065876a83SMatthew G. Knepley 
116165876a83SMatthew G. Knepley // Pressure
1162*9371c9d4SSatish Balay static PetscErrorCode cryer_3d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
116365876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
116465876a83SMatthew G. Knepley   Parameter *param;
116565876a83SMatthew G. Knepley 
11669566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
116765876a83SMatthew G. Knepley   if (time <= 0.0) {
11689566063dSJacob Faibussowitsch     PetscCall(cryer_drainage_pressure(dim, time, x, Nc, u, ctx));
116965876a83SMatthew G. Knepley   } else {
117065876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
117165876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
117265876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
117365876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
117465876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
117530602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
117665876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
117765876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
117865876a83SMatthew G. Knepley 
117965876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
118065876a83SMatthew G. Knepley     PetscScalar eta  = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
118165876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
118265876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
118365876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
118465876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
118565876a83SMatthew G. Knepley     PetscScalar R    = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
118665876a83SMatthew G. Knepley 
118765876a83SMatthew G. Knepley     PetscScalar R_star = R / R_0;
118865876a83SMatthew G. Knepley     PetscScalar t_star = PetscRealPart(c * time) / PetscSqr(R_0);
118965876a83SMatthew G. Knepley     PetscReal   A_x    = 0.0;
119065876a83SMatthew G. Knepley 
119165876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
119265876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n - 1];
119365876a83SMatthew G. Knepley       const PetscReal E_n = PetscRealPart(PetscSqr(1 - nu) * PetscSqr(1 + nu_u) * x_n - 18.0 * (1 + nu) * (nu_u - nu) * (1 - nu_u));
119465876a83SMatthew G. Knepley 
119565876a83SMatthew G. Knepley       A_x += PetscRealPart(((18.0 * PetscSqr(nu_u - nu)) / (eta * E_n)) * (PetscSinReal(R_star * PetscSqrtReal(x_n)) / (R_star * PetscSinReal(PetscSqrtReal(x_n))) - 1.0) * PetscExpReal(-x_n * t_star)); /* Cheng (7.395) */
119665876a83SMatthew G. Knepley     }
119765876a83SMatthew G. Knepley     u[0] = P_0 * A_x;
119865876a83SMatthew G. Knepley   }
119965876a83SMatthew G. Knepley   return 0;
120065876a83SMatthew G. Knepley }
120165876a83SMatthew G. Knepley 
120265876a83SMatthew G. Knepley /* Boundary Kernels */
1203*9371c9d4SSatish Balay static void f0_terzaghi_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[]) {
120465876a83SMatthew G. Knepley   const PetscReal P = PetscRealPart(constants[5]);
120565876a83SMatthew G. Knepley 
120665876a83SMatthew G. Knepley   f0[0] = 0.0;
120765876a83SMatthew G. Knepley   f0[1] = P;
120865876a83SMatthew G. Knepley }
120965876a83SMatthew G. Knepley 
121045480ffeSMatthew G. Knepley #if 0
121165876a83SMatthew G. Knepley static void f0_mandel_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
121265876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
121365876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
121465876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
121565876a83SMatthew G. Knepley {
121665876a83SMatthew G. Knepley   // Uniform stress distribution
121765876a83SMatthew G. Knepley   /* PetscScalar xmax =  0.5;
121865876a83SMatthew G. Knepley   PetscScalar xmin = -0.5;
121965876a83SMatthew G. Knepley   PetscScalar ymax =  0.5;
122065876a83SMatthew G. Knepley   PetscScalar ymin = -0.5;
122165876a83SMatthew G. Knepley   PetscScalar P = constants[5];
122265876a83SMatthew G. Knepley   PetscScalar aL = (xmax - xmin) / 2.0;
122365876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*P / aL; */
122465876a83SMatthew G. Knepley 
122565876a83SMatthew G. Knepley   // Analytical (parabolic) stress distribution
122665876a83SMatthew G. Knepley   PetscReal a1, a2, am;
122765876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
122865876a83SMatthew G. Knepley 
122965876a83SMatthew G. Knepley   PetscInt NITER = 500;
123065876a83SMatthew G. Knepley   PetscReal EPS = 0.000001;
123165876a83SMatthew G. Knepley   PetscReal zeroArray[500]; /* NITER */
123265876a83SMatthew G. Knepley   PetscReal xmax =  1.0;
123365876a83SMatthew G. Knepley   PetscReal xmin =  0.0;
123465876a83SMatthew G. Knepley   PetscReal ymax =  0.1;
123565876a83SMatthew G. Knepley   PetscReal ymin =  0.0;
123665876a83SMatthew G. Knepley   PetscReal lower[2], upper[2];
123765876a83SMatthew G. Knepley 
123865876a83SMatthew G. Knepley   lower[0] = xmin - (xmax - xmin) / 2.0;
123965876a83SMatthew G. Knepley   lower[1] = ymin - (ymax - ymin) / 2.0;
124065876a83SMatthew G. Knepley   upper[0] = xmax - (xmax - xmin) / 2.0;
124165876a83SMatthew G. Knepley   upper[1] = ymax - (ymax - ymin) / 2.0;
124265876a83SMatthew G. Knepley 
124365876a83SMatthew G. Knepley   xmin = lower[0];
124465876a83SMatthew G. Knepley   ymin = lower[1];
124565876a83SMatthew G. Knepley   xmax = upper[0];
124665876a83SMatthew G. Knepley   ymax = upper[1];
124765876a83SMatthew G. Knepley 
124865876a83SMatthew G. Knepley   PetscScalar G     = constants[0];
124965876a83SMatthew G. Knepley   PetscScalar K_u   = constants[1];
125065876a83SMatthew G. Knepley   PetscScalar alpha = constants[2];
125165876a83SMatthew G. Knepley   PetscScalar M     = constants[3];
125265876a83SMatthew G. Knepley   PetscScalar kappa = constants[4];
125365876a83SMatthew G. Knepley   PetscScalar F     = constants[5];
125465876a83SMatthew G. Knepley 
125565876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
125665876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
125765876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
125865876a83SMatthew G. Knepley   PetscReal   aL = (xmax - xmin) / 2.0;
125965876a83SMatthew G. Knepley   PetscReal   c = PetscRealPart(((2.0*kappa*G) * (1.0 - nu) * (nu_u - nu)) / (alpha*alpha * (1.0 - 2.0*nu) * (1.0 - nu_u)));
126065876a83SMatthew G. Knepley   PetscScalar B = (3.0 * (nu_u - nu)) / ( alpha * (1.0 - 2.0*nu) * (1.0 + nu_u));
126165876a83SMatthew G. Knepley   PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
126265876a83SMatthew G. Knepley   PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
126365876a83SMatthew G. Knepley 
126465876a83SMatthew G. Knepley   // Generate zero values
126565876a83SMatthew G. Knepley   for (PetscInt i=1; i < NITER+1; i++)
126665876a83SMatthew G. Knepley   {
126765876a83SMatthew G. Knepley     a1 = ((PetscReal) i - 1.0) * PETSC_PI * PETSC_PI / 4.0 + EPS;
126865876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI/2;
126965876a83SMatthew G. Knepley     for (PetscInt j=0; j<NITER; j++)
127065876a83SMatthew G. Knepley     {
127165876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart(A1/A2)*a1;
127265876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart(A1/A2)*a2;
127365876a83SMatthew G. Knepley       am = (a1 + a2)/2.0;
127465876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart(A1/A2)*am;
127565876a83SMatthew G. Knepley       if ((ym*y1) > 0)
127665876a83SMatthew G. Knepley       {
127765876a83SMatthew G. Knepley         a1 = am;
127865876a83SMatthew G. Knepley       } else {
127965876a83SMatthew G. Knepley         a2 = am;
128065876a83SMatthew G. Knepley       }
128165876a83SMatthew G. Knepley       if (PetscAbsReal(y2) < EPS)
128265876a83SMatthew G. Knepley       {
128365876a83SMatthew G. Knepley         am = a2;
128465876a83SMatthew G. Knepley       }
128565876a83SMatthew G. Knepley     }
128665876a83SMatthew G. Knepley     zeroArray[i-1] = am;
128765876a83SMatthew G. Knepley   }
128865876a83SMatthew G. Knepley 
128965876a83SMatthew G. Knepley   // Solution for sigma_zz
129065876a83SMatthew G. Knepley   PetscScalar A_x = 0.0;
129165876a83SMatthew G. Knepley   PetscScalar B_x = 0.0;
129265876a83SMatthew G. Knepley 
129365876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
129465876a83SMatthew G. Knepley   {
129565876a83SMatthew G. Knepley     PetscReal alpha_n = zeroArray[n-1];
129665876a83SMatthew G. Knepley 
129765876a83SMatthew G. Knepley     A_x += ( PetscSinReal(alpha_n) / (alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n))) * PetscCosReal( (alpha_n * x[0]) / aL) * PetscExpReal( -1.0*( (alpha_n*alpha_n*c*t)/(aL*aL)));
129865876a83SMatthew G. Knepley     B_x += ( (PetscSinReal(alpha_n) * PetscCosReal(alpha_n))/(alpha_n - PetscSinReal(alpha_n) * PetscCosReal(alpha_n))) * PetscExpReal( -1.0*( (alpha_n*alpha_n*c*t)/(aL*aL)));
129965876a83SMatthew G. Knepley   }
130065876a83SMatthew G. Knepley 
130165876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*(F/aL) - ((2.0*F)/aL) * (A2/A1) * A_x + ((2.0*F)/aL) * B_x;
130265876a83SMatthew G. Knepley 
130365876a83SMatthew G. Knepley   if (x[1] == ymax) {
130465876a83SMatthew G. Knepley     f0[1] += sigma_zz;
130565876a83SMatthew G. Knepley   } else if (x[1] == ymin) {
130665876a83SMatthew G. Knepley     f0[1] -= sigma_zz;
130765876a83SMatthew G. Knepley   }
130865876a83SMatthew G. Knepley }
130945480ffeSMatthew G. Knepley #endif
131065876a83SMatthew G. Knepley 
1311*9371c9d4SSatish Balay static void f0_cryer_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[]) {
131265876a83SMatthew G. Knepley   const PetscReal P_0 = PetscRealPart(constants[5]);
131365876a83SMatthew G. Knepley   PetscInt        d;
131465876a83SMatthew G. Knepley 
131565876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) f0[d] = -P_0 * n[d];
131665876a83SMatthew G. Knepley }
131765876a83SMatthew G. Knepley 
131865876a83SMatthew G. Knepley /* Standard Kernels - Residual */
131965876a83SMatthew G. Knepley /* f0_e */
1320*9371c9d4SSatish Balay static void f0_epsilon(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[]) {
132165876a83SMatthew G. Knepley   PetscInt d;
132265876a83SMatthew G. Knepley 
1323*9371c9d4SSatish Balay   for (d = 0; d < dim; ++d) { f0[0] += u_x[d * dim + d]; }
132465876a83SMatthew G. Knepley   f0[0] -= u[uOff[1]];
132565876a83SMatthew G. Knepley }
132665876a83SMatthew G. Knepley 
132765876a83SMatthew G. Knepley /* f0_p */
1328*9371c9d4SSatish Balay static void f0_p(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[]) {
132965876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
133065876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
133165876a83SMatthew G. Knepley 
133265876a83SMatthew G. Knepley   f0[0] += alpha * u_t[uOff[1]];
133365876a83SMatthew G. Knepley   f0[0] += u_t[uOff[2]] / M;
133430602db0SMatthew G. Knepley   if (f0[0] != f0[0]) abort();
133565876a83SMatthew G. Knepley }
133665876a83SMatthew G. Knepley 
133765876a83SMatthew G. Knepley /* f1_u */
1338*9371c9d4SSatish Balay static void f1_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[]) {
133965876a83SMatthew G. Knepley   const PetscInt  Nc     = dim;
134065876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
134165876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
134265876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
134365876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
134465876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
134565876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
134665876a83SMatthew G. Knepley   PetscInt        c, d;
134765876a83SMatthew G. Knepley 
1348*9371c9d4SSatish Balay   for (c = 0; c < Nc; ++c) {
1349*9371c9d4SSatish Balay     for (d = 0; d < dim; ++d) { f1[c * dim + d] -= G * (u_x[c * dim + d] + u_x[d * dim + c]); }
135065876a83SMatthew G. Knepley     f1[c * dim + c] -= lambda * u[uOff[1]];
135165876a83SMatthew G. Knepley     f1[c * dim + c] += alpha * u[uOff[2]];
135265876a83SMatthew G. Knepley   }
135365876a83SMatthew G. Knepley }
135465876a83SMatthew G. Knepley 
135565876a83SMatthew G. Knepley /* f1_p */
1356*9371c9d4SSatish Balay static void f1_p(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[]) {
135765876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
135865876a83SMatthew G. Knepley   PetscInt        d;
135965876a83SMatthew G. Knepley 
1360*9371c9d4SSatish Balay   for (d = 0; d < dim; ++d) { f1[d] += kappa * u_x[uOff_x[2] + d]; }
136165876a83SMatthew G. Knepley }
136265876a83SMatthew G. Knepley 
136365876a83SMatthew G. Knepley /*
136465876a83SMatthew G. Knepley   \partial_df \phi_fc g_{fc,gc,df,dg} \partial_dg \phi_gc
136565876a83SMatthew G. Knepley 
136665876a83SMatthew G. Knepley   \partial_df \phi_fc \lambda \delta_{fc,df} \sum_gc \partial_dg \phi_gc \delta_{gc,dg}
136765876a83SMatthew G. Knepley   = \partial_fc \phi_fc \sum_gc \partial_gc \phi_gc
136865876a83SMatthew G. Knepley */
136965876a83SMatthew G. Knepley 
137065876a83SMatthew G. Knepley /* Standard Kernels - Jacobian */
137165876a83SMatthew G. Knepley /* g0_ee */
1372*9371c9d4SSatish Balay static void g0_ee(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[]) {
137365876a83SMatthew G. Knepley   g0[0] = -1.0;
137465876a83SMatthew G. Knepley }
137565876a83SMatthew G. Knepley 
137665876a83SMatthew G. Knepley /* g0_pe */
1377*9371c9d4SSatish Balay static void g0_pe(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[]) {
137865876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
137965876a83SMatthew G. Knepley 
138065876a83SMatthew G. Knepley   g0[0] = u_tShift * alpha;
138165876a83SMatthew G. Knepley }
138265876a83SMatthew G. Knepley 
138365876a83SMatthew G. Knepley /* g0_pp */
1384*9371c9d4SSatish Balay static void g0_pp(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[]) {
138565876a83SMatthew G. Knepley   const PetscReal M = PetscRealPart(constants[3]);
138665876a83SMatthew G. Knepley 
138765876a83SMatthew G. Knepley   g0[0] = u_tShift / M;
138865876a83SMatthew G. Knepley }
138965876a83SMatthew G. Knepley 
139065876a83SMatthew G. Knepley /* g1_eu */
1391*9371c9d4SSatish Balay static void g1_eu(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 g1[]) {
139265876a83SMatthew G. Knepley   PetscInt d;
139365876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g1[d * dim + d] = 1.0; /* \frac{\partial\phi^{u_d}}{\partial x_d} */
139465876a83SMatthew G. Knepley }
139565876a83SMatthew G. Knepley 
139665876a83SMatthew G. Knepley /* g2_ue */
1397*9371c9d4SSatish Balay static void g2_ue(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 g2[]) {
139865876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
139965876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
140065876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
140165876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
140265876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
140365876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
140465876a83SMatthew G. Knepley   PetscInt        d;
140565876a83SMatthew G. Knepley 
1406*9371c9d4SSatish Balay   for (d = 0; d < dim; ++d) { g2[d * dim + d] -= lambda; }
140765876a83SMatthew G. Knepley }
140865876a83SMatthew G. Knepley /* g2_up */
1409*9371c9d4SSatish Balay static void g2_up(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 g2[]) {
141065876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
141165876a83SMatthew G. Knepley   PetscInt        d;
141265876a83SMatthew G. Knepley 
1413*9371c9d4SSatish Balay   for (d = 0; d < dim; ++d) { g2[d * dim + d] += alpha; }
141465876a83SMatthew G. Knepley }
141565876a83SMatthew G. Knepley 
141665876a83SMatthew G. Knepley /* g3_uu */
1417*9371c9d4SSatish Balay static void g3_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[]) {
141865876a83SMatthew G. Knepley   const PetscInt  Nc = dim;
141965876a83SMatthew G. Knepley   const PetscReal G  = PetscRealPart(constants[0]);
142065876a83SMatthew G. Knepley   PetscInt        c, d;
142165876a83SMatthew G. Knepley 
142265876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) {
142365876a83SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
142465876a83SMatthew G. Knepley       g3[((c * Nc + c) * dim + d) * dim + d] -= G;
142565876a83SMatthew G. Knepley       g3[((c * Nc + d) * dim + d) * dim + c] -= G;
142665876a83SMatthew G. Knepley     }
142765876a83SMatthew G. Knepley   }
142865876a83SMatthew G. Knepley }
142965876a83SMatthew G. Knepley 
143065876a83SMatthew G. Knepley /* g3_pp */
1431*9371c9d4SSatish Balay static void g3_pp(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[]) {
143265876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
143365876a83SMatthew G. Knepley   PetscInt        d;
143465876a83SMatthew G. Knepley 
143565876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g3[d * dim + d] += kappa;
143665876a83SMatthew G. Knepley }
143765876a83SMatthew G. Knepley 
1438*9371c9d4SSatish Balay static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) {
143965876a83SMatthew G. Knepley   PetscInt sol;
144065876a83SMatthew G. Knepley 
144165876a83SMatthew G. Knepley   PetscFunctionBeginUser;
144265876a83SMatthew G. Knepley   options->solType   = SOL_QUADRATIC_TRIG;
144365876a83SMatthew G. Knepley   options->niter     = 500;
144465876a83SMatthew G. Knepley   options->eps       = PETSC_SMALL;
144524b15d09SMatthew G. Knepley   options->dtInitial = -1.0;
1446d0609cedSBarry Smith   PetscOptionsBegin(comm, "", "Biot Poroelasticity Options", "DMPLEX");
14479566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-niter", "Number of series term iterations in exact solutions", "ex53.c", options->niter, &options->niter, NULL));
144865876a83SMatthew G. Knepley   sol = options->solType;
14499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-sol_type", "Type of exact solution", "ex53.c", solutionTypes, NUM_SOLUTION_TYPES, solutionTypes[options->solType], &sol, NULL));
145065876a83SMatthew G. Knepley   options->solType = (SolutionType)sol;
14519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-eps", "Precision value for root finding", "ex53.c", options->eps, &options->eps, NULL));
14529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-dt_initial", "Override the initial timestep", "ex53.c", options->dtInitial, &options->dtInitial, NULL));
1453d0609cedSBarry Smith   PetscOptionsEnd();
145465876a83SMatthew G. Knepley   PetscFunctionReturn(0);
145565876a83SMatthew G. Knepley }
145665876a83SMatthew G. Knepley 
1457*9371c9d4SSatish Balay static PetscErrorCode mandelZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param) {
145865876a83SMatthew G. Knepley   //PetscBag       bag;
145965876a83SMatthew G. Knepley   PetscReal a1, a2, am;
146065876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
146165876a83SMatthew G. Knepley 
146265876a83SMatthew G. Knepley   PetscFunctionBeginUser;
14639566063dSJacob Faibussowitsch   //PetscCall(PetscBagGetData(ctx->bag, (void **) &param));
146465876a83SMatthew G. Knepley   PetscInt    NITER = ctx->niter;
146565876a83SMatthew G. Knepley   PetscReal   EPS   = ctx->eps;
146665876a83SMatthew G. Knepley   //const PetscScalar YMAX = param->ymax;
146765876a83SMatthew G. Knepley   //const PetscScalar YMIN = param->ymin;
146865876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
146965876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
147065876a83SMatthew G. Knepley   PetscScalar M     = param->M;
147165876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
147265876a83SMatthew G. Knepley   //const PetscScalar k = param->k;
147365876a83SMatthew G. Knepley   //const PetscScalar mu_f = param->mu_f;
147465876a83SMatthew G. Knepley   //const PetscScalar P_0 = param->P_0;
147565876a83SMatthew G. Knepley 
147665876a83SMatthew G. Knepley   PetscScalar K_d  = K_u - alpha * alpha * M;
147765876a83SMatthew G. Knepley   PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
147865876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
147965876a83SMatthew G. Knepley   //const PetscScalar kappa = k / mu_f;
148065876a83SMatthew G. Knepley 
148165876a83SMatthew G. Knepley   // Generate zero values
1482*9371c9d4SSatish Balay   for (PetscInt i = 1; i < NITER + 1; i++) {
148365876a83SMatthew G. Knepley     a1 = ((PetscReal)i - 1.0) * PETSC_PI * PETSC_PI / 4.0 + EPS;
148465876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI / 2;
148565876a83SMatthew G. Knepley     am = a1;
1486*9371c9d4SSatish Balay     for (PetscInt j = 0; j < NITER; j++) {
148765876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * a1;
148865876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * a2;
148965876a83SMatthew G. Knepley       am = (a1 + a2) / 2.0;
149065876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * am;
1491*9371c9d4SSatish Balay       if ((ym * y1) > 0) {
149265876a83SMatthew G. Knepley         a1 = am;
149365876a83SMatthew G. Knepley       } else {
149465876a83SMatthew G. Knepley         a2 = am;
149565876a83SMatthew G. Knepley       }
1496*9371c9d4SSatish Balay       if (PetscAbsReal(y2) < EPS) { am = a2; }
149765876a83SMatthew G. Knepley     }
149865876a83SMatthew G. Knepley     ctx->zeroArray[i - 1] = am;
149965876a83SMatthew G. Knepley   }
150065876a83SMatthew G. Knepley   PetscFunctionReturn(0);
150165876a83SMatthew G. Knepley }
150265876a83SMatthew G. Knepley 
1503*9371c9d4SSatish Balay static PetscReal CryerFunction(PetscReal nu_u, PetscReal nu, PetscReal x) {
150465876a83SMatthew G. Knepley   return PetscTanReal(PetscSqrtReal(x)) * (6.0 * (nu_u - nu) - (1.0 - nu) * (1.0 + nu_u) * x) - (6.0 * (nu_u - nu) * PetscSqrtReal(x));
150565876a83SMatthew G. Knepley }
150665876a83SMatthew G. Knepley 
1507*9371c9d4SSatish Balay static PetscErrorCode cryerZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param) {
150865876a83SMatthew G. Knepley   PetscReal alpha = PetscRealPart(param->alpha); /* -  */
150965876a83SMatthew G. Knepley   PetscReal K_u   = PetscRealPart(param->K_u);   /* Pa */
151065876a83SMatthew G. Knepley   PetscReal M     = PetscRealPart(param->M);     /* Pa */
151165876a83SMatthew G. Knepley   PetscReal G     = PetscRealPart(param->mu);    /* Pa */
151265876a83SMatthew G. Knepley   PetscInt  N     = ctx->niter, n;
151365876a83SMatthew G. Knepley 
151465876a83SMatthew G. Knepley   PetscReal K_d  = K_u - alpha * alpha * M;                         /* Pa,      Cheng (B.5)  */
151565876a83SMatthew G. Knepley   PetscReal nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G)); /* -,       Cheng (B.8)  */
151665876a83SMatthew G. Knepley   PetscReal nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
151765876a83SMatthew G. Knepley 
151865876a83SMatthew G. Knepley   PetscFunctionBeginUser;
151965876a83SMatthew G. Knepley   for (n = 1; n < N + 1; ++n) {
152065876a83SMatthew G. Knepley     PetscReal tol = PetscPowReal(n, 1.5) * ctx->eps;
152165876a83SMatthew G. Knepley     PetscReal a1 = 0., a2 = 0., am = 0.;
152265876a83SMatthew G. Knepley     PetscReal y1, y2, ym;
152365876a83SMatthew G. Knepley     PetscInt  j, k = n - 1;
152465876a83SMatthew G. Knepley 
152565876a83SMatthew G. Knepley     y1 = y2 = 1.;
152665876a83SMatthew G. Knepley     while (y1 * y2 > 0) {
152765876a83SMatthew G. Knepley       ++k;
152865876a83SMatthew G. Knepley       a1 = PetscSqr(n * PETSC_PI) - k * PETSC_PI;
152965876a83SMatthew G. Knepley       a2 = PetscSqr(n * PETSC_PI) + k * PETSC_PI;
153065876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
153165876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
153265876a83SMatthew G. Knepley     }
153365876a83SMatthew G. Knepley     for (j = 0; j < 50000; ++j) {
153465876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
153565876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
153663a3b9bcSJacob Faibussowitsch       PetscCheck(y1 * y2 <= 0, comm, PETSC_ERR_PLIB, "Invalid root finding initialization for root %" PetscInt_FMT ", (%g, %g)--(%g, %g)", n, (double)a1, (double)y1, (double)a2, (double)y2);
153765876a83SMatthew G. Knepley       am = (a1 + a2) / 2.0;
153865876a83SMatthew G. Knepley       ym = CryerFunction(nu_u, nu, am);
153965876a83SMatthew G. Knepley       if ((ym * y1) < 0) a2 = am;
154065876a83SMatthew G. Knepley       else a1 = am;
154163a3b9bcSJacob Faibussowitsch       if (PetscAbsReal(ym) < tol) break;
154265876a83SMatthew G. Knepley     }
154363a3b9bcSJacob Faibussowitsch     PetscCheck(PetscAbsReal(ym) < tol, comm, PETSC_ERR_PLIB, "Root finding did not converge for root %" PetscInt_FMT " (%g)", n, (double)PetscAbsReal(ym));
154465876a83SMatthew G. Knepley     ctx->zeroArray[n - 1] = am;
154565876a83SMatthew G. Knepley   }
154665876a83SMatthew G. Knepley   PetscFunctionReturn(0);
154765876a83SMatthew G. Knepley }
154865876a83SMatthew G. Knepley 
1549*9371c9d4SSatish Balay static PetscErrorCode SetupParameters(MPI_Comm comm, AppCtx *ctx) {
155065876a83SMatthew G. Knepley   PetscBag   bag;
155165876a83SMatthew G. Knepley   Parameter *p;
155265876a83SMatthew G. Knepley 
155365876a83SMatthew G. Knepley   PetscFunctionBeginUser;
155465876a83SMatthew G. Knepley   /* setup PETSc parameter bag */
15559566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(ctx->bag, (void **)&p));
15569566063dSJacob Faibussowitsch   PetscCall(PetscBagSetName(ctx->bag, "par", "Poroelastic Parameters"));
155765876a83SMatthew G. Knepley   bag = ctx->bag;
155865876a83SMatthew G. Knepley   if (ctx->solType == SOL_TERZAGHI) {
155965876a83SMatthew G. Knepley     // Realistic values - Terzaghi
15609566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 3.0, "mu", "Shear Modulus, Pa"));
15619566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 9.76, "K_u", "Undrained Bulk Modulus, Pa"));
15629566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
15639566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 16.0, "M", "Biot Modulus, Pa"));
15649566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
15659566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
15669566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
156765876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_MANDEL) {
156865876a83SMatthew G. Knepley     // Realistic values - Mandel
15699566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 0.75, "mu", "Shear Modulus, Pa"));
15709566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 2.6941176470588233, "K_u", "Undrained Bulk Modulus, Pa"));
15719566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
15729566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 4.705882352941176, "M", "Biot Modulus, Pa"));
15739566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
15749566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
15759566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
157665876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_CRYER) {
157765876a83SMatthew G. Knepley     // Realistic values - Mandel
15789566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 0.75, "mu", "Shear Modulus, Pa"));
15799566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 2.6941176470588233, "K_u", "Undrained Bulk Modulus, Pa"));
15809566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
15819566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 4.705882352941176, "M", "Biot Modulus, Pa"));
15829566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
15839566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
15849566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
158565876a83SMatthew G. Knepley   } else {
158665876a83SMatthew G. Knepley     // Nonsense values
15879566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 1.0, "mu", "Shear Modulus, Pa"));
15889566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 1.0, "K_u", "Undrained Bulk Modulus, Pa"));
15899566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 1.0, "alpha", "Biot Effective Stress Coefficient, -"));
15909566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 1.0, "M", "Biot Modulus, Pa"));
15919566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.0, "k", "Isotropic Permeability, m**2"));
15929566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
15939566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
159465876a83SMatthew G. Knepley   }
15959566063dSJacob Faibussowitsch   PetscCall(PetscBagSetFromOptions(bag));
159665876a83SMatthew G. Knepley   {
159765876a83SMatthew G. Knepley     PetscScalar K_d  = p->K_u - p->alpha * p->alpha * p->M;
159865876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * p->K_u - 2.0 * p->mu) / (2.0 * (3.0 * p->K_u + p->mu));
159965876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * p->mu) / (2.0 * (3.0 * K_d + p->mu));
160065876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * p->K_u + 4.0 * p->mu) / (p->M * (3.0 * K_d + 4.0 * p->mu));
160165876a83SMatthew G. Knepley     PetscReal   c    = PetscRealPart((p->k / p->mu_f) / S);
160265876a83SMatthew G. Knepley 
160365876a83SMatthew G. Knepley     PetscViewer       viewer;
160465876a83SMatthew G. Knepley     PetscViewerFormat format;
160565876a83SMatthew G. Knepley     PetscBool         flg;
160665876a83SMatthew G. Knepley 
160765876a83SMatthew G. Knepley     switch (ctx->solType) {
160865876a83SMatthew G. Knepley     case SOL_QUADRATIC_LINEAR:
160965876a83SMatthew G. Knepley     case SOL_QUADRATIC_TRIG:
161030602db0SMatthew G. Knepley     case SOL_TRIG_LINEAR: ctx->t_r = PetscSqr(ctx->xmax[0] - ctx->xmin[0]) / c; break;
161130602db0SMatthew G. Knepley     case SOL_TERZAGHI: ctx->t_r = PetscSqr(2.0 * (ctx->xmax[1] - ctx->xmin[1])) / c; break;
161230602db0SMatthew G. Knepley     case SOL_MANDEL: ctx->t_r = PetscSqr(2.0 * (ctx->xmax[1] - ctx->xmin[1])) / c; break;
161330602db0SMatthew G. Knepley     case SOL_CRYER: ctx->t_r = PetscSqr(ctx->xmax[1]) / c; break;
161463a3b9bcSJacob Faibussowitsch     default: SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%d)", solutionTypes[PetscMin(ctx->solType, NUM_SOLUTION_TYPES)], ctx->solType);
161565876a83SMatthew G. Knepley     }
16169566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(comm, NULL, NULL, "-param_view", &viewer, &format, &flg));
161765876a83SMatthew G. Knepley     if (flg) {
16189566063dSJacob Faibussowitsch       PetscCall(PetscViewerPushFormat(viewer, format));
16199566063dSJacob Faibussowitsch       PetscCall(PetscBagView(bag, viewer));
16209566063dSJacob Faibussowitsch       PetscCall(PetscViewerFlush(viewer));
16219566063dSJacob Faibussowitsch       PetscCall(PetscViewerPopFormat(viewer));
16229566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&viewer));
162363a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "  Max displacement: %g %g\n", (double)PetscRealPart(p->P_0 * (ctx->xmax[1] - ctx->xmin[1]) * (1. - 2. * nu_u) / (2. * p->mu * (1. - nu_u))), (double)PetscRealPart(p->P_0 * (ctx->xmax[1] - ctx->xmin[1]) * (1. - 2. * nu) / (2. * p->mu * (1. - nu)))));
162463a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "  Relaxation time: %g\n", (double)ctx->t_r));
162565876a83SMatthew G. Knepley     }
162665876a83SMatthew G. Knepley   }
162765876a83SMatthew G. Knepley   PetscFunctionReturn(0);
162865876a83SMatthew G. Knepley }
162965876a83SMatthew G. Knepley 
1630*9371c9d4SSatish Balay static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) {
163165876a83SMatthew G. Knepley   PetscFunctionBeginUser;
16329566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
16339566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMPLEX));
16349566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(*dm));
16359566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(*dm, user));
16369566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
16379566063dSJacob Faibussowitsch   PetscCall(DMGetBoundingBox(*dm, user->xmin, user->xmax));
163865876a83SMatthew G. Knepley   PetscFunctionReturn(0);
163965876a83SMatthew G. Knepley }
164065876a83SMatthew G. Knepley 
1641*9371c9d4SSatish Balay static PetscErrorCode SetupPrimalProblem(DM dm, AppCtx *user) {
164265876a83SMatthew G. Knepley   PetscErrorCode (*exact[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
164365876a83SMatthew G. Knepley   PetscErrorCode (*exact_t[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
164445480ffeSMatthew G. Knepley   PetscDS       ds;
164545480ffeSMatthew G. Knepley   DMLabel       label;
164645480ffeSMatthew G. Knepley   PetscWeakForm wf;
164765876a83SMatthew G. Knepley   Parameter    *param;
164865876a83SMatthew G. Knepley   PetscInt      id_mandel[2];
164965876a83SMatthew G. Knepley   PetscInt      comp[1];
165065876a83SMatthew G. Knepley   PetscInt      comp_mandel[2];
165145480ffeSMatthew G. Knepley   PetscInt      dim, id, bd, f;
165265876a83SMatthew G. Knepley 
165365876a83SMatthew G. Knepley   PetscFunctionBeginUser;
16549566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "marker", &label));
16559566063dSJacob Faibussowitsch   PetscCall(DMGetDS(dm, &ds));
16569566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(ds, &dim));
16579566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
165865876a83SMatthew G. Knepley   exact_t[0] = exact_t[1] = exact_t[2] = zero;
165965876a83SMatthew G. Knepley 
166065876a83SMatthew G. Knepley   /* Setup Problem Formulation and Boundary Conditions */
166165876a83SMatthew G. Knepley   switch (user->solType) {
166265876a83SMatthew G. Knepley   case SOL_QUADRATIC_LINEAR:
16639566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_quadratic_linear_u, f1_u));
16649566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
16659566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_quadratic_linear_p, f1_p));
16669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
16679566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
16689566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
16699566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
16709566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
16719566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
16729566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
167365876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
167465876a83SMatthew G. Knepley     exact[1]   = linear_eps;
167565876a83SMatthew G. Knepley     exact[2]   = linear_linear_p;
167665876a83SMatthew G. Knepley     exact_t[2] = linear_linear_p_t;
167765876a83SMatthew G. Knepley 
167865876a83SMatthew G. Knepley     id = 1;
16799566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
16809566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure", label, 1, &id, 2, 0, NULL, (void (*)(void))exact[2], (void (*)(void))exact_t[2], user, NULL));
168165876a83SMatthew G. Knepley     break;
168265876a83SMatthew G. Knepley   case SOL_TRIG_LINEAR:
16839566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_trig_linear_u, f1_u));
16849566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
16859566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_trig_linear_p, f1_p));
16869566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
16879566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
16889566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
16899566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
16909566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
16919566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
16929566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
169365876a83SMatthew G. Knepley     exact[0]   = trig_u;
169465876a83SMatthew G. Knepley     exact[1]   = trig_eps;
169565876a83SMatthew G. Knepley     exact[2]   = trig_linear_p;
169665876a83SMatthew G. Knepley     exact_t[2] = trig_linear_p_t;
169765876a83SMatthew G. Knepley 
169865876a83SMatthew G. Knepley     id = 1;
16999566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
17009566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure", label, 1, &id, 2, 0, NULL, (void (*)(void))exact[2], (void (*)(void))exact_t[2], user, NULL));
170165876a83SMatthew G. Knepley     break;
170265876a83SMatthew G. Knepley   case SOL_QUADRATIC_TRIG:
17039566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_quadratic_trig_u, f1_u));
17049566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17059566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_quadratic_trig_p, f1_p));
17069566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17079566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17089566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17099566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17109566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17119566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17129566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
171365876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
171465876a83SMatthew G. Knepley     exact[1]   = linear_eps;
171565876a83SMatthew G. Knepley     exact[2]   = linear_trig_p;
171665876a83SMatthew G. Knepley     exact_t[2] = linear_trig_p_t;
171765876a83SMatthew G. Knepley 
171865876a83SMatthew G. Knepley     id = 1;
17199566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
17209566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure", label, 1, &id, 2, 0, NULL, (void (*)(void))exact[2], (void (*)(void))exact_t[2], user, NULL));
172165876a83SMatthew G. Knepley     break;
172265876a83SMatthew G. Knepley   case SOL_TERZAGHI:
17239566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_u));
17249566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17259566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_p, f1_p));
17269566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17279566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17289566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17299566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17309566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17319566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17329566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
173365876a83SMatthew G. Knepley 
173465876a83SMatthew G. Knepley     exact[0]   = terzaghi_2d_u;
173565876a83SMatthew G. Knepley     exact[1]   = terzaghi_2d_eps;
173665876a83SMatthew G. Knepley     exact[2]   = terzaghi_2d_p;
173765876a83SMatthew G. Knepley     exact_t[0] = terzaghi_2d_u_t;
173865876a83SMatthew G. Knepley     exact_t[1] = terzaghi_2d_eps_t;
173965876a83SMatthew G. Knepley     exact_t[2] = terzaghi_2d_p_t;
174065876a83SMatthew G. Knepley 
174165876a83SMatthew G. Knepley     id = 1;
17429566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", label, 1, &id, 0, 0, NULL, NULL, NULL, user, &bd));
17439566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
17449566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, 0, f0_terzaghi_bd_u, 0, NULL));
174545480ffeSMatthew G. Knepley 
174665876a83SMatthew G. Knepley     id      = 3;
174765876a83SMatthew G. Knepley     comp[0] = 1;
17489566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
174965876a83SMatthew G. Knepley     id      = 2;
175065876a83SMatthew G. Knepley     comp[0] = 0;
17519566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
175265876a83SMatthew G. Knepley     id      = 4;
175365876a83SMatthew G. Knepley     comp[0] = 0;
17549566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
175565876a83SMatthew G. Knepley     id = 1;
17569566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 1, &id, 2, 0, NULL, (void (*)(void))terzaghi_drainage_pressure, NULL, user, NULL));
175765876a83SMatthew G. Knepley     break;
175865876a83SMatthew G. Knepley   case SOL_MANDEL:
17599566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_u));
17609566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17619566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_p, f1_p));
17629566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17639566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17649566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17659566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17679566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17689566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
176965876a83SMatthew G. Knepley 
17709566063dSJacob Faibussowitsch     PetscCall(mandelZeros(PETSC_COMM_WORLD, user, param));
177165876a83SMatthew G. Knepley 
177265876a83SMatthew G. Knepley     exact[0]   = mandel_2d_u;
177365876a83SMatthew G. Knepley     exact[1]   = mandel_2d_eps;
177465876a83SMatthew G. Knepley     exact[2]   = mandel_2d_p;
177565876a83SMatthew G. Knepley     exact_t[0] = mandel_2d_u_t;
177665876a83SMatthew G. Knepley     exact_t[1] = mandel_2d_eps_t;
177765876a83SMatthew G. Knepley     exact_t[2] = mandel_2d_p_t;
177865876a83SMatthew G. Knepley 
177965876a83SMatthew G. Knepley     id_mandel[0]   = 3;
178065876a83SMatthew G. Knepley     id_mandel[1]   = 1;
178165876a83SMatthew G. Knepley     //comp[0] = 1;
178265876a83SMatthew G. Knepley     comp_mandel[0] = 0;
178365876a83SMatthew G. Knepley     comp_mandel[1] = 1;
17849566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "vertical stress", label, 2, id_mandel, 0, 2, comp_mandel, (void (*)(void))mandel_2d_u, NULL, user, NULL));
17859566063dSJacob Faibussowitsch     //PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", "marker", 0, 1, comp, NULL, 2, id_mandel, user));
17869566063dSJacob Faibussowitsch     //PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", "marker", 0, 1, comp, (void (*)(void)) zero, 2, id_mandel, user));
17879566063dSJacob Faibussowitsch     //PetscCall(PetscDSSetBdResidual(ds, 0, f0_mandel_bd_u, NULL));
178865876a83SMatthew G. Knepley 
178965876a83SMatthew G. Knepley     id_mandel[0] = 2;
179065876a83SMatthew G. Knepley     id_mandel[1] = 4;
17919566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 2, id_mandel, 2, 0, NULL, (void (*)(void))zero, NULL, user, NULL));
179265876a83SMatthew G. Knepley     break;
179365876a83SMatthew G. Knepley   case SOL_CRYER:
17949566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_u));
17959566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17969566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_p, f1_p));
17979566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17989566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17999566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
18009566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
18019566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
18029566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
18039566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
180465876a83SMatthew G. Knepley 
18059566063dSJacob Faibussowitsch     PetscCall(cryerZeros(PETSC_COMM_WORLD, user, param));
180665876a83SMatthew G. Knepley 
180765876a83SMatthew G. Knepley     exact[0] = cryer_3d_u;
180865876a83SMatthew G. Knepley     exact[1] = cryer_3d_eps;
180965876a83SMatthew G. Knepley     exact[2] = cryer_3d_p;
181065876a83SMatthew G. Knepley 
181165876a83SMatthew G. Knepley     id = 1;
18129566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "normal stress", label, 1, &id, 0, 0, NULL, NULL, NULL, user, &bd));
18139566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
18149566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, 0, f0_cryer_bd_u, 0, NULL));
181545480ffeSMatthew G. Knepley 
18169566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 1, &id, 2, 0, NULL, (void (*)(void))cryer_drainage_pressure, NULL, user, NULL));
181765876a83SMatthew G. Knepley     break;
181863a3b9bcSJacob Faibussowitsch   default: SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%d)", solutionTypes[PetscMin(user->solType, NUM_SOLUTION_TYPES)], user->solType);
181965876a83SMatthew G. Knepley   }
182065876a83SMatthew G. Knepley   for (f = 0; f < 3; ++f) {
18219566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(ds, f, exact[f], user));
18229566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(ds, f, exact_t[f], user));
182365876a83SMatthew G. Knepley   }
182465876a83SMatthew G. Knepley 
182565876a83SMatthew G. Knepley   /* Setup constants */
182665876a83SMatthew G. Knepley   {
182765876a83SMatthew G. Knepley     PetscScalar constants[6];
182865876a83SMatthew G. Knepley     constants[0] = param->mu;              /* shear modulus, Pa */
182965876a83SMatthew G. Knepley     constants[1] = param->K_u;             /* undrained bulk modulus, Pa */
183065876a83SMatthew G. Knepley     constants[2] = param->alpha;           /* Biot effective stress coefficient, - */
183165876a83SMatthew G. Knepley     constants[3] = param->M;               /* Biot modulus, Pa */
183265876a83SMatthew G. Knepley     constants[4] = param->k / param->mu_f; /* Darcy coefficient, m**2 / Pa*s */
183365876a83SMatthew G. Knepley     constants[5] = param->P_0;             /* Magnitude of Vertical Stress, Pa */
18349566063dSJacob Faibussowitsch     PetscCall(PetscDSSetConstants(ds, 6, constants));
183565876a83SMatthew G. Knepley   }
183665876a83SMatthew G. Knepley   PetscFunctionReturn(0);
183765876a83SMatthew G. Knepley }
183865876a83SMatthew G. Knepley 
1839*9371c9d4SSatish Balay static PetscErrorCode CreateElasticityNullSpace(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullspace) {
18407510d9b0SBarry Smith   PetscFunctionBeginUser;
18419566063dSJacob Faibussowitsch   PetscCall(DMPlexCreateRigidBody(dm, origField, nullspace));
184265876a83SMatthew G. Knepley   PetscFunctionReturn(0);
184365876a83SMatthew G. Knepley }
184465876a83SMatthew G. Knepley 
1845*9371c9d4SSatish Balay static PetscErrorCode SetupFE(DM dm, PetscInt Nf, PetscInt Nc[], const char *name[], PetscErrorCode (*setup)(DM, AppCtx *), void *ctx) {
184665876a83SMatthew G. Knepley   AppCtx         *user = (AppCtx *)ctx;
184765876a83SMatthew G. Knepley   DM              cdm  = dm;
184865876a83SMatthew G. Knepley   PetscFE         fe;
184965876a83SMatthew G. Knepley   PetscQuadrature q = NULL;
185065876a83SMatthew G. Knepley   char            prefix[PETSC_MAX_PATH_LEN];
185165876a83SMatthew G. Knepley   PetscInt        dim, f;
185230602db0SMatthew G. Knepley   PetscBool       simplex;
185365876a83SMatthew G. Knepley 
18547510d9b0SBarry Smith   PetscFunctionBeginUser;
185565876a83SMatthew G. Knepley   /* Create finite element */
18569566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
18579566063dSJacob Faibussowitsch   PetscCall(DMPlexIsSimplex(dm, &simplex));
185865876a83SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
18599566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(prefix, PETSC_MAX_PATH_LEN, "%s_", name[f]));
18609566063dSJacob Faibussowitsch     PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, Nc[f], simplex, name[f] ? prefix : NULL, -1, &fe));
18619566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetName((PetscObject)fe, name[f]));
18629566063dSJacob Faibussowitsch     if (!q) PetscCall(PetscFEGetQuadrature(fe, &q));
18639566063dSJacob Faibussowitsch     PetscCall(PetscFESetQuadrature(fe, q));
18649566063dSJacob Faibussowitsch     PetscCall(DMSetField(dm, f, NULL, (PetscObject)fe));
18659566063dSJacob Faibussowitsch     PetscCall(PetscFEDestroy(&fe));
186665876a83SMatthew G. Knepley   }
18679566063dSJacob Faibussowitsch   PetscCall(DMCreateDS(dm));
18689566063dSJacob Faibussowitsch   PetscCall((*setup)(dm, user));
186965876a83SMatthew G. Knepley   while (cdm) {
18709566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(dm, cdm));
18719566063dSJacob Faibussowitsch     if (0) PetscCall(DMSetNearNullSpaceConstructor(cdm, 0, CreateElasticityNullSpace));
187265876a83SMatthew G. Knepley     /* TODO: Check whether the boundary of coarse meshes is marked */
18739566063dSJacob Faibussowitsch     PetscCall(DMGetCoarseDM(cdm, &cdm));
187465876a83SMatthew G. Knepley   }
18759566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&fe));
187665876a83SMatthew G. Knepley   PetscFunctionReturn(0);
187765876a83SMatthew G. Knepley }
187865876a83SMatthew G. Knepley 
1879*9371c9d4SSatish Balay static PetscErrorCode SetInitialConditions(TS ts, Vec u) {
188065876a83SMatthew G. Knepley   DM        dm;
188165876a83SMatthew G. Knepley   PetscReal t;
188265876a83SMatthew G. Knepley 
18837510d9b0SBarry Smith   PetscFunctionBeginUser;
18849566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
18859566063dSJacob Faibussowitsch   PetscCall(TSGetTime(ts, &t));
188665876a83SMatthew G. Knepley   if (t <= 0.0) {
188765876a83SMatthew G. Knepley     PetscErrorCode (*funcs[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
188865876a83SMatthew G. Knepley     void   *ctxs[3];
188965876a83SMatthew G. Knepley     AppCtx *ctx;
189065876a83SMatthew G. Knepley 
18919566063dSJacob Faibussowitsch     PetscCall(DMGetApplicationContext(dm, &ctx));
189265876a83SMatthew G. Knepley     switch (ctx->solType) {
189365876a83SMatthew G. Knepley     case SOL_TERZAGHI:
1894*9371c9d4SSatish Balay       funcs[0] = terzaghi_initial_u;
1895*9371c9d4SSatish Balay       ctxs[0]  = ctx;
1896*9371c9d4SSatish Balay       funcs[1] = terzaghi_initial_eps;
1897*9371c9d4SSatish Balay       ctxs[1]  = ctx;
1898*9371c9d4SSatish Balay       funcs[2] = terzaghi_drainage_pressure;
1899*9371c9d4SSatish Balay       ctxs[2]  = ctx;
19009566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
190165876a83SMatthew G. Knepley       break;
190265876a83SMatthew G. Knepley     case SOL_MANDEL:
1903*9371c9d4SSatish Balay       funcs[0] = mandel_initial_u;
1904*9371c9d4SSatish Balay       ctxs[0]  = ctx;
1905*9371c9d4SSatish Balay       funcs[1] = mandel_initial_eps;
1906*9371c9d4SSatish Balay       ctxs[1]  = ctx;
1907*9371c9d4SSatish Balay       funcs[2] = mandel_drainage_pressure;
1908*9371c9d4SSatish Balay       ctxs[2]  = ctx;
19099566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
191065876a83SMatthew G. Knepley       break;
191165876a83SMatthew G. Knepley     case SOL_CRYER:
1912*9371c9d4SSatish Balay       funcs[0] = cryer_initial_u;
1913*9371c9d4SSatish Balay       ctxs[0]  = ctx;
1914*9371c9d4SSatish Balay       funcs[1] = cryer_initial_eps;
1915*9371c9d4SSatish Balay       ctxs[1]  = ctx;
1916*9371c9d4SSatish Balay       funcs[2] = cryer_drainage_pressure;
1917*9371c9d4SSatish Balay       ctxs[2]  = ctx;
19189566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
191965876a83SMatthew G. Knepley       break;
1920*9371c9d4SSatish Balay     default: PetscCall(DMComputeExactSolution(dm, t, u, NULL));
192165876a83SMatthew G. Knepley     }
192265876a83SMatthew G. Knepley   } else {
19239566063dSJacob Faibussowitsch     PetscCall(DMComputeExactSolution(dm, t, u, NULL));
192465876a83SMatthew G. Knepley   }
192565876a83SMatthew G. Knepley   PetscFunctionReturn(0);
192665876a83SMatthew G. Knepley }
192765876a83SMatthew G. Knepley 
192865876a83SMatthew G. Knepley /* Need to create Viewer each time because HDF5 can get corrupted */
1929*9371c9d4SSatish Balay static PetscErrorCode SolutionMonitor(TS ts, PetscInt steps, PetscReal time, Vec u, void *mctx) {
193065876a83SMatthew G. Knepley   DM                dm;
193165876a83SMatthew G. Knepley   Vec               exact;
193265876a83SMatthew G. Knepley   PetscViewer       viewer;
193365876a83SMatthew G. Knepley   PetscViewerFormat format;
193465876a83SMatthew G. Knepley   PetscOptions      options;
193565876a83SMatthew G. Knepley   const char       *prefix;
193665876a83SMatthew G. Knepley 
19377510d9b0SBarry Smith   PetscFunctionBeginUser;
19389566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
19399566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptions((PetscObject)ts, &options));
19409566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, &prefix));
19419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), options, prefix, "-monitor_solution", &viewer, &format, NULL));
19429566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &exact));
19439566063dSJacob Faibussowitsch   PetscCall(DMComputeExactSolution(dm, time, exact, NULL));
19449566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, steps, time));
19459566063dSJacob Faibussowitsch   PetscCall(VecView(exact, viewer));
19469566063dSJacob Faibussowitsch   PetscCall(VecView(u, viewer));
19479566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &exact));
194865876a83SMatthew G. Knepley   {
194965876a83SMatthew G. Knepley     PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx);
195065876a83SMatthew G. Knepley     void     **ectxs;
195165876a83SMatthew G. Knepley     PetscReal *err;
195265876a83SMatthew G. Knepley     PetscInt   Nf, f;
195365876a83SMatthew G. Knepley 
19549566063dSJacob Faibussowitsch     PetscCall(DMGetNumFields(dm, &Nf));
19559566063dSJacob Faibussowitsch     PetscCall(PetscCalloc3(Nf, &exacts, Nf, &ectxs, PetscMax(1, Nf), &err));
195665876a83SMatthew G. Knepley     {
195765876a83SMatthew G. Knepley       PetscInt Nds, s;
195865876a83SMatthew G. Knepley 
19599566063dSJacob Faibussowitsch       PetscCall(DMGetNumDS(dm, &Nds));
196065876a83SMatthew G. Knepley       for (s = 0; s < Nds; ++s) {
196165876a83SMatthew G. Knepley         PetscDS         ds;
196265876a83SMatthew G. Knepley         DMLabel         label;
196365876a83SMatthew G. Knepley         IS              fieldIS;
196465876a83SMatthew G. Knepley         const PetscInt *fields;
196565876a83SMatthew G. Knepley         PetscInt        dsNf, f;
196665876a83SMatthew G. Knepley 
19679566063dSJacob Faibussowitsch         PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds));
19689566063dSJacob Faibussowitsch         PetscCall(PetscDSGetNumFields(ds, &dsNf));
19699566063dSJacob Faibussowitsch         PetscCall(ISGetIndices(fieldIS, &fields));
197065876a83SMatthew G. Knepley         for (f = 0; f < dsNf; ++f) {
197165876a83SMatthew G. Knepley           const PetscInt field = fields[f];
19729566063dSJacob Faibussowitsch           PetscCall(PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]));
197365876a83SMatthew G. Knepley         }
19749566063dSJacob Faibussowitsch         PetscCall(ISRestoreIndices(fieldIS, &fields));
197565876a83SMatthew G. Knepley       }
197665876a83SMatthew G. Knepley     }
19779566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, time, exacts, ectxs, u, err));
197863a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "Time: %g L_2 Error: [", (double)time));
197965876a83SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
19809566063dSJacob Faibussowitsch       if (f) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), ", "));
19819566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%g", (double)err[f]));
198265876a83SMatthew G. Knepley     }
19839566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "]\n"));
19849566063dSJacob Faibussowitsch     PetscCall(PetscFree3(exacts, ectxs, err));
198565876a83SMatthew G. Knepley   }
19869566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
198765876a83SMatthew G. Knepley   PetscFunctionReturn(0);
198865876a83SMatthew G. Knepley }
198965876a83SMatthew G. Knepley 
1990*9371c9d4SSatish Balay static PetscErrorCode SetupMonitor(TS ts, AppCtx *ctx) {
199165876a83SMatthew G. Knepley   PetscViewer       viewer;
199265876a83SMatthew G. Knepley   PetscViewerFormat format;
199365876a83SMatthew G. Knepley   PetscOptions      options;
199465876a83SMatthew G. Knepley   const char       *prefix;
199565876a83SMatthew G. Knepley   PetscBool         flg;
199665876a83SMatthew G. Knepley 
19977510d9b0SBarry Smith   PetscFunctionBeginUser;
19989566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptions((PetscObject)ts, &options));
19999566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, &prefix));
20009566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), options, prefix, "-monitor_solution", &viewer, &format, &flg));
20019566063dSJacob Faibussowitsch   if (flg) PetscCall(TSMonitorSet(ts, SolutionMonitor, ctx, NULL));
20029566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
200365876a83SMatthew G. Knepley   PetscFunctionReturn(0);
200465876a83SMatthew G. Knepley }
200565876a83SMatthew G. Knepley 
2006*9371c9d4SSatish Balay static PetscErrorCode TSAdaptChoose_Terzaghi(TSAdapt adapt, TS ts, PetscReal h, PetscInt *next_sc, PetscReal *next_h, PetscBool *accept, PetscReal *wlte, PetscReal *wltea, PetscReal *wlter) {
200765876a83SMatthew G. Knepley   static PetscReal dtTarget = -1.0;
200865876a83SMatthew G. Knepley   PetscReal        dtInitial;
200965876a83SMatthew G. Knepley   DM               dm;
201065876a83SMatthew G. Knepley   AppCtx          *ctx;
201165876a83SMatthew G. Knepley   PetscInt         step;
201265876a83SMatthew G. Knepley 
20137510d9b0SBarry Smith   PetscFunctionBeginUser;
20149566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
20159566063dSJacob Faibussowitsch   PetscCall(DMGetApplicationContext(dm, &ctx));
20169566063dSJacob Faibussowitsch   PetscCall(TSGetStepNumber(ts, &step));
201724b15d09SMatthew G. Knepley   dtInitial = ctx->dtInitial < 0.0 ? 1.0e-4 * ctx->t_r : ctx->dtInitial;
201865876a83SMatthew G. Knepley   if (!step) {
201965876a83SMatthew G. Knepley     if (PetscAbsReal(dtInitial - h) > PETSC_SMALL) {
202065876a83SMatthew G. Knepley       *accept  = PETSC_FALSE;
202165876a83SMatthew G. Knepley       *next_h  = dtInitial;
202265876a83SMatthew G. Knepley       dtTarget = h;
202365876a83SMatthew G. Knepley     } else {
202465876a83SMatthew G. Knepley       *accept  = PETSC_TRUE;
202565876a83SMatthew G. Knepley       *next_h  = dtTarget < 0.0 ? dtInitial : dtTarget;
202665876a83SMatthew G. Knepley       dtTarget = -1.0;
202765876a83SMatthew G. Knepley     }
202865876a83SMatthew G. Knepley   } else {
202965876a83SMatthew G. Knepley     *accept = PETSC_TRUE;
203065876a83SMatthew G. Knepley     *next_h = h;
203165876a83SMatthew G. Knepley   }
203265876a83SMatthew G. Knepley   *next_sc = 0;  /* Reuse the same order scheme */
203365876a83SMatthew G. Knepley   *wlte    = -1; /* Weighted local truncation error was not evaluated */
203465876a83SMatthew G. Knepley   *wltea   = -1; /* Weighted absolute local truncation error was not evaluated */
203565876a83SMatthew G. Knepley   *wlter   = -1; /* Weighted relative local truncation error was not evaluated */
203665876a83SMatthew G. Knepley   PetscFunctionReturn(0);
203765876a83SMatthew G. Knepley }
203865876a83SMatthew G. Knepley 
2039*9371c9d4SSatish Balay int main(int argc, char **argv) {
204065876a83SMatthew G. Knepley   AppCtx      ctx; /* User-defined work context */
204165876a83SMatthew G. Knepley   DM          dm;  /* Problem specification */
204265876a83SMatthew G. Knepley   TS          ts;  /* Time Series / Nonlinear solver */
204365876a83SMatthew G. Knepley   Vec         u;   /* Solutions */
204465876a83SMatthew G. Knepley   const char *name[3] = {"displacement", "tracestrain", "pressure"};
204565876a83SMatthew G. Knepley   PetscReal   t;
204630602db0SMatthew G. Knepley   PetscInt    dim, Nc[3];
204765876a83SMatthew G. Knepley 
2048327415f7SBarry Smith   PetscFunctionBeginUser;
20499566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
20509566063dSJacob Faibussowitsch   PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx));
20519566063dSJacob Faibussowitsch   PetscCall(PetscBagCreate(PETSC_COMM_SELF, sizeof(Parameter), &ctx.bag));
20529566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx.niter, &ctx.zeroArray));
20539566063dSJacob Faibussowitsch   PetscCall(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm));
20549566063dSJacob Faibussowitsch   PetscCall(SetupParameters(PETSC_COMM_WORLD, &ctx));
205565876a83SMatthew G. Knepley   /* Primal System */
20569566063dSJacob Faibussowitsch   PetscCall(TSCreate(PETSC_COMM_WORLD, &ts));
20579566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(dm, &ctx));
20589566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts, dm));
205965876a83SMatthew G. Knepley 
20609566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
206130602db0SMatthew G. Knepley   Nc[0] = dim;
206265876a83SMatthew G. Knepley   Nc[1] = 1;
206365876a83SMatthew G. Knepley   Nc[2] = 1;
206465876a83SMatthew G. Knepley 
20659566063dSJacob Faibussowitsch   PetscCall(SetupFE(dm, 3, Nc, name, SetupPrimalProblem, &ctx));
20669566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(dm, &u));
20679566063dSJacob Faibussowitsch   PetscCall(DMTSSetBoundaryLocal(dm, DMPlexTSComputeBoundary, &ctx));
20689566063dSJacob Faibussowitsch   PetscCall(DMTSSetIFunctionLocal(dm, DMPlexTSComputeIFunctionFEM, &ctx));
20699566063dSJacob Faibussowitsch   PetscCall(DMTSSetIJacobianLocal(dm, DMPlexTSComputeIJacobianFEM, &ctx));
20709566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP));
20719566063dSJacob Faibussowitsch   PetscCall(TSSetFromOptions(ts));
20729566063dSJacob Faibussowitsch   PetscCall(TSSetComputeInitialCondition(ts, SetInitialConditions));
20739566063dSJacob Faibussowitsch   PetscCall(SetupMonitor(ts, &ctx));
207465876a83SMatthew G. Knepley 
207565876a83SMatthew G. Knepley   if (ctx.solType != SOL_QUADRATIC_TRIG) {
207665876a83SMatthew G. Knepley     TSAdapt adapt;
207765876a83SMatthew G. Knepley 
20789566063dSJacob Faibussowitsch     PetscCall(TSGetAdapt(ts, &adapt));
207965876a83SMatthew G. Knepley     adapt->ops->choose = TSAdaptChoose_Terzaghi;
208065876a83SMatthew G. Knepley   }
208165876a83SMatthew G. Knepley   if (ctx.solType == SOL_CRYER) {
208265876a83SMatthew G. Knepley     Mat          J;
208365876a83SMatthew G. Knepley     MatNullSpace sp;
208465876a83SMatthew G. Knepley 
20859566063dSJacob Faibussowitsch     PetscCall(TSSetUp(ts));
20869566063dSJacob Faibussowitsch     PetscCall(TSGetIJacobian(ts, &J, NULL, NULL, NULL));
20879566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateRigidBody(dm, 0, &sp));
20889566063dSJacob Faibussowitsch     PetscCall(MatSetNullSpace(J, sp));
20899566063dSJacob Faibussowitsch     PetscCall(MatNullSpaceDestroy(&sp));
209065876a83SMatthew G. Knepley   }
20919566063dSJacob Faibussowitsch   PetscCall(TSGetTime(ts, &t));
20929566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, 0, t));
20939566063dSJacob Faibussowitsch   PetscCall(DMTSCheckFromOptions(ts, u));
20949566063dSJacob Faibussowitsch   PetscCall(SetInitialConditions(ts, u));
20959566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)u, "solution"));
20969566063dSJacob Faibussowitsch   PetscCall(TSSolve(ts, u));
20979566063dSJacob Faibussowitsch   PetscCall(DMTSCheckFromOptions(ts, u));
20989566063dSJacob Faibussowitsch   PetscCall(TSGetSolution(ts, &u));
20999566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
210065876a83SMatthew G. Knepley 
210165876a83SMatthew G. Knepley   /* Cleanup */
21029566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&u));
21039566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&ts));
21049566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm));
21059566063dSJacob Faibussowitsch   PetscCall(PetscBagDestroy(&ctx.bag));
21069566063dSJacob Faibussowitsch   PetscCall(PetscFree(ctx.zeroArray));
21079566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
2108b122ec5aSJacob Faibussowitsch   return 0;
210965876a83SMatthew G. Knepley }
211065876a83SMatthew G. Knepley 
211165876a83SMatthew G. Knepley /*TEST
211265876a83SMatthew G. Knepley 
211365876a83SMatthew G. Knepley   test:
211465876a83SMatthew G. Knepley     suffix: 2d_quad_linear
211565876a83SMatthew G. Knepley     requires: triangle
211665876a83SMatthew G. Knepley     args: -sol_type quadratic_linear -dm_refine 2 \
211765876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
211865876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
211965876a83SMatthew G. Knepley 
212065876a83SMatthew G. Knepley   test:
212165876a83SMatthew G. Knepley     suffix: 3d_quad_linear
212265876a83SMatthew G. Knepley     requires: ctetgen
212330602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_linear -dm_refine 1 \
212465876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
212565876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
212665876a83SMatthew G. Knepley 
212765876a83SMatthew G. Knepley   test:
212865876a83SMatthew G. Knepley     suffix: 2d_trig_linear
212965876a83SMatthew G. Knepley     requires: triangle
213065876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
213165876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
213265876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_dt 0.00001 -ts_monitor_extreme
213365876a83SMatthew G. Knepley 
213465876a83SMatthew G. Knepley   test:
213565876a83SMatthew G. Knepley     # -dm_refine 2 -convest_num_refine 3 get L_2 convergence rate: [1.9, 2.1, 1.8]
213665876a83SMatthew G. Knepley     suffix: 2d_trig_linear_sconv
213765876a83SMatthew G. Knepley     requires: triangle
213865876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
213965876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
214065876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -ts_dt 0.00001 -pc_type lu
214165876a83SMatthew G. Knepley 
214265876a83SMatthew G. Knepley   test:
214365876a83SMatthew G. Knepley     suffix: 3d_trig_linear
214465876a83SMatthew G. Knepley     requires: ctetgen
214530602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type trig_linear -dm_refine 1 \
214665876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
214765876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 2 -ts_monitor_extreme
214865876a83SMatthew G. Knepley 
214965876a83SMatthew G. Knepley   test:
215065876a83SMatthew G. Knepley     # -dm_refine 1 -convest_num_refine 2 gets L_2 convergence rate: [2.0, 2.1, 1.9]
215165876a83SMatthew G. Knepley     suffix: 3d_trig_linear_sconv
215265876a83SMatthew G. Knepley     requires: ctetgen
215330602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type trig_linear -dm_refine 1 \
215465876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
215565876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -pc_type lu
215665876a83SMatthew G. Knepley 
215765876a83SMatthew G. Knepley   test:
215865876a83SMatthew G. Knepley     suffix: 2d_quad_trig
215965876a83SMatthew G. Knepley     requires: triangle
216065876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 2 \
216165876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
216265876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
216365876a83SMatthew G. Knepley 
216465876a83SMatthew G. Knepley   test:
216565876a83SMatthew G. Knepley     # Using -dm_refine 4 gets the convergence rates to [0.95, 0.97, 0.90]
216665876a83SMatthew G. Knepley     suffix: 2d_quad_trig_tconv
216765876a83SMatthew G. Knepley     requires: triangle
216865876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 1 \
216965876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
217065876a83SMatthew G. Knepley       -convest_num_refine 3 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
217165876a83SMatthew G. Knepley 
217265876a83SMatthew G. Knepley   test:
217365876a83SMatthew G. Knepley     suffix: 3d_quad_trig
217465876a83SMatthew G. Knepley     requires: ctetgen
217530602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_trig -dm_refine 1 \
217665876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
217765876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
217865876a83SMatthew G. Knepley 
217965876a83SMatthew G. Knepley   test:
218065876a83SMatthew G. Knepley     # Using -dm_refine 2 -convest_num_refine 3 gets the convergence rates to [1.0, 1.0, 1.0]
218165876a83SMatthew G. Knepley     suffix: 3d_quad_trig_tconv
218265876a83SMatthew G. Knepley     requires: ctetgen
218330602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_trig -dm_refine 1 \
218465876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
218565876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
218665876a83SMatthew G. Knepley 
218730602db0SMatthew G. Knepley   testset:
218830602db0SMatthew G. Knepley     args: -sol_type terzaghi -dm_plex_simplex 0 -dm_plex_box_faces 1,8 -dm_plex_box_lower 0,0 -dm_plex_box_upper 10,10 -dm_plex_separate_marker \
218930602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 -niter 16000 \
219030602db0SMatthew G. Knepley           -pc_type lu
219130602db0SMatthew G. Knepley 
219265876a83SMatthew G. Knepley     test:
219365876a83SMatthew G. Knepley       suffix: 2d_terzaghi
219430602db0SMatthew G. Knepley       requires: double
219530602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001
219665876a83SMatthew G. Knepley 
219765876a83SMatthew G. Knepley     test:
219865876a83SMatthew G. Knepley       # -dm_plex_box_faces 1,64 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [1.1, 1.1, 1.1]
219965876a83SMatthew G. Knepley       suffix: 2d_terzaghi_tconv
220030602db0SMatthew G. Knepley       args: -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1
220165876a83SMatthew G. Knepley 
220265876a83SMatthew G. Knepley     test:
220324b15d09SMatthew G. Knepley       # -dm_plex_box_faces 1,16 -convest_num_refine 4 gives L_2 convergence rate: [1.7, 1.2, 1.1]
220430602db0SMatthew G. Knepley       # if we add -displacement_petscspace_degree 3 -tracestrain_petscspace_degree 2 -pressure_petscspace_degree 2, we get [2.1, 1.6, 1.5]
220524b15d09SMatthew G. Knepley       suffix: 2d_terzaghi_sconv
220630602db0SMatthew G. Knepley       args: -ts_dt 1e-5 -dt_initial 1e-5 -ts_max_steps 2 -ts_convergence_estimate -ts_convergence_temporal 0 -convest_num_refine 1
220730602db0SMatthew G. Knepley 
220830602db0SMatthew G. Knepley   testset:
220930602db0SMatthew G. Knepley     args: -sol_type mandel -dm_plex_simplex 0 -dm_plex_box_lower -0.5,-0.125 -dm_plex_box_upper 0.5,0.125 -dm_plex_separate_marker -dm_refine 1 \
221030602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
221130602db0SMatthew G. Knepley           -pc_type lu
221224b15d09SMatthew G. Knepley 
221324b15d09SMatthew G. Knepley     test:
221465876a83SMatthew G. Knepley       suffix: 2d_mandel
221530602db0SMatthew G. Knepley       requires: double
221630602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001
221765876a83SMatthew G. Knepley 
221865876a83SMatthew G. Knepley     test:
2219f30e7d8cSMatthew G. Knepley       # -dm_refine 3 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [1.6, 0.93, 1.2]
2220f30e7d8cSMatthew G. Knepley       suffix: 2d_mandel_sconv
2221f30e7d8cSMatthew G. Knepley       args: -ts_dt 1e-5 -dt_initial 1e-5 -ts_max_steps 2 -ts_convergence_estimate -ts_convergence_temporal 0 -convest_num_refine 1
2222f30e7d8cSMatthew G. Knepley 
2223f30e7d8cSMatthew G. Knepley     test:
222465876a83SMatthew G. Knepley       # -dm_refine 5 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [0.26, -0.0058, 0.26]
222565876a83SMatthew G. Knepley       suffix: 2d_mandel_tconv
222630602db0SMatthew G. Knepley       args: -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1
222730602db0SMatthew G. Knepley 
222830602db0SMatthew G. Knepley   testset:
222930602db0SMatthew G. Knepley     requires: ctetgen !complex
223030602db0SMatthew G. Knepley     args: -sol_type cryer -dm_plex_dim 3 -dm_plex_shape ball \
223130602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1
223265876a83SMatthew G. Knepley 
223365876a83SMatthew G. Knepley     test:
223465876a83SMatthew G. Knepley       suffix: 3d_cryer
223530602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_time 0.014333 -ts_max_steps 2 -dmts_check .0001 \
223630602db0SMatthew G. Knepley             -pc_type svd
223765876a83SMatthew G. Knepley 
223865876a83SMatthew G. Knepley     test:
223965876a83SMatthew G. Knepley       # Displacement and Pressure converge. The analytic expression for trace strain is inaccurate at the origin
224065876a83SMatthew G. Knepley       # -bd_dm_refine 3 -ref_limit 0.00666667 -ts_max_steps 5 -convest_num_refine 2 gives L_2 convergence rate: [0.47, -0.43, 1.5]
224165876a83SMatthew G. Knepley       suffix: 3d_cryer_tconv
224230602db0SMatthew G. Knepley       args: -bd_dm_refine 1 -dm_refine_volume_limit_pre 0.00666667 \
224330602db0SMatthew G. Knepley             -ts_dt 0.023 -ts_max_time 0.092 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1 \
224430602db0SMatthew G. Knepley             -pc_type lu -pc_factor_shift_type nonzero
224565876a83SMatthew G. Knepley 
224665876a83SMatthew G. Knepley TEST*/
2247