Compute a straight line in polar coordinates (r,phi) in two dimensions to check performance and numerical stability.
Compute a straight line in polar coordinates (r,phi) in two dimensions to check performance and numerical stability.
#include <spacetime/Schwarzschild.hpp>
#include <spacetime/Geodesic853.hpp>
#include <spacetime/Acceleration.hpp>
#include <vecal/CartesianChart.hpp>
#include <spacetime/NumericalSpacetime.hpp>
#include <spacetime/IntegrateGeodesic.hpp>
#include <stdio.h>
#include <time.h>
using namespace VecAl;
{
typedef double real;
void Accel(real s, const real *x, const real *v, real *d2x_ds2) override
{
d2x_ds2[0] = x[0] * v[1] * v[1];
d2x_ds2[1] = 2/x[0] * v[0] * v[1];
}
};
void ExplicitPolarGeodesics2D()
{
PolarPath.init(2, 0.0, q.
ptr(), v.
ptr() );
for(int is=0; is<100; is++)
{
PolarPath.advance();
if (is %10 == 0)
{
double x = PolarPath.q(0) *
sin(PolarPath.q(1)),
y = PolarPath.q(0) *
cos(PolarPath.q(1));
cout <<
"{" << PolarPath.q(0) <<
","<< PolarPath.q(1) <<
"}" <<
endl;
cout <<
"\t{x=" << x <<
", y=" << y <<
"}" <<
endl;
}
}
}
void PolarGeodesics2D()
{
typedef TangentialSpace<PolarCoordinates<2>, float > Polar2Df;
typedef TangentialSpace<PolarCoordinates<2>, double > Polar2Dd;
typedef Polar2Df myChart;
typedef myChart::Metric_t Tensor;
typedef MultiArray<2, Tensor, Tensor*> TensorField;
enum { r = PolarCoordinates<2>::r, p = PolarCoordinates<2>::phi };
enum { N = 10 };
Tensor TensorStorage[N*N];
TensorField G(TensorStorage, MIndex(N,N) );
Tensor InitValue;
InitValue.set(0.L);
InitValue(r,r) = InitValue(p,p) = 1;
G.set( InitValue );
for(int ri=0; ri<N; ri++)
for(int pi=0; pi<N; pi++)
{
double P = pi * 2 * M_PI / N,
R = ri * 5.0 / N;
Tensor&g = G[ MIndex(ri, pi) ];
g(0,0) = 1;
g(1,1) = R*R;
}
NumSpacetime_t NumSpacetime(G);
{
myChart::Point q;
q[q->r] = 5; q[q->phi] = 0;
myChart::Vector v; v = 0,1;
cout <<
"Geodesic starts at q="<<q<<
"\t v="<<v<<
endl;
myPath.restart1(0, q, v);
clock_t start, finish;
start = clock();
{for(int is = 0; is<10000; is++)
{
if (is==0)
cout <<
"Path Accel: " << NumSpacetime(myPath.position(), myPath.velocity() ) <<
endl;
myPath.advance();
myChart::Point q = myPath.position();
myChart::Vector v = myPath.velocity();
double x = q[q->r] *
sin(q[q->phi] ),
y = q[q->r] *
cos(q[q->phi] );
if (is %1000 == 0)
{
cout <<
" q="<<q<<
"\tv="<<v;
cout <<
"\t{x=" << x <<
", y=" << y <<
"}" <<
endl;
}
}}
finish = clock();
printf( "DOP Geodesic: %2.1f seconds\n", (double)(finish - start) / CLOCKS_PER_SEC );
}
{
myChart::Point q;
q[q->r] = 5; q[q->phi] = 0;
myChart::Vector v; v = 0,1;
cout <<
"Geodesic starts at q="<<q<<
"\t v="<<v<<
endl;
typedef ChristoffelField<MultiArray<2, Tensor, Tensor*> > Chris_t;
Chris_t Chris(G, q);
clock_t start, finish;
start = clock();
{for(int is = 0; is<10000; is++)
{
float ds = 0.001;
myChart::Vector a;
Chris.getCoordinateAcceleration(a, v);
if (is==0)
{
Chris_t::Christoffel_t Gamma;
Chris.getLowerChristoffel(Gamma);
}
q += v*ds;
v += a*ds;
double x = q[q->r] *
sin(q[q->phi] ),
y = q[q->r] *
cos(q[q->phi] );
if (is %1000 == 0)
{
cout <<
" q="<<q<<
"\tv="<<v;
cout <<
"\t{x=" << x <<
", y=" << y <<
"}" <<
endl;
}
}}
finish = clock();
printf( "2D Geodesic: %2.1f seconds\n", (double)(finish - start) / CLOCKS_PER_SEC );
}
}
complex< _Tp > sin(const complex< _Tp > &)
complex< _Tp > cos(const complex< _Tp > &)
basic_ostream< _CharT, _Traits > & endl(basic_ostream< _CharT, _Traits > &__os)
constexpr value * ptr(int i=0) noexcept
Definition Geodesic853.hpp:43
Definition NumericalPolarGeodesic2D.cpp:25
It conformes to the concept of an Acceleration.
Definition NumericalSpacetime.hpp:45