GRINS-0.8.0
List of all members | Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions
GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity > Class Template Reference

Physics class for Incompressible Navier-Stokes. More...

#include <low_mach_navier_stokes.h>

Inheritance diagram for GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >:
Inheritance graph
[legend]
Collaboration diagram for GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >:
Collaboration graph
[legend]

Public Member Functions

 LowMachNavierStokes (const PhysicsName &physics_name, const GetPot &input)
 
 ~LowMachNavierStokes ()
 
virtual void auxiliary_init (MultiphysicsSystem &system)
 Any auxillary initialization a Physics class may need. More...
 
virtual void register_postprocessing_vars (const GetPot &input, PostProcessedQuantities< libMesh::Real > &postprocessing)
 Register postprocessing variables for LowMachNavierStokes. More...
 
virtual void init_context (AssemblyContext &context)
 Initialize context for added physics variables. More...
 
virtual void element_time_derivative (bool compute_jacobian, AssemblyContext &context)
 Time dependent part(s) of physics for element interiors. More...
 
virtual void element_constraint (bool compute_jacobian, AssemblyContext &context)
 Constraint part(s) of physics for element interiors. More...
 
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. More...
 
virtual void compute_element_time_derivative_cache (AssemblyContext &context)
 
virtual void compute_postprocessed_quantity (unsigned int quantity_index, const AssemblyContext &context, const libMesh::Point &point, libMesh::Real &value)
 
- Public Member Functions inherited from GRINS::LowMachNavierStokesBase< Viscosity, SpecificHeat, ThermalConductivity >
 LowMachNavierStokesBase (const PhysicsName &physics_name, const std::string &core_physics_name, const GetPot &input)
 
 ~LowMachNavierStokesBase ()
 
virtual void set_time_evolving_vars (libMesh::FEMSystem *system)
 Sets velocity variables to be time-evolving. More...
 
libMesh::Real T (const libMesh::Point &p, const AssemblyContext &c) const
 
libMesh::Real rho (libMesh::Real T, libMesh::Real p0) const
 
libMesh::Real d_rho_dT (libMesh::Real T, libMesh::Real p0) const
 
libMesh::Real get_p0_steady (const AssemblyContext &c, unsigned int qp) const
 
libMesh::Real get_p0_steady_side (const AssemblyContext &c, unsigned int qp) const
 
libMesh::Real get_p0_steady (const AssemblyContext &c, const libMesh::Point &p) const
 
libMesh::Real get_p0_transient (AssemblyContext &c, unsigned int qp) const
 
virtual void register_parameter (const std::string &param_name, libMesh::ParameterMultiAccessor< libMesh::Number > &param_pointer) const
 Each subclass will register its copy of an independent. More...
 
- Public Member Functions inherited from GRINS::Physics
 Physics (const GRINS::PhysicsName &physics_name, const GetPot &input)
 
virtual ~Physics ()
 
virtual void init_variables (libMesh::FEMSystem *)
 Initialize variables for this physics. More...
 
virtual bool enabled_on_elem (const libMesh::Elem *elem)
 Find if current physics is active on supplied element. More...
 
void set_is_steady (bool is_steady)
 Sets whether this physics is to be solved with a steady solver or not. More...
 
bool is_steady () const
 Returns whether or not this physics is being solved with a steady solver. More...
 
virtual void preassembly (MultiphysicsSystem &)
 Perform any necessary setup before element assembly begins. More...
 
virtual void reinit (MultiphysicsSystem &)
 Any reinitialization that needs to be done. More...
 
virtual void side_time_derivative (bool, AssemblyContext &)
 Time dependent part(s) of physics for boundaries of elements on the domain boundary. More...
 
virtual void nonlocal_time_derivative (bool, AssemblyContext &)
 Time dependent part(s) of physics for scalar variables. More...
 
virtual void side_constraint (bool, AssemblyContext &)
 Constraint part(s) of physics for boundaries of elements on the domain boundary. More...
 
virtual void nonlocal_constraint (bool, AssemblyContext &)
 Constraint part(s) of physics for scalar variables. More...
 
virtual void damping_residual (bool, AssemblyContext &)
 Damping matrix part(s) for element interiors. All boundary terms lie within the time_derivative part. More...
 
virtual void nonlocal_mass_residual (bool, AssemblyContext &)
 Mass matrix part(s) for scalar variables. More...
 
void init_ics (libMesh::FEMSystem *system, libMesh::CompositeFunction< libMesh::Number > &all_ics)
 
virtual void compute_side_time_derivative_cache (AssemblyContext &)
 
virtual void compute_nonlocal_time_derivative_cache (AssemblyContext &)
 
virtual void compute_element_constraint_cache (AssemblyContext &)
 
virtual void compute_side_constraint_cache (AssemblyContext &)
 
virtual void compute_nonlocal_constraint_cache (AssemblyContext &)
 
virtual void compute_damping_residual_cache (AssemblyContext &)
 
virtual void compute_mass_residual_cache (AssemblyContext &)
 
virtual void compute_nonlocal_mass_residual_cache (AssemblyContext &)
 
ICHandlingBaseget_ic_handler ()
 
- Public Member Functions inherited from GRINS::ParameterUser
 ParameterUser (const std::string &user_name)
 
virtual ~ParameterUser ()
 
virtual void set_parameter (libMesh::Number &param_variable, const GetPot &input, const std::string &param_name, libMesh::Number param_default)
 Each subclass can simultaneously read a parameter value from. More...
 
virtual void set_parameter (libMesh::ParsedFunction< libMesh::Number, libMesh::Gradient > &func, const GetPot &input, const std::string &func_param_name, const std::string &param_default)
 Each subclass can simultaneously read a parsed function from. More...
 
virtual void set_parameter (libMesh::ParsedFEMFunction< libMesh::Number > &func, const GetPot &input, const std::string &func_param_name, const std::string &param_default)
 Each subclass can simultaneously read a parsed function from. More...
 
virtual void move_parameter (const libMesh::Number &old_parameter, libMesh::Number &new_parameter)
 When cloning an object, we need to update parameter pointers. More...
 
virtual void move_parameter (const libMesh::ParsedFunction< libMesh::Number, libMesh::Gradient > &old_func, libMesh::ParsedFunction< libMesh::Number, libMesh::Gradient > &new_func)
 When cloning an object, we need to update parameter pointers. More...
 
virtual void move_parameter (const libMesh::ParsedFEMFunction< libMesh::Number > &old_func, libMesh::ParsedFEMFunction< libMesh::Number > &new_func)
 When cloning an object, we need to update parameter pointers. More...
 

Protected Member Functions

void assemble_mass_time_deriv (bool compute_jacobian, AssemblyContext &context, const CachedValues &cache)
 Helper function. More...
 
void assemble_momentum_time_deriv (bool compute_jacobian, AssemblyContext &context, const CachedValues &cache)
 Helper function. More...
 
void assemble_energy_time_deriv (bool compute_jacobian, AssemblyContext &context, const CachedValues &cache)
 Helper function. More...
 
void assemble_continuity_mass_residual (bool compute_jacobian, AssemblyContext &context)
 Helper function. More...
 
void assemble_momentum_mass_residual (bool compute_jacobian, AssemblyContext &context)
 Helper function. More...
 
void assemble_energy_mass_residual (bool compute_jacobian, AssemblyContext &context)
 Helper function. More...
 
void assemble_thermo_press_elem_time_deriv (bool compute_jacobian, AssemblyContext &context)
 
void assemble_thermo_press_side_time_deriv (bool compute_jacobian, AssemblyContext &context)
 
void assemble_thermo_press_mass_residual (bool compute_jacobian, AssemblyContext &context)
 
- Protected Member Functions inherited from GRINS::Physics
libMesh::UniquePtr< libMesh::FEGenericBase< libMesh::Real > > build_new_fe (const libMesh::Elem *elem, const libMesh::FEGenericBase< libMesh::Real > *fe, const libMesh::Point p)
 
void parse_enabled_subdomains (const GetPot &input, const std::string &physics_name)
 
void check_var_subdomain_consistency (const FEVariablesBase &var) const
 Check that var is enabled on at least the subdomains this Physics is. More...
 

Protected Attributes

bool _pin_pressure
 Enable pressure pinning. More...
 
PressurePinning _p_pinning
 
unsigned int _rho_index
 Cache index for density post-processing. More...
 
- Protected Attributes inherited from GRINS::LowMachNavierStokesBase< Viscosity, SpecificHeat, ThermalConductivity >
libMesh::Number _p0_over_R
 Thermodynamic pressure divided by gas constant. More...
 
libMesh::Number _p0
 
libMesh::Number _R
 
libMesh::Number _T0
 
VelocityVariable_flow_vars
 
PressureFEVariable_press_var
 
PrimitiveTempFEVariables_temp_vars
 
ThermoPressureVariable_p0_var
 
Viscosity _mu
 Viscosity object. More...
 
SpecificHeat _cp
 Specific heat object. More...
 
ThermalConductivity _k
 Thermal conductivity object. More...
 
libMesh::Point _g
 Gravity vector. More...
 
bool _enable_thermo_press_calc
 Flag to enable thermodynamic pressure calculation. More...
 
- Protected Attributes inherited from GRINS::Physics
const PhysicsName _physics_name
 Name of the physics object. Used for reading physics specific inputs. More...
 
GRINS::ICHandlingBase_ic_handler
 
std::set< libMesh::subdomain_id_type > _enabled_subdomains
 Subdomains on which the current Physics class is enabled. More...
 

Private Member Functions

 LowMachNavierStokes ()
 

Additional Inherited Members

- Static Public Member Functions inherited from GRINS::Physics
static void set_is_axisymmetric (bool is_axisymmetric)
 Set whether we should treat the problem as axisymmetric. More...
 
static bool is_axisymmetric ()
 
- Static Public Attributes inherited from GRINS::ParameterUser
static std::string zero_vector_function = std::string("{0}")
 A parseable function string with LIBMESH_DIM components, all 0. More...
 
- Static Protected Attributes inherited from GRINS::Physics
static bool _is_steady = false
 Caches whether or not the solver that's being used is steady or not. More...
 
static bool _is_axisymmetric = false
 Caches whether we are solving an axisymmetric problem or not. More...
 

Detailed Description

template<class Viscosity, class SpecificHeat, class ThermalConductivity>
class GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >

Physics class for Incompressible Navier-Stokes.

This physics class implements the classical Incompressible Navier-Stokes equations.

Definition at line 41 of file low_mach_navier_stokes.h.

Constructor & Destructor Documentation

template<class Mu , class SH , class TC >
GRINS::LowMachNavierStokes< Mu, SH, TC >::LowMachNavierStokes ( const PhysicsName physics_name,
const GetPot &  input 
)

Definition at line 45 of file low_mach_navier_stokes.C.

References GRINS::LowMachNavierStokesBase< Viscosity, SpecificHeat, ThermalConductivity >::_flow_vars, GRINS::Physics::_ic_handler, GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >::_pin_pressure, GRINS::MultcomponentVectorVariable::dim(), and GRINS::PhysicsNaming::low_mach_navier_stokes().

46  : LowMachNavierStokesBase<Mu,SH,TC>(physics_name,PhysicsNaming::low_mach_navier_stokes(),input),
47  _p_pinning(input,physics_name),
48  _rho_index(0) // Initialize to zero
49  {
50  this->_ic_handler = new GenericICHandler( physics_name, input );
51 
52  this->_pin_pressure = input("Physics/"+PhysicsNaming::low_mach_navier_stokes()+"/pin_pressure", false );
53 
54  if( this->_flow_vars.dim() < 2 )
55  libmesh_error_msg("ERROR: LowMachNavierStokes only valid for two or three dimensions! Make sure you have at least two components in your Velocity type variable.");
56  }
GRINS::ICHandlingBase * _ic_handler
Definition: physics.h:258
static PhysicsName low_mach_navier_stokes()
unsigned int _rho_index
Cache index for density post-processing.
bool _pin_pressure
Enable pressure pinning.
unsigned int dim() const
Number of components.
template<class Viscosity , class SpecificHeat , class ThermalConductivity >
GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >::~LowMachNavierStokes ( )
inline

Definition at line 47 of file low_mach_navier_stokes.h.

47 {};
template<class Viscosity , class SpecificHeat , class ThermalConductivity >
GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >::LowMachNavierStokes ( )
private

Member Function Documentation

template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_continuity_mass_residual ( bool  compute_jacobian,
AssemblyContext context 
)
protected

Helper function.

Definition at line 693 of file low_mach_navier_stokes.C.

695  {
696  // Element Jacobian * quadrature weights for interior integration
697  const std::vector<libMesh::Real> &JxW =
698  context.get_element_fe(this->_flow_vars.u())->get_JxW();
699 
700  // The shape functions at interior quadrature points.
701  const std::vector<std::vector<libMesh::Real> >& p_phi =
702  context.get_element_fe(this->_press_var.p())->get_phi();
703 
704  // The number of local degrees of freedom in each variable
705  const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
706 
707  // The subvectors and submatrices we need to fill:
708  libMesh::DenseSubVector<libMesh::Real> &F_p = context.get_elem_residual(this->_press_var.p());
709 
710  unsigned int n_qpoints = context.get_element_qrule().n_points();
711 
712  for (unsigned int qp = 0; qp != n_qpoints; ++qp)
713  {
714  // For the mass residual, we need to be a little careful.
715  // The time integrator is handling the time-discretization
716  // for us so we need to supply M(u_fixed)*u' for the residual.
717  // u_fixed will be given by the fixed_interior_value function
718  // while u' will be given by the interior_rate function.
719  libMesh::Real T_dot;
720  context.interior_rate(this->_temp_vars.T(), qp, T_dot);
721 
722  libMesh::Real T = context.fixed_interior_value(this->_temp_vars.T(), qp);
723 
724  for (unsigned int i = 0; i != n_p_dofs; ++i)
725  {
726  F_p(i) -= T_dot/T*p_phi[i][qp]*JxW[qp];
727  } // End DoF loop i
728 
729  } // End quadrature loop qp
730 
731  return;
732  }
VariableIndex T() const
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
VariableIndex p() const
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_energy_mass_residual ( bool  compute_jacobian,
AssemblyContext context 
)
protected

Helper function.

Definition at line 814 of file low_mach_navier_stokes.C.

816  {
817  // Element Jacobian * quadrature weights for interior integration
818  const std::vector<libMesh::Real> &JxW =
819  context.get_element_fe(this->_temp_vars.T())->get_JxW();
820 
821  // The shape functions at interior quadrature points.
822  const std::vector<std::vector<libMesh::Real> >& T_phi =
823  context.get_element_fe(this->_temp_vars.T())->get_phi();
824 
825  // The number of local degrees of freedom in each variable
826  const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
827 
828  // The subvectors and submatrices we need to fill:
829  libMesh::DenseSubVector<libMesh::Real> &F_T = context.get_elem_residual(this->_temp_vars.T());
830 
831  unsigned int n_qpoints = context.get_element_qrule().n_points();
832 
833  for (unsigned int qp = 0; qp != n_qpoints; ++qp)
834  {
835  // For the mass residual, we need to be a little careful.
836  // The time integrator is handling the time-discretization
837  // for us so we need to supply M(u_fixed)*u' for the residual.
838  // u_fixed will be given by the fixed_interior_value function
839  // while u will be given by the interior_rate function.
840  libMesh::Real T_dot;
841  context.interior_rate(this->_temp_vars.T(), qp, T_dot);
842 
843  libMesh::Real T = context.fixed_interior_value(this->_temp_vars.T(), qp);
844 
845  libMesh::Real cp = this->_cp(T);
846 
847  libMesh::Number rho = this->rho(T, this->get_p0_transient(context, qp));
848 
849  for (unsigned int i = 0; i != n_T_dofs; ++i)
850  {
851  F_T(i) -= rho*cp*T_dot*T_phi[i][qp]*JxW[qp];
852  } // End DoF loop i
853 
854  } // End quadrature loop qp
855 
856  return;
857  }
VariableIndex T() const
SpecificHeat _cp
Specific heat object.
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
libMesh::Real get_p0_transient(AssemblyContext &c, unsigned int qp) const
libMesh::Real rho(libMesh::Real T, libMesh::Real p0) const
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_energy_time_deriv ( bool  compute_jacobian,
AssemblyContext context,
const CachedValues cache 
)
protected

Helper function.

Definition at line 581 of file low_mach_navier_stokes.C.

References GRINS::CachedValues::get_cached_gradient_values(), GRINS::CachedValues::get_cached_values(), GRINS::Cache::TEMPERATURE, GRINS::Cache::TEMPERATURE_GRAD, GRINS::Cache::THERMO_PRESSURE, GRINS::Cache::X_VELOCITY, GRINS::Cache::Y_VELOCITY, and GRINS::Cache::Z_VELOCITY.

584  {
585  // The number of local degrees of freedom in each variable.
586  const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
587  const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
588 
589  // Element Jacobian * quadrature weights for interior integration.
590  const std::vector<libMesh::Real> &JxW =
591  context.get_element_fe(this->_temp_vars.T())->get_JxW();
592 
593  // The temperature shape functions at interior quadrature points.
594  const std::vector<std::vector<libMesh::Real> >& T_phi =
595  context.get_element_fe(this->_temp_vars.T())->get_phi();
596  const std::vector<std::vector<libMesh::Real> >& u_phi =
597  context.get_element_fe(this->_flow_vars.u())->get_phi();
598 
599  // The temperature shape functions gradients at interior quadrature points.
600  const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
601  context.get_element_fe(this->_temp_vars.T())->get_dphi();
602 
603  libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_temp_vars.T()); // R_{T}
604 
605  unsigned int n_qpoints = context.get_element_qrule().n_points();
606  for (unsigned int qp=0; qp != n_qpoints; qp++)
607  {
608  libMesh::Number u, v, T, p0;
609  u = cache.get_cached_values(Cache::X_VELOCITY)[qp];
610  v = cache.get_cached_values(Cache::Y_VELOCITY)[qp];
611  T = cache.get_cached_values(Cache::TEMPERATURE)[qp];
612  p0 = cache.get_cached_values(Cache::THERMO_PRESSURE)[qp];
613 
614  libMesh::Gradient grad_T = cache.get_cached_gradient_values(Cache::TEMPERATURE_GRAD)[qp];
615 
616  libMesh::NumberVectorValue U(u,v);
617  if (this->_flow_vars.dim() == 3)
618  U(2) = cache.get_cached_values(Cache::Z_VELOCITY)[qp]; // w
619 
620  libMesh::DenseSubMatrix<libMesh::Number> &KTu = context.get_elem_jacobian(this->_temp_vars.T(), this->_flow_vars.u()); // R_{u},{u}
621  libMesh::DenseSubMatrix<libMesh::Number> &KTv = context.get_elem_jacobian(this->_temp_vars.T(), this->_flow_vars.v()); // R_{u},{u}
622  libMesh::DenseSubMatrix<libMesh::Number>* KTw = NULL;
623 
624  libMesh::DenseSubMatrix<libMesh::Number> &KTT = context.get_elem_jacobian(this->_temp_vars.T(), this->_temp_vars.T()); // R_{u},{u}
625 
626  if( this->_flow_vars.dim() == 3 )
627  {
628  KTw = &context.get_elem_jacobian(this->_temp_vars.T(), this->_flow_vars.w()); // R_{u},{w}
629  }
630 
631  libMesh::Number k = this->_k(T);
632  libMesh::Number dk_dT = this->_k.deriv(T);
633  libMesh::Number cp = this->_cp(T);
634  libMesh::Number d_cp = this->_cp.deriv(T);
635  libMesh::Number rho = this->rho( T, p0 );
636  libMesh::Number d_rho = this->d_rho_dT( T, p0 );
637 
638  // Now a loop over the pressure degrees of freedom. This
639  // computes the contributions of the continuity equation.
640  for (unsigned int i=0; i != n_T_dofs; i++)
641  {
642  FT(i) += ( -rho*cp*U*grad_T*T_phi[i][qp] // convection term
643  - k*grad_T*T_gradphi[i][qp] // diffusion term
644  )*JxW[qp];
645 
646 
647  if(compute_jacobian)
648  {
649  for (unsigned int j=0; j!=n_u_dofs; j++)
650  {
651  //pre-compute repeated term
652  libMesh::Number r0 = rho*cp*T_phi[i][qp]*u_phi[j][qp];
653 
654  KTu(i,j) += JxW[qp]*
655  -r0*grad_T(0);
656  //-rho*cp*u_phi[j][qp]*grad_T(0)*T_phi[i][qp];
657 
658  KTv(i,j) += JxW[qp]*
659  -r0*grad_T(1);
660  //-rho*cp*u_phi[j][qp]*grad_T(1)*T_phi[i][qp];
661 
662  if (this->_flow_vars.dim() == 3)
663  {
664  (*KTw)(i,j) += JxW[qp]*
665  -r0*grad_T(2);
666  //-rho*cp*u_phi[j][qp]*grad_T(2)*T_phi[i][qp];
667  }
668 
669  } // end u_dofs loop (j)
670 
671 
672  for (unsigned int j=0; j!=n_T_dofs; j++)
673  {
674  KTT(i,j) += JxW[qp]* (
675  -rho*(
676  cp*U*T_phi[i][qp]*T_gradphi[j][qp]
677  + U*grad_T*T_phi[i][qp]*d_cp*T_phi[j][qp]
678  )
679  -cp*U*grad_T*T_phi[i][qp]*d_rho*T_phi[j][qp]
680  -k*T_gradphi[i][qp]*T_gradphi[j][qp]
681  -grad_T*T_gradphi[i][qp]*dk_dT*T_phi[j][qp]
682  );
683  } // end T_dofs loop (j)
684 
685  } // end if compute_jacobian
686  } // end outer T_dofs loop (i)
687  } //end qp loop
688 
689  return;
690  }
VariableIndex T() const
SpecificHeat _cp
Specific heat object.
ThermalConductivity _k
Thermal conductivity object.
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
libMesh::Real d_rho_dT(libMesh::Real T, libMesh::Real p0) const
unsigned int dim() const
Number of components.
libMesh::Real rho(libMesh::Real T, libMesh::Real p0) const
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_mass_time_deriv ( bool  compute_jacobian,
AssemblyContext context,
const CachedValues cache 
)
protected

Helper function.

Definition at line 152 of file low_mach_navier_stokes.C.

References GRINS::CachedValues::get_cached_gradient_values(), GRINS::CachedValues::get_cached_values(), GRINS::Cache::TEMPERATURE, GRINS::Cache::TEMPERATURE_GRAD, GRINS::Cache::X_VELOCITY, GRINS::Cache::X_VELOCITY_GRAD, GRINS::Cache::Y_VELOCITY, GRINS::Cache::Y_VELOCITY_GRAD, GRINS::Cache::Z_VELOCITY, and GRINS::Cache::Z_VELOCITY_GRAD.

155  {
156  // The number of local degrees of freedom in each variable.
157  const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
158 
159  // Element Jacobian * quadrature weights for interior integration.
160  const std::vector<libMesh::Real> &JxW =
161  context.get_element_fe(this->_flow_vars.u())->get_JxW();
162 
163  // The pressure shape functions at interior quadrature points.
164  const std::vector<std::vector<libMesh::Real> >& p_phi =
165  context.get_element_fe(this->_press_var.p())->get_phi();
166 
167 
168 
169  // The velocity shape functions at interior quadrature points.
170  const std::vector<std::vector<libMesh::Real> >& u_phi =
171  context.get_element_fe(this->_flow_vars.u())->get_phi();
172 
173  // The velocity shape function gradients (in global coords.)
174  // at interior quadrature points.
175  const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
176  context.get_element_fe(this->_flow_vars.u())->get_dphi();
177 
178  // The temperature shape functions at interior quadrature points.
179  const std::vector<std::vector<libMesh::Real> >& T_phi =
180  context.get_element_fe(this->_temp_vars.T())->get_phi();
181 
182  // The temperature shape function gradients (in global coords.)
183  // at interior quadrature points.
184  const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi =
185  context.get_element_fe(this->_temp_vars.T())->get_dphi();
186 
187 
188 
189  libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p()); // R_{p}
190 
191  unsigned int n_qpoints = context.get_element_qrule().n_points();
192 
193  // The number of local degrees of freedom in each variable.
194  const unsigned int n_t_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
195 
196  // The number of local degrees of freedom in each variable.
197  const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
198 
199  // Check number of dofs is same for _flow_vars.u(), v_var and w_var.
200  libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
201 
202  if (this->_flow_vars.dim() == 3)
203  libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
204 
205  for (unsigned int qp=0; qp != n_qpoints; qp++)
206  {
207  libMesh::Number u, v, T;
208  u = cache.get_cached_values(Cache::X_VELOCITY)[qp];
209  v = cache.get_cached_values(Cache::Y_VELOCITY)[qp];
210 
211  T = cache.get_cached_values(Cache::TEMPERATURE)[qp];
212 
213  libMesh::Gradient grad_u = cache.get_cached_gradient_values(Cache::X_VELOCITY_GRAD)[qp];
214  libMesh::Gradient grad_v = cache.get_cached_gradient_values(Cache::Y_VELOCITY_GRAD)[qp];
215 
216  libMesh::Gradient grad_T = cache.get_cached_gradient_values(Cache::TEMPERATURE_GRAD)[qp];
217 
218  libMesh::NumberVectorValue U(u,v);
219  if (this->_flow_vars.dim() == 3)
220  U(2) = cache.get_cached_values(Cache::Z_VELOCITY)[qp]; // w
221 
222  libMesh::Number divU = grad_u(0) + grad_v(1);
223  if (this->_flow_vars.dim() == 3)
224  {
225  libMesh::Gradient grad_w = cache.get_cached_gradient_values(Cache::Z_VELOCITY_GRAD)[qp];
226  divU += grad_w(2);
227  }
228 
229 
230  libMesh::DenseSubMatrix<libMesh::Number> &KPu = context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.u());
231  libMesh::DenseSubMatrix<libMesh::Number> &KPv = context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.v());
232  libMesh::DenseSubMatrix<libMesh::Number> &KPT = context.get_elem_jacobian(this->_press_var.p(), this->_temp_vars.T());
233 
234  libMesh::DenseSubMatrix<libMesh::Number>* KPw = NULL;
235 
236  if( this->_flow_vars.dim() == 3 )
237  {
238  KPw = &context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.w());
239  }
240 
241  // Now a loop over the pressure degrees of freedom. This
242  // computes the contributions of the continuity equation.
243  for (unsigned int i=0; i != n_p_dofs; i++)
244  {
245  Fp(i) += (-U*grad_T/T + divU)*p_phi[i][qp]*JxW[qp];
246 
247 
248  if (compute_jacobian)
249  {
250 
251  for (unsigned int j=0; j!=n_u_dofs; j++)
252  {
253  KPu(i,j) += JxW[qp]*(
254  +u_gradphi[j][qp](0)*p_phi[i][qp]
255  -u_phi[j][qp]*p_phi[i][qp]*grad_T(0)/T
256  );
257 
258  KPv(i,j) += JxW[qp]*(
259  +u_gradphi[j][qp](1)*p_phi[i][qp]
260  -u_phi[j][qp]*p_phi[i][qp]*grad_T(1)/T
261  );
262 
263  if (this->_flow_vars.dim() == 3)
264  {
265  (*KPw)(i,j) += JxW[qp]*(
266  +u_gradphi[j][qp](2)*p_phi[i][qp]
267  -u_phi[j][qp]*p_phi[i][qp]*grad_T(2)/T
268  );
269  }
270 
271  }
272 
273  for (unsigned int j=0; j!=n_t_dofs; j++)
274  {
275  KPT(i,j) += JxW[qp]*(
276  -T_gradphi[j][qp]*U*p_phi[i][qp]/T
277  +U*p_phi[i][qp]*grad_T*T_phi[j][qp])/(T*T);
278  }
279  } // end if compute_jacobian
280  } // end p_dofs loop
281  } // end qp loop
282 
283  return;
284  }
VariableIndex T() const
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
VariableIndex p() const
unsigned int dim() const
Number of components.
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_momentum_mass_residual ( bool  compute_jacobian,
AssemblyContext context 
)
protected

Helper function.

Definition at line 735 of file low_mach_navier_stokes.C.

737  {
738  // Element Jacobian * quadrature weights for interior integration
739  const std::vector<libMesh::Real> &JxW =
740  context.get_element_fe(this->_flow_vars.u())->get_JxW();
741 
742  // The shape functions at interior quadrature points.
743  const std::vector<std::vector<libMesh::Real> >& u_phi =
744  context.get_element_fe(this->_flow_vars.u())->get_phi();
745 
746  // The number of local degrees of freedom in each variable
747  const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
748 
749  // The subvectors and submatrices we need to fill:
750  libMesh::DenseSubVector<libMesh::Real> &F_u = context.get_elem_residual(this->_flow_vars.u());
751  libMesh::DenseSubVector<libMesh::Real> &F_v = context.get_elem_residual(this->_flow_vars.v());
752  libMesh::DenseSubVector<libMesh::Real>* F_w = NULL;
753 
754 
755  if( this->_flow_vars.dim() == 3 )
756  F_w = &context.get_elem_residual(this->_flow_vars.w()); // R_{w}
757 
758  unsigned int n_qpoints = context.get_element_qrule().n_points();
759 
760  for (unsigned int qp = 0; qp != n_qpoints; ++qp)
761  {
762  // For the mass residual, we need to be a little careful.
763  // The time integrator is handling the time-discretization
764  // for us so we need to supply M(u_fixed)*u' for the residual.
765  // u_fixed will be given by the fixed_interior_value function
766  // while u' will be given by the interior_rate function.
767  libMesh::Real u_dot, v_dot, w_dot = 0.0;
768  context.interior_rate(this->_flow_vars.u(), qp, u_dot);
769  context.interior_rate(this->_flow_vars.v(), qp, v_dot);
770 
771  if( this->_flow_vars.dim() == 3 )
772  context.interior_rate(this->_flow_vars.w(), qp, w_dot);
773 
774  libMesh::Real T = context.fixed_interior_value(this->_temp_vars.T(), qp);
775 
776  libMesh::Number rho = this->rho(T, this->get_p0_transient(context, qp));
777 
778  for (unsigned int i = 0; i != n_u_dofs; ++i)
779  {
780  F_u(i) -= rho*u_dot*u_phi[i][qp]*JxW[qp];
781  F_v(i) -= rho*v_dot*u_phi[i][qp]*JxW[qp];
782 
783  if( this->_flow_vars.dim() == 3 )
784  (*F_w)(i) -= rho*w_dot*u_phi[i][qp]*JxW[qp];
785 
786  /*
787  if( compute_jacobian )
788  {
789  for (unsigned int j=0; j != n_u_dofs; j++)
790  {
791  // Assuming rho is constant w.r.t. u, v, w
792  // and T (if Boussinesq added).
793  libMesh::Real value = JxW[qp]*_rho*u_phi[i][qp]*u_phi[j][qp];
794 
795  M_uu(i,j) += value;
796  M_vv(i,j) += value;
797 
798  if( _dim == 3)
799  {
800  M_ww(i,j) += value;
801  }
802 
803  } // End DoF loop j
804  } // End Jacobian check
805  */
806 
807  } // End DoF loop i
808  } // End quadrature loop qp
809 
810  return;
811  }
VariableIndex T() const
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
libMesh::Real get_p0_transient(AssemblyContext &c, unsigned int qp) const
unsigned int dim() const
Number of components.
libMesh::Real rho(libMesh::Real T, libMesh::Real p0) const
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_momentum_time_deriv ( bool  compute_jacobian,
AssemblyContext context,
const CachedValues cache 
)
protected

Helper function.

Definition at line 287 of file low_mach_navier_stokes.C.

References GRINS::CachedValues::get_cached_gradient_values(), GRINS::CachedValues::get_cached_values(), GRINS::Cache::PRESSURE, GRINS::Cache::TEMPERATURE, GRINS::Cache::THERMO_PRESSURE, GRINS::Cache::X_VELOCITY, GRINS::Cache::X_VELOCITY_GRAD, GRINS::Cache::Y_VELOCITY, GRINS::Cache::Y_VELOCITY_GRAD, GRINS::Cache::Z_VELOCITY, and GRINS::Cache::Z_VELOCITY_GRAD.

