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>
 
   60 #ifdef GRINS_USE_GRVY_TIMERS 
   61     this->_timer->BeginTimer(
"LowMachNavierStokesVMSStabilization::element_time_derivative");
 
   64     this->assemble_continuity_time_deriv( compute_jacobian, context );
 
   65     this->assemble_momentum_time_deriv( compute_jacobian, context );
 
   66     this->assemble_energy_time_deriv( compute_jacobian, context );
 
   68 #ifdef GRINS_USE_GRVY_TIMERS 
   69     this->_timer->EndTimer(
"LowMachNavierStokesVMSStabilization::element_time_derivative");
 
   74   template<
class Mu, 
class SH, 
class TC>
 
   79 #ifdef GRINS_USE_GRVY_TIMERS 
   80     this->_timer->BeginTimer(
"LowMachNavierStokesVMSStabilization::mass_residual");
 
   83     this->assemble_continuity_mass_residual( compute_jacobian, context );
 
   84     this->assemble_momentum_mass_residual( compute_jacobian, context );
 
   85     this->assemble_energy_mass_residual( compute_jacobian, context );
 
   87 #ifdef GRINS_USE_GRVY_TIMERS 
   88     this->_timer->EndTimer(
"LowMachNavierStokesVMSStabilization::mass_residual");
 
   93   template<
class Mu, 
class SH, 
class TC>
 
   98     const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
 
  101     const std::vector<libMesh::Real> &JxW =
 
  102       context.get_element_fe(this->_flow_vars.u())->get_JxW();
 
  105     const std::vector<std::vector<libMesh::RealGradient> >& p_dphi =
 
  106       context.get_element_fe(this->_press_var.p())->get_dphi();
 
  108     libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p()); 
 
  110     unsigned int n_qpoints = context.get_element_qrule().n_points();
 
  112     for (
unsigned int qp=0; qp != n_qpoints; qp++)
 
  114         libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
 
  116         libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
 
  117         libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
 
  119         libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );
 
  121         libMesh::Real mu = this->_mu(T);
 
  123         libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
 
  125         libMesh::RealGradient U( context.interior_value( this->_flow_vars.u(), qp ),
 
  126                                  context.interior_value( this->_flow_vars.v(), qp ) );
 
  127         if( this->_dim == 3 )
 
  128           U(2) = context.interior_value( this->_flow_vars.w(), qp );
 
  130         libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, this->_is_steady );
 
  132         libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
 
  136         for (
unsigned int i=0; i != n_p_dofs; i++)
 
  138             Fp(i) += tau_M*RM_s*p_dphi[i][qp]*JxW[qp];
 
  146   template<
