OpenFCST: The open-source Fuel Cell Simulation Toolbox
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
initial_and_boundary_data.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 //
3 // FCST: Fuel Cell Simulation Toolbox
4 //
5 // Copyright (C) 2006-2013 by Energy Systems Design Laboratory, University of Alberta
6 //
7 // This software is distributed under the MIT License
8 // For more information, see the README file in /doc/LICENSE
9 //
10 // - Class: initial_and_boundary_data.h
11 // - Description: This namespace contains data and methods
12 // that handle initial and boundary data of
13 // a problem at hand
14 // - Developers: Valentin N. Zingan, University of Alberta
15 // - Id: $Id: initial_and_boundary_data.h 1384 2013-08-22 21:40:07Z zingan $
16 //
17 // ----------------------------------------------------------------------------
18 
19 #ifndef _FCST_FUELCELL_INITIAL_AND_BOUNDARY_DATA_H_
20 #define _FCST_FUELCELL_INITIAL_AND_BOUNDARY_DATA_H_
21 
22 #define _IS_NOT_CONSTANT_ 1.e300
23 
24 #include <boost/lexical_cast.hpp>
25 
26 #include <base/point.h>
27 #include <base/function.h>
28 
29 #include <lac/vector.h>
30 #include <lac/block_vector.h>
31 #include <lac/block_sparse_matrix.h>
32 
33 #include <dofs/function_map.h>
34 
35 #include <fe/mapping_q1.h>
36 #include <fe/mapping_q.h>
37 
38 #include <numerics/vector_tools.h>
39 #include <numerics/matrix_tools.h>
40 
41 #include "system_management.h"
42 #include "solver_utils.h"
43 
44 using namespace dealii;
45 using namespace AppFrame;
46 
56 typedef std::map< std::string , std::map<types::material_id, double> > component_materialID_value_map;
57 
67 typedef std::map< std::string , std::map<types::boundary_id, double> > component_boundaryID_value_map;
68 
77 namespace FuelCell
78 {
79 namespace InitialAndBoundaryData
80 {
81 
87  template<typename COMPONENT_xxxID_VALUE_MAP>
88  const bool check(const
89  std::vector< COMPONENT_xxxID_VALUE_MAP >& maps)
90  {
91  // --- types info ---
92 
93  const std::type_info& material = typeid(component_materialID_value_map);
94  const std::type_info& boundary = typeid(component_boundaryID_value_map);
95 
96  const std::type_info& info = typeid(COMPONENT_xxxID_VALUE_MAP);
97 
98  // --- checkings ---
99 
100  // --- 1 ---
101 
102  if( maps.size() == 0 )
103  {
104  std::cerr << "The argument is empty" << std::endl;
105  return false;
106  }
107 
108  // --- 2 ---
109 
110  for(unsigned int i = 0; i < maps.size(); ++i)
111  if( maps[i].empty() )
112  {
113  std::cerr << "Outer map/maps of the argument is/are empty" << std::endl;
114  return false;
115  }
116 
117  // --- 3 ---
118 
119  for(unsigned int i = 0; i < maps.size(); ++i)
120  for(typename COMPONENT_xxxID_VALUE_MAP::const_iterator iter = maps[i].begin();
121  iter != maps[i].end();
122  ++iter)
123  if( iter->second.empty() )
124  {
125  std::cerr << "Inner map/maps of the argument is/are empty" << std::endl;
126  return false;
127  }
128 
129  // --- 4 ---
130 
131  if( info == material )
132  for(unsigned int i = 0; i < maps.size(); ++i)
133  for(typename COMPONENT_xxxID_VALUE_MAP::const_iterator iter = maps[i].begin();
134  iter != maps[i].end();
135  ++iter)
136  if( iter->second.find(numbers::invalid_material_id) != iter->second.end() )
137  {
138  std::cerr << "Invalid material id/ids of the argument" << std::endl;
139  return false;
140  }
141 
142  if( info == boundary )
143  for(unsigned int i = 0; i < maps.size(); ++i)
144  for(typename COMPONENT_xxxID_VALUE_MAP::const_iterator iter = maps[i].begin();
145  iter != maps[i].end();
146  ++iter)
147  if( iter->second.find(numbers::invalid_boundary_id) != iter->second.end() )
148  {
149  std::cerr << "Invalid boundary id/ids of the argument" << std::endl;
150  return false;
151  }
152 
153  return true;
154  }
155 
160  template<typename VECTOR, typename DH>
163  const DH& dof,
164  const FuelCell::SystemManagement& system_management,
165  const std::vector< component_materialID_value_map >& maps)
166  {
167  // --- checking ---
168 
169  AssertThrow( FuelCell::InitialAndBoundaryData::check< component_materialID_value_map >(maps),
170  ExcMessage("The last argument in the FuelCell::InitialAndBoundaryData::make_piece_wise_constant_initial_data function "
171  "is wrong : check the previous message") );
172 
173  // --- main ---
174 
175  const unsigned int n_components = system_management.get_number_of_solution_names();
176  AssertThrow( n_components == dof.get_fe().n_components(),
177  ExcDimensionMismatch( n_components , dof.get_fe().n_components() ) );
178 
179  for(unsigned int i = 0; i < maps.size(); ++i)
180  for(component_materialID_value_map::const_iterator iter = maps[i].begin();
181  iter != maps[i].end();
182  ++iter)
183  {
184  std::map<types::material_id, double> tmp = iter->second;
185 
186  for(std::map<types::material_id, double>::const_iterator iter2 = tmp.begin();
187  iter2 != tmp.end();
188  ++iter2)
189  {
190  if( iter2->second != _IS_NOT_CONSTANT_ )
191  {
192  typename FunctionMap<DH::space_dimension>::type2 function_map;
193 
194  const ConstantFunction<DH::space_dimension> constant_function(iter2->second, n_components);
195  function_map[boost::lexical_cast<unsigned int>(iter2->first)] = &constant_function;
196 
197  std::vector<bool> component_mask(n_components, false);
198  component_mask[system_management.solution_name_to_index(iter->first)] = true;
199 
200  VectorTools::interpolate( dst,
201  mapping,
202  dof,
203  function_map,
204  component_mask );
205  }
206  }
207  }
208  }
209 
214  template<typename VECTOR, typename DH>
217  const DH& dof,
218  const FuelCell::SystemManagement& system_management,
219  const std::vector< component_boundaryID_value_map >& maps)
220  {
221  // --- checking ---
222 
223  AssertThrow( FuelCell::InitialAndBoundaryData::check< component_boundaryID_value_map >(maps),
224  ExcMessage("The last argument in the FuelCell::InitialAndBoundaryData::apply_piece_wise_constant_DirichletBCs function "
225  "is wrong : check the previous message") );
226 
227  // --- main ---
228 
229  const unsigned int n_components = system_management.get_number_of_solution_names();
230  AssertThrow( n_components == dof.get_fe().n_components(),
231  ExcDimensionMismatch( n_components , dof.get_fe().n_components() ) );
232 
233  for(unsigned int i = 0; i < maps.size(); ++i)
234  for(component_boundaryID_value_map::const_iterator iter = maps[i].begin();
235  iter != maps[i].end();
236  ++iter)
237  {
238  std::map<types::boundary_id, double> tmp = iter->second;
239 
240  for(std::map<types::boundary_id, double>::const_iterator iter2 = tmp.begin();
241  iter2 != tmp.end();
242  ++iter2)
243  {
244  if( iter2->second != _IS_NOT_CONSTANT_ )
245  {
246  typename FunctionMap<DH::space_dimension>::type function_map;
247 
248  const ConstantFunction<DH::space_dimension> constant_function(iter2->second, n_components);
249  function_map[boost::lexical_cast<unsigned int>(iter2->first)] = &constant_function;
250 
251  std::vector<bool> component_mask(n_components, false);
252  component_mask[system_management.solution_name_to_index(iter->first)] = true;
253 
254  std::map<unsigned int, double> boundary_values;
255 
256  VectorTools::interpolate_boundary_values( mapping,
257  dof,
258  function_map,
259  boundary_values,
260  component_mask );
261 
262  for(std::map<unsigned int, double>::const_iterator iter3 = boundary_values.begin();
263  iter3 != boundary_values.end();
264  ++iter3)
265  {
266  dst(iter3->first) = iter3->second;
267  }
268  }
269  }
270  }
271  }
272 
277  template<typename DH>
278  void make_zero_boundary_values(std::map<unsigned int, double>& dst,
280  const DH& dof,
281  const FuelCell::SystemManagement& system_management,
282  const std::vector< component_boundaryID_value_map >& maps)
283  {
284  // --- checking ---
285 
286  AssertThrow( FuelCell::InitialAndBoundaryData::check< component_boundaryID_value_map >(maps),
287  ExcMessage("The last argument in the FuelCell::InitialAndBoundaryData::make_zero_boundary_values function "
288  "is wrong : check the previous message") );
289 
290  // --- main ---
291 
292  const unsigned int n_components = system_management.get_number_of_solution_names();
293  AssertThrow( n_components == dof.get_fe().n_components(),
294  ExcDimensionMismatch( n_components , dof.get_fe().n_components() ) );
295 
296  for(unsigned int i = 0; i < maps.size(); ++i)
297  for(component_boundaryID_value_map::const_iterator iter = maps[i].begin();
298  iter != maps[i].end();
299  ++iter)
300  {
301  std::map<types::boundary_id, double> tmp = iter->second;
302 
303  for(std::map<types::boundary_id, double>::const_iterator iter2 = tmp.begin();
304  iter2 != tmp.end();
305  ++iter2)
306  {
307  typename FunctionMap<DH::space_dimension>::type function_map;
308 
309  const ZeroFunction<DH::space_dimension> zero_function(n_components);
310  function_map[boost::lexical_cast<unsigned int>(iter2->first)] = &zero_function;
311 
312  std::vector<bool> component_mask(n_components, false);
313  component_mask[system_management.solution_name_to_index(iter->first)] = true;
314 
315  VectorTools::interpolate_boundary_values( mapping,
316  dof,
317  function_map,
318  dst,
319  component_mask );
320  }
321  }
322  }
323 
329  template<typename MATRIX, typename VECTOR, typename DH>
331  VECTOR& solution,
332  VECTOR& rhs,
334  const DH& dof,
335  const FuelCell::SystemManagement& system_management,
336  const std::vector< component_boundaryID_value_map >& maps,
337  const bool& repair_diagonal = false)
338  {
339  if( repair_diagonal )
340  {
341  SolverUtils solver_utils;
342  solver_utils.repair_diagonal( matrix,
343  solution,
344  rhs );
345  }
346 
347  std::map<unsigned int, double> boundary_values;
348  FuelCell::InitialAndBoundaryData::make_zero_boundary_values<DH>( boundary_values,
349  mapping,
350  dof,
351  system_management,
352  maps );
353  MatrixTools::apply_boundary_values( boundary_values,
354  matrix,
355  solution,
356  rhs );
357  }
358 
366 template<int dim>
367 class InitialOrBoundaryDataBase : public Function<dim>
368 {
369 public:
370 
372 
373 
381  virtual double value(const Point<dim>& point,
382  const unsigned int no_component = 0) const;
383 
385 
386 protected:
387 
389 
390 
397  InitialOrBoundaryDataBase(const unsigned int n_components = 1);
398 
403 
405 
407 
408 
416  virtual double math_expression(const Point<dim>& point,
417  const unsigned int no_component = 0) const;
418 
420 
422 
423 
430  void print_caller_name(const std::string& caller_name) const;
431 
433 
434 };
435 
436 } // InitialAndBoundaryData
437 
438 } // FuelCell
439 
440 #endif