38 #include "libmesh/fem_system.h"
39 #include "libmesh/dof_map.h"
40 #include "libmesh/const_function.h"
41 #include "libmesh/dirichlet_boundaries.h"
44 #include "boost/scoped_ptr.hpp"
48 template<
typename Chemistry>
51 const Chemistry& chemistry )
53 _n_species( input.vector_variable_size(
"Physics/Chemistry/species") ),
54 _species_var_names(_n_species),
55 _species_vars(_n_species),
62 std::string var_name =
"w_"+std::string(input(
"Physics/Chemistry/species",
"DIE!", s ));
66 std::string id_str =
"Physics/"+
_physics_name+
"/species_bc_ids";
67 std::string bc_str =
"Physics/"+
_physics_name+
"/species_bc_types";
68 std::string var_str =
"Physics/"+
_physics_name+
"/species_bc_variables";
69 std::string val_str =
"Physics/"+
_physics_name+
"/species_bc_values";
71 this->
read_bc_data( input, id_str, bc_str, var_str, val_str );
76 template<
typename Chemistry>
82 template<
typename Chemistry>
87 if( bc_type ==
"zero_species_flux" )
89 bc_type_out = ZERO_SPECIES_FLUX;
91 else if( bc_type ==
"prescribed_species" )
93 bc_type_out = PRESCRIBED_SPECIES;
95 else if( bc_type ==
"prescribed_mole_fracs" )
97 bc_type_out = PRESCRIBED_MOLE_FRACTIONS;
99 else if( bc_type ==
"gas_recombination_catalytic_wall" )
101 bc_type_out = GAS_RECOMBINATION_CATALYTIC_WALL;
103 else if( bc_type ==
"gas_solid_catalytic_wall" )
105 bc_type_out = GAS_SOLID_CATALYTIC_WALL;
107 else if( bc_type ==
"general_species" )
109 bc_type_out = GENERAL_SPECIES;
119 template<
typename Chemistry>
121 const std::string& bc_id_string,
123 const std::string& bc_vars,
124 const std::string& bc_value,
125 const GetPot& input )
129 case(ZERO_SPECIES_FLUX):
131 this->set_neumann_bc_type( bc_id, bc_type );
135 case(PRESCRIBED_SPECIES):
137 this->set_species_bc_type( bc_id, bc_type );
139 unsigned int n_species_comps = input.vector_variable_size(
"Physics/"+_physics_name+
"/bound_species_"+bc_id_string);
141 if( n_species_comps != _n_species )
143 std::cerr <<
"Error: The number of prescribed species values must match" << std::endl
144 <<
" the number of species in the simulation." << std::endl
145 <<
"n_species = " << _n_species << std::endl
146 <<
"n_species_comps = " << n_species_comps << std::endl;
150 std::vector<libMesh::Real> species_mass_fracs(n_species_comps);
152 for(
unsigned int s = 0; s < n_species_comps; s++ )
154 species_mass_fracs[s] = input(
"Physics/"+_physics_name+
"/bound_species_"+bc_id_string, -1.0, s );
156 if( (species_mass_fracs[s] > 1.0) ||
157 (species_mass_fracs[s] < 0.0) )
159 std::cerr <<
"Error: prescribed species mass fraction must be between 0.0 and 1.0" << std::endl
160 <<
"w[" << s <<
"] = " << species_mass_fracs[s] << std::endl;
165 this->set_species_bc_values( bc_id, species_mass_fracs );
169 case(PRESCRIBED_MOLE_FRACTIONS):
171 this->set_species_bc_type( bc_id, bc_type );
173 unsigned int n_species_comps = input.vector_variable_size(
"Physics/"+_physics_name+
"/bound_species_"+bc_id_string);
175 if( n_species_comps != _n_species )
177 std::cerr <<
"Error: The number of prescribed species values must match" << std::endl
178 <<
" the number of species in the simulation." << std::endl
179 <<
"n_species = " << _n_species << std::endl
180 <<
"n_species_comps = " << n_species_comps << std::endl;
184 std::vector<libMesh::Real> species_mole_fracs(n_species_comps);
186 for(
unsigned int s = 0; s < n_species_comps; s++ )
188 species_mole_fracs[s] = input(
"Physics/"+_physics_name+
"/bound_species_"+bc_id_string, -1.0, s );
190 if( (species_mole_fracs[s] > 1.0) ||
191 (species_mole_fracs[s] < 0.0) )
193 std::cerr <<
"Error: prescribed species mole fraction must be between 0.0 and 1.0" << std::endl
194 <<
"w[" << s <<
"] = " << species_mole_fracs[s] << std::endl;
200 libMesh::Real M = 0.0;
201 for(
unsigned int s = 0; s < n_species_comps; s++ )
203 M += species_mole_fracs[s]*_chemistry.M(s);
207 std::vector<libMesh::Real> species_mass_fracs(n_species_comps);
208 for(
unsigned int s = 0; s < n_species_comps; s++ )
210 species_mass_fracs[s] = species_mole_fracs[s]*_chemistry.M(s)/M;
213 this->set_species_bc_values( bc_id, species_mass_fracs );
217 case(GENERAL_SPECIES):
219 this->set_dirichlet_bc_type( bc_id, bc_type );
223 case(GAS_RECOMBINATION_CATALYTIC_WALL):
225 this->set_neumann_bc_type( bc_id, bc_type );
228 std::string reactions_string =
"Physics/"+_physics_name+
"/wall_catalytic_reactions_"+bc_id_string;
229 if( !input.have_variable(reactions_string) )
231 std::cerr <<
"Error: Could not find list of catalytic reactions for boundary id " << bc_id
236 const unsigned int n_reactions = input.vector_variable_size(reactions_string);
238 for(
unsigned int r = 0; r < n_reactions; r++ )
240 std::string reaction = input(reactions_string,
"DIE!", r);
243 std::vector<std::string> partners;
246 const std::string& reactant = partners[0];
247 const std::string& product = partners[1];
250 if( partners.size() == 2 )
253 const unsigned int r_species = _chemistry.species_index( reactant );
254 const unsigned int p_species = _chemistry.species_index( product );
259 boost::scoped_ptr<CatalycityBase> gamma_r(NULL);
261 this->build_catalycities( input, reactant, bc_id_string, bc_id, gamma_r );
264 libmesh_assert( gamma_r );
268 _catalytic_walls.insert( std::make_pair(bc_id, wall_ptr ) );
273 std::cerr <<
"Error: Can currently only handle 1 reactant and 1 product" << std::endl
274 <<
"in a catalytic reaction." << std::endl
275 <<
"Found " << partners.size() <<
" species." << std::endl;
283 case(GAS_SOLID_CATALYTIC_WALL):
285 this->set_neumann_bc_type( bc_id, bc_type );
288 std::string reactions_string =
"Physics/"+_physics_name+
"/wall_gas_solid_reactions_"+bc_id_string;
289 if( !input.have_variable(reactions_string) )
291 std::cerr <<
"Error: Could not find list of gas-solid catalytic reactions for boundary id "
297 const unsigned int n_reactions = input.vector_variable_size(reactions_string);
299 for(
unsigned int r = 0; r < n_reactions; r++ )
301 std::string reaction = input(reactions_string,
"DIE!", r);
309 std::vector<std::string> partners;
312 const std::string pre_split_reactants = partners[0];
313 const std::string& product = partners[1];
315 std::vector<std::string> split_reactants;
319 if( split_reactants.size() != 2 )
321 std::cerr <<
"Error: Currently, GasSolidCatalyticWall boundary condition only supports"
323 <<
" reactions of the form X+Y(s)->Z or Y(s)+X->X. Found "
324 << split_reactants.size() <<
" reactants." << std::endl;
328 std::string gas_reactant;
329 std::string solid_reactant;
331 if( split_reactants[0].find(
"(s)") == split_reactants[0].npos )
334 if( split_reactants[1].find(
"(s)") == split_reactants[1].npos )
336 std::cerr <<
"Error: could not find solid reactant for GasSolidCatalyticWall" << std::endl
337 <<
" boundary condition. Found reactants " << split_reactants[0]
338 <<
", " << split_reactants[1] << std::endl;
343 gas_reactant = split_reactants[0];
344 solid_reactant = split_reactants[1].substr(0,split_reactants[1].find(
"(s)"));
351 if( split_reactants[1].find(
"(s)") != split_reactants[1].npos )
353 std::cerr <<
"Error: can have only one solid reactant for GasSolidCatalyticWall" << std::endl
354 <<
" boundary condition. Found reactants " << split_reactants[0]
355 <<
", " << split_reactants[1] << std::endl;
359 gas_reactant = split_reactants[1];
360 solid_reactant = split_reactants[0].substr(0,split_reactants[0].find(
"(s)"));
366 const unsigned int rg_species = _chemistry.species_index( gas_reactant );
367 const unsigned int rs_species = _chemistry.species_index( solid_reactant );
368 const unsigned int p_species = _chemistry.species_index( product );
371 boost::scoped_ptr<CatalycityBase> gamma_r(NULL);
373 this->build_catalycities( input, gas_reactant, bc_id_string, bc_id, gamma_r );
375 libmesh_assert( gamma_r );
377 std::tr1::shared_ptr<CatalyticWallBase<Chemistry> > wall_ptr(
new GasSolidCatalyticWall<Chemistry>( _chemistry, *gamma_r, rg_species, rs_species, p_species ) );
379 _catalytic_walls.insert( std::make_pair(bc_id, wall_ptr ) );
388 bc_vars, bc_value, input );
397 template<
typename Chemistry>
403 for(
unsigned int s = 0; s < this->_n_species; s++ )
405 _species_vars[s] = system.variable_number( _species_var_names[s] );
409 for( std::map< GRINS::BoundaryID, GRINS::BCType>::const_iterator bc_map = _neumann_bc_map.begin();
410 bc_map != _neumann_bc_map.end(); ++bc_map )
413 const BCType bc_type = bc_map->second;
415 if( bc_type == GAS_RECOMBINATION_CATALYTIC_WALL ||
416 bc_type == GAS_SOLID_CATALYTIC_WALL )
418 typedef typename std::multimap<BoundaryID, std::tr1::shared_ptr<CatalyticWallBase<Chemistry> > >::iterator it_type;
420 std::pair< it_type, it_type > it_range = _catalytic_walls.equal_range( bc_id );
422 for( it_type it = it_range.first; it != it_range.second; ++it )
424 (it->second)->init(system);
426 if( this->is_axisymmetric() )
428 (it->second)->set_axisymmetric(
true);
438 template<
typename Chemistry>
440 libMesh::DofMap& dof_map,
446 case(ZERO_SPECIES_FLUX):
449 case(PRESCRIBED_SPECIES):
450 case(PRESCRIBED_MOLE_FRACTIONS):
452 std::set<GRINS::BoundaryID> dbc_ids;
453 dbc_ids.insert(bc_id);
455 for(
unsigned int s = 0; s < _n_species; s++ )
457 std::vector<GRINS::VariableIndex> dbc_vars(1,_species_vars[s]);
459 libMesh::ConstFunction<libMesh::Number> species_func( this->get_species_bc_value(bc_id,s) );
461 libMesh::DirichletBoundary species_dbc( dbc_ids,
465 dof_map.add_dirichlet_boundary( species_dbc );
470 case(GENERAL_SPECIES):
482 template<
typename Chemistry>
485 _species_bc_map.push_back( std::make_pair(bc_id,bc_type) );
489 template<
typename Chemistry>
491 const std::vector<libMesh::Real>& species_values )
493 _species_bc_values[bc_id] = species_values;
497 template<
typename Chemistry>
499 unsigned int species )
const
501 return (_species_bc_values.find(bc_id)->second)[species];
504 template<
typename Chemistry>
509 libMesh::DofMap& dof_map = system->get_dof_map();
511 for( std::vector<std::pair<BoundaryID,BCType> >::const_iterator it = _species_bc_map.begin();
512 it != _species_bc_map.end();
515 this->user_init_dirichlet_bcs( system, dof_map, it->first, it->second );
521 template<
typename Chemistry>
524 const bool request_jacobian,
526 const BCType bc_type )
const
530 case( GENERAL_SPECIES ):
532 for( std::vector<VariableIndex>::const_iterator var = _species_vars.begin();
533 var != _species_vars.end();
536 if( this->is_axisymmetric() )
538 _bound_conds.apply_neumann_normal_axisymmetric( context, cache,
539 request_jacobian, *var, -1.0,
540 this->get_neumann_bound_func( bc_id, *var ) );
544 _bound_conds.apply_neumann_normal( context, cache,
545 request_jacobian, *var, 1.0,
546 this->get_neumann_bound_func( bc_id, *var ) );
552 case( GAS_RECOMBINATION_CATALYTIC_WALL ):
553 case( GAS_SOLID_CATALYTIC_WALL ):
555 typedef typename std::multimap<BoundaryID, std::tr1::shared_ptr<CatalyticWallBase<Chemistry> > >::const_iterator it_type;
557 std::pair< it_type, it_type > it_range = _catalytic_walls.equal_range( bc_id );
559 for( it_type it = it_range.first; it != it_range.second; ++it )
561 (it->second)->apply_fluxes(context, cache, request_jacobian );
568 std::cerr <<
"Error: Invalid Neumann BC type for " << _physics_name
577 template<
typename Chemistry>
579 const std::string& reactant,
580 const std::string& bc_id_string,
582 boost::scoped_ptr<CatalycityBase>& gamma_r )
584 std::string catalycity_type = input(
"Physics/"+_physics_name+
"/gamma_"+reactant+
"_"+bc_id_string+
"_type",
"none");
586 if( catalycity_type == std::string(
"constant") )
588 std::string gamma_r_string =
"Physics/"+_physics_name+
"/gamma_"+reactant+
"_"+bc_id_string;
589 libMesh::Real gamma = input(gamma_r_string, 0.0);
591 if( !input.have_variable(gamma_r_string) )
593 std::cout <<
"Error: Could not find catalycity for species " << reactant
594 <<
", for boundary " << bc_id << std::endl;
600 else if( catalycity_type == std::string(
"arrhenius") )
602 std::string gamma_r_string =
"Physics/"+_physics_name+
"/gamma0_"+reactant+
"_"+bc_id_string;
603 std::string Ta_r_string =
"Physics/"+_physics_name+
"/Ta_"+reactant+
"_"+bc_id_string;
605 libMesh::Real gamma0 = input(gamma_r_string, 0.0);
606 libMesh::Real Ta = input(Ta_r_string, 0.0);
608 if( !input.have_variable(gamma_r_string) )
610 std::cout <<
"Error: Could not find gamma0 for species " << reactant
611 <<
", for boundary " << bc_id << std::endl;
615 if( !input.have_variable(Ta_r_string) )
617 std::cout <<
"Error: Could not find Ta for species " << reactant
618 <<
", for boundary " << bc_id << std::endl;
624 else if( catalycity_type == std::string(
"power") )
626 std::string gamma_r_string =
"Physics/"+_physics_name+
"/gamma0_"+reactant+
"_"+bc_id_string;
627 std::string Tref_r_string =
"Physics/"+_physics_name+
"/Tref_"+reactant+
"_"+bc_id_string;
628 std::string alpha_r_string =
"Physics/"+_physics_name+
"/alpha_"+reactant+
"_"+bc_id_string;
630 libMesh::Real gamma0 = input(gamma_r_string, 0.0);
631 libMesh::Real Tref = input(Tref_r_string, 0.0);
632 libMesh::Real alpha = input(alpha_r_string, 0.0);
634 if( !input.have_variable(gamma_r_string) )
636 std::cout <<
"Error: Could not find gamma0 for species " << reactant
637 <<
", for boundary " << bc_id << std::endl;
641 if( !input.have_variable(Tref_r_string) )
643 std::cout <<
"Error: Could not find Tref for species " << reactant
644 <<
", for boundary " << bc_id << std::endl;
648 if( !input.have_variable(alpha_r_string) )
650 std::cout <<
"Error: Could not find alpha for species " << reactant
651 <<
", for boundary " << bc_id << std::endl;
661 std::cerr <<
"Error: Unsupported catalycity type " << catalycity_type << std::endl
662 <<
" for reactant " << reactant << std::endl
663 <<
"Valid catalycity types are: constant" << std::endl
664 <<
" arrhenius" << std::endl
665 <<
" power" << std::endl;
674 template<
typename Chemistry>
677 return (_catalytic_walls.find(bc_id)->second).
get();
virtual void init_dirichlet_bcs(libMesh::FEMSystem *system) const
virtual void read_bc_data(const GetPot &input, const std::string &id_str, const std::string &bc_str, const std::string &var_str, const std::string &val_str)
virtual void init_dirichlet_bcs(libMesh::FEMSystem *system) const
virtual void user_init_dirichlet_bcs(libMesh::FEMSystem *system, libMesh::DofMap &dof_map, GRINS::BoundaryID bc_id, GRINS::BCType bc_type) const
Base class for reading and handling boundary conditions for physics classes.
virtual void init_bc_data(const libMesh::FEMSystem &system)
Override this method to initialize any system-dependent data.
ReactingLowMachNavierStokesBCHandling()
virtual void user_init_dirichlet_bcs(libMesh::FEMSystem *system, libMesh::DofMap &dof_map, GRINS::BoundaryID bc_id, GRINS::BCType bc_type) const
libMesh::boundary_id_type BoundaryID
More descriptive name of the type used for boundary ids.
virtual ~ReactingLowMachNavierStokesBCHandling()
virtual void init_bc_types(const GRINS::BoundaryID bc_id, const std::string &bc_id_string, const int bc_type, const std::string &bc_vars, const std::string &bc_value, const GetPot &input)
virtual void init_bc_types(const GRINS::BoundaryID bc_id, const std::string &bc_id_string, const int bc_type, const std::string &bc_vars, const std::string &bc_value, const GetPot &input)
virtual int string_to_int(const std::string &bc_type_in) const
void build_catalycities(const GetPot &input, const std::string &reactant, const std::string &bc_id_string, const BoundaryID bc_id, boost::scoped_ptr< CatalycityBase > &gamma_r)
void set_species_bc_type(GRINS::BoundaryID bc_id, int bc_type)
virtual int string_to_int(const std::string &bc_type_in) const
std::vector< std::string > _species_var_names
virtual void init_bc_data(const libMesh::FEMSystem &system)
Override this method to initialize any system-dependent data.
void split_string(const std::string &input, const std::string &delimiter, std::vector< std::string > &results)
virtual void user_apply_neumann_bcs(AssemblyContext &context, const GRINS::CachedValues &cache, const bool request_jacobian, const GRINS::BoundaryID bc_id, const GRINS::BCType bc_type) const
void set_species_bc_values(GRINS::BoundaryID bc_id, const std::vector< libMesh::Real > &species_values)
libMesh::Real get_species_bc_value(GRINS::BoundaryID bc_id, unsigned int species) const
std::string _physics_name
CatalyticWallBase< Chemistry > * get_catalytic_wall(const BoundaryID bc_id)