CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
RKIntegrator.cc
Go to the documentation of this file.
1// -*- C++ -*-
2// $Id:
3#include "CLHEP/GenericFunctions/RKIntegrator.hh"
4#include "CLHEP/GenericFunctions/AdaptiveRKStepper.hh"
5#include "CLHEP/GenericFunctions/Variable.hh"
6#include <climits>
7#include <memory>
8#include <stdexcept>
9#include <vector>
10
11namespace Genfun {
12FUNCTION_OBJECT_IMP(RKIntegrator::RKFunction)
13
14RKIntegrator::RKFunction::RKFunction(RKData *data, unsigned int index)
15 :_data(data),
16 _index(index)
17{
18 _data->ref();
19}
20
22{
23 _data->unref();
24}
25
27 :AbsFunction(right),
28 _data(right._data),
29 _index(right._index)
30{
31 _data->ref();
32}
33
34
36 if (t<0) return 0;
37 if (!_data->_locked) _data->lock();
38
39 // Do this first, thereafter, just read the cache
40 _data->recache();
41
42
43 // If the cache is empty, make an entry for t=0;
44 size_t nvar = _data->_startingValParameter.size();
45 if (_data->_fx.empty()) {
46 RKData::Data d((int)nvar);
47 d.time=0;
48 Argument arg((int)nvar);
49 for (size_t f=0;f<nvar;f++) {
51 arg[(int)f]=d.variable[f];
52 }
53 _data->_fx.insert(d);
54 }
55
56 if (t==0) return (*_data->_fx.begin()).variable[_index];
57
58 RKData::Data dt((int)nvar);
59 dt.time=t;
60 std::set<RKData::Data>::iterator l =_data->_fx.lower_bound(dt);
61
62 // We did find an exact value (measure 0), just return it.
63 if (l!=_data->_fx.end() && (*l).time==t) {
64 return (*l).variable[_index];
65 }
66
67 else {
68 std::set<RKData::Data>::iterator u =_data->_fx.upper_bound(dt);
69
70 while (u==_data->_fx.end()) {
71 u--;
72 RKData::Data newData((int)nvar);;
73 _data->_stepper->step(_data,*u, newData, 0);
74 _data->_fx.insert(l,newData);
75 if (newData.time==t) return newData.variable[_index];
76 u = _data->_fx.upper_bound(dt);
77 }
78 u--;
79 _data->_stepper->step(_data,*u, dt, t);
80 return dt.variable[_index];
81 }
82}
83
84
86}
87
88RKIntegrator::RKData::~RKData() {
89 for (size_t i=0;i<_startingValParameter.size();i++) delete _startingValParameter[i];
90 for (size_t i=0;i<_controlParameter.size();i++) delete _controlParameter[i];
91 for (size_t i=0;i<_diffEqn.size(); i++) delete _diffEqn[i];
92 delete _stepper;
93}
94
96 _data(new RKData())
97{
98 if (stepper) _data->_stepper=stepper->clone();
99 else _data->_stepper= new AdaptiveRKStepper();
100 _data->ref();
101}
102
104 _data->unref();
105 for (size_t i=0;i<_fcn.size();i++) delete _fcn[i];
106}
107
109 const std::string &variableName,
110 double defStartingValue,
111 double defValueMin,
112 double defValueMax) {
113 Parameter *par = new Parameter(variableName, defStartingValue, defValueMin, defValueMax);
114 _data->_startingValParameter.push_back(par);
115 _data->_diffEqn.push_back(diffEquation->clone());
116 _data->_startingValParameterCache.push_back(defStartingValue);
117 _fcn.push_back(new RKFunction(_data,(unsigned int)_fcn.size()));
118 return par;
119}
120
121
122
123
124
125Parameter * RKIntegrator::createControlParameter (const std::string & variableName,
126 double defStartingValue,
127 double startingValueMin,
128 double startingValueMax) {
129
130 Parameter *par = new Parameter(variableName, defStartingValue, startingValueMin, startingValueMax);
131 _data->_controlParameter.push_back(par);
132 _data->_controlParameterCache.push_back(defStartingValue);
133 return par;
134
135}
136
137
138
140 return _fcn[i];
141}
142
143
144
146 if (!_locked) {
147 unsigned int size = (unsigned int)_diffEqn.size();
148 for (size_t i=0;i<size;i++) {
149 if (!(_diffEqn[i]->dimensionality()==size)) throw std::runtime_error("Runtime error in RKIntegrator");
150 }
151 _locked=true;
152 }
153}
154
155
156
158
159 bool stale=false;
160 if (!stale) {
161 for (size_t p=0;p<_startingValParameter.size();p++) {
162 if (_startingValParameter[p]->getValue()!=_startingValParameterCache[p]) {
163 _startingValParameterCache[p]=_startingValParameter[p]->getValue();
164 stale=true;
165 break;
166 }
167 }
168 }
169
170 if (!stale) {
171 for (size_t p=0;p<_controlParameter.size();p++) {
172 if (_controlParameter[p]->getValue()!=_controlParameterCache[p]) {
173 _controlParameterCache[p]=_controlParameter[p]->getValue();
174 stale=true;
175 break;
176 }
177 }
178 }
179
180 if (stale) {
181 _fx.erase(_fx.begin(),_fx.end());
182 }
183
184}
185
186
187
189
190
191} // namespace Genfun
#define FUNCTION_OBJECT_IMP(classname)
Definition: AbsFunction.hh:149
virtual AbsFunction * clone() const =0
void unref() const
Definition: RCBase.cc:20
void ref() const
Definition: RCBase.cc:15
std::vector< Parameter * > _startingValParameter
std::vector< double > _startingValParameterCache
std::vector< double > _controlParameterCache
std::vector< const AbsFunction * > _diffEqn
std::vector< Parameter * > _controlParameter
const RKStepper * _stepper
RKFunction(RKData *data, unsigned int index)
Definition: RKIntegrator.cc:14
virtual double operator()(double argument) const override
Definition: RKIntegrator.cc:35
virtual void step(const RKIntegrator::RKData *data, const RKIntegrator::RKData::Data &sdata, RKIntegrator::RKData::Data &ddata, double timeLimit=0) const =0
virtual RKStepper * clone() const =0
Parameter * addDiffEquation(const AbsFunction *diffEquation, const std::string &variableName="anon", double defStartingValue=0.0, double startingValueMin=0.0, double startingValueMax=0.0)
Parameter * createControlParameter(const std::string &variableName="anon", double defStartingValue=0.0, double startingValueMin=0.0, double startingValueMax=0.0)
RKIntegrator(const RKStepper *stepper=NULL)
Definition: RKIntegrator.cc:95
const RKFunction * getFunction(unsigned int i) const
void f(void g())
Definition: excDblThrow.cc:38
Definition: Abs.hh:14
std::vector< double > variable