From 03cfd765d2516e374553e36d8cea73a12a11b439 Mon Sep 17 00:00:00 2001 From: program-- Date: Mon, 24 Jun 2024 14:37:16 -0700 Subject: [PATCH] refactor: simplification and provider masking [no ci] --- .../forcing/ForcingsEngineDataProvider.hpp | 176 +++++++++------ .../ForcingsEngineGriddedDataProvider.hpp | 87 ++++++-- .../ForcingsEngineLumpedDataProvider.hpp | 41 ++-- include/forcing/GridDataSelector.hpp | 205 +----------------- .../ForcingsEngineGriddedDataProvider.cpp | 103 ++++++--- ...ForcingsEngineGriddedDataProvider_Test.cpp | 7 +- .../ForcingsEngineLumpedDataProvider_Test.cpp | 6 +- 7 files changed, 281 insertions(+), 344 deletions(-) diff --git a/include/forcing/ForcingsEngineDataProvider.hpp b/include/forcing/ForcingsEngineDataProvider.hpp index aa1706af8a..22ee2ee9eb 100644 --- a/include/forcing/ForcingsEngineDataProvider.hpp +++ b/include/forcing/ForcingsEngineDataProvider.hpp @@ -14,6 +14,17 @@ static constexpr auto forcings_engine_python_class = "NWMv3_Forcing_Engine_BMI_ static constexpr auto forcings_engine_python_classpath = "NextGen_Forcings_Engine.NWMv3_Forcing_Engine_BMI_model"; static constexpr auto default_time_format = "%Y-%m-%d %H:%M:%S"; +//! Parse time string from format. +//! Utility function for ForcingsEngineLumpedDataProvider constructor. +time_t parse_time(const std::string& time, const std::string& fmt); + +/** + * Check that requirements for running the forcings engine + * are available at runtime. If requirements are not available, + * then this function throws. + */ +void assert_forcings_engine_requirements(); + namespace detail { //! Storage for Forcings Engine-specific BMI instances. @@ -21,20 +32,26 @@ struct ForcingsEngineStorage { using key_type = std::string; using bmi_type = models::bmi::Bmi_Py_Adapter; using value_type = std::shared_ptr; - + value_type get(const key_type& key) { auto pos = data_.find(key); if (pos == data_.end()) { return nullptr; } - + return pos->second; } - void set(const key_type& key, value_type value) { data_[key] = value; } + void set(const key_type& key, value_type value) + { + data_[key] = value; + } - void clear() { data_.clear(); } + void clear() + { + data_.clear(); + } private: //! Instance map of underlying BMI models. @@ -45,17 +62,6 @@ static ForcingsEngineStorage forcings_engine_instances{}; } // namespace detail -//! Parse time string from format. -//! Utility function for ForcingsEngineLumpedDataProvider constructor. -time_t parse_time(const std::string& time, const std::string& fmt); - -/** - * Check that requirements for running the forcings engine - * are available at runtime. If requirements are not available, - * then this function throws. - */ -void assert_forcings_engine_requirements(); - template struct ForcingsEngineDataProvider : public DataProvider @@ -64,7 +70,7 @@ struct ForcingsEngineDataProvider using selection_type = SelectionType; using clock_type = std::chrono::system_clock; - ~ForcingsEngineDataProvider() = default; + ~ForcingsEngineDataProvider() override = default; boost::span get_available_variable_names() override { @@ -75,7 +81,7 @@ struct ForcingsEngineDataProvider { return clock_type::to_time_t(time_begin_); } - + long get_data_stop_time() override { return clock_type::to_time_t(time_end_); @@ -109,65 +115,50 @@ struct ForcingsEngineDataProvider /* Remaining virtual member functions from DataProvider must be implemented by derived classes. */ - data_type get_value(const selection_type& selector, data_access::ReSampleMethod m) override = 0; - - std::vector get_values(const selection_type& selector, data_access::ReSampleMethod m) override = 0; + data_type get_value( + const selection_type& selector, + data_access::ReSampleMethod m + ) override = 0; + + std::vector get_values( + const selection_type& selector, + data_access::ReSampleMethod m + ) override = 0; protected: - // TODO: It may make more sense to have time_begin_seconds and time_end_seconds coalesced into - // a single argument: `clock_type::duration time_duration`, since the forcings engine - // manages time via a duration rather than time points. !! Need to double check ForcingsEngineDataProvider( - const std::string& init, - std::size_t time_begin_seconds, - std::size_t time_end_seconds + std::string init, + std::size_t time_begin_seconds, + std::size_t time_end_seconds ) : time_begin_(std::chrono::seconds{time_begin_seconds}) , time_end_(std::chrono::seconds{time_end_seconds}) + , bmi_(detail::forcings_engine_instances.get(init)) + , time_step_(std::chrono::seconds{static_cast(bmi_->GetTimeStep())}) + , time_current_index_(std::chrono::seconds{static_cast(bmi_->GetCurrentTime())} / time_step_) + , var_output_names_(bmi_->GetOutputVarNames()) + {} + + /** + * Update the Forcings Engine instance to the next timestep. + */ + void next() { - - assert_forcings_engine_requirements(); - - bmi_ = detail::forcings_engine_instances.get(init); - if (bmi_ == nullptr) { - bmi_ = std::make_shared( - "ForcingsEngine", - init, - forcings_engine_python_classpath, - /*allow_exceed_end=*/true, - /*has_fixed_time_step=*/true, - utils::getStdOut() - ); - - detail::forcings_engine_instances.set(init, bmi_); - } - - time_step_ = std::chrono::seconds{static_cast(bmi_->GetTimeStep())}; - time_current_index_ = std::chrono::seconds{static_cast(bmi_->GetCurrentTime())} / time_step_; - var_output_names_ = bmi_->GetOutputVarNames(); - } - - template - static std::unique_ptr make_instance( - const std::string& init, - const std::string& time_begin, - const std::string& time_end, - const std::string& time_fmt = default_time_format - ) - { - auto time_begin_epoch = parse_time(time_begin, time_fmt); - auto time_end_epoch = parse_time(time_end, time_fmt); - return std::unique_ptr{ - new Derived{init, time_begin_epoch, time_end_epoch} - }; - } - - void next() { bmi_->Update(); time_current_index_++; } - void next(double time) { + /** + * Update the Forcings Engine instance to the next timestep + * before `time`. + * + * @param time Time in seconds to update to. + * i.e. A value of 14401 will update + * the instance to the 5th time index, + * since 3600 * 4 = 14400 but 14400 < 14401. + */ + void next(double time) + { const auto start = bmi_->GetCurrentTime(); bmi_->UpdateUntil(time); const auto end = bmi_->GetCurrentTime(); @@ -192,4 +183,59 @@ struct ForcingsEngineDataProvider std::size_t time_current_index_{}; }; + +// Forcings Engine factory function +template< + typename Tp, + typename... Args, + std::enable_if_t< + std::is_base_of< + ForcingsEngineDataProvider< + typename Tp::data_type, + typename Tp::selection_type + >, + Tp + >::value, + bool + > = true +> +std::unique_ptr make_forcings_engine( + const std::string& init, + const std::string& time_begin, + const std::string& time_end, + const std::string& time_fmt = default_time_format, + Args&&... args +) +{ + // Ensure python and other requirements are met to use + // the python forcings engine. + // TODO: Move this to a place where it only runs once, + // possibly in NGen.cpp? + assert_forcings_engine_requirements(); + + // Get or create a BMI instance based on the init config path + auto instance = detail::forcings_engine_instances.get(init); + if (instance == nullptr) { + instance = std::make_shared( + "ForcingsEngine", + init, + forcings_engine_python_classpath, + /*allow_exceed_end=*/true, + /*has_fixed_time_step=*/true, + utils::getStdOut() + ); + + detail::forcings_engine_instances.set(init, instance); + } + + // Create the derived instance + return std::make_unique( + init, + parse_time(time_begin, time_fmt), + parse_time(time_end, time_fmt), + std::forward(args)... + ); +} + + } // namespace data_access diff --git a/include/forcing/ForcingsEngineGriddedDataProvider.hpp b/include/forcing/ForcingsEngineGriddedDataProvider.hpp index 2002b7f8bc..2a0567f5f9 100644 --- a/include/forcing/ForcingsEngineGriddedDataProvider.hpp +++ b/include/forcing/ForcingsEngineGriddedDataProvider.hpp @@ -3,44 +3,87 @@ #include "GridDataSelector.hpp" #include "ForcingsEngineDataProvider.hpp" -#include - namespace data_access { struct ForcingsEngineGriddedDataProvider - : public ForcingsEngineDataProvider + : public ForcingsEngineDataProvider { using data_type = data_type; using selection_type = selection_type; using base_type = ForcingsEngineDataProvider; - ~ForcingsEngineGriddedDataProvider() override = default; - - data_type get_value(const selection_type& selector, data_access::ReSampleMethod m) override; - - std::vector get_values(const selection_type& selector, data_access::ReSampleMethod m) override; - - static std::unique_ptr make_gridded_instance( + /** + * Construct a domain-wide Gridded Forcings Engine data provider + * @param init Path to instance initialization file + * @param time_begin_seconds Time in seconds for begin time. Typically 0. + * @param time_end_seconds Time in seconds for end time. Typically the lifetime of the simulation. + */ + ForcingsEngineGriddedDataProvider( const std::string& init, - const std::string& time_start, - const std::string& time_end, - const std::string& time_fmt = default_time_format - ) - { - return make_instance(init, time_start, time_end, time_fmt); - } + std::size_t time_begin_seconds, + std::size_t time_end_seconds + ); - private: - friend base_type; + /** + * Construct a masked Gridded Forcings Engine data provider + * @param mask Bounding box used to mask data provider, results will be returned + * within this region. + */ + ForcingsEngineGriddedDataProvider( + const std::string& init, + std::size_t time_begin_seconds, + std::size_t time_end_seconds, + const BoundingBox& mask + ); + /** + * Construct a polygon masked Gridded Forcings Engine data provider + * @param boundary Polygon used to mask data provider, results will be returned + * within the **bounding box** of this region. + */ ForcingsEngineGriddedDataProvider( const std::string& init, - std::time_t time_begin_seconds, - std::time_t time_end_seconds + std::size_t time_begin_seconds, + std::size_t time_end_seconds, + const geojson::polygon_t& boundary ); - int var_grid_id_{}; + ~ForcingsEngineGriddedDataProvider() override = default; + + data_type get_value( + const selection_type& selector, + data_access::ReSampleMethod m + ) override; + + /** + * Get the values of a gridded variable in time. + */ + std::vector get_values( + const selection_type& selector, + data_access::ReSampleMethod m + ) override; + + private: + /** + * Get the underlying grid specification of this provider's instance. + */ + const GridSpecification& grid() const noexcept; + + /** + * Get the mask of this provider. If the provider is domain-wide, the + * returned bounding box will equivalent to the grid's bounding box. + */ + const BoundingBox& mask() const noexcept; + + + //! Grid ID for underlying forcings engine instance + int var_grid_id_ = -1; + + //! Total grid specification for forcings engine instance GridSpecification var_grid_{}; + + //! Provider Grid Mask, the AOI this provider operates under + BoundingBox var_grid_mask_{}; }; } // namespace data_access diff --git a/include/forcing/ForcingsEngineLumpedDataProvider.hpp b/include/forcing/ForcingsEngineLumpedDataProvider.hpp index 8c33051beb..3e8d747633 100644 --- a/include/forcing/ForcingsEngineLumpedDataProvider.hpp +++ b/include/forcing/ForcingsEngineLumpedDataProvider.hpp @@ -16,6 +16,12 @@ struct ForcingsEngineLumpedDataProvider static constexpr auto bad_index = static_cast(-1); + ForcingsEngineLumpedDataProvider( + const std::string& init, + std::size_t time_begin_seconds, + std::size_t time_end_seconds + ); + ~ForcingsEngineLumpedDataProvider() override = default; data_type get_value(const selection_type& selector, data_access::ReSampleMethod m) override; @@ -25,44 +31,27 @@ struct ForcingsEngineLumpedDataProvider /** * @brief Get the index in `CAT-ID` for a given divide in the instance cache. * @note The `CAT-ID` output variable uses integer values instead of strings. - * + * * @param divide_id A hydrofabric divide ID, i.e. "cat-*" - * @return size_type + * @return size_type */ std::size_t divide_index(const std::string& divide_id) noexcept; /** * @brief Get the index of a variable in the instance cache. - * - * @param variable - * @return size_type + * + * @param variable + * @return size_type */ std::size_t variable_index(const std::string& variable) noexcept; - static std::unique_ptr make_lumped_instance( - const std::string& init, - const std::string& time_start, - const std::string& time_end, - const std::string& time_fmt = default_time_format - ) { - return make_instance(init, time_start, time_end, time_fmt); - } - private: - friend base_type; - - ForcingsEngineLumpedDataProvider( - const std::string& init, - std::time_t time_begin_seconds, - std::time_t time_end_seconds - ); - /** * @brief Get a forcing value from the instance - * + * * @param divide_id Divide ID to index at * @param variable Forcings variable to get - * @return double + * @return double */ double at( const std::string& divide_id, @@ -71,10 +60,10 @@ struct ForcingsEngineLumpedDataProvider /** * @brief Get a forcing value from the instance - * + * * @param divide_index Divide index * @param variable_index Variable index - * @return double + * @return double */ double at( std::size_t divide_idx, diff --git a/include/forcing/GridDataSelector.hpp b/include/forcing/GridDataSelector.hpp index 00cdeb50a2..cfa4008fff 100644 --- a/include/forcing/GridDataSelector.hpp +++ b/include/forcing/GridDataSelector.hpp @@ -2,37 +2,25 @@ #include #include -#include - -#include #include - #include -struct Cell { - std::uint64_t x = 0; - std::uint64_t y = 0; - std::uint64_t z = 0; - double value = NAN; - - friend inline bool operator<(const Cell& a, const Cell& b) { - // TODO: Not really meaningful - return a.x < b.x || a.y < b.y || a.z < b.z; - } -}; - using box_t = boost::geometry::model::box; struct BoundingBox { BoundingBox() = default; - BoundingBox(box_t box) - : box_(std::move(box)) + BoundingBox(double xmin, double xmax, double ymin, double ymax) + : box_(/*min_corner=*/{xmin, ymin}, /*max_corner=*/{xmax, ymax}) + {} + + explicit BoundingBox(box_t box) + : box_(box) {} template - BoundingBox(const Geometry& geom) + explicit BoundingBox(const Geometry& geom) : box_(boost::geometry::return_envelope(geom)) {} @@ -82,176 +70,11 @@ struct GridSpecification { BoundingBox extent; }; -struct SelectorConfig { - //! Initial time for query. - //! @todo Refactor to use std::chrono - time_t init_time; - - //! Duration for query, in seconds. - //! @todo Refactor to use std::chrono - long duration_seconds; - - //! Variable to return from query. - std::string variable_name; - - //! Units for output variable. - std::string variable_units; -}; - struct GridDataSelector { - - //! Cell-based constructor - GridDataSelector(SelectorConfig config, boost::span cells) - : config_(std::move(config)) - , cells_(cells.begin(), cells.end()) { - } - - /** - * Point-based constructor - * - * Constructs a selector taking only the cells - * from @p grid that correspond to coordinates in @p points. - * - * @param config Selector configuration options - * @param grid Source grid specification - * @param points Target points used for extraction - * - * @todo Implementation - */ - GridDataSelector( - SelectorConfig config, - const GridSpecification& grid, - boost::span points - ) - : config_(std::move(config)) - { - // Using a std::set since points may be close enough that they are within - // the same grid cell. This ensures that each cell is uniquely indexed. - std::set cells; - for (const auto& point : points) { - cells.emplace(Cell{ - /*x=*/position_(point.get<0>(), grid.extent.xmin(), grid.extent.xmax(), grid.columns), - /*y=*/position_(point.get<1>(), grid.extent.ymin(), grid.extent.ymax(), grid.rows), - /*z=*/0UL, - /*value=*/NAN - }); - } - - cells_.assign(cells.begin(), cells.end()); - } - - /** - * Boundary-based constructor - * - * Constructs a selector taking only the cells - * from @p grid that intersect @p polygon. - * - * @param config Selector configuration options - * @param grid Source grid specification - * @param polygon Target polygon used as mask - */ - GridDataSelector( - SelectorConfig config, - const GridSpecification& grid, - const geojson::polygon_t& polygon - ) - : config_(std::move(config)) - { - const auto xmin = grid.extent.xmin(); - const auto xmax = grid.extent.xmax(); - const auto ymin = grid.extent.ymin(); - const auto ymax = grid.extent.ymax(); - const auto ydiff = static_cast(grid.rows) / (ymax - ymin); - const auto xdiff = static_cast(grid.columns) / (xmax - xmin); - - const BoundingBox bbox = { polygon }; - for (double row = bbox.ymin(); row < bbox.ymax() - ydiff; row += ydiff) { - for (double col = bbox.xmin(); col < bbox.xmax() - xdiff; row += xdiff) { - const box_t cell_box = { - /*min_corner=*/{ col, row }, - /*max_corner=*/{ col + xdiff, row + ydiff } - }; - - if (boost::geometry::intersects(cell_box, polygon)) { - auto x = position_(col, xmin, xmax, grid.columns); - auto y = position_(row, ymin, ymax, grid.rows); - cells_.emplace_back(Cell{x, y, /*z=*/0UL, /*value=*/NAN}); - } - } - } - } - - /** - * Extent-based constructor - * - * @param config Selector configuration options - * @param grid Source grid specification - * @param extent Target bounding box used as mask - */ - GridDataSelector( - SelectorConfig config, - const GridSpecification& grid, - const BoundingBox& extent - ) - : config_(std::move(config)) - { - const auto col_min = position_(extent.xmin(), grid.extent.xmin(), grid.extent.xmax(), grid.columns); - const auto col_max = position_(extent.xmax(), grid.extent.xmin(), grid.extent.xmax(), grid.columns); - const auto row_min = position_(extent.ymin(), grid.extent.ymin(), grid.extent.ymax(), grid.rows); - const auto row_max = position_(extent.ymax(), grid.extent.ymin(), grid.extent.ymax(), grid.rows); - const auto ncells = (row_max - row_min) * (col_max - col_min); - - cells_.reserve(ncells); - for (auto row = row_min; row < row_max; row++) { - for (auto col = col_min; col < col_max; col++) { - cells_.emplace_back(Cell{/*x=*/col, /*y=*/row, /*z=*/0UL, /*value=*/NAN}); - } - } - } - - GridDataSelector() noexcept = default; - - virtual ~GridDataSelector() = default; - - time_t& initial_time() noexcept { - return config_.init_time; - } - - time_t initial_time() const noexcept { - return config_.init_time; - } - - long& duration() noexcept { - return config_.duration_seconds; - } - - long duration() const noexcept { - return config_.duration_seconds; - } - - std::string& variable() noexcept { - return config_.variable_name; - } - - const std::string& variable() const noexcept { - return config_.variable_name; - } - - std::string& units() noexcept { - return config_.variable_units; - } - - const std::string& units() const noexcept { - return config_.variable_units; - } - - boost::span cells() noexcept { - return cells_; - } - - boost::span cells() const noexcept { - return cells_; - } + std::string variable_name; + time_t init_time; + long duration; + std::string output_units; private: static std::uint64_t position_(double position, double min, double max, std::uint64_t upper_bound) { @@ -261,10 +84,4 @@ struct GridDataSelector { return std::floor((position - min) * (static_cast(upper_bound) / (max - min))); } - - //! General selector configuration - SelectorConfig config_; - - //! Cells to gather. - std::vector cells_; }; diff --git a/src/forcing/ForcingsEngineGriddedDataProvider.cpp b/src/forcing/ForcingsEngineGriddedDataProvider.cpp index e7bef70ba1..6e138557a2 100644 --- a/src/forcing/ForcingsEngineGriddedDataProvider.cpp +++ b/src/forcing/ForcingsEngineGriddedDataProvider.cpp @@ -7,71 +7,111 @@ namespace data_access { using Provider = ForcingsEngineGriddedDataProvider; using BaseProvider = Provider::base_type; -Provider::ForcingsEngineGriddedDataProvider( - const std::string& init, - std::time_t time_begin_seconds, - std::time_t time_end_seconds -) - : BaseProvider(init, time_begin_seconds, time_end_seconds) +// The following grid specification is a specific optimization +// for the NextGen Forcings Engine, since in gridded mode, all +// variables share the same grid. +GridSpecification construct_fe_grid_spec(bmi::Bmi* ptr, int grid) { - // The following grid specification is a specific optimization - // for the NextGen Forcings Engine, since in gridded mode, all - // variables share the same grid. - var_grid_id_ = bmi_->GetVarGrid(get_available_variable_names()[0]); std::array shape = {-1, -1}; - bmi_->GetGridShape(var_grid_id_, shape.data()); + ptr->GetGridShape(grid, shape.data()); assert(shape[0] == shape[1]); // since the grid must be uniform rectilinear // Allocate a coordinate vector and reuse for X and Y std::vector coordinate(shape[0]); // Get longitude bounds - bmi_->GetGridX(var_grid_id_, coordinate.data()); + ptr->GetGridX(grid, coordinate.data()); auto xminmax = std::minmax_element(coordinate.begin(), coordinate.end()); double xmin = *xminmax.first; double xmax = *xminmax.second; // Get latitude bounds - bmi_->GetGridY(var_grid_id_, coordinate.data()); + ptr->GetGridY(grid, coordinate.data()); auto yminmax = std::minmax_element(coordinate.begin(), coordinate.end()); double ymin = *yminmax.first; double ymax = *yminmax.second; - // Construct grid specification - var_grid_ = { + return { static_cast(shape[0]), static_cast(shape[1]), - box_t{{ xmin, ymin }, { xmax, ymax}} + BoundingBox{xmin, xmax, ymin, ymax} }; } -Cell Provider::get_value(const GridDataSelector& selector, data_access::ReSampleMethod m) +Provider::ForcingsEngineGriddedDataProvider( + const std::string& init, + std::size_t time_begin_seconds, + std::size_t time_end_seconds +) + : BaseProvider(init, time_begin_seconds, time_end_seconds) +{ + // The following grid specification is a specific optimization + // for the NextGen Forcings Engine, since in gridded mode, all + // variables share the same grid. + var_grid_id_ = bmi_->GetVarGrid(get_available_variable_names()[0]); + var_grid_ = construct_fe_grid_spec(bmi_.get(), var_grid_id_); + var_grid_mask_ = var_grid_.extent; +} + +Provider::ForcingsEngineGriddedDataProvider( + const std::string& init, + std::size_t time_begin_seconds, + std::size_t time_end_seconds, + const BoundingBox& mask +) : ForcingsEngineGriddedDataProvider( + init, + time_begin_seconds, + time_end_seconds + ) +{ + // TODO: assert mask is contained within the grid spec extent + var_grid_mask_ = mask; +} + +Provider::ForcingsEngineGriddedDataProvider( + const std::string& init, + std::size_t time_begin_seconds, + std::size_t time_end_seconds, + const geojson::polygon_t& boundary +) : ForcingsEngineGriddedDataProvider( + init, + time_begin_seconds, + time_end_seconds, + BoundingBox{boundary} + ) +{} + +Provider::data_type Provider::get_value(const GridDataSelector& selector, data_access::ReSampleMethod m) { throw std::runtime_error{"ForcingsEngineGriddedDataProvider::get_value() is not implemented"}; } -std::vector Provider::get_values(const GridDataSelector& selector, data_access::ReSampleMethod m) +std::vector Provider::get_values(const GridDataSelector& selector, data_access::ReSampleMethod m) { + throw std::runtime_error{"ForcingsEngineGriddedDataProvider::get_values() is not implemented"}; // Temporary + if (m != ReSampleMethod::SUM && m != ReSampleMethod::MEAN) { throw std::runtime_error{"Given ReSampleMethod " + std::to_string(m) + " not implemented."}; } - const auto start = clock_type::from_time_t(selector.initial_time()); - const auto end = std::chrono::seconds{selector.duration()} + start; + const auto start = clock_type::from_time_t(selector.init_time); + const auto end = std::chrono::seconds{selector.duration} + start; const auto step = std::chrono::seconds{record_duration()}; - - std::vector cells = { selector.cells().begin(), selector.cells().end() }; + + // std::vector values; + + // std::vector cells = { selector.cells().begin(), selector.cells().end() }; for (auto current = start; current < end; current += step) { this->next(current.time_since_epoch().count()); - + boost::span values{ - static_cast(bmi_->GetValuePtr(selector.variable())), + static_cast(bmi_->GetValuePtr(selector.variable_name)), var_grid_.rows * var_grid_.columns }; - for (auto& cell : cells) { - cell.value += values[cell.x + cell.y * var_grid_.rows]; - } + // for (auto& cell : cells) { + // cell.value += values[cell.x + cell.y * var_grid_.rows]; + // } } if (m == ReSampleMethod::MEAN) { @@ -79,12 +119,13 @@ std::vector Provider::get_values(const GridDataSelector& selector, data_ac const auto time_duration = std::chrono::duration_cast(end - start).count(); const auto num_time_steps = time_duration / time_step_seconds; - for (auto& cell : cells) { - cell.value /= num_time_steps; - } + // for (auto& cell : cells) { + // cell.value /= num_time_steps; + // } } - return cells; + // return cells; + throw; } diff --git a/test/forcing/ForcingsEngineGriddedDataProvider_Test.cpp b/test/forcing/ForcingsEngineGriddedDataProvider_Test.cpp index 2b6d39ab73..1bd45656b0 100644 --- a/test/forcing/ForcingsEngineGriddedDataProvider_Test.cpp +++ b/test/forcing/ForcingsEngineGriddedDataProvider_Test.cpp @@ -59,7 +59,7 @@ void TestFixture::SetUpTestSuite() data_access::assert_forcings_engine_requirements(); - TestFixture::provider_ = data_access::ForcingsEngineGriddedDataProvider::make_gridded_instance( + TestFixture::provider_ = data_access::make_forcings_engine( config_file, default_params.start_time, default_params.end_time @@ -83,10 +83,10 @@ void TestFixture::TearDownTestSuite() */ TEST_F(ForcingsEngineGriddedDataProviderTest, Storage) { - auto inst_a = data_access::ForcingsEngineGriddedDataProvider::make_gridded_instance(config_file, default_params.start_time, default_params.end_time); + auto inst_a = data_access::make_forcings_engine(config_file, default_params.start_time, default_params.end_time); ASSERT_EQ(inst_a->model(), provider_->model()); - auto inst_b = data_access::ForcingsEngineGriddedDataProvider::make_gridded_instance(config_file, default_params.start_time, default_params.end_time); + auto inst_b = data_access::make_forcings_engine(config_file, default_params.start_time, default_params.end_time); ASSERT_EQ(inst_a->model(), inst_b->model()); } @@ -113,6 +113,7 @@ TEST_F(ForcingsEngineGriddedDataProviderTest, VariableAccess) } // const auto selector = GridDataSelector{ + // SelectorConfig{provider_->get_data_start_time(), 3600, "LWDOWN", "seconds"}, // // } } diff --git a/test/forcing/ForcingsEngineLumpedDataProvider_Test.cpp b/test/forcing/ForcingsEngineLumpedDataProvider_Test.cpp index e355f0676a..8cd7b38774 100644 --- a/test/forcing/ForcingsEngineLumpedDataProvider_Test.cpp +++ b/test/forcing/ForcingsEngineLumpedDataProvider_Test.cpp @@ -66,7 +66,7 @@ void TestFixture::SetUpTestSuite() data_access::assert_forcings_engine_requirements(); // Create a lumped forcings engine instance - TestFixture::provider_ = data_access::ForcingsEngineLumpedDataProvider::make_lumped_instance( + TestFixture::provider_ = data_access::make_forcings_engine( config_file, default_params.start_time, default_params.end_time @@ -93,11 +93,11 @@ void TestFixture::TearDownTestSuite() */ TEST_F(ForcingsEngineLumpedDataProviderTest, Storage) { - auto inst_a = data_access::ForcingsEngineLumpedDataProvider::make_lumped_instance(config_file, default_params.start_time, default_params.end_time); + auto inst_a = data_access::make_forcings_engine(config_file, default_params.start_time, default_params.end_time); ASSERT_EQ(inst_a->model(), provider_->model()); - auto inst_b = data_access::ForcingsEngineLumpedDataProvider::make_lumped_instance(config_file, default_params.start_time, default_params.end_time); + auto inst_b = data_access::make_forcings_engine(config_file, default_params.start_time, default_params.end_time); ASSERT_EQ(inst_a->model(), inst_b->model()); }