代码仓库移植
This commit is contained in:
commit
0f57ba94f3
44 files changed
+7119
No files matched your search
+131
@@ -0,0 +1,131 @@
|
||||
# src/main.py
|
||||
"""
|
||||
Entry point: assemble tanks + pipe from config constants, run the solver,
|
||||
verify total mass/energy conservation, persist history, and generate
|
||||
plots + animation.
|
||||
|
||||
Run from project root:
|
||||
python3 src/main.py
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Ensure imports work when running from project root
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, _HERE)
|
||||
|
||||
import numpy as np
|
||||
|
||||
from config import (
|
||||
GAMMA, R_GAS,
|
||||
V1, P1_INIT, T1_INIT,
|
||||
V2, P2_INIT, T2_INIT,
|
||||
L, D, N_CELLS,
|
||||
MU, ROUGHNESS,
|
||||
T_END, CFL, RIEMANN_SOLVER,
|
||||
ANIMATION_STRIDE, OUTPUT_DIR,
|
||||
)
|
||||
from tank import Tank
|
||||
from pipe import Pipe
|
||||
from solver import run
|
||||
from output import (
|
||||
save_history,
|
||||
plot_tank_pressure,
|
||||
plot_tank_temperature,
|
||||
plot_pipe_final_profiles,
|
||||
make_pipe_animation,
|
||||
write_summary_report,
|
||||
)
|
||||
|
||||
|
||||
def _total_mass(tank1, tank2, pipe):
|
||||
pipe_mass = float(np.sum(pipe.W[0, :] * pipe.area * pipe.dx))
|
||||
return tank1.mass + tank2.mass + pipe_mass
|
||||
|
||||
|
||||
def _total_energy(tank1, tank2, pipe):
|
||||
pipe_energy = float(np.sum(pipe.W[2, :] * pipe.area * pipe.dx))
|
||||
return tank1.U + tank2.U + pipe_energy
|
||||
|
||||
|
||||
def main():
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
# --- Assemble ---
|
||||
tank1 = Tank(V=V1, P_init=P1_INIT, T_init=T1_INIT, gamma=GAMMA, R_gas=R_GAS)
|
||||
tank2 = Tank(V=V2, P_init=P2_INIT, T_init=T2_INIT, gamma=GAMMA, R_gas=R_GAS)
|
||||
pipe = Pipe(L=L, D=D, N=N_CELLS, P_init=P2_INIT, T_init=T2_INIT,
|
||||
gamma=GAMMA, R_gas=R_GAS, mu=MU, roughness=ROUGHNESS,
|
||||
riemann_solver=RIEMANN_SOLVER)
|
||||
|
||||
m_init = _total_mass(tank1, tank2, pipe)
|
||||
U_init = _total_energy(tank1, tank2, pipe)
|
||||
print(f"Initial total mass: {m_init:.6e} kg")
|
||||
print(f"Initial total energy: {U_init:.6e} J")
|
||||
print(f"Initial P1 = {tank1.P/1e6:.3f} MPa, P2 = {tank2.P/1e6:.3f} MPa")
|
||||
print(f"Pipe: L={L} m, D={D*1e3:.1f} mm, N={N_CELLS} cells, dx={pipe.dx*1e3:.1f} mm")
|
||||
print(f"Riemann solver: {RIEMANN_SOLVER.upper()}")
|
||||
if MU > 0:
|
||||
print(f"Friction: mu={MU:.2e} Pa·s, roughness={ROUGHNESS:.2e} m (eps/D={ROUGHNESS/D:.4f})")
|
||||
else:
|
||||
print("Friction: OFF")
|
||||
print(f"Running to t_end={T_END} s with CFL={CFL}...")
|
||||
print()
|
||||
|
||||
# --- Run ---
|
||||
history = run(tank1, tank2, pipe,
|
||||
t_end=T_END, cfl=CFL,
|
||||
verbose=True, log_every=200)
|
||||
|
||||
n_steps = len(history['t'])
|
||||
print()
|
||||
print(f"Simulation complete: {n_steps} steps")
|
||||
|
||||
# --- Conservation sanity check (per spec §6.1, §8) ---
|
||||
m_final = _total_mass(tank1, tank2, pipe)
|
||||
U_final = _total_energy(tank1, tank2, pipe)
|
||||
rel_err_m = abs(m_final - m_init) / m_init
|
||||
rel_err_U = abs(U_final - U_init) / U_init
|
||||
print(f"Final total mass: {m_final:.6e} kg (rel err = {rel_err_m:.2e})")
|
||||
print(f"Final total energy: {U_final:.6e} J (rel err = {rel_err_U:.2e})")
|
||||
print(f"Final P1 = {tank1.P/1e6:.3f} MPa, P2 = {tank2.P/1e6:.3f} MPa")
|
||||
assert rel_err_m < 1e-10, f"Total mass not conserved: rel_err={rel_err_m:.2e}"
|
||||
assert rel_err_U < 1e-10, f"Total energy not conserved: rel_err={rel_err_U:.2e}"
|
||||
|
||||
# --- Persist + visualize ---
|
||||
save_history(history, pipe,
|
||||
os.path.join(OUTPUT_DIR, "history.npz"),
|
||||
GAMMA, R_GAS)
|
||||
plot_tank_pressure(history,
|
||||
os.path.join(OUTPUT_DIR, "tank_pressure.png"))
|
||||
plot_tank_temperature(history,
|
||||
os.path.join(OUTPUT_DIR, "tank_temperature.png"))
|
||||
plot_pipe_final_profiles(history, pipe,
|
||||
os.path.join(OUTPUT_DIR, "pipe_final_profiles.png"),
|
||||
GAMMA, R_GAS)
|
||||
make_pipe_animation(history, pipe,
|
||||
os.path.join(OUTPUT_DIR, "pipe_animation.gif"),
|
||||
GAMMA, R_GAS, stride=ANIMATION_STRIDE)
|
||||
write_summary_report(
|
||||
history, pipe,
|
||||
os.path.join(OUTPUT_DIR, "summary_report.html"),
|
||||
GAMMA, R_GAS,
|
||||
config={
|
||||
'V1': V1, 'P1_INIT': P1_INIT, 'T1_INIT': T1_INIT,
|
||||
'V2': V2, 'P2_INIT': P2_INIT, 'T2_INIT': T2_INIT,
|
||||
'L': L, 'D': D, 'N_CELLS': N_CELLS,
|
||||
'T_END': T_END, 'CFL': CFL,
|
||||
},
|
||||
)
|
||||
|
||||
print(f"Outputs written to {OUTPUT_DIR}/")
|
||||
print(f" - history.npz")
|
||||
print(f" - tank_pressure.png")
|
||||
print(f" - tank_temperature.png")
|
||||
print(f" - pipe_final_profiles.png")
|
||||
print(f" - pipe_animation.gif")
|
||||
print(f" - summary_report.html")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user