1 static char help[] = "Biot consolidation model discretized with finite elements,\n\
2 using a parallel unstructured mesh (DMPLEX) to represent the domain.\n\
3 We follow https://arxiv.org/pdf/1507.03199.\n\n\n";
4
5 #include <petscdmplex.h>
6 #include <petscsnes.h>
7 #include <petscds.h>
8
9 typedef struct {
10 PetscScalar mu;
11 PetscScalar lam;
12 PetscScalar alpha;
13 PetscScalar kappa;
14 } Parameter;
15
u_1(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f[])16 static void u_1(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[])
17 {
18 const PetscReal mu = PetscRealPart(constants[0]);
19
20 for (PetscInt c = 0; c < dim; ++c) {
21 for (PetscInt d = 0; d < dim; ++d) f[c * dim + d] = mu * (u_x[c * dim + d] + u_x[d * dim + c]);
22 f[c * dim + c] -= u[uOff[1]];
23 }
24 }
25
26 /* Jfunction_testtrial */
Ju_1_u1p0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])27 static void Ju_1_u1p0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
28 {
29 for (PetscInt d = 0; d < dim; ++d) J[d * dim + d] = -1.0;
30 }
31
Ju_1_u1u1(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])32 static void Ju_1_u1u1(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
33 {
34 const PetscReal mu = PetscRealPart(constants[0]);
35 const PetscInt Nc = uOff[1] - uOff[0];
36
37 for (PetscInt c = 0; c < Nc; ++c) {
38 for (PetscInt d = 0; d < dim; ++d) {
39 J[((c * Nc + c) * dim + d) * dim + d] += mu;
40 J[((c * Nc + d) * dim + d) * dim + c] += mu;
41 }
42 }
43 }
44
p_0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f[])45 static void p_0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[])
46 {
47 const PetscReal lam = PetscRealPart(constants[1]);
48 const PetscReal alpha = PetscRealPart(constants[2]);
49
50 f[0] = (-u[uOff[1]] + alpha * u[uOff[2]]) / lam;
51 for (PetscInt d = 0; d < dim; ++d) f[0] -= u_x[d * dim + d];
52 }
53
Jp_0_p0u1(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])54 static void Jp_0_p0u1(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
55 {
56 for (PetscInt d = 0; d < dim; ++d) J[d * dim + d] = -1.0;
57 }
58
Jp_0_p0p0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])59 static void Jp_0_p0p0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
60 {
61 const PetscReal lam = PetscRealPart(constants[1]);
62
63 J[0] = -1.0 / lam;
64 }
65
pJp_0_p0p0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])66 static void pJp_0_p0p0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
67 {
68 const PetscReal mu = PetscRealPart(constants[0]);
69
70 J[0] = 1.0 / mu;
71 }
72
Jp_0_p0w0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])73 static void Jp_0_p0w0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
74 {
75 const PetscReal lam = PetscRealPart(constants[1]);
76 const PetscReal alpha = PetscRealPart(constants[2]);
77
78 J[0] = alpha / lam;
79 }
80
w_0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f[])81 static void w_0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[])
82 {
83 const PetscReal lam = PetscRealPart(constants[1]);
84 const PetscReal alpha = PetscRealPart(constants[2]);
85
86 f[0] = alpha / lam * (-2 * alpha * u[uOff[2]] + u[uOff[1]]);
87 }
88
Jw_0_w0p0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])89 static void Jw_0_w0p0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
90 {
91 const PetscReal lam = PetscRealPart(constants[1]);
92 const PetscReal alpha = PetscRealPart(constants[2]);
93
94 J[0] = alpha / lam;
95 }
96
Jw_0_w0w0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])97 static void Jw_0_w0w0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
98 {
99 const PetscReal lam = PetscRealPart(constants[1]);
100 const PetscReal alpha = PetscRealPart(constants[2]);
101
102 J[0] = -2 * PetscSqr(alpha) / lam;
103 }
104
pJw_0_w0w0(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])105 static void pJw_0_w0w0(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
106 {
107 const PetscReal lam = PetscRealPart(constants[1]);
108 const PetscReal alpha = PetscRealPart(constants[2]);
109
110 J[0] = 2 * PetscSqr(alpha) / lam;
111 }
112
w_1(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f[])113 static void w_1(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[])
114 {
115 const PetscReal kappa = PetscRealPart(constants[3]);
116 for (PetscInt d = 0; d < dim; ++d) f[d] = -kappa * u_x[uOff_x[2] + d];
117 }
118
Jw_1_w1w1(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])119 static void Jw_1_w1w1(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
120 {
121 const PetscReal kappa = PetscRealPart(constants[3]);
122
123 for (PetscInt d = 0; d < dim; ++d) J[d * dim + d] = -kappa;
124 }
125
pJw_1_w1w1(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar J[])126 static void pJw_1_w1w1(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar J[])
127 {
128 const PetscReal kappa = PetscRealPart(constants[3]);
129
130 for (PetscInt d = 0; d < dim; ++d) J[d * dim + d] = kappa;
131 }
132
133 typedef struct {
134 PetscScalar E;
135 PetscScalar nu;
136 PetscScalar alpha;
137 PetscScalar kappa;
138 } AppCtx;
139
ProcessOptions(MPI_Comm comm,AppCtx * user)140 static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *user)
141 {
142 PetscFunctionBeginUser;
143 user->E = 1.0;
144 user->nu = 0.3;
145 user->alpha = 0.5;
146 user->kappa = 1.0;
147 PetscOptionsBegin(comm, "", "Biot Problem Options", "DMPLEX");
148 PetscCall(PetscOptionsScalar("-E", "Young modulus", NULL, user->E, &user->E, NULL));
149 PetscCall(PetscOptionsScalar("-nu", "Poisson ratio", NULL, user->nu, &user->nu, NULL));
150 PetscCall(PetscOptionsScalar("-alpha", "Alpha", NULL, user->alpha, &user->alpha, NULL));
151 PetscCall(PetscOptionsScalar("-kappa", "kappa", NULL, user->kappa, &user->kappa, NULL));
152 PetscOptionsEnd();
153 PetscFunctionReturn(PETSC_SUCCESS);
154 }
155
CreateMesh(MPI_Comm comm,AppCtx * user,DM * dm)156 static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
157 {
158 PetscFunctionBeginUser;
159 PetscCall(DMCreate(comm, dm));
160 PetscCall(DMSetType(*dm, DMPLEX));
161 PetscCall(DMSetFromOptions(*dm));
162 PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
163 PetscFunctionReturn(PETSC_SUCCESS);
164 }
165
SetupEqn(DM dm,AppCtx * user)166 static PetscErrorCode SetupEqn(DM dm, AppCtx *user)
167 {
168 PetscDS ds;
169 DMLabel label;
170 const PetscInt id = 1;
171 PetscScalar constants[4];
172
173 PetscFunctionBeginUser;
174 PetscCall(DMGetDS(dm, &ds));
175 PetscCall(PetscDSSetResidual(ds, 0, NULL, u_1));
176 PetscCall(PetscDSSetResidual(ds, 1, p_0, NULL));
177 PetscCall(PetscDSSetResidual(ds, 2, w_0, w_1));
178 PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, Ju_1_u1u1));
179 PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, Ju_1_u1p0, NULL));
180 PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, Jp_0_p0u1, NULL, NULL));
181 PetscCall(PetscDSSetJacobian(ds, 1, 1, Jp_0_p0p0, NULL, NULL, NULL));
182 PetscCall(PetscDSSetJacobian(ds, 1, 2, Jp_0_p0w0, NULL, NULL, NULL));
183 PetscCall(PetscDSSetJacobian(ds, 2, 1, Jw_0_w0p0, NULL, NULL, NULL));
184 PetscCall(PetscDSSetJacobian(ds, 2, 2, Jw_0_w0w0, NULL, NULL, Jw_1_w1w1));
185 PetscCall(PetscDSSetJacobianPreconditioner(ds, 0, 0, NULL, NULL, NULL, Ju_1_u1u1));
186 PetscCall(PetscDSSetJacobianPreconditioner(ds, 0, 1, NULL, NULL, Ju_1_u1p0, NULL));
187 PetscCall(PetscDSSetJacobianPreconditioner(ds, 1, 0, NULL, Jp_0_p0u1, NULL, NULL));
188 PetscCall(PetscDSSetJacobianPreconditioner(ds, 1, 1, pJp_0_p0p0, NULL, NULL, NULL));
189 PetscCall(PetscDSSetJacobianPreconditioner(ds, 2, 2, pJw_0_w0w0, NULL, NULL, pJw_1_w1w1));
190
191 PetscCall(DMGetLabel(dm, "marker", &label));
192 PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall-d", label, 1, &id, 0, 0, NULL, NULL, NULL, NULL, NULL));
193 PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall-p", label, 1, &id, 2, 0, NULL, NULL, NULL, NULL, NULL));
194
195 constants[0] = user->E / (2.0 * (1.0 + user->nu));
196 constants[1] = user->nu * user->E / ((1.0 + user->nu) * (1.0 - 2.0 * user->nu));
197 constants[2] = user->alpha;
198 constants[3] = user->kappa;
199 PetscCall(PetscDSSetConstants(ds, 4, constants));
200
201 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "E = %g, nu = %g\n", (double)PetscRealPart(user->E), (double)PetscRealPart(user->nu)));
202 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "mu = %g, lambda = %g\n", (double)PetscRealPart(constants[0]), (double)PetscRealPart(constants[1])));
203 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "alpha = %g, kappa = %g\n", (double)PetscRealPart(constants[2]), (double)PetscRealPart(constants[3])));
204 PetscFunctionReturn(PETSC_SUCCESS);
205 }
206
SetupProblem(DM dm,PetscErrorCode (* setupEqn)(DM,AppCtx *),AppCtx * user)207 static PetscErrorCode SetupProblem(DM dm, PetscErrorCode (*setupEqn)(DM, AppCtx *), AppCtx *user)
208 {
209 DM cdm = dm;
210 PetscQuadrature q = NULL;
211 PetscBool simplex;
212 PetscInt dim, Nf = 3, f, Nc[3];
213 const char *name[3] = {"displacement", "totalpressure", "pressure"};
214 const char *prefix[3] = {"displacement_", "totalpressure_", "pressure_"};
215
216 PetscFunctionBegin;
217 PetscCall(DMGetDimension(dm, &dim));
218 PetscCall(DMPlexIsSimplex(dm, &simplex));
219 Nc[0] = dim;
220 Nc[1] = 1;
221 Nc[2] = 1;
222 for (f = 0; f < Nf; ++f) {
223 PetscFE fe;
224
225 PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, Nc[f], simplex, prefix[f], -1, &fe));
226 PetscCall(PetscObjectSetName((PetscObject)fe, name[f]));
227 if (!q) PetscCall(PetscFEGetQuadrature(fe, &q));
228 PetscCall(PetscFESetQuadrature(fe, q));
229 PetscCall(DMSetField(dm, f, NULL, (PetscObject)fe));
230 PetscCall(PetscFEDestroy(&fe));
231 }
232 PetscCall(DMCreateDS(dm));
233 PetscCall((*setupEqn)(dm, user));
234 while (cdm) {
235 PetscCall(DMCopyDisc(dm, cdm));
236 PetscCall(DMGetCoarseDM(cdm, &cdm));
237 }
238 PetscFunctionReturn(PETSC_SUCCESS);
239 }
240
main(int argc,char ** argv)241 int main(int argc, char **argv)
242 {
243 SNES snes;
244 DM dm;
245 Vec u;
246 AppCtx user;
247
248 PetscFunctionBeginUser;
249 PetscCall(PetscInitialize(&argc, &argv, NULL, help));
250 PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user));
251 PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm));
252 PetscCall(SetupProblem(dm, SetupEqn, &user));
253 PetscCall(DMPlexCreateClosureIndex(dm, NULL));
254 PetscCall(DMPlexSetSNESLocalFEM(dm, PETSC_FALSE, &user));
255 PetscCall(DMSetApplicationContext(dm, &user));
256
257 PetscCall(SNESCreate(PetscObjectComm((PetscObject)dm), &snes));
258 PetscCall(SNESSetDM(snes, dm));
259 PetscCall(SNESSetType(snes, SNESKSPONLY));
260 PetscCall(SNESSetFromOptions(snes));
261
262 /* Solve with random rhs */
263 PetscCall(DMCreateGlobalVector(dm, &u));
264 PetscCall(VecSetRandom(u, NULL));
265 PetscCall(SNESSolve(snes, NULL, u));
266
267 PetscCall(VecDestroy(&u));
268 PetscCall(SNESDestroy(&snes));
269 PetscCall(DMDestroy(&dm));
270 PetscCall(PetscFinalize());
271 return 0;
272 }
273
274 /*TEST
275
276 test:
277 suffix: 2d_p2_p1_p2
278 args: -displacement_petscspace_degree 2 -totalpressure_petscspace_degree 1 -pressure_petscspace_degree 2 \
279 -dm_plex_box_faces 5,5 -dm_plex_separate_marker -dm_plex_simplex 0 \
280 -snes_error_if_not_converged -ksp_error_if_not_converged \
281 -ksp_type minres -pc_type fieldsplit -pc_fieldsplit_type additive -fieldsplit_totalpressure_pc_type jacobi -fieldsplit_displacement_pc_type gamg -fieldsplit_pressure_pc_type gamg
282
283 test:
284 nsize: 4
285 suffix: 2d_p2_p1_p2_fetidp
286 args: -displacement_petscspace_degree 2 -totalpressure_petscspace_degree 1 -pressure_petscspace_degree 2 \
287 -petscpartitioner_type simple -dm_mat_type is -dm_plex_box_faces 3,3 -dm_refine 2 -dm_plex_separate_marker -dm_plex_simplex 0 \
288 -snes_error_if_not_converged -ksp_error_if_not_converged \
289 -ksp_type fetidp -ksp_fetidp_saddlepoint -ksp_fetidp_pressure_field 1,2 -ksp_fetidp_pressure_schur -fetidp_ksp_type cg -fetidp_ksp_norm_type natural \
290 -fetidp_fieldsplit_lag_ksp_type preonly \
291 -fetidp_bddc_pc_bddc_detect_disconnected -fetidp_bddc_pc_bddc_corner_selection -fetidp_bddc_pc_bddc_symmetric -fetidp_bddc_pc_bddc_coarse_redundant_pc_type cholesky \
292 -fetidp_pc_discrete_harmonic 1 -fetidp_harmonic_pc_type cholesky \
293 -fetidp_fieldsplit_p_pc_type bddc -fetidp_fieldsplit_p_ksp_type preonly
294
295 TEST*/
296