Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null/Constant Forcing Provider #601

Merged
merged 11 commits into from
Sep 21, 2023
96 changes: 96 additions & 0 deletions data/example_bmi_multi_realization_config_w_nfp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"global": {
"formulations": [
{
"name": "bmi_multi",
"params": {
"model_type_name": "bmi_multi_noahowp_cfe",
"forcing_file": "",
"init_config": "",
"allow_exceed_end_time": true,
"main_output_variable": "Q_OUT",
"modules": [
{
"name": "bmi_c++",
"params": {
"model_type_name": "bmi_c++_sloth",
"library_file": "./extern/sloth/cmake_build/libslothmodel.so",
"init_config": "/dev/null",
"allow_exceed_end_time": true,
"main_output_variable": "z",
"uses_forcing_file": false,
"model_params": {
"ice_fraction_schaake(1,double,m,node)": 0.0,
"ice_fraction_xinan(1,double,1,node)": 0.0,
"soil_moisture_profile(1,double,1,node)": 0.0,
"land_surface_air__temperature(1,double,K,node)": 285.8000183105469,
"atmosphere_water__liquid_equivalent_precipitation_rate(1,double,mm/s,node)": 0.1,
"atmosphere_air_water~vapor__relative_saturation(1,double,1,node)": 0.00930000003427267,
"land_surface_wind__x_component_of_velocity(1,double,m/s,node)": -2.299999952316284,
"land_surface_wind__y_component_of_velocity(1,double,m/s,node)": 0.10000000149011612,
"land_surface_air__pressure(1,double,Pa,node)": 100310.0,
"land_surface_radiation~incoming~shortwave__energy_flux(1,double,W/m2,node)": 0.0,
"land_surface_radiation~incoming~longwave__energy_flux(1,double,W/m2,node)": 361.3000183105469
}
}
},
{
"name": "bmi_fortran",
"params": {
"model_type_name": "bmi_fortran_noahowp",
"library_file": "./extern/noah-owp-modular/cmake_build/libsurfacebmi.so",
"forcing_file": "",
"init_config": "./data/bmi/fortran/noah-owp-modular-init-{{id}}.namelist.input",
"allow_exceed_end_time": true,
"main_output_variable": "QINSUR",
"variables_names_map": {
"PRCPNONC": "atmosphere_water__liquid_equivalent_precipitation_rate",
"Q2": "atmosphere_air_water~vapor__relative_saturation",
"SFCTMP": "land_surface_air__temperature",
"UU": "land_surface_wind__x_component_of_velocity",
"VV": "land_surface_wind__y_component_of_velocity",
"LWDN": "land_surface_radiation~incoming~longwave__energy_flux",
"SOLDN": "land_surface_radiation~incoming~shortwave__energy_flux",
"SFCPRS": "land_surface_air__pressure"
},
"uses_forcing_file": false
}
},
{
"name": "bmi_c",
"params": {
"model_type_name": "bmi_c_cfe",
"library_file": "./extern/cfe/cmake_build/libcfebmi.so",
"forcing_file": "",
"init_config": "./data/bmi/c/cfe/{{id}}_bmi_config.ini",
"allow_exceed_end_time": true,
"main_output_variable": "Q_OUT",
"registration_function": "register_bmi_cfe",
"variables_names_map": {
"water_potential_evaporation_flux": "ETRAN",
"atmosphere_air_water~vapor__relative_saturation": "SPFH_2maboveground",
"land_surface_air__temperature": "TMP_2maboveground",
"land_surface_wind__x_component_of_velocity": "UGRD_10maboveground",
"land_surface_wind__y_component_of_velocity": "VGRD_10maboveground",
"land_surface_radiation~incoming~longwave__energy_flux": "DLWRF_surface",
"land_surface_radiation~incoming~shortwave__energy_flux": "DSWRF_surface",
"land_surface_air__pressure": "PRES_surface"
},
"uses_forcing_file": false
}
}
],
"uses_forcing_file": false
}
}
],
"forcing": {
"provider": "NullForcingProvider"
}
},
"time": {
"start_time": "2015-12-01 00:00:00",
"end_time": "2015-12-30 23:00:00",
"output_interval": 3600
}
}
61 changes: 61 additions & 0 deletions include/forcing/NullForcingProvider.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef NGEN_NULLFORCING_H
#define NGEN_NULLFORCING_H

