Program Listing for File Dist_tlapse.cpp#
↰ Return to documentation for file (src/modules/interp_met/Dist_tlapse.cpp)
//
// Canadian Hydrological Model - The Canadian Hydrological Model (CHM) is a novel
// modular unstructured mesh based approach for hydrological modelling
// Copyright (C) 2018 Christopher Marsh
//
// This file is part of Canadian Hydrological Model.
//
// Canadian Hydrological Model is free software: you can redistribute it and/or
// modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Canadian Hydrological Model is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Canadian Hydrological Model. If not, see
// <http://www.gnu.org/licenses/>.
//
#include "Dist_tlapse.hpp"
REGISTER_MODULE_CPP(Dist_tlapse);
Dist_tlapse::Dist_tlapse(config_file cfg)
: module_base("Dist_tlapse", parallel::data, cfg)
{
provides("t");
provides("t_lapse_rate");
depends_from_met("t");
depends_from_met("t_lapse_rate");
SPDLOG_DEBUG("Successfully instantiated module {}",this->ID);
}
Dist_tlapse::~Dist_tlapse()
{
}
void Dist_tlapse::init(mesh& domain)
{
#pragma omp parallel for
for (size_t i = 0; i < domain->size_local_faces(); i++)
{
auto face = domain->face(i);
auto& d = face->make_module_data<data>(ID);
d.interp.init(global_param->interp_algorithm,face->stations().size() );
}
}
void Dist_tlapse::run(mesh_elem& face)
{
// Distributed forcing lapse_rate to each face (changes per time step)
std::vector< boost::tuple<double, double, double> > t_lapse_rate_values;
for (auto& s : face->stations())
{
if( is_nan((*s)["t_lapse_rate"_s]))
continue;
double v = (*s)["t_lapse_rate"_s];
if (is_nan(v))
CHM_THROW_EXCEPTION(module_error, "Nan in " + ID);
t_lapse_rate_values.push_back( boost::make_tuple(s->x(), s->y(), v ) );
}
auto query = boost::make_tuple(face->get_x(), face->get_y(), face->get_z());
double lapse_rate = face->get_module_data<data>(ID).interp(t_lapse_rate_values, query);
//lower all the station values to sea level prior to the interpolation
std::vector< boost::tuple<double, double, double> > lowered_values;
for (auto& s : face->stations())
{
if( is_nan((*s)["t"_s]))
continue;
double v = (*s)["t"_s] - lapse_rate * (0.0 - s->z());
if (is_nan(v))
CHM_THROW_EXCEPTION(module_error, "Nan in " + ID);
lowered_values.push_back( boost::make_tuple(s->x(), s->y(), v ) );
}
double value = face->get_module_data<data>(ID).interp(lowered_values, query);
//raise value back up to the face's elevation from sea level
value = value + lapse_rate * (0.0 - face->get_z());
(*face)["t"_s]=value;
(*face)["t_lapse_rate"_s]=lapse_rate;
}