pyDeltaRCM 2.1.9__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pydeltarcm-2.1.9/pyDeltaRCM.egg-info → pydeltarcm-2.2.0}/PKG-INFO +1 -1
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/conf.py +4 -2
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/custom_saving.rst +14 -9
- pydeltarcm-2.2.0/docs/source/examples/gotcha_simulataneous_models.rst +62 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/index.rst +8 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/info/outputfile.rst +20 -14
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/_version.py +1 -1
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/hook_tools.py +1 -1
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/init_tools.py +208 -59
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/iteration_tools.py +35 -4
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/model.py +44 -36
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/water_tools.py +10 -6
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0/pyDeltaRCM.egg-info}/PKG-INFO +1 -1
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM.egg-info/SOURCES.txt +1 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/integration/test_checkpointing.py +321 -255
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/integration/test_consistent_outputs.py +70 -9
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/integration/test_timing_triggers.py +11 -11
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_init_tools.py +266 -28
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_iteration_tools.py +85 -9
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/LICENSE +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/MANIFEST.in +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/README.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/.nojekyll +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/_resources/checkpoint/checkpoint.npz +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/_resources/checkpoint.yaml +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/_static/style.css +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/_templates/page.html +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/basic_runs.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/custom_class_preprocessor.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/custom_yaml.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/modelzoo.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/overwrite_topo_diffusion.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/resume_from_checkpoint.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/simple_example.ipynb +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/slight_slope.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/subsidence_region.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/updating_boundary_conditions.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/variable_bedload.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/examples/variable_velocity.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/guides/10min.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/guides/advanced_configuration_guide.inc +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/guides/developer_guide.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/guides/getting_started.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/guides/subsidence_guide.inc +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/guides/user_guide.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/info/hydrodynamics.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/info/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/info/initialization.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/info/modeltime.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/info/morphodynamics.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/info/yamlparameters.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/meta/citing.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/meta/conduct.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/meta/contributing.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/meta/installing.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/meta/license.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/meta/usedby.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/debug_tools/debug_demo.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/guides/10min_demo.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/guides/cover.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/guides/output_file.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/init_tools/domain_basin_inlet_depth.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/init_tools/domain_inlet_geometry.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/init_tools/domain_parameters.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/init_tools/domain_size_compare.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/modeltime/_base.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/modeltime/four_year_condensed_plot.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/modeltime/four_year_plot.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/modeltime/one_year_plot.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/sed_tools/_initial_bed_state.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/sed_tools/route_all_mud_parcels.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/sed_tools/route_all_sand_parcels.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/sed_tools/sediment_weights_examples.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/sed_tools/topo_diffusion.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/water_tools/_accumulate_free_surface_walks.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/water_tools/_check_for_loops.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/water_tools/_smooth_free_surface.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/water_tools/compute_free_surface_inputs.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/water_tools/compute_free_surface_outputs.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/water_tools/flooding_correction.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/water_tools/run_water_iteration.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/pyplots/water_tools/water_weights_examples.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/debug_tools/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/hook_tools/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/init_tools/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/iteration_tools/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/model/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/model/model_hooks.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/model/yaml_defaults.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/preprocessor/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/sed_tools/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/shared_tools/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/docs/source/reference/water_tools/index.rst +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/__init__.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/__main__.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/debug_tools.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/default.yml +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/preprocessor.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/sed_tools.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM/shared_tools.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM.egg-info/dependency_links.txt +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM.egg-info/entry_points.txt +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM.egg-info/requires.txt +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyDeltaRCM.egg-info/top_level.txt +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/pyproject.toml +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/setup.cfg +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/__init__.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_list_index.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_list_mix_tuple_index.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_list_tuple.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_multiple_diff_args.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_multiple_diff_kwargs.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_multiple_index_calls.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_no_grid.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_single_index.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_cell_type_single_tuple.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_velocity.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_domain_withlabel.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_iwalk.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_plot_multiple_subplots.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_show_line_pts_Nx2_array.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/imgs_baseline/test_show_line_set_points.png +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/integration/__init__.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/integration/test_cli.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_debug_tools.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_logging.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_model.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_preprocessor.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_sed_tools.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_shared_tools.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/test_water_tools.py +0 -0
- {pydeltarcm-2.1.9 → pydeltarcm-2.2.0}/tests/utilities.py +0 -0
|
@@ -113,5 +113,7 @@ linkcheck_ignore = [
|
|
|
113
113
|
r'https://doi.org/10.1029/2021GL095053',
|
|
114
114
|
r'https://doi.org/10.1029/2018GL079405',
|
|
115
115
|
r'https://doi.org/10.1029/2022JF006762',
|
|
116
|
-
r'https://doi.org/10.1086/626637'
|
|
117
|
-
|
|
116
|
+
r'https://doi.org/10.1086/626637',
|
|
117
|
+
r'https://doi.org/10.1029/2023JE008183',
|
|
118
|
+
r'https://doi.org/10.1029/2023je008183'
|
|
119
|
+
]
|
|
@@ -17,11 +17,11 @@ For example, ``self._save_fig_list['active_layer'] = ['active_layer']`` will pro
|
|
|
17
17
|
When adding variables or metadata to be initialized and subsequently saved in the output netCDF, the key-value pair relationship is as follows.
|
|
18
18
|
The key added to ``self._save_var_list`` is the name of the variable as it will be recorded in the netCDF file, this *does not* have to correspond to the name of an attribute in the model.
|
|
19
19
|
To add a variable to the metadata, a key must be added to ``self._save_var_list['meta']``.
|
|
20
|
-
The expected value for a given key is a list containing strings indicating the model attribute to be saved, its units, the variable type, and lastly the variable dimensions (e.g., ``['active_layer', 'fraction', 'f4', ('
|
|
20
|
+
The expected value for a given key is a list containing strings indicating the model attribute to be saved, its units, the variable type, and lastly the variable dimensions (e.g., ``['active_layer', 'fraction', 'f4', ('seconds', 'x', 'y')]`` for the active layer).
|
|
21
21
|
|
|
22
22
|
.. important::
|
|
23
23
|
|
|
24
|
-
The dimensions of the custom variable being specified must match *exactly* with one of the three standard dimensions: `x`, `y`, `
|
|
24
|
+
The dimensions of the custom variable being specified must match *exactly* with one of the three standard dimensions: `x`, `y`, `seconds`.
|
|
25
25
|
Use of an invalid dimension will result in an error.
|
|
26
26
|
|
|
27
27
|
An example of using the hook and creating a model subclass to customize the figures, gridded variables, and metadata being saved is provided below.
|
|
@@ -48,14 +48,19 @@ An example of using the hook and creating a model subclass to customize the figu
|
|
|
48
48
|
... self._save_fig_list['active_layer'] = ['active_layer']
|
|
49
49
|
...
|
|
50
50
|
... # save the active layer grid each save_dt w/ a short name
|
|
51
|
-
... self._save_var_list['actlay'] = [
|
|
52
|
-
...
|
|
53
|
-
...
|
|
51
|
+
... self._save_var_list['actlay'] = [
|
|
52
|
+
... 'active_layer', 'fraction',
|
|
53
|
+
... 'f4', ('seconds', 'x', 'y'),
|
|
54
|
+
... 'channel_bottom__sediment__active_layer'
|
|
55
|
+
... ]
|
|
54
56
|
...
|
|
55
57
|
... # save number of water parcels w/ a long name
|
|
56
|
-
... self._save_var_list['meta']['water_parcels'] = [
|
|
57
|
-
...
|
|
58
|
-
...
|
|
58
|
+
... self._save_var_list['meta']['water_parcels'] = [
|
|
59
|
+
... 'Np_water',
|
|
60
|
+
... 'parcels',
|
|
61
|
+
... 'i8', (),
|
|
62
|
+
... 'model_water__number_parcels'
|
|
63
|
+
... ]
|
|
59
64
|
|
|
60
65
|
Next, we instantiate the model class.
|
|
61
66
|
|
|
@@ -83,4 +88,4 @@ For simplicity we will just check that the appropriate parameters were added to
|
|
|
83
88
|
{'active_layer': ['active_layer']}
|
|
84
89
|
|
|
85
90
|
>>> print(mdl._save_var_list)
|
|
86
|
-
{'meta': {'water_parcels': ['Np_water', 'parcels', 'i8', ()]}, 'actlay': ['active_layer', 'fraction', 'f4', ('
|
|
91
|
+
{'meta': {'water_parcels': ['Np_water', 'parcels', 'i8', (), 'model_water__number_parcels']}, 'actlay': ['active_layer', 'fraction', 'f4', ('seconds', 'x', 'y'), 'channel_bottom__sediment__active_layer']}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Instantiating and running two models iteratively on the same core is not reproducible
|
|
2
|
+
=====================================================================================
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
You cannot run models "simultaneously" and get reproducible results.
|
|
6
|
+
|
|
7
|
+
In an ideal world, two models with same seed should give same result,
|
|
8
|
+
regardless of how they are run. But if two models are called intermittently,
|
|
9
|
+
then the result is not reproducible (at least on a per-model basis) because
|
|
10
|
+
the random-number generator is thrown out of sync with respect to the single
|
|
11
|
+
model and seed. More explanation below.
|
|
12
|
+
|
|
13
|
+
.. note::
|
|
14
|
+
|
|
15
|
+
As of 03/2026, numba does not implement random number generation as an
|
|
16
|
+
object, and so we cannot aviod this "gotcha".
|
|
17
|
+
|
|
18
|
+
.. code::
|
|
19
|
+
|
|
20
|
+
# initialize models
|
|
21
|
+
test1 = DeltaModel()
|
|
22
|
+
test2 = DeltaModel()
|
|
23
|
+
|
|
24
|
+
for _ in range(0, 5):
|
|
25
|
+
test1.update()
|
|
26
|
+
test2.update()
|
|
27
|
+
|
|
28
|
+
test1.finalize()
|
|
29
|
+
test2.finalize()
|
|
30
|
+
|
|
31
|
+
# test that gives same result (WILL FAIL)
|
|
32
|
+
difference = test1.eta - test2.eta
|
|
33
|
+
assert np.all(difference == 0)
|
|
34
|
+
|
|
35
|
+
.. DEVNOTE: see test in tests/integration/test_consistent_outputs.py in TestConsistentOutputsSameSeed called test_same_models_simulataneous_not_parallel
|
|
36
|
+
|
|
37
|
+
**The above code will fail to generate reproducible results.**
|
|
38
|
+
|
|
39
|
+
The problem is that both test and test2 access the same underlying random
|
|
40
|
+
number generator in Numba, and therefore follow different trajectories over
|
|
41
|
+
time. The only way around this is to instantiate the models sequentially
|
|
42
|
+
(resetting the seed via the instantiation of the second one after finishing
|
|
43
|
+
the first one), or instantiating the objects in subprocesses (this is what
|
|
44
|
+
the `preprocessor` does for parallel runs).
|
|
45
|
+
|
|
46
|
+
Of course, if you don't care about reproducibility at the moment (e.g., prototyping, testing approaches, etc), you can totally use the above approach. **Your final model code for analysis should be reproducible and not use this approach!**
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
The below code will work to give reproducible results.
|
|
50
|
+
|
|
51
|
+
.. code::
|
|
52
|
+
|
|
53
|
+
test1 = DeltaModel(input_file=p1)
|
|
54
|
+
for _ in range(0, 5):
|
|
55
|
+
test1.update()
|
|
56
|
+
test1.finalize()
|
|
57
|
+
|
|
58
|
+
test2 = DeltaModel(input_file=p2)
|
|
59
|
+
for _ in range(0, 5):
|
|
60
|
+
test2.update()
|
|
61
|
+
test2.finalize()
|
|
62
|
+
|
|
@@ -10,30 +10,35 @@ Gridded Variables
|
|
|
10
10
|
|
|
11
11
|
In any given run, the saving parameters "save_<var>_grids" control whether or
|
|
12
12
|
not that 2-D grid variable (e.g. velocity) is saved to the netCDF4 file. In
|
|
13
|
-
the netCDF4 file, a 3-D array with the dimensions `
|
|
13
|
+
the netCDF4 file, a 3-D array with the dimensions `seconds` :math:`\times`
|
|
14
14
|
`x` :math:`\times` `y` is created for each 2-D grid variable that is set to
|
|
15
15
|
be saved. Note that `x` is the *downstream* coordinate, rather than the
|
|
16
16
|
Cartesian `x` when displaying the grid. The appropriate units for all
|
|
17
17
|
variables are stored: for example "meters per second" for the *velocity*
|
|
18
|
-
grid.
|
|
18
|
+
grid. All variables include a description via the `long_name` attribute.
|
|
19
19
|
|
|
20
|
-
..
|
|
20
|
+
.. important::
|
|
21
21
|
|
|
22
|
-
The format of the output netCDF file
|
|
23
|
-
old format is documented
|
|
24
|
-
in :attr:`~pyDeltaRCM.model.DeltaModel.legacy_netcdf`, and
|
|
25
|
-
parameter `legacy_netcdf` can be used to create
|
|
26
|
-
the old coordinate configuration.
|
|
22
|
+
The format of the output netCDF file coordinates changed in `v2.2.0`. The
|
|
23
|
+
old format (up to v2.1.9) is documented
|
|
24
|
+
in :attr:`~pyDeltaRCM.model.DeltaModel.legacy_netcdf`, and the input
|
|
25
|
+
parameter `legacy_netcdf` can be used to create an output netcdf file with
|
|
26
|
+
the old coordinate configuration. The output format for pyDeltaRCM v2.1.0
|
|
27
|
+
and earlier is deprecated and has been removed. Changing to the new output
|
|
28
|
+
format should be a small change for most users, with only the name of the
|
|
29
|
+
temporal dimension and the metadata subgroup changing in the new output.
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
Grid Coordinates
|
|
30
33
|
================
|
|
31
34
|
|
|
32
|
-
Grid coordinates are specified in the variables `
|
|
33
|
-
These arrays are 1D arrays, which specify the location
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
Grid coordinates are specified in the variables `seconds`, `x`, and `y` in the
|
|
36
|
+
output netCDF4 file. These arrays are 1D arrays, which specify the location
|
|
37
|
+
of each cell in the domain in *dimensional* coordinates (e.g., meters). In
|
|
38
|
+
the downstream direction, the distance of each cell from the inlet boundary
|
|
39
|
+
is specified in `x` in meters. Similarly, the cross-domain distance is
|
|
40
|
+
specified in `y` in meters. Lastly, the `seconds` variable is stored as a 1D
|
|
41
|
+
array recording model elapsed time in seconds.
|
|
37
42
|
|
|
38
43
|
|
|
39
44
|
Model Metadata
|
|
@@ -53,6 +58,7 @@ saved as metadata are the following:
|
|
|
53
58
|
- Sediment concentration: `C0_percent`
|
|
54
59
|
- Characteristic Velocity: `u0`
|
|
55
60
|
- If subsidence is enabled:
|
|
61
|
+
|
|
56
62
|
- Subsidence start time: `start_subsidence`
|
|
57
63
|
- Subsidence rate: `sigma`
|
|
58
64
|
|
|
@@ -66,7 +72,7 @@ library. These libraries range from the
|
|
|
66
72
|
to higher-level libraries such as
|
|
67
73
|
`xarray <https://github.com/pydata/xarray>`_. For deltas, and specifically
|
|
68
74
|
*pyDeltaRCM*, there is also a package under development called
|
|
69
|
-
`
|
|
75
|
+
`sandplover <https://github.com/sandpiper-toolchain/sandplover>`_,
|
|
70
76
|
that is being designed to help post-process and analyze *pyDeltaRCM* outputs.
|
|
71
77
|
|
|
72
78
|
|
|
@@ -237,7 +237,7 @@ class hook_tools(abc.ABC):
|
|
|
237
237
|
.. note::
|
|
238
238
|
|
|
239
239
|
For a vector of time-varying metadata, the dimension
|
|
240
|
-
should be specified as ('
|
|
240
|
+
should be specified as ('time').
|
|
241
241
|
|
|
242
242
|
Expected format for time varying grid entries as keys within the
|
|
243
243
|
`self._save_var_list` dictionary:
|
|
@@ -225,9 +225,9 @@ class init_tools(abc.ABC):
|
|
|
225
225
|
self.out_dir = self._input_file_vars["out_dir"]
|
|
226
226
|
self.verbose = self._input_file_vars["verbose"]
|
|
227
227
|
if self._input_file_vars["legacy_netcdf"]:
|
|
228
|
-
self._netcdf_coords = ("total_time", "length", "width")
|
|
229
|
-
else:
|
|
230
228
|
self._netcdf_coords = ("time", "x", "y")
|
|
229
|
+
else:
|
|
230
|
+
self._netcdf_coords = ("seconds", "x", "y")
|
|
231
231
|
|
|
232
232
|
def process_input_to_model(self) -> None:
|
|
233
233
|
"""Process input file to model variables.
|
|
@@ -386,7 +386,6 @@ class init_tools(abc.ABC):
|
|
|
386
386
|
|
|
387
387
|
# kernels for topographic smoothing
|
|
388
388
|
self.kernel1 = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]]).astype(np.int64)
|
|
389
|
-
|
|
390
389
|
self.kernel2 = np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]]).astype(np.int64)
|
|
391
390
|
|
|
392
391
|
def create_boundary_conditions(self) -> None:
|
|
@@ -434,7 +433,7 @@ class init_tools(abc.ABC):
|
|
|
434
433
|
|
|
435
434
|
# at inlet
|
|
436
435
|
self.qw0 = self.u0 * self.h0 # water unit input discharge
|
|
437
|
-
self.Qp_water = self.Qw0 / self._Np_water #
|
|
436
|
+
self.Qp_water = self.Qw0 / self._Np_water # discharge each water parcel
|
|
438
437
|
self.qs0 = self.qw0 * self.C0 # sed unit discharge
|
|
439
438
|
self.dVs = 0.1 * self.N0**2 * self.V0 # total sed added per timestep
|
|
440
439
|
self.Qs0 = self.Qw0 * self.C0 # sediment total input discharge
|
|
@@ -660,6 +659,22 @@ class init_tools(abc.ABC):
|
|
|
660
659
|
file_path = os.path.join(directory, filename)
|
|
661
660
|
_msg = "Target output NetCDF4 file: {file}".format(file=file_path)
|
|
662
661
|
self.log_info(_msg, verbosity=2)
|
|
662
|
+
if not self._legacy_netcdf:
|
|
663
|
+
_sandsuet_version = "1.0.0"
|
|
664
|
+
_msg = "Output file in sandsuet version {ver} schema".format(
|
|
665
|
+
ver=_sandsuet_version
|
|
666
|
+
)
|
|
667
|
+
else:
|
|
668
|
+
_msg = "Output file in legacy schema"
|
|
669
|
+
warnings.warn(
|
|
670
|
+
"Creating output netcdf file in legacy schema. This format is "
|
|
671
|
+
"provided as a convenience for users who are currently "
|
|
672
|
+
"relying on workflows that use an old format of netcdf file. "
|
|
673
|
+
"It will be removed in the future. Any new workflows should "
|
|
674
|
+
"leverage the sandsuet formatted data specification "
|
|
675
|
+
"(i.e., `legacy_netcdf=False`)."
|
|
676
|
+
)
|
|
677
|
+
self.log_info(_msg, verbosity=1)
|
|
663
678
|
|
|
664
679
|
if (os.path.exists(file_path)) and (self._clobber_netcdf is False):
|
|
665
680
|
raise FileExistsError(
|
|
@@ -679,6 +694,8 @@ class init_tools(abc.ABC):
|
|
|
679
694
|
self.output_netcdf.source = "pyDeltaRCM v{ver}".format(
|
|
680
695
|
ver=self.__pyDeltaRCM_version__
|
|
681
696
|
)
|
|
697
|
+
if not self._legacy_netcdf:
|
|
698
|
+
self.output_netcdf.sandsuet_version = _sandsuet_version
|
|
682
699
|
|
|
683
700
|
# create master dimensions (pulls from `self._netcdf_coords`)
|
|
684
701
|
self.output_netcdf.createDimension(self._netcdf_coords[1], self.L)
|
|
@@ -686,77 +703,158 @@ class init_tools(abc.ABC):
|
|
|
686
703
|
self.output_netcdf.createDimension(self._netcdf_coords[0], None)
|
|
687
704
|
|
|
688
705
|
# create master coordinates (as netCDF variables)
|
|
689
|
-
time = self.output_netcdf.createVariable(
|
|
690
|
-
"time", "f4", (self._netcdf_coords[0],)
|
|
691
|
-
)
|
|
692
|
-
time.units = "second"
|
|
693
|
-
|
|
694
706
|
if self._legacy_netcdf:
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
"x", "f4", self._netcdf_coords[1:]
|
|
698
|
-
)
|
|
699
|
-
y = self.output_netcdf.createVariable(
|
|
700
|
-
"y", "f4", self._netcdf_coords[1:]
|
|
707
|
+
time = self.output_netcdf.createVariable(
|
|
708
|
+
"time", "f4", (self._netcdf_coords[0],)
|
|
701
709
|
)
|
|
702
|
-
x[:] = self.x
|
|
703
|
-
y[:] = self.y
|
|
704
710
|
|
|
705
711
|
else:
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
y[:] = self.yc
|
|
712
|
+
time = self.output_netcdf.createVariable(
|
|
713
|
+
"seconds", "f4", (self._netcdf_coords[0],)
|
|
714
|
+
)
|
|
715
|
+
time.units = "second"
|
|
711
716
|
|
|
717
|
+
# new output format is 1d x and y
|
|
718
|
+
x = self.output_netcdf.createVariable("x", "f4", ("x"))
|
|
719
|
+
y = self.output_netcdf.createVariable("y", "f4", ("y"))
|
|
720
|
+
x[:] = self.xc
|
|
721
|
+
y[:] = self.yc
|
|
712
722
|
x.units = "meter"
|
|
713
723
|
y.units = "meter"
|
|
714
724
|
|
|
715
|
-
# set up
|
|
716
|
-
def _create_grid_variable(
|
|
725
|
+
# set up function to output data grids
|
|
726
|
+
def _create_grid_variable(
|
|
727
|
+
varname, varunits, vartype="f4", vardims=(), varlong=None
|
|
728
|
+
):
|
|
717
729
|
_v = self.output_netcdf.createVariable(varname, vartype, vardims)
|
|
718
730
|
_v.units = varunits
|
|
731
|
+
if varlong is not None:
|
|
732
|
+
# long_name is provided, record it
|
|
733
|
+
_v.long_name = varlong
|
|
734
|
+
else:
|
|
735
|
+
if not self._legacy_netcdf:
|
|
736
|
+
raise ValueError(
|
|
737
|
+
f"long name must be provided for all variables to create a "
|
|
738
|
+
f"sandsuet compliant data output, "
|
|
739
|
+
f"but was not provided for variable '{varname}'."
|
|
740
|
+
)
|
|
719
741
|
|
|
742
|
+
# loop through main output data grids
|
|
720
743
|
_var_list = list(self._save_var_list.keys())
|
|
721
|
-
_var_list.remove("meta")
|
|
744
|
+
_var_list.remove("meta") # remove group from list
|
|
722
745
|
for _val in _var_list:
|
|
746
|
+
if isinstance(self._save_var_list[_val], list):
|
|
747
|
+
### for now, we silently convert to dictionary format
|
|
748
|
+
# # inputs should be specified as a dictionary
|
|
749
|
+
# warnings.warn(
|
|
750
|
+
# f"Specification format for output data should be `dict`, "
|
|
751
|
+
# f"but was `list`. Converting `list` for one or more variables "
|
|
752
|
+
# f"to `dict` based on item order. This compatability will "
|
|
753
|
+
# f"be removed in a future version."
|
|
754
|
+
# )
|
|
755
|
+
###
|
|
756
|
+
# do the conversion
|
|
757
|
+
__inlist = self._save_var_list[_val]
|
|
758
|
+
__varname = _val
|
|
759
|
+
__varlong = __inlist[4] if len(__inlist) > 4 else None
|
|
760
|
+
_vardict = dict(
|
|
761
|
+
varname=__varname, # use dict key as varname
|
|
762
|
+
varunits=__inlist[1],
|
|
763
|
+
vartype=__inlist[2],
|
|
764
|
+
vardims=__inlist[3],
|
|
765
|
+
varlong=__varlong,
|
|
766
|
+
)
|
|
767
|
+
else:
|
|
768
|
+
_vardict = self._save_var_list[_val]
|
|
769
|
+
|
|
723
770
|
_create_grid_variable(
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
771
|
+
varname=_vardict["varname"],
|
|
772
|
+
varunits=_vardict["varunits"],
|
|
773
|
+
vartype=_vardict["vartype"],
|
|
774
|
+
vardims=_vardict["vardims"],
|
|
775
|
+
varlong=_vardict["varlong"],
|
|
728
776
|
)
|
|
729
777
|
|
|
730
|
-
#
|
|
778
|
+
# find name for subgroup data and make list
|
|
779
|
+
if self._legacy_netcdf:
|
|
780
|
+
self._subgroup_name = "meta"
|
|
781
|
+
else:
|
|
782
|
+
self._subgroup_name = "auxdata"
|
|
783
|
+
self.output_netcdf.createGroup(self._subgroup_name)
|
|
784
|
+
|
|
785
|
+
# set up function to output additional data in subgroup
|
|
731
786
|
def _create_meta_variable(
|
|
732
|
-
varname, varvalue, varunits, vartype="f4", vardims=()
|
|
787
|
+
varname, varvalue, varunits, vartype="f4", vardims=(), varlong=None
|
|
733
788
|
):
|
|
734
789
|
_v = self.output_netcdf.createVariable(
|
|
735
|
-
"
|
|
790
|
+
f"{self._subgroup_name}/" + varname, vartype, vardims
|
|
736
791
|
)
|
|
737
792
|
_v.units = varunits
|
|
793
|
+
# convert string to value from model attrs
|
|
794
|
+
if isinstance(varvalue, str):
|
|
795
|
+
varvalue = getattr(self, varvalue)
|
|
796
|
+
# fill variable
|
|
738
797
|
_v[:] = varvalue
|
|
798
|
+
if varlong is not None:
|
|
799
|
+
# long_name is provided, record it
|
|
800
|
+
_v.long_name = varlong
|
|
801
|
+
else:
|
|
802
|
+
if not self._legacy_netcdf:
|
|
803
|
+
raise ValueError(
|
|
804
|
+
f"long name must be provided for all variables to create a "
|
|
805
|
+
f"sandsuet compliant data output, "
|
|
806
|
+
f"but was not provided for variable '{varname}'."
|
|
807
|
+
)
|
|
739
808
|
|
|
740
|
-
|
|
809
|
+
# loop through additional data in subgroup
|
|
741
810
|
for _val in self._save_var_list["meta"].keys():
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
811
|
+
if isinstance(self._save_var_list["meta"][_val], list):
|
|
812
|
+
### for now, we silently convert to dictionary format
|
|
813
|
+
# inputs should be specified as a dictionary
|
|
814
|
+
# warnings.warn(
|
|
815
|
+
# f"Specification format for output subgroup data should be `dict`, "
|
|
816
|
+
# f"but was `list`. Converting `list` for one or more subgroup variables "
|
|
817
|
+
# f"to `dict` based on item order. This compatability will "
|
|
818
|
+
# f"be removed in a future version."
|
|
819
|
+
# )
|
|
820
|
+
###
|
|
821
|
+
# do the conversion
|
|
822
|
+
__inlist = self._save_var_list["meta"][_val]
|
|
823
|
+
__varname = _val
|
|
824
|
+
if __inlist[0] is None:
|
|
825
|
+
warnings.warn(
|
|
826
|
+
UserWarning(
|
|
827
|
+
"Specifying `None` for time varying dimensions "
|
|
828
|
+
"of model outputs will soon be deprecated. "
|
|
829
|
+
"Change to specifying the name of the "
|
|
830
|
+
"variable to save a string, and/or convert to "
|
|
831
|
+
"dictionary inputs."
|
|
832
|
+
)
|
|
833
|
+
)
|
|
834
|
+
__varvalue = None
|
|
835
|
+
else:
|
|
836
|
+
__varvalue = getattr(self, __inlist[0])
|
|
837
|
+
__varlong = __inlist[4] if len(__inlist) > 4 else None
|
|
838
|
+
_vardict = dict(
|
|
839
|
+
varname=__varname,
|
|
840
|
+
varvalue=__varvalue,
|
|
841
|
+
varunits=__inlist[1],
|
|
842
|
+
vartype=__inlist[2],
|
|
843
|
+
vardims=__inlist[3],
|
|
844
|
+
varlong=__varlong,
|
|
750
845
|
)
|
|
751
|
-
|
|
846
|
+
|
|
752
847
|
else:
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
848
|
+
_vardict = self._save_var_list["meta"][_val]
|
|
849
|
+
|
|
850
|
+
_create_meta_variable(
|
|
851
|
+
varname=_vardict["varname"],
|
|
852
|
+
varvalue=_vardict["varvalue"],
|
|
853
|
+
varunits=_vardict["varunits"],
|
|
854
|
+
vartype=_vardict["vartype"],
|
|
855
|
+
vardims=_vardict["vardims"],
|
|
856
|
+
varlong=_vardict["varlong"],
|
|
857
|
+
)
|
|
760
858
|
|
|
761
859
|
_msg = "Output netCDF file created"
|
|
762
860
|
self.log_info(_msg, verbosity=2)
|
|
@@ -789,17 +887,54 @@ class init_tools(abc.ABC):
|
|
|
789
887
|
Sets up the dictionary object for the standard metadata.
|
|
790
888
|
"""
|
|
791
889
|
# fixed metadata
|
|
792
|
-
self._save_var_list["meta"]["L0"] = [
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
890
|
+
self._save_var_list["meta"]["L0"] = [
|
|
891
|
+
"L0",
|
|
892
|
+
"cells",
|
|
893
|
+
"i8",
|
|
894
|
+
(),
|
|
895
|
+
"channel_entrance__length",
|
|
896
|
+
]
|
|
897
|
+
self._save_var_list["meta"]["N0"] = [
|
|
898
|
+
"N0",
|
|
899
|
+
"cells",
|
|
900
|
+
"i8",
|
|
901
|
+
(),
|
|
902
|
+
"channel_entrance__width",
|
|
903
|
+
]
|
|
904
|
+
self._save_var_list["meta"]["CTR"] = [
|
|
905
|
+
"CTR",
|
|
906
|
+
"cells",
|
|
907
|
+
"i8",
|
|
908
|
+
(),
|
|
909
|
+
"channel_entrance__y_position",
|
|
910
|
+
]
|
|
911
|
+
self._save_var_list["meta"]["dx"] = [
|
|
912
|
+
"dx",
|
|
913
|
+
"meters",
|
|
914
|
+
"f4",
|
|
915
|
+
(),
|
|
916
|
+
"model_grid_cell_edge__length",
|
|
917
|
+
]
|
|
918
|
+
self._save_var_list["meta"]["h0"] = [
|
|
919
|
+
"h0",
|
|
920
|
+
"meters",
|
|
921
|
+
"f4",
|
|
922
|
+
(),
|
|
923
|
+
"channel_entrance__depth",
|
|
924
|
+
]
|
|
925
|
+
self._save_var_list["meta"]["hb"] = [
|
|
926
|
+
"hb",
|
|
927
|
+
"meters",
|
|
928
|
+
"f4",
|
|
929
|
+
(),
|
|
930
|
+
"basin_bottom_initial__depth",
|
|
931
|
+
]
|
|
798
932
|
self._save_var_list["meta"]["cell_type"] = [
|
|
799
933
|
"cell_type",
|
|
800
934
|
"type",
|
|
801
935
|
"i8",
|
|
802
936
|
self._netcdf_coords[1:],
|
|
937
|
+
"model_grid_cell__type",
|
|
803
938
|
]
|
|
804
939
|
# subsidence metadata
|
|
805
940
|
if self._toggle_subsidence:
|
|
@@ -808,37 +943,43 @@ class init_tools(abc.ABC):
|
|
|
808
943
|
"seconds",
|
|
809
944
|
"i8",
|
|
810
945
|
(),
|
|
946
|
+
"basin_bottom_vertical_rate_of_change__start_time",
|
|
811
947
|
]
|
|
812
948
|
self._save_var_list["meta"]["sigma"] = [
|
|
813
949
|
"sigma",
|
|
814
950
|
"meters per timestep",
|
|
815
951
|
"f4",
|
|
816
952
|
self._netcdf_coords[1:],
|
|
953
|
+
"basin_bottom__vertical_rate_of_change",
|
|
817
954
|
]
|
|
818
955
|
# time-varying metadata
|
|
819
956
|
self._save_var_list["meta"]["H_SL"] = [
|
|
820
|
-
|
|
957
|
+
"H_SL",
|
|
821
958
|
"meters",
|
|
822
959
|
"f4",
|
|
823
960
|
(self._netcdf_coords[0]),
|
|
961
|
+
"basin_water_surface__elevation",
|
|
824
962
|
]
|
|
825
963
|
self._save_var_list["meta"]["f_bedload"] = [
|
|
826
|
-
|
|
964
|
+
"f_bedload",
|
|
827
965
|
"fraction",
|
|
828
966
|
"f4",
|
|
829
967
|
(self._netcdf_coords[0]),
|
|
968
|
+
"channel_entrance_water_sediment_sand__volume_fraction",
|
|
830
969
|
]
|
|
831
970
|
self._save_var_list["meta"]["C0_percent"] = [
|
|
832
|
-
|
|
971
|
+
"C0_percent",
|
|
833
972
|
"percent",
|
|
834
973
|
"f4",
|
|
835
974
|
(self._netcdf_coords[0]),
|
|
975
|
+
"channel_entrance__water_sediment__volume_percent",
|
|
836
976
|
]
|
|
837
977
|
self._save_var_list["meta"]["u0"] = [
|
|
838
|
-
|
|
978
|
+
"u0",
|
|
839
979
|
"meters per second",
|
|
840
980
|
"f4",
|
|
841
981
|
(self._netcdf_coords[0]),
|
|
982
|
+
"channel_entrance__speed",
|
|
842
983
|
]
|
|
843
984
|
|
|
844
985
|
def _load_past_etas(self, checkpoint):
|
|
@@ -1031,6 +1172,14 @@ class init_tools(abc.ABC):
|
|
|
1031
1172
|
# set object attribute for model
|
|
1032
1173
|
self.output_netcdf = Dataset(file_path, "r+", format="NETCDF4")
|
|
1033
1174
|
|
|
1175
|
+
# find subgroup name, supporting legacy file format
|
|
1176
|
+
if "meta" in self.output_netcdf.groups.keys():
|
|
1177
|
+
self._subgroup_name = "meta"
|
|
1178
|
+
elif "auxdata" in self.output_netcdf.groups.keys():
|
|
1179
|
+
self._subgroup_name = "auxdata"
|
|
1180
|
+
else:
|
|
1181
|
+
self._subgroup_name = self.output_netcdf.groups.keys()[0]
|
|
1182
|
+
|
|
1034
1183
|
# synch netcdf file
|
|
1035
1184
|
self.output_netcdf.sync()
|
|
1036
1185
|
|