//writen by: E. van der Goot and Giorgio Cifani
//JRC, I-21020 Ispra, Italy
//date: 1996//based on the original FORTRAN/SQL CGMS and WOFOST code
//produced by Tamme van der Wal, Kees van Diepen and Daniel van Kralingen
//Alterra, P.O. Box 6700 AA, Wageningen, The NetherlandsCOleDateTime FindSowingDate(int nYear,
SCropCalendar CC,
SGridWeather GW[],
SSoilPhysicalGroup SPG)
{// Define dates from Crop Calendar
COleDateTime sowDate; // Sowing date
COleDateTime eSowDate(nYear, CC.nStartMonth1, CC.nStartMonthday1, 0, 0, 0);
// Earliest sowing day
COleDateTime lSowDate(nYear, CC.nStartMonth2, CC.nStartMonthday2, 0, 0, 0);
// Latest sowing day// Check dates
if (eSowDate.GetStatus() == ::COleDateTime::invalid ||
lSowDate.GetStatus() == ::COleDateTime::invalid ||
lSowDate < eSowDate)
{
sowDate.SetStatus(COleDateTime::invalid);
return sowDate;
}int nLenWorkPeriod = 0; // Length of workable period, should be 3 for sowing (sowing criterion)
// Define soil parameters
float fWExc = 2.0f; // Excess amount of water in plow layer
float fCaprMx = 0.0f; // Maximum upward flow into plow layer
float fEvSoil = 0.0f; // Daily evaporation from bare soil surface
float fDSeep = 0.0f; // Daily seepagefloat fDelim; // Minimum required soil moisture deficit in plow layer
// for occurrence of workable day (workability criterion)
float fSpac, fSpoc; // Topsoil seepage parameter for deep seedbed (potato)// Upward flow as a function of negative values of WEXC, when
// topsoil is drier than field capacity
float ACaprFU[] = { -0.50f, 0.50f, 0.00f, 0.20f, 0.10f, 0.15f, 0.40f,0.10f, 1.00f, 0.05f };SParameterValues CAPRFU[5];
// Set up array
for (int j = 0; j < 5; j ++)
{
CAPRFU[j].XValue = ACaprFU[j * 2];
CAPRFU[j].YValue = ACaprFU[j * 2 + 1];
}// Get parameters from Soil Physical Group table
// REMEMBER: potato hard-coded...
if (CC.nCropNo == 7)
{
// Two seepage parameters for deep seedbed (potato)
fSpac = SPG.fSpads;
fSpoc = SPG.fSpods;fDelim = SPG.fDefLim;
}
else
{
// Two seepage parameters for shallow seedbed (all other crops)
fSpac = SPG.fSpass;
fSpoc = SPG.fSposs;fDelim = 0.0f;
}
// Find startdate, but don't go before jan 1st.
sowDate = ::COleDateTime(nYear, 1, 1, 0, 0, 0);
const COleDateTimeSpan tenDays(10.0);if ((eSowDate - tenDays) > sowDate) sowDate = (eSowDate - tenDays);
const COleDateTimeSpan oneDay(1.0);int nDay = sowDate.GetDayOfYear() - 1;
while (!((sowDate >= eSowDate && nLenWorkPeriod >= 3) || (sowDate ==lSowDate)))
{
// NOTE: convert units
float fES0 = GW[nDay].fES0 / 10.0f;
// Evaporation from soil surface
if (fWExc >= 0.5f)
{
fCaprMx = 0.0f;
fEvSoil = fES0;
}
else
{
// Maximum capillary rise to surface (cf. Ritchie)
fCaprMx = AFGen(CAPRFU, 5, -fWExc);
fEvSoil = min(fES0, (fCaprMx + GW[nDay].fRainfall));
}fWExc = max(-1.0f, (fWExc + GW[nDay].fRainfall - fEvSoil));
// Seepage
if (fWExc > 0.0f)
{
fDSeep = min((fWExc * fSpac + fSpoc), fWExc);
fWExc -= fDSeep;
}// Criterion for workable day
if (fWExc <= fDelim)
nLenWorkPeriod++;
else
nLenWorkPeriod = 0;sowDate += oneDay;
nDay ++;
}return sowDate;
}