# 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_demo")
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 = 5.0 * 0.12 * (
        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(list(reversed(lower)))
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")
gmsh.model.mesh.field.setNumber(near, "InField", distance)
gmsh.model.mesh.field.setNumber(near, "SizeMin", 0.0008)
gmsh.model.mesh.field.setNumber(near, "SizeMax", 0.025)
gmsh.model.mesh.field.setNumber(near, "DistMin", 0.003)
gmsh.model.mesh.field.setNumber(near, "DistMax", 0.08)

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)
gmsh.option.setNumber("Mesh.MeshSizeFromPoints", 0)
gmsh.option.setNumber("Mesh.MeshSizeFromCurvature", 0)
gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0)
gmsh.option.setNumber("Mesh.MeshSizeMin", 0.0006)
gmsh.option.setNumber("Mesh.MeshSizeMax", 0.025)
gmsh.option.setNumber("Mesh.ElementOrder", 1)
gmsh.option.setNumber("Mesh.Algorithm", 6)
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_demo.trn"
    )
    transcript_started = True

    if settings.setup.models.is_active():
        settings.file.write_case_data(
            file_name=task_directory + r"\previous_channel_backup.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", air.get_state())
    print("DEMO_PARAMETERS", {
        "airfoil": "NACA0012",
        "chord_m": 0.1,
        "velocity_m_s": 0.1,
        "angle_deg": 0.0,
        "Re_chord": 1.225 * 0.1 * 0.1 / 1.7894e-5,
        "model": "steady laminar",
        "refinement": "prescribed distance and wake fields",
    })

    zones = settings.setup.cell_zone_conditions.fluid
    for name in zones.get_object_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("INLET", inlet.get_state())
    print("OUTLET", outlet.get_state())
    print("WALLS", boundaries.wall.get_state())
    print("RESIDUAL_SETTINGS", settings.solution.monitor.residual.get_state())

    settings.file.write_case(
        file_name=task_directory + r"\airfoil_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_batch_"
            + str(batch)
            + ".cas.h5"
        )

    settings.file.write_case_data(
        file_name=task_directory + r"\airfoil_final.cas.h5"
    )
    result = fluentagi.export_results(
        directory=task_directory,
        fields=["pressure", "velocity-magnitude"],
    )
    print("EXPORT_RESULTS", result)
    print(
        "本案例为低雷诺数零攻角风洞演示，采用预设空间局部加密，"
        "不是基于求解误差的自适应网格。"
        "实际收敛需核对 airfoil_demo.trn 和导出的 residual.csv；"
        "若未达到判据，保留当前解继续迭代，不重新初始化。"
    )

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