FEMM 5

Электростатика · Осесимметричная

Закруглённая игла над плоскостью: поле в малом промежутке

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

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

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

Принятые допущения и их назначение
Учебная модель FEMM 5Причина
Конечное полусферическое скруглениеГеометрическая концентрация поля отделена от особенности острой иглы.
Заземлённые нижняя плоскость и удалённая оболочкаЗадаётся конкретная замкнутая область, а не неявная бесконечность.
Отдельная мелкая воздушная зонаЛокальный градиент проверяется независимо от общей сетки.

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

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

Почему радиус конца необходимо задавать

Полусфера радиуса 1 мм плавно соединяется с цилиндром того же радиуса. Нижняя точка иглы находится в 2 мм над плоскостью. Такое описание задаёт конечную кривизну и исключает нефизическое утверждение о конечном максимуме у математически острой иглы.

Решается уравнение Лапласа для потенциала. Высокая кривизна конца концентрирует заряд, поэтому локальное E может сильно отличаться от среднего U/зазор.

\nabla\cdot(\varepsilon_0\nabla V)=0,\qquad \mathbf E=-\nabla V,\qquad C=q/U

Отдельный контроль интеграла и градиента

Для трёх сеток уточняется малая воздушная область около иглы и зазора. Локальное восстановленное поле читается в точке r=0,05 мм, z=1,8 мм; она находится в воздухе около вершины, а не в проводнике. Сходимость этой пробы проверяется отдельно от ёмкости.

Четвёртый расчёт удваивает напряжение при той же сетке. В линейной модели C сохраняется, E удваивается, W растёт в четыре раза. Энергия сверяется с зарядом проводника во всех состояниях.

E(2U)=2E(U),\qquad W(2U)=4W(U)

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

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

Величины, единицы и происхождение параметров
ПараметрЗначениеЕдиницаПроисхождение
Радиус цилиндра и полусферы1ммУсловие учебной задачи
Координаты цилиндрической части по z3…13ммУсловие учебной задачи
Зазор до нижней плоскости2ммУсловие учебной задачи
Размер внешней области (r,z)30 × 40ммУсловие учебной задачи
Напряжения контроля100; 200ВУсловие учебной задачи
Точка пробы (r,z)0,05; 1,8ммУсловие учебной задачи

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

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

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

Программа встроенного Python FEMM 5
Python · reproduce.py
"""Закруглённая игла над заземлённой плоскостью.
Среда: встроенный MicroPython FEMM 5; команды FEMM доступны глобально.
Геометрические размеры: миллиметры; поля и интегралы возвращаются в СИ.
Все материалы и проводники имеют русские имена. Каждая модель сохраняется,
закрывается и повторно открывается до нового расчёта, включая кириллицу.
Запуск создаёт новую папку calculated-NN рядом с программой; опубликованные
модели и предыдущие расчёты не перезаписываются. Все необходимые
исходные данные включены. Условия задачи и ограничения описаны в README.md.
"""
import os
import sys
import math
import json

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 = []
EPS0 = 8.85418781762e-12


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


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


def label(x, y, material, mesh, group=1):
    ei_addblocklabel(x, y)
    ei_selectlabel(x, y)
    ei_setblockprop(material, 0, mesh, group)
    ei_clearselected()


def circle(x, radius, conductor, angle):
    ei_addnode(x - radius, 0)
    ei_addnode(x + radius, 0)
    ei_addarc(x - radius, 0, x + radius, 0, 180, angle)
    ei_addarc(x + radius, 0, x - radius, 0, 180, angle)
    ei_selectarcsegment(x, radius)
    ei_selectarcsegment(x, -radius)
    ei_setarcsegmentprop(angle, '<None>', 0, 0, conductor)
    ei_clearselected()


def solve(model):
    ei_saveas(model)
    ei_close()
    opendocument(model)
    ei_analyze(1)
    ei_loadsolution()
    eo_smooth('off')


