Skip to content

Commit 1870e91

Browse files
added pathsim model
1 parent 5219977 commit 1870e91

File tree

4 files changed

+356
-45
lines changed

4 files changed

+356
-45
lines changed

analysis/tritium/pathsim_model.py

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import pathsim
2+
from pathsim import Simulation, Connection
3+
import numpy as np
4+
import matplotlib.pyplot as plt
5+
import pathview
6+
7+
from tritium_model import (
8+
neutron_rate,
9+
total_irradiation_time,
10+
k_top,
11+
baby_model,
12+
measured_TBR,
13+
)
14+
15+
# Create global variables
16+
A_OV = (baby_model.A_wall.to("m^2")).magnitude
17+
A_IV = (baby_model.A_top.to("m^2")).magnitude
18+
baby_vol = (baby_model.volume.to("m^3")).magnitude
19+
IV_to_OV_ratio = 70 / 12
20+
k_IV = k_top.to("m/s").magnitude * 0.6
21+
k_OV = k_IV / (IV_to_OV_ratio)
22+
# neutron_rate = (350 / 250) * 1.3e09
23+
neutron_rate = neutron_rate.to("n/s").magnitude
24+
irradiation_time = total_irradiation_time.to("s").magnitude
25+
26+
27+
tbr = measured_TBR.to("dimensionless").magnitude
28+
29+
IV_gas_residence_time = 0.01 * baby_vol / (A_IV * k_IV)
30+
OV_gas_residence_time = 3 * baby_vol / (A_OV * k_OV)
31+
32+
# Create blocks
33+
blocks, events = [], []
34+
35+
x_1_4 = pathsim.blocks.amplifier.Amplifier(gain=-1)
36+
blocks.append(x_1_4)
37+
38+
neutron_rate_6 = pathsim.blocks.adder.Adder()
39+
blocks.append(neutron_rate_6)
40+
41+
tbr_7 = pathsim.blocks.amplifier.Amplifier(gain=tbr)
42+
blocks.append(tbr_7)
43+
44+
baby_8 = pathview.custom_pathsim_blocks.Process(
45+
residence_time=baby_vol / (k_IV * A_IV + k_OV * A_OV),
46+
)
47+
blocks.append(baby_8)
48+
49+
iv_vial_activity_21 = pathsim.blocks.scope.Scope(
50+
labels=[
51+
"IV bubbler (vial1)",
52+
"IV bubbler (vial2)",
53+
"IV bubbler (vial3)",
54+
"IV bubbler (vial4)",
55+
]
56+
)
57+
blocks.append(iv_vial_activity_21)
58+
59+
soluble_vs_insoluble_1 = pathview.custom_pathsim_blocks.Splitter2(f1=0.01, f2=0.99)
60+
blocks.append(soluble_vs_insoluble_1)
61+
62+
iv_bubbler_23 = pathview.custom_pathsim_blocks.Bubbler(
63+
conversion_efficiency=0.95,
64+
vial_efficiency=0.9,
65+
replacement_times=np.array([0.4, 0.6, 1, 1.5, 2.5, 4]) * 24 * 3600,
66+
)
67+
events_iv_bubbler_23 = iv_bubbler_23.create_reset_events()
68+
events += events_iv_bubbler_23
69+
blocks.append(iv_bubbler_23)
70+
71+
iv_vs_ov_24 = pathview.custom_pathsim_blocks.Splitter2(
72+
f1=k_IV / (k_IV + k_OV), f2=k_OV / (k_IV + k_OV)
73+
)
74+
blocks.append(iv_vs_ov_24)
75+
76+
soluble_vs_insoluble_25 = pathview.custom_pathsim_blocks.Splitter2(f1=0.01, f2=0.99)
77+
blocks.append(soluble_vs_insoluble_25)
78+
79+
ov_bubbler_26 = pathview.custom_pathsim_blocks.Bubbler(
80+
conversion_efficiency=0.95,
81+
vial_efficiency=0.9,
82+
replacement_times=np.array([1, 2.5, 4]) * 24 * 3600,
83+
)
84+
events_ov_bubbler_26 = ov_bubbler_26.create_reset_events()
85+
events += events_ov_bubbler_26
86+
blocks.append(ov_bubbler_26)
87+
88+
environment_27 = pathview.custom_pathsim_blocks.Integrator()
89+
blocks.append(environment_27)
90+
91+
ov_vial_activity_28 = pathsim.blocks.scope.Scope(
92+
labels=[
93+
"OV bubbler (vial1)",
94+
"OV bubbler (vial2)",
95+
"OV bubbler (vial3)",
96+
"OV bubbler (vial4)",
97+
]
98+
)
99+
blocks.append(ov_vial_activity_28)
100+
101+
baby_inventory_30 = pathsim.blocks.scope.Scope(labels=["BABY (inv)"])
102+
blocks.append(baby_inventory_30)
103+
104+
stepsource_31 = pathsim.blocks.sources.StepSource(
105+
amplitude=neutron_rate, tau=irradiation_time
106+
)
107+
blocks.append(stepsource_31)
108+
109+
stepsource_32 = pathsim.blocks.sources.StepSource(amplitude=neutron_rate, tau=0)
110+
blocks.append(stepsource_32)
111+
112+
neutron_source_33 = pathsim.blocks.scope.Scope(labels=["Neutron rate"])
113+
blocks.append(neutron_source_33)
114+
115+
cumulative_release_34 = pathsim.blocks.scope.Scope(labels=["IV", "OV"])
116+
blocks.append(cumulative_release_34)
117+
118+
iv_35 = pathview.custom_pathsim_blocks.Integrator()
119+
blocks.append(iv_35)
120+
121+
ov_36 = pathview.custom_pathsim_blocks.Integrator()
122+
blocks.append(ov_36)
123+
124+
iv_gas_37 = pathview.custom_pathsim_blocks.Process(
125+
residence_time=IV_gas_residence_time,
126+
)
127+
blocks.append(iv_gas_37)
128+
129+
ov_gas_38 = pathview.custom_pathsim_blocks.Process(
130+
residence_time=OV_gas_residence_time,
131+
)
132+
blocks.append(ov_gas_38)
133+
134+
135+
# Create events
136+
137+
138+
# Create connections
139+
140+
connections = [
141+
Connection(x_1_4[0], neutron_rate_6[0]),
142+
Connection(neutron_rate_6[0], tbr_7[0]),
143+
Connection(tbr_7[0], baby_8[0]),
144+
Connection(soluble_vs_insoluble_1["source1"], iv_bubbler_23["sample_in_soluble"]),
145+
Connection(soluble_vs_insoluble_1["source2"], iv_bubbler_23["sample_in_insoluble"]),
146+
Connection(iv_bubbler_23["vial1"], iv_vial_activity_21[0]),
147+
Connection(iv_bubbler_23["vial2"], iv_vial_activity_21[1]),
148+
Connection(iv_bubbler_23["vial3"], iv_vial_activity_21[2]),
149+
Connection(iv_bubbler_23["vial4"], iv_vial_activity_21[3]),
150+
Connection(baby_8["mass_flow_rate"], iv_vs_ov_24[0]),
151+
Connection(soluble_vs_insoluble_25["source1"], ov_bubbler_26["sample_in_soluble"]),
152+
Connection(
153+
soluble_vs_insoluble_25["source2"], ov_bubbler_26["sample_in_insoluble"]
154+
),
155+
Connection(iv_bubbler_23["sample_out"], environment_27[0]),
156+
Connection(ov_bubbler_26["sample_out"], environment_27[1]),
157+
Connection(ov_bubbler_26["vial1"], ov_vial_activity_28[0]),
158+
Connection(ov_bubbler_26["vial2"], ov_vial_activity_28[1]),
159+
Connection(ov_bubbler_26["vial3"], ov_vial_activity_28[2]),
160+
Connection(ov_bubbler_26["vial4"], ov_vial_activity_28[3]),
161+
Connection(baby_8["inv"], baby_inventory_30[0]),
162+
Connection(stepsource_31[0], x_1_4[0]),
163+
Connection(stepsource_32[0], neutron_rate_6[1]),
164+
Connection(neutron_rate_6[0], neutron_source_33[0]),
165+
Connection(iv_35[0], cumulative_release_34[0]),
166+
Connection(ov_36[0], cumulative_release_34[1]),
167+
Connection(iv_vs_ov_24["source1"], iv_gas_37[0]),
168+
Connection(iv_gas_37["mass_flow_rate"], iv_35[0]),
169+
Connection(iv_gas_37["mass_flow_rate"], soluble_vs_insoluble_1[0]),
170+
Connection(iv_vs_ov_24["source2"], ov_gas_38[0]),
171+
Connection(ov_gas_38["mass_flow_rate"], ov_36[0]),
172+
Connection(ov_gas_38["mass_flow_rate"], soluble_vs_insoluble_25[0]),
173+
]
174+
175+
# Create simulation
176+
my_simulation = Simulation(
177+
blocks,
178+
connections,
179+
events=events,
180+
Solver=pathsim.solvers.SSPRK22,
181+
dt=100,
182+
dt_max=1.0,
183+
dt_min=1e-6,
184+
iterations_max=100,
185+
log=True,
186+
tolerance_fpi=1e-6,
187+
**{"tolerance_lte_rel": 1e-4, "tolerance_lte_abs": 1e-9},
188+
)
189+
190+
if __name__ == "__main__":
191+
my_simulation.run(8 * 24 * 3600)
192+
193+
# Optional: Plotting results
194+
scopes = [block for block in blocks if isinstance(block, pathsim.blocks.Scope)]
195+
fig, axs = plt.subplots(
196+
nrows=len(scopes), sharex=True, figsize=(10, 5 * len(scopes))
197+
)
198+
for i, scope in enumerate(scopes):
199+
plt.sca(axs[i] if len(scopes) > 1 else axs)
200+
time, data = scope.read()
201+
# plot the recorded data
202+
for p, d in enumerate(data):
203+
lb = scope.labels[p] if p < len(scope.labels) else f"port {p}"
204+
plt.plot(time, d, label=lb)
205+
plt.legend()
206+
plt.xlabel("Time")
207+
plt.show()

0 commit comments

Comments
 (0)