Skip to content

Commit a1ae413

Browse files
committed
FDS Validation Guide: update Catchpole no-spread summary figures
1 parent ef5b9f8 commit a1ae413

File tree

2 files changed

+66
-41
lines changed

2 files changed

+66
-41
lines changed

Manuals/FDS_Validation_Guide/Burning_Rate_Chapter.tex

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,14 +2988,17 @@ \subsection{USFS/Catchpole Experiments}
29882988
\label{USFS_Catchpole_parameter_summary}
29892989
\end{figure}
29902990

2991-
Additionally, neither Fig.~\ref{USFS_Catchpole_parameter_summary} nor the summary scatter plot in Fig.~\ref{RoS_Summary} include information on the cases for which FDS fails to reproduce a spreading fire. All cases tested have a reported spread rate from the experiments, so instances where FDS does not produce sustained fire spread are indicative of limitations in the current model representation. In order to guide future development efforts, Fig.~\ref{USFS_Catchpole_no_spread} attempts to summarize the model performance over the parameter space by showing lines that connect each set of parameters for a given test. Gray lines in the background correspond to successful spread predictions, while colored lines in the foreground are those for which FDS does not sustain fire spread. This highlights problematic areas of the test matrix, such as zero wind speed cases with low values of packing ratio.
2991+
Additionally, neither Fig.~\ref{USFS_Catchpole_parameter_summary} nor the summary scatter plot in Fig.~\ref{RoS_Summary} include information on the cases for which FDS fails to reproduce a spreading fire. All cases tested have a reported spread rate from the experiments, so instances where FDS does not produce sustained fire spread are indicative of limitations in the current model representation. In order to guide future development efforts, Fig.~\ref{USFS_Catchpole_no_spread} attempts to summarize the model performance over the full parameter space. Gray points in the background correspond to successful spread predictions, while colored points in the foreground are those for which FDS does not sustain fire spread. This highlights problematic areas of the test matrix, such as zero wind speed cases with low values of packing ratio.
29922992

29932993
\begin{figure}[ht]
29942994
\centering
2995-
\begin{tabular}{c}
2996-
\includegraphics[height=3.5in]{SCRIPT_FIGURES/USFS_Catchpole/Catchpole_no_spread}
2997-
\end{tabular}
2998-
\caption[USFS/Catchpole, conditions leading to failed spread predictions]{Parameter combinations for all USFS/Catchpole cases, each connected by a single line. Parameters of surface-to-volume ratio (s), packing ratio (beta), moisture content (M) and wind speed (U) are normalized between 0 (minimum value) and 1 (maximum value). Gray lines in the background are cases where FDS successfully predicts spread, and colored lines in the foreground represent failed (no spread) predictions. Failed prediction lines are colored according to the beta value for a given test in order to help distinguish trends.}
2995+
\begin{tabular*}{\textwidth}{l@{\extracolsep{\fill}}r}
2996+
\includegraphics[height=2.15in]{SCRIPT_FIGURES/USFS_Catchpole/Catchpole_no_spread_MF} &
2997+
\includegraphics[height=2.15in]{SCRIPT_FIGURES/USFS_Catchpole/Catchpole_no_spread_PPMC} \\
2998+
\includegraphics[height=2.15in]{SCRIPT_FIGURES/USFS_Catchpole/Catchpole_no_spread_EXSC} &
2999+
\includegraphics[height=2.15in]{SCRIPT_FIGURES/USFS_Catchpole/Catchpole_no_spread_EX} \\
3000+
\end{tabular*}
3001+
\caption[USFS/Catchpole, conditions leading to failed spread predictions]{Parameter combinations for all USFS/Catchpole cases. Gray points in the background are cases where FDS successfully predicts spread, and colored points in the foreground represent failed (no spread) predictions. Both the point size and color are scaled according to the packing ratio (beta) value for a given test.}
29993002
\label{USFS_Catchpole_no_spread}
30003003
\end{figure}
30013004

Utilities/Python/scripts/catchpole_spread_rates.py

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -91,39 +91,61 @@
9191

9292
# plot no-spread conditions
9393