290  {
291  // The number of local degrees of freedom in each variable.
292  const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
293  const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
294  const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
295 
296  // Check number of dofs is same for _flow_vars.u(), v_var and w_var.
297  libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
298 
299  if (this->_flow_vars.dim() == 3)
300  libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
301 
302  // Element Jacobian * quadrature weights for interior integration.
303  const std::vector<libMesh::Real> &JxW =
304  context.get_element_fe(this->_flow_vars.u())->get_JxW();
305 
306  // The pressure shape functions at interior quadrature points.
307  const std::vector<std::vector<libMesh::Real> >& u_phi =
308  context.get_element_fe(this->_flow_vars.u())->get_phi();
309  const std::vector<std::vector<libMesh::Real> >& p_phi =
310  context.get_element_fe(this->_press_var.p())->get_phi();
311  const std::vector<std::vector<libMesh::Real> >& T_phi =
312  context.get_element_fe(this->_temp_vars.T())->get_phi();
313 
314  // The velocity shape function gradients at interior quadrature points.
315  const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
316  context.get_element_fe(this->_flow_vars.u())->get_dphi();
317 
318  libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u()); // R_{u}
319  libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v()); // R_{v}
320  libMesh::DenseSubVector<libMesh::Real>* Fw = NULL;
321 
322  if( this->_flow_vars.dim() == 3 )
323  {
324  Fw = &context.get_elem_residual(this->_flow_vars.w()); // R_{w}
325  }
326 
327  unsigned int n_qpoints = context.get_element_qrule().n_points();
328  for (unsigned int qp=0; qp != n_qpoints; qp++)
329  {
330  libMesh::Number u, v, p, p0, T;
331  u = cache.get_cached_values(Cache::X_VELOCITY)[qp];
332  v = cache.get_cached_values(Cache::Y_VELOCITY)[qp];
333 
334  T = cache.get_cached_values(Cache::TEMPERATURE)[qp];
335  p = cache.get_cached_values(Cache::PRESSURE)[qp];
336  p0 = cache.get_cached_values(Cache::THERMO_PRESSURE)[qp];
337 
338  libMesh::Gradient grad_u = cache.get_cached_gradient_values(Cache::X_VELOCITY_GRAD)[qp];
339  libMesh::Gradient grad_v = cache.get_cached_gradient_values(Cache::Y_VELOCITY_GRAD)[qp];
340 
341  libMesh::Gradient grad_w;
342  if (this->_flow_vars.dim() == 3)
343  grad_w = cache.get_cached_gradient_values(Cache::Z_VELOCITY_GRAD)[qp];
344 
345  libMesh::NumberVectorValue grad_uT( grad_u(0), grad_v(0) );
346  libMesh::NumberVectorValue grad_vT( grad_u(1), grad_v(1) );
347  libMesh::NumberVectorValue grad_wT;
348  if( this->_flow_vars.dim() == 3 )
349  {
350  grad_uT(2) = grad_w(0);
351  grad_vT(2) = grad_w(1);
352  grad_wT = libMesh::NumberVectorValue( grad_u(2), grad_v(2), grad_w(2) );
353  }
354 
355  libMesh::NumberVectorValue U(u,v);
356  if (this->_flow_vars.dim() == 3)
357  U(2) = cache.get_cached_values(Cache::Z_VELOCITY)[qp]; // w
358 
359  libMesh::Number divU = grad_u(0) + grad_v(1);
360  if (this->_flow_vars.dim() == 3)
361  divU += grad_w(2);
362 
363  libMesh::Number rho = this->rho( T, p0 );
364  libMesh::Number d_rho = this->d_rho_dT( T, p0 );
365  libMesh::Number d_mu = this->_mu.deriv(T);
366 
367  libMesh::DenseSubMatrix<libMesh::Number> &Kuu = context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.u()); // R_{u},{u}
368  libMesh::DenseSubMatrix<libMesh::Number> &Kuv = context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.v()); // R_{u},{v}
369  libMesh::DenseSubMatrix<libMesh::Number>* Kuw = NULL;
370 
371  libMesh::DenseSubMatrix<libMesh::Number> &Kvu = context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.u()); // R_{v},{u}
372  libMesh::DenseSubMatrix<libMesh::Number> &Kvv = context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.v()); // R_{v},{v}
373  libMesh::DenseSubMatrix<libMesh::Number>* Kvw = NULL;
374 
375  libMesh::DenseSubMatrix<libMesh::Number>* Kwu = NULL;
376  libMesh::DenseSubMatrix<libMesh::Number>* Kwv = NULL;
377  libMesh::DenseSubMatrix<libMesh::Number>* Kww = NULL;
378 
379  libMesh::DenseSubMatrix<libMesh::Number> &Kup = context.get_elem_jacobian(this->_flow_vars.u(), this->_press_var.p()); // R_{u},{p}
380  libMesh::DenseSubMatrix<libMesh::Number> &Kvp = context.get_elem_jacobian(this->_flow_vars.v(), this->_press_var.p()); // R_{v},{p}
381  libMesh::DenseSubMatrix<libMesh::Number>* Kwp = NULL;
382 
383  libMesh::DenseSubMatrix<libMesh::Number> &KuT = context.get_elem_jacobian(this->_flow_vars.u(), this->_temp_vars.T()); // R_{u},{p}
384  libMesh::DenseSubMatrix<libMesh::Number> &KvT = context.get_elem_jacobian(this->_flow_vars.v(), this->_temp_vars.T()); // R_{v},{p}
385  libMesh::DenseSubMatrix<libMesh::Number>* KwT = NULL;
386 
387  if( this->_flow_vars.dim() == 3 )
388  {
389  Kuw = &context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.w()); // R_{u},{w}
390  Kvw = &context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.w()); // R_{v},{w}
391  Kwu = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.u()); // R_{w},{u};
392  Kwv = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.v()); // R_{w},{v};
393  Kww = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.w()); // R_{w},{w}
394  Kwp = &context.get_elem_jacobian(this->_flow_vars.w(), this->_press_var.p()); // R_{w},{p}
395  KwT = &context.get_elem_jacobian(this->_flow_vars.w(), this->_temp_vars.T()); // R_{w},{T}
396  }
397 
398  // Now a loop over the pressure degrees of freedom. This
399  // computes the contributions of the continuity equation.
400  for (unsigned int i=0; i != n_u_dofs; i++)
401  {
402  Fu(i) += ( -rho*U*grad_u*u_phi[i][qp] // convection term
403  + p*u_gradphi[i][qp](0) // pressure term
404  - this->_mu(T)*(u_gradphi[i][qp]*grad_u + u_gradphi[i][qp]*grad_uT
405  - 2.0/3.0*divU*u_gradphi[i][qp](0) ) // diffusion term
406  + rho*this->_g(0)*u_phi[i][qp] // hydrostatic term
407  )*JxW[qp];
408 
409  Fv(i) += ( -rho*U*grad_v*u_phi[i][qp] // convection term
410  + p*u_gradphi[i][qp](1) // pressure term
411  - this->_mu(T)*(u_gradphi[i][qp]*grad_v + u_gradphi[i][qp]*grad_vT
412  - 2.0/3.0*divU*u_gradphi[i][qp](1) ) // diffusion term
413  + rho*this->_g(1)*u_phi[i][qp] // hydrostatic term
414  )*JxW[qp];
415  if (this->_flow_vars.dim() == 3)
416  {
417  (*Fw)(i) += ( -rho*U*grad_w*u_phi[i][qp] // convection term
418  + p*u_gradphi[i][qp](2) // pressure term
419  - this->_mu(T)*(u_gradphi[i][qp]*grad_w + u_gradphi[i][qp]*grad_wT
420  - 2.0/3.0*divU*u_gradphi[i][qp](2) ) // diffusion term
421  + rho*this->_g(2)*u_phi[i][qp] // hydrostatic term
422  )*JxW[qp];
423  }
424 
425  if (compute_jacobian && context.get_elem_solution_derivative())
426  {
427  libmesh_assert (context.get_elem_solution_derivative() == 1.0);
428 
429  for (unsigned int j=0; j != n_u_dofs; j++)
430  {
431  //precompute repeated terms
432  libMesh::Number r0 = rho*U*u_phi[i][qp]*u_gradphi[j][qp];
433  libMesh::Number r1 = u_gradphi[i][qp]*u_gradphi[j][qp];
434  libMesh::Number r2 = rho*u_phi[i][qp]*u_phi[j][qp];
435 
436 
437  Kuu(i,j) += JxW[qp]*(
438  -r0
439  //-rho*U*u_gradphi[j][qp]*u_phi[i][qp]
440  -r2*grad_u(0)
441  //-rho*u_phi[i][qp]*grad_u(0)*u_phi[j][qp]
442  -this->_mu(T)*(
443  r1
444  //u_gradphi[i][qp]*u_gradphi[j][qp]
445  + u_gradphi[i][qp](0)*u_gradphi[j][qp](0) // transpose
446  - 2.0/3.0*u_gradphi[i][qp](0)*u_gradphi[j][qp](0)
447  ));
448  Kvv(i,j) += JxW[qp]*(
449  -r0
450  //-rho*U*u_gradphi[j][qp]*u_phi[i][qp]
451  -r2*grad_v(1)
452  //-rho*u_phi[i][qp]*grad_v(1)*u_phi[j][qp]
453  -this->_mu(T)*(
454  r1
455  //u_gradphi[i][qp]*u_gradphi[j][qp]
456  + u_gradphi[i][qp](1)*u_gradphi[j][qp](1) // transpose
457  - 2.0/3.0*u_gradphi[i][qp](1)*u_gradphi[j][qp](1)
458  ));
459 
460  Kuv(i,j) += JxW[qp]*(
461  +2.0/3.0*this->_mu(T)*u_gradphi[i][qp](0)*u_gradphi[j][qp](1)
462  -this->_mu(T)*u_gradphi[i][qp](1)*u_gradphi[j][qp](0)
463  -r2*grad_u(1)
464  //-rho*u_phi[i][qp]*u_phi[j][qp]*grad_u(1));
465  );
466 
467  Kvu(i,j) += JxW[qp]*(
468  +2.0/3.0*this->_mu(T)*u_gradphi[i][qp](1)*u_gradphi[j][qp](0)
469  -this->_mu(T)*u_gradphi[i][qp](0)*u_gradphi[j][qp](1)
470  -r2*grad_v(0)
471  //-rho*u_phi[i][qp]*u_phi[j][qp]*grad_v(0));
472  );
473 
474 
475 
476  if (this->_flow_vars.dim() == 3)
477  {
478  (*Kuw)(i,j) += JxW[qp]*(
479  +2.0/3.0*this->_mu(T)*u_gradphi[i][qp](0)*u_gradphi[j][qp](2)
480  -this->_mu(T)*u_gradphi[i][qp](2)*u_gradphi[j][qp](0)
481  -r2*grad_u(2)
482  //-rho*u_phi[i][qp]*u_phi[j][qp]*grad_u(2)
483  );
484 
485  (*Kvw)(i,j) += JxW[qp]*(
486  +2.0/3.0*this->_mu(T)*u_gradphi[i][qp](1)*u_gradphi[j][qp](2)
487  -this->_mu(T)*u_gradphi[i][qp](2)*u_gradphi[j][qp](1)
488  -r2*grad_v(2)
489  //-rho*u_phi[i][qp]*u_phi[j][qp]*grad_v(2)
490  );
491 
492  (*Kwu)(i,j) += JxW[qp]*(
493  +2.0/3.0*this->_mu(T)*u_gradphi[i][qp](2)*u_gradphi[j][qp](0)
494  -this->_mu(T)*u_gradphi[i][qp](0)*u_gradphi[j][qp](2)
495  -r2*grad_w(0)
496  //-rho*u_phi[i][qp]*u_phi[j][qp]*grad_w(0)
497  );
498 
499  (*Kwv)(i,j) += JxW[qp]*(
500  +2.0/3.0*this->_mu(T)*u_gradphi[i][qp](2)*u_gradphi[j][qp](1)
501  -this->_mu(T)*u_gradphi[i][qp](1)*u_gradphi[j][qp](2)
502  -r2*grad_w(1)
503  //-rho*u_phi[i][qp]*u_phi[j][qp]*grad_w(1)
504  );
505 
506  (*Kww)(i,j) += JxW[qp]*(
507  -r0
508  //-rho*U*u_gradphi[j][qp]*u_phi[i][qp]
509  -r2*grad_w(2)
510  //-rho*u_phi[i][qp]*grad_w(2)*u_phi[j][qp]
511  -this->_mu(T)*(
512  r1
513  //u_gradphi[i][qp]*u_gradphi[j][qp]
514  + u_gradphi[i][qp](2)*u_gradphi[j][qp](2) // transpose
515  - 2.0/3.0*u_gradphi[i][qp](2)*u_gradphi[j][qp](2)
516  ));
517 
518  } // end if _dim==3
519  } // end of the inner dof (j) loop
520 
521  for (unsigned int j=0; j!=n_T_dofs; j++)
522  {
523 
524  //precompute repeated term
525  libMesh:: Number r3 = d_rho*u_phi[i][qp]*T_phi[j][qp];
526 
527  // Analytical Jacobains
528  KuT(i,j) += JxW[qp]*(
529  -r3*U*grad_u
530  //-d_rho*T_phi[j][qp]*U*grad_u*u_phi[i][qp]
531  -d_mu*T_phi[j][qp]*grad_u*u_gradphi[i][qp]
532  -d_mu*T_phi[j][qp]*grad_u(0)*u_gradphi[i][qp](0) // transpose
533  +2.0/3.0*d_mu*T_phi[j][qp]*divU*u_gradphi[i][qp](0)
534  +r3*this->_g(0)
535  //+d_rho*T_phi[j][qp]*this->_g(0)*u_phi[i][qp]
536  );
537 
538  KvT(i,j) += JxW[qp]*(
539  -r3*U*grad_v
540  //-d_rho*T_phi[j][qp]*U*grad_v*u_phi[i][qp]
541  -d_mu*T_phi[j][qp]*grad_v*u_gradphi[i][qp]
542  -d_mu*T_phi[j][qp]*grad_v(1)*u_gradphi[i][qp](1) // transpose
543  +2.0/3.0*d_mu*T_phi[j][qp]*divU*u_gradphi[i][qp](1)
544  +r3*this->_g(1)
545  //+d_rho*T_phi[j][qp]*this->_g(1)*u_phi[i][qp]
546  );
547 
548  if (this->_flow_vars.dim() == 3)
549  {
550  (*KwT)(i,j) += JxW[qp]*(
551  -r3*U*grad_w
552  //-d_rho*T_phi[j][qp]*U*grad_v*u_phi[i][qp]
553  -d_mu*T_phi[j][qp]*grad_w*u_gradphi[i][qp]
554  -d_mu*T_phi[j][qp]*grad_w(2)*u_gradphi[i][qp](2) // transpose
555  +2.0/3.0*d_mu*T_phi[j][qp]*divU*u_gradphi[i][qp](2)
556  +r3*this->_g(2)
557  //+d_rho*T_phi[j][qp]*this->_g(2)*u_phi[i][qp]
558  );
559 
560  } // end if _dim==3
561  } // end T_dofs loop
562 
563  // Matrix contributions for the up, vp and wp couplings
564  for (unsigned int j=0; j != n_p_dofs; j++)
565  {
566  Kup(i,j) += JxW[qp]*p_phi[j][qp]*u_gradphi[i][qp](0);
567  Kvp(i,j) += JxW[qp]*p_phi[j][qp]*u_gradphi[i][qp](1);
568  if (this->_flow_vars.dim() == 3)
569  (*Kwp)(i,j) += JxW[qp]*p_phi[j][qp]*u_gradphi[i][qp](2);
570  } // end of the inner dof (j) loop
571 
572  } // end - if (compute_jacobian && context.get_elem_solution_derivative())
573 
574  } // end of the outer dof (i) loop
575  } // end of the quadrature point (qp) loop
576 
577  return;
578  }
VariableIndex T() const
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
VariableIndex p() const
libMesh::Point _g
Gravity vector.
libMesh::Real d_rho_dT(libMesh::Real T, libMesh::Real p0) const
unsigned int dim() const
Number of components.
libMesh::Real rho(libMesh::Real T, libMesh::Real p0) const
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_thermo_press_elem_time_deriv ( bool  compute_jacobian,
AssemblyContext context 
)
protected

