Skip to content
Open
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
2856654
Add VacuumVessel class and integrate into Caller model
chris-ashe Dec 5, 2025
c8f1ad4
Add calculate_dshaped_vessel_volumes method to VacuumVessel class
chris-ashe Dec 5, 2025
223eaa8
Add calculate_elliptical_vessel_volumes method to VacuumVessel class
chris-ashe Dec 5, 2025
134a43c
:fire: Remove now redundant vacuum calcs from blanket library
chris-ashe Jan 7, 2026
25635e0
Refactor BlanketLibrary: remove vacuum vessel calculations and update…
chris-ashe Jan 20, 2026
4dfb4a2
Add tests for DShaped vessel volume calculations in vacuum module
chris-ashe Jan 20, 2026
3252aeb
Add Shield class with calculate_shield_half_height method
chris-ashe Jan 23, 2026
c56de6c
Add calculate_dshaped_shield_volumes method to Shield class
chris-ashe Jan 23, 2026
06496a5
Add calculate_dshaped_shield_areas method to Shield class
chris-ashe Jan 23, 2026
64e913d
Add calculate_elliptical_shield_volumes method to Shield class
chris-ashe Jan 23, 2026
dcfe308
Add calculate_elliptical_shield_areas method to Shield class
chris-ashe Jan 23, 2026
9ec634c
Add Shield model integration to Caller and Models classes
chris-ashe Jan 23, 2026
fae93af
Implement shield area and volume calculations in run method of Shield…
chris-ashe Jan 23, 2026
d434e7b
Refactor BlanketLibrary to remove shield component calculations and s…
chris-ashe Jan 23, 2026
c03473b
Add unit test for elliptical shield volumes calculation
chris-ashe Jan 23, 2026
be1dc32
Add unit test for elliptical shield areas calculation
chris-ashe Jan 23, 2026
2976730
Add unit test for D-shaped shield volumes calculation
chris-ashe Jan 23, 2026
e31d32a
Add unit test for D-shaped shield areas calculation
chris-ashe Jan 23, 2026
9c4b508
Remove redundant D-shaped component parameters from test cases
chris-ashe Jan 23, 2026
35f690c
Remove redundant EllipticalComponentParam test cases
chris-ashe Jan 23, 2026
51f8c08
Post rebase changes
chris-ashe Jan 29, 2026
c6b1da3
Remove redundant shield surface parameters from ApplyCoverageFactorsP…
chris-ashe Jan 29, 2026
472208a
Requested style changes
chris-ashe Jan 30, 2026
dde3844
Add vacuum vessel mass calculation to VacuumVessel class
chris-ashe Jan 30, 2026
6280dc6
Add docstring to vacuum vessel volume calculation method
chris-ashe Jan 30, 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
247 changes: 49 additions & 198 deletions process/blanket_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,14 @@ def component_volumes(self):
# Calculate half-height
# Blanket
blanket_library.dz_blkt_half = self.component_half_height(icomponent=0)
# Shield
blanket_library.dz_shld_half = self.component_half_height(icomponent=1)
# Vacuum Vessel
blanket_library.dz_vv_half = self.component_half_height(icomponent=2)

# D-shaped blanket and shield
if physics_variables.itart == 1 or fwbs_variables.i_fw_blkt_vv_shape == 1:
for icomponent in range(3):
self.dshaped_component(icomponent)
self.dshaped_component()

# Elliptical blanket and shield
else:
for icomponent in range(3):
self.elliptical_component(icomponent)

# This will fail the hts_REBCO and 2D_scan regression tests,
# the number of VMCON iterations (nviter) is different.
# Seems to be because in the blanket calculations (icomponent=0):
# r2 = 1.3836567143743970 rather than old value of r2 = 1.3836567143743972,
# r3 = 3.7009701431231936 rather than r3 = 3.7009701431231923.
self.elliptical_component()

