GRINS-0.8.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-2017 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"
33 
34 #ifdef GRINS_HAVE_CANTERA
35 #include "grins/cantera_mixture.h"
36 #endif
37 
38 #ifdef GRINS_HAVE_ANTIOCH
40 #endif
41 
42 // libMesh
43 #include "libmesh/composite_function.h"
44 #include "libmesh/const_function.h"
45 #include "libmesh/zero_function.h"
46 
47 namespace GRINS
48 {
49  libMesh::UniquePtr<libMesh::FunctionBase<libMesh::Number> >
51  MultiphysicsSystem& system,
52  std::vector<std::string>& var_names,
53  const std::string& section )
54  {
55  libmesh_assert( !var_names.empty() );
56 
58  libMesh::UniquePtr<libMesh::FunctionBase<libMesh::Number> > all_funcs;
59 
60  // We're given the active variables in var_names. Let's first check
61  // which ones the user actually set in the input file.
62  // If there's only one variable in var_names, then check_for_vars will
63  // error if the user didn't set it, so we don't need to consider that
64  // case here.
65  std::set<std::string> vars_found;
66  {
67  std::vector<std::string> vars_to_search_for(var_names.size());
68  this->set_vars_to_search_for(section,var_names,vars_to_search_for);
69  this->check_for_vars(input,section,vars_to_search_for,&vars_found);
70  }
71 
72  all_funcs.reset( this->build_composite_func().release() );
73 
74  // Cast to raw CompositeFunction for convenience
76  libMesh::cast_ref<libMesh::CompositeFunction<libMesh::Number>&>(*(all_funcs.get()));
77 
78  std::set<std::string> vars_added;
79  this->add_found_vars(input, system, section, vars_found, composite_func, vars_added);
80 
81  // Now add all the other vars that weren't added as ZeroFunctions
82  for( std::vector<std::string>::const_iterator var = var_names.begin();
83  var < var_names.end(); ++var )
84  {
85  if( vars_added.find(*var) == vars_added.end() )
86  {
87  std::vector<VariableIndex> var_idx(1,system.variable_number(*var));
88  composite_func.attach_subfunction( libMesh::ZeroFunction<libMesh::Number>(),var_idx);
89  }
90  }
91 
92  return all_funcs;
93  }
94 
96  MultiphysicsSystem& system,
97  const std::string& section,
98  const std::set<std::string>& vars_found,
100  std::set<std::string>& vars_added ) const
101  {
102  libMesh::Number invalid_num = std::numeric_limits<libMesh::Number>::max();
103 
104  for( std::set<std::string>::const_iterator var = vars_found.begin();
105  var != vars_found.end(); ++var )
106  {
107  std::vector<VariableIndex> var_idx(1,system.variable_number(*var));
108 
109  libMesh::Number value = input(section+"/"+(*var),invalid_num);
110 
111  libMesh::ConstFunction<libMesh::Number> const_func(value);
112  composite_func.attach_subfunction(const_func,var_idx);
113  }
114 
115  vars_added = vars_found;
116  }
117 
118  void MoleFractionsDirichletBCFactory::extract_species_name( const std::string& var_name,
119  const std::string& prefix,
120  std::string& species_name ) const
121  {
122  std::vector<std::string> split_name;
123  StringUtilities::split_string(var_name,prefix,split_name);
124 
125  // split_string won't add the prefix, since it was used as the delimiter, so
126  // split_name should just have the lingering species name
127  libmesh_assert_equal_to(split_name.size(), 1);
128 
129  species_name = split_name[0];
130  }
131 
133  const std::vector<std::string>& var_names,
134  std::vector<std::string>&vars_to_search_for ) const
135  {
136  libmesh_assert_equal_to(var_names.size(),vars_to_search_for.size());
137 
138  // Strip out the Variable name from the section
139  std::string var_section = extract_var_section(section);
140 
141  // This only makes sense for SpeciesMassFractionsVariable in the VariableWarehouse.
142  // This call will error out if it's not there.
143  const SpeciesMassFractionsVariable& species_fe_var =
144  GRINSPrivate::VariableWarehouse::get_variable_subclass<SpeciesMassFractionsVariable>
145  (var_section);
146 
147  const std::string& prefix = species_fe_var.prefix();
148  for( unsigned int v = 0; v < var_names.size(); v++ )
149  {
150  std::string species_name;
151  this->extract_species_name(var_names[v],prefix,species_name);
152  vars_to_search_for[v] = "X_"+species_name;
153  }
154  }
155 
156  // To avoid compiler warnings without GRINS or Cantera
157 #if defined(GRINS_HAVE_ANTIOCH) || defined(GRINS_HAVE_CANTERA)
159  MultiphysicsSystem& /*system*/,
160  const std::string& section,
161  const std::set<std::string>& vars_found,
163  std::set<std::string>& vars_added ) const
164 #else
165  void MoleFractionsDirichletBCFactory::add_found_vars( const GetPot& input,
166  MultiphysicsSystem& /*system*/,
167  const std::string& section,
168  const std::set<std::string>& /*vars_found*/,
170  std::set<std::string>& /*vars_added*/ ) const
171 #endif
172  {
173  // Strip out the Variable name from the section
174  std::string var_section = extract_var_section(section);
175 
176  // This only makes sense for SpeciesMassFractionsVariable in the VariableWarehouse.
177  // This call will error out if it's not there.
178  const SpeciesMassFractionsVariable& species_fe_var =
179  GRINSPrivate::VariableWarehouse::get_variable_subclass<SpeciesMassFractionsVariable>
180  (var_section);
181 
182  const std::string& material = species_fe_var.material();
183 
184  std::string thermochem_input_str = "Materials/"+material+"/GasMixture/thermochemistry_library";
185 
186  if( !input.have_variable(thermochem_input_str) )
187  libmesh_error_msg("ERROR: Could not find input option "+thermochem_input_str+" !");
188 
189  const std::string thermochem_lib = input(thermochem_input_str, std::string("DIE!") );
190 
191  if( thermochem_lib == "cantera" )
192  {
193 #ifdef GRINS_HAVE_CANTERA
194  this->add_mole_frac_to_mass_frac<CanteraMixture>(input,section,vars_found,material,
195  species_fe_var,composite_func,vars_added);
196 #else
197  libmesh_error_msg("Error: Cantera not enabled in this configuration. Reconfigure using --with-cantera option.");
198 #endif
199  }
200  else if( thermochem_lib == "antioch" )
201  {
202 #ifdef GRINS_HAVE_ANTIOCH
203  this->add_mole_frac_to_mass_frac<AntiochChemistry>(input,section,vars_found,material,
204  species_fe_var,composite_func,vars_added);
205 #else
206  libmesh_error_msg("Error: Antioch not enabled in this configuration. Reconfigure using --with-antioch option.");
207 #endif
208  }
209  else
210  libmesh_error_msg("ERROR: Invalid thermochemistry library "+thermochem_lib+"!");
211  }
212 
213  template<typename ChemistryType>
215  const std::string& section,
216  const std::set<std::string>& vars_found,
217  const std::string& material,
218  const SpeciesMassFractionsVariable& species_fe_var,
220  std::set<std::string>& vars_added) const
221  {
222  unsigned int n_vars_found = vars_found.size();
223 
224  // Parse in all the species mole fracs that are in the input (it is assumed non-specified are 0)
225  std::vector<libMesh::Number> species_mole_fracs(n_vars_found);
226  libMesh::Number invalid_num = std::numeric_limits<libMesh::Number>::max();
227  {
228  unsigned int count = 0;
229  for(std::set<std::string>::const_iterator var = vars_found.begin();
230  var != vars_found.end(); ++var )
231  {
232  species_mole_fracs[count] = input(section+"/"+(*var),invalid_num);
233  count++;
234  }
235  }
236 
237  // Make sure mole fracs sum to 1
238  libMesh::Number sum = 0.0;
239  for(unsigned int v = 0; v < n_vars_found; v++ )
240  sum += species_mole_fracs[v];
241 
242  libMesh::Number tol = std::numeric_limits<libMesh::Number>::epsilon()*10;
243  if( std::abs(sum-1.0) > tol )
244  libmesh_error_msg("ERROR: Mole fractions do not sum to 1! Found sum = "+StringUtilities::T_to_string<libMesh::Number>(sum));
245 
246  // Extract species names
247  std::vector<std::string> species_names(n_vars_found);
248  {
249  unsigned int count = 0;
250  for(std::set<std::string>::const_iterator var = vars_found.begin();
251  var != vars_found.end(); ++var )
252  {
253  std::vector<std::string> split_name;
254  // vars_found should have the form "X_<species name>"
255  StringUtilities::split_string((*var),"_",split_name);
256  libmesh_assert_equal_to(split_name[0],std::string("X"));
257  libmesh_assert_equal_to(split_name.size(),2);
258  species_names[count] = split_name[1];
259  count++;
260  }
261  }
262 
263  // Now convert to mass frac and add to composite function
266  ChemistryBuilder chem_builder;
267  libMesh::UniquePtr<ChemistryType> chem_ptr;
268  chem_builder.build_chemistry(input,material,chem_ptr);
269 
270  const ChemistryType & chem = *chem_ptr;
271 
272  libMesh::Real M = 0.0;
273  for(unsigned int v = 0; v < n_vars_found; v++ )
274  {
275  unsigned int s = chem.species_index(species_names[v]);
276  M += species_mole_fracs[v]*chem.M(s);
277  }
278 
279  const std::string& prefix = species_fe_var.prefix();
280 
281  for(unsigned int v = 0; v < n_vars_found; v++ )
282  {
283  // Finish computing species mass fraction
284  unsigned int s = chem.species_index(species_names[v]);
285  libMesh::Number species_mass_fracs = species_mole_fracs[v]*chem.M(s)/M;
286 
287  // Add the function
288  std::vector<VariableIndex> var_idx(1,species_fe_var.species(s));
289  libMesh::ConstFunction<libMesh::Number> const_func(species_mass_fracs);
290  composite_func.attach_subfunction(const_func,var_idx);
291 
292  // Log that we added this variable
293  vars_added.insert(prefix+species_names[v]);
294  }
295  }
296 
297  std::string MoleFractionsDirichletBCFactory::extract_var_section( const std::string& section ) const
298  {
299  std::vector<std::string> tokens;
300  StringUtilities::split_string(section,"/",tokens);
301  return tokens.back();
302  }
303 
304  // Instantiate
305 #ifdef GRINS_HAVE_CANTERA
306  template void MoleFractionsDirichletBCFactory::add_mole_frac_to_mass_frac<CanteraMixture>(const GetPot&,const std::string&,const std::set<std::string>&,const std::string&,const SpeciesMassFractionsVariable&,libMesh::CompositeFunction<libMesh::Number>&,std::set<std::string>& ) const;
307 #endif
308 
309 #ifdef GRINS_HAVE_ANTIOCH
310  template void MoleFractionsDirichletBCFactory::add_mole_frac_to_mass_frac<AntiochChemistry>(const GetPot&,const std::string&,const std::set<std::string>&,const std::string&,const SpeciesMassFractionsVariable&,libMesh::CompositeFunction<libMesh::Number>&,std::set<std::string>& ) const;
311 #endif
312 
313 } // end namespace GRINS
virtual void set_vars_to_search_for(const std::string &, 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.
VariableIndex species(unsigned int species) const
virtual void set_vars_to_search_for(const std::string &section, 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.
GRINS namespace.
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()
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 SpeciesMassFractionsVariable &species_fe_var, libMesh::CompositeFunction< libMesh::Number > &composite_func, std::set< std::string > &vars_added) const
Interface with libMesh for solving Multiphysics problems.
void build_chemistry(const GetPot &input, const std::string &material, libMesh::UniquePtr< ChemistryType > &chem_ptr)
std::string extract_var_section(const std::string &section) const
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.
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.
const std::string & material() const
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 Tue Dec 19 2017 12:47:27 for GRINS-0.8.0 by  doxygen 1.8.9.1