
.. _program_listing_file_src_modules_fsm.hpp:

Program Listing for File fsm.hpp
================================

|exhale_lsh| :ref:`Return to documentation for file <file_src_modules_fsm.hpp>` (``src/modules/fsm.hpp``)

.. |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/>.
   //
   
   #pragma once
   
   #include "logger.hpp"
   #include "triangulation.hpp"
   #include "module_base.hpp"
   #include <meteoio/MeteoIO.h>
   #include <string>
   
   extern "C"
   {
       void fsm_allocate();
       void fsm_layers_config(float fvg1, float zsub, int ncnpy, int nsmax, int nsoil);
       void fsm_soilprops_config(float b, float hcap_soil, float hcon_soil, float sathh, float vcrit, float vsat);
       float fsm_constants_e0();
       float fsm_constants_eps();
       float fsm_parameters_rgr0();
       void fsm2_timestep(
       // Driving variables
           float* dt, float* elev, float* zT, float* zU,
           float* LW, float* Ps, float* Qa, float* Rf, float* Sdif, float* Sdir, float* Sf, float* Ta, float* trans, float* Ua,
   
       // Vegetation characteristics
           float* alb0, float* hveg, float* VAI,
   
           float* rhod,
   
       // State variables
           float* albs, float* Tsrf, float* Dsnw, int* Nsnow, float* Qcan, float* Rgrn, float* Sice,
           float* Sliq, float* Sveg, float* Tcan, float* Tsnow, float* Tsoil, float* Tveg, float* Vsmc,
   
       // Diagnostics
           float* H, float* LE, float* LWout, float* LWsub, float* Melt, float* Roff, float* snd, float* snw, float* subl, float* svg,
           float* SWout, float* SWsub, float* Usub, float*  Wflx
           );
   }
   
   class FSM : public module_base
   {
     REGISTER_MODULE_HPP(FSM);
     private:
       static constexpr int SNOW_LAYER_COUNT = 6;
       static constexpr int SOIL_LAYER_COUNT = 4;
       static constexpr int CANOPY_LAYER_COUNT = 2;
   
       struct data : public face_info
       {
           struct
           {
               // Vegetation characteristics
               float alb0 = 0.2;
               float vegh = 0;
               float VAI = 0;
           } veg;
   
           struct
           {
               // State variables
               float albs = 0.8;
               float Tsrf = 263.0; // cold soils
               float Dsnw[SNOW_LAYER_COUNT] = {0, 0, 0, 0, 0, 0}; //Snow layer thicknesses (m)
               int Nsnow = 0; //Number of snow layers
               float Qcan[CANOPY_LAYER_COUNT] = {0, 0}; // Canopy air space humidities
               float Rgrn[SNOW_LAYER_COUNT] = {0, 0, 0, 0, 0, 0}; //Snow layer grain radii (m)
               float Sice[SNOW_LAYER_COUNT] = {0, 0, 0, 0, 0, 0}; // Ice content of snow layers (kg/m^2)
   
               float Sliq[SNOW_LAYER_COUNT] = {0, 0, 0, 0, 0, 0}; // Liquid content of snow layers (kg/m^2)
               float Sveg[CANOPY_LAYER_COUNT] = {0, 0}; //Snow mass on vegetation layers (kg/m^2)
               float Tcan[CANOPY_LAYER_COUNT] = {285, 285}; //Canopy air space temperatures (K)
               float Tsnow[SNOW_LAYER_COUNT] = {263, 263, 263, 263, 263, 263}; //Snow layer temperatures (K)
               float Tsoil[SOIL_LAYER_COUNT] = {263, 263.1, 263.2, 263.3}; //Soil layer temperatures (K); Cold soils
               float Tveg[CANOPY_LAYER_COUNT] = {285, 285}; // Vegetation layer temperatures (K)
   
               float Vsat = 0.27;
   
               // Volumetric moisture content of soil layers
               float Vsmc[SOIL_LAYER_COUNT] = {(float)0.5 * Vsat, (float)0.5 * Vsat, (float)0.5 * Vsat, (float)0.5 * Vsat};
   
           } state;
   
           struct
           {
               // Diagnostics
               float H = -9999; // Sensible heat flux to the atmosphere (W/m^2)
               float LE = -9999; // Latent heat flux to the atmosphere (W/m^2)
               float LWout = -9999; // Outgoing LW radiation (W/m^2)
               float LWsub = -9999; // Subcanopy downward LW radiation (W/m^2)
               float Melt = -9999; // Surface melt rate (kg/m^2/s)
               float Roff = -9999; // Runoff from snow (kg/m^2/s)
   
               float snd = -9999; // Snow depth (m)
               float snw = -9999; // Total snow mass on ground (kg/m^2)
               float subl = -9999; // Sublimation rate (kg/m^2/s)
               float svg = -9999; // Total snow mass on vegetation (kg/m^2)
   
               float SWout = -9999; // Outgoing SW radiation (W/m^2)
               float SWsub = -9999; // Subcanopy downward SW radiation (W/m^2)
               float Usub = -9999; // Subcanopy wind speed (m/s)
               float Wflx[SNOW_LAYER_COUNT] = {-9999, -9999, -9999, -9999, -9999, -9999}; // Water flux into snow layer (kg/m^2/s)
   
               float sum_snowpack_subl = -9999; // cumulative sublimation (kg/m^2)
           } diag;
       };
   
       float constants_e0_ = 0.0f;
       float constants_eps_ = 0.0f;
       float parameters_rgr0_ = 0.0f;
   
     public:
       FSM(config_file cfg);
       ~FSM();
       virtual void run(mesh_elem& face);
       virtual void init(mesh& domain);
       void checkpoint(mesh& domain, netcdf& chkpt);
       void load_checkpoint(mesh& domain, netcdf& chkpt);
   };