def electric_result(mesh, model, input_name, output_name, exact_C):
    voltage_in, charge_in = eo_getconductorproperties(input_name)
    voltage_out, charge_out = eo_getconductorproperties(output_name)
    voltage = real(voltage_in) - real(voltage_out)
    charge = real(charge_in)
    eo_groupselectblock(1)
    energy = real(eo_blockintegral(0))
    eo_clearblock()
    capacitance = charge / voltage
    energy_C = 2 * energy / voltage ** 2
    row = {'mesh_mm': mesh, 'model': os.path.basename(model),
           'nodes': eo_numnodes(), 'elements': eo_numelements(),
           'voltage_V': voltage, 'charge_C': charge, 'energy_J': energy,
           'capacitance_F': capacitance, 'energy_capacitance_F': energy_C,
           'analytic_capacitance_F': exact_C,
           'analytic_C_relative_error': abs(capacitance / exact_C - 1),
           'energy_charge_relative_error': abs(energy_C / capacitance - 1)}
    records.append(row)
    check('Энергия и заряд: ' + os.path.basename(model),
          row['energy_charge_relative_error'], 1e-5)
    return row


def circle_xy(cx, cy, radius, conductor, angle):
    ei_addnode(cx - radius, cy)
    ei_addnode(cx + radius, cy)
    ei_addarc(cx - radius, cy, cx + radius, cy, 180, angle)
    ei_addarc(cx + radius, cy, cx - radius, cy, 180, angle)
    ei_selectarcsegment(cx, cy + radius)
    ei_selectarcsegment(cx, cy - radius)
    ei_setarcsegmentprop(angle, '<None>', 0, 0, conductor)
    ei_clearselected()


def polygon(points, conductor='<None>', mesh=0):
    for x, y in points:
        ei_addnode(x, y)
    for k, (x, y) in enumerate(points):
        x2, y2 = points[(k + 1) % len(points)]
        ei_addsegment(x, y, x2, y2)
        if conductor != '<None>':
            ei_selectsegment((x + x2) / 2, (y + y2) / 2)
            ei_setsegmentprop('<None>', mesh, 0, 0, 0, conductor)
            ei_clearselected()


def terminal(x, y, name, mesh):
    ei_selectsegment(x, y)
    ei_setsegmentprop('<None>', mesh, 0, 0, 0, name)
    ei_clearselected()


def summary(mesh, model, source, ground, exact_C=None):
    v1, q1 = eo_getconductorproperties(source)
    v0, q0 = eo_getconductorproperties(ground)
    v1, v0, q1, q0 = real(v1), real(v0), real(q1), real(q0)
    voltage = v1 - v0
    eo_groupselectblock(1)
    energy = real(eo_blockintegral(0))
    eo_clearblock()
    capacitance = q1 / voltage
    row = {'mesh_mm': mesh, 'model': os.path.basename(model),
           'nodes': eo_numnodes(), 'elements': eo_numelements(),
           'voltage_V': voltage, 'charge_C': q1, 'energy_J': energy,
           'capacitance_F': capacitance,
           'energy_capacitance_F': 2 * energy / voltage ** 2}
    if exact_C is not None:
        row['analytic_capacitance_F'] = exact_C
        row['analytic_C_relative_error'] = abs(capacitance / exact_C - 1)
    records.append(row)
    check('Энергия и терминальный заряд: ' + os.path.basename(model),
          abs(2 * energy / voltage ** 2 / capacitance - 1), 1e-5)
    return row


def field(x, y):
    values = eo_getpointvalues(x, y)
    return math.sqrt(real(values[3]) ** 2 + real(values[4]) ** 2)


def rectangle_field(mesh, filename, epsx=2, epsy=2, voltage=100, width=10, height=10, depth=100):
    newdocument(1)
    ei_probdef('millimeters', 'planar', 1e-10, depth, 30)
    ei_addmaterial('Диэлектрик учебного образца', epsx, epsy, 0)
    ei_addconductorprop('Питающий электрод', voltage, 0, 1)
    ei_addconductorprop('Заземлённый электрод', 0, 0, 1)
    polygon(((0, 0), (width, 0), (width, height), (0, height)))
    terminal(0, height / 2, 'Питающий электрод', mesh)
    terminal(width, height / 2, 'Заземлённый электрод', mesh)
    label(width / 2, height / 2, 'Диэлектрик учебного образца', mesh)
    model = directory + '/' + filename + '.fee'
    solve(model)
    return model