# Apply coverage factors to volumes and surface areas
self.apply_coverage_factors()
Expand All @@ -94,22 +82,6 @@ def component_half_height(self, icomponent: int):
+ divertor_variables.dz_divertor
- build_variables.dz_blkt_upper
)
# Sheild
elif icomponent == 1:
hbot = (
build_variables.z_plasma_xpoint_lower
+ build_variables.dz_xpoint_divertor
+ divertor_variables.dz_divertor
)
# Vacuum vessel
elif icomponent == 2:
hbot = (
build_variables.z_tf_inside_half
- build_variables.dz_shld_vv_gap
- build_variables.dz_vv_lower
)
else:
raise ProcessValueError(f"{icomponent=} is invalid, it must be either 0,1,2")

# Calculate component internal upper half-height (m)
# If a double null machine then symmetric
Expand All @@ -123,19 +95,11 @@ def component_half_height(self, icomponent: int):
+ build_variables.dr_fw_inboard
+ build_variables.dr_fw_outboard
)
# Shield
if icomponent == 1:
htop = htop + build_variables.dz_blkt_upper
# Vacuum Vessel
if icomponent == 2:
htop = (
htop + build_variables.dz_blkt_upper + build_variables.dz_shld_upper
)

# Average of top and bottom (m)
return 0.5 * (htop + hbot)

def dshaped_component(self, icomponent: int):
def dshaped_component(self):
"""Calculate component surface area and volume using dshaped scheme
Based on dshaped_blanket, dshaped_shield, dshaped_vv
original author: J. Morris, CCFE, Culham Science Centre
Expand All @@ -144,12 +108,10 @@ def dshaped_component(self, icomponent: int):
# Calculate major radius to outer edge of inboard ...
# ... section (m)
r1 = build_variables.r_shld_inboard_inner
# ... shield (m)
if icomponent == 1:
r1 = r1 + build_variables.dr_shld_inboard

# ... blanket (m)
elif icomponent == 0:
r1 = r1 + build_variables.dr_shld_inboard + build_variables.dr_blkt_inboard

r1 = r1 + build_variables.dr_shld_inboard + build_variables.dr_blkt_inboard

# Horizontal distance between inside edges (m)
# i.e. outer radius of inboard part to inner radius of outboard part
Expand All @@ -161,69 +123,27 @@ def dshaped_component(self, icomponent: int):
+ build_variables.dr_fw_plasma_gap_outboard
+ build_variables.dr_fw_outboard
)
# Sheild
if icomponent == 1:
r2 = build_variables.dr_blkt_inboard + r2 + build_variables.dr_blkt_outboard
# Vaccum Vessel
if icomponent == 2:
r2 = build_variables.r_shld_outboard_outer - r1

# Calculate surface area, assuming 100% coverage
if icomponent == 0:
(
build_variables.a_blkt_inboard_surface,
build_variables.a_blkt_outboard_surface,
build_variables.a_blkt_total_surface,
) = dshellarea(r1, r2, blanket_library.dz_blkt_half)
if icomponent == 1:
(
build_variables.a_shld_inboard_surface,
build_variables.a_shld_outboard_surface,
build_variables.a_shld_total_surface,
) = dshellarea(r1, r2, blanket_library.dz_shld_half)
(
build_variables.a_blkt_inboard_surface,
build_variables.a_blkt_outboard_surface,
build_variables.a_blkt_total_surface,
) = dshellarea(r1, r2, blanket_library.dz_blkt_half)

# Calculate volumes, assuming 100% coverage
if icomponent == 0:
(
fwbs_variables.vol_blkt_inboard,
fwbs_variables.vol_blkt_outboard,
fwbs_variables.vol_blkt_total,
) = dshellvol(
r1,
r2,
blanket_library.dz_blkt_half,
build_variables.dr_blkt_inboard,
build_variables.dr_blkt_outboard,
build_variables.dz_blkt_upper,
)
elif icomponent == 1:
(
blanket_library.vol_shld_inboard,
blanket_library.vol_shld_outboard,
fwbs_variables.vol_shld_total,
) = dshellvol(
r1,
r2,
blanket_library.dz_shld_half,
build_variables.dr_shld_inboard,
build_variables.dr_shld_outboard,
build_variables.dz_shld_upper,
)
elif icomponent == 2:
(
blanket_library.vol_vv_inboard,
blanket_library.vol_vv_outboard,
fwbs_variables.vol_vv,
) = dshellvol(
r1,
r2,
blanket_library.dz_vv_half,
build_variables.dr_vv_inboard,
build_variables.dr_vv_outboard,
(build_variables.dz_vv_upper + build_variables.dz_vv_lower) / 2,
)

def elliptical_component(self, icomponent: int):
(
fwbs_variables.vol_blkt_inboard,
fwbs_variables.vol_blkt_outboard,
fwbs_variables.vol_blkt_total,
) = dshellvol(
r1,
r2,
blanket_library.dz_blkt_half,
build_variables.dr_blkt_inboard,
build_variables.dr_blkt_outboard,
build_variables.dz_blkt_upper,
)

def elliptical_component(self):
"""Calculate component surface area and volume using elliptical scheme
Based on elliptical_blanket, elliptical_shield, elliptical_vv
original author: J. Morris, CCFE, Culham Science Centre
Expand All @@ -239,80 +159,38 @@ def elliptical_component(self, icomponent: int):
# Calculate distance between r1 and outer edge of inboard ...
# ... section (m)
r2 = r1 - build_variables.r_shld_inboard_inner
# ... shield (m)
if icomponent == 1:
r2 = r2 - build_variables.dr_shld_inboard
# ... blanket (m)
if icomponent == 0:
r2 = r2 - build_variables.dr_shld_inboard - build_variables.dr_blkt_inboard

