static void add_overlapping_slice(model *m, profile *p, int above, int layer, int below, Real position, Real width) { Real rho_weight_above = interface_value(m->rm, position/m->rough[layer]); Real rho_weight_below = interface_value(m->rm, (position-m->d[layer])/m->rough[below]); #ifdef HAVE_MAGNETIC Real P_weight_above = interface_value(m->rm, position/m->Prough[layer]); Real P_weight_below = interface_value(m->rm, (position-m->d[layer])/m->Prough[below]); Real theta_weight_above = interface_value(m->rm, position/m->thetarough[layer]); Real theta_weight_below = interface_value(m->rm, (position-m->d[layer])/m->thetarough[below]); #endif // printf("in add_overlapping_slice\n"); profile_slice(p, width, interface_overlap(rho_weight_above, rho_weight_below, m->rho[above],m->rho[layer],m->rho[below]), interface_overlap(rho_weight_above, rho_weight_below, m->mu[above],m->mu[layer],m->mu[below]) #ifdef HAVE_MAGNETIC ,interface_overlap(P_weight_above, P_weight_below, m->P[above],m->P[layer],m->P[below]) ,interface_overlap(theta_weight_above, theta_weight_below, m->theta[above],m->theta[layer],m->theta[below]) #endif ); }
static void add_half_interface(model *m, profile *p, int above, int below, int leftside) { interface *rm=m->rm; int i, j, midpoint = (rm->n+1)/2; Real rP = m->Prough[below]; Real rrho = m->rough[below]; Real rtheta = m->thetarough[below]; Real sm, med, big, z, c; int n = p->n; #ifdef VERBOSE printf("Add %s interface of width %g:\n\trho %g -> %g\n", leftside ? "top" : "bottom", m->rough[below], m->rho[above], m->rho[below]); #endif /* At worst, we will have 3 times the number of slices in one interface */ if (!profile_extend(p,3*midpoint)) return; /* Sort interface widths as sm, med, big */ if (rP < rrho) if (rP > rtheta) sm=rtheta, med=rP, big = rrho; else if (rrho < rtheta) sm=rP, med=rrho, big=rtheta; else sm=rP, med=rtheta, big=rrho; else /* rP > rrho */ if (rP < rtheta) sm=rrho, med=rP, big=rtheta; else if (rrho < rtheta) sm=rrho, med=rtheta, big=rP; else sm=rtheta, med=rrho, big=rP; /* If the interface has no width, do nothing */ if (big < 1e-10) return; /* We are going to first add the slices for the sharpest interface, * then extend it with slices remaining from the next sharpest * interface, and finally extend it with slices from the broadest * interface. This will make sure that we are sampling as densely * as needed for the steepest curve. * * We are storing the widths of the slices in the profile slabs that * we have reserved above but not yet used. For the bottom side * interface, we store the slices upsidedown, from the center of * the interface to the edge, then reverse them. */ z = 0.; if (leftside) { // printf("left side %d->%d\n",above,below); /* add sharpest interface (reverse order) */ for (i=midpoint-1; i >=0; i--) z += (p->d[n++] = sm*rm->step[i]); // printf("sm: i=%d out of %d, d=%g, z=%g, n=%d\n",i,rm->n,p->d[n-1],z,n); /* add extra slices to fill out the medium interface (reverse order) */ c = 0.; for (i=midpoint-1; i>=0 && c < z; i--) c += med*rm->step[i]; // printf("med overlap i=%d, c=%g, z=%G ?\n",i,c,z); if (c-z < MINSTEP) p->d[n-1] += c-z; else p->d[n++] = c-z; z = c; while (i >= 0) z += (p->d[n++] = med*rm->step[i--]); // printf("med extend: i=%d out of %d, z=%g, n=%d\n",i,rm->n,z,n); /* add extra slices to fill out the widest interface (reverse order) */ c = 0.; for (i=midpoint-1; i>=0 && c < z; i--) c += big*rm->step[i]; // printf("big overlap i=%d, c=%g, z=%G ?\n",i,c,z); if (c-z < MINSTEP) p->d[n-1] += c-z; else p->d[n++] = c-z; z = c; while (i >= 0) z += (p->d[n++] = big*rm->step[i--]); // printf("big extend: i=%d out of %d, z=%g, n=%d\n",i,rm->n,z,n); /* reverse the slices, and measure from -z to 0 rather than 0 to z */ // printf("reversing\n"); for (i=p->n, j=n-1; i < j; i++,j--) { Real temp = p->d[i]; p->d[i] = p->d[j]; p->d[j] = temp; } z = -z; } else { // printf("right side %d->%d\n",above,below); /* add sharpest interface */ for (i=midpoint; i < rm->n; i++) z += (p->d[n++] = sm*rm->step[i]); // printf("sm: i=%d out of %d, d=%g, z=%g, n=%d, sm=%g, step=%g\n",i,rm->n,p->d[n-1],z,n,sm,rm->step[i]); /* add extra slices to fill out the medium interface */ c = 0.; for (i=midpoint; i < rm->n && c < z; i++) c += med*rm->step[i]; // printf("med overlap i=%d out of %d, c=%g, n=%d\n",i,rm->n,c,n); if (c-z < MINSTEP) p->d[n-1] += c-z; else p->d[n++] = c-z; z = c; while (i < rm->n) z += (p->d[n++] = med*rm->step[i++]); // printf("med extend: i=%d out of %d, z=%g, n=%d\n",i,rm->n,z,n); /* add remaining slices to fill out the widest interface */ c = 0.; for (i=midpoint; i < rm->n && c < z; i++) c += big*rm->step[i]; // printf("big overlap i=%d out of %d, c=%g, n=%d\n",i,rm->n,c,n); if (c-z < MINSTEP) p->d[n-1] += c-z; else p->d[n++] = c-z; z = c; while (i < rm->n) z += (p->d[n++] = big*rm->step[i++]); // printf("big extend: i=%d out of %d, c=%g, n=%d\n",i,rm->n,c,n); z = 0.; } /* Fill in the slices */ while (p->n < n) { Real d = p->d[p->n]; Real zmid = z + d/2; Real wrho = interface_value(m->rm, zmid/rrho); Real wtheta = interface_value(m->rm, zmid/rtheta); Real wP = interface_value(m->rm, zmid/rP); // printf("add_half_interface slice %d: Adding %g at %g using %d->%d with %g\n",p->n,d,zmid,above,below,wrho); profile_slice(p, d, interface_average(m->rho[above],m->rho[below],wrho), interface_average(m->mu[above],m->mu[below],wrho), interface_average(m->P[above],m->P[below],wP), interface_average(m->theta[above],m->theta[below],wtheta)); z += d; } }
/*! \fn void ppmp(Real stencil[], Real bounds[], Real dx, Real dt) * \brief When passed a stencil of conserved variables, returns the left and right boundary values for the interface calculated using ppm. */ void ppmp(Real stencil[], Real bounds[], Real dx, Real dt, Real gamma) { // retrieve the values from the stencil Real d_i = stencil[0]; Real vx_i = stencil[1] / d_i; Real vy_i = stencil[2] / d_i; Real vz_i = stencil[3] / d_i; Real p_i = (stencil[4] - 0.5*d_i*(vx_i*vx_i + vy_i*vy_i + vz_i*vz_i)) * (gamma-1.0); p_i = fmax(p_i, TINY_NUMBER); Real d_imo = stencil[5]; Real vx_imo = stencil[6] / d_imo; Real vy_imo = stencil[7] / d_imo; Real vz_imo = stencil[8] / d_imo; Real p_imo = (stencil[9] - 0.5*d_imo*(vx_imo*vx_imo + vy_imo*vy_imo + vz_imo*vz_imo)) * (gamma-1.0); p_imo = fmax(p_imo, TINY_NUMBER); Real d_ipo = stencil[10]; Real vx_ipo = stencil[11] / d_ipo; Real vy_ipo = stencil[12] / d_ipo; Real vz_ipo = stencil[13] / d_ipo; Real p_ipo = (stencil[14] - 0.5*d_ipo*(vx_ipo*vx_ipo + vy_ipo*vy_ipo + vz_ipo*vz_ipo)) * (gamma-1.0); p_ipo = fmax(p_ipo, TINY_NUMBER); Real d_imt = stencil[15]; Real vx_imt = stencil[16] / d_imt; Real vy_imt = stencil[17] / d_imt; Real vz_imt = stencil[18] / d_imt; Real p_imt = (stencil[19] - 0.5*d_imt*(vx_imt*vx_imt + vy_imt*vy_imt + vz_imt*vz_imt)) * (gamma-1.0); p_imt = fmax(p_imt, TINY_NUMBER); Real d_ipt = stencil[20]; Real vx_ipt = stencil[21] / d_ipt; Real vy_ipt = stencil[22] / d_ipt; Real vz_ipt = stencil[23] / d_ipt; Real p_ipt = (stencil[24] - 0.5*d_ipt*(vx_ipt*vx_ipt + vy_ipt*vy_ipt + vz_ipt*vz_ipt)) * (gamma-1.0); p_ipt = fmax(p_ipt, TINY_NUMBER); Real p_imth = (stencil[29] - 0.5*(stencil[26]*stencil[26] + stencil[27]*stencil[27] + stencil[28]*stencil[28])/stencil[25]) * (gamma-1.0); p_imth = fmax(p_imth, TINY_NUMBER); Real p_ipth = (stencil[34] - 0.5*(stencil[31]*stencil[31] + stencil[32]*stencil[32] + stencil[33]*stencil[33])/stencil[30]) * (gamma-1.0); p_ipth = fmax(p_ipth, TINY_NUMBER); Real dx_i, dx_imo, dx_ipo, dx_imt, dx_ipt; dx_i = dx_imo = dx_ipo = dx_imt = dx_ipt = dx; // declare the primative variables we are calculating // note: dl & dr refer to the left and right boundary values of cell i Real dl, dr, vxl, vxr, vyl, vyr, vzl, vzr, pl, pr; //define constants to use in contact discontinuity detection Real d2_rho_imo, d2_rho_ipo; //second derivative of rho Real eta_i; //steepening coefficient derived from a dimensionless quantity relating //the first and third derivatives of the density (Fryxell Eqns 36 & 40) Real delta_m_imo, delta_m_ipo; //monotonized slopes (Fryxell Eqn 26) //define constants to use in shock flattening Real F_imo, F_i, F_ipo; //flattening coefficients (Fryxell Eqn 48) // define other constants Real cs, cl, cr; // sound speed in cell i, and at left and right boundaries Real del_d, del_vx, del_vy, del_vz, del_p; // "slope" accross cell i Real d_6, vx_6, vy_6, vz_6, p_6; Real beta_m, beta_0, beta_p; Real alpha_m, alpha_0, alpha_p; Real lambda_m, lambda_0, lambda_p; // speed of characteristics Real dL_m, dL_0; Real vxL_m, vyL_0, vzL_0, vxL_p; Real pL_m, pL_0, pL_p; Real dR_0, dR_p; Real vxR_m, vyR_0, vzR_0, vxR_p; Real pR_m, pR_0, pR_p; Real chi_L_m, chi_L_0, chi_L_p; Real chi_R_m, chi_R_0, chi_R_p; // use ppm routines to set cell boundary values (see Fryxell Sec. 3.1.1) // left dl = interface_value(d_imt, d_imo, d_i, d_ipo, dx_imt, dx_imo, dx_i, dx_ipo); vxl = interface_value(vx_imt, vx_imo, vx_i, vx_ipo, dx_imt, dx_imo, dx_i, dx_ipo); vyl = interface_value(vy_imt, vy_imo, vy_i, vy_ipo, dx_imt, dx_imo, dx_i, dx_ipo); vzl = interface_value(vz_imt, vz_imo, vz_i, vz_ipo, dx_imt, dx_imo, dx_i, dx_ipo); pl = interface_value(p_imt, p_imo, p_i, p_ipo, dx_imt, dx_imo, dx_i, dx_ipo); // right dr = interface_value(d_imo, d_i, d_ipo, d_ipt, dx_imo, dx_i, dx_ipo, dx_ipt); vxr = interface_value(vx_imo, vx_i, vx_ipo, vx_ipt, dx_imo, dx_i, dx_ipo, dx_ipt); vyr = interface_value(vy_imo, vy_i, vy_ipo, vy_ipt, dx_imo, dx_i, dx_ipo, dx_ipt); vzr = interface_value(vz_imo, vz_i, vz_ipo, vz_ipt, dx_imo, dx_i, dx_ipo, dx_ipt); pr = interface_value(p_imo, p_i, p_ipo, p_ipt, dx_imo, dx_i, dx_ipo, dx_ipt); #ifdef STEEPENING //check for contact discontinuities & steepen if necessary (see Fryxell Sec 3.1.2) //if condition 4 (Fryxell Eqn 37) is true, check further conditions, otherwise do nothing if ((fabs(d_ipo - d_imo) / fmin(d_ipo, d_imo)) > 0.01) { //calculate the second derivative of the density in the imo and ipo cells d2_rho_imo = calc_d2_rho(d_imt, d_imo, d_i, dx, dx, dx); d2_rho_ipo = calc_d2_rho(d_i, d_ipo, d_ipt, dx, dx, dx); //if condition 1 (Fryxell Eqn 38) is true, check further conditions, otherwise do nothing if ((d2_rho_imo * d2_rho_ipo) < 0) { //calculate condition 5, pressure vs density jumps (Fryxell Eqn 39) //if c5 is true, set value of eta for discontinuity steepening if ((fabs(p_ipo - p_imo) / fmin(p_ipo, p_imo)) < 0.1 * gamma * (fabs(d_ipo - d_imo) / fmin(d_ipo, d_imo))) { //calculate first eta value (Fryxell Eqn 36) eta_i = calc_eta(d2_rho_imo, d2_rho_ipo, dx, dx, dx, d_imo, d_ipo); //calculate steepening coefficient (Fryxell Eqn 40) eta_i = fmax(0, fmin(20*(eta_i-0.05), 1) ); //calculate new left and right interface variables using monotonized slopes delta_m_imo = calc_delta_q(d_imt, d_imo, d_i, dx, dx, dx); delta_m_imo = limit_delta_q(delta_m_imo, d_imt, d_imo, d_i); delta_m_ipo = calc_delta_q(d_i, d_ipo, d_ipt, dx, dx, dx); delta_m_ipo = limit_delta_q(delta_m_ipo, d_i, d_ipo, d_ipt); //replace left and right interface values of density dl = dl*(1-eta_i) + (d_imo + 0.5 * delta_m_imo) * eta_i; dr = dr*(1-eta_i) + (d_ipo - 0.5 * delta_m_ipo) * eta_i; } } } #endif #ifdef FLATTENING //flatten shock fronts that are too narrow (see Fryxell Sec 3.1.3) //calculate the shock steepness parameters (Fryxell Eqn 43) //calculate the dimensionless flattening coefficients (Fryxell Eqn 45) F_imo = fmax( 0, fmin(1, 10*(((p_i - p_imt) / (p_ipo - p_imth))-0.75)) ); F_i = fmax( 0, fmin(1, 10*(((p_ipo - p_imo) / (p_ipt - p_imt))-0.75)) ); F_ipo = fmax( 0, fmin(1, 10*(((p_ipt - p_i) / (p_ipth - p_imo))-0.75)) ); //ensure that we are encountering a shock (Fryxell Eqns 46 & 47) if (fabs(p_i - p_imt) / fmin(p_i, p_imt) < 1./3.) {F_imo = 0;} if (fabs(p_ipo - p_imo) / fmin(p_ipo, p_imo) < 1./3.) {F_i = 0;} if (fabs(p_ipt - p_i) / fmin(p_ipt, p_i) < 1./3.) {F_ipo = 0;} if (vx_i - vx_imt > 0) {F_imo = 0;} if (vx_ipo - vx_imo > 0) {F_i = 0;} if (vx_ipt - vx_i > 0) {F_ipo = 0;} //set the flattening coefficient (Fryxell Eqn 48) if (p_ipo - p_imo < 0) {F_i = fmax(F_i, F_ipo);} else {F_i = fmax(F_i, F_imo);} //modify the interface values dl = F_i * d_i + (1 - F_i) * dl; vxl = F_i * vx_i + (1 - F_i) * vxl; vyl = F_i * vy_i + (1 - F_i) * vyl; vzl = F_i * vz_i + (1 - F_i) * vzl; pl = F_i * p_i + (1 - F_i) * pl; dr = F_i * d_i + (1 - F_i) * dr; vxr = F_i * vx_i + (1 - F_i) * vxr; vyr = F_i * vy_i + (1 - F_i) * vyr; vzr = F_i * vz_i + (1 - F_i) * vzr; pr = F_i * p_i + (1 - F_i) * pr; #endif //ensure that the parabolic distribution of each of the primative variables is monotonic //local maximum or minimum criterion (Fryxell Eqn 52, Fig 11) if ( (dr - d_i) * (d_i - dl) <= 0) { dl = dr = d_i; } if ( (vxr - vx_i) * (vx_i - vxl) <= 0) { vxl = vxr = vx_i; } if ( (vyr - vy_i) * (vy_i - vyl) <= 0) { vyl = vyr = vy_i; } if ( (vzr - vz_i) * (vz_i - vzl) <= 0) { vzl = vzr = vz_i; } if ( (pr - p_i) * (p_i - pl) <= 0) { pl = pr = p_i; } //steep gradient criterion (Fryxell Eqn 53, Fig 12) if ( (dr - dl) * (dl - (3*d_i - 2*dr)) < 0) { dl = 3*d_i - 2*dr; } if ( (vxr - vxl) * (vxl - (3*vx_i - 2*vxr)) < 0) { vxl = 3*vx_i - 2*vxr; } if ( (vyr - vyl) * (vyl - (3*vy_i - 2*vyr)) < 0) { vyl = 3*vy_i - 2*vyr; } if ( (vzr - vzl) * (vzl - (3*vz_i - 2*vzr)) < 0) { vzl = 3*vz_i - 2*vzr; } if ( (pr - pl) * (pl - (3*p_i - 2*pr)) < 0) { pl = 3*p_i - 2*pr; } if ( (dr - dl) * ((3*d_i - 2*dl) - dr) < 0) { dr = 3*d_i - 2*dl; } if ( (vxr - vxl) * ((3*vx_i - 2*vxl) - vxr) < 0) { vxr = 3*vx_i - 2*vxl; } if ( (vyr - vyl) * ((3*vy_i - 2*vyl) - vyr) < 0) { vyr = 3*vy_i - 2*vyl; } if ( (vzr - vzl) * ((3*vz_i - 2*vzl) - vzr) < 0) { vzr = 3*vz_i - 2*vzl; } if ( (pr - pl) * ((3*p_i - 2*pl) - pr) < 0) { pr = 3*p_i - 2*pl; } // compute sound speed in cell i cs = sqrt(gamma * p_i / d_i); // compute a first guess at the left and right states by taking the average // under the characteristic on each side that has the largest speed // compute deltas and 'sixes' (Fryxell Eqns 29 & 30) del_d = dr - dl; // Fryxell Eqn 29 del_vx = vxr - vxl; // Fryxell Eqn 29 del_vy = vyr - vyl; // Fryxell Eqn 29 del_vz = vzr - vzl; // Fryxell Eqn 29 del_p = pr - pl; // Fryxell Eqn 29 d_6 = 6.0 * (d_i - 0.5*(dl + dr)); // Fryxell Eqn 30 vx_6 = 6.0 * (vx_i - 0.5*(vxl + vxr)); // Fryxell Eqn 30 vy_6 = 6.0 * (vy_i - 0.5*(vyl + vyr)); // Fryxell Eqn 30 vz_6 = 6.0 * (vz_i - 0.5*(vzl + vzr)); // Fryxell Eqn 30 p_6 = 6.0 * (p_i - 0.5*(pl + pr)); // Fryxell Eqn 30 // set speed of characteristics (v-c, v, v+c) using average values of v and c lambda_m = vx_i - cs; lambda_0 = vx_i; lambda_p = vx_i + cs; // calculate betas (for right interface guesses) beta_m = fmax( (lambda_m * dt / dx_i) , 0 ); // Fryxell Eqn 59 beta_0 = fmax( (lambda_0 * dt / dx_i) , 0 ); // Fryxell Eqn 59 beta_p = fmax( (lambda_p * dt / dx_i) , 0 ); // Fryxell Eqn 59 // calculate alphas (for left interface guesses) alpha_m = fmax( (-lambda_m * dt / dx_i), 0); // Fryxell Eqn 61 alpha_0 = fmax( (-lambda_0 * dt / dx_i), 0); // Fryxell Eqn 61 alpha_p = fmax( (-lambda_p * dt / dx_i), 0); // Fryxell Eqn 61 // average values under characteristics for left interface (Fryxell Eqn 60) dL_m = dl + 0.5 * alpha_m * (del_d + d_6 * (1 - (2./3.) * alpha_m)); vxL_m = vxl + 0.5 * alpha_m * (del_vx + vx_6 * (1 - (2./3.) * alpha_m)); pL_m = pl + 0.5 * alpha_m * (del_p + p_6 * (1 - (2./3.) * alpha_m)); dL_0 = dl + 0.5 * alpha_0 * (del_d + d_6 * (1 - (2./3.) * alpha_0)); vyL_0 = vyl + 0.5 * alpha_0 * (del_vy + vy_6 * (1 - (2./3.) * alpha_0)); vzL_0 = vzl + 0.5 * alpha_0 * (del_vz + vz_6 * (1 - (2./3.) * alpha_0)); pL_0 = pl + 0.5 * alpha_0 * (del_p + p_6 * (1 - (2./3.) * alpha_0)); vxL_p = vxl + 0.5 * alpha_p * (del_vx + vx_6 * (1 - (2./3.) * alpha_p)); pL_p = pl + 0.5 * alpha_p * (del_p + p_6 * (1 - (2./3.) * alpha_p)); // average values under characteristics for right interface (Fryxell Eqn 58) vxR_m = vxr - 0.5 * beta_m * (del_vx - vx_6 * (1 - (2./3.) * beta_m)); pR_m = pr - 0.5 * beta_m * (del_p - p_6 * (1 - (2./3.) * beta_m)); dR_0 = dr - 0.5 * beta_0 * (del_d - d_6 * (1 - (2./3.) * beta_0)); vyR_0 = vyr - 0.5 * beta_0 * (del_vy - vy_6 * (1 - (2./3.) * beta_0)); vzR_0 = vzr - 0.5 * beta_0 * (del_vz - vz_6 * (1 - (2./3.) * beta_0)); pR_0 = pr - 0.5 * beta_0 * (del_p - p_6 * (1 - (2./3.) * beta_0)); dR_p = dr - 0.5 * beta_p * (del_d - d_6 * (1 - (2./3.) * beta_p)); vxR_p = vxr - 0.5 * beta_p * (del_vx - vx_6 * (1 - (2./3.) * beta_p)); pR_p = pr - 0.5 * beta_p * (del_p - p_6 * (1 - (2./3.) * beta_p)); // as a first guess, use characteristics with the largest speeds // for transverse velocities, use the 0 characteristic // left dl = dL_m; vxl = vxL_m; vyl = vyL_0; vzl = vzL_0; pl = pL_m; // right dr = dR_p; vxr = vxR_p; vyr = vyR_0; vzr = vzR_0; pr = pR_p; // correct these initial guesses by taking into account the number of // characteristics on each side of the interface // calculate the 'guess' sound speeds cl = sqrt(gamma * pl / dl); cr = sqrt(gamma * pr / dr); // calculate the chi values (Fryxell Eqns 62 & 63) chi_L_m = 1./(2*dl*cl) * (vxl - vxL_m - (pl - pL_m)/(dl*cl)); chi_L_p = -1./(2*dl*cl) * (vxl - vxL_p + (pl - pL_p)/(dl*cl)); chi_L_0 = (pl - pL_0)/(dl*dl*cl*cl) + 1./dl - 1./dL_0; chi_R_m = 1./(2*dr*cr) * (vxr - vxR_m - (pr - pR_m)/(dr*cr)); chi_R_p = -1./(2*dr*cr) * (vxr - vxR_p + (pr - pR_p)/(dr*cr)); chi_R_0 = (pr - pR_0)/(dr*dr*cr*cr) + 1./dr - 1./dR_0; // set chi to 0 if characteristic velocity has the wrong sign (Fryxell Eqn 64) if (lambda_m >= 0) { chi_L_m = 0; } if (lambda_0 >= 0) { chi_L_0 = 0; } if (lambda_p >= 0) { chi_L_p = 0; } if (lambda_m <= 0) { chi_R_m = 0; } if (lambda_0 <= 0) { chi_R_0 = 0; } if (lambda_p <= 0) { chi_R_p = 0; } // use the chi values to correct the initial guesses and calculate final input states pl = pl + (dl*dl * cl*cl) * (chi_L_p + chi_L_m); vxl = vxl + dl * cl * (chi_L_p - chi_L_m); dl = pow( ((1.0/dl) - (chi_L_m + chi_L_0 + chi_L_p)) , -1); pr = pr + (dr*dr * cr*cr) * (chi_R_p + chi_R_m); vxr = vxr + dr * cr * (chi_R_p - chi_R_m); dr = pow( ((1.0/dr) - (chi_R_m + chi_R_0 + chi_R_p)) , -1); // send final values back (conserved variables) bounds[0] = dl; bounds[1] = dl*vxl; bounds[2] = dl*vyl; bounds[3] = dl*vzl; bounds[4] = (pl/(gamma-1.0)) + 0.5*dl*(vxl*vxl + vyl*vyl + vzl*vzl); bounds[5] = dr; bounds[6] = dr*vxr; bounds[7] = dr*vyr; bounds[8] = dr*vzr; bounds[9] = (pr/(gamma-1.0)) + 0.5*dr*(vxr*vxr + vyr*vyr + vzr*vzr); }