"""Метод Хойна для линейной цепи с сопротивлением и индуктивностью.

Среда: встроенный MicroPython FEMM 5.
Аналитический учебный пример; полевой решатель не вызывается.
Параметры, единицы величин и порядок вывода пояснены по стадиям.
"""

import math

# Линейная цепь с постоянными напряжением, В; сопротивлением, Ом; индуктивностью, Гн.
voltage_v = 24.0
resistance_ohm = 2.0
inductance_h = 0.01
# Временной шаг, с; начальный ток, А. Здесь рассчитывается один шаг интегрирования.
step_s = 0.0001
current_a = 0.0


# Правая часть уравнения L·di/dt = U − R·i; результат выражен в А/с.
def derivative(current):
    return (voltage_v - resistance_ohm * current) / inductance_h


# Начальный наклон тока; явный метод Эйлера даёт предварительное значение в конце шага.
first = derivative(current_a)
prediction = current_a + step_s * first
# Повторно вычисляем наклон в предварительно найденном состоянии.
second = derivative(prediction)
# Метод Хойна использует среднее начального и конечного наклонов.
current_a += 0.5 * step_s * (first + second)
# Точное решение линейной цепи служит независимым эталоном ошибки временного шага.
exact = (
    voltage_v / resistance_ohm * (1 - math.exp(-resistance_ohm * step_s / inductance_h))
)
print("Эйлер:", prediction)
print("Хойн:", current_a)
print("Точное решение:", exact)
