def test_iterative_scheme(): """ This function runs through the five shock tube problems outlined in Toro - Chapter 4. The results for contact velocity, pressure, and number of iterations should match those on p130-131. """ gamma = 1.4 p_left = [1.0, 0.4, 1000.0, 0.01, 460.894] rho_left = [1.0, 1.0, 1.0, 1.0, 5.99924] u_left = [0.0, -2.0, 0.0, 0.0, 19.5975] p_right = [0.1, 0.4, 0.01, 100.0, 46.0950] rho_right = [0.125, 1.0, 1.0, 1.0, 5.99242] u_right = [0.0, 2.0, 0.0, 0.0, -6.19633] solver = IterativeRiemannSolver(1.4) print '*' * 50 for i in range(0, 5): print "Riemann Test: " + str(i + 1) left_state = ThermodynamicState1D(p_left[i], rho_left[i], u_left[i], gamma) right_state = ThermodynamicState1D(p_right[i], rho_right[i], u_right[i], gamma) p_star, u_star = solver.get_star_states(left_state, right_state) print "Converged Star Pressure: " + str(p_star) print "Converged Star Velocity: " + str(u_star) print '*' * 50
def calculate_godunov_fluxes(densities, pressures, velocities, gamma): """ Function used to calculate fluxes for a 1D simulation using Godunov's scheme as in Toro Chapter 6 """ density_fluxes = np.zeros(len(densities) - 1) momentum_fluxes = np.zeros(len(densities) - 1) total_energy_fluxes = np.zeros(len(densities) - 1) solver = IterativeRiemannSolver(gamma) for i, dens_flux in enumerate(density_fluxes): # Generate left and right states from cell averaged values left_state = ThermodynamicState1D(pressures[i], densities[i], velocities[i], gamma) right_state = ThermodynamicState1D(pressures[i + 1], densities[i + 1], velocities[i + 1], gamma) # Solve Riemann problem for star states p_star, u_star = solver.get_star_states(left_state, right_state) # Calculate fluxes using solver sample function p_flux, u_flux, rho_flux, _ = solver.sample( 0.0, left_state, right_state, p_star, u_star) # Store fluxes in array density_fluxes[i] = rho_flux * u_flux momentum_fluxes[i] = rho_flux * u_flux * u_flux + p_flux e_tot = p_flux / (left_state.gamma - 1) + 0.5 * rho_flux * u_flux * u_flux total_energy_fluxes[i] = (p_flux + e_tot) * u_flux return density_fluxes, momentum_fluxes, total_energy_fluxes
def _set_boundary_conditions(self): """ Function used to extend the grid at the boundary conditions """ i_length = len(self.densities) - 1 start_state = ThermodynamicState1D(self.pressures[0], self.densities[0], self.velocities[0], self.gamma) end_state = ThermodynamicState1D(self.pressures[i_length], self.densities[i_length], self.velocities[i_length], self.gamma) if self.flux_calculator != FluxCalculator1D.MUSCL: # Low end start_state = self.boundary_functions[BoundaryConditionND.X_LOW]( start_state) self.densities = np.append([start_state.rho], self.densities, 0) self.pressures = np.append([start_state.p], self.pressures, 0) self.velocities = np.append([start_state.u], self.velocities, 0) self.internal_energies = np.append([start_state.e_int], self.internal_energies, 0) # High end end_state = self.boundary_functions[BoundaryConditionND.X_HIGH]( end_state) self.densities = np.append(self.densities, [end_state.rho], 0) self.pressures = np.append(self.pressures, [end_state.p], 0) self.velocities = np.append(self.velocities, [end_state.u], 0) self.internal_energies = np.append(self.internal_energies, [end_state.e_int], 0) else: # Low end start_state = self.boundary_functions[BoundaryConditionND.X_LOW]( start_state) self.densities = np.append([start_state.rho, start_state.rho], self.densities, 0) self.pressures = np.append([start_state.p, start_state.p], self.pressures, 0) self.velocities = np.append([start_state.u, start_state.u], self.velocities, 0) self.internal_energies = np.append( [start_state.e_int, start_state.e_int], self.internal_energies, 0) # High end end_state = self.boundary_functions[BoundaryConditionND.X_HIGH]( end_state) self.densities = np.append(self.densities, [end_state.rho, end_state.rho], 0) self.pressures = np.append(self.pressures, [end_state.p, end_state.p], 0) self.velocities = np.append(self.velocities, [end_state.u, end_state.u], 0) self.internal_energies = np.append( self.internal_energies, [end_state.e_int, end_state.e_int], 0)
def test_sound_speed(self): pressure = 1e5 rho = 1.225 gamma = 1.4 air_state = ThermodynamicState1D(pressure, rho, 0.0, gamma) self.assertTrue(333 < air_state.sound_speed() < 340)
def calculate_random_choice_fluxes(densities, pressures, velocities, gamma, ts, dx_over_dt): """ Function used to calculate states for a 1D simulation using Glimm's random choice scheme as in Toro Chapter 7 """ density_fluxes = np.zeros(len(densities) - 1) momentum_fluxes = np.zeros(len(densities) - 1) total_energy_fluxes = np.zeros(len(densities) - 1) solver = IterativeRiemannSolver(gamma) theta = VanDerCorput.calculate_theta(ts, 2, 1) for i in range(len(densities) - 2): # Generate left and right states from cell averaged values left_state = ThermodynamicState1D(pressures[i], densities[i], velocities[i], gamma) mid_state = ThermodynamicState1D(pressures[i + 1], densities[i + 1], velocities[i + 1], gamma) right_state = ThermodynamicState1D(pressures[i + 2], densities[i + 2], velocities[i + 2], gamma) # Solve Riemann problem for star states on either side of the cell p_star_left, u_star_left = solver.get_star_states( left_state, mid_state) p_star_right, u_star_right = solver.get_star_states( mid_state, right_state) # Calculate fluxes using solver sample function if theta <= 0.5: p_flux, u_flux, rho_flux, _ = solver.sample( theta * dx_over_dt, left_state, mid_state, p_star_left, u_star_left) else: p_flux, u_flux, rho_flux, _ = solver.sample( (theta - 1) * dx_over_dt, mid_state, right_state, p_star_right, u_star_right) # Store fluxes in array density_fluxes[i] = rho_flux momentum_fluxes[i] = rho_flux * u_flux total_energy_fluxes[i] = p_flux / ( left_state.gamma - 1) + 0.5 * rho_flux * u_flux * u_flux return density_fluxes, momentum_fluxes, total_energy_fluxes
def test_sod_problems(): """ This function runs through the five shock tube problems outlined in Toro - Chapter 4. The results for contact velocity, pressure, and number of iterations should match those on p130-131. """ gamma = 1.4 p_left = [1.0, 0.4, 1000.0, 0.01, 460.894, 1.0] rho_left = [1.0, 1.0, 1.0, 1.0, 5.99924, 1.0] u_left = [0.0, -2.0, 0.0, 0.0, 19.5975, 0.75] p_right = [0.1, 0.4, 0.01, 100.0, 46.0950, 0.1] rho_right = [0.125, 1.0, 1.0, 1.0, 5.99242, 0.125] u_right = [0.0, 2.0, 0.0, 0.0, -6.19633, 0.0] t = [0.25, 0.15, 0.012, 0.035, 0.035, 0.2] x = [0.5, 0.5, 0.5, 0.5, 0.5, 0.3] for i in range(0, 6): left_state = ThermodynamicState1D(p_left[i], rho_left[i], u_left[i], gamma) right_state = ThermodynamicState1D(p_right[i], rho_right[i], u_right[i], gamma) sod_test = AnalyticShockTube(left_state, right_state, x[i], 1000) x_sol, rho_sol, u_sol, p_sol, e_sol = sod_test.get_solution(t[i], x[i]) title = "Sod Test: {}".format(i + 1) num_plts_x = 2 num_plts_y = 2 plt.figure(figsize=(20, 10)) plt.suptitle(title) plt.subplot(num_plts_x, num_plts_y, 1) plt.title("Density") plt.plot(x_sol, rho_sol) plt.subplot(num_plts_x, num_plts_y, 2) plt.title("Velocity") plt.plot(x_sol, u_sol) plt.subplot(num_plts_x, num_plts_y, 3) plt.title("Pressure") plt.plot(x_sol, p_sol) plt.subplot(num_plts_x, num_plts_y, 4) plt.title("Energy") plt.plot(x_sol, e_sol) plt.show()
def calculate_hllc_fluxes(densities, pressures, velocities, gamma): """ Calculated the fluxes bases on the HLLC approximate Riemann solver """ density_fluxes = np.zeros(len(densities) - 1) momentum_fluxes = np.zeros(len(densities) - 1) total_energy_fluxes = np.zeros(len(densities) - 1) solver = HLLCRiemannSolver(gamma) for i, dens_flux in enumerate(density_fluxes): # Generate left and right states from cell averaged values left_state = ThermodynamicState1D(pressures[i], densities[i], velocities[i], gamma) right_state = ThermodynamicState1D(pressures[i + 1], densities[i + 1], velocities[i + 1], gamma) density_fluxes[i], momentum_fluxes[i], total_energy_fluxes[ i] = solver.evaluate_flux(left_state, right_state) return density_fluxes, momentum_fluxes, total_energy_fluxes
def _update_states(self, dt): """ Uses the time step and calculated fluxes to update states in each cell """ assert (isinstance(dt, float)) for i, state in enumerate(self.densities): if self.flux_calculator == FluxCalculator1D.RANDOM_CHOICE: rho = self.density_fluxes[i] momentum = self.momentum_fluxes[i] total_energy = self.total_energy_fluxes[i] velocity = momentum / rho kinetic_energy = 0.5 * rho * velocity**2 internal_energy = total_energy - kinetic_energy pressure = internal_energy * (self.gamma - 1) state = ThermodynamicState1D(pressure, rho, velocity, self.gamma) else: total_density_flux = ( self.density_fluxes[i] - self.density_fluxes[i + 1]) * dt / self.dx total_momentum_flux = ( self.momentum_fluxes[i] - self.momentum_fluxes[i + 1]) * dt / self.dx total_energy_flux = ( self.total_energy_fluxes[i] - self.total_energy_fluxes[i + 1]) * dt / self.dx state = ThermodynamicState1D(self.pressures[i], self.densities[i], self.velocities[i], self.gamma) state.update_states(total_density_flux, total_momentum_flux, total_energy_flux) self.densities[i] = state.rho self.pressures[i] = state.p self.velocities[i] = state.u self.internal_energies[i] = state.e_int
def example(): """ Runs the problems from Toro Chapter 6 to validate this simulation """ gamma = 1.4 p_left = [1.0, 0.4, 1000.0, 460.894, 1000.0] rho_left = [1.0, 1.0, 1.0, 5.99924, 1.0] u_left = [0.75, -2.0, 0.0, 19.5975, -19.5975] p_right = [0.1, 0.4, 0.01, 46.0950, 0.01] rho_right = [0.125, 1.0, 1.0, 5.99242, 1.0] u_right = [0.0, 2.0, 0.0, -6.19633, -19.59745] membrane_location = [0.3, 0.5, 0.5, 0.4, 0.8] end_times = [0.25, 0.15, 0.012, 0.035, 0.012] run_god = False run_rc = False run_hllc = False run_muscl = True for i in range(0, 5): left_state = ThermodynamicState1D(p_left[i], rho_left[i], u_left[i], gamma) right_state = ThermodynamicState1D(p_right[i], rho_right[i], u_right[i], gamma) if run_god: shock_tube_god = ShockTube1D( left_state, right_state, membrane_location[i], final_time=end_times[i], CFL=0.45, flux_calculator=FluxCalculator1D.GODUNOV) godunov_sim = Controller1D(shock_tube_god) (times_god, x_god, densities_god, pressures_god, velocities_god, internal_energies_god) = godunov_sim.run_sim() if run_rc: shock_tube_rc = ShockTube1D( left_state, right_state, membrane_location[i], final_time=end_times[i], CFL=0.45, flux_calculator=FluxCalculator1D.RANDOM_CHOICE) random_choice_sim = Controller1D(shock_tube_rc) (times_rc, x_rc, densities_rc, pressures_rc, velocities_rc, internal_energies_rc) = random_choice_sim.run_sim() if run_hllc: shock_tube_hllc = ShockTube1D( left_state, right_state, membrane_location[i], final_time=end_times[i], CFL=0.45, flux_calculator=FluxCalculator1D.HLLC) hllc_sim = Controller1D(shock_tube_hllc) (times_hllc, x_hllc, densities_hllc, pressures_hllc, velocities_hllc, internal_energies_hllc) = hllc_sim.run_sim() if run_muscl: shock_tube_muscl = ShockTube1D( left_state, right_state, membrane_location[i], final_time=end_times[i], CFL=0.45, flux_calculator=FluxCalculator1D.MUSCL) muscl_sim = Controller1D(shock_tube_muscl) (times_muscl, x_muscl, densities_muscl, pressures_muscl, velocities_muscl, internal_energies_muscl) = muscl_sim.run_sim() # Get analytic solution sod_test = AnalyticShockTube(left_state, right_state, membrane_location[i], 1000) x_sol, rho_sol, u_sol, p_sol, e_sol = sod_test.get_solution( end_times[i], membrane_location[i]) # Plot results title = "Sod Test: {}".format(i + 1) num_plts_x = 2 num_plts_y = 2 plt.figure(figsize=(20, 10)) plt.suptitle(title) plt.subplot(num_plts_x, num_plts_y, 1) plt.title("Density") plt.plot(x_sol, rho_sol) if run_god: plt.scatter(x_god, densities_god, c='g') if run_rc: plt.scatter(x_rc, densities_rc, c='r') if run_hllc: plt.scatter(x_hllc, densities_hllc, c='k') if run_muscl: plt.scatter(x_muscl, densities_muscl, c='c') plt.xlim([0.0, 1.0]) plt.subplot(num_plts_x, num_plts_y, 2) plt.title("Velocity") plt.plot(x_sol, u_sol) if run_god: plt.scatter(x_god, velocities_god, c='g') if run_rc: plt.scatter(x_rc, velocities_rc, c='r') if run_hllc: plt.scatter(x_hllc, velocities_hllc, c='k') if run_muscl: plt.scatter(x_muscl, velocities_muscl, c='c') plt.xlim([0.0, 1.0]) plt.subplot(num_plts_x, num_plts_y, 3) plt.title("Pressure") plt.plot(x_sol, p_sol) if run_god: plt.scatter(x_god, pressures_god, c='g') if run_rc: plt.scatter(x_rc, pressures_rc, c='r') if run_hllc: plt.scatter(x_hllc, pressures_hllc, c='k') if run_muscl: plt.scatter(x_muscl, pressures_muscl, c='c') plt.xlim([0.0, 1.0]) plt.subplot(num_plts_x, num_plts_y, 4) plt.title("Internal Energy") plt.plot(x_sol, e_sol) if run_god: plt.scatter(x_god, internal_energies_god, c='g') if run_rc: plt.scatter(x_rc, internal_energies_rc, c='r') if run_hllc: plt.scatter(x_hllc, internal_energies_hllc, c='k') if run_muscl: plt.scatter(x_muscl, internal_energies_muscl, c='c') plt.xlim([0.0, 1.0]) plt.show()
def test_noh_1d(): """ This function runs through the tri lab version of the Noh problem. See the Tri Lab verification test suite. """ run_god = True run_rc = True run_hllc = True # Use small pressure value for numerical stability (and to be physically meaningful) initial_state = ThermodynamicState1D(1e-4, 1.0, -1.0, 5.0 / 3.0) # Run Noh sim with Godunov and Random Choice if run_god: noh_god = Noh1D(initial_state, final_time=0.3, CFL=0.45, flux_calculator=FluxCalculator1D.GODUNOV) godunov_sim = Controller1D(noh_god) (times_god, x_god, densities_god, pressures_god, velocities_god, internal_energies_god) = godunov_sim.run_sim() if run_rc: noh_rc = Noh1D(initial_state, final_time=0.3, CFL=0.45, flux_calculator=FluxCalculator1D.RANDOM_CHOICE) rc_sim = Controller1D(noh_rc) (times_rc, x_rc, densities_rc, pressures_rc, velocities_rc, internal_energies_rc) = rc_sim.run_sim() if run_hllc: noh_hllc = Noh1D(initial_state, final_time=0.3, CFL=0.45, flux_calculator=FluxCalculator1D.HLLC) hllc_sim = Controller1D(noh_hllc) (times_hllc, x_hllc, densities_hllc, pressures_hllc, velocities_hllc, internal_energies_hllc) = hllc_sim.run_sim() # Get analytic solution noh_test = AnalyticNoh(initial_state, 0.4, 100) x_sol, rho_sol, u_sol, p_sol, e_sol = noh_test.get_solution(0.3) title = "Noh Test" num_plts_x = 2 num_plts_y = 2 plt.figure(figsize=(20, 10)) plt.suptitle(title) plt.subplot(num_plts_x, num_plts_y, 1) plt.title("Density") plt.plot(x_sol, rho_sol) if run_god: plt.scatter(x_god, densities_god, c='g', label='Godunov') if run_rc: plt.scatter(x_rc, densities_rc, c='r', label='Random Choice') if run_hllc: plt.scatter(x_hllc, densities_hllc, c='k', label='HLLC') plt.legend() plt.subplot(num_plts_x, num_plts_y, 2) plt.title("Velocity") plt.plot(x_sol, u_sol) if run_god: plt.scatter(x_god, velocities_god, c='g') if run_rc: plt.scatter(x_rc, velocities_rc, c='r') if run_hllc: plt.scatter(x_hllc, velocities_hllc, c='k') plt.subplot(num_plts_x, num_plts_y, 3) plt.title("Pressure") plt.plot(x_sol, p_sol) if run_god: plt.scatter(x_god, pressures_god, c='g') if run_rc: plt.scatter(x_rc, pressures_rc, c='r') if run_hllc: plt.scatter(x_hllc, pressures_hllc, c='k') plt.subplot(num_plts_x, num_plts_y, 4) plt.title("Energy") plt.plot(x_sol, e_sol) if run_god: plt.scatter(x_god, internal_energies_god, c='g') if run_rc: plt.scatter(x_rc, internal_energies_rc, c='r') if run_hllc: plt.scatter(x_hllc, internal_energies_hllc, c='k') plt.show()
def calculate_muscl_fluxes(densities, pressures, velocities, gamma, dt_over_dx): """ Function used to calculate fluxes for a 1D simulation using a MUSCL Hancock Scheme - Toro 14.4 """ # Get half step densities limiter = SuperBeeLimiter() half_step_densities_L = np.zeros(len(densities) - 2) half_step_velocities_L = np.zeros(len(densities) - 2) half_step_pressures_L = np.zeros(len(densities) - 2) half_step_densities_R = np.zeros(len(densities) - 2) half_step_velocities_R = np.zeros(len(densities) - 2) half_step_pressures_R = np.zeros(len(densities) - 2) for i, dens in enumerate(half_step_densities_L): idx = i + 1 # Calculate slopes left_slopes = dict() left_slopes["rho"] = (densities[idx] - densities[idx - 1]) / 2 left_slopes["mom"] = (densities[idx] * velocities[idx] - densities[idx - 1] * velocities[idx - 1]) / 2 cell_energy = 0.5 * densities[idx] * velocities[idx] * velocities[ idx] + pressures[idx] / (gamma - 1) behind_energy = 0.5 * densities[idx - 1] * velocities[ idx - 1] * velocities[idx - 1] + pressures[idx - 1] / (gamma - 1) left_slopes["energy"] = (cell_energy - behind_energy) / 2 right_slopes = dict() right_slopes["rho"] = (densities[idx + 1] - densities[idx]) / 2 right_slopes["mom"] = (densities[idx + 1] * velocities[idx + 1] - densities[idx] * velocities[idx]) / 2 forward_energy = 0.5 * densities[idx + 1] * velocities[ idx + 1] * velocities[idx + 1] + pressures[idx + 1] / (gamma - 1) right_slopes["energy"] = (forward_energy - cell_energy) / 2 average_density_slope, average_momentum_slope, average_energy_slope = limiter.calculate_limited_slopes( left_slopes, right_slopes) # Interpolate left and right densities left_density = densities[idx] - average_density_slope left_momentum = densities[idx] * velocities[ idx] - average_momentum_slope left_energy = cell_energy - average_energy_slope assert left_density > 0, left_density assert left_energy > 0, left_energy right_density = densities[idx] + average_density_slope right_momentum = densities[idx] * velocities[ idx] + average_momentum_slope right_energy = cell_energy + average_energy_slope assert right_density > 0, right_density assert right_energy > 0, right_energy # Perform half step flux left_velocity = left_momentum / left_density left_density_flux = left_momentum left_internal_energy = left_energy - 0.5 * left_momentum * left_velocity left_pressure = left_internal_energy * (gamma - 1) left_momentum_flux = left_momentum * left_velocity + left_pressure left_energy_flux = (left_energy + left_pressure) * left_velocity right_velocity = right_momentum / right_density right_density_flux = right_momentum right_internal_energy = right_energy - 0.5 * right_momentum * right_velocity right_pressure = right_internal_energy * (gamma - 1) right_momentum_flux = right_momentum * right_velocity + right_pressure right_energy_flux = (right_energy + right_pressure) * right_velocity half_step_density_flux = (left_density_flux - right_density_flux) * dt_over_dx * 0.5 half_step_momentum_flux = (left_momentum_flux - right_momentum_flux) * dt_over_dx * 0.5 half_step_energy_flux = (left_energy_flux - right_energy_flux) * dt_over_dx * 0.5 state = ThermodynamicState1D(left_pressure, left_density, left_velocity, gamma) state.update_states(half_step_density_flux, half_step_momentum_flux, half_step_energy_flux) half_step_densities_L[i] = state.rho half_step_velocities_L[i] = state.u half_step_pressures_L[i] = state.p state = ThermodynamicState1D(right_pressure, right_density, right_velocity, gamma) state.update_states(half_step_density_flux, half_step_momentum_flux, half_step_energy_flux) half_step_densities_R[i] = state.rho half_step_velocities_R[i] = state.u half_step_pressures_R[i] = state.p # Calculate final fluxes density_fluxes = np.zeros(len(half_step_densities_R) - 1) momentum_fluxes = np.zeros(len(half_step_densities_R) - 1) total_energy_fluxes = np.zeros(len(half_step_densities_R) - 1) solver = IterativeRiemannSolver(gamma) for i, dens_flux in enumerate(density_fluxes): # Generate left and right states from cell averaged values left_state = ThermodynamicState1D(half_step_pressures_R[i], half_step_densities_R[i], half_step_velocities_R[i], gamma) right_state = ThermodynamicState1D(half_step_pressures_L[i + 1], half_step_densities_L[i + 1], half_step_velocities_L[i + 1], gamma) # Solve Riemann problem for star states p_star, u_star = solver.get_star_states(left_state, right_state) # Calculate fluxes using solver sample function p_flux, u_flux, rho_flux, _ = solver.sample( 0.0, left_state, right_state, p_star, u_star) # Store fluxes in array density_fluxes[i] = rho_flux * u_flux momentum_fluxes[i] = rho_flux * u_flux * u_flux + p_flux e_tot = p_flux / (left_state.gamma - 1) + 0.5 * rho_flux * u_flux * u_flux total_energy_fluxes[i] = (p_flux + e_tot) * u_flux return density_fluxes, momentum_fluxes, total_energy_fluxes
def calculate_godunov_fluxes(densities, pressures, vel_x, vel_y, gamma): """ Function used to calculate fluxes for a 2D simulation using Godunov's scheme """ density_fluxes = np.zeros( (densities.shape[0] - 1, densities.shape[1] - 1, 2)) momentum_flux_x = np.zeros(density_fluxes.shape) momentum_flux_y = np.zeros(density_fluxes.shape) total_energy_fluxes = np.zeros(density_fluxes.shape) solver = IterativeRiemannSolver(gamma) i_length, j_length = np.shape(densities) for i in range(i_length - 1): for j in range(j_length - 1): # Generate left and right states from cell averaged values left_state = ThermodynamicState1D(pressures[i, j], densities[i, j], vel_x[i, j], gamma) right_state = ThermodynamicState1D(pressures[i + 1, j], densities[i + 1, j], vel_x[i + 1, j], gamma) # Solve Riemann problem for star states p_star, u_star = solver.get_star_states( left_state, right_state) # Calculate fluxes using solver sample function p_flux, u_flux, rho_flux, is_left = solver.sample( 0.0, left_state, right_state, p_star, u_star) # Store fluxes in array v_y = vel_y[i, j] if is_left else vel_y[i + 1, j] density_fluxes[i, j - 1, 0] = rho_flux * u_flux momentum_flux_x[i, j - 1, 0] = rho_flux * u_flux * u_flux + p_flux momentum_flux_y[i, j - 1, 0] = rho_flux * u_flux * v_y e_tot = p_flux / ( left_state.gamma - 1 ) + 0.5 * rho_flux * u_flux * u_flux + 0.5 * rho_flux * v_y**2 total_energy_fluxes[i, j - 1, 0] = (p_flux + e_tot) * u_flux # Generate left and right states from cell averaged values left_state = ThermodynamicState1D(pressures[i, j], densities[i, j], vel_y[i, j], gamma) right_state = ThermodynamicState1D(pressures[i, j + 1], densities[i, j + 1], vel_y[i, j + 1], gamma) # Solve Riemann problem for star states p_star, v_star = solver.get_star_states( left_state, right_state) # Calculate fluxes using solver sample function p_flux, v_flux, rho_flux, is_left = solver.sample( 0.0, left_state, right_state, p_star, v_star) # Store fluxes in array v_x = vel_x[i, j] if is_left else vel_x[i, j + 1] density_fluxes[i - 1, j, 1] = rho_flux * v_flux momentum_flux_x[i - 1, j, 1] = rho_flux * v_x * v_flux momentum_flux_y[i - 1, j, 1] = rho_flux * v_flux * v_flux + p_flux e_tot = p_flux / ( left_state.gamma - 1 ) + 0.5 * rho_flux * v_flux * v_flux + 0.5 * rho_flux * v_x**2 total_energy_fluxes[i - 1, j, 1] = (p_flux + e_tot) * v_flux return density_fluxes, momentum_flux_x, momentum_flux_y, total_energy_fluxes
def reflecting_boundary_condition(state): assert isinstance(state, ThermodynamicState1D) return ThermodynamicState1D(state.p, state.rho, -state.u, state.gamma)