FEMM 5

Магнитостатика · Осесимметричная

Катушки Максвелла и размер однородной области

Трёхкатушечная система позволяет подавить больше членов разложения поля около центра, чем обычная симметричная пара. При этом важны не только расстояния, но и отношение токов центральной и крайних обмоток. Работа показывает, как геометрическая настройка влияет на профиль и почему проверку однородности нужно задавать как измеримую характеристику области.

Радиус средней катушки составляет 100 мм. Радиусы крайних катушек равны R√(4/7), а их положения z=±R√(3/7) умножаются на коэффициенты 0.9, 1.0 и 1.1. Во всех катушках 100 витков сечением пакета 2×2 мм. Средняя несёт 1 А, крайние — по 49/64 А.

Самостоятельная учебная модель FEMM 5: от физических соотношений к полевому решению и проверке результата.

Допущения и устройство учебной модели

Все размеры, свойства материалов и условия возбуждения заданы ниже. Численные результаты относятся к опубликованной версии модели FEMM 5.

Физическая и математическая постановка

Настройка трёх источников

Поля катушек складываются по формуле кругового кольца. Симметрия относительно средней плоскости автоматически устраняет нечётные члены осевого разложения. Дополнительные радиусы, расстояния и отношение токов дают возможность уменьшить вторую и четвёртую производные. Это создаёт более плоский профиль в ограниченной окрестности центра.

Не следует смешивать рассматриваемую систему однородного поля с парой Максвелла для создания градиента. Здесь токи трёх обмоток имеют одинаковую ориентацию, а центральный уровень не равен нулю. Программа использует три независимые цепи, поэтому отношение токов задаётся явно и остаётся проверяемым после сохранения модели.

R_{\mathrm{край}}=R\sqrt{4/7},\quad z_{\mathrm{край}}=\pm R\sqrt{3/7},\quad I_{\mathrm{край}}=49I/64

От профиля к практическому допуску

Для трёх настроек сохраняются центральная индукция и семь значений на оси. Независимый профиль тонких колец позволяет проверить направления токов и осевую координату. Относительное отклонение оценивается в фиксированном интервале ±0.2R; этот интервал нельзя менять после расчёта ради улучшения показателя.

Далее сравните чувствительность системы к ошибке одного тока и к симметричному изменению расстояний. Эти возмущения нарушают разные условия компенсации производных. В собственном дополнительном опыте оставляйте остальные параметры постоянными и сохраняйте новый каталог расчёта. Сеточное сравнение определяет численную устойчивость, тогда как сравнение разных настроек отвечает на физический вопрос о допустимой ошибке сборки.

Исходные данные

Осесимметричная

Величины, единицы и происхождение параметров
ПараметрЗначениеЕдиницаПроисхождение
Базовый радиус100ммЗаданный параметр самостоятельной учебной модели
Число витков одной обмотки100Заданный параметр самостоятельной учебной модели
Ток; для AC — амплитуда1АЗаданный параметр самостоятельной учебной модели
Коэффициент осевого смещения0.9, 1, 1.1Заданный параметр самостоятельной учебной модели

Порядок воспроизведения

  1. До запуска запишите уравнение контрольной величины и ожидаемое направление изменения при вариации параметра. Согласуйте миллиметры геометрии с единицами СИ в формулах. Создайте отдельную папку и откройте reproduce.py во встроенном редакторе Python FEMM 5. Команды mi_* и mo_* в этой среде уже доступны глобально.
  2. Выполните программу целиком. Она создаёт новый calculated-NN, строит каждую модель с русскими именами материалов и цепей, сохраняет файл FEM, закрывает его и повторно открывает перед решением. Поэтому проверка относится к точному записанному варианту модели и охватывает сохранение кириллицы.
  3. Изучите result.json: records хранит численные результаты всех режимов и трёх сеток, checks — названия проверок, измеренные отклонения, допуски и итог. Откройте модель и решение финальной сетки; сопоставьте материалы, направление токов и характерные размеры с таблицей параметров.
  4. Составьте отчёт с физическим объяснением, таблицей сходимости и независимым контрольным расчётом. Затем измените один параметр и выполните новую серию. Сохраняйте предыдущую серию для сравнения; успешное завершение решателя само по себе не заменяет проверки физического масштаба и сеточной устойчивости.

Скачайте нужные файлы по отдельным ссылкам ниже в одну рабочую папку, затем откройте reproduce.py во встроенном Python FEMM 5 и выполните его. Сохраните имена файлов и структуру подпапок. Условия конкретного запуска и путь новых результатов указаны в комментариях программы.

