Skip to content

Commit

Permalink
add Soil Water Index
Browse files Browse the repository at this point in the history
  • Loading branch information
ftomei committed Feb 25, 2025
1 parent e760210 commit cea29de
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 11 deletions.
63 changes: 58 additions & 5 deletions agrolib/criteriaModel/criteria1DCase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,14 +724,61 @@ double Crit1DCase::getDegreeOfSaturation(double computationDepth)
lowerDepth = soilLayers[i].depth + soilLayers[i].thickness * 0.5;
if (computationDepth >= upperDepth && computationDepth <= lowerDepth)
{
return soilLayers[i].waterContent / soilLayers[i].SAT;
return soilLayers[i].getDegreeOfSaturation();
}
}

return NODATA;
}


/*!
* \brief getSoilWaterIndex
* compute Soil Water Index (SWI)
* 0: wilting point
* 1: soil saturation
* \param computationDepth = computation soil depth [cm]
* \return soil water index [-] averaged from zero to specific depth
*/
double Crit1DCase::getSoilWaterIndex(double computationDepth)
{
computationDepth /= 100; // [cm] --> [m]
if (computationDepth <= 0 || mySoil.totalDepth < (computationDepth * 0.25))
{
return NODATA;
}

double lowerDepth, upperDepth; // [m]
double depthFraction; // [-]
double currentWaterSum; // [mm]
double potentialWaterSum = 0; // [mm]

currentWaterSum = soilLayers[0].waterContent; // pond [mm]

bool islastComputationLayer = false;
unsigned int i = 1;
while (i < soilLayers.size() && ! islastComputationLayer)
{
upperDepth = soilLayers[i].depth - soilLayers[i].thickness * 0.5;
lowerDepth = soilLayers[i].depth + soilLayers[i].thickness * 0.5;

if (lowerDepth < computationDepth)
depthFraction = 1;
else
{
depthFraction = (computationDepth - upperDepth) / soilLayers[i].thickness;
islastComputationLayer = true;
}

currentWaterSum += (soilLayers[i].waterContent - soilLayers[i].WP) * depthFraction;
potentialWaterSum += (soilLayers[i].SAT - soilLayers[i].WP) * depthFraction;
i++;
}

return currentWaterSum / potentialWaterSum;
}


/*!
* \brief getWaterPotential
* \param computationDepth = computation soil depth [cm]
Expand Down Expand Up @@ -799,27 +846,28 @@ double Crit1DCase::getSlopeStability(double computationDepth)
/*!
* \brief getWaterDeficit
* \param computationDepth = computation soil depth [cm]
* \return sum of water deficit from zero to computationDepth (mm)
* \return sum of soil water deficit (mm) from zero to computationDepth
*/
double Crit1DCase::getWaterDeficitSum(double computationDepth)
{
computationDepth /= 100; // [cm] --> [m]
computationDepth /= 100.; // [cm] --> [m]
double lowerDepth, upperDepth; // [m]
double layerDeficit; // [mm]
double waterDeficitSum = 0; // [mm]

for (unsigned int i = 1; i < soilLayers.size(); i++)
{
lowerDepth = soilLayers[i].depth + soilLayers[i].thickness * 0.5;
layerDeficit = soilLayers[i].FC - soilLayers[i].waterContent;

if (lowerDepth < computationDepth)
{
waterDeficitSum += soilLayers[i].FC - soilLayers[i].waterContent;
waterDeficitSum += layerDeficit;
}
else
{
// fraction of last layer
upperDepth = soilLayers[i].depth - soilLayers[i].thickness * 0.5;
double layerDeficit = soilLayers[i].FC - soilLayers[i].waterContent;
double depthFraction = (computationDepth - upperDepth) / soilLayers[i].thickness;
return waterDeficitSum + layerDeficit * depthFraction;
}
Expand Down Expand Up @@ -903,6 +951,11 @@ double Crit1DCase::getAvailableWaterSum(double computationDepth)
double Crit1DCase::getFractionAW(double computationDepth)
{
computationDepth /= 100; // [cm] --> [m]
if (computationDepth <= 0 || mySoil.totalDepth < (computationDepth * 0.25))
{
return NODATA;
}

double lowerDepth, upperDepth; // [m]
double depthFraction; // [-]
double availableWaterSum = 0; // [mm]
Expand Down
1 change: 1 addition & 0 deletions agrolib/criteriaModel/criteria1DCase.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
double getWaterDeficitSum(double computationDepth);
double getWaterCapacitySum(double computationDepth);
double getAvailableWaterSum(double computationDepth);
double getSoilWaterIndex(double computationDepth);

private:
double minLayerThickness; // [m]
Expand Down
24 changes: 23 additions & 1 deletion agrolib/criteriaModel/criteria1DProject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ void Crit1DProject::initialize()
availableWaterDepth.clear();
fractionAvailableWaterDepth.clear();
factorOfSafetyDepth.clear();
soilWaterIndexDepth.clear();
awcDepth.clear();

texturalClassList.resize(13);
Expand Down Expand Up @@ -367,6 +368,13 @@ bool Crit1DProject::readSettings()
return false;
}

depthList = projectSettings->value("soilWaterIndex").toStringList();
if (! setVariableDepth(depthList, soilWaterIndexDepth))
{
projectError = "Wrong Soil Water Index depth in " + configFileName;
return false;
}

projectSettings->endGroup();

return true;
Expand Down Expand Up @@ -1709,6 +1717,11 @@ bool Crit1DProject::createOutputTable(QString &myError)
QString fieldName = "FoS_" + QString::number(factorOfSafetyDepth[i]);
queryString += ", " + fieldName + " REAL";
}
for (unsigned int i = 0; i < soilWaterIndexDepth.size(); i++)
{
QString fieldName = "SWI_" + QString::number(soilWaterIndexDepth[i]);
queryString += ", " + fieldName + " REAL";
}

// close query
queryString += ")";
Expand Down Expand Up @@ -1784,6 +1797,11 @@ void Crit1DProject::updateOutput(Crit3DDate myDate, bool isFirst)
QString fieldName = "FoS_" + QString::number(factorOfSafetyDepth[i]);
outputString += ", " + fieldName;
}
for (unsigned int i = 0; i < soilWaterIndexDepth.size(); i++)
{
QString fieldName = "SWI_" + QString::number(soilWaterIndexDepth[i]);
outputString += ", " + fieldName;
}

