
.. _program_listing_file_src_modules_iswr.cpp:

Program Listing for File iswr.cpp
=================================

|exhale_lsh| :ref:`Return to documentation for file <file_src_modules_iswr.cpp>` (``src/modules/iswr.cpp``)

.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS

.. code-block:: 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()
   {
   
   
   }
