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];
27 const double l = hbuf[
dim_ * (maxind - 1
U)];
28 const double r = hbuf[
dim_ * (maxind + 1
U)];
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_ - 1
U;
56 for (
unsigned i = 2;
i < rlenm1; ++
i) {
57 sum += (coord[
dim_ * (
i - 2
U)] * (-1.0 / 24.0) + coord[
dim_ * (
i - 1
U)] * (13.0 / 24.0) +
58 coord[
dim_ *
i] * (13.0 / 24.0) + coord[
dim_ * (
i + 1
U)] * (-1.0 / 24.0));
61 sum += (coord[
dim_ * rlenm1] * (3.0 / 8.0) + coord[
dim_ * (rlenm1 - 1
U)] * (19.0 / 24.0) +
62 coord[
dim_ * (rlenm1 - 2
U)] * (-5.0 / 24.0) + coord[
dim_ * (rlenm1 - 3
U)] * (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_) {
125 rhs_ =
r.rhs_->clone();
139 rhs_ =
r.rhs_->clone();
146 throw cms::Exception(
"In ConstantStepOdeSolver::truncateCoordinate: index out of range");
148 throw cms::Exception(
"In ConstantStepOdeSolver::truncateCoordinate: invalid truncation range");
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;
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;
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 + 1
U);
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 {
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];
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)
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
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
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
void writeHistory(std::ostream &os, double dt, bool cubic=false) const
static const double tmax[3]
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
char data[epos_bytes_allocation]
std::vector< double > buf_
void truncateCoordinate(unsigned which, double minValue, double maxValue)
void setHistory(double dt, const double *data, unsigned dim, unsigned runLen)
double getTime(const unsigned idx) const