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 <climits>
7 #include <ostream>
8 #include <string>
9 #include <map>
10 #include <vector>
11 #include <utility>
12 
13 #include <boost/noncopyable.hpp>
14 #include <boost/any.hpp>
15 #include <boost/shared_ptr.hpp>
16 #include <boost/call_traits.hpp>
17 
18 #include "config.h"
19 #include "util.h"
20 
21 #define FLAME_API_VERSION 0
22 
23 struct ElementVoid;
24 
29 struct StateBase : public boost::noncopyable
30 {
31  virtual ~StateBase();
32 
35  size_t next_elem;
36 
37  double pos;
38 
39  bool retreat;
40 
44  virtual void assign(const StateBase& other) =0;
45 
48  virtual void show(std::ostream&, int level =0) const {}
49 
51  struct ArrayInfo {
52  enum {maxdims=3};
53  ArrayInfo() :name(0), type(Double), ptr(NULL), ndim(0) {}
55  const char *name;
57  enum Type {
58  Double, Sizet
59  } type;
62  void *ptr;
67  unsigned ndim;
69  size_t dim[maxdims];
71  size_t stride[maxdims];
72 
74  bool inbounds(size_t* d) const {
75  bool ret = true;
76  for (int i=ndim-1; i>=0; --i) {
77  ret &= d[i] < dim[i];
78  }
79  return ret;
80  }
81 
82  void *raw(size_t* d) {
83  char *ret = (char*)ptr;
84  for (int i=ndim-1; i>=0; --i) {
85  ret += d[i] * stride[i];
86  }
87  return ret;
88  }
89 
91  template<typename E>
92  inline E* get(size_t *d) {
93  return (E*)raw(d);
94  }
95  };
96 
117  virtual bool getArray(unsigned index, ArrayInfo& Info);
118 
121  virtual StateBase* clone() const =0;
122 
125  void *pyptr;
126 protected:
131  StateBase(const Config& c);
133  struct clone_tag{};
135  StateBase(const StateBase& c, clone_tag);
136 };
137 
138 inline
139 std::ostream& operator<<(std::ostream& strm, const StateBase& s)
140 {
141  s.show(strm, 0);
142  return strm;
143 }
144 
152 struct Observer : public boost::noncopyable
153 {
154  virtual ~Observer() {}
156  virtual void view(const ElementVoid* elem, const StateBase* state) =0;
157 };
158 
165 struct ElementVoid : public boost::noncopyable
166 {
178  ElementVoid(const Config& conf);
179  virtual ~ElementVoid();
180 
184  virtual const char* type_name() const =0;
185 
187  virtual void advance(StateBase& s) =0;
188 
190  inline const Config& conf() const {return p_conf;}
191 
192  const std::string name;
193  size_t index;
194 
195  double length;
196 
198  Observer *observer() const { return p_observe; }
203  void set_observer(Observer *o) { p_observe = o; }
204 
207  virtual void show(std::ostream&, int level) const;
208 
213  virtual void assign(const ElementVoid* other ) =0;
214 private:
215  Observer *p_observe;
216  Config p_conf;
217  friend class Machine;
218 };
219 
229 struct Machine : public boost::noncopyable
230 {
235  Machine(const Config& c);
236  ~Machine();
237 
246  void propagate(StateBase* S,
247  size_t start=0,
248  int max=INT_MAX) const;
249 
256  StateBase* allocState(const Config& c) const;
257 
260  inline StateBase* allocState() const {
261  Config defaults;
262  return allocState(defaults);
263  }
264 
266  inline const Config& conf() const { return p_conf; }
267 
283  void reconfigure(size_t idx, const Config& c);
284 
286  inline const std::string& simtype() const {return p_simtype;}
287 
289  inline std::ostream* trace() const {return p_trace;}
297  void set_trace(std::ostream* v) {p_trace=v;}
298 
299 private:
300  typedef std::vector<ElementVoid*> p_elements_t;
301 
302  struct LookupKey {
303  std::string name;
304  size_t index;
305  LookupKey(const std::string& n, size_t i) :name(n), index(i) {}
306  bool operator<(const LookupKey& o) const {
307  int ord = name.compare(o.name);
308  if(ord<0) return true;
309  else if(ord>0) return false;
310  else return index<o.index;
311  }
312  };
313 
314  typedef std::map<LookupKey, ElementVoid*> p_lookup_t;
315 public:
316 
318  inline size_t size() const { return p_elements.size(); }
319 
321  inline ElementVoid* operator[](size_t i) { return p_elements[i]; }
323  inline const ElementVoid* operator[](size_t i) const { return p_elements[i]; }
324 
326  inline ElementVoid* at(size_t i) { return p_elements.at(i); }
328  inline const ElementVoid* at(size_t i) const { return p_elements.at(i); }
329 
331  typedef p_elements_t::iterator iterator;
333  typedef p_elements_t::const_iterator const_iterator;
334 
336  iterator begin() { return p_elements.begin(); }
338  const_iterator begin() const { return p_elements.begin(); }
339 
341  iterator end() { return p_elements.end(); }
343  const_iterator end() const { return p_elements.end(); }
344 
348  ElementVoid* find(const std::string& name, size_t nth=0) {
349  p_lookup_t::const_iterator low (p_lookup.lower_bound(LookupKey(name, 0))),
350  high(p_lookup.upper_bound(LookupKey(name, (size_t)-1)));
351  size_t i=0;
352  for(;low!=high;++low,++i) {
353  if(i==nth)
354  return low->second;
355  }
356  return NULL;
357  }
358 
361 
362  std::pair<lookup_iterator, lookup_iterator> all_range() {
363  return std::make_pair(lookup_iterator(p_lookup.begin()),
364  lookup_iterator(p_lookup.end()));
365  }
366 
369  std::pair<lookup_iterator, lookup_iterator> equal_range(const std::string& name) {
370  p_lookup_t::iterator low (p_lookup.lower_bound(LookupKey(name, 0))),
371  high(p_lookup.upper_bound(LookupKey(name, (size_t)-1)));
372  return std::make_pair(lookup_iterator(low),
373  lookup_iterator(high));
374  }
375 
378  std::pair<lookup_iterator, lookup_iterator> equal_range_type(const std::string& name) {
379  p_lookup_t::iterator low (p_lookup_type.lower_bound(LookupKey(name, 0))),
380  high(p_lookup_type.upper_bound(LookupKey(name, (size_t)-1)));
381  return std::make_pair(lookup_iterator(low),
382  lookup_iterator(high));
383  }
384 
385 
386 private:
387  p_elements_t p_elements;
388  p_lookup_t p_lookup;
389  p_lookup_t p_lookup_type;
390  std::string p_simtype;
391  std::ostream* p_trace;
392  Config p_conf;
393 
394  typedef StateBase* (*state_builder_t)(const Config& c);
395  template<typename State>
396  struct state_builder_impl {
397  static StateBase* build(const Config& c)
398  { return new State(c); }
399  };
400  struct element_builder_t {
401  virtual ~element_builder_t() {}
402  virtual ElementVoid* build(const Config& c) =0;
403  virtual void rebuild(ElementVoid *o, const Config& c, const size_t idx) =0;
404  };
405  template<typename Element>
406  struct element_builder_impl : public element_builder_t {
407  virtual ~element_builder_impl() {}
408  ElementVoid* build(const Config& c)
409  { return new Element(c); }
410  void rebuild(ElementVoid *o, const Config& c, const size_t idx)
411  {
412  std::unique_ptr<ElementVoid> N(build(c));
413  Element *m = dynamic_cast<Element*>(o);
414  if(!m)
415  throw std::runtime_error("reconfigure() can't change element type");
416  m->assign(N.get());
417  m->index = idx; // copy index number
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:56
p_elements_t::iterator iterator
Beamline element iterator.
Definition: base.h:331
bool retreat
retreat (backward) simulation flag
Definition: base.h:39
virtual void show(std::ostream &, int level=0) const
Definition: base.h:48
Base class for all simulated elements.
Definition: base.h:165
double length
Longitudual length of this element (added to StateBase::pos)
Definition: base.h:195
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:82
bool inbounds(size_t *d) const
is the given index valid?
Definition: base.h:74
const std::string & simtype() const
Return the sim_type string found during construction.
Definition: base.h:286
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:229
virtual StateBase * clone() const =0
size_t size() const
Definition: base.h:318
virtual const char * type_name() const =0
size_t next_elem
Definition: base.h:35
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:57
The abstract base class for all simulation state objects.
Definition: base.h:29
std::pair< lookup_iterator, lookup_iterator > equal_range_type(const std::string &name)
Definition: base.h:378
iterator begin()
Points to the first element.
Definition: base.h:336
virtual void assign(const ElementVoid *other)=0
Definition: base.cpp:74
void propagate(StateBase *S, size_t start=0, int max=INT_MAX) const
Pass the given bunch State through this Machine.
Definition: base.cpp:169
ElementVoid * find(const std::string &name, size_t nth=0)
Definition: base.h:348
Associative configuration container.
Definition: config.h:66
Used with StateBase::getArray() to describe a single parameter.
Definition: base.h:51
virtual void assign(const StateBase &other)=0
Definition: base.cpp:32
size_t index
Index of this element (unique in its Machine)
Definition: base.h:193
static void registeryCleanup()
Discard all registered State and Element type information.
Definition: base.cpp:251
double pos
absolute longitudinal position at end of Element
Definition: base.h:37
const ElementVoid * at(size_t i) const
Access a beamline element.
Definition: base.h:328
const std::string name
Name of this element (unique in its Machine)
Definition: base.h:192
size_t dim[maxdims]
Array dimensions in elements.
Definition: base.h:69
const Config & conf() const
The Config used to construct this element.
Definition: base.h:190
Allow inspection of intermediate State.
Definition: base.h:152
const Config & conf() const
Fetch Config used to construct this Machine.
Definition: base.h:266
value_proxy_iterator< p_lookup_t::iterator > lookup_iterator
iterator for use with equal_range() and equal_range_type()
Definition: base.h:360
void set_trace(std::ostream *v)
Assign new tracing stream.
Definition: base.h:297
ElementVoid * operator[](size_t i)
Access a beamline element.
Definition: base.h:321
iterator end()
Points just after the last element.
Definition: base.h:341
ElementVoid * at(size_t i)
Access a beamline element.
Definition: base.h:326
void reconfigure(size_t idx, const Config &c)
Change the configuration of a single element.
Definition: base.cpp:200
size_t stride[maxdims]
Array strides in bytes.
Definition: base.h:71
Observer * observer() const
The current observer, or NULL.
Definition: base.h:198
virtual bool getArray(unsigned index, ArrayInfo &Info)
Introspect named parameter of the derived class.
Definition: base.cpp:37
std::ostream * trace() const
The current tracing stream, or NULL.
Definition: base.h:289
std::pair< lookup_iterator, lookup_iterator > equal_range(const std::string &name)
Definition: base.h:369
const_iterator begin() const
Points to the first element.
Definition: base.h:338
const ElementVoid * operator[](size_t i) const
Access a beamline element.
Definition: base.h:323
const_iterator end() const
Points just after the last element.
Definition: base.h:343
void set_observer(Observer *o)
Definition: base.h:203
virtual void show(std::ostream &, int level) const
Definition: base.cpp:69
Used with clone ctor.
Definition: base.h:133
StateBase * allocState() const
Definition: base.h:260
const char * name
The parameter name.
Definition: base.h:55
unsigned ndim
Definition: base.h:67
p_elements_t::const_iterator const_iterator
Beamline element iterator (const version)
Definition: base.h:333