FLAME  devel
 All Classes Functions Variables Typedefs Enumerations Pages
base.h
1 #ifndef FLAME_BASE_H
2 #define FLAME_BASE_H
3 
4 #include <stdlib.h>
5 
6 #include <ostream>
7 #include <string>
8 #include <map>
9 #include <vector>
10 #include <utility>
11 
12 #include <boost/noncopyable.hpp>
13 #include <boost/any.hpp>
14 #include <boost/shared_ptr.hpp>
15 #include <boost/call_traits.hpp>
16 
17 #include "config.h"
18 #include "util.h"
19 
20 #define FLAME_API_VERSION 0
21 
22 struct ElementVoid;
23 
28 struct StateBase : public boost::noncopyable
29 {
30  virtual ~StateBase();
31 
34  size_t next_elem;
35 
36  double pos;
37 
41  virtual void assign(const StateBase& other) =0;
42 
45  virtual void show(std::ostream&, int level =0) const {}
46 
48  struct ArrayInfo {
49  enum {maxdims=3};
50  ArrayInfo() :name(0), type(Double), ptr(NULL), ndim(0) {}
52  const char *name;
54  enum Type {
55  Double, Sizet
56  } type;
59  void *ptr;
64  unsigned ndim;
66  size_t dim[maxdims];
68  size_t stride[maxdims];
69 
71  bool inbounds(size_t* d) const {
72  bool ret = true;
73  switch(ndim) {
74  case 3: ret &= d[2]<dim[2];
75  case 2: ret &= d[1]<dim[1];
76  case 1: ret &= d[0]<dim[0];
77  }
78  return ret;
79  }
80 
81  void *raw(size_t* d) {
82  char *ret = (char*)ptr;
83  switch(ndim) {
84  case 3: ret += d[2]*stride[2];
85  case 2: ret += d[1]*stride[1];
86  case 1: ret += d[0]*stride[0];
87  }
88  return ret;
89  }
90 
92  template<typename E>
93  inline E* get(size_t *d) {
94  return (E*)raw(d);
95  }
96  };
97 
118  virtual bool getArray(unsigned index, ArrayInfo& Info);
119 
122  virtual StateBase* clone() const =0;
123 
126  void *pyptr;
127 protected:
132  StateBase(const Config& c);
134  struct clone_tag{};
136  StateBase(const StateBase& c, clone_tag);
137 };
138 
139 inline
140 std::ostream& operator<<(std::ostream& strm, const StateBase& s)
141 {
142  s.show(strm, 0);
143  return strm;
144 }
145 
153 struct Observer : public boost::noncopyable
154 {
155  virtual ~Observer() {}
157  virtual void view(const ElementVoid* elem, const StateBase* state) =0;
158 };
159 
166 struct ElementVoid : public boost::noncopyable
167 {
179  ElementVoid(const Config& conf);
180  virtual ~ElementVoid();
181 
185  virtual const char* type_name() const =0;
186 
188  virtual void advance(StateBase& s) =0;
189 
191  inline const Config& conf() const {return p_conf;}
192 
193  const std::string name;
194  const size_t index;
195 
196  double length;
197 
199  Observer *observer() const { return p_observe; }
204  void set_observer(Observer *o) { p_observe = o; }
205 
208  virtual void show(std::ostream&, int level) const;
209 
214  virtual void assign(const ElementVoid* other ) =0;
215 private:
216  Observer *p_observe;
217  Config p_conf;
218  friend class Machine;
219 };
220 
230 struct Machine : public boost::noncopyable
231 {
236  Machine(const Config& c);
237  ~Machine();
238 
247  void propagate(StateBase* S,
248  size_t start=0,
249  size_t max=-1) const;
250 
257  StateBase* allocState(const Config& c) const;
258 
261  inline StateBase* allocState() const {
262  Config defaults;
263  return allocState(defaults);
264  }
265 
267  inline const Config& conf() const { return p_conf; }
268 
284  void reconfigure(size_t idx, const Config& c);
285 
287  inline const std::string& simtype() const {return p_simtype;}
288 
290  inline std::ostream* trace() const {return p_trace;}
298  void set_trace(std::ostream* v) {p_trace=v;}
299 
300 private:
301  typedef std::vector<ElementVoid*> p_elements_t;
302 
303  struct LookupKey {
304  std::string name;
305  size_t index;
306  LookupKey(const std::string& n, size_t i) :name(n), index(i) {}
307  bool operator<(const LookupKey& o) const {
308  int ord = name.compare(o.name);
309  if(ord<0) return true;
310  else if(ord>0) return false;
311  else return index<o.index;
312  }
313  };
314 
315  typedef std::map<LookupKey, ElementVoid*> p_lookup_t;
316 public:
317 
319  inline size_t size() const { return p_elements.size(); }
320 
322  inline ElementVoid* operator[](size_t i) { return p_elements[i]; }
324  inline const ElementVoid* operator[](size_t i) const { return p_elements[i]; }
325 
327  inline ElementVoid* at(size_t i) { return p_elements.at(i); }
329  inline const ElementVoid* at(size_t i) const { return p_elements.at(i); }
330 
332  typedef p_elements_t::iterator iterator;
334  typedef p_elements_t::const_iterator const_iterator;
335 
337  iterator begin() { return p_elements.begin(); }
339  const_iterator begin() const { return p_elements.begin(); }
340 
342  iterator end() { return p_elements.end(); }
344  const_iterator end() const { return p_elements.end(); }
345 
349  ElementVoid* find(const std::string& name, size_t nth=0) {
350  p_lookup_t::const_iterator low (p_lookup.lower_bound(LookupKey(name, 0))),
351  high(p_lookup.upper_bound(LookupKey(name, (size_t)-1)));
352  size_t i=0;
353  for(;low!=high;++low,++i) {
354  if(i==nth)
355  return low->second;
356  }
357  return NULL;
358  }
359 
362 
363  std::pair<lookup_iterator, lookup_iterator> all_range() {
364  return std::make_pair(lookup_iterator(p_lookup.begin()),
365  lookup_iterator(p_lookup.end()));
366  }
367 
370  std::pair<lookup_iterator, lookup_iterator> equal_range(const std::string& name) {
371  p_lookup_t::iterator low (p_lookup.lower_bound(LookupKey(name, 0))),
372  high(p_lookup.upper_bound(LookupKey(name, (size_t)-1)));
373  return std::make_pair(lookup_iterator(low),
374  lookup_iterator(high));
375  }
376 
379  std::pair<lookup_iterator, lookup_iterator> equal_range_type(const std::string& name) {
380  p_lookup_t::iterator low (p_lookup_type.lower_bound(LookupKey(name, 0))),
381  high(p_lookup_type.upper_bound(LookupKey(name, (size_t)-1)));
382  return std::make_pair(lookup_iterator(low),
383  lookup_iterator(high));
384  }
385 
386 
387 private:
388  p_elements_t p_elements;
389  p_lookup_t p_lookup;
390  p_lookup_t p_lookup_type;
391  std::string p_simtype;
392  std::ostream* p_trace;
393  Config p_conf;
394 
395  typedef StateBase* (*state_builder_t)(const Config& c);
396  template<typename State>
397  struct state_builder_impl {
398  static StateBase* build(const Config& c)
399  { return new State(c); }
400  };
401  struct element_builder_t {
402  virtual ~element_builder_t() {}
403  virtual ElementVoid* build(const Config& c) =0;
404  virtual void rebuild(ElementVoid *o, const Config& c) =0;
405  };
406  template<typename Element>
407  struct element_builder_impl : public element_builder_t {
408  virtual ~element_builder_impl() {}
409  ElementVoid* build(const Config& c)
410  { return new Element(c); }
411  void rebuild(ElementVoid *o, const Config& c)
412  {
413  std::auto_ptr<ElementVoid> N(build(c));
414  Element *m = dynamic_cast<Element*>(o);
415  if(!m)
416  throw std::runtime_error("reconfigure() can't change element type");
417  m->assign(N.get());
418  }
419  };
420 
421  struct state_info {
422  std::string name;
423  state_builder_t builder;
424  typedef std::map<std::string, element_builder_t*> elements_t;
425  elements_t elements;
426  };
427 
428  state_info p_info;
429 
430  typedef std::map<std::string, state_info> p_state_infos_t;
431  static p_state_infos_t p_state_infos;
432 
433  static void p_registerState(const char *name, state_builder_t b);
434 
435  static void p_registerElement(const std::string& sname, const char *ename, element_builder_t* b);
436 
437 public:
438 
456  template<typename State>
457  static void registerState(const char *name)
458  {
459  p_registerState(name, &state_builder_impl<State>::build);
460  }
461 
473  template<typename Element>
474  static void registerElement(const char *sname, const char *ename)
475  {
476  p_registerElement(sname, ename, new element_builder_impl<Element>);
477  }
478 
489  static void registeryCleanup();
490 
491  friend std::ostream& operator<<(std::ostream&, const Machine& m);
492 
493  struct LogRecord {
494  const char * fname;
495  unsigned short lnum; // >=64k LoC in one file is already a bug
496  unsigned short level;
497  std::ostringstream strm;
498  LogRecord(const char *fname, unsigned short lnum, unsigned short lvl)
499  :fname(fname), lnum(lnum), level(lvl) {}
500  ~LogRecord();
501  template<typename T>
502  LogRecord& operator<<(T v)
503  { strm<<v; return *this; }
504  private:
505  LogRecord(const LogRecord&);
506  LogRecord& operator=(const LogRecord&);
507  };
508 
509  struct Logger {
510  virtual ~Logger() {}
511  virtual void log(const LogRecord& r)=0;
512  };
513 
514  static int log_detail;
515 
516  static inline bool detail(int lvl) { return log_detail<=lvl; }
517 
518  static void set_logger(const boost::shared_ptr<Logger>& p);
519 private:
520  static boost::shared_ptr<Logger> p_logger;
521 };
522 
523 #define FLAME_ERROR 40
524 #define FLAME_WARN 30
525 #define FLAME_INFO 20
526 #define FLAME_DEBUG 10
527 // Super verbose logging, a la the rf cavity element
528 #define FLAME_FINE 0
529 
530 #define FLAME_LOG_ALWAYS(LVL) Machine::LogRecord(__FILE__, __LINE__, FLAME_##LVL)
531 
532 #ifndef FLAME_DISABLE_LOG
533 #define FLAME_LOG_CHECK(LVL) UNLIKELY(Machine::detail(FLAME_##LVL))
534 #else
535 #define FLAME_LOG_CHECK(LVL) (false)
536 #endif
537 
539 #define FLAME_LOG(LVL) if(FLAME_LOG_CHECK(LVL)) FLAME_LOG_ALWAYS(LVL)
540 
541 std::ostream& operator<<(std::ostream&, const Machine& m);
542 
544 void registerLinear();
546 void registerMoment();
547 
548 #endif // FLAME_BASE_H
StateBase(const Config &c)
Definition: base.cpp:18
ElementVoid(const Config &conf)
Construct this element using the provided Config.
Definition: base.cpp:54
void propagate(StateBase *S, size_t start=0, size_t max=-1) const
Pass the given bunch State through this Machine.
Definition: base.cpp:167
p_elements_t::iterator iterator
Beamline element iterator.
Definition: base.h:332
virtual void show(std::ostream &, int level=0) const
Definition: base.h:45
Base class for all simulated elements.
Definition: base.h:166
double length
Longitudual length of this element (added to StateBase::pos)
Definition: base.h:196
virtual void view(const ElementVoid *elem, const StateBase *state)=0
Called from within Machine::propagate()
Machine(const Config &c)
Construct a new Machine.
Definition: base.cpp:80
bool inbounds(size_t *d) const
is the given index valid?
Definition: base.h:71
const std::string & simtype() const
Return the sim_type string found during construction.
Definition: base.h:287
static void registerState(const char *name)
Register a new State with the simulation framework.
Definition: base.h:457
static void registerElement(const char *sname, const char *ename)
Register a new Element type with the simulation framework.
Definition: base.h:474
The core simulate Machine engine.
Definition: base.h:230
virtual StateBase * clone() const =0
size_t size() const
Definition: base.h:319
virtual const char * type_name() const =0
size_t next_elem
Definition: base.h:34
virtual void advance(StateBase &s)=0
Propogate the given State through this Element.
Type
The parameter type Double (double) or Sizet (size_t)
Definition: base.h:54
The abstract base class for all simulation state objects.
Definition: base.h:28
std::pair< lookup_iterator, lookup_iterator > equal_range_type(const std::string &name)
Definition: base.h:379
iterator begin()
Points to the first element.
Definition: base.h:337
virtual void assign(const ElementVoid *other)=0
Definition: base.cpp:72
ElementVoid * find(const std::string &name, size_t nth=0)
Definition: base.h:349
Associative configuration container.
Definition: config.h:66
Definition: config.h:26
Used with StateBase::getArray() to describe a single parameter.
Definition: base.h:48
virtual void assign(const StateBase &other)=0
Definition: base.cpp:30
static void registeryCleanup()
Discard all registered State and Element type information.
Definition: base.cpp:242
double pos
absolute longitudinal position at end of Element
Definition: base.h:36
const ElementVoid * at(size_t i) const
Access a beamline element.
Definition: base.h:329
const std::string name
Name of this element (unique in its Machine)
Definition: base.h:193
size_t dim[maxdims]
Array dimensions in elements.
Definition: base.h:66
const Config & conf() const
The Config used to construct this element.
Definition: base.h:191
Allow inspection of intermediate State.
Definition: base.h:153
const Config & conf() const
Fetch Config used to construct this Machine.
Definition: base.h:267
value_proxy_iterator< p_lookup_t::iterator > lookup_iterator
iterator for use with equal_range() and equal_range_type()
Definition: base.h:361
void set_trace(std::ostream *v)
Assign new tracing stream.
Definition: base.h:298
ElementVoid * operator[](size_t i)
Access a beamline element.
Definition: base.h:322
iterator end()
Points just after the last element.
Definition: base.h:342
ElementVoid * at(size_t i)
Access a beamline element.
Definition: base.h:327
void reconfigure(size_t idx, const Config &c)
Change the configuration of a single element.
Definition: base.cpp:191
size_t stride[maxdims]
Array strides in bytes.
Definition: base.h:68
const size_t index
Index of this element (unique in its Machine)
Definition: base.h:194
Observer * observer() const
The current observer, or NULL.
Definition: base.h:199
virtual bool getArray(unsigned index, ArrayInfo &Info)
Introspect named parameter of the derived class.
Definition: base.cpp:35
std::ostream * trace() const
The current tracing stream, or NULL.
Definition: base.h:290
std::pair< lookup_iterator, lookup_iterator > equal_range(const std::string &name)
Definition: base.h:370
const_iterator begin() const
Points to the first element.
Definition: base.h:339
const ElementVoid * operator[](size_t i) const
Access a beamline element.
Definition: base.h:324
const_iterator end() const
Points just after the last element.
Definition: base.h:344
void set_observer(Observer *o)
Definition: base.h:204
virtual void show(std::ostream &, int level) const
Definition: base.cpp:67
Used with clone ctor.
Definition: base.h:134
StateBase * allocState() const
Definition: base.h:261
const char * name
The parameter name.
Definition: base.h:52
unsigned ndim
Definition: base.h:64
p_elements_t::const_iterator const_iterator
Beamline element iterator (const version)
Definition: base.h:334