Skip to content

⚡ Add TF quench graph#4261

Open
chris-ashe wants to merge 10 commits into
mainfrom
add_tf_quench_graph
Open

⚡ Add TF quench graph#4261
chris-ashe wants to merge 10 commits into
mainfrom
add_tf_quench_graph

Conversation

@chris-ashe
Copy link
Copy Markdown
Collaborator

@chris-ashe chris-ashe commented May 19, 2026

This pull request introduces a new quench time evolution plot to the summary plotting functionality and makes several improvements and cleanups to the quench modeling code. The most important changes include adding the plot_quench_time_evolution function to the summary plots, updating figure indexing to accommodate the new plot, and improving the clarity and consistency of docstrings and variable names in the quench model. Minor formatting and reference style updates are also included.

Summary plotting enhancements:

  • Added the plot_quench_time_evolution plot to the summary, including passing all necessary parameters from main_plot and updating the number of figures/pages to accommodate the new plot. (process/core/io/plot/summary.py)

  • Updated all subsequent figure indices in main_plot and plot_summary to ensure plots are assigned to the correct pages after the new plot insertion. (process/core/io/plot/summary.py)

Quench model improvements:

  • Added matplotlib.pyplot import in quench.py to support the new plotting functionality. (process/models/tfcoil/quench.py)

  • Improved clarity and consistency of docstrings and parameter names throughout the quench modeling code, including using more descriptive parameter names (e.g., temp_quench_max instead of t_max) and updating reference formatting for better readability. (process/models/tfcoil/quench.py)

  • Minor formatting and unit consistency improvements in comments and docstrings (e.g., using kg/m³). (process/models/tfcoil/quench.py)

These changes enhance the summary plotting capabilities and improve code quality and maintainability in the quench modeling module.

image

Checklist

I confirm that I have completed the following checks:

  • My changes follow the PROCESS style guide
  • I have justified any large differences in the regression tests caused by this pull request in the comments.
  • I have added new tests where appropriate for the changes I have made.
  • If I have had to change any existing unit or integration tests, I have justified this change in the pull request comments.
  • If I have made documentation changes, I have checked they render correctly.
  • I have added documentation for my change, if appropriate.

@chris-ashe chris-ashe requested a review from CoronelBuendia May 19, 2026 13:36
@chris-ashe chris-ashe marked this pull request as ready for review May 19, 2026 13:36
@chris-ashe chris-ashe requested a review from a team as a code owner May 19, 2026 13:36
Copilot AI review requested due to automatic review settings May 19, 2026 13:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a TF coil quench time-evolution plot to the summary plotting workflow and updates quench-related naming/docstrings for clarity.

Changes:

  • Adds plot_quench_time_evolution for current-density and hotspot-temperature evolution.
  • Inserts the new quench plot into the summary pages and shifts later figure indices.
  • Cleans up quench model docstrings, references, and variable names.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
process/models/tfcoil/quench.py Adds the quench time-evolution plotting function and updates quench calculation naming/docs.
process/core/io/plot/summary.py Imports and calls the new quench plot, adjusts page count and subsequent figure indices, and tweaks TF coil summary text formatting.
Comments suppressed due to low confidence (1)

process/models/tfcoil/quench.py:591

  • np.interp silently clamps values above the precomputed integral range to temp_quench_max, so if j_operating exceeds the protection limit the operating hotspot curve will flatten at the maximum allowed temperature instead of showing that the limit is exceeded. Use an explicit out-of-range handling strategy, such as extending the temperature grid or plotting/annotating values beyond the limit as invalid/exceeded.
    hotspot_temp_real = np.interp(miit_real, scaled_integral, temp_array)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread process/core/io/plot/summary.py Outdated
