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 <memory>
38 #include <map>
39 
40 namespace schnek {
41 
42 class DependencyMap;
43 typedef std::shared_ptr<DependencyMap> pDependencyMap;
44 class Parameter;
45 typedef std::shared_ptr<Parameter> pParameter;
46 
48 {
49  private:
50  typedef std::set<long> ParameterSet;
51  ParameterSet parameters;
52  public:
53  void add(pParameter p);
54  void add(pVariable v);
55  bool isElement(pParameter p);
56  bool isElement(pVariable v);
57 
58  template<size_t rank, template<size_t> class CheckingPolicy>
60  {
61  for (size_t i=0; i<rank; ++i) add(pa[i]);
62  }
63 
64 
65  // This method has the side effect of modifying ids to the set containing all the values not
66  // contained in the group.
67  bool hasElements(std::set<long> &ids);
68 };
69 
70 typedef std::shared_ptr<ParametersGroup> pParametersGroup;
71 
72 
73 class Parameter
74 {
75  protected:
76  std::string varName;
77  pVariable variable;
78  pParametersGroup allowedDeps;
79  public:
80  Parameter(std::string varName_, pVariable variable_, pParametersGroup allowedDeps_)
81  : varName(varName_), variable(variable_), allowedDeps(allowedDeps_)
82  {}
83  virtual ~Parameter() {}
84 
85  bool canEvaluate() { return (variable) && (variable->isInitialised()); }
86  pVariable getVariable() { return variable; }
87  pParametersGroup getAllowedDeps() { return allowedDeps; }
88 
89 // bool depsAllowed(pDependencyMap deps);
90 
91  virtual void evaluate() = 0;
92  virtual void update() = 0;
93 };
94 
95 template<typename T>
97 {
98  protected:
99  T *value;
100  public:
101  ConcreteParameter(std::string varName_, pVariable variable_, T *value_, pParametersGroup allowedDeps_)
102  : Parameter(varName_, variable_, allowedDeps_), value(value_) {}
103 
104  void evaluate()
105  {
106  //std::cout << "Evaluating Parameter " << varName << "\n";
107  if (! variable->isInitialised())
108  throw VariableNotInitialisedException(varName);
109 
110  if (variable->isReadOnly())
111  {
112 // std::cout << " read only " << varName << "=" << *value << "\n";
113  return;
114  }
115 
116  if (variable->isConstant())
117  *value = boost::get<T>(variable->getValue());
118  else
119  *value = boost::get<T>(variable->evaluateExpression());
120  }
121 
122  void update()
123  {
124  if (variable->isReadOnly()) return;
125  *value = boost::get<T>(variable->getValue());
126  }
127 };
128 
129 
130 template<typename T>
132 {
133  protected:
134  public:
135  ConstantParameter(std::string varName_, pVariable variable_, const T &)
136  : Parameter(varName_, variable_, pParametersGroup(new ParametersGroup())) {}
137 
138  void evaluate()
139  {
140  return;
141  }
142 
143  void update()
144  {
145  return;
146  }
147 };
148 
150 {
151  private:
152  pBlockVariables block;
153  std::map<std::string, pParameter> parameterMap;
154  public:
155  typedef enum {readwrite, readonly} Permissions;
156  void setContext(pBlockVariables context)
157  {
158  block = context;
159  }
160 
161  pBlockVariables getContext()
162  {
163  return block;
164  }
165 
166 
167  template<typename T>
168  pParameter addParameter(std::string varName,
169  T* var,
170  pParametersGroup allowedDeps,
171  bool hasDefault = false,
172  const T &defaultValue = T(),
173  Permissions perm=readwrite)
174  {
175  pVariable variable;
176  if (perm==readwrite)
177  variable = pVariable(new Variable(defaultValue, hasDefault, false));
178  else
179  {
180  typedef std::shared_ptr<Expression<T> > ParExpression;
181  ParExpression pexp(new ExternalValue<T>(var));
182  if (hasDefault) *var = defaultValue;
183  variable = pVariable(new Variable(pexp, true, true));
184  }
185  block->addVariable(varName, variable);
186 
187  if (varName=="test4") std::cerr << "test4: ID = " << variable->getId();
188 
189  pParameter par(new ConcreteParameter<T>(varName, variable, var, allowedDeps));
190  parameterMap[varName] = par;
191  return par;
192  }
193 
194  template<typename T>
195  pParameter addParameter(std::string varName, T* var, Permissions perm=readwrite)
196  {
197  pParametersGroup empty(new ParametersGroup());
198  return addParameter(varName, var, empty, false, T(), perm);
199  }
200 
201  template<typename T>
202  pParameter addParameter(std::string varName, T* var, const T &defaultValue, Permissions perm=readwrite)
203  {
204  pParametersGroup empty(new ParametersGroup());
205  return addParameter(varName, var, empty, true, defaultValue, perm);
206  }
207 
208  template<typename T>
209  pParameter addConstant(std::string varName, const T &value)
210  {
211  pVariable variable(new Variable(value, true, true));
212  block->addVariable(varName, variable);
213 
214  pParameter par(new ConstantParameter<T>(varName, variable, value));
215  parameterMap[varName] = par;
216  return par;
217  }
218 
219  template<
220  class T,
221  size_t rank,
222  template<size_t> class CheckingPolicy
223  >
224  Array<pParameter, rank, CheckingPolicy> addArrayParameter(
225  std::string varName,
227  Permissions perm=readwrite,
228  std::string extension = "xyzuvw")
229  {
230  SCHNEK_REQUIRE(rank<=extension.length(), "addArrayParameter: extension string not long enough! Rank = "
231  + boost::lexical_cast<std::string>(rank) + ", extension.length = "+ boost::lexical_cast<std::string>(extension.length())
232  + " (\"" +extension+"\")");
234  for (int i=0; i<rank; ++i)
235  result[i] = addParameter(varName+extension[i], &(var[i]), perm);
236  return result;
237  }
238 
239  template<
240  class T,
241  size_t rank,
242  template<size_t> class CheckingPolicy
243  >
244  Array<pParameter, rank, CheckingPolicy> addArrayParameter(
245  std::string varName,
247  Array<T, rank, CheckingPolicy> default_values,
248  Permissions perm=readwrite,
249  std::string extension = "xyzuvw")
250  {
251  SCHNEK_REQUIRE(rank<=extension.length(), "addArrayParameter: extension string not long enough! Rank = "
252  + boost::lexical_cast<std::string>(rank) + ", extension.length = "+ boost::lexical_cast<std::string>(extension.length())
253  + " (\"" +extension+"\")");
255  for (int i=0; i<rank; ++i)
256  result[i] = addParameter(varName+extension[i], &(var[i]), default_values[i], perm);
257  return result;
258  }
259 
260  template<
261  class T,
262  size_t rank,
263  template<size_t> class CheckingPolicy
264  >
265  Array<pParameter, rank, CheckingPolicy> addArrayParameter(
266  std::string varName,
268  T default_value,
269  Permissions perm=readwrite,
270  std::string extension = "xyzuvw")
271  {
272  SCHNEK_REQUIRE(rank<=extension.length(), "addArrayParameter: extension string not long enough! Rank = "
273  + boost::lexical_cast<std::string>(rank) + ", extension.length = "+ boost::lexical_cast<std::string>(extension.length())
274  + " (\"" +extension+"\")");
276  for (int i=0; i<rank; ++i)
277  result[i] = addParameter(varName+extension[i], &(var[i]), default_value, perm);
278  return result;
279  }
280 
281  void evaluate()
282  {
283  typedef std::pair<std::string, pParameter> ParameterPair;
284  for(ParameterPair par: parameterMap)
285  {
286  par.second->evaluate();
287  }
288  }
289 };
290 
291 } //namespace
292 
293 #endif // SCHNEK_BLOCKPARAMETERS_HPP_
Definition: array.hpp:55
Definition: algo.hpp:30
Definition: blockparameters.hpp:131
Definition: expression.hpp:189
Definition: blockparameters.hpp:149
Definition: blockparameters.hpp:96
Definition: variables.hpp:58
Definition: blockparameters.hpp:47
Definition: blockparameters.hpp:73