Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:11:07

0001 // -*- C++ -*-
0002 // $Id:
0003 //---------------------Runge-Kutte Integrator-------------------------------//
0004 //                                                                          //
0005 // Class RKIntegrator                                                       //
0006 // Joe Boudreau, November 2002                                              //
0007 //                                                                          //
0008 // This is a Runge-Kutta Numerical integrator for a set of N autonomous     //
0009 // first order differential equations in N variables. The point is to       //
0010 // create one or more functions which are defined by A) the differential    //
0011 // equations governing their time evolution, and B) their values at time    //
0012 // t=0.                                                                     //
0013 //                                                                          //
0014 // You add differential eqns one at a time to this integrator.  Each one    //
0015 // is a GENFUNCTION governing the time evolution of the i^th variable, and  //
0016 // should depend on all of the N variables, but not on the time             //
0017 // explicitly.  You should add N differential equations in all.   Each      //
0018 // time you add a differential equation the integrator creates a parameter  //
0019 // for you representing the starting value of the variable, and returns a   //
0020 // pointer.  You may either set the values of that parameter to desired     //
0021 // values or else connect it to an external parameter if you wish to vary   //
0022 // the shape of the function by adjusting starting values.                  //
0023 //                                                                          //
0024 // In addition, you may request the integrator to create a control          //
0025 // parameter.  The control parameter may also be set, or connected.         //
0026 // It can be used in the equations that define the time evolution of the    //
0027 // variables.                                                               //
0028 //--------------------------------------------------------------------------//
0029 #ifndef RKIntegrator_h
0030 #define RKIntegrator_h 1
0031 #include "CLHEP/GenericFunctions/AbsFunction.hh"
0032 #include "CLHEP/GenericFunctions/Parameter.hh"
0033 #include "CLHEP/GenericFunctions/RCBase.hh"
0034 #include <vector>
0035 #include <set>
0036 namespace Genfun {
0037 
0038   /**
0039    * @author
0040    * @ingroup genfun
0041    */
0042 
0043   class RKIntegrator {
0044 
0045   public:
0046 
0047     // Some helper classes:
0048     class RKFunction;
0049     class RKData;
0050     class RKStepper;
0051 
0052     // Constructor
0053     RKIntegrator(const RKStepper *stepper=NULL);
0054 
0055     // Destructor
0056     virtual ~RKIntegrator();
0057   
0058     // Add a differential equation governing the time evolution of the next variable.
0059     // Get back a parameter representing the starting value of that variable.  You 
0060     // can either arrange for that parameter to have the right starting value, or you
0061     // can connect it to another parameter so that you may change it. 
0062     Parameter * addDiffEquation (const AbsFunction  * diffEquation,
0063                  const std::string & variableName="anon",
0064                  double defStartingValue=0.0,
0065                  double startingValueMin=0.0,
0066                  double startingValueMax=0.0);
0067 
0068 
0069     // Create a control parameter.  You can then connnect this to some other
0070     // parameter.
0071     Parameter *createControlParameter (const std::string & variableName="anon",
0072                        double defStartingValue=0.0,
0073                        double startingValueMin=0.0,
0074                        double startingValueMax=0.0);
0075 
0076     // Get back a function. This function will now actually change as parameters
0077     // are changed; this includes both control parameters and starting value 
0078     // parameters.
0079     const RKFunction *getFunction(unsigned int i) const;
0080 
0081 
0082   private:
0083 
0084     // It is illegal to assign an RKIntegrator
0085     const RKIntegrator & operator=(const RKIntegrator &right);
0086 
0087     // It is illegal to copy an RKIntegrator
0088     RKIntegrator(const RKIntegrator &right);
0089   
0090     // Here is the data, it belongs to the integrator and to the
0091     // functions, and is reference counted:
0092     RKData                          *_data;
0093 
0094 
0095     // Here are the functions:
0096     std::vector<const RKFunction *> _fcn;
0097 
0098 
0099   };
0100 
0101 
0102   class RKIntegrator::RKData : public Genfun::RCBase {
0103     
0104 
0105   public:
0106     
0107     // Information about solution at each mesh point.
0108     struct Data{
0109 
0110       std::vector<double>         variable;             // Solution
0111       mutable std::vector<double> firstDerivative;      // It's first derivative
0112       double time;                                      // time
0113  
0114       Data(int size): variable(size), firstDerivative(size), time(0) {} 
0115       bool operator <  (const Data & right) const { return time < right.time; }
0116       bool operator == (const Data & right) const { return time==right.time; } 
0117     };
0118 
0119     RKData();
0120     void lock();
0121     void recache();
0122 
0123     std::vector<Parameter *>           _startingValParameter;
0124     std::vector<double>                _startingValParameterCache;
0125 
0126     std::vector <Parameter *>          _controlParameter;
0127     std::vector <double>               _controlParameterCache;
0128 
0129     std::vector<const AbsFunction *>   _diffEqn;
0130     std::set<Data >                    _fx;
0131     bool                               _locked;
0132     const RKStepper                   *_stepper;
0133   private:
0134 
0135     ~RKData();
0136     friend class ImaginaryFriend;  // Silence compiler warnings.
0137 
0138   };
0139 
0140   class RKIntegrator::RKFunction : public AbsFunction {
0141 
0142     FUNCTION_OBJECT_DEF(RKFunction)
0143 
0144       public:
0145 
0146     // Constructor
0147     RKFunction(RKData *data, unsigned int index);
0148 
0149     // Destructor
0150     virtual ~RKFunction();
0151   
0152     // Copy constructor
0153     RKFunction(const RKFunction &right);
0154   
0155     // Retreive function value
0156     virtual double operator ()(double argument) const override;
0157     virtual double operator ()(const Argument & a) const override {return operator() (a[0]);}
0158 
0159   private:
0160 
0161     // It is illegal to assign a RKFunction
0162     const RKFunction & operator=(const RKFunction &right);
0163 
0164     // The shared data:
0165     RKData              *_data;
0166     const  unsigned int  _index;
0167 
0168 };
0169 
0170 
0171   // An abstract base class for steppers:
0172   class RKIntegrator::RKStepper {
0173   public:
0174 
0175     virtual ~RKStepper();
0176     virtual void step (const RKIntegrator::RKData *data, 
0177                const RKIntegrator::RKData::Data & sdata, 
0178                RKIntegrator::RKData::Data       & ddata, 
0179                double timeLimit=0) const =0;
0180     virtual RKStepper *clone() const=0;
0181 
0182   };
0183 
0184 } // namespace Genfun
0185 
0186 #endif