Skip to content

Commit

Permalink
Capacitor model tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jhillairet committed Mar 25, 2024
1 parent d25c9c4 commit f838391
Show file tree
Hide file tree
Showing 10 changed files with 104,307 additions and 44,042 deletions.
11 changes: 8 additions & 3 deletions west_ic_antenna/antenna.py
Expand Up @@ -246,8 +246,12 @@ def capa(
"""
z0_bridge = z0_bridge or self.bridge.z0[:, 1]
z0_antenna = z0_antenna or self.antenna.z0[:, 0]
# Port Characterics impedances
# NB: Taking real parts, as the small imaginary parts comes from
# lossy boundary conditions in HFSS and are supposed not physical.
z0_bridge = z0_bridge or self.bridge.z0[:, 1].real
z0_antenna = z0_antenna or self.antenna.z0[:, 0].real

# dummy transmission line to create lumped components
# the 50 Ohm characteristic impedance is artifical. However, the R,L,R1,L1,C1 values
# have been fitted to full-wave solutions using this 50 ohm value, so it should not be modified
Expand All @@ -271,7 +275,8 @@ def capa(
# ANSYS Designer seems not doing it and leaves to 50 ohm
# renormalizing the z0 will lead to decrease the matched capacitances by ~10pF @55MHz
# In reality, values are closer to 50 pF at 55 MHz
# capa.z0 = [z0_bridge, z0_antenna]
capa.renormalize(z_new=np.array([z0_bridge, z0_antenna]).T)

return capa

def _antenna_circuit(self, Cs: NumberLike) -> 'Circuit':
Expand Down
40,024 changes: 20,012 additions & 20,012 deletions west_ic_antenna/data/Sparameters/WEST_ICRH_Bridge_30to70MHz.s3p

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Binary file not shown.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

12,023 changes: 12,023 additions & 0 deletions west_ic_antenna/test/ANSYS_benchmarks/WEST_capacitor_test_connection.s1p

Large diffs are not rendered by default.

12,022 changes: 12,022 additions & 0 deletions west_ic_antenna/test/ANSYS_benchmarks/WEST_capacitor_test_connection_renorm50ohm.s1p

Large diffs are not rendered by default.

152 changes: 141 additions & 11 deletions west_ic_antenna/test/test_antenna.py
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
import os
import pytest
import skrf as rf
import os
import numpy as np


from west_ic_antenna.antenna import (
WestIcrhAntenna,
Expand All @@ -14,33 +16,161 @@

# Useful definitions
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(TEST_DIR, '../data')
DATA_DIR = os.path.join(TEST_DIR, "../data")


@pytest.fixture
def antenna_default_arg():
return WestIcrhAntenna()


# Constructor Tests
def test_constructor_default(antenna_default_arg):
"""Test creation of Antenna instance"""
assert isinstance(antenna_default_arg, WestIcrhAntenna)



def test_setup_constructor_frequency():
freq = rf.Frequency(30, 60, npoints=10, unit='MHz')
freq = rf.Frequency(30, 60, npoints=10, unit="MHz")
_ant = WestIcrhAntenna(frequency=freq)
assert isinstance(_ant, WestIcrhAntenna)



def test_setup_constructor_capa():
Cs = [20, 30, 40, 50]
_ant = WestIcrhAntenna(Cs=Cs)
_ant = WestIcrhAntenna(Cs=Cs)
assert isinstance(_ant, WestIcrhAntenna)



def test_setup_constructor_frontface_filename():
_ant = WestIcrhAntenna(front_face=DEFAULT_FRONT_FACE)
assert isinstance(_ant, WestIcrhAntenna)
_ant = WestIcrhAntenna(front_face=DEFAULT_FRONT_FACE)
assert isinstance(_ant, WestIcrhAntenna)


def test_setup_constructor_frontface_network():
ntw = rf.Network(DEFAULT_FRONT_FACE)
_ant = WestIcrhAntenna(front_face=ntw)
assert isinstance(_ant, WestIcrhAntenna)
_ant = WestIcrhAntenna(front_face=ntw)
assert isinstance(_ant, WestIcrhAntenna)


# Test capacitor model
"""
Equivalent lumped Network model of a WEST ICRH antenna capacitor.
The electrical circuit of an equivalent lumped model is:
port1 (bridge side) port2 (antenna side)
o-- R1 -- L1 --- R -- L -- C --- L1 -- R1 --o
| |
C1 C1
| |
gnd gnd
"""


def test_capa_model_50ohm_ports(antenna_default_arg):
"""
Benchmark capacitor model with ANSYS Circuit model.
Default values and 50 Ohm port impedance in ANSYS.
"""
ant = antenna_default_arg
cap = ant.capa(
C=50,
z0_bridge=50,
z0_antenna=50,
)

# Does it returns a Network?
assert isinstance(cap, rf.Network)

# ANSYS Equivalent circuit with 50 Ohm ports
ANSYS_model = (
"ANSYS_benchmarks/WEST_capacitor_equivalent_circuit_50ohm_ports.s2p"
)
cap_ANSYS = rf.Network(os.path.join(TEST_DIR, ANSYS_model))

assert cap == cap_ANSYS


def test_capa_model_bridge_antenna_ports(antenna_default_arg):
"""
Benchmark capacitor model with ANSYS Circuit model.
Specifiyng bridge and antenna ports'Z0 in ANSYS (real values).
"""
ant = antenna_default_arg
cap = ant.capa(C=50)

# ANSYS Equivalent circuit with complex bridge and antenna ports' Z0
ANSYS_model = "ANSYS_benchmarks/WEST_capacitor_equivalent_circuit_bridge_antenna_ports.s2p"
cap_ANSYS = rf.Network(os.path.join(TEST_DIR, ANSYS_model))

assert cap == cap_ANSYS


def test_capa_model_bridge_antenna_ports_renorm50ohm(antenna_default_arg):
"""
Benchmark capacitor model with ANSYS Circuit model.
Specifiyng bridge and antenna ports'Z0 in ANSYS (real values),
but renormalizing ANSYS results to 50 ohm during export of Touchstone.
"""
ant = antenna_default_arg
cap_50 = ant.capa(C=50, z0_bridge=50, z0_antenna=50)

ANSYS_model_50 = "ANSYS_benchmarks/WEST_capacitor_equivalent_circuit_bridge_antenna_ports_renorm50ohm.s2p"
cap_ANSYS_50 = rf.Network(os.path.join(TEST_DIR, ANSYS_model_50))

assert cap_50 == cap_ANSYS_50


def test_capa_model_connection(antenna_default_arg):
"""
Benchmark dummy circuit model of a antenna-capa-bridge vs ANSYS Circuit.
In ANSYS, a single capacitor electrical circuit is connected to one bridge
output and to an antenne front face input (using HFSS model).
Bridge input is connected to input port and all other ports are shorted.
Benchmark is performed when the Touchtone file is exported without and with
50 Ohm renormalization.
"""
# NB: importing S-matrix in ANSYS Circuit as a N-port component
# requires the user to know in advance the port char impedance
# ant = antenna_default_arg
ant = antenna_default_arg
cap = ant.capa(C=50)

# Creating the dummy circuit using scikit-rf
cap.name = 'capa'
port = rf.Circuit.Port(frequency=ant.frequency, name='port1', z0=ant.bridge.z0[:,0].real)
gnd = rf.Circuit.Ground(frequency=ant.frequency, name="gnd")
cnx = [
[(ant.bridge, 0), (port, 0)],
[(ant.bridge, 1), (cap, 0)],
[(cap, 1), (ant.antenna, 0)],
# grounding all other ports
[(gnd, 0), (ant.bridge, 2), (ant.antenna, 1), (ant.antenna, 2), (ant.antenna, 3)]
]
cir = rf.Circuit(cnx)
ntw = cir.network

# ANSYS Model Export without renormalization
ANSYS_model = "ANSYS_benchmarks/WEST_capacitor_test_connection.s1p"
ANSYS_connection_test = rf.Network(os.path.join(TEST_DIR, ANSYS_model))

assert ntw == ANSYS_connection_test

# ANSYS Model Export Renomalized to 50 Ohm
ANSYS_model_50 = "ANSYS_benchmarks/WEST_capacitor_test_connection_renorm50ohm.s1p"
ANSYS_connection_test_50 = rf.Network(os.path.join(TEST_DIR, ANSYS_model_50))
ntw.renormalize(50)

assert ntw == ANSYS_connection_test_50


if __name__ == "__main__":
pytest.main([__file__])

0 comments on commit f838391

Please sign in to comment.