class Mu, 
class SH, 
class TC>
 
  151     const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
 
  154     libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
 
  156       libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
 
  159     const std::vector<libMesh::Real> &JxW =
 
  160       context.get_element_fe(this->_flow_vars.u())->get_JxW();
 
  163     const std::vector<std::vector<libMesh::Real> >& u_phi =
 
  164       context.get_element_fe(this->_flow_vars.u())->get_phi();
 
  167     const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
 
  168       context.get_element_fe(this->_flow_vars.u())->get_dphi();
 
  170     libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u()); 
 
  171     libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v()); 
 
  172     libMesh::DenseSubVector<libMesh::Real>* Fw = NULL;
 
  174     if( this->_dim == 3 )
 
  176         Fw  = &context.get_elem_residual(this->_flow_vars.w()); 
 
  179     unsigned int n_qpoints = context.get_element_qrule().n_points();
 
  181     for (
unsigned int qp=0; qp != n_qpoints; qp++)
 
  183         libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );
 
  184         libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
 
  186         libMesh::RealGradient U( context.interior_value(this->_flow_vars.u(), qp),
 
  187                                  context.interior_value(this->_flow_vars.v(), qp) );
 
  189         libMesh::RealGradient grad_u = context.interior_gradient(this->_flow_vars.u(), qp);
 
  190         libMesh::RealGradient grad_v = context.interior_gradient(this->_flow_vars.v(), qp);
 
  191         libMesh::RealGradient grad_w;
 
  193         if( this->_dim == 3 )
 
  195             U(2) = context.interior_value(this->_flow_vars.w(), qp);
 
  196             grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
 
  199         libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
 
  201         libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
 
  202         libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
 
  203         libMesh::Real mu = this->_mu(T);
 
  205         libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, this->_is_steady );
 
  206         libMesh::Real tau_C = this->_stab_helper.compute_tau_continuity( tau_M, g );
 
  208         libMesh::Real RC_s = this->compute_res_continuity_steady( context, qp );
 
  209         libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
 
  211         for (
unsigned int i=0; i != n_u_dofs; i++)
 
  213             Fu(i) += ( -tau_C*RC_s*u_gradphi[i][qp](0)
 
  214                        - tau_M*RM_s(0)*rho*U*u_gradphi[i][qp] 
 
  215                        + rho*tau_M*RM_s*grad_u*u_phi[i][qp]
 
  216                        + tau_M*RM_s(0)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
 
  218             Fv(i) += ( -tau_C*RC_s*u_gradphi[i][qp](1)
 
  219                        - tau_M*RM_s(1)*rho*U*u_gradphi[i][qp]
 
  220                        + rho*tau_M*RM_s*grad_v*u_phi[i][qp]
 
  221                        + tau_M*RM_s(1)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
 
  223             if( this->_dim == 3 )
 
  225                 (*Fw)(i) += ( -tau_C*RC_s*u_gradphi[i][qp](2)
 
  226                               - tau_M*RM_s(2)*rho*U*u_gradphi[i][qp]
 
  227                               + rho*tau_M*RM_s*grad_w*u_phi[i][qp]
 
  228                               + tau_M*RM_s(2)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
 
  236   template<
class Mu, 
class SH, 
class TC>
 
  241     const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
 
  244     const std::vector<libMesh::Real> &JxW =
 
  245       context.get_element_fe(this->_temp_vars.T())->get_JxW();
 
  248     const std::vector<std::vector<libMesh::Real> >& T_phi =
 
  249       context.get_element_fe(this->_temp_vars.T())->get_phi();
 
  252     const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
 
  253       context.get_element_fe(this->_temp_vars.T())->get_dphi();
 
  255     libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T()); 
 
  257     unsigned int n_qpoints = context.get_element_qrule().n_points();
 
  259     for (
unsigned int qp=0; qp != n_qpoints; qp++)
 
  261         libMesh::Number u, v;
 
  262         u = context.interior_value(this->_flow_vars.u(), qp);
 
  263         v = context.interior_value(this->_flow_vars.v(), qp);
 
  265         libMesh::Gradient grad_T = context.interior_gradient(this->_temp_vars.T(), qp);
 
  267         libMesh::NumberVectorValue U(u,v);
 
  269           U(2) = context.interior_value(this->_flow_vars.w(), qp); 
 
  271         libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );
 
  272         libMesh::Real rho = this->rho( T, this->get_p0_steady( context, qp ) );
 
  274         libMesh::Real mu = this->_mu(T);
 
  275         libMesh::Real k = this->_k(T);
 
  276         libMesh::Real cp = this->_cp(T);
 
  278         libMesh::Number rho_cp = rho*this->_cp(T);
 
  280         libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
 
  282         libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
 
  283         libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
 
  285         libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, this->_is_steady );
 
  286         libMesh::Real tau_E = this->_stab_helper.compute_tau_energy( context, qp, g, G, rho, U, k, cp, this->_is_steady );
 
  288         libMesh::Real RE_s = this->compute_res_energy_steady( context, qp );
 
  289         libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
 
  291         for (
unsigned int i=0; i != n_T_dofs; i++)
 
  293             FT(i) += ( rho_cp*tau_M*RM_s*grad_T*T_phi[i][qp] 
 
  294                        - rho_cp*tau_E*RE_s*U*T_gradphi[i][qp]
 
  295                        + rho_cp*tau_E*RE_s*tau_M*RM_s*T_gradphi[i][qp] )*JxW[qp];
 
  303   template<
