xref: /petsc/src/ts/tutorials/ex53.c (revision 2456a0d3daa2addb3ea12027452e28cf3e3cc9fa)
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 
359371c9d4SSatish Balay typedef enum {
369371c9d4SSatish Balay   SOL_QUADRATIC_LINEAR,
379371c9d4SSatish Balay   SOL_QUADRATIC_TRIG,
389371c9d4SSatish Balay   SOL_TRIG_LINEAR,
399371c9d4SSatish Balay   SOL_TERZAGHI,
409371c9d4SSatish Balay   SOL_MANDEL,
419371c9d4SSatish Balay   SOL_CRYER,
429371c9d4SSatish Balay   NUM_SOLUTION_TYPES
439371c9d4SSatish 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 
71d71ae5a4SJacob Faibussowitsch static PetscErrorCode zero(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
72d71ae5a4SJacob Faibussowitsch {
7365876a83SMatthew G. Knepley   PetscInt c;
7465876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) u[c] = 0.0;
753ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
7665876a83SMatthew G. Knepley }
7765876a83SMatthew G. Knepley 
7865876a83SMatthew G. Knepley /* Quadratic space and linear time solution
7965876a83SMatthew G. Knepley 
8065876a83SMatthew G. Knepley   2D:
8165876a83SMatthew G. Knepley   u = x^2
8265876a83SMatthew G. Knepley   v = y^2 - 2xy
8365876a83SMatthew G. Knepley   p = (x + y) t
8465876a83SMatthew G. Knepley   e = 2y
8565876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha t, alpha t>
8665876a83SMatthew G. Knepley   g = 0
8765876a83SMatthew G. Knepley   \epsilon = / 2x     -y    \
8865876a83SMatthew G. Knepley              \ -y   2y - 2x /
8965876a83SMatthew G. Knepley   Tr(\epsilon) = e = div u = 2y
9065876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
9165876a83SMatthew G. Knepley     = 2 G < 2-1, 2 > + \lambda <0, 2> - alpha <t, t>
9265876a83SMatthew G. Knepley     = <2 G, 4 G + 2 \lambda> - <alpha t, alpha t>
9365876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
9465876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
9565876a83SMatthew G. Knepley     = (x + y)/M
9665876a83SMatthew G. Knepley 
9765876a83SMatthew G. Knepley   3D:
9865876a83SMatthew G. Knepley   u = x^2
9965876a83SMatthew G. Knepley   v = y^2 - 2xy
10065876a83SMatthew G. Knepley   w = z^2 - 2yz
10165876a83SMatthew G. Knepley   p = (x + y + z) t
10265876a83SMatthew G. Knepley   e = 2z
10365876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha t, alpha t, alpha t>
10465876a83SMatthew G. Knepley   g = 0
10565876a83SMatthew G. Knepley   \varepsilon = / 2x     -y       0   \
10665876a83SMatthew G. Knepley                 | -y   2y - 2x   -z   |
10765876a83SMatthew G. Knepley                 \  0     -z    2z - 2y/
10865876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2z
10965876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
11065876a83SMatthew G. Knepley     = 2 G < 2-1, 2-1, 2 > + \lambda <0, 0, 2> - alpha <t, t, t>
11165876a83SMatthew G. Knepley     = <2 G, 2G, 4 G + 2 \lambda> - <alpha t, alpha t, alpha t>
11265876a83SMatthew G. Knepley */
113d71ae5a4SJacob Faibussowitsch static PetscErrorCode quadratic_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
114d71ae5a4SJacob Faibussowitsch {
11565876a83SMatthew G. Knepley   PetscInt d;
11665876a83SMatthew G. Knepley 
117ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) u[d] = PetscSqr(x[d]) - (d > 0 ? 2.0 * x[d - 1] * x[d] : 0.0);
1183ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
11965876a83SMatthew G. Knepley }
12065876a83SMatthew G. Knepley 
121d71ae5a4SJacob Faibussowitsch static PetscErrorCode linear_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
122d71ae5a4SJacob Faibussowitsch {
12365876a83SMatthew G. Knepley   u[0] = 2.0 * x[dim - 1];
1243ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
12565876a83SMatthew G. Knepley }
12665876a83SMatthew G. Knepley 
127d71ae5a4SJacob Faibussowitsch static PetscErrorCode linear_linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
128d71ae5a4SJacob Faibussowitsch {
12965876a83SMatthew G. Knepley   PetscReal sum = 0.0;
13065876a83SMatthew G. Knepley   PetscInt  d;
13165876a83SMatthew G. Knepley 
13265876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
13365876a83SMatthew G. Knepley   u[0] = sum * time;
1343ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
13565876a83SMatthew G. Knepley }
13665876a83SMatthew G. Knepley 
137d71ae5a4SJacob Faibussowitsch static PetscErrorCode linear_linear_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
138d71ae5a4SJacob Faibussowitsch {
13965876a83SMatthew G. Knepley   PetscReal sum = 0.0;
14065876a83SMatthew G. Knepley   PetscInt  d;
14165876a83SMatthew G. Knepley 
14265876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
14365876a83SMatthew G. Knepley   u[0] = sum;
1443ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
14565876a83SMatthew G. Knepley }
14665876a83SMatthew G. Knepley 
147d71ae5a4SJacob Faibussowitsch 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[])
148d71ae5a4SJacob Faibussowitsch {
14965876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
15065876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
15165876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
15265876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
15365876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
15465876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
15565876a83SMatthew G. Knepley   PetscInt        d;
15665876a83SMatthew G. Knepley 
157ad540459SPierre Jolivet   for (d = 0; d < dim - 1; ++d) f0[d] -= 2.0 * G - alpha * t;
15865876a83SMatthew G. Knepley   f0[dim - 1] -= 2.0 * lambda + 4.0 * G - alpha * t;
15965876a83SMatthew G. Knepley }
16065876a83SMatthew G. Knepley 
161d71ae5a4SJacob Faibussowitsch 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[])
162d71ae5a4SJacob Faibussowitsch {
16365876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
16465876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
16565876a83SMatthew G. Knepley   PetscReal       sum   = 0.0;
16665876a83SMatthew G. Knepley   PetscInt        d;
16765876a83SMatthew G. Knepley 
16865876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
16965876a83SMatthew G. Knepley   f0[0] += u_t ? alpha * u_t[uOff[1]] : 0.0;
17065876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]] / M : 0.0;
17165876a83SMatthew G. Knepley   f0[0] -= sum / M;
17265876a83SMatthew G. Knepley }
17365876a83SMatthew G. Knepley 
17465876a83SMatthew G. Knepley /* Quadratic space and trigonometric time solution
17565876a83SMatthew G. Knepley 
17665876a83SMatthew G. Knepley   2D:
17765876a83SMatthew G. Knepley   u = x^2
17865876a83SMatthew G. Knepley   v = y^2 - 2xy
17965876a83SMatthew G. Knepley   p = (x + y) cos(t)
18065876a83SMatthew G. Knepley   e = 2y
18165876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha cos(t), alpha cos(t)>
18265876a83SMatthew G. Knepley   g = 0
18365876a83SMatthew G. Knepley   \epsilon = / 2x     -y    \
18465876a83SMatthew G. Knepley              \ -y   2y - 2x /
18565876a83SMatthew G. Knepley   Tr(\epsilon) = e = div u = 2y
18665876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
18765876a83SMatthew G. Knepley     = 2 G < 2-1, 2 > + \lambda <0, 2> - alpha <cos(t), cos(t)>
18865876a83SMatthew G. Knepley     = <2 G, 4 G + 2 \lambda> - <alpha cos(t), alpha cos(t)>
18965876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
19065876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
19165876a83SMatthew G. Knepley     = -(x + y)/M sin(t)
19265876a83SMatthew G. Knepley 
19365876a83SMatthew G. Knepley   3D:
19465876a83SMatthew G. Knepley   u = x^2
19565876a83SMatthew G. Knepley   v = y^2 - 2xy
19665876a83SMatthew G. Knepley   w = z^2 - 2yz
19765876a83SMatthew G. Knepley   p = (x + y + z) cos(t)
19865876a83SMatthew G. Knepley   e = 2z
19965876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha cos(t), alpha cos(t), alpha cos(t)>
20065876a83SMatthew G. Knepley   g = 0
20165876a83SMatthew G. Knepley   \varepsilon = / 2x     -y       0   \
20265876a83SMatthew G. Knepley                 | -y   2y - 2x   -z   |
20365876a83SMatthew G. Knepley                 \  0     -z    2z - 2y/
20465876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2z
20565876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
20665876a83SMatthew G. Knepley     = 2 G < 2-1, 2-1, 2 > + \lambda <0, 0, 2> - alpha <cos(t), cos(t), cos(t)>
20765876a83SMatthew G. Knepley     = <2 G, 2G, 4 G + 2 \lambda> - <alpha cos(t), alpha cos(t), alpha cos(t)>
20865876a83SMatthew G. Knepley */
209d71ae5a4SJacob Faibussowitsch static PetscErrorCode linear_trig_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
210d71ae5a4SJacob Faibussowitsch {
21165876a83SMatthew G. Knepley   PetscReal sum = 0.0;
21265876a83SMatthew G. Knepley   PetscInt  d;
21365876a83SMatthew G. Knepley 
21465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
21565876a83SMatthew G. Knepley   u[0] = sum * PetscCosReal(time);
2163ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
21765876a83SMatthew G. Knepley }
21865876a83SMatthew G. Knepley 
219d71ae5a4SJacob Faibussowitsch static PetscErrorCode linear_trig_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
220d71ae5a4SJacob Faibussowitsch {
22165876a83SMatthew G. Knepley   PetscReal sum = 0.0;
22265876a83SMatthew G. Knepley   PetscInt  d;
22365876a83SMatthew G. Knepley 
22465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
22565876a83SMatthew G. Knepley   u[0] = -sum * PetscSinReal(time);
2263ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
22765876a83SMatthew G. Knepley }
22865876a83SMatthew G. Knepley 
229d71ae5a4SJacob Faibussowitsch 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[])
230d71ae5a4SJacob Faibussowitsch {
23165876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
23265876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
23365876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
23465876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
23565876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
23665876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
23765876a83SMatthew G. Knepley   PetscInt        d;
23865876a83SMatthew G. Knepley 
239ad540459SPierre Jolivet   for (d = 0; d < dim - 1; ++d) f0[d] -= 2.0 * G - alpha * PetscCosReal(t);
24065876a83SMatthew G. Knepley   f0[dim - 1] -= 2.0 * lambda + 4.0 * G - alpha * PetscCosReal(t);
24165876a83SMatthew G. Knepley }
24265876a83SMatthew G. Knepley 
243d71ae5a4SJacob Faibussowitsch 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[])
244d71ae5a4SJacob Faibussowitsch {
24565876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
24665876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
24765876a83SMatthew G. Knepley   PetscReal       sum   = 0.0;
24865876a83SMatthew G. Knepley   PetscInt        d;
24965876a83SMatthew G. Knepley 
25065876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
25165876a83SMatthew G. Knepley 
25265876a83SMatthew G. Knepley   f0[0] += u_t ? alpha * u_t[uOff[1]] : 0.0;
25365876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]] / M : 0.0;
25465876a83SMatthew G. Knepley   f0[0] += PetscSinReal(t) * sum / M;
25565876a83SMatthew G. Knepley }
25665876a83SMatthew G. Knepley 
25765876a83SMatthew G. Knepley /* Trigonometric space and linear time solution
25865876a83SMatthew G. Knepley 
25965876a83SMatthew G. Knepley u = sin(2 pi x)
26065876a83SMatthew G. Knepley v = sin(2 pi y) - 2xy
26165876a83SMatthew G. Knepley \varepsilon = / 2 pi cos(2 pi x)             -y        \
26265876a83SMatthew G. Knepley               \      -y          2 pi cos(2 pi y) - 2x /
26365876a83SMatthew G. Knepley Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
26465876a83SMatthew G. Knepley div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
26565876a83SMatthew 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) >
26665876a83SMatthew 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) >
26765876a83SMatthew G. Knepley 
26865876a83SMatthew G. Knepley   2D:
26965876a83SMatthew G. Knepley   u = sin(2 pi x)
27065876a83SMatthew G. Knepley   v = sin(2 pi y) - 2xy
27165876a83SMatthew G. Knepley   p = (cos(2 pi x) + cos(2 pi y)) t
27265876a83SMatthew G. Knepley   e = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
27365876a83SMatthew 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)>
27465876a83SMatthew G. Knepley   g = 0
27565876a83SMatthew G. Knepley   \varepsilon = / 2 pi cos(2 pi x)             -y        \
27665876a83SMatthew G. Knepley                 \      -y          2 pi cos(2 pi y) - 2x /
27765876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
27865876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
27965876a83SMatthew 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>
28065876a83SMatthew 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)>
28165876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
28265876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
28365876a83SMatthew G. Knepley     = (cos(2 pi x) + cos(2 pi y))/M - 4 pi^2 \kappa (cos(2 pi x) + cos(2 pi y)) t
28465876a83SMatthew G. Knepley 
28565876a83SMatthew G. Knepley   3D:
28665876a83SMatthew G. Knepley   u = sin(2 pi x)
28765876a83SMatthew G. Knepley   v = sin(2 pi y) - 2xy
28865876a83SMatthew G. Knepley   v = sin(2 pi y) - 2yz
28965876a83SMatthew G. Knepley   p = (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) t
29065876a83SMatthew G. Knepley   e = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2y
29165876a83SMatthew 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)>
29265876a83SMatthew G. Knepley   g = 0
29365876a83SMatthew G. Knepley   \varepsilon = / 2 pi cos(2 pi x)            -y                     0         \
29465876a83SMatthew G. Knepley                 |         -y       2 pi cos(2 pi y) - 2x            -z         |
29565876a83SMatthew G. Knepley                 \          0                  -z         2 pi cos(2 pi z) - 2y /
29665876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2 y
29765876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
29865876a83SMatthew 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>
29965876a83SMatthew 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)>
30065876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
30165876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
30265876a83SMatthew 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
30365876a83SMatthew G. Knepley */
304d71ae5a4SJacob Faibussowitsch static PetscErrorCode trig_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
305d71ae5a4SJacob Faibussowitsch {
30665876a83SMatthew G. Knepley   PetscInt d;
30765876a83SMatthew G. Knepley 
308ad540459SPierre Jolivet   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);
3093ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
31065876a83SMatthew G. Knepley }
31165876a83SMatthew G. Knepley 
312d71ae5a4SJacob Faibussowitsch static PetscErrorCode trig_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
313d71ae5a4SJacob Faibussowitsch {
31465876a83SMatthew G. Knepley   PetscReal sum = 0.0;
31565876a83SMatthew G. Knepley   PetscInt  d;
31665876a83SMatthew G. Knepley 
31765876a83SMatthew 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);
31865876a83SMatthew G. Knepley   u[0] = sum;
3193ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
32065876a83SMatthew G. Knepley }
32165876a83SMatthew G. Knepley 
322d71ae5a4SJacob Faibussowitsch static PetscErrorCode trig_linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
323d71ae5a4SJacob Faibussowitsch {
32465876a83SMatthew G. Knepley   PetscReal sum = 0.0;
32565876a83SMatthew G. Knepley   PetscInt  d;
32665876a83SMatthew G. Knepley 
32765876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2. * PETSC_PI * x[d]);
32865876a83SMatthew G. Knepley   u[0] = sum * time;
3293ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
33065876a83SMatthew G. Knepley }
33165876a83SMatthew G. Knepley 
332d71ae5a4SJacob Faibussowitsch static PetscErrorCode trig_linear_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
333d71ae5a4SJacob Faibussowitsch {
33465876a83SMatthew G. Knepley   PetscReal sum = 0.0;
33565876a83SMatthew G. Knepley   PetscInt  d;
33665876a83SMatthew G. Knepley 
33765876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2. * PETSC_PI * x[d]);
33865876a83SMatthew G. Knepley   u[0] = sum;
3393ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
34065876a83SMatthew G. Knepley }
34165876a83SMatthew G. Knepley 
342d71ae5a4SJacob Faibussowitsch 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[])
343d71ae5a4SJacob Faibussowitsch {
34465876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
34565876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
34665876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
34765876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
34865876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
34965876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
35065876a83SMatthew G. Knepley   PetscInt        d;
35165876a83SMatthew G. Knepley 
352ad540459SPierre Jolivet   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;
35365876a83SMatthew 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;
35465876a83SMatthew G. Knepley }
35565876a83SMatthew G. Knepley 
356d71ae5a4SJacob Faibussowitsch 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[])
357d71ae5a4SJacob Faibussowitsch {
35865876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
35965876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
36065876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
36165876a83SMatthew G. Knepley   PetscReal       sum   = 0.0;
36265876a83SMatthew G. Knepley   PetscInt        d;
36365876a83SMatthew G. Knepley 
36465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2. * PETSC_PI * x[d]);
36565876a83SMatthew G. Knepley   f0[0] += u_t ? alpha * u_t[uOff[1]] : 0.0;
36665876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]] / M : 0.0;
36765876a83SMatthew G. Knepley   f0[0] -= sum / M - 4 * PetscSqr(PETSC_PI) * kappa * sum * t;
36865876a83SMatthew G. Knepley }
36965876a83SMatthew G. Knepley 
37065876a83SMatthew G. Knepley /* Terzaghi Solutions */
37165876a83SMatthew G. Knepley /* The analytical solutions given here are drawn from chapter 7, section 3, */
37265876a83SMatthew G. Knepley /* "One-Dimensional Consolidation Problem," from Poroelasticity, by Cheng.  */
373d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
374d71ae5a4SJacob Faibussowitsch {
37565876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
37665876a83SMatthew G. Knepley   Parameter *param;
37765876a83SMatthew G. Knepley 
3789566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
37965876a83SMatthew G. Knepley   if (time <= 0.0) {
38065876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                                        /* -  */
38165876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                                          /* Pa */
38265876a83SMatthew G. Knepley     PetscScalar M     = param->M;                                            /* Pa */
38365876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                                           /* Pa */
38465876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                                          /* Pa */
38565876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
38665876a83SMatthew G. Knepley     PetscScalar eta   = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
38765876a83SMatthew G. Knepley     PetscScalar S     = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
38865876a83SMatthew G. Knepley 
38965876a83SMatthew G. Knepley     u[0] = ((P_0 * eta) / (G * S));
39065876a83SMatthew G. Knepley   } else {
39165876a83SMatthew G. Knepley     u[0] = 0.0;
39265876a83SMatthew G. Knepley   }
3933ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
39465876a83SMatthew G. Knepley }
39565876a83SMatthew G. Knepley 
396d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
397d71ae5a4SJacob Faibussowitsch {
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 */
40630602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1];                   /* m */
40765876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
40865876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                        /* - */
40965876a83SMatthew G. Knepley 
41065876a83SMatthew G. Knepley     u[0] = 0.0;
41165876a83SMatthew G. Knepley     u[1] = ((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - zstar);
41265876a83SMatthew G. Knepley   }
4133ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
41465876a83SMatthew G. Knepley }
41565876a83SMatthew G. Knepley 
416d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
417d71ae5a4SJacob Faibussowitsch {
41865876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
41965876a83SMatthew G. Knepley   Parameter *param;
42065876a83SMatthew G. Knepley 
4219566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
42265876a83SMatthew G. Knepley   {
42365876a83SMatthew G. Knepley     PetscScalar K_u  = param->K_u;                                      /* Pa */
42465876a83SMatthew G. Knepley     PetscScalar G    = param->mu;                                       /* Pa */
42565876a83SMatthew G. Knepley     PetscScalar P_0  = param->P_0;                                      /* Pa */
42665876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
42765876a83SMatthew G. Knepley 
42865876a83SMatthew G. Knepley     u[0] = -(P_0 * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u));
42965876a83SMatthew G. Knepley   }
4303ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
43165876a83SMatthew G. Knepley }
43265876a83SMatthew G. Knepley 
433d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
434d71ae5a4SJacob Faibussowitsch {
43565876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
43665876a83SMatthew G. Knepley   Parameter *param;
43765876a83SMatthew G. Knepley 
4389566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
43965876a83SMatthew G. Knepley   if (time < 0.0) {
4409566063dSJacob Faibussowitsch     PetscCall(terzaghi_initial_u(dim, time, x, Nc, u, ctx));
44165876a83SMatthew G. Knepley   } else {
44265876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
44365876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
44465876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
44565876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
44665876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
44765876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
44830602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
44965876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
45065876a83SMatthew G. Knepley 
45165876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
45265876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
45365876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
45465876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
45565876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
45665876a83SMatthew G. Knepley 
45765876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
45865876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
45965876a83SMatthew G. Knepley     PetscScalar F2    = 0.0;
46065876a83SMatthew G. Knepley 
46165876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
462ad540459SPierre Jolivet       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));
46365876a83SMatthew G. Knepley     }
46465876a83SMatthew G. Knepley     u[0] = 0.0;
46565876a83SMatthew 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 */
46665876a83SMatthew G. Knepley   }
4673ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
46865876a83SMatthew G. Knepley }
46965876a83SMatthew G. Knepley 
470d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
471d71ae5a4SJacob Faibussowitsch {
47265876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
47365876a83SMatthew G. Knepley   Parameter *param;
47465876a83SMatthew G. Knepley 
4759566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
47665876a83SMatthew G. Knepley   if (time < 0.0) {
4779566063dSJacob Faibussowitsch     PetscCall(terzaghi_initial_eps(dim, time, x, Nc, u, ctx));
47865876a83SMatthew G. Knepley   } else {
47965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
48065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
48165876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
48265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
48365876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
48465876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
48530602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
48665876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
48765876a83SMatthew G. Knepley 
48865876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
48965876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
49065876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
49165876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
49265876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
49365876a83SMatthew G. Knepley 
49465876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
49565876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
49665876a83SMatthew G. Knepley     PetscScalar F2_z  = 0.0;
49765876a83SMatthew G. Knepley 
49865876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
499ad540459SPierre Jolivet       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));
50065876a83SMatthew G. Knepley     }
50165876a83SMatthew 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; /* - */
50265876a83SMatthew G. Knepley   }
5033ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
50465876a83SMatthew G. Knepley }
50565876a83SMatthew G. Knepley 
50665876a83SMatthew G. Knepley // Pressure
507d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
508d71ae5a4SJacob Faibussowitsch {
50965876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
51065876a83SMatthew G. Knepley   Parameter *param;
51165876a83SMatthew G. Knepley 
5129566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
51365876a83SMatthew G. Knepley   if (time <= 0.0) {
5149566063dSJacob Faibussowitsch     PetscCall(terzaghi_drainage_pressure(dim, time, x, Nc, u, ctx));
51565876a83SMatthew G. Knepley   } else {
51665876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
51765876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
51865876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
51965876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
52065876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
52165876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
52230602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
52365876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
52465876a83SMatthew G. Knepley 
52565876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
52665876a83SMatthew G. Knepley     PetscScalar eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
52765876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
52865876a83SMatthew G. Knepley     PetscScalar c   = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
52965876a83SMatthew G. Knepley 
53065876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
53165876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
53265876a83SMatthew G. Knepley     PetscScalar F1    = 0.0;
53365876a83SMatthew G. Knepley 
53463a3b9bcSJacob 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));
53565876a83SMatthew G. Knepley 
53665876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
537ad540459SPierre Jolivet       if (m % 2 == 1) F1 += (4.0 / (m * PETSC_PI)) * PetscSinReal(0.5 * m * PETSC_PI * zstar) * PetscExpReal(-PetscSqr(m * PETSC_PI) * tstar);
53865876a83SMatthew G. Knepley     }
53965876a83SMatthew G. Knepley     u[0] = ((P_0 * eta) / (G * S)) * F1; /* Pa */
54065876a83SMatthew G. Knepley   }
5413ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
54265876a83SMatthew G. Knepley }
54365876a83SMatthew G. Knepley 
544d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
545d71ae5a4SJacob Faibussowitsch {
54665876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
54765876a83SMatthew G. Knepley   Parameter *param;
54865876a83SMatthew G. Knepley 
5499566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
55065876a83SMatthew G. Knepley   if (time <= 0.0) {
55165876a83SMatthew G. Knepley     u[0] = 0.0;
55265876a83SMatthew G. Knepley     u[1] = 0.0;
55365876a83SMatthew G. Knepley   } else {
55465876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
55565876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
55665876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
55765876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
55865876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
55965876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
56030602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
56165876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
56265876a83SMatthew G. Knepley 
56365876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
56465876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
56565876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
56665876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
56765876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
56865876a83SMatthew G. Knepley 
56965876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
57065876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
57165876a83SMatthew G. Knepley     PetscScalar F2_t  = 0.0;
57265876a83SMatthew G. Knepley 
57365876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
574ad540459SPierre Jolivet       if (m % 2 == 1) F2_t += (2.0 * c / PetscSqr(L)) * PetscCosReal(0.5 * m * PETSC_PI * zstar) * PetscExpReal(-PetscSqr(m * PETSC_PI) * tstar);
57565876a83SMatthew G. Knepley     }
57665876a83SMatthew G. Knepley     u[0] = 0.0;
57765876a83SMatthew G. Knepley     u[1] = ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * F2_t; /* m / s */
57865876a83SMatthew G. Knepley   }
5793ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
58065876a83SMatthew G. Knepley }
58165876a83SMatthew G. Knepley 
582d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
583d71ae5a4SJacob Faibussowitsch {
58465876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
58565876a83SMatthew G. Knepley   Parameter *param;
58665876a83SMatthew G. Knepley 
5879566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
58865876a83SMatthew G. Knepley   if (time <= 0.0) {
58965876a83SMatthew G. Knepley     u[0] = 0.0;
59065876a83SMatthew G. Knepley   } else {
59165876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
59265876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
59365876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
59465876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
59565876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
59665876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
59730602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
59865876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
59965876a83SMatthew G. Knepley 
60065876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
60165876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
60265876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
60365876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
60465876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
60565876a83SMatthew G. Knepley 
60665876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
60765876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
60865876a83SMatthew G. Knepley     PetscScalar F2_zt = 0.0;
60965876a83SMatthew G. Knepley 
61065876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
611ad540459SPierre Jolivet       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);
61265876a83SMatthew G. Knepley     }
61365876a83SMatthew G. Knepley     u[0] = ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * F2_zt; /* 1 / s */
61465876a83SMatthew G. Knepley   }
6153ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
61665876a83SMatthew G. Knepley }
61765876a83SMatthew G. Knepley 
618d71ae5a4SJacob Faibussowitsch static PetscErrorCode terzaghi_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
619d71ae5a4SJacob Faibussowitsch {
62065876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
62165876a83SMatthew G. Knepley   Parameter *param;
62265876a83SMatthew G. Knepley 
6239566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
62465876a83SMatthew G. Knepley   if (time <= 0.0) {
62565876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
62665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
62765876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
62865876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
62965876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
63065876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
63130602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
63265876a83SMatthew G. Knepley 
63365876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
63465876a83SMatthew G. Knepley     PetscScalar eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
63565876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
63665876a83SMatthew G. Knepley     PetscScalar c   = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
63765876a83SMatthew G. Knepley 
63865876a83SMatthew G. Knepley     u[0] = -((P_0 * eta) / (G * S)) * PetscSqr(0 * PETSC_PI) * c / PetscSqr(2.0 * L); /* Pa / s */
63965876a83SMatthew G. Knepley   } else {
64065876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                  /* -  */
64165876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                    /* Pa */
64265876a83SMatthew G. Knepley     PetscScalar M     = param->M;                      /* Pa */
64365876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                     /* Pa */
64465876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                    /* Pa */
64565876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;        /* m^2 / (Pa s) */
64630602db0SMatthew G. Knepley     PetscReal   L     = user->xmax[1] - user->xmin[1]; /* m */
64765876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
64865876a83SMatthew G. Knepley 
64965876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
65065876a83SMatthew G. Knepley     PetscScalar eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
65165876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
65265876a83SMatthew G. Knepley     PetscScalar c   = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
65365876a83SMatthew G. Knepley 
65465876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                    /* - */
65565876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c * time) / PetscSqr(2.0 * L); /* - */
65665876a83SMatthew G. Knepley     PetscScalar F1_t  = 0.0;
65765876a83SMatthew G. Knepley 
65863a3b9bcSJacob 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));
65965876a83SMatthew G. Knepley 
66065876a83SMatthew G. Knepley     for (m = 1; m < 2 * N + 1; ++m) {
661ad540459SPierre Jolivet       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);
66265876a83SMatthew G. Knepley     }
66365876a83SMatthew G. Knepley     u[0] = ((P_0 * eta) / (G * S)) * F1_t; /* Pa / s */
66465876a83SMatthew G. Knepley   }
6653ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
66665876a83SMatthew G. Knepley }
66765876a83SMatthew G. Knepley 
66865876a83SMatthew G. Knepley /* Mandel Solutions */
669d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
670d71ae5a4SJacob Faibussowitsch {
67165876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
67265876a83SMatthew G. Knepley   Parameter *param;
67365876a83SMatthew G. Knepley 
6749566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
67565876a83SMatthew G. Knepley   if (time <= 0.0) {
67665876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                          /* -  */
67765876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                            /* Pa */
67865876a83SMatthew G. Knepley     PetscScalar M     = param->M;                              /* Pa */
67965876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                             /* Pa */
68065876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                            /* Pa */
68165876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;                /* m^2 / (Pa s) */
68230602db0SMatthew G. Knepley     PetscReal   a     = 0.5 * (user->xmax[0] - user->xmin[0]); /* m */
68365876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
68465876a83SMatthew G. Knepley 
68565876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
68665876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
68765876a83SMatthew G. Knepley     PetscScalar B    = alpha * M / K_u;                                     /* -,       Cheng (B.12) */
68865876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
68965876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
69065876a83SMatthew G. Knepley 
69165876a83SMatthew G. Knepley     PetscScalar A1   = 3.0 / (B * (1.0 + nu_u));
69265876a83SMatthew G. Knepley     PetscReal   aa   = 0.0;
69365876a83SMatthew G. Knepley     PetscReal   p    = 0.0;
69465876a83SMatthew G. Knepley     PetscReal   time = 0.0;
69565876a83SMatthew G. Knepley 
69665876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
69765876a83SMatthew G. Knepley       aa = user->zeroArray[n - 1];
69865876a83SMatthew 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));
69965876a83SMatthew G. Knepley     }
70065876a83SMatthew G. Knepley     u[0] = ((2.0 * P_0) / (a * A1)) * p;
70165876a83SMatthew G. Knepley   } else {
70265876a83SMatthew G. Knepley     u[0] = 0.0;
70365876a83SMatthew G. Knepley   }
7043ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
70565876a83SMatthew G. Knepley }
70665876a83SMatthew G. Knepley 
707d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
708d71ae5a4SJacob Faibussowitsch {
70965876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
71065876a83SMatthew G. Knepley   Parameter *param;
71165876a83SMatthew G. Knepley 
7129566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
71365876a83SMatthew G. Knepley   {
71465876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                          /* -  */
71565876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                            /* Pa */
71665876a83SMatthew G. Knepley     PetscScalar M     = param->M;                              /* Pa */
71765876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                             /* Pa */
71865876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                            /* Pa */
71965876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;                /* m^2 / (Pa s) */
72030602db0SMatthew G. Knepley     PetscScalar a     = 0.5 * (user->xmax[0] - user->xmin[0]); /* m */
72165876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
72265876a83SMatthew G. Knepley 
72365876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
72465876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
72565876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
72665876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
72765876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
72865876a83SMatthew G. Knepley 
72965876a83SMatthew G. Knepley     PetscScalar A_s     = 0.0;
73065876a83SMatthew G. Knepley     PetscScalar B_s     = 0.0;
73165876a83SMatthew G. Knepley     PetscScalar time    = 0.0;
73265876a83SMatthew G. Knepley     PetscScalar alpha_n = 0.0;
73365876a83SMatthew G. Knepley 
73465876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
73565876a83SMatthew G. Knepley       alpha_n = user->zeroArray[n - 1];
73665876a83SMatthew 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));
73765876a83SMatthew 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));
73865876a83SMatthew G. Knepley     }
73965876a83SMatthew 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;
74065876a83SMatthew G. Knepley     u[1] = (-1 * (P_0 * (1.0 - nu)) / (2 * G * a) + (P_0 * (1 - nu_u)) / (G * a) * A_s) * x[1];
74165876a83SMatthew G. Knepley   }
7423ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
74365876a83SMatthew G. Knepley }
74465876a83SMatthew G. Knepley 
745d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
746d71ae5a4SJacob Faibussowitsch {
74765876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
74865876a83SMatthew G. Knepley   Parameter *param;
74965876a83SMatthew G. Knepley 
7509566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
75165876a83SMatthew G. Knepley   {
75265876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                          /* -  */
75365876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                            /* Pa */
75465876a83SMatthew G. Knepley     PetscScalar M     = param->M;                              /* Pa */
75565876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                             /* Pa */
75665876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                            /* Pa */
75765876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;                /* m^2 / (Pa s) */
75830602db0SMatthew G. Knepley     PetscReal   a     = 0.5 * (user->xmax[0] - user->xmin[0]); /* m */
75965876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
76065876a83SMatthew G. Knepley 
76165876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
76265876a83SMatthew G. Knepley     PetscScalar nu  = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
76365876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
76465876a83SMatthew G. Knepley     PetscReal   c   = PetscRealPart(kappa / S);                            /* m^2 / s, Cheng (B.16) */
76565876a83SMatthew G. Knepley 
76665876a83SMatthew G. Knepley     PetscReal aa    = 0.0;
76765876a83SMatthew G. Knepley     PetscReal eps_A = 0.0;
76865876a83SMatthew G. Knepley     PetscReal eps_B = 0.0;
76965876a83SMatthew G. Knepley     PetscReal eps_C = 0.0;
77065876a83SMatthew G. Knepley     PetscReal time  = 0.0;
77165876a83SMatthew G. Knepley 
77265876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
77365876a83SMatthew G. Knepley       aa = user->zeroArray[n - 1];
77465876a83SMatthew 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)));
77565876a83SMatthew G. Knepley       eps_B += (PetscExpReal((-1.0 * aa * aa * c * time) / (a * a)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
77665876a83SMatthew G. Knepley       eps_C += (PetscExpReal((-1.0 * aa * aa * c * time) / (aa * aa)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
77765876a83SMatthew G. Knepley     }
77865876a83SMatthew 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);
77965876a83SMatthew G. Knepley   }
7803ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
78165876a83SMatthew G. Knepley }
78265876a83SMatthew G. Knepley 
78365876a83SMatthew G. Knepley // Displacement
784d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
785d71ae5a4SJacob Faibussowitsch {
78665876a83SMatthew G. Knepley   Parameter *param;
78765876a83SMatthew G. Knepley 
78865876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
78965876a83SMatthew G. Knepley 
7909566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
79165876a83SMatthew G. Knepley   if (time <= 0.0) {
7929566063dSJacob Faibussowitsch     PetscCall(mandel_initial_u(dim, time, x, Nc, u, ctx));
79365876a83SMatthew G. Knepley   } else {
79465876a83SMatthew G. Knepley     PetscInt    NITER = user->niter;
79565876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
79665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
79765876a83SMatthew G. Knepley     PetscScalar M     = param->M;
79865876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
79965876a83SMatthew G. Knepley     PetscScalar k     = param->k;
80065876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
80165876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
80265876a83SMatthew G. Knepley 
80365876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
80465876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
80565876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
80665876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
80730602db0SMatthew G. Knepley     PetscReal   a     = (user->xmax[0] - user->xmin[0]) / 2.0;
80865876a83SMatthew 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)));
80965876a83SMatthew G. Knepley 
81065876a83SMatthew G. Knepley     // Series term
81165876a83SMatthew G. Knepley     PetscScalar A_x = 0.0;
81265876a83SMatthew G. Knepley     PetscScalar B_x = 0.0;
81365876a83SMatthew G. Knepley 
81465876a83SMatthew G. Knepley     for (PetscInt n = 1; n < NITER + 1; n++) {
81565876a83SMatthew G. Knepley       PetscReal alpha_n = user->zeroArray[n - 1];
81665876a83SMatthew G. Knepley 
81765876a83SMatthew 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));
81865876a83SMatthew 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));
81965876a83SMatthew G. Knepley     }
82065876a83SMatthew G. Knepley     u[0] = ((F * nu) / (2.0 * G * a) - (F * nu_u) / (G * a) * A_x) * x[0] + F / G * B_x;
82165876a83SMatthew G. Knepley     u[1] = (-1 * (F * (1.0 - nu)) / (2 * G * a) + (F * (1 - nu_u)) / (G * a) * A_x) * x[1];
82265876a83SMatthew G. Knepley   }
8233ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
82465876a83SMatthew G. Knepley }
82565876a83SMatthew G. Knepley 
82665876a83SMatthew G. Knepley // Trace strain
827d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
828d71ae5a4SJacob Faibussowitsch {
82965876a83SMatthew G. Knepley   Parameter *param;
83065876a83SMatthew G. Knepley 
83165876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
83265876a83SMatthew G. Knepley 
8339566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
83465876a83SMatthew G. Knepley   if (time <= 0.0) {
8359566063dSJacob Faibussowitsch     PetscCall(mandel_initial_eps(dim, time, x, Nc, u, ctx));
83665876a83SMatthew G. Knepley   } else {
83765876a83SMatthew G. Knepley     PetscInt    NITER = user->niter;
83865876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
83965876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
84065876a83SMatthew G. Knepley     PetscScalar M     = param->M;
84165876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
84265876a83SMatthew G. Knepley     PetscScalar k     = param->k;
84365876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
84465876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
84565876a83SMatthew G. Knepley 
84665876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
84765876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
84865876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
84965876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
85065876a83SMatthew G. Knepley     //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
85165876a83SMatthew G. Knepley 
85265876a83SMatthew G. Knepley     //const PetscScalar b = (YMAX - YMIN) / 2.0;
85330602db0SMatthew G. Knepley     PetscScalar a = (user->xmax[0] - user->xmin[0]) / 2.0;
85465876a83SMatthew 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)));
85565876a83SMatthew G. Knepley 
85665876a83SMatthew G. Knepley     // Series term
85765876a83SMatthew G. Knepley     PetscScalar eps_A = 0.0;
85865876a83SMatthew G. Knepley     PetscScalar eps_B = 0.0;
85965876a83SMatthew G. Knepley     PetscScalar eps_C = 0.0;
86065876a83SMatthew G. Knepley 
8619371c9d4SSatish Balay     for (PetscInt n = 1; n < NITER + 1; n++) {
86265876a83SMatthew G. Knepley       PetscReal aa = user->zeroArray[n - 1];
86365876a83SMatthew G. Knepley 
86465876a83SMatthew 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)));
86565876a83SMatthew G. Knepley 
86665876a83SMatthew G. Knepley       eps_B += (PetscExpReal((-1.0 * aa * aa * c * time) / (a * a)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
86765876a83SMatthew G. Knepley 
86865876a83SMatthew G. Knepley       eps_C += (PetscExpReal((-1.0 * aa * aa * c * time) / (aa * aa)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
86965876a83SMatthew G. Knepley     }
87065876a83SMatthew G. Knepley 
87165876a83SMatthew 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);
87265876a83SMatthew G. Knepley   }
8733ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
87465876a83SMatthew G. Knepley }
87565876a83SMatthew G. Knepley 
87665876a83SMatthew G. Knepley // Pressure
877d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
878d71ae5a4SJacob Faibussowitsch {
87965876a83SMatthew G. Knepley   Parameter *param;
88065876a83SMatthew G. Knepley 
88165876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
88265876a83SMatthew G. Knepley 
8839566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
88465876a83SMatthew G. Knepley   if (time <= 0.0) {
8859566063dSJacob Faibussowitsch     PetscCall(mandel_drainage_pressure(dim, time, x, Nc, u, ctx));
88665876a83SMatthew G. Knepley   } else {
88765876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
88865876a83SMatthew G. Knepley 
88965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
89065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
89165876a83SMatthew G. Knepley     PetscScalar M     = param->M;
89265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
89365876a83SMatthew G. Knepley     PetscScalar k     = param->k;
89465876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
89565876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
89665876a83SMatthew G. Knepley 
89765876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
89865876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
89965876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
90065876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
90165876a83SMatthew G. Knepley     PetscScalar B     = (alpha * M) / (K_d + alpha * alpha * M);
90265876a83SMatthew G. Knepley 
90330602db0SMatthew G. Knepley     PetscReal   a  = (user->xmax[0] - user->xmin[0]) / 2.0;
90465876a83SMatthew 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)));
90565876a83SMatthew G. Knepley     PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
90665876a83SMatthew G. Knepley     //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
90765876a83SMatthew G. Knepley 
90865876a83SMatthew G. Knepley     // Series term
90965876a83SMatthew G. Knepley     PetscScalar aa = 0.0;
91065876a83SMatthew G. Knepley     PetscScalar p  = 0.0;
91165876a83SMatthew G. Knepley 
9129371c9d4SSatish Balay     for (PetscInt n = 1; n < NITER + 1; n++) {
91365876a83SMatthew G. Knepley       aa = user->zeroArray[n - 1];
91465876a83SMatthew 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));
91565876a83SMatthew G. Knepley     }
91665876a83SMatthew G. Knepley     u[0] = ((2.0 * F) / (a * A1)) * p;
91765876a83SMatthew G. Knepley   }
9183ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
91965876a83SMatthew G. Knepley }
92065876a83SMatthew G. Knepley 
92165876a83SMatthew G. Knepley // Time derivative of displacement
922d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
923d71ae5a4SJacob Faibussowitsch {
92465876a83SMatthew G. Knepley   Parameter *param;
92565876a83SMatthew G. Knepley 
92665876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
92765876a83SMatthew G. Knepley 
9289566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
92965876a83SMatthew G. Knepley 
93065876a83SMatthew G. Knepley   PetscInt    NITER = user->niter;
93165876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
93265876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
93365876a83SMatthew G. Knepley   PetscScalar M     = param->M;
93465876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
93565876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
93665876a83SMatthew G. Knepley 
93765876a83SMatthew G. Knepley   PetscScalar K_d   = K_u - alpha * alpha * M;
93865876a83SMatthew G. Knepley   PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
93965876a83SMatthew G. Knepley   PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
94065876a83SMatthew G. Knepley   PetscScalar kappa = param->k / param->mu_f;
94130602db0SMatthew G. Knepley   PetscReal   a     = (user->xmax[0] - user->xmin[0]) / 2.0;
94265876a83SMatthew 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)));
94365876a83SMatthew G. Knepley 
94465876a83SMatthew G. Knepley   // Series term
94565876a83SMatthew G. Knepley   PetscScalar A_s_t = 0.0;
94665876a83SMatthew G. Knepley   PetscScalar B_s_t = 0.0;
94765876a83SMatthew G. Knepley 
9489371c9d4SSatish Balay   for (PetscInt n = 1; n < NITER + 1; n++) {
94965876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n - 1];
95065876a83SMatthew G. Knepley 
95165876a83SMatthew 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)));
95265876a83SMatthew 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)));
95365876a83SMatthew G. Knepley   }
95465876a83SMatthew G. Knepley 
95565876a83SMatthew G. Knepley   u[0] = (F / G) * A_s_t - ((F * nu_u * x[0]) / (G * a)) * B_s_t;
95665876a83SMatthew G. Knepley   u[1] = ((F * x[1] * (1 - nu_u)) / (G * a)) * B_s_t;
95765876a83SMatthew G. Knepley 
9583ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
95965876a83SMatthew G. Knepley }
96065876a83SMatthew G. Knepley 
96165876a83SMatthew G. Knepley // Time derivative of trace strain
962d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
963d71ae5a4SJacob Faibussowitsch {
96465876a83SMatthew G. Knepley   Parameter *param;
96565876a83SMatthew G. Knepley 
96665876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
96765876a83SMatthew G. Knepley 
9689566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
96965876a83SMatthew G. Knepley 
97065876a83SMatthew G. Knepley   PetscInt    NITER = user->niter;
97165876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
97265876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
97365876a83SMatthew G. Knepley   PetscScalar M     = param->M;
97465876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
97565876a83SMatthew G. Knepley   PetscScalar k     = param->k;
97665876a83SMatthew G. Knepley   PetscScalar mu_f  = param->mu_f;
97765876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
97865876a83SMatthew G. Knepley 
97965876a83SMatthew G. Knepley   PetscScalar K_d   = K_u - alpha * alpha * M;
98065876a83SMatthew G. Knepley   PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
98165876a83SMatthew G. Knepley   PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
98265876a83SMatthew G. Knepley   PetscScalar kappa = k / mu_f;
98365876a83SMatthew G. Knepley   //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
98465876a83SMatthew G. Knepley 
98565876a83SMatthew G. Knepley   //const PetscScalar b = (YMAX - YMIN) / 2.0;
98630602db0SMatthew G. Knepley   PetscReal a = (user->xmax[0] - user->xmin[0]) / 2.0;
98765876a83SMatthew 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)));
98865876a83SMatthew G. Knepley 
98965876a83SMatthew G. Knepley   // Series term
99065876a83SMatthew G. Knepley   PetscScalar eps_As = 0.0;
99165876a83SMatthew G. Knepley   PetscScalar eps_Bs = 0.0;
99265876a83SMatthew G. Knepley   PetscScalar eps_Cs = 0.0;
99365876a83SMatthew G. Knepley 
9949371c9d4SSatish Balay   for (PetscInt n = 1; n < NITER + 1; n++) {
99565876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n - 1];
99665876a83SMatthew G. Knepley 
99765876a83SMatthew 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)));
99865876a83SMatthew 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)));
99965876a83SMatthew 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)));
100065876a83SMatthew G. Knepley   }
100165876a83SMatthew G. Knepley 
100265876a83SMatthew G. Knepley   u[0] = (F / G) * eps_As - ((F * nu_u) / (G * a)) * eps_Bs + ((F * (1 - nu_u)) / (G * a)) * eps_Cs;
10033ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
100465876a83SMatthew G. Knepley }
100565876a83SMatthew G. Knepley 
100665876a83SMatthew G. Knepley // Time derivative of pressure
1007d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1008d71ae5a4SJacob Faibussowitsch {
100965876a83SMatthew G. Knepley   Parameter *param;
101065876a83SMatthew G. Knepley 
101165876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
101265876a83SMatthew G. Knepley 
10139566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
101465876a83SMatthew G. Knepley 
101565876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
101665876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
101765876a83SMatthew G. Knepley   PetscScalar M     = param->M;
101865876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
101965876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
102065876a83SMatthew G. Knepley 
102165876a83SMatthew G. Knepley   PetscScalar K_d  = K_u - alpha * alpha * M;
102265876a83SMatthew G. Knepley   PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
102365876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
102465876a83SMatthew G. Knepley 
102530602db0SMatthew G. Knepley   PetscReal a = (user->xmax[0] - user->xmin[0]) / 2.0;
102665876a83SMatthew G. Knepley   //PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
102765876a83SMatthew G. Knepley   //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
102865876a83SMatthew G. Knepley 
102965876a83SMatthew G. Knepley   u[0] = ((2.0 * F * (-2.0 * nu + 3.0 * nu_u)) / (3.0 * a * alpha * (1.0 - 2.0 * nu)));
103065876a83SMatthew G. Knepley 
10313ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
103265876a83SMatthew G. Knepley }
103365876a83SMatthew G. Knepley 
103465876a83SMatthew G. Knepley /* Cryer Solutions */
1035d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1036d71ae5a4SJacob Faibussowitsch {
103765876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
103865876a83SMatthew G. Knepley   Parameter *param;
103965876a83SMatthew G. Knepley 
10409566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
104165876a83SMatthew G. Knepley   if (time <= 0.0) {
104265876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;    /* -  */
104365876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;      /* Pa */
104465876a83SMatthew G. Knepley     PetscScalar M     = param->M;        /* Pa */
104565876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;      /* Pa */
104665876a83SMatthew G. Knepley     PetscScalar B     = alpha * M / K_u; /* -, Cheng (B.12) */
104765876a83SMatthew G. Knepley 
104865876a83SMatthew G. Knepley     u[0] = P_0 * B;
104965876a83SMatthew G. Knepley   } else {
105065876a83SMatthew G. Knepley     u[0] = 0.0;
105165876a83SMatthew G. Knepley   }
10523ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
105365876a83SMatthew G. Knepley }
105465876a83SMatthew G. Knepley 
1055d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1056d71ae5a4SJacob Faibussowitsch {
105765876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
105865876a83SMatthew G. Knepley   Parameter *param;
105965876a83SMatthew G. Knepley 
10609566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
106165876a83SMatthew G. Knepley   {
106265876a83SMatthew G. Knepley     PetscScalar K_u  = param->K_u;                                      /* Pa */
106365876a83SMatthew G. Knepley     PetscScalar G    = param->mu;                                       /* Pa */
106465876a83SMatthew G. Knepley     PetscScalar P_0  = param->P_0;                                      /* Pa */
106530602db0SMatthew G. Knepley     PetscReal   R_0  = user->xmax[1];                                   /* m */
106665876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
106765876a83SMatthew G. Knepley 
106865876a83SMatthew G. Knepley     PetscScalar u_0  = -P_0 * R_0 * (1. - 2. * nu_u) / (2. * G * (1. + nu_u)); /* Cheng (7.407) */
106965876a83SMatthew G. Knepley     PetscReal   u_sc = PetscRealPart(u_0) / R_0;
107065876a83SMatthew G. Knepley 
107165876a83SMatthew G. Knepley     u[0] = u_sc * x[0];
107265876a83SMatthew G. Knepley     u[1] = u_sc * x[1];
107365876a83SMatthew G. Knepley     u[2] = u_sc * x[2];
107465876a83SMatthew G. Knepley   }
10753ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
107665876a83SMatthew G. Knepley }
107765876a83SMatthew G. Knepley 
1078d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1079d71ae5a4SJacob Faibussowitsch {
108065876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
108165876a83SMatthew G. Knepley   Parameter *param;
108265876a83SMatthew G. Knepley 
10839566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
108465876a83SMatthew G. Knepley   {
108565876a83SMatthew G. Knepley     PetscScalar K_u  = param->K_u;                                      /* Pa */
108665876a83SMatthew G. Knepley     PetscScalar G    = param->mu;                                       /* Pa */
108765876a83SMatthew G. Knepley     PetscScalar P_0  = param->P_0;                                      /* Pa */
108830602db0SMatthew G. Knepley     PetscReal   R_0  = user->xmax[1];                                   /* m */
108965876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
109065876a83SMatthew G. Knepley 
109165876a83SMatthew G. Knepley     PetscScalar u_0  = -P_0 * R_0 * (1. - 2. * nu_u) / (2. * G * (1. + nu_u)); /* Cheng (7.407) */
109265876a83SMatthew G. Knepley     PetscReal   u_sc = PetscRealPart(u_0) / R_0;
109365876a83SMatthew G. Knepley 
109465876a83SMatthew G. Knepley     /* div R = 1/R^2 d/dR R^2 R = 3 */
109565876a83SMatthew G. Knepley     u[0] = 3. * u_sc;
109665876a83SMatthew G. Knepley     u[1] = 3. * u_sc;
109765876a83SMatthew G. Knepley     u[2] = 3. * u_sc;
109865876a83SMatthew G. Knepley   }
10993ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
110065876a83SMatthew G. Knepley }
110165876a83SMatthew G. Knepley 
110265876a83SMatthew G. Knepley // Displacement
1103d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1104d71ae5a4SJacob Faibussowitsch {
110565876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
110665876a83SMatthew G. Knepley   Parameter *param;
110765876a83SMatthew G. Knepley 
11089566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
110965876a83SMatthew G. Knepley   if (time <= 0.0) {
11109566063dSJacob Faibussowitsch     PetscCall(cryer_initial_u(dim, time, x, Nc, u, ctx));
111165876a83SMatthew G. Knepley   } else {
111265876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
111365876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
111465876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
111565876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
111665876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
111765876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
111830602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
111965876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
112065876a83SMatthew G. Knepley 
112165876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
112265876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
112365876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
112465876a83SMatthew G. Knepley     PetscScalar S     = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
112565876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
112665876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0 * R_0 * (1. - 2. * nu) / (2. * G * (1. + nu));  /* m,       Cheng (7.388) */
112765876a83SMatthew G. Knepley 
112865876a83SMatthew G. Knepley     PetscReal   R      = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
112965876a83SMatthew G. Knepley     PetscReal   R_star = R / R_0;
113065876a83SMatthew G. Knepley     PetscReal   tstar  = PetscRealPart(c * time) / PetscSqr(R_0); /* - */
113165876a83SMatthew G. Knepley     PetscReal   A_n    = 0.0;
113265876a83SMatthew G. Knepley     PetscScalar u_sc;
113365876a83SMatthew G. Knepley 
113465876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
113565876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n - 1];
113665876a83SMatthew 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));
113765876a83SMatthew G. Knepley 
113865876a83SMatthew G. Knepley       /* m , Cheng (7.404) */
11399371c9d4SSatish 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));
114065876a83SMatthew G. Knepley     }
114165876a83SMatthew G. Knepley     u_sc = PetscRealPart(u_inf) * (R_star - A_n);
114265876a83SMatthew G. Knepley     u[0] = u_sc * x[0] / R;
114365876a83SMatthew G. Knepley     u[1] = u_sc * x[1] / R;
114465876a83SMatthew G. Knepley     u[2] = u_sc * x[2] / R;
114565876a83SMatthew G. Knepley   }
11463ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
114765876a83SMatthew G. Knepley }
114865876a83SMatthew G. Knepley 
114965876a83SMatthew G. Knepley // Volumetric Strain
1150d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_3d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1151d71ae5a4SJacob Faibussowitsch {
115265876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
115365876a83SMatthew G. Knepley   Parameter *param;
115465876a83SMatthew G. Knepley 
11559566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
115665876a83SMatthew G. Knepley   if (time <= 0.0) {
11579566063dSJacob Faibussowitsch     PetscCall(cryer_initial_eps(dim, time, x, Nc, u, ctx));
115865876a83SMatthew G. Knepley   } else {
115965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
116065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
116165876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
116265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
116365876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
116465876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
116530602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
116665876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
116765876a83SMatthew G. Knepley 
116865876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
116965876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
117065876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
117165876a83SMatthew G. Knepley     PetscScalar S     = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
117265876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
117365876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0 * R_0 * (1. - 2. * nu) / (2. * G * (1. + nu));  /* m,       Cheng (7.388) */
117465876a83SMatthew G. Knepley 
117565876a83SMatthew G. Knepley     PetscReal R      = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
117665876a83SMatthew G. Knepley     PetscReal R_star = R / R_0;
117765876a83SMatthew G. Knepley     PetscReal tstar  = PetscRealPart(c * time) / PetscSqr(R_0); /* - */
117865876a83SMatthew G. Knepley     PetscReal divA_n = 0.0;
117965876a83SMatthew G. Knepley 
118065876a83SMatthew G. Knepley     if (R_star < PETSC_SMALL) {
118165876a83SMatthew G. Knepley       for (n = 1; n < N + 1; ++n) {
118265876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n - 1];
118365876a83SMatthew 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));
118465876a83SMatthew G. Knepley 
11859371c9d4SSatish 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));
118665876a83SMatthew G. Knepley       }
118765876a83SMatthew G. Knepley     } else {
118865876a83SMatthew G. Knepley       for (n = 1; n < N + 1; ++n) {
118965876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n - 1];
119065876a83SMatthew 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));
119165876a83SMatthew G. Knepley 
11929371c9d4SSatish 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));
119365876a83SMatthew G. Knepley       }
119465876a83SMatthew G. Knepley     }
11953ba16761SJacob Faibussowitsch     if (PetscAbsReal(divA_n) > 1e3) PetscCall(PetscPrintf(PETSC_COMM_SELF, "(%g, %g, %g) divA_n: %g\n", (double)x[0], (double)x[1], (double)x[2], (double)divA_n));
119665876a83SMatthew G. Knepley     u[0] = PetscRealPart(u_inf) / R_0 * (3.0 - divA_n);
119765876a83SMatthew G. Knepley   }
11983ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
119965876a83SMatthew G. Knepley }
120065876a83SMatthew G. Knepley 
120165876a83SMatthew G. Knepley // Pressure
1202d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_3d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1203d71ae5a4SJacob Faibussowitsch {
120465876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
120565876a83SMatthew G. Knepley   Parameter *param;
120665876a83SMatthew G. Knepley 
12079566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
120865876a83SMatthew G. Knepley   if (time <= 0.0) {
12099566063dSJacob Faibussowitsch     PetscCall(cryer_drainage_pressure(dim, time, x, Nc, u, ctx));
121065876a83SMatthew G. Knepley   } else {
121165876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
121265876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
121365876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
121465876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
121565876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
121630602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
121765876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
121865876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
121965876a83SMatthew G. Knepley 
122065876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
122165876a83SMatthew G. Knepley     PetscScalar eta  = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
122265876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
122365876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
122465876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
122565876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
122665876a83SMatthew G. Knepley     PetscScalar R    = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
122765876a83SMatthew G. Knepley 
122865876a83SMatthew G. Knepley     PetscScalar R_star = R / R_0;
122965876a83SMatthew G. Knepley     PetscScalar t_star = PetscRealPart(c * time) / PetscSqr(R_0);
123065876a83SMatthew G. Knepley     PetscReal   A_x    = 0.0;
123165876a83SMatthew G. Knepley 
123265876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
123365876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n - 1];
123465876a83SMatthew 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));
123565876a83SMatthew G. Knepley 
123665876a83SMatthew 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) */
123765876a83SMatthew G. Knepley     }
123865876a83SMatthew G. Knepley     u[0] = P_0 * A_x;
123965876a83SMatthew G. Knepley   }
12403ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
124165876a83SMatthew G. Knepley }
124265876a83SMatthew G. Knepley 
124365876a83SMatthew G. Knepley /* Boundary Kernels */
1244d71ae5a4SJacob Faibussowitsch 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[])
1245d71ae5a4SJacob Faibussowitsch {
124665876a83SMatthew G. Knepley   const PetscReal P = PetscRealPart(constants[5]);
124765876a83SMatthew G. Knepley 
124865876a83SMatthew G. Knepley   f0[0] = 0.0;
124965876a83SMatthew G. Knepley   f0[1] = P;
125065876a83SMatthew G. Knepley }
125165876a83SMatthew G. Knepley 
125245480ffeSMatthew G. Knepley #if 0
125365876a83SMatthew G. Knepley static void f0_mandel_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
125465876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
125565876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
125665876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
125765876a83SMatthew G. Knepley {
125865876a83SMatthew G. Knepley   // Uniform stress distribution
125965876a83SMatthew G. Knepley   /* PetscScalar xmax =  0.5;
126065876a83SMatthew G. Knepley   PetscScalar xmin = -0.5;
126165876a83SMatthew G. Knepley   PetscScalar ymax =  0.5;
126265876a83SMatthew G. Knepley   PetscScalar ymin = -0.5;
126365876a83SMatthew G. Knepley   PetscScalar P = constants[5];
126465876a83SMatthew G. Knepley   PetscScalar aL = (xmax - xmin) / 2.0;
126565876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*P / aL; */
126665876a83SMatthew G. Knepley 
126765876a83SMatthew G. Knepley   // Analytical (parabolic) stress distribution
126865876a83SMatthew G. Knepley   PetscReal a1, a2, am;
126965876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
127065876a83SMatthew G. Knepley 
127165876a83SMatthew G. Knepley   PetscInt NITER = 500;
127265876a83SMatthew G. Knepley   PetscReal EPS = 0.000001;
127365876a83SMatthew G. Knepley   PetscReal zeroArray[500]; /* NITER */
127465876a83SMatthew G. Knepley   PetscReal xmax =  1.0;
127565876a83SMatthew G. Knepley   PetscReal xmin =  0.0;
127665876a83SMatthew G. Knepley   PetscReal ymax =  0.1;
127765876a83SMatthew G. Knepley   PetscReal ymin =  0.0;
127865876a83SMatthew G. Knepley   PetscReal lower[2], upper[2];
127965876a83SMatthew G. Knepley 
128065876a83SMatthew G. Knepley   lower[0] = xmin - (xmax - xmin) / 2.0;
128165876a83SMatthew G. Knepley   lower[1] = ymin - (ymax - ymin) / 2.0;
128265876a83SMatthew G. Knepley   upper[0] = xmax - (xmax - xmin) / 2.0;
128365876a83SMatthew G. Knepley   upper[1] = ymax - (ymax - ymin) / 2.0;
128465876a83SMatthew G. Knepley 
128565876a83SMatthew G. Knepley   xmin = lower[0];
128665876a83SMatthew G. Knepley   ymin = lower[1];
128765876a83SMatthew G. Knepley   xmax = upper[0];
128865876a83SMatthew G. Knepley   ymax = upper[1];
128965876a83SMatthew G. Knepley 
129065876a83SMatthew G. Knepley   PetscScalar G     = constants[0];
129165876a83SMatthew G. Knepley   PetscScalar K_u   = constants[1];
129265876a83SMatthew G. Knepley   PetscScalar alpha = constants[2];
129365876a83SMatthew G. Knepley   PetscScalar M     = constants[3];
129465876a83SMatthew G. Knepley   PetscScalar kappa = constants[4];
129565876a83SMatthew G. Knepley   PetscScalar F     = constants[5];
129665876a83SMatthew G. Knepley 
129765876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
129865876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
129965876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
130065876a83SMatthew G. Knepley   PetscReal   aL = (xmax - xmin) / 2.0;
130165876a83SMatthew 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)));
130265876a83SMatthew G. Knepley   PetscScalar B = (3.0 * (nu_u - nu)) / ( alpha * (1.0 - 2.0*nu) * (1.0 + nu_u));
130365876a83SMatthew G. Knepley   PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
130465876a83SMatthew G. Knepley   PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
130565876a83SMatthew G. Knepley 
130665876a83SMatthew G. Knepley   // Generate zero values
130765876a83SMatthew G. Knepley   for (PetscInt i=1; i < NITER+1; i++)
130865876a83SMatthew G. Knepley   {
130965876a83SMatthew G. Knepley     a1 = ((PetscReal) i - 1.0) * PETSC_PI * PETSC_PI / 4.0 + EPS;
131065876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI/2;
131165876a83SMatthew G. Knepley     for (PetscInt j=0; j<NITER; j++)
131265876a83SMatthew G. Knepley     {
131365876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart(A1/A2)*a1;
131465876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart(A1/A2)*a2;
131565876a83SMatthew G. Knepley       am = (a1 + a2)/2.0;
131665876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart(A1/A2)*am;
131765876a83SMatthew G. Knepley       if ((ym*y1) > 0)
131865876a83SMatthew G. Knepley       {
131965876a83SMatthew G. Knepley         a1 = am;
132065876a83SMatthew G. Knepley       } else {
132165876a83SMatthew G. Knepley         a2 = am;
132265876a83SMatthew G. Knepley       }
132365876a83SMatthew G. Knepley       if (PetscAbsReal(y2) < EPS)
132465876a83SMatthew G. Knepley       {
132565876a83SMatthew G. Knepley         am = a2;
132665876a83SMatthew G. Knepley       }
132765876a83SMatthew G. Knepley     }
132865876a83SMatthew G. Knepley     zeroArray[i-1] = am;
132965876a83SMatthew G. Knepley   }
133065876a83SMatthew G. Knepley 
133165876a83SMatthew G. Knepley   // Solution for sigma_zz
133265876a83SMatthew G. Knepley   PetscScalar A_x = 0.0;
133365876a83SMatthew G. Knepley   PetscScalar B_x = 0.0;
133465876a83SMatthew G. Knepley 
133565876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
133665876a83SMatthew G. Knepley   {
133765876a83SMatthew G. Knepley     PetscReal alpha_n = zeroArray[n-1];
133865876a83SMatthew G. Knepley 
133965876a83SMatthew 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)));
134065876a83SMatthew 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)));
134165876a83SMatthew G. Knepley   }
134265876a83SMatthew G. Knepley 
134365876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*(F/aL) - ((2.0*F)/aL) * (A2/A1) * A_x + ((2.0*F)/aL) * B_x;
134465876a83SMatthew G. Knepley 
134565876a83SMatthew G. Knepley   if (x[1] == ymax) {
134665876a83SMatthew G. Knepley     f0[1] += sigma_zz;
134765876a83SMatthew G. Knepley   } else if (x[1] == ymin) {
134865876a83SMatthew G. Knepley     f0[1] -= sigma_zz;
134965876a83SMatthew G. Knepley   }
135065876a83SMatthew G. Knepley }
135145480ffeSMatthew G. Knepley #endif
135265876a83SMatthew G. Knepley 
1353d71ae5a4SJacob Faibussowitsch 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[])
1354d71ae5a4SJacob Faibussowitsch {
135565876a83SMatthew G. Knepley   const PetscReal P_0 = PetscRealPart(constants[5]);
135665876a83SMatthew G. Knepley   PetscInt        d;
135765876a83SMatthew G. Knepley 
135865876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) f0[d] = -P_0 * n[d];
135965876a83SMatthew G. Knepley }
136065876a83SMatthew G. Knepley 
136165876a83SMatthew G. Knepley /* Standard Kernels - Residual */
136265876a83SMatthew G. Knepley /* f0_e */
1363d71ae5a4SJacob Faibussowitsch 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[])
1364d71ae5a4SJacob Faibussowitsch {
136565876a83SMatthew G. Knepley   PetscInt d;
136665876a83SMatthew G. Knepley 
1367ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) f0[0] += u_x[d * dim + d];
136865876a83SMatthew G. Knepley   f0[0] -= u[uOff[1]];
136965876a83SMatthew G. Knepley }
137065876a83SMatthew G. Knepley 
137165876a83SMatthew G. Knepley /* f0_p */
1372d71ae5a4SJacob Faibussowitsch 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[])
1373d71ae5a4SJacob Faibussowitsch {
137465876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
137565876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
137665876a83SMatthew G. Knepley 
137765876a83SMatthew G. Knepley   f0[0] += alpha * u_t[uOff[1]];
137865876a83SMatthew G. Knepley   f0[0] += u_t[uOff[2]] / M;
137930602db0SMatthew G. Knepley   if (f0[0] != f0[0]) abort();
138065876a83SMatthew G. Knepley }
138165876a83SMatthew G. Knepley 
138265876a83SMatthew G. Knepley /* f1_u */
1383d71ae5a4SJacob Faibussowitsch 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[])
1384d71ae5a4SJacob Faibussowitsch {
138565876a83SMatthew G. Knepley   const PetscInt  Nc     = dim;
138665876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
138765876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
138865876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
138965876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
139065876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
139165876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
139265876a83SMatthew G. Knepley   PetscInt        c, d;
139365876a83SMatthew G. Knepley 
13949371c9d4SSatish Balay   for (c = 0; c < Nc; ++c) {
1395ad540459SPierre Jolivet     for (d = 0; d < dim; ++d) f1[c * dim + d] -= G * (u_x[c * dim + d] + u_x[d * dim + c]);
139665876a83SMatthew G. Knepley     f1[c * dim + c] -= lambda * u[uOff[1]];
139765876a83SMatthew G. Knepley     f1[c * dim + c] += alpha * u[uOff[2]];
139865876a83SMatthew G. Knepley   }
139965876a83SMatthew G. Knepley }
140065876a83SMatthew G. Knepley 
140165876a83SMatthew G. Knepley /* f1_p */
1402d71ae5a4SJacob Faibussowitsch 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[])
1403d71ae5a4SJacob Faibussowitsch {
140465876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
140565876a83SMatthew G. Knepley   PetscInt        d;
140665876a83SMatthew G. Knepley 
1407ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) f1[d] += kappa * u_x[uOff_x[2] + d];
140865876a83SMatthew G. Knepley }
140965876a83SMatthew G. Knepley 
141065876a83SMatthew G. Knepley /*
141165876a83SMatthew G. Knepley   \partial_df \phi_fc g_{fc,gc,df,dg} \partial_dg \phi_gc
141265876a83SMatthew G. Knepley 
141365876a83SMatthew G. Knepley   \partial_df \phi_fc \lambda \delta_{fc,df} \sum_gc \partial_dg \phi_gc \delta_{gc,dg}
141465876a83SMatthew G. Knepley   = \partial_fc \phi_fc \sum_gc \partial_gc \phi_gc
141565876a83SMatthew G. Knepley */
141665876a83SMatthew G. Knepley 
141765876a83SMatthew G. Knepley /* Standard Kernels - Jacobian */
141865876a83SMatthew G. Knepley /* g0_ee */
1419d71ae5a4SJacob Faibussowitsch 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[])
1420d71ae5a4SJacob Faibussowitsch {
142165876a83SMatthew G. Knepley   g0[0] = -1.0;
142265876a83SMatthew G. Knepley }
142365876a83SMatthew G. Knepley 
142465876a83SMatthew G. Knepley /* g0_pe */
1425d71ae5a4SJacob Faibussowitsch 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[])
1426d71ae5a4SJacob Faibussowitsch {
142765876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
142865876a83SMatthew G. Knepley 
142965876a83SMatthew G. Knepley   g0[0] = u_tShift * alpha;
143065876a83SMatthew G. Knepley }
143165876a83SMatthew G. Knepley 
143265876a83SMatthew G. Knepley /* g0_pp */
1433d71ae5a4SJacob Faibussowitsch 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[])
1434d71ae5a4SJacob Faibussowitsch {
143565876a83SMatthew G. Knepley   const PetscReal M = PetscRealPart(constants[3]);
143665876a83SMatthew G. Knepley 
143765876a83SMatthew G. Knepley   g0[0] = u_tShift / M;
143865876a83SMatthew G. Knepley }
143965876a83SMatthew G. Knepley 
144065876a83SMatthew G. Knepley /* g1_eu */
1441d71ae5a4SJacob Faibussowitsch 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[])
1442d71ae5a4SJacob Faibussowitsch {
144365876a83SMatthew G. Knepley   PetscInt d;
144465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g1[d * dim + d] = 1.0; /* \frac{\partial\phi^{u_d}}{\partial x_d} */
144565876a83SMatthew G. Knepley }
144665876a83SMatthew G. Knepley 
144765876a83SMatthew G. Knepley /* g2_ue */
1448d71ae5a4SJacob Faibussowitsch 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[])
1449d71ae5a4SJacob Faibussowitsch {
145065876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
145165876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
145265876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
145365876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
145465876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
145565876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
145665876a83SMatthew G. Knepley   PetscInt        d;
145765876a83SMatthew G. Knepley 
1458ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) g2[d * dim + d] -= lambda;
145965876a83SMatthew G. Knepley }
146065876a83SMatthew G. Knepley /* g2_up */
1461d71ae5a4SJacob Faibussowitsch 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[])
1462d71ae5a4SJacob Faibussowitsch {
146365876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
146465876a83SMatthew G. Knepley   PetscInt        d;
146565876a83SMatthew G. Knepley 
1466ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) g2[d * dim + d] += alpha;
146765876a83SMatthew G. Knepley }
146865876a83SMatthew G. Knepley 
146965876a83SMatthew G. Knepley /* g3_uu */
1470d71ae5a4SJacob Faibussowitsch 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[])
1471d71ae5a4SJacob Faibussowitsch {
147265876a83SMatthew G. Knepley   const PetscInt  Nc = dim;
147365876a83SMatthew G. Knepley   const PetscReal G  = PetscRealPart(constants[0]);
147465876a83SMatthew G. Knepley   PetscInt        c, d;
147565876a83SMatthew G. Knepley 
147665876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) {
147765876a83SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
147865876a83SMatthew G. Knepley       g3[((c * Nc + c) * dim + d) * dim + d] -= G;
147965876a83SMatthew G. Knepley       g3[((c * Nc + d) * dim + d) * dim + c] -= G;
148065876a83SMatthew G. Knepley     }
148165876a83SMatthew G. Knepley   }
148265876a83SMatthew G. Knepley }
148365876a83SMatthew G. Knepley 
148465876a83SMatthew G. Knepley /* g3_pp */
1485d71ae5a4SJacob Faibussowitsch 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[])
1486d71ae5a4SJacob Faibussowitsch {
148765876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
148865876a83SMatthew G. Knepley   PetscInt        d;
148965876a83SMatthew G. Knepley 
149065876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g3[d * dim + d] += kappa;
149165876a83SMatthew G. Knepley }
149265876a83SMatthew G. Knepley 
1493d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
1494d71ae5a4SJacob Faibussowitsch {
149565876a83SMatthew G. Knepley   PetscInt sol;
149665876a83SMatthew G. Knepley 
149765876a83SMatthew G. Knepley   PetscFunctionBeginUser;
149865876a83SMatthew G. Knepley   options->solType   = SOL_QUADRATIC_TRIG;
149965876a83SMatthew G. Knepley   options->niter     = 500;
150065876a83SMatthew G. Knepley   options->eps       = PETSC_SMALL;
150124b15d09SMatthew G. Knepley   options->dtInitial = -1.0;
1502d0609cedSBarry Smith   PetscOptionsBegin(comm, "", "Biot Poroelasticity Options", "DMPLEX");
15039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-niter", "Number of series term iterations in exact solutions", "ex53.c", options->niter, &options->niter, NULL));
150465876a83SMatthew G. Knepley   sol = options->solType;
15059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-sol_type", "Type of exact solution", "ex53.c", solutionTypes, NUM_SOLUTION_TYPES, solutionTypes[options->solType], &sol, NULL));
150665876a83SMatthew G. Knepley   options->solType = (SolutionType)sol;
15079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-eps", "Precision value for root finding", "ex53.c", options->eps, &options->eps, NULL));
15089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-dt_initial", "Override the initial timestep", "ex53.c", options->dtInitial, &options->dtInitial, NULL));
1509d0609cedSBarry Smith   PetscOptionsEnd();
15103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
151165876a83SMatthew G. Knepley }
151265876a83SMatthew G. Knepley 
1513d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandelZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param)
1514d71ae5a4SJacob Faibussowitsch {
151565876a83SMatthew G. Knepley   //PetscBag       bag;
151665876a83SMatthew G. Knepley   PetscReal a1, a2, am;
151765876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
151865876a83SMatthew G. Knepley 
151965876a83SMatthew G. Knepley   PetscFunctionBeginUser;
15209566063dSJacob Faibussowitsch   //PetscCall(PetscBagGetData(ctx->bag, (void **) &param));
152165876a83SMatthew G. Knepley   PetscInt  NITER = ctx->niter;
152265876a83SMatthew G. Knepley   PetscReal EPS   = ctx->eps;
152365876a83SMatthew G. Knepley   //const PetscScalar YMAX = param->ymax;
152465876a83SMatthew G. Knepley   //const PetscScalar YMIN = param->ymin;
152565876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
152665876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
152765876a83SMatthew G. Knepley   PetscScalar M     = param->M;
152865876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
152965876a83SMatthew G. Knepley   //const PetscScalar k = param->k;
153065876a83SMatthew G. Knepley   //const PetscScalar mu_f = param->mu_f;
153165876a83SMatthew G. Knepley   //const PetscScalar P_0 = param->P_0;
153265876a83SMatthew G. Knepley 
153365876a83SMatthew G. Knepley   PetscScalar K_d  = K_u - alpha * alpha * M;
153465876a83SMatthew G. Knepley   PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
153565876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
153665876a83SMatthew G. Knepley   //const PetscScalar kappa = k / mu_f;
153765876a83SMatthew G. Knepley 
153865876a83SMatthew G. Knepley   // Generate zero values
15399371c9d4SSatish Balay   for (PetscInt i = 1; i < NITER + 1; i++) {
154065876a83SMatthew G. Knepley     a1 = ((PetscReal)i - 1.0) * PETSC_PI * PETSC_PI / 4.0 + EPS;
154165876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI / 2;
154265876a83SMatthew G. Knepley     am = a1;
15439371c9d4SSatish Balay     for (PetscInt j = 0; j < NITER; j++) {
154465876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * a1;
154565876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * a2;
154665876a83SMatthew G. Knepley       am = (a1 + a2) / 2.0;
154765876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * am;
15489371c9d4SSatish Balay       if ((ym * y1) > 0) {
154965876a83SMatthew G. Knepley         a1 = am;
155065876a83SMatthew G. Knepley       } else {
155165876a83SMatthew G. Knepley         a2 = am;
155265876a83SMatthew G. Knepley       }
1553ad540459SPierre Jolivet       if (PetscAbsReal(y2) < EPS) am = a2;
155465876a83SMatthew G. Knepley     }
155565876a83SMatthew G. Knepley     ctx->zeroArray[i - 1] = am;
155665876a83SMatthew G. Knepley   }
15573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
155865876a83SMatthew G. Knepley }
155965876a83SMatthew G. Knepley 
1560d71ae5a4SJacob Faibussowitsch static PetscReal CryerFunction(PetscReal nu_u, PetscReal nu, PetscReal x)
1561d71ae5a4SJacob Faibussowitsch {
156265876a83SMatthew 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));
156365876a83SMatthew G. Knepley }
156465876a83SMatthew G. Knepley 
1565d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryerZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param)
1566d71ae5a4SJacob Faibussowitsch {
156765876a83SMatthew G. Knepley   PetscReal alpha = PetscRealPart(param->alpha); /* -  */
156865876a83SMatthew G. Knepley   PetscReal K_u   = PetscRealPart(param->K_u);   /* Pa */
156965876a83SMatthew G. Knepley   PetscReal M     = PetscRealPart(param->M);     /* Pa */
157065876a83SMatthew G. Knepley   PetscReal G     = PetscRealPart(param->mu);    /* Pa */
157165876a83SMatthew G. Knepley   PetscInt  N     = ctx->niter, n;
157265876a83SMatthew G. Knepley 
157365876a83SMatthew G. Knepley   PetscReal K_d  = K_u - alpha * alpha * M;                         /* Pa,      Cheng (B.5)  */
157465876a83SMatthew G. Knepley   PetscReal nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G)); /* -,       Cheng (B.8)  */
157565876a83SMatthew G. Knepley   PetscReal nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
157665876a83SMatthew G. Knepley 
157765876a83SMatthew G. Knepley   PetscFunctionBeginUser;
157865876a83SMatthew G. Knepley   for (n = 1; n < N + 1; ++n) {
157965876a83SMatthew G. Knepley     PetscReal tol = PetscPowReal(n, 1.5) * ctx->eps;
158065876a83SMatthew G. Knepley     PetscReal a1 = 0., a2 = 0., am = 0.;
158165876a83SMatthew G. Knepley     PetscReal y1, y2, ym;
158265876a83SMatthew G. Knepley     PetscInt  j, k = n - 1;
158365876a83SMatthew G. Knepley 
158465876a83SMatthew G. Knepley     y1 = y2 = 1.;
158565876a83SMatthew G. Knepley     while (y1 * y2 > 0) {
158665876a83SMatthew G. Knepley       ++k;
158765876a83SMatthew G. Knepley       a1 = PetscSqr(n * PETSC_PI) - k * PETSC_PI;
158865876a83SMatthew G. Knepley       a2 = PetscSqr(n * PETSC_PI) + k * PETSC_PI;
158965876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
159065876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
159165876a83SMatthew G. Knepley     }
159265876a83SMatthew G. Knepley     for (j = 0; j < 50000; ++j) {
159365876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
159465876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
159563a3b9bcSJacob 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);
159665876a83SMatthew G. Knepley       am = (a1 + a2) / 2.0;
159765876a83SMatthew G. Knepley       ym = CryerFunction(nu_u, nu, am);
159865876a83SMatthew G. Knepley       if ((ym * y1) < 0) a2 = am;
159965876a83SMatthew G. Knepley       else a1 = am;
160063a3b9bcSJacob Faibussowitsch       if (PetscAbsReal(ym) < tol) break;
160165876a83SMatthew G. Knepley     }
160263a3b9bcSJacob Faibussowitsch     PetscCheck(PetscAbsReal(ym) < tol, comm, PETSC_ERR_PLIB, "Root finding did not converge for root %" PetscInt_FMT " (%g)", n, (double)PetscAbsReal(ym));
160365876a83SMatthew G. Knepley     ctx->zeroArray[n - 1] = am;
160465876a83SMatthew G. Knepley   }
16053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
160665876a83SMatthew G. Knepley }
160765876a83SMatthew G. Knepley 
1608d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupParameters(MPI_Comm comm, AppCtx *ctx)
1609d71ae5a4SJacob Faibussowitsch {
161065876a83SMatthew G. Knepley   PetscBag   bag;
161165876a83SMatthew G. Knepley   Parameter *p;
161265876a83SMatthew G. Knepley 
161365876a83SMatthew G. Knepley   PetscFunctionBeginUser;
161465876a83SMatthew G. Knepley   /* setup PETSc parameter bag */
16159566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(ctx->bag, (void **)&p));
16169566063dSJacob Faibussowitsch   PetscCall(PetscBagSetName(ctx->bag, "par", "Poroelastic Parameters"));
161765876a83SMatthew G. Knepley   bag = ctx->bag;
161865876a83SMatthew G. Knepley   if (ctx->solType == SOL_TERZAGHI) {
161965876a83SMatthew G. Knepley     // Realistic values - Terzaghi
16209566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 3.0, "mu", "Shear Modulus, Pa"));
16219566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 9.76, "K_u", "Undrained Bulk Modulus, Pa"));
16229566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
16239566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 16.0, "M", "Biot Modulus, Pa"));
16249566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
16259566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
16269566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
162765876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_MANDEL) {
162865876a83SMatthew G. Knepley     // Realistic values - Mandel
16299566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 0.75, "mu", "Shear Modulus, Pa"));
16309566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 2.6941176470588233, "K_u", "Undrained Bulk Modulus, Pa"));
16319566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
16329566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 4.705882352941176, "M", "Biot Modulus, Pa"));
16339566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
16349566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
16359566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
163665876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_CRYER) {
163765876a83SMatthew G. Knepley     // Realistic values - Mandel
16389566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 0.75, "mu", "Shear Modulus, Pa"));
16399566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 2.6941176470588233, "K_u", "Undrained Bulk Modulus, Pa"));
16409566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
16419566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 4.705882352941176, "M", "Biot Modulus, Pa"));
16429566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
16439566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
16449566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
164565876a83SMatthew G. Knepley   } else {
164665876a83SMatthew G. Knepley     // Nonsense values
16479566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 1.0, "mu", "Shear Modulus, Pa"));
16489566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 1.0, "K_u", "Undrained Bulk Modulus, Pa"));
16499566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 1.0, "alpha", "Biot Effective Stress Coefficient, -"));
16509566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 1.0, "M", "Biot Modulus, Pa"));
16519566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.0, "k", "Isotropic Permeability, m**2"));
16529566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
16539566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
165465876a83SMatthew G. Knepley   }
16559566063dSJacob Faibussowitsch   PetscCall(PetscBagSetFromOptions(bag));
165665876a83SMatthew G. Knepley   {
165765876a83SMatthew G. Knepley     PetscScalar K_d  = p->K_u - p->alpha * p->alpha * p->M;
165865876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * p->K_u - 2.0 * p->mu) / (2.0 * (3.0 * p->K_u + p->mu));
165965876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * p->mu) / (2.0 * (3.0 * K_d + p->mu));
166065876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * p->K_u + 4.0 * p->mu) / (p->M * (3.0 * K_d + 4.0 * p->mu));
166165876a83SMatthew G. Knepley     PetscReal   c    = PetscRealPart((p->k / p->mu_f) / S);
166265876a83SMatthew G. Knepley 
166365876a83SMatthew G. Knepley     PetscViewer       viewer;
166465876a83SMatthew G. Knepley     PetscViewerFormat format;
166565876a83SMatthew G. Knepley     PetscBool         flg;
166665876a83SMatthew G. Knepley 
166765876a83SMatthew G. Knepley     switch (ctx->solType) {
166865876a83SMatthew G. Knepley     case SOL_QUADRATIC_LINEAR:
166965876a83SMatthew G. Knepley     case SOL_QUADRATIC_TRIG:
1670d71ae5a4SJacob Faibussowitsch     case SOL_TRIG_LINEAR:
1671d71ae5a4SJacob Faibussowitsch       ctx->t_r = PetscSqr(ctx->xmax[0] - ctx->xmin[0]) / c;
1672d71ae5a4SJacob Faibussowitsch       break;
1673d71ae5a4SJacob Faibussowitsch     case SOL_TERZAGHI:
1674d71ae5a4SJacob Faibussowitsch       ctx->t_r = PetscSqr(2.0 * (ctx->xmax[1] - ctx->xmin[1])) / c;
1675d71ae5a4SJacob Faibussowitsch       break;
1676d71ae5a4SJacob Faibussowitsch     case SOL_MANDEL:
1677d71ae5a4SJacob Faibussowitsch       ctx->t_r = PetscSqr(2.0 * (ctx->xmax[1] - ctx->xmin[1])) / c;
1678d71ae5a4SJacob Faibussowitsch       break;
1679d71ae5a4SJacob Faibussowitsch     case SOL_CRYER:
1680d71ae5a4SJacob Faibussowitsch       ctx->t_r = PetscSqr(ctx->xmax[1]) / c;
1681d71ae5a4SJacob Faibussowitsch       break;
1682d71ae5a4SJacob Faibussowitsch     default:
1683d71ae5a4SJacob Faibussowitsch       SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%d)", solutionTypes[PetscMin(ctx->solType, NUM_SOLUTION_TYPES)], ctx->solType);
168465876a83SMatthew G. Knepley     }
16859566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(comm, NULL, NULL, "-param_view", &viewer, &format, &flg));
168665876a83SMatthew G. Knepley     if (flg) {
16879566063dSJacob Faibussowitsch       PetscCall(PetscViewerPushFormat(viewer, format));
16889566063dSJacob Faibussowitsch       PetscCall(PetscBagView(bag, viewer));
16899566063dSJacob Faibussowitsch       PetscCall(PetscViewerFlush(viewer));
16909566063dSJacob Faibussowitsch       PetscCall(PetscViewerPopFormat(viewer));
16919566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&viewer));
169263a3b9bcSJacob 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)))));
169363a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "  Relaxation time: %g\n", (double)ctx->t_r));
169465876a83SMatthew G. Knepley     }
169565876a83SMatthew G. Knepley   }
16963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
169765876a83SMatthew G. Knepley }
169865876a83SMatthew G. Knepley 
1699d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
1700d71ae5a4SJacob Faibussowitsch {
170165876a83SMatthew G. Knepley   PetscFunctionBeginUser;
17029566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
17039566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMPLEX));
17049566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(*dm));
17059566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(*dm, user));
17069566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
17079566063dSJacob Faibussowitsch   PetscCall(DMGetBoundingBox(*dm, user->xmin, user->xmax));
17083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
170965876a83SMatthew G. Knepley }
171065876a83SMatthew G. Knepley 
1711d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupPrimalProblem(DM dm, AppCtx *user)
1712d71ae5a4SJacob Faibussowitsch {
171365876a83SMatthew G. Knepley   PetscErrorCode (*exact[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
171465876a83SMatthew G. Knepley   PetscErrorCode (*exact_t[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
171545480ffeSMatthew G. Knepley   PetscDS       ds;
171645480ffeSMatthew G. Knepley   DMLabel       label;
171745480ffeSMatthew G. Knepley   PetscWeakForm wf;
171865876a83SMatthew G. Knepley   Parameter    *param;
171965876a83SMatthew G. Knepley   PetscInt      id_mandel[2];
172065876a83SMatthew G. Knepley   PetscInt      comp[1];
172165876a83SMatthew G. Knepley   PetscInt      comp_mandel[2];
172245480ffeSMatthew G. Knepley   PetscInt      dim, id, bd, f;
172365876a83SMatthew G. Knepley 
172465876a83SMatthew G. Knepley   PetscFunctionBeginUser;
17259566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "marker", &label));
17269566063dSJacob Faibussowitsch   PetscCall(DMGetDS(dm, &ds));
17279566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(ds, &dim));
17289566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
172965876a83SMatthew G. Knepley   exact_t[0] = exact_t[1] = exact_t[2] = zero;
173065876a83SMatthew G. Knepley 
173165876a83SMatthew G. Knepley   /* Setup Problem Formulation and Boundary Conditions */
173265876a83SMatthew G. Knepley   switch (user->solType) {
173365876a83SMatthew G. Knepley   case SOL_QUADRATIC_LINEAR:
17349566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_quadratic_linear_u, f1_u));
17359566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17369566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_quadratic_linear_p, f1_p));
17379566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17389566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17399566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17409566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17419566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17429566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17439566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
174465876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
174565876a83SMatthew G. Knepley     exact[1]   = linear_eps;
174665876a83SMatthew G. Knepley     exact[2]   = linear_linear_p;
174765876a83SMatthew G. Knepley     exact_t[2] = linear_linear_p_t;
174865876a83SMatthew G. Knepley 
174965876a83SMatthew G. Knepley     id = 1;
17509566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
17519566063dSJacob 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));
175265876a83SMatthew G. Knepley     break;
175365876a83SMatthew G. Knepley   case SOL_TRIG_LINEAR:
17549566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_trig_linear_u, f1_u));
17559566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17569566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_trig_linear_p, f1_p));
17579566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17589566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17599566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17609566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17619566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17629566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17639566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
176465876a83SMatthew G. Knepley     exact[0]   = trig_u;
176565876a83SMatthew G. Knepley     exact[1]   = trig_eps;
176665876a83SMatthew G. Knepley     exact[2]   = trig_linear_p;
176765876a83SMatthew G. Knepley     exact_t[2] = trig_linear_p_t;
176865876a83SMatthew G. Knepley 
176965876a83SMatthew G. Knepley     id = 1;
17709566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
17719566063dSJacob 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));
177265876a83SMatthew G. Knepley     break;
177365876a83SMatthew G. Knepley   case SOL_QUADRATIC_TRIG:
17749566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_quadratic_trig_u, f1_u));
17759566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17769566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_quadratic_trig_p, f1_p));
17779566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17789566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17799566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17809566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17819566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17829566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17839566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
178465876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
178565876a83SMatthew G. Knepley     exact[1]   = linear_eps;
178665876a83SMatthew G. Knepley     exact[2]   = linear_trig_p;
178765876a83SMatthew G. Knepley     exact_t[2] = linear_trig_p_t;
178865876a83SMatthew G. Knepley 
178965876a83SMatthew G. Knepley     id = 1;
17909566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
17919566063dSJacob 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));
179265876a83SMatthew G. Knepley     break;
179365876a83SMatthew G. Knepley   case SOL_TERZAGHI:
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 
180565876a83SMatthew G. Knepley     exact[0]   = terzaghi_2d_u;
180665876a83SMatthew G. Knepley     exact[1]   = terzaghi_2d_eps;
180765876a83SMatthew G. Knepley     exact[2]   = terzaghi_2d_p;
180865876a83SMatthew G. Knepley     exact_t[0] = terzaghi_2d_u_t;
180965876a83SMatthew G. Knepley     exact_t[1] = terzaghi_2d_eps_t;
181065876a83SMatthew G. Knepley     exact_t[2] = terzaghi_2d_p_t;
181165876a83SMatthew G. Knepley 
181265876a83SMatthew G. Knepley     id = 1;
18139566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", label, 1, &id, 0, 0, NULL, NULL, NULL, user, &bd));
18149566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
18159566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, 0, f0_terzaghi_bd_u, 0, NULL));
181645480ffeSMatthew G. Knepley 
181765876a83SMatthew G. Knepley     id      = 3;
181865876a83SMatthew G. Knepley     comp[0] = 1;
18199566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
182065876a83SMatthew G. Knepley     id      = 2;
182165876a83SMatthew G. Knepley     comp[0] = 0;
18229566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
182365876a83SMatthew G. Knepley     id      = 4;
182465876a83SMatthew G. Knepley     comp[0] = 0;
18259566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
182665876a83SMatthew G. Knepley     id = 1;
18279566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 1, &id, 2, 0, NULL, (void (*)(void))terzaghi_drainage_pressure, NULL, user, NULL));
182865876a83SMatthew G. Knepley     break;
182965876a83SMatthew G. Knepley   case SOL_MANDEL:
18309566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_u));
18319566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
18329566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_p, f1_p));
18339566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
18349566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
18359566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
18369566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
18379566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
18389566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
18399566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
184065876a83SMatthew G. Knepley 
18419566063dSJacob Faibussowitsch     PetscCall(mandelZeros(PETSC_COMM_WORLD, user, param));
184265876a83SMatthew G. Knepley 
184365876a83SMatthew G. Knepley     exact[0]   = mandel_2d_u;
184465876a83SMatthew G. Knepley     exact[1]   = mandel_2d_eps;
184565876a83SMatthew G. Knepley     exact[2]   = mandel_2d_p;
184665876a83SMatthew G. Knepley     exact_t[0] = mandel_2d_u_t;
184765876a83SMatthew G. Knepley     exact_t[1] = mandel_2d_eps_t;
184865876a83SMatthew G. Knepley     exact_t[2] = mandel_2d_p_t;
184965876a83SMatthew G. Knepley 
185065876a83SMatthew G. Knepley     id_mandel[0] = 3;
185165876a83SMatthew G. Knepley     id_mandel[1] = 1;
185265876a83SMatthew G. Knepley     //comp[0] = 1;
185365876a83SMatthew G. Knepley     comp_mandel[0] = 0;
185465876a83SMatthew G. Knepley     comp_mandel[1] = 1;
18559566063dSJacob 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));
18569566063dSJacob Faibussowitsch     //PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", "marker", 0, 1, comp, NULL, 2, id_mandel, user));
18579566063dSJacob Faibussowitsch     //PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", "marker", 0, 1, comp, (void (*)(void)) zero, 2, id_mandel, user));
18589566063dSJacob Faibussowitsch     //PetscCall(PetscDSSetBdResidual(ds, 0, f0_mandel_bd_u, NULL));
185965876a83SMatthew G. Knepley 
186065876a83SMatthew G. Knepley     id_mandel[0] = 2;
186165876a83SMatthew G. Knepley     id_mandel[1] = 4;
18629566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 2, id_mandel, 2, 0, NULL, (void (*)(void))zero, NULL, user, NULL));
186365876a83SMatthew G. Knepley     break;
186465876a83SMatthew G. Knepley   case SOL_CRYER:
18659566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_u));
18669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
18679566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_p, f1_p));
18689566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
18699566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
18709566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
18719566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
18729566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
18739566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
18749566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
187565876a83SMatthew G. Knepley 
18769566063dSJacob Faibussowitsch     PetscCall(cryerZeros(PETSC_COMM_WORLD, user, param));
187765876a83SMatthew G. Knepley 
187865876a83SMatthew G. Knepley     exact[0] = cryer_3d_u;
187965876a83SMatthew G. Knepley     exact[1] = cryer_3d_eps;
188065876a83SMatthew G. Knepley     exact[2] = cryer_3d_p;
188165876a83SMatthew G. Knepley 
188265876a83SMatthew G. Knepley     id = 1;
18839566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "normal stress", label, 1, &id, 0, 0, NULL, NULL, NULL, user, &bd));
18849566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
18859566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, 0, f0_cryer_bd_u, 0, NULL));
188645480ffeSMatthew G. Knepley 
18879566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 1, &id, 2, 0, NULL, (void (*)(void))cryer_drainage_pressure, NULL, user, NULL));
188865876a83SMatthew G. Knepley     break;
1889d71ae5a4SJacob Faibussowitsch   default:
1890d71ae5a4SJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%d)", solutionTypes[PetscMin(user->solType, NUM_SOLUTION_TYPES)], user->solType);
189165876a83SMatthew G. Knepley   }
189265876a83SMatthew G. Knepley   for (f = 0; f < 3; ++f) {
18939566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(ds, f, exact[f], user));
18949566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(ds, f, exact_t[f], user));
189565876a83SMatthew G. Knepley   }
189665876a83SMatthew G. Knepley 
189765876a83SMatthew G. Knepley   /* Setup constants */
189865876a83SMatthew G. Knepley   {
189965876a83SMatthew G. Knepley     PetscScalar constants[6];
190065876a83SMatthew G. Knepley     constants[0] = param->mu;              /* shear modulus, Pa */
190165876a83SMatthew G. Knepley     constants[1] = param->K_u;             /* undrained bulk modulus, Pa */
190265876a83SMatthew G. Knepley     constants[2] = param->alpha;           /* Biot effective stress coefficient, - */
190365876a83SMatthew G. Knepley     constants[3] = param->M;               /* Biot modulus, Pa */
190465876a83SMatthew G. Knepley     constants[4] = param->k / param->mu_f; /* Darcy coefficient, m**2 / Pa*s */
190565876a83SMatthew G. Knepley     constants[5] = param->P_0;             /* Magnitude of Vertical Stress, Pa */
19069566063dSJacob Faibussowitsch     PetscCall(PetscDSSetConstants(ds, 6, constants));
190765876a83SMatthew G. Knepley   }
19083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
190965876a83SMatthew G. Knepley }
191065876a83SMatthew G. Knepley 
1911d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateElasticityNullSpace(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullspace)
1912d71ae5a4SJacob Faibussowitsch {
19137510d9b0SBarry Smith   PetscFunctionBeginUser;
19149566063dSJacob Faibussowitsch   PetscCall(DMPlexCreateRigidBody(dm, origField, nullspace));
19153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
191665876a83SMatthew G. Knepley }
191765876a83SMatthew G. Knepley 
1918d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupFE(DM dm, PetscInt Nf, PetscInt Nc[], const char *name[], PetscErrorCode (*setup)(DM, AppCtx *), void *ctx)
1919d71ae5a4SJacob Faibussowitsch {
192065876a83SMatthew G. Knepley   AppCtx         *user = (AppCtx *)ctx;
192165876a83SMatthew G. Knepley   DM              cdm  = dm;
192265876a83SMatthew G. Knepley   PetscFE         fe;
1923*2456a0d3SMatthew G. Knepley   PetscQuadrature q = NULL, fq = NULL;
192465876a83SMatthew G. Knepley   char            prefix[PETSC_MAX_PATH_LEN];
192565876a83SMatthew G. Knepley   PetscInt        dim, f;
192630602db0SMatthew G. Knepley   PetscBool       simplex;
192765876a83SMatthew G. Knepley 
19287510d9b0SBarry Smith   PetscFunctionBeginUser;
192965876a83SMatthew G. Knepley   /* Create finite element */
19309566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
19319566063dSJacob Faibussowitsch   PetscCall(DMPlexIsSimplex(dm, &simplex));
193265876a83SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
19339566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(prefix, PETSC_MAX_PATH_LEN, "%s_", name[f]));
19349566063dSJacob Faibussowitsch     PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, Nc[f], simplex, name[f] ? prefix : NULL, -1, &fe));
19359566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetName((PetscObject)fe, name[f]));
19369566063dSJacob Faibussowitsch     if (!q) PetscCall(PetscFEGetQuadrature(fe, &q));
1937*2456a0d3SMatthew G. Knepley     if (!fq) PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
19389566063dSJacob Faibussowitsch     PetscCall(PetscFESetQuadrature(fe, q));
1939*2456a0d3SMatthew G. Knepley     PetscCall(PetscFESetFaceQuadrature(fe, fq));
19409566063dSJacob Faibussowitsch     PetscCall(DMSetField(dm, f, NULL, (PetscObject)fe));
19419566063dSJacob Faibussowitsch     PetscCall(PetscFEDestroy(&fe));
194265876a83SMatthew G. Knepley   }
19439566063dSJacob Faibussowitsch   PetscCall(DMCreateDS(dm));
19449566063dSJacob Faibussowitsch   PetscCall((*setup)(dm, user));
194565876a83SMatthew G. Knepley   while (cdm) {
19469566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(dm, cdm));
19479566063dSJacob Faibussowitsch     if (0) PetscCall(DMSetNearNullSpaceConstructor(cdm, 0, CreateElasticityNullSpace));
194865876a83SMatthew G. Knepley     /* TODO: Check whether the boundary of coarse meshes is marked */
19499566063dSJacob Faibussowitsch     PetscCall(DMGetCoarseDM(cdm, &cdm));
195065876a83SMatthew G. Knepley   }
19519566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&fe));
19523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
195365876a83SMatthew G. Knepley }
195465876a83SMatthew G. Knepley 
1955d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetInitialConditions(TS ts, Vec u)
1956d71ae5a4SJacob Faibussowitsch {
195765876a83SMatthew G. Knepley   DM        dm;
195865876a83SMatthew G. Knepley   PetscReal t;
195965876a83SMatthew G. Knepley 
19607510d9b0SBarry Smith   PetscFunctionBeginUser;
19619566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
19629566063dSJacob Faibussowitsch   PetscCall(TSGetTime(ts, &t));
196365876a83SMatthew G. Knepley   if (t <= 0.0) {
196465876a83SMatthew G. Knepley     PetscErrorCode (*funcs[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
196565876a83SMatthew G. Knepley     void   *ctxs[3];
196665876a83SMatthew G. Knepley     AppCtx *ctx;
196765876a83SMatthew G. Knepley 
19689566063dSJacob Faibussowitsch     PetscCall(DMGetApplicationContext(dm, &ctx));
196965876a83SMatthew G. Knepley     switch (ctx->solType) {
197065876a83SMatthew G. Knepley     case SOL_TERZAGHI:
19719371c9d4SSatish Balay       funcs[0] = terzaghi_initial_u;
19729371c9d4SSatish Balay       ctxs[0]  = ctx;
19739371c9d4SSatish Balay       funcs[1] = terzaghi_initial_eps;
19749371c9d4SSatish Balay       ctxs[1]  = ctx;
19759371c9d4SSatish Balay       funcs[2] = terzaghi_drainage_pressure;
19769371c9d4SSatish Balay       ctxs[2]  = ctx;
19779566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
197865876a83SMatthew G. Knepley       break;
197965876a83SMatthew G. Knepley     case SOL_MANDEL:
19809371c9d4SSatish Balay       funcs[0] = mandel_initial_u;
19819371c9d4SSatish Balay       ctxs[0]  = ctx;
19829371c9d4SSatish Balay       funcs[1] = mandel_initial_eps;
19839371c9d4SSatish Balay       ctxs[1]  = ctx;
19849371c9d4SSatish Balay       funcs[2] = mandel_drainage_pressure;
19859371c9d4SSatish Balay       ctxs[2]  = ctx;
19869566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
198765876a83SMatthew G. Knepley       break;
198865876a83SMatthew G. Knepley     case SOL_CRYER:
19899371c9d4SSatish Balay       funcs[0] = cryer_initial_u;
19909371c9d4SSatish Balay       ctxs[0]  = ctx;
19919371c9d4SSatish Balay       funcs[1] = cryer_initial_eps;
19929371c9d4SSatish Balay       ctxs[1]  = ctx;
19939371c9d4SSatish Balay       funcs[2] = cryer_drainage_pressure;
19949371c9d4SSatish Balay       ctxs[2]  = ctx;
19959566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
199665876a83SMatthew G. Knepley       break;
1997d71ae5a4SJacob Faibussowitsch     default:
1998d71ae5a4SJacob Faibussowitsch       PetscCall(DMComputeExactSolution(dm, t, u, NULL));
199965876a83SMatthew G. Knepley     }
200065876a83SMatthew G. Knepley   } else {
20019566063dSJacob Faibussowitsch     PetscCall(DMComputeExactSolution(dm, t, u, NULL));
200265876a83SMatthew G. Knepley   }
20033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
200465876a83SMatthew G. Knepley }
200565876a83SMatthew G. Knepley 
200665876a83SMatthew G. Knepley /* Need to create Viewer each time because HDF5 can get corrupted */
2007d71ae5a4SJacob Faibussowitsch static PetscErrorCode SolutionMonitor(TS ts, PetscInt steps, PetscReal time, Vec u, void *mctx)
2008d71ae5a4SJacob Faibussowitsch {
200965876a83SMatthew G. Knepley   DM                dm;
201065876a83SMatthew G. Knepley   Vec               exact;
201165876a83SMatthew G. Knepley   PetscViewer       viewer;
201265876a83SMatthew G. Knepley   PetscViewerFormat format;
201365876a83SMatthew G. Knepley   PetscOptions      options;
201465876a83SMatthew G. Knepley   const char       *prefix;
201565876a83SMatthew G. Knepley 
20167510d9b0SBarry Smith   PetscFunctionBeginUser;
20179566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
20189566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptions((PetscObject)ts, &options));
20199566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, &prefix));
20209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), options, prefix, "-monitor_solution", &viewer, &format, NULL));
20219566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &exact));
20229566063dSJacob Faibussowitsch   PetscCall(DMComputeExactSolution(dm, time, exact, NULL));
20239566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, steps, time));
20249566063dSJacob Faibussowitsch   PetscCall(VecView(exact, viewer));
20259566063dSJacob Faibussowitsch   PetscCall(VecView(u, viewer));
20269566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &exact));
202765876a83SMatthew G. Knepley   {
202865876a83SMatthew G. Knepley     PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx);
202965876a83SMatthew G. Knepley     void     **ectxs;
203065876a83SMatthew G. Knepley     PetscReal *err;
203165876a83SMatthew G. Knepley     PetscInt   Nf, f;
203265876a83SMatthew G. Knepley 
20339566063dSJacob Faibussowitsch     PetscCall(DMGetNumFields(dm, &Nf));
20349566063dSJacob Faibussowitsch     PetscCall(PetscCalloc3(Nf, &exacts, Nf, &ectxs, PetscMax(1, Nf), &err));
203565876a83SMatthew G. Knepley     {
203665876a83SMatthew G. Knepley       PetscInt Nds, s;
203765876a83SMatthew G. Knepley 
20389566063dSJacob Faibussowitsch       PetscCall(DMGetNumDS(dm, &Nds));
203965876a83SMatthew G. Knepley       for (s = 0; s < Nds; ++s) {
204065876a83SMatthew G. Knepley         PetscDS         ds;
204165876a83SMatthew G. Knepley         DMLabel         label;
204265876a83SMatthew G. Knepley         IS              fieldIS;
204365876a83SMatthew G. Knepley         const PetscInt *fields;
204465876a83SMatthew G. Knepley         PetscInt        dsNf, f;
204565876a83SMatthew G. Knepley 
20469566063dSJacob Faibussowitsch         PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds));
20479566063dSJacob Faibussowitsch         PetscCall(PetscDSGetNumFields(ds, &dsNf));
20489566063dSJacob Faibussowitsch         PetscCall(ISGetIndices(fieldIS, &fields));
204965876a83SMatthew G. Knepley         for (f = 0; f < dsNf; ++f) {
205065876a83SMatthew G. Knepley           const PetscInt field = fields[f];
20519566063dSJacob Faibussowitsch           PetscCall(PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]));
205265876a83SMatthew G. Knepley         }
20539566063dSJacob Faibussowitsch         PetscCall(ISRestoreIndices(fieldIS, &fields));
205465876a83SMatthew G. Knepley       }
205565876a83SMatthew G. Knepley     }
20569566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, time, exacts, ectxs, u, err));
205763a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "Time: %g L_2 Error: [", (double)time));
205865876a83SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
20599566063dSJacob Faibussowitsch       if (f) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), ", "));
20609566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%g", (double)err[f]));
206165876a83SMatthew G. Knepley     }
20629566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "]\n"));
20639566063dSJacob Faibussowitsch     PetscCall(PetscFree3(exacts, ectxs, err));
206465876a83SMatthew G. Knepley   }
20659566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
20663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
206765876a83SMatthew G. Knepley }
206865876a83SMatthew G. Knepley 
2069d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupMonitor(TS ts, AppCtx *ctx)
2070d71ae5a4SJacob Faibussowitsch {
207165876a83SMatthew G. Knepley   PetscViewer       viewer;
207265876a83SMatthew G. Knepley   PetscViewerFormat format;
207365876a83SMatthew G. Knepley   PetscOptions      options;
207465876a83SMatthew G. Knepley   const char       *prefix;
207565876a83SMatthew G. Knepley   PetscBool         flg;
207665876a83SMatthew G. Knepley 
20777510d9b0SBarry Smith   PetscFunctionBeginUser;
20789566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptions((PetscObject)ts, &options));
20799566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, &prefix));
20809566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), options, prefix, "-monitor_solution", &viewer, &format, &flg));
20819566063dSJacob Faibussowitsch   if (flg) PetscCall(TSMonitorSet(ts, SolutionMonitor, ctx, NULL));
20829566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
20833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
208465876a83SMatthew G. Knepley }
208565876a83SMatthew G. Knepley 
2086d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdaptChoose_Terzaghi(TSAdapt adapt, TS ts, PetscReal h, PetscInt *next_sc, PetscReal *next_h, PetscBool *accept, PetscReal *wlte, PetscReal *wltea, PetscReal *wlter)
2087d71ae5a4SJacob Faibussowitsch {
208865876a83SMatthew G. Knepley   static PetscReal dtTarget = -1.0;
208965876a83SMatthew G. Knepley   PetscReal        dtInitial;
209065876a83SMatthew G. Knepley   DM               dm;
209165876a83SMatthew G. Knepley   AppCtx          *ctx;
209265876a83SMatthew G. Knepley   PetscInt         step;
209365876a83SMatthew G. Knepley 
20947510d9b0SBarry Smith   PetscFunctionBeginUser;
20959566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
20969566063dSJacob Faibussowitsch   PetscCall(DMGetApplicationContext(dm, &ctx));
20979566063dSJacob Faibussowitsch   PetscCall(TSGetStepNumber(ts, &step));
209824b15d09SMatthew G. Knepley   dtInitial = ctx->dtInitial < 0.0 ? 1.0e-4 * ctx->t_r : ctx->dtInitial;
209965876a83SMatthew G. Knepley   if (!step) {
210065876a83SMatthew G. Knepley     if (PetscAbsReal(dtInitial - h) > PETSC_SMALL) {
210165876a83SMatthew G. Knepley       *accept  = PETSC_FALSE;
210265876a83SMatthew G. Knepley       *next_h  = dtInitial;
210365876a83SMatthew G. Knepley       dtTarget = h;
210465876a83SMatthew G. Knepley     } else {
210565876a83SMatthew G. Knepley       *accept  = PETSC_TRUE;
210665876a83SMatthew G. Knepley       *next_h  = dtTarget < 0.0 ? dtInitial : dtTarget;
210765876a83SMatthew G. Knepley       dtTarget = -1.0;
210865876a83SMatthew G. Knepley     }
210965876a83SMatthew G. Knepley   } else {
211065876a83SMatthew G. Knepley     *accept = PETSC_TRUE;
211165876a83SMatthew G. Knepley     *next_h = h;
211265876a83SMatthew G. Knepley   }
211365876a83SMatthew G. Knepley   *next_sc = 0;  /* Reuse the same order scheme */
211465876a83SMatthew G. Knepley   *wlte    = -1; /* Weighted local truncation error was not evaluated */
211565876a83SMatthew G. Knepley   *wltea   = -1; /* Weighted absolute local truncation error was not evaluated */
211665876a83SMatthew G. Knepley   *wlter   = -1; /* Weighted relative local truncation error was not evaluated */
21173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
211865876a83SMatthew G. Knepley }
211965876a83SMatthew G. Knepley 
2120d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv)
2121d71ae5a4SJacob Faibussowitsch {
212265876a83SMatthew G. Knepley   AppCtx      ctx; /* User-defined work context */
212365876a83SMatthew G. Knepley   DM          dm;  /* Problem specification */
212465876a83SMatthew G. Knepley   TS          ts;  /* Time Series / Nonlinear solver */
212565876a83SMatthew G. Knepley   Vec         u;   /* Solutions */
212665876a83SMatthew G. Knepley   const char *name[3] = {"displacement", "tracestrain", "pressure"};
212765876a83SMatthew G. Knepley   PetscReal   t;
212830602db0SMatthew G. Knepley   PetscInt    dim, Nc[3];
212965876a83SMatthew G. Knepley 
2130327415f7SBarry Smith   PetscFunctionBeginUser;
21319566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
21329566063dSJacob Faibussowitsch   PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx));
21339566063dSJacob Faibussowitsch   PetscCall(PetscBagCreate(PETSC_COMM_SELF, sizeof(Parameter), &ctx.bag));
21349566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx.niter, &ctx.zeroArray));
21359566063dSJacob Faibussowitsch   PetscCall(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm));
21369566063dSJacob Faibussowitsch   PetscCall(SetupParameters(PETSC_COMM_WORLD, &ctx));
213765876a83SMatthew G. Knepley   /* Primal System */
21389566063dSJacob Faibussowitsch   PetscCall(TSCreate(PETSC_COMM_WORLD, &ts));
21399566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(dm, &ctx));
21409566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts, dm));
214165876a83SMatthew G. Knepley 
21429566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
214330602db0SMatthew G. Knepley   Nc[0] = dim;
214465876a83SMatthew G. Knepley   Nc[1] = 1;
214565876a83SMatthew G. Knepley   Nc[2] = 1;
214665876a83SMatthew G. Knepley 
21479566063dSJacob Faibussowitsch   PetscCall(SetupFE(dm, 3, Nc, name, SetupPrimalProblem, &ctx));
21489566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(dm, &u));
21499566063dSJacob Faibussowitsch   PetscCall(DMTSSetBoundaryLocal(dm, DMPlexTSComputeBoundary, &ctx));
21509566063dSJacob Faibussowitsch   PetscCall(DMTSSetIFunctionLocal(dm, DMPlexTSComputeIFunctionFEM, &ctx));
21519566063dSJacob Faibussowitsch   PetscCall(DMTSSetIJacobianLocal(dm, DMPlexTSComputeIJacobianFEM, &ctx));
21529566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP));
21539566063dSJacob Faibussowitsch   PetscCall(TSSetFromOptions(ts));
21549566063dSJacob Faibussowitsch   PetscCall(TSSetComputeInitialCondition(ts, SetInitialConditions));
21559566063dSJacob Faibussowitsch   PetscCall(SetupMonitor(ts, &ctx));
215665876a83SMatthew G. Knepley 
215765876a83SMatthew G. Knepley   if (ctx.solType != SOL_QUADRATIC_TRIG) {
215865876a83SMatthew G. Knepley     TSAdapt adapt;
215965876a83SMatthew G. Knepley 
21609566063dSJacob Faibussowitsch     PetscCall(TSGetAdapt(ts, &adapt));
216165876a83SMatthew G. Knepley     adapt->ops->choose = TSAdaptChoose_Terzaghi;
216265876a83SMatthew G. Knepley   }
216365876a83SMatthew G. Knepley   if (ctx.solType == SOL_CRYER) {
216465876a83SMatthew G. Knepley     Mat          J;
216565876a83SMatthew G. Knepley     MatNullSpace sp;
216665876a83SMatthew G. Knepley 
21679566063dSJacob Faibussowitsch     PetscCall(TSSetUp(ts));
21689566063dSJacob Faibussowitsch     PetscCall(TSGetIJacobian(ts, &J, NULL, NULL, NULL));
21699566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateRigidBody(dm, 0, &sp));
21709566063dSJacob Faibussowitsch     PetscCall(MatSetNullSpace(J, sp));
21719566063dSJacob Faibussowitsch     PetscCall(MatNullSpaceDestroy(&sp));
217265876a83SMatthew G. Knepley   }
21739566063dSJacob Faibussowitsch   PetscCall(TSGetTime(ts, &t));
21749566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, 0, t));
21759566063dSJacob Faibussowitsch   PetscCall(DMTSCheckFromOptions(ts, u));
21769566063dSJacob Faibussowitsch   PetscCall(SetInitialConditions(ts, u));
21779566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)u, "solution"));
21789566063dSJacob Faibussowitsch   PetscCall(TSSolve(ts, u));
21799566063dSJacob Faibussowitsch   PetscCall(DMTSCheckFromOptions(ts, u));
21809566063dSJacob Faibussowitsch   PetscCall(TSGetSolution(ts, &u));
21819566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
218265876a83SMatthew G. Knepley 
218365876a83SMatthew G. Knepley   /* Cleanup */
21849566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&u));
21859566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&ts));
21869566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm));
21879566063dSJacob Faibussowitsch   PetscCall(PetscBagDestroy(&ctx.bag));
21889566063dSJacob Faibussowitsch   PetscCall(PetscFree(ctx.zeroArray));
21899566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
2190b122ec5aSJacob Faibussowitsch   return 0;
219165876a83SMatthew G. Knepley }
219265876a83SMatthew G. Knepley 
219365876a83SMatthew G. Knepley /*TEST
219465876a83SMatthew G. Knepley 
219565876a83SMatthew G. Knepley   test:
219665876a83SMatthew G. Knepley     suffix: 2d_quad_linear
219765876a83SMatthew G. Knepley     requires: triangle
219865876a83SMatthew G. Knepley     args: -sol_type quadratic_linear -dm_refine 2 \
219965876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
220065876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
220165876a83SMatthew G. Knepley 
220265876a83SMatthew G. Knepley   test:
220365876a83SMatthew G. Knepley     suffix: 3d_quad_linear
220465876a83SMatthew G. Knepley     requires: ctetgen
220530602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_linear -dm_refine 1 \
220665876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
220765876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
220865876a83SMatthew G. Knepley 
220965876a83SMatthew G. Knepley   test:
221065876a83SMatthew G. Knepley     suffix: 2d_trig_linear
221165876a83SMatthew G. Knepley     requires: triangle
221265876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
221365876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
221465876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_dt 0.00001 -ts_monitor_extreme
221565876a83SMatthew G. Knepley 
221665876a83SMatthew G. Knepley   test:
221765876a83SMatthew G. Knepley     # -dm_refine 2 -convest_num_refine 3 get L_2 convergence rate: [1.9, 2.1, 1.8]
221865876a83SMatthew G. Knepley     suffix: 2d_trig_linear_sconv
221965876a83SMatthew G. Knepley     requires: triangle
222065876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
222165876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
222265876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -ts_dt 0.00001 -pc_type lu
222365876a83SMatthew G. Knepley 
222465876a83SMatthew G. Knepley   test:
222565876a83SMatthew G. Knepley     suffix: 3d_trig_linear
222665876a83SMatthew G. Knepley     requires: ctetgen
222730602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type trig_linear -dm_refine 1 \
222865876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
222965876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 2 -ts_monitor_extreme
223065876a83SMatthew G. Knepley 
223165876a83SMatthew G. Knepley   test:
223265876a83SMatthew G. Knepley     # -dm_refine 1 -convest_num_refine 2 gets L_2 convergence rate: [2.0, 2.1, 1.9]
223365876a83SMatthew G. Knepley     suffix: 3d_trig_linear_sconv
223465876a83SMatthew G. Knepley     requires: ctetgen
223530602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type trig_linear -dm_refine 1 \
223665876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
223765876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -pc_type lu
223865876a83SMatthew G. Knepley 
223965876a83SMatthew G. Knepley   test:
224065876a83SMatthew G. Knepley     suffix: 2d_quad_trig
224165876a83SMatthew G. Knepley     requires: triangle
224265876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 2 \
224365876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
224465876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
224565876a83SMatthew G. Knepley 
224665876a83SMatthew G. Knepley   test:
224765876a83SMatthew G. Knepley     # Using -dm_refine 4 gets the convergence rates to [0.95, 0.97, 0.90]
224865876a83SMatthew G. Knepley     suffix: 2d_quad_trig_tconv
224965876a83SMatthew G. Knepley     requires: triangle
225065876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 1 \
225165876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
225265876a83SMatthew G. Knepley       -convest_num_refine 3 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
225365876a83SMatthew G. Knepley 
225465876a83SMatthew G. Knepley   test:
225565876a83SMatthew G. Knepley     suffix: 3d_quad_trig
225665876a83SMatthew G. Knepley     requires: ctetgen
225730602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_trig -dm_refine 1 \
225865876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
225965876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
226065876a83SMatthew G. Knepley 
226165876a83SMatthew G. Knepley   test:
226265876a83SMatthew G. Knepley     # Using -dm_refine 2 -convest_num_refine 3 gets the convergence rates to [1.0, 1.0, 1.0]
226365876a83SMatthew G. Knepley     suffix: 3d_quad_trig_tconv
226465876a83SMatthew G. Knepley     requires: ctetgen
226530602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_trig -dm_refine 1 \
226665876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
226765876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
226865876a83SMatthew G. Knepley 
226930602db0SMatthew G. Knepley   testset:
227030602db0SMatthew 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 \
227130602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 -niter 16000 \
227230602db0SMatthew G. Knepley           -pc_type lu
227330602db0SMatthew G. Knepley 
227465876a83SMatthew G. Knepley     test:
227565876a83SMatthew G. Knepley       suffix: 2d_terzaghi
227630602db0SMatthew G. Knepley       requires: double
227730602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001
227865876a83SMatthew G. Knepley 
227965876a83SMatthew G. Knepley     test:
228065876a83SMatthew 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]
228165876a83SMatthew G. Knepley       suffix: 2d_terzaghi_tconv
228230602db0SMatthew G. Knepley       args: -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1
228365876a83SMatthew G. Knepley 
228465876a83SMatthew G. Knepley     test:
228524b15d09SMatthew G. Knepley       # -dm_plex_box_faces 1,16 -convest_num_refine 4 gives L_2 convergence rate: [1.7, 1.2, 1.1]
228630602db0SMatthew 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]
228724b15d09SMatthew G. Knepley       suffix: 2d_terzaghi_sconv
228830602db0SMatthew 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
228930602db0SMatthew G. Knepley 
229030602db0SMatthew G. Knepley   testset:
229130602db0SMatthew 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 \
229230602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
229330602db0SMatthew G. Knepley           -pc_type lu
229424b15d09SMatthew G. Knepley 
229524b15d09SMatthew G. Knepley     test:
229665876a83SMatthew G. Knepley       suffix: 2d_mandel
229730602db0SMatthew G. Knepley       requires: double
229830602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001
229965876a83SMatthew G. Knepley 
230065876a83SMatthew G. Knepley     test:
2301f30e7d8cSMatthew G. Knepley       # -dm_refine 3 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [1.6, 0.93, 1.2]
2302f30e7d8cSMatthew G. Knepley       suffix: 2d_mandel_sconv
2303f30e7d8cSMatthew 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
2304f30e7d8cSMatthew G. Knepley 
2305f30e7d8cSMatthew G. Knepley     test:
230665876a83SMatthew G. Knepley       # -dm_refine 5 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [0.26, -0.0058, 0.26]
230765876a83SMatthew G. Knepley       suffix: 2d_mandel_tconv
230830602db0SMatthew G. Knepley       args: -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1
230930602db0SMatthew G. Knepley 
231030602db0SMatthew G. Knepley   testset:
231130602db0SMatthew G. Knepley     requires: ctetgen !complex
231230602db0SMatthew G. Knepley     args: -sol_type cryer -dm_plex_dim 3 -dm_plex_shape ball \
231330602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1
231465876a83SMatthew G. Knepley 
231565876a83SMatthew G. Knepley     test:
231665876a83SMatthew G. Knepley       suffix: 3d_cryer
231730602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_time 0.014333 -ts_max_steps 2 -dmts_check .0001 \
231830602db0SMatthew G. Knepley             -pc_type svd
231965876a83SMatthew G. Knepley 
232065876a83SMatthew G. Knepley     test:
232114bf6794SMatthew G. Knepley       # -bd_dm_refine 3 -dm_refine_volume_limit_pre 0.004 -convest_num_refine 2 gives L_2 convergence rate: []
232214bf6794SMatthew G. Knepley       suffix: 3d_cryer_sconv
232314bf6794SMatthew G. Knepley       args: -bd_dm_refine 1 -dm_refine_volume_limit_pre 0.00666667 \
232414bf6794SMatthew G. Knepley             -ts_dt 1e-5 -dt_initial 1e-5 -ts_max_steps 2 \
232514bf6794SMatthew G. Knepley             -ts_convergence_estimate -ts_convergence_temporal 0 -convest_num_refine 1 \
232614bf6794SMatthew G. Knepley             -pc_type lu -pc_factor_shift_type nonzero
232714bf6794SMatthew G. Knepley 
232814bf6794SMatthew G. Knepley     test:
232965876a83SMatthew G. Knepley       # Displacement and Pressure converge. The analytic expression for trace strain is inaccurate at the origin
233065876a83SMatthew 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]
233165876a83SMatthew G. Knepley       suffix: 3d_cryer_tconv
233230602db0SMatthew G. Knepley       args: -bd_dm_refine 1 -dm_refine_volume_limit_pre 0.00666667 \
233330602db0SMatthew G. Knepley             -ts_dt 0.023 -ts_max_time 0.092 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1 \
233430602db0SMatthew G. Knepley             -pc_type lu -pc_factor_shift_type nonzero
233565876a83SMatthew G. Knepley 
233665876a83SMatthew G. Knepley TEST*/
2337