r2 = r2 - build_variables.dr_shld_inboard - build_variables.dr_blkt_inboard

# Calculate distance between r1 and inner edge of outboard ...
# ... section (m)
r3 = build_variables.r_shld_outboard_outer - r1
# ... shield (m)
if icomponent == 1:
r3 = r3 - build_variables.dr_shld_outboard
# ... blanket (m)
if icomponent == 0:
r3 = r3 - build_variables.dr_shld_outboard - build_variables.dr_blkt_outboard

r3 = r3 - build_variables.dr_shld_outboard - build_variables.dr_blkt_outboard

# Calculate surface area, assuming 100% coverage
if icomponent == 0:
(
build_variables.a_blkt_inboard_surface,
build_variables.a_blkt_outboard_surface,
build_variables.a_blkt_total_surface,
) = eshellarea(r1, r2, r3, blanket_library.dz_blkt_half)
if icomponent == 1:
(
build_variables.a_shld_inboard_surface,
build_variables.a_shld_outboard_surface,
build_variables.a_shld_total_surface,
) = eshellarea(r1, r2, r3, blanket_library.dz_shld_half)

(
build_variables.a_blkt_inboard_surface,
build_variables.a_blkt_outboard_surface,
build_variables.a_blkt_total_surface,
) = eshellarea(r1, r2, r3, blanket_library.dz_blkt_half)

# Calculate volumes, assuming 100% coverage
if icomponent == 0:
(
fwbs_variables.vol_blkt_inboard,
fwbs_variables.vol_blkt_outboard,
fwbs_variables.vol_blkt_total,
) = eshellvol(
r1,
r2,
r3,
blanket_library.dz_blkt_half,
build_variables.dr_blkt_inboard,
build_variables.dr_blkt_outboard,
build_variables.dz_blkt_upper,
)
if icomponent == 1:
(
blanket_library.vol_shld_inboard,
blanket_library.vol_shld_outboard,
fwbs_variables.vol_shld_total,
) = eshellvol(
r1,
r2,
r3,
blanket_library.dz_shld_half,
build_variables.dr_shld_inboard,
build_variables.dr_shld_outboard,
build_variables.dz_shld_upper,
)
if icomponent == 2:
(
blanket_library.vol_vv_inboard,
blanket_library.vol_vv_outboard,
fwbs_variables.vol_vv,
) = eshellvol(
r1,
r2,
r3,
blanket_library.dz_vv_half,
build_variables.dr_vv_inboard,
build_variables.dr_vv_outboard,
(build_variables.dz_vv_upper + build_variables.dz_vv_lower) / 2,
)

