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

Test domain layer implementation #882

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions data/example_domainlayer_multilayer_realization_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
{
"global": {
"formulations": [
{
"name": "bmi_c++",
"params": {
"model_type_name": "test_bmi_cpp",
"library_file": "./extern/test_bmi_cpp/cmake_build/libtestbmicppmodel.so",
"init_config": "./data/bmi/c/test/test_bmi_c_config.ini",
"main_output_variable": "OUTPUT_VAR_2",
"variables_names_map" : {
"INPUT_VAR_2": "TMP_2maboveground",
"INPUT_VAR_1": "precip_rate"
},
"create_function": "bmi_model_create",
"destroy_function": "bmi_model_destroy",
"uses_forcing_file": false
}
}
],
"forcing": {
"file_pattern": ".*{{id}}.*.csv",
"path": "./data/forcing/"
}
},
"time": {
"start_time": "2015-12-01 00:00:00",
"end_time": "2015-12-30 23:00:00",
"output_interval": 3600
},
"layers": {
"cat-27": {
"formulations": [
{
"name": "bmi_fortran",
"params": {
"model_type_name": "bmi_fortran_noahowp",
"library_file": "./extern/noah-owp-modular/cmake_build/libsurfacebmi",
"forcing_file": "",
"init_config": "./data/bmi/fortran/noah-owp-modular-init-cat-27.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
}
}
],
"forcing": {
"path": "./data/forcing/cat-27_2015-12-01 00_00_00_2015-12-30 23_00_00.csv"
},
"layer_name": "domain_layer",
"time_step_units": "s",
"id": 1,
"time_step": 3600,
"domain": "catchments"
},
"cat-52": {
"formulations": [
{
"name": "bmi_c++",
"params": {
"model_type_name": "test_bmi_cpp",
"library_file": "./extern/test_bmi_cpp/cmake_build/libtestbmicppmodel.so",
"init_config": "./data/bmi/c/test/test_bmi_c_config.ini",
"main_output_variable": "OUTPUT_VAR_2",
"variables_names_map" : {
"INPUT_VAR_2": "TMP_2maboveground",
"INPUT_VAR_1": "precip_rate"
},
"create_function": "bmi_model_create",
"destroy_function": "bmi_model_destroy",
"uses_forcing_file": false
}
}
],
"forcing": {
"path": "./data/forcing/cat-52_2015-12-01 00_00_00_2015-12-30 23_00_00.csv"
},
"layer_name": "domain_layer",
"time_step_units": "s",
"id": 2,
"time_step": 3600,
"domain": "catchments"
},
"cat-67": {
"formulations": [
{
"name": "bmi_c++",
"params": {
"model_type_name": "test_bmi_cpp",
"library_file": "./extern/test_bmi_cpp/cmake_build/libtestbmicppmodel.so",
"init_config": "./data/bmi/c/test/test_bmi_c_config.ini",
"main_output_variable": "OUTPUT_VAR_2",
"variables_names_map" : {
"INPUT_VAR_2": "TMP_2maboveground",
"INPUT_VAR_1": "precip_rate"
},
"create_function": "bmi_model_create",
"destroy_function": "bmi_model_destroy",
"uses_forcing_file": false
}
}
],
"forcing": {
"path": "./data/forcing/cat-67_2015-12-01 00_00_00_2015-12-30 23_00_00.csv"
},
"layer_name": "domain_layer",
"time_step_units": "s",
"id": 3,
"time_step": 3600,
"domain": "catchments"
},
"agg-1": {
"formulations": [
{
"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-agg-1.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
}
}
],
"forcing": {
"path": "./data/forcing/agg-1_2015-12-01 00_00_00_2015-12-30 23_00_00.csv"
},
"layer_name": "domain_layer",
"time_step_units": "s",
"id": 4,
"time_step": 3600,
"domain": "catchments"
}
}
}
125 changes: 125 additions & 0 deletions data/example_domainlayer_realization_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
{
"global": {
"formulations": [
{
"name": "bmi_c++",
"params": {
"model_type_name": "test_bmi_cpp",
"library_file": "./extern/test_bmi_cpp/cmake_build/libtestbmicppmodel.so",
"init_config": "./data/bmi/c/test/test_bmi_c_config.ini",
"main_output_variable": "OUTPUT_VAR_2",
"variables_names_map" : {
"INPUT_VAR_2": "TMP_2maboveground",
"INPUT_VAR_1": "precip_rate"
},
"create_function": "bmi_model_create",
"destroy_function": "bmi_model_destroy",
"uses_forcing_file": false
}
}
],
"forcing": {
"file_pattern": ".*{{id}}.*.csv",
"path": "./data/forcing/"
}
},
"time": {
"start_time": "2015-12-01 00:00:00",
"end_time": "2015-12-30 23:00:00",
"output_interval": 3600
},
"layers": {
"cat-27": {
"formulations": [
{
"name": "bmi_fortran",
"params": {
"model_type_name": "bmi_fortran_noahowp",
"library_file": "./extern/noah-owp-modular/cmake_build/libsurfacebmi",
"forcing_file": "",
"init_config": "./data/bmi/fortran/noah-owp-modular-init-cat-27.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"
},
"create_function": "bmi_model_create",
"destroy_function": "bmi_model_destroy",
"uses_forcing_file": false
}
}
],
"forcing": {
"path": "./data/forcing/cat-27_2015-12-01 00_00_00_2015-12-30 23_00_00.csv"
},
"layer_name": "domain_layer",
"time_step_units": "s",
"id": 1,
"time_step": 3600,
"domain": "catchments"
},
"cat-52": {
"formulations": [
{
"name": "bmi_c++",
"params": {
"model_type_name": "test_bmi_cpp",
"library_file": "./extern/test_bmi_cpp/cmake_build/libtestbmicppmodel.so",
"init_config": "./data/bmi/c/test/test_bmi_c_config.ini",
"main_output_variable": "OUTPUT_VAR_2",
"variables_names_map" : {
"INPUT_VAR_2": "TMP_2maboveground",
"INPUT_VAR_1": "precip_rate"
},
"create_function": "bmi_model_create",
"destroy_function": "bmi_model_destroy",
"uses_forcing_file": false
}
}
],
"forcing": {
"path": "./data/forcing/cat-52_2015-12-01 00_00_00_2015-12-30 23_00_00.csv"
},
"layer_name": "domain_layer",
"time_step_units": "s",
"id": 2,
"time_step": 3600,
"domain": "catchments"
},
"cat-67": {
"formulations": [
{
"name": "bmi_c++",
"params": {
"model_type_name": "test_bmi_cpp",
"library_file": "./extern/test_bmi_cpp/cmake_build/libtestbmicppmodel.so",
"init_config": "./data/bmi/c/test/test_bmi_c_config.ini",
"main_output_variable": "OUTPUT_VAR_2",
"variables_names_map" : {
"INPUT_VAR_2": "TMP_2maboveground",
"INPUT_VAR_1": "precip_rate"
},
"create_function": "bmi_model_create",
"destroy_function": "bmi_model_destroy",
"uses_forcing_file": false
}
}
],
"forcing": {
"path": "./data/forcing/cat-67_2015-12-01 00_00_00_2015-12-30 23_00_00.csv"
},
"layer_name": "domain_layer",
"time_step_units": "s",
"id": 3,
"time_step": 3600,
"domain": "catchments"
}
}
}
4 changes: 2 additions & 2 deletions include/realizations/config/layer.hpp
Original file line number Diff line number Diff line change
@@ -29,8 +29,8 @@ namespace realization{
*/
Layer(const boost::property_tree::ptree& tree):formulation(tree){
std::vector<std::string> missing_keys;
auto name = tree.get_optional<std::string>("name");
if(!name) missing_keys.push_back("name");
auto name = tree.get_optional<std::string>("layer_name");
if(!name) missing_keys.push_back("layer_name");
auto unit = tree.get<std::string>("time_step_units", "s");

auto id = tree.get_optional<int>("id");
2 changes: 1 addition & 1 deletion src/NGen.cpp
Original file line number Diff line number Diff line change
@@ -534,7 +534,7 @@ int main(int argc, char *argv[]) {
// only advance if you would not pass the master next time and the previous layer next time
if ( layer_next_time <= next_time && layer_next_time <= prev_layer_time)
{
if(count%100==0) std::cout<<"Updating layer: "<<layer->get_name()<<"\n";
if(count%100==0) std::cout<<"Running timestep " <<count<<", Updating layer: "<<layer->get_name()<<"\n";
layer->update_models(); //assume update_models() calls time->advance_timestep()
prev_layer_time = layer_next_time;
}
15 changes: 15 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -294,6 +294,21 @@ ngen_add_test(
NGEN_WITH_BMI_FORTRAN
)

########################## DomainLayer Tests
ngen_add_test(
test_domainlayer
OBJECTS
core/multilayer/DomainLayerTest.cpp
LIBRARIES
NGen::core
NGen::geojson
NGen::realizations_catchment
NGen::core_mediator
NGen::forcing
REQUIRES
NGEN_WITH_NETCDF
NGEN_WITH_BMI_FORTRAN
)

########################## BMI C++ Tests
ngen_add_test(
104 changes: 104 additions & 0 deletions test/core/multilayer/DomainLayerTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include "gtest/gtest.h"
#include "FileChecker.h"
#include <Formulation_Manager.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/range/algorithm/sort.hpp>
#include "DomainLayer.hpp"
#include "Layer.hpp"

class DomainLayerTest : public ::testing::Test {

static std::string find_file(std::vector<std::string> dir_opts, const std::string& basename) {
std::vector<std::string> file_opts(dir_opts.size());
for (int i = 0; i < dir_opts.size(); ++i)
file_opts[i] = dir_opts[i] + basename;
return utils::FileChecker::find_first_readable(file_opts);
}
protected:

std::vector<std::string> path_options = {
"",
"../",
"../../",
"./test/",
"../test/",
"../../test/"
};

DomainLayerTest()
{
nexus_data_path = find_file(path_options, "./data/nexus_data.geojson");
catchment_data_path = find_file(path_options, "./data/catchment_data.geojson");
realization_config_path = find_file(path_options, "./data/example_domainlayer_realization_config.json");
}

~DomainLayerTest() override {

}

void SetUp() override {
nexus_collection = geojson::read(nexus_data_path.c_str());
catchment_collection = geojson::read(catchment_data_path.c_str());

// add the catchments to the nexus collection
for(auto& feature: *catchment_collection)
{
nexus_collection->add_feature(feature);
}
}

void TearDown() override {

}

geojson::GeoJSON nexus_collection;
geojson::GeoJSON catchment_collection;
std::shared_ptr<realization::Formulation_Manager> manager;

std::string nexus_data_path;
std::string catchment_data_path;
std::string realization_config_path;

};

TEST_F(DomainLayerTest, TestInit0)
{
manager = std::make_shared<realization::Formulation_Manager>(realization_config_path.c_str());

ASSERT_TRUE(true);
}

TEST_F(DomainLayerTest, TestRead0)
{
manager = std::make_shared<realization::Formulation_Manager>(realization_config_path.c_str());
manager->read(catchment_collection, utils::getStdOut());

// check domain layer description struct is parsed correctly
ngen::LayerDataStorage& layer_meta_data = manager->get_layer_metadata();
std::vector<int>& keys = layer_meta_data.get_keys();
std::vector<double> time_steps;
for(int i = 0; i < keys.size(); ++i)
{
auto& m_data = layer_meta_data.get_layer(keys[i]);
double c_value = UnitsHelper::get_converted_value(m_data.time_step_units,m_data.time_step,"s");
time_steps.push_back(c_value);
}
//boost::range::sort(keys, std::greater<int>());
boost::range::sort(keys);
std::vector<std::shared_ptr<ngen::Layer> > layers;
layers.resize(keys.size());

for(long i = 0; i < keys.size(); ++i)
{
auto desc = layer_meta_data.get_layer(keys[i]);
if (i == 0) {
ASSERT_EQ(desc.name, "surface layer");
} else {
ASSERT_EQ(desc.name, "domain_layer");
}
ASSERT_EQ(desc.time_step_units, "s");
ASSERT_EQ(desc.id, i);
ASSERT_EQ(desc.time_step, 3600);
}

}