xref: /petsc/src/ts/tutorials/ex53.c (revision 9fa27a79b1a8b7db2a564b40106acf3ce64dc8fa)
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) */
720*9fa27a79SStefano Zampini     PetscReal   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) */
727*9fa27a79SStefano Zampini     PetscReal   c    = PetscRealPart(kappa / S);                            /* m^2 / s, Cheng (B.16) */
72865876a83SMatthew G. Knepley 
729*9fa27a79SStefano Zampini     PetscReal A_s = 0.0;
730*9fa27a79SStefano Zampini     PetscReal B_s = 0.0;
73165876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
732*9fa27a79SStefano Zampini       PetscReal alpha_n = user->zeroArray[n - 1];
73365876a83SMatthew 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));
73465876a83SMatthew 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));
73565876a83SMatthew G. Knepley     }
73665876a83SMatthew 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;
73765876a83SMatthew G. Knepley     u[1] = (-1 * (P_0 * (1.0 - nu)) / (2 * G * a) + (P_0 * (1 - nu_u)) / (G * a) * A_s) * x[1];
73865876a83SMatthew G. Knepley   }
7393ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
74065876a83SMatthew G. Knepley }
74165876a83SMatthew G. Knepley 
742d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
743d71ae5a4SJacob Faibussowitsch {
74465876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
74565876a83SMatthew G. Knepley   Parameter *param;
74665876a83SMatthew G. Knepley 
7479566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
74865876a83SMatthew G. Knepley   {
74965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;                          /* -  */
75065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;                            /* Pa */
75165876a83SMatthew G. Knepley     PetscScalar M     = param->M;                              /* Pa */
75265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;                             /* Pa */
75365876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;                            /* Pa */
75465876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;                /* m^2 / (Pa s) */
75530602db0SMatthew G. Knepley     PetscReal   a     = 0.5 * (user->xmax[0] - user->xmin[0]); /* m */
75665876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
75765876a83SMatthew G. Knepley 
75865876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
75965876a83SMatthew G. Knepley     PetscScalar nu  = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
76065876a83SMatthew G. Knepley     PetscScalar S   = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
76165876a83SMatthew G. Knepley     PetscReal   c   = PetscRealPart(kappa / S);                            /* m^2 / s, Cheng (B.16) */
76265876a83SMatthew G. Knepley 
76365876a83SMatthew G. Knepley     PetscReal aa    = 0.0;
76465876a83SMatthew G. Knepley     PetscReal eps_A = 0.0;
76565876a83SMatthew G. Knepley     PetscReal eps_B = 0.0;
76665876a83SMatthew G. Knepley     PetscReal eps_C = 0.0;
76765876a83SMatthew G. Knepley     PetscReal time  = 0.0;
76865876a83SMatthew G. Knepley 
76965876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
77065876a83SMatthew G. Knepley       aa = user->zeroArray[n - 1];
77165876a83SMatthew 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)));
77265876a83SMatthew G. Knepley       eps_B += (PetscExpReal((-1.0 * aa * aa * c * time) / (a * a)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
77365876a83SMatthew G. Knepley       eps_C += (PetscExpReal((-1.0 * aa * aa * c * time) / (aa * aa)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
77465876a83SMatthew G. Knepley     }
77565876a83SMatthew 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);
77665876a83SMatthew G. Knepley   }
7773ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
77865876a83SMatthew G. Knepley }
77965876a83SMatthew G. Knepley 
78065876a83SMatthew G. Knepley // Displacement
781d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
782d71ae5a4SJacob Faibussowitsch {
78365876a83SMatthew G. Knepley   Parameter *param;
78465876a83SMatthew G. Knepley 
78565876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
78665876a83SMatthew G. Knepley 
7879566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
78865876a83SMatthew G. Knepley   if (time <= 0.0) {
7899566063dSJacob Faibussowitsch     PetscCall(mandel_initial_u(dim, time, x, Nc, u, ctx));
79065876a83SMatthew G. Knepley   } else {
79165876a83SMatthew G. Knepley     PetscInt    NITER = user->niter;
79265876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
79365876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
79465876a83SMatthew G. Knepley     PetscScalar M     = param->M;
79565876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
79665876a83SMatthew G. Knepley     PetscScalar k     = param->k;
79765876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
79865876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
79965876a83SMatthew G. Knepley 
80065876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
80165876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
80265876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
80365876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
80430602db0SMatthew G. Knepley     PetscReal   a     = (user->xmax[0] - user->xmin[0]) / 2.0;
80565876a83SMatthew 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)));
80665876a83SMatthew G. Knepley 
80765876a83SMatthew G. Knepley     // Series term
80865876a83SMatthew G. Knepley     PetscScalar A_x = 0.0;
80965876a83SMatthew G. Knepley     PetscScalar B_x = 0.0;
81065876a83SMatthew G. Knepley 
81165876a83SMatthew G. Knepley     for (PetscInt n = 1; n < NITER + 1; n++) {
81265876a83SMatthew G. Knepley       PetscReal alpha_n = user->zeroArray[n - 1];
81365876a83SMatthew G. Knepley 
81465876a83SMatthew 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));
81565876a83SMatthew 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));
81665876a83SMatthew G. Knepley     }
81765876a83SMatthew G. Knepley     u[0] = ((F * nu) / (2.0 * G * a) - (F * nu_u) / (G * a) * A_x) * x[0] + F / G * B_x;
81865876a83SMatthew G. Knepley     u[1] = (-1 * (F * (1.0 - nu)) / (2 * G * a) + (F * (1 - nu_u)) / (G * a) * A_x) * x[1];
81965876a83SMatthew G. Knepley   }
8203ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
82165876a83SMatthew G. Knepley }
82265876a83SMatthew G. Knepley 
82365876a83SMatthew G. Knepley // Trace strain
824d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
825d71ae5a4SJacob Faibussowitsch {
82665876a83SMatthew G. Knepley   Parameter *param;
82765876a83SMatthew G. Knepley 
82865876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
82965876a83SMatthew G. Knepley 
8309566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
83165876a83SMatthew G. Knepley   if (time <= 0.0) {
8329566063dSJacob Faibussowitsch     PetscCall(mandel_initial_eps(dim, time, x, Nc, u, ctx));
83365876a83SMatthew G. Knepley   } else {
83465876a83SMatthew G. Knepley     PetscInt    NITER = user->niter;
83565876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
83665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
83765876a83SMatthew G. Knepley     PetscScalar M     = param->M;
83865876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
83965876a83SMatthew G. Knepley     PetscScalar k     = param->k;
84065876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
84165876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
84265876a83SMatthew G. Knepley 
84365876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
84465876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
84565876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
84665876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
84765876a83SMatthew G. Knepley     //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
84865876a83SMatthew G. Knepley 
84965876a83SMatthew G. Knepley     //const PetscScalar b = (YMAX - YMIN) / 2.0;
850*9fa27a79SStefano Zampini     PetscReal a = (user->xmax[0] - user->xmin[0]) / 2.0;
85165876a83SMatthew 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)));
85265876a83SMatthew G. Knepley 
85365876a83SMatthew G. Knepley     // Series term
854*9fa27a79SStefano Zampini     PetscReal eps_A = 0.0;
855*9fa27a79SStefano Zampini     PetscReal eps_B = 0.0;
856*9fa27a79SStefano Zampini     PetscReal eps_C = 0.0;
85765876a83SMatthew G. Knepley 
8589371c9d4SSatish Balay     for (PetscInt n = 1; n < NITER + 1; n++) {
85965876a83SMatthew G. Knepley       PetscReal aa = user->zeroArray[n - 1];
86065876a83SMatthew G. Knepley 
86165876a83SMatthew 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)));
86265876a83SMatthew G. Knepley 
86365876a83SMatthew G. Knepley       eps_B += (PetscExpReal((-1.0 * aa * aa * c * time) / (a * a)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
86465876a83SMatthew G. Knepley 
86565876a83SMatthew G. Knepley       eps_C += (PetscExpReal((-1.0 * aa * aa * c * time) / (aa * aa)) * PetscSinReal(aa) * PetscCosReal(aa)) / (aa - PetscSinReal(aa) * PetscCosReal(aa));
86665876a83SMatthew G. Knepley     }
86765876a83SMatthew G. Knepley 
86865876a83SMatthew 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);
86965876a83SMatthew G. Knepley   }
8703ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
87165876a83SMatthew G. Knepley }
87265876a83SMatthew G. Knepley 
87365876a83SMatthew G. Knepley // Pressure
874d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
875d71ae5a4SJacob Faibussowitsch {
87665876a83SMatthew G. Knepley   Parameter *param;
87765876a83SMatthew G. Knepley 
87865876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
87965876a83SMatthew G. Knepley 
8809566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
88165876a83SMatthew G. Knepley   if (time <= 0.0) {
8829566063dSJacob Faibussowitsch     PetscCall(mandel_drainage_pressure(dim, time, x, Nc, u, ctx));
88365876a83SMatthew G. Knepley   } else {
88465876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
88565876a83SMatthew G. Knepley 
88665876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
88765876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;
88865876a83SMatthew G. Knepley     PetscScalar M     = param->M;
88965876a83SMatthew G. Knepley     PetscScalar G     = param->mu;
89065876a83SMatthew G. Knepley     PetscScalar k     = param->k;
89165876a83SMatthew G. Knepley     PetscScalar mu_f  = param->mu_f;
89265876a83SMatthew G. Knepley     PetscScalar F     = param->P_0;
89365876a83SMatthew G. Knepley 
89465876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;
89565876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
89665876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
89765876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
89865876a83SMatthew G. Knepley     PetscScalar B     = (alpha * M) / (K_d + alpha * alpha * M);
89965876a83SMatthew G. Knepley 
90030602db0SMatthew G. Knepley     PetscReal   a  = (user->xmax[0] - user->xmin[0]) / 2.0;
90165876a83SMatthew 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)));
90265876a83SMatthew G. Knepley     PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
90365876a83SMatthew G. Knepley     //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
90465876a83SMatthew G. Knepley 
90565876a83SMatthew G. Knepley     // Series term
906*9fa27a79SStefano Zampini     PetscReal p = 0.0;
90765876a83SMatthew G. Knepley 
9089371c9d4SSatish Balay     for (PetscInt n = 1; n < NITER + 1; n++) {
909*9fa27a79SStefano Zampini       PetscReal aa = user->zeroArray[n - 1];
91065876a83SMatthew 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));
91165876a83SMatthew G. Knepley     }
91265876a83SMatthew G. Knepley     u[0] = ((2.0 * F) / (a * A1)) * p;
91365876a83SMatthew G. Knepley   }
9143ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
91565876a83SMatthew G. Knepley }
91665876a83SMatthew G. Knepley 
91765876a83SMatthew G. Knepley // Time derivative of displacement
918d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
919d71ae5a4SJacob Faibussowitsch {
92065876a83SMatthew G. Knepley   Parameter *param;
92165876a83SMatthew G. Knepley 
92265876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
92365876a83SMatthew G. Knepley 
9249566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
92565876a83SMatthew G. Knepley 
92665876a83SMatthew G. Knepley   PetscInt    NITER = user->niter;
92765876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
92865876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
92965876a83SMatthew G. Knepley   PetscScalar M     = param->M;
93065876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
93165876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
93265876a83SMatthew G. Knepley 
93365876a83SMatthew G. Knepley   PetscScalar K_d   = K_u - alpha * alpha * M;
93465876a83SMatthew G. Knepley   PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
93565876a83SMatthew G. Knepley   PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
93665876a83SMatthew G. Knepley   PetscScalar kappa = param->k / param->mu_f;
93730602db0SMatthew G. Knepley   PetscReal   a     = (user->xmax[0] - user->xmin[0]) / 2.0;
93865876a83SMatthew 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)));
93965876a83SMatthew G. Knepley 
94065876a83SMatthew G. Knepley   // Series term
94165876a83SMatthew G. Knepley   PetscScalar A_s_t = 0.0;
94265876a83SMatthew G. Knepley   PetscScalar B_s_t = 0.0;
94365876a83SMatthew G. Knepley 
9449371c9d4SSatish Balay   for (PetscInt n = 1; n < NITER + 1; n++) {
94565876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n - 1];
94665876a83SMatthew G. Knepley 
94765876a83SMatthew 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)));
94865876a83SMatthew 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)));
94965876a83SMatthew G. Knepley   }
95065876a83SMatthew G. Knepley 
95165876a83SMatthew G. Knepley   u[0] = (F / G) * A_s_t - ((F * nu_u * x[0]) / (G * a)) * B_s_t;
95265876a83SMatthew G. Knepley   u[1] = ((F * x[1] * (1 - nu_u)) / (G * a)) * B_s_t;
95365876a83SMatthew G. Knepley 
9543ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
95565876a83SMatthew G. Knepley }
95665876a83SMatthew G. Knepley 
95765876a83SMatthew G. Knepley // Time derivative of trace strain
958d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
959d71ae5a4SJacob Faibussowitsch {
96065876a83SMatthew G. Knepley   Parameter *param;
96165876a83SMatthew G. Knepley 
96265876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
96365876a83SMatthew G. Knepley 
9649566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
96565876a83SMatthew G. Knepley 
96665876a83SMatthew G. Knepley   PetscInt    NITER = user->niter;
96765876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
96865876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
96965876a83SMatthew G. Knepley   PetscScalar M     = param->M;
97065876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
97165876a83SMatthew G. Knepley   PetscScalar k     = param->k;
97265876a83SMatthew G. Knepley   PetscScalar mu_f  = param->mu_f;
97365876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
97465876a83SMatthew G. Knepley 
97565876a83SMatthew G. Knepley   PetscScalar K_d   = K_u - alpha * alpha * M;
97665876a83SMatthew G. Knepley   PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
97765876a83SMatthew G. Knepley   PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
97865876a83SMatthew G. Knepley   PetscScalar kappa = k / mu_f;
97965876a83SMatthew G. Knepley   //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
98065876a83SMatthew G. Knepley 
98165876a83SMatthew G. Knepley   //const PetscScalar b = (YMAX - YMIN) / 2.0;
98230602db0SMatthew G. Knepley   PetscReal a = (user->xmax[0] - user->xmin[0]) / 2.0;
98365876a83SMatthew 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)));
98465876a83SMatthew G. Knepley 
98565876a83SMatthew G. Knepley   // Series term
98665876a83SMatthew G. Knepley   PetscScalar eps_As = 0.0;
98765876a83SMatthew G. Knepley   PetscScalar eps_Bs = 0.0;
98865876a83SMatthew G. Knepley   PetscScalar eps_Cs = 0.0;
98965876a83SMatthew G. Knepley 
9909371c9d4SSatish Balay   for (PetscInt n = 1; n < NITER + 1; n++) {
99165876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n - 1];
99265876a83SMatthew G. Knepley 
99365876a83SMatthew 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)));
99465876a83SMatthew 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)));
99565876a83SMatthew 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)));
99665876a83SMatthew G. Knepley   }
99765876a83SMatthew G. Knepley 
99865876a83SMatthew G. Knepley   u[0] = (F / G) * eps_As - ((F * nu_u) / (G * a)) * eps_Bs + ((F * (1 - nu_u)) / (G * a)) * eps_Cs;
9993ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
100065876a83SMatthew G. Knepley }
100165876a83SMatthew G. Knepley 
100265876a83SMatthew G. Knepley // Time derivative of pressure
1003d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandel_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1004d71ae5a4SJacob Faibussowitsch {
100565876a83SMatthew G. Knepley   Parameter *param;
100665876a83SMatthew G. Knepley 
100765876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *)ctx;
100865876a83SMatthew G. Knepley 
10099566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
101065876a83SMatthew G. Knepley 
101165876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
101265876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
101365876a83SMatthew G. Knepley   PetscScalar M     = param->M;
101465876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
101565876a83SMatthew G. Knepley   PetscScalar F     = param->P_0;
101665876a83SMatthew G. Knepley 
101765876a83SMatthew G. Knepley   PetscScalar K_d  = K_u - alpha * alpha * M;
101865876a83SMatthew G. Knepley   PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
101965876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
102065876a83SMatthew G. Knepley 
102130602db0SMatthew G. Knepley   PetscReal a = (user->xmax[0] - user->xmin[0]) / 2.0;
102265876a83SMatthew G. Knepley   //PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
102365876a83SMatthew G. Knepley   //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
102465876a83SMatthew G. Knepley 
102565876a83SMatthew G. Knepley   u[0] = ((2.0 * F * (-2.0 * nu + 3.0 * nu_u)) / (3.0 * a * alpha * (1.0 - 2.0 * nu)));
102665876a83SMatthew G. Knepley 
10273ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
102865876a83SMatthew G. Knepley }
102965876a83SMatthew G. Knepley 
103065876a83SMatthew G. Knepley /* Cryer Solutions */
1031d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1032d71ae5a4SJacob Faibussowitsch {
103365876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
103465876a83SMatthew G. Knepley   Parameter *param;
103565876a83SMatthew G. Knepley 
10369566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
103765876a83SMatthew G. Knepley   if (time <= 0.0) {
103865876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;    /* -  */
103965876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;      /* Pa */
104065876a83SMatthew G. Knepley     PetscScalar M     = param->M;        /* Pa */
104165876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;      /* Pa */
104265876a83SMatthew G. Knepley     PetscScalar B     = alpha * M / K_u; /* -, Cheng (B.12) */
104365876a83SMatthew G. Knepley 
104465876a83SMatthew G. Knepley     u[0] = P_0 * B;
104565876a83SMatthew G. Knepley   } else {
104665876a83SMatthew G. Knepley     u[0] = 0.0;
104765876a83SMatthew G. Knepley   }
10483ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
104965876a83SMatthew G. Knepley }
105065876a83SMatthew G. Knepley 
1051d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1052d71ae5a4SJacob Faibussowitsch {
105365876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
105465876a83SMatthew G. Knepley   Parameter *param;
105565876a83SMatthew G. Knepley 
10569566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
105765876a83SMatthew G. Knepley   {
105865876a83SMatthew G. Knepley     PetscScalar K_u  = param->K_u;                                      /* Pa */
105965876a83SMatthew G. Knepley     PetscScalar G    = param->mu;                                       /* Pa */
106065876a83SMatthew G. Knepley     PetscScalar P_0  = param->P_0;                                      /* Pa */
106130602db0SMatthew G. Knepley     PetscReal   R_0  = user->xmax[1];                                   /* m */
106265876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
106365876a83SMatthew G. Knepley 
106465876a83SMatthew G. Knepley     PetscScalar u_0  = -P_0 * R_0 * (1. - 2. * nu_u) / (2. * G * (1. + nu_u)); /* Cheng (7.407) */
106565876a83SMatthew G. Knepley     PetscReal   u_sc = PetscRealPart(u_0) / R_0;
106665876a83SMatthew G. Knepley 
106765876a83SMatthew G. Knepley     u[0] = u_sc * x[0];
106865876a83SMatthew G. Knepley     u[1] = u_sc * x[1];
106965876a83SMatthew G. Knepley     u[2] = u_sc * x[2];
107065876a83SMatthew G. Knepley   }
10713ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
107265876a83SMatthew G. Knepley }
107365876a83SMatthew G. Knepley 
1074d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1075d71ae5a4SJacob Faibussowitsch {
107665876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
107765876a83SMatthew G. Knepley   Parameter *param;
107865876a83SMatthew G. Knepley 
10799566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
108065876a83SMatthew G. Knepley   {
108165876a83SMatthew G. Knepley     PetscScalar K_u  = param->K_u;                                      /* Pa */
108265876a83SMatthew G. Knepley     PetscScalar G    = param->mu;                                       /* Pa */
108365876a83SMatthew G. Knepley     PetscScalar P_0  = param->P_0;                                      /* Pa */
108430602db0SMatthew G. Knepley     PetscReal   R_0  = user->xmax[1];                                   /* m */
108565876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
108665876a83SMatthew G. Knepley 
108765876a83SMatthew G. Knepley     PetscScalar u_0  = -P_0 * R_0 * (1. - 2. * nu_u) / (2. * G * (1. + nu_u)); /* Cheng (7.407) */
108865876a83SMatthew G. Knepley     PetscReal   u_sc = PetscRealPart(u_0) / R_0;
108965876a83SMatthew G. Knepley 
109065876a83SMatthew G. Knepley     /* div R = 1/R^2 d/dR R^2 R = 3 */
109165876a83SMatthew G. Knepley     u[0] = 3. * u_sc;
109265876a83SMatthew G. Knepley     u[1] = 3. * u_sc;
109365876a83SMatthew G. Knepley     u[2] = 3. * u_sc;
109465876a83SMatthew G. Knepley   }
10953ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
109665876a83SMatthew G. Knepley }
109765876a83SMatthew G. Knepley 
109865876a83SMatthew G. Knepley // Displacement
1099d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1100d71ae5a4SJacob Faibussowitsch {
110165876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
110265876a83SMatthew G. Knepley   Parameter *param;
110365876a83SMatthew G. Knepley 
11049566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
110565876a83SMatthew G. Knepley   if (time <= 0.0) {
11069566063dSJacob Faibussowitsch     PetscCall(cryer_initial_u(dim, time, x, Nc, u, ctx));
110765876a83SMatthew G. Knepley   } else {
110865876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
110965876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
111065876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
111165876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
111265876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
111365876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
111430602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
111565876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
111665876a83SMatthew G. Knepley 
111765876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
111865876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
111965876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
112065876a83SMatthew G. Knepley     PetscScalar S     = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
112165876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
112265876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0 * R_0 * (1. - 2. * nu) / (2. * G * (1. + nu));  /* m,       Cheng (7.388) */
112365876a83SMatthew G. Knepley 
112465876a83SMatthew G. Knepley     PetscReal   R      = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
112565876a83SMatthew G. Knepley     PetscReal   R_star = R / R_0;
112665876a83SMatthew G. Knepley     PetscReal   tstar  = PetscRealPart(c * time) / PetscSqr(R_0); /* - */
112765876a83SMatthew G. Knepley     PetscReal   A_n    = 0.0;
112865876a83SMatthew G. Knepley     PetscScalar u_sc;
112965876a83SMatthew G. Knepley 
113065876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
113165876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n - 1];
113265876a83SMatthew 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));
113365876a83SMatthew G. Knepley 
113465876a83SMatthew G. Knepley       /* m , Cheng (7.404) */
11359371c9d4SSatish 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));
113665876a83SMatthew G. Knepley     }
113765876a83SMatthew G. Knepley     u_sc = PetscRealPart(u_inf) * (R_star - A_n);
113865876a83SMatthew G. Knepley     u[0] = u_sc * x[0] / R;
113965876a83SMatthew G. Knepley     u[1] = u_sc * x[1] / R;
114065876a83SMatthew G. Knepley     u[2] = u_sc * x[2] / R;
114165876a83SMatthew G. Knepley   }
11423ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
114365876a83SMatthew G. Knepley }
114465876a83SMatthew G. Knepley 
114565876a83SMatthew G. Knepley // Volumetric Strain
1146d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_3d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1147d71ae5a4SJacob Faibussowitsch {
114865876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
114965876a83SMatthew G. Knepley   Parameter *param;
115065876a83SMatthew G. Knepley 
11519566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
115265876a83SMatthew G. Knepley   if (time <= 0.0) {
11539566063dSJacob Faibussowitsch     PetscCall(cryer_initial_eps(dim, time, x, Nc, u, ctx));
115465876a83SMatthew G. Knepley   } else {
115565876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
115665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
115765876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
115865876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
115965876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
116065876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
116130602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
116265876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
116365876a83SMatthew G. Knepley 
116465876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
116565876a83SMatthew G. Knepley     PetscScalar nu    = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
116665876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
116765876a83SMatthew G. Knepley     PetscScalar S     = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
116865876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
116965876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0 * R_0 * (1. - 2. * nu) / (2. * G * (1. + nu));  /* m,       Cheng (7.388) */
117065876a83SMatthew G. Knepley 
117165876a83SMatthew G. Knepley     PetscReal R      = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
117265876a83SMatthew G. Knepley     PetscReal R_star = R / R_0;
117365876a83SMatthew G. Knepley     PetscReal tstar  = PetscRealPart(c * time) / PetscSqr(R_0); /* - */
117465876a83SMatthew G. Knepley     PetscReal divA_n = 0.0;
117565876a83SMatthew G. Knepley 
117665876a83SMatthew G. Knepley     if (R_star < PETSC_SMALL) {
117765876a83SMatthew G. Knepley       for (n = 1; n < N + 1; ++n) {
117865876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n - 1];
117965876a83SMatthew 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));
118065876a83SMatthew G. Knepley 
11819371c9d4SSatish 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));
118265876a83SMatthew G. Knepley       }
118365876a83SMatthew G. Knepley     } else {
118465876a83SMatthew G. Knepley       for (n = 1; n < N + 1; ++n) {
118565876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n - 1];
118665876a83SMatthew 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));
118765876a83SMatthew G. Knepley 
11889371c9d4SSatish 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));
118965876a83SMatthew G. Knepley       }
119065876a83SMatthew G. Knepley     }
11913ba16761SJacob 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));
119265876a83SMatthew G. Knepley     u[0] = PetscRealPart(u_inf) / R_0 * (3.0 - divA_n);
119365876a83SMatthew G. Knepley   }
11943ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
119565876a83SMatthew G. Knepley }
119665876a83SMatthew G. Knepley 
119765876a83SMatthew G. Knepley // Pressure
1198d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryer_3d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1199d71ae5a4SJacob Faibussowitsch {
120065876a83SMatthew G. Knepley   AppCtx    *user = (AppCtx *)ctx;
120165876a83SMatthew G. Knepley   Parameter *param;
120265876a83SMatthew G. Knepley 
12039566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
120465876a83SMatthew G. Knepley   if (time <= 0.0) {
12059566063dSJacob Faibussowitsch     PetscCall(cryer_drainage_pressure(dim, time, x, Nc, u, ctx));
120665876a83SMatthew G. Knepley   } else {
120765876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;           /* -  */
120865876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;             /* Pa */
120965876a83SMatthew G. Knepley     PetscScalar M     = param->M;               /* Pa */
121065876a83SMatthew G. Knepley     PetscScalar G     = param->mu;              /* Pa */
121165876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;             /* Pa */
121230602db0SMatthew G. Knepley     PetscReal   R_0   = user->xmax[1];          /* m */
121365876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f; /* m^2 / (Pa s) */
121465876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
121565876a83SMatthew G. Knepley 
121665876a83SMatthew G. Knepley     PetscScalar K_d  = K_u - alpha * alpha * M;                             /* Pa,      Cheng (B.5)  */
121765876a83SMatthew G. Knepley     PetscScalar eta  = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G);           /* -,       Cheng (B.11) */
121865876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));     /* -,       Cheng (B.8)  */
121965876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));     /* -,       Cheng (B.9)  */
122065876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)); /* Pa^{-1}, Cheng (B.14) */
122165876a83SMatthew G. Knepley     PetscScalar c    = kappa / S;                                           /* m^2 / s, Cheng (B.16) */
1222*9fa27a79SStefano Zampini     PetscReal   R    = PetscSqrtReal(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
122365876a83SMatthew G. Knepley 
1224*9fa27a79SStefano Zampini     PetscReal R_star = R / R_0;
1225*9fa27a79SStefano Zampini     PetscReal t_star = PetscRealPart(c * time) / PetscSqr(R_0);
122665876a83SMatthew G. Knepley     PetscReal A_x    = 0.0;
122765876a83SMatthew G. Knepley 
122865876a83SMatthew G. Knepley     for (n = 1; n < N + 1; ++n) {
122965876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n - 1];
123065876a83SMatthew 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));
123165876a83SMatthew G. Knepley 
123265876a83SMatthew 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) */
123365876a83SMatthew G. Knepley     }
123465876a83SMatthew G. Knepley     u[0] = P_0 * A_x;
123565876a83SMatthew G. Knepley   }
12363ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
123765876a83SMatthew G. Knepley }
123865876a83SMatthew G. Knepley 
123965876a83SMatthew G. Knepley /* Boundary Kernels */
1240d71ae5a4SJacob 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[])
1241d71ae5a4SJacob Faibussowitsch {
124265876a83SMatthew G. Knepley   const PetscReal P = PetscRealPart(constants[5]);
124365876a83SMatthew G. Knepley 
124465876a83SMatthew G. Knepley   f0[0] = 0.0;
124565876a83SMatthew G. Knepley   f0[1] = P;
124665876a83SMatthew G. Knepley }
124765876a83SMatthew G. Knepley 
124845480ffeSMatthew G. Knepley #if 0
124965876a83SMatthew G. Knepley static void f0_mandel_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
125065876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
125165876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
125265876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
125365876a83SMatthew G. Knepley {
125465876a83SMatthew G. Knepley   // Uniform stress distribution
125565876a83SMatthew G. Knepley   /* PetscScalar xmax =  0.5;
125665876a83SMatthew G. Knepley   PetscScalar xmin = -0.5;
125765876a83SMatthew G. Knepley   PetscScalar ymax =  0.5;
125865876a83SMatthew G. Knepley   PetscScalar ymin = -0.5;
125965876a83SMatthew G. Knepley   PetscScalar P = constants[5];
126065876a83SMatthew G. Knepley   PetscScalar aL = (xmax - xmin) / 2.0;
126165876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*P / aL; */
126265876a83SMatthew G. Knepley 
126365876a83SMatthew G. Knepley   // Analytical (parabolic) stress distribution
126465876a83SMatthew G. Knepley   PetscReal a1, a2, am;
126565876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
126665876a83SMatthew G. Knepley 
126765876a83SMatthew G. Knepley   PetscInt NITER = 500;
126865876a83SMatthew G. Knepley   PetscReal EPS = 0.000001;
126965876a83SMatthew G. Knepley   PetscReal zeroArray[500]; /* NITER */
127065876a83SMatthew G. Knepley   PetscReal xmax =  1.0;
127165876a83SMatthew G. Knepley   PetscReal xmin =  0.0;
127265876a83SMatthew G. Knepley   PetscReal ymax =  0.1;
127365876a83SMatthew G. Knepley   PetscReal ymin =  0.0;
127465876a83SMatthew G. Knepley   PetscReal lower[2], upper[2];
127565876a83SMatthew G. Knepley 
127665876a83SMatthew G. Knepley   lower[0] = xmin - (xmax - xmin) / 2.0;
127765876a83SMatthew G. Knepley   lower[1] = ymin - (ymax - ymin) / 2.0;
127865876a83SMatthew G. Knepley   upper[0] = xmax - (xmax - xmin) / 2.0;
127965876a83SMatthew G. Knepley   upper[1] = ymax - (ymax - ymin) / 2.0;
128065876a83SMatthew G. Knepley 
128165876a83SMatthew G. Knepley   xmin = lower[0];
128265876a83SMatthew G. Knepley   ymin = lower[1];
128365876a83SMatthew G. Knepley   xmax = upper[0];
128465876a83SMatthew G. Knepley   ymax = upper[1];
128565876a83SMatthew G. Knepley 
128665876a83SMatthew G. Knepley   PetscScalar G     = constants[0];
128765876a83SMatthew G. Knepley   PetscScalar K_u   = constants[1];
128865876a83SMatthew G. Knepley   PetscScalar alpha = constants[2];
128965876a83SMatthew G. Knepley   PetscScalar M     = constants[3];
129065876a83SMatthew G. Knepley   PetscScalar kappa = constants[4];
129165876a83SMatthew G. Knepley   PetscScalar F     = constants[5];
129265876a83SMatthew G. Knepley 
129365876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
129465876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
129565876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
129665876a83SMatthew G. Knepley   PetscReal   aL = (xmax - xmin) / 2.0;
129765876a83SMatthew 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)));
129865876a83SMatthew G. Knepley   PetscScalar B = (3.0 * (nu_u - nu)) / ( alpha * (1.0 - 2.0*nu) * (1.0 + nu_u));
129965876a83SMatthew G. Knepley   PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
130065876a83SMatthew G. Knepley   PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
130165876a83SMatthew G. Knepley 
130265876a83SMatthew G. Knepley   // Generate zero values
130365876a83SMatthew G. Knepley   for (PetscInt i=1; i < NITER+1; i++)
130465876a83SMatthew G. Knepley   {
130565876a83SMatthew G. Knepley     a1 = ((PetscReal) i - 1.0) * PETSC_PI * PETSC_PI / 4.0 + EPS;
130665876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI/2;
130765876a83SMatthew G. Knepley     for (PetscInt j=0; j<NITER; j++)
130865876a83SMatthew G. Knepley     {
130965876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart(A1/A2)*a1;
131065876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart(A1/A2)*a2;
131165876a83SMatthew G. Knepley       am = (a1 + a2)/2.0;
131265876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart(A1/A2)*am;
131365876a83SMatthew G. Knepley       if ((ym*y1) > 0)
131465876a83SMatthew G. Knepley       {
131565876a83SMatthew G. Knepley         a1 = am;
131665876a83SMatthew G. Knepley       } else {
131765876a83SMatthew G. Knepley         a2 = am;
131865876a83SMatthew G. Knepley       }
131965876a83SMatthew G. Knepley       if (PetscAbsReal(y2) < EPS)
132065876a83SMatthew G. Knepley       {
132165876a83SMatthew G. Knepley         am = a2;
132265876a83SMatthew G. Knepley       }
132365876a83SMatthew G. Knepley     }
132465876a83SMatthew G. Knepley     zeroArray[i-1] = am;
132565876a83SMatthew G. Knepley   }
132665876a83SMatthew G. Knepley 
132765876a83SMatthew G. Knepley   // Solution for sigma_zz
132865876a83SMatthew G. Knepley   PetscScalar A_x = 0.0;
132965876a83SMatthew G. Knepley   PetscScalar B_x = 0.0;
133065876a83SMatthew G. Knepley 
133165876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
133265876a83SMatthew G. Knepley   {
133365876a83SMatthew G. Knepley     PetscReal alpha_n = zeroArray[n-1];
133465876a83SMatthew G. Knepley 
133565876a83SMatthew 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)));
133665876a83SMatthew 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)));
133765876a83SMatthew G. Knepley   }
133865876a83SMatthew G. Knepley 
133965876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*(F/aL) - ((2.0*F)/aL) * (A2/A1) * A_x + ((2.0*F)/aL) * B_x;
134065876a83SMatthew G. Knepley 
134165876a83SMatthew G. Knepley   if (x[1] == ymax) {
134265876a83SMatthew G. Knepley     f0[1] += sigma_zz;
134365876a83SMatthew G. Knepley   } else if (x[1] == ymin) {
134465876a83SMatthew G. Knepley     f0[1] -= sigma_zz;
134565876a83SMatthew G. Knepley   }
134665876a83SMatthew G. Knepley }
134745480ffeSMatthew G. Knepley #endif
134865876a83SMatthew G. Knepley 
1349d71ae5a4SJacob 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[])
1350d71ae5a4SJacob Faibussowitsch {
135165876a83SMatthew G. Knepley   const PetscReal P_0 = PetscRealPart(constants[5]);
135265876a83SMatthew G. Knepley   PetscInt        d;
135365876a83SMatthew G. Knepley 
135465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) f0[d] = -P_0 * n[d];
135565876a83SMatthew G. Knepley }
135665876a83SMatthew G. Knepley 
135765876a83SMatthew G. Knepley /* Standard Kernels - Residual */
135865876a83SMatthew G. Knepley /* f0_e */
1359d71ae5a4SJacob 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[])
1360d71ae5a4SJacob Faibussowitsch {
136165876a83SMatthew G. Knepley   PetscInt d;
136265876a83SMatthew G. Knepley 
1363ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) f0[0] += u_x[d * dim + d];
136465876a83SMatthew G. Knepley   f0[0] -= u[uOff[1]];
136565876a83SMatthew G. Knepley }
136665876a83SMatthew G. Knepley 
136765876a83SMatthew G. Knepley /* f0_p */
1368d71ae5a4SJacob 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[])
1369d71ae5a4SJacob Faibussowitsch {
137065876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
137165876a83SMatthew G. Knepley   const PetscReal M     = PetscRealPart(constants[3]);
137265876a83SMatthew G. Knepley 
137365876a83SMatthew G. Knepley   f0[0] += alpha * u_t[uOff[1]];
137465876a83SMatthew G. Knepley   f0[0] += u_t[uOff[2]] / M;
137530602db0SMatthew G. Knepley   if (f0[0] != f0[0]) abort();
137665876a83SMatthew G. Knepley }
137765876a83SMatthew G. Knepley 
137865876a83SMatthew G. Knepley /* f1_u */
1379d71ae5a4SJacob 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[])
1380d71ae5a4SJacob Faibussowitsch {
138165876a83SMatthew G. Knepley   const PetscInt  Nc     = dim;
138265876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
138365876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
138465876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
138565876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
138665876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
138765876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
138865876a83SMatthew G. Knepley   PetscInt        c, d;
138965876a83SMatthew G. Knepley 
13909371c9d4SSatish Balay   for (c = 0; c < Nc; ++c) {
1391ad540459SPierre Jolivet     for (d = 0; d < dim; ++d) f1[c * dim + d] -= G * (u_x[c * dim + d] + u_x[d * dim + c]);
139265876a83SMatthew G. Knepley     f1[c * dim + c] -= lambda * u[uOff[1]];
139365876a83SMatthew G. Knepley     f1[c * dim + c] += alpha * u[uOff[2]];
139465876a83SMatthew G. Knepley   }
139565876a83SMatthew G. Knepley }
139665876a83SMatthew G. Knepley 
139765876a83SMatthew G. Knepley /* f1_p */
1398d71ae5a4SJacob 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[])
1399d71ae5a4SJacob Faibussowitsch {
140065876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
140165876a83SMatthew G. Knepley   PetscInt        d;
140265876a83SMatthew G. Knepley 
1403ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) f1[d] += kappa * u_x[uOff_x[2] + d];
140465876a83SMatthew G. Knepley }
140565876a83SMatthew G. Knepley 
140665876a83SMatthew G. Knepley /*
140765876a83SMatthew G. Knepley   \partial_df \phi_fc g_{fc,gc,df,dg} \partial_dg \phi_gc
140865876a83SMatthew G. Knepley 
140965876a83SMatthew G. Knepley   \partial_df \phi_fc \lambda \delta_{fc,df} \sum_gc \partial_dg \phi_gc \delta_{gc,dg}
141065876a83SMatthew G. Knepley   = \partial_fc \phi_fc \sum_gc \partial_gc \phi_gc
141165876a83SMatthew G. Knepley */
141265876a83SMatthew G. Knepley 
141365876a83SMatthew G. Knepley /* Standard Kernels - Jacobian */
141465876a83SMatthew G. Knepley /* g0_ee */
1415d71ae5a4SJacob 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[])
1416d71ae5a4SJacob Faibussowitsch {
141765876a83SMatthew G. Knepley   g0[0] = -1.0;
141865876a83SMatthew G. Knepley }
141965876a83SMatthew G. Knepley 
142065876a83SMatthew G. Knepley /* g0_pe */
1421d71ae5a4SJacob 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[])
1422d71ae5a4SJacob Faibussowitsch {
142365876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
142465876a83SMatthew G. Knepley 
142565876a83SMatthew G. Knepley   g0[0] = u_tShift * alpha;
142665876a83SMatthew G. Knepley }
142765876a83SMatthew G. Knepley 
142865876a83SMatthew G. Knepley /* g0_pp */
1429d71ae5a4SJacob 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[])
1430d71ae5a4SJacob Faibussowitsch {
143165876a83SMatthew G. Knepley   const PetscReal M = PetscRealPart(constants[3]);
143265876a83SMatthew G. Knepley 
143365876a83SMatthew G. Knepley   g0[0] = u_tShift / M;
143465876a83SMatthew G. Knepley }
143565876a83SMatthew G. Knepley 
143665876a83SMatthew G. Knepley /* g1_eu */
1437d71ae5a4SJacob 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[])
1438d71ae5a4SJacob Faibussowitsch {
143965876a83SMatthew G. Knepley   PetscInt d;
144065876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g1[d * dim + d] = 1.0; /* \frac{\partial\phi^{u_d}}{\partial x_d} */
144165876a83SMatthew G. Knepley }
144265876a83SMatthew G. Knepley 
144365876a83SMatthew G. Knepley /* g2_ue */
1444d71ae5a4SJacob 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[])
1445d71ae5a4SJacob Faibussowitsch {
144665876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
144765876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
144865876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
144965876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
145065876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha * alpha * M;
145165876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
145265876a83SMatthew G. Knepley   PetscInt        d;
145365876a83SMatthew G. Knepley 
1454ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) g2[d * dim + d] -= lambda;
145565876a83SMatthew G. Knepley }
145665876a83SMatthew G. Knepley /* g2_up */
1457d71ae5a4SJacob 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[])
1458d71ae5a4SJacob Faibussowitsch {
145965876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
146065876a83SMatthew G. Knepley   PetscInt        d;
146165876a83SMatthew G. Knepley 
1462ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) g2[d * dim + d] += alpha;
146365876a83SMatthew G. Knepley }
146465876a83SMatthew G. Knepley 
146565876a83SMatthew G. Knepley /* g3_uu */
1466d71ae5a4SJacob 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[])
1467d71ae5a4SJacob Faibussowitsch {
146865876a83SMatthew G. Knepley   const PetscInt  Nc = dim;
146965876a83SMatthew G. Knepley   const PetscReal G  = PetscRealPart(constants[0]);
147065876a83SMatthew G. Knepley   PetscInt        c, d;
147165876a83SMatthew G. Knepley 
147265876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) {
147365876a83SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
147465876a83SMatthew G. Knepley       g3[((c * Nc + c) * dim + d) * dim + d] -= G;
147565876a83SMatthew G. Knepley       g3[((c * Nc + d) * dim + d) * dim + c] -= G;
147665876a83SMatthew G. Knepley     }
147765876a83SMatthew G. Knepley   }
147865876a83SMatthew G. Knepley }
147965876a83SMatthew G. Knepley 
148065876a83SMatthew G. Knepley /* g3_pp */
1481d71ae5a4SJacob 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[])
1482d71ae5a4SJacob Faibussowitsch {
148365876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
148465876a83SMatthew G. Knepley   PetscInt        d;
148565876a83SMatthew G. Knepley 
148665876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g3[d * dim + d] += kappa;
148765876a83SMatthew G. Knepley }
148865876a83SMatthew G. Knepley 
1489d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
1490d71ae5a4SJacob Faibussowitsch {
149165876a83SMatthew G. Knepley   PetscInt sol;
149265876a83SMatthew G. Knepley 
149365876a83SMatthew G. Knepley   PetscFunctionBeginUser;
149465876a83SMatthew G. Knepley   options->solType   = SOL_QUADRATIC_TRIG;
149565876a83SMatthew G. Knepley   options->niter     = 500;
149665876a83SMatthew G. Knepley   options->eps       = PETSC_SMALL;
149724b15d09SMatthew G. Knepley   options->dtInitial = -1.0;
1498d0609cedSBarry Smith   PetscOptionsBegin(comm, "", "Biot Poroelasticity Options", "DMPLEX");
14999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-niter", "Number of series term iterations in exact solutions", "ex53.c", options->niter, &options->niter, NULL));
150065876a83SMatthew G. Knepley   sol = options->solType;
15019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-sol_type", "Type of exact solution", "ex53.c", solutionTypes, NUM_SOLUTION_TYPES, solutionTypes[options->solType], &sol, NULL));
150265876a83SMatthew G. Knepley   options->solType = (SolutionType)sol;
15039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-eps", "Precision value for root finding", "ex53.c", options->eps, &options->eps, NULL));
15049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-dt_initial", "Override the initial timestep", "ex53.c", options->dtInitial, &options->dtInitial, NULL));
1505d0609cedSBarry Smith   PetscOptionsEnd();
15063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
150765876a83SMatthew G. Knepley }
150865876a83SMatthew G. Knepley 
1509d71ae5a4SJacob Faibussowitsch static PetscErrorCode mandelZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param)
1510d71ae5a4SJacob Faibussowitsch {
151165876a83SMatthew G. Knepley   //PetscBag       bag;
151265876a83SMatthew G. Knepley   PetscReal a1, a2, am;
151365876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
151465876a83SMatthew G. Knepley 
151565876a83SMatthew G. Knepley   PetscFunctionBeginUser;
15169566063dSJacob Faibussowitsch   //PetscCall(PetscBagGetData(ctx->bag, (void **) &param));
151765876a83SMatthew G. Knepley   PetscInt  NITER = ctx->niter;
151865876a83SMatthew G. Knepley   PetscReal EPS   = ctx->eps;
151965876a83SMatthew G. Knepley   //const PetscScalar YMAX = param->ymax;
152065876a83SMatthew G. Knepley   //const PetscScalar YMIN = param->ymin;
152165876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
152265876a83SMatthew G. Knepley   PetscScalar K_u   = param->K_u;
152365876a83SMatthew G. Knepley   PetscScalar M     = param->M;
152465876a83SMatthew G. Knepley   PetscScalar G     = param->mu;
152565876a83SMatthew G. Knepley   //const PetscScalar k = param->k;
152665876a83SMatthew G. Knepley   //const PetscScalar mu_f = param->mu_f;
152765876a83SMatthew G. Knepley   //const PetscScalar P_0 = param->P_0;
152865876a83SMatthew G. Knepley 
152965876a83SMatthew G. Knepley   PetscScalar K_d  = K_u - alpha * alpha * M;
153065876a83SMatthew G. Knepley   PetscScalar nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G));
153165876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G));
153265876a83SMatthew G. Knepley   //const PetscScalar kappa = k / mu_f;
153365876a83SMatthew G. Knepley 
153465876a83SMatthew G. Knepley   // Generate zero values
15359371c9d4SSatish Balay   for (PetscInt i = 1; i < NITER + 1; i++) {
153665876a83SMatthew G. Knepley     a1 = ((PetscReal)i - 1.0) * PETSC_PI * PETSC_PI / 4.0 + EPS;
153765876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI / 2;
153865876a83SMatthew G. Knepley     am = a1;
15399371c9d4SSatish Balay     for (PetscInt j = 0; j < NITER; j++) {
154065876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * a1;
154165876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * a2;
154265876a83SMatthew G. Knepley       am = (a1 + a2) / 2.0;
154365876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart((1.0 - nu) / (nu_u - nu)) * am;
15449371c9d4SSatish Balay       if ((ym * y1) > 0) {
154565876a83SMatthew G. Knepley         a1 = am;
154665876a83SMatthew G. Knepley       } else {
154765876a83SMatthew G. Knepley         a2 = am;
154865876a83SMatthew G. Knepley       }
1549ad540459SPierre Jolivet       if (PetscAbsReal(y2) < EPS) am = a2;
155065876a83SMatthew G. Knepley     }
155165876a83SMatthew G. Knepley     ctx->zeroArray[i - 1] = am;
155265876a83SMatthew G. Knepley   }
15533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
155465876a83SMatthew G. Knepley }
155565876a83SMatthew G. Knepley 
1556d71ae5a4SJacob Faibussowitsch static PetscReal CryerFunction(PetscReal nu_u, PetscReal nu, PetscReal x)
1557d71ae5a4SJacob Faibussowitsch {
155865876a83SMatthew 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));
155965876a83SMatthew G. Knepley }
156065876a83SMatthew G. Knepley 
1561d71ae5a4SJacob Faibussowitsch static PetscErrorCode cryerZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param)
1562d71ae5a4SJacob Faibussowitsch {
156365876a83SMatthew G. Knepley   PetscReal alpha = PetscRealPart(param->alpha); /* -  */
156465876a83SMatthew G. Knepley   PetscReal K_u   = PetscRealPart(param->K_u);   /* Pa */
156565876a83SMatthew G. Knepley   PetscReal M     = PetscRealPart(param->M);     /* Pa */
156665876a83SMatthew G. Knepley   PetscReal G     = PetscRealPart(param->mu);    /* Pa */
156765876a83SMatthew G. Knepley   PetscInt  N     = ctx->niter, n;
156865876a83SMatthew G. Knepley 
156965876a83SMatthew G. Knepley   PetscReal K_d  = K_u - alpha * alpha * M;                         /* Pa,      Cheng (B.5)  */
157065876a83SMatthew G. Knepley   PetscReal nu   = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G)); /* -,       Cheng (B.8)  */
157165876a83SMatthew G. Knepley   PetscReal nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)); /* -,       Cheng (B.9)  */
157265876a83SMatthew G. Knepley 
157365876a83SMatthew G. Knepley   PetscFunctionBeginUser;
157465876a83SMatthew G. Knepley   for (n = 1; n < N + 1; ++n) {
157565876a83SMatthew G. Knepley     PetscReal tol = PetscPowReal(n, 1.5) * ctx->eps;
157665876a83SMatthew G. Knepley     PetscReal a1 = 0., a2 = 0., am = 0.;
157765876a83SMatthew G. Knepley     PetscReal y1, y2, ym;
157865876a83SMatthew G. Knepley     PetscInt  j, k = n - 1;
157965876a83SMatthew G. Knepley 
158065876a83SMatthew G. Knepley     y1 = y2 = 1.;
158165876a83SMatthew G. Knepley     while (y1 * y2 > 0) {
158265876a83SMatthew G. Knepley       ++k;
158365876a83SMatthew G. Knepley       a1 = PetscSqr(n * PETSC_PI) - k * PETSC_PI;
158465876a83SMatthew G. Knepley       a2 = PetscSqr(n * PETSC_PI) + k * PETSC_PI;
158565876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
158665876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
158765876a83SMatthew G. Knepley     }
158865876a83SMatthew G. Knepley     for (j = 0; j < 50000; ++j) {
158965876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
159065876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
159163a3b9bcSJacob 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);
159265876a83SMatthew G. Knepley       am = (a1 + a2) / 2.0;
159365876a83SMatthew G. Knepley       ym = CryerFunction(nu_u, nu, am);
159465876a83SMatthew G. Knepley       if ((ym * y1) < 0) a2 = am;
159565876a83SMatthew G. Knepley       else a1 = am;
159663a3b9bcSJacob Faibussowitsch       if (PetscAbsReal(ym) < tol) break;
159765876a83SMatthew G. Knepley     }
159863a3b9bcSJacob Faibussowitsch     PetscCheck(PetscAbsReal(ym) < tol, comm, PETSC_ERR_PLIB, "Root finding did not converge for root %" PetscInt_FMT " (%g)", n, (double)PetscAbsReal(ym));
159965876a83SMatthew G. Knepley     ctx->zeroArray[n - 1] = am;
160065876a83SMatthew G. Knepley   }
16013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
160265876a83SMatthew G. Knepley }
160365876a83SMatthew G. Knepley 
1604d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupParameters(MPI_Comm comm, AppCtx *ctx)
1605d71ae5a4SJacob Faibussowitsch {
160665876a83SMatthew G. Knepley   PetscBag   bag;
160765876a83SMatthew G. Knepley   Parameter *p;
160865876a83SMatthew G. Knepley 
160965876a83SMatthew G. Knepley   PetscFunctionBeginUser;
161065876a83SMatthew G. Knepley   /* setup PETSc parameter bag */
16119566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(ctx->bag, (void **)&p));
16129566063dSJacob Faibussowitsch   PetscCall(PetscBagSetName(ctx->bag, "par", "Poroelastic Parameters"));
161365876a83SMatthew G. Knepley   bag = ctx->bag;
161465876a83SMatthew G. Knepley   if (ctx->solType == SOL_TERZAGHI) {
161565876a83SMatthew G. Knepley     // Realistic values - Terzaghi
16169566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 3.0, "mu", "Shear Modulus, Pa"));
16179566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 9.76, "K_u", "Undrained Bulk Modulus, Pa"));
16189566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
16199566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 16.0, "M", "Biot Modulus, Pa"));
16209566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
16219566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
16229566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
162365876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_MANDEL) {
162465876a83SMatthew G. Knepley     // Realistic values - Mandel
16259566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 0.75, "mu", "Shear Modulus, Pa"));
16269566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 2.6941176470588233, "K_u", "Undrained Bulk Modulus, Pa"));
16279566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
16289566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 4.705882352941176, "M", "Biot Modulus, Pa"));
16299566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
16309566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
16319566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
163265876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_CRYER) {
163365876a83SMatthew G. Knepley     // Realistic values - Mandel
16349566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 0.75, "mu", "Shear Modulus, Pa"));
16359566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 2.6941176470588233, "K_u", "Undrained Bulk Modulus, Pa"));
16369566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 0.6, "alpha", "Biot Effective Stress Coefficient, -"));
16379566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 4.705882352941176, "M", "Biot Modulus, Pa"));
16389566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.5, "k", "Isotropic Permeability, m**2"));
16399566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
16409566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
164165876a83SMatthew G. Knepley   } else {
164265876a83SMatthew G. Knepley     // Nonsense values
16439566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu, 1.0, "mu", "Shear Modulus, Pa"));
16449566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->K_u, 1.0, "K_u", "Undrained Bulk Modulus, Pa"));
16459566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->alpha, 1.0, "alpha", "Biot Effective Stress Coefficient, -"));
16469566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->M, 1.0, "M", "Biot Modulus, Pa"));
16479566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->k, 1.0, "k", "Isotropic Permeability, m**2"));
16489566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->mu_f, 1.0, "mu_f", "Fluid Dynamic Viscosity, Pa*s"));
16499566063dSJacob Faibussowitsch     PetscCall(PetscBagRegisterScalar(bag, &p->P_0, 1.0, "P_0", "Magnitude of Vertical Stress, Pa"));
165065876a83SMatthew G. Knepley   }
16519566063dSJacob Faibussowitsch   PetscCall(PetscBagSetFromOptions(bag));
165265876a83SMatthew G. Knepley   {
165365876a83SMatthew G. Knepley     PetscScalar K_d  = p->K_u - p->alpha * p->alpha * p->M;
165465876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0 * p->K_u - 2.0 * p->mu) / (2.0 * (3.0 * p->K_u + p->mu));
165565876a83SMatthew G. Knepley     PetscScalar nu   = (3.0 * K_d - 2.0 * p->mu) / (2.0 * (3.0 * K_d + p->mu));
165665876a83SMatthew G. Knepley     PetscScalar S    = (3.0 * p->K_u + 4.0 * p->mu) / (p->M * (3.0 * K_d + 4.0 * p->mu));
165765876a83SMatthew G. Knepley     PetscReal   c    = PetscRealPart((p->k / p->mu_f) / S);
165865876a83SMatthew G. Knepley 
165965876a83SMatthew G. Knepley     PetscViewer       viewer;
166065876a83SMatthew G. Knepley     PetscViewerFormat format;
166165876a83SMatthew G. Knepley     PetscBool         flg;
166265876a83SMatthew G. Knepley 
166365876a83SMatthew G. Knepley     switch (ctx->solType) {
166465876a83SMatthew G. Knepley     case SOL_QUADRATIC_LINEAR:
166565876a83SMatthew G. Knepley     case SOL_QUADRATIC_TRIG:
1666d71ae5a4SJacob Faibussowitsch     case SOL_TRIG_LINEAR:
1667d71ae5a4SJacob Faibussowitsch       ctx->t_r = PetscSqr(ctx->xmax[0] - ctx->xmin[0]) / c;
1668d71ae5a4SJacob Faibussowitsch       break;
1669d71ae5a4SJacob Faibussowitsch     case SOL_TERZAGHI:
1670d71ae5a4SJacob Faibussowitsch       ctx->t_r = PetscSqr(2.0 * (ctx->xmax[1] - ctx->xmin[1])) / c;
1671d71ae5a4SJacob Faibussowitsch       break;
1672d71ae5a4SJacob Faibussowitsch     case SOL_MANDEL:
1673d71ae5a4SJacob Faibussowitsch       ctx->t_r = PetscSqr(2.0 * (ctx->xmax[1] - ctx->xmin[1])) / c;
1674d71ae5a4SJacob Faibussowitsch       break;
1675d71ae5a4SJacob Faibussowitsch     case SOL_CRYER:
1676d71ae5a4SJacob Faibussowitsch       ctx->t_r = PetscSqr(ctx->xmax[1]) / c;
1677d71ae5a4SJacob Faibussowitsch       break;
1678d71ae5a4SJacob Faibussowitsch     default:
1679d71ae5a4SJacob Faibussowitsch       SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%d)", solutionTypes[PetscMin(ctx->solType, NUM_SOLUTION_TYPES)], ctx->solType);
168065876a83SMatthew G. Knepley     }
16819566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(comm, NULL, NULL, "-param_view", &viewer, &format, &flg));
168265876a83SMatthew G. Knepley     if (flg) {
16839566063dSJacob Faibussowitsch       PetscCall(PetscViewerPushFormat(viewer, format));
16849566063dSJacob Faibussowitsch       PetscCall(PetscBagView(bag, viewer));
16859566063dSJacob Faibussowitsch       PetscCall(PetscViewerFlush(viewer));
16869566063dSJacob Faibussowitsch       PetscCall(PetscViewerPopFormat(viewer));
16879566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&viewer));
168863a3b9bcSJacob 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)))));
168963a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "  Relaxation time: %g\n", (double)ctx->t_r));
169065876a83SMatthew G. Knepley     }
169165876a83SMatthew G. Knepley   }
16923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
169365876a83SMatthew G. Knepley }
169465876a83SMatthew G. Knepley 
1695d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
1696d71ae5a4SJacob Faibussowitsch {
169765876a83SMatthew G. Knepley   PetscFunctionBeginUser;
16989566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
16999566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMPLEX));
17009566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(*dm));
17019566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(*dm, user));
17029566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
17039566063dSJacob Faibussowitsch   PetscCall(DMGetBoundingBox(*dm, user->xmin, user->xmax));
17043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
170565876a83SMatthew G. Knepley }
170665876a83SMatthew G. Knepley 
1707d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupPrimalProblem(DM dm, AppCtx *user)
1708d71ae5a4SJacob Faibussowitsch {
170965876a83SMatthew G. Knepley   PetscErrorCode (*exact[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
171065876a83SMatthew G. Knepley   PetscErrorCode (*exact_t[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
171145480ffeSMatthew G. Knepley   PetscDS       ds;
171245480ffeSMatthew G. Knepley   DMLabel       label;
171345480ffeSMatthew G. Knepley   PetscWeakForm wf;
171465876a83SMatthew G. Knepley   Parameter    *param;
171565876a83SMatthew G. Knepley   PetscInt      id_mandel[2];
171665876a83SMatthew G. Knepley   PetscInt      comp[1];
171765876a83SMatthew G. Knepley   PetscInt      comp_mandel[2];
171845480ffeSMatthew G. Knepley   PetscInt      dim, id, bd, f;
171965876a83SMatthew G. Knepley 
172065876a83SMatthew G. Knepley   PetscFunctionBeginUser;
17219566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "marker", &label));
17229566063dSJacob Faibussowitsch   PetscCall(DMGetDS(dm, &ds));
17239566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(ds, &dim));
17249566063dSJacob Faibussowitsch   PetscCall(PetscBagGetData(user->bag, (void **)&param));
172565876a83SMatthew G. Knepley   exact_t[0] = exact_t[1] = exact_t[2] = zero;
172665876a83SMatthew G. Knepley 
172765876a83SMatthew G. Knepley   /* Setup Problem Formulation and Boundary Conditions */
172865876a83SMatthew G. Knepley   switch (user->solType) {
172965876a83SMatthew G. Knepley   case SOL_QUADRATIC_LINEAR:
17309566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_quadratic_linear_u, f1_u));
17319566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17329566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_quadratic_linear_p, f1_p));
17339566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17349566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17359566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17369566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17379566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17389566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17399566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
174065876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
174165876a83SMatthew G. Knepley     exact[1]   = linear_eps;
174265876a83SMatthew G. Knepley     exact[2]   = linear_linear_p;
174365876a83SMatthew G. Knepley     exact_t[2] = linear_linear_p_t;
174465876a83SMatthew G. Knepley 
174565876a83SMatthew G. Knepley     id = 1;
17469566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
17479566063dSJacob 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));
174865876a83SMatthew G. Knepley     break;
174965876a83SMatthew G. Knepley   case SOL_TRIG_LINEAR:
17509566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_trig_linear_u, f1_u));
17519566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17529566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_trig_linear_p, f1_p));
17539566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17549566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17559566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17569566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17579566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17589566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17599566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
176065876a83SMatthew G. Knepley     exact[0]   = trig_u;
176165876a83SMatthew G. Knepley     exact[1]   = trig_eps;
176265876a83SMatthew G. Knepley     exact[2]   = trig_linear_p;
176365876a83SMatthew G. Knepley     exact_t[2] = trig_linear_p_t;
176465876a83SMatthew G. Knepley 
176565876a83SMatthew G. Knepley     id = 1;
17669566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
17679566063dSJacob 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));
176865876a83SMatthew G. Knepley     break;
176965876a83SMatthew G. Knepley   case SOL_QUADRATIC_TRIG:
17709566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, f0_quadratic_trig_u, f1_u));
17719566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17729566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_quadratic_trig_p, f1_p));
17739566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17749566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17759566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17769566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17779566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17789566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17799566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
178065876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
178165876a83SMatthew G. Knepley     exact[1]   = linear_eps;
178265876a83SMatthew G. Knepley     exact[2]   = linear_trig_p;
178365876a83SMatthew G. Knepley     exact_t[2] = linear_trig_p_t;
178465876a83SMatthew G. Knepley 
178565876a83SMatthew G. Knepley     id = 1;
17869566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void))exact[0], NULL, user, NULL));
17879566063dSJacob 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));
178865876a83SMatthew G. Knepley     break;
178965876a83SMatthew G. Knepley   case SOL_TERZAGHI:
17909566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_u));
17919566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
17929566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_p, f1_p));
17939566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
17949566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
17959566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
17969566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
17979566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
17989566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
17999566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
180065876a83SMatthew G. Knepley 
180165876a83SMatthew G. Knepley     exact[0]   = terzaghi_2d_u;
180265876a83SMatthew G. Knepley     exact[1]   = terzaghi_2d_eps;
180365876a83SMatthew G. Knepley     exact[2]   = terzaghi_2d_p;
180465876a83SMatthew G. Knepley     exact_t[0] = terzaghi_2d_u_t;
180565876a83SMatthew G. Knepley     exact_t[1] = terzaghi_2d_eps_t;
180665876a83SMatthew G. Knepley     exact_t[2] = terzaghi_2d_p_t;
180765876a83SMatthew G. Knepley 
180865876a83SMatthew G. Knepley     id = 1;
18099566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", label, 1, &id, 0, 0, NULL, NULL, NULL, user, &bd));
18109566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
18119566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, 0, f0_terzaghi_bd_u, 0, NULL));
181245480ffeSMatthew G. Knepley 
181365876a83SMatthew G. Knepley     id      = 3;
181465876a83SMatthew G. Knepley     comp[0] = 1;
18159566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
181665876a83SMatthew G. Knepley     id      = 2;
181765876a83SMatthew G. Knepley     comp[0] = 0;
18189566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
181965876a83SMatthew G. Knepley     id      = 4;
182065876a83SMatthew G. Knepley     comp[0] = 0;
18219566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side", label, 1, &id, 0, 1, comp, (void (*)(void))zero, NULL, user, NULL));
182265876a83SMatthew G. Knepley     id = 1;
18239566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 1, &id, 2, 0, NULL, (void (*)(void))terzaghi_drainage_pressure, NULL, user, NULL));
182465876a83SMatthew G. Knepley     break;
182565876a83SMatthew G. Knepley   case SOL_MANDEL:
18269566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_u));
18279566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
18289566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_p, f1_p));
18299566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
18309566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
18319566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
18329566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
18339566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
18349566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
18359566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
183665876a83SMatthew G. Knepley 
18379566063dSJacob Faibussowitsch     PetscCall(mandelZeros(PETSC_COMM_WORLD, user, param));
183865876a83SMatthew G. Knepley 
183965876a83SMatthew G. Knepley     exact[0]   = mandel_2d_u;
184065876a83SMatthew G. Knepley     exact[1]   = mandel_2d_eps;
184165876a83SMatthew G. Knepley     exact[2]   = mandel_2d_p;
184265876a83SMatthew G. Knepley     exact_t[0] = mandel_2d_u_t;
184365876a83SMatthew G. Knepley     exact_t[1] = mandel_2d_eps_t;
184465876a83SMatthew G. Knepley     exact_t[2] = mandel_2d_p_t;
184565876a83SMatthew G. Knepley 
184665876a83SMatthew G. Knepley     id_mandel[0] = 3;
184765876a83SMatthew G. Knepley     id_mandel[1] = 1;
184865876a83SMatthew G. Knepley     //comp[0] = 1;
184965876a83SMatthew G. Knepley     comp_mandel[0] = 0;
185065876a83SMatthew G. Knepley     comp_mandel[1] = 1;
18519566063dSJacob 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));
18529566063dSJacob Faibussowitsch     //PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", "marker", 0, 1, comp, NULL, 2, id_mandel, user));
18539566063dSJacob Faibussowitsch     //PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", "marker", 0, 1, comp, (void (*)(void)) zero, 2, id_mandel, user));
18549566063dSJacob Faibussowitsch     //PetscCall(PetscDSSetBdResidual(ds, 0, f0_mandel_bd_u, NULL));
185565876a83SMatthew G. Knepley 
185665876a83SMatthew G. Knepley     id_mandel[0] = 2;
185765876a83SMatthew G. Knepley     id_mandel[1] = 4;
18589566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 2, id_mandel, 2, 0, NULL, (void (*)(void))zero, NULL, user, NULL));
185965876a83SMatthew G. Knepley     break;
186065876a83SMatthew G. Knepley   case SOL_CRYER:
18619566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 0, NULL, f1_u));
18629566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 1, f0_epsilon, NULL));
18639566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(ds, 2, f0_p, f1_p));
18649566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_uu));
18659566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_ue, NULL));
18669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 0, 2, NULL, NULL, g2_up, NULL));
18679566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_eu, NULL, NULL));
18689566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL, NULL, NULL));
18699566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL, NULL, NULL));
18709566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL, NULL, g3_pp));
187165876a83SMatthew G. Knepley 
18729566063dSJacob Faibussowitsch     PetscCall(cryerZeros(PETSC_COMM_WORLD, user, param));
187365876a83SMatthew G. Knepley 
187465876a83SMatthew G. Knepley     exact[0] = cryer_3d_u;
187565876a83SMatthew G. Knepley     exact[1] = cryer_3d_eps;
187665876a83SMatthew G. Knepley     exact[2] = cryer_3d_p;
187765876a83SMatthew G. Knepley 
187865876a83SMatthew G. Knepley     id = 1;
18799566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_NATURAL, "normal stress", label, 1, &id, 0, 0, NULL, NULL, NULL, user, &bd));
18809566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
18819566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, 0, f0_cryer_bd_u, 0, NULL));
188245480ffeSMatthew G. Knepley 
18839566063dSJacob Faibussowitsch     PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 1, &id, 2, 0, NULL, (void (*)(void))cryer_drainage_pressure, NULL, user, NULL));
188465876a83SMatthew G. Knepley     break;
1885d71ae5a4SJacob Faibussowitsch   default:
1886d71ae5a4SJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%d)", solutionTypes[PetscMin(user->solType, NUM_SOLUTION_TYPES)], user->solType);
188765876a83SMatthew G. Knepley   }
188865876a83SMatthew G. Knepley   for (f = 0; f < 3; ++f) {
18899566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(ds, f, exact[f], user));
18909566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(ds, f, exact_t[f], user));
189165876a83SMatthew G. Knepley   }
189265876a83SMatthew G. Knepley 
189365876a83SMatthew G. Knepley   /* Setup constants */
189465876a83SMatthew G. Knepley   {
189565876a83SMatthew G. Knepley     PetscScalar constants[6];
189665876a83SMatthew G. Knepley     constants[0] = param->mu;              /* shear modulus, Pa */
189765876a83SMatthew G. Knepley     constants[1] = param->K_u;             /* undrained bulk modulus, Pa */
189865876a83SMatthew G. Knepley     constants[2] = param->alpha;           /* Biot effective stress coefficient, - */
189965876a83SMatthew G. Knepley     constants[3] = param->M;               /* Biot modulus, Pa */
190065876a83SMatthew G. Knepley     constants[4] = param->k / param->mu_f; /* Darcy coefficient, m**2 / Pa*s */
190165876a83SMatthew G. Knepley     constants[5] = param->P_0;             /* Magnitude of Vertical Stress, Pa */
19029566063dSJacob Faibussowitsch     PetscCall(PetscDSSetConstants(ds, 6, constants));
190365876a83SMatthew G. Knepley   }
19043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
190565876a83SMatthew G. Knepley }
190665876a83SMatthew G. Knepley 
1907d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateElasticityNullSpace(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullspace)
1908d71ae5a4SJacob Faibussowitsch {
19097510d9b0SBarry Smith   PetscFunctionBeginUser;
19109566063dSJacob Faibussowitsch   PetscCall(DMPlexCreateRigidBody(dm, origField, nullspace));
19113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
191265876a83SMatthew G. Knepley }
191365876a83SMatthew G. Knepley 
1914d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupFE(DM dm, PetscInt Nf, PetscInt Nc[], const char *name[], PetscErrorCode (*setup)(DM, AppCtx *), void *ctx)
1915d71ae5a4SJacob Faibussowitsch {
191665876a83SMatthew G. Knepley   AppCtx         *user = (AppCtx *)ctx;
191765876a83SMatthew G. Knepley   DM              cdm  = dm;
191865876a83SMatthew G. Knepley   PetscFE         fe;
19192456a0d3SMatthew G. Knepley   PetscQuadrature q = NULL, fq = NULL;
192065876a83SMatthew G. Knepley   char            prefix[PETSC_MAX_PATH_LEN];
192165876a83SMatthew G. Knepley   PetscInt        dim, f;
192230602db0SMatthew G. Knepley   PetscBool       simplex;
192365876a83SMatthew G. Knepley 
19247510d9b0SBarry Smith   PetscFunctionBeginUser;
192565876a83SMatthew G. Knepley   /* Create finite element */
19269566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
19279566063dSJacob Faibussowitsch   PetscCall(DMPlexIsSimplex(dm, &simplex));
192865876a83SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
19299566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(prefix, PETSC_MAX_PATH_LEN, "%s_", name[f]));
19309566063dSJacob Faibussowitsch     PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, Nc[f], simplex, name[f] ? prefix : NULL, -1, &fe));
19319566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetName((PetscObject)fe, name[f]));
19329566063dSJacob Faibussowitsch     if (!q) PetscCall(PetscFEGetQuadrature(fe, &q));
19332456a0d3SMatthew G. Knepley     if (!fq) PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
19349566063dSJacob Faibussowitsch     PetscCall(PetscFESetQuadrature(fe, q));
19352456a0d3SMatthew G. Knepley     PetscCall(PetscFESetFaceQuadrature(fe, fq));
19369566063dSJacob Faibussowitsch     PetscCall(DMSetField(dm, f, NULL, (PetscObject)fe));
19379566063dSJacob Faibussowitsch     PetscCall(PetscFEDestroy(&fe));
193865876a83SMatthew G. Knepley   }
19399566063dSJacob Faibussowitsch   PetscCall(DMCreateDS(dm));
19409566063dSJacob Faibussowitsch   PetscCall((*setup)(dm, user));
194165876a83SMatthew G. Knepley   while (cdm) {
19429566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(dm, cdm));
19439566063dSJacob Faibussowitsch     if (0) PetscCall(DMSetNearNullSpaceConstructor(cdm, 0, CreateElasticityNullSpace));
194465876a83SMatthew G. Knepley     /* TODO: Check whether the boundary of coarse meshes is marked */
19459566063dSJacob Faibussowitsch     PetscCall(DMGetCoarseDM(cdm, &cdm));
194665876a83SMatthew G. Knepley   }
19479566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&fe));
19483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
194965876a83SMatthew G. Knepley }
195065876a83SMatthew G. Knepley 
1951d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetInitialConditions(TS ts, Vec u)
1952d71ae5a4SJacob Faibussowitsch {
195365876a83SMatthew G. Knepley   DM        dm;
195465876a83SMatthew G. Knepley   PetscReal t;
195565876a83SMatthew G. Knepley 
19567510d9b0SBarry Smith   PetscFunctionBeginUser;
19579566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
19589566063dSJacob Faibussowitsch   PetscCall(TSGetTime(ts, &t));
195965876a83SMatthew G. Knepley   if (t <= 0.0) {
196065876a83SMatthew G. Knepley     PetscErrorCode (*funcs[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
196165876a83SMatthew G. Knepley     void   *ctxs[3];
196265876a83SMatthew G. Knepley     AppCtx *ctx;
196365876a83SMatthew G. Knepley 
19649566063dSJacob Faibussowitsch     PetscCall(DMGetApplicationContext(dm, &ctx));
196565876a83SMatthew G. Knepley     switch (ctx->solType) {
196665876a83SMatthew G. Knepley     case SOL_TERZAGHI:
19679371c9d4SSatish Balay       funcs[0] = terzaghi_initial_u;
19689371c9d4SSatish Balay       ctxs[0]  = ctx;
19699371c9d4SSatish Balay       funcs[1] = terzaghi_initial_eps;
19709371c9d4SSatish Balay       ctxs[1]  = ctx;
19719371c9d4SSatish Balay       funcs[2] = terzaghi_drainage_pressure;
19729371c9d4SSatish Balay       ctxs[2]  = ctx;
19739566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
197465876a83SMatthew G. Knepley       break;
197565876a83SMatthew G. Knepley     case SOL_MANDEL:
19769371c9d4SSatish Balay       funcs[0] = mandel_initial_u;
19779371c9d4SSatish Balay       ctxs[0]  = ctx;
19789371c9d4SSatish Balay       funcs[1] = mandel_initial_eps;
19799371c9d4SSatish Balay       ctxs[1]  = ctx;
19809371c9d4SSatish Balay       funcs[2] = mandel_drainage_pressure;
19819371c9d4SSatish Balay       ctxs[2]  = ctx;
19829566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
198365876a83SMatthew G. Knepley       break;
198465876a83SMatthew G. Knepley     case SOL_CRYER:
19859371c9d4SSatish Balay       funcs[0] = cryer_initial_u;
19869371c9d4SSatish Balay       ctxs[0]  = ctx;
19879371c9d4SSatish Balay       funcs[1] = cryer_initial_eps;
19889371c9d4SSatish Balay       ctxs[1]  = ctx;
19899371c9d4SSatish Balay       funcs[2] = cryer_drainage_pressure;
19909371c9d4SSatish Balay       ctxs[2]  = ctx;
19919566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u));
199265876a83SMatthew G. Knepley       break;
1993d71ae5a4SJacob Faibussowitsch     default:
1994d71ae5a4SJacob Faibussowitsch       PetscCall(DMComputeExactSolution(dm, t, u, NULL));
199565876a83SMatthew G. Knepley     }
199665876a83SMatthew G. Knepley   } else {
19979566063dSJacob Faibussowitsch     PetscCall(DMComputeExactSolution(dm, t, u, NULL));
199865876a83SMatthew G. Knepley   }
19993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
200065876a83SMatthew G. Knepley }
200165876a83SMatthew G. Knepley 
200265876a83SMatthew G. Knepley /* Need to create Viewer each time because HDF5 can get corrupted */
2003d71ae5a4SJacob Faibussowitsch static PetscErrorCode SolutionMonitor(TS ts, PetscInt steps, PetscReal time, Vec u, void *mctx)
2004d71ae5a4SJacob Faibussowitsch {
200565876a83SMatthew G. Knepley   DM                dm;
200665876a83SMatthew G. Knepley   Vec               exact;
200765876a83SMatthew G. Knepley   PetscViewer       viewer;
200865876a83SMatthew G. Knepley   PetscViewerFormat format;
200965876a83SMatthew G. Knepley   PetscOptions      options;
201065876a83SMatthew G. Knepley   const char       *prefix;
201165876a83SMatthew G. Knepley 
20127510d9b0SBarry Smith   PetscFunctionBeginUser;
20139566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
20149566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptions((PetscObject)ts, &options));
20159566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, &prefix));
20169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), options, prefix, "-monitor_solution", &viewer, &format, NULL));
20179566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &exact));
20189566063dSJacob Faibussowitsch   PetscCall(DMComputeExactSolution(dm, time, exact, NULL));
20199566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, steps, time));
20209566063dSJacob Faibussowitsch   PetscCall(VecView(exact, viewer));
20219566063dSJacob Faibussowitsch   PetscCall(VecView(u, viewer));
20229566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &exact));
202365876a83SMatthew G. Knepley   {
202465876a83SMatthew G. Knepley     PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx);
202565876a83SMatthew G. Knepley     void     **ectxs;
202665876a83SMatthew G. Knepley     PetscReal *err;
202765876a83SMatthew G. Knepley     PetscInt   Nf, f;
202865876a83SMatthew G. Knepley 
20299566063dSJacob Faibussowitsch     PetscCall(DMGetNumFields(dm, &Nf));
20309566063dSJacob Faibussowitsch     PetscCall(PetscCalloc3(Nf, &exacts, Nf, &ectxs, PetscMax(1, Nf), &err));
203165876a83SMatthew G. Knepley     {
203265876a83SMatthew G. Knepley       PetscInt Nds, s;
203365876a83SMatthew G. Knepley 
20349566063dSJacob Faibussowitsch       PetscCall(DMGetNumDS(dm, &Nds));
203565876a83SMatthew G. Knepley       for (s = 0; s < Nds; ++s) {
203665876a83SMatthew G. Knepley         PetscDS         ds;
203765876a83SMatthew G. Knepley         DMLabel         label;
203865876a83SMatthew G. Knepley         IS              fieldIS;
203965876a83SMatthew G. Knepley         const PetscInt *fields;
204065876a83SMatthew G. Knepley         PetscInt        dsNf, f;
204165876a83SMatthew G. Knepley 
204207218a29SMatthew G. Knepley         PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL));
20439566063dSJacob Faibussowitsch         PetscCall(PetscDSGetNumFields(ds, &dsNf));
20449566063dSJacob Faibussowitsch         PetscCall(ISGetIndices(fieldIS, &fields));
204565876a83SMatthew G. Knepley         for (f = 0; f < dsNf; ++f) {
204665876a83SMatthew G. Knepley           const PetscInt field = fields[f];
20479566063dSJacob Faibussowitsch           PetscCall(PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]));
204865876a83SMatthew G. Knepley         }
20499566063dSJacob Faibussowitsch         PetscCall(ISRestoreIndices(fieldIS, &fields));
205065876a83SMatthew G. Knepley       }
205165876a83SMatthew G. Knepley     }
20529566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, time, exacts, ectxs, u, err));
205363a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "Time: %g L_2 Error: [", (double)time));
205465876a83SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
20559566063dSJacob Faibussowitsch       if (f) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), ", "));
20569566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%g", (double)err[f]));
205765876a83SMatthew G. Knepley     }
20589566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "]\n"));
20599566063dSJacob Faibussowitsch     PetscCall(PetscFree3(exacts, ectxs, err));
206065876a83SMatthew G. Knepley   }
20619566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
20623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
206365876a83SMatthew G. Knepley }
206465876a83SMatthew G. Knepley 
2065d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupMonitor(TS ts, AppCtx *ctx)
2066d71ae5a4SJacob Faibussowitsch {
206765876a83SMatthew G. Knepley   PetscViewer       viewer;
206865876a83SMatthew G. Knepley   PetscViewerFormat format;
206965876a83SMatthew G. Knepley   PetscOptions      options;
207065876a83SMatthew G. Knepley   const char       *prefix;
207165876a83SMatthew G. Knepley   PetscBool         flg;
207265876a83SMatthew G. Knepley 
20737510d9b0SBarry Smith   PetscFunctionBeginUser;
20749566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptions((PetscObject)ts, &options));
20759566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, &prefix));
20769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), options, prefix, "-monitor_solution", &viewer, &format, &flg));
20779566063dSJacob Faibussowitsch   if (flg) PetscCall(TSMonitorSet(ts, SolutionMonitor, ctx, NULL));
20789566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
20793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
208065876a83SMatthew G. Knepley }
208165876a83SMatthew G. Knepley 
2082d71ae5a4SJacob 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)
2083d71ae5a4SJacob Faibussowitsch {
208465876a83SMatthew G. Knepley   static PetscReal dtTarget = -1.0;
208565876a83SMatthew G. Knepley   PetscReal        dtInitial;
208665876a83SMatthew G. Knepley   DM               dm;
208765876a83SMatthew G. Knepley   AppCtx          *ctx;
208865876a83SMatthew G. Knepley   PetscInt         step;
208965876a83SMatthew G. Knepley 
20907510d9b0SBarry Smith   PetscFunctionBeginUser;
20919566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
20929566063dSJacob Faibussowitsch   PetscCall(DMGetApplicationContext(dm, &ctx));
20939566063dSJacob Faibussowitsch   PetscCall(TSGetStepNumber(ts, &step));
209424b15d09SMatthew G. Knepley   dtInitial = ctx->dtInitial < 0.0 ? 1.0e-4 * ctx->t_r : ctx->dtInitial;
209565876a83SMatthew G. Knepley   if (!step) {
209665876a83SMatthew G. Knepley     if (PetscAbsReal(dtInitial - h) > PETSC_SMALL) {
209765876a83SMatthew G. Knepley       *accept  = PETSC_FALSE;
209865876a83SMatthew G. Knepley       *next_h  = dtInitial;
209965876a83SMatthew G. Knepley       dtTarget = h;
210065876a83SMatthew G. Knepley     } else {
210165876a83SMatthew G. Knepley       *accept  = PETSC_TRUE;
210265876a83SMatthew G. Knepley       *next_h  = dtTarget < 0.0 ? dtInitial : dtTarget;
210365876a83SMatthew G. Knepley       dtTarget = -1.0;
210465876a83SMatthew G. Knepley     }
210565876a83SMatthew G. Knepley   } else {
210665876a83SMatthew G. Knepley     *accept = PETSC_TRUE;
210765876a83SMatthew G. Knepley     *next_h = h;
210865876a83SMatthew G. Knepley   }
210965876a83SMatthew G. Knepley   *next_sc = 0;  /* Reuse the same order scheme */
211065876a83SMatthew G. Knepley   *wlte    = -1; /* Weighted local truncation error was not evaluated */
211165876a83SMatthew G. Knepley   *wltea   = -1; /* Weighted absolute local truncation error was not evaluated */
211265876a83SMatthew G. Knepley   *wlter   = -1; /* Weighted relative local truncation error was not evaluated */
21133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
211465876a83SMatthew G. Knepley }
211565876a83SMatthew G. Knepley 
2116d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv)
2117d71ae5a4SJacob Faibussowitsch {
211865876a83SMatthew G. Knepley   AppCtx      ctx; /* User-defined work context */
211965876a83SMatthew G. Knepley   DM          dm;  /* Problem specification */
212065876a83SMatthew G. Knepley   TS          ts;  /* Time Series / Nonlinear solver */
212165876a83SMatthew G. Knepley   Vec         u;   /* Solutions */
212265876a83SMatthew G. Knepley   const char *name[3] = {"displacement", "tracestrain", "pressure"};
212365876a83SMatthew G. Knepley   PetscReal   t;
212430602db0SMatthew G. Knepley   PetscInt    dim, Nc[3];
212565876a83SMatthew G. Knepley 
2126327415f7SBarry Smith   PetscFunctionBeginUser;
21279566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
21289566063dSJacob Faibussowitsch   PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx));
21299566063dSJacob Faibussowitsch   PetscCall(PetscBagCreate(PETSC_COMM_SELF, sizeof(Parameter), &ctx.bag));
21309566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx.niter, &ctx.zeroArray));
21319566063dSJacob Faibussowitsch   PetscCall(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm));
21329566063dSJacob Faibussowitsch   PetscCall(SetupParameters(PETSC_COMM_WORLD, &ctx));
213365876a83SMatthew G. Knepley   /* Primal System */
21349566063dSJacob Faibussowitsch   PetscCall(TSCreate(PETSC_COMM_WORLD, &ts));
21359566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(dm, &ctx));
21369566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts, dm));
213765876a83SMatthew G. Knepley 
21389566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
213930602db0SMatthew G. Knepley   Nc[0] = dim;
214065876a83SMatthew G. Knepley   Nc[1] = 1;
214165876a83SMatthew G. Knepley   Nc[2] = 1;
214265876a83SMatthew G. Knepley 
21439566063dSJacob Faibussowitsch   PetscCall(SetupFE(dm, 3, Nc, name, SetupPrimalProblem, &ctx));
21449566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(dm, &u));
21459566063dSJacob Faibussowitsch   PetscCall(DMTSSetBoundaryLocal(dm, DMPlexTSComputeBoundary, &ctx));
21469566063dSJacob Faibussowitsch   PetscCall(DMTSSetIFunctionLocal(dm, DMPlexTSComputeIFunctionFEM, &ctx));
21479566063dSJacob Faibussowitsch   PetscCall(DMTSSetIJacobianLocal(dm, DMPlexTSComputeIJacobianFEM, &ctx));
21489566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP));
21499566063dSJacob Faibussowitsch   PetscCall(TSSetFromOptions(ts));
21509566063dSJacob Faibussowitsch   PetscCall(TSSetComputeInitialCondition(ts, SetInitialConditions));
21519566063dSJacob Faibussowitsch   PetscCall(SetupMonitor(ts, &ctx));
215265876a83SMatthew G. Knepley 
215365876a83SMatthew G. Knepley   if (ctx.solType != SOL_QUADRATIC_TRIG) {
215465876a83SMatthew G. Knepley     TSAdapt adapt;
215565876a83SMatthew G. Knepley 
21569566063dSJacob Faibussowitsch     PetscCall(TSGetAdapt(ts, &adapt));
215765876a83SMatthew G. Knepley     adapt->ops->choose = TSAdaptChoose_Terzaghi;
215865876a83SMatthew G. Knepley   }
215965876a83SMatthew G. Knepley   if (ctx.solType == SOL_CRYER) {
216065876a83SMatthew G. Knepley     Mat          J;
216165876a83SMatthew G. Knepley     MatNullSpace sp;
216265876a83SMatthew G. Knepley 
21639566063dSJacob Faibussowitsch     PetscCall(TSSetUp(ts));
21649566063dSJacob Faibussowitsch     PetscCall(TSGetIJacobian(ts, &J, NULL, NULL, NULL));
21659566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateRigidBody(dm, 0, &sp));
21669566063dSJacob Faibussowitsch     PetscCall(MatSetNullSpace(J, sp));
21679566063dSJacob Faibussowitsch     PetscCall(MatNullSpaceDestroy(&sp));
216865876a83SMatthew G. Knepley   }
21699566063dSJacob Faibussowitsch   PetscCall(TSGetTime(ts, &t));
21709566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, 0, t));
21719566063dSJacob Faibussowitsch   PetscCall(DMTSCheckFromOptions(ts, u));
21729566063dSJacob Faibussowitsch   PetscCall(SetInitialConditions(ts, u));
21739566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)u, "solution"));
21749566063dSJacob Faibussowitsch   PetscCall(TSSolve(ts, u));
21759566063dSJacob Faibussowitsch   PetscCall(DMTSCheckFromOptions(ts, u));
21769566063dSJacob Faibussowitsch   PetscCall(TSGetSolution(ts, &u));
21779566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
217865876a83SMatthew G. Knepley 
217965876a83SMatthew G. Knepley   /* Cleanup */
21809566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&u));
21819566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&ts));
21829566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm));
21839566063dSJacob Faibussowitsch   PetscCall(PetscBagDestroy(&ctx.bag));
21849566063dSJacob Faibussowitsch   PetscCall(PetscFree(ctx.zeroArray));
21859566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
2186b122ec5aSJacob Faibussowitsch   return 0;
218765876a83SMatthew G. Knepley }
218865876a83SMatthew G. Knepley 
218965876a83SMatthew G. Knepley /*TEST
219065876a83SMatthew G. Knepley 
219165876a83SMatthew G. Knepley   test:
219265876a83SMatthew G. Knepley     suffix: 2d_quad_linear
219365876a83SMatthew G. Knepley     requires: triangle
219465876a83SMatthew G. Knepley     args: -sol_type quadratic_linear -dm_refine 2 \
219565876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
219665876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
219765876a83SMatthew G. Knepley 
219865876a83SMatthew G. Knepley   test:
219965876a83SMatthew G. Knepley     suffix: 3d_quad_linear
220065876a83SMatthew G. Knepley     requires: ctetgen
220130602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_linear -dm_refine 1 \
220265876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
220365876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
220465876a83SMatthew G. Knepley 
220565876a83SMatthew G. Knepley   test:
220665876a83SMatthew G. Knepley     suffix: 2d_trig_linear
220765876a83SMatthew G. Knepley     requires: triangle
220865876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
220965876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
221065876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_dt 0.00001 -ts_monitor_extreme
221165876a83SMatthew G. Knepley 
221265876a83SMatthew G. Knepley   test:
221365876a83SMatthew G. Knepley     # -dm_refine 2 -convest_num_refine 3 get L_2 convergence rate: [1.9, 2.1, 1.8]
221465876a83SMatthew G. Knepley     suffix: 2d_trig_linear_sconv
221565876a83SMatthew G. Knepley     requires: triangle
221665876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
221765876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
221865876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -ts_dt 0.00001 -pc_type lu
221965876a83SMatthew G. Knepley 
222065876a83SMatthew G. Knepley   test:
222165876a83SMatthew G. Knepley     suffix: 3d_trig_linear
222265876a83SMatthew G. Knepley     requires: ctetgen
222330602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type trig_linear -dm_refine 1 \
222465876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
222565876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 2 -ts_monitor_extreme
222665876a83SMatthew G. Knepley 
222765876a83SMatthew G. Knepley   test:
222865876a83SMatthew G. Knepley     # -dm_refine 1 -convest_num_refine 2 gets L_2 convergence rate: [2.0, 2.1, 1.9]
222965876a83SMatthew G. Knepley     suffix: 3d_trig_linear_sconv
223065876a83SMatthew G. Knepley     requires: ctetgen
223130602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type trig_linear -dm_refine 1 \
223265876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
223365876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -pc_type lu
223465876a83SMatthew G. Knepley 
223565876a83SMatthew G. Knepley   test:
223665876a83SMatthew G. Knepley     suffix: 2d_quad_trig
223765876a83SMatthew G. Knepley     requires: triangle
223865876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 2 \
223965876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
224065876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
224165876a83SMatthew G. Knepley 
224265876a83SMatthew G. Knepley   test:
224365876a83SMatthew G. Knepley     # Using -dm_refine 4 gets the convergence rates to [0.95, 0.97, 0.90]
224465876a83SMatthew G. Knepley     suffix: 2d_quad_trig_tconv
224565876a83SMatthew G. Knepley     requires: triangle
224665876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 1 \
224765876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
224865876a83SMatthew G. Knepley       -convest_num_refine 3 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
224965876a83SMatthew G. Knepley 
225065876a83SMatthew G. Knepley   test:
225165876a83SMatthew G. Knepley     suffix: 3d_quad_trig
225265876a83SMatthew G. Knepley     requires: ctetgen
225330602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_trig -dm_refine 1 \
225465876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
225565876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
225665876a83SMatthew G. Knepley 
225765876a83SMatthew G. Knepley   test:
225865876a83SMatthew G. Knepley     # Using -dm_refine 2 -convest_num_refine 3 gets the convergence rates to [1.0, 1.0, 1.0]
225965876a83SMatthew G. Knepley     suffix: 3d_quad_trig_tconv
226065876a83SMatthew G. Knepley     requires: ctetgen
226130602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -sol_type quadratic_trig -dm_refine 1 \
226265876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
226365876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
226465876a83SMatthew G. Knepley 
226530602db0SMatthew G. Knepley   testset:
226630602db0SMatthew 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 \
226730602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 -niter 16000 \
226830602db0SMatthew G. Knepley           -pc_type lu
226930602db0SMatthew G. Knepley 
227065876a83SMatthew G. Knepley     test:
227165876a83SMatthew G. Knepley       suffix: 2d_terzaghi
227230602db0SMatthew G. Knepley       requires: double
227330602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001
227465876a83SMatthew G. Knepley 
227565876a83SMatthew G. Knepley     test:
227665876a83SMatthew 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]
227765876a83SMatthew G. Knepley       suffix: 2d_terzaghi_tconv
227830602db0SMatthew G. Knepley       args: -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1
227965876a83SMatthew G. Knepley 
228065876a83SMatthew G. Knepley     test:
228124b15d09SMatthew G. Knepley       # -dm_plex_box_faces 1,16 -convest_num_refine 4 gives L_2 convergence rate: [1.7, 1.2, 1.1]
228230602db0SMatthew 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]
228324b15d09SMatthew G. Knepley       suffix: 2d_terzaghi_sconv
228430602db0SMatthew 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
228530602db0SMatthew G. Knepley 
228630602db0SMatthew G. Knepley   testset:
228730602db0SMatthew 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 \
228830602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
228930602db0SMatthew G. Knepley           -pc_type lu
229024b15d09SMatthew G. Knepley 
229124b15d09SMatthew G. Knepley     test:
229265876a83SMatthew G. Knepley       suffix: 2d_mandel
229330602db0SMatthew G. Knepley       requires: double
229430602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001
229565876a83SMatthew G. Knepley 
229665876a83SMatthew G. Knepley     test:
2297f30e7d8cSMatthew G. Knepley       # -dm_refine 3 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [1.6, 0.93, 1.2]
2298f30e7d8cSMatthew G. Knepley       suffix: 2d_mandel_sconv
2299f30e7d8cSMatthew 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
2300f30e7d8cSMatthew G. Knepley 
2301f30e7d8cSMatthew G. Knepley     test:
230265876a83SMatthew G. Knepley       # -dm_refine 5 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [0.26, -0.0058, 0.26]
230365876a83SMatthew G. Knepley       suffix: 2d_mandel_tconv
230430602db0SMatthew G. Knepley       args: -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1
230530602db0SMatthew G. Knepley 
230630602db0SMatthew G. Knepley   testset:
230730602db0SMatthew G. Knepley     requires: ctetgen !complex
230830602db0SMatthew G. Knepley     args: -sol_type cryer -dm_plex_dim 3 -dm_plex_shape ball \
230930602db0SMatthew G. Knepley           -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1
231065876a83SMatthew G. Knepley 
231165876a83SMatthew G. Knepley     test:
231265876a83SMatthew G. Knepley       suffix: 3d_cryer
231330602db0SMatthew G. Knepley       args: -ts_dt 0.0028666667 -ts_max_time 0.014333 -ts_max_steps 2 -dmts_check .0001 \
231430602db0SMatthew G. Knepley             -pc_type svd
231565876a83SMatthew G. Knepley 
231665876a83SMatthew G. Knepley     test:
231714bf6794SMatthew G. Knepley       # -bd_dm_refine 3 -dm_refine_volume_limit_pre 0.004 -convest_num_refine 2 gives L_2 convergence rate: []
231814bf6794SMatthew G. Knepley       suffix: 3d_cryer_sconv
231914bf6794SMatthew G. Knepley       args: -bd_dm_refine 1 -dm_refine_volume_limit_pre 0.00666667 \
232014bf6794SMatthew G. Knepley             -ts_dt 1e-5 -dt_initial 1e-5 -ts_max_steps 2 \
232114bf6794SMatthew G. Knepley             -ts_convergence_estimate -ts_convergence_temporal 0 -convest_num_refine 1 \
232214bf6794SMatthew G. Knepley             -pc_type lu -pc_factor_shift_type nonzero
232314bf6794SMatthew G. Knepley 
232414bf6794SMatthew G. Knepley     test:
232565876a83SMatthew G. Knepley       # Displacement and Pressure converge. The analytic expression for trace strain is inaccurate at the origin
232665876a83SMatthew 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]
232765876a83SMatthew G. Knepley       suffix: 3d_cryer_tconv
232830602db0SMatthew G. Knepley       args: -bd_dm_refine 1 -dm_refine_volume_limit_pre 0.00666667 \
232930602db0SMatthew G. Knepley             -ts_dt 0.023 -ts_max_time 0.092 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1 \
233030602db0SMatthew G. Knepley             -pc_type lu -pc_factor_shift_type nonzero
233165876a83SMatthew G. Knepley 
233265876a83SMatthew G. Knepley TEST*/
2333