Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
ae99919
Add poloidal angle attributes for inboard and outboard blankets
chris-ashe Apr 28, 2026
36d1337
Add calculation for outboard blanket poloidal angle subtended by plasma
chris-ashe Apr 28, 2026
c832dd0
Add poloidal angle visualization for blanket structure in plot
chris-ashe Apr 28, 2026
85e6c94
Add calculation and visualization for inboard blanket poloidal angle
chris-ashe Apr 28, 2026
a70ea9e
Add outboard blanket poloidal angle calculation and update plot annot…
chris-ashe Apr 28, 2026
98f7eb1
Add divertor poloidal angle subtended by plasma variable
chris-ashe Apr 28, 2026
459fb40
Add calculation and visualization for divertor poloidal angle subtend…
chris-ashe Apr 28, 2026
ea9c856
Add divertor poloidal angle output and calculation updates
chris-ashe Apr 28, 2026
1ee1086
Remove major radius line plotting from blanket structure visualization
chris-ashe Apr 28, 2026
73aba31
Add fractions for outboard and inboard blanket poloidal angles subten…
chris-ashe Apr 28, 2026
eb7d886
Add calculations and output for blanket poloidal angles subtended by …
chris-ashe Apr 28, 2026
7dc5212
Adjust font sizes and z-order for blanket and divertor angle labels i…
chris-ashe Apr 28, 2026
4a3fd63
Enhance BLKT structure plotting by adding poloidal angle annotations …
chris-ashe Apr 28, 2026
c3f823b
Fix calculation of single divertor angle to use inboard blanket poloi…
chris-ashe Apr 28, 2026
ff8b4ed
Add unit test for calculating inboard blanket poloidal plasma angle
chris-ashe Apr 28, 2026
da28c9e
Remove obsolete variable 'f_ster_div_single' from input variables and…
chris-ashe Apr 28, 2026
d5eb5b7
Add calculations for blanket poloidal plasma angles in DCLL class
chris-ashe Apr 28, 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
3 changes: 0 additions & 3 deletions process/core/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,9 +764,6 @@ def __post_init__(self):
"fjohc0": InputVariable(
data_structure.constraint_variables, float, range=(0.001, 1.0)
),
"f_ster_div_single": InputVariable(
data_structure.fwbs_variables, float, range=(0.0, 1.0)
),
"fdiva": InputVariable(data_structure.divertor_variables, float, range=(0.1, 2.0)),
"fdivwet": InputVariable(
data_structure.stellarator_variables, float, range=(0.01, 1.0)
Expand Down
1 change: 1 addition & 0 deletions process/core/io/obsolete_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@
"vcool": "vel_cp_coolant_midplane",
"rcool": "radius_cp_coolant_channel",
"fl_h_threshold": None,
"f_ster_div_single": None,
}