f_he=m_file.get("f_a_tf_turn_cable_space_cooling", scan=scan),
t_he_peak=m_file.get("tftmp", scan=scan),
temp_quench_max=m_file.get("temp_tf_conductor_quench_max", scan=scan),
cu_rrr=100.0,
cu_rrr=100.0,
t_quench_detection=m_file.get("t_tf_quench_detection", scan=scan),
fluence=m_file.get("nflutfmax", scan=scan),
j_operating=m_file.get("j_tf_wp", scan=scan),
plot_resistive_tf_info(ax19, m_file, scan, figs[24])
plot_tf_coil_structure(
figs[26].add_subplot(111, aspect="equal"), m_file, scan, colour_scheme
figs[27].add_subplot(111, aspect="equal"), m_file, scan, colour_scheme
Comment on lines +578 to +583
# Numerically integrate J² dt over time to get MIIT at each time step
dt = times[1] - times[0]
miit_required = np.cumsum(j_profile_required**2) * dt
miit_required_1e23 = np.cumsum(j_profile_required_1e23**2) * dt
miit_real = np.cumsum(j_profile_real**2) * dt

if figure is not None:
figure.tight_layout()
else:
plt.tight_layout()
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 19, 2026

Codecov Report

❌ Patch coverage is 8.82353% with 93 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.10%. Comparing base (226576d) to head (a1c2d70).

Files with missing lines Patch % Lines
process/models/tfcoil/quench.py 8.98% 81 Missing ⚠️
process/core/io/plot/summary.py 7.69% 12 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4261      +/-   ##
==========================================
- Coverage   50.23%   50.10%   -0.14%     
==========================================
  Files         151      151              
  Lines       29365    29450      +85     
==========================================
+ Hits        14752    14755       +3     
- Misses      14613    14695      +82     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@CoronelBuendia CoronelBuendia left a comment

Choose a reason for hiding this comment

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

Couple of mods and comments while I have a think about how you're doing the temperature evolution plot here. I don't have all that much time at the moment to look at this properly, sorry!


# Adiabatic hotspot temperature: integrate heat balance over time
# T(t) is found by inverting: integral_{T0}^{T(t)} [sum(rho*cp)] / rho_cu dT = integral_0^t J^2 dt
# We accumulate the "MIIT" (integral J^2 dt) and map it to temperature via the precomputed integral.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is MIIT? Could you define it somewhere in words? I guess it is an acronym?

Comment on lines +526 to +542
j_profile_required = np.where(
times < t_quench_detection,
j_max,
j_max * np.exp(-(times - t_quench_detection) / tau_discharge),
)

j_profile_required_1e23 = np.where(
times < t_quench_detection,
j_max_1e23,
j_max_1e23 * np.exp(-(times - t_quench_detection) / tau_discharge),
)

j_profile_real = np.where(
times < t_quench_detection,
j_operating,
j_operating * np.exp(-(times - t_quench_detection) / tau_discharge),
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
j_profile_required = np.where(
times < t_quench_detection,
j_max,
j_max * np.exp(-(times - t_quench_detection) / tau_discharge),
)
j_profile_required_1e23 = np.where(
times < t_quench_detection,
j_max_1e23,
j_max_1e23 * np.exp(-(times - t_quench_detection) / tau_discharge),
)
j_profile_real = np.where(
times < t_quench_detection,
j_operating,
j_operating * np.exp(-(times - t_quench_detection) / tau_discharge),
)
decay = np.exp(-(times - t_quench_detection) / tau_discharge)
j_profile_required, j_profile_required_1e23, j_profile_real = [
np.where(times < t_quench_detection, j0, j0 * decay)
for j0 in (j_max, j_max_1e23, j_operating)
]

Comment on lines +496 to +519
j_max = calculate_quench_protection_current_density(
tau_discharge,
b_peak,
f_cu,
f_he,
t_he_peak,
temp_quench_max,
cu_rrr,
t_quench_detection,
fluence,
)

fluence_1e23 = 1e23
j_max_1e23 = calculate_quench_protection_current_density(
tau_discharge,
b_peak,
f_cu,
f_he,
t_he_peak,
temp_quench_max,
cu_rrr,
t_quench_detection,
fluence_1e23,
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
j_max = calculate_quench_protection_current_density(
tau_discharge,
b_peak,
f_cu,
f_he,
t_he_peak,
temp_quench_max,
cu_rrr,
t_quench_detection,
fluence,
)
fluence_1e23 = 1e23
j_max_1e23 = calculate_quench_protection_current_density(
tau_discharge,
b_peak,
f_cu,
f_he,
t_he_peak,
temp_quench_max,
cu_rrr,
t_quench_detection,
fluence_1e23,
)
j_max, j_max_1e23 = [
calculate_quench_protection_current_density(
tau_discharge,
b_peak,
f_cu,
f_he,
t_he_peak,
temp_quench_max,
cu_rrr,
t_quench_detection,
fl,
)
for fl in (fluence, 1e23)
]

+ f_cu_cable * _copper_specific_heat_capacity(ti) * COPPER_DENSITY
+ f_sc_cable * _nb3sn_specific_heat_capacity(ti) * NB3SN_DENSITY
) / nu_cu
val += dti * integrand
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can see this would be a pain, but it is a potential source of future technical debt we're taking on here in not re-using the same function that is actually used in the module. Would require re-factoring what is already in quench.py, but nothing too difficult, I'd imagine.

This could also help clear up why the temperature evolution is not meeting the hotspot criterion when the current density constraint is hit.

miit_real = np.cumsum(j_profile_real**2) * dt

# Map MIIT -> temperature via inverse interpolation of cum_integral * f_cu_cable
scaled_integral = f_cu_cable * cum_integral
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So crude thoughts. The equation is of the form:

$$ \int A(t) dt = \int B(T) dT $$

We resolve the LHS analytically, and the RHS numerically.

You essentially want $dT/dt|_{t_n} = A(t_n)/B(T_n)$ which is an ODE, and I'm not sure this is what happening here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants