123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588 |
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /// \file cropphenology.cpp
- /// \brief Crop phenology including phu calculations
- /// \author Mats Lindeskog
- /// $Date: $
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- #include "config.h"
- #include "landcover.h"
- #include "cropphenology.h"
- const double MAXHUTEMP = 30; // Degree limit for heat unit summation
- /// Calculation of down-scaling of lai during crop senescence
- /** Follows Bondeau et al. 2007.
- */
- double senescence_curve(Pft& pft, double fphu) {
- if (pft.shapesenescencenorm)
- return pow(1-fphu,2) / pow(1 - pft.fphusen, 2) * (1 - pft.flaimaxharvest) + pft.flaimaxharvest;
- else
- return pow(1 - fphu, 0.5) / pow(1 - pft.fphusen, 0.5) * (1 - pft.flaimaxharvest) + pft.flaimaxharvest;
- }
- /// Initiation of potential heat unit calculation
- /** Calculates pvd (required vernalising days), tb (base temperature)
- * and phu (potential heat units) based on Bondeau et al. 2007.
- * Dynamic phu calculation based on Lindeskog et al. 2013.
- * Called on sowing date.
- */
- void phu_init(cropphen_struct& ppftcrop, Gridcellpft& gridcellpft, Patch& patch) {
- Pft& pft = gridcellpft.pft;
- const Climate& climate = patch.get_climate();
- double phu_last_year = ppftcrop.phu;
- ppftcrop.husum = 0.0;
- ppftcrop.vrf = 1.0;
- ppftcrop.vdsum = 0;
- ppftcrop.prf = 1.0;
- ppftcrop.pvd = pft.pvd; // default; kept for TrMi, TePu, TeSb, TrMa, TeSo, TrPe
- ppftcrop.phu = pft.phu;
- ppftcrop.tb = pft.tb;
- ppftcrop.vdsum_alloc=0.0;
- ppftcrop.vd=0.0;
- ppftcrop.dev_stage=0.0;
- // Calculation of phu and pvd according to Bondeau et al. 2007
- if (pft.ifsdautumn) { // TeWW,TeRa
- // maximum pvd allowed
- const int max_pvd = 60;
- if (gridcellpft.wintertype) { // Autumn sowing
- // if neither spring or winter conditions for the past 20 years
- if ((gridcellpft.first_autumndate20 == climate.testday_temp || gridcellpft.first_autumndate20 == climate.coldestday)
- && gridcellpft.first_autumndate % date.year_length() == gridcellpft.first_autumndate20
- && (gridcellpft.last_springdate20 == climate.testday_temp || gridcellpft.last_springdate20 == climate.coldestday)
- && gridcellpft.last_springdate == gridcellpft.last_springdate20) {
- ppftcrop.pvd = pft.pvd;
- ppftcrop.phu = pft.phu;
- }
- // not all past 20 years without vernendoccurred: too cold
- else if (!(gridcellpft.last_verndate20 == gridcellpft.last_springdate20 + def_verndate_ndays_after_last_springdate
- && gridcellpft.last_verndate == gridcellpft.last_verndate20)) {
- // pvd (required vernalising days): undocumented equations from Bondeau's code
- // vernalization (below 12 degrees) is supposed to occur directly at sowing (trg=tempautumn) for TeWW, for TeRa a 20-day lag (tempautumn=17)
- // first_autumndate20 occurred before last_verndate20
- if ((ppftcrop.sdate < 180 || gridcellpft.last_verndate20 >= 180) && climate.lat >= 0.0 || climate.lat < 0.0) {
- ppftcrop.pvd = (int)max(0, min(max_pvd, gridcellpft.last_verndate20 - ppftcrop.sdate - pft.vern_lag));
- }
- // first_autumndate20 occurred after last_verndate20
- else {
- ppftcrop.pvd = (int)max(0, min(max_pvd, gridcellpft.last_verndate20 + date.year_length() - ppftcrop.sdate - pft.vern_lag));
- }
- // phu (potential heat units): quadratic calculation according to sowing month; see Fig.2 in Bondeau et al.2007
- const double k1 = -0.1081;
- const double k2 = 3.1633;
- if (ppftcrop.sdate < 184 + climate.adjustlat) {
- ppftcrop.phu = max(pft.phu_min, k1 * pow((double)(ppftcrop.sdate - climate.adjustlat),2) + k2 * ((double)(ppftcrop.sdate - climate.adjustlat)) + pft.phu_max);
- }
- else {
- ppftcrop.phu = max(pft.phu_min, k1 * pow((double)ppftcrop.sdate - date.year_length(),2) + k2 * ((double)ppftcrop.sdate - 365) + pft.phu_max);
- ppftcrop.phu *= pft.phu_red_spring_sow; // undocumented reduction in spring variants from Bondeau's code
- }
- }
- }
- else { // spring sowing
- // default pvd of spring varieties when vernalisation has not occurred during the past 20 years
- const int pvd_def_spring = 30;
- // phu of spring varieties when vernalisation has occurred during the past 20 years
- const double phu_spring_ifvern = 1300.0;
- // phu of spring varieties when vernalisation has not occurred during the past 20 years
- const double phu_spring_ifnvern = 1500.0;
- // If last_verndate has occurred during the past 20 years (or too warm):
- if (!(gridcellpft.last_verndate20 == ppftcrop.sdate + def_verndate_ndays_after_last_springdate
- && gridcellpft.last_verndate == gridcellpft.last_verndate20)) {
- ppftcrop.pvd = (int)min(max_pvd, gridcellpft.last_verndate20 - ppftcrop.sdate);
- ppftcrop.phu = phu_spring_ifvern;
- }
- // If no last_verndate occurred during the past 20 year (too cold):
- else {
- ppftcrop.pvd = pvd_def_spring;
- ppftcrop.phu = phu_spring_ifnvern;
- }
- }
- }
- else {
- // phu: Linear calculation according to sowing month; see Fig.2 in Bondeau et al.2007
- if (pft.phu_calc_lin) {
- ppftcrop.phu = min(pft.phu_max, max(pft.phu_min, -(pft.phu_max - pft.phu_min) / pft.ndays_ramp_phu * (double)(ppftcrop.sdate - climate.adjustlat) + pft.phu_interc));
- }
- }
- // Calculation of potential heat units according to local climate.
- if (ifcalcdynamic_phu) {
- const double min_phu = 900.0; // minimum allowed phu based on phu range in the literature
- const int min_phu_sample_period = 20; // minimum no. of years of the phu sample period
- // add last year's husum_max to running 10-year mean
- if (ppftcrop.husum_max) {
- ppftcrop.nyears_hu_sample++;
- int years = min(ppftcrop.nyears_hu_sample, 10);
- ppftcrop.husum_max_10 = (ppftcrop.husum_max_10 * (years - 1) + ppftcrop.husum_max) / years;
- }
- ppftcrop.husum_max = 0.0;
- ppftcrop.phu_old = ppftcrop.phu; // phu_old for printout
- // set phu according to running mean
- if (ppftcrop.nyears_hu_sample)
- ppftcrop.phu = max(min_phu, 0.9 * ppftcrop.husum_max_10);
- // ... unless past specified time period
- if (ifdyn_phu_limit && patch.stand.get_gridcell().getsimulationyear(date.year) >= patch.stand.first_year + min_phu_sample_period && patch.stand.get_gridcell().getsimulationyear(date.year) >= nyear_spinup + nyear_dyn_phu)
- ppftcrop.phu = phu_last_year;
- }
- }
- /// Calculation of harvest index
- /** Based on fphu. Restricted by water stress.
- * SWAT equations are from Neitsch et al. 2002.
- */
- void harvest_index(Patch& patch, Pft& pft) {
- double wdf, fwdf, hi_save;
- Patchpft& patchpft = patch.pft[pft.id];
- cropphen_struct& ppftcrop = *(patchpft.get_cropphen());
- ppftcrop.hi = pft.hiopt * 100 * ppftcrop.fphu / (100 * ppftcrop.fphu + exp(11.1 - 10.0 * ppftcrop.fphu)); // SWAT 5:2.4.1
- ppftcrop.fhi_phen = ppftcrop.hi / pft.hiopt;
- // Correction of HI according to water stress:
- ppftcrop.demandsum_crop += patch.wdemand;
- if (patchpft.wsupply > patch.wdemand)
- ppftcrop.supplysum_crop += patch.wdemand;
- else
- ppftcrop.supplysum_crop += patchpft.wsupply;
- if (ppftcrop.demandsum_crop > 0.0)
- wdf = 100.0 * ppftcrop.supplysum_crop / ppftcrop.demandsum_crop; // SWAT 5:3.3.2 : aetsum/petsum
- else
- wdf = 100.0;
- fwdf = wdf / (wdf + exp(6.13 - 0.0883 * wdf)); // (SWAT 5:3.3.1)
- hi_save = ppftcrop.hi;
- ppftcrop.hi = ppftcrop.fhi_phen * ((pft.hiopt - pft.himin) * fwdf + pft.himin);
- if (ppftcrop.hi > 0.0 && hi_save)
- ppftcrop.fhi_water = ppftcrop.hi / hi_save;
- ppftcrop.fhi = ppftcrop.fhi_phen * ppftcrop.fhi_water;
- }
- /// Calculation of accumulated of heat units
- /** Accumulation of heat units during sampling period used for calculation of
- * dynamic phu if ifcalcdynamic_phu = true. SWAT equation is from Neitsch et al. 2002
- */
- void heat_units(Patch& patch, Pft& pft) {
- Patchpft& patchpft = patch.pft[pft.id];
- cropphen_struct& ppftcrop = *(patchpft.get_cropphen());
- const Climate& climate = patch.get_climate();
- // calculation av fphu:
- double hu = max(0.0, min(climate.temp, MAXHUTEMP) - ppftcrop.tb);
- // account for vernalization if needs for vernalization not yet satisfied //trg=tb for crops other than TeWW and TeRa and don't enter here
- if (climate.temp < pft.trg && ppftcrop.vdsum < ppftcrop.pvd) { //trg=12 for TeWW & TeRa
- ppftcrop.vdsum++;
- ppftcrop.vrf = min(1.0, (double)ppftcrop.vdsum / (double)ppftcrop.pvd);
- // vernalisation reduction factor has no effect once temp>trg even if needs are not satisfied
- // no effect as well if temp>trg at the beginning of the growing season...
- hu *= ppftcrop.vrf;
- }
- // account for response to photoperiod
- ppftcrop.prf = (1 - pft.psens) * min(1.0, max(0.0, (climate.daylength_save[date.day] - pft.pb) / (pft.ps - pft.pb))) + pft.psens;
- hu *= ppftcrop.prf;
- if (date.day == ppftcrop.sdate) {
- ppftcrop.husum = 0.0;
- }
- // Accumulate heat units during growing period
- if (ppftcrop.growingseason) {
- // daily effective temperature sum (degree-days)
- ppftcrop.husum += hu;
- // phenological scale (fraction of growing season)
- ppftcrop.fphu = min(1.0, ppftcrop.husum / ppftcrop.phu); // SWAT 5:2.1.11
- }
- // Sample heat units for dynamic phu calculation
- if (ifcalcdynamic_phu) {
- if (date.day == ppftcrop.sdate) {
- ppftcrop.hu_samplingperiod = true;
- ppftcrop.hu_samplingdays = 0;
- ppftcrop.husum_sampled = 0;
- }
- if (ppftcrop.hu_samplingperiod) {
- ppftcrop.husum_sampled += hu;
- ppftcrop.hu_samplingdays++;
- if (date.day == ppftcrop.hucountend) {
- ppftcrop.husum_sampled -= hu; // Don't count the hu's on last day
- ppftcrop.husum_max = ppftcrop.husum_sampled;
- ppftcrop.hu_samplingperiod = false;
- }
- }
- }
- }
- /// Temperature factor used in development stage calculation
- inline double temperature_factor(double temp, double min, double opt, double max) {
- if (temp <= min || temp >= max) {
- return 0;
- }
- double _opt = opt - min;
- double alpha = log(2.) / log((max - min) / _opt);
- return (2 * pow(temp - min, alpha) * pow(_opt, alpha) - pow(temp - min, 2*alpha))/
- pow(_opt, 2*alpha);
- }
- /// Calculation of development stage
- /** Accumulation of development during sampling period, based on Wang & Engel 1998.
- */
- void development_stage(Patch& patch, Pft& pft) {
- Patchpft& patchpft = patch.pft[pft.id];
- cropphen_struct& ppftcrop = *(patchpft.get_cropphen());
- const Climate& climate = patch.get_climate();
- // account for vernalization if needs for vernalization not yet satisfied //trg=tb for crops other than TeWW and TeRa and don't enter here
- if (ppftcrop.vdsum_alloc < 1 && climate.temp > pft.T_vn_min && climate.temp < pft.T_vn_max) {
- ppftcrop.vd += temperature_factor(climate.temp, pft.T_vn_min, pft.T_vn_opt, pft.T_vn_max);
- double vd5 = pow(ppftcrop.vd, 5.);
- ppftcrop.vdsum_alloc = min(1.0, vd5 / (pow(22.5, 5.0) + vd5));
- }
- double daylength = max(0.0, climate.daylength_save[date.day] - pft.photo[0]);
- double e = exp(-pft.photo[1] * daylength);
- double fP = min(1.0, pft.photo[2] > 0 ? e : 1.0 - e);
- double T_min = pft.T_veg_min;
- double T_opt = pft.T_veg_opt;
- double T_max = pft.T_veg_max;
- if (ppftcrop.dev_stage >= 1) {
- T_min = pft.T_rep_min;
- T_opt = pft.T_rep_opt;
- T_max = pft.T_rep_max;
- }
- double fT = min(1.0, temperature_factor(climate.temp, T_min, T_opt, T_max));
- double dev_rate = 0.0;
- if (ppftcrop.dev_stage < 1.0)
- dev_rate = pft.dev_rate_veg * ppftcrop.vdsum_alloc * fP * fT;
- else
- dev_rate = pft.dev_rate_rep * fT;
- ppftcrop.dev_stage = min(2.0, ppftcrop.dev_stage + dev_rate);
- }
- /// Handles heat unit and harvest index calculation and identifies harvest, senescence and intercrop events.
- /** Accumulation of heat units during sampling period used for calculation of dynamic phu if DYNAMIC_PHU defined.
- * Sets patchpft.cropphen variables growingseason, hdate, intercropseason and senescence
- */
- void crop_phenology(Patch& patch) {
- patch.pft.firstobj();
- while (patch.pft.isobj) {
- Patchpft& patchpft = patch.pft.getobj();
- Pft& pft=patchpft.pft;
- Standpft& standpft = patch.stand.pft[pft.id];
- Gridcell& gridcell = patch.stand.get_gridcell();
- Climate& climate = gridcell.climate;
- Gridcellpft& gridcellpft = gridcell.pft[pft.id];
- if (patch.stand.pft[pft.id].active) {
- if (pft.phenology == CROPGREEN) {
- cropphen_struct& ppftcrop = *(patchpft.get_cropphen());
- ppftcrop.growingseason_ystd = ppftcrop.growingseason;
- // resets on first day of the year:
- if (date.day == 0) {
- ppftcrop.fphu_harv = -1.0;
- ppftcrop.fhi_harv = -1.0;
- ppftcrop.sdate_harv = -1;
- ppftcrop.nsow = 0;
- ppftcrop.sendate = -1;
- ppftcrop.nharv = 0;
- ppftcrop.sownlastyear=false;
- for(int i=0;i<2;i++) {
- ppftcrop.sdate_harvest[i] = -1;
- ppftcrop.hdate_harvest[i] = -1;
- ppftcrop.sdate_thisyear[i] = -1;
- }
- }
- // initiations on sowing day:
- if (date.day == ppftcrop.sdate) {
- ppftcrop.fphu = 0.0;
- ppftcrop.fhi = 0.0;
- ppftcrop.fhi_phen = 0.0;
- ppftcrop.fhi_water = 1.0;
- ppftcrop.hdate = -1;
- ppftcrop.bicdate = -1;
- ppftcrop.growingseason = true;
- ppftcrop.growingdays = 0;
- ppftcrop.nsow++;
- if (ppftcrop.nsow == 1)
- ppftcrop.sdate_thisyear[0] = ppftcrop.sdate;
- else if (ppftcrop.nsow == 2)
- ppftcrop.sdate_thisyear[1] = ppftcrop.sdate;
- // calculate pvd, phu & tb
- phu_init(ppftcrop, gridcellpft, patch);
- }
- // Calculation of accumulated heat units and harvest index from sowing to maturity
- if (ppftcrop.growingseason) {
- ppftcrop.senescence_ystd = ppftcrop.senescence;
- ppftcrop.intercropseason = false;
- ppftcrop.growingdays++;
- // check if harvest is prescribed
- bool force_harvest = date.day == standpft.hdate_force;
- // before maturity is reached
- bool pre_maturity = ifnlim ? ppftcrop.dev_stage < 2.0 : ppftcrop.husum < ppftcrop.phu;
- if (pre_maturity && dayinperiod(date.day, ppftcrop.sdate, stepfromdate(ppftcrop.hlimitdate, -1)) && !force_harvest) {
- // count accumulated heat units after sowing date
- heat_units(patch, pft);
- if (ifnlim)
- development_stage(patch, pft);
- // test for senescence
- if (ppftcrop.fphu >= pft.fphusen) {
- if (ppftcrop.senescence_ystd == false)
- ppftcrop.sendate = date.day;
- ppftcrop.senescence = true;
- }
- // calculated harvest index
- harvest_index(patch, pft);
- }
- else { // harvest
- // save today as harvest day
- ppftcrop.hdate = date.day;
- ppftcrop.growingseason = false;
- ppftcrop.intercropseason = false;
- ppftcrop.senescence = false;
- ppftcrop.fertilised[0] = false;
- ppftcrop.fertilised[1] = false;
- ppftcrop.fertilised[2] = false;
- // set start of intercrop grass growth
- ppftcrop.bicdate = stepfromdate(ppftcrop.hdate, 15);
- // count number of harvest events this year
- ppftcrop.nharv++;
- // Save phenological values and dates at harvest:
- ppftcrop.fphu_harv = ppftcrop.fphu;
- ppftcrop.fhi_harv = ppftcrop.fhi;
- ppftcrop.sdate_harv = ppftcrop.sdate;
- ppftcrop.lgp = ppftcrop.growingdays;
- // allowing saving at two harvests per year
- if (ppftcrop.nharv == 1) {
- ppftcrop.sdate_harvest[0] = ppftcrop.sdate;
- ppftcrop.hdate_harvest[0] = date.day;
- if (ppftcrop.sdate > date.day)
- ppftcrop.sownlastyear = true;
- }
- else if (ppftcrop.nharv == 2) {
- ppftcrop.sdate_harvest[1] = ppftcrop.sdate;
- ppftcrop.hdate_harvest[1] = date.day;
- }
- ppftcrop.demandsum_crop = 0.0;
- ppftcrop.supplysum_crop = 0.0;
- ppftcrop.sdate = -1;
- ppftcrop.eicdate = -1;
- } //end harvest
- } //from sowing has taken place until harvest day
- // continue sampling heat units from hdate until last sampling date
- if (ifcalcdynamic_phu && ppftcrop.growingseason == false && ppftcrop.hu_samplingperiod) {
- heat_units(patch, pft);
- }
- if (patch.stand.pftid == pft.id && stlist[patch.stand.stid].intercrop == NATURALGRASS) {
- if (!ppftcrop.intercropseason && date.day == ppftcrop.bicdate) {
- ppftcrop.intercropseason = true;
- }
- if (date.day == ppftcrop.eicdate) {
- ppftcrop.intercropseason = false;
- }
- }
- }
- else if (pft.phenology == ANY) { // crop grasses using standard guess phenology calculation
- if (patch.stand.pftid != pft.id) {
- cropphen_struct& ppftcrop = *(patchpft.get_cropphen());
- if (date.day == 0) {
- ppftcrop.nharv = 0;
- }
- if (date.day == patch.pft[patch.stand.pftid].cropphen->bicdate) {
- ppftcrop.growingseason = true;
- ppftcrop.growingdays = 0;
- }
- else if (date.day == patch.pft[patch.stand.pftid].cropphen->eicdate) {
- ppftcrop.growingseason = false;
- ppftcrop.lgp = ppftcrop.growingdays;
- }
- if (ppftcrop.growingseason == true) {
- ppftcrop.growingdays++;
- }
- }
- }
- }
- patch.pft.nextobj();
- }
- }
- /// Updates crop phen from yesterday's lai_daily
- /** True crops derive phen from yesterday's fpc_daily, assuming only one crop individual.
- * Intercrop grass and pasture grass grown in crop stands use gdd5 and is treated
- * similar to pasture grass.
- */
- void leaf_phenology_crop(Pft& pft, Patch& patch) {
- Gridcell& gridcell = patch.stand.get_gridcell();
- Climate& climate = gridcell.climate;
- Patchpft& patchpft = patch.pft[pft.id];
- cropphen_struct& ppftcrop = *(patchpft.get_cropphen());
- if (pft.phenology == CROPGREEN) {
- if (ppftcrop.growingseason) {
- Vegetation& vegetation = patch.vegetation;
- vegetation.firstobj();
- while (vegetation.isobj) {
- Individual& indiv = vegetation.getobj();
- if (indiv.pft.id == pft.id) {
- patchpft.phen = indiv.fpc ? indiv.fpc_daily / indiv.fpc : 0;
- }
- vegetation.nextobj();
- }
- }
- else if (date.day == ppftcrop.hdate) {
- patchpft.phen = 0.0;
- }
- }
- else if (pft.phenology == ANY) { // crop grasses using standard guess phenology calculation
- if (patch.stand.pftid == pft.id // pasture grass in crop stand
- || patch.stand.hasgrassintercrop && (patch.pft[patch.stand.pftid].cropphen->intercropseason // intercrop grass
- || date.day == patch.pft[patch.stand.pftid].cropphen->eicdate)) { // intercrop grass
- if (patch.stand.pftid != pft.id) {
- if (date.day == patch.pft[patch.stand.pftid].cropphen->bicdate) {
- patch.stand.gdd0_intercrop = climate.gdd5;
- }
- if (date.day == patch.pft[patch.stand.pftid].cropphen->eicdate) {
- patch.stand.gdd0_intercrop = 0.0;
- patchpft.phen = 0.0;
- }
- }
- // reset stand.gdd0_intercrop same day as gdd5
- if (climate.lat >= 0.0 && date.day == COLDEST_DAY_NHEMISPHERE
- || climate.lat < 0.0 && date.day == COLDEST_DAY_SHEMISPHERE
- || climate.gdd5 == 0.0) {
- patch.stand.gdd0_intercrop = 0.0;
- }
- if (ppftcrop.growingseason) { // includes bicdate, not eicdate
- if (patch.stand.pftid == pft.id || gridcell.pft[patch.stand.pftid].sowing_restriction) { // Normal grass growth: gives identical result to natural stands.
- patchpft.phen = min(1.0, climate.gdd5 / pft.phengdd5ramp);
- }
- else if (patch.stand.gdd0_intercrop > 0.0) {
- patchpft.phen = min(1.0, (climate.gdd5 - patch.stand.gdd0_intercrop) / (pft.phengdd5ramp * 0.9)); // intercrop grass
- }
- else {
- patchpft.phen = min(1.0, (climate.gdd5 - patch.stand.gdd0_intercrop) / pft.phengdd5ramp); // intercrop grass
- }
- if (patchpft.phen < 0.0) {
- patchpft.phen = 0.0;
- }
- // raingreen phenology
- if (patchpft.wscal < pft.wscal_min) {
- patchpft.phen = 0.0;
- patch.stand.gdd0_intercrop = climate.gdd5;
- }
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- // REFERENCES
- //
- // Bondeau A, Smith PC, Zaehle S, Schaphoff S, Lucht W, Cramer W, Gerten D, Lotze-Campen H,
- // Müller C, Reichstein M & Smith B 2007. Modelling the role of agriculture for the
- // 20th century global terrestrial carbon balance. Global Change Biology, 13:679-706.
- // Lindeskog M, Arneth A, Bondeau A, Waha K, Seaquist J, Olin S, & Smith B 2013.
- // Implications of accounting for land use in simulations of ecosystem carbon cycling
- // in Africa. Earth Syst Dynam 4:385-407.
- // Neitsch SL, Arnold JG, Kiniry JR et al.2002 Soil and Water Assessment Tool, Theorethical
- // Documentation + User's Manual. USDA_ARS-SR Grassland, Soil and Water Research Laboratory.
- // Agricultural Reasearch Service, Temple,Tx, US.
- // Wang, E. and Engel, T. 1998 Simulation of phenological development
- // of wheat crops, Agr. Syst., 58, 1-24
|