# Use the existing connected PyFluent variable solver.
import math

task_directory = r"C:\Users\13977\AppData\Local\FluentAGI\data\runs\20261018-142547-90d0a4"
s = solver.settings

def checked(label, result):
    print(label, result)
    if isinstance(result, dict):
        if result.get("status") in ("error", "failed", "needs_review"):
            raise RuntimeError(str(result))
        if result.get("error") or result.get("errors"):
            raise RuntimeError(str(result))
    return result

def numbers(value):
    if isinstance(value, bool):
        return []
    if isinstance(value, (int, float)):
        return [float(value)]
    if isinstance(value, dict):
        return [number for child in value.values() for number in numbers(child)]
    if isinstance(value, (list, tuple)):
        return [number for child in value for number in numbers(child)]
    return []

def value_of(result, name):
    if isinstance(result, dict):
        if name in result:
            values = numbers(result[name])
            if values and math.isfinite(values[0]):
                return values[0]
        children = result.values()
    elif isinstance(result, (list, tuple)):
        children = result
    else:
        children = []
    for child in children:
        try:
            return value_of(child, name)
        except ValueError:
            pass
    raise ValueError("无法提取报告：" + name + "；返回：" + str(result))

if not s.setup.models.is_active():
    raise RuntimeError("当前网格未激活。")

reports = s.solution.report_definitions
if not reports.compute.is_active():
    raise RuntimeError("当前解的报告不可用；停止，不执行初始化。")

print("CURRENT_SOLVER", s.setup.general.solver.get_state())
print("CURRENT_ITERATION", s.solution.run_calculation.iter_count.get_state())
print(
    "CURRENT_TRANSIENT_CONTROLS",
    s.solution.run_calculation.transient_controls.get_state(),
)

force_names = ["front_wing_drag_interface", "front_wing_lift_interface"]
for name in force_names:
    if name not in reports.force.get_object_names():
        raise RuntimeError("缺少已配置的前翼受力报告：" + name)

wing_zones = reports.force[force_names[0]].zones.get_state()
lift_zones = reports.force[force_names[1]].zones.get_state()
if not wing_zones or set(wing_zones) != set(lift_zones):
    raise RuntimeError("升阻力统计区域为空或不一致。")
print("WING_FORCE_ZONES", wing_zones)

force_result = reports.compute(report_defs=force_names)
drag, lift = [value_of(force_result, name) for name in force_names]
reference_area = 0.552
denominator = 0.5 * 1.225 * 30.0**2 * reference_area
print("AERODYNAMIC_READBACK", {
    "drag": drag,
    "lift": lift,
    "downforce": -lift,
    "CD": drag / denominator,
    "CL": lift / denominator,
    "reference_area": reference_area,
})

mass_names = ["fw_inlet_mass", "fw_outlet_mass"]
if all(name in reports.surface.get_object_names() for name in mass_names):
    mass_result = reports.compute(report_defs=mass_names)
    mass_values = [value_of(mass_result, name) for name in mass_names]
    imbalance = abs(sum(mass_values)) / max(
        max(abs(value) for value in mass_values), 1e-20
    )
    print("MASS_BALANCE_READBACK", {
        "inlet": mass_values[0],
        "outlet": mass_values[1],
        "relative_imbalance": imbalance,
    })

time_reports = reports.time
time_name = "front_wing_actual_flow_time"
if name not in []:
    if time_name not in time_reports.get_object_names():
        time_reports[time_name] = {}
time_report = time_reports[time_name]
if "report_type" in getattr(time_report, "child_names", []):
    options = time_report.report_type.allowed_values()
    selected = [
        option for option in options
        if option in ["flow-time", "flow_time", "time-flow-time"]
    ]
    if selected:
        time_report.report_type = selected[0]
        print(
            "ACTUAL_FLOW_TIME",
            reports.compute(report_defs=[time_name]),
        )
    else:
        print("TIME_REPORT_OPTIONS", options)
else:
    print("TIME_REPORT_STATE", time_report.get_state())

paths = s.results.graphics.pathline
if not paths.is_active():
    raise RuntimeError("当前解的原生流线对象不可用。")

path_name = "front_wing_streamlines"
if path_name not in paths.get_object_names():
    paths[path_name] = {}
path = paths[path_name]
if "velocity-magnitude" not in path.field.allowed_values():
    raise RuntimeError("流线着色字段不可用。")
path.field = "velocity-magnitude"
path.release_from_surfaces = ["inlet"]
print("STREAMLINE_CONFIGURATION", {
    "field": path.field.get_state(),
    "release_from_surfaces": path.release_from_surfaces.get_state(),
    "step": path.step.get_state(),
    "skip": path.skip.get_state(),
})
for name in ["options", "accuracy_control"]:
    child = getattr(path, name)
    if child.is_active():
        print("STREAMLINE_CONTROL", name, child.get_state())

views = s.results.graphics.views
views.restore_view(view_name="isometric")
views.auto_scale()
paths.display(object_name=path_name)
views.auto_scale()

picture = s.results.graphics.picture
commands = getattr(picture, "command_names", [])
if "save_picture" not in commands:
    raise RuntimeError("当前原生图片保存命令不可用。")
command = picture.save_picture
if "file_name" not in getattr(command, "argument_names", []):
    raise RuntimeError("图片保存命令参数不匹配。")
streamline_file = task_directory + r"\front_wing_streamlines.png"
print("STREAMLINE_PICTURE_RESULT", command(file_name=streamline_file))
print("STREAMLINE_PICTURE_REQUESTED", streamline_file)

checked(
    "WING_SURFACE_EXPORT",
    fluentagi.export_results(
        directory=task_directory,
        fields=["pressure", "velocity-magnitude"],
        surfaces=wing_zones,
    ),
)

s.file.write_case_data(
    file_name=task_directory + r"\front_wing_postprocessed_checkpoint.cas.h5"
)
print("POSTPROCESSING_SCOPE", {
    "initialized": False,
    "advanced_time_steps": 0,
    "streamlines": "instantaneous_velocity_field",
    "force_stability_verified": False,
    "all_step_convergence_verified": False,
    "mesh_independence_verified": False,
})