From e1c895ee6db2d07daac87a30230fc13ad96cf647 Mon Sep 17 00:00:00 2001 From: program-- Date: Wed, 3 Jul 2024 10:37:51 -0700 Subject: [PATCH 1/8] refactor(DataProvider): add const and noexcept specifiers to virtual methods --- include/forcing/DataProvider.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/forcing/DataProvider.hpp b/include/forcing/DataProvider.hpp index a8ffb56040..a13cac35ce 100644 --- a/include/forcing/DataProvider.hpp +++ b/include/forcing/DataProvider.hpp @@ -40,18 +40,18 @@ namespace data_access /** Return the variables that are accessable by this data provider */ - virtual boost::span get_available_variable_names() = 0; + virtual boost::span get_available_variable_names() const noexcept = 0; /** Return the first valid time for which data from the request variable can be requested */ - virtual long get_data_start_time() = 0; + virtual long get_data_start_time() const noexcept = 0; /** Return the last valid time for which data from the requested variable can be requested */ - virtual long get_data_stop_time() = 0; + virtual long get_data_stop_time() const noexcept = 0; /** Return the stride in the time dimension */ - virtual long record_duration() = 0; + virtual long record_duration() const noexcept = 0; /** * Get the index of the data time step that contains the given point in time. @@ -62,7 +62,7 @@ namespace data_access * @return The index of the forcing time step that contains the given point in time. * @throws std::out_of_range If the given point is not in any time step. */ - virtual size_t get_ts_index_for_time(const time_t &epoch_time) = 0; + virtual size_t get_ts_index_for_time(const time_t &epoch_time) const = 0; /** * Get the value of a forcing property for an arbitrary time period, converting units if needed. From a068869a135e56b2605a9af7ea0468089a882ab7 Mon Sep 17 00:00:00 2001 From: program-- Date: Wed, 3 Jul 2024 10:42:31 -0700 Subject: [PATCH 2/8] refactor(DataProvider): add const and noexcept specifiers to derived implementations --- include/forcing/CsvPerFeatureForcingProvider.hpp | 10 +++++----- include/forcing/DataProvider.hpp | 10 +++++----- include/forcing/ForcingsEngineDataProvider.hpp | 10 +++++----- include/forcing/NetCDFPerFeatureDataProvider.hpp | 10 +++++----- include/forcing/NullForcingProvider.hpp | 10 +++++----- src/forcing/NetCDFPerFeatureDataProvider.cpp | 10 +++++----- src/forcing/NullForcingProvider.cpp | 10 +++++----- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/include/forcing/CsvPerFeatureForcingProvider.hpp b/include/forcing/CsvPerFeatureForcingProvider.hpp index 7ad9bc6cc5..0c5c8f5379 100644 --- a/include/forcing/CsvPerFeatureForcingProvider.hpp +++ b/include/forcing/CsvPerFeatureForcingProvider.hpp @@ -46,7 +46,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * * @return The inclusive beginning of the period of time over which this instance can provide this data. */ - long get_data_start_time() override { + long get_data_start_time() const noexcept override { //FIXME: Trace this back and you will find that it is the simulation start time, not having anything to do with the forcing at all. // Apparently this "worked", but at a minimum the description above is false. return start_date_time_epoch; @@ -57,7 +57,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * * @return The exclusive ending of the period of time over which this instance can provide this data. */ - long get_data_stop_time() override { + long get_data_stop_time() const noexcept override { return end_date_time_epoch; } @@ -66,7 +66,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * * @return The duration of one record of this forcing source */ - long record_duration() override { + long record_duration() const noexcept override { return time_epoch_vector[1] - time_epoch_vector[0]; } @@ -79,7 +79,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * @return The index of the forcing time step that contains the given point in time. * @throws std::out_of_range If the given point is not in any time step. */ - size_t get_ts_index_for_time(const time_t &epoch_time) override { + size_t get_ts_index_for_time(const time_t &epoch_time) const override { if (epoch_time < start_date_time_epoch) { throw std::out_of_range("Forcing had bad pre-start time for index query: " + std::to_string(epoch_time)); } @@ -222,7 +222,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider return is_param_sum_over_time_step(name); } - boost::span get_available_variable_names() override { + boost::span get_available_variable_names() const noexcept override { return available_forcings; } diff --git a/include/forcing/DataProvider.hpp b/include/forcing/DataProvider.hpp index a13cac35ce..a3488cd3ee 100644 --- a/include/forcing/DataProvider.hpp +++ b/include/forcing/DataProvider.hpp @@ -40,18 +40,18 @@ namespace data_access /** Return the variables that are accessable by this data provider */ - virtual boost::span get_available_variable_names() const noexcept = 0; + virtual boost::span get_available_variable_names() const = 0; /** Return the first valid time for which data from the request variable can be requested */ - virtual long get_data_start_time() const noexcept = 0; + virtual long get_data_start_time() const = 0; /** Return the last valid time for which data from the requested variable can be requested */ - virtual long get_data_stop_time() const noexcept = 0; + virtual long get_data_stop_time() const = 0; /** Return the stride in the time dimension */ - virtual long record_duration() const noexcept = 0; + virtual long record_duration() const = 0; /** * Get the index of the data time step that contains the given point in time. @@ -93,7 +93,7 @@ namespace data_access */ virtual std::vector get_values(const selection_type& selector, ReSampleMethod m=SUM) = 0; - virtual bool is_property_sum_over_time_step(const std::string& name) {return false; } + virtual bool is_property_sum_over_time_step(const std::string& name) const {return false; } private: }; diff --git a/include/forcing/ForcingsEngineDataProvider.hpp b/include/forcing/ForcingsEngineDataProvider.hpp index 5dcf8f8f69..4349126e10 100644 --- a/include/forcing/ForcingsEngineDataProvider.hpp +++ b/include/forcing/ForcingsEngineDataProvider.hpp @@ -104,27 +104,27 @@ struct ForcingsEngineDataProvider ~ForcingsEngineDataProvider() override = default; - boost::span get_available_variable_names() override + boost::span get_available_variable_names() const noexcept override { return var_output_names_; } - long get_data_start_time() override + long get_data_start_time() const noexcept override { return clock_type::to_time_t(time_begin_); } - long get_data_stop_time() override + long get_data_stop_time() const noexcept override { return clock_type::to_time_t(time_end_); } - long record_duration() override + long record_duration() const noexcept override { return std::chrono::duration_cast(time_step_).count(); } - size_t get_ts_index_for_time(const time_t& epoch_time) override + size_t get_ts_index_for_time(const time_t& epoch_time) const override { const auto epoch = clock_type::from_time_t(epoch_time); diff --git a/include/forcing/NetCDFPerFeatureDataProvider.hpp b/include/forcing/NetCDFPerFeatureDataProvider.hpp index 823593cca0..0eceffe0a7 100644 --- a/include/forcing/NetCDFPerFeatureDataProvider.hpp +++ b/include/forcing/NetCDFPerFeatureDataProvider.hpp @@ -72,18 +72,18 @@ namespace data_access void finalize() override; /** Return the variables that are accessable by this data provider */ - boost::span get_available_variable_names() override; + boost::span get_available_variable_names() const noexcept override; /** return a list of ids in the current file */ const std::vector& get_ids() const; /** Return the first valid time for which data from the request variable can be requested */ - long get_data_start_time() override; + long get_data_start_time() const noexcept override; /** Return the last valid time for which data from the requested variable can be requested */ - long get_data_stop_time() override; + long get_data_stop_time() const noexcept override; - long record_duration() override; + long record_duration() const noexcept override; /** * Get the index of the data time step that contains the given point in time. @@ -94,7 +94,7 @@ namespace data_access * @return The index of the forcing time step that contains the given point in time. * @throws std::out_of_range If the given point is not in any time step. */ - size_t get_ts_index_for_time(const time_t &epoch_time) override; + size_t get_ts_index_for_time(const time_t &epoch_time) const override; /** * Get the value of a forcing property for an arbitrary time period, converting units if needed. diff --git a/include/forcing/NullForcingProvider.hpp b/include/forcing/NullForcingProvider.hpp index a7d3c8b6d8..90d7a3582e 100644 --- a/include/forcing/NullForcingProvider.hpp +++ b/include/forcing/NullForcingProvider.hpp @@ -16,13 +16,13 @@ class NullForcingProvider : public data_access::GenericDataProvider // BEGIN DataProvider interface methods - long get_data_start_time() override; + long get_data_start_time() const noexcept override; - long get_data_stop_time() override; + long get_data_stop_time() const noexcept override; - long record_duration() override; + long record_duration() const noexcept override; - size_t get_ts_index_for_time(const time_t &epoch_time) override; + size_t get_ts_index_for_time(const time_t &epoch_time) const override; double get_value(const CatchmentAggrDataSelector& selector, data_access::ReSampleMethod m) override; @@ -30,7 +30,7 @@ class NullForcingProvider : public data_access::GenericDataProvider inline bool is_property_sum_over_time_step(const std::string& name) override; - boost::span get_available_variable_names() override; + boost::span get_available_variable_names() const noexcept override; }; #endif // NGEN_NULLFORCING_H diff --git a/src/forcing/NetCDFPerFeatureDataProvider.cpp b/src/forcing/NetCDFPerFeatureDataProvider.cpp index 10e7d70552..3fc1c91cf3 100644 --- a/src/forcing/NetCDFPerFeatureDataProvider.cpp +++ b/src/forcing/NetCDFPerFeatureDataProvider.cpp @@ -272,7 +272,7 @@ void NetCDFPerFeatureDataProvider::finalize() nc_file = nullptr; } -boost::span NetCDFPerFeatureDataProvider::get_available_variable_names() +boost::span NetCDFPerFeatureDataProvider::get_available_variable_names() const noexcept { return variable_names; } @@ -283,7 +283,7 @@ const std::vector& NetCDFPerFeatureDataProvider::get_ids() const } /** Return the first valid time for which data from the request variable can be requested */ -long NetCDFPerFeatureDataProvider::get_data_start_time() +long NetCDFPerFeatureDataProvider::get_data_start_time() const noexcept { //return start_time; //FIXME: Matching behavior from CsvPerFeatureForcingProvider, but both are probably wrong! @@ -291,19 +291,19 @@ long NetCDFPerFeatureDataProvider::get_data_start_time() } /** Return the last valid time for which data from the requested variable can be requested */ -long NetCDFPerFeatureDataProvider::get_data_stop_time() +long NetCDFPerFeatureDataProvider::get_data_stop_time() const noexcept { //return stop_time; //FIXME: Matching behavior from CsvPerFeatureForcingProvider, but both are probably wrong! return sim_end_date_time_epoch; // return end_time + sim_to_data_time_offset; } -long NetCDFPerFeatureDataProvider::record_duration() +long NetCDFPerFeatureDataProvider::record_duration() const noexcept { return time_stride; } -size_t NetCDFPerFeatureDataProvider::get_ts_index_for_time(const time_t &epoch_time) +size_t NetCDFPerFeatureDataProvider::get_ts_index_for_time(const time_t &epoch_time) const { if (start_time <= epoch_time && epoch_time < stop_time) { diff --git a/src/forcing/NullForcingProvider.cpp b/src/forcing/NullForcingProvider.cpp index 6307f7fbfa..df3e419139 100644 --- a/src/forcing/NullForcingProvider.cpp +++ b/src/forcing/NullForcingProvider.cpp @@ -7,20 +7,20 @@ NullForcingProvider::NullForcingProvider() = default; -long NullForcingProvider::get_data_start_time() +long NullForcingProvider::get_data_start_time() const noexcept { return 0; } -long NullForcingProvider::get_data_stop_time() { +long NullForcingProvider::get_data_stop_time() const noexcept { return std::numeric_limits::max(); } -long NullForcingProvider::record_duration() { +long NullForcingProvider::record_duration() const noexcept { return 1; } -size_t NullForcingProvider::get_ts_index_for_time(const time_t &epoch_time) { +size_t NullForcingProvider::get_ts_index_for_time(const time_t &epoch_time) const { return 0; } @@ -38,6 +38,6 @@ inline bool NullForcingProvider::is_property_sum_over_time_step(const std::strin throw std::runtime_error("Got request for variable " + name + " but no such variable is provided by NullForcingProvider." + SOURCE_LOC); } -boost::span NullForcingProvider::get_available_variable_names() { +boost::span NullForcingProvider::get_available_variable_names() const noexcept { return {}; } From 18507dddb2d75fadd6dfa2f1980dbcb07271d46a Mon Sep 17 00:00:00 2001 From: program-- Date: Wed, 3 Jul 2024 11:55:33 -0700 Subject: [PATCH 3/8] refactor(core): add const specifier --- include/core/catchment/HY_CatchmentRealization.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/core/catchment/HY_CatchmentRealization.hpp b/include/core/catchment/HY_CatchmentRealization.hpp index fdbd1699cb..e0eb7d5879 100644 --- a/include/core/catchment/HY_CatchmentRealization.hpp +++ b/include/core/catchment/HY_CatchmentRealization.hpp @@ -39,7 +39,7 @@ class HY_CatchmentRealization std::shared_ptr realized_catchment; - virtual std::string get_catchment_id() = 0; + virtual std::string get_catchment_id() const = 0; virtual void set_catchment_id(std::string cat_id) = 0; From 14edd1bb70436e7c6b8d357bea260e5b29de4b48 Mon Sep 17 00:00:00 2001 From: program-- Date: Wed, 3 Jul 2024 11:56:02 -0700 Subject: [PATCH 4/8] refactor(forcing): add const specifier --- include/forcing/CsvPerFeatureForcingProvider.hpp | 12 ++++++------ include/forcing/DeferredWrappedProvider.hpp | 2 +- include/forcing/NetCDFPerFeatureDataProvider.hpp | 8 ++++---- include/forcing/NullForcingProvider.hpp | 10 +++++----- include/forcing/WrappedDataProvider.hpp | 12 ++++++------ src/forcing/NetCDFPerFeatureDataProvider.cpp | 8 ++++---- src/forcing/NullForcingProvider.cpp | 10 +++++----- test/forcing/GridDataSelector_Test.cpp | 10 +++++----- test/forcing/TrivialForcingProvider.hpp | 12 ++++++------ 9 files changed, 42 insertions(+), 42 deletions(-) diff --git a/include/forcing/CsvPerFeatureForcingProvider.hpp b/include/forcing/CsvPerFeatureForcingProvider.hpp index 0c5c8f5379..a173f63310 100644 --- a/include/forcing/CsvPerFeatureForcingProvider.hpp +++ b/include/forcing/CsvPerFeatureForcingProvider.hpp @@ -46,7 +46,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * * @return The inclusive beginning of the period of time over which this instance can provide this data. */ - long get_data_start_time() const noexcept override { + long get_data_start_time() const override { //FIXME: Trace this back and you will find that it is the simulation start time, not having anything to do with the forcing at all. // Apparently this "worked", but at a minimum the description above is false. return start_date_time_epoch; @@ -57,7 +57,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * * @return The exclusive ending of the period of time over which this instance can provide this data. */ - long get_data_stop_time() const noexcept override { + long get_data_stop_time() const override { return end_date_time_epoch; } @@ -66,7 +66,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * * @return The duration of one record of this forcing source */ - long record_duration() const noexcept override { + long record_duration() const override { return time_epoch_vector[1] - time_epoch_vector[0]; } @@ -190,7 +190,7 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * @param name The name of the forcing param for which the current value is desired. * @return Whether the param's value is an aggregate sum. */ - inline bool is_param_sum_over_time_step(const std::string& name) { + inline bool is_param_sum_over_time_step(const std::string& name) const { if (name == CSDMS_STD_NAME_RAIN_VOLUME_FLUX) { return true; } @@ -218,11 +218,11 @@ class CsvPerFeatureForcingProvider : public data_access::GenericDataProvider * @param name The name of the forcing property for which the current value is desired. * @return Whether the property's value is an aggregate sum. */ - inline bool is_property_sum_over_time_step(const std::string& name) override { + inline bool is_property_sum_over_time_step(const std::string& name) const override { return is_param_sum_over_time_step(name); } - boost::span get_available_variable_names() const noexcept override { + boost::span get_available_variable_names() const override { return available_forcings; } diff --git a/include/forcing/DeferredWrappedProvider.hpp b/include/forcing/DeferredWrappedProvider.hpp index 1bb0e8b87e..9b8e279005 100644 --- a/include/forcing/DeferredWrappedProvider.hpp +++ b/include/forcing/DeferredWrappedProvider.hpp @@ -70,7 +70,7 @@ namespace data_access { * @return The names of the outputs for which this instance is (or will be) able to provide values. */ - boost::span get_available_variable_names() override { + boost::span get_available_variable_names() const override { return providedOutputs; } diff --git a/include/forcing/NetCDFPerFeatureDataProvider.hpp b/include/forcing/NetCDFPerFeatureDataProvider.hpp index 0eceffe0a7..92ef771fff 100644 --- a/include/forcing/NetCDFPerFeatureDataProvider.hpp +++ b/include/forcing/NetCDFPerFeatureDataProvider.hpp @@ -72,18 +72,18 @@ namespace data_access void finalize() override; /** Return the variables that are accessable by this data provider */ - boost::span get_available_variable_names() const noexcept override; + boost::span get_available_variable_names() const override; /** return a list of ids in the current file */ const std::vector& get_ids() const; /** Return the first valid time for which data from the request variable can be requested */ - long get_data_start_time() const noexcept override; + long get_data_start_time() const override; /** Return the last valid time for which data from the requested variable can be requested */ - long get_data_stop_time() const noexcept override; + long get_data_stop_time() const override; - long record_duration() const noexcept override; + long record_duration() const override; /** * Get the index of the data time step that contains the given point in time. diff --git a/include/forcing/NullForcingProvider.hpp b/include/forcing/NullForcingProvider.hpp index 90d7a3582e..c43a842c4e 100644 --- a/include/forcing/NullForcingProvider.hpp +++ b/include/forcing/NullForcingProvider.hpp @@ -16,11 +16,11 @@ class NullForcingProvider : public data_access::GenericDataProvider // BEGIN DataProvider interface methods - long get_data_start_time() const noexcept override; + long get_data_start_time() const override; - long get_data_stop_time() const noexcept override; + long get_data_stop_time() const override; - long record_duration() const noexcept override; + long record_duration() const override; size_t get_ts_index_for_time(const time_t &epoch_time) const override; @@ -28,9 +28,9 @@ class NullForcingProvider : public data_access::GenericDataProvider std::vector get_values(const CatchmentAggrDataSelector& selector, data_access::ReSampleMethod m) override; - inline bool is_property_sum_over_time_step(const std::string& name) override; + inline bool is_property_sum_over_time_step(const std::string& name) const override; - boost::span get_available_variable_names() const noexcept override; + boost::span get_available_variable_names() const override; }; #endif // NGEN_NULLFORCING_H diff --git a/include/forcing/WrappedDataProvider.hpp b/include/forcing/WrappedDataProvider.hpp index 1258157989..b7d0b4c456 100644 --- a/include/forcing/WrappedDataProvider.hpp +++ b/include/forcing/WrappedDataProvider.hpp @@ -59,7 +59,7 @@ namespace data_access { * @return const std::vector& the names of available data variables */ - boost::span get_available_variable_names() override { + boost::span get_available_variable_names() const override { return wrapped_provider->get_available_variable_names(); } @@ -68,7 +68,7 @@ namespace data_access { * * @return The inclusive beginning of the period of time over which this instance can provide this data. */ - long get_data_start_time() override { + long get_data_start_time() const override { return wrapped_provider->get_data_start_time(); } @@ -77,11 +77,11 @@ namespace data_access { * * @return The exclusive ending of the period of time over which this instance can provide this data. */ - long get_data_stop_time() override { + long get_data_stop_time() const override { return wrapped_provider->get_data_stop_time(); } - long record_duration() override { + long record_duration() const override { return wrapped_provider->record_duration(); } @@ -94,7 +94,7 @@ namespace data_access { * @return The index of the forcing time step that contains the given point in time. * @throws std::out_of_range If the given point is not in any time step. */ - size_t get_ts_index_for_time(const time_t &epoch_time) override { + size_t get_ts_index_for_time(const time_t &epoch_time) const override { return wrapped_provider->get_ts_index_for_time(epoch_time); } @@ -132,7 +132,7 @@ namespace data_access { * @param name The name of the forcing property for which the current value is desired. * @return Whether the property's value is an aggregate sum. */ - bool is_property_sum_over_time_step(const std::string& name) override { + bool is_property_sum_over_time_step(const std::string& name) const override { return wrapped_provider->is_property_sum_over_time_step(name); } diff --git a/src/forcing/NetCDFPerFeatureDataProvider.cpp b/src/forcing/NetCDFPerFeatureDataProvider.cpp index 3fc1c91cf3..2ddb9ab578 100644 --- a/src/forcing/NetCDFPerFeatureDataProvider.cpp +++ b/src/forcing/NetCDFPerFeatureDataProvider.cpp @@ -272,7 +272,7 @@ void NetCDFPerFeatureDataProvider::finalize() nc_file = nullptr; } -boost::span NetCDFPerFeatureDataProvider::get_available_variable_names() const noexcept +boost::span NetCDFPerFeatureDataProvider::get_available_variable_names() const { return variable_names; } @@ -283,7 +283,7 @@ const std::vector& NetCDFPerFeatureDataProvider::get_ids() const } /** Return the first valid time for which data from the request variable can be requested */ -long NetCDFPerFeatureDataProvider::get_data_start_time() const noexcept +long NetCDFPerFeatureDataProvider::get_data_start_time() const { //return start_time; //FIXME: Matching behavior from CsvPerFeatureForcingProvider, but both are probably wrong! @@ -291,14 +291,14 @@ long NetCDFPerFeatureDataProvider::get_data_start_time() const noexcept } /** Return the last valid time for which data from the requested variable can be requested */ -long NetCDFPerFeatureDataProvider::get_data_stop_time() const noexcept +long NetCDFPerFeatureDataProvider::get_data_stop_time() const { //return stop_time; //FIXME: Matching behavior from CsvPerFeatureForcingProvider, but both are probably wrong! return sim_end_date_time_epoch; // return end_time + sim_to_data_time_offset; } -long NetCDFPerFeatureDataProvider::record_duration() const noexcept +long NetCDFPerFeatureDataProvider::record_duration() const { return time_stride; } diff --git a/src/forcing/NullForcingProvider.cpp b/src/forcing/NullForcingProvider.cpp index df3e419139..6023c20a29 100644 --- a/src/forcing/NullForcingProvider.cpp +++ b/src/forcing/NullForcingProvider.cpp @@ -7,16 +7,16 @@ NullForcingProvider::NullForcingProvider() = default; -long NullForcingProvider::get_data_start_time() const noexcept +long NullForcingProvider::get_data_start_time() const { return 0; } -long NullForcingProvider::get_data_stop_time() const noexcept { +long NullForcingProvider::get_data_stop_time() const { return std::numeric_limits::max(); } -long NullForcingProvider::record_duration() const noexcept { +long NullForcingProvider::record_duration() const { return 1; } @@ -34,10 +34,10 @@ std::vector NullForcingProvider::get_values(const CatchmentAggrDataSelec throw std::runtime_error("Called get_values function in NullDataProvider"); } -inline bool NullForcingProvider::is_property_sum_over_time_step(const std::string& name) { +inline bool NullForcingProvider::is_property_sum_over_time_step(const std::string& name) const { throw std::runtime_error("Got request for variable " + name + " but no such variable is provided by NullForcingProvider." + SOURCE_LOC); } -boost::span NullForcingProvider::get_available_variable_names() const noexcept { +boost::span NullForcingProvider::get_available_variable_names() const { return {}; } diff --git a/test/forcing/GridDataSelector_Test.cpp b/test/forcing/GridDataSelector_Test.cpp index 35997fe8f2..6821b868b5 100644 --- a/test/forcing/GridDataSelector_Test.cpp +++ b/test/forcing/GridDataSelector_Test.cpp @@ -21,19 +21,19 @@ struct TestGridDataProvider : TestGridDataProvider(GridSpecification{10, 10, box_t{{0, 0},{10, 10}}}) {} - boost::span get_available_variable_names() override + boost::span get_available_variable_names() const override { return { &variable_, 1 }; } - long get_data_start_time() override + long get_data_start_time() const override { return 0; } - long get_data_stop_time() override + long get_data_stop_time() const override { return get_data_start_time() + record_duration(); } - long record_duration() override + long record_duration() const override { return 3600; } - size_t get_ts_index_for_time(const time_t& epoch_time) override + size_t get_ts_index_for_time(const time_t& epoch_time) const override { return -1; } Cell get_value(const GridDataSelector& selector, data_access::ReSampleMethod method) override diff --git a/test/forcing/TrivialForcingProvider.hpp b/test/forcing/TrivialForcingProvider.hpp index 0f170c73fe..9d523bd460 100644 --- a/test/forcing/TrivialForcingProvider.hpp +++ b/test/forcing/TrivialForcingProvider.hpp @@ -23,23 +23,23 @@ namespace data_access { outputs.push_back(OUTPUT_NAME_1); } - boost::span get_available_variable_names() override { + boost::span get_available_variable_names() const override { return outputs; } - long get_data_start_time() override { + long get_data_start_time() const override { return std::numeric_limits::min(); } - long get_data_stop_time() override { + long get_data_stop_time() const override { return std::numeric_limits::max(); } - long record_duration() override { + long record_duration() const override { return 1; } - size_t get_ts_index_for_time(const time_t &epoch_time) override { + size_t get_ts_index_for_time(const time_t &epoch_time) const override { return 0; } @@ -52,7 +52,7 @@ namespace data_access { return std::vector(1, get_value(selector, m)); } - bool is_property_sum_over_time_step(const std::string &name) override { + bool is_property_sum_over_time_step(const std::string &name) const override { return true; } From 25823b6f64daeb229b4231bc2b2b4b5079e942fd Mon Sep 17 00:00:00 2001 From: program-- Date: Wed, 3 Jul 2024 12:00:52 -0700 Subject: [PATCH 5/8] refactor(realizations): add const specifier --- .../catchment/Bmi_C_Formulation.hpp | 10 ++-- .../catchment/Bmi_Cpp_Formulation.hpp | 10 ++-- .../catchment/Bmi_Formulation.hpp | 28 ++++----- .../catchment/Bmi_Fortran_Formulation.hpp | 4 +- .../catchment/Bmi_Module_Formulation.hpp | 36 +++++------ .../catchment/Bmi_Multi_Formulation.hpp | 60 +++++++++---------- .../catchment/Bmi_Py_Formulation.hpp | 14 ++--- .../catchment/Catchment_Formulation.hpp | 6 +- .../realizations/catchment/Formulation.hpp | 4 +- .../catchment/Bmi_C_Formulation.cpp | 8 +-- .../catchment/Bmi_Cpp_Formulation.cpp | 8 +-- .../catchment/Bmi_Fortran_Formulation.cpp | 2 +- .../catchment/Bmi_Module_Formulation.cpp | 54 +++++++++-------- .../catchment/Bmi_Multi_Formulation.cpp | 25 +++----- .../catchment/Bmi_Py_Formulation.cpp | 14 ++--- 15 files changed, 139 insertions(+), 144 deletions(-) diff --git a/include/realizations/catchment/Bmi_C_Formulation.hpp b/include/realizations/catchment/Bmi_C_Formulation.hpp index d43db59d97..10a1e5e671 100644 --- a/include/realizations/catchment/Bmi_C_Formulation.hpp +++ b/include/realizations/catchment/Bmi_C_Formulation.hpp @@ -16,11 +16,11 @@ namespace realization { Bmi_C_Formulation(std::string id, std::shared_ptr forcing_provider, utils::StreamHandler output_stream); - std::string get_formulation_type() override; + std::string get_formulation_type() const override; - bool is_bmi_input_variable(const std::string &var_name) override; + bool is_bmi_input_variable(const std::string &var_name) const override; - bool is_bmi_output_variable(const std::string &var_name) override; + bool is_bmi_output_variable(const std::string &var_name) const override; protected: @@ -36,7 +36,7 @@ namespace realization { */ std::shared_ptr construct_model(const geojson::PropertyMap& properties) override; - time_t convert_model_time(const double &model_time) override { + time_t convert_model_time(const double &model_time) const override { return (time_t) (get_bmi_model()->convert_model_time_to_seconds(model_time)); } @@ -98,7 +98,7 @@ namespace realization { * * @return Whether backing model object has been initialize using the BMI standard ``Initialize`` function. */ - bool is_model_initialized() override; + bool is_model_initialized() const override; // Unit test access friend class ::Bmi_Formulation_Test; diff --git a/include/realizations/catchment/Bmi_Cpp_Formulation.hpp b/include/realizations/catchment/Bmi_Cpp_Formulation.hpp index 8ec1c55b35..5021cb44b2 100644 --- a/include/realizations/catchment/Bmi_Cpp_Formulation.hpp +++ b/include/realizations/catchment/Bmi_Cpp_Formulation.hpp @@ -16,17 +16,17 @@ namespace realization { Bmi_Cpp_Formulation(std::string id, std::shared_ptr forcing_provider, utils::StreamHandler output_stream); - std::string get_formulation_type() override; + std::string get_formulation_type() const override; - bool is_bmi_input_variable(const std::string &var_name) override; + bool is_bmi_input_variable(const std::string &var_name) const override; - bool is_bmi_output_variable(const std::string &var_name) override; + bool is_bmi_output_variable(const std::string &var_name) const override; protected: std::shared_ptr construct_model(const geojson::PropertyMap& properties) override; - time_t convert_model_time(const double &model_time) override { + time_t convert_model_time(const double &model_time) const override { return (time_t) (get_bmi_model()->convert_model_time_to_seconds(model_time)); } @@ -38,7 +38,7 @@ namespace realization { double get_var_value_as_double(const int& index, const std::string& var_name) override; - bool is_model_initialized() override; + bool is_model_initialized() const override; // Unit test access friend class ::Bmi_Formulation_Test; diff --git a/include/realizations/catchment/Bmi_Formulation.hpp b/include/realizations/catchment/Bmi_Formulation.hpp index 13ad0b426d..a8cbc34bf7 100644 --- a/include/realizations/catchment/Bmi_Formulation.hpp +++ b/include/realizations/catchment/Bmi_Formulation.hpp @@ -78,7 +78,7 @@ namespace realization { * @param model_time * @return */ - virtual time_t convert_model_time(const double &model_time) = 0; + virtual time_t convert_model_time(const double &model_time) const = 0; /** * Get whether a model may perform updates beyond its ``end_time``. @@ -97,15 +97,15 @@ namespace realization { */ virtual const bool &get_allow_model_exceed_end_time() const = 0; - virtual const std::vector get_bmi_input_variables() = 0; + virtual const std::vector get_bmi_input_variables() const = 0; const std::string &get_bmi_main_output_var() const { return bmi_main_output_var; } - virtual const time_t &get_bmi_model_start_time_forcing_offset_s() = 0; + virtual const time_t &get_bmi_model_start_time_forcing_offset_s() const = 0; - virtual const std::vector get_bmi_output_variables() = 0; + virtual const std::vector get_bmi_output_variables() const = 0; /** * When possible, translate a variable name for a BMI model to an internally recognized name. @@ -113,28 +113,28 @@ namespace realization { * @param model_var_name The BMI variable name to translate so its purpose is recognized internally. * @return Either the translated equivalent variable name, or the provided name if there is not a mapping entry. */ - virtual const std::string &get_config_mapped_variable_name(const std::string &model_var_name) = 0; + virtual const std::string &get_config_mapped_variable_name(const std::string &model_var_name) const = 0; /** * Get the current time for the backing BMI model in its native format and units. * * @return The current time for the backing BMI model in its native format and units. */ - virtual const double get_model_current_time() = 0; + virtual const double get_model_current_time() const = 0; /** * Get the end time for the backing BMI model in its native format and units. * * @return The end time for the backing BMI model in its native format and units. */ - virtual const double get_model_end_time() = 0; + virtual const double get_model_end_time() const = 0; /** * Get the name of the specific type of the backing model object. * * @return The name of the backing model object's type. */ - std::string get_model_type_name() { + std::string get_model_type_name() const { return model_type_name; } @@ -155,7 +155,7 @@ namespace realization { * * @return An appropriate header line for this type. */ - std::string get_output_header_line(std::string delimiter) override { + std::string get_output_header_line(std::string delimiter) const override { return boost::algorithm::join(get_output_header_fields(), delimiter); } @@ -172,27 +172,27 @@ namespace realization { return output_variable_names; } - const std::vector &get_required_parameters() override { + const std::vector &get_required_parameters() const override { return REQUIRED_PARAMETERS; } - virtual bool is_bmi_input_variable(const std::string &var_name) = 0; + virtual bool is_bmi_input_variable(const std::string &var_name) const = 0; /** * Test whether backing model has fixed time step size. * * @return Whether backing model has fixed time step size. */ - virtual bool is_bmi_model_time_step_fixed() = 0; + virtual bool is_bmi_model_time_step_fixed() const = 0; - virtual bool is_bmi_output_variable(const std::string &var_name) = 0; + virtual bool is_bmi_output_variable(const std::string &var_name) const = 0; /** * Test whether the backing model has been initialize using the BMI standard ``Initialize`` function. * * @return Whether backing model has been initialize using the BMI standard ``Initialize`` function. */ - virtual bool is_model_initialized() = 0; + virtual bool is_model_initialized() const = 0; /** * Set the precision of output values when converted to text. diff --git a/include/realizations/catchment/Bmi_Fortran_Formulation.hpp b/include/realizations/catchment/Bmi_Fortran_Formulation.hpp index 7c9630f4e1..4f6863b883 100644 --- a/include/realizations/catchment/Bmi_Fortran_Formulation.hpp +++ b/include/realizations/catchment/Bmi_Fortran_Formulation.hpp @@ -21,7 +21,7 @@ namespace realization { Bmi_Fortran_Formulation(std::string id, std::shared_ptr forcing, utils::StreamHandler output_stream); - std::string get_formulation_type() override; + std::string get_formulation_type() const override; protected: @@ -39,7 +39,7 @@ namespace realization { */ std::shared_ptr construct_model(const geojson::PropertyMap& properties) override; - time_t convert_model_time(const double &model_time) override { + time_t convert_model_time(const double &model_time) const override { return (time_t) (get_bmi_model()->convert_model_time_to_seconds(model_time)); } diff --git a/include/realizations/catchment/Bmi_Module_Formulation.hpp b/include/realizations/catchment/Bmi_Module_Formulation.hpp index 286baf1aeb..259ac1ee3b 100644 --- a/include/realizations/catchment/Bmi_Module_Formulation.hpp +++ b/include/realizations/catchment/Bmi_Module_Formulation.hpp @@ -57,7 +57,7 @@ namespace realization { * @return The collection of forcing output property names this instance can provide. * @see ForcingProvider */ - boost::span get_available_variable_names() override; + boost::span get_available_variable_names() const override; /** * Get a delimited string with all the output variable values for the given time step. @@ -139,27 +139,27 @@ namespace realization { * * @return The inclusive beginning of the period of time over which this instance can provide this data. */ - long get_data_start_time() override; + long get_data_start_time() const override; - long get_data_stop_time() override; + long get_data_stop_time() const override; - long record_duration() override; + long record_duration() const override; /** * Get the current time for the backing BMI model in its native format and units. * * @return The current time for the backing BMI model in its native format and units. */ - const double get_model_current_time() override; + const double get_model_current_time() const override; /** * Get the end time for the backing BMI model in its native format and units. * * @return The end time for the backing BMI model in its native format and units. */ - const double get_model_end_time() override; + const double get_model_end_time() const override; - const std::vector &get_required_parameters() override; + const std::vector &get_required_parameters() const override; /** * When possible, translate a variable name for a BMI model to an internally recognized name. @@ -175,7 +175,7 @@ namespace realization { * @param model_var_name The BMI variable name to translate so its purpose is recognized internally. * @return Either the internal equivalent variable name, or the provided name if there is not a mapping entry. */ - const std::string &get_config_mapped_variable_name(const std::string &model_var_name) override; + const std::string &get_config_mapped_variable_name(const std::string &model_var_name) const override; /** * Get the index of the forcing time step that contains the given point in time. @@ -190,7 +190,7 @@ namespace realization { * @return The index of the forcing time step that contains the given point in time. * @throws std::out_of_range If the given point is not in any time step. */ - size_t get_ts_index_for_time(const time_t &epoch_time) override; + size_t get_ts_index_for_time(const time_t &epoch_time) const override; /** * @brief Get the 1D values of a forcing property for an arbitrary time period, converting units if needed. @@ -224,8 +224,8 @@ namespace realization { */ double get_value(const CatchmentAggrDataSelector& selector, data_access::ReSampleMethod m) override; - bool is_bmi_input_variable(const std::string &var_name) override; - bool is_bmi_output_variable(const std::string &var_name) override; + bool is_bmi_input_variable(const std::string &var_name) const override; + bool is_bmi_output_variable(const std::string &var_name) const override; /** * Get whether a property's per-time-step values are each an aggregate sum over the entire time step. @@ -245,10 +245,10 @@ namespace realization { * @param name The name of the forcing property for which the current value is desired. * @return Whether the property's value is an aggregate sum, which is always ``true`` for this type. */ - bool is_property_sum_over_time_step(const std::string& name) override; + bool is_property_sum_over_time_step(const std::string& name) const override; - const std::vector get_bmi_input_variables() override; - const std::vector get_bmi_output_variables() override; + const std::vector get_bmi_input_variables() const override; + const std::vector get_bmi_output_variables() const override; protected: @@ -306,9 +306,9 @@ namespace realization { * * @return Shared pointer to the backing model object that implements the BMI. */ - std::shared_ptr get_bmi_model(); + std::shared_ptr get_bmi_model() const; - const time_t &get_bmi_model_start_time_forcing_offset_s() override; + const time_t &get_bmi_model_start_time_forcing_offset_s() const override; /** * Universal logic applied when creating a BMI-backed formulation from NGen config. @@ -341,14 +341,14 @@ namespace realization { * * @return Whether backing model has fixed time step size. */ - bool is_bmi_model_time_step_fixed() override; + bool is_bmi_model_time_step_fixed() const override; /** * Test whether the backing model object has been initialize using the BMI standard ``Initialize`` function. * * @return Whether backing model object has been initialize using the BMI standard ``Initialize`` function. */ - bool is_model_initialized() override; + bool is_model_initialized() const override; void set_allow_model_exceed_end_time(bool allow_exceed_end); diff --git a/include/realizations/catchment/Bmi_Multi_Formulation.hpp b/include/realizations/catchment/Bmi_Multi_Formulation.hpp index d068f0e312..5d07137e29 100644 --- a/include/realizations/catchment/Bmi_Multi_Formulation.hpp +++ b/include/realizations/catchment/Bmi_Multi_Formulation.hpp @@ -56,7 +56,7 @@ namespace realization { * @param model_time The time value in a model's representation that is to be converted. * @return The equivalent epoch time. */ - time_t convert_model_time(const double &model_time) override { + time_t convert_model_time(const double &model_time) const override { return convert_model_time(model_time, get_index_for_primary_module()); } @@ -73,7 +73,7 @@ namespace realization { * @param model_time The time value in a model's representation that is to be converted. * @return The equivalent epoch time. */ - inline time_t convert_model_time(const double &model_time, int module_index) { + inline time_t convert_model_time(const double &model_time, int module_index) const { return modules[module_index]->convert_model_time(model_time); } @@ -117,7 +117,7 @@ namespace realization { * @return The collection of forcing output property names this instance can provide. * @see ForcingProvider */ - boost::span get_available_variable_names() override; + boost::span get_available_variable_names() const override; /** * Get the input variables of @@ -125,18 +125,18 @@ namespace realization { * * @return The input variables of the first nested BMI model. */ - const std::vector get_bmi_input_variables() override { + const std::vector get_bmi_input_variables() const override { return modules[0]->get_bmi_input_variables(); } - const time_t &get_bmi_model_start_time_forcing_offset_s() override; + const time_t &get_bmi_model_start_time_forcing_offset_s() const override; /** * Get the output variables of the last nested BMI model. * * @return The output variables of the last nested BMI model. */ - const std::vector get_bmi_output_variables() override { + const std::vector get_bmi_output_variables() const override { return modules.back()->get_bmi_output_variables(); } @@ -160,7 +160,7 @@ namespace realization { * @see get_config_mapped_variable_name(string, bool, bool) * @see get_config_mapped_variable_name(string, shared_ptr, shared_ptr) */ - const std::string &get_config_mapped_variable_name(const std::string &model_var_name) override; + const std::string &get_config_mapped_variable_name(const std::string &model_var_name) const override; /** * When possible, translate a variable name for the first or last BMI model to an internally recognized name. @@ -178,7 +178,7 @@ namespace realization { * @param check_last Whether an output variable mapping for the last module should sought. * @return Either the translated equivalent variable name, or the provided name if there is not a mapping entry. */ - const std::string &get_config_mapped_variable_name(const std::string &model_var_name, bool check_first, bool check_last); + const std::string &get_config_mapped_variable_name(const std::string &model_var_name, bool check_first, bool check_last) const; /** * When possible, translate the name of an output variable for one BMI model to an input variable for another. @@ -206,7 +206,7 @@ namespace realization { */ const std::string &get_config_mapped_variable_name(const std::string &output_var_name, const std::shared_ptr& out_module, - const std::shared_ptr& in_module); + const std::shared_ptr& in_module) const; /** * Get the inclusive beginning of the period of time over which this instance can provide data for this forcing. @@ -219,7 +219,7 @@ namespace realization { */ - long get_data_start_time() override + long get_data_start_time() const override { return get_variable_time_begin(""); } @@ -234,7 +234,7 @@ namespace realization { * @return The inclusive beginning of the period of time over which this instance can provide this data. */ - time_t get_variable_time_begin(const std::string &variable_name) { + time_t get_variable_time_begin(const std::string &variable_name) const { std::string var_name = variable_name; // when unspecified, assume all data is available for the same range. // If no var_name, use forcing ... @@ -245,7 +245,7 @@ namespace realization { if (availableData.empty() || availableData.find(var_name) == availableData.end()) { throw std::runtime_error(get_formulation_type() + " cannot get output time for unknown \"" + variable_name + "\""); } - return availableData[var_name]->get_data_start_time(); + return availableData.at(var_name)->get_data_start_time(); } /** @@ -258,7 +258,7 @@ namespace realization { * @return The exclusive ending of the period of time over which this instance can provide this data. */ - long get_data_stop_time() override + long get_data_stop_time() const override { return get_variable_time_end(""); } @@ -273,7 +273,7 @@ namespace realization { * @return The exclusive ending of the period of time over which this instance can provide this data. */ //time_t get_forcing_output_time_end(const std::string &forcing_name) { - time_t get_variable_time_end(const std::string &variable_name) { + time_t get_variable_time_end(const std::string &variable_name) const { // when unspecified, assume all data is available for the same range. // If no var_name, use forcing ... std::string var_name = variable_name; @@ -284,18 +284,18 @@ namespace realization { if (availableData.empty() || availableData.find(var_name) == availableData.end()) { throw std::runtime_error(get_formulation_type() + " cannot get output time for unknown \"" + variable_name + "\""); } - return availableData[var_name]->get_data_stop_time(); + return availableData.at(var_name)->get_data_stop_time(); } - long record_duration() override + long record_duration() const override { std::string var_name; - for(std::map>::iterator iter = availableData.begin(); iter != availableData.end(); ++iter) + for(auto iter = availableData.begin(); iter != availableData.end(); ++iter) { var_name = iter->first; //TODO: Find a probably more performant way than trial and exception here. try { - time_t rv = availableData[var_name]->record_duration(); + time_t rv = availableData.at(var_name)->record_duration(); return rv; } catch (...){ @@ -308,10 +308,10 @@ namespace realization { if (availableData.empty() || availableData.find(var_name) == availableData.end()) { throw std::runtime_error(get_formulation_type() + " cannot get output record duration for unknown \"" + var_name + "\""); } - return availableData[var_name]->record_duration(); + return availableData.at(var_name)->record_duration(); } - std::string get_formulation_type() override { + std::string get_formulation_type() const override { return "bmi_multi"; } @@ -320,7 +320,7 @@ namespace realization { * * @return The current time for the primary nested BMI model in its native format and units. */ - const double get_model_current_time() override { + const double get_model_current_time() const override { return modules[get_index_for_primary_module()]->get_model_current_time(); } @@ -329,7 +329,7 @@ namespace realization { * * @return The end time for the primary nested BMI model in its native format and units. */ - const double get_model_end_time() override { + const double get_model_end_time() const override { return modules[get_index_for_primary_module()]->get_model_end_time(); } @@ -359,7 +359,7 @@ namespace realization { * @return The index of the forcing time step that contains the given point in time. * @throws std::out_of_range If the given point is not in any time step. */ - size_t get_ts_index_for_time(const time_t &epoch_time) override { + size_t get_ts_index_for_time(const time_t &epoch_time) const override { // TODO: come back and implement if actually necessary for this type; for now don't use throw std::runtime_error("Bmi_Multi_Formulation does not yet implement get_ts_index_for_time"); } @@ -412,23 +412,23 @@ namespace realization { return availableData[output_name]->get_values(CatchmentAggrDataSelector(this->get_catchment_id(),output_name, init_time, duration_s, output_units), m); } - bool is_bmi_input_variable(const std::string &var_name) override; + bool is_bmi_input_variable(const std::string &var_name) const override; /** * Test whether all backing models have fixed time step size. * * @return Whether all backing models has fixed time step size. */ - bool is_bmi_model_time_step_fixed() override; + bool is_bmi_model_time_step_fixed() const override; - bool is_bmi_output_variable(const std::string &var_name) override; + bool is_bmi_output_variable(const std::string &var_name) const override; /** * Test whether all backing models have been initialize using the BMI standard ``Initialize`` function. * * @return Whether all backing models have been initialize using the BMI standard ``Initialize`` function. */ - bool is_model_initialized() override; + bool is_model_initialized() const override; /** * Get whether a property's per-time-step values are each an aggregate sum over the entire time step. @@ -448,12 +448,12 @@ namespace realization { * @param name The name of the forcing property for which the current value is desired. * @return Whether the property's value is an aggregate sum. */ - bool is_property_sum_over_time_step(const std::string &name) override { + bool is_property_sum_over_time_step(const std::string &name) const override { if (availableData.empty() || availableData.find(name) == availableData.end()) { throw std::runtime_error( get_formulation_type() + " cannot get whether unknown property " + name + " is summation"); } - return availableData[name]->is_property_sum_over_time_step(name); + return availableData.at(name)->is_property_sum_over_time_step(name); } /** @@ -469,7 +469,7 @@ namespace realization { * * @return The index of the primary module. */ - inline int get_index_for_primary_module() { + inline int get_index_for_primary_module() const { return primary_module_index; } diff --git a/include/realizations/catchment/Bmi_Py_Formulation.hpp b/include/realizations/catchment/Bmi_Py_Formulation.hpp index b67e71321e..76904165c9 100644 --- a/include/realizations/catchment/Bmi_Py_Formulation.hpp +++ b/include/realizations/catchment/Bmi_Py_Formulation.hpp @@ -25,21 +25,21 @@ namespace realization { Bmi_Py_Formulation(std::string id, std::shared_ptr forcing, utils::StreamHandler output_stream); - const std::vector get_bmi_input_variables() override; + const std::vector get_bmi_input_variables() const override; - const std::vector get_bmi_output_variables() override; + const std::vector get_bmi_output_variables() const override; - std::string get_formulation_type() override; + std::string get_formulation_type() const override; - bool is_bmi_input_variable(const std::string &var_name) override; + bool is_bmi_input_variable(const std::string &var_name) const override; - bool is_bmi_output_variable(const std::string &var_name) override; + bool is_bmi_output_variable(const std::string &var_name) const override; protected: std::shared_ptr construct_model(const geojson::PropertyMap &properties) override; - time_t convert_model_time(const double &model_time) override; + time_t convert_model_time(const double &model_time) const override; double get_var_value_as_double(const int &index, const std::string &var_name) override; @@ -53,7 +53,7 @@ namespace realization { * * @return Whether backing model object has been initialize using the BMI standard ``Initialize`` function. */ - bool is_model_initialized() override; + bool is_model_initialized() const override; // Unit test access friend class ::Bmi_Formulation_Test; diff --git a/include/realizations/catchment/Catchment_Formulation.hpp b/include/realizations/catchment/Catchment_Formulation.hpp index b35e553afa..e85f2709ae 100644 --- a/include/realizations/catchment/Catchment_Formulation.hpp +++ b/include/realizations/catchment/Catchment_Formulation.hpp @@ -72,7 +72,7 @@ namespace realization { * * @return An appropriate header line for this type. */ - virtual std::string get_output_header_line(std::string delimiter=DEFAULT_FORMULATION_OUTPUT_DELIMITER) { + virtual std::string get_output_header_line(std::string delimiter=DEFAULT_FORMULATION_OUTPUT_DELIMITER) const { return "Total Discharge"; } @@ -110,7 +110,7 @@ namespace realization { */ virtual double get_response(time_step_t t_index, time_step_t t_delta) override = 0; - const std::vector& get_required_parameters() override = 0; + const std::vector& get_required_parameters() const override = 0; void create_formulation(boost::property_tree::ptree &config, geojson::PropertyMap *global = nullptr) override = 0; void create_formulation(geojson::PropertyMap properties) override = 0; @@ -128,7 +128,7 @@ namespace realization { } protected: - std::string get_catchment_id() override { + std::string get_catchment_id() const override { return this->cat_id; } diff --git a/include/realizations/catchment/Formulation.hpp b/include/realizations/catchment/Formulation.hpp index 54f7bbc5fa..0c593d197c 100644 --- a/include/realizations/catchment/Formulation.hpp +++ b/include/realizations/catchment/Formulation.hpp @@ -22,7 +22,7 @@ namespace realization { virtual ~Formulation(){}; - virtual std::string get_formulation_type() = 0; + virtual std::string get_formulation_type() const = 0; // TODO: to truly make this properly generalized (beyond catchments, and to some degree even in that // context) a more complex type for the entirety of the response/output is needed, perhaps with independent @@ -46,7 +46,7 @@ namespace realization { protected: - virtual const std::vector& get_required_parameters() = 0; + virtual const std::vector& get_required_parameters() const = 0; geojson::PropertyMap interpret_parameters(boost::property_tree::ptree &config, geojson::PropertyMap *global = nullptr) { geojson::PropertyMap options; diff --git a/src/realizations/catchment/Bmi_C_Formulation.cpp b/src/realizations/catchment/Bmi_C_Formulation.cpp index 783595753b..e59f0cd484 100644 --- a/src/realizations/catchment/Bmi_C_Formulation.cpp +++ b/src/realizations/catchment/Bmi_C_Formulation.cpp @@ -5,7 +5,7 @@ using namespace models::bmi; Bmi_C_Formulation::Bmi_C_Formulation(std::string id, std::shared_ptr forcing_provider, utils::StreamHandler output_stream) : Bmi_Module_Formulation(id, forcing_provider, output_stream) { } -std::string Bmi_C_Formulation::get_formulation_type() { +std::string Bmi_C_Formulation::get_formulation_type() const { return "bmi_c"; } @@ -75,16 +75,16 @@ double Bmi_C_Formulation::get_var_value_as_double(const int& index, const std::s " as double: no logic for converting variable type " + type); } -bool Bmi_C_Formulation::is_bmi_input_variable(const std::string &var_name) { +bool Bmi_C_Formulation::is_bmi_input_variable(const std::string &var_name) const { const std::vector names = get_bmi_model()->GetInputVarNames(); return std::any_of(names.cbegin(), names.cend(), [var_name](const std::string &s){ return var_name == s; }); } -bool Bmi_C_Formulation::is_bmi_output_variable(const std::string &var_name) { +bool Bmi_C_Formulation::is_bmi_output_variable(const std::string &var_name) const { const std::vector names = get_bmi_model()->GetOutputVarNames(); return std::any_of(names.cbegin(), names.cend(), [var_name](const std::string &s){ return var_name == s; }); } -bool Bmi_C_Formulation::is_model_initialized() { +bool Bmi_C_Formulation::is_model_initialized() const { return std::dynamic_pointer_cast(get_bmi_model())->is_model_initialized(); } diff --git a/src/realizations/catchment/Bmi_Cpp_Formulation.cpp b/src/realizations/catchment/Bmi_Cpp_Formulation.cpp index 4ccb1f4fb5..8dede14393 100644 --- a/src/realizations/catchment/Bmi_Cpp_Formulation.cpp +++ b/src/realizations/catchment/Bmi_Cpp_Formulation.cpp @@ -8,7 +8,7 @@ using ModelDestoryer = void (*)(bmi::Bmi*); Bmi_Cpp_Formulation::Bmi_Cpp_Formulation(std::string id, std::shared_ptr forcing_provider, utils::StreamHandler output_stream) : Bmi_Module_Formulation(id, forcing_provider, output_stream) { } -std::string Bmi_Cpp_Formulation::get_formulation_type() { +std::string Bmi_Cpp_Formulation::get_formulation_type() const { return "bmi_c++"; } @@ -86,16 +86,16 @@ double Bmi_Cpp_Formulation::get_var_value_as_double(const int& index, const std: " as double: no logic for converting variable type " + type); } -bool Bmi_Cpp_Formulation::is_bmi_input_variable(const std::string &var_name) { +bool Bmi_Cpp_Formulation::is_bmi_input_variable(const std::string &var_name) const { const std::vector names = get_bmi_model()->GetInputVarNames(); return std::any_of(names.cbegin(), names.cend(), [var_name](const std::string &s){ return var_name == s; }); } -bool Bmi_Cpp_Formulation::is_bmi_output_variable(const std::string &var_name) { +bool Bmi_Cpp_Formulation::is_bmi_output_variable(const std::string &var_name) const { const std::vector names = get_bmi_model()->GetOutputVarNames(); return std::any_of(names.cbegin(), names.cend(), [var_name](const std::string &s){ return var_name == s; }); } -bool Bmi_Cpp_Formulation::is_model_initialized() { +bool Bmi_Cpp_Formulation::is_model_initialized() const { return get_bmi_model()->is_model_initialized(); } diff --git a/src/realizations/catchment/Bmi_Fortran_Formulation.cpp b/src/realizations/catchment/Bmi_Fortran_Formulation.cpp index d4a305b488..6882d89304 100644 --- a/src/realizations/catchment/Bmi_Fortran_Formulation.cpp +++ b/src/realizations/catchment/Bmi_Fortran_Formulation.cpp @@ -41,7 +41,7 @@ std::shared_ptr Bmi_Fortran_Formulation::construct_model(const geoj reg_func); } -std::string Bmi_Fortran_Formulation::get_formulation_type() { +std::string Bmi_Fortran_Formulation::get_formulation_type() const { return "bmi_fortran"; } diff --git a/src/realizations/catchment/Bmi_Module_Formulation.cpp b/src/realizations/catchment/Bmi_Module_Formulation.cpp index 5c6c2c2623..1a16c6b5ef 100644 --- a/src/realizations/catchment/Bmi_Module_Formulation.cpp +++ b/src/realizations/catchment/Bmi_Module_Formulation.cpp @@ -12,14 +12,7 @@ namespace realization { inner_create_formulation(properties, true); } - boost::span Bmi_Module_Formulation::get_available_variable_names() { - if (is_model_initialized() && available_forcings.empty()) { - for (const std::string &output_var_name : get_bmi_model()->GetOutputVarNames()) { - available_forcings.push_back(output_var_name); - if (bmi_var_names_map.find(output_var_name) != bmi_var_names_map.end()) - available_forcings.push_back(bmi_var_names_map[output_var_name]); - } - } + boost::span Bmi_Module_Formulation::get_available_variable_names() const { return available_forcings; } @@ -83,41 +76,41 @@ namespace realization { throw std::runtime_error("Bmi_Modular_Formulation does not yet implement get_variable_time_begin"); } - long Bmi_Module_Formulation::get_data_start_time() + long Bmi_Module_Formulation::get_data_start_time() const { return this->get_bmi_model()->GetStartTime(); } - long Bmi_Module_Formulation::get_data_stop_time() { + long Bmi_Module_Formulation::get_data_stop_time() const { // TODO: come back and implement if actually necessary for this type; for now don't use throw std::runtime_error("Bmi_Module_Formulation does not yet implement get_data_stop_time"); } - long Bmi_Module_Formulation::record_duration() { + long Bmi_Module_Formulation::record_duration() const { throw std::runtime_error("Bmi_Module_Formulation does not yet implement record_duration"); } - const double Bmi_Module_Formulation::get_model_current_time() { + const double Bmi_Module_Formulation::get_model_current_time() const { return get_bmi_model()->GetCurrentTime(); } - const double Bmi_Module_Formulation::get_model_end_time() { + const double Bmi_Module_Formulation::get_model_end_time() const { return get_bmi_model()->GetEndTime(); } - const std::vector& Bmi_Module_Formulation::get_required_parameters() { + const std::vector& Bmi_Module_Formulation::get_required_parameters() const { return REQUIRED_PARAMETERS; } - const std::string& Bmi_Module_Formulation::get_config_mapped_variable_name(const std::string &model_var_name) { + const std::string& Bmi_Module_Formulation::get_config_mapped_variable_name(const std::string &model_var_name) const { // TODO: need to introduce validation elsewhere that all mapped names are valid AORC field constants. if (bmi_var_names_map.find(model_var_name) != bmi_var_names_map.end()) - return bmi_var_names_map[model_var_name]; + return bmi_var_names_map.at(model_var_name); else return model_var_name; } - size_t Bmi_Module_Formulation::get_ts_index_for_time(const time_t &epoch_time) { + size_t Bmi_Module_Formulation::get_ts_index_for_time(const time_t &epoch_time) const { // TODO: come back and implement if actually necessary for this type; for now don't use throw std::runtime_error("Bmi_Singular_Formulation does not yet implement get_ts_index_for_time"); } @@ -225,24 +218,24 @@ namespace realization { return std::count(all_names.begin(), all_names.end(), var_name) > 0; } - bool Bmi_Module_Formulation::is_bmi_input_variable(const std::string &var_name) { + bool Bmi_Module_Formulation::is_bmi_input_variable(const std::string &var_name) const { return is_var_name_in_collection(get_bmi_input_variables(), var_name); } - bool Bmi_Module_Formulation::is_bmi_output_variable(const std::string &var_name) { + bool Bmi_Module_Formulation::is_bmi_output_variable(const std::string &var_name) const { return is_var_name_in_collection(get_bmi_output_variables(), var_name); } - bool Bmi_Module_Formulation::is_property_sum_over_time_step(const std::string& name) { + bool Bmi_Module_Formulation::is_property_sum_over_time_step(const std::string& name) const { // TODO: verify with some kind of proof that "always true" is appropriate return true; } - const std::vector Bmi_Module_Formulation::get_bmi_input_variables() { + const std::vector Bmi_Module_Formulation::get_bmi_input_variables() const { return get_bmi_model()->GetInputVarNames(); } - const std::vector Bmi_Module_Formulation::get_bmi_output_variables() { + const std::vector Bmi_Module_Formulation::get_bmi_output_variables() const { return get_bmi_model()->GetOutputVarNames(); } @@ -285,11 +278,11 @@ namespace realization { return bmi_init_config; } - std::shared_ptr Bmi_Module_Formulation::get_bmi_model() { + std::shared_ptr Bmi_Module_Formulation::get_bmi_model() const { return bmi_model; } - const time_t& Bmi_Module_Formulation::get_bmi_model_start_time_forcing_offset_s() { + const time_t& Bmi_Module_Formulation::get_bmi_model_start_time_forcing_offset_s() const { return bmi_model_start_time_forcing_offset_s; } @@ -381,6 +374,15 @@ namespace realization { // Finally, make sure this is set model_initialized = get_bmi_model()->is_model_initialized(); + + // Get output variable names + if (model_initialized) { + for (const std::string &output_var_name : get_bmi_model()->GetOutputVarNames()) { + available_forcings.push_back(output_var_name); + if (bmi_var_names_map.find(output_var_name) != bmi_var_names_map.end()) + available_forcings.push_back(bmi_var_names_map[output_var_name]); + } + } } /** * @brief Template function for copying iterator range into contiguous array. @@ -551,11 +553,11 @@ namespace realization { //implment the overloads in each adapter //ensure proper type is prepared before setting value } - bool Bmi_Module_Formulation::is_bmi_model_time_step_fixed() { + bool Bmi_Module_Formulation::is_bmi_model_time_step_fixed() const { return bmi_model_time_step_fixed; } - bool Bmi_Module_Formulation::is_model_initialized() { + bool Bmi_Module_Formulation::is_model_initialized() const { return model_initialized; } diff --git a/src/realizations/catchment/Bmi_Multi_Formulation.cpp b/src/realizations/catchment/Bmi_Multi_Formulation.cpp index 961ea6e20d..3611adc8da 100644 --- a/src/realizations/catchment/Bmi_Multi_Formulation.cpp +++ b/src/realizations/catchment/Bmi_Multi_Formulation.cpp @@ -186,18 +186,11 @@ const bool &Bmi_Multi_Formulation::get_allow_model_exceed_end_time() const { * @return The collection of forcing output property names this instance can provide. * @see ForcingProvider */ -boost::span Bmi_Multi_Formulation::get_available_variable_names() { - if (is_model_initialized() && available_forcings.empty()) { - for (const nested_module_ptr &module: modules) { - for (const std::string &out_var_name: module->get_bmi_output_variables()) { - available_forcings.push_back(module->get_config_mapped_variable_name(out_var_name)); - } - } - } +boost::span Bmi_Multi_Formulation::get_available_variable_names() const { return available_forcings; } -const time_t &Bmi_Multi_Formulation::get_bmi_model_start_time_forcing_offset_s() { +const time_t &Bmi_Multi_Formulation::get_bmi_model_start_time_forcing_offset_s() const { return modules[0]->get_bmi_model_start_time_forcing_offset_s(); } @@ -219,12 +212,12 @@ const time_t &Bmi_Multi_Formulation::get_bmi_model_start_time_forcing_offset_s() * @return Either the translated equivalent variable name, or the provided name if there is not a mapping entry. * @see get_config_mapped_variable_name(string, shared_ptr, shared_ptr) */ -const std::string &Bmi_Multi_Formulation::get_config_mapped_variable_name(const std::string &model_var_name) { +const std::string &Bmi_Multi_Formulation::get_config_mapped_variable_name(const std::string &model_var_name) const { return get_config_mapped_variable_name(model_var_name, true, true); } const std::string &Bmi_Multi_Formulation::get_config_mapped_variable_name(const std::string &model_var_name, bool check_first, - bool check_last) + bool check_last) const { if (check_first) { // If an input var in first module, see if we get back a mapping (i.e., not the same thing), and return if so @@ -269,7 +262,7 @@ const std::string &Bmi_Multi_Formulation::get_config_mapped_variable_name(const */ const std::string &Bmi_Multi_Formulation::get_config_mapped_variable_name(const std::string &output_var_name, const std::shared_ptr& out_module, - const std::shared_ptr& in_module) + const std::shared_ptr& in_module) const { if (!out_module->is_bmi_output_variable(output_var_name)) return output_var_name; @@ -389,20 +382,20 @@ double Bmi_Multi_Formulation::get_response(time_step_t t_index, time_step_t t_de return modules[index]->get_var_value_as_double(0, get_bmi_main_output_var()); } -bool Bmi_Multi_Formulation::is_bmi_input_variable(const std::string &var_name) { +bool Bmi_Multi_Formulation::is_bmi_input_variable(const std::string &var_name) const { return modules[0]->is_bmi_input_variable(var_name); } -bool Bmi_Multi_Formulation::is_bmi_model_time_step_fixed() { +bool Bmi_Multi_Formulation::is_bmi_model_time_step_fixed() const { return std::all_of(modules.cbegin(), modules.cend(), [](const std::shared_ptr& m) { return m->is_bmi_model_time_step_fixed(); }); } -bool Bmi_Multi_Formulation::is_bmi_output_variable(const std::string &var_name) { +bool Bmi_Multi_Formulation::is_bmi_output_variable(const std::string &var_name) const { return modules.back()->is_bmi_output_variable(var_name); } -bool Bmi_Multi_Formulation::is_model_initialized() { +bool Bmi_Multi_Formulation::is_model_initialized() const { return std::all_of(modules.cbegin(), modules.cend(), [](const std::shared_ptr& m) { return m->is_model_initialized(); }); } diff --git a/src/realizations/catchment/Bmi_Py_Formulation.cpp b/src/realizations/catchment/Bmi_Py_Formulation.cpp index 80563f61d7..95f22ac404 100644 --- a/src/realizations/catchment/Bmi_Py_Formulation.cpp +++ b/src/realizations/catchment/Bmi_Py_Formulation.cpp @@ -31,19 +31,19 @@ std::shared_ptr Bmi_Py_Formulation::construct_model(const geojson:: is_bmi_model_time_step_fixed()); } -time_t realization::Bmi_Py_Formulation::convert_model_time(const double &model_time) { +time_t realization::Bmi_Py_Formulation::convert_model_time(const double &model_time) const { return (time_t) (get_bmi_model()->convert_model_time_to_seconds(model_time)); } -const std::vector Bmi_Py_Formulation::get_bmi_input_variables() { +const std::vector Bmi_Py_Formulation::get_bmi_input_variables() const { return get_bmi_model()->GetInputVarNames(); } -const std::vector Bmi_Py_Formulation::get_bmi_output_variables() { +const std::vector Bmi_Py_Formulation::get_bmi_output_variables() const { return get_bmi_model()->GetOutputVarNames(); } -std::string Bmi_Py_Formulation::get_formulation_type() { +std::string Bmi_Py_Formulation::get_formulation_type() const { return "bmi_py"; } @@ -100,17 +100,17 @@ double Bmi_Py_Formulation::get_var_value_as_double(const int &index, const std:: " as double: no logic for converting variable type " + val_type); } -bool Bmi_Py_Formulation::is_bmi_input_variable(const std::string &var_name) { +bool Bmi_Py_Formulation::is_bmi_input_variable(const std::string &var_name) const { const std::vector names = get_bmi_model()->GetInputVarNames(); return std::any_of(names.cbegin(), names.cend(), [var_name](const std::string &s){ return var_name == s; }); } -bool Bmi_Py_Formulation::is_bmi_output_variable(const std::string &var_name) { +bool Bmi_Py_Formulation::is_bmi_output_variable(const std::string &var_name) const { const std::vector names = get_bmi_model()->GetOutputVarNames(); return std::any_of(names.cbegin(), names.cend(), [var_name](const std::string &s){ return var_name == s; }); } -bool Bmi_Py_Formulation::is_model_initialized() { +bool Bmi_Py_Formulation::is_model_initialized() const { return get_bmi_model()->is_model_initialized(); } From ec54fedf8ad1adbe2fdcfdf0dc5737bce3c3f059 Mon Sep 17 00:00:00 2001 From: program-- Date: Wed, 3 Jul 2024 12:11:14 -0700 Subject: [PATCH 6/8] fix(ForcingsEngineDataProvider): remove noexcept specifiers --- include/forcing/ForcingsEngineDataProvider.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/forcing/ForcingsEngineDataProvider.hpp b/include/forcing/ForcingsEngineDataProvider.hpp index 4349126e10..f8a94dadab 100644 --- a/include/forcing/ForcingsEngineDataProvider.hpp +++ b/include/forcing/ForcingsEngineDataProvider.hpp @@ -104,22 +104,22 @@ struct ForcingsEngineDataProvider ~ForcingsEngineDataProvider() override = default; - boost::span get_available_variable_names() const noexcept override + boost::span get_available_variable_names() const override { return var_output_names_; } - long get_data_start_time() const noexcept override + long get_data_start_time() const override { return clock_type::to_time_t(time_begin_); } - long get_data_stop_time() const noexcept override + long get_data_stop_time() const override { return clock_type::to_time_t(time_end_); } - long record_duration() const noexcept override + long record_duration() const override { return std::chrono::duration_cast(time_step_).count(); } From 9a3e45795181c9198d27d5b2f75f8d6beafaddda Mon Sep 17 00:00:00 2001 From: program-- Date: Thu, 18 Jul 2024 11:53:57 -0700 Subject: [PATCH 7/8] tests(Bmi_Multi_Formulation): check get_available_variable_names --- .../catchments/Bmi_Multi_Formulation_Test.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/realizations/catchments/Bmi_Multi_Formulation_Test.cpp b/test/realizations/catchments/Bmi_Multi_Formulation_Test.cpp index 9deb6d8de4..3ea307e6a7 100644 --- a/test/realizations/catchments/Bmi_Multi_Formulation_Test.cpp +++ b/test/realizations/catchments/Bmi_Multi_Formulation_Test.cpp @@ -855,6 +855,35 @@ TEST_F(Bmi_Multi_Formulation_Test, GetIdAndCatchmentId) { #endif //ASSERT_EQ(formulation.get_catchment_id(), "id"); } + +TEST_F(Bmi_Multi_Formulation_Test, GetAvailableVariableNames) { + int ex_index = 1; + + Bmi_Multi_Formulation formulation(catchment_ids[ex_index], std::make_unique(*forcing_params_examples[ex_index]), utils::StreamHandler()); + formulation.create_formulation(config_prop_ptree[ex_index]); + + const auto actual_names = formulation.get_available_variable_names(); + const auto expected_names = { + "OUTPUT_VAR_1__0", + "OUTPUT_VAR_2__0", + "OUTPUT_VAR_3__0", + "FORTRAN_Grid_Var_2__0", + "FORTRAN_Grid_Var_3__0", + "GRID_VAR_4", + "OUTPUT_VAR_1__1", + "OUTPUT_VAR_2__1", + "OUTPUT_VAR_3", + "GRID_VAR_2", + "GRID_VAR_3" + }; + + for (const auto& expected : expected_names) { + EXPECT_NE( + std::find(actual_names.begin(), actual_names.end(), expected), + actual_names.end() + ); + } +} #endif // NGEN_WITH_BMI_C || NGEN_WITH_BMI_FORTRAN || NGEN_WITH_PYTHON #endif // NGEN_BMI_MULTI_FORMULATION_TEST_CPP From c5243e66a0e7b69458aa377186e6c1e5d5af18b4 Mon Sep 17 00:00:00 2001 From: program-- Date: Thu, 18 Jul 2024 13:41:04 -0700 Subject: [PATCH 8/8] refactor(Bmi_Multi_Formulation): initialize available_forcings in initialization func --- src/realizations/catchment/Bmi_Multi_Formulation.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/realizations/catchment/Bmi_Multi_Formulation.cpp b/src/realizations/catchment/Bmi_Multi_Formulation.cpp index 3611adc8da..43f1f9dfeb 100644 --- a/src/realizations/catchment/Bmi_Multi_Formulation.cpp +++ b/src/realizations/catchment/Bmi_Multi_Formulation.cpp @@ -147,6 +147,13 @@ void Bmi_Multi_Formulation::create_multi_formulation(geojson::PropertyMap proper // check if a requested output variable name is valid, if not, stop the execution check_output_var_names(); + + // initialize available_forcings from nested modules + for (const nested_module_ptr &module: modules) { + for (const std::string &out_var_name: module->get_bmi_output_variables()) { + available_forcings.push_back(module->get_config_mapped_variable_name(out_var_name)); + } + } } /**