import math import numpy as np import pytest from gausse.physics.inductance import ( CoilInductanceModel, air_core_inductance_wheeler, demagnetizing_factor_prolate, effective_permeability, winding_geometry, ) def test_winding_geometry_scales_with_turns_and_layers(): geo = winding_geometry(tube_od_m=0.02, wire_od_m=0.001, turns_per_layer=50, layers=3) assert geo.total_turns == 150 assert geo.coil_length_m == pytest.approx(0.05) assert geo.radial_depth_m == pytest.approx(0.003) assert geo.total_wire_length_m > 0 # больше слоёв -> больше провода при тех же витках на слой geo_more_layers = winding_geometry(0.02, 0.001, 50, 5) assert geo_more_layers.total_wire_length_m > geo.total_wire_length_m def test_wheeler_inductance_is_positive_and_grows_with_turns(): l_small = air_core_inductance_wheeler(mean_radius_m=0.015, length_m=0.05, depth_m=0.003, turns=50) l_large = air_core_inductance_wheeler(mean_radius_m=0.015, length_m=0.05, depth_m=0.003, turns=200) assert l_small > 0 assert l_large > l_small def test_demagnetizing_factor_bounds(): # почти сфера (aspect_ratio -> 1): классическое значение 1/3 assert demagnetizing_factor_prolate(1.001) == pytest.approx(1 / 3, abs=0.02) # очень вытянутый стержень: коэффициент размагничивания стремится к 0 assert demagnetizing_factor_prolate(200.0) < 0.01 def test_effective_permeability_limits(): # без размагничивания (Nd=0) эффективная проницаемость равна мю материала assert effective_permeability(mu_r=500.0, demagnetizing_factor=0.0) == pytest.approx(500.0) # полное размагничивание (Nd=1) гасит эффект проницаемости до 1 assert effective_permeability(mu_r=500.0, demagnetizing_factor=1.0) == pytest.approx(1.0) @pytest.fixture def model() -> CoilInductanceModel: return CoilInductanceModel( l_air_h=100e-6, coil_length_m=0.05, slug_length_m=0.03, mu_eff=50.0, smoothing_width_m=0.001, ) def test_inductance_peaks_when_slug_centered(model): l_center = model.l_of_x(np.array(0.0)) l_far = model.l_of_x(np.array(0.2)) assert l_center > l_far assert l_far == pytest.approx(model.l_air_h, rel=1e-3) def test_dl_dx_vanishes_at_symmetric_center(model): assert model.dl_dx(np.array(0.0)) == pytest.approx(0.0, abs=1e-9) def test_dl_dx_sign_flips_across_center(model): # слева от центра индуктивность растёт (dL/dx > 0), справа убывает (< 0) assert model.dl_dx(np.array(-0.01)) > 0 assert model.dl_dx(np.array(0.01)) < 0 def test_analytic_dl_dx_matches_finite_difference(model): xs = np.linspace(-0.06, 0.06, 25) h = 1e-7 analytic = np.array([model.dl_dx(x) for x in xs]) finite_diff = np.array( [(model.l_of_x(x + h) - model.l_of_x(x - h)) / (2 * h) for x in xs] ) assert np.allclose(analytic, finite_diff, rtol=1e-3, atol=1e-9)