Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b101008
added GLC model but needs some verification
RemDelaporteMathurin Oct 27, 2025
5282306
added glc to nodeconfig
RemDelaporteMathurin Oct 28, 2025
5afac25
fixes for glc
rossmacdonald98 Oct 28, 2025
8ee0eb3
output mass flow rates instead
RemDelaporteMathurin Oct 28, 2025
3fa39db
removed print statements + raise error
RemDelaporteMathurin Oct 29, 2025
b836a8f
docstrings
RemDelaporteMathurin Oct 29, 2025
b2f6927
custom styling
RemDelaporteMathurin Oct 30, 2025
cfa11e0
added port aliases
RemDelaporteMathurin Oct 30, 2025
11281d7
R from scipy
RemDelaporteMathurin Oct 30, 2025
3875250
efficiency as dynamic output + fixed negative pressure
RemDelaporteMathurin Oct 30, 2025
0b7ba3e
zero initial guess
RemDelaporteMathurin Oct 30, 2025
c7119f9
most recent model
RemDelaporteMathurin Nov 4, 2025
88efb06
Merge branch 'main' into glc
RemDelaporteMathurin Nov 5, 2025
28a6165
fix for Process
RemDelaporteMathurin Nov 5, 2025
9ecc855
Merge branch 'glc' of https://github.com/festim-dev/PathView into glc
RemDelaporteMathurin Nov 5, 2025
a36c9fc
Merge branch 'main' into glc
RemDelaporteMathurin Nov 6, 2025
aae3bec
removed glc
RemDelaporteMathurin Nov 13, 2025
5eea6e7
Merge remote-tracking branch 'origin/main' into glc
RemDelaporteMathurin Nov 13, 2025
afe9568
GLC from pathsim-chem
RemDelaporteMathurin Nov 13, 2025
c82a677
fixed syntax
RemDelaporteMathurin Nov 13, 2025
67decf6
added comma
RemDelaporteMathurin Nov 13, 2025
a9b757d
fixed branch
RemDelaporteMathurin Nov 13, 2025
7f27a67
added new handle
RemDelaporteMathurin Nov 13, 2025
0b63561
added n_T_out_gas handle
RemDelaporteMathurin Nov 13, 2025
0fff964
rm print statemetn
RemDelaporteMathurin Nov 17, 2025
2bbe572
Updated handles on GLC block
rossmacdonald98 Nov 17, 2025
aeb8f3b
Updated handles on GLC block 2
rossmacdonald98 Nov 17, 2025
69df131
Updated GLC block handle positions
rossmacdonald98 Nov 17, 2025
c524c1c
Added n_T out handles to GLC block
rossmacdonald98 Nov 18, 2025
f8fbd9d
added flow handles
rossmacdonald98 Nov 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions glc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import pathsim
from pathsim import Simulation, Connection
import numpy as np
import matplotlib.pyplot as plt
import pathview

# Create global variables
import numpy as np

c_T_inlet = 3.09e-2 # mol/m^3 (c_T(L+)), Inlet tritium concentration in liquid just before inlet
y_T2_in = 0.0 # Inlet tritium molar fraction in gas (0 = pure purge gas)
P_0 = 5e5 # Pa, Gas total pressure at inlet
ρ_l = 9000 # kg/m^3, Liquid density
K_s = 2e-6 # Tritium Sievert's constant in liquid

L = 3.0 # m, Height of the bubble column
D = 0.5 # m, Column diameter
ε_g = 0.04 # Gas phase fraction

Q_l = 0.01 # m^3/s, Volumetric flow rate of liquid phase
Q_g = 0.0005 # m^3/s, Volumetric flow rate of gas phase at inlet

a = 20 # m^-1, Specific liquid-gas interfacial area

E_g = 0.05 # m^2/s, Effective axial dispersion coefficient, gas phase
E_l = 0.01 # m^2/s, Effective axial dispersion coefficient, liquid phase

h_l = 1e-4 # m/s, Mass transfer coefficient, tritium liquid - gas

g = 9.81 # m/s^2, Gravitational acceleration

# Calculated parameters
ε_l = 1 - ε_g # Liquid phase fraction

A = np.pi * (D / 2) ** 2 # m^2, Cross-sectional area of the column
A_l = A * ε_l # m^2, Cross-sectional area of the liquid phase
A_g = A * ε_g # m^2, Cross-sectional area of the gas phase

u_l = Q_l / A_l # m/s, superficial liquid inlet velocity (positive for downward flow)
u_g0 = Q_g / A_g # m/s, gas inlet velocity (positive for upward flow)
R = 8.314
T = 623
N_A = 6.0221408e23

# Create blocks
blocks, events = [], []

p_t2_inlet_5 = pathsim.blocks.sources.Constant(value=y_T2_in)
blocks.append(p_t2_inlet_5)

blanket_6 = pathview.custom_pathsim_blocks.Process(
residence_time=2, initial_value=1, source_term=0
)
blocks.append(blanket_6)

storage_7 = pathview.custom_pathsim_blocks.Process(residence_time=0, source_term=0)
blocks.append(storage_7)

to_concentration_14 = pathsim.blocks.amplifier.Amplifier(gain=Q_l**-1)
blocks.append(to_concentration_14)

inventories_16 = pathsim.blocks.scope.Scope(
labels=["blanket (inv)", "storage (inv)", "adder 20"]
)
blocks.append(inventories_16)

all_t_flow_rates_18 = pathsim.blocks.scope.Scope(labels=["blanket (mass_flow_rate)"])
blocks.append(all_t_flow_rates_18)

