Program Listing for File Dist_tlapse.cpp

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;

}