Skip to content

Commit

Permalink
refactor run enable scipy solvers
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-long committed Nov 15, 2021
1 parent 1a60ffd commit 8b0603a
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 45 deletions.
4 changes: 3 additions & 1 deletion add_book_to_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
add_book_to_path: ../
"""
import os
import sys

sys.path.append('./docs/source')
path_to_here = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(path_to_here, 'docs'))


def setup(dummy):
Expand Down
14 changes: 7 additions & 7 deletions docs/driver-example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 1,
"id": "46c9df26-5ac1-4511-9b9f-3b78a10dc4af",
"metadata": {},
"outputs": [],
Expand All @@ -30,7 +30,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 2,
"id": "09ec80a2-06d0-42e8-be0f-935c0920cb81",
"metadata": {},
"outputs": [],
Expand All @@ -48,7 +48,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 3,
"id": "f68ea35b-93e4-4dea-a67d-919ee79af8e9",
"metadata": {},
"outputs": [],
Expand All @@ -66,7 +66,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 4,
"id": "7e0f185b-e03b-4650-9f41-01668903e797",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -109,17 +109,17 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 5,
"id": "fddbc69a-44fb-4877-8fc4-2f7fbf8d0076",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x161e17cd0>]"
"[<matplotlib.lines.Line2D at 0x15f725d90>]"
]
},
"execution_count": 9,
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
},
Expand Down
85 changes: 53 additions & 32 deletions feisty/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from .core import settings as settings_mod
from .core.interface import feisty_instance_type

path_to_here = os.path.dirname(os.path.realpath(__file__))


_test_domain = dict(
tanh_shelf=testcase.domain_tanh_shelf,
)
Expand Down Expand Up @@ -102,16 +105,13 @@ def __init__(
def _forcing_t(self, t):
return self.forcing.interp(time=t)

def _init_time_coord(self, nt):
def _init_output_arrays(self, nt):
self.time = xr.DataArray(
np.arange(1.0, nt + 1.0, 1.0),
dims=('time'),
name='time',
attrs={'long_name': 'time'},
)

def _init_output_arrays(self):

zeros = xr.full_like(self.time, fill_value=0.0)
ds_diag = zeros * self.obj.tendency_data[self._diagnostic_names]
ds_prog = zeros * self.obj.get_prognostic().to_dataset()
Expand All @@ -127,45 +127,65 @@ def ds(self):
"""Data comprising the output from a ``feisty`` simulation."""
return self._ds

def run(self, nt, file_out=None):
def _compute_tendency(self, t, state_t):
"""Return the feisty time tendency."""
gcm_data_t = self._forcing_t(t)
return self.obj.compute_tendencies(
state_t.isel(group=self.obj.prog_ndx_fish),
state_t.isel(group=self.obj.prog_ndx_benthic_prey),
gcm_data_t.zooC,
gcm_data_t.zoo_mort,
T_pelagic=gcm_data_t.T_pelagic,
T_bottom=gcm_data_t.T_bottom,
poc_flux=gcm_data_t.poc_flux_bottom,
)

def _solve(self, nt, method):
"""Call a numerical ODE solver to integrate the feisty model in time."""

state_t = self.obj.get_prognostic().copy()
self._init_output_arrays(nt)
print('here')
if method == 'euler':
self._solve_foward_euler(nt, state_t)

elif method in ['Radau', 'RK45']:
# TODO: make input arguments
self._solve_scipy(nt, state_t, method)
else:
raise ValueError(f'unknown method: {method}')

def _solve_foward_euler(self, nt, state_t):
"""use forward-euler to solve feisty model"""
for n in range(nt):
dfdt = self._compute_tendency(self.time[n], state_t)
state_t[self.obj.prog_ndx_fish, :] = state_t[self.obj.prog_ndx_fish, :] + dfdt * self.dt
self._post_data(n, state_t)

def _solve_scipy(self, nt, state_t, method):
"""use a SciPy solver to integrate the model equation."""
raise NotImplementedError('scipy solvers not implemented')

def run(self, nt, file_out=None, method='euler'):
"""Integrate the FEISTY model.
Parameters
----------
nt : integer
Number of timesteps to run.
"""
# get tracer values
state_t = self.obj.get_prognostic().copy()
file_out : string
File name to write model output data.
# set up time-coordinate
self._init_time_coord(nt)
method : string
Method of solving feisty equations. Options: ['euler', 'Radau', 'RK45'].
# initialize memory for output
self._init_output_arrays()

# run loop
for n in range(nt):
# interpolate forcing
gcm_data_t = self._forcing_t(self.time[n])

# compute tendencies
dfdt = self.obj.compute_tendencies(
state_t.isel(group=self.obj.prog_ndx_fish),
state_t.isel(group=self.obj.prog_ndx_benthic_prey),
gcm_data_t.zooC,
gcm_data_t.zoo_mort,
T_pelagic=gcm_data_t.T_pelagic,
T_bottom=gcm_data_t.T_bottom,
poc_flux=gcm_data_t.poc_flux_bottom,
)

# advance FEISTY state
state_t[self.obj.prog_ndx_fish, :] = state_t[self.obj.prog_ndx_fish, :] + dfdt * self.dt
self._post_data(n, state_t)
.. note::
Only ``method='euler'`` is supported currently.
"""
self._solve(nt, method)
self._shutdown(file_out)

