示例#1
0
void calculate_water_balance(control *c, fluxes *f, met *m, params *p,
                             state *s, int daylen, double trans_leaf,
                             double omega_leaf, double rnet_leaf) {
    /*

    Calculate the water balance (including all water fluxes).

    Parameters:
    ----------
    control : structure
        control structure
    fluxes : structure
        fluxes structure
    met : structure
        meteorological drivers structure
    params : structure
        parameters structure
    day : int
        project day. (Dummy argument, only passed for daily model)
    daylen : double
        length of day in hours. (Dummy argument, only passed for daily model)
    trans_leaf : double
        leaf transpiration (Dummy argument, only passed for sub-daily model)
    omega_leaf : double
        decoupling coefficient (Dummy argument, only passed for sub-daily model)
    rnet_leaf : double
        total canopy rnet (Dummy argument, only passed for sub-daily model)

    */
    double soil_evap, et, interception, runoff, conv,
           transpiration, net_rad, SEC_2_DAY, DAY_2_SEC,
           transpiration_am, transpiration_pm, gs_am, gs_pm, LE_am,
           LE_pm, ga_am, ga_pm, net_rad_am, net_rad_pm, trans_am,
           omega_am, gs_mol_m2_hfday_am, ga_mol_m2_hfday_am, gpp_am,
           gpp_pm, trans_pm, omega_pm, gs_mol_m2_hfday_pm, ga_mol_m2_hfday_pm,
           throughfall, canopy_evap;

    SEC_2_DAY = 60.0 * 60.0 * daylen;
    DAY_2_SEC = 1.0 / SEC_2_DAY;

    if (c->sub_daily) {
        /* calculate potential canopy evap rate, this may be reduced later
           depending on canopy water storage */
        canopy_evap = calc_canopy_evaporation(m, p, s, rnet_leaf);

        /* mol m-2 s-1 to mm/day */
        conv = MOLE_WATER_2_G_WATER * G_TO_KG * SEC_2_HLFHR;
        canopy_evap *= conv;
        calc_interception(c, m, p, f, s, &throughfall, &interception,
                          &canopy_evap);
    } else {
        /* don't need to work out the canopy evap */
        calc_interception(c, m, p, f, s, &throughfall, &interception,
                          &canopy_evap);

    }

    net_rad = calc_net_radiation(p, m->sw_rad, m->tair);
    soil_evap = calc_soil_evaporation(m, p, s, net_rad);
    if (c->sub_daily) {
        soil_evap *= MOLE_WATER_2_G_WATER * G_TO_KG * SEC_2_HLFHR;
    } else {
        net_rad_am = calc_net_radiation(p, m->sw_rad_am, m->tair_am);
        net_rad_pm = calc_net_radiation(p, m->sw_rad_pm, m->tair_pm);
        soil_evap *= MOLE_WATER_2_G_WATER * G_TO_KG * (60.0 * 60.0 * daylen);
    }

    if (c->sub_daily) {
        /* mol m-2 s-1 to mm/30 min */
        transpiration = trans_leaf * MOLE_WATER_2_G_WATER * G_TO_KG * \
                        SEC_2_HLFHR;

    } else {
        /* gC m-2 day-1 -> umol m-2 s-1 */
        conv = GRAMS_C_TO_MOL_C * MOL_TO_UMOL * DAY_2_SEC;
        gpp_am = f->gpp_am * conv;
        gpp_pm = f->gpp_pm * conv;

        penman_canopy_wrapper(p, s, m->press, m->vpd_am, m->tair_am, m->wind_am,
                              net_rad_am, m->Ca, gpp_am, &ga_am, &gs_am,
                              &transpiration_am, &LE_am, &omega_am);
        penman_canopy_wrapper(p, s, m->press, m->vpd_pm, m->tair_pm, m->wind_pm,
                              net_rad_pm, m->Ca, gpp_pm, &ga_pm, &gs_pm,
                              &transpiration_pm, &LE_pm, &omega_pm);

        /* mol m-2 s-1 to mm/day */
        conv = MOLE_WATER_2_G_WATER * G_TO_KG * SEC_2_DAY;
        transpiration = (transpiration_am + transpiration_pm) * conv;

        f->omega = (omega_am + omega_pm) / 2.0;

        /* output in mol H20 m-2 s-1 */
        f->gs_mol_m2_sec = gs_am + gs_pm;
        f->ga_mol_m2_sec = ga_am + ga_pm;
    }

    /*
    ** NB. et, transpiration & soil evap may all be adjusted in
    ** update_water_storage if we don't have sufficient water
    */
    et = transpiration + soil_evap + canopy_evap;

    update_water_storage(c, f, p, s, throughfall, interception, canopy_evap,
                         &transpiration, &soil_evap, &et, &runoff);

    if (c->sub_daily) {
        sum_hourly_water_fluxes(f, soil_evap, transpiration, et, interception,
                                throughfall, canopy_evap, runoff, omega_leaf);
    } else {
        update_daily_water_struct(f, soil_evap, transpiration, et, interception,
                                  throughfall, canopy_evap, runoff);
    }

    return;
}
void calculate_water_balance_sub_daily(control *c, fluxes *f, met *m,
                                       nrutil *nr, params *p, state *s,
                                       int daylen, double trans,
                                       double omega_leaf,
                                       double rnet_leaf) {
    /*
        Calculate the water balance (including all water fluxes).
        - we are using all the hydraulics instead

        Parameters:
        ----------
        control : structure
            control structure
        fluxes : structure
            fluxes structure
        met : structure
            meteorological drivers structure
        params : structure
            parameters structure
        day : int
            project day. (Dummy argument, only passed for daily model)
        daylen : double
            length of day in hours. (Dummy argument, only passed for daily
            model)
        trans : double
            transpiration (Dummy argument, only passed for sub-daily
            model)
        omega_leaf : double
            decoupling coefficient (Dummy argument, only passed for sub-daily
            model)
        rnet_leaf : double
            total canopy rnet (Dummy argument, only passed for sub-daily model)
    */

    int    i;
    double soil_evap, et, interception, runoff, conv, transpiration, net_rad;
    double SEC_2_DAY, DAY_2_SEC, transpiration_am, transpiration_pm, gs_am;
    double canopy_evap, surface_water;

    // Water drained through the bottom soil layer
    double water_lost = 0.0;

    if (c->water_balance == HYDRAULICS) {

        zero_water_movement(f, p);

        // calculate potential canopy evap rate, this may be reduced later
        // depending on canopy water storage
        canopy_evap = calc_canopy_evaporation(m, p, s, rnet_leaf);

        /* mol m-2 s-1 to mm d-1 */
        conv = MOLE_WATER_2_G_WATER * G_TO_KG * SEC_2_HLFHR;
        canopy_evap *= conv;

        /* We could now replace this interception bit with the Rutter scheme? */
        calc_interception(c, m, p, f, s, &surface_water, &interception,
                          &canopy_evap);

        net_rad = calc_net_radiation(p, m->sw_rad, m->tair);
        soil_evap = calc_soil_evaporation(m, p, s, net_rad);
        soil_evap *= MOLE_WATER_2_G_WATER * G_TO_KG * SEC_2_HLFHR;


        /* mol m-2 s-1 to mm/30 min */
        transpiration = trans * MOLE_WATER_2_G_WATER * G_TO_KG * \
                        SEC_2_HLFHR;

        et = transpiration + soil_evap + canopy_evap;

        //
        // The loop needs to be outside the func as we need to be able to
        // calculate the soil conductance per layer and call this via
        // the integration func when we update the soil water balance
        //
        for (i = 0; i < p->n_layers; i++) {
            f->soil_conduct[i] = calc_soil_conductivity(s->water_frac[i],
                                                        p->cond1[i],
                                                        p->cond2[i],
                                                        p->cond3[i]);
        }

        calc_soil_water_potential(f, p, s);
        calc_soil_root_resistance(f, p, s);

        // If we have leaves we are transpiring
        if (s->lai > 0.0) {
            calc_water_uptake_per_layer(f, p, s);
        }

        // Calculates the thickness of the top dry layer and determines water
        // lost in upper layers due to evaporation
        calc_wetting_layers(f, p, s, soil_evap, surface_water);
        extract_water_from_layers(f, s, soil_evap, transpiration);

        //
        // determines water movement between soil layers due drainage
        // down the profile
        //
        for (i = 0; i < p->n_layers; i++) {
            calc_soil_balance(f, nr, p, s, i, &water_lost);
        }

        //
        // how much surface water infiltrantes the first soil layer in the
        // current time step? Water which does not infiltrate in a single step
        // is considered runoff
        //
        runoff = calc_infiltration(f, p, s, surface_water);
        runoff += water_lost * M_TO_MM;

        // Don't see point of calculating these again
        // Find SWP & soil resistance without updating waterfrac yet
        calc_soil_water_potential(f, p, s);
        calc_soil_root_resistance(f, p, s);

        update_soil_water_storage(f, p, s, &soil_evap, &transpiration);
        et = transpiration + soil_evap + canopy_evap;
    } else {

        // Simple soil water bucket appoximation

        // calculate potential canopy evap rate, this may be reduced later
        // depending on canopy water storage
        canopy_evap = calc_canopy_evaporation(m, p, s, rnet_leaf);

        /* mol m-2 s-1 to mm/day */
        conv = MOLE_WATER_2_G_WATER * G_TO_KG * SEC_2_HLFHR;
        canopy_evap *= conv;
        calc_interception(c, m, p, f, s, &surface_water, &interception,
                          &canopy_evap);

        net_rad = calc_net_radiation(p, m->sw_rad, m->tair);
        soil_evap = calc_soil_evaporation(m, p, s, net_rad);
        soil_evap *= MOLE_WATER_2_G_WATER * G_TO_KG * SEC_2_HLFHR;

        /* mol m-2 s-1 to mm/30 min */
        transpiration = trans * MOLE_WATER_2_G_WATER * G_TO_KG * \
                        SEC_2_HLFHR;

        /*
        ** NB. et, transpiration & soil evap may all be adjusted in
        ** update_water_storage if we don't have sufficient water
        */
        et = transpiration + soil_evap + canopy_evap;


        update_water_storage(c, f, p, s, surface_water, interception, canopy_evap,
                             &transpiration, &soil_evap, &et, &runoff);

    }

    sum_hourly_water_fluxes(f, soil_evap, transpiration, et, interception,
                            surface_water, canopy_evap, runoff, omega_leaf,
                            m->rain);


}