Программа встроенного Python FEMM 5
Python · reproduce.py
"""Собственная учебная лабораторная FEMM 5: встроенный Python.
Команды FEMM доступны глобально, внешний пакет femm не используется.
Каждая сетка сохраняется в отдельный FEM, закрывается, открывается повторно
и решается с русскими именами свойств. Новый запуск создаёт calculated-NN.
Опубликованные модели и квитанции не изменяются. Размеры: мм; результаты: СИ.
"""
import os
import sys
import math
import json
CONFIG = {'R': 100, 'N': 100, 'I': 1, 'variants': [0.9, 1, 1.1]}
MODE = 'maxwell'
saved=globals().get('__file__','') or (sys.argv[0] if sys.argv else '')
base=os.path.dirname(os.path.abspath(saved)) if saved else os.getcwd()
index=1
while os.path.exists(base+'/calculated-%02d'%index):index+=1
directory=base+'/calculated-%02d'%index
os.mkdir(directory)
records=[]
checks=[]
MU0=4*math.pi*1e-7

def real(x):
    if isinstance(x,(list,tuple)):x=x[0]
    return complex(x).real

def check(name,value,limit):
    checks.append({'name':name,'value':value,'limit':limit,'passed':math.isfinite(value) and value<=limit})

def material(name,mu=1,sigma=0):
    mi_addmaterial(name,mu,mu,0,0,sigma/1e6)

def label(x,y,name,mesh,group=1,circuit='<None>',turns=1):
    mi_addblocklabel(x,y);mi_selectlabel(x,y)
    mi_setblockprop(name,0,mesh,circuit,0,group,turns);mi_clearselected()

def polygon(points,boundary=None,spacing=0):
    for x,y in points:mi_addnode(x,y)
    for i,(x,y) in enumerate(points):
        x2,y2=points[(i+1)%len(points)];mi_addsegment(x,y,x2,y2)
        if boundary:
            mi_selectsegment((x+x2)/2,(y+y2)/2)
            mi_setsegmentprop(boundary,spacing,0,0,0);mi_clearselected()

def rect(x1,y1,x2,y2):polygon([(x1,y1),(x2,y1),(x2,y2),(x1,y2)])

def circle(x,y,r,angle,boundary=None):
    mi_addnode(x-r,y);mi_addnode(x+r,y)
    mi_addarc(x-r,y,x+r,y,180,angle);mi_addarc(x+r,y,x-r,y,180,angle)
    if boundary:
        mi_selectarcsegment(x,y-r);mi_selectarcsegment(x,y+r)
        mi_setarcsegmentprop(angle,boundary,0,0);mi_clearselected()

def halfcircle(r,angle,boundary=None):
    mi_addnode(0,-r);mi_addnode(0,r)
    mi_addarc(0,-r,0,r,180,angle)
    if boundary:
        mi_selectarcsegment(r,0);mi_setarcsegmentprop(angle,boundary,0,0);mi_clearselected()

def start(axis,f,outer,level,uniform=0):
    newdocument(0)
    mi_probdef(f,'millimeters','axi' if axis else 'planar',1e-10,1000,30,0)
    material('Воздух')
    # Коэффициенты пространственной функции A вводятся на миллиметр геометрии.
    mi_addboundprop('Внешняя граница',0,uniform/2000 if axis else 0,0 if axis else uniform/1000,0,0,0,0,0,0)
    if axis:
        # Ось r=0, z снизу вверх: исходные координаты библиотек не используются.
        halfcircle(outer,4/(2**level),'Внешняя граница')
        mi_addsegment(0,-outer,0,outer)
    else:circle(0,0,outer,4/(2**level),'Внешняя граница')

def close_axis():
    # FEMM автоматически разбивает осевой отрезок вершинами внутренних дуг.
    pass

def coil(r,z,width,height,current,turns,mesh,num):
    name='Обмотка %d'%num
    mi_addcircprop(name,current,1)
    rect(r-width/2,z-height/2,r+width/2,z+height/2)
    label(r,z,'Медь обмотки',mesh,10+num,name,turns)
    return name

def solve(level,variant,tag=''):
    name='model-%s-%02d%s.fem'%(str(variant).replace('.','p'),level+1,tag)
    mi_saveas(directory+'/'+name);mi_close();opendocument(directory+'/'+name)
    mi_analyze(1);mi_loadsolution();mo_smooth('off')
    mo_groupselectblock();energy=real(mo_blockintegral(2));loss=real(mo_blockintegral(4));mo_clearblock()
    return {'model':name,'level':level+1,'variant':variant,'nodes':mo_numnodes(),'elements':mo_numelements(),'energy_J':energy,'ohmic_loss_W':loss,'saved_reopened_solved':True}

def finish():mo_close();mi_close()

def loop_field(r,z,turns,current,position):
    r*=0.001;dz=(position-z)*0.001
    return MU0*turns*current*r*r/(2*(r*r+dz*dz)**1.5)

def bessel(n,z):
    term=(z/2)**n
    total=term
    for k in range(1,100):
        term*=-(z*z/4)/(k*(k+n));total+=term
        if abs(term)<1e-15*max(1,abs(total)):break
    return total

def skin_resistance(radius,sigma,f):
    a=radius*.001
    if f==0:return 1/(math.pi*a*a*sigma)
    delta=math.sqrt(2/(2*math.pi*f*MU0*sigma));k=(1-1j)/delta
    return (k*bessel(0,k*a)/(2*math.pi*a*sigma*bessel(1,k*a))).real

