
.. _program_listing_file_src_modules_fast_shadow.cpp:

Program Listing for File fast_shadow.cpp
========================================

|exhale_lsh| :ref:`Return to documentation for file <file_src_modules_fast_shadow.cpp>` (``src/modules/fast_shadow.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 "fast_shadow.hpp"
   REGISTER_MODULE_CPP(fast_shadow);
   
   fast_shadow::fast_shadow(config_file cfg)
           : module_base("fast_shadow", parallel::data, cfg)
   {
       depends("solar_az");
       depends("solar_el");
       provides("shadow");
   
       //number of steps along the search vector to check for a higher point
       steps = cfg.get("steps",10);
       //max distance to search
       max_distance = cfg.get("max_distance",1000.0);
   
       //size of the step to take
       size_of_step = max_distance / steps;
   }
   
   fast_shadow::~fast_shadow()
   {
   
   
   }
   
   void fast_shadow::run(mesh_elem& face)
   {
   
       double solar_el = (*face)["solar_el"_s] *M_PI / 180.;
   
       (*face)["shadow"_s]= 0;
       //bail early
       if (solar_el < 0)
           return;
   
       double solar_az = (*face)["solar_az"_s] ;
   
       Point_3 me = face->center();
   
       double phi = 0.;
       // search along each azimuth in j step increments to find horizon angle
       for (int j = 1; j <= steps; ++j)
       {
           double distance = j * size_of_step;
   
           auto f = face->find_closest_face(solar_az, distance);
   
           double z_diff = f->center().z() - me.z() ;
           if (z_diff > 0)
           {
               double dist = math::gis::distance(f->center(), me);
               phi = std::max(atan(z_diff / dist), phi);
           }
           //try to bail early if possible
           if (phi > solar_el )
           {
               (*face)["shadow"_s]= 1;
           }
       }
       //try to bail early if possible
       if (phi > solar_el )
       {
           (*face)["shadow"_s]= 1;
       }
   
   
   
   }
