# Use the existing connected PyFluent variable solver.
task_directory = r"C:\Users\13977\AppData\Local\FluentAGI\data\runs\20261018-131135-2f3559"
settings = solver.settings
transcript_started = False

gmsh_code = """
gmsh.model.add("naca0012_fast_repair")
occ = gmsh.model.occ
chord = 0.1
n = 36
upper = []
lower = []
for i in range(n + 1):
    x = 0.5 * (1.0 - math.cos(math.pi * i / n))
    yt = 0.6 * (
        0.2969 * math.sqrt(x)
        - 0.1260 * x
        - 0.3516 * x * x
        + 0.2843 * x * x * x
        - 0.1036 * x * x * x * x
    )
    if i == 0 or i == n:
        p = occ.addPoint(chord * x, 0.0, 0.0)
        upper.append(p)
        lower.append(p)
    else:
        upper.append(occ.addPoint(chord * x, chord * yt, 0.0))
        lower.append(occ.addPoint(chord * x, -chord * yt, 0.0))
cu = occ.addSpline(upper)
cl = occ.addSpline(lower[::-1])
foil_loop = occ.addCurveLoop([cu, cl])

p0 = occ.addPoint(-0.3, -0.3, 0)
p1 = occ.addPoint(0.7, -0.3, 0)
p2 = occ.addPoint(0.7, 0.3, 0)
p3 = occ.addPoint(-0.3, 0.3, 0)
bottom = occ.addLine(p0, p1)
right = occ.addLine(p1, p2)
top = occ.addLine(p2, p3)
left = occ.addLine(p3, p0)
outer_loop = occ.addCurveLoop([bottom, right, top, left])
fluid = occ.addPlaneSurface([outer_loop, foil_loop])
occ.synchronize()

for name, curves in [
    ("inlet", [left]),
    ("outlet", [right]),
    ("walls", [bottom, top, cu, cl]),
]:
    tag = gmsh.model.addPhysicalGroup(1, curves)
    gmsh.model.setPhysicalName(1, tag, name)
tag = gmsh.model.addPhysicalGroup(2, [fluid])
gmsh.model.setPhysicalName(2, tag, "fluid")

distance = gmsh.model.mesh.field.add("Distance")
gmsh.model.mesh.field.setNumbers(distance, "CurvesList", [cu, cl])
gmsh.model.mesh.field.setNumber(distance, "Sampling", 160)
near = gmsh.model.mesh.field.add("Threshold")
for key, value in [
    ("InField", distance),
    ("SizeMin", 0.0008),
    ("SizeMax", 0.025),
    ("DistMin", 0.003),
    ("DistMax", 0.08),
]:
    gmsh.model.mesh.field.setNumber(near, key, value)

wake = gmsh.model.mesh.field.add("Box")
for key, value in [
    ("VIn", 0.004), ("VOut", 0.025),
    ("XMin", 0.085), ("XMax", 0.4),
    ("YMin", -0.025), ("YMax", 0.025),
    ("ZMin", -0.001), ("ZMax", 0.001),
    ("Thickness", 0.025),
]:
    gmsh.model.mesh.field.setNumber(wake, key, value)
combined = gmsh.model.mesh.field.add("Min")
gmsh.model.mesh.field.setNumbers(combined, "FieldsList", [near, wake])
gmsh.model.mesh.field.setAsBackgroundMesh(combined)

for key, value in [
    ("Mesh.MeshSizeFromPoints", 0),
    ("Mesh.MeshSizeFromCurvature", 0),
    ("Mesh.MeshSizeExtendFromBoundary", 0),
    ("Mesh.MeshSizeMin", 0.0006),
    ("Mesh.MeshSizeMax", 0.025),
    ("Mesh.ElementOrder", 1),
    ("Mesh.Algorithm", 6),
]:
    gmsh.option.setNumber(key, value)
gmsh.write(output_dir + "/naca0012.step")
gmsh.model.mesh.generate(2)
gmsh.model.mesh.optimize("Relocate2D")
"""