94-
fig_file = os.path.join(fig_path, "Catchpole_no_spread.pdf")
95-
# Dummy call to establish figure
96-
fig = fdsplotlib.plot_to_fig(x_data=[-1,-1], y_data=[-1,-1],
97-
x_label='Parameter',y_label='Normalized value',
98-
x_min=0,x_max=3,y_min=0,y_max=1,ynumticks=2,
99-
revision_label=version_string)
100-
ax = plt.gca()
101-
102-
# Normalize by max and min
103-
tests_normalized = tests
104-
tests_normalized[list(dep_variables.keys())] = tests[list(dep_variables.keys())].apply(
105-
lambda x: (x - x.min()) / (x.max() - x.min()))
106-
107-
go_mask = tests_normalized['category'] == 'spread'
108-
nogo_mask = tests_normalized['category'] == 'no spread'
109-
110-
pd.plotting.parallel_coordinates(tests_normalized[go_mask], 'category',
111-
cols=['s','beta','M','U'],
112-
color=[(0.,0.,0.,.04)],
113-
ax=ax,
114-
ls='-')
115-
ax.get_legend().remove() # Hide the parallel_coordinates legend
116-
117-
color_var = 'beta' # or 'beta', 'M', 'U'
118-
cmap = plt.cm.plasma
119-
norm = mpl.colors.Normalize(vmin=tests[color_var].min(),
120-
vmax=tests[color_var].max())
121-
colors = cmap(norm(tests[color_var]))
122-
123-
for idx, (i, row) in enumerate(tests_normalized[nogo_mask].iterrows()):
124-
x_vals = ['s','beta','M','U']
125-
y_vals = [row['s'], row['beta'], row['M'], row['U']]
126-
ax.plot(x_vals, y_vals, color=colors[i], linestyle='-')
127-
128-
plt.savefig(fig_file)
129-
plt.close()
94+
go_mask = tests['category'] == 'spread'
95+
nogo_mask = tests['category'] == 'no spread'
96+
97+
# Create scatter plot for each fuel type
98+
for i, fuel in enumerate(fuel_labels):
99+
fuel_name = fuel_names[i]
100+
fig_file = os.path.join(fig_path, f"Catchpole_no_spread_{fuel}.pdf")
101+
102+
# Filter for this fuel type
103+
if fuel == 'EX':
104+
fuel_mask = tests['Test'].str.startswith(fuel) & (~tests['Test'].str.startswith('EXSC'))
105+
else:
106+
fuel_mask = tests['Test'].str.startswith(fuel)
107+
108+
# Get data for this fuel type
109+
fuel_go_data = tests[go_mask & fuel_mask]
110+
fuel_nogo_data = tests[nogo_mask & fuel_mask]
111+
112+
s_value = fuel_go_data['s'].iloc[0]
113+
# Create figure
114+
fig = fdsplotlib.plot_to_fig(x_data=[-1,1], y_data=[0,0],
115+
marker_style='k--',
116+
x_label='Moisture Content, M (-)',
117+
y_label='Wind Speed, U (m/s)',
118+
x_min=0,
119+
x_max=0.3,
120+
y_min=-0.2,
121+
y_max=3.5,
122+
revision_label=version_string,
123+
plot_title=rf'{fuel_name}, {s_value:.0f} m$^{{-1}}$')
124+
ax = plt.gca()
125+
126+
# Fixed scale for beta (0 to 0.1)
127+
beta_min_fixed = 0.0
128+
beta_max_fixed = 0.1
129+
130+
# Plot spread cases (background, gray, sized by beta)
131+
if len(fuel_go_data) > 0:
132+
sizes_go = (fuel_go_data['beta'] - beta_min_fixed) / (beta_max_fixed - beta_min_fixed) * 100 + 20
133+
ax.scatter(fuel_go_data['M'], fuel_go_data['U'],
134+
s=sizes_go, c='gray', alpha=0.3, edgecolors='none')
135+
136+
# Plot no-spread cases (foreground, colored by beta, sized by beta)
137+
if len(fuel_nogo_data) > 0:
138+
cmap = plt.cm.plasma
139+
norm = mpl.colors.Normalize(vmin=beta_min_fixed, vmax=beta_max_fixed)
140+
sizes_nogo = (fuel_nogo_data['beta'] - beta_min_fixed) / (beta_max_fixed - beta_min_fixed) * 100 + 20
141+
scatter = ax.scatter(fuel_nogo_data['M'], fuel_nogo_data['U'],
142+
s=sizes_nogo, c=fuel_nogo_data['beta'], cmap=cmap, norm=norm,
143+
alpha=0.8, edgecolors='black', linewidths=0.5)
144+
145+
# Add colorbar
146+
cbar = plt.colorbar(scatter, ax=ax)
147+
cbar.set_label('Packing Ratio, beta (-)', rotation=90, labelpad=15, fontsize=plot_style['Label_Font_Size'])
148+
cbar.ax.tick_params(labelsize=plot_style['Label_Font_Size'])
149+
150+
plt.savefig(fig_file)
151+
plt.close()

0 commit comments

Comments
 (0)