#include <vector>
PhilMiller marked this conversation as resolved.
Show resolved Hide resolved
#include <string>
#include <stdexcept>
#include <limits>
#include "GenericDataProvider.hpp"

/**
* @brief Forcing class that returns no variables to the simulation--use this e.g. if a BMI model provides forcing data.
*/
class NullForcingProvider : public data_access::GenericDataProvider
{
public:

NullForcingProvider(){}

// BEGIN DataProvider interface methods

long get_data_start_time() override {
return 0;
}

long get_data_stop_time() override {
return LONG_MAX;
}

long record_duration() override {
return 1;
}

size_t get_ts_index_for_time(const time_t &epoch_time) override {
return 0;
}

double get_value(const CatchmentAggrDataSelector& selector, data_access::ReSampleMethod m) override
{
throw std::runtime_error("Called get_value function in NullDataProvider");
}

virtual std::vector<double> get_values(const CatchmentAggrDataSelector& selector, data_access::ReSampleMethod m) override
{
throw std::runtime_error("Called get_values function in NullDataProvider");
}

inline bool is_property_sum_over_time_step(const std::string& name) override {
throw std::runtime_error("Got request for variable " + name + " but no such variable is provided by NullForcingProvider." + SOURCE_LOC);
}

const std::vector<std::string> &get_available_variable_names() override {
PhilMiller marked this conversation as resolved.
Show resolved Hide resolved
return available_forcings;
}

private:

std::vector<std::string> available_forcings;

};

#endif // NGEN_NULLFORCING_H
19 changes: 3 additions & 16 deletions include/realizations/catchment/Bmi_Multi_Formulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,24 +277,11 @@ namespace realization {
*/
//time_t get_forcing_output_time_end(const std::string &forcing_name) {
time_t get_variable_time_end(const std::string &variable_name) {
// If not found ...
// when unspecified, assume all data is available for the same range.
// If no var_name, use forcing ...
std::string var_name = variable_name;
if(var_name == "*" || var_name == ""){
// when unspecified, assume all data is available for the same range.
// Find one that successfully returns...
for(std::map<std::string,std::shared_ptr<data_access::GenericDataProvider>>::iterator 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]->get_data_stop_time();
return rv;
}
catch (...){
continue;
}
break;
}
return forcing->get_data_stop_time();
}
// If not found ...
if (availableData.empty() || availableData.find(var_name) == availableData.end()) {
Expand Down
4 changes: 4 additions & 0 deletions include/realizations/catchment/Formulation_Constructors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Bmi_Py_Formulation.hpp"
#include <GenericDataProvider.hpp>
#include "CsvPerFeatureForcingProvider.hpp"
#include "NullForcingProvider.hpp"
#ifdef NETCDF_ACTIVE
#include "NetCDFPerFeatureDataProvider.hpp"
#endif
Expand Down Expand Up @@ -64,6 +65,9 @@ namespace realization {
fp = data_access::NetCDFPerFeatureDataProvider::get_shared_provider(forcing_config.path, forcing_config.simulation_start_t, forcing_config.simulation_end_t, output_stream);
}
#endif
else if (forcing_config.provider == "NullForcingProvider"){
fp = std::make_shared<NullForcingProvider>();
}
else { // Some unknown string in the provider field?
throw std::runtime_error(
"Invalid formulation forcing provider configuration! identifier: \"" + identifier +
Expand Down
5 changes: 4 additions & 1 deletion include/realizations/catchment/Formulation_Manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,10 @@ namespace realization {
}

forcing_params get_forcing_params(geojson::PropertyMap &forcing_prop_map, std::string identifier, simulation_time_params &simulation_time_config) {
std::string path = forcing_prop_map.at("path").as_string();
std::string path = "";
if(forcing_prop_map.count("path") != 0){
path = forcing_prop_map.at("path").as_string();
}
std::string provider = "";
if(forcing_prop_map.count("provider") != 0){
provider = forcing_prop_map.at("provider").as_string();
Expand Down