14 #ifndef ALGORITHM_LIBRARY_H 15 #define ALGORITHM_LIBRARY_H 25 valarray<T>
MakeAxis(
const T min,
const T max,
const size_t N){
27 for (
size_t i(0); i < N; ++i) {
28 v[i] =
static_cast<T
>(i);
30 v *= (max-min)/(static_cast<T>(N-1));
36 valarray<T>
MakeCAxis(
const T min,
const T max,
const size_t N){
38 for (
size_t i(0); i < N; ++i) {
39 v[i] =
static_cast<T
>(i);
41 v *= (max-min)/(static_cast<T>(N));
42 v += min+0.5*(max-min)/(static_cast<T>(N));
46 template<
typename T>
class Axis {
51 Axis(
const T min=0,
const T max=0,
const size_t N=1){
53 v =
new valarray<T>(
MakeAxis(min,max,N));
60 if (other.
v != NULL) {
61 v =
new valarray<T>(*(other.
v));
70 template<
typename T>
class CAxis {
75 CAxis(
const T min=0,
const T max=0,
const size_t N=1){
77 v =
new valarray<T>(
MakeCAxis(min,max,N));
84 if (other.
v != NULL) {
85 v =
new valarray<T>(*(other.
v));
97 valarray<T>
x(
size_t i)
const {
return *(_x[i].v); }
98 size_t Nx(
size_t i)
const {
return (*(_x[i].
v)).size(); }
99 T
xmin(
size_t i)
const {
return (*(_x[i].
v))[0]-0.5*_dx[i]; }
100 T
xmax(
size_t i)
const {
return (*(_x[i].
v))[Nx(i)-1]+0.5*_dx[i]; }
101 size_t xdim()
const {
return _x.size(); }
102 T
dx(
size_t i)
const {
return _dx[i]; }
105 valarray<T>
xg(
size_t i)
const {
return *(_xg[i].v); }
106 size_t Nxg(
size_t i)
const {
return (*(_xg[i].
v)).size(); }
107 T
xgmin(
size_t i)
const {
return (*(_xg[i].
v))[0]-0.5*_dx[i]; }
108 T
xgmax(
size_t i)
const {
return (*(_xg[i].
v))[Nxg(i)-1]+0.5*_dx[i]; }
109 size_t xgdim()
const {
return _xg.size(); }
112 valarray<T>
p(
size_t i)
const {
return *(_p[i].v); }
113 size_t Np(
size_t i)
const {
return (*(_p[i].
v)).size(); }
114 T
pmin(
size_t i)
const {
return (*(_p[i].
v))[0]-0.5*_dp[i]; }
115 T
pmax(
size_t i)
const {
return (*(_p[i].
v))[Np(i)-1]+0.5*_dp[i]; }
116 size_t pdim()
const {
return _p.size(); }
117 T
dp(
size_t i)
const {
return _dp[i]; }
120 valarray<T>
px(
size_t i)
const {
return *(_px[i].v); }
121 size_t Npx(
size_t i)
const {
return (*(_px[i].
v)).size(); }
122 T
pxmin(
size_t i)
const {
return (*(_px[i].
v))[0]; }
123 T
pxmax(
size_t i)
const {
return (*(_px[i].
v))[Npx(i)-1]; }
124 size_t pxdim()
const {
return _px.size(); }
127 valarray<T>
py(
size_t i)
const {
return *(_py[i].v); }
128 size_t Npy(
size_t i)
const {
return (*(_py[i].
v)).size(); }
129 T
pymin(
size_t i)
const {
return (*(_py[i].
v))[0]; }
130 T
pymax(
size_t i)
const {
return (*(_py[i].
v))[Npy(i)-1]; }
131 size_t pydim()
const {
return _py.size(); }
134 valarray<T>
pz(
size_t i)
const {
return *(_pz[i].v); }
135 size_t Npz(
size_t i)
const {
return (*(_pz[i].
v)).size(); }
136 T
pzmin(
size_t i)
const {
return (*(_pz[i].
v))[0]; }
137 T
pzmax(
size_t i)
const {
return (*(_pz[i].
v))[Npz(i)-1]; }
138 size_t pzdim()
const {
return _pz.size(); }
141 AxisBundle(
const vector<T> _xmin,
const vector<T> _xmax,
const vector<size_t> _Nx,
142 const vector<T> _xgmin,
const vector<T> _xgmax,
const vector<size_t> _Nxg,
143 const vector<T> _pmax,
const vector<size_t> _Np,
144 const vector<size_t> _Npx,
const vector<size_t> _Npy,
const vector<size_t> _Npz ){
145 for (
size_t i(0); i < _Nx.size(); ++i) {
146 _x.push_back(
CAxis<T>( _xmin[i], _xmax[i], _Nx[i]));
148 for (
size_t i(0); i < _Nxg.size(); ++i) {
149 _xg.push_back(
CAxis<T>( _xgmin[i], _xgmax[i], _Nxg[i]));
151 for (
size_t i(0); i < _Nxg.size(); ++i) {
152 _dx.push_back((_xmax[i]-_xmin[i])/(static_cast<T>(_Nx[i])));
157 for (
size_t i(0); i < _Np.size(); ++i) {
158 _p.push_back(
CAxis<T>(static_cast<T>(0.0), _pmax[i], _Np[i]) );
161 for (
size_t i(0); i < _Np.size(); ++i) {
162 _dp.push_back((_pmax[i])/(static_cast<T>(_Np[i])));
165 for (
size_t i(0); i < _Npx.size(); ++i) {
166 _px.push_back(
Axis<T>( static_cast<T>(-1.0) * _pmax[i], _pmax[i], _Npx[i]));
168 for (
size_t i(0); i < _Npy.size(); ++i) {
169 _py.push_back(
Axis<T>( static_cast<T>(-1.0) * _pmax[i], _pmax[i], _Npy[i]));
171 for (
size_t i(0); i < _Npz.size(); ++i) {
172 _pz.push_back(
Axis<T>( static_cast<T>(-1.0) * _pmax[i], _pmax[i], _Npz[i]));
177 for (
size_t i(0); i < a.
xdim(); ++i) {
180 for (
size_t i(0); i < a.
xgdim(); ++i) {
183 for (
size_t i(0); i < a.
xdim(); ++i) {
189 for (
size_t i(0); i < a.
pdim(); ++i) {
192 for (
size_t i(0); i < a.
pdim(); ++i) {
193 _dp.push_back( a.
pmax(i)/a.
Np(i) );
196 for (
size_t i(0); i < a.
pxdim(); ++i) {
199 for (
size_t i(0); i < a.
pydim(); ++i) {
202 for (
size_t i(0); i < a.
pzdim(); ++i) {
212 vector< Axis<T> > _px, _py,
_pz;
213 vector< CAxis<T> > _x,
_xg, _p;
229 valarray<T> P_Legendre(0.0, Nl);
230 if ( abs(x) > 1 )
return P_Legendre;
232 T r1, sqrtx = sqrt(1.0-x*x);
238 for (
size_t l(1); l < Nl - 1; ++l){
239 r1 = 1.0 / double(l + 1);
240 P_Legendre[l+1] = P_Legendre[l] * (x*(2.0*l+1.0) * r1) -
241 P_Legendre[l-1]*(
double(l) * r1);
253 cout <<
"ERROR: " <<
"l0+1 = " << Nl <<
" < " << Nm <<
" = m0+1\n";
268 T r1, sqrtx = sqrt(1.0-x*x), fact = 1.0;
272 P_Legendre(0,0) = 1.0;
274 for (
size_t l = 1; l < Nm+1; ++l){
276 P_Legendre(l,l) = - P_Legendre(l-1,l-1)*(fact*sqrtx);
281 for (
size_t l = 0; l < ((Nm < Nl) ? Nm+1 : Nl+1); ++l){
283 P_Legendre(l+1,l) = P_Legendre(l,l)*(x*(2.0*l+1.0));
287 for (
size_t m = 0; m < Nm+1; ++m){
288 for (
size_t l = m+1; l < Nl ; ++l){
290 r1 = 1.0 / double(l - m + 1);
291 P_Legendre(l+1,m) = P_Legendre(l,m) * (x*(2.0*l+1.0) * r1) -
292 P_Legendre(l-1,m)*(double(l+m) * r1);
305 T
moment(
const vector<T> q,
const vector<T> x,
const int p){
319 integral += q[0] * pow(x[0], p)
321 for (
size_t i(1); i < q.size()-1; ++i){
322 integral += q[i] * pow(x[i], p)
323 * 0.5*(x[i+1] - x[i-1]);
325 integral += q[q.size()-1] * pow(x[q.size()-1], p)
326 * (x[q.size()-1]-x[q.size()-2]);
331 T
moment(
const vector<T> q,
const valarray<T> x,
const int p){
344 integral += q[0] * pow(x[0], p)
346 for (
size_t i(1); i < q.size()-1; ++i){
347 integral += q[i] * pow(x[i], p)
348 * 0.5*(x[i+1] - x[i-1]);
350 integral += q[q.size()-1] * pow(x[q.size()-1], p)
351 * (x[q.size()-1]-x[q.size()-2]);
355 T
moment(
const valarray<T> q,
const valarray<T> x,
const int p){
368 integral += q[0] * pow(x[0], p)
370 for (
size_t i(1); i < q.size()-1; ++i){
371 integral += q[i] * pow(x[i], p)
372 * 0.5*(x[i+1] - x[i-1]);
374 integral += q[q.size()-1] * pow(x[q.size()-1], p)
375 * (x[q.size()-1]-x[q.size()-2]);
399 integral += q[0] * pow(x[0], p)
401 / sqrt(1.0+x[0]*x[0]);
402 for (
size_t i(1); i < q.size()-1; ++i){
403 integral += q[i] * pow(x[i], p)
404 * 0.5*(x[i+1] - x[i-1])
405 / sqrt(1.0+x[i]*x[i]);
407 integral += q[q.size()-1] * pow(x[q.size()-1], p)
408 * (x[q.size()-1]-x[q.size()-2])
409 / sqrt(1.0+x[q.size()-1]*x[q.size()-1]);
430 integral += q[0] * pow(x[0], p)
432 / sqrt(1.0+x[0]*x[0]);
433 for (
size_t i(1); i < q.size()-1; ++i){
434 integral += q[i] * pow(x[i], p)
435 * 0.5*(x[i+1] - x[i-1])
436 / sqrt(1.0+x[i]*x[i]);
438 integral += q[q.size()-1] * pow(x[q.size()-1], p)
439 * (x[q.size()-1]-x[q.size()-2])
440 / sqrt(1.0+x[q.size-1]*x[q.size-1]);
461 integral += q[0] * pow(x[0], p)
463 * sqrt(1.0+x[0]*x[0]);
464 for (
size_t i(1); i < q.size()-1; ++i){
465 integral += q[i] * pow(x[i], p)
466 * 0.5*(x[i+1] - x[i-1])
467 * sqrt(1.0+x[i]*x[i]);
469 integral += q[q.size()-1] * pow(x[q.size()-1], p)
470 * (x[q.size()-1]-x[q.size()-2])
471 * sqrt(1.0+x[q.size-1]*x[q.size-1]);
483 virtual void operator()(
const T& Yin, T& Yslope)=0;
484 virtual void operator()(
const T& Yin, T& Yslope,
size_t dir)=0;
489 template<
class T>
class RK2 {
492 RK2(T& Yin): Y0(Yin), Yh(Yin) { }
511 (*F)(Y0,Yh); Yh *= h;
517 (*F)(Y0,Yh); Yh *= 0.5*h;
531 (*F)(Y0,Yh,dir); Yh *= h;
537 (*F)(Y0,Yh,dir); Yh *= 0.5*h;
546 template<
class T>
class RK3 {
549 RK3(T& Yin): Y0(Yin), Yh(Yin) { }
569 (*F)(Y0,Yh); Yh *= h;
575 (*F)(Y0,Yh); Yh *= h;
576 Y0 += Yh; Y *= 3.0; Y0 += Y; Y0 *= 0.25;
581 (*F)(Y0,Yh); Yh *= h;
582 Y0 += Yh; Y0 *= 6.0; Y += Y0; Y *= (1.0/9.0);
597 (*F)(Y0,Yh,dir); Yh *= h;
603 (*F)(Y0,Yh,dir); Yh *= h;
604 Y0 += Yh; Y *= 3.0; Y0 += Y; Y0 *= 0.25;
609 (*F)(Y0,Yh,dir); Yh *= h;
610 Y0 += Yh; Y0 *= 6.0; Y += Y0; Y *= (1.0/9.0);
620 template<
class T>
class RK4 {
623 RK4(T& Yin): Y0(Yin), Y1(Yin), Yh(Yin) { }
643 Yh *= (0.5*h); Y1 += Yh;
644 Yh *= (1.0/3.0); Y += Yh;
648 (*F)(Y1,Yh); Y1 = Y0;
649 Yh *= (0.5*h); Y1 += Yh;
650 Yh *= (2.0/3.0); Y += Yh;
656 Yh *= (1.0/3.0); Y += Yh;
661 Yh *= (h/6.0); Y += Yh;
675 Yh *= (0.5*h); Y1 += Yh;
676 Yh *= (1.0/3.0); Y += Yh;
680 (*F)(Y1,Yh,dir); Y1 = Y0;
681 Yh *= (0.5*h); Y1 += Yh;
682 Yh *= (2.0/3.0); Y += Yh;
688 Yh *= (1.0/3.0); Y += Yh;
693 Yh *= (h/6.0); Y += Yh;
724 (*F_space)(Y0,Yh); Yh *= 0.5*h;
726 (*F_momentum)(Y0,Yh); Yh *= h;
728 (*F_space)(Y0,Yh); Yh *= 0.5*h;
744 (*F_space)(Y0,Yh); Yh *= 0.5*h;
746 (*F_momentum)(Y0,Yh); Yh *= h;
748 (*F_space)(Y0,Yh); Yh *= 0.5*h;
781 (*F_momentum)(Y0,Yh); Yh *= 0.5*h;
783 (*F_space)(Y0,Yh); Yh *= h;
785 (*F_momentum)(Y0,Yh); Yh *= 0.5*h;
800 (*F_momentum)(Y0,Yh); Yh *= 0.5*h;
802 (*F_space)(Y0,Yh); Yh *= h;
804 (*F_momentum)(Y0,Yh); Yh *= 0.5*h;
820 xsi(0.1786178958448091),
821 lambda(-0.2123418310626054),
822 chi(-0.06626458266981849)
843 (*F_space)(Y0,Yh); Yh *= xsi*h;
846 (*F_momentum)(Y0,Yh); Yh *= (1.0-2.0*lambda)*0.5*h;
849 (*F_space)(Y0,Yh); Yh *= chi*h;
852 (*F_momentum)(Y0,Yh); Yh *= lambda*h;
855 (*F_space)(Y0,Yh); Yh *= (1.0-2.0*(chi+xsi))*h;
858 (*F_momentum)(Y0,Yh); Yh *= lambda*h;
861 (*F_space)(Y0,Yh); Yh *= chi*h;
864 (*F_momentum)(Y0,Yh); Yh *= (1.0-2.0*lambda)*0.5*h;
867 (*F_space)(Y0,Yh); Yh *= xsi*h;
883 (*F_space)(Y0,Yh); Yh *= xsi*h;
886 (*F_momentum)(Y0,Yh); Yh *= (1.0-2.0*lambda)*0.5*h;
889 (*F_space)(Y0,Yh); Yh *= chi*h;
892 (*F_momentum)(Y0,Yh); Yh *= lambda*h;
895 (*F_space)(Y0,Yh); Yh *= (1.0-2.0*(chi+xsi))*h;
898 (*F_momentum)(Y0,Yh); Yh *= lambda*h;
901 (*F_space)(Y0,Yh); Yh *= chi*h;
904 (*F_momentum)(Y0,Yh); Yh *= (1.0-2.0*lambda)*0.5*h;
907 (*F_space)(Y0,Yh); Yh *= xsi*h;
930 Clock(
int tout_start,
double dt_out,
double CFL) {
932 _t_start = double(tout_start)*dt_out;
933 _numh = size_t(static_cast<int>(dt_out/CFL))+1;
934 _h = dt_out/
static_cast<double>(_numh);
938 double h()
const {
return _h;}
939 size_t numh()
const {
return _numh;}
940 size_t tick()
const {
return _hstep;}
941 double time()
const {
return tick()*h() + _t_start;}
valarray< T > py(size_t i) const
Clock(int tout_start, double dt_out, double CFL)
AxisBundle(const vector< T > _xmin, const vector< T > _xmax, const vector< size_t > _Nx, const vector< T > _xgmin, const vector< T > _xgmax, const vector< size_t > _Nxg, const vector< T > _pmax, const vector< size_t > _Np, const vector< size_t > _Npx, const vector< size_t > _Npy, const vector< size_t > _Npz)
valarray< T > Legendre(const T x, const size_t Nl)
valarray< T > px(size_t i) const
Axis(const T min=0, const T max=0, const size_t N=1)
size_t Npy(size_t i) const
valarray< T > xg(size_t i) const
AxisBundle(const AxisBundle &a)
T relativistic_invg_moment(const vector< T > q, const valarray< T > x, const int p)
size_t Np(size_t i) const
valarray< T > MakeAxis(const T min, const T max, const size_t N)
CAxis(const T min=0, const T max=0, const size_t N=1)
T relativistic_gamma_moment(const valarray< T > q, const valarray< T > x, const int p)
valarray< T > p(size_t i) const
CAxis(const CAxis &other)
size_t Npx(size_t i) const
valarray< T > MakeCAxis(const T min, const T max, const size_t N)
size_t Npz(size_t i) const
size_t Nx(size_t i) const
size_t Nxg(size_t i) const
valarray< T > x(size_t i) const
valarray< T > pz(size_t i) const
T moment(const vector< T > q, const vector< T > x, const int p)