Definition at line 860 of file low_mach_navier_stokes.C.

862  {
863  // Element Jacobian * quadrature weights for interior integration
864  const std::vector<libMesh::Real> &JxW =
865  context.get_element_fe(this->_temp_vars.T())->get_JxW();
866 
867  // The number of local degrees of freedom in each variable
868  const unsigned int n_p0_dofs = context.get_dof_indices(this->_p0_var->p0()).size();
869 
870  // The subvectors and submatrices we need to fill:
871  libMesh::DenseSubVector<libMesh::Real> &F_p0 = context.get_elem_residual(this->_p0_var->p0());
872 
873  unsigned int n_qpoints = context.get_element_qrule().n_points();
874 
875  for (unsigned int qp = 0; qp != n_qpoints; ++qp)
876  {
877  libMesh::Number T;
878  T = context.interior_value(this->_temp_vars.T(), qp);
879 
880  libMesh::Gradient grad_u, grad_v, grad_w;
881  grad_u = context.interior_gradient(this->_flow_vars.u(), qp);
882  grad_v = context.interior_gradient(this->_flow_vars.v(), qp);
883  if (this->_flow_vars.dim() == 3)
884  grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
885 
886  libMesh::Number divU = grad_u(0) + grad_v(1);
887  if(this->_flow_vars.dim()==3)
888  divU += grad_w(2);
889 
890  //libMesh::Number cp = this->_cp(T);
891  //libMesh::Number cv = cp + this->_R;
892  //libMesh::Number gamma = cp/cv;
893  //libMesh::Number gamma_ratio = gamma/(gamma-1.0);
894 
895  libMesh::Number p0 = context.interior_value( this->_p0_var->p0(), qp );
896 
897  for (unsigned int i = 0; i != n_p0_dofs; ++i)
898  {
899  F_p0(i) += (p0/T - this->_p0/this->_T0)*JxW[qp];
900  //F_p0(i) -= p0*gamma_ratio*divU*JxW[qp];
901  } // End DoF loop i
902  }
903 
904  return;
905  }
VariableIndex T() const
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
VariableIndex p0() const
unsigned int dim() const
Number of components.
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_thermo_press_mass_residual ( bool  compute_jacobian,
AssemblyContext context 
)
protected