def circuit_values(name):
    i,v,psi=mo_getcircuitproperties(name)
    return complex(i),complex(v),complex(psi)

def magnetic_b(x,y):
    mo_smooth('on')
    values=mo_getpointvalues(x,y)
    mo_smooth('off')
    return values[1],values[2]

def asinh(x):return math.log(x+math.sqrt(x*x+1))

def energy_identity(row,circuits,frequency):
    power=0;fluxenergy=0
    for name in circuits:
        i,v,psi=circuit_values(name)
        power+=(v*i.conjugate()).real/2
        fluxenergy+=(psi*i.conjugate()).real/(4 if frequency else 2)
    row['circuit_active_power_W']=power
    row['circuit_energy_J']=fluxenergy
    if frequency:
        error=abs(power-row['ohmic_loss_W'])/max(abs(power),1e-20)
        row['power_balance_relative']=error
        check('Баланс активной мощности '+row['model'],error,0.015)
    else:
        error=abs(fluxenergy-row['energy_J'])/max(abs(fluxenergy),1e-20)
        row['energy_identity_relative']=error
        check('Энергия и потокосцепление '+row['model'],error,0.012/(2**(row['level']-1)))

if MODE in ('wires','wireL','skin','proximity','busbars'):
    variants=CONFIG.get('variants',[0])
    for variant in variants:
      shapes=('solid','tube') if MODE=='busbars' else ('solid',)
      for shape in shapes:
       for level in range(3):
        f=variant if MODE in ('skin','proximity','busbars') else 0
        r=CONFIG.get('r',math.sqrt(20));d=CONFIG.get('d',30)
        if MODE=='skin':d=200
        outer=5000 if MODE=='wireL' else (1000 if MODE=='wires' else max(300,8*d))
        start(False,f,outer,level)
        if MODE in ('wires','wireL'):
            local=150 if MODE=='wires' else 750
            circle(0,0,local,4/(2**level))
            label(0,local*.7,'Воздух',(5 if MODE=='wires' else 15)/(2**level),3)
        sigma=CONFIG.get('sigma',0);material('Медь проводников',1,sigma)
        names=[]
        for side in (-1,1):
            name='Прямой проводник' if side<0 else 'Обратный проводник'
            mi_addcircprop(name,-side*CONFIG['I'],1);names.append(name)
            rr=6 if MODE=='busbars' and shape=='tube' else r
            circle(side*d/2,0,rr,4/(2**level))
            if MODE=='busbars' and shape=='tube':
                circle(side*d/2,0,4,4/(2**level));label(side*d/2,0,'Воздух',r/3/(2**level),2)
                label(side*d/2+5,0,'Медь проводников',r/4/(2**level),10,name,1)
            else:label(side*d/2,0,'Медь проводников',r/4/(2**level),10,name,1)
        label(0,outer*.6,'Воздух',outer/16/(2**level),1)
        row=solve(level,variant,'-'+shape);row['shape']=shape
        energy_identity(row,names,f)
        if MODE=='wires':
            x,y=-d/2,50;bx,by=magnetic_b(x,y);bx=real(bx);by=real(by)
            exactx=0;exacty=0
            for side in (-1,1):
                xx=x-side*d/2;ii=-side*CONFIG['I'];dist2=(xx*.001)**2+(y*.001)**2
                exactx-=MU0*ii*(y*.001)/(2*math.pi*dist2);exacty+=MU0*ii*(xx*.001)/(2*math.pi*dist2)
            row.update({'Bx_T':bx,'By_T':by,'analytic_Bx_T':exactx,'analytic_By_T':exacty})
            error=math.sqrt((bx-exactx)**2+(by-exacty)**2)/math.sqrt(exactx**2+exacty**2)
            check('Векторный закон Био — Савара '+row['model'],error,0.035/(2**level))
            row['primary']=math.sqrt(bx*bx+by*by)
        elif MODE=='wireL':
            inductance=2*row['energy_J']/CONFIG['I']**2
            exact=MU0/math.pi*(math.log(d/r)+.25)
            row.update({'L_H_per_m':inductance,'analytic_L_H_per_m':exact,'primary':inductance})
            check('Аналитическая индуктивность линии '+row['model'],abs(inductance/exact-1),0.03/(2**level))
        else:
            resistance=2*row['ohmic_loss_W']/CONFIG['I']**2
            row.update({'loop_R_ohm_per_m':resistance,'skin_only_loop_R_ohm_per_m':2*skin_resistance(r,sigma,f),'primary':resistance})
            if MODE=='skin':check('Внутреннее сопротивление по функциям Бесселя '+row['model'],abs(resistance/(2*skin_resistance(r,sigma,f))-1),0.018)
            elif MODE=='proximity':check('Потери не ниже двух изолированных проводов '+row['model'],max(0,2*skin_resistance(r,sigma,f)/resistance-1),0.015)
            else:
                dc=2/(math.pi*20e-6*sigma)
                check('AC-сопротивление не ниже DC '+row['model'],max(0,dc/resistance-1),0.01)
        records.append(row);finish()

