Exemplo n.º 1
0
Arquivo: rmhd.cpp Projeto: jzrake/ctf
int Rmhd::PrimToCons(const double *P, double *U) const
{
  const double V2   =   P[vx]*P[vx] + P[vy]*P[vy] + P[vz]*P[vz];
  const double B2   =   P[Bx]*P[Bx] + P[By]*P[By] + P[Bz]*P[Bz];
  const double Bv   =   P[Bx]*P[vx] + P[By]*P[vy] + P[Bz]*P[vz];
  const double W2   =   1.0 / (1.0 - V2);
  const double W    =   sqrt(W2);
  const double b0   =   W*Bv;
  const double b2   =   (B2 + b0*b0) / W2;
  const double bx   =  (P[Bx] + b0 * W*P[vx]) / W;
  const double by   =  (P[By] + b0 * W*P[vy]) / W;
  const double bz   =  (P[Bz] + b0 * W*P[vz]) / W;
  const double e    =   EOS->Internal(P[rho], EOS->Temperature_p(P[rho], P[pre]))/P[rho];
  const double e_   =   e      + 0.5 * b2 / P[rho];
  const double p_   =   P[pre] + 0.5 * b2;
  const double h_   =   1 + e_ + p_ / P[rho];

  U[ddd] = P[rho] * W;
  U[tau] = P[rho] * h_ * W2 - p_    - b0*b0 - U[ddd];
  U[Sx ] = P[rho] * h_ * W2 * P[vx] - b0*bx;
  U[Sy ] = P[rho] * h_ * W2 * P[vy] - b0*by;
  U[Sz ] = P[rho] * h_ * W2 * P[vz] - b0*bz;
  U[Bx ] = P[Bx ];
  U[By ] = P[By ];
  U[Bz ] = P[Bz ];

  if (V2 >= 1.0) {
    return RMHD_C2P_PRIM_SUPERLUMINAL;
  }
  return rmhd_c2p_check_cons(U);
}
Exemplo n.º 2
0
Arquivo: rmhd.cpp Projeto: jzrake/ctf
int Rmhd::ConsToPrim(const double *U, double *P) const
{
  int error = rmhd_c2p_check_cons(U);

  if (error) {
    fprintf(stderr, "[0] %s\n", rmhd_c2p_get_error(error));
    std::cerr << PrintCons(U) << std::endl;
    return error;
  }
  else {
    error = 1;
  }

  // This piece of code drives cons to prim inversions for an arbitrary equation
  // of state.
  // ---------------------------------------------------------------------------
  if (typeid(*EOS) != typeid(AdiabaticEos)) {

    rmhd_c2p_eos_set_eos(EOS);
    rmhd_c2p_eos_new_state(U);

    //    std::cout << PrintPrim(P) << std::endl;
    //    std::cout << PrintCons(U) << std::endl;

    if (error) {
      rmhd_c2p_eos_set_starting_prim(P);
      error = rmhd_c2p_eos_solve_duffell3d(P);
    }
    if (error) {

      // NOTE: disregarding further c2p trials for debugging purposes
      return error;
      // ------------------------------------------------------------

      rmhd_c2p_eos_set_starting_prim(P);
      error = rmhd_c2p_eos_solve_noble2dzt(P);
    }
    if (error) {
      rmhd_c2p_eos_estimate_from_cons();
      error = rmhd_c2p_eos_solve_noble2dzt(P);
    }

    return error;
  }

  // This piece of code drives cons to prim inversions for a gamma-law equation
  // of state.
  // ---------------------------------------------------------------------------
  rmhd_c2p_set_gamma(Mara->GetEos<AdiabaticEos>().Gamma);
  rmhd_c2p_new_state(U);

  if (error) {
    rmhd_c2p_estimate_from_cons();
    error = rmhd_c2p_solve_anton2dzw(P);
    //    if (error) fprintf(stderr, "[1] %s\n", rmhd_c2p_get_error(error));
  }
  if (error) {
    rmhd_c2p_set_starting_prim(P);
    error = rmhd_c2p_solve_anton2dzw(P);
    //    if (error) fprintf(stderr, "[2] %s\n", rmhd_c2p_get_error(error));
  }
  if (error) {
    rmhd_c2p_estimate_from_cons();
    error = rmhd_c2p_solve_noble1dw(P);
    //    if (error) fprintf(stderr, "[3] %s\n", rmhd_c2p_get_error(error));
  }
  if (error) {
    rmhd_c2p_set_starting_prim(P);
    error = rmhd_c2p_solve_noble1dw(P);
    //    if (error) fprintf(stderr, "[4] %s\n", rmhd_c2p_get_error(error));
  }

  return error;
}
Exemplo n.º 3
0
Arquivo: rmhd.cpp Projeto: jzrake/ctf
int Rmhd::ConsCheck(const double *U) const
{
  return rmhd_c2p_check_cons(U);
}
Exemplo n.º 4
0
// Solution based on Noble et. al. (2006), using Z = rho h W^2 as the single
// unkown. Unfortunately, Noble uses 'W' for what I call Z. This function should
// really be called '1dz', but I use this name to reflect the name of the
// section in which it appears.
// -----------------------------------------------------------------------------
int rmhd_c2p_solve_noble1dw(double *P)
{
  int bad_input = rmhd_c2p_check_cons(Cons);
  if (bad_input) {
    return bad_input;
  }
  // Starting values
  // ---------------------------------------------------------------------------
  Iterations = 0;
  double error = 1.0;
  double Z = Z_start;

  double f, g;

  while (error > Tolerance) {

    const double Z2  = Z*Z;
    const double Z3  = Z*Z2;
    const double a   = S2*Z2 + BS2*(B2 + 2*Z);
    const double b   = (B2 + Z)*(B2 + Z)*Z2;
    const double ap  = 2*(S2*Z + BS2);          // da/dZ
    const double bp  = 2*Z*(B2 + Z)*(B2 + 2*Z); // db/dZ
    const double V2  = a / b;
    const double W2  = 1.0 / (1.0 - V2);
    const double W   = sqrt(W2);
    const double W3  = W*W2;
    const double Pre = (D/W) * (Z/(D*W) - 1.0) * gamf;

    const double dv2dZ    = (ap*b - bp*a) / (b*b); // (a'b - b'a) / b^2
    const double delPdelZ = gamf/W2;
    const double delPdelW = gamf*(D/W2 - 2*Z/W3);
    const double dWdv2    = 0.5*W3;
    const double dPdZ     = delPdelW * dWdv2 * dv2dZ + delPdelZ;

    f = Tau + D - 0.5*B2*(1+V2) + 0.5*BS2/Z2 - Z + Pre; // equation (29)
    g = -0.5*B2*dv2dZ - BS2/Z3 - 1.0 + dPdZ;

    const double dZ = -f/g;

    // -------------------------------------------------------------------------
    double Z_new = Z + dZ;

    Z_new = (Z_new > smlZ) ? Z_new : -Z_new;
    Z_new = (Z_new < bigZ) ? Z_new :  Z;

    Z = Z_new;

    error = fabs(dZ/Z);
    ++Iterations;

    if (Iterations == MaxIteration) {
      return RMHD_C2P_MAXITER;
    }
  }

  // Recover the W value from the converged Z value.
  // -------------------------------------------------------------------------
  const double Z2  = Z*Z;
  const double a   = S2*Z2 + BS2*(B2 + 2*Z);
  const double b   = (B2 + Z)*(B2 + Z)*Z2;
  const double V2  = a / b;
  const double W2  = 1.0 / (1.0 - V2);
  const double W   = sqrt(W2);

  return rmhd_c2p_reconstruct_prim(Z, W, P);
}
Exemplo n.º 5
0
// Solution based on Anton & Zanotti (2006), equations 84 and 85.
// -----------------------------------------------------------------------------
int rmhd_c2p_solve_anton2dzw(double *P)
{
  int bad_input = rmhd_c2p_check_cons(Cons);
  if (bad_input) {
    return bad_input;
  }
  // Starting values
  // ---------------------------------------------------------------------------
  Iterations = 0;
  double error = 1.0;
  double W = W_start;
  double Z = Z_start;

  while (error > Tolerance) {

    const double Z2 = Z*Z;
    const double Z3 = Z*Z2;
    const double W2 = W*W;
    const double W3 = W*W2;
    const double Pre = (D/W) * (Z/(D*W) - 1.0) * gamf;

    const double df0dZ = 2*(B2+Z)*(BS2*W2 + (W2-1)*Z3) / (W2*Z3);
    const double df0dW = 2*(B2+Z)*(B2+Z) / W3;
    const double df1dZ = 1.0 + BS2/Z3 - gamf/W2;
    const double df1dW = B2/W3 + (2*Z - D*W)/W3 * gamf;

    double f[2];
    double J[4], G[4];


    // Evaluation of the function, and its Jacobian
    // -------------------------------------------------------------------------
    f[0] = -S2  + (Z+B2)*(Z+B2)*(W2-1)/W2 - (2*Z+B2)*BS2/Z2;      // eqn (84)
    f[1] = -Tau +  Z+B2 - Pre - 0.5*B2/W2 -      0.5*BS2/Z2 - D;  // eqn (85)

    J[0] = df0dZ; J[1] = df0dW;
    J[2] = df1dZ; J[3] = df1dW;

    // G in the inverse Jacobian
    // -------------------------------------------------------------------------
    const double det = J[0]*J[3] - J[1]*J[2];
    G[0] =  J[3]/det; G[1] = -J[1]/det;
    G[2] = -J[2]/det; G[3] =  J[0]/det;      // G = J^{-1}

    const double dZ = -(G[0]*f[0] + G[1]*f[1]); // Matrix multiply, dx = -G . f
    const double dW = -(G[2]*f[0] + G[3]*f[1]);

    // Bracketing the root
    // -------------------------------------------------------------------------
    double Z_new = Z + dZ;
    double W_new = W + dW;

    Z_new = (Z_new > smlZ) ? Z_new : -Z_new;
    Z_new = (Z_new < bigZ) ? Z_new :  Z;

    W_new = (W_new > smlW) ? W_new : smlW;
    W_new = (W_new < bigW) ? W_new : bigW;

    Z = Z_new;
    W = W_new;

    // -------------------------------------------------------------------------
    error = fabs(dZ/Z) + fabs(dW/W);
    ++Iterations;

    if (Iterations == MaxIteration) {
      return RMHD_C2P_MAXITER;
    }
  }

  return rmhd_c2p_reconstruct_prim(Z, W, P);
}