def _shutdown(self, file_out):
Expand Down Expand Up @@ -264,6 +284,7 @@ def simulate_testcase(

domain_dict = _test_domain[domain_name](**domain_kwargs)
forcing = _test_forcing[forcing_name](domain_dict, **forcing_kwargs)

return simulation(
domain_dict,
forcing,
Expand Down
2 changes: 1 addition & 1 deletion test-reports/junit.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="76" time="12.438" timestamp="2021-11-14T11:15:44.103291" hostname="cgdm-dine"><testcase classname="tests.test_core" name="test__set_zoo_biomass" time="0.003" /><testcase classname="tests.test_core" name="test__set_zoo_mortality" time="0.001" /><testcase classname="tests.test_core" name="test__set_zoo_mortality_wrong_shape" time="0.001" /><testcase classname="tests.test_core" name="test__set_fish_biomass" time="0.002" /><testcase classname="tests.test_core" name="test_set_benthic_biomass" time="0.002" /><testcase classname="tests.test_core" name="test_set_biomass_wrong_shape" time="0.001" /><testcase classname="tests.test_core" name="test_gcm_state_update" time="0.002" /><testcase classname="tests.test_driver" name="test_gen_domain" time="0.002" /><testcase classname="tests.test_driver" name="test_forcing_cyclic" time="0.060" /><testcase classname="tests.test_driver" name="test_read_settings" time="0.181" /><testcase classname="tests.test_driver" name="test_simulate_testcase_init_1" time="0.380" /><testcase classname="tests.test_driver" name="test_simulate_testcase_init_2" time="0.321" /><testcase classname="tests.test_driver" name="test_simulate_testcase_run" time="1.740" /><testcase classname="tests.test_fish_instance" name="test_fish_init" time="0.003" /><testcase classname="tests.test_fish_instance" name="test_fish_init_duplicate_fish" time="0.093" /><testcase classname="tests.test_fish_instance" name="test_fish_defaults" time="0.046" /><testcase classname="tests.test_fish_instance" name="test_fish_bad_harvest_selectivity" time="0.091" /><testcase classname="tests.test_fish_instance" name="test_fish_bad_energy_frac_somatic_growth" time="0.093" /><testcase classname="tests.test_fish_instance" name="test_fish_init_uncoupled" time="0.090" /><testcase classname="tests.test_fish_instance" name="test_fish_apply_pref" time="0.002" /><testcase classname="tests.test_fish_instance" name="test_is_demersal" time="0.002" /><testcase classname="tests.test_food_web" name="test_food_web_init_1" time="0.011" /><testcase classname="tests.test_food_web" name="test_food_web_init_2" time="0.002" /><testcase classname="tests.test_food_web" name="test_food_web_init_3" time="0.012" /><testcase classname="tests.test_food_web" name="test_missing_fish" time="0.105" /><testcase classname="tests.test_food_web" name="test_nonfish_predator" time="0.099" /><testcase classname="tests.test_food_web" name="test_pred_ndx_prey_filt" time="0.002" /><testcase classname="tests.test_food_web" name="test_duplicated_link_fails" time="0.098" /><testcase classname="tests.test_food_web" name="test_get_prey_biomass" time="0.426" /><testcase classname="tests.test_food_web" name="test_get_prey_biomass_dne" time="0.001" /><testcase classname="tests.test_food_web" name="test_get_consumption_bad_args" time="0.003" /><testcase classname="tests.test_food_web" name="test_get_consumption_none_existent_predprey" time="0.002" /><testcase classname="tests.test_food_web" name="test_get_consumption" time="0.187" /><testcase classname="tests.test_food_web" name="test_compute_feeding_1" time="0.161" /><testcase classname="tests.test_food_web" name="test_rescale_zoo_consumption" time="0.056" /><testcase classname="tests.test_init" name="test_reproduction_routing" time="0.003" /><testcase classname="tests.test_init" name="test_reproduction_routing_bad_is_larval" time="0.098" /><testcase classname="tests.test_init" name="test_domain_values" time="0.002" /><testcase classname="tests.test_init" name="test_domain_bad_bathymetry" time="0.047" /><testcase classname="tests.test_init" name="test_ecosystem_init" time="0.001" /><testcase classname="tests.test_init" name="test_ecosystem_size_class_bounds" time="0.001" /><testcase classname="tests.test_init" name="test_func_type_init" time="0.001" /><testcase classname="tests.test_init" name="test_bad_func_type_fails" time="0.091" /><testcase classname="tests.test_init" name="test_bad_mortality_type_fails" time="0.098" /><testcase classname="tests.test_init" name="test_bad_pelagic_demersal_coupling_types_fails" time="0.102" /><testcase classname="tests.test_init" name="test_bad_pelagic_functional_types_fails" time="0.109" /><testcase classname="tests.test_init" name="test_bad_functional_types_apply_pref" time="0.101" /><testcase classname="tests.test_init" name="test_bad_demersal_functional_types_fails" time="0.088" /><testcase classname="tests.test_init" name="test_bad_size_class_fail" time="0.090" /><testcase classname="tests.test_init" name="test_duplicated_pelagic_demersal_type_keys" time="0.089" /><testcase classname="tests.test_init" name="test_zoo_init" time="0.001" /><testcase classname="tests.test_init" name="test_zoo_mortality_not_offline" time="0.299" /><testcase classname="tests.test_init" name="test_biomass_init" time="0.003" /><testcase classname="tests.test_init" name="test_biomass_init_values" time="0.001" /><testcase classname="tests.test_init" name="test_biomass_bad_shape_benthic_prey" time="0.060" /><testcase classname="tests.test_init" name="test_biomass_bad_shape_fish" time="0.061" /><testcase classname="tests.test_init" name="test_duplicate_names_across_groups" time="0.095" /><testcase classname="tests.test_init" name="test_gcm_state" time="0.001" /><testcase classname="tests.test_init" name="test_fishing" time="0.001" /><testcase classname="tests.test_init" name="test_init_tendency_arrays" time="0.003" /><testcase classname="tests.test_process" name="test_t_weighted_mean_temp[10.0-1.0-1.0-10.0]" time="0.001" /><testcase classname="tests.test_process" name="test_t_weighted_mean_temp[10.0-1.0-0.5-5.5]" time="0.001" /><testcase classname="tests.test_process" name="test_t_weighted_mean_temp[10.0-1.0-0.0-1.0]" time="0.002" /><testcase classname="tests.test_process" name="test_t_frac_pelagic" time="0.025" /><testcase classname="tests.test_process" name="test_update_benthic_prey" time="0.006" /><testcase classname="tests.test_process" name="test_compute_metabolism" time="0.057" /><testcase classname="tests.test_process" name="test_compute_ingestion" time="0.030" /><testcase classname="tests.test_process" name="test_compute_predation" time="0.053" /><testcase classname="tests.test_process" name="test_compute_mortality" time="2.426" /><testcase classname="tests.test_process" name="test_compute_nu" time="0.015" /><testcase classname="tests.test_process" name="test_compute_gamma" time="0.088" /><testcase classname="tests.test_process" name="test_compute_reproduction" time="0.014" /><testcase classname="tests.test_process" name="test_compute_recruitment" time="0.017" /><testcase classname="tests.test_process" name="test_compute_total_tendency" time="0.069" /><testcase classname="tests.test_process" name="test_compute_fish_catch" time="0.009" /><testcase classname="tests.test_process" name="test_compute_tendencies" time="0.397" /></testsuite></testsuites>
<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="78" time="11.965" timestamp="2021-11-14T17:16:48.201506" hostname="cgdm-dine"><testcase classname="tests.test_core" name="test__set_zoo_biomass" time="0.003" /><testcase classname="tests.test_core" name="test__set_zoo_mortality" time="0.001" /><testcase classname="tests.test_core" name="test__set_zoo_mortality_wrong_shape" time="0.001" /><testcase classname="tests.test_core" name="test__set_fish_biomass" time="0.003" /><testcase classname="tests.test_core" name="test_set_benthic_biomass" time="0.004" /><testcase classname="tests.test_core" name="test_set_biomass_wrong_shape" time="0.002" /><testcase classname="tests.test_core" name="test_gcm_state_update" time="0.002" /><testcase classname="tests.test_docs" name="test_add_to_path" time="0.003" /><testcase classname="tests.test_driver" name="test_gen_domain" time="0.002" /><testcase classname="tests.test_driver" name="test_forcing_cyclic" time="0.057" /><testcase classname="tests.test_driver" name="test_not_implemented" time="0.298" /><testcase classname="tests.test_driver" name="test_read_settings" time="0.237" /><testcase classname="tests.test_driver" name="test_simulate_testcase_init_1" time="0.397" /><testcase classname="tests.test_driver" name="test_simulate_testcase_init_2" time="0.301" /><testcase classname="tests.test_driver" name="test_simulate_testcase_run" time="1.523" /><testcase classname="tests.test_fish_instance" name="test_fish_init" time="0.003" /><testcase classname="tests.test_fish_instance" name="test_fish_init_duplicate_fish" time="0.090" /><testcase classname="tests.test_fish_instance" name="test_fish_defaults" time="0.044" /><testcase classname="tests.test_fish_instance" name="test_fish_bad_harvest_selectivity" time="0.087" /><testcase classname="tests.test_fish_instance" name="test_fish_bad_energy_frac_somatic_growth" time="0.087" /><testcase classname="tests.test_fish_instance" name="test_fish_init_uncoupled" time="0.087" /><testcase classname="tests.test_fish_instance" name="test_fish_apply_pref" time="0.001" /><testcase classname="tests.test_fish_instance" name="test_is_demersal" time="0.002" /><testcase classname="tests.test_food_web" name="test_food_web_init_1" time="0.008" /><testcase classname="tests.test_food_web" name="test_food_web_init_2" time="0.001" /><testcase classname="tests.test_food_web" name="test_food_web_init_3" time="0.011" /><testcase classname="tests.test_food_web" name="test_missing_fish" time="0.099" /><testcase classname="tests.test_food_web" name="test_nonfish_predator" time="0.093" /><testcase classname="tests.test_food_web" name="test_pred_ndx_prey_filt" time="0.004" /><testcase classname="tests.test_food_web" name="test_duplicated_link_fails" time="0.098" /><testcase classname="tests.test_food_web" name="test_get_prey_biomass" time="0.367" /><testcase classname="tests.test_food_web" name="test_get_prey_biomass_dne" time="0.001" /><testcase classname="tests.test_food_web" name="test_get_consumption_bad_args" time="0.003" /><testcase classname="tests.test_food_web" name="test_get_consumption_none_existent_predprey" time="0.002" /><testcase classname="tests.test_food_web" name="test_get_consumption" time="0.156" /><testcase classname="tests.test_food_web" name="test_compute_feeding_1" time="0.156" /><testcase classname="tests.test_food_web" name="test_rescale_zoo_consumption" time="0.056" /><testcase classname="tests.test_init" name="test_reproduction_routing" time="0.003" /><testcase classname="tests.test_init" name="test_reproduction_routing_bad_is_larval" time="0.095" /><testcase classname="tests.test_init" name="test_domain_values" time="0.002" /><testcase classname="tests.test_init" name="test_domain_bad_bathymetry" time="0.044" /><testcase classname="tests.test_init" name="test_ecosystem_init" time="0.001" /><testcase classname="tests.test_init" name="test_ecosystem_size_class_bounds" time="0.001" /><testcase classname="tests.test_init" name="test_func_type_init" time="0.001" /><testcase classname="tests.test_init" name="test_bad_func_type_fails" time="0.089" /><testcase classname="tests.test_init" name="test_bad_mortality_type_fails" time="0.090" /><testcase classname="tests.test_init" name="test_bad_pelagic_demersal_coupling_types_fails" time="0.085" /><testcase classname="tests.test_init" name="test_bad_pelagic_functional_types_fails" time="0.087" /><testcase classname="tests.test_init" name="test_bad_functional_types_apply_pref" time="0.087" /><testcase classname="tests.test_init" name="test_bad_demersal_functional_types_fails" time="0.085" /><testcase classname="tests.test_init" name="test_bad_size_class_fail" time="0.089" /><testcase classname="tests.test_init" name="test_duplicated_pelagic_demersal_type_keys" time="0.085" /><testcase classname="tests.test_init" name="test_zoo_init" time="0.001" /><testcase classname="tests.test_init" name="test_zoo_mortality_not_offline" time="0.280" /><testcase classname="tests.test_init" name="test_biomass_init" time="0.003" /><testcase classname="tests.test_init" name="test_biomass_init_values" time="0.001" /><testcase classname="tests.test_init" name="test_biomass_bad_shape_benthic_prey" time="0.054" /><testcase classname="tests.test_init" name="test_biomass_bad_shape_fish" time="0.053" /><testcase classname="tests.test_init" name="test_duplicate_names_across_groups" time="0.090" /><testcase classname="tests.test_init" name="test_gcm_state" time="0.001" /><testcase classname="tests.test_init" name="test_fishing" time="0.002" /><testcase classname="tests.test_init" name="test_init_tendency_arrays" time="0.004" /><testcase classname="tests.test_process" name="test_t_weighted_mean_temp[10.0-1.0-1.0-10.0]" time="0.001" /><testcase classname="tests.test_process" name="test_t_weighted_mean_temp[10.0-1.0-0.5-5.5]" time="0.001" /><testcase classname="tests.test_process" name="test_t_weighted_mean_temp[10.0-1.0-0.0-1.0]" time="0.001" /><testcase classname="tests.test_process" name="test_t_frac_pelagic" time="0.027" /><testcase classname="tests.test_process" name="test_update_benthic_prey" time="0.007" /><testcase classname="tests.test_process" name="test_compute_metabolism" time="0.058" /><testcase classname="tests.test_process" name="test_compute_ingestion" time="0.029" /><testcase classname="tests.test_process" name="test_compute_predation" time="0.054" /><testcase classname="tests.test_process" name="test_compute_mortality" time="2.350" /><testcase classname="tests.test_process" name="test_compute_nu" time="0.015" /><testcase classname="tests.test_process" name="test_compute_gamma" time="0.077" /><testcase classname="tests.test_process" name="test_compute_reproduction" time="0.013" /><testcase classname="tests.test_process" name="test_compute_recruitment" time="0.015" /><testcase classname="tests.test_process" name="test_compute_total_tendency" time="0.061" /><testcase classname="tests.test_process" name="test_compute_fish_catch" time="0.008" /><testcase classname="tests.test_process" name="test_compute_tendencies" time="0.360" /></testsuite></testsuites>
10 changes: 10 additions & 0 deletions tests/test_docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import os
import sys

from . import conftest


def test_add_to_path():
import add_book_to_path

assert conftest.path_to_here.replace('tests', 'docs') in sys.path
Loading

0 comments on commit 8b0603a

Please sign in to comment.