elif MODE in ('helmholtz','maxwell','brooks','solenoid','mutual'):
    for variant in CONFIG['variants']:
      excitations=(1,2) if MODE=='mutual' else (1,)
      for excitation in excitations:
       for level in range(3):
        outer=2500 if MODE=='solenoid' else 1500
        start(True,0,outer,level);material('Медь обмотки')
        rect(0,-400,400,400)
        label(300,0,'Воздух',8/(2**level),3)
        names=[];specs=[]
        if MODE=='helmholtz':
            R=CONFIG['R'];sep=variant*R
            specs=[(R,-sep/2,2,2,CONFIG['I'],CONFIG['N']),(R,sep/2,2,2,CONFIG['I'],CONFIG['N'])]
        elif MODE=='maxwell':
            R=CONFIG['R'];rr=R*math.sqrt(4/7);zz=R*math.sqrt(3/7)*variant
            specs=[(R,0,2,2,CONFIG['I'],CONFIG['N']),(rr,-zz,2,2,CONFIG['I']*49/64,CONFIG['N']),(rr,zz,2,2,CONFIG['I']*49/64,CONFIG['N'])]
        elif MODE=='brooks':specs=[(1.5*variant,0,variant,variant,CONFIG['I'],CONFIG['N'])]
        elif MODE=='solenoid':specs=[(32.5,0,5,variant,CONFIG['I'],CONFIG['N'])]
        else:
            specs=[(50,-variant/2,4,4,1 if excitation==1 else 0,CONFIG['N']),(60,variant/2,4,4,1 if excitation==2 else 0,CONFIG['N'])]
        mesh=(variant/20 if MODE=='brooks' else 1)/(2**level)
        for num,spec in enumerate(specs,1):names.append(coil(*spec,mesh,num))
        label(outer*.5,0,'Воздух',outer/18/(2**level))
        row=solve(level,variant,'-e%d'%excitation);row['excitation']=excitation
        energy_identity(row,names,0)
        br,bz=magnetic_b(0,0);bz=real(bz);row['Bz_center_T']=bz
        if MODE in ('helmholtz','maxwell'):
            exact=sum(loop_field(r,z,n,i,0) for r,z,w,h,i,n in specs)
            row['analytic_Bz_center_T']=exact
            check('Знак и модуль осевого поля '+row['model'],abs(bz/exact-1),0.025/(2**level))
            profile=[]
            for frac in (-.3,-.2,-.1,0,.1,.2,.3):
                zz=frac*CONFIG['R'];bb=real(magnetic_b(0,zz)[1]);theory=sum(loop_field(r,z,n,i,zz) for r,z,w,h,i,n in specs)
                profile.append([zz,bb,theory]);check('Профиль поля z='+str(zz)+' '+row['model'],abs(bb/theory-1),0.035/(2**level))
            row['axis_profile_mm_T']=profile;row['uniformity_20percent']=max(abs(p[1]/bz-1) for p in profile if abs(p[0])<=.2*CONFIG['R']);row['primary']=bz
        elif MODE=='brooks':
            ll=2*row['energy_J']/CONFIG['I']**2;exact=1.6994e-6*1.5*variant*.001*CONFIG['N']**2
            row.update({'L_H':ll,'analytic_Grover_L_H':exact,'primary':ll})
            check('Формула Брукса — Гровера '+row['model'],abs(ll/exact-1),0.025)
        elif MODE=='solenoid':
            aa=variant*.001/2;exact=MU0*CONFIG['N']*CONFIG['I']/(2*.005)*(asinh(.035/aa)-asinh(.030/aa))
            ll=2*row['energy_J']/CONFIG['I']**2
            row.update({'analytic_center_T':exact,'L_H':ll,'primary':bz})
            check('Интеграл Био — Савара для конечной обмотки '+row['model'],abs(bz/exact-1),0.012)
        else:
            one=circuit_values(names[0]);two=circuit_values(names[1])
            ll=(one if excitation==1 else two)[2].real;mm=(two if excitation==1 else one)[2].real
            row.update({'L_self_H':ll,'M_H':mm,'primary':mm})
        records.append(row);finish()
    if MODE=='mutual':
        for variant in CONFIG['variants']:
            a=[r for r in records if r['variant']==variant and r['level']==3 and r['excitation']==1][0]
            b=[r for r in records if r['variant']==variant and r['level']==3 and r['excitation']==2][0]
            check('Взаимность M12=M21 при зазоре '+str(variant),abs(a['M_H']/b['M_H']-1),0.003)
            check('Положительная определённость матрицы L при зазоре '+str(variant),max(0,a['M_H']**2/(a['L_self_H']*b['L_self_H'])-1),1e-8)

