ROOT logo
// $Id: ODECrawler.h 2481 2011-06-19 06:05:23Z matevz $

#ifndef Numerica_ODECrawler_H
#define Numerica_ODECrawler_H

#include <Glasses/ZGlass.h>

#include <gsl/gsl_odeiv.h>


class ODECrawlerMaster
{
public:
  virtual ~ODECrawlerMaster() {}

  virtual Int_t  ODEOrder() = 0;
  virtual void   ODEStart(Double_t y[], Double_t& x1, Double_t& x2) = 0;
  virtual void   ODEDerivatives(Double_t x, const Double_t y[], Double_t d[]) = 0;
  virtual bool   ODEHasJacobian() const { return false; }
  virtual void   ODEJacobian(Double_t x, const Double_t y[], Double_t* dfdy, Double_t dfdt[]) {}

  ClassDef(ODECrawlerMaster, 1);
};


//==============================================================================
// ODEStorage, ODEStorageT and typedefs
//==============================================================================

class ODEStorage
{
protected:
  Int_t      mOrder;
  Int_t      mSize;

public:
  ODEStorage() :
    mOrder(0), mSize(0) {}
  ODEStorage(Int_t order, Int_t capacity=128) :
    mOrder(order), mSize(0) {}
  virtual ~ODEStorage() {}

  Int_t Order() const { return mOrder; }
  Int_t Size()  const { return mSize; }

  void ResetOrder(Int_t order, Int_t capacity=-1)
  {
    // Reset storage for new ODE-order and given capacity.
    // If capacity is -1 (default), 1.2 of size is used.

    mOrder = order;
    if (capacity == -1)
      capacity = 12*mSize/10;
    Reset(capacity);
  }

  void Reset()
  {
    // Reset storage. Capacity of containers is set to 1.2 of size.

    Reset(12*mSize/10);
  }

  virtual void Reset(Int_t capacity) = 0;

  virtual void AddEntry(Double_t x, Double_t* y) = 0;

  virtual Double_t GetMinXStored()   const = 0;
  virtual Double_t GetMaxXStored()   const = 0;
  virtual Double_t GetDeltaXStored() const { return GetMaxXStored() -  GetMinXStored(); }

  ClassDef(ODEStorage, 1);
};

template<typename TT>
class ODEStorageT : public ODEStorage
{
protected:
  vector<TT> mX;
  vector<TT> mY;

public:
  ODEStorageT(Int_t order, Int_t capacity=128) :
    ODEStorage(order, capacity)
  {
    mX.reserve(capacity);
    mY.reserve(mOrder*capacity);
  }
  virtual ~ODEStorageT() {}

  virtual void Reset(Int_t capacity)
  {
    // Reset storage to given capacity.

    vector<TT> x; x.reserve(capacity);        mX.swap(x);
    vector<TT> y; y.reserve(mOrder*capacity); mY.swap(y);
    mSize = 0;
  }

  virtual void AddEntry(Double_t x, Double_t* y)
  {
    mX.push_back(x);
    size_t ys = mY.size();
    mY.resize(ys + mOrder);
    for (Int_t i = 0; i < mOrder; ++i, ++ys)
      mY[ys] = y[i];
    ++mSize;
  }

  virtual Double_t GetMinXStored()   const { return mSize > 0 ? mX[0]       : 0; }
  virtual Double_t GetMaxXStored()   const { return mSize > 0 ? mX[mSize-1] : 0; }
  virtual Double_t GetDeltaXStored() const { return mSize > 0 ? mX[mSize-1] - mX[0] : 0; }

  TT        GetX(Int_t i) const { return  mX[i];        }
  const TT* GetY(Int_t i) const { return &mY[mOrder*i]; }
  const TT* GetXArr()     const { return &mX[0];        }
  const TT* GetYArr()     const { return &mY[0];        }

  ClassDef(ODEStorageT, 1);
};

typedef ODEStorageT<Float_t>  ODEStorageF;
typedef ODEStorageT<Double_t> ODEStorageD;


//==============================================================================
// ODECrawler
//==============================================================================

class ODECrawler : public ZGlass
{
public:
  enum StepFunc_e
  {
    SF_RK2, SF_RK4, SF_RKF45, SF_RKCK, SF_RK8PD, SF_RK2Imp, SF_RK4Imp,
    SF_BSImp, SF_Gear1, SF_Gear2
  };

  static const gsl_odeiv_step_type* s_get_step_func(StepFunc_e sf);

private:
  ODECrawlerMaster  *m_true_master; //!
  Bool_t             m_crawling;    //!