class Mu, 
class SH, 
class TC>
 
  308     const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
 
  311     const std::vector<libMesh::Real> &JxW =
 
  312       context.get_element_fe(this->_flow_vars.u())->get_JxW();
 
  315     const std::vector<std::vector<libMesh::RealGradient> >& p_dphi =
 
  316       context.get_element_fe(this->_press_var.p())->get_dphi();
 
  318     libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p()); 
 
  320     unsigned int n_qpoints = context.get_element_qrule().n_points();
 
  322     for (
unsigned int qp=0; qp != n_qpoints; qp++)
 
  324         libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
 
  326         libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
 
  327         libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
 
  329         libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
 
  330         libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
 
  332         libMesh::Real mu = this->_mu(T);
 
  334         libMesh::RealGradient U( context.fixed_interior_value( this->_flow_vars.u(), qp ),
 
  335                                  context.fixed_interior_value( this->_flow_vars.v(), qp ) );
 
  336         if( this->_dim == 3 )
 
  337           U(2) = context.fixed_interior_value( this->_flow_vars.w(), qp );
 
  339         libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, 
false );
 
  340         libMesh::RealGradient RM_t = this->compute_res_momentum_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]*JxW[qp];
 
  353   template<
class Mu, 
class SH, 
class TC>
 
  358     const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
 
  361     libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
 
  363       libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
 
  366     const std::vector<libMesh::Real> &JxW =
 
  367       context.get_element_fe(this->_flow_vars.u())->get_JxW();
 
  370     const std::vector<std::vector<libMesh::Real> >& u_phi =
 
  371       context.get_element_fe(this->_flow_vars.u())->get_phi();
 
  374     const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
 
  375       context.get_element_fe(this->_flow_vars.u())->get_dphi();
 
  377     libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u()); 
 
  378     libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v()); 
 
  379     libMesh::DenseSubVector<libMesh::Real>* Fw = NULL;
 
  381     if( this->_dim == 3 )
 
  383         Fw  = &context.get_elem_residual(this->_flow_vars.w()); 
 
  386     unsigned int n_qpoints = context.get_element_qrule().n_points();
 
  387     for (
unsigned int qp=0; qp != n_qpoints; qp++)
 
  389         libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
 
  390         libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
 
  392         libMesh::Real mu = this->_mu(T);
 
  394         libMesh::RealGradient U( context.fixed_interior_value(this->_flow_vars.u(), qp),
 
  395                                  context.fixed_interior_value(this->_flow_vars.v(), qp) );
 
  397         libMesh::RealGradient grad_u = context.fixed_interior_gradient(this->_flow_vars.u(), qp);
 
  398         libMesh::RealGradient grad_v = context.fixed_interior_gradient(this->_flow_vars.v(), qp);
 
  399         libMesh::RealGradient grad_w;
 
  401         if( this->_dim == 3 )
 
  403             U(2) = context.fixed_interior_value(this->_flow_vars.w(), qp);
 
  404             grad_w = context.fixed_interior_gradient(this->_flow_vars.w(), qp);
 
  407         libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
 
  409         libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
 
  410         libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
 
  412         libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, 
