Skip to content

Commit 921f5bd

Browse files
authored
Merge pull request #14392 from ericvmueller/catchpole
FDS Validation: add python version of FDS_validation_script; add proc…
2 parents b5122a1 + 1b7a683 commit 921f5bd

File tree

2 files changed

+200
-0
lines changed

2 files changed

+200
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!$FIREMODELS/fds/.github/fds_python_env/bin/python
2+
3+
import subprocess
4+
import fdsplotlib
5+
import importlib
6+
importlib.reload(fdsplotlib) # use for development (while making changes to fdsplotlib.py)
7+
8+
# Scripts to run prior to dataplot
9+
10+
print("catchpole_spread_rates..."); subprocess.run(["python","./scripts/catchpole_spread_rates.py"])
11+
12+
# Dataplot and scatplot options
13+
14+
# Statistics output options
15+
16+
# Run dataplot and scatplot scripts
17+
18+
# fdsplotlib.dataplot(config_filename='../Matlab/FDS_verification_dataplot_inputs.csv',
19+
# expdir='../../Verification/',
20+
# cmpdir='../../Verification/',
21+
# pltdir='../../Manuals/',
22+
# close_figs=True,
23+
# verbose=True,
24+
# plot_range=[2])
25+
26+
# Special cases
27+
28+
print("Python validation scripts completed successfully!")
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
import os
4+
import pandas as pd
5+
6+
# include FDS plot styles, etc.
7+
import fdsplotlib
8+
9+
# Get plot style parameters
10+
plot_style = fdsplotlib.get_plot_style("fds")
11+
plt.rcParams['text.usetex'] = True # supports latex math (set per plot below)
12+
plt.rcParams["pdf.use14corefonts"] = True # forces matplotlib to write native pdf fonts rather than embed
13+
plt.rcParams["font.family"] = plot_style["Font_Name"]
14+
plt.rcParams["font.size"] = plot_style["Label_Font_Size"]
15+
16+
# Define paths
17+
base_path = "../../../out/USFS_Catchpole/"
18+
fig_path = "../../Manuals/FDS_Validation_Guide/SCRIPT_FIGURES/USFS_Catchpole/"
19+
20+
# Experiment parameters
21+
tests = pd.read_csv("../../Validation/USFS_Catchpole/FDS_Input_Files/Test_Matrix.csv")
22+
23+
for ti,test in tests.iterrows():
24+
chid = test['Test']
25+
fds_file = os.path.join(base_path, f"{chid}_devc.csv")
26+
git_file = os.path.join(base_path, f"{chid}_git.txt")
27+
fig_file = os.path.join(fig_path, f"{chid}.pdf")
28+
29+
if os.path.exists(fds_file) is False:
30+
print(f'Error: File {fds_file} does not exist. Skipping case.')
31+
continue
32+
33+
fds_data = pd.read_csv(fds_file,header=1)
34+
35+
# fit spread rate
36+
try:
37+
# fit slope filtering to positions greater than 2 m from ignition
38+
R_FDS,intercept = np.polyfit(fds_data[fds_data['x']>2]['Time'],
39+
fds_data[fds_data['x']>2]['x'], 1) # 1 indicates linear fit (degree 1)
40+
# not enough data to fit
41+
except:
42+
R_FDS=0.
43+
44+
if R_FDS<0:
45+
R_FDS=0
46+
47+
fig, ax = plt.subplots(figsize=(plot_style["Paper_Width"], plot_style["Paper_Height"]))
48+
49+
# Exp results
50+
x_exp = np.array([0., 8.])
51+
t_exp = np.array([0., 8./test['R']])
52+
ax.plot(t_exp,x_exp,'k-',label='Exp')
53+
54+
# FDS results
55+
ax.plot(fds_data['Time'],fds_data['x'],'k--',label='FDS')
56+
57+
# plot attributes
58+
ax.set_xlabel("Time (s)",
59+
fontdict={"fontname": plot_style["Font_Name"],
60+
"fontsize": plot_style["Label_Font_Size"]})
61+
ax.set_ylabel("Distance (m)",
62+
fontdict={"fontname": plot_style["Font_Name"],
63+
"fontsize": plot_style["Label_Font_Size"]})
64+
t_end = max(fds_data['Time'].max(),8./test['R'])
65+
ax.set_xlim([0, t_end])
66+
ax.set_ylim([0, 8.])
67+
plt.legend(loc="lower right", fontsize=plot_style["Key_Font_Size"],
68+
framealpha=1,frameon=True)
69+
ax.set_title(chid,fontsize=plot_style["Title_Font_Size"],
70+
loc="left",x=0.05,y=0.9)
71+
72+
# add version sting
73+
version_str = fdsplotlib.get_version_string(git_file)
74+
fdsplotlib.add_version_string(ax, version_str, plot_type='linear')
75+
76+
fig.tight_layout()
77+
plt.savefig(fig_file)
78+
plt.close()
79+
80+
# write table for dataplot
81+
test['R_FDS'] = R_FDS
82+
test = test.drop('Test')
83+
out_file = os.path.join(base_path,f"{chid}_FDS.csv")
84+
pd.DataFrame([test]).to_csv(out_file,index=False)
85+
86+
# add fds data to full table for summary plotting
87+
tests.loc[ti,'R_FDS'] = R_FDS
88+
89+
90+
##### Create summary plots
91+
92+
# variables of interest
93+
dep_variables={"s":"Surface-to-Volume Ratio (1/m)",
94+
"beta":"Packing Ratio (-)",
95+
"U":"Wind Speed (m/s)",
96+
"M":"FMC (-)"}
97+
98+
# fuel labels for filtering data
99+
fuel_labels=["MF","EXSC","PPMC","EX"]
100+
101+
for dvar in dep_variables:
102+
103+
fig_file = os.path.join(fig_path, f"Catchpole_R_v_{dvar}.pdf")
104+
fig, ax = plt.subplots(figsize=(plot_style["Paper_Width"], plot_style["Paper_Height"]))
105+
106+
# show +/- 20% relative error
107+
[xmin,xmax] = [tests[dvar].min(),tests[dvar].max()]
108+
ax.semilogy([xmin,xmax],[0.8,0.8],'k--')
109+
ax.semilogy([xmin,xmax],[1.2,1.2],'k--')
110+
111+
for fuel in fuel_labels:
112+
filtered_data = tests[tests['Test'].str.startswith(fuel)]
113+
if fuel=='EX':
114+
filtered_data = tests[
115+
(tests['Test'].str.startswith(fuel))&(~tests['Test'].str.startswith('EXSC'))]
116+
117+
ax.semilogy(filtered_data[dvar],filtered_data['R_FDS']/filtered_data['R'],
118+
'.',label=fuel)
119+
120+
# plot attributes
121+
ax.set_xlabel(dep_variables[dvar],
122+
fontdict={"fontname": plot_style["Font_Name"],
123+
"fontsize": plot_style["Label_Font_Size"]})
124+
ax.set_ylabel("$R_{FDS}/R_{Exp}$ (-)",
125+
fontdict={"fontname": plot_style["Font_Name"],
126+
"fontsize": plot_style["Label_Font_Size"]})
127+
plt.legend(fontsize=plot_style["Key_Font_Size"],
128+
framealpha=1,frameon=True)
129+
ax.set_xlim([xmin,xmax])
130+
131+
# add version sting
132+
version_str = fdsplotlib.get_version_string(git_file)
133+
fdsplotlib.add_version_string(ax, version_str, plot_type='semilogy')
134+
135+
plt.tight_layout()
136+
plt.savefig(fig_file)
137+
plt.close()
138+
139+
140+
# plot no-spread conditions
141+
142+
fig_file = os.path.join(fig_path, "Catchpole_no_spread.pdf")
143+
fig, ax = plt.subplots(figsize=(plot_style["Paper_Width"], plot_style["Paper_Height"]))
144+
145+
# dummy column for labeling
146+
tests['category']='go'
147+
tests.loc[tests['R_FDS']<1e-5,'category'] = 'no-go'
148+
149+
# normalize by max and min
150+
tests_normalized = tests
151+
tests_normalized[list(dep_variables.keys())] = tests[list(dep_variables.keys())].apply(
152+
lambda x: (x - x.min()) / (x.max() - x.min()))
153+
154+
# move M toward the middle of x-axis for more clarity
155+
tests_normalized=tests_normalized[['category','s','beta','M','U']]
156+
157+
pd.plotting.parallel_coordinates(tests_normalized, 'category',
158+
cols=['s','beta','M','U'],
159+
color=[(1.,0.,0.,1), (0.,0.,0.,.2)],
160+
ax=ax,
161+
ls='-')
162+
163+
ax.set_ylim([0, 1])
164+
ax.set_yticks([0, 1],['min','max'])
165+
plt.legend(loc="upper left", fontsize=plot_style["Key_Font_Size"],
166+
framealpha=1,frameon=True)
167+
168+
# Show the plot
169+
plt.tight_layout()
170+
plt.savefig(fig_file)
171+
plt.close()
172+

0 commit comments

Comments
 (0)