Definition at line 958 of file low_mach_navier_stokes.C.

960  {
961  // The number of local degrees of freedom in each variable.
962  const unsigned int n_p0_dofs = context.get_dof_indices(this->_p0_var->p0()).size();
963  const unsigned int n_T_dofs = context.get_dof_indices(this->_temp_vars.T()).size();
964  const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
965 
966  // Element Jacobian * quadrature weights for interior integration
967  const std::vector<libMesh::Real> &JxW =
968  context.get_element_fe(this->_temp_vars.T())->get_JxW();
969 
970  // The temperature shape functions at interior quadrature points.
971  const std::vector<std::vector<libMesh::Real> >& T_phi =
972  context.get_element_fe(this->_temp_vars.T())->get_phi();
973 
974  // The temperature shape functions at interior quadrature points.
975  const std::vector<std::vector<libMesh::Real> >& p_phi =
976  context.get_element_fe(this->_press_var.p())->get_phi();
977 
978  // The subvectors and submatrices we need to fill:
979  libMesh::DenseSubVector<libMesh::Real> &F_p0 = context.get_elem_residual(this->_p0_var->p0());
980  libMesh::DenseSubVector<libMesh::Real> &F_T = context.get_elem_residual(this->_temp_vars.T());
981  libMesh::DenseSubVector<libMesh::Real> &F_p = context.get_elem_residual(this->_press_var.p());
982 
983  unsigned int n_qpoints = context.get_element_qrule().n_points();
984 
985  for (unsigned int qp = 0; qp != n_qpoints; ++qp)
986  {
987  libMesh::Number T;
988  T = context.fixed_interior_value(this->_temp_vars.T(), qp);
989 
990  libMesh::Number cp = this->_cp(T);
991  libMesh::Number cv = cp + this->_R;
992  libMesh::Number gamma = cp/cv;
993  libMesh::Number one_over_gamma = 1.0/(gamma-1.0);
994 
995  libMesh::Number p0_dot;
996  context.interior_rate(this->_p0_var->p0(), qp, p0_dot);
997 
998  libMesh::Number p0 = context.fixed_interior_value(this->_p0_var->p0(), qp );
999 
1000  for (unsigned int i=0; i != n_p0_dofs; i++)
1001  {
1002  F_p0(i) -= p0_dot*one_over_gamma*JxW[qp];
1003  }
1004 
1005  for (unsigned int i=0; i != n_T_dofs; i++)
1006  {
1007  F_T(i) += p0_dot*T_phi[i][qp]*JxW[qp];
1008  }
1009 
1010  for (unsigned int i=0; i != n_p_dofs; i++)
1011  {
1012  F_p(i) += p0_dot/p0*p_phi[i][qp]*JxW[qp];
1013  }
1014 
1015  }
1016  return;
1017  }
VariableIndex T() const
SpecificHeat _cp
Specific heat object.
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
VariableIndex p() const
VariableIndex p0() const
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::assemble_thermo_press_side_time_deriv ( bool  compute_jacobian,
AssemblyContext context 
)
protected

Definition at line 908 of file low_mach_navier_stokes.C.

910  {
911  // The number of local degrees of freedom in each variable.
912  const unsigned int n_p0_dofs = context.get_dof_indices(this->_p0_var->p0()).size();
913 
914  // Element Jacobian * quadrature weight for side integration.
915  //const std::vector<libMesh::Real> &JxW_side = context.get_side_fe(this->_temp_vars.T())->get_JxW();
916 
917  //const std::vector<Point> &normals = context.get_side_fe(this->_temp_vars.T())->get_normals();
918 
919  //libMesh::DenseSubVector<libMesh::Number> &F_p0 = context.get_elem_residual(this->_p0_var->p0()); // residual
920 
921  // Physical location of the quadrature points
922  //const std::vector<libMesh::Point>& qpoint = context.get_side_fe(this->_temp_vars.T())->get_xyz();
923 
924  unsigned int n_qpoints = context.get_side_qrule().n_points();
925  for (unsigned int qp=0; qp != n_qpoints; qp++)
926  {
927  /*
928  libMesh::Number T = context.side_value( this->_temp_vars.T(), qp );
929  libMesh::Gradient U = ( context.side_value( this->_flow_vars.u(), qp ),
930  context.side_value( this->_flow_vars.v(), qp ) );
931  libMesh::Gradient grad_T = context.side_gradient( this->_temp_vars.T(), qp );
932 
933 
934  libMesh::Number p0 = context.side_value( this->_p0_var->p0(), qp );
935 
936  libMesh::Number k = this->_k(T);
937  libMesh::Number cp = this->_cp(T);
938 
939  libMesh::Number cv = cp + this->_R;
940  libMesh::Number gamma = cp/cv;
941  libMesh::Number gamma_ratio = gamma/(gamma-1.0);
942  */
943 
944  //std::cout << "U = " << U << std::endl;
945 
946  //std::cout << "x = " << qpoint[qp] << ", grad_T = " << grad_T << std::endl;
947 
948  for (unsigned int i=0; i != n_p0_dofs; i++)
949  {
950  //F_p0(i) += (k*grad_T*normals[qp] - p0*gamma_ratio*U*normals[qp] )*JxW_side[qp];
951  }
952  }
953 
954  return;
955  }
VariableIndex p0() const
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::auxiliary_init ( MultiphysicsSystem system)
virtual

Any auxillary initialization a Physics class may need.

This is called after all variables are added, so this method can safely query the MultiphysicsSystem about variable information.

Reimplemented from GRINS::Physics.

Definition at line 59 of file low_mach_navier_stokes.C.

60  {
61  if( _pin_pressure )
62  _p_pinning.check_pin_location(system.get_mesh());
63  }
void check_pin_location(const libMesh::MeshBase &mesh)
Check the mesh to ensure pin location is found.
bool _pin_pressure
Enable pressure pinning.
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::compute_element_time_derivative_cache ( AssemblyContext context)
virtual

Reimplemented from GRINS::Physics.

Definition at line 1020 of file low_mach_navier_stokes.C.

References GRINS::AssemblyContext::get_cached_values(), GRINS::Cache::PRESSURE, GRINS::CachedValues::set_gradient_values(), GRINS::CachedValues::set_values(), GRINS::Cache::TEMPERATURE, GRINS::Cache::TEMPERATURE_GRAD, GRINS::Cache::THERMO_PRESSURE, GRINS::Cache::X_VELOCITY, GRINS::Cache::X_VELOCITY_GRAD, GRINS::Cache::Y_VELOCITY, GRINS::Cache::Y_VELOCITY_GRAD, GRINS::Cache::Z_VELOCITY, and GRINS::Cache::Z_VELOCITY_GRAD.

1021  {
1022  CachedValues & cache = context.get_cached_values();
1023 
1024  const unsigned int n_qpoints = context.get_element_qrule().n_points();
1025 
1026  std::vector<libMesh::Real> u, v, w, T, p, p0;
1027  u.resize(n_qpoints);
1028  v.resize(n_qpoints);
1029  if( this->_flow_vars.dim() > 2 )
1030  w.resize(n_qpoints);
1031 
1032  T.resize(n_qpoints);
1033  p.resize(n_qpoints);
1034  p0.resize(n_qpoints);
1035 
1036  std::vector<libMesh::Gradient> grad_u, grad_v, grad_w, grad_T;
1037  grad_u.resize(n_qpoints);
1038  grad_v.resize(n_qpoints);
1039  if( this->_flow_vars.dim() > 2 )
1040  grad_w.resize(n_qpoints);
1041 
1042  grad_T.resize(n_qpoints);
1043 
1044  for (unsigned int qp = 0; qp != n_qpoints; ++qp)
1045  {
1046  u[qp] = context.interior_value(this->_flow_vars.u(), qp);
1047  v[qp] = context.interior_value(this->_flow_vars.v(), qp);
1048 
1049  grad_u[qp] = context.interior_gradient(this->_flow_vars.u(), qp);
1050  grad_v[qp] = context.interior_gradient(this->_flow_vars.v(), qp);
1051  if( this->_flow_vars.dim() > 2 )
1052  {
1053  w[qp] = context.interior_value(this->_flow_vars.w(), qp);
1054  grad_w[qp] = context.interior_gradient(this->_flow_vars.w(), qp);
1055  }
1056  T[qp] = context.interior_value(this->_temp_vars.T(), qp);
1057  grad_T[qp] = context.interior_gradient(this->_temp_vars.T(), qp);
1058 
1059  p[qp] = context.interior_value(this->_press_var.p(), qp);
1060  p0[qp] = this->get_p0_steady(context, qp);
1061  }
1062 
1063  cache.set_values(Cache::X_VELOCITY, u);
1064  cache.set_values(Cache::Y_VELOCITY, v);
1065 
1066  cache.set_gradient_values(Cache::X_VELOCITY_GRAD, grad_u);
1067  cache.set_gradient_values(Cache::Y_VELOCITY_GRAD, grad_v);
1068 
1069  if(this->_flow_vars.dim() > 2)
1070  {
1071  cache.set_values(Cache::Z_VELOCITY, w);
1072  cache.set_gradient_values(Cache::Z_VELOCITY_GRAD, grad_w);
1073  }
1074 
1075  cache.set_values(Cache::TEMPERATURE, T);
1076  cache.set_gradient_values(Cache::TEMPERATURE_GRAD, grad_T);
1077 
1078  cache.set_values(Cache::PRESSURE, p);
1079  cache.set_values(Cache::THERMO_PRESSURE, p0);
1080  }
VariableIndex T() const
libMesh::Real get_p0_steady(const AssemblyContext &c, unsigned int qp) const
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
VariableIndex p() const
unsigned int dim() const
Number of components.
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::compute_postprocessed_quantity ( unsigned int  quantity_index,
const AssemblyContext context,
const libMesh::Point &  point,
libMesh::Real &  value 
)
virtual