adder_20_20 = pathsim.blocks.adder.Adder()
blocks.append(adder_20_20)

glc_21_21 = pathview.custom_pathsim_blocks.GLC(
P_outlet=5e5,
L=L,
u_l=u_l,
u_g0=u_g0,
ε_g=ε_g,
ε_l=ε_l,
E_g=E_g,
E_l=E_l,
a=a,
h_l=h_l,
ρ_l=ρ_l,
K_s=K_s,
Q_l=Q_l,
Q_g=Q_g,
D=D,
T=T,
initial_nb_of_elements=20,
)
blocks.append(glc_21_21)


# Create events


# Create connections

connections = [
Connection(blanket_6["mass_flow_rate"], to_concentration_14[0]),
Connection(blanket_6["inv"], inventories_16[0]),
Connection(storage_7["inv"], inventories_16[1]),
Connection(blanket_6["mass_flow_rate"], all_t_flow_rates_18[0]),
Connection(blanket_6["inv"], adder_20_20[0]),
Connection(storage_7["inv"], adder_20_20[1]),
Connection(adder_20_20[0], inventories_16[2]),
Connection(to_concentration_14[0], glc_21_21["c_T_inlet"]),
Connection(p_t2_inlet_5[0], glc_21_21["y_T2_in"]),
Connection(glc_21_21["T_out_gas"], storage_7[0]),
Connection(glc_21_21["T_out_liquid"], blanket_6[0]),
]

# Create simulation
my_simulation = Simulation(
blocks,
connections,
events=events,
Solver=pathsim.solvers.SSPRK22,
dt=1,
dt_min=1e-16,
iterations_max=200,
log=True,
tolerance_fpi=1e-10,
**{},
)

if __name__ == "__main__":
my_simulation.run(200)

# Optional: Plotting results
scopes = [block for block in blocks if isinstance(block, pathsim.blocks.Scope)]
fig, axs = plt.subplots(
nrows=len(scopes), sharex=True, figsize=(10, 5 * len(scopes))
)
for i, scope in enumerate(scopes):
plt.sca(axs[i] if len(scopes) > 1 else axs)
time, data = scope.read()
# plot the recorded data
for p, d in enumerate(data):
lb = scope.labels[p] if p < len(scope.labels) else f"port {p}"
plt.plot(time, d, label=lb)
plt.legend()
plt.xlabel("Time")
plt.show()
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ classifiers = [
requires-python = ">=3.8"
dependencies = [
"pathsim>=0.8.2",
"pathsim-chem",
"pathsim-chem@git+https://github.com/pathsim/pathsim-chem@glc",
"matplotlib>=3.7.0",
"numpy>=1.24.0",
"plotly>=6.0",
Expand Down
66 changes: 33 additions & 33 deletions src/components/nodes/BubblerNode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,29 @@ export default function BubblerNode({ data }) {

{/* Labels for sample in handles */}

<div style={{
position: 'absolute',
left: '2px',
bottom: '20%',
<div style={{
position: 'absolute',
left: '2px',
bottom: '20%',
fontSize: '12px',
fontWeight: 'bold',
textAlign: 'right'
}}>
Sample in
</div>
<div style={{
position: 'absolute',
left: '6px',
top: '29%',
<div style={{
position: 'absolute',
left: '6px',
top: '29%',
fontSize: '12px',
fontWeight: 'normal',
}}>
soluble
</div>
<div style={{
position: 'absolute',
left: '6px',
top: '62%',
<div style={{
position: 'absolute',
left: '6px',
top: '62%',
fontSize: '12px',
fontWeight: 'normal',
}}>
Expand All @@ -52,52 +52,52 @@ export default function BubblerNode({ data }) {
<Handle type="target" id="sample_in_soluble" position="left" style={{ background: '#555', top: '33%' }} />
<Handle type="target" id="sample_in_insoluble" position="left" style={{ background: '#555', top: '66%' }} />

<div style={{
position: 'absolute',
top: '6px',
left: '6%',
<div style={{
position: 'absolute',
top: '6px',
left: '6%',
fontSize: '12px',
fontWeight: 'normal',
}}>
Vials 1
</div>
<div style={{
position: 'absolute',
top: '6px',
left: '38%',
<div style={{
position: 'absolute',
top: '6px',
left: '38%',
fontSize: '12px',
fontWeight: 'normal',
}}>2</div>

<div style={{
position: 'absolute',
top: '6px',
left: '58%',
<div style={{
position: 'absolute',
top: '6px',
left: '58%',
fontSize: '12px',
fontWeight: 'normal',
}}>
3
</div>
<div style={{
position: 'absolute',
top: '6px',
left: '78%',
<div style={{
position: 'absolute',
top: '6px',
left: '78%',
fontSize: '12px',
fontWeight: 'normal',
}}>
4
</div>

<Handle type="source" id="vial1" position="top" style={{ background: '#555', left: '20%'}} />
<Handle type="source" id="vial1" position="top" style={{ background: '#555', left: '20%' }} />
<Handle type="source" id="vial2" position="top" style={{ background: '#555', left: '40%' }} />
<Handle type="source" id="vial3" position="top" style={{ background: '#555', left: '60%' }} />
<Handle type="source" id="vial4" position="top" style={{ background: '#555', left: '80%' }} />


<div style={{
position: 'absolute',
right: '6px',
bottom: '50%',
<div style={{
position: 'absolute',
right: '6px',
bottom: '50%',
fontSize: '12px',
fontWeight: 'normal',
textAlign: 'right'
Expand Down
Loading
Loading