xref: /petsc/src/ts/tutorials/ex53.c (revision 45480ffeba491aca5d3f3b8c78679069fb317d32)
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 
3565876a83SMatthew G. Knepley typedef enum {SOL_QUADRATIC_LINEAR, SOL_QUADRATIC_TRIG, SOL_TRIG_LINEAR, SOL_TERZAGHI, SOL_MANDEL, SOL_CRYER, NUM_SOLUTION_TYPES} SolutionType;
3665876a83SMatthew G. Knepley const char *solutionTypes[NUM_SOLUTION_TYPES+1] = {"quadratic_linear", "quadratic_trig", "trig_linear", "terzaghi", "mandel", "cryer", "unknown"};
3765876a83SMatthew G. Knepley 
3865876a83SMatthew G. Knepley typedef struct {
3965876a83SMatthew G. Knepley   PetscScalar mu;    /* shear modulus */
4065876a83SMatthew G. Knepley   PetscScalar K_u;   /* undrained bulk modulus */
4165876a83SMatthew G. Knepley   PetscScalar alpha; /* Biot effective stress coefficient */
4265876a83SMatthew G. Knepley   PetscScalar M;     /* Biot modulus */
4365876a83SMatthew G. Knepley   PetscScalar k;     /* (isotropic) permeability */
4465876a83SMatthew G. Knepley   PetscScalar mu_f;  /* fluid dynamic viscosity */
4565876a83SMatthew G. Knepley   PetscReal   zmax;  /* depth maximum extent */
4665876a83SMatthew G. Knepley   PetscReal   zmin;  /* depth minimum extent */
4765876a83SMatthew G. Knepley   PetscReal   ymax;  /* vertical maximum extent */
4865876a83SMatthew G. Knepley   PetscReal   ymin;  /* vertical minimum extent */
4965876a83SMatthew G. Knepley   PetscReal   xmax;  /* horizontal maximum extent */
5065876a83SMatthew G. Knepley   PetscReal   xmin;  /* horizontal minimum extent */
5165876a83SMatthew G. Knepley   PetscScalar P_0;   /* magnitude of vertical stress */
5265876a83SMatthew G. Knepley } Parameter;
5365876a83SMatthew G. Knepley 
5465876a83SMatthew G. Knepley typedef struct {
5565876a83SMatthew G. Knepley   /* Domain and mesh definition */
5665876a83SMatthew G. Knepley   char         dmType[256]; /* DM type for the solve */
5765876a83SMatthew G. Knepley   PetscInt     dim;         /* The topological mesh dimension */
5865876a83SMatthew G. Knepley   PetscBool    simplex;     /* Simplicial mesh */
5965876a83SMatthew G. Knepley   PetscReal    refLimit;    /* Refine mesh with generator */
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 
7165876a83SMatthew G. Knepley static PetscErrorCode zero(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
7265876a83SMatthew G. Knepley {
7365876a83SMatthew G. Knepley   PetscInt c;
7465876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) u[c] = 0.0;
7565876a83SMatthew G. Knepley   return 0;
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 */
11365876a83SMatthew G. Knepley static PetscErrorCode quadratic_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
11465876a83SMatthew G. Knepley {
11565876a83SMatthew G. Knepley   PetscInt d;
11665876a83SMatthew G. Knepley 
11765876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
11865876a83SMatthew G. Knepley     u[d] = PetscSqr(x[d]) - (d > 0 ? 2.0 * x[d-1] * x[d] : 0.0);
11965876a83SMatthew G. Knepley   }
12065876a83SMatthew G. Knepley   return 0;
12165876a83SMatthew G. Knepley }
12265876a83SMatthew G. Knepley 
12365876a83SMatthew G. Knepley static PetscErrorCode linear_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
12465876a83SMatthew G. Knepley {
12565876a83SMatthew G. Knepley   u[0] = 2.0*x[dim-1];
12665876a83SMatthew G. Knepley   return 0;
12765876a83SMatthew G. Knepley }
12865876a83SMatthew G. Knepley 
12965876a83SMatthew G. Knepley static PetscErrorCode linear_linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
13065876a83SMatthew G. Knepley {
13165876a83SMatthew G. Knepley   PetscReal sum = 0.0;
13265876a83SMatthew G. Knepley   PetscInt  d;
13365876a83SMatthew G. Knepley 
13465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
13565876a83SMatthew G. Knepley   u[0] = sum*time;
13665876a83SMatthew G. Knepley   return 0;
13765876a83SMatthew G. Knepley }
13865876a83SMatthew G. Knepley 
13965876a83SMatthew G. Knepley static PetscErrorCode linear_linear_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
14065876a83SMatthew G. Knepley {
14165876a83SMatthew G. Knepley   PetscReal sum = 0.0;
14265876a83SMatthew G. Knepley   PetscInt  d;
14365876a83SMatthew G. Knepley 
14465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
14565876a83SMatthew G. Knepley   u[0] = sum;
14665876a83SMatthew G. Knepley   return 0;
14765876a83SMatthew G. Knepley }
14865876a83SMatthew G. Knepley 
14965876a83SMatthew G. Knepley static void f0_quadratic_linear_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
15065876a83SMatthew G. Knepley                                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
15165876a83SMatthew G. Knepley                                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
15265876a83SMatthew G. Knepley                                   PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
15365876a83SMatthew G. Knepley {
15465876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
15565876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
15665876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
15765876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
15865876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
15965876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
16065876a83SMatthew G. Knepley   PetscInt        d;
16165876a83SMatthew G. Knepley 
16265876a83SMatthew G. Knepley   for (d = 0; d < dim-1; ++d) {
16365876a83SMatthew G. Knepley     f0[d] -= 2.0*G - alpha*t;
16465876a83SMatthew G. Knepley   }
16565876a83SMatthew G. Knepley   f0[dim-1] -= 2.0*lambda + 4.0*G - alpha*t;
16665876a83SMatthew G. Knepley }
16765876a83SMatthew G. Knepley 
16865876a83SMatthew G. Knepley static void f0_quadratic_linear_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
16965876a83SMatthew G. Knepley                                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
17065876a83SMatthew G. Knepley                                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
17165876a83SMatthew G. Knepley                                   PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
17265876a83SMatthew G. Knepley {
17365876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
17465876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
17565876a83SMatthew G. Knepley   PetscReal       sum    = 0.0;
17665876a83SMatthew G. Knepley   PetscInt        d;
17765876a83SMatthew G. Knepley 
17865876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
17965876a83SMatthew G. Knepley   f0[0] += u_t ? alpha*u_t[uOff[1]] : 0.0;
18065876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]]/M     : 0.0;
18165876a83SMatthew G. Knepley   f0[0] -= sum/M;
18265876a83SMatthew G. Knepley }
18365876a83SMatthew G. Knepley 
18465876a83SMatthew G. Knepley /* Quadratic space and trigonometric time solution
18565876a83SMatthew G. Knepley 
18665876a83SMatthew G. Knepley   2D:
18765876a83SMatthew G. Knepley   u = x^2
18865876a83SMatthew G. Knepley   v = y^2 - 2xy
18965876a83SMatthew G. Knepley   p = (x + y) cos(t)
19065876a83SMatthew G. Knepley   e = 2y
19165876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha cos(t), alpha cos(t)>
19265876a83SMatthew G. Knepley   g = 0
19365876a83SMatthew G. Knepley   \epsilon = / 2x     -y    \
19465876a83SMatthew G. Knepley              \ -y   2y - 2x /
19565876a83SMatthew G. Knepley   Tr(\epsilon) = e = div u = 2y
19665876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
19765876a83SMatthew G. Knepley     = 2 G < 2-1, 2 > + \lambda <0, 2> - alpha <cos(t), cos(t)>
19865876a83SMatthew G. Knepley     = <2 G, 4 G + 2 \lambda> - <alpha cos(t), alpha cos(t)>
19965876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
20065876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
20165876a83SMatthew G. Knepley     = -(x + y)/M sin(t)
20265876a83SMatthew G. Knepley 
20365876a83SMatthew G. Knepley   3D:
20465876a83SMatthew G. Knepley   u = x^2
20565876a83SMatthew G. Knepley   v = y^2 - 2xy
20665876a83SMatthew G. Knepley   w = z^2 - 2yz
20765876a83SMatthew G. Knepley   p = (x + y + z) cos(t)
20865876a83SMatthew G. Knepley   e = 2z
20965876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha cos(t), alpha cos(t), alpha cos(t)>
21065876a83SMatthew G. Knepley   g = 0
21165876a83SMatthew G. Knepley   \varepsilon = / 2x     -y       0   \
21265876a83SMatthew G. Knepley                 | -y   2y - 2x   -z   |
21365876a83SMatthew G. Knepley                 \  0     -z    2z - 2y/
21465876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2z
21565876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
21665876a83SMatthew G. Knepley     = 2 G < 2-1, 2-1, 2 > + \lambda <0, 0, 2> - alpha <cos(t), cos(t), cos(t)>
21765876a83SMatthew G. Knepley     = <2 G, 2G, 4 G + 2 \lambda> - <alpha cos(t), alpha cos(t), alpha cos(t)>
21865876a83SMatthew G. Knepley */
21965876a83SMatthew G. Knepley static PetscErrorCode linear_trig_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
22065876a83SMatthew G. Knepley {
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*PetscCosReal(time);
22665876a83SMatthew G. Knepley   return 0;
22765876a83SMatthew G. Knepley }
22865876a83SMatthew G. Knepley 
22965876a83SMatthew G. Knepley static PetscErrorCode linear_trig_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
23065876a83SMatthew G. Knepley {
23165876a83SMatthew G. Knepley   PetscReal sum = 0.0;
23265876a83SMatthew G. Knepley   PetscInt  d;
23365876a83SMatthew G. Knepley 
23465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
23565876a83SMatthew G. Knepley   u[0] = -sum*PetscSinReal(time);
23665876a83SMatthew G. Knepley   return 0;
23765876a83SMatthew G. Knepley }
23865876a83SMatthew G. Knepley 
23965876a83SMatthew G. Knepley static void f0_quadratic_trig_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
24065876a83SMatthew G. Knepley                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
24165876a83SMatthew G. Knepley                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
24265876a83SMatthew G. Knepley                                 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
24365876a83SMatthew G. Knepley {
24465876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
24565876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
24665876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
24765876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
24865876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
24965876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
25065876a83SMatthew G. Knepley   PetscInt        d;
25165876a83SMatthew G. Knepley 
25265876a83SMatthew G. Knepley   for (d = 0; d < dim-1; ++d) {
25365876a83SMatthew G. Knepley     f0[d] -= 2.0*G - alpha*PetscCosReal(t);
25465876a83SMatthew G. Knepley   }
25565876a83SMatthew G. Knepley   f0[dim-1] -= 2.0*lambda + 4.0*G - alpha*PetscCosReal(t);
25665876a83SMatthew G. Knepley }
25765876a83SMatthew G. Knepley 
25865876a83SMatthew G. Knepley static void f0_quadratic_trig_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
25965876a83SMatthew G. Knepley                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
26065876a83SMatthew G. Knepley                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
26165876a83SMatthew G. Knepley                                 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
26265876a83SMatthew G. Knepley {
26365876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
26465876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
26565876a83SMatthew G. Knepley   PetscReal       sum    = 0.0;
26665876a83SMatthew G. Knepley   PetscInt        d;
26765876a83SMatthew G. Knepley 
26865876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
26965876a83SMatthew G. Knepley 
27065876a83SMatthew G. Knepley   f0[0] += u_t ? alpha*u_t[uOff[1]] : 0.0;
27165876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]]/M     : 0.0;
27265876a83SMatthew G. Knepley   f0[0] += PetscSinReal(t)*sum/M;
27365876a83SMatthew G. Knepley }
27465876a83SMatthew G. Knepley 
27565876a83SMatthew G. Knepley /* Trigonometric space and linear time solution
27665876a83SMatthew G. Knepley 
27765876a83SMatthew G. Knepley u = sin(2 pi x)
27865876a83SMatthew G. Knepley v = sin(2 pi y) - 2xy
27965876a83SMatthew G. Knepley \varepsilon = / 2 pi cos(2 pi x)             -y        \
28065876a83SMatthew G. Knepley               \      -y          2 pi cos(2 pi y) - 2x /
28165876a83SMatthew G. Knepley Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
28265876a83SMatthew G. Knepley div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
28365876a83SMatthew 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) >
28465876a83SMatthew 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) >
28565876a83SMatthew G. Knepley 
28665876a83SMatthew G. Knepley   2D:
28765876a83SMatthew G. Knepley   u = sin(2 pi x)
28865876a83SMatthew G. Knepley   v = sin(2 pi y) - 2xy
28965876a83SMatthew G. Knepley   p = (cos(2 pi x) + cos(2 pi y)) t
29065876a83SMatthew G. Knepley   e = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
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) (2G + lambda) > + 2 pi alpha t <sin(2 pi x), sin(2 pi y)>
29265876a83SMatthew G. Knepley   g = 0
29365876a83SMatthew G. Knepley   \varepsilon = / 2 pi cos(2 pi x)             -y        \
29465876a83SMatthew G. Knepley                 \      -y          2 pi cos(2 pi y) - 2x /
29565876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
29665876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
29765876a83SMatthew 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>
29865876a83SMatthew 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)>
29965876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
30065876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
30165876a83SMatthew G. Knepley     = (cos(2 pi x) + cos(2 pi y))/M - 4 pi^2 \kappa (cos(2 pi x) + cos(2 pi y)) t
30265876a83SMatthew G. Knepley 
30365876a83SMatthew G. Knepley   3D:
30465876a83SMatthew G. Knepley   u = sin(2 pi x)
30565876a83SMatthew G. Knepley   v = sin(2 pi y) - 2xy
30665876a83SMatthew G. Knepley   v = sin(2 pi y) - 2yz
30765876a83SMatthew G. Knepley   p = (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) t
30865876a83SMatthew G. Knepley   e = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2y
30965876a83SMatthew 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)>
31065876a83SMatthew G. Knepley   g = 0
31165876a83SMatthew G. Knepley   \varepsilon = / 2 pi cos(2 pi x)            -y                     0         \
31265876a83SMatthew G. Knepley                 |         -y       2 pi cos(2 pi y) - 2x            -z         |
31365876a83SMatthew G. Knepley                 \          0                  -z         2 pi cos(2 pi z) - 2y /
31465876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2 y
31565876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
31665876a83SMatthew 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>
31765876a83SMatthew 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)>
31865876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
31965876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
32065876a83SMatthew 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
32165876a83SMatthew G. Knepley */
32265876a83SMatthew G. Knepley static PetscErrorCode trig_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
32365876a83SMatthew G. Knepley {
32465876a83SMatthew G. Knepley   PetscInt d;
32565876a83SMatthew G. Knepley 
32665876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
32765876a83SMatthew G. Knepley     u[d] = PetscSinReal(2.*PETSC_PI*x[d]) - (d > 0 ? 2.0 * x[d-1] * x[d] : 0.0);
32865876a83SMatthew G. Knepley   }
32965876a83SMatthew G. Knepley   return 0;
33065876a83SMatthew G. Knepley }
33165876a83SMatthew G. Knepley 
33265876a83SMatthew G. Knepley static PetscErrorCode trig_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
33365876a83SMatthew G. Knepley {
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 += 2.*PETSC_PI*PetscCosReal(2.*PETSC_PI*x[d]) - (d < dim-1 ? 2.*x[d] : 0.0);
33865876a83SMatthew G. Knepley   u[0] = sum;
33965876a83SMatthew G. Knepley   return 0;
34065876a83SMatthew G. Knepley }
34165876a83SMatthew G. Knepley 
34265876a83SMatthew G. Knepley static PetscErrorCode trig_linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
34365876a83SMatthew G. Knepley {
34465876a83SMatthew G. Knepley   PetscReal sum = 0.0;
34565876a83SMatthew G. Knepley   PetscInt  d;
34665876a83SMatthew G. Knepley 
34765876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2.*PETSC_PI*x[d]);
34865876a83SMatthew G. Knepley   u[0] = sum*time;
34965876a83SMatthew G. Knepley   return 0;
35065876a83SMatthew G. Knepley }
35165876a83SMatthew G. Knepley 
35265876a83SMatthew G. Knepley static PetscErrorCode trig_linear_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
35365876a83SMatthew G. Knepley {
35465876a83SMatthew G. Knepley   PetscReal sum = 0.0;
35565876a83SMatthew G. Knepley   PetscInt  d;
35665876a83SMatthew G. Knepley 
35765876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2.*PETSC_PI*x[d]);
35865876a83SMatthew G. Knepley   u[0] = sum;
35965876a83SMatthew G. Knepley   return 0;
36065876a83SMatthew G. Knepley }
36165876a83SMatthew G. Knepley 
36265876a83SMatthew G. Knepley static void f0_trig_linear_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
36365876a83SMatthew G. Knepley                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
36465876a83SMatthew G. Knepley                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
36565876a83SMatthew G. Knepley                              PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
36665876a83SMatthew G. Knepley {
36765876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
36865876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
36965876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
37065876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
37165876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
37265876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
37365876a83SMatthew G. Knepley   PetscInt        d;
37465876a83SMatthew G. Knepley 
37565876a83SMatthew G. Knepley   for (d = 0; d < dim-1; ++d) {
37665876a83SMatthew G. Knepley     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;
37765876a83SMatthew G. Knepley   }
37865876a83SMatthew 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;
37965876a83SMatthew G. Knepley }
38065876a83SMatthew G. Knepley 
38165876a83SMatthew G. Knepley static void f0_trig_linear_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
38265876a83SMatthew G. Knepley                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
38365876a83SMatthew G. Knepley                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
38465876a83SMatthew G. Knepley                              PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
38565876a83SMatthew G. Knepley {
38665876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
38765876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
38865876a83SMatthew G. Knepley   const PetscReal kappa  = PetscRealPart(constants[4]);
38965876a83SMatthew G. Knepley   PetscReal       sum    = 0.0;
39065876a83SMatthew G. Knepley   PetscInt        d;
39165876a83SMatthew G. Knepley 
39265876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2.*PETSC_PI*x[d]);
39365876a83SMatthew G. Knepley   f0[0] += u_t ? alpha*u_t[uOff[1]] : 0.0;
39465876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]]/M     : 0.0;
39565876a83SMatthew G. Knepley   f0[0] -= sum/M - 4*PetscSqr(PETSC_PI)*kappa*sum*t;
39665876a83SMatthew G. Knepley }
39765876a83SMatthew G. Knepley 
39865876a83SMatthew G. Knepley /* Terzaghi Solutions */
39965876a83SMatthew G. Knepley /* The analytical solutions given here are drawn from chapter 7, section 3, */
40065876a83SMatthew G. Knepley /* "One-Dimensional Consolidation Problem," from Poroelasticity, by Cheng.  */
40165876a83SMatthew G. Knepley static PetscErrorCode terzaghi_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
40265876a83SMatthew G. Knepley {
40365876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
40465876a83SMatthew G. Knepley   Parameter     *param;
40565876a83SMatthew G. Knepley   PetscErrorCode ierr;
40665876a83SMatthew G. Knepley 
40765876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
40865876a83SMatthew G. Knepley   if (time <= 0.0) {
40965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
41065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
41165876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
41265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
41365876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
41465876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
41565876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
41665876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
41765876a83SMatthew G. Knepley 
41865876a83SMatthew G. Knepley     u[0] = ((P_0*eta) / (G*S));
41965876a83SMatthew G. Knepley   } else {
42065876a83SMatthew G. Knepley     u[0] = 0.0;
42165876a83SMatthew G. Knepley   }
42265876a83SMatthew G. Knepley   return 0;
42365876a83SMatthew G. Knepley }
42465876a83SMatthew G. Knepley 
42565876a83SMatthew G. Knepley static PetscErrorCode terzaghi_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
42665876a83SMatthew G. Knepley {
42765876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
42865876a83SMatthew G. Knepley   Parameter     *param;
42965876a83SMatthew G. Knepley   PetscErrorCode ierr;
43065876a83SMatthew G. Knepley 
43165876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
43265876a83SMatthew G. Knepley   {
43365876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
43465876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
43565876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
43665876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
43765876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G)); /* -,       Cheng (B.9)  */
43865876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                /* - */
43965876a83SMatthew G. Knepley 
44065876a83SMatthew G. Knepley     u[0] = 0.0;
44165876a83SMatthew G. Knepley     u[1] = ((P_0*L*(1.0 - 2.0*nu_u)) / (2.0*G*(1.0 - nu_u))) * (1.0 - zstar);
44265876a83SMatthew G. Knepley   }
44365876a83SMatthew G. Knepley   return 0;
44465876a83SMatthew G. Knepley }
44565876a83SMatthew G. Knepley 
44665876a83SMatthew G. Knepley static PetscErrorCode terzaghi_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
44765876a83SMatthew G. Knepley {
44865876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
44965876a83SMatthew G. Knepley   Parameter     *param;
45065876a83SMatthew G. Knepley   PetscErrorCode ierr;
45165876a83SMatthew G. Knepley 
45265876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
45365876a83SMatthew G. Knepley   {
45465876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
45565876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
45665876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
45765876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
45865876a83SMatthew G. Knepley 
45965876a83SMatthew G. Knepley     u[0] = -(P_0*(1.0 - 2.0*nu_u)) / (2.0*G*(1.0 - nu_u));
46065876a83SMatthew G. Knepley   }
46165876a83SMatthew G. Knepley   return 0;
46265876a83SMatthew G. Knepley }
46365876a83SMatthew G. Knepley 
46465876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
46565876a83SMatthew G. Knepley {
46665876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
46765876a83SMatthew G. Knepley   Parameter     *param;
46865876a83SMatthew G. Knepley   PetscErrorCode ierr;
46965876a83SMatthew G. Knepley 
47065876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
47165876a83SMatthew G. Knepley   if (time < 0.0) {
47265876a83SMatthew G. Knepley     ierr = terzaghi_initial_u(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
47365876a83SMatthew G. Knepley   } else {
47465876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
47565876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
47665876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
47765876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
47865876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
47965876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
48065876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
48165876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
48265876a83SMatthew G. Knepley 
48365876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
48465876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
48565876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
48665876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
48765876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
48865876a83SMatthew G. Knepley 
48965876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
49065876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
49165876a83SMatthew G. Knepley     PetscScalar F2    = 0.0;
49265876a83SMatthew G. Knepley 
49365876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
49465876a83SMatthew G. Knepley       if (m%2 == 1) {
49565876a83SMatthew G. Knepley         F2 += (8.0 / PetscSqr(m*PETSC_PI)) * PetscCosReal(0.5*m*PETSC_PI*zstar) * (1.0 - PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar));
49665876a83SMatthew G. Knepley       }
49765876a83SMatthew G. Knepley     }
49865876a83SMatthew G. Knepley     u[0] = 0.0;
49965876a83SMatthew 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 */
50065876a83SMatthew G. Knepley   }
50165876a83SMatthew G. Knepley   return 0;
50265876a83SMatthew G. Knepley }
50365876a83SMatthew G. Knepley 
50465876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
50565876a83SMatthew G. Knepley {
50665876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
50765876a83SMatthew G. Knepley   Parameter     *param;
50865876a83SMatthew G. Knepley   PetscErrorCode ierr;
50965876a83SMatthew G. Knepley 
51065876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
51165876a83SMatthew G. Knepley   if (time < 0.0) {
51265876a83SMatthew G. Knepley     ierr = terzaghi_initial_eps(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
51365876a83SMatthew G. Knepley   } else {
51465876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
51565876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
51665876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
51765876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
51865876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
51965876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
52065876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
52165876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
52265876a83SMatthew G. Knepley 
52365876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
52465876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
52565876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
52665876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
52765876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
52865876a83SMatthew G. Knepley 
52965876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
53065876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
53165876a83SMatthew G. Knepley     PetscScalar F2_z  = 0.0;
53265876a83SMatthew G. Knepley 
53365876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
53465876a83SMatthew G. Knepley       if (m%2 == 1) {
53565876a83SMatthew G. Knepley         F2_z += (-4.0 / (m*PETSC_PI*L)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * (1.0 - PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar));
53665876a83SMatthew G. Knepley       }
53765876a83SMatthew G. Knepley     }
53865876a83SMatthew 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; /* - */
53965876a83SMatthew G. Knepley   }
54065876a83SMatthew G. Knepley   return 0;
54165876a83SMatthew G. Knepley }
54265876a83SMatthew G. Knepley 
54365876a83SMatthew G. Knepley // Pressure
54465876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
54565876a83SMatthew G. Knepley {
54665876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
54765876a83SMatthew G. Knepley   Parameter     *param;
54865876a83SMatthew G. Knepley   PetscErrorCode ierr;
54965876a83SMatthew G. Knepley 
55065876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
55165876a83SMatthew G. Knepley   if (time <= 0.0) {
55265876a83SMatthew G. Knepley     ierr = terzaghi_drainage_pressure(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
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) */
56065876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* 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 eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
56565876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
56665876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
56765876a83SMatthew G. Knepley 
56865876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
56965876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
57065876a83SMatthew G. Knepley     PetscScalar F1    = 0.0;
57165876a83SMatthew G. Knepley 
57265876a83SMatthew G. Knepley     if (PetscAbsScalar((1/M + (alpha*eta)/G) - S) > 1.0e-10) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "S %g != check %g", S, (1/M + (alpha*eta)/G));
57365876a83SMatthew G. Knepley 
57465876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
57565876a83SMatthew G. Knepley       if (m%2 == 1) {
57665876a83SMatthew G. Knepley         F1 += (4.0 / (m*PETSC_PI)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
57765876a83SMatthew G. Knepley       }
57865876a83SMatthew G. Knepley     }
57965876a83SMatthew G. Knepley     u[0] = ((P_0*eta) / (G*S)) * F1; /* Pa */
58065876a83SMatthew G. Knepley   }
58165876a83SMatthew G. Knepley   return 0;
58265876a83SMatthew G. Knepley }
58365876a83SMatthew G. Knepley 
58465876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
58565876a83SMatthew G. Knepley {
58665876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
58765876a83SMatthew G. Knepley   Parameter     *param;
58865876a83SMatthew G. Knepley   PetscErrorCode ierr;
58965876a83SMatthew G. Knepley 
59065876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
59165876a83SMatthew G. Knepley   if (time <= 0.0) {
59265876a83SMatthew G. Knepley     u[0] = 0.0;
59365876a83SMatthew G. Knepley     u[1] = 0.0;
59465876a83SMatthew G. Knepley   } else {
59565876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
59665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
59765876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
59865876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
59965876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
60065876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
60165876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
60265876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
60365876a83SMatthew G. Knepley 
60465876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
60565876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
60665876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
60765876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
60865876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
60965876a83SMatthew G. Knepley 
61065876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
61165876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
61265876a83SMatthew G. Knepley     PetscScalar F2_t  = 0.0;
61365876a83SMatthew G. Knepley 
61465876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
61565876a83SMatthew G. Knepley       if (m%2 == 1) {
61665876a83SMatthew G. Knepley         F2_t += (2.0*c / PetscSqr(L)) * PetscCosReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
61765876a83SMatthew G. Knepley       }
61865876a83SMatthew G. Knepley     }
61965876a83SMatthew G. Knepley     u[0] = 0.0;
62065876a83SMatthew G. Knepley     u[1] = ((P_0*L*(nu_u - nu)) / (2.0*G*(1.0 - nu_u)*(1.0 - nu)))*F2_t; /* m / s */
62165876a83SMatthew G. Knepley   }
62265876a83SMatthew G. Knepley   return 0;
62365876a83SMatthew G. Knepley }
62465876a83SMatthew G. Knepley 
62565876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
62665876a83SMatthew G. Knepley {
62765876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
62865876a83SMatthew G. Knepley   Parameter     *param;
62965876a83SMatthew G. Knepley   PetscErrorCode ierr;
63065876a83SMatthew G. Knepley 
63165876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
63265876a83SMatthew G. Knepley   if (time <= 0.0) {
63365876a83SMatthew G. Knepley     u[0] = 0.0;
63465876a83SMatthew G. Knepley   } else {
63565876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
63665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
63765876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
63865876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
63965876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
64065876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
64165876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
64265876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
64365876a83SMatthew G. Knepley 
64465876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
64565876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
64665876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
64765876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
64865876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
64965876a83SMatthew G. Knepley 
65065876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
65165876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
65265876a83SMatthew G. Knepley     PetscScalar F2_zt = 0.0;
65365876a83SMatthew G. Knepley 
65465876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
65565876a83SMatthew G. Knepley       if (m%2 == 1) {
65665876a83SMatthew G. Knepley         F2_zt += ((-m*PETSC_PI*c) / (L*L*L)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
65765876a83SMatthew G. Knepley       }
65865876a83SMatthew G. Knepley     }
65965876a83SMatthew G. Knepley     u[0] = ((P_0*L*(nu_u - nu)) / (2.0*G*(1.0 - nu_u)*(1.0 - nu)))*F2_zt; /* 1 / s */
66065876a83SMatthew G. Knepley   }
66165876a83SMatthew G. Knepley   return 0;
66265876a83SMatthew G. Knepley }
66365876a83SMatthew G. Knepley 
66465876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
66565876a83SMatthew G. Knepley {
66665876a83SMatthew G. Knepley 
66765876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
66865876a83SMatthew G. Knepley   Parameter     *param;
66965876a83SMatthew G. Knepley   PetscErrorCode ierr;
67065876a83SMatthew G. Knepley 
67165876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
67265876a83SMatthew G. Knepley   if (time <= 0.0) {
67365876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
67465876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
67565876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
67665876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
67765876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
67865876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
67965876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
68065876a83SMatthew G. Knepley 
68165876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
68265876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
68365876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
68465876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
68565876a83SMatthew G. Knepley 
68665876a83SMatthew G. Knepley     u[0] = -((P_0*eta) / (G*S)) * PetscSqr(0*PETSC_PI)*c / PetscSqr(2.0*L); /* Pa / s */
68765876a83SMatthew G. Knepley   } else {
68865876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
68965876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
69065876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
69165876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
69265876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
69365876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
69465876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
69565876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
69665876a83SMatthew G. Knepley 
69765876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
69865876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
69965876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
70065876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
70165876a83SMatthew G. Knepley 
70265876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
70365876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
70465876a83SMatthew G. Knepley     PetscScalar F1_t  = 0.0;
70565876a83SMatthew G. Knepley     PetscScalar F1_zz = 0.0;
70665876a83SMatthew G. Knepley 
70765876a83SMatthew G. Knepley     if (PetscAbsScalar((1/M + (alpha*eta)/G) - S) > 1.0e-10) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "S %g != check %g", S, (1/M + (alpha*eta)/G));
70865876a83SMatthew G. Knepley 
70965876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
71065876a83SMatthew G. Knepley       if (m%2 == 1) {
71165876a83SMatthew G. Knepley         F1_t += ((-m*PETSC_PI*c) / PetscSqr(L)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
71265876a83SMatthew G. Knepley         F1_zz += (-m*PETSC_PI / PetscSqr(L)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
71365876a83SMatthew G. Knepley       }
71465876a83SMatthew G. Knepley     }
71565876a83SMatthew G. Knepley     u[0] = ((P_0*eta) / (G*S)) * F1_t; /* Pa / s */
71665876a83SMatthew G. Knepley   }
71765876a83SMatthew G. Knepley   return 0;
71865876a83SMatthew G. Knepley }
71965876a83SMatthew G. Knepley 
72065876a83SMatthew G. Knepley /* Mandel Solutions */
72165876a83SMatthew G. Knepley static PetscErrorCode mandel_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
72265876a83SMatthew G. Knepley {
72365876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
72465876a83SMatthew G. Knepley   Parameter     *param;
72565876a83SMatthew G. Knepley   PetscErrorCode ierr;
72665876a83SMatthew G. Knepley 
72765876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
72865876a83SMatthew G. Knepley   if (time <= 0.0) {
72965876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
73065876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
73165876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
73265876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
73365876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
73465876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
73565876a83SMatthew G. Knepley     PetscReal   a     = 0.5*(param->xmax - param->xmin); /* m */
73665876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
73765876a83SMatthew G. Knepley 
73865876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
73965876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
74065876a83SMatthew G. Knepley     PetscScalar B     = alpha*M / K_u;                             /* -,       Cheng (B.12) */
74165876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
74265876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
74365876a83SMatthew G. Knepley 
74465876a83SMatthew G. Knepley     PetscScalar A1    = 3.0 / (B * (1.0 + nu_u));
74565876a83SMatthew G. Knepley     PetscReal   aa    = 0.0;
74665876a83SMatthew G. Knepley     PetscReal   p     = 0.0;
74765876a83SMatthew G. Knepley     PetscReal   time  = 0.0;
74865876a83SMatthew G. Knepley 
74965876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
75065876a83SMatthew G. Knepley       aa = user->zeroArray[n-1];
75165876a83SMatthew 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));
75265876a83SMatthew G. Knepley     }
75365876a83SMatthew G. Knepley     u[0] = ((2.0 * P_0) / (a*A1)) * p;
75465876a83SMatthew G. Knepley   } else {
75565876a83SMatthew G. Knepley     u[0] = 0.0;
75665876a83SMatthew G. Knepley   }
75765876a83SMatthew G. Knepley   return 0;
75865876a83SMatthew G. Knepley }
75965876a83SMatthew G. Knepley 
76065876a83SMatthew G. Knepley static PetscErrorCode mandel_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
76165876a83SMatthew G. Knepley {
76265876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
76365876a83SMatthew G. Knepley   Parameter     *param;
76465876a83SMatthew G. Knepley   PetscErrorCode ierr;
76565876a83SMatthew G. Knepley 
76665876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
76765876a83SMatthew G. Knepley   {
76865876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
76965876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
77065876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
77165876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
77265876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
77365876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
77465876a83SMatthew G. Knepley     PetscScalar a     = 0.5*(param->xmax - param->xmin); /* m */
77565876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
77665876a83SMatthew G. Knepley 
77765876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
77865876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
77965876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
78065876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
78165876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
78265876a83SMatthew G. Knepley 
78365876a83SMatthew G. Knepley     PetscScalar A_s   = 0.0;
78465876a83SMatthew G. Knepley     PetscScalar B_s   = 0.0;
78565876a83SMatthew G. Knepley     PetscScalar time  = 0.0;
78665876a83SMatthew G. Knepley     PetscScalar alpha_n = 0.0;
78765876a83SMatthew G. Knepley 
78865876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
78965876a83SMatthew G. Knepley       alpha_n = user->zeroArray[n-1];
79065876a83SMatthew 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));
79165876a83SMatthew 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));
79265876a83SMatthew G. Knepley     }
79365876a83SMatthew 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;
79465876a83SMatthew G. Knepley     u[1] = (-1*(P_0*(1.0-nu))/(2*G*a) + (P_0*(1-nu_u))/(G*a) * A_s)*x[1];
79565876a83SMatthew G. Knepley   }
79665876a83SMatthew G. Knepley   return 0;
79765876a83SMatthew G. Knepley }
79865876a83SMatthew G. Knepley 
79965876a83SMatthew G. Knepley static PetscErrorCode mandel_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
80065876a83SMatthew G. Knepley {
80165876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
80265876a83SMatthew G. Knepley   Parameter     *param;
80365876a83SMatthew G. Knepley   PetscErrorCode ierr;
80465876a83SMatthew G. Knepley 
80565876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
80665876a83SMatthew G. Knepley   {
80765876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
80865876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
80965876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
81065876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
81165876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
81265876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
81365876a83SMatthew G. Knepley     PetscReal   a     = 0.5*(param->xmax - param->xmin); /* m */
81465876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
81565876a83SMatthew G. Knepley 
81665876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
81765876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
81865876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
81965876a83SMatthew G. Knepley     PetscReal   c     = PetscRealPart(kappa / S);                  /* m^2 / s, Cheng (B.16) */
82065876a83SMatthew G. Knepley 
82165876a83SMatthew G. Knepley     PetscReal   aa    = 0.0;
82265876a83SMatthew G. Knepley     PetscReal   eps_A = 0.0;
82365876a83SMatthew G. Knepley     PetscReal   eps_B = 0.0;
82465876a83SMatthew G. Knepley     PetscReal   eps_C = 0.0;
82565876a83SMatthew G. Knepley     PetscReal   time  = 0.0;
82665876a83SMatthew G. Knepley 
82765876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
82865876a83SMatthew G. Knepley       aa     = user->zeroArray[n-1];
82965876a83SMatthew 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)));
83065876a83SMatthew G. Knepley       eps_B += ( PetscExpReal( (-1.0*aa*aa*c*time)/(a*a))*PetscSinReal(aa)*PetscCosReal(aa)) / (aa - PetscSinReal(aa)*PetscCosReal(aa));
83165876a83SMatthew G. Knepley       eps_C += ( PetscExpReal( (-1.0*aa*aa*c*time)/(aa*aa))*PetscSinReal(aa)*PetscCosReal(aa)) / (aa - PetscSinReal(aa)*PetscCosReal(aa));
83265876a83SMatthew G. Knepley     }
83365876a83SMatthew 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);
83465876a83SMatthew G. Knepley   }
83565876a83SMatthew G. Knepley   return 0;
83665876a83SMatthew G. Knepley }
83765876a83SMatthew G. Knepley 
83865876a83SMatthew G. Knepley // Displacement
83965876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
84065876a83SMatthew G. Knepley {
84165876a83SMatthew G. Knepley 
84265876a83SMatthew G. Knepley   Parameter  *param;
84365876a83SMatthew G. Knepley   PetscErrorCode ierr;
84465876a83SMatthew G. Knepley 
84565876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
84665876a83SMatthew G. Knepley 
84765876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
84865876a83SMatthew G. Knepley   if (time <= 0.0) {
84965876a83SMatthew G. Knepley     ierr = mandel_initial_u(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
85065876a83SMatthew G. Knepley   } else {
85165876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
85265876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
85365876a83SMatthew G. Knepley     PetscScalar K_u = param->K_u;
85465876a83SMatthew G. Knepley     PetscScalar M = param->M;
85565876a83SMatthew G. Knepley     PetscScalar G = param->mu;
85665876a83SMatthew G. Knepley     PetscScalar k = param->k;
85765876a83SMatthew G. Knepley     PetscScalar mu_f = param->mu_f;
85865876a83SMatthew G. Knepley     PetscScalar F = param->P_0;
85965876a83SMatthew G. Knepley 
86065876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha*alpha*M;
86165876a83SMatthew G. Knepley     PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
86265876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
86365876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
86465876a83SMatthew G. Knepley     PetscReal   a = (param->xmax - param->xmin) / 2.0;
86565876a83SMatthew 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)));
86665876a83SMatthew G. Knepley 
86765876a83SMatthew G. Knepley     // Series term
86865876a83SMatthew G. Knepley     PetscScalar A_x = 0.0;
86965876a83SMatthew G. Knepley     PetscScalar B_x = 0.0;
87065876a83SMatthew G. Knepley 
87165876a83SMatthew G. Knepley     for (PetscInt n=1; n < NITER+1; n++) {
87265876a83SMatthew G. Knepley       PetscReal alpha_n = user->zeroArray[n-1];
87365876a83SMatthew G. Knepley 
87465876a83SMatthew 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));
87565876a83SMatthew 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));
87665876a83SMatthew G. Knepley     }
87765876a83SMatthew G. Knepley     u[0] = ((F*nu)/(2.0*G*a) - (F*nu_u)/(G*a) * A_x)* x[0] + F/G * B_x;
87865876a83SMatthew G. Knepley     u[1] = (-1*(F*(1.0-nu))/(2*G*a) + (F*(1-nu_u))/(G*a) * A_x)*x[1];
87965876a83SMatthew G. Knepley   }
88065876a83SMatthew G. Knepley   return 0;
88165876a83SMatthew G. Knepley }
88265876a83SMatthew G. Knepley 
88365876a83SMatthew G. Knepley // Trace strain
88465876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
88565876a83SMatthew G. Knepley {
88665876a83SMatthew G. Knepley 
88765876a83SMatthew G. Knepley   Parameter  *param;
88865876a83SMatthew G. Knepley   PetscErrorCode ierr;
88965876a83SMatthew G. Knepley 
89065876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
89165876a83SMatthew G. Knepley 
89265876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
89365876a83SMatthew G. Knepley   if (time <= 0.0) {
89465876a83SMatthew G. Knepley     ierr = mandel_initial_eps(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
89565876a83SMatthew G. Knepley   } else {
89665876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
89765876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
89865876a83SMatthew G. Knepley     PetscScalar K_u = param->K_u;
89965876a83SMatthew G. Knepley     PetscScalar M = param->M;
90065876a83SMatthew G. Knepley     PetscScalar G = param->mu;
90165876a83SMatthew G. Knepley     PetscScalar k = param->k;
90265876a83SMatthew G. Knepley     PetscScalar mu_f = param->mu_f;
90365876a83SMatthew G. Knepley     PetscScalar F = param->P_0;
90465876a83SMatthew G. Knepley 
90565876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha*alpha*M;
90665876a83SMatthew G. Knepley     PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
90765876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
90865876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
90965876a83SMatthew G. Knepley     //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
91065876a83SMatthew G. Knepley 
91165876a83SMatthew G. Knepley     //const PetscScalar b = (YMAX - YMIN) / 2.0;
91265876a83SMatthew G. Knepley     PetscScalar a = (param->xmax - param->xmin) / 2.0;
91365876a83SMatthew 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)));
91465876a83SMatthew G. Knepley 
91565876a83SMatthew G. Knepley     // Series term
91665876a83SMatthew G. Knepley     PetscScalar eps_A = 0.0;
91765876a83SMatthew G. Knepley     PetscScalar eps_B = 0.0;
91865876a83SMatthew G. Knepley     PetscScalar eps_C = 0.0;
91965876a83SMatthew G. Knepley 
92065876a83SMatthew G. Knepley     for (PetscInt n=1; n < NITER+1; n++)
92165876a83SMatthew G. Knepley     {
92265876a83SMatthew G. Knepley       PetscReal aa = user->zeroArray[n-1];
92365876a83SMatthew G. Knepley 
92465876a83SMatthew 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)));
92565876a83SMatthew G. Knepley 
92665876a83SMatthew G. Knepley       eps_B += ( PetscExpReal( (-1.0*aa*aa*c*time)/(a*a))*PetscSinReal(aa)*PetscCosReal(aa)) / (aa - PetscSinReal(aa)*PetscCosReal(aa));
92765876a83SMatthew G. Knepley 
92865876a83SMatthew G. Knepley       eps_C += ( PetscExpReal( (-1.0*aa*aa*c*time)/(aa*aa))*PetscSinReal(aa)*PetscCosReal(aa)) / (aa - PetscSinReal(aa)*PetscCosReal(aa));
92965876a83SMatthew G. Knepley     }
93065876a83SMatthew G. Knepley 
93165876a83SMatthew 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);
93265876a83SMatthew G. Knepley   }
93365876a83SMatthew G. Knepley   return 0;
93465876a83SMatthew G. Knepley 
93565876a83SMatthew G. Knepley }
93665876a83SMatthew G. Knepley 
93765876a83SMatthew G. Knepley // Pressure
93865876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
93965876a83SMatthew G. Knepley {
94065876a83SMatthew G. Knepley 
94165876a83SMatthew G. Knepley   Parameter  *param;
94265876a83SMatthew G. Knepley   PetscErrorCode ierr;
94365876a83SMatthew G. Knepley 
94465876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
94565876a83SMatthew G. Knepley 
94665876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
94765876a83SMatthew G. Knepley   if (time <= 0.0) {
94865876a83SMatthew G. Knepley     ierr = mandel_drainage_pressure(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
94965876a83SMatthew G. Knepley   } else {
95065876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
95165876a83SMatthew G. Knepley 
95265876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
95365876a83SMatthew G. Knepley     PetscScalar K_u = param->K_u;
95465876a83SMatthew G. Knepley     PetscScalar M = param->M;
95565876a83SMatthew G. Knepley     PetscScalar G = param->mu;
95665876a83SMatthew G. Knepley     PetscScalar k = param->k;
95765876a83SMatthew G. Knepley     PetscScalar mu_f = param->mu_f;
95865876a83SMatthew G. Knepley     PetscScalar F = param->P_0;
95965876a83SMatthew G. Knepley 
96065876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha*alpha*M;
96165876a83SMatthew G. Knepley     PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
96265876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
96365876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
96465876a83SMatthew G. Knepley     PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
96565876a83SMatthew G. Knepley 
96665876a83SMatthew G. Knepley     PetscReal   a  = (param->xmax - param->xmin) / 2.0;
96765876a83SMatthew 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)));
96865876a83SMatthew G. Knepley     PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
96965876a83SMatthew G. Knepley     //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
97065876a83SMatthew G. Knepley 
97165876a83SMatthew G. Knepley     // Series term
97265876a83SMatthew G. Knepley     PetscScalar aa = 0.0;
97365876a83SMatthew G. Knepley     PetscScalar p  = 0.0;
97465876a83SMatthew G. Knepley 
97565876a83SMatthew G. Knepley     for (PetscInt n=1; n < NITER+1; n++)
97665876a83SMatthew G. Knepley     {
97765876a83SMatthew G. Knepley       aa = user->zeroArray[n-1];
97865876a83SMatthew 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));
97965876a83SMatthew G. Knepley     }
98065876a83SMatthew G. Knepley     u[0] = ((2.0 * F) / (a*A1)) * p;
98165876a83SMatthew G. Knepley   }
98265876a83SMatthew G. Knepley   return 0;
98365876a83SMatthew G. Knepley }
98465876a83SMatthew G. Knepley 
98565876a83SMatthew G. Knepley // Time derivative of displacement
98665876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
98765876a83SMatthew G. Knepley {
98865876a83SMatthew G. Knepley 
98965876a83SMatthew G. Knepley   Parameter  *param;
99065876a83SMatthew G. Knepley   PetscErrorCode ierr;
99165876a83SMatthew G. Knepley 
99265876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
99365876a83SMatthew G. Knepley 
99465876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
99565876a83SMatthew G. Knepley 
99665876a83SMatthew G. Knepley   PetscInt NITER = user->niter;
99765876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
99865876a83SMatthew G. Knepley   PetscScalar K_u = param->K_u;
99965876a83SMatthew G. Knepley   PetscScalar M = param->M;
100065876a83SMatthew G. Knepley   PetscScalar G = param->mu;
100165876a83SMatthew G. Knepley   PetscScalar F = param->P_0;
100265876a83SMatthew G. Knepley 
100365876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
100465876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
100565876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
100665876a83SMatthew G. Knepley   PetscScalar kappa = param->k / param->mu_f;
100765876a83SMatthew G. Knepley   PetscReal   a = (param->xmax - param->xmin) / 2.0;
100865876a83SMatthew 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)));
100965876a83SMatthew G. Knepley 
101065876a83SMatthew G. Knepley   // Series term
101165876a83SMatthew G. Knepley   PetscScalar A_s_t = 0.0;
101265876a83SMatthew G. Knepley   PetscScalar B_s_t = 0.0;
101365876a83SMatthew G. Knepley 
101465876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
101565876a83SMatthew G. Knepley   {
101665876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n-1];
101765876a83SMatthew G. Knepley 
101865876a83SMatthew 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)));
101965876a83SMatthew 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)));
102065876a83SMatthew G. Knepley   }
102165876a83SMatthew G. Knepley 
102265876a83SMatthew G. Knepley   u[0] = (F/G)*A_s_t - ( (F*nu_u*x[0])/(G*a))*B_s_t;
102365876a83SMatthew G. Knepley   u[1] = ( (F*x[1]*(1 - nu_u)) / (G*a))*B_s_t;
102465876a83SMatthew G. Knepley 
102565876a83SMatthew G. Knepley   return 0;
102665876a83SMatthew G. Knepley }
102765876a83SMatthew G. Knepley 
102865876a83SMatthew G. Knepley // Time derivative of trace strain
102965876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
103065876a83SMatthew G. Knepley {
103165876a83SMatthew G. Knepley 
103265876a83SMatthew G. Knepley   Parameter  *param;
103365876a83SMatthew G. Knepley   PetscErrorCode ierr;
103465876a83SMatthew G. Knepley 
103565876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
103665876a83SMatthew G. Knepley 
103765876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
103865876a83SMatthew G. Knepley 
103965876a83SMatthew G. Knepley   PetscInt NITER = user->niter;
104065876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
104165876a83SMatthew G. Knepley   PetscScalar K_u = param->K_u;
104265876a83SMatthew G. Knepley   PetscScalar M = param->M;
104365876a83SMatthew G. Knepley   PetscScalar G = param->mu;
104465876a83SMatthew G. Knepley   PetscScalar k = param->k;
104565876a83SMatthew G. Knepley   PetscScalar mu_f = param->mu_f;
104665876a83SMatthew G. Knepley   PetscScalar F = param->P_0;
104765876a83SMatthew G. Knepley 
104865876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
104965876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
105065876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
105165876a83SMatthew G. Knepley   PetscScalar kappa = k / mu_f;
105265876a83SMatthew G. Knepley   //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
105365876a83SMatthew G. Knepley 
105465876a83SMatthew G. Knepley   //const PetscScalar b = (YMAX - YMIN) / 2.0;
105565876a83SMatthew G. Knepley   PetscReal   a = (param->xmax - param->xmin) / 2.0;
105665876a83SMatthew 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)));
105765876a83SMatthew G. Knepley 
105865876a83SMatthew G. Knepley   // Series term
105965876a83SMatthew G. Knepley   PetscScalar eps_As = 0.0;
106065876a83SMatthew G. Knepley   PetscScalar eps_Bs = 0.0;
106165876a83SMatthew G. Knepley   PetscScalar eps_Cs = 0.0;
106265876a83SMatthew G. Knepley 
106365876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
106465876a83SMatthew G. Knepley   {
106565876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n-1];
106665876a83SMatthew G. Knepley 
106765876a83SMatthew 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)));
106865876a83SMatthew 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)));
106965876a83SMatthew 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)));
107065876a83SMatthew G. Knepley   }
107165876a83SMatthew G. Knepley 
107265876a83SMatthew G. Knepley   u[0] = (F/G)*eps_As - ( (F*nu_u)/(G*a))*eps_Bs + ( (F*(1-nu_u))/(G*a))*eps_Cs;
107365876a83SMatthew G. Knepley   return 0;
107465876a83SMatthew G. Knepley 
107565876a83SMatthew G. Knepley }
107665876a83SMatthew G. Knepley 
107765876a83SMatthew G. Knepley // Time derivative of pressure
107865876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
107965876a83SMatthew G. Knepley {
108065876a83SMatthew G. Knepley 
108165876a83SMatthew G. Knepley   Parameter  *param;
108265876a83SMatthew G. Knepley   PetscErrorCode ierr;
108365876a83SMatthew G. Knepley 
108465876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
108565876a83SMatthew G. Knepley 
108665876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
108765876a83SMatthew G. Knepley 
108865876a83SMatthew G. Knepley   PetscInt NITER = user->niter;
108965876a83SMatthew G. Knepley 
109065876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
109165876a83SMatthew G. Knepley   PetscScalar K_u = param->K_u;
109265876a83SMatthew G. Knepley   PetscScalar M = param->M;
109365876a83SMatthew G. Knepley   PetscScalar G = param->mu;
109465876a83SMatthew G. Knepley   PetscScalar k = param->k;
109565876a83SMatthew G. Knepley   PetscScalar mu_f = param->mu_f;
109665876a83SMatthew G. Knepley   PetscScalar F = param->P_0;
109765876a83SMatthew G. Knepley 
109865876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
109965876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
110065876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
110165876a83SMatthew G. Knepley   PetscScalar kappa = k / mu_f;
110265876a83SMatthew G. Knepley 
110365876a83SMatthew G. Knepley   PetscReal   a = (param->xmax - param->xmin) / 2.0;
110465876a83SMatthew 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)));
110565876a83SMatthew G. Knepley   //PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
110665876a83SMatthew G. Knepley   //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
110765876a83SMatthew G. Knepley 
110865876a83SMatthew G. Knepley   // Series term
110965876a83SMatthew G. Knepley   PetscScalar P_s = 0.0;
111065876a83SMatthew G. Knepley 
111165876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
111265876a83SMatthew G. Knepley   {
111365876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n-1];
111465876a83SMatthew G. Knepley 
111565876a83SMatthew G. Knepley     P_s += (-1.0*alpha_n*alpha_n*c*( -1.0*PetscCosReal(alpha_n) + PetscCosReal( (alpha_n*x[0])/a))*PetscExpReal( (-1.0*alpha_n*alpha_n*c*time)/(a*a))*PetscSinReal(alpha_n)) / ( a*a*(alpha_n - PetscSinReal(alpha_n)*PetscCosReal(alpha_n)));
111665876a83SMatthew G. Knepley   }
111765876a83SMatthew G. Knepley   u[0] = ( (2.0*F*(-2.0*nu + 3.0*nu_u))/(3.0*a*alpha*(1.0 - 2.0*nu)));
111865876a83SMatthew G. Knepley 
111965876a83SMatthew G. Knepley   return 0;
112065876a83SMatthew G. Knepley }
112165876a83SMatthew G. Knepley 
112265876a83SMatthew G. Knepley /* Cryer Solutions */
112365876a83SMatthew G. Knepley static PetscErrorCode cryer_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
112465876a83SMatthew G. Knepley {
112565876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
112665876a83SMatthew G. Knepley   Parameter     *param;
112765876a83SMatthew G. Knepley   PetscErrorCode ierr;
112865876a83SMatthew G. Knepley 
112965876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
113065876a83SMatthew G. Knepley   if (time <= 0.0) {
113165876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
113265876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
113365876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
113465876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
113565876a83SMatthew G. Knepley     PetscScalar B     = alpha*M / K_u; /* -, Cheng (B.12) */
113665876a83SMatthew G. Knepley 
113765876a83SMatthew G. Knepley     u[0] = P_0*B;
113865876a83SMatthew G. Knepley   } else {
113965876a83SMatthew G. Knepley     u[0] = 0.0;
114065876a83SMatthew G. Knepley   }
114165876a83SMatthew G. Knepley   return 0;
114265876a83SMatthew G. Knepley }
114365876a83SMatthew G. Knepley 
114465876a83SMatthew G. Knepley static PetscErrorCode cryer_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
114565876a83SMatthew G. Knepley {
114665876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
114765876a83SMatthew G. Knepley   Parameter     *param;
114865876a83SMatthew G. Knepley   PetscErrorCode ierr;
114965876a83SMatthew G. Knepley 
115065876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
115165876a83SMatthew G. Knepley   {
115265876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
115365876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
115465876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
115565876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
115665876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
115765876a83SMatthew G. Knepley 
115865876a83SMatthew G. Knepley     PetscScalar u_0   = -P_0*R_0*(1. - 2.*nu_u) / (2.*G*(1. + nu_u)); /* Cheng (7.407) */
115965876a83SMatthew G. Knepley     PetscReal   u_sc  = PetscRealPart(u_0)/R_0;
116065876a83SMatthew G. Knepley 
116165876a83SMatthew G. Knepley     u[0] = u_sc * x[0];
116265876a83SMatthew G. Knepley     u[1] = u_sc * x[1];
116365876a83SMatthew G. Knepley     u[2] = u_sc * x[2];
116465876a83SMatthew G. Knepley   }
116565876a83SMatthew G. Knepley   return 0;
116665876a83SMatthew G. Knepley }
116765876a83SMatthew G. Knepley 
116865876a83SMatthew G. Knepley static PetscErrorCode cryer_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
116965876a83SMatthew G. Knepley {
117065876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
117165876a83SMatthew G. Knepley   Parameter     *param;
117265876a83SMatthew G. Knepley   PetscErrorCode ierr;
117365876a83SMatthew G. Knepley 
117465876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
117565876a83SMatthew G. Knepley   {
117665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
117765876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
117865876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
117965876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
118065876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
118165876a83SMatthew G. Knepley 
118265876a83SMatthew G. Knepley     PetscScalar u_0   = -P_0*R_0*(1. - 2.*nu_u) / (2.*G*(1. + nu_u)); /* Cheng (7.407) */
118365876a83SMatthew G. Knepley     PetscReal   u_sc  = PetscRealPart(u_0)/R_0;
118465876a83SMatthew G. Knepley 
118565876a83SMatthew G. Knepley     /* div R = 1/R^2 d/dR R^2 R = 3 */
118665876a83SMatthew G. Knepley     u[0] = 3.*u_sc;
118765876a83SMatthew G. Knepley     u[1] = 3.*u_sc;
118865876a83SMatthew G. Knepley     u[2] = 3.*u_sc;
118965876a83SMatthew G. Knepley   }
119065876a83SMatthew G. Knepley   return 0;
119165876a83SMatthew G. Knepley }
119265876a83SMatthew G. Knepley 
119365876a83SMatthew G. Knepley // Displacement
119465876a83SMatthew G. Knepley static PetscErrorCode cryer_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
119565876a83SMatthew G. Knepley {
119665876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
119765876a83SMatthew G. Knepley   Parameter     *param;
119865876a83SMatthew G. Knepley   PetscErrorCode ierr;
119965876a83SMatthew G. Knepley 
120065876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
120165876a83SMatthew G. Knepley   if (time <= 0.0) {
120265876a83SMatthew G. Knepley     ierr = cryer_initial_u(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
120365876a83SMatthew G. Knepley   } else {
120465876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
120565876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
120665876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
120765876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
120865876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
120965876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
121065876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
121165876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
121265876a83SMatthew G. Knepley 
121365876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
121465876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
121565876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
121665876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
121765876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
121865876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0*R_0*(1. - 2.*nu) / (2.*G*(1. + nu));  /* m,       Cheng (7.388) */
121965876a83SMatthew G. Knepley 
122065876a83SMatthew G. Knepley     PetscReal   R      = PetscSqrtReal(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
122165876a83SMatthew G. Knepley     PetscReal   R_star = R/R_0;
122265876a83SMatthew G. Knepley     PetscReal   tstar  = PetscRealPart(c*time) / PetscSqr(R_0);    /* - */
122365876a83SMatthew G. Knepley     PetscReal   A_n    = 0.0;
122465876a83SMatthew G. Knepley     PetscScalar u_sc;
122565876a83SMatthew G. Knepley 
122665876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
122765876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n-1];
122865876a83SMatthew 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));
122965876a83SMatthew G. Knepley 
123065876a83SMatthew G. Knepley       /* m , Cheng (7.404) */
123165876a83SMatthew G. Knepley       A_n += PetscRealPart(
123265876a83SMatthew G. Knepley              (12.0*(1.0 + nu)*(nu_u - nu))/((1.0 - 2.0*nu)*E_n*PetscSqr(R_star)*x_n*PetscSinReal(PetscSqrtReal(x_n))) *
123365876a83SMatthew G. Knepley              (3.0*(nu_u - nu) * (PetscSinReal(R_star * PetscSqrtReal(x_n)) - R_star*PetscSqrtReal(x_n)*PetscCosReal(R_star * PetscSqrtReal(x_n)))
123465876a83SMatthew G. Knepley               + (1.0 - nu)*(1.0 - 2.0*nu)*PetscPowRealInt(R_star, 3)*x_n*PetscSinReal(PetscSqrtReal(x_n))) * PetscExpReal(-x_n * tstar));
123565876a83SMatthew G. Knepley     }
123665876a83SMatthew G. Knepley     u_sc = PetscRealPart(u_inf) * (R_star - A_n);
123765876a83SMatthew G. Knepley     u[0] = u_sc * x[0] / R;
123865876a83SMatthew G. Knepley     u[1] = u_sc * x[1] / R;
123965876a83SMatthew G. Knepley     u[2] = u_sc * x[2] / R;
124065876a83SMatthew G. Knepley   }
124165876a83SMatthew G. Knepley   return 0;
124265876a83SMatthew G. Knepley }
124365876a83SMatthew G. Knepley 
124465876a83SMatthew G. Knepley // Volumetric Strain
124565876a83SMatthew G. Knepley static PetscErrorCode cryer_3d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
124665876a83SMatthew G. Knepley {
124765876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
124865876a83SMatthew G. Knepley   Parameter     *param;
124965876a83SMatthew G. Knepley   PetscErrorCode ierr;
125065876a83SMatthew G. Knepley 
125165876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
125265876a83SMatthew G. Knepley   if (time <= 0.0) {
125365876a83SMatthew G. Knepley     ierr = cryer_initial_eps(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
125465876a83SMatthew G. Knepley   } else {
125565876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
125665876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
125765876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
125865876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
125965876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
126065876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
126165876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
126265876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
126365876a83SMatthew G. Knepley 
126465876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
126565876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
126665876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
126765876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
126865876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
126965876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0*R_0*(1. - 2.*nu) / (2.*G*(1. + nu));  /* m,       Cheng (7.388) */
127065876a83SMatthew G. Knepley 
127165876a83SMatthew G. Knepley     PetscReal   R      = PetscSqrtReal(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
127265876a83SMatthew G. Knepley     PetscReal   R_star = R/R_0;
127365876a83SMatthew G. Knepley     PetscReal   tstar  = PetscRealPart(c*time) / PetscSqr(R_0);    /* - */
127465876a83SMatthew G. Knepley     PetscReal   divA_n = 0.0;
127565876a83SMatthew G. Knepley 
127665876a83SMatthew G. Knepley     if (R_star < PETSC_SMALL) {
127765876a83SMatthew G. Knepley       for (n = 1; n < N+1; ++n) {
127865876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n-1];
127965876a83SMatthew 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));
128065876a83SMatthew G. Knepley 
128165876a83SMatthew G. Knepley         divA_n += PetscRealPart(
128265876a83SMatthew G. Knepley                   (12.0*(1.0 + nu)*(nu_u - nu))/((1.0 - 2.0*nu)*E_n*PetscSqr(R_star)*x_n*PetscSinReal(PetscSqrtReal(x_n))) *
128365876a83SMatthew G. Knepley                   (3.0*(nu_u - nu) * PetscSqrtReal(x_n) * ((2.0 + PetscSqr(R_star*PetscSqrtReal(x_n))) - 2.0*PetscCosReal(R_star * PetscSqrtReal(x_n)))
128465876a83SMatthew G. Knepley                   + 5.0 * (1.0 - nu)*(1.0 - 2.0*nu)*PetscPowRealInt(R_star, 2)*x_n*PetscSinReal(PetscSqrtReal(x_n))) * PetscExpReal(-x_n * tstar));
128565876a83SMatthew G. Knepley       }
128665876a83SMatthew G. Knepley     } else {
128765876a83SMatthew G. Knepley       for (n = 1; n < N+1; ++n) {
128865876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n-1];
128965876a83SMatthew 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));
129065876a83SMatthew G. Knepley 
129165876a83SMatthew G. Knepley         divA_n += PetscRealPart(
129265876a83SMatthew G. Knepley                   (12.0*(1.0 + nu)*(nu_u - nu))/((1.0 - 2.0*nu)*E_n*PetscSqr(R_star)*x_n*PetscSinReal(PetscSqrtReal(x_n))) *
129365876a83SMatthew G. Knepley                   (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)))
129465876a83SMatthew G. Knepley                   + 5.0 * (1.0 - nu)*(1.0 - 2.0*nu)*PetscPowRealInt(R_star, 2)*x_n*PetscSinReal(PetscSqrtReal(x_n))) * PetscExpReal(-x_n * tstar));
129565876a83SMatthew G. Knepley       }
129665876a83SMatthew G. Knepley     }
129765876a83SMatthew G. Knepley     if (PetscAbsReal(divA_n) > 1e3) PetscPrintf(PETSC_COMM_SELF, "(%g, %g, %g) divA_n: %g\n", x[0], x[1], x[2], divA_n);
129865876a83SMatthew G. Knepley     u[0] = PetscRealPart(u_inf)/R_0 * (3.0 - divA_n);
129965876a83SMatthew G. Knepley   }
130065876a83SMatthew G. Knepley   return 0;
130165876a83SMatthew G. Knepley }
130265876a83SMatthew G. Knepley 
130365876a83SMatthew G. Knepley // Pressure
130465876a83SMatthew G. Knepley static PetscErrorCode cryer_3d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
130565876a83SMatthew G. Knepley {
130665876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
130765876a83SMatthew G. Knepley   Parameter     *param;
130865876a83SMatthew G. Knepley   PetscErrorCode ierr;
130965876a83SMatthew G. Knepley 
131065876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
131165876a83SMatthew G. Knepley   if (time <= 0.0) {
131265876a83SMatthew G. Knepley     ierr = cryer_drainage_pressure(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
131365876a83SMatthew G. Knepley   } else {
131465876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
131565876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
131665876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
131765876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
131865876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
131965876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
132065876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
132165876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
132265876a83SMatthew G. Knepley 
132365876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
132465876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
132565876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
132665876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
132765876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
132865876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
132965876a83SMatthew G. Knepley     PetscScalar R     = PetscSqrtReal(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
133065876a83SMatthew G. Knepley 
133165876a83SMatthew G. Knepley     PetscScalar R_star = R / R_0;
133265876a83SMatthew G. Knepley     PetscScalar t_star = PetscRealPart(c * time) / PetscSqr(R_0);
133365876a83SMatthew G. Knepley     PetscReal   A_x    = 0.0;
133465876a83SMatthew G. Knepley 
133565876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
133665876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n-1];
133765876a83SMatthew 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));
133865876a83SMatthew G. Knepley 
133965876a83SMatthew 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) */
134065876a83SMatthew G. Knepley     }
134165876a83SMatthew G. Knepley     u[0] = P_0 * A_x;
134265876a83SMatthew G. Knepley   }
134365876a83SMatthew G. Knepley   return 0;
134465876a83SMatthew G. Knepley }
134565876a83SMatthew G. Knepley 
134665876a83SMatthew G. Knepley /* Boundary Kernels */
134765876a83SMatthew G. Knepley static void f0_terzaghi_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
134865876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
134965876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
135065876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
135165876a83SMatthew G. Knepley {
135265876a83SMatthew G. Knepley   const PetscReal P = PetscRealPart(constants[5]);
135365876a83SMatthew G. Knepley 
135465876a83SMatthew G. Knepley   f0[0] = 0.0;
135565876a83SMatthew G. Knepley   f0[1] = P;
135665876a83SMatthew G. Knepley }
135765876a83SMatthew G. Knepley 
1358*45480ffeSMatthew G. Knepley #if 0
135965876a83SMatthew G. Knepley static void f0_mandel_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
136065876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
136165876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
136265876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
136365876a83SMatthew G. Knepley {
136465876a83SMatthew G. Knepley   // Uniform stress distribution
136565876a83SMatthew G. Knepley   /* PetscScalar xmax =  0.5;
136665876a83SMatthew G. Knepley   PetscScalar xmin = -0.5;
136765876a83SMatthew G. Knepley   PetscScalar ymax =  0.5;
136865876a83SMatthew G. Knepley   PetscScalar ymin = -0.5;
136965876a83SMatthew G. Knepley   PetscScalar P = constants[5];
137065876a83SMatthew G. Knepley   PetscScalar aL = (xmax - xmin) / 2.0;
137165876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*P / aL; */
137265876a83SMatthew G. Knepley 
137365876a83SMatthew G. Knepley   // Analytical (parabolic) stress distribution
137465876a83SMatthew G. Knepley   PetscReal a1, a2, am;
137565876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
137665876a83SMatthew G. Knepley 
137765876a83SMatthew G. Knepley   PetscInt NITER = 500;
137865876a83SMatthew G. Knepley   PetscReal EPS = 0.000001;
137965876a83SMatthew G. Knepley   PetscReal zeroArray[500]; /* NITER */
138065876a83SMatthew G. Knepley   PetscReal xmax =  1.0;
138165876a83SMatthew G. Knepley   PetscReal xmin =  0.0;
138265876a83SMatthew G. Knepley   PetscReal ymax =  0.1;
138365876a83SMatthew G. Knepley   PetscReal ymin =  0.0;
138465876a83SMatthew G. Knepley   PetscReal lower[2], upper[2];
138565876a83SMatthew G. Knepley 
138665876a83SMatthew G. Knepley   lower[0] = xmin - (xmax - xmin) / 2.0;
138765876a83SMatthew G. Knepley   lower[1] = ymin - (ymax - ymin) / 2.0;
138865876a83SMatthew G. Knepley   upper[0] = xmax - (xmax - xmin) / 2.0;
138965876a83SMatthew G. Knepley   upper[1] = ymax - (ymax - ymin) / 2.0;
139065876a83SMatthew G. Knepley 
139165876a83SMatthew G. Knepley   xmin = lower[0];
139265876a83SMatthew G. Knepley   ymin = lower[1];
139365876a83SMatthew G. Knepley   xmax = upper[0];
139465876a83SMatthew G. Knepley   ymax = upper[1];
139565876a83SMatthew G. Knepley 
139665876a83SMatthew G. Knepley   PetscScalar G     = constants[0];
139765876a83SMatthew G. Knepley   PetscScalar K_u   = constants[1];
139865876a83SMatthew G. Knepley   PetscScalar alpha = constants[2];
139965876a83SMatthew G. Knepley   PetscScalar M     = constants[3];
140065876a83SMatthew G. Knepley   PetscScalar kappa = constants[4];
140165876a83SMatthew G. Knepley   PetscScalar F     = constants[5];
140265876a83SMatthew G. Knepley 
140365876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
140465876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
140565876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
140665876a83SMatthew G. Knepley   PetscReal   aL = (xmax - xmin) / 2.0;
140765876a83SMatthew 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)));
140865876a83SMatthew G. Knepley   PetscScalar B = (3.0 * (nu_u - nu)) / ( alpha * (1.0 - 2.0*nu) * (1.0 + nu_u));
140965876a83SMatthew G. Knepley   PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
141065876a83SMatthew G. Knepley   PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
141165876a83SMatthew G. Knepley 
141265876a83SMatthew G. Knepley   // Generate zero values
141365876a83SMatthew G. Knepley   for (PetscInt i=1; i < NITER+1; i++)
141465876a83SMatthew G. Knepley   {
141565876a83SMatthew G. Knepley     a1 = ((PetscReal) i - 1.0) * PETSC_PI * PETSC_PI / 4.0 + EPS;
141665876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI/2;
141765876a83SMatthew G. Knepley     for (PetscInt j=0; j<NITER; j++)
141865876a83SMatthew G. Knepley     {
141965876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart(A1/A2)*a1;
142065876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart(A1/A2)*a2;
142165876a83SMatthew G. Knepley       am = (a1 + a2)/2.0;
142265876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart(A1/A2)*am;
142365876a83SMatthew G. Knepley       if ((ym*y1) > 0)
142465876a83SMatthew G. Knepley       {
142565876a83SMatthew G. Knepley         a1 = am;
142665876a83SMatthew G. Knepley       } else {
142765876a83SMatthew G. Knepley         a2 = am;
142865876a83SMatthew G. Knepley       }
142965876a83SMatthew G. Knepley       if (PetscAbsReal(y2) < EPS)
143065876a83SMatthew G. Knepley       {
143165876a83SMatthew G. Knepley         am = a2;
143265876a83SMatthew G. Knepley       }
143365876a83SMatthew G. Knepley     }
143465876a83SMatthew G. Knepley     zeroArray[i-1] = am;
143565876a83SMatthew G. Knepley   }
143665876a83SMatthew G. Knepley 
143765876a83SMatthew G. Knepley   // Solution for sigma_zz
143865876a83SMatthew G. Knepley   PetscScalar A_x = 0.0;
143965876a83SMatthew G. Knepley   PetscScalar B_x = 0.0;
144065876a83SMatthew G. Knepley 
144165876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
144265876a83SMatthew G. Knepley   {
144365876a83SMatthew G. Knepley     PetscReal alpha_n = zeroArray[n-1];
144465876a83SMatthew G. Knepley 
144565876a83SMatthew 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)));
144665876a83SMatthew 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)));
144765876a83SMatthew G. Knepley   }
144865876a83SMatthew G. Knepley 
144965876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*(F/aL) - ((2.0*F)/aL) * (A2/A1) * A_x + ((2.0*F)/aL) * B_x;
145065876a83SMatthew G. Knepley 
145165876a83SMatthew G. Knepley 
145265876a83SMatthew G. Knepley   if (x[1] == ymax) {
145365876a83SMatthew G. Knepley     f0[1] += sigma_zz;
145465876a83SMatthew G. Knepley   } else if (x[1] == ymin) {
145565876a83SMatthew G. Knepley     f0[1] -= sigma_zz;
145665876a83SMatthew G. Knepley   }
145765876a83SMatthew G. Knepley }
1458*45480ffeSMatthew G. Knepley #endif
145965876a83SMatthew G. Knepley 
146065876a83SMatthew G. Knepley static void f0_cryer_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
146165876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
146265876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
146365876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
146465876a83SMatthew G. Knepley {
146565876a83SMatthew G. Knepley   const PetscReal P_0 = PetscRealPart(constants[5]);
14660fdc7489SMatthew Knepley   //const PetscReal R   = PetscSqrtReal(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
146765876a83SMatthew G. Knepley   PetscInt        d;
146865876a83SMatthew G. Knepley 
146965876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) f0[d] = -P_0*n[d];
147065876a83SMatthew G. Knepley   //PetscPrintf(PETSC_COMM_SELF, "R: %g P_0: %g n: (%g, %g, %g) hat n (%g, %g, %g)\n", R, P_0, n[0], n[1], n[2], x[0]/R, x[1]/R, x[2]/R);
14710fdc7489SMatthew Knepley   //for (d = 0; d < dim; ++d) if (PetscAbsReal(n[d] - x[d]/R) > 1.0) PetscPrintf(PETSC_COMM_SELF, "WTF? R: %g P_0: %g n: (%g, %g, %g) hat n (%g, %g, %g)\n", R, P_0, n[0], n[1], n[2], x[0]/R, x[1]/R, x[2]/R);
147265876a83SMatthew G. Knepley   //for (d = 0; d < dim; ++d) f0[d] = -P_0*x[d]/R;
147365876a83SMatthew G. Knepley }
147465876a83SMatthew G. Knepley 
147565876a83SMatthew G. Knepley /* Standard Kernels - Residual */
147665876a83SMatthew G. Knepley /* f0_e */
147765876a83SMatthew G. Knepley static void f0_epsilon(PetscInt dim, PetscInt Nf, PetscInt NfAux,
147865876a83SMatthew G. Knepley                        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
147965876a83SMatthew G. Knepley                        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
148065876a83SMatthew G. Knepley                        PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
148165876a83SMatthew G. Knepley {
148265876a83SMatthew G. Knepley   PetscInt d;
148365876a83SMatthew G. Knepley 
148465876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
148565876a83SMatthew G. Knepley     f0[0] += u_x[d*dim+d];
148665876a83SMatthew G. Knepley   }
148765876a83SMatthew G. Knepley   f0[0] -= u[uOff[1]];
148865876a83SMatthew G. Knepley }
148965876a83SMatthew G. Knepley 
149065876a83SMatthew G. Knepley /* f0_p */
149165876a83SMatthew G. Knepley static void f0_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
149265876a83SMatthew G. Knepley                  const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
149365876a83SMatthew G. Knepley                  const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
149465876a83SMatthew G. Knepley                  PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
149565876a83SMatthew G. Knepley {
149665876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
149765876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
149865876a83SMatthew G. Knepley 
149965876a83SMatthew G. Knepley   f0[0] += alpha*u_t[uOff[1]];
150065876a83SMatthew G. Knepley   f0[0] += u_t[uOff[2]]/M;
150165876a83SMatthew G. Knepley }
150265876a83SMatthew G. Knepley 
150365876a83SMatthew G. Knepley /* f1_u */
150465876a83SMatthew G. Knepley static void f1_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
150565876a83SMatthew G. Knepley                  const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
150665876a83SMatthew G. Knepley                  const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
150765876a83SMatthew G. Knepley                  PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])
150865876a83SMatthew G. Knepley {
150965876a83SMatthew G. Knepley   const PetscInt  Nc     = dim;
151065876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
151165876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
151265876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
151365876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
151465876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
151565876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
151665876a83SMatthew G. Knepley   PetscInt        c, d;
151765876a83SMatthew G. Knepley 
151865876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c)
151965876a83SMatthew G. Knepley   {
152065876a83SMatthew G. Knepley     for (d = 0; d < dim; ++d)
152165876a83SMatthew G. Knepley     {
152265876a83SMatthew G. Knepley       f1[c*dim+d] -= G*(u_x[c*dim+d] + u_x[d*dim+c]);
152365876a83SMatthew G. Knepley     }
152465876a83SMatthew G. Knepley     f1[c*dim+c] -= lambda*u[uOff[1]];
152565876a83SMatthew G. Knepley     f1[c*dim+c] += alpha*u[uOff[2]];
152665876a83SMatthew G. Knepley   }
152765876a83SMatthew G. Knepley }
152865876a83SMatthew G. Knepley 
152965876a83SMatthew G. Knepley /* f1_p */
153065876a83SMatthew G. Knepley static void f1_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
153165876a83SMatthew G. Knepley                  const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
153265876a83SMatthew G. Knepley                  const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
153365876a83SMatthew G. Knepley                  PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])
153465876a83SMatthew G. Knepley {
153565876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
153665876a83SMatthew G. Knepley   PetscInt        d;
153765876a83SMatthew G. Knepley 
153865876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
153965876a83SMatthew G. Knepley     f1[d] += kappa*u_x[uOff_x[2]+d];
154065876a83SMatthew G. Knepley   }
154165876a83SMatthew G. Knepley }
154265876a83SMatthew G. Knepley 
154365876a83SMatthew G. Knepley /*
154465876a83SMatthew G. Knepley   \partial_df \phi_fc g_{fc,gc,df,dg} \partial_dg \phi_gc
154565876a83SMatthew G. Knepley 
154665876a83SMatthew G. Knepley   \partial_df \phi_fc \lambda \delta_{fc,df} \sum_gc \partial_dg \phi_gc \delta_{gc,dg}
154765876a83SMatthew G. Knepley   = \partial_fc \phi_fc \sum_gc \partial_gc \phi_gc
154865876a83SMatthew G. Knepley */
154965876a83SMatthew G. Knepley 
155065876a83SMatthew G. Knepley 
155165876a83SMatthew G. Knepley /* Standard Kernels - Jacobian */
155265876a83SMatthew G. Knepley /* g0_ee */
155365876a83SMatthew G. Knepley static void g0_ee(PetscInt dim, PetscInt Nf, PetscInt NfAux,
155465876a83SMatthew G. Knepley            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
155565876a83SMatthew G. Knepley            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
155665876a83SMatthew G. Knepley            PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
155765876a83SMatthew G. Knepley {
155865876a83SMatthew G. Knepley   g0[0] = -1.0;
155965876a83SMatthew G. Knepley }
156065876a83SMatthew G. Knepley 
156165876a83SMatthew G. Knepley /* g0_pe */
156265876a83SMatthew G. Knepley static void g0_pe(PetscInt dim, PetscInt Nf, PetscInt NfAux,
156365876a83SMatthew G. Knepley            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
156465876a83SMatthew G. Knepley            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
156565876a83SMatthew G. Knepley            PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
156665876a83SMatthew G. Knepley {
156765876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
156865876a83SMatthew G. Knepley 
156965876a83SMatthew G. Knepley   g0[0] = u_tShift*alpha;
157065876a83SMatthew G. Knepley }
157165876a83SMatthew G. Knepley 
157265876a83SMatthew G. Knepley /* g0_pp */
157365876a83SMatthew G. Knepley static void g0_pp(PetscInt dim, PetscInt Nf, PetscInt NfAux,
157465876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
157565876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
157665876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
157765876a83SMatthew G. Knepley {
157865876a83SMatthew G. Knepley   const PetscReal M = PetscRealPart(constants[3]);
157965876a83SMatthew G. Knepley 
158065876a83SMatthew G. Knepley   g0[0] = u_tShift/M;
158165876a83SMatthew G. Knepley }
158265876a83SMatthew G. Knepley 
158365876a83SMatthew G. Knepley /* g1_eu */
158465876a83SMatthew G. Knepley static void g1_eu(PetscInt dim, PetscInt Nf, PetscInt NfAux,
158565876a83SMatthew G. Knepley            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
158665876a83SMatthew G. Knepley            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
158765876a83SMatthew G. Knepley            PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[])
158865876a83SMatthew G. Knepley {
158965876a83SMatthew G. Knepley   PetscInt d;
159065876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g1[d*dim+d] = 1.0; /* \frac{\partial\phi^{u_d}}{\partial x_d} */
159165876a83SMatthew G. Knepley }
159265876a83SMatthew G. Knepley 
159365876a83SMatthew G. Knepley /* g2_ue */
159465876a83SMatthew G. Knepley static void g2_ue(PetscInt dim, PetscInt Nf, PetscInt NfAux,
159565876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
159665876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
159765876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[])
159865876a83SMatthew G. Knepley {
159965876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
160065876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
160165876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
160265876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
160365876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
160465876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
160565876a83SMatthew G. Knepley   PetscInt        d;
160665876a83SMatthew G. Knepley 
160765876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
160865876a83SMatthew G. Knepley     g2[d*dim + d] -= lambda;
160965876a83SMatthew G. Knepley   }
161065876a83SMatthew G. Knepley }
161165876a83SMatthew G. Knepley /* g2_up */
161265876a83SMatthew G. Knepley static void g2_up(PetscInt dim, PetscInt Nf, PetscInt NfAux,
161365876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
161465876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
161565876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[])
161665876a83SMatthew G. Knepley {
161765876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
161865876a83SMatthew G. Knepley   PetscInt        d;
161965876a83SMatthew G. Knepley 
162065876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
162165876a83SMatthew G. Knepley     g2[d*dim + d] += alpha;
162265876a83SMatthew G. Knepley   }
162365876a83SMatthew G. Knepley }
162465876a83SMatthew G. Knepley 
162565876a83SMatthew G. Knepley /* g3_uu */
162665876a83SMatthew G. Knepley static void g3_uu(PetscInt dim, PetscInt Nf, PetscInt NfAux,
162765876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
162865876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
162965876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])
163065876a83SMatthew G. Knepley {
163165876a83SMatthew G. Knepley   const PetscInt  Nc = dim;
163265876a83SMatthew G. Knepley   const PetscReal G  = PetscRealPart(constants[0]);
163365876a83SMatthew G. Knepley   PetscInt        c, d;
163465876a83SMatthew G. Knepley 
163565876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) {
163665876a83SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
163765876a83SMatthew G. Knepley       g3[((c*Nc + c)*dim + d)*dim + d] -= G;
163865876a83SMatthew G. Knepley       g3[((c*Nc + d)*dim + d)*dim + c] -= G;
163965876a83SMatthew G. Knepley     }
164065876a83SMatthew G. Knepley   }
164165876a83SMatthew G. Knepley }
164265876a83SMatthew G. Knepley 
164365876a83SMatthew G. Knepley /* g3_pp */
164465876a83SMatthew G. Knepley static void g3_pp(PetscInt dim, PetscInt Nf, PetscInt NfAux,
164565876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
164665876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
164765876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])
164865876a83SMatthew G. Knepley {
164965876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
165065876a83SMatthew G. Knepley   PetscInt        d;
165165876a83SMatthew G. Knepley 
165265876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g3[d*dim+d] += kappa;
165365876a83SMatthew G. Knepley }
165465876a83SMatthew G. Knepley 
165565876a83SMatthew G. Knepley static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
165665876a83SMatthew G. Knepley {
165765876a83SMatthew G. Knepley   PetscInt sol;
165865876a83SMatthew G. Knepley   PetscErrorCode ierr;
165965876a83SMatthew G. Knepley 
166065876a83SMatthew G. Knepley   PetscFunctionBeginUser;
166165876a83SMatthew G. Knepley   options->dim       = 2;
166265876a83SMatthew G. Knepley   options->simplex   = PETSC_TRUE;
166365876a83SMatthew G. Knepley   options->refLimit  = -1.0;
166465876a83SMatthew G. Knepley   options->solType   = SOL_QUADRATIC_TRIG;
166565876a83SMatthew G. Knepley   options->niter     = 500;
166665876a83SMatthew G. Knepley   options->eps       = PETSC_SMALL;
166724b15d09SMatthew G. Knepley   options->dtInitial = -1.0;
166865876a83SMatthew G. Knepley   ierr = PetscStrncpy(options->dmType, DMPLEX, 256);CHKERRQ(ierr);
166965876a83SMatthew G. Knepley 
167065876a83SMatthew G. Knepley   ierr = PetscOptionsBegin(comm, "", "Biot Poroelasticity Options", "DMPLEX");CHKERRQ(ierr);
167165876a83SMatthew G. Knepley   ierr = PetscOptionsInt("-dim", "The topological mesh dimension", "ex53.c", options->dim, &options->dim, NULL);CHKERRQ(ierr);
167265876a83SMatthew G. Knepley   ierr = PetscOptionsInt("-niter", "Number of series term iterations in exact solutions", "ex53.c", options->niter, &options->niter, NULL);CHKERRQ(ierr);
167365876a83SMatthew G. Knepley   ierr = PetscOptionsBool("-simplex", "Simplicial (true) or tensor (false) mesh", "ex53.c", options->simplex, &options->simplex, NULL);CHKERRQ(ierr);
167465876a83SMatthew G. Knepley   ierr = PetscOptionsReal("-ref_limit", "Maximum cell volume for refined mesh", "ex53.c", options->refLimit, &options->refLimit, NULL);CHKERRQ(ierr);
167565876a83SMatthew G. Knepley   sol  = options->solType;
167665876a83SMatthew G. Knepley   ierr = PetscOptionsEList("-sol_type", "Type of exact solution", "ex53.c", solutionTypes, NUM_SOLUTION_TYPES, solutionTypes[options->solType], &sol, NULL);CHKERRQ(ierr);
167765876a83SMatthew G. Knepley   options->solType = (SolutionType) sol;
167865876a83SMatthew G. Knepley   ierr = PetscOptionsFList("-dm_type", "Convert DMPlex to another format", "ex53.c", DMList, options->dmType, options->dmType, 256, NULL);CHKERRQ(ierr);
167965876a83SMatthew G. Knepley   ierr = PetscOptionsReal("-eps", "Precision value for root finding", "ex53.c", options->eps, &options->eps, NULL);CHKERRQ(ierr);
168024b15d09SMatthew G. Knepley   ierr = PetscOptionsReal("-dt_initial", "Override the initial timestep", "ex53.c", options->dtInitial, &options->dtInitial, NULL);CHKERRQ(ierr);
168165876a83SMatthew G. Knepley 
168265876a83SMatthew G. Knepley   // Wrap up loose ends
168365876a83SMatthew G. Knepley   if (options->solType == SOL_CRYER) {
168465876a83SMatthew G. Knepley     options->dim = 3;
168565876a83SMatthew G. Knepley   }
168665876a83SMatthew G. Knepley 
168765876a83SMatthew G. Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
168865876a83SMatthew G. Knepley   PetscFunctionReturn(0);
168965876a83SMatthew G. Knepley }
169065876a83SMatthew G. Knepley 
169165876a83SMatthew G. Knepley static PetscErrorCode mandelZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param)
169265876a83SMatthew G. Knepley {
169365876a83SMatthew G. Knepley   //PetscBag       bag;
169465876a83SMatthew G. Knepley   PetscReal a1, a2, am;
169565876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
169665876a83SMatthew G. Knepley 
169765876a83SMatthew G. Knepley   PetscFunctionBeginUser;
169865876a83SMatthew G. Knepley   //ierr = PetscBagGetData(ctx->bag, (void **) &param);CHKERRQ(ierr);
169965876a83SMatthew G. Knepley   PetscInt NITER = ctx->niter;
170065876a83SMatthew G. Knepley   PetscReal EPS = ctx->eps;
170165876a83SMatthew G. Knepley   //const PetscScalar YMAX = param->ymax;
170265876a83SMatthew G. Knepley   //const PetscScalar YMIN = param->ymin;
170365876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
170465876a83SMatthew G. Knepley   PetscScalar K_u = param->K_u;
170565876a83SMatthew G. Knepley   PetscScalar M = param->M;
170665876a83SMatthew G. Knepley   PetscScalar G = param->mu;
170765876a83SMatthew G. Knepley   //const PetscScalar k = param->k;
170865876a83SMatthew G. Knepley   //const PetscScalar mu_f = param->mu_f;
170965876a83SMatthew G. Knepley   //const PetscScalar P_0 = param->P_0;
171065876a83SMatthew G. Knepley 
171165876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
171265876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));
171365876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));
171465876a83SMatthew G. Knepley   //const PetscScalar kappa = k / mu_f;
171565876a83SMatthew G. Knepley 
171665876a83SMatthew G. Knepley   // Generate zero values
171765876a83SMatthew G. Knepley   for (PetscInt i=1; i < NITER+1; i++)
171865876a83SMatthew G. Knepley   {
171965876a83SMatthew G. Knepley     a1 = ((PetscReal) i - 1.0) * PETSC_PI * PETSC_PI / 4.0 + EPS;
172065876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI/2;
172165876a83SMatthew G. Knepley     am = a1;
172265876a83SMatthew G. Knepley     for (PetscInt j=0; j<NITER; j++)
172365876a83SMatthew G. Knepley     {
172465876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart((1.0 - nu)/(nu_u - nu))*a1;
172565876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart((1.0 - nu)/(nu_u - nu))*a2;
172665876a83SMatthew G. Knepley       am = (a1 + a2)/2.0;
172765876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart((1.0 - nu)/(nu_u - nu))*am;
172865876a83SMatthew G. Knepley       if ((ym*y1) > 0)
172965876a83SMatthew G. Knepley       {
173065876a83SMatthew G. Knepley         a1 = am;
173165876a83SMatthew G. Knepley       } else {
173265876a83SMatthew G. Knepley         a2 = am;
173365876a83SMatthew G. Knepley       }
173465876a83SMatthew G. Knepley       if (PetscAbsReal(y2) < EPS)
173565876a83SMatthew G. Knepley       {
173665876a83SMatthew G. Knepley         am = a2;
173765876a83SMatthew G. Knepley       }
173865876a83SMatthew G. Knepley     }
173965876a83SMatthew G. Knepley     ctx->zeroArray[i-1] = am;
174065876a83SMatthew G. Knepley   }
174165876a83SMatthew G. Knepley   PetscFunctionReturn(0);
174265876a83SMatthew G. Knepley }
174365876a83SMatthew G. Knepley 
174465876a83SMatthew G. Knepley static PetscReal CryerFunction(PetscReal nu_u, PetscReal nu, PetscReal x)
174565876a83SMatthew G. Knepley {
174665876a83SMatthew 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));
174765876a83SMatthew G. Knepley }
174865876a83SMatthew G. Knepley 
174965876a83SMatthew G. Knepley static PetscErrorCode cryerZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param)
175065876a83SMatthew G. Knepley {
175165876a83SMatthew G. Knepley   PetscReal   alpha = PetscRealPart(param->alpha); /* -  */
175265876a83SMatthew G. Knepley   PetscReal   K_u   = PetscRealPart(param->K_u);   /* Pa */
175365876a83SMatthew G. Knepley   PetscReal   M     = PetscRealPart(param->M);     /* Pa */
175465876a83SMatthew G. Knepley   PetscReal   G     = PetscRealPart(param->mu);    /* Pa */
175565876a83SMatthew G. Knepley   PetscInt    N     = ctx->niter, n;
175665876a83SMatthew G. Knepley 
175765876a83SMatthew G. Knepley   PetscReal   K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
175865876a83SMatthew G. Knepley   PetscReal   nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
175965876a83SMatthew G. Knepley   PetscReal   nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
176065876a83SMatthew G. Knepley 
176165876a83SMatthew G. Knepley   PetscFunctionBeginUser;
176265876a83SMatthew G. Knepley   for (n = 1; n < N+1; ++n) {
176365876a83SMatthew G. Knepley     PetscReal tol = PetscPowReal(n, 1.5)*ctx->eps;
176465876a83SMatthew G. Knepley     PetscReal a1 = 0., a2 = 0., am = 0.;
176565876a83SMatthew G. Knepley     PetscReal y1, y2, ym;
176665876a83SMatthew G. Knepley     PetscInt  j, k = n-1;
176765876a83SMatthew G. Knepley 
176865876a83SMatthew G. Knepley     y1 = y2 = 1.;
176965876a83SMatthew G. Knepley     while (y1*y2 > 0) {
177065876a83SMatthew G. Knepley       ++k;
177165876a83SMatthew G. Knepley       a1 = PetscSqr(n*PETSC_PI) - k*PETSC_PI;
177265876a83SMatthew G. Knepley       a2 = PetscSqr(n*PETSC_PI) + k*PETSC_PI;
177365876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
177465876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
177565876a83SMatthew G. Knepley     }
177665876a83SMatthew G. Knepley     for (j = 0; j < 50000; ++j) {
177765876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
177865876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
177965876a83SMatthew G. Knepley       if (y1*y2 > 0) SETERRQ5(comm, PETSC_ERR_PLIB, "Invalid root finding initialization for root %D, (%g, %g)--(%g, %g)", n, a1, y1, a2, y2);
178065876a83SMatthew G. Knepley       am = (a1 + a2) / 2.0;
178165876a83SMatthew G. Knepley       ym = CryerFunction(nu_u, nu, am);
178265876a83SMatthew G. Knepley       if ((ym * y1) < 0) a2 = am;
178365876a83SMatthew G. Knepley       else               a1 = am;
178465876a83SMatthew G. Knepley       if (PetscAbsScalar(ym) < tol) break;
178565876a83SMatthew G. Knepley     }
178665876a83SMatthew G. Knepley     if (PetscAbsScalar(ym) >= tol) SETERRQ2(comm, PETSC_ERR_PLIB, "Root finding did not converge for root %D (%g)", n, PetscAbsScalar(ym));
178765876a83SMatthew G. Knepley     ctx->zeroArray[n-1] = am;
178865876a83SMatthew G. Knepley   }
178965876a83SMatthew G. Knepley   PetscFunctionReturn(0);
179065876a83SMatthew G. Knepley }
179165876a83SMatthew G. Knepley 
179265876a83SMatthew G. Knepley static PetscErrorCode SetupParameters(MPI_Comm comm, AppCtx *ctx)
179365876a83SMatthew G. Knepley {
179465876a83SMatthew G. Knepley   PetscBag       bag;
179565876a83SMatthew G. Knepley   Parameter     *p;
179665876a83SMatthew G. Knepley   PetscErrorCode ierr;
179765876a83SMatthew G. Knepley 
179865876a83SMatthew G. Knepley   PetscFunctionBeginUser;
179965876a83SMatthew G. Knepley   /* setup PETSc parameter bag */
180065876a83SMatthew G. Knepley   ierr = PetscBagGetData(ctx->bag,(void**)&p);CHKERRQ(ierr);
180165876a83SMatthew G. Knepley   ierr = PetscBagSetName(ctx->bag,"par","Poroelastic Parameters");CHKERRQ(ierr);
180265876a83SMatthew G. Knepley   bag  = ctx->bag;
180365876a83SMatthew G. Knepley   if (ctx->solType == SOL_TERZAGHI) {
180465876a83SMatthew G. Knepley     // Realistic values - Terzaghi
180565876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu,     3.0,                 "mu",    "Shear Modulus, Pa");CHKERRQ(ierr);
180665876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->K_u,    9.76,                "K_u",   "Undrained Bulk Modulus, Pa");CHKERRQ(ierr);
180765876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->alpha,  0.6,                 "alpha", "Biot Effective Stress Coefficient, -");CHKERRQ(ierr);
180865876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->M,      16.0,                "M",     "Biot Modulus, Pa");CHKERRQ(ierr);
180965876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->k,      1.5,                 "k",     "Isotropic Permeability, m**2");CHKERRQ(ierr);
181065876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu_f,   1.0,                 "mu_f",  "Fluid Dynamic Viscosity, Pa*s");CHKERRQ(ierr);
181165876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmax,   1.0,                 "zmax",  "Depth Maximum Extent, m");CHKERRQ(ierr);
181265876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmin,   0.0,                 "zmin",  "Depth Minimum Extent, m");CHKERRQ(ierr);
181365876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymax,   10.0,                "ymax",  "Vertical Maximum Extent, m");CHKERRQ(ierr);
181465876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymin,   0.0,                 "ymin",  "Vertical Minimum Extent, m");CHKERRQ(ierr);
181565876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmax,   10.0,                "xmax",  "Horizontal Maximum Extent, m");CHKERRQ(ierr);
181665876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmin,   0.0,                 "xmin",  "Horizontal Minimum Extent, m");CHKERRQ(ierr);
181765876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->P_0,    1.0,                 "P_0",   "Magnitude of Vertical Stress, Pa");CHKERRQ(ierr);
181865876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_MANDEL) {
181965876a83SMatthew G. Knepley     // Realistic values - Mandel
182065876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu,     0.75,                "mu",    "Shear Modulus, Pa");CHKERRQ(ierr);
182165876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->K_u,    2.6941176470588233,  "K_u",   "Undrained Bulk Modulus, Pa");CHKERRQ(ierr);
182265876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->alpha,  0.6,                 "alpha", "Biot Effective Stress Coefficient, -");CHKERRQ(ierr);
182365876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->M,      4.705882352941176,   "M",     "Biot Modulus, Pa");CHKERRQ(ierr);
182465876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->k,      1.5,                 "k",     "Isotropic Permeability, m**2");CHKERRQ(ierr);
182565876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu_f,   1.0,                 "mu_f",  "Fluid Dynamic Viscosity, Pa*s");CHKERRQ(ierr);
182665876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmax,   1.0,                 "zmax",  "Depth Maximum Extent, m");CHKERRQ(ierr);
182765876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmin,   0.0,                 "zmin",  "Depth Minimum Extent, m");CHKERRQ(ierr);
182865876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymax,   0.25,                "ymax",  "Vertical Maximum Extent, m");CHKERRQ(ierr);
182965876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymin,   0.0,                 "ymin",  "Vertical Minimum Extent, m");CHKERRQ(ierr);
183065876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmax,   1.0,                 "xmax",  "Horizontal Maximum Extent, m");CHKERRQ(ierr);
183165876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmin,   0.0,                 "xmin",  "Horizontal Minimum Extent, m");CHKERRQ(ierr);
183265876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->P_0,    1.0,                 "P_0",   "Magnitude of Vertical Stress, Pa");CHKERRQ(ierr);
183365876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_CRYER) {
183465876a83SMatthew G. Knepley     // Realistic values - Mandel
183565876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu,     0.75,                "mu",    "Shear Modulus, Pa");CHKERRQ(ierr);
183665876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->K_u,    2.6941176470588233,  "K_u",   "Undrained Bulk Modulus, Pa");CHKERRQ(ierr);
183765876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->alpha,  0.6,                 "alpha", "Biot Effective Stress Coefficient, -");CHKERRQ(ierr);
183865876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->M,      4.705882352941176,   "M",     "Biot Modulus, Pa");CHKERRQ(ierr);
183965876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->k,      1.5,                 "k",     "Isotropic Permeability, m**2");CHKERRQ(ierr);
184065876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu_f,   1.0,                 "mu_f",  "Fluid Dynamic Viscosity, Pa*s");CHKERRQ(ierr);
184165876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmax,   1.0,                 "zmax",  "Depth Maximum Extent, m");CHKERRQ(ierr);
184265876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmin,   0.0,                 "zmin",  "Depth Minimum Extent, m");CHKERRQ(ierr);
184365876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymax,   1.0,                 "ymax",  "Vertical Maximum Extent, m");CHKERRQ(ierr);
184465876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymin,   0.0,                 "ymin",  "Vertical Minimum Extent, m");CHKERRQ(ierr);
184565876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmax,   1.0,                 "xmax",  "Horizontal Maximum Extent, m");CHKERRQ(ierr);
184665876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmin,   0.0,                 "xmin",  "Horizontal Minimum Extent, m");CHKERRQ(ierr);
184765876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->P_0,    1.0,                 "P_0",   "Magnitude of Vertical Stress, Pa");CHKERRQ(ierr);
184865876a83SMatthew G. Knepley   } else {
184965876a83SMatthew G. Knepley     // Nonsense values
185065876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu,     1.0,                 "mu",    "Shear Modulus, Pa");CHKERRQ(ierr);
185165876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->K_u,    1.0,                 "K_u",   "Undrained Bulk Modulus, Pa");CHKERRQ(ierr);
185265876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->alpha,  1.0,                 "alpha", "Biot Effective Stress Coefficient, -");CHKERRQ(ierr);
185365876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->M,      1.0,                 "M",     "Biot Modulus, Pa");CHKERRQ(ierr);
185465876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->k,      1.0,                 "k",     "Isotropic Permeability, m**2");CHKERRQ(ierr);
185565876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu_f,   1.0,                 "mu_f",  "Fluid Dynamic Viscosity, Pa*s");CHKERRQ(ierr);
185665876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmax,   1.0,                 "zmax",  "Depth Maximum Extent, m");CHKERRQ(ierr);
185765876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmin,   0.0,                 "zmin",  "Depth Minimum Extent, m");CHKERRQ(ierr);
185865876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymax,   1.0,                 "ymax",  "Vertical Maximum Extent, m");CHKERRQ(ierr);
185965876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymin,   0.0,                 "ymin",  "Vertical Minimum Extent, m");CHKERRQ(ierr);
186065876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmax,   1.0,                 "xmax",  "Horizontal Maximum Extent, m");CHKERRQ(ierr);
186165876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmin,   0.0,                 "xmin",  "Horizontal Minimum Extent, m");CHKERRQ(ierr);
186265876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->P_0,    1.0,                 "P_0",   "Magnitude of Vertical Stress, Pa");CHKERRQ(ierr);
186365876a83SMatthew G. Knepley   }
186465876a83SMatthew G. Knepley   ierr = PetscBagSetFromOptions(bag);CHKERRQ(ierr);
186565876a83SMatthew G. Knepley   {
186665876a83SMatthew G. Knepley     PetscScalar K_d  = p->K_u - p->alpha*p->alpha*p->M;
186765876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0*p->K_u - 2.0*p->mu) / (2.0*(3.0*p->K_u + p->mu));
186865876a83SMatthew G. Knepley     PetscScalar nu   = (3.0*K_d - 2.0*p->mu) / (2.0*(3.0*K_d + p->mu));
186965876a83SMatthew G. Knepley     PetscScalar S    = (3.0*p->K_u + 4.0*p->mu) / (p->M*(3.0*K_d + 4.0*p->mu));
187065876a83SMatthew G. Knepley     PetscReal   c    = PetscRealPart((p->k/p->mu_f) / S);
187165876a83SMatthew G. Knepley 
187265876a83SMatthew G. Knepley     PetscViewer       viewer;
187365876a83SMatthew G. Knepley     PetscViewerFormat format;
187465876a83SMatthew G. Knepley     PetscBool         flg;
187565876a83SMatthew G. Knepley 
187665876a83SMatthew G. Knepley     switch (ctx->solType) {
187765876a83SMatthew G. Knepley       case SOL_QUADRATIC_LINEAR:
187865876a83SMatthew G. Knepley       case SOL_QUADRATIC_TRIG:
187965876a83SMatthew G. Knepley       case SOL_TRIG_LINEAR: ctx->t_r = PetscSqr(p->xmax - p->xmin)/c; break;
188065876a83SMatthew G. Knepley       case SOL_TERZAGHI:    ctx->t_r = PetscSqr(2.0*(p->ymax - p->ymin))/c; break;
188165876a83SMatthew G. Knepley       case SOL_MANDEL:      ctx->t_r = PetscSqr(2.0*(p->ymax - p->ymin))/c; break;
188265876a83SMatthew G. Knepley       case SOL_CRYER:       ctx->t_r = PetscSqr(p->ymax)/c; break;
188365876a83SMatthew G. Knepley       default: SETERRQ2(comm, PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%D)", solutionTypes[PetscMin(ctx->solType, NUM_SOLUTION_TYPES)], ctx->solType);
188465876a83SMatthew G. Knepley     }
188565876a83SMatthew G. Knepley     ierr = PetscOptionsGetViewer(comm, NULL, NULL, "-param_view", &viewer, &format, &flg);CHKERRQ(ierr);
188665876a83SMatthew G. Knepley     if (flg) {
188765876a83SMatthew G. Knepley       ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
188865876a83SMatthew G. Knepley       ierr = PetscBagView(bag, viewer);CHKERRQ(ierr);
188965876a83SMatthew G. Knepley       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
189065876a83SMatthew G. Knepley       ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
189165876a83SMatthew G. Knepley       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
189265876a83SMatthew G. Knepley       ierr = PetscPrintf(comm, "  Max displacement: %g %g\n", p->P_0*(p->ymax - p->ymin)*(1. - 2.*nu_u)/(2.*p->mu*(1. - nu_u)), p->P_0*(p->ymax - p->ymin)*(1. - 2.*nu)/(2.*p->mu*(1. - nu)));
189365876a83SMatthew G. Knepley       ierr = PetscPrintf(comm, "  Relaxation time: %g\n", ctx->t_r);
189465876a83SMatthew G. Knepley     }
189565876a83SMatthew G. Knepley   }
189665876a83SMatthew G. Knepley   PetscFunctionReturn(0);
189765876a83SMatthew G. Knepley }
189865876a83SMatthew G. Knepley 
189965876a83SMatthew G. Knepley static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
190065876a83SMatthew G. Knepley {
190165876a83SMatthew G. Knepley   Parameter     *param;
190265876a83SMatthew G. Knepley   PetscBool      flg;
190365876a83SMatthew G. Knepley   PetscErrorCode ierr;
190465876a83SMatthew G. Knepley 
190565876a83SMatthew G. Knepley   PetscFunctionBeginUser;
190665876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
190765876a83SMatthew G. Knepley   if (user->solType == SOL_CRYER) {
190865876a83SMatthew G. Knepley     DM rdm;
190965876a83SMatthew G. Knepley 
191065876a83SMatthew G. Knepley     if (!user->simplex) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Cannot create ball with cubic cells");
191165876a83SMatthew G. Knepley     if (param->xmin != 0.0 || param->ymin != 0.0) SETERRQ2(comm, PETSC_ERR_ARG_WRONG, "Cannot shift center of ball to (%g, %g)", param->xmin, param->ymin);
191265876a83SMatthew G. Knepley     if (param->xmax != param->ymax) SETERRQ2(comm, PETSC_ERR_ARG_WRONG, "Cannot radius of ball must be equal in x and y: %g != %g", param->xmax, param->ymax);
191365876a83SMatthew G. Knepley     ierr = DMPlexCreateBallMesh(comm, user->dim, param->xmax, dm);CHKERRQ(ierr);
191465876a83SMatthew G. Knepley 
191565876a83SMatthew G. Knepley     ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr);
191665876a83SMatthew G. Knepley     ierr = DMPlexSetRefinementLimit(*dm, user->refLimit);CHKERRQ(ierr);
191765876a83SMatthew G. Knepley     ierr = DMRefine(*dm, comm, &rdm);CHKERRQ(ierr);
191865876a83SMatthew G. Knepley     if (rdm) {
191965876a83SMatthew G. Knepley       ierr = DMDestroy(dm);CHKERRQ(ierr);
192065876a83SMatthew G. Knepley       *dm  = rdm;
192165876a83SMatthew G. Knepley     }
192265876a83SMatthew G. Knepley     ierr = DMPlexSetRefinementUniform(*dm, PETSC_TRUE);CHKERRQ(ierr);
192365876a83SMatthew G. Knepley   } else if (user->solType == SOL_MANDEL) {
192465876a83SMatthew G. Knepley     PetscReal lower[2], upper[2];
192565876a83SMatthew G. Knepley 
192665876a83SMatthew G. Knepley     lower[0] = param->xmin - (param->xmax - param->xmin) / 2.0;
192765876a83SMatthew G. Knepley     lower[1] = param->ymin - (param->ymax - param->ymin) / 2.0;
192865876a83SMatthew G. Knepley     upper[0] = param->xmax - (param->xmax - param->xmin) / 2.0;
192965876a83SMatthew G. Knepley     upper[1] = param->ymax - (param->ymax - param->ymin) / 2.0;
193065876a83SMatthew G. Knepley     //reset min / max values for mandel
193165876a83SMatthew G. Knepley     param->xmin = lower[0];
193265876a83SMatthew G. Knepley     param->ymin = lower[1];
193365876a83SMatthew G. Knepley     param->xmax = upper[0];
193465876a83SMatthew G. Knepley     param->ymax = upper[1];
193565876a83SMatthew G. Knepley     ierr = DMPlexCreateBoxMesh(comm, user->dim, user->simplex, NULL, lower, upper, NULL, PETSC_TRUE, dm);CHKERRQ(ierr);
193665876a83SMatthew G. Knepley   } else {
193765876a83SMatthew G. Knepley     Parameter *param;
193865876a83SMatthew G. Knepley     PetscReal  lower[3], upper[3];
193965876a83SMatthew G. Knepley 
194065876a83SMatthew G. Knepley     ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
194165876a83SMatthew G. Knepley     lower[0] = param->xmin;
194265876a83SMatthew G. Knepley     lower[1] = param->ymin;
194365876a83SMatthew G. Knepley     lower[2] = param->zmin;
194465876a83SMatthew G. Knepley     upper[0] = param->xmax;
194565876a83SMatthew G. Knepley     upper[1] = param->ymax;
194665876a83SMatthew G. Knepley     upper[2] = param->zmax;
194765876a83SMatthew G. Knepley     ierr = DMPlexCreateBoxMesh(comm, user->dim, user->simplex, NULL, lower, upper, NULL, PETSC_TRUE, dm);CHKERRQ(ierr);
194865876a83SMatthew G. Knepley   }
194965876a83SMatthew G. Knepley   {
195065876a83SMatthew G. Knepley     DM               pdm = NULL;
195165876a83SMatthew G. Knepley     PetscPartitioner part;
195265876a83SMatthew G. Knepley 
195365876a83SMatthew G. Knepley     ierr = DMPlexGetPartitioner(*dm, &part);CHKERRQ(ierr);
195465876a83SMatthew G. Knepley     ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr);
195565876a83SMatthew G. Knepley     ierr = DMPlexDistribute(*dm, 0, NULL, &pdm);CHKERRQ(ierr);
195665876a83SMatthew G. Knepley     if (pdm) {
195765876a83SMatthew G. Knepley       ierr = DMDestroy(dm);CHKERRQ(ierr);
195865876a83SMatthew G. Knepley       *dm  = pdm;
195965876a83SMatthew G. Knepley     }
196065876a83SMatthew G. Knepley   }
196165876a83SMatthew G. Knepley   ierr = PetscStrcmp(user->dmType, DMPLEX, &flg);CHKERRQ(ierr);
196265876a83SMatthew G. Knepley   if (flg) {
196365876a83SMatthew G. Knepley     DM ndm;
196465876a83SMatthew G. Knepley 
196565876a83SMatthew G. Knepley     ierr = DMConvert(*dm, user->dmType, &ndm);CHKERRQ(ierr);
196665876a83SMatthew G. Knepley     if (ndm) {
196765876a83SMatthew G. Knepley       ierr = DMDestroy(dm);CHKERRQ(ierr);
196865876a83SMatthew G. Knepley       *dm  = ndm;
196965876a83SMatthew G. Knepley     }
197065876a83SMatthew G. Knepley   }
197165876a83SMatthew G. Knepley   ierr = DMLocalizeCoordinates(*dm);CHKERRQ(ierr);
197265876a83SMatthew G. Knepley 
197365876a83SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *dm, "Mesh");CHKERRQ(ierr);
197465876a83SMatthew G. Knepley   ierr = DMSetApplicationContext(*dm, user);CHKERRQ(ierr);
197565876a83SMatthew G. Knepley   ierr = DMSetFromOptions(*dm);CHKERRQ(ierr);
197665876a83SMatthew G. Knepley   ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr);
197765876a83SMatthew G. Knepley   PetscFunctionReturn(0);
197865876a83SMatthew G. Knepley }
197965876a83SMatthew G. Knepley 
198065876a83SMatthew G. Knepley static PetscErrorCode SetupPrimalProblem(DM dm, AppCtx *user)
198165876a83SMatthew G. Knepley {
198265876a83SMatthew G. Knepley   PetscErrorCode (*exact[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
198365876a83SMatthew G. Knepley   PetscErrorCode (*exact_t[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
1984*45480ffeSMatthew G. Knepley   PetscDS          ds;
1985*45480ffeSMatthew G. Knepley   DMLabel          label;
1986*45480ffeSMatthew G. Knepley   PetscWeakForm    wf;
198765876a83SMatthew G. Knepley   Parameter       *param;
198865876a83SMatthew G. Knepley   PetscInt         id_mandel[2];
198965876a83SMatthew G. Knepley   PetscInt         comp[1];
199065876a83SMatthew G. Knepley   PetscInt         comp_mandel[2];
1991*45480ffeSMatthew G. Knepley   PetscInt         dim, id, bd, f;
199265876a83SMatthew G. Knepley   PetscErrorCode   ierr;
199365876a83SMatthew G. Knepley 
199465876a83SMatthew G. Knepley   PetscFunctionBeginUser;
1995*45480ffeSMatthew G. Knepley   ierr = DMGetLabel(dm, "marker", &label);CHKERRQ(ierr);
1996*45480ffeSMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
1997*45480ffeSMatthew G. Knepley   ierr = PetscDSGetSpatialDimension(ds, &dim);CHKERRQ(ierr);
199865876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
199965876a83SMatthew G. Knepley   exact_t[0] = exact_t[1] = exact_t[2] = zero;
200065876a83SMatthew G. Knepley 
200165876a83SMatthew G. Knepley   /* Setup Problem Formulation and Boundary Conditions */
200265876a83SMatthew G. Knepley   switch (user->solType) {
200365876a83SMatthew G. Knepley   case SOL_QUADRATIC_LINEAR:
2004*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 0, f0_quadratic_linear_u, f1_u);CHKERRQ(ierr);
2005*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 1, f0_epsilon,            NULL);CHKERRQ(ierr);
2006*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 2, f0_quadratic_linear_p, f1_p);CHKERRQ(ierr);
2007*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2008*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2009*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2010*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2011*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2012*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL,  NULL,  NULL);CHKERRQ(ierr);
2013*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL,  NULL,  g3_pp);CHKERRQ(ierr);
201465876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
201565876a83SMatthew G. Knepley     exact[1]   = linear_eps;
201665876a83SMatthew G. Knepley     exact[2]   = linear_linear_p;
201765876a83SMatthew G. Knepley     exact_t[2] = linear_linear_p_t;
201865876a83SMatthew G. Knepley 
201965876a83SMatthew G. Knepley     id = 1;
2020*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void)) exact[0], NULL, user, NULL);CHKERRQ(ierr);
2021*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure",     label, 1, &id, 2, 0, NULL, (void (*)(void)) exact[2], (void (*)(void)) exact_t[2], user, NULL);CHKERRQ(ierr);
202265876a83SMatthew G. Knepley     break;
202365876a83SMatthew G. Knepley   case SOL_TRIG_LINEAR:
2024*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 0, f0_trig_linear_u, f1_u);CHKERRQ(ierr);
2025*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 1, f0_epsilon,       NULL);CHKERRQ(ierr);
2026*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 2, f0_trig_linear_p, f1_p);CHKERRQ(ierr);
2027*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2028*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2029*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2030*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2031*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2032*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL,  NULL,  NULL);CHKERRQ(ierr);
2033*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL,  NULL,  g3_pp);CHKERRQ(ierr);
203465876a83SMatthew G. Knepley     exact[0]   = trig_u;
203565876a83SMatthew G. Knepley     exact[1]   = trig_eps;
203665876a83SMatthew G. Knepley     exact[2]   = trig_linear_p;
203765876a83SMatthew G. Knepley     exact_t[2] = trig_linear_p_t;
203865876a83SMatthew G. Knepley 
203965876a83SMatthew G. Knepley     id = 1;
2040*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void)) exact[0], NULL, user, NULL);CHKERRQ(ierr);
2041*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure",     label, 1, &id, 2, 0, NULL, (void (*)(void)) exact[2], (void (*)(void)) exact_t[2], user, NULL);CHKERRQ(ierr);
204265876a83SMatthew G. Knepley     break;
204365876a83SMatthew G. Knepley   case SOL_QUADRATIC_TRIG:
2044*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 0, f0_quadratic_trig_u, f1_u);CHKERRQ(ierr);
2045*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 1, f0_epsilon,          NULL);CHKERRQ(ierr);
2046*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 2, f0_quadratic_trig_p, f1_p);CHKERRQ(ierr);
2047*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2048*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2049*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2050*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2051*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2052*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 1, g0_pe, NULL,  NULL,  NULL);CHKERRQ(ierr);
2053*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 2, g0_pp, NULL,  NULL,  g3_pp);CHKERRQ(ierr);
205465876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
205565876a83SMatthew G. Knepley     exact[1]   = linear_eps;
205665876a83SMatthew G. Knepley     exact[2]   = linear_trig_p;
205765876a83SMatthew G. Knepley     exact_t[2] = linear_trig_p_t;
205865876a83SMatthew G. Knepley 
205965876a83SMatthew G. Knepley     id = 1;
2060*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", label, 1, &id, 0, 0, NULL, (void (*)(void)) exact[0], NULL, user, NULL);CHKERRQ(ierr);
2061*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure",     label, 1, &id, 2, 0, NULL, (void (*)(void)) exact[2], (void (*)(void)) exact_t[2], user, NULL);CHKERRQ(ierr);
206265876a83SMatthew G. Knepley     break;
206365876a83SMatthew G. Knepley   case SOL_TERZAGHI:
2064*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 0, NULL, f1_u);CHKERRQ(ierr);
2065*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 1, f0_epsilon,     NULL);CHKERRQ(ierr);
2066*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 2, f0_p,           f1_p);CHKERRQ(ierr);
2067*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2068*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2069*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2070*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2071*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2072*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 1, g0_pe,  NULL,  NULL,  NULL);CHKERRQ(ierr);
2073*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 2, g0_pp,  NULL,  NULL,  g3_pp);CHKERRQ(ierr);
207465876a83SMatthew G. Knepley 
207565876a83SMatthew G. Knepley     exact[0] = terzaghi_2d_u;
207665876a83SMatthew G. Knepley     exact[1] = terzaghi_2d_eps;
207765876a83SMatthew G. Knepley     exact[2] = terzaghi_2d_p;
207865876a83SMatthew G. Knepley     exact_t[0] = terzaghi_2d_u_t;
207965876a83SMatthew G. Knepley     exact_t[1] = terzaghi_2d_eps_t;
208065876a83SMatthew G. Knepley     exact_t[2] = terzaghi_2d_p_t;
208165876a83SMatthew G. Knepley 
208265876a83SMatthew G. Knepley     id = 1;
2083*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress",   label, 1, &id, 0, 0, NULL, NULL, NULL, user, &bd);CHKERRQ(ierr);
2084*45480ffeSMatthew G. Knepley     ierr = PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
2085*45480ffeSMatthew G. Knepley     ierr = PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, f0_terzaghi_bd_u, 0, NULL);CHKERRQ(ierr);
2086*45480ffeSMatthew G. Knepley 
208765876a83SMatthew G. Knepley     id = 3;
208865876a83SMatthew G. Knepley     comp[0] = 1;
2089*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base",      label, 1, &id, 0, 1, comp, (void (*)(void)) zero, NULL, user, NULL);CHKERRQ(ierr);
209065876a83SMatthew G. Knepley     id = 2;
209165876a83SMatthew G. Knepley     comp[0] = 0;
2092*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side",      label, 1, &id, 0, 1, comp, (void (*)(void)) zero, NULL, user, NULL);CHKERRQ(ierr);
209365876a83SMatthew G. Knepley     id = 4;
209465876a83SMatthew G. Knepley     comp[0] = 0;
2095*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side",      label, 1, &id, 0, 1, comp, (void (*)(void)) zero, NULL, user, NULL);CHKERRQ(ierr);
209665876a83SMatthew G. Knepley     id = 1;
2097*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 1, &id, 2, 0, NULL, (void (*)(void)) terzaghi_drainage_pressure, NULL, user, NULL);CHKERRQ(ierr);
209865876a83SMatthew G. Knepley     break;
209965876a83SMatthew G. Knepley   case SOL_MANDEL:
2100*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 0, NULL, f1_u);CHKERRQ(ierr);
2101*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 1, f0_epsilon,     NULL);CHKERRQ(ierr);
2102*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 2, f0_p,           f1_p);CHKERRQ(ierr);
2103*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2104*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2105*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2106*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2107*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2108*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 1, g0_pe,  NULL,  NULL,  NULL);CHKERRQ(ierr);
2109*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 2, g0_pp,  NULL,  NULL,  g3_pp);CHKERRQ(ierr);
211065876a83SMatthew G. Knepley 
211165876a83SMatthew G. Knepley     ierr = mandelZeros(PETSC_COMM_WORLD, user, param);CHKERRQ(ierr);
211265876a83SMatthew G. Knepley 
211365876a83SMatthew G. Knepley     exact[0] = mandel_2d_u;
211465876a83SMatthew G. Knepley     exact[1] = mandel_2d_eps;
211565876a83SMatthew G. Knepley     exact[2] = mandel_2d_p;
211665876a83SMatthew G. Knepley     exact_t[0] = mandel_2d_u_t;
211765876a83SMatthew G. Knepley     exact_t[1] = mandel_2d_eps_t;
211865876a83SMatthew G. Knepley     exact_t[2] = mandel_2d_p_t;
211965876a83SMatthew G. Knepley 
212065876a83SMatthew G. Knepley     id_mandel[0] = 3;
212165876a83SMatthew G. Knepley     id_mandel[1] = 1;
212265876a83SMatthew G. Knepley     //comp[0] = 1;
212365876a83SMatthew G. Knepley     comp_mandel[0] = 0;
212465876a83SMatthew G. Knepley     comp_mandel[1] = 1;
2125*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "vertical stress", label, 2, id_mandel, 0, 2, comp_mandel, (void (*)(void)) mandel_2d_u, NULL, user, NULL);CHKERRQ(ierr);
212665876a83SMatthew G. Knepley     //ierr = DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", "marker", 0, 1, comp, NULL, 2, id_mandel, user);CHKERRQ(ierr);
212765876a83SMatthew G. Knepley     //ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", "marker", 0, 1, comp, (void (*)(void)) zero, 2, id_mandel, user);CHKERRQ(ierr);
2128*45480ffeSMatthew G. Knepley     //ierr = PetscDSSetBdResidual(ds, 0, f0_mandel_bd_u, NULL);CHKERRQ(ierr);
212965876a83SMatthew G. Knepley 
213065876a83SMatthew G. Knepley     id_mandel[0] = 2;
213165876a83SMatthew G. Knepley     id_mandel[1] = 4;
2132*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 2, id_mandel, 2, 0, NULL, (void (*)(void)) zero, NULL, user, NULL);CHKERRQ(ierr);
213365876a83SMatthew G. Knepley     break;
213465876a83SMatthew G. Knepley   case SOL_CRYER:
2135*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 0, NULL, f1_u);CHKERRQ(ierr);
2136*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 1, f0_epsilon,     NULL);CHKERRQ(ierr);
2137*45480ffeSMatthew G. Knepley     ierr = PetscDSSetResidual(ds, 2, f0_p,           f1_p);CHKERRQ(ierr);
2138*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2139*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2140*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2141*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2142*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2143*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 1, g0_pe,  NULL,  NULL,  NULL);CHKERRQ(ierr);
2144*45480ffeSMatthew G. Knepley     ierr = PetscDSSetJacobian(ds, 2, 2, g0_pp,  NULL,  NULL,  g3_pp);CHKERRQ(ierr);
214565876a83SMatthew G. Knepley 
214665876a83SMatthew G. Knepley     ierr = cryerZeros(PETSC_COMM_WORLD, user, param);CHKERRQ(ierr);
214765876a83SMatthew G. Knepley 
214865876a83SMatthew G. Knepley     exact[0] = cryer_3d_u;
214965876a83SMatthew G. Knepley     exact[1] = cryer_3d_eps;
215065876a83SMatthew G. Knepley     exact[2] = cryer_3d_p;
215165876a83SMatthew G. Knepley 
215265876a83SMatthew G. Knepley     id = 1;
2153*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_NATURAL,   "normal stress",   label, 1, &id, 0, 0, NULL, NULL,                                     NULL, user, &bd);CHKERRQ(ierr);
2154*45480ffeSMatthew G. Knepley     ierr = PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
2155*45480ffeSMatthew G. Knepley     ierr = PetscWeakFormSetIndexBdResidual(wf, label, id, 0, 0, f0_cryer_bd_u, 0, NULL);CHKERRQ(ierr);
2156*45480ffeSMatthew G. Knepley 
2157*45480ffeSMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", label, 1, &id, 2, 0, NULL, (void (*)(void)) cryer_drainage_pressure, NULL, user, NULL);CHKERRQ(ierr);
215865876a83SMatthew G. Knepley     break;
2159*45480ffeSMatthew G. Knepley   default: SETERRQ2(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%D)", solutionTypes[PetscMin(user->solType, NUM_SOLUTION_TYPES)], user->solType);
216065876a83SMatthew G. Knepley   }
216165876a83SMatthew G. Knepley   for (f = 0; f < 3; ++f) {
2162*45480ffeSMatthew G. Knepley     ierr = PetscDSSetExactSolution(ds, f, exact[f], user);CHKERRQ(ierr);
2163*45480ffeSMatthew G. Knepley     ierr = PetscDSSetExactSolutionTimeDerivative(ds, f, exact_t[f], user);CHKERRQ(ierr);
216465876a83SMatthew G. Knepley   }
216565876a83SMatthew G. Knepley 
216665876a83SMatthew G. Knepley   /* Setup constants */
216765876a83SMatthew G. Knepley   {
216865876a83SMatthew G. Knepley     PetscScalar constants[6];
216965876a83SMatthew G. Knepley     constants[0] = param->mu;            /* shear modulus, Pa */
217065876a83SMatthew G. Knepley     constants[1] = param->K_u;           /* undrained bulk modulus, Pa */
217165876a83SMatthew G. Knepley     constants[2] = param->alpha;         /* Biot effective stress coefficient, - */
217265876a83SMatthew G. Knepley     constants[3] = param->M;             /* Biot modulus, Pa */
217365876a83SMatthew G. Knepley     constants[4] = param->k/param->mu_f; /* Darcy coefficient, m**2 / Pa*s */
217465876a83SMatthew G. Knepley     constants[5] = param->P_0;           /* Magnitude of Vertical Stress, Pa */
2175*45480ffeSMatthew G. Knepley     ierr = PetscDSSetConstants(ds, 6, constants);CHKERRQ(ierr);
217665876a83SMatthew G. Knepley   }
217765876a83SMatthew G. Knepley   PetscFunctionReturn(0);
217865876a83SMatthew G. Knepley }
217965876a83SMatthew G. Knepley 
21808cda7954SMatthew G. Knepley static PetscErrorCode CreateElasticityNullSpace(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullspace)
218165876a83SMatthew G. Knepley {
218265876a83SMatthew G. Knepley   PetscErrorCode ierr;
218365876a83SMatthew G. Knepley 
218465876a83SMatthew G. Knepley   PetscFunctionBegin;
21858cda7954SMatthew G. Knepley   ierr = DMPlexCreateRigidBody(dm, origField, nullspace);CHKERRQ(ierr);
218665876a83SMatthew G. Knepley   PetscFunctionReturn(0);
218765876a83SMatthew G. Knepley }
218865876a83SMatthew G. Knepley 
2189346a0eb2SMatthew Knepley static PetscErrorCode SetupFE(DM dm, PetscBool simplex, PetscInt Nf, PetscInt Nc[], const char *name[], PetscErrorCode (*setup)(DM, AppCtx *), void *ctx)
219065876a83SMatthew G. Knepley {
219165876a83SMatthew G. Knepley   AppCtx         *user = (AppCtx *) ctx;
219265876a83SMatthew G. Knepley   DM              cdm  = dm;
219365876a83SMatthew G. Knepley   PetscFE         fe;
219465876a83SMatthew G. Knepley   PetscQuadrature q = NULL;
219565876a83SMatthew G. Knepley   char            prefix[PETSC_MAX_PATH_LEN];
219665876a83SMatthew G. Knepley   PetscInt        dim, f;
219765876a83SMatthew G. Knepley   PetscErrorCode  ierr;
219865876a83SMatthew G. Knepley 
219965876a83SMatthew G. Knepley   PetscFunctionBegin;
220065876a83SMatthew G. Knepley   /* Create finite element */
220165876a83SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
220265876a83SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
220365876a83SMatthew G. Knepley     ierr = PetscSNPrintf(prefix, PETSC_MAX_PATH_LEN, "%s_", name[f]);CHKERRQ(ierr);
2204346a0eb2SMatthew Knepley     ierr = PetscFECreateDefault(PETSC_COMM_SELF, dim, Nc[f], simplex, name[f] ? prefix : NULL, -1, &fe);CHKERRQ(ierr);
220565876a83SMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) fe, name[f]);CHKERRQ(ierr);
220665876a83SMatthew G. Knepley     if (!q) {ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr);}
220765876a83SMatthew G. Knepley     ierr = PetscFESetQuadrature(fe, q);CHKERRQ(ierr);
220865876a83SMatthew G. Knepley     ierr = DMSetField(dm, f, NULL, (PetscObject) fe);CHKERRQ(ierr);
220965876a83SMatthew G. Knepley     ierr = PetscFEDestroy(&fe);CHKERRQ(ierr);
221065876a83SMatthew G. Knepley   }
221165876a83SMatthew G. Knepley   ierr = DMCreateDS(dm);CHKERRQ(ierr);
221265876a83SMatthew G. Knepley   ierr = (*setup)(dm, user);CHKERRQ(ierr);
221365876a83SMatthew G. Knepley   while (cdm) {
221465876a83SMatthew G. Knepley     ierr = DMCopyDisc(dm, cdm);CHKERRQ(ierr);
221565876a83SMatthew G. Knepley     if (0) {ierr = DMSetNearNullSpaceConstructor(cdm, 0, CreateElasticityNullSpace);CHKERRQ(ierr);}
221665876a83SMatthew G. Knepley     /* TODO: Check whether the boundary of coarse meshes is marked */
221765876a83SMatthew G. Knepley     ierr = DMGetCoarseDM(cdm, &cdm);CHKERRQ(ierr);
221865876a83SMatthew G. Knepley   }
221965876a83SMatthew G. Knepley   ierr = PetscFEDestroy(&fe);CHKERRQ(ierr);
222065876a83SMatthew G. Knepley   PetscFunctionReturn(0);
222165876a83SMatthew G. Knepley }
222265876a83SMatthew G. Knepley 
222365876a83SMatthew G. Knepley static PetscErrorCode SetInitialConditions(TS ts, Vec u)
222465876a83SMatthew G. Knepley {
222565876a83SMatthew G. Knepley   DM             dm;
222665876a83SMatthew G. Knepley   PetscReal      t;
222765876a83SMatthew G. Knepley   PetscErrorCode ierr;
222865876a83SMatthew G. Knepley 
222965876a83SMatthew G. Knepley   PetscFunctionBegin;
223065876a83SMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
223165876a83SMatthew G. Knepley   ierr = TSGetTime(ts, &t);CHKERRQ(ierr);
223265876a83SMatthew G. Knepley   if (t <= 0.0) {
223365876a83SMatthew G. Knepley     PetscErrorCode (*funcs[3])(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *);
223465876a83SMatthew G. Knepley     void            *ctxs[3];
223565876a83SMatthew G. Knepley     AppCtx          *ctx;
223665876a83SMatthew G. Knepley 
223765876a83SMatthew G. Knepley     ierr = DMGetApplicationContext(dm, (void **) &ctx);CHKERRQ(ierr);
223865876a83SMatthew G. Knepley     switch (ctx->solType) {
223965876a83SMatthew G. Knepley       case SOL_TERZAGHI:
224065876a83SMatthew G. Knepley         funcs[0] = terzaghi_initial_u;         ctxs[0] = ctx;
224165876a83SMatthew G. Knepley         funcs[1] = terzaghi_initial_eps;       ctxs[1] = ctx;
224265876a83SMatthew G. Knepley         funcs[2] = terzaghi_drainage_pressure; ctxs[2] = ctx;
224365876a83SMatthew G. Knepley         ierr = DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u);CHKERRQ(ierr);
224465876a83SMatthew G. Knepley         break;
224565876a83SMatthew G. Knepley       case SOL_MANDEL:
224665876a83SMatthew G. Knepley         funcs[0] = mandel_initial_u;         ctxs[0] = ctx;
224765876a83SMatthew G. Knepley         funcs[1] = mandel_initial_eps;       ctxs[1] = ctx;
224865876a83SMatthew G. Knepley         funcs[2] = mandel_drainage_pressure; ctxs[2] = ctx;
224965876a83SMatthew G. Knepley         ierr = DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u);CHKERRQ(ierr);
225065876a83SMatthew G. Knepley         break;
225165876a83SMatthew G. Knepley       case SOL_CRYER:
225265876a83SMatthew G. Knepley         funcs[0] = cryer_initial_u;         ctxs[0] = ctx;
225365876a83SMatthew G. Knepley         funcs[1] = cryer_initial_eps;       ctxs[1] = ctx;
225465876a83SMatthew G. Knepley         funcs[2] = cryer_drainage_pressure; ctxs[2] = ctx;
225565876a83SMatthew G. Knepley         ierr = DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u);CHKERRQ(ierr);
225665876a83SMatthew G. Knepley         break;
225765876a83SMatthew G. Knepley       default:
225865876a83SMatthew G. Knepley         ierr = DMComputeExactSolution(dm, t, u, NULL);CHKERRQ(ierr);
225965876a83SMatthew G. Knepley     }
226065876a83SMatthew G. Knepley   } else {
226165876a83SMatthew G. Knepley     ierr = DMComputeExactSolution(dm, t, u, NULL);CHKERRQ(ierr);
226265876a83SMatthew G. Knepley   }
226365876a83SMatthew G. Knepley   PetscFunctionReturn(0);
226465876a83SMatthew G. Knepley }
226565876a83SMatthew G. Knepley 
226665876a83SMatthew G. Knepley /* Need to create Viewer each time because HDF5 can get corrupted */
226765876a83SMatthew G. Knepley static PetscErrorCode SolutionMonitor(TS ts, PetscInt steps, PetscReal time, Vec u, void *mctx)
226865876a83SMatthew G. Knepley {
226965876a83SMatthew G. Knepley   DM                dm;
227065876a83SMatthew G. Knepley   Vec               exact;
227165876a83SMatthew G. Knepley   PetscViewer       viewer;
227265876a83SMatthew G. Knepley   PetscViewerFormat format;
227365876a83SMatthew G. Knepley   PetscOptions      options;
227465876a83SMatthew G. Knepley   const char       *prefix;
227565876a83SMatthew G. Knepley   PetscErrorCode    ierr;
227665876a83SMatthew G. Knepley 
227765876a83SMatthew G. Knepley   PetscFunctionBegin;
227865876a83SMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
227965876a83SMatthew G. Knepley   ierr = PetscObjectGetOptions((PetscObject) ts, &options);CHKERRQ(ierr);
228065876a83SMatthew G. Knepley   ierr = PetscObjectGetOptionsPrefix((PetscObject) ts, &prefix);CHKERRQ(ierr);
228165876a83SMatthew G. Knepley   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) ts), options, prefix, "-monitor_solution", &viewer, &format, NULL);CHKERRQ(ierr);
228265876a83SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &exact);CHKERRQ(ierr);
228365876a83SMatthew G. Knepley   ierr = DMComputeExactSolution(dm, time, exact, NULL);CHKERRQ(ierr);
228465876a83SMatthew G. Knepley   ierr = DMSetOutputSequenceNumber(dm, steps, time);CHKERRQ(ierr);
228565876a83SMatthew G. Knepley   ierr = VecView(exact, viewer);CHKERRQ(ierr);
228665876a83SMatthew G. Knepley   ierr = VecView(u, viewer);CHKERRQ(ierr);
228765876a83SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &exact);CHKERRQ(ierr);
228865876a83SMatthew G. Knepley   {
228965876a83SMatthew G. Knepley     PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx);
229065876a83SMatthew G. Knepley     void            **ectxs;
229165876a83SMatthew G. Knepley     PetscReal        *err;
229265876a83SMatthew G. Knepley     PetscInt          Nf, f;
229365876a83SMatthew G. Knepley 
229465876a83SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
229565876a83SMatthew G. Knepley     ierr = PetscCalloc3(Nf, &exacts, Nf, &ectxs, PetscMax(1, Nf), &err);CHKERRQ(ierr);
229665876a83SMatthew G. Knepley     {
229765876a83SMatthew G. Knepley       PetscInt Nds, s;
229865876a83SMatthew G. Knepley 
229965876a83SMatthew G. Knepley       ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
230065876a83SMatthew G. Knepley       for (s = 0; s < Nds; ++s) {
230165876a83SMatthew G. Knepley         PetscDS         ds;
230265876a83SMatthew G. Knepley         DMLabel         label;
230365876a83SMatthew G. Knepley         IS              fieldIS;
230465876a83SMatthew G. Knepley         const PetscInt *fields;
230565876a83SMatthew G. Knepley         PetscInt        dsNf, f;
230665876a83SMatthew G. Knepley 
230765876a83SMatthew G. Knepley         ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr);
230865876a83SMatthew G. Knepley         ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr);
230965876a83SMatthew G. Knepley         ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr);
231065876a83SMatthew G. Knepley         for (f = 0; f < dsNf; ++f) {
231165876a83SMatthew G. Knepley           const PetscInt field = fields[f];
231265876a83SMatthew G. Knepley           ierr = PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr);
231365876a83SMatthew G. Knepley         }
231465876a83SMatthew G. Knepley         ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr);
231565876a83SMatthew G. Knepley       }
231665876a83SMatthew G. Knepley     }
231765876a83SMatthew G. Knepley     ierr = DMComputeL2FieldDiff(dm, time, exacts, ectxs, u, err);CHKERRQ(ierr);
231865876a83SMatthew G. Knepley     ierr = PetscPrintf(PetscObjectComm((PetscObject) ts), "Time: %g L_2 Error: [", time);CHKERRQ(ierr);
231965876a83SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
232065876a83SMatthew G. Knepley       if (f) {ierr = PetscPrintf(PetscObjectComm((PetscObject) ts), ", ");CHKERRQ(ierr);}
232165876a83SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject) ts), "%g", (double) err[f]);CHKERRQ(ierr);
232265876a83SMatthew G. Knepley     }
232365876a83SMatthew G. Knepley     ierr = PetscPrintf(PetscObjectComm((PetscObject) ts), "]\n");CHKERRQ(ierr);
232465876a83SMatthew G. Knepley     ierr = PetscFree3(exacts, ectxs, err);CHKERRQ(ierr);
232565876a83SMatthew G. Knepley   }
232665876a83SMatthew G. Knepley   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
232765876a83SMatthew G. Knepley   PetscFunctionReturn(0);
232865876a83SMatthew G. Knepley }
232965876a83SMatthew G. Knepley 
233065876a83SMatthew G. Knepley static PetscErrorCode SetupMonitor(TS ts, AppCtx *ctx)
233165876a83SMatthew G. Knepley {
233265876a83SMatthew G. Knepley   PetscViewer       viewer;
233365876a83SMatthew G. Knepley   PetscViewerFormat format;
233465876a83SMatthew G. Knepley   PetscOptions      options;
233565876a83SMatthew G. Knepley   const char       *prefix;
233665876a83SMatthew G. Knepley   PetscBool         flg;
233765876a83SMatthew G. Knepley   PetscErrorCode    ierr;
233865876a83SMatthew G. Knepley 
233965876a83SMatthew G. Knepley   PetscFunctionBegin;
234065876a83SMatthew G. Knepley   ierr = PetscObjectGetOptions((PetscObject) ts, &options);CHKERRQ(ierr);
234165876a83SMatthew G. Knepley   ierr = PetscObjectGetOptionsPrefix((PetscObject) ts, &prefix);CHKERRQ(ierr);
234265876a83SMatthew G. Knepley   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) ts), options, prefix, "-monitor_solution", &viewer, &format, &flg);CHKERRQ(ierr);
234365876a83SMatthew G. Knepley   if (flg) {ierr = TSMonitorSet(ts, SolutionMonitor, ctx, NULL);CHKERRQ(ierr);}
234465876a83SMatthew G. Knepley   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
234565876a83SMatthew G. Knepley   PetscFunctionReturn(0);
234665876a83SMatthew G. Knepley }
234765876a83SMatthew G. Knepley 
234865876a83SMatthew G. Knepley static PetscErrorCode TSAdaptChoose_Terzaghi(TSAdapt adapt, TS ts, PetscReal h, PetscInt *next_sc, PetscReal *next_h, PetscBool *accept, PetscReal *wlte, PetscReal *wltea, PetscReal *wlter)
234965876a83SMatthew G. Knepley {
235065876a83SMatthew G. Knepley   static PetscReal dtTarget = -1.0;
235165876a83SMatthew G. Knepley   PetscReal        dtInitial;
235265876a83SMatthew G. Knepley   DM               dm;
235365876a83SMatthew G. Knepley   AppCtx          *ctx;
235465876a83SMatthew G. Knepley   PetscInt         step;
235565876a83SMatthew G. Knepley   PetscErrorCode   ierr;
235665876a83SMatthew G. Knepley 
235765876a83SMatthew G. Knepley   PetscFunctionBegin;
235865876a83SMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
235965876a83SMatthew G. Knepley   ierr = DMGetApplicationContext(dm, (void **) &ctx);CHKERRQ(ierr);
236065876a83SMatthew G. Knepley   ierr = TSGetStepNumber(ts, &step);CHKERRQ(ierr);
236124b15d09SMatthew G. Knepley   dtInitial = ctx->dtInitial < 0.0 ? 1.0e-4*ctx->t_r : ctx->dtInitial;
236265876a83SMatthew G. Knepley   if (!step) {
236365876a83SMatthew G. Knepley     if (PetscAbsReal(dtInitial - h) > PETSC_SMALL) {
236465876a83SMatthew G. Knepley       *accept  = PETSC_FALSE;
236565876a83SMatthew G. Knepley       *next_h  = dtInitial;
236665876a83SMatthew G. Knepley       dtTarget = h;
236765876a83SMatthew G. Knepley     } else {
236865876a83SMatthew G. Knepley       *accept  = PETSC_TRUE;
236965876a83SMatthew G. Knepley       *next_h  = dtTarget < 0.0 ? dtInitial : dtTarget;
237065876a83SMatthew G. Knepley       dtTarget = -1.0;
237165876a83SMatthew G. Knepley     }
237265876a83SMatthew G. Knepley   } else {
237365876a83SMatthew G. Knepley     *accept = PETSC_TRUE;
237465876a83SMatthew G. Knepley     *next_h = h;
237565876a83SMatthew G. Knepley   }
237665876a83SMatthew G. Knepley   *next_sc = 0;  /* Reuse the same order scheme */
237765876a83SMatthew G. Knepley   *wlte    = -1; /* Weighted local truncation error was not evaluated */
237865876a83SMatthew G. Knepley   *wltea   = -1; /* Weighted absolute local truncation error was not evaluated */
237965876a83SMatthew G. Knepley   *wlter   = -1; /* Weighted relative local truncation error was not evaluated */
238065876a83SMatthew G. Knepley   PetscFunctionReturn(0);
238165876a83SMatthew G. Knepley }
238265876a83SMatthew G. Knepley 
238365876a83SMatthew G. Knepley int main(int argc, char **argv)
238465876a83SMatthew G. Knepley {
238565876a83SMatthew G. Knepley   AppCtx         ctx;       /* User-defined work context */
238665876a83SMatthew G. Knepley   DM             dm;        /* Problem specification */
238765876a83SMatthew G. Knepley   TS             ts;        /* Time Series / Nonlinear solver */
238865876a83SMatthew G. Knepley   Vec            u;         /* Solutions */
238965876a83SMatthew G. Knepley   const char    *name[3] = {"displacement", "tracestrain", "pressure"};
239065876a83SMatthew G. Knepley   PetscReal      t;
239165876a83SMatthew G. Knepley   PetscInt       Nc[3];
239265876a83SMatthew G. Knepley   PetscErrorCode ierr;
239365876a83SMatthew G. Knepley 
239465876a83SMatthew G. Knepley   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
239565876a83SMatthew G. Knepley   ierr = ProcessOptions(PETSC_COMM_WORLD, &ctx);CHKERRQ(ierr);
239665876a83SMatthew G. Knepley   ierr = PetscBagCreate(PETSC_COMM_SELF, sizeof(Parameter), &ctx.bag);CHKERRQ(ierr);
239765876a83SMatthew G. Knepley   ierr = PetscMalloc1(ctx.niter, &ctx.zeroArray);CHKERRQ(ierr);
239865876a83SMatthew G. Knepley   ierr = SetupParameters(PETSC_COMM_WORLD, &ctx);CHKERRQ(ierr);
239965876a83SMatthew G. Knepley   /* Primal System */
240065876a83SMatthew G. Knepley   ierr = TSCreate(PETSC_COMM_WORLD, &ts);CHKERRQ(ierr);
240165876a83SMatthew G. Knepley   ierr = CreateMesh(PETSC_COMM_WORLD, &ctx, &dm);CHKERRQ(ierr);
240265876a83SMatthew G. Knepley   ierr = DMSetApplicationContext(dm, &ctx);CHKERRQ(ierr);
240365876a83SMatthew G. Knepley   ierr = TSSetDM(ts, dm);CHKERRQ(ierr);
240465876a83SMatthew G. Knepley 
240565876a83SMatthew G. Knepley   Nc[0] = ctx.dim;
240665876a83SMatthew G. Knepley   Nc[1] = 1;
240765876a83SMatthew G. Knepley   Nc[2] = 1;
240865876a83SMatthew G. Knepley 
240965876a83SMatthew G. Knepley   ierr = SetupFE(dm, ctx.simplex, 3, Nc, name, SetupPrimalProblem, &ctx);CHKERRQ(ierr);
241065876a83SMatthew G. Knepley   ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr);
241165876a83SMatthew G. Knepley   ierr = DMTSSetBoundaryLocal(dm, DMPlexTSComputeBoundary, &ctx);CHKERRQ(ierr);
241265876a83SMatthew G. Knepley   ierr = DMTSSetIFunctionLocal(dm, DMPlexTSComputeIFunctionFEM, &ctx);CHKERRQ(ierr);
241365876a83SMatthew G. Knepley   ierr = DMTSSetIJacobianLocal(dm, DMPlexTSComputeIJacobianFEM, &ctx);CHKERRQ(ierr);
241465876a83SMatthew G. Knepley   ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr);
241565876a83SMatthew G. Knepley   ierr = TSSetFromOptions(ts);CHKERRQ(ierr);
241665876a83SMatthew G. Knepley   ierr = TSSetComputeInitialCondition(ts, SetInitialConditions);CHKERRQ(ierr);
241765876a83SMatthew G. Knepley   ierr = SetupMonitor(ts, &ctx);CHKERRQ(ierr);
241865876a83SMatthew G. Knepley 
241965876a83SMatthew G. Knepley   if (ctx.solType != SOL_QUADRATIC_TRIG) {
242065876a83SMatthew G. Knepley     TSAdapt adapt;
242165876a83SMatthew G. Knepley 
242265876a83SMatthew G. Knepley     ierr = TSGetAdapt(ts, &adapt);CHKERRQ(ierr);
242365876a83SMatthew G. Knepley     adapt->ops->choose = TSAdaptChoose_Terzaghi;
242465876a83SMatthew G. Knepley   }
242565876a83SMatthew G. Knepley   if (ctx.solType == SOL_CRYER) {
242665876a83SMatthew G. Knepley     Mat          J;
242765876a83SMatthew G. Knepley     MatNullSpace sp;
242865876a83SMatthew G. Knepley 
242965876a83SMatthew G. Knepley     ierr = TSSetUp(ts);CHKERRQ(ierr);
243065876a83SMatthew G. Knepley     ierr = TSGetIJacobian(ts, &J, NULL, NULL, NULL);CHKERRQ(ierr);
243165876a83SMatthew G. Knepley     ierr = DMPlexCreateRigidBody(dm, 0, &sp);CHKERRQ(ierr);
243265876a83SMatthew G. Knepley     ierr = MatSetNullSpace(J, sp);CHKERRQ(ierr);
243365876a83SMatthew G. Knepley     ierr = MatNullSpaceDestroy(&sp);CHKERRQ(ierr);
243465876a83SMatthew G. Knepley   }
243565876a83SMatthew G. Knepley   ierr = TSGetTime(ts, &t);CHKERRQ(ierr);
243665876a83SMatthew G. Knepley   ierr = DMSetOutputSequenceNumber(dm, 0, t);CHKERRQ(ierr);
243765876a83SMatthew G. Knepley   ierr = DMTSCheckFromOptions(ts, u);CHKERRQ(ierr);
243865876a83SMatthew G. Knepley   ierr = SetInitialConditions(ts, u);CHKERRQ(ierr);
243965876a83SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) u, "solution");CHKERRQ(ierr);
244065876a83SMatthew G. Knepley   ierr = TSSolve(ts, u);CHKERRQ(ierr);
244165876a83SMatthew G. Knepley   ierr = DMTSCheckFromOptions(ts, u);CHKERRQ(ierr);
244265876a83SMatthew G. Knepley   ierr = TSGetSolution(ts, &u);CHKERRQ(ierr);
244365876a83SMatthew G. Knepley   ierr = VecViewFromOptions(u, NULL, "-sol_vec_view");CHKERRQ(ierr);
244465876a83SMatthew G. Knepley 
244565876a83SMatthew G. Knepley   /* Cleanup */
244665876a83SMatthew G. Knepley   ierr = VecDestroy(&u);CHKERRQ(ierr);
244765876a83SMatthew G. Knepley   ierr = TSDestroy(&ts);CHKERRQ(ierr);
244865876a83SMatthew G. Knepley   ierr = DMDestroy(&dm);CHKERRQ(ierr);
244965876a83SMatthew G. Knepley   ierr = PetscBagDestroy(&ctx.bag);CHKERRQ(ierr);
245065876a83SMatthew G. Knepley   ierr = PetscFree(ctx.zeroArray);CHKERRQ(ierr);
245165876a83SMatthew G. Knepley   ierr = PetscFinalize();
245265876a83SMatthew G. Knepley   return ierr;
245365876a83SMatthew G. Knepley }
245465876a83SMatthew G. Knepley 
245565876a83SMatthew G. Knepley /*TEST
245665876a83SMatthew G. Knepley 
245765876a83SMatthew G. Knepley   test:
245865876a83SMatthew G. Knepley     suffix: 2d_quad_linear
245965876a83SMatthew G. Knepley     requires: triangle
246065876a83SMatthew G. Knepley     args: -sol_type quadratic_linear -dm_refine 2 \
246165876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
246265876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
246365876a83SMatthew G. Knepley 
246465876a83SMatthew G. Knepley   test:
246565876a83SMatthew G. Knepley     suffix: 3d_quad_linear
246665876a83SMatthew G. Knepley     requires: ctetgen
246765876a83SMatthew G. Knepley     args: -dim 3 -sol_type quadratic_linear -dm_refine 1 \
246865876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
246965876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
247065876a83SMatthew G. Knepley 
247165876a83SMatthew G. Knepley   test:
247265876a83SMatthew G. Knepley     suffix: 2d_trig_linear
247365876a83SMatthew G. Knepley     requires: triangle
247465876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
247565876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
247665876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_dt 0.00001 -ts_monitor_extreme
247765876a83SMatthew G. Knepley 
247865876a83SMatthew G. Knepley   test:
247965876a83SMatthew G. Knepley     # -dm_refine 2 -convest_num_refine 3 get L_2 convergence rate: [1.9, 2.1, 1.8]
248065876a83SMatthew G. Knepley     suffix: 2d_trig_linear_sconv
248165876a83SMatthew G. Knepley     requires: triangle
248265876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
248365876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
248465876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -ts_dt 0.00001 -pc_type lu
248565876a83SMatthew G. Knepley 
248665876a83SMatthew G. Knepley   test:
248765876a83SMatthew G. Knepley     suffix: 3d_trig_linear
248865876a83SMatthew G. Knepley     requires: ctetgen
248965876a83SMatthew G. Knepley     args: -dim 3 -sol_type trig_linear -dm_refine 1 \
249065876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
249165876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 2 -ts_monitor_extreme
249265876a83SMatthew G. Knepley 
249365876a83SMatthew G. Knepley   test:
249465876a83SMatthew G. Knepley     # -dm_refine 1 -convest_num_refine 2 gets L_2 convergence rate: [2.0, 2.1, 1.9]
249565876a83SMatthew G. Knepley     suffix: 3d_trig_linear_sconv
249665876a83SMatthew G. Knepley     requires: ctetgen
249765876a83SMatthew G. Knepley     args: -dim 3 -sol_type trig_linear -dm_refine 1 \
249865876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
249965876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -pc_type lu
250065876a83SMatthew G. Knepley 
250165876a83SMatthew G. Knepley   test:
250265876a83SMatthew G. Knepley     suffix: 2d_quad_trig
250365876a83SMatthew G. Knepley     requires: triangle
250465876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 2 \
250565876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
250665876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
250765876a83SMatthew G. Knepley 
250865876a83SMatthew G. Knepley   test:
250965876a83SMatthew G. Knepley     # Using -dm_refine 4 gets the convergence rates to [0.95, 0.97, 0.90]
251065876a83SMatthew G. Knepley     suffix: 2d_quad_trig_tconv
251165876a83SMatthew G. Knepley     requires: triangle
251265876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 1 \
251365876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
251465876a83SMatthew G. Knepley       -convest_num_refine 3 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
251565876a83SMatthew G. Knepley 
251665876a83SMatthew G. Knepley   test:
251765876a83SMatthew G. Knepley     suffix: 3d_quad_trig
251865876a83SMatthew G. Knepley     requires: ctetgen
251965876a83SMatthew G. Knepley     args: -dim 3 -sol_type quadratic_trig -dm_refine 1 \
252065876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
252165876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
252265876a83SMatthew G. Knepley 
252365876a83SMatthew G. Knepley   test:
252465876a83SMatthew G. Knepley     # Using -dm_refine 2 -convest_num_refine 3 gets the convergence rates to [1.0, 1.0, 1.0]
252565876a83SMatthew G. Knepley     suffix: 3d_quad_trig_tconv
252665876a83SMatthew G. Knepley     requires: ctetgen
252765876a83SMatthew G. Knepley     args: -dim 3 -sol_type quadratic_trig -dm_refine 1 \
252865876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
252965876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
253065876a83SMatthew G. Knepley 
253165876a83SMatthew G. Knepley   test:
253265876a83SMatthew G. Knepley     suffix: 2d_terzaghi
253365876a83SMatthew G. Knepley     requires: triangle
253465876a83SMatthew G. Knepley     args: -sol_type terzaghi -dm_plex_separate_marker -dm_plex_box_faces 1,8 -simplex 0 \
253565876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 -niter 16000 \
253665876a83SMatthew G. Knepley       -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001 -pc_type lu
253765876a83SMatthew G. Knepley 
253865876a83SMatthew G. Knepley   test:
253965876a83SMatthew 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]
254065876a83SMatthew G. Knepley     suffix: 2d_terzaghi_tconv
254165876a83SMatthew G. Knepley     requires: triangle
254265876a83SMatthew G. Knepley     args: -sol_type terzaghi -dm_plex_separate_marker -dm_plex_box_faces 1,8 -simplex 0 \
254365876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 -niter 16000 \
254465876a83SMatthew G. Knepley       -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1 -pc_type lu
254565876a83SMatthew G. Knepley 
254665876a83SMatthew G. Knepley   test:
254724b15d09SMatthew G. Knepley     # -dm_plex_box_faces 1,16 -convest_num_refine 4 gives L_2 convergence rate: [1.7, 1.2, 1.1]
254824b15d09SMatthew 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], so I think we lose an order
254924b15d09SMatthew G. Knepley     suffix: 2d_terzaghi_sconv
255024b15d09SMatthew G. Knepley     requires: triangle
255124b15d09SMatthew G. Knepley     args: -sol_type terzaghi -dm_plex_separate_marker -dm_plex_box_faces 1,8 -simplex 0 \
255224b15d09SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 -niter 16000 \
255324b15d09SMatthew G. Knepley       -ts_dt 1e-5 -dt_initial 1e-5 -ts_max_steps 2 -ts_convergence_estimate -ts_convergence_temporal 0 -convest_num_refine 1 -pc_type lu
255424b15d09SMatthew G. Knepley 
255524b15d09SMatthew G. Knepley   test:
255665876a83SMatthew G. Knepley     suffix: 2d_mandel
255765876a83SMatthew G. Knepley     requires: triangle
255865876a83SMatthew G. Knepley     args: -sol_type mandel -dm_plex_separate_marker -dm_refine 1 \
255965876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
256065876a83SMatthew G. Knepley       -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001 -pc_type lu
256165876a83SMatthew G. Knepley 
256265876a83SMatthew G. Knepley   test:
256365876a83SMatthew G. Knepley     # -dm_refine 5 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [0.26, -0.0058, 0.26]
256465876a83SMatthew G. Knepley     suffix: 2d_mandel_tconv
256565876a83SMatthew G. Knepley     requires: triangle
256665876a83SMatthew G. Knepley     args: -sol_type mandel -dm_plex_separate_marker -dm_refine 1 \
256765876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
256865876a83SMatthew G. Knepley       -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1 -pc_type lu
256965876a83SMatthew G. Knepley 
257065876a83SMatthew G. Knepley   test:
257165876a83SMatthew G. Knepley     suffix: 3d_cryer
257265876a83SMatthew G. Knepley     requires: ctetgen !complex
257365876a83SMatthew G. Knepley     args: -sol_type cryer \
257465876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
25750fdc7489SMatthew Knepley       -ts_dt 0.0028666667 -ts_max_time 0.014333 -ts_max_steps 2 -dmts_check .0001 -pc_type svd
257665876a83SMatthew G. Knepley 
257765876a83SMatthew G. Knepley   test:
257865876a83SMatthew G. Knepley     # Displacement and Pressure converge. The analytic expression for trace strain is inaccurate at the origin
257965876a83SMatthew 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]
258065876a83SMatthew G. Knepley     suffix: 3d_cryer_tconv
258165876a83SMatthew G. Knepley     requires: ctetgen !complex
258265876a83SMatthew G. Knepley     args: -sol_type cryer -bd_dm_refine 1 -ref_limit 0.00666667 \
258365876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
258465876a83SMatthew G. Knepley       -ts_dt 0.023 -ts_max_time 0.092 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1 -pc_type lu -pc_factor_shift_type nonzero
258565876a83SMatthew G. Knepley 
258665876a83SMatthew G. Knepley TEST*/
2587