36 #include "libmesh/quadrature.h"
41 template<
class Mu,
class SH,
class TC>
49 template<
class Mu,
class SH,
class TC>
55 template<
class Mu,
class SH,
class TC>
57 (
bool compute_jacobian,
60 this->assemble_continuity_time_deriv( compute_jacobian, context );
61 this->assemble_momentum_time_deriv( compute_jacobian, context );
62 this->assemble_energy_time_deriv( compute_jacobian, context );
65 template<
class Mu,
class SH,
class TC>
69 this->assemble_continuity_mass_residual( compute_jacobian, context );
70 this->assemble_momentum_mass_residual( compute_jacobian, context );
71 this->assemble_energy_mass_residual( compute_jacobian, context );
74 template<
class Mu,
class SH,
class TC>
79 const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
82 const std::vector<libMesh::Real> &JxW =
83 context.get_element_fe(this->_flow_vars.u())->get_JxW();
86 const std::vector<std::vector<libMesh::RealGradient> >& p_dphi =
87 context.get_element_fe(this->_press_var.p())->get_dphi();
89 libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p());
91 unsigned int n_qpoints = context.get_element_qrule().n_points();
93 for (
unsigned int qp=0; qp != n_qpoints; qp++)
95 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
97 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
98 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
100 libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );
101 libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
103 libMesh::Real mu = this->_mu(T);
104 libMesh::Real k = this->_k(T);
105 libMesh::Real cp = this->_cp(T);
107 libMesh::RealGradient U( context.interior_value( this->_flow_vars.u(), qp ),
108 context.interior_value( this->_flow_vars.v(), qp ) );
109 if( this->_flow_vars.dim() == 3 )
110 U(2) = context.interior_value( this->_flow_vars.w(), qp );
112 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, this->_is_steady );
113 libMesh::Real tau_E = this->_stab_helper.compute_tau_energy( context, qp, g, G, rho, U, k, cp, this->_is_steady );
115 libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
116 libMesh::Real RE_s = this->compute_res_energy_steady( context, qp );
120 for (
unsigned int i=0; i != n_p_dofs; i++)
122 Fp(i) += ( tau_M*RM_s*p_dphi[i][qp]
123 + tau_E*RE_s*(U*p_dphi[i][qp])/T )*JxW[qp];
131 template<
class Mu,
class SH,
class TC>
136 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
139 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
140 if (this->_flow_vars.dim() == 3)
141 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
144 const std::vector<libMesh::Real> &JxW =
145 context.get_element_fe(this->_flow_vars.u())->get_JxW();
148 const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
149 context.get_element_fe(this->_flow_vars.u())->get_dphi();
151 const std::vector<std::vector<libMesh::RealTensor> >& u_hessphi =
152 context.get_element_fe(this->_flow_vars.u())->get_d2phi();
154 libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u());
155 libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v());
156 libMesh::DenseSubVector<libMesh::Real>* Fw = NULL;
158 if( this->_flow_vars.dim() == 3 )
160 Fw = &context.get_elem_residual(this->_flow_vars.w());
163 unsigned int n_qpoints = context.get_element_qrule().n_points();
165 for (
unsigned int qp=0; qp != n_qpoints; qp++)
167 libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );
168 libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
170 libMesh::Real mu = this->_mu(T);
172 libMesh::RealGradient U( context.interior_value(this->_flow_vars.u(), qp),
173 context.interior_value(this->_flow_vars.v(), qp) );
175 libMesh::RealGradient grad_u = context.interior_gradient(this->_flow_vars.u(), qp);
176 libMesh::RealGradient grad_v = context.interior_gradient(this->_flow_vars.v(), qp);
177 libMesh::RealGradient grad_w;
179 if( this->_flow_vars.dim() == 3 )
181 U(2) = context.interior_value(this->_flow_vars.w(), qp);
182 grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
185 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
187 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
188 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
190 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, this->_is_steady );
191 libMesh::Real tau_C = this->_stab_helper.compute_tau_continuity( tau_M, g );
193 libMesh::Real RC_s = this->compute_res_continuity_steady( context, qp );
194 libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
196 for (
unsigned int i=0; i != n_u_dofs; i++)
198 Fu(i) += ( tau_C*RC_s*u_gradphi[i][qp](0)
199 + tau_M*RM_s(0)*rho*U*u_gradphi[i][qp]
200 + mu*tau_M*RM_s(0)*(u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,1)
201 + u_hessphi[i][qp](0,0) + u_hessphi[i][qp](0,1)
202 - 2.0/3.0*(u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,0)) )
205 Fv(i) += ( tau_C*RC_s*u_gradphi[i][qp](1)
206 + tau_M*RM_s(1)*rho*U*u_gradphi[i][qp]
207 + mu*tau_M*RM_s(1)*(u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,1)
208 + u_hessphi[i][qp](1,0) + u_hessphi[i][qp](1,1)
209 - 2.0/3.0*(u_hessphi[i][qp](0,1) + u_hessphi[i][qp](1,1)) )
212 if( this->_flow_vars.dim() == 3 )
214 Fu(i) += mu*tau_M*RM_s(0)*(u_hessphi[i][qp](2,2) + u_hessphi[i][qp](0,2)
215 - 2.0/3.0*u_hessphi[i][qp](2,0))*JxW[qp];
217 Fv(i) += mu*tau_M*RM_s(1)*(u_hessphi[i][qp](2,2) + u_hessphi[i][qp](1,2)
218 - 2.0/3.0*u_hessphi[i][qp](2,1))*JxW[qp];
220 (*Fw)(i) += ( tau_C*RC_s*u_gradphi[i][qp](2)
221 + tau_M*RM_s(2)*rho*U*u_gradphi[i][qp]
222 + mu*tau_M*RM_s(2)*(u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,1) + u_hessphi[i][qp](2,2)
223 + u_hessphi[i][qp](2,0) + u_hessphi[i][qp](2,1) + u_hessphi[i][qp](2,2)
224 - 2.0/3.0*(u_hessphi[i][qp](0,2) + u_hessphi[i][qp](1,2)
225 + u_hessphi[i][qp](2,2))
235 template<
class Mu,
class SH,
class TC>
240 const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
243 const std::vector<libMesh::Real> &JxW =
244 context.get_element_fe(this->_temp_vars.T())->get_JxW();
247 const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
248 context.get_element_fe(this->_temp_vars.T())->get_dphi();
250 const std::vector<std::vector<libMesh::RealTensor> >& T_hessphi =
251 context.get_element_fe(this->_temp_vars.T())->get_d2phi();
253 libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T());
255 unsigned int n_qpoints = context.get_element_qrule().n_points();
257 for (
unsigned int qp=0; qp != n_qpoints; qp++)
259 libMesh::Number u, v;
260 u = context.interior_value(this->_flow_vars.u(), qp);
261 v = context.interior_value(this->_flow_vars.v(), qp);
263 libMesh::Gradient grad_T = context.interior_gradient(this->_temp_vars.T(), qp);
265 libMesh::NumberVectorValue U(u,v);
266 if (this->_flow_vars.dim() == 3)
267 U(2) = context.interior_value(this->_flow_vars.w(), qp);
269 libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );
270 libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
272 libMesh::Real k = this->_k(T);
273 libMesh::Real cp = this->_cp(T);
275 libMesh::Number rho_cp = rho*this->_cp(T);
277 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
279 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
280 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
282 libMesh::Real tau_E = this->_stab_helper.compute_tau_energy( context, qp, g, G, rho, U, k, cp, this->_is_steady );
284 libMesh::Real RE_s = this->compute_res_energy_steady( context, qp );
286 for (
unsigned int i=0; i != n_T_dofs; i++)
288 FT(i) += ( rho_cp*tau_E*RE_s*U*T_gradphi[i][qp]
289 + tau_E*RE_s*k*(T_hessphi[i][qp](0,0) + T_hessphi[i][qp](1,1) + T_hessphi[i][qp](2,2) )
298 template<
class Mu,
class SH,
class TC>
303 const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
306 const std::vector<libMesh::Real> &JxW =
307 context.get_element_fe(this->_flow_vars.u())->get_JxW();
310 const std::vector<std::vector<libMesh::RealGradient> >& p_dphi =
311 context.get_element_fe(this->_press_var.p())->get_dphi();
313 libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p());
315 unsigned int n_qpoints = context.get_element_qrule().n_points();
317 for (
unsigned int qp=0; qp != n_qpoints; qp++)
319 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
321 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
322 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
324 libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
325 libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
327 libMesh::Real mu = this->_mu(T);
328 libMesh::Real k = this->_k(T);
329 libMesh::Real cp = this->_cp(T);
331 libMesh::RealGradient U( context.fixed_interior_value( this->_flow_vars.u(), qp ),
332 context.fixed_interior_value( this->_flow_vars.v(), qp ) );
333 if( this->_flow_vars.dim() == 3 )
334 U(2) = context.fixed_interior_value( this->_flow_vars.w(), qp );
336 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu,
false );
337 libMesh::RealGradient RM_t = this->compute_res_momentum_transient( context, qp );
339 libMesh::Real tau_E = this->_stab_helper.compute_tau_energy( context, qp, g, G, rho, U, k, cp,
false );
340 libMesh::Real RE_t = this->compute_res_energy_transient( context, qp );
344 for (
unsigned int i=0; i != n_p_dofs; i++)
346 Fp(i) += ( tau_M*RM_t*p_dphi[i][qp]
347 + tau_E*RE_t*(U*p_dphi[i][qp])/T
355 template<
class Mu,
class SH,
class TC>
360 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
363 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
364 if (this->_flow_vars.dim() == 3)
365 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
368 const std::vector<libMesh::Real> &JxW =
369 context.get_element_fe(this->_flow_vars.u())->get_JxW();
372 const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
373 context.get_element_fe(this->_flow_vars.u())->get_dphi();
375 const std::vector<std::vector<libMesh::RealTensor> >& u_hessphi =
376 context.get_element_fe(this->_flow_vars.u())->get_d2phi();
378 libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u());
379 libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v());
380 libMesh::DenseSubVector<libMesh::Real>* Fw = NULL;
382 if( this->_flow_vars.dim() == 3 )
384 Fw = &context.get_elem_residual(this->_flow_vars.w());
387 unsigned int n_qpoints = context.get_element_qrule().n_points();
388 for (
unsigned int qp=0; qp != n_qpoints; qp++)
390 libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
391 libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
393 libMesh::Real mu = this->_mu(T);
395 libMesh::RealGradient U( context.fixed_interior_value(this->_flow_vars.u(), qp),
396 context.fixed_interior_value(this->_flow_vars.v(), qp) );
398 libMesh::RealGradient grad_u = context.fixed_interior_gradient(this->_flow_vars.u(), qp);
399 libMesh::RealGradient grad_v = context.fixed_interior_gradient(this->_flow_vars.v(), qp);
400 libMesh::RealGradient grad_w;
402 if( this->_flow_vars.dim() == 3 )
404 U(2) = context.fixed_interior_value(this->_flow_vars.w(), qp);
405 grad_w = context.fixed_interior_gradient(this->_flow_vars.w(), qp);
408 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
410 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
411 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
413 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu,
false );
414 libMesh::Real tau_C = this->_stab_helper.compute_tau_continuity( tau_M, g );
416 libMesh::Real RC_t = this->compute_res_continuity_transient( context, qp );
417 libMesh::RealGradient RM_t = this->compute_res_momentum_transient( context, qp );
419 for (
unsigned int i=0; i != n_u_dofs; i++)
421 Fu(i) += ( tau_C*RC_t*u_gradphi[i][qp](0)
422 + tau_M*RM_t(0)*rho*U*u_gradphi[i][qp]
423 + mu*tau_M*RM_t(0)*(u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,1)
424 + u_hessphi[i][qp](0,0) + u_hessphi[i][qp](0,1)
425 - 2.0/3.0*(u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,0)) )
428 Fv(i) += ( tau_C*RC_t*u_gradphi[i][qp](1)
429 + tau_M*RM_t(1)*rho*U*u_gradphi[i][qp]
430 + mu*tau_M*RM_t(1)*(u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,1)
431 + u_hessphi[i][qp](1,0) + u_hessphi[i][qp](1,1)
432 - 2.0/3.0*(u_hessphi[i][qp](0,1) + u_hessphi[i][qp](1,1)) )
435 if( this->_flow_vars.dim() == 3 )
437 Fu(i) -= mu*tau_M*RM_t(0)*(u_hessphi[i][qp](2,2) + u_hessphi[i][qp](0,2)
438 - 2.0/3.0*u_hessphi[i][qp](2,0))*JxW[qp];
440 Fv(i) -= mu*tau_M*RM_t(1)*(u_hessphi[i][qp](2,2) + u_hessphi[i][qp](1,2)
441 - 2.0/3.0*u_hessphi[i][qp](2,1))*JxW[qp];
443 (*Fw)(i) -= ( tau_C*RC_t*u_gradphi[i][qp](2)
444 + tau_M*RM_t(2)*rho*U*u_gradphi[i][qp]
445 + mu*tau_M*RM_t(2)*(u_hessphi[i][qp](0,0) + u_hessphi[i][qp](1,1) + u_hessphi[i][qp](2,2)
446 + u_hessphi[i][qp](2,0) + u_hessphi[i][qp](2,1) + u_hessphi[i][qp](2,2)
447 - 2.0/3.0*(u_hessphi[i][qp](0,2) + u_hessphi[i][qp](1,2)
448 + u_hessphi[i][qp](2,2))
458 template<
class Mu,
class SH,
class TC>
463 const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
466 const std::vector<libMesh::Real> &JxW =
467 context.get_element_fe(this->_temp_vars.T())->get_JxW();
470 const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
471 context.get_element_fe(this->_temp_vars.T())->get_dphi();
473 const std::vector<std::vector<libMesh::RealTensor> >& T_hessphi =
474 context.get_element_fe(this->_temp_vars.T())->get_d2phi();
476 libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T());
478 unsigned int n_qpoints = context.get_element_qrule().n_points();
480 for (
unsigned int qp=0; qp != n_qpoints; qp++)
482 libMesh::Number u, v;
483 u = context.fixed_interior_value(this->_flow_vars.u(), qp);
484 v = context.fixed_interior_value(this->_flow_vars.v(), qp);
486 libMesh::Gradient grad_T = context.fixed_interior_gradient(this->_temp_vars.T(), qp);
488 libMesh::NumberVectorValue U(u,v);
489 if (this->_flow_vars.dim() == 3)
490 U(2) = context.fixed_interior_value(this->_flow_vars.w(), qp);
492 libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
493 libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
495 libMesh::Real k = this->_k(T);
496 libMesh::Real cp = this->_cp(T);
498 libMesh::Number rho_cp = rho*cp;
500 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
502 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
503 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
505 libMesh::Real tau_E = this->_stab_helper.compute_tau_energy( context, qp, g, G, rho, U, k, cp,
false );
507 libMesh::Real RE_t = this->compute_res_energy_transient( context, qp );
509 for (
unsigned int i=0; i != n_T_dofs; i++)
511 FT(i) += ( rho_cp*tau_E*RE_t*U*T_gradphi[i][qp]
512 + tau_E*RE_t*k*(T_hessphi[i][qp](0,0) + T_hessphi[i][qp](1,1) + T_hessphi[i][qp](2,2))
virtual void element_time_derivative(bool compute_jacobian, AssemblyContext &context)
Time dependent part(s) of physics for element interiors.
void assemble_energy_mass_residual(bool compute_jacobian, AssemblyContext &context)
Adds VMS-based stabilization to LowMachNavierStokes physics class.
void assemble_energy_time_deriv(bool compute_jacobian, AssemblyContext &context)
void assemble_momentum_mass_residual(bool compute_jacobian, AssemblyContext &context)
void assemble_continuity_time_deriv(bool compute_jacobian, AssemblyContext &context)
virtual ~LowMachNavierStokesBraackStabilization()
Adds VMS-based stabilization to LowMachNavierStokes physics class.
void assemble_continuity_mass_residual(bool compute_jacobian, AssemblyContext &context)
LowMachNavierStokesBraackStabilization()
void assemble_momentum_time_deriv(bool compute_jacobian, AssemblyContext &context)
virtual void mass_residual(bool compute_jacobian, AssemblyContext &context)
Mass matrix part(s) for element interiors. All boundary terms lie within the time_derivative part...