xref: /petsc/src/ts/tutorials/ex53.c (revision 65876a83dd1eebc719715f276f4f84d6da2015b3)
1*65876a83SMatthew G. Knepley static char help[] = "Time dependent Biot Poroelasticity problem with finite elements.\n\
2*65876a83SMatthew G. Knepley We solve three field, quasi-static poroelasticity in a rectangular\n\
3*65876a83SMatthew G. Knepley domain, using a parallel unstructured mesh (DMPLEX) to discretize it.\n\
4*65876a83SMatthew G. Knepley Contributed by: Robert Walker <rwalker6@buffalo.edu>\n\n\n";
5*65876a83SMatthew G. Knepley 
6*65876a83SMatthew G. Knepley #include <petscdmplex.h>
7*65876a83SMatthew G. Knepley #include <petscsnes.h>
8*65876a83SMatthew G. Knepley #include <petscts.h>
9*65876a83SMatthew G. Knepley #include <petscds.h>
10*65876a83SMatthew G. Knepley #include <petscbag.h>
11*65876a83SMatthew G. Knepley 
12*65876a83SMatthew G. Knepley #include <petsc/private/tsimpl.h>
13*65876a83SMatthew G. Knepley 
14*65876a83SMatthew G. Knepley /* This presentation of poroelasticity is taken from
15*65876a83SMatthew G. Knepley 
16*65876a83SMatthew G. Knepley @book{Cheng2016,
17*65876a83SMatthew G. Knepley   title={Poroelasticity},
18*65876a83SMatthew G. Knepley   author={Cheng, Alexander H-D},
19*65876a83SMatthew G. Knepley   volume={27},
20*65876a83SMatthew G. Knepley   year={2016},
21*65876a83SMatthew G. Knepley   publisher={Springer}
22*65876a83SMatthew G. Knepley }
23*65876a83SMatthew G. Knepley 
24*65876a83SMatthew G. Knepley For visualization, use
25*65876a83SMatthew G. Knepley 
26*65876a83SMatthew G. Knepley   -dm_view hdf5:${PETSC_DIR}/sol.h5 -monitor_solution hdf5:${PETSC_DIR}/sol.h5::append
27*65876a83SMatthew G. Knepley 
28*65876a83SMatthew G. Knepley The weak form would then be, using test function $(v, q, \tau)$,
29*65876a83SMatthew G. Knepley 
30*65876a83SMatthew G. Knepley             (q, \frac{1}{M} \frac{dp}{dt}) + (q, \alpha \frac{d\varepsilon}{dt}) + (\nabla q, \kappa \nabla p) = (q, g)
31*65876a83SMatthew 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)
32*65876a83SMatthew G. Knepley                                                                           (\tau, \nabla \cdot u - \varepsilon) = 0
33*65876a83SMatthew G. Knepley */
34*65876a83SMatthew G. Knepley 
35*65876a83SMatthew G. Knepley typedef enum {SOL_QUADRATIC_LINEAR, SOL_QUADRATIC_TRIG, SOL_TRIG_LINEAR, SOL_TERZAGHI, SOL_MANDEL, SOL_CRYER, NUM_SOLUTION_TYPES} SolutionType;
36*65876a83SMatthew G. Knepley const char *solutionTypes[NUM_SOLUTION_TYPES+1] = {"quadratic_linear", "quadratic_trig", "trig_linear", "terzaghi", "mandel", "cryer", "unknown"};
37*65876a83SMatthew G. Knepley 
38*65876a83SMatthew G. Knepley typedef struct {
39*65876a83SMatthew G. Knepley   PetscScalar mu;    /* shear modulus */
40*65876a83SMatthew G. Knepley   PetscScalar K_u;   /* undrained bulk modulus */
41*65876a83SMatthew G. Knepley   PetscScalar alpha; /* Biot effective stress coefficient */
42*65876a83SMatthew G. Knepley   PetscScalar M;     /* Biot modulus */
43*65876a83SMatthew G. Knepley   PetscScalar k;     /* (isotropic) permeability */
44*65876a83SMatthew G. Knepley   PetscScalar mu_f;  /* fluid dynamic viscosity */
45*65876a83SMatthew G. Knepley   PetscReal   zmax;  /* depth maximum extent */
46*65876a83SMatthew G. Knepley   PetscReal   zmin;  /* depth minimum extent */
47*65876a83SMatthew G. Knepley   PetscReal   ymax;  /* vertical maximum extent */
48*65876a83SMatthew G. Knepley   PetscReal   ymin;  /* vertical minimum extent */
49*65876a83SMatthew G. Knepley   PetscReal   xmax;  /* horizontal maximum extent */
50*65876a83SMatthew G. Knepley   PetscReal   xmin;  /* horizontal minimum extent */
51*65876a83SMatthew G. Knepley   PetscScalar P_0;   /* magnitude of vertical stress */
52*65876a83SMatthew G. Knepley } Parameter;
53*65876a83SMatthew G. Knepley 
54*65876a83SMatthew G. Knepley typedef struct {
55*65876a83SMatthew G. Knepley   /* Domain and mesh definition */
56*65876a83SMatthew G. Knepley   char         dmType[256]; /* DM type for the solve */
57*65876a83SMatthew G. Knepley   PetscInt     dim;         /* The topological mesh dimension */
58*65876a83SMatthew G. Knepley   PetscBool    simplex;     /* Simplicial mesh */
59*65876a83SMatthew G. Knepley   PetscReal    refLimit;    /* Refine mesh with generator */
60*65876a83SMatthew G. Knepley   /* Problem definition */
61*65876a83SMatthew G. Knepley   SolutionType solType;     /* Type of exact solution */
62*65876a83SMatthew G. Knepley   PetscBag     bag;         /* Problem parameters */
63*65876a83SMatthew G. Knepley   PetscReal    t_r;         /* Relaxation time: 4 L^2 / c */
64*65876a83SMatthew G. Knepley   /* Exact solution terms */
65*65876a83SMatthew G. Knepley   PetscInt    niter; /* Number of series term iterations in exact solutions */
66*65876a83SMatthew G. Knepley   PetscReal   eps;   /* Precision value for root finding */
67*65876a83SMatthew G. Knepley   PetscReal  *zeroArray; /* Array of root locations */
68*65876a83SMatthew G. Knepley } AppCtx;
69*65876a83SMatthew G. Knepley 
70*65876a83SMatthew G. Knepley static PetscErrorCode zero(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
71*65876a83SMatthew G. Knepley {
72*65876a83SMatthew G. Knepley   PetscInt c;
73*65876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) u[c] = 0.0;
74*65876a83SMatthew G. Knepley   return 0;
75*65876a83SMatthew G. Knepley }
76*65876a83SMatthew G. Knepley 
77*65876a83SMatthew G. Knepley /* Quadratic space and linear time solution
78*65876a83SMatthew G. Knepley 
79*65876a83SMatthew G. Knepley   2D:
80*65876a83SMatthew G. Knepley   u = x^2
81*65876a83SMatthew G. Knepley   v = y^2 - 2xy
82*65876a83SMatthew G. Knepley   p = (x + y) t
83*65876a83SMatthew G. Knepley   e = 2y
84*65876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha t, alpha t>
85*65876a83SMatthew G. Knepley   g = 0
86*65876a83SMatthew G. Knepley   \epsilon = / 2x     -y    \
87*65876a83SMatthew G. Knepley              \ -y   2y - 2x /
88*65876a83SMatthew G. Knepley   Tr(\epsilon) = e = div u = 2y
89*65876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
90*65876a83SMatthew G. Knepley     = 2 G < 2-1, 2 > + \lambda <0, 2> - alpha <t, t>
91*65876a83SMatthew G. Knepley     = <2 G, 4 G + 2 \lambda> - <alpha t, alpha t>
92*65876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
93*65876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
94*65876a83SMatthew G. Knepley     = (x + y)/M
95*65876a83SMatthew G. Knepley 
96*65876a83SMatthew G. Knepley   3D:
97*65876a83SMatthew G. Knepley   u = x^2
98*65876a83SMatthew G. Knepley   v = y^2 - 2xy
99*65876a83SMatthew G. Knepley   w = z^2 - 2yz
100*65876a83SMatthew G. Knepley   p = (x + y + z) t
101*65876a83SMatthew G. Knepley   e = 2z
102*65876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha t, alpha t, alpha t>
103*65876a83SMatthew G. Knepley   g = 0
104*65876a83SMatthew G. Knepley   \varepsilon = / 2x     -y       0   \
105*65876a83SMatthew G. Knepley                 | -y   2y - 2x   -z   |
106*65876a83SMatthew G. Knepley                 \  0     -z    2z - 2y/
107*65876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2z
108*65876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
109*65876a83SMatthew G. Knepley     = 2 G < 2-1, 2-1, 2 > + \lambda <0, 0, 2> - alpha <t, t, t>
110*65876a83SMatthew G. Knepley     = <2 G, 2G, 4 G + 2 \lambda> - <alpha t, alpha t, alpha t>
111*65876a83SMatthew G. Knepley */
112*65876a83SMatthew G. Knepley static PetscErrorCode quadratic_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
113*65876a83SMatthew G. Knepley {
114*65876a83SMatthew G. Knepley   PetscInt d;
115*65876a83SMatthew G. Knepley 
116*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
117*65876a83SMatthew G. Knepley     u[d] = PetscSqr(x[d]) - (d > 0 ? 2.0 * x[d-1] * x[d] : 0.0);
118*65876a83SMatthew G. Knepley   }
119*65876a83SMatthew G. Knepley   return 0;
120*65876a83SMatthew G. Knepley }
121*65876a83SMatthew G. Knepley 
122*65876a83SMatthew G. Knepley static PetscErrorCode linear_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
123*65876a83SMatthew G. Knepley {
124*65876a83SMatthew G. Knepley   u[0] = 2.0*x[dim-1];
125*65876a83SMatthew G. Knepley   return 0;
126*65876a83SMatthew G. Knepley }
127*65876a83SMatthew G. Knepley 
128*65876a83SMatthew G. Knepley static PetscErrorCode linear_linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
129*65876a83SMatthew G. Knepley {
130*65876a83SMatthew G. Knepley   PetscReal sum = 0.0;
131*65876a83SMatthew G. Knepley   PetscInt  d;
132*65876a83SMatthew G. Knepley 
133*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
134*65876a83SMatthew G. Knepley   u[0] = sum*time;
135*65876a83SMatthew G. Knepley   return 0;
136*65876a83SMatthew G. Knepley }
137*65876a83SMatthew G. Knepley 
138*65876a83SMatthew G. Knepley static PetscErrorCode linear_linear_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
139*65876a83SMatthew G. Knepley {
140*65876a83SMatthew G. Knepley   PetscReal sum = 0.0;
141*65876a83SMatthew G. Knepley   PetscInt  d;
142*65876a83SMatthew G. Knepley 
143*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
144*65876a83SMatthew G. Knepley   u[0] = sum;
145*65876a83SMatthew G. Knepley   return 0;
146*65876a83SMatthew G. Knepley }
147*65876a83SMatthew G. Knepley 
148*65876a83SMatthew G. Knepley static void f0_quadratic_linear_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
149*65876a83SMatthew G. Knepley                                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
150*65876a83SMatthew G. Knepley                                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
151*65876a83SMatthew G. Knepley                                   PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
152*65876a83SMatthew G. Knepley {
153*65876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
154*65876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
155*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
156*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
157*65876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
158*65876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
159*65876a83SMatthew G. Knepley   PetscInt        d;
160*65876a83SMatthew G. Knepley 
161*65876a83SMatthew G. Knepley   for (d = 0; d < dim-1; ++d) {
162*65876a83SMatthew G. Knepley     f0[d] -= 2.0*G - alpha*t;
163*65876a83SMatthew G. Knepley   }
164*65876a83SMatthew G. Knepley   f0[dim-1] -= 2.0*lambda + 4.0*G - alpha*t;
165*65876a83SMatthew G. Knepley }
166*65876a83SMatthew G. Knepley 
167*65876a83SMatthew G. Knepley static void f0_quadratic_linear_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
168*65876a83SMatthew G. Knepley                                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
169*65876a83SMatthew G. Knepley                                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
170*65876a83SMatthew G. Knepley                                   PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
171*65876a83SMatthew G. Knepley {
172*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
173*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
174*65876a83SMatthew G. Knepley   PetscReal       sum    = 0.0;
175*65876a83SMatthew G. Knepley   PetscInt        d;
176*65876a83SMatthew G. Knepley 
177*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
178*65876a83SMatthew G. Knepley   f0[0] += u_t ? alpha*u_t[uOff[1]] : 0.0;
179*65876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]]/M     : 0.0;
180*65876a83SMatthew G. Knepley   f0[0] -= sum/M;
181*65876a83SMatthew G. Knepley }
182*65876a83SMatthew G. Knepley 
183*65876a83SMatthew G. Knepley /* Quadratic space and trigonometric time solution
184*65876a83SMatthew G. Knepley 
185*65876a83SMatthew G. Knepley   2D:
186*65876a83SMatthew G. Knepley   u = x^2
187*65876a83SMatthew G. Knepley   v = y^2 - 2xy
188*65876a83SMatthew G. Knepley   p = (x + y) cos(t)
189*65876a83SMatthew G. Knepley   e = 2y
190*65876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha cos(t), alpha cos(t)>
191*65876a83SMatthew G. Knepley   g = 0
192*65876a83SMatthew G. Knepley   \epsilon = / 2x     -y    \
193*65876a83SMatthew G. Knepley              \ -y   2y - 2x /
194*65876a83SMatthew G. Knepley   Tr(\epsilon) = e = div u = 2y
195*65876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
196*65876a83SMatthew G. Knepley     = 2 G < 2-1, 2 > + \lambda <0, 2> - alpha <cos(t), cos(t)>
197*65876a83SMatthew G. Knepley     = <2 G, 4 G + 2 \lambda> - <alpha cos(t), alpha cos(t)>
198*65876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
199*65876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
200*65876a83SMatthew G. Knepley     = -(x + y)/M sin(t)
201*65876a83SMatthew G. Knepley 
202*65876a83SMatthew G. Knepley   3D:
203*65876a83SMatthew G. Knepley   u = x^2
204*65876a83SMatthew G. Knepley   v = y^2 - 2xy
205*65876a83SMatthew G. Knepley   w = z^2 - 2yz
206*65876a83SMatthew G. Knepley   p = (x + y + z) cos(t)
207*65876a83SMatthew G. Knepley   e = 2z
208*65876a83SMatthew G. Knepley   f = <2 G, 4 G + 2 \lambda > - <alpha cos(t), alpha cos(t), alpha cos(t)>
209*65876a83SMatthew G. Knepley   g = 0
210*65876a83SMatthew G. Knepley   \varepsilon = / 2x     -y       0   \
211*65876a83SMatthew G. Knepley                 | -y   2y - 2x   -z   |
212*65876a83SMatthew G. Knepley                 \  0     -z    2z - 2y/
213*65876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2z
214*65876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
215*65876a83SMatthew G. Knepley     = 2 G < 2-1, 2-1, 2 > + \lambda <0, 0, 2> - alpha <cos(t), cos(t), cos(t)>
216*65876a83SMatthew G. Knepley     = <2 G, 2G, 4 G + 2 \lambda> - <alpha cos(t), alpha cos(t), alpha cos(t)>
217*65876a83SMatthew G. Knepley */
218*65876a83SMatthew G. Knepley static PetscErrorCode linear_trig_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
219*65876a83SMatthew G. Knepley {
220*65876a83SMatthew G. Knepley   PetscReal sum = 0.0;
221*65876a83SMatthew G. Knepley   PetscInt  d;
222*65876a83SMatthew G. Knepley 
223*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
224*65876a83SMatthew G. Knepley   u[0] = sum*PetscCosReal(time);
225*65876a83SMatthew G. Knepley   return 0;
226*65876a83SMatthew G. Knepley }
227*65876a83SMatthew G. Knepley 
228*65876a83SMatthew G. Knepley static PetscErrorCode linear_trig_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
229*65876a83SMatthew G. Knepley {
230*65876a83SMatthew G. Knepley   PetscReal sum = 0.0;
231*65876a83SMatthew G. Knepley   PetscInt  d;
232*65876a83SMatthew G. Knepley 
233*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
234*65876a83SMatthew G. Knepley   u[0] = -sum*PetscSinReal(time);
235*65876a83SMatthew G. Knepley   return 0;
236*65876a83SMatthew G. Knepley }
237*65876a83SMatthew G. Knepley 
238*65876a83SMatthew G. Knepley static void f0_quadratic_trig_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
239*65876a83SMatthew G. Knepley                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
240*65876a83SMatthew G. Knepley                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
241*65876a83SMatthew G. Knepley                                 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
242*65876a83SMatthew G. Knepley {
243*65876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
244*65876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
245*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
246*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
247*65876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
248*65876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
249*65876a83SMatthew G. Knepley   PetscInt        d;
250*65876a83SMatthew G. Knepley 
251*65876a83SMatthew G. Knepley   for (d = 0; d < dim-1; ++d) {
252*65876a83SMatthew G. Knepley     f0[d] -= 2.0*G - alpha*PetscCosReal(t);
253*65876a83SMatthew G. Knepley   }
254*65876a83SMatthew G. Knepley   f0[dim-1] -= 2.0*lambda + 4.0*G - alpha*PetscCosReal(t);
255*65876a83SMatthew G. Knepley }
256*65876a83SMatthew G. Knepley 
257*65876a83SMatthew G. Knepley static void f0_quadratic_trig_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
258*65876a83SMatthew G. Knepley                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
259*65876a83SMatthew G. Knepley                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
260*65876a83SMatthew G. Knepley                                 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
261*65876a83SMatthew G. Knepley {
262*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
263*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
264*65876a83SMatthew G. Knepley   PetscReal       sum    = 0.0;
265*65876a83SMatthew G. Knepley   PetscInt        d;
266*65876a83SMatthew G. Knepley 
267*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += x[d];
268*65876a83SMatthew G. Knepley 
269*65876a83SMatthew G. Knepley   f0[0] += u_t ? alpha*u_t[uOff[1]] : 0.0;
270*65876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]]/M     : 0.0;
271*65876a83SMatthew G. Knepley   f0[0] += PetscSinReal(t)*sum/M;
272*65876a83SMatthew G. Knepley }
273*65876a83SMatthew G. Knepley 
274*65876a83SMatthew G. Knepley /* Trigonometric space and linear time solution
275*65876a83SMatthew G. Knepley 
276*65876a83SMatthew G. Knepley u = sin(2 pi x)
277*65876a83SMatthew G. Knepley v = sin(2 pi y) - 2xy
278*65876a83SMatthew G. Knepley \varepsilon = / 2 pi cos(2 pi x)             -y        \
279*65876a83SMatthew G. Knepley               \      -y          2 pi cos(2 pi y) - 2x /
280*65876a83SMatthew G. Knepley Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
281*65876a83SMatthew G. Knepley div \sigma = \partial_i \lambda \delta_{ij} \varepsilon_{kk} + \partial_i 2\mu\varepsilon_{ij}
282*65876a83SMatthew 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) >
283*65876a83SMatthew 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) >
284*65876a83SMatthew G. Knepley 
285*65876a83SMatthew G. Knepley   2D:
286*65876a83SMatthew G. Knepley   u = sin(2 pi x)
287*65876a83SMatthew G. Knepley   v = sin(2 pi y) - 2xy
288*65876a83SMatthew G. Knepley   p = (cos(2 pi x) + cos(2 pi y)) t
289*65876a83SMatthew G. Knepley   e = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
290*65876a83SMatthew 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)>
291*65876a83SMatthew G. Knepley   g = 0
292*65876a83SMatthew G. Knepley   \varepsilon = / 2 pi cos(2 pi x)             -y        \
293*65876a83SMatthew G. Knepley                 \      -y          2 pi cos(2 pi y) - 2x /
294*65876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y)) - 2 x
295*65876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
296*65876a83SMatthew 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>
297*65876a83SMatthew 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)>
298*65876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
299*65876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
300*65876a83SMatthew G. Knepley     = (cos(2 pi x) + cos(2 pi y))/M - 4 pi^2 \kappa (cos(2 pi x) + cos(2 pi y)) t
301*65876a83SMatthew G. Knepley 
302*65876a83SMatthew G. Knepley   3D:
303*65876a83SMatthew G. Knepley   u = sin(2 pi x)
304*65876a83SMatthew G. Knepley   v = sin(2 pi y) - 2xy
305*65876a83SMatthew G. Knepley   v = sin(2 pi y) - 2yz
306*65876a83SMatthew G. Knepley   p = (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) t
307*65876a83SMatthew G. Knepley   e = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2y
308*65876a83SMatthew 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)>
309*65876a83SMatthew G. Knepley   g = 0
310*65876a83SMatthew G. Knepley   \varepsilon = / 2 pi cos(2 pi x)            -y                     0         \
311*65876a83SMatthew G. Knepley                 |         -y       2 pi cos(2 pi y) - 2x            -z         |
312*65876a83SMatthew G. Knepley                 \          0                  -z         2 pi cos(2 pi z) - 2y /
313*65876a83SMatthew G. Knepley   Tr(\varepsilon) = div u = 2 pi (cos(2 pi x) + cos(2 pi y) + cos(2 pi z)) - 2 x - 2 y
314*65876a83SMatthew G. Knepley   div \sigma = \partial_i 2 G \epsilon_{ij} + \partial_i \lambda \varepsilon \delta_{ij} - \partial_i \alpha p \delta_{ij}
315*65876a83SMatthew 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>
316*65876a83SMatthew 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)>
317*65876a83SMatthew G. Knepley   \frac{1}{M} \frac{dp}{dt} + \alpha \frac{d\varepsilon}{dt} - \nabla \cdot \kappa \nabla p
318*65876a83SMatthew G. Knepley     = \frac{1}{M} \frac{dp}{dt} + \kappa \Delta p
319*65876a83SMatthew 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
320*65876a83SMatthew G. Knepley */
321*65876a83SMatthew G. Knepley static PetscErrorCode trig_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
322*65876a83SMatthew G. Knepley {
323*65876a83SMatthew G. Knepley   PetscInt d;
324*65876a83SMatthew G. Knepley 
325*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
326*65876a83SMatthew G. Knepley     u[d] = PetscSinReal(2.*PETSC_PI*x[d]) - (d > 0 ? 2.0 * x[d-1] * x[d] : 0.0);
327*65876a83SMatthew G. Knepley   }
328*65876a83SMatthew G. Knepley   return 0;
329*65876a83SMatthew G. Knepley }
330*65876a83SMatthew G. Knepley 
331*65876a83SMatthew G. Knepley static PetscErrorCode trig_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
332*65876a83SMatthew G. Knepley {
333*65876a83SMatthew G. Knepley   PetscReal sum = 0.0;
334*65876a83SMatthew G. Knepley   PetscInt  d;
335*65876a83SMatthew G. Knepley 
336*65876a83SMatthew 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);
337*65876a83SMatthew G. Knepley   u[0] = sum;
338*65876a83SMatthew G. Knepley   return 0;
339*65876a83SMatthew G. Knepley }
340*65876a83SMatthew G. Knepley 
341*65876a83SMatthew G. Knepley static PetscErrorCode trig_linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
342*65876a83SMatthew G. Knepley {
343*65876a83SMatthew G. Knepley   PetscReal sum = 0.0;
344*65876a83SMatthew G. Knepley   PetscInt  d;
345*65876a83SMatthew G. Knepley 
346*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2.*PETSC_PI*x[d]);
347*65876a83SMatthew G. Knepley   u[0] = sum*time;
348*65876a83SMatthew G. Knepley   return 0;
349*65876a83SMatthew G. Knepley }
350*65876a83SMatthew G. Knepley 
351*65876a83SMatthew G. Knepley static PetscErrorCode trig_linear_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
352*65876a83SMatthew G. Knepley {
353*65876a83SMatthew G. Knepley   PetscReal sum = 0.0;
354*65876a83SMatthew G. Knepley   PetscInt  d;
355*65876a83SMatthew G. Knepley 
356*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2.*PETSC_PI*x[d]);
357*65876a83SMatthew G. Knepley   u[0] = sum;
358*65876a83SMatthew G. Knepley   return 0;
359*65876a83SMatthew G. Knepley }
360*65876a83SMatthew G. Knepley 
361*65876a83SMatthew G. Knepley static void f0_trig_linear_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
362*65876a83SMatthew G. Knepley                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
363*65876a83SMatthew G. Knepley                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
364*65876a83SMatthew G. Knepley                              PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
365*65876a83SMatthew G. Knepley {
366*65876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
367*65876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
368*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
369*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
370*65876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
371*65876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
372*65876a83SMatthew G. Knepley   PetscInt        d;
373*65876a83SMatthew G. Knepley 
374*65876a83SMatthew G. Knepley   for (d = 0; d < dim-1; ++d) {
375*65876a83SMatthew 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;
376*65876a83SMatthew G. Knepley   }
377*65876a83SMatthew 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;
378*65876a83SMatthew G. Knepley }
379*65876a83SMatthew G. Knepley 
380*65876a83SMatthew G. Knepley static void f0_trig_linear_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
381*65876a83SMatthew G. Knepley                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
382*65876a83SMatthew G. Knepley                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
383*65876a83SMatthew G. Knepley                              PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
384*65876a83SMatthew G. Knepley {
385*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
386*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
387*65876a83SMatthew G. Knepley   const PetscReal kappa  = PetscRealPart(constants[4]);
388*65876a83SMatthew G. Knepley   PetscReal       sum    = 0.0;
389*65876a83SMatthew G. Knepley   PetscInt        d;
390*65876a83SMatthew G. Knepley 
391*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) sum += PetscCosReal(2.*PETSC_PI*x[d]);
392*65876a83SMatthew G. Knepley   f0[0] += u_t ? alpha*u_t[uOff[1]] : 0.0;
393*65876a83SMatthew G. Knepley   f0[0] += u_t ? u_t[uOff[2]]/M     : 0.0;
394*65876a83SMatthew G. Knepley   f0[0] -= sum/M - 4*PetscSqr(PETSC_PI)*kappa*sum*t;
395*65876a83SMatthew G. Knepley }
396*65876a83SMatthew G. Knepley 
397*65876a83SMatthew G. Knepley /* Terzaghi Solutions */
398*65876a83SMatthew G. Knepley /* The analytical solutions given here are drawn from chapter 7, section 3, */
399*65876a83SMatthew G. Knepley /* "One-Dimensional Consolidation Problem," from Poroelasticity, by Cheng.  */
400*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
401*65876a83SMatthew G. Knepley {
402*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
403*65876a83SMatthew G. Knepley   Parameter     *param;
404*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
405*65876a83SMatthew G. Knepley 
406*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
407*65876a83SMatthew G. Knepley   if (time <= 0.0) {
408*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
409*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
410*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
411*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
412*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
413*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
414*65876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
415*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
416*65876a83SMatthew G. Knepley 
417*65876a83SMatthew G. Knepley     u[0] = ((P_0*eta) / (G*S));
418*65876a83SMatthew G. Knepley   } else {
419*65876a83SMatthew G. Knepley     u[0] = 0.0;
420*65876a83SMatthew G. Knepley   }
421*65876a83SMatthew G. Knepley   return 0;
422*65876a83SMatthew G. Knepley }
423*65876a83SMatthew G. Knepley 
424*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
425*65876a83SMatthew G. Knepley {
426*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
427*65876a83SMatthew G. Knepley   Parameter     *param;
428*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
429*65876a83SMatthew G. Knepley 
430*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
431*65876a83SMatthew G. Knepley   {
432*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
433*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
434*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
435*65876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
436*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G)); /* -,       Cheng (B.9)  */
437*65876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                /* - */
438*65876a83SMatthew G. Knepley 
439*65876a83SMatthew G. Knepley     u[0] = 0.0;
440*65876a83SMatthew G. Knepley     u[1] = ((P_0*L*(1.0 - 2.0*nu_u)) / (2.0*G*(1.0 - nu_u))) * (1.0 - zstar);
441*65876a83SMatthew G. Knepley   }
442*65876a83SMatthew G. Knepley   return 0;
443*65876a83SMatthew G. Knepley }
444*65876a83SMatthew G. Knepley 
445*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
446*65876a83SMatthew G. Knepley {
447*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
448*65876a83SMatthew G. Knepley   Parameter     *param;
449*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
450*65876a83SMatthew G. Knepley 
451*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
452*65876a83SMatthew G. Knepley   {
453*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
454*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
455*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
456*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
457*65876a83SMatthew G. Knepley 
458*65876a83SMatthew G. Knepley     u[0] = -(P_0*(1.0 - 2.0*nu_u)) / (2.0*G*(1.0 - nu_u));
459*65876a83SMatthew G. Knepley   }
460*65876a83SMatthew G. Knepley   return 0;
461*65876a83SMatthew G. Knepley }
462*65876a83SMatthew G. Knepley 
463*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
464*65876a83SMatthew G. Knepley {
465*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
466*65876a83SMatthew G. Knepley   Parameter     *param;
467*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
468*65876a83SMatthew G. Knepley 
469*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
470*65876a83SMatthew G. Knepley   if (time < 0.0) {
471*65876a83SMatthew G. Knepley     ierr = terzaghi_initial_u(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
472*65876a83SMatthew G. Knepley   } else {
473*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
474*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
475*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
476*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
477*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
478*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
479*65876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
480*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
481*65876a83SMatthew G. Knepley 
482*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
483*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
484*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
485*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
486*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
487*65876a83SMatthew G. Knepley 
488*65876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
489*65876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
490*65876a83SMatthew G. Knepley     PetscScalar F2    = 0.0;
491*65876a83SMatthew G. Knepley 
492*65876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
493*65876a83SMatthew G. Knepley       if (m%2 == 1) {
494*65876a83SMatthew G. Knepley         F2 += (8.0 / PetscSqr(m*PETSC_PI)) * PetscCosReal(0.5*m*PETSC_PI*zstar) * (1.0 - PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar));
495*65876a83SMatthew G. Knepley       }
496*65876a83SMatthew G. Knepley     }
497*65876a83SMatthew G. Knepley     u[0] = 0.0;
498*65876a83SMatthew 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 */
499*65876a83SMatthew G. Knepley   }
500*65876a83SMatthew G. Knepley   return 0;
501*65876a83SMatthew G. Knepley }
502*65876a83SMatthew G. Knepley 
503*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
504*65876a83SMatthew G. Knepley {
505*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
506*65876a83SMatthew G. Knepley   Parameter     *param;
507*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
508*65876a83SMatthew G. Knepley 
509*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
510*65876a83SMatthew G. Knepley   if (time < 0.0) {
511*65876a83SMatthew G. Knepley     ierr = terzaghi_initial_eps(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
512*65876a83SMatthew G. Knepley   } else {
513*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
514*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
515*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
516*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
517*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
518*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
519*65876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
520*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
521*65876a83SMatthew G. Knepley 
522*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
523*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
524*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
525*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
526*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
527*65876a83SMatthew G. Knepley 
528*65876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
529*65876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
530*65876a83SMatthew G. Knepley     PetscScalar F2_z  = 0.0;
531*65876a83SMatthew G. Knepley 
532*65876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
533*65876a83SMatthew G. Knepley       if (m%2 == 1) {
534*65876a83SMatthew 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));
535*65876a83SMatthew G. Knepley       }
536*65876a83SMatthew G. Knepley     }
537*65876a83SMatthew 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; /* - */
538*65876a83SMatthew G. Knepley   }
539*65876a83SMatthew G. Knepley   return 0;
540*65876a83SMatthew G. Knepley }
541*65876a83SMatthew G. Knepley 
542*65876a83SMatthew G. Knepley // Pressure
543*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
544*65876a83SMatthew G. Knepley {
545*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
546*65876a83SMatthew G. Knepley   Parameter     *param;
547*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
548*65876a83SMatthew G. Knepley 
549*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
550*65876a83SMatthew G. Knepley   if (time <= 0.0) {
551*65876a83SMatthew G. Knepley     ierr = terzaghi_drainage_pressure(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
552*65876a83SMatthew G. Knepley   } else {
553*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
554*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
555*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
556*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
557*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
558*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
559*65876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
560*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
561*65876a83SMatthew G. Knepley 
562*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
563*65876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
564*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
565*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
566*65876a83SMatthew G. Knepley 
567*65876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
568*65876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
569*65876a83SMatthew G. Knepley     PetscScalar F1    = 0.0;
570*65876a83SMatthew G. Knepley 
571*65876a83SMatthew 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));
572*65876a83SMatthew G. Knepley 
573*65876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
574*65876a83SMatthew G. Knepley       if (m%2 == 1) {
575*65876a83SMatthew G. Knepley         F1 += (4.0 / (m*PETSC_PI)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
576*65876a83SMatthew G. Knepley       }
577*65876a83SMatthew G. Knepley     }
578*65876a83SMatthew G. Knepley     u[0] = ((P_0*eta) / (G*S)) * F1; /* Pa */
579*65876a83SMatthew G. Knepley   }
580*65876a83SMatthew G. Knepley   return 0;
581*65876a83SMatthew G. Knepley }
582*65876a83SMatthew G. Knepley 
583*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
584*65876a83SMatthew G. Knepley {
585*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
586*65876a83SMatthew G. Knepley   Parameter     *param;
587*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
588*65876a83SMatthew G. Knepley 
589*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
590*65876a83SMatthew G. Knepley   if (time <= 0.0) {
591*65876a83SMatthew G. Knepley     u[0] = 0.0;
592*65876a83SMatthew G. Knepley     u[1] = 0.0;
593*65876a83SMatthew G. Knepley   } else {
594*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
595*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
596*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
597*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
598*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
599*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
600*65876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
601*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
602*65876a83SMatthew G. Knepley 
603*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
604*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
605*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
606*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
607*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
608*65876a83SMatthew G. Knepley 
609*65876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
610*65876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
611*65876a83SMatthew G. Knepley     PetscScalar F2_t  = 0.0;
612*65876a83SMatthew G. Knepley 
613*65876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
614*65876a83SMatthew G. Knepley       if (m%2 == 1) {
615*65876a83SMatthew G. Knepley         F2_t += (2.0*c / PetscSqr(L)) * PetscCosReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
616*65876a83SMatthew G. Knepley       }
617*65876a83SMatthew G. Knepley     }
618*65876a83SMatthew G. Knepley     u[0] = 0.0;
619*65876a83SMatthew G. Knepley     u[1] = ((P_0*L*(nu_u - nu)) / (2.0*G*(1.0 - nu_u)*(1.0 - nu)))*F2_t; /* m / s */
620*65876a83SMatthew G. Knepley   }
621*65876a83SMatthew G. Knepley   return 0;
622*65876a83SMatthew G. Knepley }
623*65876a83SMatthew G. Knepley 
624*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
625*65876a83SMatthew G. Knepley {
626*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
627*65876a83SMatthew G. Knepley   Parameter     *param;
628*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
629*65876a83SMatthew G. Knepley 
630*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
631*65876a83SMatthew G. Knepley   if (time <= 0.0) {
632*65876a83SMatthew G. Knepley     u[0] = 0.0;
633*65876a83SMatthew G. Knepley   } else {
634*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
635*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
636*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
637*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
638*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
639*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
640*65876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
641*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
642*65876a83SMatthew G. Knepley 
643*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
644*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
645*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
646*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
647*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
648*65876a83SMatthew G. Knepley 
649*65876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
650*65876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
651*65876a83SMatthew G. Knepley     PetscScalar F2_zt = 0.0;
652*65876a83SMatthew G. Knepley 
653*65876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
654*65876a83SMatthew G. Knepley       if (m%2 == 1) {
655*65876a83SMatthew G. Knepley         F2_zt += ((-m*PETSC_PI*c) / (L*L*L)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
656*65876a83SMatthew G. Knepley       }
657*65876a83SMatthew G. Knepley     }
658*65876a83SMatthew G. Knepley     u[0] = ((P_0*L*(nu_u - nu)) / (2.0*G*(1.0 - nu_u)*(1.0 - nu)))*F2_zt; /* 1 / s */
659*65876a83SMatthew G. Knepley   }
660*65876a83SMatthew G. Knepley   return 0;
661*65876a83SMatthew G. Knepley }
662*65876a83SMatthew G. Knepley 
663*65876a83SMatthew G. Knepley static PetscErrorCode terzaghi_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
664*65876a83SMatthew G. Knepley {
665*65876a83SMatthew G. Knepley 
666*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
667*65876a83SMatthew G. Knepley   Parameter     *param;
668*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
669*65876a83SMatthew G. Knepley 
670*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
671*65876a83SMatthew G. Knepley   if (time <= 0.0) {
672*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
673*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
674*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
675*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
676*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
677*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
678*65876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
679*65876a83SMatthew G. Knepley 
680*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
681*65876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
682*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
683*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
684*65876a83SMatthew G. Knepley 
685*65876a83SMatthew G. Knepley     u[0] = -((P_0*eta) / (G*S)) * PetscSqr(0*PETSC_PI)*c / PetscSqr(2.0*L); /* Pa / s */
686*65876a83SMatthew G. Knepley   } else {
687*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
688*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
689*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
690*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
691*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
692*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
693*65876a83SMatthew G. Knepley     PetscReal   L     = param->ymax - param->ymin; /* m */
694*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, m;
695*65876a83SMatthew G. Knepley 
696*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
697*65876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
698*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
699*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
700*65876a83SMatthew G. Knepley 
701*65876a83SMatthew G. Knepley     PetscReal   zstar = x[1] / L;                                  /* - */
702*65876a83SMatthew G. Knepley     PetscReal   tstar = PetscRealPart(c*time) / PetscSqr(2.0*L);   /* - */
703*65876a83SMatthew G. Knepley     PetscScalar F1_t  = 0.0;
704*65876a83SMatthew G. Knepley     PetscScalar F1_zz = 0.0;
705*65876a83SMatthew G. Knepley 
706*65876a83SMatthew 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));
707*65876a83SMatthew G. Knepley 
708*65876a83SMatthew G. Knepley     for (m = 1; m < 2*N+1; ++m) {
709*65876a83SMatthew G. Knepley       if (m%2 == 1) {
710*65876a83SMatthew G. Knepley         F1_t += ((-m*PETSC_PI*c) / PetscSqr(L)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
711*65876a83SMatthew G. Knepley         F1_zz += (-m*PETSC_PI / PetscSqr(L)) * PetscSinReal(0.5*m*PETSC_PI*zstar) * PetscExpReal(-PetscSqr(m*PETSC_PI)*tstar);
712*65876a83SMatthew G. Knepley       }
713*65876a83SMatthew G. Knepley     }
714*65876a83SMatthew G. Knepley     u[0] = ((P_0*eta) / (G*S)) * F1_t; /* Pa / s */
715*65876a83SMatthew G. Knepley   }
716*65876a83SMatthew G. Knepley   return 0;
717*65876a83SMatthew G. Knepley }
718*65876a83SMatthew G. Knepley 
719*65876a83SMatthew G. Knepley /* Mandel Solutions */
720*65876a83SMatthew G. Knepley static PetscErrorCode mandel_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
721*65876a83SMatthew G. Knepley {
722*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
723*65876a83SMatthew G. Knepley   Parameter     *param;
724*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
725*65876a83SMatthew G. Knepley 
726*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
727*65876a83SMatthew G. Knepley   if (time <= 0.0) {
728*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
729*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
730*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
731*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
732*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
733*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
734*65876a83SMatthew G. Knepley     PetscReal   a     = 0.5*(param->xmax - param->xmin); /* m */
735*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
736*65876a83SMatthew G. Knepley 
737*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
738*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
739*65876a83SMatthew G. Knepley     PetscScalar B     = alpha*M / K_u;                             /* -,       Cheng (B.12) */
740*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
741*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
742*65876a83SMatthew G. Knepley 
743*65876a83SMatthew G. Knepley     PetscScalar A1    = 3.0 / (B * (1.0 + nu_u));
744*65876a83SMatthew G. Knepley     PetscReal   aa    = 0.0;
745*65876a83SMatthew G. Knepley     PetscReal   p     = 0.0;
746*65876a83SMatthew G. Knepley     PetscReal   time  = 0.0;
747*65876a83SMatthew G. Knepley 
748*65876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
749*65876a83SMatthew G. Knepley       aa = user->zeroArray[n-1];
750*65876a83SMatthew 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));
751*65876a83SMatthew G. Knepley     }
752*65876a83SMatthew G. Knepley     u[0] = ((2.0 * P_0) / (a*A1)) * p;
753*65876a83SMatthew G. Knepley   } else {
754*65876a83SMatthew G. Knepley     u[0] = 0.0;
755*65876a83SMatthew G. Knepley   }
756*65876a83SMatthew G. Knepley   return 0;
757*65876a83SMatthew G. Knepley }
758*65876a83SMatthew G. Knepley 
759*65876a83SMatthew G. Knepley static PetscErrorCode mandel_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
760*65876a83SMatthew G. Knepley {
761*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
762*65876a83SMatthew G. Knepley   Parameter     *param;
763*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
764*65876a83SMatthew G. Knepley 
765*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
766*65876a83SMatthew G. Knepley   {
767*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
768*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
769*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
770*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
771*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
772*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
773*65876a83SMatthew G. Knepley     PetscScalar a     = 0.5*(param->xmax - param->xmin); /* m */
774*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
775*65876a83SMatthew G. Knepley 
776*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
777*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
778*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
779*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
780*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
781*65876a83SMatthew G. Knepley 
782*65876a83SMatthew G. Knepley     PetscScalar A_s   = 0.0;
783*65876a83SMatthew G. Knepley     PetscScalar B_s   = 0.0;
784*65876a83SMatthew G. Knepley     PetscScalar time  = 0.0;
785*65876a83SMatthew G. Knepley     PetscScalar alpha_n = 0.0;
786*65876a83SMatthew G. Knepley 
787*65876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
788*65876a83SMatthew G. Knepley       alpha_n = user->zeroArray[n-1];
789*65876a83SMatthew 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));
790*65876a83SMatthew 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));
791*65876a83SMatthew G. Knepley     }
792*65876a83SMatthew 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;
793*65876a83SMatthew G. Knepley     u[1] = (-1*(P_0*(1.0-nu))/(2*G*a) + (P_0*(1-nu_u))/(G*a) * A_s )*x[1];
794*65876a83SMatthew G. Knepley   }
795*65876a83SMatthew G. Knepley   return 0;
796*65876a83SMatthew G. Knepley }
797*65876a83SMatthew G. Knepley 
798*65876a83SMatthew G. Knepley static PetscErrorCode mandel_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
799*65876a83SMatthew G. Knepley {
800*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
801*65876a83SMatthew G. Knepley   Parameter     *param;
802*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
803*65876a83SMatthew G. Knepley 
804*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
805*65876a83SMatthew G. Knepley   {
806*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
807*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
808*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
809*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
810*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
811*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
812*65876a83SMatthew G. Knepley     PetscReal   a     = 0.5*(param->xmax - param->xmin); /* m */
813*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
814*65876a83SMatthew G. Knepley 
815*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
816*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
817*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
818*65876a83SMatthew G. Knepley     PetscReal   c     = PetscRealPart(kappa / S);                  /* m^2 / s, Cheng (B.16) */
819*65876a83SMatthew G. Knepley 
820*65876a83SMatthew G. Knepley     PetscReal   aa    = 0.0;
821*65876a83SMatthew G. Knepley     PetscReal   eps_A = 0.0;
822*65876a83SMatthew G. Knepley     PetscReal   eps_B = 0.0;
823*65876a83SMatthew G. Knepley     PetscReal   eps_C = 0.0;
824*65876a83SMatthew G. Knepley     PetscReal   time  = 0.0;
825*65876a83SMatthew G. Knepley 
826*65876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
827*65876a83SMatthew G. Knepley       aa     = user->zeroArray[n-1];
828*65876a83SMatthew 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)));
829*65876a83SMatthew G. Knepley       eps_B += ( PetscExpReal( (-1.0*aa*aa*c*time)/(a*a) )*PetscSinReal(aa)*PetscCosReal(aa) ) / (aa - PetscSinReal(aa)*PetscCosReal(aa));
830*65876a83SMatthew G. Knepley       eps_C += ( PetscExpReal( (-1.0*aa*aa*c*time)/(aa*aa) )*PetscSinReal(aa)*PetscCosReal(aa) ) / (aa - PetscSinReal(aa)*PetscCosReal(aa));
831*65876a83SMatthew G. Knepley     }
832*65876a83SMatthew 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);
833*65876a83SMatthew G. Knepley   }
834*65876a83SMatthew G. Knepley   return 0;
835*65876a83SMatthew G. Knepley }
836*65876a83SMatthew G. Knepley 
837*65876a83SMatthew G. Knepley // Displacement
838*65876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
839*65876a83SMatthew G. Knepley {
840*65876a83SMatthew G. Knepley 
841*65876a83SMatthew G. Knepley   Parameter  *param;
842*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
843*65876a83SMatthew G. Knepley 
844*65876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
845*65876a83SMatthew G. Knepley 
846*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
847*65876a83SMatthew G. Knepley   if (time <= 0.0) {
848*65876a83SMatthew G. Knepley     ierr = mandel_initial_u(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
849*65876a83SMatthew G. Knepley   } else {
850*65876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
851*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
852*65876a83SMatthew G. Knepley     PetscScalar K_u = param->K_u;
853*65876a83SMatthew G. Knepley     PetscScalar M = param->M;
854*65876a83SMatthew G. Knepley     PetscScalar G = param->mu;
855*65876a83SMatthew G. Knepley     PetscScalar k = param->k;
856*65876a83SMatthew G. Knepley     PetscScalar mu_f = param->mu_f;
857*65876a83SMatthew G. Knepley     PetscScalar F = param->P_0;
858*65876a83SMatthew G. Knepley 
859*65876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha*alpha*M;
860*65876a83SMatthew G. Knepley     PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G ));
861*65876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G ));
862*65876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
863*65876a83SMatthew G. Knepley     PetscReal   a = (param->xmax - param->xmin) / 2.0;
864*65876a83SMatthew 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)));
865*65876a83SMatthew G. Knepley 
866*65876a83SMatthew G. Knepley     // Series term
867*65876a83SMatthew G. Knepley     PetscScalar A_x = 0.0;
868*65876a83SMatthew G. Knepley     PetscScalar B_x = 0.0;
869*65876a83SMatthew G. Knepley 
870*65876a83SMatthew G. Knepley     for (PetscInt n=1; n < NITER+1; n++) {
871*65876a83SMatthew G. Knepley       PetscReal alpha_n = user->zeroArray[n-1];
872*65876a83SMatthew G. Knepley 
873*65876a83SMatthew 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) );
874*65876a83SMatthew 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) );
875*65876a83SMatthew G. Knepley     }
876*65876a83SMatthew G. Knepley     u[0] = ((F*nu)/(2.0*G*a) - (F*nu_u)/(G*a) * A_x)* x[0] + F/G * B_x;
877*65876a83SMatthew G. Knepley     u[1] = (-1*(F*(1.0-nu))/(2*G*a) + (F*(1-nu_u))/(G*a) * A_x )*x[1];
878*65876a83SMatthew G. Knepley   }
879*65876a83SMatthew G. Knepley   return 0;
880*65876a83SMatthew G. Knepley }
881*65876a83SMatthew G. Knepley 
882*65876a83SMatthew G. Knepley // Trace strain
883*65876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
884*65876a83SMatthew G. Knepley {
885*65876a83SMatthew G. Knepley 
886*65876a83SMatthew G. Knepley   Parameter  *param;
887*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
888*65876a83SMatthew G. Knepley 
889*65876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
890*65876a83SMatthew G. Knepley 
891*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
892*65876a83SMatthew G. Knepley   if (time <= 0.0) {
893*65876a83SMatthew G. Knepley     ierr = mandel_initial_eps(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
894*65876a83SMatthew G. Knepley   } else {
895*65876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
896*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
897*65876a83SMatthew G. Knepley     PetscScalar K_u = param->K_u;
898*65876a83SMatthew G. Knepley     PetscScalar M = param->M;
899*65876a83SMatthew G. Knepley     PetscScalar G = param->mu;
900*65876a83SMatthew G. Knepley     PetscScalar k = param->k;
901*65876a83SMatthew G. Knepley     PetscScalar mu_f = param->mu_f;
902*65876a83SMatthew G. Knepley     PetscScalar F = param->P_0;
903*65876a83SMatthew G. Knepley 
904*65876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha*alpha*M;
905*65876a83SMatthew G. Knepley     PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G ));
906*65876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G ));
907*65876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
908*65876a83SMatthew G. Knepley     //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
909*65876a83SMatthew G. Knepley 
910*65876a83SMatthew G. Knepley     //const PetscScalar b = (YMAX - YMIN) / 2.0;
911*65876a83SMatthew G. Knepley     PetscScalar a = (param->xmax - param->xmin) / 2.0;
912*65876a83SMatthew 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)));
913*65876a83SMatthew G. Knepley 
914*65876a83SMatthew G. Knepley     // Series term
915*65876a83SMatthew G. Knepley     PetscScalar eps_A = 0.0;
916*65876a83SMatthew G. Knepley     PetscScalar eps_B = 0.0;
917*65876a83SMatthew G. Knepley     PetscScalar eps_C = 0.0;
918*65876a83SMatthew G. Knepley 
919*65876a83SMatthew G. Knepley     for (PetscInt n=1; n < NITER+1; n++)
920*65876a83SMatthew G. Knepley     {
921*65876a83SMatthew G. Knepley       PetscReal aa = user->zeroArray[n-1];
922*65876a83SMatthew G. Knepley 
923*65876a83SMatthew 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)));
924*65876a83SMatthew G. Knepley 
925*65876a83SMatthew G. Knepley       eps_B += ( PetscExpReal( (-1.0*aa*aa*c*time)/(a*a) )*PetscSinReal(aa)*PetscCosReal(aa) ) / (aa - PetscSinReal(aa)*PetscCosReal(aa));
926*65876a83SMatthew G. Knepley 
927*65876a83SMatthew G. Knepley       eps_C += ( PetscExpReal( (-1.0*aa*aa*c*time)/(aa*aa) )*PetscSinReal(aa)*PetscCosReal(aa) ) / (aa - PetscSinReal(aa)*PetscCosReal(aa));
928*65876a83SMatthew G. Knepley     }
929*65876a83SMatthew G. Knepley 
930*65876a83SMatthew 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);
931*65876a83SMatthew G. Knepley   }
932*65876a83SMatthew G. Knepley   return 0;
933*65876a83SMatthew G. Knepley 
934*65876a83SMatthew G. Knepley }
935*65876a83SMatthew G. Knepley 
936*65876a83SMatthew G. Knepley // Pressure
937*65876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
938*65876a83SMatthew G. Knepley {
939*65876a83SMatthew G. Knepley 
940*65876a83SMatthew G. Knepley   Parameter  *param;
941*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
942*65876a83SMatthew G. Knepley 
943*65876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
944*65876a83SMatthew G. Knepley 
945*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
946*65876a83SMatthew G. Knepley   if (time <= 0.0) {
947*65876a83SMatthew G. Knepley     ierr = mandel_drainage_pressure(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
948*65876a83SMatthew G. Knepley   } else {
949*65876a83SMatthew G. Knepley     PetscInt NITER = user->niter;
950*65876a83SMatthew G. Knepley 
951*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha;
952*65876a83SMatthew G. Knepley     PetscScalar K_u = param->K_u;
953*65876a83SMatthew G. Knepley     PetscScalar M = param->M;
954*65876a83SMatthew G. Knepley     PetscScalar G = param->mu;
955*65876a83SMatthew G. Knepley     PetscScalar k = param->k;
956*65876a83SMatthew G. Knepley     PetscScalar mu_f = param->mu_f;
957*65876a83SMatthew G. Knepley     PetscScalar F = param->P_0;
958*65876a83SMatthew G. Knepley 
959*65876a83SMatthew G. Knepley     PetscScalar K_d = K_u - alpha*alpha*M;
960*65876a83SMatthew G. Knepley     PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G ));
961*65876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G ));
962*65876a83SMatthew G. Knepley     PetscScalar kappa = k / mu_f;
963*65876a83SMatthew G. Knepley     PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
964*65876a83SMatthew G. Knepley 
965*65876a83SMatthew G. Knepley     PetscReal   a  = (param->xmax - param->xmin) / 2.0;
966*65876a83SMatthew 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)));
967*65876a83SMatthew G. Knepley     PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
968*65876a83SMatthew G. Knepley     //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
969*65876a83SMatthew G. Knepley 
970*65876a83SMatthew G. Knepley     // Series term
971*65876a83SMatthew G. Knepley     PetscScalar aa = 0.0;
972*65876a83SMatthew G. Knepley     PetscScalar p  = 0.0;
973*65876a83SMatthew G. Knepley 
974*65876a83SMatthew G. Knepley     for (PetscInt n=1; n < NITER+1; n++)
975*65876a83SMatthew G. Knepley     {
976*65876a83SMatthew G. Knepley       aa = user->zeroArray[n-1];
977*65876a83SMatthew 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));
978*65876a83SMatthew G. Knepley     }
979*65876a83SMatthew G. Knepley     u[0] = ((2.0 * F) / (a*A1) ) * p;
980*65876a83SMatthew G. Knepley   }
981*65876a83SMatthew G. Knepley   return 0;
982*65876a83SMatthew G. Knepley }
983*65876a83SMatthew G. Knepley 
984*65876a83SMatthew G. Knepley // Time derivative of displacement
985*65876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_u_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
986*65876a83SMatthew G. Knepley {
987*65876a83SMatthew G. Knepley 
988*65876a83SMatthew G. Knepley   Parameter  *param;
989*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
990*65876a83SMatthew G. Knepley 
991*65876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
992*65876a83SMatthew G. Knepley 
993*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
994*65876a83SMatthew G. Knepley 
995*65876a83SMatthew G. Knepley   PetscInt NITER = user->niter;
996*65876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
997*65876a83SMatthew G. Knepley   PetscScalar K_u = param->K_u;
998*65876a83SMatthew G. Knepley   PetscScalar M = param->M;
999*65876a83SMatthew G. Knepley   PetscScalar G = param->mu;
1000*65876a83SMatthew G. Knepley   PetscScalar F = param->P_0;
1001*65876a83SMatthew G. Knepley 
1002*65876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
1003*65876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G ));
1004*65876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G ));
1005*65876a83SMatthew G. Knepley   PetscScalar kappa = param->k / param->mu_f;
1006*65876a83SMatthew G. Knepley   PetscReal   a = (param->xmax - param->xmin) / 2.0;
1007*65876a83SMatthew 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)));
1008*65876a83SMatthew G. Knepley 
1009*65876a83SMatthew G. Knepley   // Series term
1010*65876a83SMatthew G. Knepley   PetscScalar A_s_t = 0.0;
1011*65876a83SMatthew G. Knepley   PetscScalar B_s_t = 0.0;
1012*65876a83SMatthew G. Knepley 
1013*65876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
1014*65876a83SMatthew G. Knepley   {
1015*65876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n-1];
1016*65876a83SMatthew G. Knepley 
1017*65876a83SMatthew 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)) );
1018*65876a83SMatthew 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)) );
1019*65876a83SMatthew G. Knepley   }
1020*65876a83SMatthew G. Knepley 
1021*65876a83SMatthew G. Knepley   u[0] = (F/G)*A_s_t - ( (F*nu_u*x[0])/(G*a) )*B_s_t;
1022*65876a83SMatthew G. Knepley   u[1] = ( (F*x[1]*(1 - nu_u)) / (G*a) )*B_s_t;
1023*65876a83SMatthew G. Knepley 
1024*65876a83SMatthew G. Knepley   return 0;
1025*65876a83SMatthew G. Knepley }
1026*65876a83SMatthew G. Knepley 
1027*65876a83SMatthew G. Knepley // Time derivative of trace strain
1028*65876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_eps_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1029*65876a83SMatthew G. Knepley {
1030*65876a83SMatthew G. Knepley 
1031*65876a83SMatthew G. Knepley   Parameter  *param;
1032*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1033*65876a83SMatthew G. Knepley 
1034*65876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
1035*65876a83SMatthew G. Knepley 
1036*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1037*65876a83SMatthew G. Knepley 
1038*65876a83SMatthew G. Knepley   PetscInt NITER = user->niter;
1039*65876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
1040*65876a83SMatthew G. Knepley   PetscScalar K_u = param->K_u;
1041*65876a83SMatthew G. Knepley   PetscScalar M = param->M;
1042*65876a83SMatthew G. Knepley   PetscScalar G = param->mu;
1043*65876a83SMatthew G. Knepley   PetscScalar k = param->k;
1044*65876a83SMatthew G. Knepley   PetscScalar mu_f = param->mu_f;
1045*65876a83SMatthew G. Knepley   PetscScalar F = param->P_0;
1046*65876a83SMatthew G. Knepley 
1047*65876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
1048*65876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G ));
1049*65876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G ));
1050*65876a83SMatthew G. Knepley   PetscScalar kappa = k / mu_f;
1051*65876a83SMatthew G. Knepley   //const PetscScalar B = (alpha*M)/(K_d + alpha*alpha * M);
1052*65876a83SMatthew G. Knepley 
1053*65876a83SMatthew G. Knepley   //const PetscScalar b = (YMAX - YMIN) / 2.0;
1054*65876a83SMatthew G. Knepley   PetscReal   a = (param->xmax - param->xmin) / 2.0;
1055*65876a83SMatthew 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)));
1056*65876a83SMatthew G. Knepley 
1057*65876a83SMatthew G. Knepley   // Series term
1058*65876a83SMatthew G. Knepley   PetscScalar eps_As = 0.0;
1059*65876a83SMatthew G. Knepley   PetscScalar eps_Bs = 0.0;
1060*65876a83SMatthew G. Knepley   PetscScalar eps_Cs = 0.0;
1061*65876a83SMatthew G. Knepley 
1062*65876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
1063*65876a83SMatthew G. Knepley   {
1064*65876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n-1];
1065*65876a83SMatthew G. Knepley 
1066*65876a83SMatthew 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)) );
1067*65876a83SMatthew 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)) );
1068*65876a83SMatthew 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)) );
1069*65876a83SMatthew G. Knepley   }
1070*65876a83SMatthew G. Knepley 
1071*65876a83SMatthew G. Knepley   u[0] = (F/G)*eps_As - ( (F*nu_u)/(G*a) )*eps_Bs + ( (F*(1-nu_u))/(G*a) )*eps_Cs;
1072*65876a83SMatthew G. Knepley   return 0;
1073*65876a83SMatthew G. Knepley 
1074*65876a83SMatthew G. Knepley }
1075*65876a83SMatthew G. Knepley 
1076*65876a83SMatthew G. Knepley // Time derivative of pressure
1077*65876a83SMatthew G. Knepley static PetscErrorCode mandel_2d_p_t(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1078*65876a83SMatthew G. Knepley {
1079*65876a83SMatthew G. Knepley 
1080*65876a83SMatthew G. Knepley   Parameter  *param;
1081*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1082*65876a83SMatthew G. Knepley 
1083*65876a83SMatthew G. Knepley   AppCtx *user = (AppCtx *) ctx;
1084*65876a83SMatthew G. Knepley 
1085*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1086*65876a83SMatthew G. Knepley 
1087*65876a83SMatthew G. Knepley   PetscInt NITER = user->niter;
1088*65876a83SMatthew G. Knepley 
1089*65876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
1090*65876a83SMatthew G. Knepley   PetscScalar K_u = param->K_u;
1091*65876a83SMatthew G. Knepley   PetscScalar M = param->M;
1092*65876a83SMatthew G. Knepley   PetscScalar G = param->mu;
1093*65876a83SMatthew G. Knepley   PetscScalar k = param->k;
1094*65876a83SMatthew G. Knepley   PetscScalar mu_f = param->mu_f;
1095*65876a83SMatthew G. Knepley   PetscScalar F = param->P_0;
1096*65876a83SMatthew G. Knepley 
1097*65876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
1098*65876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G ));
1099*65876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G ));
1100*65876a83SMatthew G. Knepley   PetscScalar kappa = k / mu_f;
1101*65876a83SMatthew G. Knepley 
1102*65876a83SMatthew G. Knepley   PetscReal   a = (param->xmax - param->xmin) / 2.0;
1103*65876a83SMatthew 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)));
1104*65876a83SMatthew G. Knepley   //PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
1105*65876a83SMatthew G. Knepley   //PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
1106*65876a83SMatthew G. Knepley 
1107*65876a83SMatthew G. Knepley   // Series term
1108*65876a83SMatthew G. Knepley   PetscScalar P_s = 0.0;
1109*65876a83SMatthew G. Knepley 
1110*65876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
1111*65876a83SMatthew G. Knepley   {
1112*65876a83SMatthew G. Knepley     PetscReal alpha_n = user->zeroArray[n-1];
1113*65876a83SMatthew G. Knepley 
1114*65876a83SMatthew 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) ) );
1115*65876a83SMatthew G. Knepley   }
1116*65876a83SMatthew G. Knepley   u[0] = ( (2.0*F*(-2.0*nu + 3.0*nu_u))/(3.0*a*alpha*(1.0 - 2.0*nu) ) );
1117*65876a83SMatthew G. Knepley 
1118*65876a83SMatthew G. Knepley   return 0;
1119*65876a83SMatthew G. Knepley }
1120*65876a83SMatthew G. Knepley 
1121*65876a83SMatthew G. Knepley /* Cryer Solutions */
1122*65876a83SMatthew G. Knepley static PetscErrorCode cryer_drainage_pressure(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1123*65876a83SMatthew G. Knepley {
1124*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
1125*65876a83SMatthew G. Knepley   Parameter     *param;
1126*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1127*65876a83SMatthew G. Knepley 
1128*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1129*65876a83SMatthew G. Knepley   if (time <= 0.0) {
1130*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
1131*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
1132*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
1133*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
1134*65876a83SMatthew G. Knepley     PetscScalar B     = alpha*M / K_u; /* -, Cheng (B.12) */
1135*65876a83SMatthew G. Knepley 
1136*65876a83SMatthew G. Knepley     u[0] = P_0*B;
1137*65876a83SMatthew G. Knepley   } else {
1138*65876a83SMatthew G. Knepley     u[0] = 0.0;
1139*65876a83SMatthew G. Knepley   }
1140*65876a83SMatthew G. Knepley   return 0;
1141*65876a83SMatthew G. Knepley }
1142*65876a83SMatthew G. Knepley 
1143*65876a83SMatthew G. Knepley static PetscErrorCode cryer_initial_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1144*65876a83SMatthew G. Knepley {
1145*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
1146*65876a83SMatthew G. Knepley   Parameter     *param;
1147*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1148*65876a83SMatthew G. Knepley 
1149*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1150*65876a83SMatthew G. Knepley   {
1151*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
1152*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
1153*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
1154*65876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
1155*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
1156*65876a83SMatthew G. Knepley 
1157*65876a83SMatthew G. Knepley     PetscScalar u_0   = -P_0*R_0*(1. - 2.*nu_u) / (2.*G*(1. + nu_u)); /* Cheng (7.407) */
1158*65876a83SMatthew G. Knepley     PetscReal   u_sc  = PetscRealPart(u_0)/R_0;
1159*65876a83SMatthew G. Knepley 
1160*65876a83SMatthew G. Knepley     u[0] = u_sc * x[0];
1161*65876a83SMatthew G. Knepley     u[1] = u_sc * x[1];
1162*65876a83SMatthew G. Knepley     u[2] = u_sc * x[2];
1163*65876a83SMatthew G. Knepley   }
1164*65876a83SMatthew G. Knepley   return 0;
1165*65876a83SMatthew G. Knepley }
1166*65876a83SMatthew G. Knepley 
1167*65876a83SMatthew G. Knepley static PetscErrorCode cryer_initial_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1168*65876a83SMatthew G. Knepley {
1169*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
1170*65876a83SMatthew G. Knepley   Parameter     *param;
1171*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1172*65876a83SMatthew G. Knepley 
1173*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1174*65876a83SMatthew G. Knepley   {
1175*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
1176*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
1177*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
1178*65876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
1179*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
1180*65876a83SMatthew G. Knepley 
1181*65876a83SMatthew G. Knepley     PetscScalar u_0   = -P_0*R_0*(1. - 2.*nu_u) / (2.*G*(1. + nu_u)); /* Cheng (7.407) */
1182*65876a83SMatthew G. Knepley     PetscReal   u_sc  = PetscRealPart(u_0)/R_0;
1183*65876a83SMatthew G. Knepley 
1184*65876a83SMatthew G. Knepley     /* div R = 1/R^2 d/dR R^2 R = 3 */
1185*65876a83SMatthew G. Knepley     u[0] = 3.*u_sc;
1186*65876a83SMatthew G. Knepley     u[1] = 3.*u_sc;
1187*65876a83SMatthew G. Knepley     u[2] = 3.*u_sc;
1188*65876a83SMatthew G. Knepley   }
1189*65876a83SMatthew G. Knepley   return 0;
1190*65876a83SMatthew G. Knepley }
1191*65876a83SMatthew G. Knepley 
1192*65876a83SMatthew G. Knepley // Displacement
1193*65876a83SMatthew G. Knepley static PetscErrorCode cryer_3d_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1194*65876a83SMatthew G. Knepley {
1195*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
1196*65876a83SMatthew G. Knepley   Parameter     *param;
1197*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1198*65876a83SMatthew G. Knepley 
1199*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1200*65876a83SMatthew G. Knepley   if (time <= 0.0) {
1201*65876a83SMatthew G. Knepley     ierr = cryer_initial_u(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
1202*65876a83SMatthew G. Knepley   } else {
1203*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
1204*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
1205*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
1206*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
1207*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
1208*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
1209*65876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
1210*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
1211*65876a83SMatthew G. Knepley 
1212*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
1213*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
1214*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
1215*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
1216*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
1217*65876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0*R_0*(1. - 2.*nu) / (2.*G*(1. + nu));  /* m,       Cheng (7.388) */
1218*65876a83SMatthew G. Knepley 
1219*65876a83SMatthew G. Knepley     PetscReal   R      = PetscSqrtReal(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
1220*65876a83SMatthew G. Knepley     PetscReal   R_star = R/R_0;
1221*65876a83SMatthew G. Knepley     PetscReal   tstar  = PetscRealPart(c*time) / PetscSqr(R_0);    /* - */
1222*65876a83SMatthew G. Knepley     PetscReal   A_n    = 0.0;
1223*65876a83SMatthew G. Knepley     PetscScalar u_sc;
1224*65876a83SMatthew G. Knepley 
1225*65876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
1226*65876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n-1];
1227*65876a83SMatthew 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));
1228*65876a83SMatthew G. Knepley 
1229*65876a83SMatthew G. Knepley       /* m , Cheng (7.404) */
1230*65876a83SMatthew G. Knepley       A_n += PetscRealPart(
1231*65876a83SMatthew 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))) *
1232*65876a83SMatthew G. Knepley              (3.0*(nu_u - nu) * (PetscSinReal(R_star * PetscSqrtReal(x_n)) - R_star*PetscSqrtReal(x_n)*PetscCosReal(R_star * PetscSqrtReal(x_n)))
1233*65876a83SMatthew G. Knepley               + (1.0 - nu)*(1.0 - 2.0*nu)*PetscPowRealInt(R_star, 3)*x_n*PetscSinReal(PetscSqrtReal(x_n))) * PetscExpReal(-x_n * tstar));
1234*65876a83SMatthew G. Knepley     }
1235*65876a83SMatthew G. Knepley     u_sc = PetscRealPart(u_inf) * (R_star - A_n);
1236*65876a83SMatthew G. Knepley     u[0] = u_sc * x[0] / R;
1237*65876a83SMatthew G. Knepley     u[1] = u_sc * x[1] / R;
1238*65876a83SMatthew G. Knepley     u[2] = u_sc * x[2] / R;
1239*65876a83SMatthew G. Knepley   }
1240*65876a83SMatthew G. Knepley   return 0;
1241*65876a83SMatthew G. Knepley }
1242*65876a83SMatthew G. Knepley 
1243*65876a83SMatthew G. Knepley // Volumetric Strain
1244*65876a83SMatthew G. Knepley static PetscErrorCode cryer_3d_eps(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1245*65876a83SMatthew G. Knepley {
1246*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
1247*65876a83SMatthew G. Knepley   Parameter     *param;
1248*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1249*65876a83SMatthew G. Knepley 
1250*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1251*65876a83SMatthew G. Knepley   if (time <= 0.0) {
1252*65876a83SMatthew G. Knepley     ierr = cryer_initial_eps(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
1253*65876a83SMatthew G. Knepley   } else {
1254*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
1255*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
1256*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
1257*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
1258*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
1259*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
1260*65876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
1261*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
1262*65876a83SMatthew G. Knepley 
1263*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
1264*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
1265*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
1266*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
1267*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
1268*65876a83SMatthew G. Knepley     PetscScalar u_inf = -P_0*R_0*(1. - 2.*nu) / (2.*G*(1. + nu));  /* m,       Cheng (7.388) */
1269*65876a83SMatthew G. Knepley 
1270*65876a83SMatthew G. Knepley     PetscReal   R      = PetscSqrtReal(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
1271*65876a83SMatthew G. Knepley     PetscReal   R_star = R/R_0;
1272*65876a83SMatthew G. Knepley     PetscReal   tstar  = PetscRealPart(c*time) / PetscSqr(R_0);    /* - */
1273*65876a83SMatthew G. Knepley     PetscReal   divA_n = 0.0;
1274*65876a83SMatthew G. Knepley 
1275*65876a83SMatthew G. Knepley     if (R_star < PETSC_SMALL) {
1276*65876a83SMatthew G. Knepley       for (n = 1; n < N+1; ++n) {
1277*65876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n-1];
1278*65876a83SMatthew 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));
1279*65876a83SMatthew G. Knepley 
1280*65876a83SMatthew G. Knepley         divA_n += PetscRealPart(
1281*65876a83SMatthew 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))) *
1282*65876a83SMatthew 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)))
1283*65876a83SMatthew 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));
1284*65876a83SMatthew G. Knepley       }
1285*65876a83SMatthew G. Knepley     } else {
1286*65876a83SMatthew G. Knepley       for (n = 1; n < N+1; ++n) {
1287*65876a83SMatthew G. Knepley         const PetscReal x_n = user->zeroArray[n-1];
1288*65876a83SMatthew 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));
1289*65876a83SMatthew G. Knepley 
1290*65876a83SMatthew G. Knepley         divA_n += PetscRealPart(
1291*65876a83SMatthew 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))) *
1292*65876a83SMatthew 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)))
1293*65876a83SMatthew 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));
1294*65876a83SMatthew G. Knepley       }
1295*65876a83SMatthew G. Knepley     }
1296*65876a83SMatthew 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);
1297*65876a83SMatthew G. Knepley     u[0] = PetscRealPart(u_inf)/R_0 * (3.0 - divA_n);
1298*65876a83SMatthew G. Knepley   }
1299*65876a83SMatthew G. Knepley   return 0;
1300*65876a83SMatthew G. Knepley }
1301*65876a83SMatthew G. Knepley 
1302*65876a83SMatthew G. Knepley // Pressure
1303*65876a83SMatthew G. Knepley static PetscErrorCode cryer_3d_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
1304*65876a83SMatthew G. Knepley {
1305*65876a83SMatthew G. Knepley   AppCtx        *user = (AppCtx *) ctx;
1306*65876a83SMatthew G. Knepley   Parameter     *param;
1307*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1308*65876a83SMatthew G. Knepley 
1309*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1310*65876a83SMatthew G. Knepley   if (time <= 0.0) {
1311*65876a83SMatthew G. Knepley     ierr = cryer_drainage_pressure(dim, time, x, Nc, u, ctx);CHKERRQ(ierr);
1312*65876a83SMatthew G. Knepley   } else {
1313*65876a83SMatthew G. Knepley     PetscScalar alpha = param->alpha; /* -  */
1314*65876a83SMatthew G. Knepley     PetscScalar K_u   = param->K_u;   /* Pa */
1315*65876a83SMatthew G. Knepley     PetscScalar M     = param->M;     /* Pa */
1316*65876a83SMatthew G. Knepley     PetscScalar G     = param->mu;    /* Pa */
1317*65876a83SMatthew G. Knepley     PetscScalar P_0   = param->P_0;   /* Pa */
1318*65876a83SMatthew G. Knepley     PetscReal   R_0   = param->ymax;  /* m */
1319*65876a83SMatthew G. Knepley     PetscScalar kappa = param->k / param->mu_f;    /* m^2 / (Pa s) */
1320*65876a83SMatthew G. Knepley     PetscInt    N     = user->niter, n;
1321*65876a83SMatthew G. Knepley 
1322*65876a83SMatthew G. Knepley     PetscScalar K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
1323*65876a83SMatthew G. Knepley     PetscScalar eta   = (3.0*alpha*G) / (3.0*K_d + 4.0*G);         /* -,       Cheng (B.11) */
1324*65876a83SMatthew G. Knepley     PetscScalar nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
1325*65876a83SMatthew G. Knepley     PetscScalar nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
1326*65876a83SMatthew G. Knepley     PetscScalar S     = (3.0*K_u + 4.0*G) / (M*(3.0*K_d + 4.0*G)); /* Pa^{-1}, Cheng (B.14) */
1327*65876a83SMatthew G. Knepley     PetscScalar c     = kappa / S;                                 /* m^2 / s, Cheng (B.16) */
1328*65876a83SMatthew G. Knepley     PetscScalar R     = PetscSqrtReal(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
1329*65876a83SMatthew G. Knepley 
1330*65876a83SMatthew G. Knepley     PetscScalar R_star = R / R_0;
1331*65876a83SMatthew G. Knepley     PetscScalar t_star = PetscRealPart(c * time) / PetscSqr(R_0);
1332*65876a83SMatthew G. Knepley     PetscReal   A_x    = 0.0;
1333*65876a83SMatthew G. Knepley 
1334*65876a83SMatthew G. Knepley     for (n = 1; n < N+1; ++n) {
1335*65876a83SMatthew G. Knepley       const PetscReal x_n = user->zeroArray[n-1];
1336*65876a83SMatthew 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));
1337*65876a83SMatthew G. Knepley 
1338*65876a83SMatthew 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) */
1339*65876a83SMatthew G. Knepley     }
1340*65876a83SMatthew G. Knepley     u[0] = P_0 * A_x;
1341*65876a83SMatthew G. Knepley   }
1342*65876a83SMatthew G. Knepley   return 0;
1343*65876a83SMatthew G. Knepley }
1344*65876a83SMatthew G. Knepley 
1345*65876a83SMatthew G. Knepley /* Boundary Kernels */
1346*65876a83SMatthew G. Knepley static void f0_terzaghi_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1347*65876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1348*65876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1349*65876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
1350*65876a83SMatthew G. Knepley {
1351*65876a83SMatthew G. Knepley   const PetscReal P = PetscRealPart(constants[5]);
1352*65876a83SMatthew G. Knepley 
1353*65876a83SMatthew G. Knepley   f0[0] = 0.0;
1354*65876a83SMatthew G. Knepley   f0[1] = P;
1355*65876a83SMatthew G. Knepley }
1356*65876a83SMatthew G. Knepley 
1357*65876a83SMatthew G. Knepley static void f0_mandel_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1358*65876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1359*65876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1360*65876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
1361*65876a83SMatthew G. Knepley {
1362*65876a83SMatthew G. Knepley   // Uniform stress distribution
1363*65876a83SMatthew G. Knepley   /* PetscScalar xmax =  0.5;
1364*65876a83SMatthew G. Knepley   PetscScalar xmin = -0.5;
1365*65876a83SMatthew G. Knepley   PetscScalar ymax =  0.5;
1366*65876a83SMatthew G. Knepley   PetscScalar ymin = -0.5;
1367*65876a83SMatthew G. Knepley   PetscScalar P = constants[5];
1368*65876a83SMatthew G. Knepley   PetscScalar aL = (xmax - xmin) / 2.0;
1369*65876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*P / aL; */
1370*65876a83SMatthew G. Knepley 
1371*65876a83SMatthew G. Knepley   // Analytical (parabolic) stress distribution
1372*65876a83SMatthew G. Knepley   PetscReal a1, a2, am;
1373*65876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
1374*65876a83SMatthew G. Knepley 
1375*65876a83SMatthew G. Knepley   PetscInt NITER = 500;
1376*65876a83SMatthew G. Knepley   PetscReal EPS = 0.000001;
1377*65876a83SMatthew G. Knepley   PetscReal zeroArray[500]; /* NITER */
1378*65876a83SMatthew G. Knepley   PetscReal xmax =  1.0;
1379*65876a83SMatthew G. Knepley   PetscReal xmin =  0.0;
1380*65876a83SMatthew G. Knepley   PetscReal ymax =  0.1;
1381*65876a83SMatthew G. Knepley   PetscReal ymin =  0.0;
1382*65876a83SMatthew G. Knepley   PetscReal lower[2], upper[2];
1383*65876a83SMatthew G. Knepley 
1384*65876a83SMatthew G. Knepley   lower[0] = xmin - (xmax - xmin) / 2.0;
1385*65876a83SMatthew G. Knepley   lower[1] = ymin - (ymax - ymin) / 2.0;
1386*65876a83SMatthew G. Knepley   upper[0] = xmax - (xmax - xmin) / 2.0;
1387*65876a83SMatthew G. Knepley   upper[1] = ymax - (ymax - ymin) / 2.0;
1388*65876a83SMatthew G. Knepley 
1389*65876a83SMatthew G. Knepley   xmin = lower[0];
1390*65876a83SMatthew G. Knepley   ymin = lower[1];
1391*65876a83SMatthew G. Knepley   xmax = upper[0];
1392*65876a83SMatthew G. Knepley   ymax = upper[1];
1393*65876a83SMatthew G. Knepley 
1394*65876a83SMatthew G. Knepley   PetscScalar G     = constants[0];
1395*65876a83SMatthew G. Knepley   PetscScalar K_u   = constants[1];
1396*65876a83SMatthew G. Knepley   PetscScalar alpha = constants[2];
1397*65876a83SMatthew G. Knepley   PetscScalar M     = constants[3];
1398*65876a83SMatthew G. Knepley   PetscScalar kappa = constants[4];
1399*65876a83SMatthew G. Knepley   PetscScalar F     = constants[5];
1400*65876a83SMatthew G. Knepley 
1401*65876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
1402*65876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G ));
1403*65876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G ));
1404*65876a83SMatthew G. Knepley   PetscReal   aL = (xmax - xmin) / 2.0;
1405*65876a83SMatthew 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)));
1406*65876a83SMatthew G. Knepley   PetscScalar B = (3.0 * (nu_u - nu) ) / ( alpha * (1.0 - 2.0*nu) * (1.0 + nu_u));
1407*65876a83SMatthew G. Knepley   PetscScalar A1 = 3.0 / (B * (1.0 + nu_u));
1408*65876a83SMatthew G. Knepley   PetscScalar A2 = (alpha * (1.0 - 2.0*nu)) / (1.0 - nu);
1409*65876a83SMatthew G. Knepley 
1410*65876a83SMatthew G. Knepley   // Generate zero values
1411*65876a83SMatthew G. Knepley   for (PetscInt i=1; i < NITER+1; i++)
1412*65876a83SMatthew G. Knepley   {
1413*65876a83SMatthew G. Knepley     a1 = ((PetscReal) i - 1.0 ) * PETSC_PI * PETSC_PI / 4.0 + EPS;
1414*65876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI/2;
1415*65876a83SMatthew G. Knepley     for (PetscInt j=0; j<NITER; j++)
1416*65876a83SMatthew G. Knepley     {
1417*65876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart(A1/A2)*a1;
1418*65876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart(A1/A2)*a2;
1419*65876a83SMatthew G. Knepley       am = (a1 + a2)/2.0;
1420*65876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart(A1/A2)*am;
1421*65876a83SMatthew G. Knepley       if ((ym*y1) > 0)
1422*65876a83SMatthew G. Knepley       {
1423*65876a83SMatthew G. Knepley         a1 = am;
1424*65876a83SMatthew G. Knepley       } else {
1425*65876a83SMatthew G. Knepley         a2 = am;
1426*65876a83SMatthew G. Knepley       }
1427*65876a83SMatthew G. Knepley       if (PetscAbsReal(y2) < EPS)
1428*65876a83SMatthew G. Knepley       {
1429*65876a83SMatthew G. Knepley         am = a2;
1430*65876a83SMatthew G. Knepley       }
1431*65876a83SMatthew G. Knepley     }
1432*65876a83SMatthew G. Knepley     zeroArray[i-1] = am;
1433*65876a83SMatthew G. Knepley   }
1434*65876a83SMatthew G. Knepley 
1435*65876a83SMatthew G. Knepley   // Solution for sigma_zz
1436*65876a83SMatthew G. Knepley   PetscScalar A_x = 0.0;
1437*65876a83SMatthew G. Knepley   PetscScalar B_x = 0.0;
1438*65876a83SMatthew G. Knepley 
1439*65876a83SMatthew G. Knepley   for (PetscInt n=1; n < NITER+1; n++)
1440*65876a83SMatthew G. Knepley   {
1441*65876a83SMatthew G. Knepley     PetscReal alpha_n = zeroArray[n-1];
1442*65876a83SMatthew G. Knepley 
1443*65876a83SMatthew 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) ) );
1444*65876a83SMatthew 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) ) );
1445*65876a83SMatthew G. Knepley   }
1446*65876a83SMatthew G. Knepley 
1447*65876a83SMatthew G. Knepley   PetscScalar sigma_zz = -1.0*(F/aL) - ((2.0*F)/aL) * (A2/A1) * A_x + ((2.0*F)/aL) * B_x;
1448*65876a83SMatthew G. Knepley 
1449*65876a83SMatthew G. Knepley 
1450*65876a83SMatthew G. Knepley   if (x[1] == ymax) {
1451*65876a83SMatthew G. Knepley     f0[1] += sigma_zz;
1452*65876a83SMatthew G. Knepley   } else if (x[1] == ymin) {
1453*65876a83SMatthew G. Knepley     f0[1] -= sigma_zz;
1454*65876a83SMatthew G. Knepley   }
1455*65876a83SMatthew G. Knepley }
1456*65876a83SMatthew G. Knepley 
1457*65876a83SMatthew G. Knepley static void f0_cryer_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1458*65876a83SMatthew G. Knepley                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1459*65876a83SMatthew G. Knepley                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1460*65876a83SMatthew G. Knepley                                     PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
1461*65876a83SMatthew G. Knepley {
1462*65876a83SMatthew G. Knepley   const PetscReal P_0 = PetscRealPart(constants[5]);
1463*65876a83SMatthew G. Knepley   const PetscReal R   = PetscSqrtReal(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
1464*65876a83SMatthew G. Knepley   PetscInt        d;
1465*65876a83SMatthew G. Knepley 
1466*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) f0[d] = -P_0*n[d];
1467*65876a83SMatthew 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);
1468*65876a83SMatthew G. 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);
1469*65876a83SMatthew G. Knepley   //for (d = 0; d < dim; ++d) f0[d] = -P_0*x[d]/R;
1470*65876a83SMatthew G. Knepley }
1471*65876a83SMatthew G. Knepley 
1472*65876a83SMatthew G. Knepley /* Standard Kernels - Residual */
1473*65876a83SMatthew G. Knepley /* f0_e */
1474*65876a83SMatthew G. Knepley static void f0_epsilon(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1475*65876a83SMatthew G. Knepley                        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1476*65876a83SMatthew G. Knepley                        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1477*65876a83SMatthew G. Knepley                        PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
1478*65876a83SMatthew G. Knepley {
1479*65876a83SMatthew G. Knepley   PetscInt d;
1480*65876a83SMatthew G. Knepley 
1481*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
1482*65876a83SMatthew G. Knepley     f0[0] += u_x[d*dim+d];
1483*65876a83SMatthew G. Knepley   }
1484*65876a83SMatthew G. Knepley   f0[0] -= u[uOff[1]];
1485*65876a83SMatthew G. Knepley }
1486*65876a83SMatthew G. Knepley 
1487*65876a83SMatthew G. Knepley /* f0_p */
1488*65876a83SMatthew G. Knepley static void f0_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1489*65876a83SMatthew G. Knepley                  const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1490*65876a83SMatthew G. Knepley                  const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1491*65876a83SMatthew G. Knepley                  PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
1492*65876a83SMatthew G. Knepley {
1493*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
1494*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
1495*65876a83SMatthew G. Knepley 
1496*65876a83SMatthew G. Knepley   f0[0] += alpha*u_t[uOff[1]];
1497*65876a83SMatthew G. Knepley   f0[0] += u_t[uOff[2]]/M;
1498*65876a83SMatthew G. Knepley }
1499*65876a83SMatthew G. Knepley 
1500*65876a83SMatthew G. Knepley /* f1_u */
1501*65876a83SMatthew G. Knepley static void f1_u(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1502*65876a83SMatthew G. Knepley                  const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1503*65876a83SMatthew G. Knepley                  const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1504*65876a83SMatthew G. Knepley                  PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])
1505*65876a83SMatthew G. Knepley {
1506*65876a83SMatthew G. Knepley   const PetscInt  Nc     = dim;
1507*65876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
1508*65876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
1509*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
1510*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
1511*65876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
1512*65876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
1513*65876a83SMatthew G. Knepley   PetscInt        c, d;
1514*65876a83SMatthew G. Knepley 
1515*65876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c)
1516*65876a83SMatthew G. Knepley   {
1517*65876a83SMatthew G. Knepley     for (d = 0; d < dim; ++d)
1518*65876a83SMatthew G. Knepley     {
1519*65876a83SMatthew G. Knepley       f1[c*dim+d] -= G*(u_x[c*dim+d] + u_x[d*dim+c]);
1520*65876a83SMatthew G. Knepley     }
1521*65876a83SMatthew G. Knepley     f1[c*dim+c] -= lambda*u[uOff[1]];
1522*65876a83SMatthew G. Knepley     f1[c*dim+c] += alpha*u[uOff[2]];
1523*65876a83SMatthew G. Knepley   }
1524*65876a83SMatthew G. Knepley }
1525*65876a83SMatthew G. Knepley 
1526*65876a83SMatthew G. Knepley /* f1_p */
1527*65876a83SMatthew G. Knepley static void f1_p(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1528*65876a83SMatthew G. Knepley                  const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1529*65876a83SMatthew G. Knepley                  const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1530*65876a83SMatthew G. Knepley                  PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])
1531*65876a83SMatthew G. Knepley {
1532*65876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
1533*65876a83SMatthew G. Knepley   PetscInt        d;
1534*65876a83SMatthew G. Knepley 
1535*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
1536*65876a83SMatthew G. Knepley     f1[d] += kappa*u_x[uOff_x[2]+d];
1537*65876a83SMatthew G. Knepley   }
1538*65876a83SMatthew G. Knepley }
1539*65876a83SMatthew G. Knepley 
1540*65876a83SMatthew G. Knepley /*
1541*65876a83SMatthew G. Knepley   \partial_df \phi_fc g_{fc,gc,df,dg} \partial_dg \phi_gc
1542*65876a83SMatthew G. Knepley 
1543*65876a83SMatthew G. Knepley   \partial_df \phi_fc \lambda \delta_{fc,df} \sum_gc \partial_dg \phi_gc \delta_{gc,dg}
1544*65876a83SMatthew G. Knepley   = \partial_fc \phi_fc \sum_gc \partial_gc \phi_gc
1545*65876a83SMatthew G. Knepley */
1546*65876a83SMatthew G. Knepley 
1547*65876a83SMatthew G. Knepley 
1548*65876a83SMatthew G. Knepley /* Standard Kernels - Jacobian */
1549*65876a83SMatthew G. Knepley /* g0_ee */
1550*65876a83SMatthew G. Knepley static void g0_ee(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1551*65876a83SMatthew G. Knepley            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1552*65876a83SMatthew G. Knepley            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1553*65876a83SMatthew G. Knepley            PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
1554*65876a83SMatthew G. Knepley {
1555*65876a83SMatthew G. Knepley   g0[0] = -1.0;
1556*65876a83SMatthew G. Knepley }
1557*65876a83SMatthew G. Knepley 
1558*65876a83SMatthew G. Knepley /* g0_pe */
1559*65876a83SMatthew G. Knepley static void g0_pe(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1560*65876a83SMatthew G. Knepley            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1561*65876a83SMatthew G. Knepley            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1562*65876a83SMatthew G. Knepley            PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
1563*65876a83SMatthew G. Knepley {
1564*65876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
1565*65876a83SMatthew G. Knepley 
1566*65876a83SMatthew G. Knepley   g0[0] = u_tShift*alpha;
1567*65876a83SMatthew G. Knepley }
1568*65876a83SMatthew G. Knepley 
1569*65876a83SMatthew G. Knepley /* g0_pp */
1570*65876a83SMatthew G. Knepley static void g0_pp(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1571*65876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1572*65876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1573*65876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
1574*65876a83SMatthew G. Knepley {
1575*65876a83SMatthew G. Knepley   const PetscReal M = PetscRealPart(constants[3]);
1576*65876a83SMatthew G. Knepley 
1577*65876a83SMatthew G. Knepley   g0[0] = u_tShift/M;
1578*65876a83SMatthew G. Knepley }
1579*65876a83SMatthew G. Knepley 
1580*65876a83SMatthew G. Knepley /* g1_eu */
1581*65876a83SMatthew G. Knepley static void g1_eu(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1582*65876a83SMatthew G. Knepley            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1583*65876a83SMatthew G. Knepley            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1584*65876a83SMatthew G. Knepley            PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[])
1585*65876a83SMatthew G. Knepley {
1586*65876a83SMatthew G. Knepley   PetscInt d;
1587*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g1[d*dim+d] = 1.0; /* \frac{\partial\phi^{u_d}}{\partial x_d} */
1588*65876a83SMatthew G. Knepley }
1589*65876a83SMatthew G. Knepley 
1590*65876a83SMatthew G. Knepley /* g2_ue */
1591*65876a83SMatthew G. Knepley static void g2_ue(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1592*65876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1593*65876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1594*65876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[])
1595*65876a83SMatthew G. Knepley {
1596*65876a83SMatthew G. Knepley   const PetscReal G      = PetscRealPart(constants[0]);
1597*65876a83SMatthew G. Knepley   const PetscReal K_u    = PetscRealPart(constants[1]);
1598*65876a83SMatthew G. Knepley   const PetscReal alpha  = PetscRealPart(constants[2]);
1599*65876a83SMatthew G. Knepley   const PetscReal M      = PetscRealPart(constants[3]);
1600*65876a83SMatthew G. Knepley   const PetscReal K_d    = K_u - alpha*alpha*M;
1601*65876a83SMatthew G. Knepley   const PetscReal lambda = K_d - (2.0 * G) / 3.0;
1602*65876a83SMatthew G. Knepley   PetscInt        d;
1603*65876a83SMatthew G. Knepley 
1604*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
1605*65876a83SMatthew G. Knepley     g2[d*dim + d] -= lambda;
1606*65876a83SMatthew G. Knepley   }
1607*65876a83SMatthew G. Knepley }
1608*65876a83SMatthew G. Knepley /* g2_up */
1609*65876a83SMatthew G. Knepley static void g2_up(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1610*65876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1611*65876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1612*65876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[])
1613*65876a83SMatthew G. Knepley {
1614*65876a83SMatthew G. Knepley   const PetscReal alpha = PetscRealPart(constants[2]);
1615*65876a83SMatthew G. Knepley   PetscInt        d;
1616*65876a83SMatthew G. Knepley 
1617*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) {
1618*65876a83SMatthew G. Knepley     g2[d*dim + d] += alpha;
1619*65876a83SMatthew G. Knepley   }
1620*65876a83SMatthew G. Knepley }
1621*65876a83SMatthew G. Knepley 
1622*65876a83SMatthew G. Knepley /* g3_uu */
1623*65876a83SMatthew G. Knepley static void g3_uu(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1624*65876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1625*65876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1626*65876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])
1627*65876a83SMatthew G. Knepley {
1628*65876a83SMatthew G. Knepley   const PetscInt  Nc = dim;
1629*65876a83SMatthew G. Knepley   const PetscReal G  = PetscRealPart(constants[0]);
1630*65876a83SMatthew G. Knepley   PetscInt        c, d;
1631*65876a83SMatthew G. Knepley 
1632*65876a83SMatthew G. Knepley   for (c = 0; c < Nc; ++c) {
1633*65876a83SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
1634*65876a83SMatthew G. Knepley       g3[((c*Nc + c)*dim + d)*dim + d] -= G;
1635*65876a83SMatthew G. Knepley       g3[((c*Nc + d)*dim + d)*dim + c] -= G;
1636*65876a83SMatthew G. Knepley     }
1637*65876a83SMatthew G. Knepley   }
1638*65876a83SMatthew G. Knepley }
1639*65876a83SMatthew G. Knepley 
1640*65876a83SMatthew G. Knepley /* g3_pp */
1641*65876a83SMatthew G. Knepley static void g3_pp(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1642*65876a83SMatthew G. Knepley                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1643*65876a83SMatthew G. Knepley                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1644*65876a83SMatthew G. Knepley                   PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])
1645*65876a83SMatthew G. Knepley {
1646*65876a83SMatthew G. Knepley   const PetscReal kappa = PetscRealPart(constants[4]);
1647*65876a83SMatthew G. Knepley   PetscInt        d;
1648*65876a83SMatthew G. Knepley 
1649*65876a83SMatthew G. Knepley   for (d = 0; d < dim; ++d) g3[d*dim+d] += kappa;
1650*65876a83SMatthew G. Knepley }
1651*65876a83SMatthew G. Knepley 
1652*65876a83SMatthew G. Knepley static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
1653*65876a83SMatthew G. Knepley {
1654*65876a83SMatthew G. Knepley   PetscInt sol;
1655*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1656*65876a83SMatthew G. Knepley 
1657*65876a83SMatthew G. Knepley   PetscFunctionBeginUser;
1658*65876a83SMatthew G. Knepley   options->dim      = 2;
1659*65876a83SMatthew G. Knepley   options->simplex  = PETSC_TRUE;
1660*65876a83SMatthew G. Knepley   options->refLimit = -1.0;
1661*65876a83SMatthew G. Knepley   options->solType  = SOL_QUADRATIC_TRIG;
1662*65876a83SMatthew G. Knepley   options->niter    = 500;
1663*65876a83SMatthew G. Knepley   options->eps      = PETSC_SMALL;
1664*65876a83SMatthew G. Knepley   ierr = PetscStrncpy(options->dmType, DMPLEX, 256);CHKERRQ(ierr);
1665*65876a83SMatthew G. Knepley 
1666*65876a83SMatthew G. Knepley   ierr = PetscOptionsBegin(comm, "", "Biot Poroelasticity Options", "DMPLEX");CHKERRQ(ierr);
1667*65876a83SMatthew G. Knepley   ierr = PetscOptionsInt("-dim", "The topological mesh dimension", "ex53.c", options->dim, &options->dim, NULL);CHKERRQ(ierr);
1668*65876a83SMatthew G. Knepley   ierr = PetscOptionsInt("-niter", "Number of series term iterations in exact solutions", "ex53.c", options->niter, &options->niter, NULL);CHKERRQ(ierr);
1669*65876a83SMatthew G. Knepley   ierr = PetscOptionsBool("-simplex", "Simplicial (true) or tensor (false) mesh", "ex53.c", options->simplex, &options->simplex, NULL);CHKERRQ(ierr);
1670*65876a83SMatthew G. Knepley   ierr = PetscOptionsReal("-ref_limit", "Maximum cell volume for refined mesh", "ex53.c", options->refLimit, &options->refLimit, NULL);CHKERRQ(ierr);
1671*65876a83SMatthew G. Knepley   sol  = options->solType;
1672*65876a83SMatthew G. Knepley   ierr = PetscOptionsEList("-sol_type", "Type of exact solution", "ex53.c", solutionTypes, NUM_SOLUTION_TYPES, solutionTypes[options->solType], &sol, NULL);CHKERRQ(ierr);
1673*65876a83SMatthew G. Knepley   options->solType = (SolutionType) sol;
1674*65876a83SMatthew G. Knepley   ierr = PetscOptionsFList("-dm_type", "Convert DMPlex to another format", "ex53.c", DMList, options->dmType, options->dmType, 256, NULL);CHKERRQ(ierr);
1675*65876a83SMatthew G. Knepley   ierr = PetscOptionsReal("-eps", " Precision value for root finding", "ex53.c", options->eps, &options->eps, NULL);CHKERRQ(ierr);
1676*65876a83SMatthew G. Knepley 
1677*65876a83SMatthew G. Knepley   // Wrap up loose ends
1678*65876a83SMatthew G. Knepley   if (options->solType == SOL_CRYER) {
1679*65876a83SMatthew G. Knepley     options->dim = 3;
1680*65876a83SMatthew G. Knepley   }
1681*65876a83SMatthew G. Knepley 
1682*65876a83SMatthew G. Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
1683*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
1684*65876a83SMatthew G. Knepley }
1685*65876a83SMatthew G. Knepley 
1686*65876a83SMatthew G. Knepley static PetscErrorCode mandelZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param)
1687*65876a83SMatthew G. Knepley {
1688*65876a83SMatthew G. Knepley   //PetscBag       bag;
1689*65876a83SMatthew G. Knepley   PetscReal a1, a2, am;
1690*65876a83SMatthew G. Knepley   PetscReal y1, y2, ym;
1691*65876a83SMatthew G. Knepley 
1692*65876a83SMatthew G. Knepley   PetscFunctionBeginUser;
1693*65876a83SMatthew G. Knepley   //ierr = PetscBagGetData(ctx->bag, (void **) &param);CHKERRQ(ierr);
1694*65876a83SMatthew G. Knepley   PetscInt NITER = ctx->niter;
1695*65876a83SMatthew G. Knepley   PetscReal EPS = ctx->eps;
1696*65876a83SMatthew G. Knepley   //const PetscScalar YMAX = param->ymax;
1697*65876a83SMatthew G. Knepley   //const PetscScalar YMIN = param->ymin;
1698*65876a83SMatthew G. Knepley   PetscScalar alpha = param->alpha;
1699*65876a83SMatthew G. Knepley   PetscScalar K_u = param->K_u;
1700*65876a83SMatthew G. Knepley   PetscScalar M = param->M;
1701*65876a83SMatthew G. Knepley   PetscScalar G = param->mu;
1702*65876a83SMatthew G. Knepley   //const PetscScalar k = param->k;
1703*65876a83SMatthew G. Knepley   //const PetscScalar mu_f = param->mu_f;
1704*65876a83SMatthew G. Knepley   //const PetscScalar P_0 = param->P_0;
1705*65876a83SMatthew G. Knepley 
1706*65876a83SMatthew G. Knepley   PetscScalar K_d = K_u - alpha*alpha*M;
1707*65876a83SMatthew G. Knepley   PetscScalar nu = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G ));
1708*65876a83SMatthew G. Knepley   PetscScalar nu_u = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G ));
1709*65876a83SMatthew G. Knepley   //const PetscScalar kappa = k / mu_f;
1710*65876a83SMatthew G. Knepley 
1711*65876a83SMatthew G. Knepley   // Generate zero values
1712*65876a83SMatthew G. Knepley   for (PetscInt i=1; i < NITER+1; i++)
1713*65876a83SMatthew G. Knepley   {
1714*65876a83SMatthew G. Knepley     a1 = ((PetscReal) i - 1.0 ) * PETSC_PI * PETSC_PI / 4.0 + EPS;
1715*65876a83SMatthew G. Knepley     a2 = a1 + PETSC_PI/2;
1716*65876a83SMatthew G. Knepley     am = a1;
1717*65876a83SMatthew G. Knepley     for (PetscInt j=0; j<NITER; j++)
1718*65876a83SMatthew G. Knepley     {
1719*65876a83SMatthew G. Knepley       y1 = PetscTanReal(a1) - PetscRealPart((1.0 - nu)/(nu_u - nu))*a1;
1720*65876a83SMatthew G. Knepley       y2 = PetscTanReal(a2) - PetscRealPart((1.0 - nu)/(nu_u - nu))*a2;
1721*65876a83SMatthew G. Knepley       am = (a1 + a2)/2.0;
1722*65876a83SMatthew G. Knepley       ym = PetscTanReal(am) - PetscRealPart((1.0 - nu)/(nu_u - nu))*am;
1723*65876a83SMatthew G. Knepley       if ((ym*y1) > 0)
1724*65876a83SMatthew G. Knepley       {
1725*65876a83SMatthew G. Knepley         a1 = am;
1726*65876a83SMatthew G. Knepley       } else {
1727*65876a83SMatthew G. Knepley         a2 = am;
1728*65876a83SMatthew G. Knepley       }
1729*65876a83SMatthew G. Knepley       if (PetscAbsReal(y2) < EPS)
1730*65876a83SMatthew G. Knepley       {
1731*65876a83SMatthew G. Knepley         am = a2;
1732*65876a83SMatthew G. Knepley       }
1733*65876a83SMatthew G. Knepley     }
1734*65876a83SMatthew G. Knepley     ctx->zeroArray[i-1] = am;
1735*65876a83SMatthew G. Knepley   }
1736*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
1737*65876a83SMatthew G. Knepley }
1738*65876a83SMatthew G. Knepley 
1739*65876a83SMatthew G. Knepley static PetscReal CryerFunction(PetscReal nu_u, PetscReal nu, PetscReal x)
1740*65876a83SMatthew G. Knepley {
1741*65876a83SMatthew 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));
1742*65876a83SMatthew G. Knepley }
1743*65876a83SMatthew G. Knepley 
1744*65876a83SMatthew G. Knepley static PetscErrorCode cryerZeros(MPI_Comm comm, AppCtx *ctx, Parameter *param)
1745*65876a83SMatthew G. Knepley {
1746*65876a83SMatthew G. Knepley   PetscReal   alpha = PetscRealPart(param->alpha); /* -  */
1747*65876a83SMatthew G. Knepley   PetscReal   K_u   = PetscRealPart(param->K_u);   /* Pa */
1748*65876a83SMatthew G. Knepley   PetscReal   M     = PetscRealPart(param->M);     /* Pa */
1749*65876a83SMatthew G. Knepley   PetscReal   G     = PetscRealPart(param->mu);    /* Pa */
1750*65876a83SMatthew G. Knepley   PetscInt    N     = ctx->niter, n;
1751*65876a83SMatthew G. Knepley 
1752*65876a83SMatthew G. Knepley   PetscReal   K_d   = K_u - alpha*alpha*M;                       /* Pa,      Cheng (B.5)  */
1753*65876a83SMatthew G. Knepley   PetscReal   nu    = (3.0*K_d - 2.0*G) / (2.0*(3.0*K_d + G));   /* -,       Cheng (B.8)  */
1754*65876a83SMatthew G. Knepley   PetscReal   nu_u  = (3.0*K_u - 2.0*G) / (2.0*(3.0*K_u + G));   /* -,       Cheng (B.9)  */
1755*65876a83SMatthew G. Knepley 
1756*65876a83SMatthew G. Knepley   PetscFunctionBeginUser;
1757*65876a83SMatthew G. Knepley   for (n = 1; n < N+1; ++n) {
1758*65876a83SMatthew G. Knepley     PetscReal tol = PetscPowReal(n, 1.5)*ctx->eps;
1759*65876a83SMatthew G. Knepley     PetscReal a1 = 0., a2 = 0., am = 0.;
1760*65876a83SMatthew G. Knepley     PetscReal y1, y2, ym;
1761*65876a83SMatthew G. Knepley     PetscInt  j, k = n-1;
1762*65876a83SMatthew G. Knepley 
1763*65876a83SMatthew G. Knepley     y1 = y2 = 1.;
1764*65876a83SMatthew G. Knepley     while (y1*y2 > 0) {
1765*65876a83SMatthew G. Knepley       ++k;
1766*65876a83SMatthew G. Knepley       a1 = PetscSqr(n*PETSC_PI) - k*PETSC_PI;
1767*65876a83SMatthew G. Knepley       a2 = PetscSqr(n*PETSC_PI) + k*PETSC_PI;
1768*65876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
1769*65876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
1770*65876a83SMatthew G. Knepley     }
1771*65876a83SMatthew G. Knepley     for (j = 0; j < 50000; ++j) {
1772*65876a83SMatthew G. Knepley       y1 = CryerFunction(nu_u, nu, a1);
1773*65876a83SMatthew G. Knepley       y2 = CryerFunction(nu_u, nu, a2);
1774*65876a83SMatthew 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);
1775*65876a83SMatthew G. Knepley       am = (a1 + a2) / 2.0;
1776*65876a83SMatthew G. Knepley       ym = CryerFunction(nu_u, nu, am);
1777*65876a83SMatthew G. Knepley       if ((ym * y1) < 0) a2 = am;
1778*65876a83SMatthew G. Knepley       else               a1 = am;
1779*65876a83SMatthew G. Knepley       if (PetscAbsScalar(ym) < tol) break;
1780*65876a83SMatthew G. Knepley     }
1781*65876a83SMatthew G. Knepley     if (PetscAbsScalar(ym) >= tol) SETERRQ2(comm, PETSC_ERR_PLIB, "Root finding did not converge for root %D (%g)", n, PetscAbsScalar(ym));
1782*65876a83SMatthew G. Knepley     ctx->zeroArray[n-1] = am;
1783*65876a83SMatthew G. Knepley   }
1784*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
1785*65876a83SMatthew G. Knepley }
1786*65876a83SMatthew G. Knepley 
1787*65876a83SMatthew G. Knepley static PetscErrorCode SetupParameters(MPI_Comm comm, AppCtx *ctx)
1788*65876a83SMatthew G. Knepley {
1789*65876a83SMatthew G. Knepley   PetscBag       bag;
1790*65876a83SMatthew G. Knepley   Parameter     *p;
1791*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1792*65876a83SMatthew G. Knepley 
1793*65876a83SMatthew G. Knepley   PetscFunctionBeginUser;
1794*65876a83SMatthew G. Knepley   /* setup PETSc parameter bag */
1795*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(ctx->bag,(void**)&p);CHKERRQ(ierr);
1796*65876a83SMatthew G. Knepley   ierr = PetscBagSetName(ctx->bag,"par","Poroelastic Parameters");CHKERRQ(ierr);
1797*65876a83SMatthew G. Knepley   bag  = ctx->bag;
1798*65876a83SMatthew G. Knepley   if (ctx->solType == SOL_TERZAGHI) {
1799*65876a83SMatthew G. Knepley     // Realistic values - Terzaghi
1800*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu,     3.0,                 "mu",    "Shear Modulus, Pa");CHKERRQ(ierr);
1801*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->K_u,    9.76,                "K_u",   "Undrained Bulk Modulus, Pa");CHKERRQ(ierr);
1802*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->alpha,  0.6,                 "alpha", "Biot Effective Stress Coefficient, -");CHKERRQ(ierr);
1803*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->M,      16.0,                "M",     "Biot Modulus, Pa");CHKERRQ(ierr);
1804*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->k,      1.5,                 "k",     "Isotropic Permeability, m**2");CHKERRQ(ierr);
1805*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu_f,   1.0,                 "mu_f",  "Fluid Dynamic Viscosity, Pa*s");CHKERRQ(ierr);
1806*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmax,   1.0,                 "zmax",  "Depth Maximum Extent, m");CHKERRQ(ierr);
1807*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmin,   0.0,                 "zmin",  "Depth Minimum Extent, m");CHKERRQ(ierr);
1808*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymax,   10.0,                "ymax",  "Vertical Maximum Extent, m");CHKERRQ(ierr);
1809*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymin,   0.0,                 "ymin",  "Vertical Minimum Extent, m");CHKERRQ(ierr);
1810*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmax,   10.0,                "xmax",  "Horizontal Maximum Extent, m");CHKERRQ(ierr);
1811*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmin,   0.0,                 "xmin",  "Horizontal Minimum Extent, m");CHKERRQ(ierr);
1812*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->P_0,    1.0,                 "P_0",   "Magnitude of Vertical Stress, Pa");CHKERRQ(ierr);
1813*65876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_MANDEL) {
1814*65876a83SMatthew G. Knepley     // Realistic values - Mandel
1815*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu,     0.75,                "mu",    "Shear Modulus, Pa");CHKERRQ(ierr);
1816*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->K_u,    2.6941176470588233,  "K_u",   "Undrained Bulk Modulus, Pa");CHKERRQ(ierr);
1817*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->alpha,  0.6,                 "alpha", "Biot Effective Stress Coefficient, -");CHKERRQ(ierr);
1818*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->M,      4.705882352941176,   "M",     "Biot Modulus, Pa");CHKERRQ(ierr);
1819*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->k,      1.5,                 "k",     "Isotropic Permeability, m**2");CHKERRQ(ierr);
1820*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu_f,   1.0,                 "mu_f",  "Fluid Dynamic Viscosity, Pa*s");CHKERRQ(ierr);
1821*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmax,   1.0,                 "zmax",  "Depth Maximum Extent, m");CHKERRQ(ierr);
1822*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmin,   0.0,                 "zmin",  "Depth Minimum Extent, m");CHKERRQ(ierr);
1823*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymax,   0.25,                "ymax",  "Vertical Maximum Extent, m");CHKERRQ(ierr);
1824*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymin,   0.0,                 "ymin",  "Vertical Minimum Extent, m");CHKERRQ(ierr);
1825*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmax,   1.0,                 "xmax",  "Horizontal Maximum Extent, m");CHKERRQ(ierr);
1826*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmin,   0.0,                 "xmin",  "Horizontal Minimum Extent, m");CHKERRQ(ierr);
1827*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->P_0,    1.0,                 "P_0",   "Magnitude of Vertical Stress, Pa");CHKERRQ(ierr);
1828*65876a83SMatthew G. Knepley   } else if (ctx->solType == SOL_CRYER) {
1829*65876a83SMatthew G. Knepley     // Realistic values - Mandel
1830*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu,     0.75,                "mu",    "Shear Modulus, Pa");CHKERRQ(ierr);
1831*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->K_u,    2.6941176470588233,  "K_u",   "Undrained Bulk Modulus, Pa");CHKERRQ(ierr);
1832*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->alpha,  0.6,                 "alpha", "Biot Effective Stress Coefficient, -");CHKERRQ(ierr);
1833*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->M,      4.705882352941176,   "M",     "Biot Modulus, Pa");CHKERRQ(ierr);
1834*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->k,      1.5,                 "k",     "Isotropic Permeability, m**2");CHKERRQ(ierr);
1835*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu_f,   1.0,                 "mu_f",  "Fluid Dynamic Viscosity, Pa*s");CHKERRQ(ierr);
1836*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmax,   1.0,                 "zmax",  "Depth Maximum Extent, m");CHKERRQ(ierr);
1837*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmin,   0.0,                 "zmin",  "Depth Minimum Extent, m");CHKERRQ(ierr);
1838*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymax,   1.0,                 "ymax",  "Vertical Maximum Extent, m");CHKERRQ(ierr);
1839*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymin,   0.0,                 "ymin",  "Vertical Minimum Extent, m");CHKERRQ(ierr);
1840*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmax,   1.0,                 "xmax",  "Horizontal Maximum Extent, m");CHKERRQ(ierr);
1841*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmin,   0.0,                 "xmin",  "Horizontal Minimum Extent, m");CHKERRQ(ierr);
1842*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->P_0,    1.0,                 "P_0",   "Magnitude of Vertical Stress, Pa");CHKERRQ(ierr);
1843*65876a83SMatthew G. Knepley   } else {
1844*65876a83SMatthew G. Knepley     // Nonsense values
1845*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu,     1.0,                 "mu",    "Shear Modulus, Pa");CHKERRQ(ierr);
1846*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->K_u,    1.0,                 "K_u",   "Undrained Bulk Modulus, Pa");CHKERRQ(ierr);
1847*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->alpha,  1.0,                 "alpha", "Biot Effective Stress Coefficient, -");CHKERRQ(ierr);
1848*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->M,      1.0,                 "M",     "Biot Modulus, Pa");CHKERRQ(ierr);
1849*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->k,      1.0,                 "k",     "Isotropic Permeability, m**2");CHKERRQ(ierr);
1850*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->mu_f,   1.0,                 "mu_f",  "Fluid Dynamic Viscosity, Pa*s");CHKERRQ(ierr);
1851*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmax,   1.0,                 "zmax",  "Depth Maximum Extent, m");CHKERRQ(ierr);
1852*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->zmin,   0.0,                 "zmin",  "Depth Minimum Extent, m");CHKERRQ(ierr);
1853*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymax,   1.0,                 "ymax",  "Vertical Maximum Extent, m");CHKERRQ(ierr);
1854*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->ymin,   0.0,                 "ymin",  "Vertical Minimum Extent, m");CHKERRQ(ierr);
1855*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmax,   1.0,                 "xmax",  "Horizontal Maximum Extent, m");CHKERRQ(ierr);
1856*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->xmin,   0.0,                 "xmin",  "Horizontal Minimum Extent, m");CHKERRQ(ierr);
1857*65876a83SMatthew G. Knepley     ierr = PetscBagRegisterScalar(bag, &p->P_0,    1.0,                 "P_0",   "Magnitude of Vertical Stress, Pa");CHKERRQ(ierr);
1858*65876a83SMatthew G. Knepley   }
1859*65876a83SMatthew G. Knepley   ierr = PetscBagSetFromOptions(bag);CHKERRQ(ierr);
1860*65876a83SMatthew G. Knepley   {
1861*65876a83SMatthew G. Knepley     PetscScalar K_d  = p->K_u - p->alpha*p->alpha*p->M;
1862*65876a83SMatthew G. Knepley     PetscScalar nu_u = (3.0*p->K_u - 2.0*p->mu) / (2.0*(3.0*p->K_u + p->mu));
1863*65876a83SMatthew G. Knepley     PetscScalar nu   = (3.0*K_d - 2.0*p->mu) / (2.0*(3.0*K_d + p->mu));
1864*65876a83SMatthew G. Knepley     PetscScalar S    = (3.0*p->K_u + 4.0*p->mu) / (p->M*(3.0*K_d + 4.0*p->mu));
1865*65876a83SMatthew G. Knepley     PetscReal   c    = PetscRealPart((p->k/p->mu_f) / S);
1866*65876a83SMatthew G. Knepley 
1867*65876a83SMatthew G. Knepley     PetscViewer       viewer;
1868*65876a83SMatthew G. Knepley     PetscViewerFormat format;
1869*65876a83SMatthew G. Knepley     PetscBool         flg;
1870*65876a83SMatthew G. Knepley 
1871*65876a83SMatthew G. Knepley     switch (ctx->solType) {
1872*65876a83SMatthew G. Knepley       case SOL_QUADRATIC_LINEAR:
1873*65876a83SMatthew G. Knepley       case SOL_QUADRATIC_TRIG:
1874*65876a83SMatthew G. Knepley       case SOL_TRIG_LINEAR: ctx->t_r = PetscSqr(p->xmax - p->xmin)/c; break;
1875*65876a83SMatthew G. Knepley       case SOL_TERZAGHI:    ctx->t_r = PetscSqr(2.0*(p->ymax - p->ymin))/c; break;
1876*65876a83SMatthew G. Knepley       case SOL_MANDEL:      ctx->t_r = PetscSqr(2.0*(p->ymax - p->ymin))/c; break;
1877*65876a83SMatthew G. Knepley       case SOL_CRYER:       ctx->t_r = PetscSqr(p->ymax)/c; break;
1878*65876a83SMatthew G. Knepley       default: SETERRQ2(comm, PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%D)", solutionTypes[PetscMin(ctx->solType, NUM_SOLUTION_TYPES)], ctx->solType);
1879*65876a83SMatthew G. Knepley     }
1880*65876a83SMatthew G. Knepley     ierr = PetscOptionsGetViewer(comm, NULL, NULL, "-param_view", &viewer, &format, &flg);CHKERRQ(ierr);
1881*65876a83SMatthew G. Knepley     if (flg) {
1882*65876a83SMatthew G. Knepley       ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
1883*65876a83SMatthew G. Knepley       ierr = PetscBagView(bag, viewer);CHKERRQ(ierr);
1884*65876a83SMatthew G. Knepley       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
1885*65876a83SMatthew G. Knepley       ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
1886*65876a83SMatthew G. Knepley       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1887*65876a83SMatthew 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)));
1888*65876a83SMatthew G. Knepley       ierr = PetscPrintf(comm, "  Relaxation time: %g\n", ctx->t_r);
1889*65876a83SMatthew G. Knepley     }
1890*65876a83SMatthew G. Knepley   }
1891*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
1892*65876a83SMatthew G. Knepley }
1893*65876a83SMatthew G. Knepley 
1894*65876a83SMatthew G. Knepley static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
1895*65876a83SMatthew G. Knepley {
1896*65876a83SMatthew G. Knepley   Parameter     *param;
1897*65876a83SMatthew G. Knepley   PetscBool      flg;
1898*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
1899*65876a83SMatthew G. Knepley 
1900*65876a83SMatthew G. Knepley   PetscFunctionBeginUser;
1901*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1902*65876a83SMatthew G. Knepley   if (user->solType == SOL_CRYER) {
1903*65876a83SMatthew G. Knepley     DM rdm;
1904*65876a83SMatthew G. Knepley 
1905*65876a83SMatthew G. Knepley     if (!user->simplex) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Cannot create ball with cubic cells");
1906*65876a83SMatthew 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);
1907*65876a83SMatthew 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);
1908*65876a83SMatthew G. Knepley     ierr = DMPlexCreateBallMesh(comm, user->dim, param->xmax, dm);CHKERRQ(ierr);
1909*65876a83SMatthew G. Knepley 
1910*65876a83SMatthew G. Knepley     ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr);
1911*65876a83SMatthew G. Knepley     ierr = DMPlexSetRefinementLimit(*dm, user->refLimit);CHKERRQ(ierr);
1912*65876a83SMatthew G. Knepley     ierr = DMRefine(*dm, comm, &rdm);CHKERRQ(ierr);
1913*65876a83SMatthew G. Knepley     if (rdm) {
1914*65876a83SMatthew G. Knepley       ierr = DMDestroy(dm);CHKERRQ(ierr);
1915*65876a83SMatthew G. Knepley       *dm  = rdm;
1916*65876a83SMatthew G. Knepley     }
1917*65876a83SMatthew G. Knepley     ierr = DMPlexSetRefinementUniform(*dm, PETSC_TRUE);CHKERRQ(ierr);
1918*65876a83SMatthew G. Knepley   } else if (user->solType == SOL_MANDEL) {
1919*65876a83SMatthew G. Knepley     PetscReal lower[2], upper[2];
1920*65876a83SMatthew G. Knepley 
1921*65876a83SMatthew G. Knepley     lower[0] = param->xmin - (param->xmax - param->xmin) / 2.0;
1922*65876a83SMatthew G. Knepley     lower[1] = param->ymin - (param->ymax - param->ymin) / 2.0;
1923*65876a83SMatthew G. Knepley     upper[0] = param->xmax - (param->xmax - param->xmin) / 2.0;
1924*65876a83SMatthew G. Knepley     upper[1] = param->ymax - (param->ymax - param->ymin) / 2.0;
1925*65876a83SMatthew G. Knepley     //reset min / max values for mandel
1926*65876a83SMatthew G. Knepley     param->xmin = lower[0];
1927*65876a83SMatthew G. Knepley     param->ymin = lower[1];
1928*65876a83SMatthew G. Knepley     param->xmax = upper[0];
1929*65876a83SMatthew G. Knepley     param->ymax = upper[1];
1930*65876a83SMatthew G. Knepley     ierr = DMPlexCreateBoxMesh(comm, user->dim, user->simplex, NULL, lower, upper, NULL, PETSC_TRUE, dm);CHKERRQ(ierr);
1931*65876a83SMatthew G. Knepley   } else {
1932*65876a83SMatthew G. Knepley     Parameter *param;
1933*65876a83SMatthew G. Knepley     PetscReal  lower[3], upper[3];
1934*65876a83SMatthew G. Knepley 
1935*65876a83SMatthew G. Knepley     ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1936*65876a83SMatthew G. Knepley     lower[0] = param->xmin;
1937*65876a83SMatthew G. Knepley     lower[1] = param->ymin;
1938*65876a83SMatthew G. Knepley     lower[2] = param->zmin;
1939*65876a83SMatthew G. Knepley     upper[0] = param->xmax;
1940*65876a83SMatthew G. Knepley     upper[1] = param->ymax;
1941*65876a83SMatthew G. Knepley     upper[2] = param->zmax;
1942*65876a83SMatthew G. Knepley     ierr = DMPlexCreateBoxMesh(comm, user->dim, user->simplex, NULL, lower, upper, NULL, PETSC_TRUE, dm);CHKERRQ(ierr);
1943*65876a83SMatthew G. Knepley   }
1944*65876a83SMatthew G. Knepley   {
1945*65876a83SMatthew G. Knepley     DM               pdm = NULL;
1946*65876a83SMatthew G. Knepley     PetscPartitioner part;
1947*65876a83SMatthew G. Knepley 
1948*65876a83SMatthew G. Knepley     ierr = DMPlexGetPartitioner(*dm, &part);CHKERRQ(ierr);
1949*65876a83SMatthew G. Knepley     ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr);
1950*65876a83SMatthew G. Knepley     ierr = DMPlexDistribute(*dm, 0, NULL, &pdm);CHKERRQ(ierr);
1951*65876a83SMatthew G. Knepley     if (pdm) {
1952*65876a83SMatthew G. Knepley       ierr = DMDestroy(dm);CHKERRQ(ierr);
1953*65876a83SMatthew G. Knepley       *dm  = pdm;
1954*65876a83SMatthew G. Knepley     }
1955*65876a83SMatthew G. Knepley   }
1956*65876a83SMatthew G. Knepley   ierr = PetscStrcmp(user->dmType, DMPLEX, &flg);CHKERRQ(ierr);
1957*65876a83SMatthew G. Knepley   if (flg) {
1958*65876a83SMatthew G. Knepley     DM ndm;
1959*65876a83SMatthew G. Knepley 
1960*65876a83SMatthew G. Knepley     ierr = DMConvert(*dm, user->dmType, &ndm);CHKERRQ(ierr);
1961*65876a83SMatthew G. Knepley     if (ndm) {
1962*65876a83SMatthew G. Knepley       ierr = DMDestroy(dm);CHKERRQ(ierr);
1963*65876a83SMatthew G. Knepley       *dm  = ndm;
1964*65876a83SMatthew G. Knepley     }
1965*65876a83SMatthew G. Knepley   }
1966*65876a83SMatthew G. Knepley   ierr = DMLocalizeCoordinates(*dm);CHKERRQ(ierr);
1967*65876a83SMatthew G. Knepley 
1968*65876a83SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *dm, "Mesh");CHKERRQ(ierr);
1969*65876a83SMatthew G. Knepley   ierr = DMSetApplicationContext(*dm, user);CHKERRQ(ierr);
1970*65876a83SMatthew G. Knepley   ierr = DMSetFromOptions(*dm);CHKERRQ(ierr);
1971*65876a83SMatthew G. Knepley   ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr);
1972*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
1973*65876a83SMatthew G. Knepley }
1974*65876a83SMatthew G. Knepley 
1975*65876a83SMatthew G. Knepley static PetscErrorCode SetupPrimalProblem(DM dm, AppCtx *user)
1976*65876a83SMatthew G. Knepley {
1977*65876a83SMatthew G. Knepley   PetscErrorCode (*exact[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
1978*65876a83SMatthew G. Knepley   PetscErrorCode (*exact_t[3])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
1979*65876a83SMatthew G. Knepley   PetscDS          prob;
1980*65876a83SMatthew G. Knepley   Parameter       *param;
1981*65876a83SMatthew G. Knepley   PetscInt         id_mandel[2];
1982*65876a83SMatthew G. Knepley   PetscInt         comp[1];
1983*65876a83SMatthew G. Knepley   PetscInt         comp_mandel[2];
1984*65876a83SMatthew G. Knepley   PetscInt         dim, id, f;
1985*65876a83SMatthew G. Knepley   PetscErrorCode   ierr;
1986*65876a83SMatthew G. Knepley 
1987*65876a83SMatthew G. Knepley   PetscFunctionBeginUser;
1988*65876a83SMatthew G. Knepley   ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
1989*65876a83SMatthew G. Knepley   ierr = PetscDSGetSpatialDimension(prob, &dim);CHKERRQ(ierr);
1990*65876a83SMatthew G. Knepley   ierr = PetscBagGetData(user->bag, (void **) &param);CHKERRQ(ierr);
1991*65876a83SMatthew G. Knepley   exact_t[0] = exact_t[1] = exact_t[2] = zero;
1992*65876a83SMatthew G. Knepley 
1993*65876a83SMatthew G. Knepley   /* Setup Problem Formulation and Boundary Conditions */
1994*65876a83SMatthew G. Knepley   switch (user->solType) {
1995*65876a83SMatthew G. Knepley   case SOL_QUADRATIC_LINEAR:
1996*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 0, f0_quadratic_linear_u, f1_u);CHKERRQ(ierr);
1997*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 1, f0_epsilon,            NULL);CHKERRQ(ierr);
1998*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 2, f0_quadratic_linear_p, f1_p);CHKERRQ(ierr);
1999*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2000*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2001*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2002*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2003*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2004*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 1, g0_pe, NULL,  NULL,  NULL);CHKERRQ(ierr);
2005*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 2, g0_pp, NULL,  NULL,  g3_pp);CHKERRQ(ierr);
2006*65876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
2007*65876a83SMatthew G. Knepley     exact[1]   = linear_eps;
2008*65876a83SMatthew G. Knepley     exact[2]   = linear_linear_p;
2009*65876a83SMatthew G. Knepley     exact_t[2] = linear_linear_p_t;
2010*65876a83SMatthew G. Knepley 
2011*65876a83SMatthew G. Knepley     id = 1;
2012*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", "marker", 0, 0, NULL, (void (*)(void)) exact[0], NULL,                        1, &id, user);CHKERRQ(ierr);
2013*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure",     "marker", 2, 0, NULL, (void (*)(void)) exact[2], (void (*)(void)) exact_t[2], 1, &id, user);CHKERRQ(ierr);
2014*65876a83SMatthew G. Knepley     break;
2015*65876a83SMatthew G. Knepley   case SOL_TRIG_LINEAR:
2016*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 0, f0_trig_linear_u, f1_u);CHKERRQ(ierr);
2017*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 1, f0_epsilon,       NULL);CHKERRQ(ierr);
2018*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 2, f0_trig_linear_p, f1_p);CHKERRQ(ierr);
2019*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2020*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2021*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2022*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2023*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2024*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 1, g0_pe, NULL,  NULL,  NULL);CHKERRQ(ierr);
2025*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 2, g0_pp, NULL,  NULL,  g3_pp);CHKERRQ(ierr);
2026*65876a83SMatthew G. Knepley     exact[0]   = trig_u;
2027*65876a83SMatthew G. Knepley     exact[1]   = trig_eps;
2028*65876a83SMatthew G. Knepley     exact[2]   = trig_linear_p;
2029*65876a83SMatthew G. Knepley     exact_t[2] = trig_linear_p_t;
2030*65876a83SMatthew G. Knepley 
2031*65876a83SMatthew G. Knepley     id = 1;
2032*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", "marker", 0, 0, NULL, (void (*)(void)) exact[0], NULL,                        1, &id, user);CHKERRQ(ierr);
2033*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure",     "marker", 2, 0, NULL, (void (*)(void)) exact[2], (void (*)(void)) exact_t[2], 1, &id, user);CHKERRQ(ierr);
2034*65876a83SMatthew G. Knepley     break;
2035*65876a83SMatthew G. Knepley   case SOL_QUADRATIC_TRIG:
2036*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 0, f0_quadratic_trig_u, f1_u);CHKERRQ(ierr);
2037*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 1, f0_epsilon,          NULL);CHKERRQ(ierr);
2038*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 2, f0_quadratic_trig_p, f1_p);CHKERRQ(ierr);
2039*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2040*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2041*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2042*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2043*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2044*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 1, g0_pe, NULL,  NULL,  NULL);CHKERRQ(ierr);
2045*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 2, g0_pp, NULL,  NULL,  g3_pp);CHKERRQ(ierr);
2046*65876a83SMatthew G. Knepley     exact[0]   = quadratic_u;
2047*65876a83SMatthew G. Knepley     exact[1]   = linear_eps;
2048*65876a83SMatthew G. Knepley     exact[2]   = linear_trig_p;
2049*65876a83SMatthew G. Knepley     exact_t[2] = linear_trig_p_t;
2050*65876a83SMatthew G. Knepley 
2051*65876a83SMatthew G. Knepley     id = 1;
2052*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall displacement", "marker", 0, 0, NULL, (void (*)(void)) exact[0],                        NULL, 1, &id, user);CHKERRQ(ierr);
2053*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall pressure",     "marker", 2, 0, NULL, (void (*)(void)) exact[2], (void (*)(void)) exact_t[2], 1, &id, user);CHKERRQ(ierr);
2054*65876a83SMatthew G. Knepley     break;
2055*65876a83SMatthew G. Knepley   case SOL_TERZAGHI:
2056*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 0, NULL, f1_u);CHKERRQ(ierr);
2057*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 1, f0_epsilon,     NULL);CHKERRQ(ierr);
2058*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 2, f0_p,           f1_p);CHKERRQ(ierr);
2059*65876a83SMatthew G. Knepley     ierr = PetscDSSetBdResidual(prob, 0, f0_terzaghi_bd_u, NULL);CHKERRQ(ierr);
2060*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2061*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2062*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2063*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2064*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2065*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 1, g0_pe,  NULL,  NULL,  NULL);CHKERRQ(ierr);
2066*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 2, g0_pp,  NULL,  NULL,  g3_pp);CHKERRQ(ierr);
2067*65876a83SMatthew G. Knepley 
2068*65876a83SMatthew G. Knepley     exact[0] = terzaghi_2d_u;
2069*65876a83SMatthew G. Knepley     exact[1] = terzaghi_2d_eps;
2070*65876a83SMatthew G. Knepley     exact[2] = terzaghi_2d_p;
2071*65876a83SMatthew G. Knepley     exact_t[0] = terzaghi_2d_u_t;
2072*65876a83SMatthew G. Knepley     exact_t[1] = terzaghi_2d_eps_t;
2073*65876a83SMatthew G. Knepley     exact_t[2] = terzaghi_2d_p_t;
2074*65876a83SMatthew G. Knepley 
2075*65876a83SMatthew G. Knepley     id = 1;
2076*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", "marker", 0, 0, NULL, NULL, NULL, 1, &id, user);CHKERRQ(ierr);
2077*65876a83SMatthew G. Knepley     id = 3;
2078*65876a83SMatthew G. Knepley     comp[0] = 1;
2079*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", "marker", 0, 1, comp, (void (*)(void)) zero, NULL, 1, &id, user);CHKERRQ(ierr);
2080*65876a83SMatthew G. Knepley     id = 2;
2081*65876a83SMatthew G. Knepley     comp[0] = 0;
2082*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side", "marker", 0, 1, comp, (void (*)(void)) zero, NULL, 1, &id, user);CHKERRQ(ierr);
2083*65876a83SMatthew G. Knepley     id = 4;
2084*65876a83SMatthew G. Knepley     comp[0] = 0;
2085*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed side", "marker", 0, 1, comp, (void (*)(void)) zero, NULL, 1, &id, user);CHKERRQ(ierr);
2086*65876a83SMatthew G. Knepley     id = 1;
2087*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", "marker", 2, 0, NULL, (void (*)(void)) terzaghi_drainage_pressure, NULL, 1, &id, user);CHKERRQ(ierr);
2088*65876a83SMatthew G. Knepley     break;
2089*65876a83SMatthew G. Knepley   case SOL_MANDEL:
2090*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 0, NULL, f1_u);CHKERRQ(ierr);
2091*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 1, f0_epsilon,     NULL);CHKERRQ(ierr);
2092*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 2, f0_p,           f1_p);CHKERRQ(ierr);
2093*65876a83SMatthew G. Knepley     ierr = PetscDSSetBdResidual(prob, 0, f0_mandel_bd_u, NULL);CHKERRQ(ierr);
2094*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2095*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2096*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2097*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2098*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2099*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 1, g0_pe,  NULL,  NULL,  NULL);CHKERRQ(ierr);
2100*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 2, g0_pp,  NULL,  NULL,  g3_pp);CHKERRQ(ierr);
2101*65876a83SMatthew G. Knepley 
2102*65876a83SMatthew G. Knepley     ierr = mandelZeros(PETSC_COMM_WORLD, user, param);CHKERRQ(ierr);
2103*65876a83SMatthew G. Knepley 
2104*65876a83SMatthew G. Knepley     exact[0] = mandel_2d_u;
2105*65876a83SMatthew G. Knepley     exact[1] = mandel_2d_eps;
2106*65876a83SMatthew G. Knepley     exact[2] = mandel_2d_p;
2107*65876a83SMatthew G. Knepley     exact_t[0] = mandel_2d_u_t;
2108*65876a83SMatthew G. Knepley     exact_t[1] = mandel_2d_eps_t;
2109*65876a83SMatthew G. Knepley     exact_t[2] = mandel_2d_p_t;
2110*65876a83SMatthew G. Knepley 
2111*65876a83SMatthew G. Knepley     id_mandel[0] = 3;
2112*65876a83SMatthew G. Knepley     id_mandel[1] = 1;
2113*65876a83SMatthew G. Knepley     //comp[0] = 1;
2114*65876a83SMatthew G. Knepley     comp_mandel[0] = 0;
2115*65876a83SMatthew G. Knepley     comp_mandel[1] = 1;
2116*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "vertical stress", "marker", 0, 2, comp_mandel, (void (*)(void)) mandel_2d_u, NULL, 2, id_mandel, user);CHKERRQ(ierr);
2117*65876a83SMatthew G. Knepley     //ierr = DMAddBoundary(dm, DM_BC_NATURAL, "vertical stress", "marker", 0, 1, comp, NULL, 2, id_mandel, user);CHKERRQ(ierr);
2118*65876a83SMatthew G. Knepley     //ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "fixed base", "marker", 0, 1, comp, (void (*)(void)) zero, 2, id_mandel, user);CHKERRQ(ierr);
2119*65876a83SMatthew G. Knepley 
2120*65876a83SMatthew G. Knepley     id_mandel[0] = 2;
2121*65876a83SMatthew G. Knepley     id_mandel[1] = 4;
2122*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", "marker", 2, 0, NULL, (void (*)(void)) zero, NULL, 2, id_mandel, user);CHKERRQ(ierr);
2123*65876a83SMatthew G. Knepley     break;
2124*65876a83SMatthew G. Knepley   case SOL_CRYER:
2125*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 0, NULL, f1_u);CHKERRQ(ierr);
2126*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 1, f0_epsilon,     NULL);CHKERRQ(ierr);
2127*65876a83SMatthew G. Knepley     ierr = PetscDSSetResidual(prob, 2, f0_p,           f1_p);CHKERRQ(ierr);
2128*65876a83SMatthew G. Knepley     ierr = PetscDSSetBdResidual(prob, 0, f0_cryer_bd_u, NULL);CHKERRQ(ierr);
2129*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 0, NULL,  NULL,  NULL,  g3_uu);CHKERRQ(ierr);
2130*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 1, NULL,  NULL,  g2_ue, NULL);CHKERRQ(ierr);
2131*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 0, 2, NULL,  NULL,  g2_up, NULL);CHKERRQ(ierr);
2132*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 0, NULL,  g1_eu, NULL,  NULL);CHKERRQ(ierr);
2133*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 1, 1, g0_ee, NULL,  NULL,  NULL);CHKERRQ(ierr);
2134*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 1, g0_pe,  NULL,  NULL,  NULL);CHKERRQ(ierr);
2135*65876a83SMatthew G. Knepley     ierr = PetscDSSetJacobian(prob, 2, 2, g0_pp,  NULL,  NULL,  g3_pp);CHKERRQ(ierr);
2136*65876a83SMatthew G. Knepley 
2137*65876a83SMatthew G. Knepley     ierr = cryerZeros(PETSC_COMM_WORLD, user, param);CHKERRQ(ierr);
2138*65876a83SMatthew G. Knepley 
2139*65876a83SMatthew G. Knepley     exact[0] = cryer_3d_u;
2140*65876a83SMatthew G. Knepley     exact[1] = cryer_3d_eps;
2141*65876a83SMatthew G. Knepley     exact[2] = cryer_3d_p;
2142*65876a83SMatthew G. Knepley 
2143*65876a83SMatthew G. Knepley     id = 1;
2144*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_NATURAL,   "normal stress",   "marker", 0, 0, NULL, NULL,                                     NULL, 1, &id, user);CHKERRQ(ierr);
2145*65876a83SMatthew G. Knepley     ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "drained surface", "marker", 2, 0, NULL, (void (*)(void)) cryer_drainage_pressure, NULL, 1, &id, user);CHKERRQ(ierr);
2146*65876a83SMatthew G. Knepley     break;
2147*65876a83SMatthew G. Knepley   default: SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Invalid solution type: %s (%D)", solutionTypes[PetscMin(user->solType, NUM_SOLUTION_TYPES)], user->solType);
2148*65876a83SMatthew G. Knepley   }
2149*65876a83SMatthew G. Knepley   for (f = 0; f < 3; ++f) {
2150*65876a83SMatthew G. Knepley     ierr = PetscDSSetExactSolution(prob, f, exact[f], user);CHKERRQ(ierr);
2151*65876a83SMatthew G. Knepley     ierr = PetscDSSetExactSolutionTimeDerivative(prob, f, exact_t[f], user);CHKERRQ(ierr);
2152*65876a83SMatthew G. Knepley   }
2153*65876a83SMatthew G. Knepley 
2154*65876a83SMatthew G. Knepley   /* Setup constants */
2155*65876a83SMatthew G. Knepley   {
2156*65876a83SMatthew G. Knepley     PetscScalar constants[6];
2157*65876a83SMatthew G. Knepley     constants[0] = param->mu;            /* shear modulus, Pa */
2158*65876a83SMatthew G. Knepley     constants[1] = param->K_u;           /* undrained bulk modulus, Pa */
2159*65876a83SMatthew G. Knepley     constants[2] = param->alpha;         /* Biot effective stress coefficient, - */
2160*65876a83SMatthew G. Knepley     constants[3] = param->M;             /* Biot modulus, Pa */
2161*65876a83SMatthew G. Knepley     constants[4] = param->k/param->mu_f; /* Darcy coefficient, m**2 / Pa*s */
2162*65876a83SMatthew G. Knepley     constants[5] = param->P_0;           /* Magnitude of Vertical Stress, Pa */
2163*65876a83SMatthew G. Knepley     ierr = PetscDSSetConstants(prob, 6, constants);CHKERRQ(ierr);
2164*65876a83SMatthew G. Knepley   }
2165*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
2166*65876a83SMatthew G. Knepley }
2167*65876a83SMatthew G. Knepley 
2168*65876a83SMatthew G. Knepley static PetscErrorCode CreateElasticityNullSpace(DM dm, PetscInt dummy, MatNullSpace *nullspace)
2169*65876a83SMatthew G. Knepley {
2170*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
2171*65876a83SMatthew G. Knepley 
2172*65876a83SMatthew G. Knepley   PetscFunctionBegin;
2173*65876a83SMatthew G. Knepley   ierr = DMPlexCreateRigidBody(dm, 0, nullspace);CHKERRQ(ierr);
2174*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
2175*65876a83SMatthew G. Knepley }
2176*65876a83SMatthew G. Knepley 
2177*65876a83SMatthew G. Knepley PetscErrorCode SetupFE(DM dm, PetscBool simplex, PetscInt Nf, PetscInt Nc[], const char *name[], PetscErrorCode (*setup)(DM, AppCtx *), void *ctx)
2178*65876a83SMatthew G. Knepley {
2179*65876a83SMatthew G. Knepley   AppCtx         *user = (AppCtx *) ctx;
2180*65876a83SMatthew G. Knepley   DM              cdm  = dm;
2181*65876a83SMatthew G. Knepley   PetscFE         fe;
2182*65876a83SMatthew G. Knepley   PetscQuadrature q = NULL;
2183*65876a83SMatthew G. Knepley   char            prefix[PETSC_MAX_PATH_LEN];
2184*65876a83SMatthew G. Knepley   PetscInt        dim, f;
2185*65876a83SMatthew G. Knepley   PetscErrorCode  ierr;
2186*65876a83SMatthew G. Knepley 
2187*65876a83SMatthew G. Knepley   PetscFunctionBegin;
2188*65876a83SMatthew G. Knepley   /* Create finite element */
2189*65876a83SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
2190*65876a83SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
2191*65876a83SMatthew G. Knepley     ierr = PetscSNPrintf(prefix, PETSC_MAX_PATH_LEN, "%s_", name[f]);CHKERRQ(ierr);
2192*65876a83SMatthew G. Knepley     ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) dm), dim, Nc[f], simplex, name[f] ? prefix : NULL, -1, &fe);CHKERRQ(ierr);
2193*65876a83SMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) fe, name[f]);CHKERRQ(ierr);
2194*65876a83SMatthew G. Knepley     if (!q) {ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr);}
2195*65876a83SMatthew G. Knepley     ierr = PetscFESetQuadrature(fe, q);CHKERRQ(ierr);
2196*65876a83SMatthew G. Knepley     ierr = DMSetField(dm, f, NULL, (PetscObject) fe);CHKERRQ(ierr);
2197*65876a83SMatthew G. Knepley     ierr = PetscFEDestroy(&fe);CHKERRQ(ierr);
2198*65876a83SMatthew G. Knepley   }
2199*65876a83SMatthew G. Knepley   ierr = DMCreateDS(dm);CHKERRQ(ierr);
2200*65876a83SMatthew G. Knepley   ierr = (*setup)(dm, user);CHKERRQ(ierr);
2201*65876a83SMatthew G. Knepley   while (cdm) {
2202*65876a83SMatthew G. Knepley     ierr = DMCopyDisc(dm, cdm);CHKERRQ(ierr);
2203*65876a83SMatthew G. Knepley     if (0) {ierr = DMSetNearNullSpaceConstructor(cdm, 0, CreateElasticityNullSpace);CHKERRQ(ierr);}
2204*65876a83SMatthew G. Knepley     /* TODO: Check whether the boundary of coarse meshes is marked */
2205*65876a83SMatthew G. Knepley     ierr = DMGetCoarseDM(cdm, &cdm);CHKERRQ(ierr);
2206*65876a83SMatthew G. Knepley   }
2207*65876a83SMatthew G. Knepley   ierr = PetscFEDestroy(&fe);CHKERRQ(ierr);
2208*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
2209*65876a83SMatthew G. Knepley }
2210*65876a83SMatthew G. Knepley 
2211*65876a83SMatthew G. Knepley static PetscErrorCode SetInitialConditions(TS ts, Vec u)
2212*65876a83SMatthew G. Knepley {
2213*65876a83SMatthew G. Knepley   DM             dm;
2214*65876a83SMatthew G. Knepley   PetscReal      t;
2215*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
2216*65876a83SMatthew G. Knepley 
2217*65876a83SMatthew G. Knepley   PetscFunctionBegin;
2218*65876a83SMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
2219*65876a83SMatthew G. Knepley   ierr = TSGetTime(ts, &t);CHKERRQ(ierr);
2220*65876a83SMatthew G. Knepley   if (t <= 0.0) {
2221*65876a83SMatthew G. Knepley     PetscErrorCode (*funcs[3])(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *);
2222*65876a83SMatthew G. Knepley     void            *ctxs[3];
2223*65876a83SMatthew G. Knepley     AppCtx          *ctx;
2224*65876a83SMatthew G. Knepley 
2225*65876a83SMatthew G. Knepley     ierr = DMGetApplicationContext(dm, (void **) &ctx);CHKERRQ(ierr);
2226*65876a83SMatthew G. Knepley     switch (ctx->solType) {
2227*65876a83SMatthew G. Knepley       case SOL_TERZAGHI:
2228*65876a83SMatthew G. Knepley         funcs[0] = terzaghi_initial_u;         ctxs[0] = ctx;
2229*65876a83SMatthew G. Knepley         funcs[1] = terzaghi_initial_eps;       ctxs[1] = ctx;
2230*65876a83SMatthew G. Knepley         funcs[2] = terzaghi_drainage_pressure; ctxs[2] = ctx;
2231*65876a83SMatthew G. Knepley         ierr = DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u);CHKERRQ(ierr);
2232*65876a83SMatthew G. Knepley         break;
2233*65876a83SMatthew G. Knepley       case SOL_MANDEL:
2234*65876a83SMatthew G. Knepley         funcs[0] = mandel_initial_u;         ctxs[0] = ctx;
2235*65876a83SMatthew G. Knepley         funcs[1] = mandel_initial_eps;       ctxs[1] = ctx;
2236*65876a83SMatthew G. Knepley         funcs[2] = mandel_drainage_pressure; ctxs[2] = ctx;
2237*65876a83SMatthew G. Knepley         ierr = DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u);CHKERRQ(ierr);
2238*65876a83SMatthew G. Knepley         break;
2239*65876a83SMatthew G. Knepley       case SOL_CRYER:
2240*65876a83SMatthew G. Knepley         funcs[0] = cryer_initial_u;         ctxs[0] = ctx;
2241*65876a83SMatthew G. Knepley         funcs[1] = cryer_initial_eps;       ctxs[1] = ctx;
2242*65876a83SMatthew G. Knepley         funcs[2] = cryer_drainage_pressure; ctxs[2] = ctx;
2243*65876a83SMatthew G. Knepley         ierr = DMProjectFunction(dm, t, funcs, ctxs, INSERT_VALUES, u);CHKERRQ(ierr);
2244*65876a83SMatthew G. Knepley         break;
2245*65876a83SMatthew G. Knepley       default:
2246*65876a83SMatthew G. Knepley         ierr = DMComputeExactSolution(dm, t, u, NULL);CHKERRQ(ierr);
2247*65876a83SMatthew G. Knepley     }
2248*65876a83SMatthew G. Knepley   } else {
2249*65876a83SMatthew G. Knepley     ierr = DMComputeExactSolution(dm, t, u, NULL);CHKERRQ(ierr);
2250*65876a83SMatthew G. Knepley   }
2251*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
2252*65876a83SMatthew G. Knepley }
2253*65876a83SMatthew G. Knepley 
2254*65876a83SMatthew G. Knepley /* Need to create Viewer each time because HDF5 can get corrupted */
2255*65876a83SMatthew G. Knepley static PetscErrorCode SolutionMonitor(TS ts, PetscInt steps, PetscReal time, Vec u, void *mctx)
2256*65876a83SMatthew G. Knepley {
2257*65876a83SMatthew G. Knepley   DM                dm;
2258*65876a83SMatthew G. Knepley   Vec               exact;
2259*65876a83SMatthew G. Knepley   PetscViewer       viewer;
2260*65876a83SMatthew G. Knepley   PetscViewerFormat format;
2261*65876a83SMatthew G. Knepley   PetscOptions      options;
2262*65876a83SMatthew G. Knepley   const char       *prefix;
2263*65876a83SMatthew G. Knepley   PetscErrorCode    ierr;
2264*65876a83SMatthew G. Knepley 
2265*65876a83SMatthew G. Knepley   PetscFunctionBegin;
2266*65876a83SMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
2267*65876a83SMatthew G. Knepley   ierr = PetscObjectGetOptions((PetscObject) ts, &options);CHKERRQ(ierr);
2268*65876a83SMatthew G. Knepley   ierr = PetscObjectGetOptionsPrefix((PetscObject) ts, &prefix);CHKERRQ(ierr);
2269*65876a83SMatthew G. Knepley   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) ts), options, prefix, "-monitor_solution", &viewer, &format, NULL);CHKERRQ(ierr);
2270*65876a83SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &exact);CHKERRQ(ierr);
2271*65876a83SMatthew G. Knepley   ierr = DMComputeExactSolution(dm, time, exact, NULL);CHKERRQ(ierr);
2272*65876a83SMatthew G. Knepley   ierr = DMSetOutputSequenceNumber(dm, steps, time);CHKERRQ(ierr);
2273*65876a83SMatthew G. Knepley   ierr = VecView(exact, viewer);CHKERRQ(ierr);
2274*65876a83SMatthew G. Knepley   ierr = VecView(u, viewer);CHKERRQ(ierr);
2275*65876a83SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &exact);CHKERRQ(ierr);
2276*65876a83SMatthew G. Knepley   {
2277*65876a83SMatthew G. Knepley     PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx);
2278*65876a83SMatthew G. Knepley     void            **ectxs;
2279*65876a83SMatthew G. Knepley     PetscReal        *err;
2280*65876a83SMatthew G. Knepley     PetscInt          Nf, f;
2281*65876a83SMatthew G. Knepley 
2282*65876a83SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
2283*65876a83SMatthew G. Knepley     ierr = PetscCalloc3(Nf, &exacts, Nf, &ectxs, PetscMax(1, Nf), &err);CHKERRQ(ierr);
2284*65876a83SMatthew G. Knepley     {
2285*65876a83SMatthew G. Knepley       PetscInt Nds, s;
2286*65876a83SMatthew G. Knepley 
2287*65876a83SMatthew G. Knepley       ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
2288*65876a83SMatthew G. Knepley       for (s = 0; s < Nds; ++s) {
2289*65876a83SMatthew G. Knepley         PetscDS         ds;
2290*65876a83SMatthew G. Knepley         DMLabel         label;
2291*65876a83SMatthew G. Knepley         IS              fieldIS;
2292*65876a83SMatthew G. Knepley         const PetscInt *fields;
2293*65876a83SMatthew G. Knepley         PetscInt        dsNf, f;
2294*65876a83SMatthew G. Knepley 
2295*65876a83SMatthew G. Knepley         ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr);
2296*65876a83SMatthew G. Knepley         ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr);
2297*65876a83SMatthew G. Knepley         ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr);
2298*65876a83SMatthew G. Knepley         for (f = 0; f < dsNf; ++f) {
2299*65876a83SMatthew G. Knepley           const PetscInt field = fields[f];
2300*65876a83SMatthew G. Knepley           ierr = PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr);
2301*65876a83SMatthew G. Knepley         }
2302*65876a83SMatthew G. Knepley         ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr);
2303*65876a83SMatthew G. Knepley       }
2304*65876a83SMatthew G. Knepley     }
2305*65876a83SMatthew G. Knepley     ierr = DMComputeL2FieldDiff(dm, time, exacts, ectxs, u, err);CHKERRQ(ierr);
2306*65876a83SMatthew G. Knepley     ierr = PetscPrintf(PetscObjectComm((PetscObject) ts), "Time: %g L_2 Error: [", time);CHKERRQ(ierr);
2307*65876a83SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
2308*65876a83SMatthew G. Knepley       if (f) {ierr = PetscPrintf(PetscObjectComm((PetscObject) ts), ", ");CHKERRQ(ierr);}
2309*65876a83SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject) ts), "%g", (double) err[f]);CHKERRQ(ierr);
2310*65876a83SMatthew G. Knepley     }
2311*65876a83SMatthew G. Knepley     ierr = PetscPrintf(PetscObjectComm((PetscObject) ts), "]\n");CHKERRQ(ierr);
2312*65876a83SMatthew G. Knepley     ierr = PetscFree3(exacts, ectxs, err);CHKERRQ(ierr);
2313*65876a83SMatthew G. Knepley   }
2314*65876a83SMatthew G. Knepley   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2315*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
2316*65876a83SMatthew G. Knepley }
2317*65876a83SMatthew G. Knepley 
2318*65876a83SMatthew G. Knepley static PetscErrorCode SetupMonitor(TS ts, AppCtx *ctx)
2319*65876a83SMatthew G. Knepley {
2320*65876a83SMatthew G. Knepley   PetscViewer       viewer;
2321*65876a83SMatthew G. Knepley   PetscViewerFormat format;
2322*65876a83SMatthew G. Knepley   PetscOptions      options;
2323*65876a83SMatthew G. Knepley   const char       *prefix;
2324*65876a83SMatthew G. Knepley   PetscBool         flg;
2325*65876a83SMatthew G. Knepley   PetscErrorCode    ierr;
2326*65876a83SMatthew G. Knepley 
2327*65876a83SMatthew G. Knepley   PetscFunctionBegin;
2328*65876a83SMatthew G. Knepley   ierr = PetscObjectGetOptions((PetscObject) ts, &options);CHKERRQ(ierr);
2329*65876a83SMatthew G. Knepley   ierr = PetscObjectGetOptionsPrefix((PetscObject) ts, &prefix);CHKERRQ(ierr);
2330*65876a83SMatthew G. Knepley   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) ts), options, prefix, "-monitor_solution", &viewer, &format, &flg);CHKERRQ(ierr);
2331*65876a83SMatthew G. Knepley   if (flg) {ierr = TSMonitorSet(ts, SolutionMonitor, ctx, NULL);CHKERRQ(ierr);}
2332*65876a83SMatthew G. Knepley   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2333*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
2334*65876a83SMatthew G. Knepley }
2335*65876a83SMatthew G. Knepley 
2336*65876a83SMatthew 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)
2337*65876a83SMatthew G. Knepley {
2338*65876a83SMatthew G. Knepley   static PetscReal dtTarget = -1.0;
2339*65876a83SMatthew G. Knepley   PetscReal        dtInitial;
2340*65876a83SMatthew G. Knepley   DM               dm;
2341*65876a83SMatthew G. Knepley   AppCtx          *ctx;
2342*65876a83SMatthew G. Knepley   PetscInt         step;
2343*65876a83SMatthew G. Knepley   PetscErrorCode   ierr;
2344*65876a83SMatthew G. Knepley 
2345*65876a83SMatthew G. Knepley   PetscFunctionBegin;
2346*65876a83SMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
2347*65876a83SMatthew G. Knepley   ierr = DMGetApplicationContext(dm, (void **) &ctx);CHKERRQ(ierr);
2348*65876a83SMatthew G. Knepley   ierr = TSGetStepNumber(ts, &step);CHKERRQ(ierr);
2349*65876a83SMatthew G. Knepley   dtInitial = 1.0e-4*ctx->t_r;
2350*65876a83SMatthew G. Knepley   if (!step) {
2351*65876a83SMatthew G. Knepley     if (PetscAbsReal(dtInitial - h) > PETSC_SMALL) {
2352*65876a83SMatthew G. Knepley       *accept  = PETSC_FALSE;
2353*65876a83SMatthew G. Knepley       *next_h  = dtInitial;
2354*65876a83SMatthew G. Knepley       dtTarget = h;
2355*65876a83SMatthew G. Knepley     } else {
2356*65876a83SMatthew G. Knepley       *accept  = PETSC_TRUE;
2357*65876a83SMatthew G. Knepley       *next_h  = dtTarget < 0.0 ? dtInitial : dtTarget;
2358*65876a83SMatthew G. Knepley       dtTarget = -1.0;
2359*65876a83SMatthew G. Knepley     }
2360*65876a83SMatthew G. Knepley   } else {
2361*65876a83SMatthew G. Knepley     *accept = PETSC_TRUE;
2362*65876a83SMatthew G. Knepley     *next_h = h;
2363*65876a83SMatthew G. Knepley   }
2364*65876a83SMatthew G. Knepley   *next_sc = 0;  /* Reuse the same order scheme */
2365*65876a83SMatthew G. Knepley   *wlte    = -1; /* Weighted local truncation error was not evaluated */
2366*65876a83SMatthew G. Knepley   *wltea   = -1; /* Weighted absolute local truncation error was not evaluated */
2367*65876a83SMatthew G. Knepley   *wlter   = -1; /* Weighted relative local truncation error was not evaluated */
2368*65876a83SMatthew G. Knepley   PetscFunctionReturn(0);
2369*65876a83SMatthew G. Knepley }
2370*65876a83SMatthew G. Knepley 
2371*65876a83SMatthew G. Knepley int main(int argc, char **argv)
2372*65876a83SMatthew G. Knepley {
2373*65876a83SMatthew G. Knepley   AppCtx         ctx;       /* User-defined work context */
2374*65876a83SMatthew G. Knepley   DM             dm;        /* Problem specification */
2375*65876a83SMatthew G. Knepley   TS             ts;        /* Time Series / Nonlinear solver */
2376*65876a83SMatthew G. Knepley   Vec            u;         /* Solutions */
2377*65876a83SMatthew G. Knepley   const char    *name[3] = {"displacement", "tracestrain", "pressure"};
2378*65876a83SMatthew G. Knepley   PetscReal      t;
2379*65876a83SMatthew G. Knepley   PetscInt       Nc[3];
2380*65876a83SMatthew G. Knepley   PetscErrorCode ierr;
2381*65876a83SMatthew G. Knepley 
2382*65876a83SMatthew G. Knepley   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
2383*65876a83SMatthew G. Knepley   ierr = ProcessOptions(PETSC_COMM_WORLD, &ctx);CHKERRQ(ierr);
2384*65876a83SMatthew G. Knepley   ierr = PetscBagCreate(PETSC_COMM_SELF, sizeof(Parameter), &ctx.bag);CHKERRQ(ierr);
2385*65876a83SMatthew G. Knepley   ierr = PetscMalloc1(ctx.niter, &ctx.zeroArray);CHKERRQ(ierr);
2386*65876a83SMatthew G. Knepley   ierr = SetupParameters(PETSC_COMM_WORLD, &ctx);CHKERRQ(ierr);
2387*65876a83SMatthew G. Knepley   /* Primal System */
2388*65876a83SMatthew G. Knepley   ierr = TSCreate(PETSC_COMM_WORLD, &ts);CHKERRQ(ierr);
2389*65876a83SMatthew G. Knepley   ierr = CreateMesh(PETSC_COMM_WORLD, &ctx, &dm);CHKERRQ(ierr);
2390*65876a83SMatthew G. Knepley   ierr = DMSetApplicationContext(dm, &ctx);CHKERRQ(ierr);
2391*65876a83SMatthew G. Knepley   ierr = TSSetDM(ts, dm);CHKERRQ(ierr);
2392*65876a83SMatthew G. Knepley 
2393*65876a83SMatthew G. Knepley   Nc[0] = ctx.dim;
2394*65876a83SMatthew G. Knepley   Nc[1] = 1;
2395*65876a83SMatthew G. Knepley   Nc[2] = 1;
2396*65876a83SMatthew G. Knepley 
2397*65876a83SMatthew G. Knepley   ierr = SetupFE(dm, ctx.simplex, 3, Nc, name, SetupPrimalProblem, &ctx);CHKERRQ(ierr);
2398*65876a83SMatthew G. Knepley   ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr);
2399*65876a83SMatthew G. Knepley   ierr = DMTSSetBoundaryLocal(dm, DMPlexTSComputeBoundary, &ctx);CHKERRQ(ierr);
2400*65876a83SMatthew G. Knepley   ierr = DMTSSetIFunctionLocal(dm, DMPlexTSComputeIFunctionFEM, &ctx);CHKERRQ(ierr);
2401*65876a83SMatthew G. Knepley   ierr = DMTSSetIJacobianLocal(dm, DMPlexTSComputeIJacobianFEM, &ctx);CHKERRQ(ierr);
2402*65876a83SMatthew G. Knepley   ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr);
2403*65876a83SMatthew G. Knepley   ierr = TSSetFromOptions(ts);CHKERRQ(ierr);
2404*65876a83SMatthew G. Knepley   ierr = TSSetComputeInitialCondition(ts, SetInitialConditions);CHKERRQ(ierr);
2405*65876a83SMatthew G. Knepley   ierr = SetupMonitor(ts, &ctx);CHKERRQ(ierr);
2406*65876a83SMatthew G. Knepley 
2407*65876a83SMatthew G. Knepley   if (ctx.solType != SOL_QUADRATIC_TRIG) {
2408*65876a83SMatthew G. Knepley     TSAdapt adapt;
2409*65876a83SMatthew G. Knepley 
2410*65876a83SMatthew G. Knepley     ierr = TSGetAdapt(ts, &adapt);CHKERRQ(ierr);
2411*65876a83SMatthew G. Knepley     adapt->ops->choose = TSAdaptChoose_Terzaghi;
2412*65876a83SMatthew G. Knepley   }
2413*65876a83SMatthew G. Knepley   if (ctx.solType == SOL_CRYER) {
2414*65876a83SMatthew G. Knepley     Mat          J;
2415*65876a83SMatthew G. Knepley     MatNullSpace sp;
2416*65876a83SMatthew G. Knepley 
2417*65876a83SMatthew G. Knepley     ierr = TSSetUp(ts);CHKERRQ(ierr);
2418*65876a83SMatthew G. Knepley     ierr = TSGetIJacobian(ts, &J, NULL, NULL, NULL);CHKERRQ(ierr);
2419*65876a83SMatthew G. Knepley     ierr = DMPlexCreateRigidBody(dm, 0, &sp); CHKERRQ(ierr);
2420*65876a83SMatthew G. Knepley     ierr = MatSetNullSpace(J, sp);CHKERRQ(ierr);
2421*65876a83SMatthew G. Knepley     ierr = MatNullSpaceDestroy(&sp);CHKERRQ(ierr);
2422*65876a83SMatthew G. Knepley   }
2423*65876a83SMatthew G. Knepley   ierr = TSGetTime(ts, &t);CHKERRQ(ierr);
2424*65876a83SMatthew G. Knepley   ierr = DMSetOutputSequenceNumber(dm, 0, t);CHKERRQ(ierr);
2425*65876a83SMatthew G. Knepley   ierr = DMTSCheckFromOptions(ts, u);CHKERRQ(ierr);
2426*65876a83SMatthew G. Knepley   ierr = SetInitialConditions(ts, u);CHKERRQ(ierr);
2427*65876a83SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) u, "solution");CHKERRQ(ierr);
2428*65876a83SMatthew G. Knepley   ierr = TSSolve(ts, u);CHKERRQ(ierr);
2429*65876a83SMatthew G. Knepley   ierr = DMTSCheckFromOptions(ts, u);CHKERRQ(ierr);
2430*65876a83SMatthew G. Knepley   ierr = TSGetSolution(ts, &u);CHKERRQ(ierr);
2431*65876a83SMatthew G. Knepley   ierr = VecViewFromOptions(u, NULL, "-sol_vec_view");CHKERRQ(ierr);
2432*65876a83SMatthew G. Knepley 
2433*65876a83SMatthew G. Knepley   /* Cleanup */
2434*65876a83SMatthew G. Knepley   ierr = VecDestroy(&u);CHKERRQ(ierr);
2435*65876a83SMatthew G. Knepley   ierr = TSDestroy(&ts);CHKERRQ(ierr);
2436*65876a83SMatthew G. Knepley   ierr = DMDestroy(&dm);CHKERRQ(ierr);
2437*65876a83SMatthew G. Knepley   ierr = PetscBagDestroy(&ctx.bag);CHKERRQ(ierr);
2438*65876a83SMatthew G. Knepley   ierr = PetscFree(ctx.zeroArray);CHKERRQ(ierr);
2439*65876a83SMatthew G. Knepley   ierr = PetscFinalize();
2440*65876a83SMatthew G. Knepley   return ierr;
2441*65876a83SMatthew G. Knepley }
2442*65876a83SMatthew G. Knepley 
2443*65876a83SMatthew G. Knepley /*TEST
2444*65876a83SMatthew G. Knepley 
2445*65876a83SMatthew G. Knepley   test:
2446*65876a83SMatthew G. Knepley     suffix: 2d_quad_linear
2447*65876a83SMatthew G. Knepley     requires: triangle
2448*65876a83SMatthew G. Knepley     args: -sol_type quadratic_linear -dm_refine 2 \
2449*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2450*65876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
2451*65876a83SMatthew G. Knepley 
2452*65876a83SMatthew G. Knepley   test:
2453*65876a83SMatthew G. Knepley     suffix: 3d_quad_linear
2454*65876a83SMatthew G. Knepley     requires: ctetgen
2455*65876a83SMatthew G. Knepley     args: -dim 3 -sol_type quadratic_linear -dm_refine 1 \
2456*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2457*65876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
2458*65876a83SMatthew G. Knepley 
2459*65876a83SMatthew G. Knepley   test:
2460*65876a83SMatthew G. Knepley     suffix: 2d_trig_linear
2461*65876a83SMatthew G. Knepley     requires: triangle
2462*65876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
2463*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2464*65876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_dt 0.00001 -ts_monitor_extreme
2465*65876a83SMatthew G. Knepley 
2466*65876a83SMatthew G. Knepley   test:
2467*65876a83SMatthew G. Knepley     # -dm_refine 2 -convest_num_refine 3 get L_2 convergence rate: [1.9, 2.1, 1.8]
2468*65876a83SMatthew G. Knepley     suffix: 2d_trig_linear_sconv
2469*65876a83SMatthew G. Knepley     requires: triangle
2470*65876a83SMatthew G. Knepley     args: -sol_type trig_linear -dm_refine 1 \
2471*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2472*65876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -ts_dt 0.00001 -pc_type lu
2473*65876a83SMatthew G. Knepley 
2474*65876a83SMatthew G. Knepley   test:
2475*65876a83SMatthew G. Knepley     suffix: 3d_trig_linear
2476*65876a83SMatthew G. Knepley     requires: ctetgen
2477*65876a83SMatthew G. Knepley     args: -dim 3 -sol_type trig_linear -dm_refine 1 \
2478*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2479*65876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 2 -ts_monitor_extreme
2480*65876a83SMatthew G. Knepley 
2481*65876a83SMatthew G. Knepley   test:
2482*65876a83SMatthew G. Knepley     # -dm_refine 1 -convest_num_refine 2 gets L_2 convergence rate: [2.0, 2.1, 1.9]
2483*65876a83SMatthew G. Knepley     suffix: 3d_trig_linear_sconv
2484*65876a83SMatthew G. Knepley     requires: ctetgen
2485*65876a83SMatthew G. Knepley     args: -dim 3 -sol_type trig_linear -dm_refine 1 \
2486*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2487*65876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_convergence_temporal 0 -ts_max_steps 1 -pc_type lu
2488*65876a83SMatthew G. Knepley 
2489*65876a83SMatthew G. Knepley   test:
2490*65876a83SMatthew G. Knepley     suffix: 2d_quad_trig
2491*65876a83SMatthew G. Knepley     requires: triangle
2492*65876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 2 \
2493*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2494*65876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
2495*65876a83SMatthew G. Knepley 
2496*65876a83SMatthew G. Knepley   test:
2497*65876a83SMatthew G. Knepley     # Using -dm_refine 4 gets the convergence rates to [0.95, 0.97, 0.90]
2498*65876a83SMatthew G. Knepley     suffix: 2d_quad_trig_tconv
2499*65876a83SMatthew G. Knepley     requires: triangle
2500*65876a83SMatthew G. Knepley     args: -sol_type quadratic_trig -dm_refine 1 \
2501*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2502*65876a83SMatthew G. Knepley       -convest_num_refine 3 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
2503*65876a83SMatthew G. Knepley 
2504*65876a83SMatthew G. Knepley   test:
2505*65876a83SMatthew G. Knepley     suffix: 3d_quad_trig
2506*65876a83SMatthew G. Knepley     requires: ctetgen
2507*65876a83SMatthew G. Knepley     args: -dim 3 -sol_type quadratic_trig -dm_refine 1 \
2508*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2509*65876a83SMatthew G. Knepley       -dmts_check .0001 -ts_max_steps 5 -ts_monitor_extreme
2510*65876a83SMatthew G. Knepley 
2511*65876a83SMatthew G. Knepley   test:
2512*65876a83SMatthew G. Knepley     # Using -dm_refine 2 -convest_num_refine 3 gets the convergence rates to [1.0, 1.0, 1.0]
2513*65876a83SMatthew G. Knepley     suffix: 3d_quad_trig_tconv
2514*65876a83SMatthew G. Knepley     requires: ctetgen
2515*65876a83SMatthew G. Knepley     args: -dim 3 -sol_type quadratic_trig -dm_refine 1 \
2516*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2517*65876a83SMatthew G. Knepley       -convest_num_refine 1 -ts_convergence_estimate -ts_max_steps 5 -pc_type lu
2518*65876a83SMatthew G. Knepley 
2519*65876a83SMatthew G. Knepley   test:
2520*65876a83SMatthew G. Knepley     suffix: 2d_terzaghi
2521*65876a83SMatthew G. Knepley     requires: triangle
2522*65876a83SMatthew G. Knepley     args: -sol_type terzaghi -dm_plex_separate_marker -dm_plex_box_faces 1,8 -simplex 0 \
2523*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 -niter 16000 \
2524*65876a83SMatthew G. Knepley       -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001 -pc_type lu
2525*65876a83SMatthew G. Knepley 
2526*65876a83SMatthew G. Knepley   test:
2527*65876a83SMatthew 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]
2528*65876a83SMatthew G. Knepley     suffix: 2d_terzaghi_tconv
2529*65876a83SMatthew G. Knepley     requires: triangle
2530*65876a83SMatthew G. Knepley     args: -sol_type terzaghi -dm_plex_separate_marker -dm_plex_box_faces 1,8 -simplex 0 \
2531*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 -niter 16000 \
2532*65876a83SMatthew G. Knepley       -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1 -pc_type lu
2533*65876a83SMatthew G. Knepley 
2534*65876a83SMatthew G. Knepley   test:
2535*65876a83SMatthew G. Knepley     suffix: 2d_mandel
2536*65876a83SMatthew G. Knepley     requires: triangle
2537*65876a83SMatthew G. Knepley     args: -sol_type mandel -dm_plex_separate_marker -dm_refine 1 \
2538*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2539*65876a83SMatthew G. Knepley       -ts_dt 0.0028666667 -ts_max_steps 2 -ts_monitor -dmts_check .0001 -pc_type lu
2540*65876a83SMatthew G. Knepley 
2541*65876a83SMatthew G. Knepley   test:
2542*65876a83SMatthew G. Knepley     # -dm_refine 5 -ts_max_steps 4 -convest_num_refine 3 gives L_2 convergence rate: [0.26, -0.0058, 0.26]
2543*65876a83SMatthew G. Knepley     suffix: 2d_mandel_tconv
2544*65876a83SMatthew G. Knepley     requires: triangle
2545*65876a83SMatthew G. Knepley     args: -sol_type mandel -dm_plex_separate_marker -dm_refine 1 \
2546*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2547*65876a83SMatthew G. Knepley       -ts_dt 0.023 -ts_max_steps 2 -ts_convergence_estimate -convest_num_refine 1 -pc_type lu
2548*65876a83SMatthew G. Knepley 
2549*65876a83SMatthew G. Knepley   test:
2550*65876a83SMatthew G. Knepley     suffix: 3d_cryer
2551*65876a83SMatthew G. Knepley     requires: ctetgen !complex
2552*65876a83SMatthew G. Knepley     args: -sol_type cryer \
2553*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2554*65876a83SMatthew G. Knepley       -ts_dt 0.0028666667 -ts_max_time 0.014333 -ts_max_steps 2 -dmts_check .0001 -pc_type lu -pc_factor_shift_type nonzero
2555*65876a83SMatthew G. Knepley 
2556*65876a83SMatthew G. Knepley   test:
2557*65876a83SMatthew G. Knepley     # Displacement and Pressure converge. The analytic expression for trace strain is inaccurate at the origin
2558*65876a83SMatthew 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]
2559*65876a83SMatthew G. Knepley     suffix: 3d_cryer_tconv
2560*65876a83SMatthew G. Knepley     requires: ctetgen !complex
2561*65876a83SMatthew G. Knepley     args: -sol_type cryer -bd_dm_refine 1 -ref_limit 0.00666667 \
2562*65876a83SMatthew G. Knepley       -displacement_petscspace_degree 2 -tracestrain_petscspace_degree 1 -pressure_petscspace_degree 1 \
2563*65876a83SMatthew 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
2564*65876a83SMatthew G. Knepley 
2565*65876a83SMatthew G. Knepley TEST*/
2566