"""Повторное открытие и расчёт опубликованных учебных моделей в FEMM 5.

Эталонные файлы не изменяются: FEM и новые ANS сохраняются в отдельной папке.
"""
import os,sys,json,math
assert sys.implementation.name=='micropython'
saved=globals().get('__file__') or (sys.argv[0] if sys.argv else '')
if not saved or not os.path.isfile(saved): raise RuntimeError('Запустите сохранённый файл')
folder=os.path.dirname(os.path.abspath(saved)); os.chdir(folder)
with open('model-controls.json') as f: controls=json.load(f)
try: os.mkdir('runs')
except OSError: pass
index=1
while os.path.exists('runs/проверка-моделей-'+str(index)): index+=1
out='runs/проверка-моделей-'+str(index); os.mkdir(out)
rows=[]
for item in controls['models']:
    source=os.path.join(folder,item['path'])
    opendocument(source)
    mi_saveas(out+'/'+os.path.basename(source)); mi_analyze(1); mi_loadsolution()
    mo_clearblock(); mo_groupselectblock(2); torque=float(mo_blockintegral(22)); mo_clearblock()
    elements=int(mo_numelements())
    for circuit in ('Фаза A','Фаза B','Фаза C'):
        properties=mo_getcircuitproperties(circuit)
        assert len(properties)==3 and all(math.isfinite(float(v)) for v in properties), 'Не прочитана цепь с русским именем'
    assert math.isfinite(torque)
    error=abs(torque-item['expected_torque_Nm'])
    passed=error<=max(1e-6,abs(item['expected_torque_Nm'])*1e-6) and elements==item['expected_elements']
    rows.append({'path':item['path'],'torque_Nm':torque,'expected_torque_Nm':item['expected_torque_Nm'],'absolute_error_Nm':error,'elements':elements,'passed':passed})
    mo_close(); mi_close()
    assert passed, 'Повторный расчёт не совпал с эталоном'
with open(out+'/verification.json','w') as f: json.dump({'passed':all(r['passed'] for r in rows),'models':rows},f)
print('NATIVE MODELS VERIFIED',len(rows),out)
