"""Учебные материалы: сохранение, повторное открытие и расчёт FEMM 5.

Запуск: встроенный Python FEMM 5 из отдельной рабочей папки.
Создаются только собственные файлы Учебный-материал-*.fem/.ans.
Однородное B задаётся граничным потенциалом, H определяется материалом.
"""
import json
from math import pi

# Геометрия: миллиметры. Глубина: 100 мм. B = 0,5 Тл по оси +y.
rows = []
for variant in ["Линейная сталь", "Нелинейная сталь", "Постоянный магнит"]:
    newdocument(0)
    mi_probdef(0, "millimeters", "planar", 1e-9, 100, 30)
    hc = 1.2/(4*pi*1e-7*1.05) if variant == "Постоянный магнит" else 0
    mur = 1.05 if hc else (1000 if variant == "Линейная сталь" else 1)
    mi_addmaterial(variant, mur, mur, hc)
    if variant == "Нелинейная сталь":
        # API принимает B, H; в паспорте порядок колонок может быть обратным.
        for b, h in [(0, 0), (0.2, 100), (0.5, 300), (1.0, 1000), (1.5, 5000), (2.0, 20000)]:
            mi_addbhpoint(variant, b, h)
    mi_drawrectangle(0, 0, 10, 20)
    mi_addboundprop("Левая граница", 0, 0, 0, 0, 0, 0, 0, 0, 0)
    mi_addboundprop("Правая граница", -0.005, 0, 0, 0, 0, 0, 0, 0, 0)
    for x, name in [(0, "Левая граница"), (10, "Правая граница")]:
        mi_selectsegment(x, 10)
        mi_setsegmentprop(name, 0, 1, 0, 0)
        mi_clearselected()
    mi_addblocklabel(5, 10)
    mi_selectlabel(5, 10)
    mi_setblockprop(variant, 0, 1, "<None>", 90 if hc else 0, 1, 0)
    mi_clearselected()
    name = "Учебный-материал-"+variant.replace(" ", "-")+".fem"
    mi_saveas(name)
    mi_close()
    # Проверяем точный сохранённый документ повторным открытием перед решением.
    opendocument(name)
    mi_analyze(1)
    mi_loadsolution()
    values = mo_getpointvalues(5, 10)
    bx, by = values[1], values[2]
    assert abs(bx) < 1e-7 and abs(by-0.5) < 1e-6, (variant, bx, by)
    rows.append({"material":variant,"model":name,"B_x_T":bx,"B_y_T":by,
                 "H_parallel_A_m":(by-1.2)/(4*pi*1e-7*1.05) if hc else values[6],
                 "elements":mo_numelements()})
    mo_close()
    mi_close()
with open("material-results.json", "w") as stream:
    json.dump({"passed":True,"models":rows}, stream)
