27 #include "grins_config.h"
35 #include "libmesh/quadrature.h"
43 _stab_helper( physics_name+
"StabHelper", input )
55 context.get_element_fe(this->_press_var.p())->get_dphi();
57 context.get_element_fe(this->_flow_vars.u())->get_xyz();
58 context.get_element_fe(this->_flow_vars.u())->get_phi();
59 context.get_element_fe(this->_flow_vars.u())->get_dphi();
60 context.get_element_fe(this->_flow_vars.u())->get_d2phi();
67 (
bool compute_jacobian,
70 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
73 const std::vector<libMesh::Real> &JxW = fe->get_JxW();
76 const std::vector<std::vector<libMesh::Real> >& u_phi = fe->get_phi();
78 const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
79 context.get_element_fe(this->_flow_vars.u())->get_dphi();
81 const std::vector<std::vector<libMesh::RealTensor> >& u_hessphi =
82 context.get_element_fe(this->_flow_vars.u())->get_d2phi();
84 const std::vector<libMesh::Point>& u_qpoint = fe->get_xyz();
87 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
90 libMesh::DenseSubMatrix<libMesh::Number> &Kuu = context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.u());
91 libMesh::DenseSubMatrix<libMesh::Number> &Kuv = context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.v());
92 libMesh::DenseSubMatrix<libMesh::Number> &Kvu = context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.u());
93 libMesh::DenseSubMatrix<libMesh::Number> &Kvv = context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.v());
95 libMesh::DenseSubMatrix<libMesh::Number>* Kwu = NULL;
96 libMesh::DenseSubMatrix<libMesh::Number>* Kwv = NULL;
97 libMesh::DenseSubMatrix<libMesh::Number>* Kww = NULL;
98 libMesh::DenseSubMatrix<libMesh::Number>* Kuw = NULL;
99 libMesh::DenseSubMatrix<libMesh::Number>* Kvw = NULL;
101 libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u());
102 libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v());
103 libMesh::DenseSubVector<libMesh::Number>* Fw = NULL;
105 if( this->_flow_vars.dim() == 3 )
107 Kuw = &context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.w());
108 Kvw = &context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.w());
110 Kwu = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.u());
111 Kwv = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.v());
112 Kww = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.w());
113 Fw = &context.get_elem_residual(this->_flow_vars.w());
116 unsigned int n_qpoints = context.get_element_qrule().n_points();
118 for (
unsigned int qp=0; qp != n_qpoints; qp++)
120 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
121 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
123 libMesh::RealGradient U( context.interior_value( this->_flow_vars.u(), qp ),
124 context.interior_value( this->_flow_vars.v(), qp ) );
125 if( this->_flow_vars.dim() == 3 )
127 U(2) = context.interior_value( this->_flow_vars.w(), qp );
131 libMesh::Real mu_qp = this->_mu(context, qp);
134 libMesh::Real d_tau_M_d_rho;
135 libMesh::Gradient d_tau_M_dU;
137 if (compute_jacobian)
138 this->_stab_helper.compute_tau_momentum_and_derivs
139 ( context, qp, g, G, this->_rho, U, mu_qp,
140 tau_M, d_tau_M_d_rho, d_tau_M_dU,
143 tau_M = this->_stab_helper.compute_tau_momentum
144 ( context, qp, g, G, this->_rho, U, mu_qp,
147 libMesh::NumberVectorValue F;
148 libMesh::NumberTensorValue dFdU;
149 libMesh::NumberTensorValue* dFdU_ptr =
150 compute_jacobian ? &dFdU : NULL;
151 if (!this->compute_force(u_qpoint[qp], context.time, U, F, dFdU_ptr))
154 for (
unsigned int i=0; i != n_u_dofs; i++)
156 libMesh::Real test_func = this->_rho*U*u_gradphi[i][qp] +
157 mu_qp*( u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,1) + u_hessphi[i][qp](2,2) );
158 Fu(i) += tau_M*F(0)*test_func*JxW[qp];
160 Fv(i) += tau_M*F(1)*test_func*JxW[qp];
162 if (this->_flow_vars.dim() == 3)
164 (*Fw)(i) += tau_M*F(2)*test_func*JxW[qp];
167 if (compute_jacobian)
169 const libMesh::Real sol_deriv =
170 context.get_elem_solution_derivative();
172 const libMesh::Real JxWxS = JxW[qp] * sol_deriv;
174 const libMesh::Real fixed_deriv =
175 context.get_fixed_solution_derivative();
177 const libMesh::Real JxWxF = JxW[qp] * fixed_deriv;
179 libMesh::Gradient d_test_func_dU = this->_rho*u_gradphi[i][qp];
181 for (
unsigned int j=0; j != n_u_dofs; ++j)
183 Kuu(i,j) += tau_M*F(0)*d_test_func_dU(0)*u_phi[j][qp]*JxWxS;
184 Kuu(i,j) += d_tau_M_dU(0)*u_phi[j][qp]*F(0)*test_func*JxWxF;
185 Kuu(i,j) += tau_M*dFdU(0,0)*u_phi[j][qp]*test_func*JxWxS;
186 Kuv(i,j) += tau_M*F(0)*d_test_func_dU(1)*u_phi[j][qp]*JxWxS;
187 Kuv(i,j) += d_tau_M_dU(1)*u_phi[j][qp]*F(0)*test_func*JxWxF;
188 Kuv(i,j) += tau_M*dFdU(0,1)*u_phi[j][qp]*test_func*JxWxS;
189 Kvu(i,j) += tau_M*F(1)*d_test_func_dU(0)*u_phi[j][qp]*JxWxS;
190 Kvu(i,j) += d_tau_M_dU(0)*u_phi[j][qp]*F(1)*test_func*JxWxF;
191 Kvu(i,j) += tau_M*dFdU(1,0)*u_phi[j][qp]*test_func*JxWxS;
192 Kvv(i,j) += tau_M*F(1)*d_test_func_dU(1)*u_phi[j][qp]*JxWxS;
193 Kvv(i,j) += d_tau_M_dU(1)*u_phi[j][qp]*F(1)*test_func*JxWxF;
194 Kvv(i,j) += tau_M*dFdU(1,1)*u_phi[j][qp]*test_func*JxWxS;
197 if (this->_flow_vars.dim() == 3)
199 for (
unsigned int j=0; j != n_u_dofs; ++j)
201 (*Kuw)(i,j) += tau_M*F(0)*d_test_func_dU(2)*u_phi[j][qp]*JxWxS;
202 (*Kuw)(i,j) += d_tau_M_dU(2)*u_phi[j][qp]*F(0)*test_func*JxWxF;
203 (*Kuw)(i,j) += tau_M*dFdU(0,2)*u_phi[j][qp]*test_func*JxWxS;
204 (*Kvw)(i,j) += tau_M*F(1)*d_test_func_dU(2)*u_phi[j][qp]*JxWxS;
205 (*Kvw)(i,j) += d_tau_M_dU(2)*u_phi[j][qp]*F(1)*test_func*JxWxF;
206 (*Kvw)(i,j) += tau_M*dFdU(1,2)*u_phi[j][qp]*test_func*JxWxS;
207 (*Kwu)(i,j) += tau_M*F(2)*d_test_func_dU(0)*u_phi[j][qp]*JxWxS;
208 (*Kwu)(i,j) += d_tau_M_dU(0)*u_phi[j][qp]*F(2)*test_func*JxWxF;
209 (*Kwu)(i,j) += tau_M*dFdU(2,0)*u_phi[j][qp]*test_func*JxWxS;
210 (*Kwv)(i,j) += tau_M*F(2)*d_test_func_dU(1)*u_phi[j][qp]*JxWxS;
211 (*Kwv)(i,j) += d_tau_M_dU(1)*u_phi[j][qp]*F(2)*test_func*JxWxF;
212 (*Kwv)(i,j) += tau_M*dFdU(2,1)*u_phi[j][qp]*test_func*JxWxS;
213 (*Kww)(i,j) += tau_M*F(2)*d_test_func_dU(2)*u_phi[j][qp]*JxWxS;
214 (*Kww)(i,j) += d_tau_M_dU(2)*u_phi[j][qp]*F(2)*test_func*JxWxF;
215 (*Kww)(i,j) += tau_M*dFdU(2,2)*u_phi[j][qp]*test_func*JxWxS;
230 const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
231 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
234 const std::vector<libMesh::Real> &JxW =
235 context.get_element_fe(this->_flow_vars.u())->get_JxW();
237 const std::vector<libMesh::Point>& u_qpoint =
238 context.get_element_fe(this->_flow_vars.u())->get_xyz();
240 const std::vector<std::vector<libMesh::Real> >& u_phi =
241 context.get_element_fe(this->_flow_vars.u())->get_phi();
243 const std::vector<std::vector<libMesh::RealGradient> >& p_dphi =
244 context.get_element_fe(this->_press_var.p())->get_dphi();
246 libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p());
248 libMesh::DenseSubMatrix<libMesh::Number> &Kpu =
249 context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.u());
250 libMesh::DenseSubMatrix<libMesh::Number> &Kpv =
251 context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.v());
252 libMesh::DenseSubMatrix<libMesh::Number> *Kpw = NULL;
254 if(this->_flow_vars.dim() == 3)
256 Kpw = &context.get_elem_jacobian
257 (this->_press_var.p(), this->_flow_vars.w());
266 unsigned int n_qpoints = context.get_element_qrule().n_points();
268 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
270 for (
unsigned int qp=0; qp != n_qpoints; qp++)
272 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
273 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
275 libMesh::RealGradient U( context.interior_value( this->_flow_vars.u(), qp ),
276 context.interior_value( this->_flow_vars.v(), qp ) );
277 if( this->_flow_vars.dim() == 3 )
279 U(2) = context.interior_value( this->_flow_vars.w(), qp );
283 libMesh::Real mu_qp = this->_mu(context, qp);
286 libMesh::Real d_tau_M_d_rho;
287 libMesh::Gradient d_tau_M_dU;
289 if (compute_jacobian)
290 this->_stab_helper.compute_tau_momentum_and_derivs
291 ( context, qp, g, G, this->_rho, U, mu_qp,
292 tau_M, d_tau_M_d_rho, d_tau_M_dU,
295 tau_M = this->_stab_helper.compute_tau_momentum
296 ( context, qp, g, G, this->_rho, U, mu_qp,
299 libMesh::NumberVectorValue F;
300 libMesh::NumberTensorValue dFdU;
301 libMesh::NumberTensorValue* dFdU_ptr =
302 compute_jacobian ? &dFdU : NULL;
303 if (!this->compute_force(u_qpoint[qp], context.time, U, F, dFdU_ptr))
309 for (
unsigned int i=0; i != n_p_dofs; i++)
311 Fp(i) += -tau_M*F*p_dphi[i][qp]*JxW[qp];
313 if (compute_jacobian)
315 const libMesh::Real sol_deriv =
316 context.get_elem_solution_derivative();
318 const libMesh::Real JxWxS = JxW[qp] * sol_deriv;
320 const libMesh::Real fixed_deriv =
321 context.get_fixed_solution_derivative();
323 const libMesh::Real JxWxF = JxW[qp] * fixed_deriv;
325 for (
unsigned int j=0; j != n_u_dofs; ++j)
326 if( this->_flow_vars.dim() == 3 )
328 Kpu(i,j) += -d_tau_M_dU(0)*u_phi[j][qp]*F*p_dphi[i][qp]*JxWxF;
329 Kpv(i,j) += -d_tau_M_dU(1)*u_phi[j][qp]*F*p_dphi[i][qp]*JxWxF;
330 for (
unsigned int d=0; d != 3; ++d)
332 Kpu(i,j) += -tau_M*dFdU(d,0)*u_phi[j][qp]*p_dphi[i][qp](d)*JxWxS;
333 Kpv(i,j) += -tau_M*dFdU(d,1)*u_phi[j][qp]*p_dphi[i][qp](d)*JxWxS;
336 for (
unsigned int j=0; j != n_u_dofs; ++j)
338 (*Kpw)(i,j) += -d_tau_M_dU(2)*u_phi[j][qp]*F*p_dphi[i][qp]*JxWxF;
339 for (
unsigned int d=0; d != 3; ++d)
341 (*Kpw)(i,j) += -tau_M*dFdU(d,2)*u_phi[j][qp]*p_dphi[i][qp](d)*JxWxS;
INSTANTIATE_INC_NS_SUBCLASS(AveragedFanAdjointStabilization)
virtual void init_context(AssemblyContext &context)
Initialize context for added physics variables.
AveragedFanAdjointStabilization()
~AveragedFanAdjointStabilization()
virtual void element_time_derivative(bool compute_jacobian, AssemblyContext &context)
Time dependent part(s) of physics for element interiors.
virtual void element_constraint(bool compute_jacobian, AssemblyContext &context)
Constraint part(s) of physics for element interiors.