OBS_VARS_HELP = {
Expand Down
250 changes: 230 additions & 20 deletions process/core/io/plot/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -13741,26 +13741,55 @@ def plot_blkt_structure(
radial_build: dict[str, float],
colour_scheme: Literal[1, 2],
):
"""Plot the BLKT structure on the given axis."""
"""Plot the blkt structure and relevant angles"""
# MFILE variables needed to plot the blkt structure and angles
rmajor = m_file.get("rmajor", scan=scan)
rminor = m_file.get("rminor", scan=scan)
dr_fw_plasma_gap_outboard = m_file.get("dr_fw_plasma_gap_outboard", scan=scan)
dr_fw_plasma_gap_inboard = m_file.get("dr_fw_plasma_gap_inboard", scan=scan)
dr_fw_inboard = m_file.get("dr_fw_inboard", scan=scan)
dr_fw_outboard = m_file.get("dr_fw_outboard", scan=scan)
dr_blkt_outboard = m_file.get("dr_blkt_outboard", scan=scan)
dr_blkt_inboard = m_file.get("dr_blkt_inboard", scan=scan)
dz_blkt_half = m_file.get("dz_blkt_half", scan=scan)
deg_blkt_outboard_poloidal_plasma = m_file.get(
"deg_blkt_outboard_poloidal_plasma", scan=scan
)
deg_blkt_inboard_poloidal_plasma = m_file.get(
"deg_blkt_inboard_poloidal_plasma", scan=scan
)
f_deg_blkt_outboard_poloidal_plasma = m_file.get(
"f_deg_blkt_outboard_poloidal_plasma", scan=scan
)
f_deg_blkt_inboard_poloidal_plasma = m_file.get(
"f_deg_blkt_inboard_poloidal_plasma", scan=scan
)
deg_div_poloidal_plasma = m_file.get("deg_div_poloidal_plasma", scan=scan)
f_ster_div_single = m_file.get("f_ster_div_single", scan=scan)
i_single_null = m_file.get("i_single_null", scan=scan)

# ======================

plot_blanket(ax, m_file, scan, radial_build, colour_scheme)
plot_plasma(ax, m_file, scan, colour_scheme)
plot_firstwall(ax, m_file, scan, radial_build, colour_scheme)

ax.set_xlabel("Radial position [m]")
ax.set_ylabel("Vertical position [m]")
ax.set_title("Blanket and First Wall Poloidal Cross-Section")
ax.minorticks_on()
ax.grid(which="minor", linestyle=":", linewidth=0.5, alpha=0.5)
# Plot major radius line (vertical dashed line at rmajor)
ax.axvline(
m_file.get("rminor", scan=scan),
color="black",
linestyle="--",
linewidth=1.5,
label="Major Radius $R_0$",

r_blkt_outboard_out = (
rmajor + rminor + dr_fw_outboard + dr_fw_plasma_gap_outboard + dr_blkt_outboard
)
r_blkt_inboard_in = (
rmajor - rminor - dr_fw_plasma_gap_inboard - dr_fw_inboard - dr_blkt_inboard
)
r_fw_outboard_in = r_blkt_outboard_out - dr_blkt_outboard - dr_fw_outboard
r_fw_inboard_out = r_blkt_inboard_in + dr_blkt_inboard + dr_fw_inboard
Comment on lines +13783 to +13790
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it not possible to get these from the MFILE? If not, should these variables be added?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to what Matti raised. We output the radial build but that is just the left edge. The confusing bit is that the left edge is one is the right edge of the other.I have kept the naming here explicit. What we really need is a full build output object that stores the left, middle and right of each component and can be easily called


# Plot a horizontal line at dz_blkt_half (blanket half height)
dz_blkt_half = m_file.get("dz_blkt_half", scan=scan)
ax.axhline(
dz_blkt_half,
color="purple",
Expand All @@ -13776,25 +13805,206 @@ def plot_blkt_structure(
label="Blanket Half Height",
)

# Plot arrows for the outboard blanket angles
ax.annotate(
"",
xy=(rmajor, dz_blkt_half),
xy=(rmajor, 0),
xytext=(rmajor, dz_blkt_half),
arrowprops={"arrowstyle": "<-", "color": "purple"},
zorder=5,
)

ax.annotate(
"",
xy=(rmajor, 0),
xytext=(rmajor, -dz_blkt_half),
arrowprops={"arrowstyle": "<->", "color": "black"},
arrowprops={"arrowstyle": "<-", "color": "purple"},
zorder=5,
)

# Add a label for the internal coil width
# Plot arc showing the angle between the two outboard blanket arrows
arc_radius = 1.0
angle_start = -deg_blkt_outboard_poloidal_plasma / 2
angle_end = deg_blkt_outboard_poloidal_plasma / 2

theta = np.linspace(np.deg2rad(angle_start), np.deg2rad(angle_end), 50)
arc_x = rmajor + arc_radius * np.cos(theta)
arc_y = arc_radius * np.sin(theta)

ax.plot(arc_x, arc_y, color="purple", linewidth=2)

# Add angle label at the arc
mid_angle = np.deg2rad((angle_start + angle_end) / 2)
label_radius = arc_radius * 1.8
label_x = rmajor + label_radius * np.cos(mid_angle)
label_y = label_radius * np.sin(mid_angle)

# Plot the info box for the outboard blanket
ax.text(
rmajor,
0.0,
f"{2 * dz_blkt_half:.3f} m",
label_x,
label_y,
f"{deg_blkt_outboard_poloidal_plasma:.1f}°\n({f_deg_blkt_outboard_poloidal_plasma * 100:.1f}%)",
fontsize=7,
color="purple",
ha="center",
va="center",
weight="bold",
bbox={
"boxstyle": "round",
"facecolor": "white",
"alpha": 0.8,
"edgecolor": "purple",
"linewidth": 1.5,
},
)

# Plot arrows for the inboard blanket angles
ax.annotate(
"",
xy=(rmajor, 0),
xytext=(r_fw_inboard_out, dz_blkt_half),
arrowprops={"arrowstyle": "<-", "color": "green"},
zorder=5,
)

ax.annotate(
"",
xy=(rmajor, 0),
xytext=(r_fw_inboard_out, -dz_blkt_half),
arrowprops={"arrowstyle": "<-", "color": "green"},
zorder=5,
)

# Plot arc showing the angle between the two inboard blanket arrows
arc_radius = 1.0
angle_start = -deg_blkt_inboard_poloidal_plasma / 2
angle_end = deg_blkt_inboard_poloidal_plasma / 2

theta = np.linspace(np.deg2rad(angle_start), np.deg2rad(angle_end), 50)
arc_x = rmajor - arc_radius * np.cos(theta)
arc_y = arc_radius * np.sin(theta)

ax.plot(arc_x, arc_y, color="green", linewidth=2)

# Add angle label at the arc
mid_angle = np.deg2rad((angle_start + angle_end) / 2)
label_radius = arc_radius * 1.8
label_x = rmajor - label_radius * np.cos(mid_angle)
label_y = label_radius * np.sin(mid_angle)

# Plot the info box for the inboard blanket
ax.text(
label_x,
label_y,
f"{deg_blkt_inboard_poloidal_plasma:.1f}°\n({f_deg_blkt_inboard_poloidal_plasma * 100:.1f}%)",
fontsize=7,
color="green",
ha="center",
va="center",
weight="bold",
bbox={
"boxstyle": "round",
"facecolor": "white",
"alpha": 0.8,
"edgecolor": "green",
"linewidth": 1.5,
},
zorder=5,
)

# Plot arrows for the divertor angles
# If double null then plot the upper also
if i_single_null == 0:
# Plot arc showing the angle between the two arrows (divertor angle)
arc_radius = 1.5
angle_start = deg_blkt_outboard_poloidal_plasma / 2 + deg_div_poloidal_plasma
angle_end = deg_blkt_inboard_poloidal_plasma / 2 + deg_div_poloidal_plasma

theta = np.linspace(np.deg2rad(angle_start), np.deg2rad(angle_end), 50)
arc_x = rmajor + arc_radius * np.cos(theta)
arc_y = arc_radius * np.sin(theta)

ax.plot(arc_x, arc_y, color="black", linewidth=2)

# Add angle label at the arc
mid_angle = np.deg2rad((angle_start + angle_end) / 2)
label_radius = arc_radius * 1.8
label_x = rmajor + label_radius * np.cos(mid_angle)
label_y = label_radius * np.sin(mid_angle)

ax.text(
label_x,
label_y,
f"{deg_div_poloidal_plasma:.1f}°\n({f_ster_div_single * 100:.1f}%)",
fontsize=7,
color="black",
ha="center",
va="center",
weight="bold",
bbox={
"boxstyle": "round",
"facecolor": "white",
"alpha": 0.8,
"edgecolor": "black",
"linewidth": 1.5,
},
zorder=5,
)

# Plot arc showing the angle between the two arrows for the lower divertor (divertor angle)
arc_radius = 1.5
angle_start = -deg_blkt_outboard_poloidal_plasma / 2 - deg_div_poloidal_plasma
angle_end = -deg_blkt_inboard_poloidal_plasma / 2 - deg_div_poloidal_plasma

theta = np.linspace(np.deg2rad(angle_start), np.deg2rad(angle_end), 50)
arc_x = rmajor + arc_radius * np.cos(theta)
arc_y = arc_radius * np.sin(theta)

ax.plot(arc_x, arc_y, color="black", linewidth=2)

# Add angle label at the arc
mid_angle = np.deg2rad((angle_start + angle_end) / 2)
label_radius = arc_radius * 1.8
label_x = rmajor + label_radius * np.cos(mid_angle)
label_y = label_radius * np.sin(mid_angle)

# Plot the info box for the lower divertor angle
ax.text(
label_x,
label_y,
f"{deg_div_poloidal_plasma:.1f}°\n({f_ster_div_single * 100:.1f}%)",
fontsize=7,
color="black",
rotation=270,
verticalalignment="center",
horizontalalignment="center",
bbox={"boxstyle": "round", "facecolor": "pink", "alpha": 1.0},
zorder=101, # Ensure label is on top of all plots
ha="center",
va="center",
weight="bold",
bbox={
"boxstyle": "round",
"facecolor": "white",
"alpha": 0.8,
"edgecolor": "black",
"linewidth": 1.5,
},
zorder=5,
)

# Plot vertical lines at the inner and outer radial boundaries of the blanket
ax.axvline(
r_blkt_inboard_in, color="black", linestyle="--", linewidth=1.5, zorder=10
)
ax.axvline(
r_blkt_outboard_out, color="black", linestyle="--", linewidth=1.5, zorder=10
)
ax.axvline(r_fw_inboard_out, color="black", linestyle="--", linewidth=1.5, zorder=10)

ax.axvline(r_fw_outboard_in, color="black", linestyle="--", linewidth=1.5, zorder=10)

ax.axvline(
rmajor,
color="black",
linestyle="--",
linewidth=1.5,
label="Major Radius $R_0$",
)

# Plot midplane line (horizontal dashed line at Z=0)
Expand Down
22 changes: 21 additions & 1 deletion process/data_structure/blanket_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,18 @@
icomponent: int = None
"""Switch used to specify selected component: blanket=0, shield=1, vacuum vessel=2"""

deg_blkt_outboard_poloidal_plasma: float = None
"""Outboard blanket poloidal angle subtended by plasma (degrees)"""

f_deg_blkt_outboard_poloidal_plasma: float = None
"""Fraction of outboard blanket poloidal angle subtended by plasma (degrees)"""

deg_blkt_inboard_poloidal_plasma: float = None
"""Inboard blanket poloidal angle subtended by plasma (degrees)"""

f_deg_blkt_inboard_poloidal_plasma: float = None
"""Fraction of inboard blanket poloidal angle subtended by plasma (degrees)"""


def init_blanket_library():
global \
Expand Down Expand Up @@ -288,7 +300,11 @@ def init_blanket_library():
htpmw_blkti, \
htpmw_blkto, \
vfblkti, \
vfblkto
vfblkto, \
deg_blkt_outboard_poloidal_plasma, \
deg_blkt_inboard_poloidal_plasma, \
f_deg_blkt_outboard_poloidal_plasma, \
f_deg_blkt_inboard_poloidal_plasma

dz_blkt_half = 0.0
dz_shld_half = 0.0
Expand Down Expand Up @@ -340,3 +356,7 @@ def init_blanket_library():
htpmw_blkto = 0.0
vfblkti = 0.0
vfblkto = 0.0
deg_blkt_outboard_poloidal_plasma = 0.0
deg_blkt_inboard_poloidal_plasma = 0.0
f_deg_blkt_outboard_poloidal_plasma = 0.0
f_deg_blkt_inboard_poloidal_plasma = 0.0
7 changes: 6 additions & 1 deletion process/data_structure/divertor_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
n_divertors: int = None
"""Number of divertors (calculated from `i_single_null`)"""

deg_div_poloidal_plasma: float = None
"""Divertor poloidal angle subtended by plasma (degrees)"""


def init_divertor_variables():
global \
Expand All @@ -96,7 +99,8 @@ def init_divertor_variables():
p_div_upper_nuclear_heat_mw, \
p_div_upper_rad_mw, \
p_div_lower_rad_mw, \
n_divertors
n_divertors, \
deg_div_poloidal_plasma

anginc = 0.262
deg_div_field_plate = 1.0
Expand All @@ -121,3 +125,4 @@ def init_divertor_variables():
p_div_upper_rad_mw = 0.0
p_div_lower_rad_mw = 0.0
n_divertors = 2
deg_div_poloidal_plasma = 0.0
Loading
Loading