CMS 3D CMS Logo

RK4PreciseStep.cc
Go to the documentation of this file.
1 #include "RK4PreciseStep.h"
2 #include "RK4OneStep.h"
3 //#include "Utilities/UI/interface/SimpleConfigurable.h"
4 #include <iostream>
5 
7  const RKCartesianDerivative& deriv,
8  double step,
9  double eps) const {
10  const double Safety = 0.9;
11  double remainigStep = step;
12  double stepSize = step;
14  int nsteps = 0;
15  std::pair<CartesianState, double> tryStep;
16 
17  do {
18  tryStep = stepWithAccuracy(currentStart, deriv, stepSize);
19  nsteps++;
20  if (tryStep.second < eps) {
21  if (remainigStep - stepSize < eps / 2) {
22  if (verbose())
23  std::cout << "Accuracy reached, and full step taken in " << nsteps << " steps" << std::endl;
24  return tryStep.first; // we are there
25  } else {
26  remainigStep -= stepSize;
27  // increase step size
28  double factor = std::min(Safety * pow(fabs(eps / tryStep.second), 0.2), 4.);
29  stepSize = std::min(stepSize * factor, remainigStep);
30  currentStart = tryStep.first;
31  if (verbose())
32  std::cout << "Accuracy reached, but " << remainigStep << " remain after " << nsteps
33  << " steps. Step size increased by " << factor << " to " << stepSize << std::endl;
34  }
35  } else {
36  // decrease step size
37  double factor = std::max(Safety * pow(fabs(eps / tryStep.second), 0.25), 0.1);
38  stepSize *= factor;
39  if (verbose())
40  std::cout << "Accuracy not yet reached: delta = " << tryStep.second << ", step reduced by " << factor << " to "
41  << stepSize << ", (R,z)= " << currentStart.position().perp() << ", " << currentStart.position().z()
42  << std::endl;
43  }
44  } while (remainigStep > eps / 2);
45 
46  return tryStep.first;
47 }
48 
49 std::pair<CartesianState, double> RK4PreciseStep::stepWithAccuracy(const CartesianState& start,
50  const RKCartesianDerivative& deriv,
51  double step) const {
52  RK4OneStep solver;
53  CartesianState one(solver(start, deriv, step));
54  CartesianState firstHalf(solver(start, deriv, step / 2));
55  CartesianState secondHalf(solver(firstHalf, deriv, step / 2));
56  double diff = distance(one, secondHalf);
57  return std::pair<CartesianState, double>(secondHalf, diff);
58 }
59 
61  return (a.position() - b.position()).mag() + (a.momentum() - b.momentum()).mag() / b.momentum().mag();
62 }
63 
64 bool RK4PreciseStep::verbose() const { return true; }
Definition: start.py:1
bool verbose() const
double distance(const CartesianState &a, const CartesianState &b) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
double b
Definition: hdecay.h:120
CartesianState operator()(const CartesianState &start, const RKCartesianDerivative &deriv, double step, double eps) const
int currentStart
Definition: mps_splice.py:66
double a
Definition: hdecay.h:121
step
Definition: StallMonitor.cc:83
std::pair< CartesianState, double > stepWithAccuracy(const CartesianState &start, const RKCartesianDerivative &deriv, double step) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29