GRINS-0.7.0
constant_function_dirichlet_bc_factory.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // GRINS - General Reacting Incompressible Navier-Stokes
5 //
6 // Copyright (C) 2014-2016 Paul T. Bauman, Roy H. Stogner
7 // Copyright (C) 2010-2013 The PECOS Development Team
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the Version 2.1 GNU Lesser General
11 // Public License as published by the Free Software Foundation.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
21 // Boston, MA 02110-1301 USA
22 //
23 //-----------------------------------------------------------------------el-
24 
25 // This class
27 
28 // GRINS
29 #include "grins/string_utils.h"
32 
33 #ifdef GRINS_HAVE_CANTERA
34 #include "grins/cantera_mixture.h"
35 #endif
36 
37 #ifdef GRINS_HAVE_ANTIOCH
39 #endif
40 
41 // libMesh
42 #include "libmesh/composite_function.h"
43 #include "libmesh/const_function.h"
44 #include "libmesh/zero_function.h"
45 
46 namespace GRINS
47 {
48  libMesh::UniquePtr<libMesh::FunctionBase<libMesh::Number> >
50  MultiphysicsSystem& system,
51  std::vector<std::string>& var_names,
52  const std::string& section )
53  {
54  libmesh_assert( !var_names.empty() );
55 
57  libMesh::UniquePtr<libMesh::FunctionBase<libMesh::Number> > all_funcs;
58 
59  // We're given the active variables in var_names. Let's first check
60  // which ones the user actually set in the input file.
61  // If there's only one variable in var_names, then check_for_vars will
62  // error if the user didn't set it, so we don't need to consider that
63  // case here.
64  std::set<std::string> vars_found;
65  {
66  std::vector<std::string> vars_to_search_for(var_names.size());
67  this->set_vars_to_search_for(var_names,vars_to_search_for);
68  this->check_for_vars(input,section,vars_to_search_for,&vars_found);
69  }
70 
71  all_funcs.reset( this->build_composite_func().release() );
72 
73  // Cast to raw CompositeFunction for convenience
75  libMesh::libmesh_cast_ref<libMesh::CompositeFunction<libMesh::Number>&>(*(all_funcs.get()));
76 
77  std::set<std::string> vars_added;
78  this->add_found_vars(input, system, section, vars_found, composite_func, vars_added);
79 
80  // Now add all the other vars that weren't added as ZeroFunctions
81  for( std::vector<std::string>::const_iterator var = var_names.begin();
82  var < var_names.end(); ++var )
83  {
84  if( vars_added.find(*var) == vars_added.end() )
85  {
86  std::vector<VariableIndex> var_idx(1,system.variable_number(*var));
87  composite_func.attach_subfunction( libMesh::ZeroFunction<libMesh::Number>(),var_idx);
88  }
89  }
90 
91  return all_funcs;
92  }
93 
95  MultiphysicsSystem& system,
96  const std::string& section,
97  const std::set<std::string>& vars_found,
99  std::set<std::string>& vars_added ) const
100  {
101  libMesh::Number invalid_num = std::numeric_limits<libMesh::Number>::max();
102 
103  for( std::set<std::string>::const_iterator var = vars_found.begin();
104  var != vars_found.end(); ++var )
105  {
106  std::vector<VariableIndex> var_idx(1,system.variable_number(*var));
107 
108  libMesh::Number value = input(section+"/"+(*var),invalid_num);
109 
110  libMesh::ConstFunction<libMesh::Number> const_func(value);
111  composite_func.attach_subfunction(const_func,var_idx);
112  }
113 
114  vars_added = vars_found;
115  }
116 
117  void MoleFractionsDirichletBCFactory::extract_species_name( const std::string& var_name,
118  const std::string& prefix,
119  std::string& species_name ) const
120  {
121  std::vector<std::string> split_name;
122  StringUtilities::split_string(var_name,prefix,split_name);
123 
124  // split_string won't add the prefix, since it was used as the delimiter, so
125  // split_name should just have the lingering species name
126  libmesh_assert_equal_to(split_name.size(), 1);
127 
128  species_name = split_name[0];
129  }
130 
131  void MoleFractionsDirichletBCFactory::set_vars_to_search_for( const std::vector<std::string>& var_names,
132  std::vector<std::string>&vars_to_search_for ) const
133  {
134  libmesh_assert_equal_to(var_names.size(),vars_to_search_for.size());
135 
136  // This only makes sense for SpeciesMassFractionsFEVariables in the VariableWarehouse.
137  // This call will error out if it's not there.
138  const SpeciesMassFractionsFEVariables& species_fe_var =
139  GRINSPrivate::VariableWarehouse::get_variable_subclass<SpeciesMassFractionsFEVariables>
141 
142  const std::string& prefix = species_fe_var.prefix();
143  for( unsigned int v = 0; v < var_names.size(); v++ )
144  {
145  std::string species_name;
146  this->extract_species_name(var_names[v],prefix,species_name);
147  vars_to_search_for[v] = "X_"+species_name;
148  }
149  }
150 
151  // To avoid compiler warnings without GRINS or Cantera
152 #if defined(GRINS_HAVE_ANTIOCH) || defined(GRINS_HAVE_CANTERA)
154  MultiphysicsSystem& /*system*/,
155  const std::string& section,
156  const std::set<std::string>& vars_found,
158  std::set<std::string>& vars_added ) const
159 #else
160  void MoleFractionsDirichletBCFactory::add_found_vars( const GetPot& input,
161  MultiphysicsSystem& /*system*/,
162  const std::string& /*section*/,
163  const std::set<std::string>& /*vars_found*/,
165  std::set<std::string>& /*vars_added*/ ) const
166 #endif
167  {
168  // This only makes sense for SpeciesMassFractionsFEVariables in the VariableWarehouse.
169  // This call will error out if it's not there.
170  const SpeciesMassFractionsFEVariables& species_fe_var =
171  GRINSPrivate::VariableWarehouse::get_variable_subclass<SpeciesMassFractionsFEVariables>
173 
174  const std::string& material = species_fe_var.material();
175 
176  std::string thermochem_input_str = "Materials/"+material+"/GasMixture/thermochemistry_library";
177 
178  if( !input.have_variable(thermochem_input_str) )
179  libmesh_error_msg("ERROR: Could not find input option "+thermochem_input_str+" !");
180 
181  const std::string thermochem_lib = input(thermochem_input_str, std::string("DIE!") );
182 
183  if( thermochem_lib == "cantera" )
184  {
185 #ifdef GRINS_HAVE_CANTERA
186  this->add_mole_frac_to_mass_frac<CanteraMixture>(input,section,vars_found,material,
187  species_fe_var,composite_func,vars_added);
188 #else
189  libmesh_error_msg("Error: Cantera not enabled in this configuration. Reconfigure using --with-cantera option.");
190 #endif
191  }
192  else if( thermochem_lib == "antioch" )
193  {
194 #ifdef GRINS_HAVE_ANTIOCH
195  this->add_mole_frac_to_mass_frac<AntiochChemistry>(input,section,vars_found,material,
196  species_fe_var,composite_func,vars_added);
197 #else
198  libmesh_error_msg("Error: Antioch not enabled in this configuration. Reconfigure using --with-antioch option.");
199 #endif
200  }
201  else
202  libmesh_error_msg("ERROR: Invalid thermochemistry library "+thermochem_lib+"!");
203  }
204 
205  template<typename ChemistryType>
207  const std::string& section,
208  const std::set<std::string>& vars_found,
209  const std::string& material,
210  const SpeciesMassFractionsFEVariables& species_fe_var,
212  std::set<std::string>& vars_added) const
213  {
214  unsigned int n_vars_found = vars_found.size();
215 
216  // Parse in all the species mole fracs that are in the input (it is assumed non-specified are 0)
217  std::vector<libMesh::Number> species_mole_fracs(n_vars_found);
218  libMesh::Number invalid_num = std::numeric_limits<libMesh::Number>::max();
219  {
220  unsigned int count = 0;
221  for(std::set<std::string>::const_iterator var = vars_found.begin();
222  var != vars_found.end(); ++var )
223  {
224  species_mole_fracs[count] = input(section+"/"+(*var),invalid_num);
225  count++;
226  }
227  }
228 
229  // Make sure mole fracs sum to 1
230  libMesh::Number sum = 0.0;
231  for(unsigned int v = 0; v < n_vars_found; v++ )
232  sum += species_mole_fracs[v];
233 
234  libMesh::Number tol = std::numeric_limits<libMesh::Number>::epsilon()*10;
235  if( std::abs(sum-1.0) > tol )
236  libmesh_error_msg("ERROR: Mole fractions do not sum to 1! Found sum = "+StringUtilities::T_to_string<libMesh::Number>(sum));
237 
238  // Extract species names
239  std::vector<std::string> species_names(n_vars_found);
240  {
241  unsigned int count = 0;
242  for(std::set<std::string>::const_iterator var = vars_found.begin();
243  var != vars_found.end(); ++var )
244  {
245  std::vector<std::string> split_name;
246  // vars_found should have the form "X_<species name>"
247  StringUtilities::split_string((*var),"_",split_name);
248  libmesh_assert_equal_to(split_name[0],std::string("X"));
249  libmesh_assert_equal_to(split_name.size(),2);
250  species_names[count] = split_name[1];
251  count++;
252  }
253  }
254 
255  // Now convert to mass frac and add to composite function
258  ChemistryType chem(input,material);
259 
260  libMesh::Real M = 0.0;
261  for(unsigned int v = 0; v < n_vars_found; v++ )
262  {
263  unsigned int s = chem.species_index(species_names[v]);
264  M += species_mole_fracs[v]*chem.M(s);
265  }
266 
267  const std::string& prefix = species_fe_var.prefix();
268 
269  for(unsigned int v = 0; v < n_vars_found; v++ )
270  {
271  // Finish computing species mass fraction
272  unsigned int s = chem.species_index(species_names[v]);
273  libMesh::Number species_mass_fracs = species_mole_fracs[v]*chem.M(s)/M;
274 
275  // Add the function
276  std::vector<VariableIndex> var_idx(1,species_fe_var.species(s));
277  libMesh::ConstFunction<libMesh::Number> const_func(species_mass_fracs);
278  composite_func.attach_subfunction(const_func,var_idx);
279 
280  // Log that we added this variable
281  vars_added.insert(prefix+species_names[v]);
282  }
283  }
284 
285  // Instantiate
286 #ifdef GRINS_HAVE_CANTERA
287  template void MoleFractionsDirichletBCFactory::add_mole_frac_to_mass_frac<CanteraMixture>(const GetPot&,const std::string&,const std::set<std::string>&,const std::string&,const SpeciesMassFractionsFEVariables&,libMesh::CompositeFunction<libMesh::Number>&,std::set<std::string>& ) const;
288 #endif
289 
290 #ifdef GRINS_HAVE_ANTIOCH
291  template void MoleFractionsDirichletBCFactory::add_mole_frac_to_mass_frac<AntiochChemistry>(const GetPot&,const std::string&,const std::set<std::string>&,const std::string&,const SpeciesMassFractionsFEVariables&,libMesh::CompositeFunction<libMesh::Number>&,std::set<std::string>& ) const;
292 #endif
293 
294  // Register all the ConstantFunction factories.
299 
300 } // end namespace GRINS
virtual void set_vars_to_search_for(const std::vector< std::string > &var_names, std::vector< std::string > &vars_to_search_for) const
We'll search for mole fractions: X_.
virtual void add_found_vars(const GetPot &input, MultiphysicsSystem &system, const std::string &section, const std::set< std::string > &vars_found, libMesh::CompositeFunction< libMesh::Number > &composite_func, std::set< std::string > &vars_added) const
Adds the vars_found to the composite_func.
void add_mole_frac_to_mass_frac(const GetPot &input, const std::string &section, const std::set< std::string > &vars_found, const std::string &material, const SpeciesMassFractionsFEVariables &species_fe_var, libMesh::CompositeFunction< libMesh::Number > &composite_func, std::set< std::string > &vars_added) const
virtual void set_vars_to_search_for(const std::vector< std::string > &var_names, std::vector< std::string > &vars_to_search_for) const
Set the vars_to_search_for, based on var_names.
GRINS namespace.
Constructs ConstFunction objects for Dirichlet boundary conditions.
void extract_species_name(const std::string &var_name, const std::string &prefix, std::string &species_name) const
libMesh::UniquePtr< libMesh::FunctionBase< libMesh::Number > > build_composite_func()
static std::string species_mass_fractions_section()
Parses mole fraction values and converts to mass fractions.
Interface with libMesh for solving Multiphysics problems.
void split_string(const std::string &input, const std::string &delimiter, std::vector< std::string > &results)
Definition: string_utils.C:31
virtual libMesh::UniquePtr< libMesh::FunctionBase< libMesh::Number > > build_func(const GetPot &input, MultiphysicsSystem &system, std::vector< std::string > &var_names, const std::string &section)
Builds ConstantFunction objects for boundary conditions.
ConstantFunctionDirichletBCFactory grins_factory_constant_dirichlet("constant_dirichlet")
VariableIndex species(unsigned int species) const
void check_for_vars(const GetPot &input, const std::string &section, const std::vector< std::string > &var_names, std::set< std::string > *vars_found=NULL)
Helper function.
ConstantFunctionDirichletBCFactory grins_factory_constant_displacement("constant_displacement")
ConstantFunctionDirichletBCFactory grins_factory_constant_isothermal("isothermal")
MoleFractionsDirichletBCFactory grins_factory_mole_fractions("mole_fractions")
virtual void add_found_vars(const GetPot &input, MultiphysicsSystem &system, const std::string &section, const std::set< std::string > &vars_found, libMesh::CompositeFunction< libMesh::Number > &composite_func, std::set< std::string > &vars_added) const
Here, we're expected vars_found to correspond to mole fractions and we'll add mass fractions...

Generated on Thu Jun 2 2016 21:52:27 for GRINS-0.7.0 by  doxygen 1.8.10