CMS 3D CMS Logo

ConstantStepOdeSolver.h
Go to the documentation of this file.
1 #ifndef CalibCalorimetry_HcalAlgos_ConstantStepOdeSolver_h_
2 #define CalibCalorimetry_HcalAlgos_ConstantStepOdeSolver_h_
3 
4 #include <vector>
5 #include <iostream>
7 
9 
10 //
11 // ODE solver with a constant time step. The derived classes are supposed
12 // to implement concrete ODE solving algorithms (Runge-Kutta, etc).
13 //
15 public:
16  inline ConstantStepOdeSolver() : rhs_(nullptr), dt_(0.0), dim_(0), runLen_(0), lastIntegrated_(0) {}
17 
18  inline ConstantStepOdeSolver(const AbsODERHS& rhs)
19  : rhs_(nullptr), dt_(0.0), dim_(0), runLen_(0), lastIntegrated_(0) {
20  rhs_ = rhs.clone();
21  }
22 
23  // The copy constructor and the assignment operator are explicitly provided
26 
27  inline virtual ~ConstantStepOdeSolver() { delete rhs_; }
28 
29  // Access the equation right hand side
30  inline void setRHS(const AbsODERHS& rhs) {
31  delete rhs_;
32  rhs_ = rhs.clone();
33  }
34  inline const AbsODERHS* getRHS() const { return rhs_; }
35  inline AbsODERHS* getRHS() { return rhs_; }
36 
37  // Inspectors (will be valid after at least one "run" call)
38  inline unsigned lastDim() const { return dim_; }
39  inline unsigned lastRunLength() const { return runLen_; }
40  inline double lastDeltaT() const { return dt_; }
41  inline double lastMaxT() const { return runLen_ ? dt_ * (runLen_ - 1U) : 0.0; }
42 
43  inline double getTime(const unsigned idx) const {
44  if (idx >= runLen_)
45  throw cms::Exception("In ConstantStepOdeSolver::getTime: index out of range");
46  return idx * dt_;
47  }
48 
49  inline double getCoordinate(const unsigned which, const unsigned idx) const {
50  if (which >= dim_ || idx >= runLen_)
51  throw cms::Exception("In ConstantStepOdeSolver::getCoordinate: index out of range");
52  return historyBuffer_[dim_ * idx + which];
53  }
54 
55  // Integrate the node with the given number and get
56  // the value of the integral at the given history point
57  double getIntegrated(unsigned which, unsigned idx) const;
58 
59  // Truncate some coordinate
60  void truncateCoordinate(unsigned which, double minValue, double maxValue);
61 
62  // Linear interpolation methods will be used in case the "cubic"
63  // argument is false, and cubic in case it is true
64  double interpolateCoordinate(unsigned which, double t, bool cubic = false) const;
65 
66  // Interpolate the integrated node
67  double interpolateIntegrated(unsigned which, double t, bool cubic = false) const;
68 
69  // Get the time of the peak position
70  double getPeakTime(unsigned which) const;
71 
72  // Solve the ODE and remember the history
73  void run(const double* initialConditions, unsigned lenConditions, double dt, unsigned nSteps);
74 
75  // Set the history from some external source. The size
76  // of the data array should be at least dim*runLen.
77  void setHistory(double dt, const double* data, unsigned dim, unsigned runLen);
78 
79  // Write out the history
80  void writeHistory(std::ostream& os, double dt, bool cubic = false) const;
81 
82  // Write out the integrated node
83  void writeIntegrated(std::ostream& os, unsigned which, double dt, bool cubic = false) const;
84 
85  // The following method must be overriden by derived classes
86  virtual const char* methodName() const = 0;
87 
88 protected:
90 
91 private:
92  // The following method must be overriden by derived classes
93  virtual void step(double t, double dt, const double* x, unsigned lenX, double* coordIncrement) const = 0;
94 
95  // The following integration corresponds to the cubic
96  // interpolation of the coordinate
97  void integrateCoordinate(const unsigned which);
98 
99  double dt_;
100  unsigned dim_;
101  unsigned runLen_;
102  unsigned lastIntegrated_;
103 
104  std::vector<double> historyBuffer_;
105  std::vector<double> chargeBuffer_;
106 };
107 
108 // Dump the coordinate history as it was collected
109 inline std::ostream& operator<<(std::ostream& os, const ConstantStepOdeSolver& s) {
110  s.writeHistory(os, s.lastDeltaT());
111  return os;
112 }
113 
114 // A few concrete ODE solvers
116 public:
118 
119  inline explicit EulerOdeSolver(const AbsODERHS& rhs) : ConstantStepOdeSolver(rhs) {}
120 
121  inline const char* methodName() const override { return "Euler"; }
122 
123 private:
124  void step(double t, double dt, const double* x, unsigned lenX, double* coordIncrement) const override;
125 };
126 
127 class RK2 : public ConstantStepOdeSolver {
128 public:
129  inline RK2() : ConstantStepOdeSolver() {}
130 
131  inline explicit RK2(const AbsODERHS& rhs) : ConstantStepOdeSolver(rhs) {}
132 
133  inline const char* methodName() const override { return "2nd order Runge-Kutta"; }
134 
135 private:
136  void step(double t, double dt, const double* x, unsigned lenX, double* coordIncrement) const override;
137 
138  mutable std::vector<double> buf_;
139 };
140 
141 class RK4 : public ConstantStepOdeSolver {
142 public:
143  inline RK4() : ConstantStepOdeSolver() {}
144 
145  inline explicit RK4(const AbsODERHS& rhs) : ConstantStepOdeSolver(rhs) {}
146 
147  inline const char* methodName() const override { return "4th order Runge-Kutta"; }
148 
149 private:
150  void step(double t, double dt, const double* x, unsigned lenX, double* coordIncrement) const override;
151 
152  mutable std::vector<double> buf_;
153 };
154 
155 #endif // CalibCalorimetry_HcalAlgos_ConstantStepOdeSolver_h_
virtual AbsODERHS * clone() const =0
float dt
Definition: AMPTWrapper.h:136
RK4(const AbsODERHS &rhs)
const AbsODERHS * getRHS() const
std::ostream & operator<<(std::ostream &os, const ConstantStepOdeSolver &s)
double getPeakTime(unsigned which) const
void step(double t, double dt, const double *x, unsigned lenX, double *coordIncrement) const override
double interpolateCoordinate(unsigned which, double t, bool cubic=false) const
ConstantStepOdeSolver(const AbsODERHS &rhs)
std::vector< double > chargeBuffer_
void step(double t, double dt, const double *x, unsigned lenX, double *coordIncrement) const override
double getCoordinate(const unsigned which, const unsigned idx) const
double interpolateIntegrated(unsigned which, double t, bool cubic=false) const
virtual void step(double t, double dt, const double *x, unsigned lenX, double *coordIncrement) const =0
std::vector< double > buf_
virtual const char * methodName() const =0
EulerOdeSolver(const AbsODERHS &rhs)
void step(double t, double dt, const double *x, unsigned lenX, double *coordIncrement) const override
void setRHS(const AbsODERHS &rhs)
void integrateCoordinate(const unsigned which)
unsigned lastRunLength() const
void writeHistory(std::ostream &os, double dt, bool cubic=false) const
ConstantStepOdeSolver & operator=(const ConstantStepOdeSolver &r)
std::vector< double > historyBuffer_
void writeIntegrated(std::ostream &os, unsigned which, double dt, bool cubic=false) const
void run(const double *initialConditions, unsigned lenConditions, double dt, unsigned nSteps)
double getIntegrated(unsigned which, unsigned idx) const
const char * methodName() const override
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
std::vector< double > buf_
void truncateCoordinate(unsigned which, double minValue, double maxValue)
const char * methodName() const override
def which(cmd)
Definition: eostools.py:336
void setHistory(double dt, const double *data, unsigned dim, unsigned runLen)
const char * methodName() const override
double getTime(const unsigned idx) const
RK2(const AbsODERHS &rhs)