(
fwbs_variables.vol_blkt_inboard,
fwbs_variables.vol_blkt_outboard,
fwbs_variables.vol_blkt_total,
) = eshellvol(
r1,
r2,
r3,
blanket_library.dz_blkt_half,
build_variables.dr_blkt_inboard,
build_variables.dr_blkt_outboard,
build_variables.dz_blkt_upper,
)

def apply_coverage_factors(self):
"""Apply coverage factors to volumes
Expand Down Expand Up @@ -361,33 +239,6 @@ def apply_coverage_factors(self):
fwbs_variables.vol_blkt_inboard + fwbs_variables.vol_blkt_outboard
)

# Apply shield coverage factors
build_variables.a_shld_inboard_surface = (
fwbs_variables.fvolsi * build_variables.a_shld_inboard_surface
)
build_variables.a_shld_outboard_surface = (
fwbs_variables.fvolso * build_variables.a_shld_outboard_surface
)
build_variables.a_shld_total_surface = (
build_variables.a_shld_inboard_surface
+ build_variables.a_shld_outboard_surface
)

blanket_library.vol_shld_inboard = (
fwbs_variables.fvolsi * blanket_library.vol_shld_inboard
)
blanket_library.vol_shld_outboard = (
fwbs_variables.fvolso * blanket_library.vol_shld_outboard
)
fwbs_variables.vol_shld_total = (
blanket_library.vol_shld_inboard + blanket_library.vol_shld_outboard
)

# Apply vacuum vessel coverage factor
# moved from dshaped_* and elliptical_* to keep coverage factor
# changes in the same location.
fwbs_variables.vol_vv = fwbs_variables.fvoldw * fwbs_variables.vol_vv

def primary_coolant_properties(self, output: bool):
"""Calculates the fluid properties of the Primary Coolant in the FW and BZ.
Uses middle value of input and output temperatures of coolant.
Expand Down
4 changes: 4 additions & 0 deletions process/caller.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ def _call_models_once(self, xc: np.ndarray) -> None:
# First wall model
self.models.fw.run()

self.models.shield.run()

self.models.vacuum_vessel.run()

# Blanket model
"""Blanket switch values
No. | model
Expand Down
3 changes: 0 additions & 3 deletions process/cryostat.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ def external_cryo_geometry() -> None:
* (build_variables.dr_cryostat + fwbs_variables.z_cryostat_half_inside)
) - (fwbs_variables.vol_cryostat_internal)

# Vacuum vessel mass (kg)
fwbs_variables.m_vv = fwbs_variables.vol_vv * fwbs_variables.den_steel

# Sum of internal vacuum vessel and cryostat masses (kg)
fwbs_variables.dewmkg = (
fwbs_variables.vol_vv + fwbs_variables.vol_cryostat
Expand Down
5 changes: 4 additions & 1 deletion process/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,12 @@
from process.pulse import Pulse
from process.resistive_tf_coil import AluminiumTFCoil, CopperTFCoil, ResistiveTFCoil
from process.scan import Scan
from process.shield import Shield
from process.stellarator import Neoclassics, Stellarator
from process.structure import Structure
from process.superconducting_tf_coil import SuperconductingTFCoil
from process.tf_coil import TFCoil
from process.vacuum import Vacuum
from process.vacuum import Vacuum, VacuumVessel
from process.water_use import WaterUse

os.environ["PYTHON_PROCESS_ROOT"] = os.path.join(os.path.dirname(__file__))
Expand Down Expand Up @@ -664,8 +665,10 @@ def __init__(self):
self.availability = Availability()
self.buildings = Buildings()
self.vacuum = Vacuum()
self.vacuum_vessel = VacuumVessel()
self.water_use = WaterUse()
self.pulse = Pulse()
self.shield = Shield()
self.ife = IFE(availability=self.availability, costs=self.costs)
self.plasma_profile = PlasmaProfile()
self.fw = Fw()
Expand Down
Loading