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 
8  double step, double eps) const
9 {
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()) std::cout << "Accuracy reached, and full step taken in "
23  << nsteps << " steps" << std::endl;
24  return tryStep.first; // we are there
25  }
26  else {
27  remainigStep -= stepSize;
28  // increase step size
29  double factor = std::min( Safety * pow( fabs(eps/tryStep.second),0.2), 4.);
30  stepSize = std::min( stepSize*factor, remainigStep);
31  currentStart = tryStep.first;
32  if (verbose()) std::cout << "Accuracy reached, but " << remainigStep
33  << " remain after " << nsteps << " steps. Step size increased by "
34  << factor << " to " << stepSize << std::endl;
35  }
36  }
37  else {
38  // decrease step size
39  double factor = std::max( Safety * pow( fabs(eps/tryStep.second),0.25), 0.1);
40  stepSize *= factor;
41  if (verbose()) std::cout << "Accuracy not yet reached: delta = " << tryStep.second
42  << ", step reduced by " << factor << " to " << stepSize
43  << ", (R,z)= " << currentStart.position().perp()
44  << ", " << currentStart.position().z() << std::endl;
45  }
46  } while (remainigStep > eps/2);
47 
48  return tryStep.first;
49 }
50 
51 std::pair<CartesianState, double>
53  double step) const
54 {
55  RK4OneStep solver;
56  CartesianState one(solver(start, deriv, step));
57  CartesianState firstHalf(solver(start, deriv, step/2));
58  CartesianState secondHalf(solver(firstHalf, deriv, step/2));
59  double diff = distance(one, secondHalf);
60  return std::pair<CartesianState, double>(secondHalf,diff);
61 }
62 
64 {
65  return (a.position() - b.position()).mag() + (a.momentum() - b.momentum()).mag() / b.momentum().mag();
66 }
67 
69 {
70  return true;
71 }
Definition: start.py:1
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
double distance(const CartesianState &a, const CartesianState &b) const
bool verbose() const
CartesianState operator()(const CartesianState &start, const RKCartesianDerivative &deriv, double step, double eps) const
T z() const
Cartesian z coordinate.
std::pair< CartesianState, double > stepWithAccuracy(const CartesianState &start, const RKCartesianDerivative &deriv, double step) const
T min(T a, T b)
Definition: MathUtil.h:58
T perp() const
Magnitude of transverse component.
double b
Definition: hdecay.h:120
const Vector3D & momentum() const
int currentStart
Definition: mps_splice.py:64
double a
Definition: hdecay.h:121
step
const Vector3D & position() const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40