try:
    settings.file.start_transcript(
        file_name=task_directory + r"\airfoil_repair.trn"
    )
    transcript_started = True

    if settings.setup.models.is_active():
        print("CURRENT_MODELS", settings.setup.models.get_state())
        settings.file.write_case_data(
            file_name=task_directory + r"\before_airfoil_repair.cas.h5"
        )

    mesh = fluentagi.geometry_mesh(
        directory=task_directory,
        code=gmsh_code,
    )
    print("AIRFOIL_MESH", mesh)
    settings.file.read_mesh(file_name=mesh["mesh_file"])
    settings.mesh.check()

    if not settings.setup.models.is_active():
        raise RuntimeError("翼型网格读入后模型未激活。")

    settings.setup.general.solver.type = "pressure-based"
    settings.setup.general.solver.time = "steady"
    settings.setup.models.viscous.model = "laminar"
    settings.setup.models.energy.enabled = False
    settings.setup.general.operating_conditions.gravity.enable = False

    air = settings.setup.materials.fluid["air"]
    air.density.set_state({"option": "constant", "value": 1.225})
    air.viscosity.set_state({"option": "constant", "value": 1.7894e-5})
    print("AIR_READBACK", air.get_state())

    zones = settings.setup.cell_zone_conditions.fluid
    zone_names = zones.get_object_names()
    if not zone_names:
        raise RuntimeError("没有流体单元区。")
    for name in zone_names:
        zones[name].general.material = "air"

    boundaries = settings.setup.boundary_conditions
    inlet = boundaries.velocity_inlet["inlet"]
    inlet.momentum.velocity_specification_method = "Magnitude, Normal to Boundary"
    inlet.momentum.velocity.set_state({"option": "value", "value": 0.1})
    outlet = boundaries.pressure_outlet["outlet"]
    outlet.momentum.gauge_pressure.set_state(
        {"option": "value", "value": 0.0}
    )
    for name in boundaries.wall.get_object_names():
        wall = boundaries.wall[name]
        wall.momentum.wall_motion = "Stationary Wall"
        wall.momentum.shear_condition = "No Slip"
        print("WALL_READBACK", name, wall.get_state())

    velocity_state = inlet.momentum.velocity.get_state()
    pressure_state = outlet.momentum.gauge_pressure.get_state()
    print("INLET_READBACK", velocity_state)
    print("OUTLET_READBACK", pressure_state)
    if abs(velocity_state["value"] - 0.1) > 1e-10:
        raise RuntimeError("入口速度读回不符。")
    if abs(pressure_state["value"]) > 1e-10:
        raise RuntimeError("出口表压读回不符。")

    print("RE_CHORD", 1.225 * 0.1 * 0.1 / 1.7894e-5)
    print("RESIDUAL_SETTINGS", settings.solution.monitor.residual.get_state())
    settings.file.write_case(
        file_name=task_directory + r"\airfoil_repair_configured.cas.h5"
    )
    settings.solution.initialization.hybrid_initialize()

    for batch in range(1, 4):
        print("BATCH_BEGIN", batch, "MAX_ITERATIONS", 100)
        settings.solution.run_calculation.iterate(iter_count=100)
        print("BATCH_END", batch)
        settings.file.write_case_data(
            file_name=task_directory
            + r"\airfoil_repair_batch_"
            + str(batch)
            + ".cas.h5"
        )

    settings.file.write_case_data(
        file_name=task_directory + r"\airfoil_repair_final.cas.h5"
    )
    result = fluentagi.export_results(
        directory=task_directory,
        fields=["pressure", "velocity-magnitude"],
    )
    print("EXPORT_RESULTS", result)
    print(
        "低雷诺数零攻角风洞演示；翼面距离场和尾迹区域预设加密。"
        "收敛依据 airfoil_repair.trn 中实际残差和收敛提示判断，"
        "导出成功与否依据 EXPORT_RESULTS 返回状态及错误列表判断。"
    )

finally:
    if transcript_started:
        settings.file.stop_transcript()