elif MODE in ('cylinder','sphere','acshield'):
    for variant in CONFIG['variants']:
      for level in range(3):
        axis=MODE!='cylinder';a=CONFIG['a'];b=CONFIG['b'];mu=CONFIG.get('mu',variant);f=variant if MODE=='acshield' else 0
        sigma=CONFIG.get('sigma',0);outer=b*12
        start(axis,f,outer,level,CONFIG['B']);material('Материал экрана',mu,sigma)
        if axis:
            halfcircle(a,3/(2**level));halfcircle(b,3/(2**level))
            label((a+b)/2,0,'Материал экрана',(.5 if MODE=='acshield' else (b-a)/8)/(2**level),5)
        else:
            circle(0,0,a,3/(2**level));circle(0,0,b,3/(2**level));label((a+b)/2,0,'Материал экрана',(b-a)/6/(2**level),5)
        label(a/2,0,'Воздух',a/8/(2**level),2)
        label(b*3,0,'Воздух',outer/18/(2**level),1)
        row=solve(level,variant);bx,by=magnetic_b(0,0);bb=abs(complex(by if axis else bx))
        ratio=bb/CONFIG['B'];row.update({'B_inside_T':bb,'attenuation_ratio':ratio,'primary':ratio})
        if MODE=='cylinder':shield=((mu+1)**2-(mu-1)**2*(a/b)**2)/(4*mu)
        else:shield=((2*mu+1)*(mu+2)-2*(mu-1)**2*(a/b)**3)/(9*mu)
        row['analytic_DC_ratio']=1/shield
        if f==0:check('Аналитическое экранирование '+row['model'],abs(ratio*shield-1),0.018)
        if f>0:
            # Независимое интегрирование J^2/(2σ) по центрам элементов экрана.
            total=0
            for ei in range(1,mo_numelements()+1):
                elem=mo_getelement(ei)
                if int(elem[6])!=5:continue
                x,y,area=elem[3],elem[4],elem[5]
                values=mo_getpointvalues(x,y);jj=(complex(values[7])+complex(values[8]))*1e6
                volume=area*1e-6*(2*math.pi*x*.001 if axis else 1)
                total+=abs(jj)**2/(2*sigma)*volume
            row['element_Joule_integral_W']=total
            check('Интеграл Джоуля в экране '+row['model'],abs(total/row['ohmic_loss_W']-1),0.04)
        records.append(row);finish()
    if MODE=='acshield':
        last=[r for r in records if r['level']==3]
        for i in range(1,len(last)):
            check('Частотное усиление экранирования '+str(last[i]['variant']),max(0,last[i]['attenuation_ratio']/last[i-1]['attenuation_ratio']-1),0.01)

elif MODE in ('sensor','pipe','heating'):
    for variant in CONFIG['variants']:
      for level in range(3):
        f=variant if MODE=='heating' else CONFIG['f']
        start(True,f,500,level);material('Медь обмотки');material('Проводящая мишень',1,CONFIG['sigma'])
        if MODE=='sensor':
            name=coil(20,variant+3,4,6,CONFIG['I'],CONFIG['N'],1/(2**level),1)
            rect(0,-8,60,0);label(30,-4,'Проводящая мишень',1/(2**level),5)
        elif MODE=='heating':
            name=coil(40,10,6,8,CONFIG['I'],CONFIG['N'],1/(2**level),1)
            rect(0,-5,60,0);label(30,-2.5,'Проводящая мишень',.6/(2**level),5)
        else:
            name=coil(24,0,4,6,CONFIG['I'],CONFIG['N'],.8/(2**level),1)
            polygon([(16,-40),(20,-40),(20,-4),(20-variant,-4),(20-variant,4),(20,4),(20,40),(16,40)])
            label(18,-20,'Проводящая мишень',.8/(2**level),5)
        label(300,0,'Воздух',30/(2**level))
        row=solve(level,variant);energy_identity(row,[name],f)
        ii,vv,pp=circuit_values(name);zz=vv/ii
        row.update({'impedance_real_ohm':zz.real,'impedance_imag_ohm':zz.imag,'L_apparent_H':zz.imag/(2*math.pi*f),'primary':row['ohmic_loss_W']})
        check('Пассивность мишени '+row['model'],max(0,-zz.real),1e-10)
        check('Реактивное сопротивление катушки '+row['model'],max(0,-zz.imag),1e-10)
        records.append(row);finish()
    finest=[r for r in records if r['level']==3]
    if MODE=='sensor':
        for i in range(1,len(finest)):check('Убывание потерь с зазором '+str(finest[i]['variant']),max(0,finest[i]['ohmic_loss_W']/finest[i-1]['ohmic_loss_W']-1),0.005)
    if MODE=='pipe':
        difference=abs(finest[1]['impedance_imag_ohm']/finest[0]['impedance_imag_ohm']-1)
        check('Утонение даёт разрешимый сигнал',max(0,0.001-difference),0)
        records.append({'measurement':'thinning_signal','relative_impedance_change':difference})

# Сходимость по трём сеткам проверяется отдельно для каждого физического режима.
groups={}
for row in records:
    if 'level' not in row:continue
    key=str(row['variant'])+str(row.get('shape',''))+str(row.get('excitation',''))
    if key not in groups:groups[key]=[]
    groups[key].append(row)
for key,rows in groups.items():
    rows.sort(key=lambda row:row['level'])
    value=abs(rows[-1]['primary']/rows[-2]['primary']-1)
    check('Сходимость измеряемой величины, режим '+key,value,0.025 if MODE in ('acshield','heating','pipe','sensor','proximity','skin','busbars') else 0.012)
