Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
02bf8de
Move elbow coeffieicnt calc from blanket to pumping
chris-ashe Jun 4, 2026
c4833bd
Add coolant properties to BlanketData class
chris-ashe Jun 4, 2026
21d96fe
Add coolant friction loss parameters and output functions for blanket…
chris-ashe Jun 4, 2026
7deab95
Add function to plot blanket coolant channel structure and update mai…
chris-ashe Jun 4, 2026
777783a
Refactor pressure drop assertions in blanket tests for clarity and co…
chris-ashe Jun 5, 2026
ce16e53
Add function to plot outboard blanket coolant properties along the po…
chris-ashe Jun 5, 2026
5854071
Tidy some variable names to match style guide
chris-ashe Jun 5, 2026
7ba0551
Create mass flow required function and implement
chris-ashe Jun 5, 2026
84e6fc5
🔄 Rename FW and Blkt heat capacity variables
chris-ashe Jun 5, 2026
8cf9faa
Add output for outboard blanket piping
chris-ashe Jun 5, 2026
11f03f9
Add output table for outboard blanket
chris-ashe Jun 5, 2026
20608a0
Refactor coolant friction loss parameters and update related tests
chris-ashe Jun 7, 2026
5576047
Enhance inboard blanket coolant channel output and pressure drop calc…
chris-ashe Jun 7, 2026
8f270d0
Move FW number of bends to FW file
chris-ashe Jun 8, 2026
9c68452
Remove pipe plotting
chris-ashe Jun 8, 2026
95a820f
Update summary positions of tables
chris-ashe Jun 8, 2026
3b043bb
Post rebase fixes
chris-ashe Jun 11, 2026
96202a1
Remove unused CoolProp imports and related plotting functions for out…
chris-ashe Jun 23, 2026
de7d76d
Merge branch 'main' into add_blkt_pipes_output
chris-ashe Jul 2, 2026
c529a74
Post merge coflict fixes
chris-ashe Jul 2, 2026
188a388
Move all of the pumping related function from `BlanketLibrary` into t…
chris-ashe Jul 2, 2026
65deabe
Merge branch 'main' into add_blkt_pipes_output
chris-ashe Jul 3, 2026
9717a9a
Update some output formatting
chris-ashe Jul 3, 2026
e543773
Fix some coolant pumping power function imports
chris-ashe Jul 3, 2026
0bda143
Refactor pumping outputs to be specifically for inboard and outboard …
chris-ashe Jul 3, 2026
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
8 changes: 8 additions & 0 deletions documentation/source/development/standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,14 @@ This should be used for units of $\text{kg} \cdot \text{m}^{-2}\text{s}^{-1}$

---------------------

##### Specific Heat Capacities

- Specific heat capacities for materials $[\text{J/kg/K}]$ should start with the `heatcap_` prefix
- Specific heat capacities at constant volume should start with the `heatcap_vol_` pefix
- Specific heat capacities at constant pressure should start with the `heatcap_pres_` pefix

---------------------

##### Pressures

- Pressures should start with the `pres_` prefix
Expand Down
97 changes: 0 additions & 97 deletions documentation/source/eng-models/blanket_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,100 +5,3 @@

--------------------

### Coolant mechanical pumping power | `coolant_pumping_power()`

To calculate the coolant pumping power we use the change in enthalpies of the coolant as it goes through the pump.
**We assume the pump is isentropic so the entropy change of the coolant is 0**.

The mechanical pumping power is defined as:

$$
P = \frac{\frac{\dot{m} \times \left(H_{\text{out}}-H_{\text{in}}\right)}{\eta}}{\left(1-fp\right)}
$$

where $\dot{m}$ is the coolant mass flow rate, $H$ is the coolant enthalpy, $\eta$ is the isentropic efficiency of the pump and $\gamma$ is the adiabatic index of the coolant.

$$
fp = \frac{T_{\text{pump,out}}\left(\frac{P_{\text{pump,out}}}{P_{\text{pump,in}}}\right)^{-\frac{\gamma -1}{\gamma}}}{\eta \left(T_{\text{pump,in}}-T_{\text{pump,out}}\right)}
$$

