Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
759fa7f
Add calculation for outboard blanket poloidal angle subtended by plasma
chris-ashe Apr 28, 2026
efc8084
Add poloidal angle visualization for blanket structure in plot
chris-ashe Apr 28, 2026
936de2e
Add calculation and visualization for inboard blanket poloidal angle
chris-ashe Apr 28, 2026
2e1d87e
Add outboard blanket poloidal angle calculation and update plot annot…
chris-ashe Apr 28, 2026
0f98735
Add divertor poloidal angle subtended by plasma variable
chris-ashe Apr 28, 2026
36f4c41
Add calculation and visualization for divertor poloidal angle subtend…
chris-ashe Apr 28, 2026
d20afe0
Add divertor poloidal angle output and calculation updates
chris-ashe Apr 28, 2026
e1e8b50
Remove major radius line plotting from blanket structure visualization
chris-ashe Apr 28, 2026
1618791
Add calculations and output for blanket poloidal angles subtended by …
chris-ashe Apr 28, 2026
7d968f4
Adjust font sizes and z-order for blanket and divertor angle labels i…
chris-ashe Apr 28, 2026
3739636
Enhance BLKT structure plotting by adding poloidal angle annotations …
chris-ashe Apr 28, 2026
159e16c
Fix calculation of single divertor angle to use inboard blanket poloi…
chris-ashe Apr 28, 2026
c99c570
Add unit test for calculating inboard blanket poloidal plasma angle
chris-ashe Apr 28, 2026
3ff054d
Remove obsolete variable 'f_ster_div_single' from input variables and…
chris-ashe Apr 28, 2026
da26032
Add calculations for blanket poloidal plasma angles in DCLL class
chris-ashe Apr 28, 2026
37996fe
Post rebase commit
chris-ashe May 12, 2026
5012f03
Assign extra angle to outboard blanket if in single null
chris-ashe May 12, 2026
55fe3ab
Post rebase fixes
chris-ashe May 19, 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
1 change: 0 additions & 1 deletion process/core/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,6 @@ def __post_init__(self):
"fiooic": InputVariable("constraints", float, range=(0.001, 1.0)),
"fjohc": InputVariable("constraints", float, range=(0.001, 1.0)),
"fjohc0": InputVariable("constraints", float, range=(0.001, 1.0)),
"f_ster_div_single": InputVariable("fwbs", float, range=(0.0, 1.0)),
"fdiva": InputVariable("divertor", 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
259 changes: 239 additions & 20 deletions process/core/io/plot/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -13830,26 +13830,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 +13872 to +13879
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 @@ -13865,25 +13894,215 @@ def plot_blkt_structure(
label="Blanket Half Height",
)

if i_single_null == 0:
# Plot arrows for the outboard blanket angles
ax.annotate(
"",
xy=(rmajor, 0),
xytext=(rmajor, dz_blkt_half),
arrowprops={"arrowstyle": "<-", "color": "purple"},
zorder=5,
)
# If single null then only plot the lower arrow for the outboard blanket angle
ax.annotate(
"",
xy=(rmajor, dz_blkt_half),
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

# 3 to 6 o'clock position is -90 degrees,
angle_start = -90.0
if i_single_null == 1:
angle_end = 90.0 + deg_div_poloidal_plasma
elif i_single_null == 0:
# 3 to 12 o'clock position is +90 degrees
angle_end = 90.0

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
# 3 to 12 o'clock position is +90 degrees,
angle_start = 90.0
angle_end = 90.0 + 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
# 3 to 6 o'clock is -90 degrees
angle_start = -90.0
angle_end = -90.0 - 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
12 changes: 12 additions & 0 deletions process/data_structure/blanket_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,17 @@ class BlanketData:
dz_vv_half: float = 0.0
"""Vacuum vessel internal half-height (m)"""

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

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

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

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


CREATE_DICTS_FROM_DATACLASS = BlanketData
3 changes: 3 additions & 0 deletions process/data_structure/divertor_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,8 @@ class DivertorData:
n_divertors: int = 2
"""Number of divertors (calculated from `i_single_null`)"""

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


CREATE_DICTS_FROM_DATACLASS = DivertorData
Loading
Loading