Program Listing for File iswr.cpp

Program Listing for File iswr.cpp#

Return to documentation for file (src/modules/iswr.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 "iswr.hpp"
REGISTER_MODULE_CPP(iswr);

iswr::iswr(config_file cfg)
        :module_base("iswr", parallel::data, cfg)
{

    depends("iswr_diffuse_no_slope");
    depends("iswr_direct_no_slope");

    depends("solar_el");
    depends("solar_az");


    provides("iswr");
    provides("iswr_direct");
    provides("iswr_diffuse");

    provides("solar_angle");

    optional("shadow");

    SPDLOG_DEBUG("Successfully instantiated module {}",this->ID);

    assume_no_slope = cfg.get("no_slope",false);
    already_cosine_corrected = cfg.get("already_cosine_corrected",false);


}
void iswr::run(mesh_elem& face)
{

    if(global_param->is_point_mode() && !already_cosine_corrected)
    {
        SPDLOG_ERROR("Most observations implicitly have a cosine-correction built in by virtu of the flat-plane observation. "
                     "When using point-mode, you probably want to set -c config.iswr.already_cosine_corrected:true");
    }

    double A = (*face)["solar_az"_s] * mio::Cst::to_rad;
    double E = (*face)["solar_el"_s] * mio::Cst::to_rad;

    //radiation data
    //solar vector
    //xyz cartesian
    arma::vec S ={ cos(E) * sin(A), cos(E) * cos(A), sin(E)};

    arma::vec N;
    if (assume_no_slope)
    {

        N ={0, 0, 1};
    }
    else
    {
        Vector_3 n = face->normal();


        N = {n[0],  n[1], n[2]};
    }


    double angle = acos(arma::dot(S,N));
    angle = cos(angle);

    if(angle < 0.0 || E < 0.0523598776) //3deg -> rad
        angle = 0.0;

    (*face)["solar_angle"_s]=angle;

    //if we have remote shadowing
    if(has_optional("shadow"))
    {
        if((*face)["shadow"_s] == 1)
        {
            angle = 0;
        }
    }

    double direct_beam = (*face)["iswr_direct_no_slope"_s];

    //If we're using obs at a point, this should be set to true
    if(already_cosine_corrected)
    {
        direct_beam = direct_beam / sin(E);
    }

    double swr =  angle * direct_beam;
    double diff = (*face)["iswr_diffuse_no_slope"_s];

    swr = std::max(0.0, swr);
    diff = std::max(0.0,diff);

    (*face)["iswr_direct"_s]=swr ;
    (*face)["iswr_diffuse"_s]=diff ;
    (*face)["iswr"_s]= swr + diff ;

}

iswr::~iswr()
{


}