Program Listing for File p_lapse.cpp#
↰ Return to documentation for file (src/modules/interp_met/p_lapse.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 "p_lapse.hpp"
REGISTER_MODULE_CPP(p_lapse);
p_lapse::p_lapse(config_file cfg)
: module_base("p_lapse", parallel::data, cfg)
{
depends_from_met("p");
provides("p");
provides("p_no_slope");
apply_cosine_correction = cfg.get("apply_cosine_correction",false);
SPDLOG_DEBUG("Successfully instantiated module {}",this->ID);
}
void p_lapse::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<p_lapse::data>(ID);
d.interp.init(global_param->interp_algorithm,face->stations().size() );
}
}
void p_lapse::run(mesh_elem& face)
{
// Precipitation lapse rate derived from Marmot Creek stations by Logan Fang (used in CRHM for Marmot Creek domain)
//(100 m)^-1
double monthly_factors[] = {0.1081,0.1081 ,0.1081, 0.0997, 0.0997, 0.0592, 0.0592, 0.0592, 0.0868, 0.0868, 0.1081, 0.1081};
// Precipitation lapse rate derived from stations located in the Upper Bow River basin by Logan Fang :
// Stations Banff VS Sunshine; Station Lake Louise VS Skoki
// (used in CRHM for Marmot Creek domain)
//(100 m)^-1
// double monthly_factors[] = {0.1932,0.1932 ,0.1932, 0.1182, 0.1182, 0.1182, 0.0592, 0.0592, 0.09292, 0.09292, 0.1932, 0.1932};
for(auto& mf: monthly_factors)
{
mf /= 100.0; //to m^-1
}
std::vector< boost::tuple<double, double, double> > ppt;
std::vector< boost::tuple<double, double, double> > staion_z;
for (auto& s : face->stations())
{
if( is_nan((*s)["p"_s]))
continue;
double p = (*s)["p"_s];
ppt.push_back( boost::make_tuple(s->x(), s->y(), p ) );
staion_z.push_back( boost::make_tuple(s->x(), s->y(), s->z() ) );
}
auto query = boost::make_tuple(face->get_x(), face->get_y(), face->get_z());
double p0 = face->get_module_data<data>(ID).interp(ppt, query);
double z0 = face->get_module_data<data>(ID).interp(staion_z,query);
double z = face->get_z();
double slp = face->slope();
int month = global_param->month()-1;
double lapse = monthly_factors[month];
double adj_fac = 1. + lapse*(z-z0);
// Limit the precipitation-elevation adjustment factor in the range 0.5 - 1.5
adj_fac = std::max(0.5,adj_fac);
adj_fac = std::min(1.5,adj_fac);
double P = p0*adj_fac;
double P_fin;
// Correct precipitation input using triangle slope when input preciptation are given for the horizontally projected area.
if(apply_cosine_correction)
{
P_fin = Atmosphere::corr_precip_slope(P,slp);
} else
{
P_fin = P;
}
P_fin = std::max(0.0,P_fin);
(*face)["p"_s]= P_fin;
P = std::max(0.0,P);
(*face)["p_no_slope"_s]= P;
}
p_lapse::~p_lapse()
{
}