void CanteraTransport::D( const CachedValues& cache, unsigned int qp, std::vector<libMesh::Real>& D ) const { const libMesh::Real T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; const libMesh::Real P = cache.get_cached_values(Cache::THERMO_PRESSURE)[qp]; const std::vector<libMesh::Real>& Y = cache.get_cached_vector_values(Cache::MASS_FRACTIONS)[qp]; libmesh_assert_equal_to( Y.size(), D.size() ); libmesh_assert_equal_to( Y.size(), _cantera_gas.nSpecies() ); { libMesh::Threads::spin_mutex::scoped_lock lock(cantera_mutex); /*! \todo Need to make sure this will work in a threaded environment. Not sure if we will get thread lock here or not. */ try { _cantera_gas.setState_TPY(T, P, &Y[0]); _cantera_transport.getMixDiffCoeffsMass(&D[0]); } catch(Cantera::CanteraError) { Cantera::showErrors(std::cerr); libmesh_error(); } } return; }
libMesh::Real CanteraThermodynamics::cv( const CachedValues& cache, unsigned int qp ) const { const libMesh::Real T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; const libMesh::Real P = cache.get_cached_values(Cache::THERMO_PRESSURE)[qp]; const std::vector<libMesh::Real>& Y = cache.get_cached_vector_values(Cache::MASS_FRACTIONS)[qp]; libmesh_assert_equal_to( Y.size(), _cantera_gas.nSpecies() ); libMesh::Real cv = 0.0; { /*! \todo Need to make sure this will work in a threaded environment. Not sure if we will get thread lock here or not. */ libMesh::Threads::spin_mutex::scoped_lock lock(cantera_mutex); try { _cantera_gas.setState_TPY( T, P, &Y[0] ); cv = _cantera_gas.cv_mass(); } catch(Cantera::CanteraError) { Cantera::showErrors(std::cerr); libmesh_error(); } } return cv; }
libMesh::Real AntiochWilkeTransportEvaluator<Th,V,C,D>::k( const CachedValues& cache, unsigned int qp ) { const libMesh::Real T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; const std::vector<libMesh::Real>& Y = cache.get_cached_vector_values(Cache::MASS_FRACTIONS)[qp]; return this->k( T, Y ); }
void AntiochWilkeTransportEvaluator<Th,V,C,D>::mu_and_k( const CachedValues& cache, unsigned int qp, libMesh::Real& mu, libMesh::Real& k ) { const libMesh::Real T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; const std::vector<libMesh::Real>& Y = cache.get_cached_vector_values(Cache::MASS_FRACTIONS)[qp]; _wilke_evaluator->mu_and_k( T, Y, mu, k ); return; }
void LowMachNavierStokes<Mu,SH,TC>::assemble_energy_time_deriv( bool /*compute_jacobian*/, AssemblyContext& context, CachedValues& cache ) { // The number of local degrees of freedom in each variable. const unsigned int n_T_dofs = context.get_dof_indices(this->_T_var).size(); // Element Jacobian * quadrature weights for interior integration. const std::vector<libMesh::Real> &JxW = context.get_element_fe(this->_T_var)->get_JxW(); // The temperature shape functions at interior quadrature points. const std::vector<std::vector<libMesh::Real> >& T_phi = context.get_element_fe(this->_T_var)->get_phi(); // The temperature shape functions gradients at interior quadrature points. const std::vector<std::vector<libMesh::RealGradient> >& T_gradphi = context.get_element_fe(this->_T_var)->get_dphi(); libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(this->_T_var); // R_{T} unsigned int n_qpoints = context.get_element_qrule().n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { libMesh::Number u, v, T, p0; u = cache.get_cached_values(Cache::X_VELOCITY)[qp]; v = cache.get_cached_values(Cache::Y_VELOCITY)[qp]; T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; p0 = cache.get_cached_values(Cache::THERMO_PRESSURE)[qp]; libMesh::Gradient grad_T = cache.get_cached_gradient_values(Cache::TEMPERATURE_GRAD)[qp]; libMesh::NumberVectorValue U(u,v); if (this->_dim == 3) U(2) = cache.get_cached_values(Cache::Z_VELOCITY)[qp]; // w libMesh::Number k = this->_k(T); libMesh::Number cp = this->_cp(T); libMesh::Number rho = this->rho( T, p0 ); // Now a loop over the pressure degrees of freedom. This // computes the contributions of the continuity equation. for (unsigned int i=0; i != n_T_dofs; i++) { FT(i) += ( -rho*cp*U*grad_T*T_phi[i][qp] // convection term - k*grad_T*T_gradphi[i][qp] // diffusion term )*JxW[qp]; } } return; }
void AntiochWilkeTransportEvaluator<Th,V,C,D>::D( const CachedValues& cache, unsigned int qp, std::vector<libMesh::Real>& D ) { const libMesh::Real rho = cache.get_cached_values(Cache::MIXTURE_DENSITY)[qp]; /*! \todo Find a way to cache these so we don't have to recompute them */ const libMesh::Real cp = this->cp(cache,qp); const libMesh::Real k = this->k(cache,qp); this->D(rho,cp,k,D); return; }
void LowMachNavierStokes<Mu,SH,TC>::compute_element_cache( const AssemblyContext& context, const std::vector<libMesh::Point>& points, CachedValues& cache ) { if( cache.is_active(Cache::PERFECT_GAS_DENSITY) ) { std::vector<libMesh::Real> rho_values; rho_values.reserve( points.size() ); for( std::vector<libMesh::Point>::const_iterator point = points.begin(); point != points.end(); point++ ) { libMesh::Real T = this->T(*point,context); libMesh::Real p0 = this->get_p0_steady(context,*point); rho_values.push_back(this->rho( T, p0 ) ); } cache.set_values( Cache::PERFECT_GAS_DENSITY, rho_values ); } return; }
void CanteraThermodynamics::h( const CachedValues& cache, unsigned int qp, std::vector<libMesh::Real>& h) const { const libMesh::Real T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; const libMesh::Real P = cache.get_cached_values(Cache::THERMO_PRESSURE)[qp]; const std::vector<libMesh::Real>& Y = cache.get_cached_vector_values(Cache::MASS_FRACTIONS)[qp]; libmesh_assert_equal_to( Y.size(), h.size() ); libmesh_assert_equal_to( Y.size(), _cantera_gas.nSpecies() ); { /*! \todo Need to make sure this will work in a threaded environment. Not sure if we will get thread lock here or not. */ libMesh::Threads::spin_mutex::scoped_lock lock(cantera_mutex); try { _cantera_gas.setState_TPY( T, P, &Y[0] ); _cantera_gas.getEnthalpy_RT( &h[0] ); } catch(Cantera::CanteraError) { Cantera::showErrors(std::cerr); libmesh_error(); } for( unsigned int s = 0; s < h.size(); s++ ) { h[s] *= _cantera_mixture.R(s)*T; } } return; }
void LowMachNavierStokes<Mu,SH,TC>::assemble_mass_time_deriv( bool /*compute_jacobian*/, AssemblyContext& context, CachedValues& cache ) { // The number of local degrees of freedom in each variable. const unsigned int n_p_dofs = context.get_dof_indices(this->_p_var).size(); // Element Jacobian * quadrature weights for interior integration. const std::vector<libMesh::Real> &JxW = context.get_element_fe(this->_u_var)->get_JxW(); // The pressure shape functions at interior quadrature points. const std::vector<std::vector<libMesh::Real> >& p_phi = context.get_element_fe(this->_p_var)->get_phi(); libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_p_var); // R_{p} unsigned int n_qpoints = context.get_element_qrule().n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { libMesh::Number u, v, T; u = cache.get_cached_values(Cache::X_VELOCITY)[qp]; v = cache.get_cached_values(Cache::Y_VELOCITY)[qp]; T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; libMesh::Gradient grad_u = cache.get_cached_gradient_values(Cache::X_VELOCITY_GRAD)[qp]; libMesh::Gradient grad_v = cache.get_cached_gradient_values(Cache::Y_VELOCITY_GRAD)[qp]; libMesh::Gradient grad_T = cache.get_cached_gradient_values(Cache::TEMPERATURE_GRAD)[qp]; libMesh::NumberVectorValue U(u,v); if (this->_dim == 3) U(2) = cache.get_cached_values(Cache::Z_VELOCITY)[qp]; // w libMesh::Number divU = grad_u(0) + grad_v(1); if (this->_dim == 3) { libMesh::Gradient grad_w = cache.get_cached_gradient_values(Cache::Z_VELOCITY_GRAD)[qp]; divU += grad_w(2); } // Now a loop over the pressure degrees of freedom. This // computes the contributions of the continuity equation. for (unsigned int i=0; i != n_p_dofs; i++) { Fp(i) += (-U*grad_T/T + divU)*p_phi[i][qp]*JxW[qp]; } } return; }
void GasRecombinationCatalyticWall<Chemistry>::apply_fluxes( AssemblyContext& context, const CachedValues& cache, const bool request_jacobian ) { libmesh_do_once(libmesh_deprecated()); libMesh::FEGenericBase<libMesh::Real>* side_fe = NULL; context.get_side_fe( _reactant_var_idx, side_fe ); // The number of local degrees of freedom in each variable. const unsigned int n_var_dofs = context.get_dof_indices(_reactant_var_idx).size(); libmesh_assert_equal_to( n_var_dofs, context.get_dof_indices(_product_var_idx).size() ); // Element Jacobian * quadrature weight for side integration. const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW(); // The var shape functions at side quadrature points. const std::vector<std::vector<libMesh::Real> >& var_phi_side = side_fe->get_phi(); // Physical location of the quadrature points const std::vector<libMesh::Point>& var_qpoint = side_fe->get_xyz(); // reactant residual libMesh::DenseSubVector<libMesh::Number> &F_r_var = context.get_elem_residual(_reactant_var_idx); // product residual libMesh::DenseSubVector<libMesh::Number> &F_p_var = context.get_elem_residual(_product_var_idx); unsigned int n_qpoints = context.get_side_qrule().n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { libMesh::Real jac = JxW_side[qp]; if(Physics::is_axisymmetric()) { const libMesh::Number r = var_qpoint[qp](0); jac *= r; } const libMesh::Real rho = cache.get_cached_values(Cache::MIXTURE_DENSITY)[qp]; const libMesh::Real Y_r = cache.get_cached_vector_values(Cache::MASS_FRACTIONS)[qp][this->_reactant_species_idx]; const libMesh::Real T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; const libMesh::Real r_value = this->compute_reactant_mass_flux(rho, Y_r, T); const libMesh::Real p_value = -r_value; for (unsigned int i=0; i != n_var_dofs; i++) { F_r_var(i) += r_value*var_phi_side[i][qp]*jac; F_p_var(i) += p_value*var_phi_side[i][qp]*jac; if( request_jacobian ) { libmesh_not_implemented(); } } } }
void LowMachNavierStokes<Mu,SH,TC>::compute_element_time_derivative_cache( const AssemblyContext& context, CachedValues& cache ) { const unsigned int n_qpoints = context.get_element_qrule().n_points(); std::vector<libMesh::Real> u, v, w, T, p, p0; u.resize(n_qpoints); v.resize(n_qpoints); if( this->_dim > 2 ) w.resize(n_qpoints); T.resize(n_qpoints); p.resize(n_qpoints); p0.resize(n_qpoints); std::vector<libMesh::Gradient> grad_u, grad_v, grad_w, grad_T; grad_u.resize(n_qpoints); grad_v.resize(n_qpoints); if( this->_dim > 2 ) grad_w.resize(n_qpoints); grad_T.resize(n_qpoints); for (unsigned int qp = 0; qp != n_qpoints; ++qp) { u[qp] = context.interior_value(this->_u_var, qp); v[qp] = context.interior_value(this->_v_var, qp); grad_u[qp] = context.interior_gradient(this->_u_var, qp); grad_v[qp] = context.interior_gradient(this->_v_var, qp); if( this->_dim > 2 ) { w[qp] = context.interior_value(this->_w_var, qp); grad_w[qp] = context.interior_gradient(this->_w_var, qp); } T[qp] = context.interior_value(this->_T_var, qp); grad_T[qp] = context.interior_gradient(this->_T_var, qp); p[qp] = context.interior_value(this->_p_var, qp); p0[qp] = this->get_p0_steady(context, qp); } cache.set_values(Cache::X_VELOCITY, u); cache.set_values(Cache::Y_VELOCITY, v); cache.set_gradient_values(Cache::X_VELOCITY_GRAD, grad_u); cache.set_gradient_values(Cache::Y_VELOCITY_GRAD, grad_v); if(this->_dim > 2) { cache.set_values(Cache::Z_VELOCITY, w); cache.set_gradient_values(Cache::Z_VELOCITY_GRAD, grad_w); } cache.set_values(Cache::TEMPERATURE, T); cache.set_gradient_values(Cache::TEMPERATURE_GRAD, grad_T); cache.set_values(Cache::PRESSURE, p); cache.set_values(Cache::THERMO_PRESSURE, p0); return; }
void LowMachNavierStokes<Mu,SH,TC>::assemble_momentum_time_deriv( bool /*compute_jacobian*/, AssemblyContext& context, CachedValues& cache ) { // The number of local degrees of freedom in each variable. const unsigned int n_u_dofs = context.get_dof_indices(this->_u_var).size(); // Check number of dofs is same for _u_var, v_var and w_var. libmesh_assert (n_u_dofs == context.get_dof_indices(this->_v_var).size()); if (this->_dim == 3) libmesh_assert (n_u_dofs == context.get_dof_indices(this->_w_var).size()); // Element Jacobian * quadrature weights for interior integration. const std::vector<libMesh::Real> &JxW = context.get_element_fe(this->_u_var)->get_JxW(); // The pressure shape functions at interior quadrature points. const std::vector<std::vector<libMesh::Real> >& u_phi = context.get_element_fe(this->_u_var)->get_phi(); // The velocity shape function gradients at interior quadrature points. const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi = context.get_element_fe(this->_u_var)->get_dphi(); libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_u_var); // R_{u} libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_v_var); // R_{v} libMesh::DenseSubVector<libMesh::Number> &Fw = context.get_elem_residual(this->_w_var); // R_{w} unsigned int n_qpoints = context.get_element_qrule().n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { libMesh::Number u, v, p, p0, T; u = cache.get_cached_values(Cache::X_VELOCITY)[qp]; v = cache.get_cached_values(Cache::Y_VELOCITY)[qp]; T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; p = cache.get_cached_values(Cache::PRESSURE)[qp]; p0 = cache.get_cached_values(Cache::THERMO_PRESSURE)[qp]; libMesh::Gradient grad_u = cache.get_cached_gradient_values(Cache::X_VELOCITY_GRAD)[qp]; libMesh::Gradient grad_v = cache.get_cached_gradient_values(Cache::Y_VELOCITY_GRAD)[qp]; libMesh::Gradient grad_w; if (this->_dim == 3) grad_w = cache.get_cached_gradient_values(Cache::Z_VELOCITY_GRAD)[qp]; libMesh::NumberVectorValue grad_uT( grad_u(0), grad_v(0) ); libMesh::NumberVectorValue grad_vT( grad_u(1), grad_v(1) ); libMesh::NumberVectorValue grad_wT; if( this->_dim == 3 ) { grad_uT(2) = grad_w(0); grad_vT(2) = grad_w(1); grad_wT = libMesh::NumberVectorValue( grad_u(2), grad_v(2), grad_w(2) ); } libMesh::NumberVectorValue U(u,v); if (this->_dim == 3) U(2) = cache.get_cached_values(Cache::Z_VELOCITY)[qp]; // w libMesh::Number divU = grad_u(0) + grad_v(1); if (this->_dim == 3) divU += grad_w(2); libMesh::Number rho = this->rho( T, p0 ); // Now a loop over the pressure degrees of freedom. This // computes the contributions of the continuity equation. for (unsigned int i=0; i != n_u_dofs; i++) { Fu(i) += ( -rho*U*grad_u*u_phi[i][qp] // convection term + p*u_gradphi[i][qp](0) // pressure term - this->_mu(T)*(u_gradphi[i][qp]*grad_u + u_gradphi[i][qp]*grad_uT - 2.0/3.0*divU*u_gradphi[i][qp](0) ) // diffusion term + rho*this->_g(0)*u_phi[i][qp] // hydrostatic term )*JxW[qp]; Fv(i) += ( -rho*U*grad_v*u_phi[i][qp] // convection term + p*u_gradphi[i][qp](1) // pressure term - this->_mu(T)*(u_gradphi[i][qp]*grad_v + u_gradphi[i][qp]*grad_vT - 2.0/3.0*divU*u_gradphi[i][qp](1) ) // diffusion term + rho*this->_g(1)*u_phi[i][qp] // hydrostatic term )*JxW[qp]; if (this->_dim == 3) { Fw(i) += ( -rho*U*grad_w*u_phi[i][qp] // convection term + p*u_gradphi[i][qp](2) // pressure term - this->_mu(T)*(u_gradphi[i][qp]*grad_w + u_gradphi[i][qp]*grad_wT - 2.0/3.0*divU*u_gradphi[i][qp](2) ) // diffusion term + rho*this->_g(2)*u_phi[i][qp] // hydrostatic term )*JxW[qp]; } /* if (compute_jacobian && context.get_elem_solution_derivative()) { libmesh_assert (context.get_elem_solution_derivative() == 1.0); for (unsigned int j=0; j != n_u_dofs; j++) { // TODO: precompute some terms like: // (Uvec*vel_gblgradphivec[j][qp]), // vel_phi[i][qp]*vel_phi[j][qp], // (vel_gblgradphivec[i][qp]*vel_gblgradphivec[j][qp]) Kuu(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*(Uvec*vel_gblgradphivec[j][qp]) // convection term -_rho*vel_phi[i][qp]*graduvec_x*vel_phi[j][qp] // convection term -_mu*(vel_gblgradphivec[i][qp]*vel_gblgradphivec[j][qp])); // diffusion term Kuv(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*graduvec_y*vel_phi[j][qp]); // convection term Kvv(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*(Uvec*vel_gblgradphivec[j][qp]) // convection term -_rho*vel_phi[i][qp]*gradvvec_y*vel_phi[j][qp] // convection term -_mu*(vel_gblgradphivec[i][qp]*vel_gblgradphivec[j][qp])); // diffusion term Kvu(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*gradvvec_x*vel_phi[j][qp]); // convection term if (_dim == 3) { Kuw(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*graduvec_z*vel_phi[j][qp]); // convection term Kvw(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*gradvvec_z*vel_phi[j][qp]); // convection term Kww(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*(Uvec*vel_gblgradphivec[j][qp]) // convection term -_rho*vel_phi[i][qp]*gradwvec_z*vel_phi[j][qp] // convection term -_mu*(vel_gblgradphivec[i][qp]*vel_gblgradphivec[j][qp])); // diffusion term Kwu(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*gradwvec_x*vel_phi[j][qp]); // convection term Kwv(i,j) += JxW[qp] * (-_rho*vel_phi[i][qp]*gradwvec_y*vel_phi[j][qp]); // convection term } } // end of the inner dof (j) loop // Matrix contributions for the up, vp and wp couplings for (unsigned int j=0; j != n_p_dofs; j++) { Kup(i,j) += JxW[qp]*vel_gblgradphivec[i][qp](0)*p_phi[j][qp]; Kvp(i,j) += JxW[qp]*vel_gblgradphivec[i][qp](1)*p_phi[j][qp]; if (_dim == 3) Kwp(i,j) += JxW[qp]*vel_gblgradphivec[i][qp](2)*p_phi[j][qp]; } // end of the inner dof (j) loop } // end - if (compute_jacobian && context.get_elem_solution_derivative()) } // end of the outer dof (i) loop } // end of the quadrature point (qp) loop */ } // End of DoF loop i } // End quadrature loop qp return; }