⚡ Add TF quench graph#4261
Conversation
…au_discharge visualization
… summary.py and quench.py
…or copper and helium fractions
There was a problem hiding this comment.
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_evolutionfor 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.interpsilently clamps values above the precomputed integral range totemp_quench_max, so ifj_operatingexceeds 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.
| 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 |
| # 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 Report❌ Patch coverage is
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. 🚀 New features to boost your workflow:
|
…r typing and enhance label formatting for temperature display
… and neutron fluence in superconducting TF coil model
CoronelBuendia
left a comment
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
What is MIIT? Could you define it somewhere in words? I guess it is an acronym?
| 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), | ||
| ) |
There was a problem hiding this comment.
| 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) | |
| ] |
| 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, | ||
| ) |
There was a problem hiding this comment.
| 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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
So crude thoughts. The equation is of the form:
We resolve the LHS analytically, and the RHS numerically.
You essentially want
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_evolutionfunction 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_evolutionplot to the summary, including passing all necessary parameters frommain_plotand updating the number of figures/pages to accommodate the new plot. (process/core/io/plot/summary.py)Updated all subsequent figure indices in
main_plotandplot_summaryto ensure plots are assigned to the correct pages after the new plot insertion. (process/core/io/plot/summary.py)Quench model improvements:
Added
matplotlib.pyplotimport inquench.pyto 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_maxinstead oft_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.
Checklist
I confirm that I have completed the following checks: