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 );
102 libMesh::Real mu = this->_mu(T);
104 libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
106 libMesh::RealGradient U( context.interior_value( this->_flow_vars.u(), qp ),
107 context.interior_value( this->_flow_vars.v(), qp ) );
108 if( this->_flow_vars.dim() == 3 )
109 U(2) = context.interior_value( this->_flow_vars.w(), qp );
111 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, this->_is_steady );
113 libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
117 for (
unsigned int i=0; i != n_p_dofs; i++)
119 Fp(i) += tau_M*RM_s*p_dphi[i][qp]*JxW[qp];
127 template<
class Mu,
class SH,
class TC>
132 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
135 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
136 if (this->_flow_vars.dim() == 3)
137 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
140 const std::vector<libMesh::Real> &JxW =
141 context.get_element_fe(this->_flow_vars.u())->get_JxW();
144 const std::vector<std::vector<libMesh::Real> >& u_phi =
145 context.get_element_fe(this->_flow_vars.u())->get_phi();
148 const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
149 context.get_element_fe(this->_flow_vars.u())->get_dphi();
151 libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u());
152 libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v());
153 libMesh::DenseSubVector<libMesh::Real>* Fw = NULL;
155 if( this->_flow_vars.dim() == 3 )
157 Fw = &context.get_elem_residual(this->_flow_vars.w());
160 unsigned int n_qpoints = context.get_element_qrule().n_points();
162 for (
unsigned int qp=0; qp != n_qpoints; qp++)
164 libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );
165 libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
167 libMesh::RealGradient U( context.interior_value(this->_flow_vars.u(), qp),
168 context.interior_value(this->_flow_vars.v(), qp) );
170 libMesh::RealGradient grad_u = context.interior_gradient(this->_flow_vars.u(), qp);
171 libMesh::RealGradient grad_v = context.interior_gradient(this->_flow_vars.v(), qp);
172 libMesh::RealGradient grad_w;
174 if( this->_flow_vars.dim() == 3 )
176 U(2) = context.interior_value(this->_flow_vars.w(), qp);
177 grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
180 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
182 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
183 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
184 libMesh::Real mu = this->_mu(T);
186 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, this->_is_steady );
187 libMesh::Real tau_C = this->_stab_helper.compute_tau_continuity( tau_M, g );
189 libMesh::Real RC_s = this->compute_res_continuity_steady( context, qp );
190 libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
192 for (
unsigned int i=0; i != n_u_dofs; i++)
194 Fu(i) += ( -tau_C*RC_s*u_gradphi[i][qp](0)
195 - tau_M*RM_s(0)*rho*U*u_gradphi[i][qp]
196 + rho*tau_M*RM_s*grad_u*u_phi[i][qp]
197 + tau_M*RM_s(0)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
199 Fv(i) += ( -tau_C*RC_s*u_gradphi[i][qp](1)
200 - tau_M*RM_s(1)*rho*U*u_gradphi[i][qp]
201 + rho*tau_M*RM_s*grad_v*u_phi[i][qp]
202 + tau_M*RM_s(1)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
204 if( this->_flow_vars.dim() == 3 )
206 (*Fw)(i) += ( -tau_C*RC_s*u_gradphi[i][qp](2)
207 - tau_M*RM_s(2)*rho*U*u_gradphi[i][qp]
208 + rho*tau_M*RM_s*grad_w*u_phi[i][qp]
209 + tau_M*RM_s(2)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
217 template<
class Mu,
class SH,
class TC>
222 const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
225 const std::vector<libMesh::Real> &JxW =
226 context.get_element_fe(this->_temp_vars.T())->get_JxW();
229 const std::vector<std::vector<libMesh::Real> >& T_phi =
230 context.get_element_fe(this->_temp_vars.T())->get_phi();
233 const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
234 context.get_element_fe(this->_temp_vars.T())->get_dphi();
236 libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T());
238 unsigned int n_qpoints = context.get_element_qrule().n_points();
240 for (
unsigned int qp=0; qp != n_qpoints; qp++)
242 libMesh::Number u, v;
243 u = context.interior_value(this->_flow_vars.u(), qp);
244 v = context.interior_value(this->_flow_vars.v(), qp);
246 libMesh::Gradient grad_T = context.interior_gradient(this->_temp_vars.T(), qp);
248 libMesh::NumberVectorValue U(u,v);
249 if (this->_flow_vars.dim() == 3)
250 U(2) = context.interior_value(this->_flow_vars.w(), qp);
252 libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );
253 libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
255 libMesh::Real mu = this->_mu(T);
256 libMesh::Real k = this->_k(T);
257 libMesh::Real cp = this->_cp(T);
259 libMesh::Number rho_cp = rho*this->_cp(T);
261 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
263 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
264 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
266 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, this->_is_steady );
267 libMesh::Real tau_E = this->_stab_helper.compute_tau_energy( context, qp, g, G, rho, U, k, cp, this->_is_steady );
269 libMesh::Real RE_s = this->compute_res_energy_steady( context, qp );
270 libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
272 for (
unsigned int i=0; i != n_T_dofs; i++)
274 FT(i) += ( rho_cp*tau_M*RM_s*grad_T*T_phi[i][qp]
275 - rho_cp*tau_E*RE_s*U*T_gradphi[i][qp]
276 + rho_cp*tau_E*RE_s*tau_M*RM_s*T_gradphi[i][qp] )*JxW[qp];
284 template<
class Mu,
class SH,
class TC>
289 const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
292 const std::vector<libMesh::Real> &JxW =
293 context.get_element_fe(this->_flow_vars.u())->get_JxW();
296 const std::vector<std::vector<libMesh::RealGradient> >& p_dphi =
297 context.get_element_fe(this->_press_var.p())->get_dphi();
299 libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p());
301 unsigned int n_qpoints = context.get_element_qrule().n_points();
303 for (
unsigned int qp=0; qp != n_qpoints; qp++)
305 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
307 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
308 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
310 libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
311 libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
313 libMesh::Real mu = this->_mu(T);
315 libMesh::RealGradient U( context.fixed_interior_value( this->_flow_vars.u(), qp ),
316 context.fixed_interior_value( this->_flow_vars.v(), qp ) );
317 if( this->_flow_vars.dim() == 3 )
318 U(2) = context.fixed_interior_value( this->_flow_vars.w(), qp );
320 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu,
false );
321 libMesh::RealGradient RM_t = this->compute_res_momentum_transient( context, qp );
325 for (
unsigned int i=0; i != n_p_dofs; i++)
327 Fp(i) += tau_M*RM_t*p_dphi[i][qp]*JxW[qp];
334 template<
class Mu,
class SH,
class TC>
339 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
342 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
343 if (this->_flow_vars.dim() == 3)
344 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
347 const std::vector<libMesh::Real> &JxW =
348 context.get_element_fe(this->_flow_vars.u())->get_JxW();
351 const std::vector<std::vector<libMesh::Real> >& u_phi =
352 context.get_element_fe(this->_flow_vars.u())->get_phi();
355 const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
356 context.get_element_fe(this->_flow_vars.u())->get_dphi();
358 libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u());
359 libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v());
360 libMesh::DenseSubVector<libMesh::Real>* Fw = NULL;
362 if( this->_flow_vars.dim() == 3 )
364 Fw = &context.get_elem_residual(this->_flow_vars.w());
367 unsigned int n_qpoints = context.get_element_qrule().n_points();
368 for (
unsigned int qp=0; qp != n_qpoints; qp++)
370 libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
371 libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
373 libMesh::Real mu = this->_mu(T);
375 libMesh::RealGradient U( context.fixed_interior_value(this->_flow_vars.u(), qp),
376 context.fixed_interior_value(this->_flow_vars.v(), qp) );
378 libMesh::RealGradient grad_u = context.fixed_interior_gradient(this->_flow_vars.u(), qp);
379 libMesh::RealGradient grad_v = context.fixed_interior_gradient(this->_flow_vars.v(), qp);
380 libMesh::RealGradient grad_w;
382 if( this->_flow_vars.dim() == 3 )
384 U(2) = context.fixed_interior_value(this->_flow_vars.w(), qp);
385 grad_w = context.fixed_interior_gradient(this->_flow_vars.w(), qp);
388 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
390 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
391 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
393 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu,
false );
394 libMesh::Real tau_C = this->_stab_helper.compute_tau_continuity( tau_M, g );
396 libMesh::Real RC_t = this->compute_res_continuity_transient( context, qp );
397 libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
398 libMesh::RealGradient RM_t = this->compute_res_momentum_transient( context, qp );
400 for (
unsigned int i=0; i != n_u_dofs; i++)
402 Fu(i) -= ( tau_C*RC_t*u_gradphi[i][qp](0)
403 + tau_M*RM_t(0)*rho*U*u_gradphi[i][qp]
404 - rho*tau_M*RM_t*grad_u*u_phi[i][qp]
405 - tau_M*(RM_s(0)+RM_t(0))*rho*tau_M*RM_t*u_gradphi[i][qp]
406 - tau_M*RM_t(0)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
408 Fv(i) -= ( tau_C*RC_t*u_gradphi[i][qp](1)
409 - rho*tau_M*RM_t*grad_v*u_phi[i][qp]
410 + tau_M*RM_t(1)*rho*U*u_gradphi[i][qp]
411 - tau_M*(RM_s(1)+RM_t(1))*rho*tau_M*RM_t*u_gradphi[i][qp]
412 - tau_M*RM_t(1)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
414 if( this->_flow_vars.dim() == 3 )
416 (*Fw)(i) -= ( tau_C*RC_t*u_gradphi[i][qp](2)
417 - rho*tau_M*RM_t*grad_w*u_phi[i][qp]
418 + tau_M*RM_t(2)*rho*U*u_gradphi[i][qp]
419 - tau_M*(RM_s(2)+RM_t(2))*rho*tau_M*RM_t*u_gradphi[i][qp]
420 - tau_M*RM_t(2)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
428 template<
class Mu,
class SH,
class TC>
433 const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
436 const std::vector<libMesh::Real> &JxW =
437 context.get_element_fe(this->_temp_vars.T())->get_JxW();
440 const std::vector<std::vector<libMesh::Real> >& T_phi =
441 context.get_element_fe(this->_temp_vars.T())->get_phi();
444 const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
445 context.get_element_fe(this->_temp_vars.T())->get_dphi();
447 libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T());
449 unsigned int n_qpoints = context.get_element_qrule().n_points();
451 for (
unsigned int qp=0; qp != n_qpoints; qp++)
453 libMesh::Number u, v;
454 u = context.fixed_interior_value(this->_flow_vars.u(), qp);
455 v = context.fixed_interior_value(this->_flow_vars.v(), qp);
457 libMesh::Gradient grad_T = context.fixed_interior_gradient(this->_temp_vars.T(), qp);
459 libMesh::NumberVectorValue U(u,v);
460 if (this->_flow_vars.dim() == 3)
461 U(2) = context.fixed_interior_value(this->_flow_vars.w(), qp);
463 libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
464 libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
466 libMesh::Real mu = this->_mu(T);
467 libMesh::Real k = this->_k(T);
468 libMesh::Real cp = this->_cp(T);
470 libMesh::Number rho_cp = rho*this->_cp(T);
472 libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
474 libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
475 libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
477 libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu,
false );
478 libMesh::Real tau_E = this->_stab_helper.compute_tau_energy( context, qp, g, G, rho, U, k, cp,
false );
480 libMesh::Real RE_s = this->compute_res_energy_steady( context, qp );
481 libMesh::Real RE_t = this->compute_res_energy_transient( context, qp );
483 libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
484 libMesh::RealGradient RM_t = this->compute_res_momentum_transient( context, qp );
486 for (
unsigned int i=0; i != n_T_dofs; i++)
488 FT(i) -= ( -rho_cp*tau_M*RM_t*grad_T*T_phi[i][qp]
489 +rho_cp*tau_E*RE_t*U*T_gradphi[i][qp]
490 - rho_cp*tau_E*(RE_s+RE_t)*tau_M*RM_t*T_gradphi[i][qp]
491 - rho_cp*tau_E*RE_t*tau_M*RM_s*T_gradphi[i][qp] )*JxW[qp];
virtual void element_time_derivative(bool compute_jacobian, AssemblyContext &context)
Time dependent part(s) of physics for element interiors.
Adds VMS-based stabilization to LowMachNavierStokes physics class.
LowMachNavierStokesVMSStabilization()
virtual ~LowMachNavierStokesVMSStabilization()
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...
void assemble_energy_time_deriv(bool compute_jacobian, AssemblyContext &context)
void assemble_momentum_mass_residual(bool compute_jacobian, AssemblyContext &context)
Adds VMS-based stabilization to LowMachNavierStokes physics class.
void assemble_momentum_time_deriv(bool compute_jacobian, AssemblyContext &context)
void assemble_continuity_mass_residual(bool compute_jacobian, AssemblyContext &context)
void assemble_continuity_time_deriv(bool compute_jacobian, AssemblyContext &context)
void assemble_energy_mass_residual(bool compute_jacobian, AssemblyContext &context)