Exemple #1
0
// Iterative method to calculate new X and Z values for the specified time of flight
static inline void CalcXandZ(double &X, double &Z, const VECTOR3 Pos, const VECTOR3 Vel,
							 double a, const double Time, const double SqrtMu)
{
	const double MAX_ITERS = 10;
	double C, S, T, dTdX, DeltaTime, r = Mag(Pos), IterNum = 0;

	// These don't change over the iterations
	double RVMu = (Pos * Vel) / SqrtMu;		// Dot product of position and velocity divided
											// by the squareroot of Mu
	double OneRA = (1 - (r / a));			// One minus Pos over the semi-major axis

	C = CalcC(Z);
	S = CalcS(Z);
	T = ((RVMu * pow(X, 2) * C) +  (OneRA * pow(X, 3) * S) + (r * X)) / SqrtMu;

	DeltaTime = Time - T;

	// Iterate while the result isn't within tolerances
	while (fabs(DeltaTime) > EPSILON && IterNum++ < MAX_ITERS) {
		dTdX = ((pow(X, 2) * C) + (RVMu * X * (1 - Z * S)) + (r * (1 - Z * C))) / SqrtMu;

		X = X + (DeltaTime / dTdX);
		Z = CalcZ(X, a);

		C = CalcC(Z);
		S = CalcS(Z);
		T = ((RVMu * pow(X, 2) * C) +  (OneRA * pow(X, 3) * S) + (r * X)) / SqrtMu;

		DeltaTime = Time - T;

	}


}
Exemple #2
0
// Given the specified position and velocity vectors for a given orbit, retuns the position
// and velocity vectors after a specified time
void PredictPosVelVectors(const VECTOR3 &Pos, const VECTOR3 &Vel, double a, double Mu,
						  double Time, VECTOR3 &NewPos, VECTOR3 &NewVel, double &NewVelMag)
{
	double SqrtMu = sqrt(Mu);

	// Variables for computation
	double X = (SqrtMu * Time) / a;					// Initial guesses for X
	double Z = CalcZ(X, a);							// and Z
	double C, S;									// C(Z) and S(Z)
	double F, FDot, G, GDot;

	// Calculate the X and Z for the specified time of flight
	CalcXandZ(X, Z, Pos, Vel, a, Time, SqrtMu);

	// Calculate C(Z) and S(Z)
	C = CalcC(Z);
	S = CalcS(Z);

	// Calculate the new position and velocity vectors
	F = CalcF(X, C, Mag(Pos));
	G = CalcG(Time, X, S, SqrtMu);
	NewPos = (Pos * F) + (Vel * G);

	FDot = CalcFDot(SqrtMu, Mag(Pos), Mag(NewPos), X, Z, S);
	GDot = CalcGDot(X, C, Mag(NewPos));

	NewVel = (Pos * FDot) + (Vel * GDot);

	NewVelMag = Mag(NewVel);
}
ribi::PlaneZ::Coordinats2D ribi::PlaneZ::CalcProjection(
  const Coordinats3D& points
) const
{
  assert(points.size() >= 3);
  const double x_origin = 0.0;
  const double y_origin = 0.0;
  const double z_origin = CalcZ(x_origin,y_origin);

  Coordinats2D v;
  for (const auto& point: points)
  {
    const Double x(boost::geometry::get<0>(point));
    const Double y(boost::geometry::get<1>(point));
    const Double z(boost::geometry::get<2>(point));
    const Double dx =
      sqrt( //Apfloat does not add the std::
          ((x - x_origin) * (x - x_origin))
        + ((z - z_origin) * (z - z_origin))
      ) * (x - x_origin)
    ;
    const Double dy =
      sqrt( //Apfloat does not add the std::
          ((y - y_origin) * (y - y_origin))
        + ((z - z_origin) * (z - z_origin))
      ) * (y - y_origin)
    ;

    Coordinat2D point_xy(dx,dy);
    v.push_back(point_xy);
  }
  return v;
}
double ribi::PlaneZ::CalcError(const Coordinat3D& coordinat) const noexcept
{
  const double x = boost::geometry::get<0>(coordinat);
  const double y = boost::geometry::get<1>(coordinat);
  const double z = boost::geometry::get<2>(coordinat);
  const double expected{z};
  const double calculated{CalcZ(x,y)};
  const double error{std::abs(calculated - expected)};
  return error;
}
Exemple #5
0
double CalcR(double (*y)(double), double a, double b)
{
    double z = CalcZ(y,a,b);
    double w = CalcW(y,a,b);
    return a+(b-a)*(z-derevative(y,a)+w)/(derevative(y,b)-derevative(y,a)+2*w);
}
Exemple #6
0
double CalcW(double (*y)(double), double a, double b)
{
    double z = CalcZ(y,a,b);
    return sqrt(z*z - derevative(y,a)*derevative(y,b));
}
Exemple #7
0
void SmallFlowStep(ConfigData *config) {
  // Here we have to implement the RK scheme from 1006.4518 [hep-lat]
  // Appendix C
  // W_0 = V_t
  // W_1 = exp(1/4 Z_0) W_0
  // W_2 = exp(8/9 Z_1 - 17/36 Z_0) W_1
  // W_t+eps = exp(3/4 Z_2 - 8/9 Z_1 + 17/36 Z_0) W_2
  //
  // Z_i = eps Z(W_i)
  //
  // The input configuration 'config' will be overwritten with the
  // configuration at flow time t'=t+eps.
  
  // We allocate a new ConfigData
  // W_0 = V_t : W0 = config;
  ConfigData *S0 = new ConfigData(opt.ns, opt.ns, opt.ns, opt.nt, 3);
  
  // W_1 = exp(1/4 Z_0) W_0
  ConfigData *W1 = new ConfigData(opt.ns, opt.ns, opt.ns, opt.nt, 3);

  #pragma omp parallel for
  for (int x=0; x<opt.ns*opt.ns*opt.ns*opt.nt; x++) {
    std::complex<double> U[3][3], Z0[3][3], A[3][3], expA[3][3], newU[3][3];
    for (int mu=0; mu<4; mu++) {
      // For link U_x,mu
      CalcZ(Z0, config, x, mu);
      S0->replace(*Z0, x, mu); // save this into ConfigData for Z0s
      za(A, 1.0/4.0*opt.eps, Z0);

      expM(expA, A);
      config->extract(*U, x, mu);
      axb(newU, expA, U);

      #ifdef DEBUG
        if (testUnitarity(newU) > 1e-5) {
          std::cout << "WARNING: New link in SmallFlowStep() not unitary anymore!" << std::endl;
        }
      #endif

      W1->replace(*newU, x, mu);
    }
  }
  
  // W_2 = exp(8/9 Z_1 - 17/36 Z_0) W_1
  ConfigData *W2 = new ConfigData(opt.ns, opt.ns, opt.ns, opt.nt, 3);
  
  #pragma omp parallel for
  for (int x=0; x<opt.ns*opt.ns*opt.ns*opt.nt; x++) {
    std::complex<double> U[3][3], Z0[3][3], Z1[3][3], A[3][3], A2[3][3], expA[3][3], newU[3][3];
    for (int mu=0; mu<4; mu++) {
      // First part with Z0
      S0->extract(*Z0, x, mu); // get this from ConfigData for Z0s
      za(A, -17.0/36.0*opt.eps, Z0);

      // Add second part with Z1
      CalcZ(Z1, W1, x, mu);
      za(A2, 8.0/9.0*opt.eps, Z1);

      // Add both parts
      apb(A,A2);
      S0->replace(*A, x, mu); // save this into ConfigData S0 (A=-17/36*Z0 + 8/9*Z1)

      expM(expA, A);
      W1->extract(*U, x, mu);
      axb(newU, expA, U);

      #ifdef DEBUG
        if (testUnitarity(newU) > 1e-5) {
          std::cout << "WARNING: New link in SmallFlowStep() not unitary anymore!" << std::endl;
        }
      #endif

      W2->replace(*newU, x, mu);
    }
  }
  delete W1; W1 = 0;
  
  // W_t+eps = exp(3/4 Z_2 - 8/9 Z_1 + 17/36 Z_0) W_2
  
  #pragma omp parallel for
  for (int x=0; x<opt.ns*opt.ns*opt.ns*opt.nt; x++) {
    std::complex<double> U[3][3], Z0[3][3], Z2[3][3], A[3][3], A2[3][3], expA[3][3], newU[3][3];
    for (int mu=0; mu<4; mu++) {
      // For link U_x,mu
      
      // First part with Z0 and Z1
      S0->extract(*Z0, x, mu); // load -17/36*Z0 + 8/9*Z1
      za(A, -1.0, Z0); // switch the sign
      
      // Add third part with Z2
      CalcZ(Z2, W2, x, mu);
      za(A2, 3.0/4.0*opt.eps, Z2);
      
      // Add both parts
      apb(A,A2);

      expM(expA, A);
      W2->extract(*U, x, mu);
      axb(newU, expA, U);

      #ifdef DEBUG
        if (testUnitarity(newU) > 1e-5) {
          std::cout << "WARNING: New link in SmallFlowStep() not unitary anymore!" << std::endl;
        }
      #endif

      config->replace(*newU, x, mu);
    }
  }

  // Cleaning up
  delete W2; W2 = 0;
  delete S0; S0 = 0;
}