diff --git a/agrolib/hydrall/hydrall.cpp b/agrolib/hydrall/hydrall.cpp index a1a627c0..4d4e7c4f 100644 --- a/agrolib/hydrall/hydrall.cpp +++ b/agrolib/hydrall/hydrall.cpp @@ -17,7 +17,7 @@ Crit3DHydrallMaps::Crit3DHydrallMaps() { mapLAI = new gis::Crit3DRasterGrid; - aboveGroundBiomassMap = new gis::Crit3DRasterGrid; + standBiomassMap = new gis::Crit3DRasterGrid; rootBiomassMap = new gis::Crit3DRasterGrid; mapLast30DaysTavg = new gis::Crit3DRasterGrid; } @@ -25,7 +25,7 @@ Crit3DHydrallMaps::Crit3DHydrallMaps() void Crit3DHydrallMaps::initialize(const gis::Crit3DRasterGrid& DEM) { mapLAI->initializeGrid(DEM); - aboveGroundBiomassMap->initializeGrid(DEM); + standBiomassMap->initializeGrid(DEM); rootBiomassMap->initializeGrid(DEM); mapLast30DaysTavg->initializeGrid(DEM); } @@ -33,14 +33,14 @@ void Crit3DHydrallMaps::initialize(const gis::Crit3DRasterGrid& DEM) Crit3DHydrallMaps::~Crit3DHydrallMaps() { mapLAI->clear(); - aboveGroundBiomassMap->clear(); + standBiomassMap->clear(); rootBiomassMap->clear(); mapLast30DaysTavg->clear(); } bool Crit3D_Hydrall::computeHydrallPoint(Crit3DDate myDate, double myTemperature, double myElevation, int secondPerStep, double &AGBiomass, double &rootBiomass) { - getCO2(myDate, myTemperature, myElevation); + //getCO2(myDate, myTemperature, myElevation); // da qui in poi bisogna fare un ciclo su tutte le righe e le colonne @@ -97,9 +97,65 @@ double Crit3D_Hydrall::photosynthesisAndTranspiration() { TweatherDerivedVariable weatherDerivedVariable; + Crit3D_Hydrall::radiationAbsorption(); + Crit3D_Hydrall::aerodynamicalCoupling(); + Crit3D_Hydrall::upscale(); + + Crit3D_Hydrall::carbonWaterFluxesProfile(); + Crit3D_Hydrall::cumulatedResults(); + return 0; } +double Crit3D_Hydrall::photosynthesisAndTranspirationUnderstorey() +{ + const double rootEfficiencyInWaterExtraction = 1.25e-3; //[kgH2O kgDM-1 s-1] + const double understoreyLightUtilization = 1.77e-9; //[kgC J-1] + double cumulatedUnderstoreyTranspirationRate = 0; + double waterUseEfficiency; //[molC molH2O-1] + + if (understorey.absorbedPAR > EPSILON) + { + waterUseEfficiency = environmentalVariable.CO2 * 0.1875 / weatherVariable.vaporPressureDeficit; + + double lightLimitedUnderstoreyAssimilation; //[molC m-2 s-1] + double waterLimitedUnderstoreyAssimilation; //[molC m-2 s-1] + + lightLimitedUnderstoreyAssimilation = understoreyLightUtilization * understorey.absorbedPAR / MC; //convert units from kgC m-2 s-1 into molC m-2 s-1 + + for (int i = 0; i < soil.layersNr; i++) + { + understoreyTranspirationRate[i] = rootEfficiencyInWaterExtraction * understoreyBiomass.fineRoot * soil.stressCoefficient[i]; + cumulatedUnderstoreyTranspirationRate += understoreyTranspirationRate[i]; + } + + cumulatedUnderstoreyTranspirationRate /= MH2O; //convert units from kgH2O m-2 s-1 into molH2O m-2 s-1 + waterLimitedUnderstoreyAssimilation = cumulatedUnderstoreyTranspirationRate * waterUseEfficiency; + + if (lightLimitedUnderstoreyAssimilation > waterLimitedUnderstoreyAssimilation) + { + understoreyAssimilationRate = waterLimitedUnderstoreyAssimilation; + } + else + { + understoreyAssimilationRate = lightLimitedUnderstoreyAssimilation; + double lightWaterRatio = lightLimitedUnderstoreyAssimilation/waterLimitedUnderstoreyAssimilation; + for (int j = 0; j < soil.layersNr; j++) + { + understoreyTranspirationRate[j] *= lightWaterRatio; + } + } + } + else + { + for (int i = 0; i < understoreyTranspirationRate.size(); i++) + understoreyTranspirationRate[i] = 0; + understoreyAssimilationRate = 0; + } + return 0; +} + + void Crit3D_Hydrall::initialize() { plant.myChlorophyllContent = NODATA; @@ -156,7 +212,7 @@ void Crit3D_Hydrall::setPlantVariables(double chlorophyllContent) plant.myChlorophyllContent = chlorophyllContent; } -void Crit3D_Hydrall::radiationAbsorption(double mySunElevation) +void Crit3D_Hydrall::radiationAbsorption() { // taken from Hydrall Model, Magnani UNIBO @@ -190,6 +246,7 @@ void Crit3D_Hydrall::radiationAbsorption(double mySunElevation) //Leaf area index of sunlit (1) and shaded (2) big-leaf sunlit.leafAreaIndex = UPSCALINGFUNC(directLightExtinctionCoefficient.global,leafAreaIndex); shaded.leafAreaIndex = leafAreaIndex - sunlit.leafAreaIndex ; + understorey.leafAreaIndex = 0.2; //Extinction coefficients for direct and diffuse PAR and NIR radiation, scattering leaves //Based on approximation by Goudriaan 1977 (in Goudriaan & van Laar 1994) double exponent= -pow(10,0.28 + 0.63*log10(plant.myChlorophyllContent*0.85/1000)); @@ -241,6 +298,11 @@ void Crit3D_Hydrall::radiationAbsorption(double mySunElevation) // Isothermal net radiation for sunlit (1) and shaded (2) big-leaf sunlit.isothermalNetRadiation= sunlit.absorbedPAR + sunlitAbsorbedNIR + sunlitAbsorbedLW ; shaded.isothermalNetRadiation = shaded.absorbedPAR + shadedAbsorbedNIR + shadedAbsorbedLW ; + + //TODO: cover + double cover = 1; + understorey.absorbedPAR = (directIncomingPAR + diffuseIncomingPAR - sunlit.absorbedPAR - shaded.absorbedPAR) * cover + (directIncomingPAR + diffuseIncomingPAR) * (1 - cover); + understorey.absorbedPAR *= (1-std::exp(-0.8*understorey.leafAreaIndex)); } else { @@ -252,6 +314,9 @@ void Crit3D_Hydrall::radiationAbsorption(double mySunElevation) sunlitAbsorbedLW = 0.0 ; sunlit.isothermalNetRadiation = 0.0 ; + understorey.absorbedPAR = 0.0; + understorey.leafAreaIndex = 0.0; + shaded.leafAreaIndex = leafAreaIndex; shaded.absorbedPAR = 0.0 ; shadedAbsorbedNIR = 0.0 ; @@ -429,20 +494,6 @@ void Crit3D_Hydrall::upscale() // taken from Hydrall Model, Magnani UNIBO static double BETA = 0.5 ; - //CONSTANTS (only used here) - const double CRD = 18.7; /*!< scaling factor in RD0 response to temperature (-) */ - const double HARD = 46.39; /*!< activation energy of RD0 (kJ mol-1) */ - const double CKC = 38.05; /*!< scaling factor in KCT0 response to temperature (-) */ - const double CKO = 20.30; /*!< scaling factor in KOT0 response to temperature (-) */ - const double HAKO = 36.38; /*!< activation energy of KOT0 (kJ mol-1) */ - const double HAGSTAR = 37.83; /*!< activation energy of Gamma_star (kJ mol-1) */ - const double HAKC = 79.43; /*!< activation energy of KCT0 (kJ mol-1) */ - const double CGSTAR = 19.02; /*!< scaling factor in Gamma_star response to temperature (-) */ - const double HAJM = 43.9; /*!< activation energy of JMOP (kJ mol-1 e-) */ - const double HDEACTIVATION = 200; /*!< deactivation energy from Kattge & Knorr 2007 (kJ mol-1) */ - const double HAVCM = 65.33; /*!< activation energy of VCMOP (kJ mol-1) */ - - double dum[10],darkRespirationT0; double optimalCarboxylationRate,optimalElectronTransportRate ; double leafConvexityFactor ; @@ -454,7 +505,7 @@ void Crit3D_Hydrall::upscale() - // optimalCarboxylationRate = (nitrogen.interceptLeaf + nitrogen.slopeLeaf * nitrogen.leafNitrogen/specificLeafArea*1000)*1e-6; // carboxylation rate based on nitrogen leaf + // optimalCarboxylationRate = (nitrogenContent.interceptLeaf + nitrogenContent.slopeLeaf * nitrogenContent.leafNitrogen/specificLeafArea*1000)*1e-6; // carboxylation rate based on nitrogen leaf optimalCarboxylationRate = maxCarboxRate * 1.0e-6; // [mol m-2 s-1] from Greer et al. 2011 darkRespirationT0 = 0.0089 * optimalCarboxylationRate ; // Adjust unit dark respiration rate for temperature (mol m-2 s-1) @@ -538,22 +589,24 @@ double Crit3D_Hydrall::acclimationFunction(double Ha , double Hd, double leafTem } -/*void Crit3D_Hydrall::carbonWaterFluxesProfile() +void Crit3D_Hydrall::carbonWaterFluxesProfile() { // taken from Hydrall Model, Magnani UNIBO - double assimilationInstant = 0 ; + treeAssimilationRate = 0 ; + + treeTranspirationRate.resize(soil.layersNr); double totalStomatalConductance = 0 ; - for (int i=0; i < modelCase->soilLayersNr; i++) + for (int i=0; i < soil.layersNr; i++) { - transpirationInstantLayer[i] = 0 ; + treeTranspirationRate[i] = 0 ; if(sunlit.leafAreaIndex > 0) { - Crit3D_Hydrall::photosynthesisKernel(modelCase->cultivar, sunlit.compensationPoint, sunlit.minimalStomatalConductance, + Crit3D_Hydrall::photosynthesisKernel(sunlit.compensationPoint, sunlit.aerodynamicConductanceCO2Exchange, sunlit.aerodynamicConductanceHeatExchange, sunlit.minimalStomatalConductance, sunlit.maximalElectronTrasportRate, sunlit.carbonMichaelisMentenConstant, - sunlit.oxygenMichaelisMentenConstant,sunlit.darkRespiration, - alphaLeuning * stressCoefficientProfile[i], sunlit.maximalCarboxylationRate, + sunlit.oxygenMichaelisMentenConstant,sunlit.darkRespiration, sunlit.isothermalNetRadiation, + parameterWangLeuning.alpha * soil.stressCoefficient[i], sunlit.maximalCarboxylationRate, &(sunlit.assimilation), &(sunlit.stomatalConductance), &(sunlit.transpiration)); } @@ -564,21 +617,21 @@ double Crit3D_Hydrall::acclimationFunction(double Ha , double Hd, double leafTem sunlit.transpiration = 0.0; } - assimilationInstant += sunlit.assimilation * modelCase->rootDensity[i] ; - transpirationInstantLayer[i] += sunlit.transpiration * modelCase->rootDensity[i] ; - totalStomatalConductance += sunlit.stomatalConductance * modelCase->rootDensity[i] ; + treeAssimilationRate += sunlit.assimilation * soil.rootDensity[i] ; + treeTranspirationRate[i] += sunlit.transpiration * soil.rootDensity[i] ; + // shaded big leaf - Crit3D_Hydrall::photosynthesisKernel(modelCase->cultivar, shaded.compensationPoint, shaded.minimalStomatalConductance, + Crit3D_Hydrall::photosynthesisKernel(shaded.compensationPoint, shaded.aerodynamicConductanceCO2Exchange,shaded.aerodynamicConductanceHeatExchange, shaded.minimalStomatalConductance, shaded.maximalElectronTrasportRate, shaded.carbonMichaelisMentenConstant, - shaded.oxygenMichaelisMentenConstant,shaded.darkRespiration, - alphaLeuning * stressCoefficientProfile[i], shaded.maximalCarboxylationRate, + shaded.oxygenMichaelisMentenConstant,shaded.darkRespiration, shaded.isothermalNetRadiation, + parameterWangLeuning.alpha * soil.stressCoefficient[i], shaded.maximalCarboxylationRate, &(shaded.assimilation), &(shaded.stomatalConductance), &(shaded.transpiration)); - assimilationInstant += shaded.assimilation * modelCase->rootDensity[i] ; //canopy gross assimilation (mol m-2 s-1) - transpirationInstantLayer[i] += shaded.transpiration * modelCase->rootDensity[i] ; //canopy transpiration (mol m-2 s-1) - totalStomatalConductance += shaded.stomatalConductance * modelCase->rootDensity[i] ; //canopy conductance to CO2 (mol m-2 s-1) + treeAssimilationRate += shaded.assimilation * soil.rootDensity[i] ; //canopy gross assimilation (mol m-2 s-1) + treeTranspirationRate[i] += shaded.transpiration * soil.rootDensity[i] ; //canopy transpiration (mol m-2 s-1) + } -}*/ +} void Crit3D_Hydrall::photosynthesisKernel(double COMP,double GAC,double GHR,double GSCD,double J,double KC,double KO @@ -639,3 +692,122 @@ void Crit3D_Hydrall::photosynthesisKernel(double COMP,double GAC,double GHR,doub *TR = (*GSC / 0.64) * VPDS/weatherVariable.atmosphericPressure ; //Transpiration rate (mol m-2 s-1). Ratio of diffusivities from Wang & Leuning 1998 *TR = MAXVALUE(1.0E-8,*TR) ; } + + +void Crit3D_Hydrall::cumulatedResults() +{ + // taken from Hydrall Model, Magnani UNIBO + // Cumulate hourly values of gas exchange + deltaTime.absorbedPAR = simulationStepInSeconds*(sunlit.absorbedPAR+shaded.absorbedPAR); //absorbed PAR (mol m-2 yr-1) + deltaTime.grossAssimilation = simulationStepInSeconds * treeAssimilationRate ; // canopy gross assimilation (mol m-2) + deltaTime.respiration = simulationStepInSeconds * Crit3D_Hydrall::plantRespiration() ; + deltaTime.netAssimilation = deltaTime.grossAssimilation- deltaTime.respiration ; + deltaTime.netAssimilation = deltaTime.netAssimilation*12/1000.0/CARBONFACTOR ; + + //statePlant.stateGrowth.cumulatedBiomass += deltaTime.netAssimilation ; TODO stand biomass + + deltaTime.transpiration = 0.; + + for (int i=0; i < soil.layersNr; i++) + { + treeTranspirationRate[i] = simulationStepInSeconds * MH2O * treeTranspirationRate[i]; // [mm] + deltaTime.transpiration += treeTranspirationRate[i]; + } + + +} + + +double Crit3D_Hydrall::plantRespiration() +{ + // taken from Hydrall Model, Magnani UNIBO + double leafRespiration,rootRespiration,sapwoodRespiration,shootRespiration ; + double totalRespiration; + nitrogenContent.leaf = 0.02; //[kg kgDM-1] //0.02 * 10^3 [g kgDM-1] + nitrogenContent.root = 0.0078; //[kg kgDM-1] + nitrogenContent.stem = 0.0021; //[kg kgDM-1] + + // Compute hourly stand respiration at 10 oC (mol m-2 h-1) + leafRespiration = 0.0106/2.0 * (treeBiomass.leaf * nitrogenContent.leaf/0.014) / 3600 ; //TODO: CHECK se veramente erano output orari da trasformare in respirazione al secondo + sapwoodRespiration = 0.0106/2.0 * (treeBiomass.sapwood * nitrogenContent.stem/0.014) / 3600 ; + rootRespiration = 0.0106/2.0 * (treeBiomass.fineRoot * nitrogenContent.root/0.014) / 3600 ; + + // Adjust for temperature effects + //leafRespiration *= MAXVALUE(0,MINVALUE(1,Vine3D_Grapevine::temperatureMoistureFunction(myInstantTemp + ZEROCELSIUS))) ; + //sapwoodRespiration *= MAXVALUE(0,MINVALUE(1,Vine3D_Grapevine::temperatureMoistureFunction(myInstantTemp + ZEROCELSIUS))) ; + //shootRespiration *= MAXVALUE(0,MINVALUE(1,Vine3D_Grapevine::temperatureMoistureFunction(myInstantTemp + ZEROCELSIUS))) ; + soil.temperature = Crit3D_Hydrall::soilTemperatureModel(); + rootRespiration *= MAXVALUE(0,MINVALUE(1,Crit3D_Hydrall::temperatureMoistureFunction(soil.temperature + ZEROCELSIUS))) ; + // hourly canopy respiration (sapwood+fine roots) + totalRespiration =(leafRespiration + sapwoodRespiration + rootRespiration); + // per second respiration + totalRespiration /= double(HOUR_SECONDS); + + //TODO understorey respiration + + return totalRespiration; +} + +double Crit3D_Hydrall::soilTemperatureModel() +{ + // taken from Hydrall Model, Magnani UNIBO + double temp; + temp = 0.8 * weatherVariable.last30DaysTAvg + 0.2 * weatherVariable.myInstantTemp; + return temp; +} + +double Crit3D_Hydrall::temperatureMoistureFunction(double temperature) +{ + double temperatureMoistureFactor; + // TODO + /*// taken from Hydrall Model, Magnani UNIBO + int MODEL; + double temperatureMoistureFactor,correctionSoilMoisture; //K_VW + //K_VW= 1.5; + temperatureMoistureFactor = 1. ; + MODEL = 2; + //T = climate.instantT; + //1. AP_H model + if (MODEL == 1) { + + if(psiSoilAverage >= psiFieldCapacityAverage) + { + correctionSoilMoisture = 1.0; //effects of soil water potential + } + else if (psiSoilAverage <= wiltingPoint) + { + correctionSoilMoisture = 0.0; + } + else + { + correctionSoilMoisture = log(wiltingPoint/psiSoilAverage) / log(wiltingPoint/psiFieldCapacityAverage); + } + temperatureMoistureFactor = pow(2.0,((temperature - parameterWangLeuningFix.optimalTemperatureForPhotosynthesis)/10.0)); // temperature dependence of respiration, based on Q10 approach + temperatureMoistureFactor *= correctionSoilMoisture; + } + // 2. AP_LT model + else if (MODEL == 2){ + //effects of soil water potential + if (psiSoilAverage >= psiFieldCapacityAverage) + { + correctionSoilMoisture = 1.0; + } + else if (psiSoilAverage <= wiltingPoint) + { + correctionSoilMoisture = 0.0; + } + else + { + correctionSoilMoisture = log(wiltingPoint/psiSoilAverage) / log(wiltingPoint/psiFieldCapacityAverage); + } + temperatureMoistureFactor= exp(308.56 * (1.0/(parameterWangLeuningFix.optimalTemperatureForPhotosynthesis + 46.02) - 1.0/(temperature+46.02))); //temperature dependence of respiration, based on Lloyd & Taylor (1994) + temperatureMoistureFactor *= correctionSoilMoisture; + }*/ + return temperatureMoistureFactor; +} + +bool Crit3D_Hydrall::growthStand() +{ + + return true; +} diff --git a/agrolib/hydrall/hydrall.h b/agrolib/hydrall/hydrall.h index d88b8dc4..0da86c69 100644 --- a/agrolib/hydrall/hydrall.h +++ b/agrolib/hydrall/hydrall.h @@ -24,6 +24,59 @@ #define KSMAX 2.5E-3 // max. sapwood specific conductivity (m2 MPa-1 s-1) [not relevant] #define PSITHR -2.5 // water potential threshold for cavitation (MPa) [not relevant] + /*! + * Assign physical and miscellaneous constants + */ + + #define CARBONFACTOR 0.5 /*!< coeff for conversion of carbon into DM, kgC kgDM-1 */ + #define GAMMA 66.2 /*!< psychrometer constant, Pa K-1 */ + #define LATENT 43956 /*!< latent heat of vaporization, J mol-1 */ + #define H2OMOLECULARWEIGHT 0.018 /*!< molecular weight of H2O, kg mol-1 */ + #define OSS 21176 /*!< oxygen part pressure in the atmosphere, Pa */ + + /*! + * Define additional photosynthetic parameters + */ + #define HARD 46.39 /*!< activation energy of RD0 (kJ mol-1) */ + #define HAVCM 65.33 /*!< activation energy of VCMOP (kJ mol-1) */ + #define HAJM 43.9 /*!< activation energy of JMOP (kJ mol-1 e-) */ + #define HAKC 79.43 /*!< activation energy of KCT0 (kJ mol-1) */ + #define HAKO 36.38 /*!< activation energy of KOT0 (kJ mol-1) */ + #define HAGSTAR 37.83 /*!< activation energy of Gamma_star (kJ mol-1) */ + #define HDEACTIVATION 200 /*!< deactivation energy from Kattge & Knorr 2007 (kJ mol-1) */ + + #define CRD 18.72 /*!< scaling factor in RD0 response to temperature (-) */ + #define CVCM 26.35 /*!< scaling factor in VCMOP response to temperature (-) */ + #define CVOM 22.98 /*!< scaling factor in VOMOP response to temperature (-) */ + #define CGSTAR 19.02 /*!< scaling factor in Gamma_star response to temperature (-) */ + #define CKC 38.05 /*!< scaling factor in KCT0 response to temperature (-) */ + #define CKO 20.30 /*!< scaling factor in KOT0 response to temperature (-) */ + #define CJM 17.7 /*!< scaling factor in JMOP response to temperature (-) */ + + /*! + * Define additional functional and structural parameters for stand and understorey + */ + #define CONV 0.8 // dry matter conversion efficiency (growth resp.)(-) + #define MERCH 0.85 // merchantable wood as fraction of stem biomass (-) + #define RADRT 1.E-3 // root radius (m) + #define STH0 0.8561 // intercept in self-thinning eq. (log(TREES) vs log(WST)) (m-2) + #define STH1 1.9551 // slope in self-thinning eq. (log(TREES) vs log(WST)) (kgDM-1) + #define ALLRUND 0.5 // coeff of allocation to roots in understorey (-) + + /*! + * Define soil respiration parameters, partition soil C into young and old components + * Note: initial steady-state conditions are assumed (Andren & Katterer 1997) + * Reference respiration rates are for a 'tropical' soil (Andren & Katterer 1997, p. 1231). + */ + #define HUMCOEF 0.125 /*!< humification coefficient (-) */ + #define R0SLO 0.04556 /*!< resp per unit old soil carbon at ref conditions (kgDM kgDM-1 d-1) */ + #define R0SLY 4.228 /*!< resp per unit young soil carbon at ref conditions (kgDM kgDM-1 d-1) */ + #define CHLDEFAULT 500 /*!< [g cm-2] */ + #define RUEGRASS 1.0 /*!< maize: 1.5-2.0, vine: 0.6-1.0 */ + + #define SHADEDGRASS true + #define SUNLITGRASS false + #define NOT_INITIALIZED_VINE -1 @@ -70,13 +123,20 @@ double myLeafWidth; bool isAmphystomatic; + }; struct ThydrallSoil { - int soilLayersNr; - double soilTotalDepth; - double* rootDensity; + int layersNr; + double totalDepth; + double temperature; + std::vector rootDensity; + std::vector stressCoefficient; + std::vector waterContent; + std::vector wiltingPoint; + std::vector fieldCapacity; + std::vector saturation; }; struct TbigLeaf @@ -94,8 +154,7 @@ double carbonMichaelisMentenConstant, oxygenMichaelisMentenConstant ; double compensationPoint, convexityFactorNonRectangularHyperbola ; double quantumYieldPS2 ; - double assimilation,transpiration,stomatalConductance ; - + double assimilation,transpiration,stomatalConductance; }; @@ -109,7 +168,6 @@ double waterStressThreshold; double maxCarboxRate; // Vcmo at optimal temperature - }; struct TlightExtinctionCoefficient @@ -120,12 +178,40 @@ }; + struct ThydrallDeltaTimeOutputs { + + double netAssimilation; + double grossAssimilation ; + double transpiration ; + double interceptedWater ; + double netDryMatter ; + double absorbedPAR ; + double respiration ; + double transpirationGrass; + double transpirationNoStress; + }; + + struct ThydrallNitrogen { + double interceptLeaf, slopeLeaf, leafNitrogen; + double leaf , stem , root; + }; + + struct ThydrallBiomass { + + double total ; + double leaf ; + double sapwood ; + double fineRoot ; + }; + + class Crit3DHydrallMaps { private: public: - gis::Crit3DRasterGrid* aboveGroundBiomassMap; + //sapwood, foliage, fine root + gis::Crit3DRasterGrid* standBiomassMap; gis::Crit3DRasterGrid* rootBiomassMap; gis::Crit3DRasterGrid* mapLAI; gis::Crit3DRasterGrid* mapLast30DaysTavg; @@ -144,7 +230,7 @@ void initialize(); bool writeHydrallMaps; - TbigLeaf sunlit,shaded; + TbigLeaf sunlit,shaded, understorey; TweatherVariable weatherVariable; TenvironmentalVariable environmentalVariable; TparameterWangLeuning parameterWangLeuning; @@ -152,6 +238,9 @@ ThydrallSoil soil; TlightExtinctionCoefficient directLightExtinctionCoefficient; TlightExtinctionCoefficient diffuseLightExtinctionCoefficient; + ThydrallDeltaTimeOutputs deltaTime; + ThydrallNitrogen nitrogenContent; + ThydrallBiomass treeBiomass, understoreyBiomass; @@ -159,12 +248,14 @@ int simulationStepInSeconds; double leafAreaIndex; - double* transpirationInstantLayer; //molH2O m^-2 s^-1 - - + //gasflux results + std::vector treeTranspirationRate; //molH2O m^-2 s^-1 + double treeAssimilationRate; + std::vector understoreyTranspirationRate; + double understoreyAssimilationRate; - void radiationAbsorption(double mySunElevation); + void radiationAbsorption(); void setHourlyVariables(double temp, double irradiance , double prec , double relativeHumidity , double windSpeed, double directIrradiance, double diffuseIrradiance, double cloudIndex, double atmosphericPressure, double CO2, double sunElevation); bool setWeatherVariables(double temp, double irradiance , double prec , double relativeHumidity , double windSpeed, double directIrradiance, double diffuseIrradiance, double cloudIndex, double atmosphericPressure); void setDerivedWeatherVariables(double directIrradiance, double diffuseIrradiance, double cloudIndex); @@ -175,6 +266,7 @@ double getLAI(); double meanLastMonthTemperature(double previousLastMonthTemp, double simulationStepInSeconds, double myInstantTemp); double photosynthesisAndTranspiration(); + double photosynthesisAndTranspirationUnderstorey(); void leafTemperature(); void aerodynamicalCoupling(); double leafWidth(); @@ -182,6 +274,12 @@ double acclimationFunction(double Ha , double Hd, double leafTemp, double entropicTerm,double optimumTemp); void photosynthesisKernel(double COMP,double GAC,double GHR,double GSCD,double J,double KC,double KO ,double RD,double RNI,double STOMWL,double VCmax,double *ASS,double *GSC,double *TR); + void carbonWaterFluxesProfile(); + void cumulatedResults(); + double plantRespiration(); + double soilTemperatureModel(); + double temperatureMoistureFunction(double temperature); + bool growthStand(); }; diff --git a/agrolib/mathFunctions/commonConstants.h b/agrolib/mathFunctions/commonConstants.h index af2c30b0..49a922a7 100644 --- a/agrolib/mathFunctions/commonConstants.h +++ b/agrolib/mathFunctions/commonConstants.h @@ -160,6 +160,8 @@ #define MO2 0.032 // [kg mol-1] mass of molecular nitrogen (N2) #define MN2 0.028 + // [kg mol-1] mass of carbon (C) + #define MC 0.012 // [kg mol-1] mass of air #define M_AIR 0.029 // [K] zero Celsius diff --git a/agrolib/soilFluxes3D/header/soilFluxes3D.h b/agrolib/soilFluxes3D/header/soilFluxes3D.h index 99f69212..51f88845 100644 --- a/agrolib/soilFluxes3D/header/soilFluxes3D.h +++ b/agrolib/soilFluxes3D/header/soilFluxes3D.h @@ -28,7 +28,7 @@ int maxIterationNumber, int maxApproximationsNumber, int errorMagnitude, float MBRMagnitude); - int DLL_EXPORT __STDCALL setThreads(int nrThreads); + __EXTERN int DLL_EXPORT __STDCALL setThreads(int nrThreads); // TOPOLOGY __EXTERN int DLL_EXPORT __STDCALL setNode(long myIndex, float x, float y, double z, double volume_or_area, diff --git a/agrolib/soilFluxes3D/soilFluxes3D.cpp b/agrolib/soilFluxes3D/soilFluxes3D.cpp index 09295d74..5afb5241 100644 --- a/agrolib/soilFluxes3D/soilFluxes3D.cpp +++ b/agrolib/soilFluxes3D/soilFluxes3D.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "commonConstants.h" #include "physics.h" @@ -177,14 +178,19 @@ int DLL_EXPORT __STDCALL setNumericalParameters(float minDeltaT, float maxDeltaT /*! \brief setThreads - sets threads for parallel computing + sets number of threads for parallel computing + if nrThreads < 1, hardware_concurrency get the number of logical processors + returns the number of threads */ int DLL_EXPORT __STDCALL setThreads(int nrThreads) { - if (nrThreads < 1) nrThreads = 1; + if (nrThreads < 1) + { + nrThreads = std::thread::hardware_concurrency(); + } myParameters.threadsNumber = nrThreads; - return CRIT3D_OK; + return nrThreads; }