Reimplemented from GRINS::Physics.

Definition at line 1083 of file low_mach_navier_stokes.C.

1087  {
1088  if( quantity_index == this->_rho_index )
1089  {
1090  libMesh::Real T = this->T(point,context);
1091  libMesh::Real p0 = this->get_p0_steady(context,point);
1092 
1093  value = this->rho( T, p0 );
1094  }
1095 
1096  return;
1097  }
libMesh::Real get_p0_steady(const AssemblyContext &c, unsigned int qp) const
libMesh::Real T(const libMesh::Point &p, const AssemblyContext &c) const
unsigned int _rho_index
Cache index for density post-processing.
libMesh::Real rho(libMesh::Real T, libMesh::Real p0) const
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::element_constraint ( bool  ,
AssemblyContext  
)
virtual

Constraint part(s) of physics for element interiors.

Reimplemented from GRINS::Physics.

Definition at line 129 of file low_mach_navier_stokes.C.

131  {
132  // Pin p = p_value at p_point
133  if( this->_pin_pressure )
134  this->_p_pinning.pin_value( context, compute_jacobian, this->_press_var.p());
135  }
VariableIndex p() const
void pin_value(libMesh::DiffContext &context, const bool request_jacobian, const GRINS::VariableIndex var, const double penalty=1.0)
The idea here is to pin a variable to a particular value if there is a null space - e...
bool _pin_pressure
Enable pressure pinning.
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::element_time_derivative ( bool  ,
AssemblyContext  
)
virtual

Time dependent part(s) of physics for element interiors.

Reimplemented from GRINS::Physics.

Definition at line 115 of file low_mach_navier_stokes.C.

References GRINS::AssemblyContext::get_cached_values().

116  {
117  const CachedValues & cache = context.get_cached_values();
118 
119  this->assemble_mass_time_deriv( compute_jacobian, context, cache );
120  this->assemble_momentum_time_deriv( compute_jacobian, context, cache );
121  this->assemble_energy_time_deriv( compute_jacobian, context, cache );
122 
123  if( this->_enable_thermo_press_calc )
124  this->assemble_thermo_press_elem_time_deriv( compute_jacobian, context );
125  }
void assemble_mass_time_deriv(bool compute_jacobian, AssemblyContext &context, const CachedValues &cache)
Helper function.
void assemble_energy_time_deriv(bool compute_jacobian, AssemblyContext &context, const CachedValues &cache)
Helper function.
bool _enable_thermo_press_calc
Flag to enable thermodynamic pressure calculation.
void assemble_momentum_time_deriv(bool compute_jacobian, AssemblyContext &context, const CachedValues &cache)
Helper function.
void assemble_thermo_press_elem_time_deriv(bool compute_jacobian, AssemblyContext &context)
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::init_context ( AssemblyContext context)
virtual

Initialize context for added physics variables.

Reimplemented from GRINS::LowMachNavierStokesBase< Viscosity, SpecificHeat, ThermalConductivity >.

Definition at line 95 of file low_mach_navier_stokes.C.

References GRINS::LowMachNavierStokesBase< Viscosity, SpecificHeat, ThermalConductivity >::init_context().

96  {
97  // First call base class
99 
100  // We also need the side shape functions, etc.
101  context.get_side_fe(this->_flow_vars.u())->get_JxW();
102  context.get_side_fe(this->_flow_vars.u())->get_phi();
103  context.get_side_fe(this->_flow_vars.u())->get_dphi();
104  context.get_side_fe(this->_flow_vars.u())->get_xyz();
105 
106  context.get_side_fe(this->_temp_vars.T())->get_JxW();
107  context.get_side_fe(this->_temp_vars.T())->get_phi();
108  context.get_side_fe(this->_temp_vars.T())->get_dphi();
109  context.get_side_fe(this->_temp_vars.T())->get_xyz();
110  }
VariableIndex T() const
virtual void init_context(AssemblyContext &context)
Initialize context for added physics variables.
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::mass_residual ( bool  ,
AssemblyContext  
)
virtual

Mass matrix part(s) for element interiors. All boundary terms lie within the time_derivative part.

Reimplemented from GRINS::Physics.

Definition at line 139 of file low_mach_navier_stokes.C.

140  {
141  this->assemble_continuity_mass_residual( compute_jacobian, context );
142 
143  this->assemble_momentum_mass_residual( compute_jacobian, context );
144 
145  this->assemble_energy_mass_residual( compute_jacobian, context );
146 
147  if( this->_enable_thermo_press_calc )
148  this->assemble_thermo_press_mass_residual( compute_jacobian, context );
149  }
void assemble_momentum_mass_residual(bool compute_jacobian, AssemblyContext &context)
Helper function.
bool _enable_thermo_press_calc
Flag to enable thermodynamic pressure calculation.
void assemble_continuity_mass_residual(bool compute_jacobian, AssemblyContext &context)
Helper function.
void assemble_thermo_press_mass_residual(bool compute_jacobian, AssemblyContext &context)
void assemble_energy_mass_residual(bool compute_jacobian, AssemblyContext &context)
Helper function.
template<class Mu , class SH , class TC >
void GRINS::LowMachNavierStokes< Mu, SH, TC >::register_postprocessing_vars ( const GetPot &  input,
PostProcessedQuantities< libMesh::Real > &  postprocessing 
)
virtual

Register postprocessing variables for LowMachNavierStokes.

Reimplemented from GRINS::Physics.

Definition at line 66 of file low_mach_navier_stokes.C.

References GRINS::PhysicsNaming::low_mach_navier_stokes(), and GRINS::PostProcessedQuantities< NumericType >::register_quantity().

68  {
69  std::string section = "Physics/"+PhysicsNaming::low_mach_navier_stokes()+"/output_vars";
70 
71  if( input.have_variable(section) )
72  {
73  unsigned int n_vars = input.vector_variable_size(section);
74 
75  for( unsigned int v = 0; v < n_vars; v++ )
76  {
77  std::string name = input(section,"DIE!",v);
78 
79  if( name == std::string("rho") )
80  {
81  this->_rho_index = postprocessing.register_quantity( name );
82  }
83  else
84  {
85  std::cerr << "Error: Invalue output_vars value for "+PhysicsNaming::low_mach_navier_stokes() << std::endl
86  << " Found " << name << std::endl
87  << " Acceptable values are: rho" << std::endl;
88  libmesh_error();
89  }
90  }
91  }
92  }
static PhysicsName low_mach_navier_stokes()
unsigned int _rho_index
Cache index for density post-processing.

Member Data Documentation

template<class Viscosity , class SpecificHeat , class ThermalConductivity >
PressurePinning GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >::_p_pinning
protected

Definition at line 81 of file low_mach_navier_stokes.h.

template<class Viscosity , class SpecificHeat , class ThermalConductivity >
bool GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >::_pin_pressure
protected
template<class Viscosity , class SpecificHeat , class ThermalConductivity >
unsigned int GRINS::LowMachNavierStokes< Viscosity, SpecificHeat, ThermalConductivity >::_rho_index
protected

Cache index for density post-processing.

Definition at line 84 of file low_mach_navier_stokes.h.


The documentation for this class was generated from the following files:

Generated on Tue Dec 19 2017 12:47:31 for GRINS-0.8.0 by  doxygen 1.8.9.1