Loading environment.yamldeleted 100644 → 0 +0 −14 Original line number Diff line number Diff line name: powersheds channels: - conda-forge - defaults dependencies: - python=3.12 - pyyaml=6.0.2 - pandas>=2.2,<2.3 - numpy>=2.2,<2.3 - pip>=24.3,<24.4 - matplotlib>=3.10 - pip: - maturin>=1.8.1,<1.9 - scipy>=1.15 examples/Cumberland/script.qmd +2 −1 Original line number Diff line number Diff line Loading @@ -13,10 +13,11 @@ library(ggplot2) library(patchwork) library(purrr) library(httpgd) reticulate::use_virtualenv("./.venv", required = TRUE) setwd("examples/Cumberland/") use_condaenv("powersheds") ``` ```{python} import pandas as pd import powersheds Loading pyproject.toml +13 −3 Original line number Diff line number Diff line [build-system] requires = ["maturin>=1.8,<2.0"] requires = ["maturin==1.8.1"] build-backend = "maturin" [project] name = "powersheds" requires-python = ">=3.8" requires-python = ">=3.12" dynamic = ["version"] classifiers = [ "Programming Language :: Rust", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ] dynamic = ["version"] dependencies = [ "PyYAML==6.0.2", "pandas>=2.2,<2.3", "numpy>=2.2,<2.3", "matplotlib>=3.10", "scipy>=1.15", "pyarrow==21.0" ] [tool.maturin] features = ["pyo3/extension-module"] src/lib.rs +17 −6 Original line number Diff line number Diff line Loading @@ -10,6 +10,9 @@ use helpers::interpolate_storage; use helpers::compute_release_to_meet_target_power; use helpers::compute_power; // Set object types: reservoir, river, confluence #[derive(Debug)] enum ObjectType { Reservoir, Loading @@ -29,6 +32,7 @@ impl FromStr for ObjectType { } } // Set Reservoir data struct #[derive(FromPyObject)] struct ReservoirData { object_type: String, Loading @@ -48,6 +52,7 @@ struct ReservoirData { downstream_object: String, } // Set River data struct #[derive(FromPyObject)] struct RiverData { object_type: String, Loading @@ -57,6 +62,7 @@ struct RiverData { legacy_flows: Vec<f64> } // Set Confluence data struct #[derive(FromPyObject)] struct ConfluenceData { object_type: String, Loading @@ -71,6 +77,7 @@ struct CascadeData { confluences: HashMap<String, ConfluenceData> } // Define structure for reservoir state struct ReservoirState { storage: f64, pool_elevation: f64, Loading Loading @@ -115,6 +122,9 @@ enum CascadeResults { Confluence(ConfluenceResults), } // Define function for performing the reservoir simulation at each timestep. // This function updates the reservoir state according to initial conditions, ... // ... inflows, and power generation targeted. fn simulate_timestep( reservoir: &ReservoirData, inflow: f64, Loading @@ -122,7 +132,7 @@ fn simulate_timestep( previous_storage: f64, ) -> ReservoirState { // Use previous storage to estimate pool elevation, then head // Use previous (initial) storage to estimate pool elevation let previous_pool_elevation = interpolate_elevation( previous_storage, &reservoir.set_storage, Loading @@ -136,6 +146,7 @@ fn simulate_timestep( let head = previous_pool_elevation - reservoir.tailwater_elevation; // Compute the target release, given the power generation desired // THIS SECTION TO BE UPDATED USING HEAD-POWER-FLOW TABLES let target_release = compute_release_to_meet_target_power( target_power, head, Loading @@ -159,6 +170,8 @@ fn simulate_timestep( let potential_storage = available_water - release; // Calculate actual power based on the actual release and head // THIS SECTION TO BE UPDATED USING HEAD-POWER-FLOW TABLES // ALSO ADD IF STATEMENT TO VOID THIS COMPUTATION IF release = target_release let actual_power = compute_power( release, head, Loading @@ -166,7 +179,7 @@ fn simulate_timestep( reservoir.power_params_b, ); // Determine spill--driven solely by storage capacity limit // Determine spill, presently driven solely by storage capacity limit let (storage, spill) = if potential_storage > reservoir.capacity { (reservoir.capacity, potential_storage - reservoir.capacity) } else { Loading @@ -174,7 +187,6 @@ fn simulate_timestep( }; // Compute final pool elevation let pool_elevation = interpolate_elevation( storage, &reservoir.set_storage, Loading @@ -192,8 +204,7 @@ fn simulate_timestep( } } /// Simulates a cascade of reservoirs /// /// Perform simulation of all objects using pre-specified "simulation order" #[pyfunction] fn simulate_cascade( cascade_data: CascadeData, Loading uv.lock 0 → 100644 +573 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
environment.yamldeleted 100644 → 0 +0 −14 Original line number Diff line number Diff line name: powersheds channels: - conda-forge - defaults dependencies: - python=3.12 - pyyaml=6.0.2 - pandas>=2.2,<2.3 - numpy>=2.2,<2.3 - pip>=24.3,<24.4 - matplotlib>=3.10 - pip: - maturin>=1.8.1,<1.9 - scipy>=1.15
examples/Cumberland/script.qmd +2 −1 Original line number Diff line number Diff line Loading @@ -13,10 +13,11 @@ library(ggplot2) library(patchwork) library(purrr) library(httpgd) reticulate::use_virtualenv("./.venv", required = TRUE) setwd("examples/Cumberland/") use_condaenv("powersheds") ``` ```{python} import pandas as pd import powersheds Loading
pyproject.toml +13 −3 Original line number Diff line number Diff line [build-system] requires = ["maturin>=1.8,<2.0"] requires = ["maturin==1.8.1"] build-backend = "maturin" [project] name = "powersheds" requires-python = ">=3.8" requires-python = ">=3.12" dynamic = ["version"] classifiers = [ "Programming Language :: Rust", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ] dynamic = ["version"] dependencies = [ "PyYAML==6.0.2", "pandas>=2.2,<2.3", "numpy>=2.2,<2.3", "matplotlib>=3.10", "scipy>=1.15", "pyarrow==21.0" ] [tool.maturin] features = ["pyo3/extension-module"]
src/lib.rs +17 −6 Original line number Diff line number Diff line Loading @@ -10,6 +10,9 @@ use helpers::interpolate_storage; use helpers::compute_release_to_meet_target_power; use helpers::compute_power; // Set object types: reservoir, river, confluence #[derive(Debug)] enum ObjectType { Reservoir, Loading @@ -29,6 +32,7 @@ impl FromStr for ObjectType { } } // Set Reservoir data struct #[derive(FromPyObject)] struct ReservoirData { object_type: String, Loading @@ -48,6 +52,7 @@ struct ReservoirData { downstream_object: String, } // Set River data struct #[derive(FromPyObject)] struct RiverData { object_type: String, Loading @@ -57,6 +62,7 @@ struct RiverData { legacy_flows: Vec<f64> } // Set Confluence data struct #[derive(FromPyObject)] struct ConfluenceData { object_type: String, Loading @@ -71,6 +77,7 @@ struct CascadeData { confluences: HashMap<String, ConfluenceData> } // Define structure for reservoir state struct ReservoirState { storage: f64, pool_elevation: f64, Loading Loading @@ -115,6 +122,9 @@ enum CascadeResults { Confluence(ConfluenceResults), } // Define function for performing the reservoir simulation at each timestep. // This function updates the reservoir state according to initial conditions, ... // ... inflows, and power generation targeted. fn simulate_timestep( reservoir: &ReservoirData, inflow: f64, Loading @@ -122,7 +132,7 @@ fn simulate_timestep( previous_storage: f64, ) -> ReservoirState { // Use previous storage to estimate pool elevation, then head // Use previous (initial) storage to estimate pool elevation let previous_pool_elevation = interpolate_elevation( previous_storage, &reservoir.set_storage, Loading @@ -136,6 +146,7 @@ fn simulate_timestep( let head = previous_pool_elevation - reservoir.tailwater_elevation; // Compute the target release, given the power generation desired // THIS SECTION TO BE UPDATED USING HEAD-POWER-FLOW TABLES let target_release = compute_release_to_meet_target_power( target_power, head, Loading @@ -159,6 +170,8 @@ fn simulate_timestep( let potential_storage = available_water - release; // Calculate actual power based on the actual release and head // THIS SECTION TO BE UPDATED USING HEAD-POWER-FLOW TABLES // ALSO ADD IF STATEMENT TO VOID THIS COMPUTATION IF release = target_release let actual_power = compute_power( release, head, Loading @@ -166,7 +179,7 @@ fn simulate_timestep( reservoir.power_params_b, ); // Determine spill--driven solely by storage capacity limit // Determine spill, presently driven solely by storage capacity limit let (storage, spill) = if potential_storage > reservoir.capacity { (reservoir.capacity, potential_storage - reservoir.capacity) } else { Loading @@ -174,7 +187,6 @@ fn simulate_timestep( }; // Compute final pool elevation let pool_elevation = interpolate_elevation( storage, &reservoir.set_storage, Loading @@ -192,8 +204,7 @@ fn simulate_timestep( } } /// Simulates a cascade of reservoirs /// /// Perform simulation of all objects using pre-specified "simulation order" #[pyfunction] fn simulate_cascade( cascade_data: CascadeData, Loading