Skip to content

Commit 12c155f

Browse files
committed
create example for TF WP build from dict
1 parent 527c4db commit 12c155f

File tree

1 file changed

+251
-0
lines changed

1 file changed

+251
-0
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
from pathlib import Path
2+
3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
6+
from bluemira.base.constants import MU_0, MU_0_2PI, MU_0_4PI
7+
from bluemira.base.file import get_bluemira_path
8+
from bluemira.magnets.case_tf import create_case_tf_from_dict
9+
from bluemira.materials import MaterialCache
10+
11+
material_path = get_bluemira_path("magnets", subfolder="examples")
12+
material_file = Path(material_path, "materials_mag.json")
13+
MATERIAL_CACHE = MaterialCache()
14+
MATERIAL_CACHE.load_from_file(material_file)
15+
16+
case_tf_dict = {
17+
"name_in_registry": "TrapezoidalCaseTF",
18+
"name": "TrapezoidalCaseTF",
19+
"Ri": 3.708571428571428,
20+
"dy_ps": 0.05733333333333333,
21+
"dy_vault": 0.4529579163961617,
22+
"theta_TF": 22.5,
23+
"mat_case": "SS316-LN",
24+
"WPs": [
25+
{
26+
"name_in_registry": "WindingPack",
27+
"name": "WindingPack",
28+
"conductor": {
29+
"name_in_registry": "SymmetricConductor",
30+
"name": "SymmetricConductor",
31+
"cable": {
32+
"name_in_registry": "DummyRectangularCableLTS",
33+
"name": "DummyRectangularCableLTS",
34+
"n_sc_strand": 321,
35+
"n_stab_strand": 476,
36+
"d_cooling_channel": 0.01,
37+
"void_fraction": 0.7,
38+
"cos_theta": 0.97,
39+
"sc_strand": {
40+
"name_in_registry": "SuperconductingStrand",
41+
"name": "Nb3Sn_strand",
42+
"d_strand": 0.001,
43+
"temperature": 5.7,
44+
"materials": [
45+
{"material": "Nb3Sn - WST", "fraction": 0.5},
46+
{"material": "Copper100", "fraction": 0.5},
47+
],
48+
},
49+
"stab_strand": {
50+
"name_in_registry": "Strand",
51+
"name": "Stabilizer",
52+
"d_strand": 0.001,
53+
"temperature": 5.7,
54+
"materials": [{"material": "Copper300", "fraction": 1.0}],
55+
},
56+
"dx": 0.034648435154495685,
57+
"aspect_ratio": 1.2,
58+
},
59+
"mat_jacket": "SS316-LN",
60+
"mat_ins": "DummyInsulator",
61+
"dx_jacket": 0.0030808556812487366,
62+
"dx_ins": 0.001,
63+
},
64+
"nx": 25,
65+
"ny": 6,
66+
},
67+
{
68+
"name_in_registry": "WindingPack",
69+
"name": "WindingPack",
70+
"conductor": {
71+
"name_in_registry": "SymmetricConductor",
72+
"name": "SymmetricConductor",
73+
"cable": {
74+
"name_in_registry": "DummyRectangularCableLTS",
75+
"name": "DummyRectangularCableLTS",
76+
"n_sc_strand": 321,
77+
"n_stab_strand": 476,
78+
"d_cooling_channel": 0.01,
79+
"void_fraction": 0.7,
80+
"cos_theta": 0.97,
81+
"sc_strand": {
82+
"name_in_registry": "SuperconductingStrand",
83+
"name": "Nb3Sn_strand",
84+
"d_strand": 0.001,
85+
"temperature": 5.7,
86+
"materials": [
87+
{"material": "Nb3Sn - WST", "fraction": 0.5},
88+
{"material": "Copper100", "fraction": 0.5},
89+
],
90+
},
91+
"stab_strand": {
92+
"name_in_registry": "Strand",
93+
"name": "Stabilizer",
94+
"d_strand": 0.001,
95+
"temperature": 5.7,
96+
"materials": [{"material": "Copper300", "fraction": 1.0}],
97+
},
98+
"dx": 0.034648435154495685,
99+
"aspect_ratio": 1.2,
100+
},
101+
"mat_jacket": "SS316-LN",
102+
"mat_ins": "DummyInsulator",
103+
"dx_jacket": 0.0030808556812487366,
104+
"dx_ins": 0.001,
105+
},
106+
"nx": 18,
107+
"ny": 1,
108+
},
109+
],
110+
}
111+
112+
case_tf = create_case_tf_from_dict(case_tf_dict)
113+
114+
case_tf.plot(show=True, homogenized=False)
115+
116+
# Machine parameters (should match the original setup)
117+
R0 = 8.6
118+
B0 = 4.39
119+
A = 2.8
120+
n_TF = 16
121+
ripple = 6e-3
122+
# operational current per conductor
123+
Iop = 70.0e3
124+
# Safety factor to be considered on the allowable stress
125+
safety_factor = 1.5 * 1.3
126+
127+
# Derived values
128+
a = R0 / A
129+
d = 1.82
130+
Ri = R0 - a - d
131+
Re = (R0 + a) * (1 / ripple) ** (1 / n_TF)
132+
B_TF_i = 1.08 * (MU_0_2PI * n_TF * (B0 * R0 / MU_0_2PI / n_TF) / Ri)
133+
pm = B_TF_i**2 / (2 * MU_0)
134+
t_z = 0.5 * np.log(Re / Ri) * MU_0_4PI * n_TF * (B0 * R0 / MU_0_2PI / n_TF) ** 2
135+
T_sc = 4.2
136+
T_margin = 1.5
137+
T_op = T_sc + T_margin
138+
S_Y = 1e9 / safety_factor
139+
n_cond = int(np.floor((B0 * R0 / MU_0_2PI / n_TF) / Iop))
140+
141+
# Layout and WP parameters
142+
layout = "auto"
143+
wp_reduction_factor = 0.75
144+
min_gap_x = 2 * (R0 * 2 / 3 * 1e-2) # 2 * dr_plasma_side
145+
n_layers_reduction = 4
146+
147+
# Optimization parameters already defined earlier
148+
bounds_cond_jacket = np.array([1e-5, 0.2])
149+
bounds_dy_vault = np.array([0.1, 2])
150+
max_niter = 100
151+
err = 1e-6
152+
153+
# optimize number of stabilizer strands
154+
sc_strand = case_tf.WPs[0].conductor.cable.sc_strand
155+
Ic_sc = sc_strand.Ic(B=B_TF_i, temperature=T_op)
156+
case_tf.WPs[0].conductor.cable.n_sc_strand = int(np.ceil(Iop / Ic_sc))
157+
158+
from bluemira.magnets.utils import delayed_exp_func
159+
160+
Tau_discharge = 20 # [s]
161+
t_delay = 3 # [s]
162+
t0 = 0 # [s]
163+
hotspot_target_temperature = 250.0 # [K]
164+
165+
tf = Tau_discharge
166+
T_for_hts = T_op
167+
I_fun = delayed_exp_func(Iop, Tau_discharge, t_delay)
168+
B_fun = delayed_exp_func(B_TF_i, Tau_discharge, t_delay)
169+
170+
print("cable")
171+
print(case_tf.WPs[0].conductor.cable)
172+
173+
case_tf.WPs[0].conductor.cable.optimize_n_stab_ths(
174+
t0,
175+
tf,
176+
T_for_hts,
177+
hotspot_target_temperature,
178+
B_fun,
179+
I_fun,
180+
bounds=[1, 10000],
181+
show=True,
182+
)
183+
184+
# Optimize case with structural constraints
185+
case_tf.optimize_jacket_and_vault(
186+
pm=pm,
187+
fz=t_z,
188+
temperature=T_op,
189+
B=B_TF_i,
190+
allowable_sigma=S_Y,
191+
bounds_cond_jacket=bounds_cond_jacket,
192+
bounds_dy_vault=bounds_dy_vault,
193+
layout=layout,
194+
wp_reduction_factor=wp_reduction_factor,
195+
min_gap_x=min_gap_x,
196+
n_layers_reduction=n_layers_reduction,
197+
max_niter=max_niter,
198+
eps=err,
199+
n_conds=n_cond,
200+
)
201+
202+
case_tf.plot_convergence()
203+
204+
show = True
205+
homogenized = True
206+
if show:
207+
scalex = np.array([2, 1])
208+
scaley = np.array([1, 1.2])
209+
210+
ax = case_tf.plot(homogenized=homogenized)
211+
ax.set_aspect("equal")
212+
213+
# Fix the x and y limits
214+
ax.set_xlim(-scalex[0] * case_tf.dx_i, scalex[1] * case_tf.dx_i)
215+
ax.set_ylim(scaley[0] * 0, scaley[1] * case_tf.Ri)
216+
217+
deltax = [-case_tf.dx_i / 2, case_tf.dx_i / 2]
218+
219+
ax.plot(
220+
[-scalex[0] * case_tf.dx_i, -case_tf.dx_i / 2], [case_tf.Ri, case_tf.Ri], "k:"
221+
)
222+
223+
for i in range(len(case_tf.WPs)):
224+
ax.plot(
225+
[-scalex[0] * case_tf.dx_i, -case_tf.dx_i / 2],
226+
[case_tf.R_wp_i[i], case_tf.R_wp_i[i]],
227+
"k:",
228+
)
229+
230+
ax.plot(
231+
[-scalex[0] * case_tf.dx_i, -case_tf.dx_i / 2],
232+
[case_tf.R_wp_k[-1], case_tf.R_wp_k[-1]],
233+
"k:",
234+
)
235+
ax.plot(
236+
[-scalex[0] * case_tf.dx_i, -case_tf.dx_i / 2], [case_tf.Rk, case_tf.Rk], "k:"
237+
)
238+
239+
ax.set_title("Equatorial cross section of the TF WP")
240+
ax.set_xlabel("Toroidal direction [m]")
241+
ax.set_ylabel("Radial direction [m]")
242+
243+
plt.show()
244+
245+
I_sc = case_tf.WPs[0].conductor.cable.sc_strand.Ic(B=B_TF_i, temperature=T_op)
246+
I_max = I_sc * case_tf.WPs[0].conductor.cable.n_sc_strand
247+
I_TF_max = I_max * case_tf.n_conductors
248+
print(I_max)
249+
print(I_TF_max)
250+
I_TF = R0 * B0 / (MU_0_2PI * n_TF)
251+
print(I_TF)

0 commit comments

Comments
 (0)