Skip to content

Commit

Permalink
big fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
adrifoster committed Oct 30, 2024
1 parent 0831336 commit 920c549
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 152 deletions.
6 changes: 3 additions & 3 deletions fire/FatesFuelMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ module FatesFuelMod
procedure :: SumLoading
procedure :: CalculateFractionalLoading
procedure :: UpdateFuelMoisture
procedure :: AverageBulkDensity
procedure :: AverageSAV
procedure :: AverageBulkDensity_NoTrunks
procedure :: AverageSAV_NoTrunks

end type fuel_type

Expand Down Expand Up @@ -302,7 +302,7 @@ real(r8) function MoistureOfExtinction(sav)
real(r8), parameter :: MEF_b = 0.066_r8

if (sav <= 0.0_r8) then
write(fates_log(), *) 'SAV cannot be negative - SAV = ' // sav
write(fates_log(), *) 'SAV cannot be negative - SAV'
call endrun(msg=errMsg(__FILE__, __LINE__))
else
MoistureOfExtinction = MEF_a - MEF_b*log(sav)
Expand Down
2 changes: 1 addition & 1 deletion fire/SFParamsMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module SFParamsMod
real(r8),protected, public :: SF_val_SAV(num_fuel_classes)
real(r8),protected, public :: SF_val_FBD(num_fuel_classes)
real(r8),protected, public :: SF_val_min_moisture(num_fuel_classes)
real(r8),protected, public :: SF_val_mid_moisture(NFSC)
real(r8),protected, public :: SF_val_mid_moisture(num_fuel_classes)
real(r8),protected, public :: SF_val_low_moisture_Coeff(num_fuel_classes)
real(r8),protected, public :: SF_val_low_moisture_Slope(num_fuel_classes)
real(r8),protected, public :: SF_val_mid_moisture_Coeff(num_fuel_classes)
Expand Down
4 changes: 2 additions & 2 deletions testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
## Functional tests
add_subdirectory(functional_testing/allometry fates_allom_ftest)
add_subdirectory(functional_testing/math_utils fates_math_ftest)
add_subdirectory(functional_testing/fire fates_fuel_test)
add_subdirectory(functional_testing/fire fates_fuel_ftest)

## Unit tests
add_subdirectory(unit_testing/fire_weather_test fates_fire_weather_utest)
add_subdirectory(unit_testing/fire_fuel_test fates_fire_fuel_utest)
add_subdirectory(unit_testing/fire_fuel_test fates_fire_fuel_utest)
4 changes: 2 additions & 2 deletions testing/functional_testing/fire/FatesTestFuel.F90
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ program FatesTestFuel
call fuel(f)%CalculateFractionalLoading()

! calculate geometric properties
call fuel(f)%AverageBulkDensity(SF_val_FBD)
call fuel(f)%AverageSAV(SF_val_SAV)
call fuel(f)%AverageBulkDensity_NoTrunks(SF_val_FBD)
call fuel(f)%AverageSAV_NoTrunks(SF_val_SAV)

! save values
fuel_loading(:,f) = fuel(f)%loading(:)
Expand Down
96 changes: 0 additions & 96 deletions testing/functional_testing/fire/fuel_plotting.py

This file was deleted.

187 changes: 187 additions & 0 deletions testing/functional_testing/fire/fuel_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
"""
Concrete class for running the fuel functional test for FATES.
"""
import os
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
from functional_class import FunctionalTest


class FuelTest(FunctionalTest):
"""Fuel test class"""

name = "fuel"

def __init__(self, test_dict):
super().__init__(
FuelTest.name,
test_dict["test_dir"],
test_dict["test_exe"],
test_dict["out_file"],
test_dict["use_param_file"],
test_dict["other_args"],
)
self.plot = True

def plot_output(self, run_dir: str, save_figs: bool, plot_dir: str):
"""Plot output associated with fuel tests
Args:
run_dir (str): run directory
out_file (str): output file
save_figs (bool): whether or not to save the figures
plot_dir (str): plot directory
"""

fuel_dat = xr.open_dataset(os.path.join(run_dir, self.out_file))

self.plot_NI_dat(fuel_dat, save_figs, plot_dir)
self.plot_moisture_dat(fuel_dat, save_figs, plot_dir)
self.plot_barchart(
fuel_dat,
"fuel_loading",
"Fuel loading",
"kgC m$^{-2}$",
save_figs,
plot_dir,
)
self.plot_barchart(
fuel_dat,
"frac_loading",
"Fractional fuel loading",
"0-1",
save_figs,
plot_dir,
)
self.plot_barchart(
fuel_dat,
"bulk_density",
"Fuel bulk density",
"kg m$^{-3}$",
save_figs,
plot_dir,
by_litter_type=False,
)
self.plot_barchart(
fuel_dat,
"SAV",
"Fuel surface area to volume ratio",
"cm$^{-1}$",
save_figs,
plot_dir,
by_litter_type=False,
)

