Files
toroid/core.py

208 lines
5.8 KiB
Python

import numpy as np
# -------------------------------------------------------------------
# 1. Put your digitized data here
# Units:
# - B in Tesla
# - frequency in kHz (x-axis of your plot)
# - Pv in kW/m^3 (y-axis of your plot)
#
# IMPORTANT:
# The numbers below are ONLY EXAMPLES / PLACEHOLDERS.
# Replace each "f_khz" and "Pv_kW_m3" array with points
# read from your datasheet plot (solid 25 °C lines).
# -------------------------------------------------------------------
core_loss_data_25C = {
0.025: { # 25 mT
"f_khz": np.array([2.93084374470676,
8.7361542468832,
44.706096185109,
125.963436020903,
193.225112880907,
], dtype=float),
"Pv_kW_m3": np.array([0.177193262696068,
0.679670055798598,
5.03342212801684,
17.4677120801992,
30.0788251804309,
], dtype=float),
},
0.050: { # 50 mT
"f_khz": np.array([2.9975926563905,
9.24208952674728,
38.618648046052,
188.92247157063,
], dtype=float),
"Pv_kW_m3": np.array([0.917768017464649,
3.47034515205292,
19.0328184767803,
123.927503749051,
], dtype=float),
},
0.100: { # 100 mT
"f_khz": np.array([2.48,
8.84,
34.12,
87.85,
193.23,
], dtype=float),
"Pv_kW_m3": np.array([3.14,
13.89,
69.94,
216.47,
564.36,
], dtype=float),
},
0.200: { # 200 mT
"f_khz": np.array([2.14,
8.64,
32.25,
83.05,
195.41,
], dtype=float),
"Pv_kW_m3": np.array([10.44,
56.44,
276.05,
891.89,
2497.56,
], dtype=float),
},
0.300: { # 300 mT
"f_khz": np.array([2.19,
5.03,
12.39,
24.89,
49.47,
], dtype=float),
"Pv_kW_m3": np.array([26.83,
67.97,
193.07,
442.55,
1000,
], dtype=float),
},
}
# -------------------------------------------------------------------
# 2. Helper: 1-D log-log interpolation in frequency
# -------------------------------------------------------------------
def _loglog_interp(x, xp, fp):
"""
Log-log interpolation: fp vs xp, evaluated at x.
All arguments are assumed > 0.
"""
x = np.asarray(x, dtype=float)
xp = np.asarray(xp, dtype=float)
fp = np.asarray(fp, dtype=float)
logx = np.log10(x)
logxp = np.log10(xp)
logfp = np.log10(fp)
logy = np.interp(logx, logxp, logfp)
return 10.0 ** logy
# -------------------------------------------------------------------
# 3. Main function: Pv(B, f) interpolation
# -------------------------------------------------------------------
def core_loss_Pv(B_T, f_Hz, data=core_loss_data_25C):
"""
Interpolate core loss density P_v for given flux density and frequency.
Parameters
----------
B_T : float
Peak flux density in Tesla (e.g. 0.05 for 50 mT).
f_Hz : float or array_like
Frequency in Hz.
data : dict
Dict mapping B_T -> {"f_khz": array, "Pv_kW_m3": array}.
Returns
-------
Pv_kW_m3 : float or ndarray
Core loss density in kW/m^3 at 25 °C.
"""
B_T = float(B_T)
f_khz = np.asarray(f_Hz, dtype=float) / 1e3 # plot uses kHz
if np.any(f_khz <= 0):
raise ValueError("Frequency must be > 0 Hz")
# Sorted list of available B values from your digitized curves
B_list = np.array(sorted(data.keys()))
# Handle out-of-range B values
if B_T < B_list.min():
raise ValueError(
f"B={B_T:.3f} T is below available range "
f"[{B_list.min():.3f}, {B_list.max():.3f}] T"
)
# For B > max data (0.3T), extrapolate up to 0.4T using two highest curves
# If B > 0.4T, clamp to the extrapolated value at 0.4T
if B_T > B_list.max():
# Use the two highest B values for extrapolation
B1 = B_list[-2] # 0.2T
B2 = B_list[-1] # 0.3T
d1 = data[B1]
d2 = data[B2]
# Interpolate along frequency (log-log) on each B curve
Pv1 = _loglog_interp(f_khz, d1["f_khz"], d1["Pv_kW_m3"])
Pv2 = _loglog_interp(f_khz, d2["f_khz"], d2["Pv_kW_m3"])
# Extrapolate in log(Pv) vs B (Pv ~ B^b approximately)
logPv1 = np.log10(Pv1)
logPv2 = np.log10(Pv2)
# Clamp B_T to 0.4T for extrapolation calculation
B_T_clamped = min(B_T, 0.4)
alpha = (B_T_clamped - B1) / (B2 - B1)
logPv = (1.0 - alpha) * logPv1 + alpha * logPv2
return 10.0 ** logPv
# If B_T is (approximately) one of the tabulated curves, just interpolate in f
idx_match = np.where(np.isclose(B_list, B_T, rtol=1e-4, atol=1e-6))[0]
if idx_match.size:
B_key = B_list[idx_match[0]]
d = data[B_key]
return _loglog_interp(f_khz, d["f_khz"], d["Pv_kW_m3"])
# Otherwise, find the two B curves that bracket B_T
idx = np.searchsorted(B_list, B_T)
B1 = B_list[idx - 1]
B2 = B_list[idx]
d1 = data[B1]
d2 = data[B2]
# Interpolate along frequency (log-log) on each B curve
Pv1 = _loglog_interp(f_khz, d1["f_khz"], d1["Pv_kW_m3"])
Pv2 = _loglog_interp(f_khz, d2["f_khz"], d2["Pv_kW_m3"])
# Now interpolate between B1 and B2.
# Do it in log(Pv) vs B (Pv ~ B^b approximately).
logPv1 = np.log10(Pv1)
logPv2 = np.log10(Pv2)
alpha = (B_T - B1) / (B2 - B1)
logPv = (1.0 - alpha) * logPv1 + alpha * logPv2
return 10.0 ** logPv
if __name__ == '__main__':
p = core_loss_Pv(0.2, 25_000)
print (p)