false );
 
  413         libMesh::Real tau_C = this->_stab_helper.compute_tau_continuity( tau_M, g );
 
  415         libMesh::Real RC_t = this->compute_res_continuity_transient( context, qp );
 
  416         libMesh::RealGradient RM_s = this->compute_res_momentum_steady( 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                        - rho*tau_M*RM_t*grad_u*u_phi[i][qp]
 
  424                        - tau_M*(RM_s(0)+RM_t(0))*rho*tau_M*RM_t*u_gradphi[i][qp]
 
  425                        - tau_M*RM_t(0)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
 
  427             Fv(i) -= ( tau_C*RC_t*u_gradphi[i][qp](1)
 
  428                        - rho*tau_M*RM_t*grad_v*u_phi[i][qp]
 
  429                        + tau_M*RM_t(1)*rho*U*u_gradphi[i][qp]
 
  430                        - tau_M*(RM_s(1)+RM_t(1))*rho*tau_M*RM_t*u_gradphi[i][qp]
 
  431                        - tau_M*RM_t(1)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
 
  433             if( this->_dim == 3 )
 
  435                 (*Fw)(i) -= ( tau_C*RC_t*u_gradphi[i][qp](2)
 
  436                               - rho*tau_M*RM_t*grad_w*u_phi[i][qp]
 
  437                               + tau_M*RM_t(2)*rho*U*u_gradphi[i][qp]
 
  438                               - tau_M*(RM_s(2)+RM_t(2))*rho*tau_M*RM_t*u_gradphi[i][qp]
 
  439                               - tau_M*RM_t(2)*rho*tau_M*RM_s*u_gradphi[i][qp] )*JxW[qp];
 
  447   template<
class Mu, 
class SH, 
class TC>
 
  452     const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
 
  455     const std::vector<libMesh::Real> &JxW =
 
  456       context.get_element_fe(this->_temp_vars.T())->get_JxW();
 
  459     const std::vector<std::vector<libMesh::Real> >& T_phi =
 
  460       context.get_element_fe(this->_temp_vars.T())->get_phi();
 
  463     const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
 
  464       context.get_element_fe(this->_temp_vars.T())->get_dphi();
 
  466     libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T()); 
 
  468     unsigned int n_qpoints = context.get_element_qrule().n_points();
 
  470     for (
unsigned int qp=0; qp != n_qpoints; qp++)
 
  472         libMesh::Number u, v;
 
  473         u = context.fixed_interior_value(this->_flow_vars.u(), qp);
 
  474         v = context.fixed_interior_value(this->_flow_vars.v(), qp);
 
  476         libMesh::Gradient grad_T = context.fixed_interior_gradient(this->_temp_vars.T(), qp);
 
  478         libMesh::NumberVectorValue U(u,v);
 
  480           U(2) = context.fixed_interior_value(this->_flow_vars.w(), qp); 
 
  482         libMesh::Real T = context.fixed_interior_value( this->_temp_vars.T(), qp );
 
  483         libMesh::Real rho = this->rho( T, this->get_p0_transient( context, qp ) );
 
  485         libMesh::Real mu = this->_mu(T);
 
  486         libMesh::Real k = this->_k(T);
 
  487         libMesh::Real cp = this->_cp(T);
 
  489         libMesh::Number rho_cp = rho*this->_cp(T);
 
  491         libMesh::FEBase* fe = context.get_element_fe(this->_flow_vars.u());
 
  493         libMesh::RealGradient g = this->_stab_helper.compute_g( fe, context, qp );
 
  494         libMesh::RealTensor G = this->_stab_helper.compute_G( fe, context, qp );
 
  496         libMesh::Real tau_M = this->_stab_helper.compute_tau_momentum( context, qp, g, G, rho, U, mu, 
false );
 
  497         libMesh::Real tau_E = this->_stab_helper.compute_tau_energy( context, qp, g, G, rho, U, k, cp, 
false );
 
  499         libMesh::Real RE_s = this->compute_res_energy_steady( context, qp );
 
  500         libMesh::Real RE_t = this->compute_res_energy_transient( context, qp );
 
  502         libMesh::RealGradient RM_s = this->compute_res_momentum_steady( context, qp );
 
  503         libMesh::RealGradient RM_t = this->compute_res_momentum_transient( context, qp );
 
  505         for (
unsigned int i=0; i != n_T_dofs; i++)
 
  507             FT(i) -= ( -rho_cp*tau_M*RM_t*grad_T*T_phi[i][qp] 
 
  508                        +rho_cp*tau_E*RE_t*U*T_gradphi[i][qp]
 
  509                        - rho_cp*tau_E*(RE_s+RE_t)*tau_M*RM_t*T_gradphi[i][qp]
 
  510                        - rho_cp*tau_E*RE_t*tau_M*RM_s*T_gradphi[i][qp] )*JxW[qp];
 
Adds VMS-based stabilization to LowMachNavierStokes physics class. 
 
LowMachNavierStokesVMSStabilization()
 
virtual ~LowMachNavierStokesVMSStabilization()
 
virtual void mass_residual(bool compute_jacobian, AssemblyContext &context, CachedValues &cache)
Mass matrix part(s) for element interiors. All boundary terms lie within the time_derivative part...
 
virtual void element_time_derivative(bool compute_jacobian, AssemblyContext &context, CachedValues &cache)
Time dependent part(s) of physics for element interiors. 
 
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)