Schnek
blockparameters.hpp
1 /*
2  * blockparameters.hpp
3  *
4  * Created on: 1 May 2012
5  * Author: Holger Schmitz
6  * Email: holger@notjustphysics.com
7  *
8  * Copyright 2012 Holger Schmitz
9  *
10  * This file is part of Schnek.
11  *
12  * Schnek is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * Schnek is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with Schnek. If not, see <http://www.gnu.org/licenses/>.
24  *
25  */
26 
27 #ifndef SCHNEK_BLOCKPARAMETERS_HPP_
28 #define SCHNEK_BLOCKPARAMETERS_HPP_
29 
30 #include "types.hpp"
31 #include "variables.hpp"
32 #include "expression.hpp"
33 
34 #include "../grid/array.hpp"
35 #include "../util/exceptions.hpp"
36 
37 #include <boost/foreach.hpp>
38 #include <boost/shared_ptr.hpp>
39 #include <map>
40 
41 namespace schnek {
42 
43 class DependencyMap;
44 typedef boost::shared_ptr<DependencyMap> pDependencyMap;
45 class Parameter;
46 typedef boost::shared_ptr<Parameter> pParameter;
47 
49 {
50  private:
51  typedef std::set<long> ParameterSet;
52  ParameterSet parameters;
53  public:
54  void add(pParameter p);
55  void add(pVariable v);
56  bool isElement(pParameter p);
57  bool isElement(pVariable v);
58 
59  template<int rank, template<int> class CheckingPolicy>
61  {
62  for (int i=0; i<rank; ++i) add(pa[i]);
63  }
64 
65 
66  // This method has the side effect of modifying ids to the set containing all the values not
67  // contained in the group.
68  bool hasElements(std::set<long> &ids);
69 };
70 
71 typedef boost::shared_ptr<ParametersGroup> pParametersGroup;
72 
73 
74 class Parameter
75 {
76  protected:
77  std::string varName;
78  pVariable variable;
79  pParametersGroup allowedDeps;
80  public:
81  Parameter(std::string varName_, pVariable variable_, pParametersGroup allowedDeps_)
82  : varName(varName_), variable(variable_), allowedDeps(allowedDeps_)
83  {}
84  virtual ~Parameter() {}
85 
86  bool canEvaluate() { return (variable) && (variable->isInitialised()); }
87  pVariable getVariable() { return variable; }
88  pParametersGroup getAllowedDeps() { return allowedDeps; }
89 
90 // bool depsAllowed(pDependencyMap deps);
91 
92  virtual void evaluate() = 0;
93  virtual void update() = 0;
94 };
95 
96 template<typename T>
98 {
99  protected:
100  T *value;
101  public:
102  ConcreteParameter(std::string varName_, pVariable variable_, T *value_, pParametersGroup allowedDeps_)
103  : Parameter(varName_, variable_, allowedDeps_), value(value_) {}
104 
105  void evaluate()
106  {
107  //std::cout << "Evaluating Parameter " << varName << "\n";
108  if (! variable->isInitialised())
109  throw VariableNotInitialisedException(varName);
110 
111  if (variable->isReadOnly())
112  {
113 // std::cout << " read only " << varName << "=" << *value << "\n";
114  return;
115  }
116 
117  if (variable->isConstant())
118  *value = boost::get<T>(variable->getValue());
119  else
120  *value = boost::get<T>(variable->evaluateExpression());
121  }
122 
123  void update()
124  {
125  if (variable->isReadOnly()) return;
126  *value = boost::get<T>(variable->getValue());
127  }
128 };
129 
130 
131 template<typename T>
133 {
134  protected:
135  public:
136  ConstantParameter(std::string varName_, pVariable variable_, const T &value_)
137  : Parameter(varName_, variable_, pParametersGroup(new ParametersGroup())) {}
138 
139  void evaluate()
140  {
141  return;
142  }
143 
144  void update()
145  {
146  return;
147  }
148 };
149 
151 {
152  private:
153  pBlockVariables block;
154  std::map<std::string, pParameter> parameterMap;
155  public:
156  typedef enum {readwrite, readonly} Permissions;
157  void setContext(pBlockVariables context)
158  {
159  block = context;
160  }
161 
162  pBlockVariables getContext()
163  {
164  return block;
165  }
166 
167 
168  template<typename T>
169  pParameter addParameter(std::string varName,
170  T* var,
171  pParametersGroup allowedDeps,
172  bool hasDefault = false,
173  const T &defaultValue = T(),
174  Permissions perm=readwrite)
175  {
176  pVariable variable;
177  if (perm==readwrite)
178  variable = pVariable(new Variable(defaultValue, hasDefault, false));
179  else
180  {
181  typedef boost::shared_ptr<Expression<T> > ParExpression;
182  ParExpression pexp(new ExternalValue<T>(var));
183  if (hasDefault) *var = defaultValue;
184  variable = pVariable(new Variable(pexp, true, true));
185  }
186  block->addVariable(varName, variable);
187 
188  if (varName=="test4") std::cerr << "test4: ID = " << variable->getId();
189 
190  pParameter par(new ConcreteParameter<T>(varName, variable, var, allowedDeps));
191  parameterMap[varName] = par;
192  return par;
193  }
194 
195  template<typename T>
196  pParameter addParameter(std::string varName, T* var, Permissions perm=readwrite)
197  {
198  pParametersGroup empty(new ParametersGroup());
199  return addParameter(varName, var, empty, false, T(), perm);
200  }
201 
202  template<typename T>
203  pParameter addParameter(std::string varName, T* var, const T &defaultValue, Permissions perm=readwrite)
204  {
205  pParametersGroup empty(new ParametersGroup());
206  return addParameter(varName, var, empty, true, defaultValue, perm);
207  }
208 
209  template<typename T>
210  pParameter addConstant(std::string varName, const T &value)
211  {
212  pVariable variable(new Variable(value, true, true));
213  block->addVariable(varName, variable);
214 
215  pParameter par(new ConstantParameter<T>(varName, variable, value));
216  parameterMap[varName] = par;
217  return par;
218  }
219 
220  template<
221  class T,
222  int rank,
223  template<int> class CheckingPolicy
224  >
225  Array<pParameter, rank, CheckingPolicy> addArrayParameter(
226  std::string varName,
228  Permissions perm=readwrite,
229  std::string extension = "xyzuvw")
230  {
231  SCHNEK_REQUIRE(rank<=extension.length(), "addArrayParameter: extension string not long enough! Rank = "
232  + boost::lexical_cast<std::string>(rank) + ", extension.length = "+ boost::lexical_cast<std::string>(extension.length())
233  + " (\"" +extension+"\")");
235  for (int i=0; i<rank; ++i)
236  result[i] = addParameter(varName+extension[i], &(var[i]), perm);
237  return result;
238  }
239 
240  template<
241  class T,
242  int rank,
243  template<int> class CheckingPolicy
244  >
245  Array<pParameter, rank, CheckingPolicy> addArrayParameter(
246  std::string varName,
248  Array<T, rank, CheckingPolicy> default_values,
249  Permissions perm=readwrite,
250  std::string extension = "xyzuvw")
251  {
252  SCHNEK_REQUIRE(rank<=extension.length(), "addArrayParameter: extension string not long enough! Rank = "
253  + boost::lexical_cast<std::string>(rank) + ", extension.length = "+ boost::lexical_cast<std::string>(extension.length())
254  + " (\"" +extension+"\")");
256  for (int i=0; i<rank; ++i)
257  result[i] = addParameter(varName+extension[i], &(var[i]), default_values[i], perm);
258  return result;
259  }
260 
261  template<
262  class T,
263  int rank,
264  template<int> class CheckingPolicy
265  >
266  Array<pParameter, rank, CheckingPolicy> addArrayParameter(
267  std::string varName,
269  T default_value,
270  Permissions perm=readwrite,
271  std::string extension = "xyzuvw")
272  {
273  SCHNEK_REQUIRE(rank<=extension.length(), "addArrayParameter: extension string not long enough! Rank = "
274  + boost::lexical_cast<std::string>(rank) + ", extension.length = "+ boost::lexical_cast<std::string>(extension.length())
275  + " (\"" +extension+"\")");
277  for (int i=0; i<rank; ++i)
278  result[i] = addParameter(varName+extension[i], &(var[i]), default_value, perm);
279  return result;
280  }
281 
282  void evaluate()
283  {
284  typedef std::pair<std::string, pParameter> ParameterPair;
285  BOOST_FOREACH(ParameterPair par, parameterMap)
286  {
287  par.second->evaluate();
288  }
289  }
290 };
291 
292 } //namespace
293 
294 #endif // SCHNEK_BLOCKPARAMETERS_HPP_
Definition: array.hpp:49
Definition: algo.hpp:30
Definition: blockparameters.hpp:132
Definition: expression.hpp:184
Definition: blockparameters.hpp:150
Definition: blockparameters.hpp:97
Definition: variables.hpp:53
Definition: blockparameters.hpp:48
Definition: blockparameters.hpp:74