"""Магнитостатические таблицы вентильно-индукторной машины и нелинейная цепь.

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

import math


# Устойчивое вычисление гиперболического тангенса без положительной большой экспоненты.
def tanh_stable(x):
    if x < 0:
        return -tanh_stable(-x)
    e = math.exp(-2 * x)
    return (1 - e) / (1 + e)


# Квадрат гиперболического секанса: производная гиперболического тангенса.
def sech_squared(x):
    e = math.exp(-2 * abs(x))
    return 4 * e / (1 + e) ** 2


# Логарифм гиперболического косинуса вычисляется без переполнения при больших |x|.
def log_cosh(x):
    a = abs(x)
    return a + math.log(1 + math.exp(-2 * a)) - math.log(2)


# В проверенной встроенной math отсутствует tanh.
# Собственные функции не требуют внешних библиотек и устойчивы при больших |x|.
# Учебная характеристика насыщения: индуктивности, Гн; ток насыщения и рабочий ток, А.
base_h, variation_h, saturation_a, current_a = 0.002, 0.01, 5.0, 5.0
# Механический угол преобразуем в радианы. Угловая зависимость повторяется через 90°.
angle = math.radians(22.5)
factor = 0.5 * (1 - math.cos(4 * angle))
# Производная углового множителя берётся по углу в радианах.
factor_derivative = 2 * math.sin(4 * angle)
# Потокосцепление, Вб; его производная по току, Гн; коэнергия, Дж, вычисляются согласованно.
linkage = (
    base_h * current_a
    + variation_h * saturation_a * tanh_stable(current_a / saturation_a) * factor
)
incremental = base_h + variation_h * sech_squared(current_a / saturation_a) * factor
coenergy = (
    0.5 * base_h * current_a**2
    + variation_h * saturation_a**2 * log_cosh(current_a / saturation_a) * factor
)
# Момент — производная коэнергии по механическому углу при неизменном токе, Н·м.
torque = (
    variation_h
    * saturation_a**2
    * log_cosh(current_a / saturation_a)
    * factor_derivative
)
# Порядок вывода: потокосцепление; дифференциальная индуктивность; коэнергия; момент.
print(linkage, incremental, coenergy, torque)