outputString += ") VALUES ";
}
Expand Down Expand Up @@ -1850,12 +1868,16 @@ void Crit1DProject::updateOutput(Crit3DDate myDate, bool isFirst)
}
for (unsigned int i = 0; i < fractionAvailableWaterDepth.size(); i++)
{
outputString += "," + QString::number(myCase.getFractionAW(fractionAvailableWaterDepth[i]), 'g', 3);
outputString += "," + QString::number(myCase.getFractionAW(fractionAvailableWaterDepth[i]), 'g', 4);
}
for (unsigned int i = 0; i < factorOfSafetyDepth.size(); i++)
{
outputString += "," + QString::number(myCase.getSlopeStability(factorOfSafetyDepth[i]), 'g', 4);
}
for (unsigned int i = 0; i < soilWaterIndexDepth.size(); i++)
{
outputString += "," + QString::number(myCase.getSoilWaterIndex(soilWaterIndexDepth[i]), 'g', 4);
}

outputString += ")";
}
Expand Down
1 change: 1 addition & 0 deletions agrolib/criteriaModel/criteria1DProject.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
std::vector<int> availableWaterDepth; // [cm]
std::vector<int> fractionAvailableWaterDepth; // [cm]
std::vector<int> factorOfSafetyDepth; // [cm]
std::vector<int> soilWaterIndexDepth; // [cm]

// DATABASE
QSqlDatabase dbForecast;
Expand Down
2 changes: 1 addition & 1 deletion agrolib/gis/gis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2055,7 +2055,7 @@ namespace gis
}

// step 3: cleans the basin (removes points relating to other basins)
float threshold = basinRaster.header->cellSize * 5;
double threshold = basinRaster.header->cellSize * 3.;
for (int row = 0; row < basinRaster.header->nrRows; row++)
{
for (int col = 0; col < basinRaster.header->nrCols; col++)
Expand Down
4 changes: 2 additions & 2 deletions agrolib/mathFunctions/statistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,8 @@ namespace statistics
double weighedMeanMultifactor(meanType type, std::vector <std::vector <double>> weights, std::vector<double> &data)
{
double mean = NODATA;
int nrData = data.size();
int nrWeightFactors = weights.size();
int nrData = int(data.size());
int nrWeightFactors = int(weights.size());
std::vector<double> compositeWeights(nrData,1);
std::vector<double> normalizationCoefficient(nrWeightFactors,0);

Expand Down
2 changes: 1 addition & 1 deletion agrolib/soil/soil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ namespace soil

/*!
* \brief Compute degree of saturation from volumetric water content
* \param theta [m^3 m-3] volumetric water content
* \param theta [m3 m-3] volumetric water content
* \param horizon pointer to Crit3DHorizon class
* \return [-] degree of saturation
*/
Expand Down
2 changes: 1 addition & 1 deletion bin/CRITERIA1D/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void usage()
int main(int argc, char *argv[])
{
QCoreApplication myApp(argc, argv);
std::cout << "CRITERIA-1D agro-hydrological model v1.8.6\n" << std::endl;
std::cout << "CRITERIA-1D agro-hydrological model v1.8.7\n" << std::endl;

Crit1DProject myProject;

Expand Down

0 comments on commit cea29de

Please sign in to comment.