deal2lkit: A ToolKit library for Deal.II
parsed_mapped_functions.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------
2 //
3 // Copyright (C) 2015 by the deal2lkit authors
4 //
5 // This file is part of the deal2lkit library.
6 //
7 // The deal2lkit library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal2lkit distribution.
13 //
14 //-----------------------------------------------------------
15 
17 
18 
19 D2K_NAMESPACE_OPEN
20 
21 template <int spacedim>
23  const unsigned int &n_components,
24  const std::string &parsed_component_names,
25  const std::string &parsed_id_components,
26  const std::string &parsed_id_functions,
27  const std::string &parsed_constants):
28  ParameterAcceptor(parsed_name),
29  name (parsed_name),
30  str_id_components (parsed_id_components),
31  str_id_functions (parsed_id_functions),
32  str_component_names (parsed_component_names),
33  str_constants (parsed_constants),
34  n_components(n_components)
35 {}
36 
37 template <int spacedim>
39 {
40  std::vector<std::string> var = unique(_component_names);
41  for (unsigned int i=0; i<var.size(); ++i)
42  {
43  int n = std::count(_component_names.begin(),_component_names.end(), var[i]);
44  if (n>1)
45  {
46  _normal_components.push_back(var[i]+".N");
47  int pos = std::find(_component_names.begin(),_component_names.end(), var[i]) - _component_names.begin();
48  std::pair<unsigned int, std::string> nc (pos, var[i]+".N");
49  normal_components.push_back(nc);
50  }
51  }
52 }
53 
54 template <int spacedim>
56 {
59  for (unsigned int i=0; i<_normal_components.size(); ++i)
60  {
61  _all_components.push_back(_normal_components[i]);
62  }
65  AssertThrow(id_components.size() == id_functions.size(),
66  ExcIdsMismatch(id_components.size(), id_functions.size()));
67 
68  typedef std::map<unsigned int, ComponentMask>::iterator it_type;
69  for (it_type it=id_components.begin(); it != id_components.end(); ++it)
70  {
71  std::pair<ComponentMask, shared_ptr<dealii::Functions::ParsedFunction<spacedim> > > mapped(it->second, id_functions[it->first]);
72 
73  mapped_functions[it->first] = mapped;
74 
75  }
76 
78 
79 }
80 
81 template <int spacedim>
82 void ParsedMappedFunctions<spacedim>::split_id_components(const std::string &parsed_idcomponents)
83 {
84  std::vector<std::string> idcomponents;
85 
86  idcomponents = Utilities::split_string_list(parsed_idcomponents, '%');
87 
88  for (unsigned int i=0; i<idcomponents.size(); ++i)
89  {
90  std::vector<std::string> id_comp;
91  std::vector<std::string> components;
92  std::vector<bool> mask(n_components,false);
93 
94  id_comp = Utilities::split_string_list(idcomponents[i], '=');
95 
96  unsigned int id = Utilities::string_to_int(id_comp[0]);
97  ids.push_back(id);
98 
99  components = Utilities::split_string_list(id_comp[1], ';');
100  AssertThrow(components.size() <= n_components,
101  ExcMessage("Wrong number of components specified for id " + id_comp[0]));
102  for (unsigned int c=0; c<components.size(); ++c)
103  {
104  if (components[c] == "ALL")
105  {
106  for (unsigned int j=0; j<n_components; ++j)
107  mask[j] = true;
108  break;
109  }
110 
112  ExcMessage("Parsed components name must match the number of components of the problem"));
113 
114  if ((std::find(_component_names.begin(), _component_names.end(), components[c]) != _component_names.end()))
115  for (unsigned int j=0; j<_component_names.size(); ++j)
116  mask[j] = (_component_names[j] == components[c] || mask[j]);
117 
118  else if ((std::find(_normal_components.begin(), _normal_components.end(), components[c]) != _normal_components.end()))
119  {
120  normal_ids.push_back(id);
121  for (unsigned int j=0; j<normal_components.size(); ++j)
122  if (normal_components[j].second == components[c])
123  {
124  mapped_normal_components[components[c]].second = normal_components[j].first;
125  mapped_normal_components[components[c]].first.push_back(id);
126  }
127  }
128  else
129  {
130  try
131  {
132  unsigned int m = Utilities::string_to_int(components[c]);
133  AssertThrow(m < n_components, ExcWrongComponent(id,m,n_components));
134  mask[m] = true;
135  }
136  catch (std::exception &exc)
137  AssertThrow(false, ExcWrongVariable(id,components[c],_all_components));
138  }
139 
140  }
141  id_components[id] = ComponentMask(mask);
142  }
143 }
144 
145 template <int spacedim>
146 void ParsedMappedFunctions<spacedim>::split_id_functions(const std::string &parsed_idfunctions,
147  const std::string &constants)
148 {
149  std::vector<unsigned int> id_defined_functions;
150 
151  // if it is empty a ZeroFunction<dim>(n_components) is applied on the
152  // parsed ids in the components
153  if (parsed_idfunctions == "")
154  {
155  for (unsigned int i=0; i<ids.size(); ++i)
156  {
157  id_defined_functions.push_back(ids[i]);
158  shared_ptr<dealii::Functions::ParsedFunction<spacedim> > ptr;
159 
160  ParameterHandler internal_prm;
161  dealii::Functions::ParsedFunction<spacedim>::declare_parameters(internal_prm, n_components);
162  ptr = SP(new dealii::Functions::ParsedFunction<spacedim>(n_components));
163  ptr->parse_parameters(internal_prm);
164 
165  id_functions[ids[i]] = ptr;
166  std::string str;
167  for (unsigned int j=0; j<n_components-1; ++j)
168  str += "0;";
169  str+="0";
170 
171  id_str_functions[ids[i]] = str;
172 
173  }
174  }
175  else
176  {
177 
178 
179  std::vector<std::string> idfunctions;
180  idfunctions = Utilities::split_string_list(parsed_idfunctions, '%');
181 
182  for (unsigned int i=0; i<idfunctions.size(); ++i)
183  {
184  std::vector<std::string> id_func;
185 
186  id_func = Utilities::split_string_list(idfunctions[i], '=');
187 
188  unsigned int id = Utilities::string_to_int(id_func[0]);
189  id_str_functions[id] = id_func[1];
190 
191  // check if the current id is also defined in id_components
192  AssertThrow((std::find(ids.begin(), ids.end(), id) != ids.end()),
193  ExcIdNotMatch(id));
194  id_defined_functions.push_back(id);
195 
196  shared_ptr<dealii::Functions::ParsedFunction<spacedim> > ptr;
197 
198  ParameterHandler internal_prm;
199  dealii::Functions::ParsedFunction<spacedim>::declare_parameters(internal_prm, n_components);
200  internal_prm.set("Function expression", id_func[1]);
201  internal_prm.set("Function constants", constants);
202  ptr = SP(new dealii::Functions::ParsedFunction<spacedim>(n_components));
203  ptr->parse_parameters(internal_prm);
204 
205  id_functions[id] = ptr;
206 
207 
208  }
209  }
210 
211  // check if the number of ids defined in id_components and id_functions are the same
212  AssertThrow(ids.size() == id_defined_functions.size(),
213  ExcMessage("Ids associated to components and to functions are not the same."));
214 
215 }
216 
217 template <int spacedim>
218 shared_ptr<dealii::Functions::ParsedFunction<spacedim> >
219 ParsedMappedFunctions<spacedim>::get_mapped_normal_function(const unsigned int &id, const unsigned int &fcv) const
220 {
221  std::pair<unsigned int, unsigned int> id_fcv (id,fcv);
222  Assert( _normal_functions.find(id_fcv) != _normal_functions.end(),
223  ExcIdNotFound(id));
224 
225  return _normal_functions.at(id_fcv);
226 }
227 
228 template <int spacedim>
229 shared_ptr<dealii::Functions::ParsedFunction<spacedim> > ParsedMappedFunctions<spacedim>::get_mapped_function(const unsigned int &id) const
230 {
231  Assert( mapped_functions.find(id) != mapped_functions.end(),
232  ExcIdNotFound(id));
233  return mapped_functions.at(id).second;
234 }
235 
236 template <int spacedim>
238 {
239  Assert( mapped_functions.find(id) != mapped_functions.end(),
240  ExcIdNotFound(id));
241  return mapped_functions.at(id).first;
242 }
243 
244 template <int spacedim>
245 std::vector<unsigned int> ParsedMappedFunctions<spacedim>::get_mapped_ids() const
246 {
247  return ids;
248 }
249 
250 template <int spacedim>
252 {
253  return normal_ids;
254 }
255 
256 template <int spacedim>
258 {
259  if (str_component_names != "")
260  add_parameter(prm, &_component_names, "Known component names", str_component_names,
262  "These variables can be used to set the corrisponding component mask, "
263  "instead of specifying each component number");
264 
265  else
266  {
267  std::vector<std::string> cn(n_components, "u");
268  add_parameter(prm, &_component_names, "Known component names", print(cn),
270  "These variables can be used to set the corrisponding component mask, "
271  "instead of specifying each component number");
272 
273  }
274  add_parameter(prm, &str_id_components, "IDs and component masks", str_id_components,
276  "Pattern to be used "
277  "id followed by '=' component masks separated by ';' "
278  "each couple of id and mask is separated by '%' "
279  "0=0;1;2 % 4=u;p % 2=3 % 5=ALL "
280  "You can specify the components either by numbers "
281  "or by the corrisponding variable name, which are parsed at "
282  "construction time. "
283  "The keyword 'ALL' means all the components. "
284  "Normal component is referred with suffix N "
285  "e.g. uN means the normal component of u. "
286  "note that the normal component can be set only "
287  "for a vector variable.");
288 
289  add_parameter(prm, &str_id_functions, "IDs and expressions", str_id_functions,
291  "Pattern to be used "
292  "id followed by '=' component separated by ';' "
293  "each couple of id and expression _id_functions separated by '%' "
294  "0=x;y;k;0 % 4=sin(x);cos(y);2*k;1 % 2=0;0;0;0 "
295  "If it is left empty, a ZeroFunction<dim>(n_components) "
296  "is applied on the parsed ids in the components. ");
297 
298  add_parameter(prm, &str_constants , "Used constants", str_constants, Patterns::Anything(),
299  "Costants which are employed in the definitions of the function expressions. "
300  "The pattern to be used is "
301  "constant_name=value , other_constant=other_value");
302 
303 }
304 
305 template <int spacedim>
307 {
308  return id_components.find(id) != id_components.end();
309 }
310 
311 template <int spacedim>
313 {
314  typedef typename std::map<unsigned int, shared_ptr<dealii::Functions::ParsedFunction<spacedim> > >::iterator it_type;
315  for (it_type it=id_functions.begin(); it != id_functions.end(); ++it)
316  it->second->set_time(t);
317 }
318 
319 template <int spacedim>
321 {
322  typedef std::map<std::string, std::pair<std::vector<unsigned int>, unsigned int > >::iterator it_type;
323 
324  for (it_type it=mapped_normal_components.begin(); it != mapped_normal_components.end(); ++it)
325  {
326 
327  std::vector<unsigned int> normal_ids = (it->second).first;
328  unsigned int fcv = (it->second).second; // unsigned int first component vector
329 
330  for (unsigned int i=0; i<normal_ids.size(); ++i)
331  {
332  std::vector<std::string> normal_func;
333  normal_func = Utilities::split_string_list(id_str_functions[normal_ids[i]], ';');
334  shared_ptr<dealii::Functions::ParsedFunction<spacedim> > normal_ptr;
335 
336  ParameterHandler normal_prm;
337  dealii::Functions::ParsedFunction<spacedim>::declare_parameters(normal_prm, spacedim);
338  std::string str_normal_func;
339  Assert(spacedim>1, ExcNotImplemented());
340  for (unsigned int j=0; j<spacedim-1; ++j)
341  str_normal_func += normal_func[fcv+j] + ";";
342  str_normal_func += normal_func[fcv+spacedim-1];
343 
344  normal_prm.set("Function expression", str_normal_func);
345  normal_prm.set("Function constants", str_constants);
346  normal_ptr = SP(new dealii::Functions::ParsedFunction<spacedim>(spacedim));
347  normal_ptr->parse_parameters(normal_prm);
348  std::pair<unsigned int, unsigned int> id_fcv (normal_ids[i],fcv);
349  _normal_functions[id_fcv]=normal_ptr;
350  }
351  }
352 }
353 
354 
355 D2K_NAMESPACE_CLOSE
356 
357 template class deal2lkit::ParsedMappedFunctions<1>;
358 template class deal2lkit::ParsedMappedFunctions<2>;
359 template class deal2lkit::ParsedMappedFunctions<3>;
A parameter acceptor base class.
const unsigned int n_components
static ParameterHandler prm
Static parameter.
std::vector< std::pair< unsigned int, std::string > > normal_components
std::map< unsigned int, std::string > id_str_functions
std::vector< unsigned int > ids
void set(const std::string &entry_name, const std::string &new_value)
std::vector< unsigned int > get_mapped_normal_ids() const
return the list of the mapped ids for which normal components have been set
std::vector< unsigned int > normal_ids
#define AssertThrow(cond, exc)
shared_ptr< T > SP(T *t)
Construct a shared pointer to a non const class T.
Definition: utilities.h:483
std::vector< std::string > _component_names
std::vector< unsigned int > get_mapped_ids() const
return the list of the mapped ids
std::map< unsigned int, shared_ptr< dealii::Functions::ParsedFunction< spacedim > > > id_functions
void set_time(const double &t)
set time equal to t for all the mapped functions
static::ExceptionBase & ExcMessage(std::string arg1)
std::map< std::string, std::pair< std::vector< unsigned int >, unsigned int > > mapped_normal_components
void split_id_components(const std::string &parsed_idcomponents)
virtual void parse_parameters_call_back()
parse_parameters_call_back is inherithed by ParameterAcceptor
#define Assert(cond, exc)
void split_id_functions(const std::string &parsed_idfunctions, const std::string &constants)
std::map< std::pair< unsigned int, unsigned int >, shared_ptr< dealii::Functions::ParsedFunction< spacedim > > > _normal_functions
virtual void declare_parameters(ParameterHandler &prm)
declare_parameters is inherithed by ParameterAcceptor
std::map< unsigned int, std::pair< ComponentMask, shared_ptr< dealii::Functions::ParsedFunction< spacedim > > > > mapped_functions
std::string print(const std::vector< Type > &list, const std::string sep=",")
Return a string containing the content of the vector, with elements separated by the @ sep parameter...
Definition: utilities.h:425
bool acts_on_id(unsigned int &id) const
return true if there is a function that acts on the passed id
std::vector< std::string > _normal_components
std::vector< std::string > split_string_list(const std::string &s, const char delimiter=',')
std::vector< T > unique(const std::vector< T > &myvector)
A simple function that accepts a vector as an input and returns a second vector containing only the u...
Definition: utilities.h:412
ParsedMappedFunctions(const std::string &name="Mapped Functions", const unsigned int &n_components=1, const std::string &component_names="", const std::string &default_id_components="0=ALL", const std::string &default_id_functions="", const std::string &default_constants="")
Constructor.
int string_to_int(const std::string &s)
static::ExceptionBase & ExcNotImplemented()
shared_ptr< dealii::Functions::ParsedFunction< spacedim > > get_mapped_function(const unsigned int &id) const
return a shared_ptr to the ParsedFunction corresponding to the given id
void add_parameter(ParameterHandler &prm, T *parameter, const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation=std::string())
Add a parameter the given parameter list.
shared_ptr< dealii::Functions::ParsedFunction< spacedim > > get_mapped_normal_function(const unsigned int &id, const unsigned int &fcv) const
return a shared_ptr to the ParsedFunction corresponding to the given id the function has spacedim com...
std::map< unsigned int, ComponentMask > id_components
ComponentMask get_mapped_mask(const unsigned int &id) const
return the ComponentMask corresponding to the given id
std::vector< std::string > _all_components