コード例 #1
0
ファイル: riemann_solver.py プロジェクト: Sathyan64/CFD_Codes
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
コード例 #2
0
    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
コード例 #3
0
ファイル: controller.py プロジェクト: Sathyan64/CFD_Codes
    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)
コード例 #4
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)
コード例 #5
0
    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
コード例 #6
0
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()
コード例 #7
0
    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
コード例 #8
0
ファイル: controller.py プロジェクト: Sathyan64/CFD_Codes
    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
コード例 #9
0
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()
コード例 #10
0
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()
コード例 #11
0
    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
コード例 #12
0
    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
コード例 #13
0
    def reflecting_boundary_condition(state):
        assert isinstance(state, ThermodynamicState1D)

        return ThermodynamicState1D(state.p, state.rho, -state.u, state.gamma)