# Точка входа модели 2×+SDF. Запуск из этой папки: # python run.py # AMR_STEPS=2000 python run.py # короткий прогон # AMR_CUDAGRAPH=0 python run.py # без CUDA-графов # AMR_FP64=1 python run.py # двойная точность import os, time import config as C import backend as B import solver as S import diagnostics as Diag import visualization as Viz HERE = os.path.dirname(os.path.abspath(__file__)) OUT = os.path.join(HERE, "out"); os.makedirs(OUT, exist_ok=True) def main(): cfg = C.from_env() print(f"[2×+SDF] backend={B.BACKEND}; домен {cfg.Nx}x{cfg.Ny}; D={cfg.D}; steps={cfg.steps}; " f"collision=kbc; force=gmem; " f"graphs={'on' if cfg.use_cuda_graph else 'off'}; " f"L1 {cfg.refine}× = {(cfg.bx1-cfg.ax1)*cfg.refine+1}x{(cfg.by1-cfg.ay1)*cfg.refine+1}; " f"вход {cfg.cx/cfg.D:.1f}D / выход {(cfg.Nx-1-cfg.cx)/cfg.D:.1f}D; outlet_uy={cfg.outlet_uy}") t0 = time.perf_counter() sim = S.Solver(cfg) res = sim.run(Viz.make_progress("2x+sdf")) print(" время:", round(time.perf_counter() - t0, 1), "s") a = Diag.analyze(res, cfg) Diag.print_table(a, cfg) Diag.print_crosscheck(a) Diag.convergence_report(res, cfg) Viz.save_gif(res, sim.geo, cfg, os.path.join(OUT, "cyl_2x_sdf.gif")) Viz.save_series_panel(res, a, cfg, os.path.join(OUT, "series_2x_sdf.png")) import numpy as np np.savez(os.path.join(OUT, "probe_2x_sdf.npz"), # сводные числа (самоописываемость для ноутбука: он только читает артефакты) St=a["St"], Cd=a["Cd"], Clrms=a["Clrms"], uyrms=a["uyrms"], Cm=a.get("Cm", float("nan")), Cd_st=a.get("Cd_st", float("nan")), Clrms_st=a.get("Clrms_st", float("nan")), Cm_st=a.get("Cm_st", float("nan")), Ny=cfg.Ny, beta=cfg.D/cfg.Ny, D=cfg.D, U=cfg.U, Re=cfg.Re, steps=cfg.steps, Nx=cfg.Nx, cx=cfg.cx, outlet_uy=cfg.outlet_uy, stress_every=res["stress_every"], # ряды Cl=a["Cl_s"], uy=a["uy"], Fx=B.to_cpu(res["Fx"]), Fy=B.to_cpu(res["Fy"]), Tz=B.to_cpu(res["Tz"]), rho=B.to_cpu(res["rho"]), Fx_st=B.to_cpu(res["Fx_st"]), Fy_st=B.to_cpu(res["Fy_st"]), Tz_st=B.to_cpu(res["Tz_st"])) print("DONE (2×+SDF)") if __name__ == "__main__": main()