Skip to content

Commit

Permalink
Adapt to updated SCHISM BMI implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilMiller committed Dec 2, 2024
1 parent 8eca58c commit 86a5271
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
10 changes: 6 additions & 4 deletions include/realizations/coastal/SchismFormulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,17 @@ class SchismFormulation final : public CoastalFormulation

void get_values(const selection_type& selector, boost::span<data_type> data) override;

// Visible only for testing use
enum ForcingSelector { METEO, OFFSHORE, LAND };
struct InputMapping { ForcingSelector selector; std::string name; };
static std::map<std::string, InputMapping> expected_input_variables_;

protected:
size_t mesh_size(std::string const& variable_name) override;

private:
std::unique_ptr<models::bmi::Bmi_Fortran_Adapter> bmi_;

enum ForcingSelector { METEO, OFFSHORE, INFLOW };
struct InputMapping { ForcingSelector selector; std::string name; };
static std::map<std::string, InputMapping> expected_input_variables_;
std::map<std::string, std::string> input_variable_units_;
std::map<std::string, std::string> input_variable_type_;
std::map<std::string, size_t> input_variable_count_;
Expand All @@ -76,7 +78,7 @@ class SchismFormulation final : public CoastalFormulation
std::shared_ptr<ProviderType> offshore_boundary_provider_;
std::shared_ptr<ProviderType> inflows_boundary_provider_;

void set_inputs();
void set_inputs(int timestep_offset);
};

#endif // NGEN_WITH_BMI_FORTRAN && NGEN_WITH_MPI
26 changes: 15 additions & 11 deletions src/realizations/coastal/SchismFormulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ std::map<std::string, SchismFormulation::InputMapping> SchismFormulation::expect
// ETA2_bnd - water surface elevation at the boundaries
{"ETA2_bnd", { SchismFormulation::OFFSHORE, "ETA2_bnd"}},
// Q_bnd - flows at boundaries
{"Q_bnd", { SchismFormulation::INFLOW, "Q_bnd"}},
{"Q_bnd_source", { SchismFormulation::LAND, "Q_bnd_source"}},
// Q_bnd - flows at boundaries
{"Q_bnd_sink", { SchismFormulation::LAND, "Q_bnd_sink"}},
};

std::vector<std::string> SchismFormulation::exported_output_variable_names_ =
Expand Down Expand Up @@ -68,14 +70,15 @@ void SchismFormulation::initialize()
{
auto const& input_vars = bmi_->GetInputVarNames();

for (auto const& name : input_vars) {
for (auto const& full_name : input_vars) {
auto name = full_name.substr(0, full_name.size()-3); // Chop off _t0/_t1 suffixes
if (expected_input_variables_.find(name) == expected_input_variables_.end()) {
throw std::runtime_error("SCHISM instance requests unexpected input variable '" + name + "'");
}

input_variable_units_[name] = bmi_->GetVarUnits(name);
input_variable_type_[name] = bmi_->GetVarType(name);
input_variable_count_[name] = mesh_size(name);
input_variable_units_[name] = bmi_->GetVarUnits(name + "_t0");
input_variable_type_[name] = bmi_->GetVarType(name + "_t0");
input_variable_count_[name] = mesh_size(name + "_t0");
}

auto const& output_vars = bmi_->GetOutputVarNames();
Expand All @@ -92,7 +95,7 @@ void SchismFormulation::initialize()

time_step_length_ = std::chrono::seconds((long long)bmi_->GetTimeStep());

set_inputs();
set_inputs(0);
}

void SchismFormulation::finalize()
Expand All @@ -104,7 +107,7 @@ void SchismFormulation::finalize()
bmi_->Finalize();
}

void SchismFormulation::set_inputs()
void SchismFormulation::set_inputs(int timestep_offset)
{
for (auto var : expected_input_variables_) {
auto const& name = var.first;
Expand All @@ -117,20 +120,21 @@ void SchismFormulation::set_inputs()
switch(selector) {
case METEO: return meteorological_forcings_provider_.get();
case OFFSHORE: return offshore_boundary_provider_.get();
case INFLOW: return inflows_boundary_provider_.get();
case LAND: return inflows_boundary_provider_.get();
default: throw std::runtime_error("Unknown SCHISM provider selector type");
}
}();
std::vector<double> buffer(mesh_size(name));
auto offset_name = name + "_t" + std::to_string(timestep_offset);
std::vector<double> buffer(mesh_size(offset_name));
provider->get_values(points, buffer);
bmi_->SetValue(name, buffer.data());
bmi_->SetValue(offset_name, buffer.data());
}
}

