Beispiel #1
0
// calculates the inverted flux, for testing purposes
// it should return the same thing as riemann_solver(), only with minus sign
void NumericalFlux::riemann_solver_invert(double result[4], double w_l[4], double w_r[4])
{
    double m[4][4];
    double _w_l[4];
    double _w_r[4];
    double _tmp[4];
    T_rot(m, M_PI);
    dot_vector(_w_l, m, w_l);
    dot_vector(_w_r, m, w_r);
    riemann_solver(_tmp, _w_r, _w_l);
    T_rot(m, -M_PI);
    dot_vector(result, m, _tmp);
}
Beispiel #2
0
// Calculates the numerical flux in the normal (nx, ny) by rotating into the
// local system, solving the Riemann problem and rotating back. It returns the
// state as a 4-component vector.
void NumericalFlux::numerical_flux(double result[4], double w_l[4], double w_r[4],
        double nx, double ny)
{
    double alpha = atan2(ny, nx);
    double mat_rot[4][4];
    double mat_rot_inv[4][4];
    double w_l_local[4];
    double w_r_local[4];
    double flux_local[4];
    T_rot(mat_rot, alpha);
    T_rot(mat_rot_inv, -alpha);
    dot_vector(w_l_local, mat_rot, w_l);
    dot_vector(w_r_local, mat_rot, w_r);
    riemann_solver(flux_local, w_l_local, w_r_local);
    dot_vector(result, mat_rot_inv, flux_local);
}
Beispiel #3
0
static void riemann_solver(m2vol *VL, m2vol *VR, int axis, double *F,
                           int suppress_extrapolation)
{
  int q;
  m2riemann_problem R = { .m2 = VL->m2 };
  double *UL = R.Ul;
  double *UR = R.Ur;
  double *FL = R.Fl;
  double *FR = R.Fr;
  double *lamL = R.lamL;
  double *lamR = R.lamR;
  double yl[8], yr[8]; /* cell-centered left/right interpolation variables */
  double yL[8], yR[8]; /* face-centered left/right interpolation variables */
  double xL = m2vol_coordinate_centroid(VL, axis);
  double xR = m2vol_coordinate_centroid(VR, axis);
  double *n = R.nhat;
  m2prim *PL = &R.Pl;
  m2prim *PR = &R.Pr;
  m2aux *AL = &R.Al;
  m2aux *AR = &R.Ar;
  int err[6];
  int E = 1;

  if (suppress_extrapolation) E = 0;
  if (VL->m2->suppress_extrapolation_at_unhealthy_zones) {
    if (VL->zone_health != 0) E = 0;
    if (VR->zone_health != 0) E = 0;
  }

  if (VL->zone_type == M2_ZONE_TYPE_SHELL ||
      VR->zone_type == M2_ZONE_TYPE_SHELL) {
    return;
  }

  n[0] = 0.0;
  n[1] = 0.0;
  n[2] = 0.0;
  n[3] = 0.0;
  n[axis] = 1.0;

  m2vol_to_interpolated(VL, yl, 1);
  m2vol_to_interpolated(VR, yr, 1);

  switch (axis) {
  case 1:
    for (q=0; q<8; ++q) yL[q] = yl[q] + E*VL->grad1[q] * (VL->x1[1] - xL);
    for (q=0; q<8; ++q) yR[q] = yr[q] + E*VR->grad1[q] * (VR->x0[1] - xR);
    break;
  case 2:
    for (q=0; q<8; ++q) yL[q] = yl[q] + E*VL->grad2[q] * (VL->x1[2] - xL);
    for (q=0; q<8; ++q) yR[q] = yr[q] + E*VR->grad2[q] * (VR->x0[2] - xR);
    break;
  case 3:
    for (q=0; q<8; ++q) yL[q] = yl[q] + E*VL->grad3[q] * (VL->x1[3] - xL);
    for (q=0; q<8; ++q) yR[q] = yr[q] + E*VR->grad3[q] * (VR->x0[3] - xR);
    break;
  }

  m2sim_from_interpolated(VL->m2, yL, PL);
  m2sim_from_interpolated(VR->m2, yR, PR);

  UL[B11] = PL->B1;
  UL[B22] = PL->B2;
  UL[B33] = PL->B3;
  UR[B11] = PR->B1;
  UR[B22] = PR->B2;
  UR[B33] = PR->B3;

  switch (axis) {
  case 1: UL[B11] = UR[B11] = PL->B1 = PR->B1 = VL->Bflux1A / VL->area1; break;
  case 2: UL[B22] = UR[B22] = PL->B2 = PR->B2 = VL->Bflux2A / VL->area2; break;
  case 3: UL[B33] = UR[B33] = PL->B3 = PR->B3 = VL->Bflux3A / VL->area3; break;
  }

  err[0] = m2sim_from_primitive(VL->m2, PL, NULL, NULL, 1.0, UL, AL);
  err[1] = m2sim_from_primitive(VR->m2, PR, NULL, NULL, 1.0, UR, AR);
  err[2] = m2aux_eigenvalues(AL, n, lamL);
  err[3] = m2aux_eigenvalues(AR, n, lamR);
  err[4] = m2aux_fluxes(AL, n, FL);
  err[5] = m2aux_fluxes(AR, n, FR);

  if (err[2]) VL->zone_health |= (1<<M2_BIT_BAD_EIGENVALUES);
  if (err[3]) VR->zone_health |= (1<<M2_BIT_BAD_EIGENVALUES);

  if (err[2] || err[3]) {
    if (suppress_extrapolation) {
      MSGF(INFO, "eigenvalues for %d-interface [%d %d %d] could not be found",
           axis, VL->global_index[1], VL->global_index[2], VL->global_index[3]);
      lamL[0] = -1.0;
      lamL[7] = +1.0;
      lamR[0] = -1.0;
      lamR[7] = +1.0;
    }
    else {
      riemann_solver(VL, VR, axis, F, 1);
      return;
    }
  }

  R.Sl = M2_MIN3(lamL[0], lamR[0], 0.0);
  R.Sr = M2_MAX3(lamL[7], lamR[7], 0.0);

  switch (VL->m2->riemann_solver) {
  case M2_RIEMANN_HLLE: riemann_solver_hlle(&R); break;
  case M2_RIEMANN_HLLC: riemann_solver_hllc(&R); break;
  default: MSG(FATAL, "invalid riemann solver"); break;
  }
  memcpy(F, R.F_hat, 8 * sizeof(double));
}