result={'runtime':'FEMM 5; embedded MicroPython','case_id':'maxwell-coils','records':records,'checks':checks,'passed':all(c['passed'] for c in checks),'scope':'Самостоятельная учебная 2D/осесимметричная модель; численные проверки относятся к указанным параметрам.'}
with open(directory+'/result.json','w') as stream:json.dump(result,stream)
print(json.dumps(result))
assert result['passed']

Картина рассчитанного поля

Линии магнитного потока: model-1p1-03-e1.ans
Визуализация сохранённого решения FEMM 5 model-1p1-03-e1.ans. Осесимметричная потоковая функция ψ=2πrAφ; интерполяция FEMM 5. Показана магнитостатическая картина; численной шкалы индукции здесь нет. Показан увеличенный фрагмент расчётной области. Контуры деталей взяты из той же модели. Области вне сохранённых треугольников не заполняются. Это научный график сохранённых данных. Нажмите на карту, чтобы открыть её отдельно и увеличить.

Окна FEMM 5

Снимки интерфейса FEMM показывают геометрию, настройки и работу с результатами в FEMM 5. Откройте изображение, чтобы рассмотреть подписи и значения в полном размере.

Меридиональный разрез трёхкатушечной системы Максвелла: ось вращения слева, сечения центральной и двух крайних обмоток справа. Исследуемый вариант коэффициента осевого расстояния 1,1; удалённая граница за кадром.
Меридиональный разрез трёхкатушечной системы Максвелла: ось вращения слева, сечения центральной и двух крайних обмоток справа. Исследуемый вариант коэффициента осевого расстояния 1,1; удалённая граница за кадром. Открыть в полном размере
Сохранённое решение «Катушки Максвелла и размер однородной области». Модуль магнитной индукции |B|, Тл, и линии статического поля трёхкатушечной системы Максвелла. Показан исследуемый вариант коэффициента осевого расстояния 1,1; рабочая область.
Сохранённое решение «Катушки Максвелла и размер однородной области». Модуль магнитной индукции |B|, Тл, и линии статического поля трёхкатушечной системы Максвелла. Показан исследуемый вариант коэффициента осевого расстояния 1,1; рабочая область. Открыть в полном размере

Результаты и численные проверки

Сохранено решений FEMM: 9. Выполнено проверок: 84. Полная точность чисел и условия сравнения доступны в таблицах результатов JSON.

