11 #include "libmesh/utility.h"
20 params.addRequiredRangeCheckedParam<Real>(
23 "SUPG pressure. This parameter controls the strength of the "
24 "upwinding. This parameter must be positive. If you need to track "
25 "advancing fronts in a problem, then set to less than your expected "
26 "range of pressures in your unsaturated zone. Otherwise, set "
27 "larger, and then minimal upwinding will occur and convergence will "
28 "typically be good. If you need no SUPG, it is more efficient not "
29 "to use this UserObject.");
30 params.addClassDescription(
31 "Standard SUPG relationships for Richards flow based on Appendix A of TJR Hughes, M "
32 "Mallet and A Mizukami ``A new finite element formulation for computational fluid dynamics:: "
33 "II. Behond SUPG'' Computer Methods in Applied Mechanics and Engineering 54 (1986) 341--355");
38 :
RichardsSUPG(parameters), _p_SUPG(getParam<Real>(
"p_SUPG"))
44 RealVectorValue gradp,
46 RealVectorValue gravity)
const
48 return -perm * (gradp -
density * gravity);
60 RealVectorValue gravity)
const
62 return perm * density_prime * gravity;
68 if (alpha >= 5.0 || alpha <= -5.0)
69 return ((alpha > 0.0) ? 1.0 : -1.0) - 1.0 / alpha;
72 return 1.0 / std::tanh(alpha) - 1.0 / alpha;
78 if (alpha >= 5.0 || alpha <= -5.0)
79 return 1.0 / (alpha * alpha);
82 return 1.0 - Utility::pow<2>(std::cosh(alpha) / std::sinh(alpha)) + 1.0 / (alpha * alpha);
89 RealVectorValue xi_prime,
90 RealVectorValue eta_prime,
91 RealVectorValue zeta_prime)
const
94 b(0) = xi_prime * vel;
96 b(1) = eta_prime * vel;
98 b(2) = zeta_prime * vel;
105 RealTensorValue dvel_dgradp,
106 RealVectorValue xi_prime,
107 RealVectorValue eta_prime,
108 RealVectorValue zeta_prime)
const
111 return 2.0 * ((xi_prime * vel) * (dvel_dgradp.transpose() * xi_prime) +
112 (eta_prime * vel) * (dvel_dgradp.transpose() * eta_prime) +
113 (zeta_prime * vel) * (dvel_dgradp.transpose() * zeta_prime));
119 RealVectorValue dvel_dp,
120 RealVectorValue xi_prime,
121 RealVectorValue eta_prime,
122 RealVectorValue zeta_prime)
const
125 ((xi_prime * vel) * (dvel_dp * xi_prime) + (eta_prime * vel) * (dvel_dp * eta_prime) +
126 (zeta_prime * vel) * (dvel_dp * zeta_prime));
133 Real norm_v = vel.norm();
134 Real norm_b = b.norm();
141 Real h = 2.0 * norm_v / norm_b;
142 Real alpha = 0.5 * norm_v * h / (traceperm *
_p_SUPG);
146 return xi_tilde / norm_b;
151 RealTensorValue dvel_dgradp,
154 RealVectorValue db2_dgradp)
const
156 Real norm_vel = vel.norm();
158 return RealVectorValue();
160 RealVectorValue norm_vel_dgradp(dvel_dgradp * vel / norm_vel);
162 Real norm_b = b.norm();
164 return RealVectorValue();
165 RealVectorValue norm_b_dgradp = db2_dgradp / 2.0 / norm_b;
167 Real h = 2 * norm_vel / norm_b;
168 RealVectorValue h_dgradp(2 * norm_vel_dgradp / norm_b -
169 2.0 * norm_vel * norm_b_dgradp / norm_b / norm_b);
171 Real alpha = 0.5 * norm_vel * h / traceperm /
_p_SUPG;
172 RealVectorValue alpha_dgradp =
173 0.5 * (norm_vel_dgradp * h + norm_vel * h_dgradp) / traceperm /
_p_SUPG;
177 RealVectorValue xi_tilde_dgradp = xi_tilde_prime * alpha_dgradp;
179 RealVectorValue tau_dgradp =
180 xi_tilde_dgradp / norm_b - xi_tilde * norm_b_dgradp / (norm_b * norm_b);
187 RealVectorValue dvel_dp,
192 Real norm_vel = vel.norm();
196 Real norm_vel_dp = dvel_dp * vel / norm_vel;
198 Real norm_b = b.norm();
201 Real norm_b_dp = db2_dp / (2.0 * norm_b);
203 Real h = 2.0 * norm_vel / norm_b;
204 Real h_dp = 2.0 * norm_vel_dp / norm_b - 2.0 * norm_vel * norm_b_dp / (norm_b * norm_b);
206 Real alpha = 0.5 * norm_vel * h / (traceperm *
_p_SUPG);
207 Real alpha_dp = 0.5 * (norm_vel_dp * h + norm_vel * h_dp) / (traceperm *
_p_SUPG);
211 Real xi_tilde_dp = xi_tilde_prime * alpha_dp;
214 const Real tau_dp = xi_tilde_dp / norm_b - xi_tilde * norm_b_dp / (norm_b * norm_b);