Program Listing for File Gray_inf.cpp

Program Listing for File Gray_inf.cpp#

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

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

    depends("swe");
    depends("snowmelt_int");

    provides("inf");
    provides("total_inf");
    provides("total_excess");
    provides("runoff");
    provides("soil_storage");
    provides("potential_inf");
    provides("opportunity_time");
    provides("available_storage");

}

Gray_inf::~Gray_inf()
{

}

void Gray_inf::init(mesh& domain)
{

    //store all of snobals global variables from this timestep to be used as ICs for the next timestep
#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<Gray_inf::data>(ID);

        d.soil_depth = 400;
        d.porosity = .4;
        d.max_storage =  d.soil_depth * d.porosity;
        //        d.storage =  d.max_storage  - (1 - d.max_storage * face->parameter("sm"_s)/100.);
        d.storage =  d.max_storage * face->parameter("sm"_s)/100.;

        d.last_ts_potential_inf = 0;
        d.opportunity_time=0.;
        d.total_inf = 0.;
        d.total_excess = 0.;
    }
}
void Gray_inf::run(mesh_elem &face)
{
    if(is_water(face))
    {
        set_all_nan_on_skip(face);
        return;
    }


    auto& d = face->get_module_data<Gray_inf::data>(ID);

    auto id = face->cell_local_id;
    double C = 2.;
    double S0 = 1;
    double SI = face->get_initial_condition("sm")/100.;

    double TI = 272.;

    double runoff = 0.;
    double inf = 0.;

    double snowmelt = (*face)["snowmelt_int"_s];

    double potential_inf = d.last_ts_potential_inf;
    double avail_storage = (d.max_storage - d.storage);

    if(snowmelt > 0)
    {
        d.opportunity_time += global_param->dt() / 3600.;
        double t0 = d.opportunity_time;
        potential_inf = C * pow(S0,2.92) * pow((1. - SI),1.64) * pow((273.15 - TI) / 273.15, -0.45) * pow(t0,0.44);


        //cap the total infiltration to be no more than our available storage
        if (potential_inf > avail_storage )
        {
            potential_inf = avail_storage;
        }

        d.last_ts_potential_inf = potential_inf;

        if( d.total_inf + snowmelt > potential_inf)
        {
            runoff = (d.total_inf + snowmelt) - potential_inf;
        }


        //infiltrate everything else
        inf    = snowmelt - runoff;


        d.storage += inf;

        if (d.storage > d.max_storage)
        {
            d.storage = d.max_storage;
        }


        d.total_inf += inf;
        d.total_excess += runoff;

    }


    if( !is_nan(face->get_initial_condition("sm")))
    {
        (*face)["total_excess"_s]=d.total_excess;
        (*face)["total_inf"_s]=d.total_inf;

        (*face)["runoff"_s]=runoff;
        (*face)["inf"_s]=inf;
        (*face)["potential_inf"_s]=potential_inf;
        (*face)["soil_storage"_s]= d.storage;
        (*face)["opportunity_time"_s]=d.opportunity_time;
        (*face)["available_storage"_s]=avail_storage;
    }
    else
    {
        set_all_nan_on_skip(face);
    }

}