Beispiel #1
0
void ReservoirMethod::Get1DData(const char *key, int *nRows, float **data)
{
	initialOutputs();
    string sk(key);
    if (StringMatch(sk, VAR_REVAP))
    {
        *data = m_D_Revap;
        *nRows = m_nCells;
    }
    else if (StringMatch(sk, VAR_RG))
    {
        *data = m_T_RG;
        *nRows = m_nSubbasins + 1;
    }
    else if (StringMatch(sk, VAR_SBQG))
    {
        *data = m_T_QG;
        *nRows = m_nSubbasins + 1;
    }
    else if (StringMatch(sk, VAR_SBGS))
    {
        *data = m_gwStore;
        *nRows = m_nSubbasins + 1;
    }
    else if (StringMatch(sk, VAR_SBPET))
    {
        *data = m_petSubbasin;
        *nRows = m_nSubbasins + 1;
    }
    else
        throw ModelException(MID_GWA_RE, "Get1DData", "Parameter " + sk + " does not exist.");
}
Beispiel #2
0
int MUSLE_AS::Execute()
{
    CheckInputData();
    initialOutputs();
#pragma omp parallel for
    for (int i = 0; i < m_nCells; i++)
    {
        if (m_surfaceRunoff[i] < 0.0001f || m_streamLink[i] > 0)
            m_sedimentYield[i] = 0.f;
        else
        {
            float q = getPeakRunoffRate(i); //equation 2 in memo, peak flow
            float Y = 11.8f * pow(m_surfaceRunoff[i] * m_cellAreaKM * 1000.0f * q, 0.56f)
                      * m_usle_k[i][0] * m_usle_ls[i] * m_usle_c[i] * m_usle_p[i];    //equation 1 in memo, sediment yield

            if (m_snowAccumulation[i] > 0.0001f)
                Y /= exp(3.f * m_snowAccumulation[i] / 25.4f);  //equation 4 in memo, the snow pack effect
            m_sedimentYield[i] = Y * 1000.f; /// kg
		}
		//if(i == 1000) cout << m_sedimentYield[i] << "," << m_surfaceRunoff[i] << endl;
		/// particle size distribution of sediment yield
		m_sandYield[i] = m_sedimentYield[i] * m_detachSand[i];
		m_siltYield[i] = m_sedimentYield[i] * m_detachSilt[i];
		m_clayYield[i] = m_sedimentYield[i] * m_detachClay[i];
		m_smaggreYield[i] = m_sedimentYield[i] * m_detachSmAggre[i];
		m_lgaggreYield[i] = m_sedimentYield[i] * m_detachLgAggre[i];
    }
    return 0;
}
Beispiel #3
0
void ReservoirMethod::Get2DData(const char *key, int *nRows, int *nCols, float ***data)
{
	initialOutputs();
    string sk(key);
	if (StringMatch(sk, VAR_GWWB))
	{
		*data = m_T_GWWB;
		*nRows = m_nSubbasins + 1;
		*nCols = 6;
	}
    else
        throw ModelException(MID_GWA_RE, "Get2DData", "Parameter " + sk + " does not exist in current module.");
}
void DepressionFSDaily::Get1DData(const char *key, int *n, float **data)
{
    initialOutputs();
    string sk(key);
    *n = m_nCells;
    if (StringMatch(sk, VAR_DPST))
        *data = m_sd;
    else if (StringMatch(sk, VAR_DEET))
        *data = m_ed;
    else if (StringMatch(sk, VAR_SURU))
        *data = m_sr;
    else
        throw ModelException(MID_DEP_LINSLEY, "Get1DData", "Output " + sk+" does not exist.");
}
Beispiel #5
0
void MUSLE_AS::Get1DData(const char *key, int *n, float **data)
{
	initialOutputs();
    string sk(key);
    if (StringMatch(sk, VAR_SOER)) *data = m_sedimentYield;
    else if (StringMatch(sk, VAR_USLE_LS)) *data = m_usle_ls;
	else if (StringMatch(sk, VAR_SANDYLD)) *data = m_sandYield;
	else if (StringMatch(sk, VAR_SILTYLD)) *data = m_siltYield;
	else if (StringMatch(sk, VAR_CLAYYLD)) *data = m_clayYield;
	else if (StringMatch(sk, VAR_SAGYLD)) *data = m_smaggreYield;
	else if (StringMatch(sk, VAR_LAGYLD)) *data = m_lgaggreYield;
    else
        throw ModelException(MID_MUSLE_AS, "Get1DData", "Result " + sk + " does not exist.");
    *n = m_nCells;
}
Beispiel #6
0
int YLD::Execute()
{
    CheckInputData();
    initialOutputs();

    struct tm timeinfo;
    LocalTime(m_date, &timeinfo);
    timeinfo.tm_mon = 0;
    timeinfo.tm_mday = 0;
    timeinfo.tm_hour = 0;
    timeinfo.tm_min = 0;
    timeinfo.tm_sec = 0;
    timeinfo.tm_isdst = false;
    time_t tYear = mktime(&timeinfo);

    time_t harvestDate = tYear + m_harvestDate;

#pragma omp parallel for
    for (int i = 0; i < m_nCells; i++)
    {
        if (m_date > harvestDate && !m_harvested)
        {
            m_harvested = true;
            m_common->m_classification = (int) (m_classification[i]);
            //Harvest index
            //float harvestIndex = 0.0f;// potential harvest index for a given day
            //float totalPlantET = 0.0f;//actual ET simulated during life of plant
            //float totalPlantPET = 0.0f;//potential ET simulated during life of plant
            ////get total ET and PET(see grow.f Line 289-292) from zhiqiang
            if (m_frPHU[i] > 0.5 && m_frPHU[i] < m_frDeclineLAI[i])
            {
                m_totalPlantET[i] += m_totalWaterUptake[i] + m_soilET[i];
                m_totalPlantPET[i] += m_PET[i];
            }
            // water deficiency factor
            m_wur[i] = 100.0f;
            if (m_totalPlantPET[i] > 10)
                m_wur[i] *= m_totalPlantET[i] / m_totalPlantPET[i];

            //get optimal harvest index, p309 5:2.4.1
            m_HI[i] = m_HiOpt[i] * 100.0f * m_frPHU[i] / (100.0f * m_frPHU[i] + exp(11.1f - 10.0f * m_frPHU[i]));
            m_Hiact[i] = m_HI[i] - m_HiMin[i] * (m_wur[i] / (m_wur[i] + exp(6.13f - 0.0883f * m_wur[i]))) + m_HiMin[i];

            m_HI[i] = min(m_HI[i], m_Hiact[i]);
            //float yield = 0.0f;
            if (m_HiOpt[i] > 1.001)
                m_yield[i] = m_biomass[i] * (1.0f - 1.0f / (1.0f + m_HI[i]));
            else
                m_yield[i] = m_biomassAG[i] * m_HI[i];
            m_yield[i] = max(0.0f, m_yield[i]);
            m_harvestEfficiency[i] = 0.5f; //harvestEfficiency read from database
            //IsGrain should read from database
            if (m_common->IsGrain())//grain harvest, no residue, see harvgrainop.f
            {
                m_yield[i] *= m_harvestEfficiency[i];
                m_yieldN[i] = max(0.0f, min(m_yield[i] * m_frNyld[i], 0.85f * m_biomassN[i]));
                m_yieldP[i] = max(0.0f, min(m_yield[i] * m_frPyld[i], 0.85f * m_biomassP[i]));

                m_biomass[i] -= m_yield[i];
            }
            else //biomass harvest, has residue, residue redistribute to soil layer, see harvestop.f
            {
                //divide yield to two parts:clip and yield
                m_clip[i] = m_yield[i] * (1 - m_harvestEfficiency[i]);
                m_yield[i] -= m_clip[i];
                m_clip[i] = max(0.0f, m_clip[i]);
                m_yield[i] = max(0.0f, m_yield[i]);

                //harvest index override  read from database
                //get N&P in clip and yield[i]
                m_yieldN[i] = max(0.0f, min(m_yield[i] * m_frNyld[i], 0.8f * (m_biomassN[i])));
                m_yieldP[i] = max(0.0f, min(m_yield[i] * m_frPyld[i], 0.8f * (m_biomassP[i])));
                m_clipN[i] = max(0.0f, min(m_clip[i] * m_frNyld[i], m_biomassN[i] -
                                                                    m_yieldN[i])); //N in clip residual,needed by nitrient cycling module
                m_clipP[i] = max(0.0f, min(m_clip[i] * m_frPyld[i], m_biomassP[i] -
                                                                    m_yieldP[i])); //P in clip residual,needed by nitrient cycling module
                //reset LAI, frPHU and root fraction
                m_removeFraction[i] = 1.0f; //the fraction of remove part to aboveground part
                if (m_biomass[i] - m_biomassRoot[i] > 1.0e-6)
                    m_removeFraction[i] = (m_yield[i] + m_clip[i]) / (m_biomass[i] - m_biomassRoot[i]);
                m_removeFraction[i] = min(1.0f, m_removeFraction[i]);

                //root part
                m_rootFraction[i] = m_biomassRoot[i] / m_biomass[i];
                m_rootLeft[i] = (m_biomass[i] - m_biomassRoot[i]) * (1 - m_removeFraction[i]) * m_rootFraction[i] /
                                (1.0f - m_rootFraction[i]);
                m_rootRemove[i] = m_biomassRoot[i] - m_rootLeft[i];  //removed root as residual
                m_rootRemoveFraction[i] = 0.0f;
                if (m_biomassRoot[i] > 1.0e-6) m_rootRemoveFraction[i] = m_rootRemove[i] / (m_biomassRoot[i]);
                m_rootRemoveN[i] = m_rootRemoveFraction[i] * (m_biomassN[i]);
                m_rootRemoveP[i] = m_rootRemoveFraction[i] * (m_biomassP[i]);

                //remove aboveground and root biomass from total biomass
                //change the LAI and growth step
                if (m_biomass[i] > 0.001)
                {
                    m_LAI[i] *= 1.0f - m_removeFraction[i];
                    if (m_frPHU[i] < 0.999)
                        m_frPHU[i] *= 1.0f - m_removeFraction[i];

                    m_biomass[i] -= m_yield[i] + m_clip[i] + m_rootRemove[i];
                    m_biomassN[i] -= m_yieldN[i] + m_clipN[i] + m_rootRemoveN[i];
                    m_biomassP[i] -= m_yieldP[i] + m_clipP[i] + m_rootRemoveP[i];

                    m_biomass[i] = min(0.0f, m_biomass[i]);
                    m_biomassN[i] = min(0.0f, m_biomassP[i]);
                    m_biomassP[i] = min(0.0f, m_biomassP[i]);

                    m_biomassRoot[i] = m_biomass[i] * (0.4f - 0.2f * m_frPHU[i]);
                }
                else
                {
                    m_biomass[i] = 0.0f;
                    m_biomassN[i] = 0.0f;
                    m_biomassP[i] = 0.0f;
                    m_biomassRoot[i] = 0.0f;

                    m_LAI[i] = 0.0f;
                    m_frPHU[i] = 0.0f;
                }
            }
        }
    }

    //m_lastSWE = m_swe;
    return 0;
}
Beispiel #7
0
int PER_PI::Execute()
{
    CheckInputData();
	initialOutputs();
    
//#pragma omp parallel for
    for (int i = 0; i < m_nCells; i++)
    {
        float k = 0.f, maxSoilWater = 0.f, fcSoilWater = 0.f;
		float swater = 0.f;//, wpSoilWater = 0.f;        
        /// firstly, assume all infiltrated water is added to the first soil layer.
		m_soilStorage[i][0] += m_infil[i];
		/// secondly, model water percolation across layers
        for (int j = 0; j < (int)m_nSoilLayers[i]; j++)
        {
            // for the upper two layers, soil may be frozen
            // No movement if soil moisture is below field capacity
            if (j == 0 && m_soilT[i] <= m_frozenT) 
                continue;
			swater = m_soilStorage[i][j];
			maxSoilWater = m_sat[i][j];
			fcSoilWater = m_fc[i][j];
			//wpSoilWater = m_wp[i][j];

            if (swater > fcSoilWater)
            {
                //the moisture content can exceed the porosity in the way the algorithm is implemented
                if (swater > maxSoilWater)
                    k = m_ks[i][j];
                else
                {
                    float dcIndex = 2.f / m_poreIndex[i][j] + 3.f; // pore disconnectedness index
					k = m_ks[i][j] * pow(swater / maxSoilWater, dcIndex);
                }

                m_perc[i][j] = k * m_dt / 3600.f;  /// mm
				
                if (swater - m_perc[i][j] > maxSoilWater)
                    m_perc[i][j] = swater - maxSoilWater;
                else if (swater - m_perc[i][j] < fcSoilWater)
                    m_perc[i][j] = swater - fcSoilWater;

                //Adjust the moisture content in the current layer, and the layer immediately below it
                m_soilStorage[i][j] -= m_perc[i][j];// / m_soilThick[i][j];
                if (j < m_nSoilLayers[i] - 1)
                    m_soilStorage[i][j + 1] += m_perc[i][j];// / m_soilThick[i][j + 1];

				
                //if (m_soilStorage[i][j] != m_soilStorage[i][j] || m_soilStorage[i][j] < 0.f)
                //{
                //    cout << MID_PER_PI << " CELL:" << i << ", Layer: " << j << "\tPerco:" << swater << "\t" <<
                //    fcSoilWater << "\t" << m_perc[i][j] << "\t" << m_soilThick[i][j] << "\tValue:" << m_soilStorage[i][j] <<
                //    endl;
                //    throw ModelException(MID_PER_PI, "Execute", "moisture is less than zero.");
                //}
            }
			else
			{
				for (int j = 0; j < (int)m_nSoilLayers[i]; j++)
					m_perc[i][j] = 0.f;
			}
			/// update total soil water content
			m_soilStorageProfile[i] = 0.f;
			for (int ly = 0; ly < (int)m_nSoilLayers[i]; ly++)
				m_soilStorageProfile[i] += m_soilStorage[i][ly];
        }
    }
    return 0;
}
Beispiel #8
0
int PER_STR::Execute()
{
    CheckInputData();
	initialOutputs();
	/*if (m_perc == NULL)
	{
	m_perc = new float *[m_nCells];

	#pragma omp parallel for
	for (int i = 0; i < m_nCells; i++)
	{
	m_perc[i] = new float[m_nSoilLayers];
	for (int j = 0; j < m_nSoilLayers; j++)
	m_perc[i][j] = 0.f;
	}
	}*/
#pragma omp parallel for
    for (int i = 0; i < m_nCells; i++)
    {
		float maxSoilWater = 0.f, fcSoilWater = 0.f;
		float swater = 0.f, wpSoilWater = 0.f;     
        //// Update soil layers from solid two layers to multi-layers by m_nSoilLayers. By LJ
        //int curSoilLayers = -1, j;
        //m_upSoilDepth[0] = m_soilDepth[i][0];
        //for (j = 1; j < m_nSoilLayers; j++)
        //{
        //    if (!FloatEqual(m_soilDepth[i][j], NODATA_VALUE))
        //        m_upSoilDepth[j] = m_soilDepth[i][j] - m_soilDepth[i][j - 1];
        //    else
        //        break;
        //}
        //curSoilLayers = j;

        //float depth[3];
        //depth[0] = m_upSoilDepth;
        //depth[1] = m_rootDepth[i] - m_upSoilDepth;
        //if(depth[1] < 0)
        //{
        //	ostringstream oss;
        //	oss << "The root depth at cell(" << i << ") is " << m_rootDepth[i] << ", and is less than the upper soil depth (" << m_upSoilDepth << endl;
        //	throw ModelException(MID_PER_STR, "Execute",  oss.str());
        //}


        m_somo[i][0] += m_infil[i] / m_soilThick[i][0];
        for (int j = 0; j < (int)m_soilLayers[i]; j++)
        {
            //No movement if soil moisture is below field capacity
            m_perc[i][j] = 0.f;

            // for the upper two layers, soil may be frozen
            if (j == 0 && m_soilT[i] <= m_frozenT)
                continue;

            if (m_somo[i][j] > m_fc[i][j])
            {
                maxSoilWater = m_soilThick[i][j] * m_porosity[i][j];
                swater = m_soilThick[i][j] * m_somo[i][j];
                fcSoilWater = m_soilThick[i][j] * m_fc[i][j];
				wpSoilWater = m_soilThick[i][j] * m_wp[i][j];
                //////////////////////////////////////////////////////////////////////////
                // method from swat
                float tt = 3600.f * (m_porosity[i][j] - m_fc[i][j]) * m_soilThick[i][j] / m_ks[i][j];
                m_perc[i][j] = swater * (1.f - exp(-m_dt / tt));

				if (swater - m_perc[i][j] > maxSoilWater)
					m_perc[i][j] = swater - maxSoilWater;
				else if (swater - m_perc[i][j] < fcSoilWater)
					m_perc[i][j] = swater - fcSoilWater;
				else if (swater - m_perc[i][j] < wpSoilWater)
					m_perc[i][j] = swater - wpSoilWater;
				else  /// percolation is not allowed!
					m_perc[i][j] = 0.f;
                //Adjust the moisture content in the current layer, and the layer immediately below it
                m_somo[i][j] -= m_perc[i][j] / m_soilThick[i][j];
                if (j < m_nSoilLayers - 1)
                    m_somo[i][j + 1] += m_perc[i][j] / m_soilThick[i][j + 1];


                //if (m_somo[i][j] != m_somo[i][j] || m_somo[i][j] < 0.f)
                //{
                //    cout << "PER_STR CELL:" << i << ", Layer: " << j << "\tPerco:" << soilWater << "\t" <<
                //    fcSoilWater << "\t" << m_perc[i][j] << "\t" << m_soilThick[i][j] << "\tValue:" << m_somo[i][j] <<
                //    endl;
                //    throw ModelException(MID_PER_STR, "Execute", "moisture is less than zero.");
                //}

            }
			else
			{
				for (int j = 0; j < (int)m_soilLayers[i]; j++)
					m_perc[i][j] = 0.f;
			}
			for (int j = (int)m_soilLayers[i]; j < m_nSoilLayers; j++)
				m_perc[i][j] = NODATA_VALUE;
        }
    }
    return 0;

}
Beispiel #9
0
int ReservoirMethod::Execute()
{
    if (!CheckInputData()) return -1;
	initialOutputs();
    float QGConvert = 1.f * m_CellWidth * m_CellWidth / (m_TimeStep) / 1000.f; // mm ==> m3/s
	for (vector<int>::iterator it = m_subbasinIDs.begin(); it!=m_subbasinIDs.end();it++)
    {
		int subID = *it;
		Subbasin *curSub = m_subbasinsInfo->GetSubbasinByID(subID);

		// get percolation from the bottom soil layer at the subbasin scale
		int curCellsNum = curSub->getCellCount();
		int *curCells = curSub->getCells();
		float perco = 0.f;
#pragma omp parallel for reduction(+:perco)
		for (int i = 0; i < curCellsNum; i++)
		{
			int index = 0;
			index = curCells[i];
			perco += m_perc[index][(int)m_soilLayers[index]-1];
		}
		perco /= curCellsNum; // mean mm
		/// percolated water ==> vadose zone ==> shallow aquifer ==> deep aquifer
		/// currently, for convenience, we assume a small portion of the percolated water
		/// will enter groundwater. By LJ. 2016-9-2
		float ratio2gw = 1.f;
		perco *= ratio2gw;
		curSub->setPerco(perco);

		//if (perco > 0.f)
		//{
		//	cout << "subID: "<<subID<<", perco mean: "<<perco << endl;
		//}

		//calculate EG, i.e. Revap
		float revap = 0.f;
		float fPET = 0.f;
		float fEI = 0.f;
		float fED = 0.f;
		float fES = 0.f;
		float plantEP = 0.f;
		fPET = Sum(curCellsNum, curCells, m_D_PET) / curCellsNum;
		fEI = Sum(curCellsNum, curCells, m_D_EI) / curCellsNum;
		fED = Sum(curCellsNum, curCells, m_D_ED) / curCellsNum;
		fES = Sum(curCellsNum, curCells, m_D_ES) / curCellsNum;
		plantEP = Sum(curCellsNum, curCells, m_plantEP) / curCellsNum;

		curSub->setPET(fPET);
		
		//if percolation < 0.01, EG will be 0. if percolation >= 0.01, EG will be calculated by equation (why? this is not used currently. Junzhi Liu 2016-08-14).
		//if (perco >= 0.01f)
		//{
			revap = (fPET - fEI - fED - fES - plantEP) * m_gwStore[subID] / m_GWMAX;
			if (revap != revap)
				cout <<"fPET: "<<fPET<<", fEI: "<<fEI<<", fED: "<<fED<<", fES: "<<fES<<", plantEP: "<<plantEP
				<<"gwStore: "<<subID<<","<<m_gwStore[subID]<<endl;
			revap = max(revap, 0.f);
			revap = min(revap, perco);
		//}
		//float prevRevap = curSub->getEG();
		//if (prevRevap != revap)
		//{
		//	curSub->setEG(revap);
		//	curSub->setIsRevapChanged(true);
		//}
		//else
		//	curSub->setIsRevapChanged(false);		
		curSub->setEG(revap);
		
		//deep percolation
		float percoDeep = perco * m_dp_co; 
		curSub->setPerde(percoDeep);

		// groundwater runoff (mm)
		float slopeCoef = curSub->getSlopeCoef();
		float kg = m_Kg * slopeCoef;
		float groundRunoff = kg * pow(m_gwStore[subID], m_Base_ex); //mm
		if (groundRunoff  != groundRunoff )
			cout << groundRunoff;

		float groundQ = groundRunoff * curCellsNum * QGConvert; // groundwater discharge (m3/s)

		float groundStorage = m_gwStore[subID];
		groundStorage += (perco - revap - percoDeep - groundRunoff);

		//add the ground water from bank storage, 2011-3-14
		float gwBank = 0.f;
		// at the first time step m_VgroundwaterFromBankStorage is NULL
		if (m_VgroundwaterFromBankStorage != NULL)
			gwBank = m_VgroundwaterFromBankStorage[subID];
		groundStorage += gwBank / curSub->getArea() * 1000.f;

		groundStorage = max(groundStorage, 0.f);
		if (groundStorage > m_GWMAX)
		{
			groundRunoff += (groundStorage - m_GWMAX);
			groundQ = groundRunoff * curCellsNum * QGConvert; // groundwater discharge (m3/s)
			groundStorage = m_GWMAX;
		}
		curSub->setRG(groundRunoff);
		curSub->setGW(groundStorage);
		curSub->setQG(groundQ);
		if (groundStorage != groundStorage)
		{
			ostringstream oss;
			oss << perco << "\t" << revap << "\t" << percoDeep << "\t" << groundRunoff << "\t" << m_gwStore[subID] << "\t" << m_Kg << "\t" <<
				m_Base_ex << "\t" << slopeCoef << endl;
			throw ModelException("Subbasin", "setInputs", oss.str());
		}
		m_T_Perco[subID] = curSub->getPerco();
		m_T_Revap[subID] = curSub->getEG();
		m_T_PerDep[subID] = curSub->getPerde();
        m_T_RG[subID] = curSub->getRG();                //get rg of specific subbasin
        m_T_QG[subID] = curSub->getQG();                //get qg of specific subbasin
        m_petSubbasin[subID] = curSub->getPET();
        m_gwStore[subID] = curSub->getGW();
    }

	m_T_Perco[0] = m_subbasinsInfo->subbasin2basin(VAR_PERCO);
	m_T_Revap[0] = m_subbasinsInfo->subbasin2basin(VAR_REVAP);
	m_T_PerDep[0] = m_subbasinsInfo->subbasin2basin(VAR_PERDE);
	m_T_RG[0] = m_subbasinsInfo->subbasin2basin(VAR_RG);  // get rg of entire watershed
	m_gwStore[0] = m_subbasinsInfo->subbasin2basin(VAR_GW_Q);
	m_T_QG[0] = m_subbasinsInfo->subbasin2basin(VAR_QG);  // get qg of entire watershed

	// output to GWWB
	for (int i = 0; i <= m_nSubbasins; i++)
	{
		m_T_GWWB[i][0] = m_T_Perco[i];
		m_T_GWWB[i][1] = m_T_Revap[i];
		m_T_GWWB[i][2] = m_T_PerDep[i];
		m_T_GWWB[i][3] = m_T_RG[i];
		m_T_GWWB[i][4] = m_gwStore[i];
		m_T_GWWB[i][5] = m_T_QG[i];
	}

	// update soil moisture
	for (vector<int>::iterator it = m_subbasinIDs.begin(); it!=m_subbasinIDs.end();it++)
	{
		Subbasin *sub = m_subbasinsInfo->GetSubbasinByID(*it);
        int *cells = sub->getCells();
        int nCells = sub->getCellCount();
        int index = 0;
        for (int i = 0; i < nCells; i++)
        {
            index = cells[i];
            m_soilStorage[index][(int)m_soilLayers[index] - 1] += sub->getEG();
			// TODO: Is it need to allocate revap to each soil layers??? By LJ
        }
    }
    return 0;
}
int DepressionFSDaily::Execute()
{
    //check the data
    CheckInputData();
    initialOutputs();

#pragma omp parallel for
    for (int i = 0; i < m_nCells; ++i)
    {
        //////////////////////////////////////////////////////////////////////////
        // runoff
        if (m_depCap[i] < 0.001f)
        {
            m_sr[i] = m_pe[i];
            m_sd[i] = 0.f;
        }
        else if (m_pe[i] > 0.f)
        {
            float pc = m_pe[i] - m_depCap[i] * log(1.f - m_sd[i] / m_depCap[i]);
            float deltaSd = m_pe[i] * exp(-pc / m_depCap[i]);
            if (deltaSd > m_depCap[i] - m_sd[i])
                deltaSd = m_depCap[i] - m_sd[i];
            m_sd[i] += deltaSd;
            m_sr[i] = m_pe[i] - deltaSd;
        }
        else
        {
            m_sd[i] += m_pe[i];
            m_sr[i] = 0.f;
        }

        //////////////////////////////////////////////////////////////////////////
        // evaporation
        if (m_sd[i] > 0)
        {
			/// TODO: Is this logically right? PET is just potential, which include 
			///       not only ET from surface water, but also from plant and soil.
			///       Please Check the corresponding theory. By LJ.
            // evaporation from depression storage
            if (m_pet[i] - m_ei[i] < m_sd[i])
            {
                m_ed[i] = m_pet[i] - m_ei[i];
            }
            else
            {
                m_ed[i] = m_sd[i];
            }
            m_sd[i] -= m_ed[i];
        }
        else
        {
            m_ed[i] = 0.f;
            m_sd[i] = 0.f;
        }
		if (m_impoundTriger != NULL && FloatEqual(m_impoundTriger[i], 0.f)){
			if (m_potVol != NULL)
			{
				m_potVol[i] += m_sr[i];
				m_potVol[i] += m_sd[i];
				m_sr[i] = 0.f;
				m_sd[i] = 0.f;
			}
		}
    }
    return true;
}