void SchismFormulation::update()
{
current_time_ += time_step_length_;
set_inputs();
set_inputs(1);
bmi_->Update();
}

Expand Down
29 changes: 18 additions & 11 deletions test/coastal/SchismFormulation_Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
#include <utilities/parallel_utils.h>

#include "realizations/coastal/SchismFormulation.hpp"
#include <cmath>
#include <limits>
#include <iostream>
#include <NetCDFMeshPointsDataProvider.hpp>

const static std::string library_path = "/Users/phil/Code/noaa/BUILD/bmischism_2024-08-19-ngen/libtestbmifortranmodel.dylib";
const static std::string init_config_path = "/Users/phil/Code/noaa/SCHISM_Lake_Champlain_BMI_test/namelist.input";
const static std::string met_forcing_netcdf_path = "/Users/phil/Code/noaa/NextGen_Forcings_Engine_SCHISM_Lake_Champlain_2015120100.nc";
const static std::string library_path = "/Users/phil/Code/noaa/BUILD/bmischism_2024-09-27-ngen/libtestbmifortranmodel.dylib";
const static std::string init_config_path = "/Users/phil/Code/noaa/SCHISM_Lake_Champlain_driver_test/namelist.input";
const static std::string met_forcing_netcdf_path = "/Users/phil/Code/noaa/SCHISM_Lake_Champlain_BMI_test/NextGen_Forcings_Engine_MESH_output_201104302300.nc";

#if 0
struct Schism_Formulation_IT : public ::testing::Test
Expand Down Expand Up @@ -37,6 +38,10 @@ std::map<std::string, double> input_variables_defaults =
{"ETA2_bnd", 30},
// Q_bnd - flows at boundaries
{"Q_bnd", 0.1},
// Q_bnd - flows at boundaries
{"Q_bnd_source", 0.1},
// Q_bnd - flows at boundaries
{"Q_bnd_sink", 0.1},
};

struct MockProvider : data_access::DataProvider<double, MeshPointsSelector>
Expand Down Expand Up @@ -76,15 +81,15 @@ int main(int argc, char **argv)
auto provider = std::make_shared<MockProvider>();

std::tm start_time_tm{};
start_time_tm.tm_year = 2015 - 1900;
start_time_tm.tm_mon = 12 - 1;
start_time_tm.tm_mday = 1;
start_time_tm.tm_year = 2011 - 1900;
start_time_tm.tm_mon = 5 - 1;
start_time_tm.tm_mday = 2;
auto start_time_t = std::mktime(&start_time_tm);

std::tm stop_time_tm{};
stop_time_tm.tm_year = 2015 - 1900;
stop_time_tm.tm_mon = 12 - 1;
stop_time_tm.tm_mday = 2;
stop_time_tm.tm_year = 2011 - 1900;
stop_time_tm.tm_mon = 5 - 1;
stop_time_tm.tm_mday = 3;
auto stop_time_t = std::mktime(&stop_time_tm);

auto netcdf_met_provider = std::make_shared<data_access::NetCDFMeshPointsDataProvider>(met_forcing_netcdf_path,
Expand All @@ -101,8 +106,10 @@ int main(int argc, char **argv)

schism->initialize();

for (int i = 0; i < 3; ++i)
for (int i = 0; i < 3; ++i) {
std::cout << "Step " << i << std::endl;
schism->update();
}

using namespace std::chrono_literals;

Expand All @@ -118,7 +125,7 @@ int main(int argc, char **argv)
min = std::min(val, min);
max = std::max(val, max);
}
std::cout << name << " ranges from " << min << " to " << max << std::endl;
std::cout << name << " with " << data.size() << " entries ranges from " << min << " to " << max << std::endl;
};

std::vector<double> bedlevel(278784, std::numeric_limits<double>::quiet_NaN());
Expand Down

0 comments on commit 86a5271

Please sign in to comment.