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; }
change_name.diff
diff
Definition: change_name.py:13
start
Definition: start.py:1
step
step
Definition: StallMonitor.cc:94
RKCartesianDerivative
Definition: RKCartesianDerivative.h:6
min
T min(T a, T b)
Definition: MathUtil.h:58
gather_cfg.cout
cout
Definition: gather_cfg.py:144
CartesianState
Definition: CartesianState.h:8
RK4PreciseStep::stepWithAccuracy
std::pair< CartesianState, double > stepWithAccuracy(const CartesianState &start, const RKCartesianDerivative &deriv, double step) const
Definition: RK4PreciseStep.cc:49
RK4PreciseStep.h
DQMScaleToClient_cfi.factor
factor
Definition: DQMScaleToClient_cfi.py:8
b
double b
Definition: hdecay.h:118
a
double a
Definition: hdecay.h:119
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
RK4OneStep.h
mag
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Definition: Basic3DVectorLD.h:127
RK4PreciseStep::operator()
CartesianState operator()(const CartesianState &start, const RKCartesianDerivative &deriv, double step, double eps) const
Definition: RK4PreciseStep.cc:6
RK4PreciseStep::distance
double distance(const CartesianState &a, const CartesianState &b) const
Definition: RK4PreciseStep.cc:60
RK4OneStep
Definition: RK4OneStep.h:9
funct::pow
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:30
command_line.start
start
Definition: command_line.py:167
mps_splice.currentStart
int currentStart
Definition: mps_splice.py:66
RK4PreciseStep::verbose
bool verbose() const
Definition: RK4PreciseStep.cc:64