Результаты расчётов и производные итоги
Индукция в центре Bz, ТлКоэффициент осевого смещенияФайл моделиСохранение, открытие и решениеОсевой профиль: z, поле FEMM и аналитикаЧисло узловОтносительная неоднородность на ±0,2RЭнергия по потокосцеплениям, ДжУровень сеткиСредние джоулевы потери, ВтНеоднородность в интервале ±0,2RАктивная мощность цепей, ВтЧисло элементовНомер возбуждённой катушкиОтносительная ошибка энергетического равенстваЭнергия поля, ДжИндукция тонких колец в центре, Тл
0,00125228480,9model-0p9-01-e1.femДа7 точек; полные данные JSON92620,0022748830,0061993171100,0012522848018183131,463143 × 10⁻⁶0,00619912210,0012527985
0,00125234610,9model-0p9-02-e1.femДа7 точек; полные данные JSON272800,00190373820,0064890131200,0012523461054112142,43374 × 10⁻⁶0,00648928850,0012527985
0,0012524220,9model-0p9-03-e1.femДа7 точек; полные данные JSON1043740,00213782330,0065649822300,00125242202079801804,20935 × 10⁻⁹0,00656498750,0012527985
0,00117722121model-1-01-e1.femДа7 точек; полные данные JSON9276398,23728 × 10⁻⁶0,0060751469100,0011772212018207156,953838 × 10⁻⁶0,00607480090,0011780972
0,00117761881model-1-02-e1.femДа7 точек; полные данные JSON27266174,75902 × 10⁻⁶0,0063628067200,0011776188054088158,483321 × 10⁻⁶0,00636317890,0011780972
0,00117771581model-1-03-e1.femДа7 точек; полные данные JSON104413164,30013 × 10⁻⁶0,0064399486300,0011777158020805812,2455731 × 10⁻⁶0,00643996310,0011780972
0,00111044911,1model-1p1-01-e1.femДа7 точек; полные данные JSON9279178,85837 × 10⁻⁶0,0059663952100,0011104491018213195,049351 × 10⁻⁶0,00596696230,0011114309
0,00111101821,1model-1p1-02-e1.femДа7 точек; полные данные JSON27237329,97166 × 10⁻⁶0,0062559268200,0011110182054029140,369655 × 10⁻⁶0,00625617930,0011114309
0,00111106271,1model-1p1-03-e1.femДа7 точек; полные данные JSON104510355,54944 × 10⁻⁶0,0063331296300,0011110627020825014,7553615 × 10⁻⁶0,00633309950,0011114309
Проверки опубликованного расчёта
КритерийПолученоДопуск или ожидаемое значениеИтог
Энергия и потокосцепление model-0p9-01-e1.fem31,46 × 10⁻⁶0,012Выполнен
Знак и модуль осевого поля model-0p9-01-e1.fem410,1 × 10⁻⁶0,025Выполнен
Профиль поля z=-30.0 model-0p9-01-e1.fem0,0016490,035Выполнен
Профиль поля z=-20.0 model-0p9-01-e1.fem684,7 × 10⁻⁶0,035Выполнен
Профиль поля z=-10.0 model-0p9-01-e1.fem528,5 × 10⁻⁶0,035Выполнен
Профиль поля z=0 model-0p9-01-e1.fem410,1 × 10⁻⁶0,035Выполнен
Профиль поля z=10.0 model-0p9-01-e1.fem550 × 10⁻⁶0,035Выполнен
Профиль поля z=20.0 model-0p9-01-e1.fem652,6 × 10⁻⁶0,035Выполнен
Профиль поля z=30.0 model-0p9-01-e1.fem0,0010470,035Выполнен
Энергия и потокосцепление model-0p9-02-e1.fem42,43 × 10⁻⁶0,006Выполнен
Знак и модуль осевого поля model-0p9-02-e1.fem361,1 × 10⁻⁶0,0125Выполнен
Профиль поля z=-30.0 model-0p9-02-e1.fem713,9 × 10⁻⁶0,0175Выполнен
Профиль поля z=-20.0 model-0p9-02-e1.fem135,7 × 10⁻⁶0,0175Выполнен
Профиль поля z=-10.0 model-0p9-02-e1.fem535,6 × 10⁻⁶0,0175Выполнен
Профиль поля z=0 model-0p9-02-e1.fem361,1 × 10⁻⁶0,0175Выполнен
Профиль поля z=10.0 model-0p9-02-e1.fem361,6 × 10⁻⁶0,0175Выполнен
Профиль поля z=20.0 model-0p9-02-e1.fem264 × 10⁻⁶0,0175Выполнен
Профиль поля z=30.0 model-0p9-02-e1.fem377,1 × 10⁻⁶0,0175Выполнен
Энергия и потокосцепление model-0p9-03-e1.fem804,2 × 10⁻⁹0,003Выполнен
Знак и модуль осевого поля model-0p9-03-e1.fem300,5 × 10⁻⁶0,00625Выполнен
Профиль поля z=-30.0 model-0p9-03-e1.fem840,2 × 10⁻⁶0,00875Выполнен
Профиль поля z=-20.0 model-0p9-03-e1.fem438 × 10⁻⁶0,00875Выполнен
Профиль поля z=-10.0 model-0p9-03-e1.fem341,3 × 10⁻⁶0,00875Выполнен
Профиль поля z=0 model-0p9-03-e1.fem300,5 × 10⁻⁶0,00875Выполнен
Профиль поля z=10.0 model-0p9-03-e1.fem275,6 × 10⁻⁶0,00875Выполнен
Профиль поля z=20.0 model-0p9-03-e1.fem295,4 × 10⁻⁶0,00875Выполнен
Профиль поля z=30.0 model-0p9-03-e1.fem996,2 × 10⁻⁶0,00875Выполнен
Энергия и потокосцепление model-1-01-e1.fem56,95 × 10⁻⁶0,012Выполнен
Знак и модуль осевого поля model-1-01-e1.fem743,6 × 10⁻⁶0,025Выполнен
Профиль поля z=-30.0 model-1-01-e1.fem0,0022540,035Выполнен
Профиль поля z=-20.0 model-1-01-e1.fem937,7 × 10⁻⁶0,035Выполнен
Профиль поля z=-10.0 model-1-01-e1.fem809,9 × 10⁻⁶0,035Выполнен
Профиль поля z=0 model-1-01-e1.fem743,6 × 10⁻⁶0,035Выполнен
Профиль поля z=10.0 model-1-01-e1.fem751,3 × 10⁻⁶0,035Выполнен
Профиль поля z=20.0 model-1-01-e1.fem0,0010180,035Выполнен
Профиль поля z=30.0 model-1-01-e1.fem384,4 × 10⁻⁶0,035Выполнен
Энергия и потокосцепление model-1-02-e1.fem58,48 × 10⁻⁶0,006Выполнен
Знак и модуль осевого поля model-1-02-e1.fem406,1 × 10⁻⁶0,0125Выполнен
Профиль поля z=-30.0 model-1-02-e1.fem485 × 10⁻⁶0,0175Выполнен
Профиль поля z=-20.0 model-1-02-e1.fem420,1 × 10⁻⁶0,0175Выполнен
Профиль поля z=-10.0 model-1-02-e1.fem413,6 × 10⁻⁶0,0175Выполнен
Профиль поля z=0 model-1-02-e1.fem406,1 × 10⁻⁶0,0175Выполнен
Профиль поля z=10.0 model-1-02-e1.fem408,5 × 10⁻⁶0,0175Выполнен
Профиль поля z=20.0 model-1-02-e1.fem457,4 × 10⁻⁶0,0175Выполнен
Профиль поля z=30.0 model-1-02-e1.fem799,2 × 10⁻⁶0,0175Выполнен
Энергия и потокосцепление model-1-03-e1.fem2,246 × 10⁻⁶0,003Выполнен
Знак и модуль осевого поля model-1-03-e1.fem323,8 × 10⁻⁶0,00625Выполнен
Профиль поля z=-30.0 model-1-03-e1.fem333 × 10⁻⁶0,00875Выполнен
Профиль поля z=-20.0 model-1-03-e1.fem364,6 × 10⁻⁶0,00875Выполнен
Профиль поля z=-10.0 model-1-03-e1.fem324,1 × 10⁻⁶0,00875Выполнен
Профиль поля z=0 model-1-03-e1.fem323,8 × 10⁻⁶0,00875Выполнен
Профиль поля z=10.0 model-1-03-e1.fem327,3 × 10⁻⁶0,00875Выполнен
Профиль поля z=20.0 model-1-03-e1.fem340,4 × 10⁻⁶0,00875Выполнен
Профиль поля z=30.0 model-1-03-e1.fem425,7 × 10⁻⁶0,00875Выполнен
Энергия и потокосцепление model-1p1-01-e1.fem95,05 × 10⁻⁶0,012Выполнен
Знак и модуль осевого поля model-1p1-01-e1.fem883,4 × 10⁻⁶0,025Выполнен
Профиль поля z=-30.0 model-1p1-01-e1.fem729,9 × 10⁻⁶0,035Выполнен
Профиль поля z=-20.0 model-1p1-01-e1.fem697 × 10⁻⁶0,035Выполнен
Профиль поля z=-10.0 model-1p1-01-e1.fem799,8 × 10⁻⁶0,035Выполнен
Профиль поля z=0 model-1p1-01-e1.fem883,4 × 10⁻⁶0,035Выполнен
Профиль поля z=10.0 model-1p1-01-e1.fem820,4 × 10⁻⁶0,035Выполнен
Профиль поля z=20.0 model-1p1-01-e1.fem666,2 × 10⁻⁶0,035Выполнен
Профиль поля z=30.0 model-1p1-01-e1.fem858 × 10⁻⁶0,035Выполнен
Энергия и потокосцепление model-1p1-02-e1.fem40,37 × 10⁻⁶0,006Выполнен
Знак и модуль осевого поля model-1p1-02-e1.fem371,3 × 10⁻⁶0,0125Выполнен
Профиль поля z=-30.0 model-1p1-02-e1.fem390,2 × 10⁻⁶0,0175Выполнен
Профиль поля z=-20.0 model-1p1-02-e1.fem334 × 10⁻⁶0,0175Выполнен
Профиль поля z=-10.0 model-1p1-02-e1.fem367,8 × 10⁻⁶0,0175Выполнен
Профиль поля z=0 model-1p1-02-e1.fem371,3 × 10⁻⁶0,0175Выполнен
Профиль поля z=10.0 model-1p1-02-e1.fem344,4 × 10⁻⁶0,0175Выполнен
Профиль поля z=20.0 model-1p1-02-e1.fem336 × 10⁻⁶0,0175Выполнен
Профиль поля z=30.0 model-1p1-02-e1.fem358,7 × 10⁻⁶0,0175Выполнен
Энергия и потокосцепление model-1p1-03-e1.fem4,755 × 10⁻⁶0,003Выполнен
Знак и модуль осевого поля model-1p1-03-e1.fem331,3 × 10⁻⁶0,00625Выполнен
Профиль поля z=-30.0 model-1p1-03-e1.fem353,7 × 10⁻⁶0,00875Выполнен
Профиль поля z=-20.0 model-1p1-03-e1.fem320,2 × 10⁻⁶0,00875Выполнен
Профиль поля z=-10.0 model-1p1-03-e1.fem343,5 × 10⁻⁶0,00875Выполнен
Профиль поля z=0 model-1p1-03-e1.fem331,3 × 10⁻⁶0,00875Выполнен
Профиль поля z=10.0 model-1p1-03-e1.fem331,3 × 10⁻⁶0,00875Выполнен
Профиль поля z=20.0 model-1p1-03-e1.fem321,5 × 10⁻⁶0,00875Выполнен
Профиль поля z=30.0 model-1p1-03-e1.fem335,8 × 10⁻⁶0,00875Выполнен
Сходимость измеряемой величины, режим 1182,32 × 10⁻⁶0,012Выполнен
Сходимость измеряемой величины, режим 1.1140,06 × 10⁻⁶0,012Выполнен
Сходимость измеряемой величины, режим 0.9160,58 × 10⁻⁶0,012Выполнен

Допуски относятся к указанной учебной задаче и способу сравнения. Число показанных цифр не означает такой же физической точности.

Модели, решения и программа

Для нового расчёта сохраните программу, модели и необходимые данные в одну рабочую папку, сохраняя структуру подпапок.

Полные численные результаты

Границы применимости