FEMM 5

Электростатика · Плоскопараллельная

Микрополосковая линия: два скалярных поля и квази-ТЕМ оценка

Вычислите ёмкость полоскового проводника над диэлектрической подложкой и повторите тот же расчёт с воздухом. Из двух скалярных решений получите эффективную проницаемость и квази-ТЕМ оценку волнового сопротивления.

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

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

Принятые допущения и их назначение
Учебная модель FEMM 5Причина
Две геометрически одинаковые серии: εr=1 и εr=4Воздушный эталон нужен для определения L′ и эффективной проницаемости.
Нулевой толщины электрод расположен прямо на интерфейсеСгущается поле у обеих кромок полоски.
Конечная удалённая оболочка включена в определение моделиГеометрический ответ не выдаётся за точное открытое пространство.

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

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

Зачем нужен воздушный эталон

Пусть C′ — ёмкость на единицу длины с подложкой, C₀′ — ёмкость той же геометрии с εr=1. Для немагнитной среды квазистатическое приближение даёт εeff=C′/C₀′ и L′=1/(c²C₀′). Отсюда находятся скорость и сопротивление линии.

\varepsilon_{\mathrm{eff}}=C^\prime/C_0^\prime,\quad v\approx c\sqrt{C_0^\prime/C^\prime},\quad Z_0\approx\frac{1}{c\sqrt{C^\prime C_0^\prime}}

Граница применимости квази-ТЕМ результата

Проводник нулевой толщины расположен на границе подложки εr=4 и воздуха. Земля задана внизу, удалённая оболочка — по бокам и сверху. На каждом из трёх уровней сетки выполняются оба поля, всего шесть решений.

Контролируются энергия и заряд, сеточная устойчивость C и Z₀, физические границы 1≤εeff≤4 и приближённая инженерная формула открытой микрополосковой линии. Допуск инженерного ориентира 8% относится к этому сравнению и не является универсальной точностью FEMM.

FEMM здесь не решает распространение электромагнитной волны. Полученное Z₀ — результат квазистатической постобработки в условиях, когда поперечные размеры малы относительно длины волны; дисперсия, излучение и потери отсутствуют.

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

Плоскопараллельная

Величины, единицы и происхождение параметров
ПараметрЗначениеЕдиницаПроисхождение
Ширина полоски4ммУсловие учебной задачи
Толщина подложки2ммУсловие учебной задачи
Проницаемость подложки41Условие учебной задачи
Длина участка1мУсловие учебной задачи
Ширина и высота области40; 20ммУсловие учебной задачи
Напряжение полоски1ВУсловие учебной задачи

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

  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


C0 = []
for level, mesh in enumerate((0.8, 0.4, 0.2)):
    for eps in (1, 4):
        newdocument(1)
        ei_probdef('millimeters', 'planar', 1e-10, 1000, 30)
        ei_addmaterial('Подложка линии', eps, eps, 0)
        ei_addmaterial('Воздух над линией', 1, 1, 0)
        ei_addconductorprop('Полосковый проводник', 1, 0, 1)
        ei_addconductorprop('Земля и удалённый экран', 0, 0, 1)
        polygon(((-20, 0), (20, 0), (20, 2), (20, 20), (-20, 20), (-20, 2)), 'Земля и удалённый экран', mesh)
        for x in (-2, 2):
            ei_addnode(x, 2)
        ei_addsegment(-20, 2, -2, 2)
        ei_addsegment(-2, 2, 2, 2)
        ei_addsegment(2, 2, 20, 2)
        terminal(0, 2, 'Полосковый проводник', mesh / 6)
        label(0, 1, 'Подложка линии', mesh / 2)
        label(0, 5, 'Воздух над линией', mesh)
        model = directory + '/microstrip-%02d-eps%d.fee' % (level + 1, eps)
        solve(model)
        row = summary(mesh, model, 'Полосковый проводник', 'Земля и удалённый экран')
        row['substrate_epsr'] = eps
        if eps == 1:
            C0.append(row['capacitance_F'])
        else:
            effective = row['capacitance_F'] / C0[level]
            impedance = 1 / (299792458 * math.sqrt(row['capacitance_F'] * C0[level]))
            row['effective_epsr'] = effective
            row['Z0_ohm'] = impedance
            check('Границы эффективной проницаемости 1≤εeff≤4', max(0, 1 - effective, effective - 4), 0)
        eo_close()
        ei_close()
check('Сходимость ёмкости микрополосковой линии', abs(records[5]['capacitance_F'] / records[3]['capacitance_F'] - 1), 0.01)
check('Сходимость квази-ТЕМ сопротивления', abs(records[5]['Z0_ohm'] / records[3]['Z0_ohm'] - 1), 0.01)
approx_eps = 2.5 + 1.5 / math.sqrt(1 + 12 / 2)
approx_Z = 120 * math.pi / (math.sqrt(approx_eps) * (2 + 1.393 + 0.667 * math.log(2 + 1.444)))
check('Инженерная формула Z0: ориентир для открытой микрополосковой линии', abs(records[5]['Z0_ohm'] / approx_Z - 1), 0.08)

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'], 'Не выполнен численный критерий'

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

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

Окна FEMM 5

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

Рабочая область модели «Микрополосковая линия: два скалярных поля и квази-ТЕМ оценка». Нативный препроцессор FEMM 5.
Рабочая область модели «Микрополосковая линия: два скалярных поля и квази-ТЕМ оценка». Нативный препроцессор FEMM 5. Открыть в полном размере
Сохранённое решение «Микрополосковая линия: два скалярных поля и квази-ТЕМ оценка». Электростатический потенциал V, В, в воздухе и подложке микрополосковой линии; поперечная модель для квазистатического приближения.
Сохранённое решение «Микрополосковая линия: два скалярных поля и квази-ТЕМ оценка». Электростатический потенциал V, В, в воздухе и подложке микрополосковой линии; поперечная модель для квазистатического приближения. Открыть в полном размере

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

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

Результаты расчётов и производные итоги
Разность потенциалов, ВРазмер сетки, ммЁмкость по заряду, ФЭнергия, ДжУзловЗаряд, КлЭлементовПроницаемость подложкиФайл моделиЁмкость по энергии, ФКвази-ТЕМ сопротивление, ОмЭффективная проницаемость
10,838,39 × 10⁻¹²19,19 × 10⁻¹²437538,39 × 10⁻¹²84651microstrip-01-eps1.fee38,39 × 10⁻¹²——
10,8117 × 10⁻¹²58,51 × 10⁻¹²4375117 × 10⁻¹²84654microstrip-01-eps4.fee117 × 10⁻¹²49,773,048
10,438,21 × 10⁻¹²19,1 × 10⁻¹²866938,21 × 10⁻¹²168461microstrip-02-eps1.fee38,21 × 10⁻¹²——
10,4116,3 × 10⁻¹²58,14 × 10⁻¹²8669116,3 × 10⁻¹²168464microstrip-02-eps4.fee116,3 × 10⁻¹²50,043,043
10,238,04 × 10⁻¹²19,02 × 10⁻¹²3236138,04 × 10⁻¹²637681microstrip-03-eps1.fee38,04 × 10⁻¹²——
10,2115,8 × 10⁻¹²57,89 × 10⁻¹²32361115,8 × 10⁻¹²637684microstrip-03-eps4.fee115,8 × 10⁻¹²50,263,044
Проверки опубликованного расчёта
КритерийПолученоДопуск или ожидаемое значениеИтог
Энергия и терминальный заряд: microstrip-01-eps1.fee52,14 × 10⁻¹²1e-05Выполнен
Энергия и терминальный заряд: microstrip-01-eps4.fee69,64 × 10⁻¹²1e-05Выполнен
Границы эффективной проницаемости 1≤εeff≤400Выполнен
Энергия и терминальный заряд: microstrip-02-eps1.fee500,8 × 10⁻¹²1e-05Выполнен
Энергия и терминальный заряд: microstrip-02-eps4.fee824,9 × 10⁻¹²1e-05Выполнен
Границы эффективной проницаемости 1≤εeff≤400Выполнен
Энергия и терминальный заряд: microstrip-03-eps1.fee52,36 × 10⁻¹²1e-05Выполнен
Энергия и терминальный заряд: microstrip-03-eps4.fee95,31 × 10⁻¹²1e-05Выполнен
Границы эффективной проницаемости 1≤εeff≤400Выполнен
Сходимость ёмкости микрополосковой линии0,0043420,01Выполнен
Сходимость квази-ТЕМ сопротивления0,0043990,01Выполнен
Инженерная формула Z0: ориентир для открытой микрополосковой линии0,015210,08Выполнен

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

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

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

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

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