  gsl_odeiv_system  *m_gsl_system;  //!
  gsl_odeiv_evolve  *m_gsl_evolve;  //!
  gsl_odeiv_control *m_gsl_control; //!
  gsl_odeiv_step    *m_gsl_step;    //!

  void _init();

  void _gsl_alloc();
  void _gsl_free();

protected:
  ZLink<ZGlass> mODEMaster;     // X{GS} L{a}

  Int_t 	mStepOK;	//! X{G}  7 ValOut(-join=>1)
  Int_t 	mStepChanged;	//! X{G}  7 ValOut()
  Int_t 	mStored;	//! X{G}  7 ValOut(-join=>1)
  Int_t 	mMaxSteps;	//  X{GS} 7 Value()
  Int_t 	mStoreMax;	//  X{GS} 7 Value(-join=>1)
  Double_t	mStoreDx;	//  X{GS} 7 Value(-range=>[0,1e12])
  ODEStorage   *mStorage;       //  X{g}

  vector<Double_t> mY;		//! X{r}
  Int_t		mN;		//  X{G}  7 ValOut()
  Double_t	mEpsAbs;	//  X{GS} 7 Value(-range=>[0,1000], -join=>1)
  Double_t	mEpsRel;	//  X{GS} 7 Value(-range=>[0,1])
  Double_t	mFacVal;	//  X{GS} 7 Value(-range=>[0,100], -join=>1)
  Double_t	mFacDer;	//  X{GS} 7 Value(-range=>[0,100])
  Double_t	mH1;		//  X{GS} 7 Value(-join=>1)
  Double_t	mHmin;		//  X{GS} 7 Value()
  Double_t      mH;             //  X{G}  7 ValOut(-join=>1)
  Bool_t        bStoreH;	//  X{GS} 7 Bool()
  StepFunc_e    mStepFunc;      //  X{GS} 7 PhonyEnum()
  StepFunc_e    mPrevStepFunc;  //!
  Double_t	mX1;		//  X{GS} 7 Value(-join=>1)
  Double_t	mX2;		//  X{GS} 7 Value()

  void          init_integration(Bool_t call_ode_start);

  void		Integrate();

public:
  ODECrawler(const Text_t* n="ODECrawler", const Text_t* t=0);
  virtual ~ODECrawler();

  void        AdvanceXLimits(Double_t delta_x=0);

  void        SetStorage(ODEStorage* s);
  void        DetachStorage();
  ODEStorage* SwapStorage(ODEStorage* s);

  void        Crawl(Bool_t call_ode_start=true); // X{ED} 7 MCWButt()

  // If you really (really) know what you're doing.
  void        ChangeOrderInPlace(Int_t order);
  Double_t*   RawYArray();

#include "ODECrawler.h7"
  ClassDef(ODECrawler, 1);
}; // endclass ODECrawler