------------------

### Coolant pressure drop | `coolant_friction_pressure_drop()`

The pressure drop in the coolant is given by the [Darcy-Weisbach Equation](https://en.wikipedia.org/wiki/Darcy%E2%80%93Weisbach_equation)

For a cylindrical pipe of uniform diameter the pressure loss due to viscous effects can be characterized by:

$$
\Delta P = L\left[f_{\text{D}}\frac{\rho}{2}\frac{\langle v \rangle^2}{D_{\text{H}}}\right]
$$

where $L$ is the pipe length, $f_{\text{D}}$ is the [Darcy friction factor](https://en.wikipedia.org/wiki/Darcy_friction_factor_formulae), $\rho$ is the coolant density, $\langle v \rangle$ is the mean flow coolant velocity and $D_{\text{H}}$ is the hydraulic diameter or the pipe diameter in this case.

To find the Darcy friction factor we need to know the Reynolds number given by:

$$
\text{Re} = \frac{\rho v L}{\mu}
$$

here $L$ is the characteristic length which we set to be the pipe diameter and $\mu$ is the coolant dynamic viscosity.

Using the Reynolds number we calculate the Darcy friction factor using the Haaland approximation calculated by [`darcy_friction_haaland()`](../eng-models/generic_methods/pumping.md#pumping-coolant-friction--darcy_friction_haaland).

For the radius of the pipe bend we assume it to be 3 times the radius of the coolant channel.

The elbow coefficients for the 90 and 180 degree bends $\left(f_{\text{90,elbow}}, f_{\text{180,elbow}}\right)$ are calculated via [`elbow_coeff()`](#pipe-bend-elbow-coefficient--elbow_coeff).

The pressure drop for the straights along the entire pipe length is the same as above:

$$
\Delta P = L\left[f_{\text{D}}\frac{\rho}{2}\frac{\langle v \rangle^2}{D_{\text{H}}}\right]
$$

where we define $\frac{f_{\text{D}}L}{D_{\text{H}}}$ as our straight section coefficient.

The pressure drop for the 90 and 180 degree bends are:

$$
\Delta P = N_{\text{90}} \left[f_{\text{90,elbow}} \frac{\rho \langle v \rangle^2}{2}\right]
$$

$$
\Delta P = N_{\text{180}} \left[f_{\text{180,elbow}} \frac{\rho \langle v \rangle^2}{2}\right]
$$

where $N_{\text{90}}$ and $N_{\text{180}}$ are the number of 90 and 180 degree bends in the system.

The total returned pressure drop is simply:

$$
\Delta P = L\left[f_{\text{D}}\frac{\rho}{2}\frac{\langle v \rangle^2}{D_{\text{H}}}\right] + N_{\text{90}} \left[f_{\text{90,elbow}} \frac{\rho \langle v \rangle^2}{2}\right] + N_{\text{180}} \left[f_{\text{180,elbow}} \frac{\rho \langle v \rangle^2}{2}\right]
$$

-------------------

### Pipe bend elbow coefficient | `elbow_coeff()`

This function calculates the elbow bend coefficients for pressure drop calculations.

$$
a = 1.0 \quad \text{if} \ \theta = 90^{\circ} \\
a = 0.9 \times \sin{\left(\frac{\theta \pi}{180^{\circ}}\right)} \quad \text{if} \ \theta < 70^{\circ} \\
a = 0.7 + 0.35 \times \sin{\left(\frac{\theta}{90^{\circ}} \times \frac{\pi}{180^{\circ}}\right)} \quad \text{if} \ \theta > 90^{\circ} \\
$$

where $\theta$ is the angle of the pipe bend.

$$
b = \frac{0.21}{\sqrt{\frac{R_{\text{elbow}}}{D_{\text{pipe}}}}}\quad \text{if} \ \frac{R_{\text{elbow}}}{D_{\text{pipe}}} \ge 1 \\
b = \frac{0.21}{\left(\frac{R_{\text{elbow}}}{D_{\text{pipe}}}\right)^{2.5}}\quad \text{if} \ \frac{R_{\text{elbow}}}{D_{\text{pipe}}} \le 1 \\
\text{else} \quad b =0.21
$$

The elbow coefficient is given by:

$$
ab + \left( f_{\text{D}} \times \frac{R_{\text{elbow}}}{D_{\text{pipe}}}\right) \times \theta \times \left(\frac{\pi}{180^{\circ}}\right)
$$

131 changes: 130 additions & 1 deletion documentation/source/eng-models/generic_methods/pumping.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,80 @@
# Pumping Methods


## Coolant mechanical pumping power | `coolant_pumping_power()`

To calculate the coolant pumping power we use the change in enthalpies of the coolant as it goes through the pump.
**We assume the pump is isentropic so the entropy change of the coolant is 0**.

The mechanical pumping power is defined as:

$$
P = \frac{\frac{\dot{m} \times \left(H_{\text{out}}-H_{\text{in}}\right)}{\eta}}{\left(1-fp\right)}
$$

where $\dot{m}$ is the coolant mass flow rate, $H$ is the coolant enthalpy, $\eta$ is the isentropic efficiency of the pump and $\gamma$ is the adiabatic index of the coolant.

$$
fp = \frac{T_{\text{pump,out}}\left(\frac{P_{\text{pump,out}}}{P_{\text{pump,in}}}\right)^{-\frac{\gamma -1}{\gamma}}}{\eta \left(T_{\text{pump,in}}-T_{\text{pump,out}}\right)}
$$

------------------

## Coolant pressure drop | `coolant_friction_pressure_drop()`

The pressure drop in the coolant is given by the [Darcy-Weisbach Equation](https://en.wikipedia.org/wiki/Darcy%E2%80%93Weisbach_equation)

For a cylindrical pipe of uniform diameter the pressure loss due to viscous effects can be characterized by:

$$
\Delta P = L\left[f_{\text{D}}\frac{\rho}{2}\frac{\langle v \rangle^2}{D_{\text{H}}}\right]
$$

where $L$ is the pipe length, $f_{\text{D}}$ is the [Darcy friction factor](https://en.wikipedia.org/wiki/Darcy_friction_factor_formulae), $\rho$ is the coolant density, $\langle v \rangle$ is the mean flow coolant velocity and $D_{\text{H}}$ is the hydraulic diameter or the pipe diameter in this case.

To find the Darcy friction factor we need to know the Reynolds number given by:

$$
\text{Re} = \frac{\rho v L}{\mu}
$$

here $L$ is the characteristic length which we set to be the pipe diameter and $\mu$ is the coolant dynamic viscosity.

Using the Reynolds number we calculate the Darcy friction factor using the Haaland approximation calculated by [`darcy_friction_haaland()`](../eng-models/generic_methods/pumping.md#pumping-coolant-friction--darcy_friction_haaland).

For the radius of the pipe bend we assume it to be 3 times the radius of the coolant channel.

The elbow coefficients for the 90 and 180 degree bends $\left(f_{\text{90,elbow}}, f_{\text{180,elbow}}\right)$ are calculated via [`elbow_coeff()`](#pipe-bend-elbow-coefficient--elbow_coeff).

The pressure drop for the straights along the entire pipe length is the same as above:

$$
\Delta P = L\left[f_{\text{D}}\frac{\rho}{2}\frac{\langle v \rangle^2}{D_{\text{H}}}\right]
$$

where we define $\frac{f_{\text{D}}L}{D_{\text{H}}}$ as our straight section coefficient.

The pressure drop for the 90 and 180 degree bends are:

$$
\Delta P = N_{\text{90}} \left[f_{\text{90,elbow}} \frac{\rho \langle v \rangle^2}{2}\right]
$$

$$
\Delta P = N_{\text{180}} \left[f_{\text{180,elbow}} \frac{\rho \langle v \rangle^2}{2}\right]
$$

where $N_{\text{90}}$ and $N_{\text{180}}$ are the number of 90 and 180 degree bends in the system.

The total returned pressure drop is simply:

$$
\Delta P = L\left[f_{\text{D}}\frac{\rho}{2}\frac{\langle v \rangle^2}{D_{\text{H}}}\right] + N_{\text{90}} \left[f_{\text{90,elbow}} \frac{\rho \langle v \rangle^2}{2}\right] + N_{\text{180}} \left[f_{\text{180,elbow}} \frac{\rho \langle v \rangle^2}{2}\right]
$$

-------------------


## Pumping coolant friction | `darcy_friction_haaland()`

The pressure drop is based on the Darcy friction factor, using the [Haaland equation](https://en.wikipedia.org/wiki/Darcy_friction_factor_formulae#Haaland_equation), an approximation to the implicit Colebrook–White equation.
Expand Down Expand Up @@ -61,4 +136,58 @@ where $\rho$ is the coolant density and $\mu$ is the coolant viscosity.

$$
h = \frac{\mathrm{Nu_D}k}{2r_{\text{channel}}}
$$
$$

-------------------------

## Pipe bend elbow coefficient | `elbow_coeff()`

This function calculates the elbow bend coefficients for pressure drop calculations.

$$
a = 1.0 \quad \text{if} \ \theta = 90^{\circ} \\
a = 0.9 \times \sin{\left(\frac{\theta \pi}{180^{\circ}}\right)} \quad \text{if} \ \theta < 70^{\circ} \\
a = 0.7 + 0.35 \times \sin{\left(\frac{\theta}{90^{\circ}} \times \frac{\pi}{180^{\circ}}\right)} \quad \text{if} \ \theta > 90^{\circ} \\
$$

where $\theta$ is the angle of the pipe bend.

$$
b = \frac{0.21}{\sqrt{\frac{R_{\text{elbow}}}{D_{\text{pipe}}}}}\quad \text{if} \ \frac{R_{\text{elbow}}}{D_{\text{pipe}}} \ge 1 \\
b = \frac{0.21}{\left(\frac{R_{\text{elbow}}}{D_{\text{pipe}}}\right)^{2.5}}\quad \text{if} \ \frac{R_{\text{elbow}}}{D_{\text{pipe}}} \le 1 \\
\text{else} \quad b =0.21
$$

The elbow coefficient is given by:

$$
ab + \left( f_{\text{D}} \times \frac{R_{\text{elbow}}}{D_{\text{pipe}}}\right) \times \theta \times \left(\frac{\pi}{180^{\circ}}\right)
$$

--------------

## Required mass flow rate | `calculate_required_mass_flow_rate()`

The required mass flow rate of a coolant is given simply by the fundamental heat transfer equation:

$$
\dot{m} = \frac{P}{c_{\text{p}}(T)\times \Delta T}
$$

where $\dot{m}$ is the required mass flow rate in, $P$ is the heating power to be removed, $c_{\text{p}}$ is the coolant specific heat capacity for constant pressure and $\Delta T$ is the temperature change in the coolant.

!!! note "Variation specific heat capacity"

The heat capacity itself is a function of temperature. Therefore it is common to use the heat capacity value at the simple average between the initial and final temperature.
This however assumes a linear relationship. Ideally the equation should be solves as:

$$
\dot{m} = \frac{P}{\int_{T_{\text{in}}}^{T_{\text{in}}}c_{\text{p}}(T) dT}
$$


!!! info "Choice of specific heat capacity"

For pumping, the specific heat capacity for constant pressure $(c_{\text{p}})$ is used as cooling loops are open-flow systems where the fluid moves continuously through pipes, heat exchangers, and pumps. As the coolant heats up, it expands freely along the loop. Because it is free to expand, the local pressure remains relatively constant while the volume changes.

You would only use the specific heat capacity for constant volume $(c_{\text{v}})$ if the coolant was completely sealed inside a rigid, unyielding container with zero flow, where heating it would cause the pressure to spike but the volume to stay exactly the same.
98 changes: 90 additions & 8 deletions process/core/io/plot/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -15298,6 +15298,89 @@ def plot_cs_radial_stress_profile(
axis.legend(loc="best")


def plot_blanket_coolant_channel_structure_and_properties(
fig: plt.Figure, m_file: MFile, scan: int
):
"""Combined plot of blanket coolant channel structure and properties."""
# Add info about the Winding Pack
textstr_outboard_blkt = (
f"$\\mathbf{{Outboard \\ blanket:}}$\n \n"
f"Radius of blanket channel: {m_file.get('radius_blkt_channel', scan=scan):.4f} m\n"
f"Channel roughness ($\\epsilon$): {m_file.get('roughness_fw_channel', scan=scan):.4e} m\n\n"
f"Radial coolant channel length: {m_file.get('len_blkt_outboard_coolant_channel_radial', scan=scan):.4f} m\n"
f"Poloidal coolant channel length: {m_file.get('len_blkt_outboard_segment_poloidal', scan=scan):.4f} m\n"
f"Number of radial channels: {m_file.get('n_blkt_outboard_module_coolant_sections_radial', scan=scan)}\n"
f"Number of poloidal channels: {m_file.get('n_blkt_outboard_module_coolant_sections_poloidal', scan=scan)}\n"
f"Total length of coolant channel straight sections: {m_file.get('len_blkt_outboard_channel_total', scan=scan):.4f} m\n\n"
f"Pressure drop for straight sections: {m_file.get('dpres_blkt_outboard_coolant_channel_straight_total', scan=scan):.2e} Pa\n"
f"Pressure drop for 90° bends: {m_file.get('dpres_blkt_outboard_coolant_channel_90_bend', scan=scan):.2e} Pa\n"
f"Total pressure drop for 90° bends: {m_file.get('dpres_blkt_outboard_coolant_channel_90_bends_total', scan=scan):.2e} Pa\n"
f"Pressure drop for 180° bends: {m_file.get('dpres_blkt_outboard_coolant_channel_180_bend', scan=scan):.2e} Pa\n"
f"Total pressure drop for 180° bends: {m_file.get('dpres_blkt_outboard_coolant_channel_180_bends_total', scan=scan):.2e} Pa\n"
f"Total pressure drop for all bends: {m_file.get('dpres_blkt_outboard_bends_total', scan=scan):.2e} Pa\n\n"
f"Reynolds number ($Re$): {m_file.get('reynolds_blkt_outboard_coolant', scan=scan):.4f}\n"
f"Darcy Friction factor ($f$): {m_file.get('darcy_frict_blkt_outboard_coolant', scan=scan):.4f}\n\n"
f"Friction drop coefficient for straight sections: {m_file.get('f_straight_blkt_outboard_coolant', scan=scan):.4f}\n"
f"Friction drop coefficient for 90° bends: {m_file.get('f_elbow_blkt_outboard_90_bend', scan=scan):.4f}\n"
f"Friction drop coefficient for 180° bends: {m_file.get('f_elbow_blkt_outboard_180_bend', scan=scan):.4f}\n"
)

fig.text(
0.5,
0.5,
textstr_outboard_blkt,
fontsize=9,
verticalalignment="top",
horizontalalignment="left",
transform=fig.transFigure,
bbox={
"boxstyle": "round",
"facecolor": "wheat",
"alpha": 1.0,
"linewidth": 2,
},
)

# Add info about the Winding Pack
textstr_inboard_blkt = (
f"$\\mathbf{{Inboard \\ blanket:}}$\n \n"
f"Radius of blanket channel: {m_file.get('radius_blkt_channel', scan=scan):.4f} m\n"
f"Channel roughness ($\\epsilon$): {m_file.get('roughness_fw_channel', scan=scan):.4e} m\n\n"
f"Radial coolant channel length: {m_file.get('len_blkt_inboard_coolant_channel_radial', scan=scan):.4f} m\n"
f"Poloidal coolant channel length: {m_file.get('len_blkt_inboard_segment_poloidal', scan=scan):.4f} m\n"
f"Number of radial channels: {m_file.get('n_blkt_inboard_module_coolant_sections_radial', scan=scan)}\n"
f"Number of poloidal channels: {m_file.get('n_blkt_inboard_module_coolant_sections_poloidal', scan=scan)}\n"
f"Total length of coolant channel straight sections: {m_file.get('len_blkt_inboard_channel_total', scan=scan):.4f} m\n\n"
f"Pressure drop for straight sections: {m_file.get('dpres_blkt_inboard_coolant_channel_straight_total', scan=scan):.2e} Pa\n"
f"Pressure drop for 90° bends: {m_file.get('dpres_blkt_inboard_coolant_channel_90_bend', scan=scan):.2e} Pa\n"
f"Total pressure drop for 90° bends: {m_file.get('dpres_blkt_inboard_coolant_channel_90_bends_total', scan=scan):.2e} Pa\n"
f"Pressure drop for 180° bends: {m_file.get('dpres_blkt_inboard_coolant_channel_180_bend', scan=scan):.2e} Pa\n"
f"Total pressure drop for 180° bends: {m_file.get('dpres_blkt_inboard_coolant_channel_180_bends_total', scan=scan):.2e} Pa\n"
f"Total pressure drop for all bends: {m_file.get('dpres_blkt_inboard_bends_total', scan=scan):.2e} Pa\n\n"
f"Reynolds number ($Re$): {m_file.get('reynolds_blkt_inboard_coolant', scan=scan):.4f}\n"
f"Darcy Friction factor ($f$): {m_file.get('darcy_frict_blkt_inboard_coolant', scan=scan):.4f}\n\n"
f"Friction drop coefficient for straight sections: {m_file.get('f_straight_blkt_inboard_coolant', scan=scan):.4f}\n"
f"Friction drop coefficient for 90° bends: {m_file.get('f_elbow_blkt_inboard_90_bend', scan=scan):.4f}\n"
f"Friction drop coefficient for 180° bends: {m_file.get('f_elbow_blkt_inboard_180_bend', scan=scan):.4f}\n"
)

fig.text(
0.1,
0.5,
textstr_inboard_blkt,
fontsize=9,
verticalalignment="top",
horizontalalignment="left",
transform=fig.transFigure,
bbox={
"boxstyle": "round",
"facecolor": "wheat",
"alpha": 1.0,
"linewidth": 2,
},
)


def main_plot(
m_file: MFile,
scan: int,
Expand Down Expand Up @@ -15759,15 +15842,14 @@ def _add_page(name: str | None = None):
)
plot_fw_90_deg_pipe_bend(pages["fw_td_cross_section"].add_subplot(337), m_file, scan)

plot_blkt_pipe_bends(_add_page("blkt_pipe_bends"), m_file, scan)
ax_blanket = pages["blkt_pipe_bends"].add_subplot(122, aspect="equal")
ax_blanket = _add_page("blkt_structure").add_subplot(122, aspect="equal")
plot_blkt_structure(
ax_blanket,
pages["blkt_pipe_bends"],
m_file,
scan,
radial_build,
colour_scheme,
ax_blanket, pages["blkt_structure"], m_file, scan, radial_build, colour_scheme
)

plot_blkt_pipe_bends(_add_page("blkt_cooling"), m_file, scan)
plot_blanket_coolant_channel_structure_and_properties(
pages["blkt_cooling"], m_file, scan
)

plot_main_power_flow(
Expand Down
6 changes: 6 additions & 0 deletions process/core/output.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from process.core.log import logging_model_handler
from process.data_structure.blanket_variables import BlktModelTypes
from process.data_structure.build_variables import InboardBlanketConfiguration
from process.models.tfcoil.base import TFConductorModel
from process.models.tfcoil.superconducting import (
SuperconductingTFTurnType,
Expand Down Expand Up @@ -127,6 +128,11 @@ def write(models, data, _outfile):
# DCLL model
models.dcll.output()

if data.build.i_blkt_inboard == InboardBlanketConfiguration.INBOARD_BLANKET_PRESENT:
models.blanket_library.output_inboard_blkt_pumping_variables()

models.blanket_library.output_outboard_blkt_pumping_variables()

# FISPACT and LOCA model (not used)- removed

# Power model
Expand Down
Loading