Начальный коммит: Vulkan-редактор SimVulcan + исследование KBC-LBM
Состояние на момент заведения репозитория. C++ приложение (src/, shaders/, tests/) — минимальный редактор 3D-моделей на Vulkan 1.3: орбитальная камера, три опорные сетки через начало координат, загрузка .obj с режимами отображения. Весь Vulkan изолирован в src/vk/. Исследование (docs/) — оригинальные статьи по KBC (docs/origins) и Python-решатель D2Q9 KBC-N1 с AMR 2x и SDF+Bouzidi (docs/theory). В решателе перед коммитом исправлены дефекты, найденные сверкой с первоисточниками: относительный порог знаменателя энтропийного стабилизатора (абсолютный вырождал KBC в LBGK на 77-99% узлов), заворот вход/выход в углах домена, диагностика средней плотности по фиктивным узлам тела, зашитый refine=2. Подробности — docs/theory/solver_2x_sdf/README.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# Точка входа модели 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()
|
||||
Reference in New Issue
Block a user