static double plm_gradient(double *xs, double *fs, double plm)
{
#define minval3(a,b,c) ((a<b) ? ((a<c) ? a : c) : ((b<c) ? b : c))
#define sign(x) ((x > 0.0) - (x < 0.0))

  double xL = xs[0];
  double x0 = xs[1];
  double xR = xs[2];

  double yL = fs[0];
  double y0 = fs[1];
  double yR = fs[2];

  double a = (yL - y0) / (xL - x0) * plm;
  double b = (yL - yR) / (xL - xR);
  double c = (y0 - yR) / (x0 - xR) * plm;

  double sa = sign(a), sb = sign(b), sc = sign(c);
  double fa = fabs(a), fb = fabs(b), fc = fabs(c);
  double g = 0.25 * fabs(sa + sb) * (sa + sc) * minval3(fa, fb, fc);

  if (g != g) {
    MSGF(FATAL, "got NAN gradient: [%f %f %f] [%f %f %f]",
         xs[0], xs[1], xs[2], fs[0], fs[1], fs[2]);
  }

  return g;
#undef minval3
#undef sign
}
Beispiel #4
0
int m2sim_calculate_flux(m2sim *m2)
{
  int i, j, k;
  int *L = m2->local_grid_size;
  int *G = m2->domain_resolution;
  m2vol *V0, *V1, *V2, *V3;

  double n1[4] = { 0.0, 1.0, 0.0, 0.0 };
  double n2[4] = { 0.0, 0.0, 1.0, 0.0 };
  double n3[4] = { 0.0, 0.0, 0.0, 1.0 };

#ifdef _OPENMP
#pragma omp parallel for private(V0,V1,V2,V3,j,k)
#endif
  for (i=0; i<L[1]; ++i) {
    for (j=0; j<L[2]; ++j) {
      for (k=0; k<L[3]; ++k) {

        V0 = M2_VOL(i+0, j+0, k+0);
        V1 = M2_VOL(i+1, j+0, k+0);
        V2 = M2_VOL(i+0, j+1, k+0);
        V3 = M2_VOL(i+0, j+0, k+1);

        if (V1 == NULL) m2aux_fluxes(&V0->aux, n1, V0->flux1);
        else riemann_solver(V0, V1, 1, V0->flux1, 0);

        if (V2 == NULL) m2aux_fluxes(&V0->aux, n2, V0->flux2);
        else riemann_solver(V0, V2, 2, V0->flux2, 0);

        if (V3 == NULL) m2aux_fluxes(&V0->aux, n3, V0->flux3);
        else riemann_solver(V0, V3, 3, V0->flux3, 0);
      }
    }
  }

  for (i=0; i<L[1]; ++i) {
    for (j=0; j<L[2]; ++j) {
      for (k=0; k<L[3]; ++k) {
        V0 = M2_VOL(i, j, k);
        if (m2->periodic_dimension[1] == 0 &&
            (V0->global_index[1] == -1 ||
             V0->global_index[1] == G[1] - 1)) {
          if (m2->boundary_conditions_flux1) {
            m2->boundary_conditions_flux1(V0);
          }
        }
        if (m2->periodic_dimension[2] == 0 &&
            (V0->global_index[2] == -1 ||
             V0->global_index[2] == G[2] - 1)) {
          if (m2->boundary_conditions_flux2) {
            m2->boundary_conditions_flux2(V0);
          }
        }
        if (m2->periodic_dimension[3] == 0 &&
            (V0->global_index[3] == -1 ||
             V0->global_index[3] == G[3] - 1)) {
          if (m2->boundary_conditions_flux3) {
            m2->boundary_conditions_flux3(V0);
          }
        }
      }
    }
  }
  return 0;
}