for level, mesh in enumerate((1.2, 0.6, 0.3, 0.3)):
    voltage = 100 if level < 3 else 200
    local_mesh = mesh / 6
    newdocument(1)
    ei_probdef('millimeters', 'axi', 1e-10, 1, 30)
    ei_addmaterial('Воздух промежутка игла-плоскость', 1, 1, 0)
    ei_addconductorprop('Закруглённая игла', voltage, 0, 1)
    ei_addconductorprop('Земля и удалённая граница', 0, 0, 1)
    polygon(((0, 0), (30, 0), (30, 40), (0, 40)))
    for x, y in ((15, 0), (30, 20), (15, 40)):
        terminal(x, y, 'Земля и удалённая граница', mesh)
    # Нижний конец цилиндрической иглы замыкается полусферой радиуса 1 мм.
    ei_addnode(0, 2)
    ei_addnode(1, 3)
    ei_addnode(1, 13)
    ei_addnode(0, 13)
    angle = 4 / (2 ** min(level, 2))
    ei_addarc(0, 2, 1, 3, 90, angle)
    p = 1 / math.sqrt(2)
    ei_selectarcsegment(p, 3 - p)
    ei_setarcsegmentprop(angle, '<None>', 0, 0, 'Закруглённая игла')
    ei_clearselected()
    ei_addsegment(1, 3, 1, 13)
    ei_addsegment(1, 13, 0, 13)
    ei_addsegment(0, 13, 0, 2)
    terminal(1, 8, 'Закруглённая игла', local_mesh)
    terminal(0.5, 13, 'Закруглённая игла', local_mesh)
    label(0.5, 5, '<No Mesh>', local_mesh, 0)
    # Уточняем весь промежуток и окружающий воздух независимо от дальней зоны.
    ei_addnode(6, 0)
    ei_addnode(6, 18)
    ei_addnode(0, 18)
    ei_addsegment(6, 0, 6, 18)
    ei_addsegment(6, 18, 0, 18)
    label(3, 5, 'Воздух промежутка игла-плоскость', local_mesh)
    label(12, 20, 'Воздух промежутка игла-плоскость', mesh)
    model = directory + '/needle-%02d.fee' % (level + 1)
    solve(model)
    row = summary(mesh, model, 'Закруглённая игла', 'Земля и удалённая граница')
    eo_smooth('on')
    row['E_tip_sample_V_m'] = field(0.05, 1.8)
    row['local_mesh_mm'] = local_mesh
    eo_close()
    ei_close()
check('Сходимость ёмкости иглы', abs(records[2]['capacitance_F'] / records[1]['capacitance_F'] - 1), 0.01)
check('Сходимость восстановленного поля около конца иглы', abs(records[2]['E_tip_sample_V_m'] / records[1]['E_tip_sample_V_m'] - 1), 0.05)
check('Масштабирование ёмкости при удвоении U', abs(records[3]['capacitance_F'] / records[2]['capacitance_F'] - 1), 1e-5)
check('Масштабирование поля при удвоении U', abs(records[3]['E_tip_sample_V_m'] / records[2]['E_tip_sample_V_m'] / 2 - 1), 1e-5)

columns = {
    'mesh_mm': 'Размер сетки, мм', 'model': 'Файл модели',
    'nodes': 'Узлов', 'elements': 'Элементов',
    'voltage_V': 'Разность потенциалов, В', 'charge_C': 'Заряд, Кл',
    'energy_J': 'Энергия, Дж', 'capacitance_F': 'Ёмкость по заряду, Ф',
    'energy_capacitance_F': 'Ёмкость по энергии, Ф',
    'analytic_capacitance_F': 'Аналитическая ёмкость, Ф',
    'analytic_C_relative_error': 'Относительная ошибка ёмкости',
    'energy_charge_relative_error': 'Невязка энергии и заряда',
    'E_7p5mm_V_m': 'Поле при r=7,5 мм, В/м',
    'analytic_E_7p5mm_V_m': 'Аналитическое поле при r=7,5 мм, В/м',
    'E_150mm_V_m': 'Поле при r=150 мм, В/м',
    'analytic_E_150mm_V_m': 'Аналитическое поле при r=150 мм, В/м',
    'outer_radius_mm': 'Радиус внешней границы, мм',
    'insulation': 'Изоляция', 'analytic_Emax_kV_mm': 'Аналитический максимум поля, кВ/мм',
    'Emax_from_charge_kV_mm': 'Максимум поля по заряду, кВ/мм',
    'E_10mm_kV_mm': 'Поле при r=10 мм, кВ/мм',
    'E_25mm_kV_mm': 'Поле при r=25 мм, кВ/мм',
    'conductivity_S_m': 'Эквивалентная проводимость, См/м',
    'I_real_A': 'Активная компонента амплитуды тока, А',
    'I_imag_A': 'Квадратурная компонента амплитуды тока, А',
    'analytic_I_real_A': 'Аналитическая активная компонента, А',
    'analytic_I_imag_A': 'Аналитическая квадратурная компонента, А',
    'losses_W': 'Диэлектрические потери, Вт',
    'analytic_losses_W': 'Аналитические потери, Вт',
    'terminal_power_W': 'Средняя мощность электрода, Вт',
    'apparent_power_VA': 'Полная мощность, ВА',
    'U_RMS_V': 'Действующее напряжение, В', 'U_amplitude_V': 'Амплитуда напряжения, В'
}
columns.update({'E_tip_sample_V_m': 'Поле около закруглённого конца, В/м', 'local_mesh_mm': 'Сетка около иглы, мм', 'substrate_epsr': 'Проницаемость подложки', 'effective_epsr': 'Эффективная проницаемость', 'Z0_ohm': 'Квази-ТЕМ сопротивление, Ом', 'liquid_height_mm': 'Уровень жидкости, мм', 'offset_mm': 'Эксцентриситет, мм'})
result = {'runtime': 'FEMM 5.0; встроенный MicroPython', 'records': records,
          'checks': checks, 'columns': columns,
          'passed': all(item['passed'] for item in checks)}