#endif
 ODECrawler.h:1
 ODECrawler.h:2
 ODECrawler.h:3
 ODECrawler.h:4
 ODECrawler.h:5
 ODECrawler.h:6
 ODECrawler.h:7
 ODECrawler.h:8
 ODECrawler.h:9
 ODECrawler.h:10
 ODECrawler.h:11
 ODECrawler.h:12
 ODECrawler.h:13
 ODECrawler.h:14
 ODECrawler.h:15
 ODECrawler.h:16
 ODECrawler.h:17
 ODECrawler.h:18
 ODECrawler.h:19
 ODECrawler.h:20
 ODECrawler.h:21
 ODECrawler.h:22
 ODECrawler.h:23
 ODECrawler.h:24
 ODECrawler.h:25
 ODECrawler.h:26
 ODECrawler.h:27
 ODECrawler.h:28
 ODECrawler.h:29
 ODECrawler.h:30
 ODECrawler.h:31
 ODECrawler.h:32
 ODECrawler.h:33
 ODECrawler.h:34
 ODECrawler.h:35
 ODECrawler.h:36
 ODECrawler.h:37
 ODECrawler.h:38
 ODECrawler.h:39
 ODECrawler.h:40
 ODECrawler.h:41
 ODECrawler.h:42
 ODECrawler.h:43
 ODECrawler.h:44
 ODECrawler.h:45
 ODECrawler.h:46
 ODECrawler.h:47
 ODECrawler.h:48
 ODECrawler.h:49
 ODECrawler.h:50
 ODECrawler.h:51
 ODECrawler.h:52
 ODECrawler.h:53
 ODECrawler.h:54
 ODECrawler.h:55
 ODECrawler.h:56
 ODECrawler.h:57
 ODECrawler.h:58
 ODECrawler.h:59
 ODECrawler.h:60
 ODECrawler.h:61
 ODECrawler.h:62
 ODECrawler.h:63
 ODECrawler.h:64
 ODECrawler.h:65
 ODECrawler.h:66
 ODECrawler.h:67
 ODECrawler.h:68
 ODECrawler.h:69
 ODECrawler.h:70
 ODECrawler.h:71
 ODECrawler.h:72
 ODECrawler.h:73
 ODECrawler.h:74
 ODECrawler.h:75
 ODECrawler.h:76
 ODECrawler.h:77
 ODECrawler.h:78
 ODECrawler.h:79
 ODECrawler.h:80
 ODECrawler.h:81
 ODECrawler.h:82
 ODECrawler.h:83
 ODECrawler.h:84
 ODECrawler.h:85
 ODECrawler.h:86
 ODECrawler.h:87
 ODECrawler.h:88
 ODECrawler.h:89
 ODECrawler.h:90
 ODECrawler.h:91
 ODECrawler.h:92
 ODECrawler.h:93
 ODECrawler.h:94
 ODECrawler.h:95
 ODECrawler.h:96
 ODECrawler.h:97
 ODECrawler.h:98
 ODECrawler.h:99
 ODECrawler.h:100
 ODECrawler.h:101
 ODECrawler.h:102
 ODECrawler.h:103
 ODECrawler.h:104
 ODECrawler.h:105
 ODECrawler.h:106
 ODECrawler.h:107
 ODECrawler.h:108
 ODECrawler.h:109
 ODECrawler.h:110
 ODECrawler.h:111
 ODECrawler.h:112
 ODECrawler.h:113
 ODECrawler.h:114
 ODECrawler.h:115
 ODECrawler.h:116
 ODECrawler.h:117
 ODECrawler.h:118
 ODECrawler.h:119
 ODECrawler.h:120
 ODECrawler.h:121
 ODECrawler.h:122
 ODECrawler.h:123
 ODECrawler.h:124
 ODECrawler.h:125
 ODECrawler.h:126
 ODECrawler.h:127
 ODECrawler.h:128
 ODECrawler.h:129
 ODECrawler.h:130
 ODECrawler.h:131
 ODECrawler.h:132
 ODECrawler.h:133
 ODECrawler.h:134
 ODECrawler.h:135
 ODECrawler.h:136
 ODECrawler.h:137
 ODECrawler.h:138
 ODECrawler.h:139
 ODECrawler.h:140
 ODECrawler.h:141
 ODECrawler.h:142
 ODECrawler.h:143
 ODECrawler.h:144
 ODECrawler.h:145
 ODECrawler.h:146
 ODECrawler.h:147
 ODECrawler.h:148
 ODECrawler.h:149
 ODECrawler.h:150
 ODECrawler.h:151
 ODECrawler.h:152
 ODECrawler.h:153
 ODECrawler.h:154
 ODECrawler.h:155
 ODECrawler.h:156
 ODECrawler.h:157
 ODECrawler.h:158
 ODECrawler.h:159
 ODECrawler.h:160
 ODECrawler.h:161
 ODECrawler.h:162
 ODECrawler.h:163
 ODECrawler.h:164
 ODECrawler.h:165
 ODECrawler.h:166
 ODECrawler.h:167
 ODECrawler.h:168
 ODECrawler.h:169
 ODECrawler.h:170
 ODECrawler.h:171
 ODECrawler.h:172
 ODECrawler.h:173
 ODECrawler.h:174
 ODECrawler.h:175
 ODECrawler.h:176
 ODECrawler.h:177
 ODECrawler.h:178
 ODECrawler.h:179
 ODECrawler.h:180
 ODECrawler.h:181
 ODECrawler.h:182
 ODECrawler.h:183
 ODECrawler.h:184
 ODECrawler.h:185
 ODECrawler.h:186
 ODECrawler.h:187
 ODECrawler.h:188
 ODECrawler.h:189
 ODECrawler.h:190
 ODECrawler.h:191
 ODECrawler.h:192
 ODECrawler.h:193
 ODECrawler.h:194
 ODECrawler.h:195
 ODECrawler.h:196
 ODECrawler.h:197
 ODECrawler.h:198
 ODECrawler.h:199
 ODECrawler.h:200
 ODECrawler.h:201
 ODECrawler.h:202
 ODECrawler.h:203
 ODECrawler.h:204
 ODECrawler.h:205
 ODECrawler.h:206