@staticmethod
def plot_barchart(
fuel_dat: xr.Dataset,
var: str,
varname: str,
units: str,
save_figs: bool,
plot_dir: bool,
by_litter_type: bool = True,
):
"""Plots fuel data output as a bar chart
Args:
fuel_dat (xr.Dataset): fuel data output
var (str): variable to plot
varname (str): variable name for x axis
units (str): units description
save_figs (bool): whether or not to save figure
plot_dir (bool): where to save figure
by_litter_type (bool, optional): whether the bar chart is by litter type. Defaults to True.
"""

litter_classes = [
"twigs",
"small branches",
"large branches",
"trunks",
"dead leaves",
"live grass",
]
colors = [
"darksalmon",
"peru",
"saddlebrown",
"black",
"moccasin",
"yellowgreen",
]
fuel_models = [str(f) for f in fuel_dat.fuel_model.values]

if by_litter_type:
data_dict = {
lc: fuel_dat.isel(litter_class=i)[var].values
for i, lc in enumerate(litter_classes)
}
else:
data_dict = fuel_dat[var].values

_, ax = plt.subplots()
if by_litter_type:
bottom = np.zeros(len(fuel_models))
for i, (litter_class, dat) in enumerate(data_dict.items()):
ax.bar(
fuel_models,
dat,
0.5,
label=litter_class,
bottom=bottom,
color=colors[i],
)
bottom += dat
plt.legend(loc="center left", bbox_to_anchor=(1, 0.5))
else:
ax.bar(fuel_models, data_dict, color="darkcyan")

box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.75, box.height])
plt.ylabel(f"{varname} ({units})", fontsize=11)
plt.xticks(rotation=90)
plt.xlabel("Fuel Model")

if save_figs:
fig_name = os.path.join(plot_dir, f"{varname}_plot.png")
plt.savefig(fig_name)

@staticmethod
def plot_NI_dat(fuel_dat: xr.Dataset, save_figs: bool, plot_dir: str):
"""Plot output for Nesterov index
Args:
fuel_dat (Xarray Dataset): output fuel data
save_figs (bool): whether or not to save the figures
plot_dir (str): plot directory
"""

plt.figure()
fuel_dat.NI.plot()
plt.xlabel("Time", fontsize=11)
plt.ylabel("Nesterov Index", fontsize=11)

if save_figs:
fig_name = os.path.join(plot_dir, "Nesterov_plot.png")
plt.savefig(fig_name)

@staticmethod
def plot_moisture_dat(fuel_dat: xr.Dataset, save_figs: bool, plot_dir: str):
"""Plot output for fuel moisture
Args:
fuel_dat (Xarray Dataset): output fuel data
save_figs (bool): whether or not to save the figures
plot_dir (str): plot directory
"""

plt.figure()
fuel_dat.fuel_moisture.plot(hue="fuel_model")
plt.xlabel("Time", fontsize=11)
plt.ylabel("Fuel Moisture", fontsize=11)

if save_figs:
fig_name = os.path.join(plot_dir, "fuel_moisture_plot.png")
plt.savefig(fig_name)
6 changes: 5 additions & 1 deletion testing/functional_tests.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ use_param_file = False
other_args = []

[fuel]
test_dir = fates_fuel_ftest
test_dir = fates_fuel_ftest
test_exe = FATES_fuel_exe
out_file = fuel_out.nc
use_param_file = True
other_args = ['../testing/test_data/BONA_datm.nc']
13 changes: 10 additions & 3 deletions testing/run_functional_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,19 @@

# add testing subclasses here
from functional_class import FunctionalTest
from functional_testing.allometry.allometry_test import AllometryTest # pylint: disable=unused-import
from functional_testing.math_utils.math_utils_test import QuadraticTest # pylint: disable=unused-import
from functional_testing.allometry.allometry_test import (
AllometryTest,
) # pylint: disable=unused-import
from functional_testing.math_utils.math_utils_test import (
QuadraticTest,
) # pylint: disable=unused-import
from functional_testing.fire.fuel_test import FuelTest # pylint: disable=unused-import

add_cime_lib_to_path()

from CIME.utils import run_cmd_no_fail # pylint: disable=wrong-import-position,import-error,wrong-import-order
from CIME.utils import (
run_cmd_no_fail,
) # pylint: disable=wrong-import-position,import-error,wrong-import-order

# constants for this script
_DEFAULT_CONFIG_FILE = "functional_tests.cfg"
Expand Down
3 changes: 3 additions & 0 deletions testing/unit_tests.cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[fire_weather]
test_dir = fates_fire_weather_utest

[fire_fuel]
test_dir = fates_fire_fuel_utest
Loading

0 comments on commit 920c549

Please sign in to comment.