6 return f0 * (1.0 -
x) + f1 * x;
11 throw cms::Exception(
"In ConstantStepOdeSolver::getPeakTime: index out of range");
13 throw cms::Exception(
"In ConstantStepOdeSolver::getPeakTime: not enough data");
16 double maxval = hbuf[0];
19 if (hbuf[
dim_ *
i] > maxval) {
20 maxval = hbuf[
dim_ *
i];
25 if (maxind == runLen_ - 1U)
27 const double l = hbuf[
dim_ * (maxind - 1U)];
28 const double r = hbuf[
dim_ * (maxind + 1U)];
29 if (l < maxval || r < maxval)
30 return dt_ * (maxind + (l -
r) / 2.0 / (l + r - 2.0 * maxval));
37 throw cms::Exception(
"In ConstantStepOdeSolver::getIntegrated: index out of range");
45 throw cms::Exception(
"In ConstantStepOdeSolver::integrateCoordinate: not enough data");
52 integ[1] = coord[
dim_ * 0] * (3.0 / 8.0) + coord[
dim_ * 1] * (19.0 / 24.0) + coord[
dim_ * 2] * (-5.0 / 24.0) +
53 coord[
dim_ * 3] * (1.0 / 24.0);
54 long double sum = integ[1];
55 const unsigned rlenm1 =
runLen_ - 1U;
56 for (
unsigned i = 2;
i < rlenm1; ++
i) {
57 sum += (coord[
dim_ * (
i - 2U)] * (-1.0 / 24.0) + coord[
dim_ * (
i - 1U)] * (13.0 / 24.0) +
58 coord[
dim_ *
i] * (13.0 / 24.0) + coord[
dim_ * (
i + 1U)] * (-1.0 / 24.0));
61 sum += (coord[
dim_ * rlenm1] * (3.0 / 8.0) + coord[
dim_ * (rlenm1 - 1U)] * (19.0 / 24.0) +
62 coord[
dim_ * (rlenm1 - 2U)] * (-5.0 / 24.0) + coord[
dim_ * (rlenm1 - 3U)] * (1.0 / 24.0));
74 for (
unsigned ipt = 0; ipt <
runLen_; ++ipt) {
82 for (
unsigned i = 0;; ++
i) {
83 const double t =
i *
dt;
98 const bool cubic)
const {
102 for (
unsigned ipt = 0; ipt <
runLen_; ++ipt)
106 for (
unsigned i = 0;; ++
i) {
107 const double t =
i *
dt;
121 lastIntegrated_(r.lastIntegrated_),
122 historyBuffer_(r.historyBuffer_),
123 chargeBuffer_(r.chargeBuffer_) {
146 throw cms::Exception(
"In ConstantStepOdeSolver::truncateCoordinate: index out of range");
147 if (minValue > maxValue)
148 throw cms::Exception(
"In ConstantStepOdeSolver::truncateCoordinate: invalid truncation range");
152 if (buf[
dim_ *
i] < minValue)
153 buf[
dim_ *
i] = minValue;
154 else if (buf[
dim_ *
i] > maxValue)
155 buf[
dim_ *
i] = maxValue;
161 throw cms::Exception(
"In ConstantStepOdeSolver::interpolateCoordinate: index out of range");
163 throw cms::Exception(
"In ConstantStepOdeSolver::interpolateCoordinate: not enough data");
165 if (t < 0.0 || t > maxt)
166 throw cms::Exception(
"In ConstantStepOdeSolver::interpolateCoordinate: time out of range");
175 const double tSteps = t /
dt_;
176 unsigned nLow = tSteps;
179 double x = tSteps - nLow;
190 const double*
base = arr + (which +
dim_ * i0);
200 throw cms::Exception(
"In ConstantStepOdeSolver::interpolateIntegrated: index out of range");
202 throw cms::Exception(
"In ConstantStepOdeSolver::interpolateIntegrated: not enough data");
204 if (t < 0.0 || t > maxt)
205 throw cms::Exception(
"In ConstantStepOdeSolver::interpolateIntegrated: time out of range");
216 const double tSteps = t /
dt_;
217 unsigned nLow = tSteps;
220 double x = tSteps - nLow;
231 const double*
base = buf + i0;
240 const unsigned len = dim * runLen;
244 throw cms::Exception(
"In ConstantStepOdeSolver::setHistory: can not run backwards in time");
246 const unsigned sz = dim * (runLen + 1U);
254 for (
unsigned i = 0;
i < len; ++
i)
256 for (
unsigned i = 0;
i < dim; ++
i)
261 const unsigned lenInitialConditions,
263 const unsigned nSteps) {
264 if (!nSteps || !lenInitialConditions)
267 throw cms::Exception(
"In ConstantStepOdeSolver::run: ODE right hand side has not been set");
269 throw cms::Exception(
"In ConstantStepOdeSolver::run: can not run backwards in time");
270 assert(initialConditions);
272 dim_ = lenInitialConditions;
279 for (
unsigned i = 0;
i < lenInitialConditions; ++
i)
280 arr[
i] = initialConditions[
i];
283 for (
unsigned i = 0;
i < nSteps; ++
i, arr += lenInitialConditions) {
284 const double t =
i *
dt;
285 this->
step(t, dt, arr, lenInitialConditions, stepBuffer);
286 double*
next = arr + lenInitialConditions;
287 for (
unsigned i = 0;
i < lenInitialConditions; ++
i)
288 next[
i] = arr[
i] + stepBuffer[
i];
293 const double t,
const double dt,
const double*
x,
const unsigned lenX,
double* coordIncrement)
const {
294 rhs_->
calc(t, x, lenX, coordIncrement);
295 for (
unsigned i = 0;
i < lenX; ++
i)
296 coordIncrement[
i] *= dt;
299 void RK2::step(
const double t,
const double dt,
const double*
x,
const unsigned lenX,
double* coordIncrement)
const {
300 const double halfstep = dt / 2.0;
301 if (
buf_.size() < lenX)
303 double* midpoint = &
buf_[0];
305 for (
unsigned i = 0;
i < lenX; ++
i) {
306 midpoint[
i] *= halfstep;
309 rhs_->
calc(t + halfstep, midpoint, lenX, coordIncrement);
310 for (
unsigned i = 0;
i < lenX; ++
i)
311 coordIncrement[
i] *= dt;
314 void RK4::step(
const double t,
const double dt,
const double*
x,
const unsigned lenX,
double* coordIncrement)
const {
315 const double halfstep = dt / 2.0;
316 if (
buf_.size() < 4 * lenX)
317 buf_.resize(4 * lenX);
318 double* k1x = &
buf_[0];
319 double* k2x = k1x + lenX;
320 double* k3x = k2x + lenX;
321 double* k4x = k3x + lenX;
323 for (
unsigned i = 0;
i < lenX; ++
i)
324 coordIncrement[
i] = x[
i] + halfstep * k1x[
i];
325 rhs_->
calc(t + halfstep, coordIncrement, lenX, k2x);
326 for (
unsigned i = 0;
i < lenX; ++
i)
327 coordIncrement[
i] = x[
i] + halfstep * k2x[
i];
328 rhs_->
calc(t + halfstep, coordIncrement, lenX, k3x);
329 for (
unsigned i = 0;
i < lenX; ++
i)
330 coordIncrement[
i] = x[
i] + dt * k3x[
i];
331 rhs_->
calc(t + dt, coordIncrement, lenX, k4x);
332 for (
unsigned i = 0;
i < lenX; ++
i)
333 coordIncrement[
i] = dt / 6.0 * (k1x[
i] + 2.0 * (k2x[
i] + k3x[
i]) + k4x[i]);
static double interpolateLinear(const double x, const double f0, const double f1)
virtual AbsODERHS * clone() const =0
double getCoordinate(const unsigned which, const unsigned idx) const
double interpolateIntegrated(unsigned which, double t, bool cubic=false) const
void step(double t, double dt, const double *x, unsigned lenX, double *coordIncrement) const override
double getTime(const unsigned idx) const
std::vector< double > chargeBuffer_
double getPeakTime(unsigned which) const
void step(double t, double dt, const double *x, unsigned lenX, double *coordIncrement) const override
double getIntegrated(unsigned which, unsigned idx) const
void writeIntegrated(std::ostream &os, unsigned which, double dt, bool cubic=false) const
virtual void step(double t, double dt, const double *x, unsigned lenX, double *coordIncrement) const =0
uint16_t const *__restrict__ x
std::vector< double > buf_
virtual const char * methodName() const =0
void step(double t, double dt, const double *x, unsigned lenX, double *coordIncrement) const override
void integrateCoordinate(const unsigned which)
virtual void calc(double t, const double *x, unsigned lenX, double *derivative)=0
static const double tmax[3]
ConstantStepOdeSolver & operator=(const ConstantStepOdeSolver &r)
double interpolateCoordinate(unsigned which, double t, bool cubic=false) const
std::vector< double > historyBuffer_
void run(const double *initialConditions, unsigned lenConditions, double dt, unsigned nSteps)
char data[epos_bytes_allocation]
std::vector< double > buf_
void truncateCoordinate(unsigned which, double minValue, double maxValue)
void writeHistory(std::ostream &os, double dt, bool cubic=false) const
void setHistory(double dt, const double *data, unsigned dim, unsigned runLen)