with open(directory + '/result.json', 'w') as output:
    json.dump(result, output)
print(json.dumps(result))
assert result['passed'], 'Не выполнен численный критерий'

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

Потенциал, В: needle-04.res
Визуализация сохранённого решения FEMM 5 needle-04.res. Электрический потенциал по сохранённым узловым значениям. Показан увеличенный фрагмент расчётной области. Контуры деталей взяты из той же модели. Области вне сохранённых треугольников не заполняются. Это научный график сохранённых данных. Нажмите на карту, чтобы открыть её отдельно и увеличить.

Окна FEMM 5

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

Рабочая область осесимметричной модели «игла — плоскость»: скруглённое острие, воздушный промежуток и заземлённая плоскость. Удалённые границы за кадром.
Рабочая область осесимметричной модели «игла — плоскость»: скруглённое острие, воздушный промежуток и заземлённая плоскость. Удалённые границы за кадром. Открыть в полном размере
Сохранённое решение «Закруглённая игла над плоскостью: поле в малом промежутке». Потенциал V, В, и эквипотенциали в увеличенной рабочей области осесимметричной модели «игла — плоскость».
Сохранённое решение «Закруглённая игла над плоскостью: поле в малом промежутке». Потенциал V, В, и эквипотенциали в увеличенной рабочей области осесимметричной модели «игла — плоскость». Открыть в полном размере

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

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

Результаты расчётов и производные итоги
Размер сетки, ммРазность потенциалов, ВЗаряд, КлЭлементовПоле около закруглённого конца, В/мФайл моделиЁмкость по энергии, ФЁмкость по заряду, ФСетка около иглы, ммЭнергия, ДжУзлов
1,210041,12 × 10⁻¹²1206480680needle-01.fee411,2 × 10⁻¹⁵411,2 × 10⁻¹⁵0,22,056 × 10⁻⁹6202
0,610040,88 × 10⁻¹²2349583250needle-02.fee408,8 × 10⁻¹⁵408,8 × 10⁻¹⁵0,12,044 × 10⁻⁹11994
0,310040,86 × 10⁻¹²8726085100needle-03.fee408,6 × 10⁻¹⁵408,6 × 10⁻¹⁵0,052,043 × 10⁻⁹44100
0,320081,72 × 10⁻¹²87260170200needle-04.fee408,6 × 10⁻¹⁵408,6 × 10⁻¹⁵0,058,172 × 10⁻⁹44100
Проверки опубликованного расчёта
КритерийПолученоДопуск или ожидаемое значениеИтог
Энергия и терминальный заряд: needle-01.fee17,43 × 10⁻¹²1e-05Выполнен
Энергия и терминальный заряд: needle-02.fee102,8 × 10⁻¹²1e-05Выполнен
Энергия и терминальный заряд: needle-03.fee130,5 × 10⁻¹²1e-05Выполнен
Энергия и терминальный заряд: needle-04.fee130,5 × 10⁻¹²1e-05Выполнен
Сходимость ёмкости иглы494,5 × 10⁻⁶0,01Выполнен
Сходимость восстановленного поля около конца иглы0,022190,05Выполнен
Масштабирование ёмкости при удвоении U01e-05Выполнен
Масштабирование поля при удвоении U01e-05Выполнен

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

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

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

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

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