From 1f750ebe0e30f449092713c68bcba92715679306 Mon Sep 17 00:00:00 2001 From: ebilir Date: Thu, 24 Jul 2025 12:43:59 -0700 Subject: [PATCH 01/30] Thermal updates v1 --- .../DALEC/DALEC_1100/DALEC_1100.c | 29 +++++++++-- .../DALEC/DALEC_ALL/THERMAL_CONDUCTIVITY.c | 48 +++++++++++++++---- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index d53ecb5c..dbe7c115 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -17,6 +17,7 @@ #include "../DALEC_ALL/INITIALIZE_INTERNAL_SOIL_ENERGY.c" #include "../DALEC_ALL/INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS.c" #include "../DALEC_ALL/ALLOC_AND_AUTO_RESP_FLUXES.c" +#include "../DALEC_ALL/THERMAL_CONDUCTIVITY.c" @@ -663,8 +664,30 @@ double moles_per_m3 = Psurf/(Rgas*air_temp_k); // FLUXES[f+F.ground_heat] = G; // W m-2 // FLUXES[f+F.gh_in] = G*DGCM_SEC_DAY; // J m-2 d-1 +//******************Declare THERM STRUCT********************* +Thermal_struct THERM; + + //define time-invariant parameters +THERM.IN.surf_por=pars[P.LY1_por]; +THERM.IN.mid_por=0.5*(pars[P.LY2_por]+pars[P.LY1_por]); +THERM.IN.deep_por=0.5*(pars[P.LY3_por]+pars[P.LY2_por]); +THERM.IN.soil_VWC_surf=POOLS[p+S.D_SM_LY1]; +THERM.IN.soil_VWC_mid=0.5*(POOLS[p+S.D_SM_LY1]+POOLS[p+S.D_SM_LY2]); +THERM.IN.soil_VWC_deep=0.5*(POOLS[p+S.D_SM_LY2]+POOLS[p+S.D_SM_LY3]); +THERM.IN.LF_surf=POOLS[p+S.D_LF_LY1]; +THERM.IN.LF_mid=0.5*(POOLS[p+S.D_LF_LY1]+POOLS[p+S.D_LF_LY2]); +THERM.IN.LF_deep=0.5*(POOLS[p+S.D_LF_LY2]+POOLS[p+S.D_LF_LY3]); +THERM.IN.soil_thermal_conductivity_surf=pars[P.thermal_cond_surf]; +THERM.IN.soil_thermal_conductivity_middeep=pars[P.thermal_cond]; + + //Call function: uses THERM->IN to update THERM->OUT +THERMAL_COND(&THERM); +double therm_cond_surf=THERM.OUT.THERMAL_COND_SURF; +double therm_cond_mid=THERM.OUT.THERMAL_COND_MID; +double therm_cond_deep=THERM.OUT.THERMAL_COND_DEEP; + //Gh_in approach 2 based on soil and LST -FLUXES[f+F.ground_heat] =(pars[P.thermal_cond_surf]* (tskin_k - POOLS[p+S.D_TEMP_LY1])/(pars[P.LY1_z]*0.5))*(1. - POOLS[p+S.D_SCF]); +FLUXES[f+F.ground_heat] =(therm_cond_surf* (tskin_k - POOLS[p+S.D_TEMP_LY1])/(pars[P.LY1_z]*0.5))*(1. - POOLS[p+S.D_SCF]); FLUXES[f+F.gh_in] =FLUXES[f+F.ground_heat] *DGCM_SEC_DAY; //Using G, Rn and LE to derive H // H = Rn - G - LE @@ -799,8 +822,8 @@ FLUXES[f+F.q_ly1_e] = FLUXES[f+F.q_ly1]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS FLUXES[f+F.q_ly2_e] = FLUXES[f+F.q_ly2]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY2]); FLUXES[f+F.q_ly3_e] = FLUXES[f+F.q_ly3]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY3]); //Thermal conductivity = k*dT/dz, units are W/m2, converting to J/m2/d -FLUXES[f+F.ly1xly2_th_e] = 2*pars[P.thermal_cond]* (POOLS[p+S.D_TEMP_LY1] - POOLS[p+S.D_TEMP_LY2])/(pars[P.LY1_z] + pars[P.LY2_z])*DGCM_SEC_DAY; -FLUXES[f+F.ly2xly3_th_e] = 2*pars[P.thermal_cond]* (POOLS[p+S.D_TEMP_LY2] - POOLS[p+S.D_TEMP_LY3])/(pars[P.LY2_z] + pars[P.LY3_z])*DGCM_SEC_DAY; +FLUXES[f+F.ly1xly2_th_e] = 2*therm_cond_mid* (POOLS[p+S.D_TEMP_LY1] - POOLS[p+S.D_TEMP_LY2])/(pars[P.LY1_z] + pars[P.LY2_z])*DGCM_SEC_DAY; +FLUXES[f+F.ly2xly3_th_e] = 2*therm_cond_deep* (POOLS[p+S.D_TEMP_LY2] - POOLS[p+S.D_TEMP_LY3])/(pars[P.LY2_z] + pars[P.LY3_z])*DGCM_SEC_DAY; FLUXES[f+F.geological]=PREDERIVED_GEO_FLUX;//In J/m2/d //105mW/m2 diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/THERMAL_CONDUCTIVITY.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/THERMAL_CONDUCTIVITY.c index d2bb3333..47849dbb 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/THERMAL_CONDUCTIVITY.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/THERMAL_CONDUCTIVITY.c @@ -1,15 +1,47 @@ #pragma once //***Main function*** -double THERMAL_CONDUCTIVITY(double porosity,double soil_water, double soil_liquid_fraction, double soil_temp, double soil_thermal_conductivity){ +typedef struct { + struct {double surf_por; + double mid_por; + double deep_por; + double soil_VWC_surf; + double soil_VWC_mid; + double soil_VWC_deep; + double LF_surf; + double LF_mid; + double LF_deep; + double soil_thermal_conductivity_surf; + double soil_thermal_conductivity_middeep;} IN; + struct {double THERMAL_COND_SURF; + double THERMAL_COND_MID; + double THERMAL_COND_DEEP;} OUT; + }Thermal_struct; -double THERMAL_COND; -double air_cond=0.026;//Conductivity of ar at 0C -double water_cond=0.026;//Conductivity of water at 0C -double ice_cond=0.026;//Conductivity of water at 0C - +int THERMAL_COND(Thermal_struct * S){ + +const double air_cond=0.026;//Conductivity of ar at 0C +const double water_cond=0.57;//Conductivity of water at 0C +const double ice_cond=2.22;//Conductivity of water at 0C +S->OUT.THERMAL_COND_SURF =0; +S->OUT.THERMAL_COND_MID =0; +S->OUT.THERMAL_COND_DEEP =0; + +S->OUT.THERMAL_COND_SURF=((S->IN.surf_por-S->IN.soil_VWC_surf*S->IN.surf_por)*air_cond + // Air contribution + S->IN.surf_por*S->IN.soil_VWC_surf*S->IN.LF_surf*water_cond + // water contribution + S->IN.surf_por*S->IN.soil_VWC_surf*(1-S->IN.LF_surf)*ice_cond + // ice contribution + (1-S->IN.surf_por)*S->IN.soil_thermal_conductivity_surf); // soil contribution + +S->OUT.THERMAL_COND_MID=((S->IN.mid_por-S->IN.soil_VWC_mid*S->IN.mid_por)*air_cond + // Air contribution + S->IN.mid_por*S->IN.soil_VWC_mid*S->IN.LF_mid*water_cond + // water contribution + S->IN.mid_por*S->IN.soil_VWC_mid*(1-S->IN.LF_mid)*ice_cond + // ice contribution + (1-S->IN.mid_por)*S->IN.soil_thermal_conductivity_middeep); // soil contribution + +S->OUT.THERMAL_COND_DEEP=((S->IN.deep_por-S->IN.soil_VWC_deep*S->IN.deep_por)*air_cond + // Air contribution + S->IN.deep_por*S->IN.soil_VWC_deep*S->IN.LF_deep*water_cond + // water contribution + S->IN.deep_por*S->IN.soil_VWC_deep*(1-S->IN.LF_deep)*ice_cond + // ice contribution + (1-S->IN.deep_por)*S->IN.soil_thermal_conductivity_middeep); // soil contribution - //CODE GOES HERE -return THERMAL_COND; + return 0; } From 8cfd6a19333e74ff04e272d123165fa3e7809938 Mon Sep 17 00:00:00 2001 From: ebilir Date: Fri, 25 Jul 2025 15:15:06 -0700 Subject: [PATCH 02/30] cryo-hydro_cond update --- C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index dbe7c115..fe63925f 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -716,9 +716,9 @@ FLUXES[f+F.q_ly3] = HYDROFUN_MOI2EWT(drain_LY3,pars[P.LY3_por],pars[P.LY3_z])*on FLUXES[f+F.q_surf],FLUXES[f+F.q_ly1],FLUXES[f+F.q_ly2],FLUXES[f+F.q_ly3]);*/ // Convert to conductivity -double k_LY1 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY1],pars[P.hydr_cond],pars[P.retention]); -double k_LY2 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY2],pars[P.hydr_cond],pars[P.retention]); -double k_LY3 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY3],pars[P.hydr_cond],pars[P.retention]); +double k_LY1 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY1]*POOLS[p+S.D_LF_LY1]),pars[P.hydr_cond],pars[P.retention]); +double k_LY2 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY2]*POOLS[p+S.D_LF_LY2]),pars[P.hydr_cond],pars[P.retention]); +double k_LY3 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY3]*POOLS[p+S.D_LF_LY3]),pars[P.hydr_cond],pars[P.retention]); // Calculate inter-pool transfer in m/s (positive is LY1 to LY2) double pot_xfer = 1000 * sqrt(k_LY1*k_LY2) * (1e-9*(POOLS[p+S.D_PSI_LY1]-POOLS[p+S.D_PSI_LY2])/(9.8*0.5*(pars[P.LY1_z]+pars[P.LY2_z])) + 1); From 64583314ed755fbd172c00bc0126f34c4ce1d4e8 Mon Sep 17 00:00:00 2001 From: ebilir Date: Wed, 30 Jul 2025 06:33:48 -0700 Subject: [PATCH 03/30] try update geoflux --- C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index fe63925f..21ae30ba 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -279,7 +279,7 @@ double pi=DGCM_PI; //PREDERIVED TERMS - double PREDERIVED_GEO_FLUX=0.105*3600*24; + double PREDERIVED_GEO_FLUX=0.065*3600*24; /*try values from https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/93rg01249*/ double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; From 8080e9166e518423eeeccfb0a0109dca7942f0cb Mon Sep 17 00:00:00 2001 From: ebilir Date: Sat, 9 Aug 2025 18:10:11 -0700 Subject: [PATCH 04/30] update hydro conductivity impact of ice --- .../CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 21ae30ba..659faa66 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -716,9 +716,15 @@ FLUXES[f+F.q_ly3] = HYDROFUN_MOI2EWT(drain_LY3,pars[P.LY3_por],pars[P.LY3_z])*on FLUXES[f+F.q_surf],FLUXES[f+F.q_ly1],FLUXES[f+F.q_ly2],FLUXES[f+F.q_ly3]);*/ // Convert to conductivity -double k_LY1 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY1]*POOLS[p+S.D_LF_LY1]),pars[P.hydr_cond],pars[P.retention]); -double k_LY2 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY2]*POOLS[p+S.D_LF_LY2]),pars[P.hydr_cond],pars[P.retention]); -double k_LY3 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY3]*POOLS[p+S.D_LF_LY3]),pars[P.hydr_cond],pars[P.retention]); +double k_LY1 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY1]*POOLS[p+S.D_LF_LY1])/ //water fraction + (1-POOLS[p+S.D_SM_LY1]+(POOLS[p+S.D_SM_LY1]*POOLS[p+S.D_LF_LY1])), //water + air fraction + pars[P.hydr_cond],pars[P.retention]); +double k_LY2 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY2]*POOLS[p+S.D_LF_LY2])/ + (1-POOLS[p+S.D_SM_LY2]+(POOLS[p+S.D_SM_LY2]*POOLS[p+S.D_LF_LY2])), + pars[P.hydr_cond],pars[P.retention]); +double k_LY3 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY3]*POOLS[p+S.D_LF_LY3])/ + (1-POOLS[p+S.D_SM_LY3]+(POOLS[p+S.D_SM_LY3]*POOLS[p+S.D_LF_LY3])), + pars[P.hydr_cond],pars[P.retention]); // Calculate inter-pool transfer in m/s (positive is LY1 to LY2) double pot_xfer = 1000 * sqrt(k_LY1*k_LY2) * (1e-9*(POOLS[p+S.D_PSI_LY1]-POOLS[p+S.D_PSI_LY2])/(9.8*0.5*(pars[P.LY1_z]+pars[P.LY2_z])) + 1); From d4dd261e07424b33ce1b51562213dd90fd38b287 Mon Sep 17 00:00:00 2001 From: ebilir Date: Tue, 24 Mar 2026 17:09:16 -0700 Subject: [PATCH 05/30] LIU changes test --- .../DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c index 6e5b27c3..176612be 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c @@ -107,22 +107,22 @@ double Rd; PAR = SRAD/(2*Ephoton*NA)*1e6; -double canopy_scale = (1. - exp(-VegK*LAI*clumping))/(VegK); +double canopy_scale = (1. - exp(-VegK*LAI*clumping))/(VegK*clumping); //printf(" \n Initial LAI %f \n ", LAI); //absorbed PAR assuming black canopy. //PAR = PAR*(1. - exp(-LAI*VegK)); -PAR *= (1. - leaf_refl_par)*(1. - exp(-VegK*LAI*clumping)); - +double APAR = PAR*(1. - leaf_refl_par)*(1. - exp(-VegK*LAI*clumping)); //absorbed PAR for non-black canopy +double PAR_leaf = PAR * (1. - leaf_refl_par) * VegK * clumping; //absorbed PAR per unit of leaf at top of canopy (therefore we don't need exponential extinction of light) T_C = TEMP - DGCM_TK0C; // Convert temperature to degrees C Kc = 300.*exp(0.074*(T_C - 25.)); Ko = 300.*exp(0.015*(T_C - 25.)); -cp = 36.9 + 1.18*(T_C - 25.) + 0.36*pow((T_C - 25.), 2.); +cp = 36.9 + 1.18*(T_C - 25.) + 0.036*pow((T_C - 25.), 2.); //Vcmax = vcmax25*exp(50.*(TEMP - 298.)/(298.*R*TEMP)); @@ -136,7 +136,7 @@ Vcmax = vcmax25*pow(q_10,0.1*(T_C-25.))/((1 + exp(0.3*(T_C-(Tupp-DGCM_TK0C))))*( Jmax = Vcmax*exp(1.); -J = (0.3*PAR + Jmax - sqrt(pow(0.3*PAR + Jmax,2) - 4.*0.9*0.3*PAR*Jmax))/2./0.9; +J = (0.3*PAR_leaf + Jmax - sqrt(pow(0.3*PAR_leaf + Jmax,2) - 4.*0.9*0.3*PAR_leaf*Jmax))/2./0.9; medlyn_term = 1. + g1/sqrt(VPD); @@ -168,11 +168,11 @@ Rd_C4 =A->IN.canopyRdsf*vcmax25*fT; //Total photosynthesis -Ag = C3_frac*(Ag_C3) + (1. - C3_frac)*(Ag_C4); -Rd = C3_frac*(Rd_C3) + (1. - C3_frac)*(Rd_C4); +double Ag_leaf = C3_frac*(Ag_C3) + (1. - C3_frac)*(Ag_C4); +double Rd_leaf = C3_frac*(Rd_C3) + (1. - C3_frac)*(Rd_C4); //Potential Rd -double Rd_daily_potential = Rd*canopy_scale*(12.e-6)*(24.*60.*60.); +double Rd_daily_potential = Rd_leaf*canopy_scale*(12.e-6)*(24.*60.*60.); //Ensures NSCs available //A->OUT.LEAF_MORTALITY_FACTOR=fmax( 1- A->IN.NSC/(Rd_daily_potential * A->IN.deltat) ,0); @@ -183,14 +183,14 @@ A->OUT.LEAF_MORTALITY_FACTOR=(1/(exp(A->IN.NSC/(Rd_daily_potential * A->IN.delta } // printf(" \n Rd_pot and NSC: %f %f \n ", Rd_daily_potential * A->IN.deltat, A->IN.NSC); //Actual daily Rd -A->OUT.Rd =Rd_daily_potential*(1 - A->OUT.LEAF_MORTALITY_FACTOR); +A->OUT.Rd =Rd_daily_potential*(1 - A->OUT.LEAF_MORTALITY_FACTOR); //Rd is canopy scaled //Scaling Rd to available NSCs - Rd = Rd *(1 - A->OUT.LEAF_MORTALITY_FACTOR); +double Rd_leaf_lim = Rd_leaf *(1 - A->OUT.LEAF_MORTALITY_FACTOR); //Net A -An = Ag - Rd; +double An_leaf = Ag_leaf - Rd_leaf_lim; @@ -198,8 +198,8 @@ An = Ag - Rd; //double canopy_scale = 1.; //r[0] = An*canopy_scale*(12.e-6)*(24.*60.*60.); //from umolCO2m-2s-1 to gCm-2day-1 -A->OUT.Ag = Ag*canopy_scale*(12.e-6)*(24.*60.*60.); -A->OUT.An = An*canopy_scale*(12.e-6)*(24.*60.*60.); +A->OUT.Ag = Ag_leaf*canopy_scale*(12.e-6)*(24.*60.*60.); +A->OUT.An = An_leaf*canopy_scale*(12.e-6)*(24.*60.*60.); //##################Transpiration################# @@ -220,17 +220,17 @@ SRADg = (1. - 0.5*(leaf_refl_par+leaf_refl_nir))*SRAD*exp(-VegK*LAI*clumping); SRAD = (1. - 0.5*(leaf_refl_par+leaf_refl_nir))*SRAD; -petVnum = (sV*(SRAD-SRADg)+1.225*1000*VPD_kPa*ga)/lambda0*60*60; +petVnum = (sV*(SRAD-SRADg)+1.225*1005*VPD_kPa*ga)/lambda0*60*60; petVnumB = 1.26*(sV*SRADg)/(sV+gammaV)/lambda0*60*60; //from mm.hr-1 if(beta_factor > 0 && SRAD >0){ //Option 1. gs = 1.6*Ag/(co2-ci)*LAI*0.02405; //Option 1. gs = 1.6*An/(co2-ci)*LAI*0.02405; -gs = fmax(0,1.6*An/(co2-ci)*LAI*0.02405); +gs = fmax(0,1.6*An_leaf/(co2-ci)*LAI*0.02405); //transp = petVnum/(sV+gammaV*(1+ga*(1/ga+1/gs))); -transp = petVnum/(sV+gammaV*(1+ga*(1/ga+1/gs))); +transp = petVnum/(sV+gammaV*(ga*(1/ga+1/gs))); @@ -261,4 +261,4 @@ A->OUT.evap = evap*24; //printf("transp = %f, evap = %f\n", r[1], r[2] ); return 0; -} \ No newline at end of file +} From bf0ceb7c3a20cd478c33550fdca576af186ea49b Mon Sep 17 00:00:00 2001 From: ebilir Date: Wed, 25 Mar 2026 12:20:50 -0700 Subject: [PATCH 06/30] More LIU updates: revert canopy scaling, correct leaf scaling, add pointers to lit --- .../DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c index 176612be..8c8bb6be 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c @@ -107,15 +107,17 @@ double Rd; PAR = SRAD/(2*Ephoton*NA)*1e6; -double canopy_scale = (1. - exp(-VegK*LAI*clumping))/(VegK*clumping); +double canopy_scale = (1. - exp(-VegK*LAI*clumping))/(VegK); /*equivalent to Lsun in Li et al 2023 eq. 3 +https://onlinelibrary.wiley.com/doi/10.1111/gcb.16503, with clumping)*/ //printf(" \n Initial LAI %f \n ", LAI); //absorbed PAR assuming black canopy. //PAR = PAR*(1. - exp(-LAI*VegK)); - -double APAR = PAR*(1. - leaf_refl_par)*(1. - exp(-VegK*LAI*clumping)); //absorbed PAR for non-black canopy -double PAR_leaf = PAR * (1. - leaf_refl_par) * VegK * clumping; //absorbed PAR per unit of leaf at top of canopy (therefore we don't need exponential extinction of light) + +double PAR_leaf = PAR * (1. - leaf_refl_par) * VegK; /*absorbed PAR per unit of leaf at top of canopy, derived from de Pury and Farquhar 1997 Eq 20b (no clumping) +(https://biocycle.atmos.colostate.edu/Documents/SiB/De_Pury_1997_Plant_Cell_%26_Environment.pdf) and Li et al 2023 eq. 2 & 3 +https://onlinelibrary.wiley.com/doi/10.1111/gcb.16503, with clumping)*/ T_C = TEMP - DGCM_TK0C; // Convert temperature to degrees C @@ -226,7 +228,7 @@ if(beta_factor > 0 && SRAD >0){ //Option 1. gs = 1.6*Ag/(co2-ci)*LAI*0.02405; //Option 1. gs = 1.6*An/(co2-ci)*LAI*0.02405; -gs = fmax(0,1.6*An_leaf/(co2-ci)*LAI*0.02405); +gs = fmax(0,1.6*An_leaf/(co2-ci)*canopy_scale*0.02405); //transp = petVnum/(sV+gammaV*(1+ga*(1/ga+1/gs))); From 5f5aba8e96e4701c47285877bea4fe5363db45bf Mon Sep 17 00:00:00 2001 From: ebilir Date: Wed, 25 Mar 2026 17:42:55 -0700 Subject: [PATCH 07/30] debug print statements --- .../DALEC/DALEC_1100/DALEC_1100.c | 36 +++++++-- .../DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c | 16 ++-- .../DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c | 80 ++++++++++++------- 3 files changed, 87 insertions(+), 45 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 659faa66..b664186a 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -19,7 +19,7 @@ #include "../DALEC_ALL/ALLOC_AND_AUTO_RESP_FLUXES.c" #include "../DALEC_ALL/THERMAL_CONDUCTIVITY.c" - +static int mcmc_iteration = 0; typedef struct DALEC_1100_DATA_STRUCT{ double * VegK; @@ -64,7 +64,7 @@ double zenith_angle = 90-alpha; double LAD = 0.5; //leaf angle distribution// optimize leaf angle distribution. - VegK[n] = LAD/cos(zenith_angle/180*pi); + VegK[n] = LAD / fmax(0.01, cos(zenith_angle/180*pi)); } @@ -179,10 +179,10 @@ int DALEC_1100_FLUX_SOURCES_SINKS(DALEC * DALECmodel){ FIOMATRIX.SOURCE[F.f_som]=S.C_som; // H2O_SWE + FIOMATRIX.SINK[F.snowfall]=S.H2O_SWE; FIOMATRIX.SOURCE[F.melt]=S.H2O_SWE; FIOMATRIX.SOURCE[F.sublimation]=S.H2O_SWE; - FIOMATRIX.SINK[F.snowfall]=S.H2O_SWE; - + // H2O_LY1 FIOMATRIX.SINK[F.infil]=S.H2O_LY1; FIOMATRIX.SOURCE[F.evap]=S.H2O_LY1; @@ -196,10 +196,10 @@ int DALEC_1100_FLUX_SOURCES_SINKS(DALEC * DALECmodel){ FIOMATRIX.SOURCE[F.ly2xly3]=S.H2O_LY2; FIOMATRIX.SOURCE[F.q_ly2]=S.H2O_LY2; - // H2O_LY3 + // H2O_LY3 + FIOMATRIX.SINK[F.ly2xly3]=S.H2O_LY3; FIOMATRIX.SOURCE[F.q_ly3]=S.H2O_LY3; - FIOMATRIX.SINK[F.ly2xly3]=S.H2O_LY3; - + // E_LY1 FIOMATRIX.SINK[F.gh_in]=S.E_LY1; FIOMATRIX.SINK[F.infil_e]=S.E_LY1; @@ -458,6 +458,8 @@ int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; /*repeating loop for each timestep*/ for (n=0; n < N_timesteps; n++){ + +if (n == 0) { mcmc_iteration++; } /*pool index*/ p=nopools*n; /*next pool index*/ @@ -697,6 +699,26 @@ FLUXES[f+F.sensible_heat] = Rn - FLUXES[f+F.ground_heat] - FLUXES[f+F.latent_hea double liquid_in = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]); FLUXES[f+F.infil] = pars[P.max_infil]*(1 - exp(-liquid_in/pars[P.max_infil])); + // --- START DIAGNOSTIC BLOCK --- + //(DOY between 182 and 213 is roughly July) + if (mcmc_iteration % 10000 == 0 && DOY[n] > 190 && DOY[n] < 200) { + double current_rain = PREC[n] - SNOWFALL[n]; + double current_melt = FLUXES[f+F.melt]; + double total_liquid = current_rain + current_melt; + + printf("\n[MCMC ITER %d] Summer Physics (DOY %g, Timestep %d)\n", mcmc_iteration, DOY[n], n); + printf(" Forcing: PREC=%g | SNOWFALL=%g | (P-S)=%g\n", PREC[n], SNOWFALL[n], current_rain); + printf(" Melt: SKT=%gC | Thresh=%gC | MELT_FLUX=%g\n", SKT[n], pars[P.min_melt]-DGCM_TK0C, current_melt); + printf(" Infil: MAX_INFIL=%g | LIQUID_IN=%g | RESULT=%g\n", pars[P.max_infil], total_liquid, FLUXES[f+F.infil]); + + if (total_liquid <= 0) { + printf(" !! ALERT: Zero water available for infiltration in summer !!\n"); + } + fflush(stdout); + } + // --- END DIAGNOSTIC BLOCK --- + + // Surface runoff (mm/day) FLUXES[f+F.q_surf] = liquid_in - FLUXES[f+F.infil]; diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c index 623aa496..a2fc677a 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c @@ -1,5 +1,5 @@ -// static int attempt_count[100]; -// static int pass_count[100]; +static int attempt_count[100]; +static int pass_count[100]; typedef struct { @@ -23,7 +23,7 @@ double DALEC_EDC_STATE_RANGES(DATA * DATA, void * EDCstruct){ while (PEDC==0 & pnopools & k==0 ){ //looping through timesteps int n=0; - //attempt_count[p]+=1; + attempt_count[p]+=1; while (PEDC==0 & nncdf_data.TIME_INDEX.length & k==0){ @@ -35,16 +35,16 @@ while (PEDC==0 & nncdf_data.TIME_INDEX.length & k==0){ //if (p == 18){printf("E.max_val[p] = %2.2f, E.min_val[p] = %2.2f, SM = %2.2f\n",E.max_val[p], E.min_val[p],DATA->M_POOLS[p+n*DATA->nopools]);} n+=1;} - //if(k==0){pass_count[p]+=1;} + if(k==0){pass_count[p]+=1;} p+=1; } -// if (k==0){ -// for (p=0;pnopools;p++){ -// printf("pool %i; Attempt = %i, Pass = %i, Percent = %2.2f\%\n",p,attempt_count[p], pass_count[p], 100*(double)pass_count[p]/(double)attempt_count[p]); -// }} + // if (k==0){ + // for (p=0;pnopools;p++){ + // printf("pool %i; Attempt = %i, Pass = %i, Percent = %2.2f%%\n",p,attempt_count[p], pass_count[p], 100*(double)pass_count[p]/(double)attempt_count[p]); + // }} //printf("Fail check = %2.2i\n",p); diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c index 09e89ee0..e9a1230e 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c @@ -7,13 +7,18 @@ #include "../../../../math_fun/ipow.c" #include "stdlib.h" #include "stdio.h" +#include "math.h" //***************General inequality EDC****************** //***************DALEC_EDC_PARS_INEQUALITY********* - - +static int traj_attempt_count[100] = {0}; +static int traj_pass_count[100] = {0}; +static int fin_zero_count[100] = {0}; +static int fin_neg_count[100] = {0}; +static int fout_zero_count[100] = {0}; +static int fout_neg_count[100] = {0}; //Doing all pools @@ -72,6 +77,7 @@ for (s=0;sM_POOLS,p,N_timesteps+1,nopools); @@ -131,34 +137,48 @@ for (s=0;snopools; j++) { + if (traj_attempt_count[j] > 0) { + double percent = (100.0 * (double)traj_pass_count[j] / (double)traj_attempt_count[j]); + int total_fails = traj_attempt_count[j] - traj_pass_count[j]; + + printf("pool %2i; Att = %6i, Pass = %6i (%5.2f%%) | Fails: %6i [Fin=0: %6i, Fin<0: %6i | Fout=0: %6i, Fout<0: %6i]\n", + j, traj_attempt_count[j], traj_pass_count[j], percent, + total_fails, fin_zero_count[j], fin_neg_count[j], fout_zero_count[j], fout_neg_count[j]); + } + } + fflush(stdout); + } // printf("PEDC = %2.2f\n",PEDC); return PEDC; } \ No newline at end of file From bfeba4e66c996be2051fd3b3a09b699eb5f4c9d5 Mon Sep 17 00:00:00 2001 From: ebilir Date: Wed, 25 Mar 2026 17:50:23 -0700 Subject: [PATCH 08/30] remove Dx code, retain VegK fix --- .../DALEC/DALEC_1100/DALEC_1100.c | 23 ------ .../DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c | 16 ++-- .../DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c | 80 +++++++------------ 3 files changed, 38 insertions(+), 81 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index b664186a..a9fc3fde 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -19,8 +19,6 @@ #include "../DALEC_ALL/ALLOC_AND_AUTO_RESP_FLUXES.c" #include "../DALEC_ALL/THERMAL_CONDUCTIVITY.c" -static int mcmc_iteration = 0; - typedef struct DALEC_1100_DATA_STRUCT{ double * VegK; double example_const; @@ -458,8 +456,6 @@ int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; /*repeating loop for each timestep*/ for (n=0; n < N_timesteps; n++){ - -if (n == 0) { mcmc_iteration++; } /*pool index*/ p=nopools*n; /*next pool index*/ @@ -699,25 +695,6 @@ FLUXES[f+F.sensible_heat] = Rn - FLUXES[f+F.ground_heat] - FLUXES[f+F.latent_hea double liquid_in = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]); FLUXES[f+F.infil] = pars[P.max_infil]*(1 - exp(-liquid_in/pars[P.max_infil])); - // --- START DIAGNOSTIC BLOCK --- - //(DOY between 182 and 213 is roughly July) - if (mcmc_iteration % 10000 == 0 && DOY[n] > 190 && DOY[n] < 200) { - double current_rain = PREC[n] - SNOWFALL[n]; - double current_melt = FLUXES[f+F.melt]; - double total_liquid = current_rain + current_melt; - - printf("\n[MCMC ITER %d] Summer Physics (DOY %g, Timestep %d)\n", mcmc_iteration, DOY[n], n); - printf(" Forcing: PREC=%g | SNOWFALL=%g | (P-S)=%g\n", PREC[n], SNOWFALL[n], current_rain); - printf(" Melt: SKT=%gC | Thresh=%gC | MELT_FLUX=%g\n", SKT[n], pars[P.min_melt]-DGCM_TK0C, current_melt); - printf(" Infil: MAX_INFIL=%g | LIQUID_IN=%g | RESULT=%g\n", pars[P.max_infil], total_liquid, FLUXES[f+F.infil]); - - if (total_liquid <= 0) { - printf(" !! ALERT: Zero water available for infiltration in summer !!\n"); - } - fflush(stdout); - } - // --- END DIAGNOSTIC BLOCK --- - // Surface runoff (mm/day) FLUXES[f+F.q_surf] = liquid_in - FLUXES[f+F.infil]; diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c index a2fc677a..623aa496 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c @@ -1,5 +1,5 @@ -static int attempt_count[100]; -static int pass_count[100]; +// static int attempt_count[100]; +// static int pass_count[100]; typedef struct { @@ -23,7 +23,7 @@ double DALEC_EDC_STATE_RANGES(DATA * DATA, void * EDCstruct){ while (PEDC==0 & pnopools & k==0 ){ //looping through timesteps int n=0; - attempt_count[p]+=1; + //attempt_count[p]+=1; while (PEDC==0 & nncdf_data.TIME_INDEX.length & k==0){ @@ -35,16 +35,16 @@ while (PEDC==0 & nncdf_data.TIME_INDEX.length & k==0){ //if (p == 18){printf("E.max_val[p] = %2.2f, E.min_val[p] = %2.2f, SM = %2.2f\n",E.max_val[p], E.min_val[p],DATA->M_POOLS[p+n*DATA->nopools]);} n+=1;} - if(k==0){pass_count[p]+=1;} + //if(k==0){pass_count[p]+=1;} p+=1; } - // if (k==0){ - // for (p=0;pnopools;p++){ - // printf("pool %i; Attempt = %i, Pass = %i, Percent = %2.2f%%\n",p,attempt_count[p], pass_count[p], 100*(double)pass_count[p]/(double)attempt_count[p]); - // }} +// if (k==0){ +// for (p=0;pnopools;p++){ +// printf("pool %i; Attempt = %i, Pass = %i, Percent = %2.2f\%\n",p,attempt_count[p], pass_count[p], 100*(double)pass_count[p]/(double)attempt_count[p]); +// }} //printf("Fail check = %2.2i\n",p); diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c index e9a1230e..09e89ee0 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c @@ -7,18 +7,13 @@ #include "../../../../math_fun/ipow.c" #include "stdlib.h" #include "stdio.h" -#include "math.h" //***************General inequality EDC****************** //***************DALEC_EDC_PARS_INEQUALITY********* -static int traj_attempt_count[100] = {0}; -static int traj_pass_count[100] = {0}; -static int fin_zero_count[100] = {0}; -static int fin_neg_count[100] = {0}; -static int fout_zero_count[100] = {0}; -static int fout_neg_count[100] = {0}; + + //Doing all pools @@ -77,7 +72,6 @@ for (s=0;sM_POOLS,p,N_timesteps+1,nopools); @@ -137,48 +131,34 @@ for (s=0;snopools; j++) { - if (traj_attempt_count[j] > 0) { - double percent = (100.0 * (double)traj_pass_count[j] / (double)traj_attempt_count[j]); - int total_fails = traj_attempt_count[j] - traj_pass_count[j]; - - printf("pool %2i; Att = %6i, Pass = %6i (%5.2f%%) | Fails: %6i [Fin=0: %6i, Fin<0: %6i | Fout=0: %6i, Fout<0: %6i]\n", - j, traj_attempt_count[j], traj_pass_count[j], percent, - total_fails, fin_zero_count[j], fin_neg_count[j], fout_zero_count[j], fout_neg_count[j]); - } - } - fflush(stdout); - } + PEDC+=-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow(log(Rs/Rm)/log(1+etol),2); + +// printf("******Pool p = %i *********\n",p); +// +// printf("p = %i\n",s); +// printf("-0.5*pow(log(Rs)/log(EQF),2) = %2.2f\n",-0.5*pow(log(Rs)/log(EQF),2)); +// printf("- 0.5 *pow((Rs-Rm)/etol,2) = %2.2f\n",- 0.5 *pow((Rs-Rm)/etol,2)); +// // +// +// printf("Rs = %2.2f\n",Rs); +// printf("Rm = %2.2f\n",Rm); +// +// printf("log(Rs) = %2.2f\n",log(Rs)); +// +// printf("-0.5*pow(log(Rs)/log(EQF),2) = %2.2f\n",-0.5*pow(log(Rs)/log(EQF),2)); +// printf("Fin = %2.2f\n", Fin); +// printf("dint = %i\n", dint); +// printf("Fout = %2.2f\n", Fout); +// printf("Pstart = %2.2f\n", Pstart); +// printf("Pend = %2.2f\n", Pend); +// printf("MPOOLSjan= %2.2f\n", MPOOLSjan); +// +// printf("EQF P = %2.2f\n", -0.5*pow(log(Rs)/log(EQF),2)); +// printf("Etol P = %2.2f\n", - 0.5 *pow((Rs-Rm)/etol,2)); +// printf("PEDC = %2.2f\n",PEDC); + + } + free(FT); // printf("PEDC = %2.2f\n",PEDC); return PEDC; } \ No newline at end of file From 2adbc20a4937b921fd1c7684f0be6b6b53bca21c Mon Sep 17 00:00:00 2001 From: ebilir Date: Fri, 27 Mar 2026 22:17:11 -0700 Subject: [PATCH 09/30] VegK and gs update --- C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 4 ++-- .../CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index a9fc3fde..ad9a29f2 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -54,7 +54,7 @@ LST=0.5*24*60; double AST = LST+ET1; double h = (AST-12*60)/4; //hour angle double alpha = asin((sin(pi/180*LAT)*sin(pi/180*DA)+cos(pi/180*LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude -double zenith_angle = 90-alpha; +double zenith_angle = fmin(89,90-alpha); //printf("SZA local = %2.2f, SZA global = %2.2f, SZA diff = %2.2f\n", zenith_angle,DATA.ncdf_data.SZA.values,DATA.ncdf_data.SZA.values - zenith_angle); //double LAD = 1.0; //leaf angle distribution @@ -62,7 +62,7 @@ double zenith_angle = 90-alpha; double LAD = 0.5; //leaf angle distribution// optimize leaf angle distribution. - VegK[n] = LAD / fmax(0.01, cos(zenith_angle/180*pi)); + VegK[n] = LAD / cos(zenith_angle/180*pi); } diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c index 8c8bb6be..759de732 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c @@ -228,7 +228,7 @@ if(beta_factor > 0 && SRAD >0){ //Option 1. gs = 1.6*Ag/(co2-ci)*LAI*0.02405; //Option 1. gs = 1.6*An/(co2-ci)*LAI*0.02405; -gs = fmax(0,1.6*An_leaf/(co2-ci)*canopy_scale*0.02405); +gs = fmax(0,1.6*An_leaf/(co2-ci)*LAI*0.02405); //transp = petVnum/(sV+gammaV*(1+ga*(1/ga+1/gs))); From 13910b3e2be5b28223d40597190a55f709039eea Mon Sep 17 00:00:00 2001 From: ebilir Date: Mon, 30 Mar 2026 14:49:40 -0700 Subject: [PATCH 10/30] overhaul hydrology implementation for ice correction --- .../DALEC/DALEC_1100/DALEC_1100.c | 70 +++++++++---------- .../CONVERTERS/HYDROFUN_MOI2CON.c | 18 ++++- .../CONVERTERS/HYDROFUN_MOI2PSI.c | 18 ++++- .../CONVERTERS/HYDROFUN_PSI2LIQ.c | 19 +++++ .../CONVERTERS/HYDROFUN_PSI2MOI.c | 4 +- .../DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c | 51 +++++++++----- 6 files changed, 118 insertions(+), 62 deletions(-) create mode 100644 C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2LIQ.c diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index ee08f5fe..7b5d5d0c 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -306,9 +306,9 @@ POOLS[S.C_cwd]=pars[P.i_cwd]; POOLS[S.C_lit]=pars[P.i_lit]; POOLS[S.C_som]=pars[P.i_som]; /*water pools*/ -POOLS[S.H2O_LY1]=HYDROFUN_MOI2EWT(pars[P.i_LY1_SM],pars[P.LY1_por],pars[P.LY1_z]); -POOLS[S.H2O_LY2]=HYDROFUN_MOI2EWT(pars[P.i_LY2_SM],pars[P.LY2_por],pars[P.LY2_z]); -POOLS[S.H2O_LY3]=HYDROFUN_MOI2EWT(pars[P.i_LY3_SM],pars[P.LY3_por],pars[P.LY3_z]); +POOLS[S.H2O_LY1]=HYDROFUN_MOI2EWT(pars[P.i_LY1_SM],pars[P.LY1_por],pars[P.LY1_z]); //liquid + frozen state +POOLS[S.H2O_LY2]=HYDROFUN_MOI2EWT(pars[P.i_LY2_SM],pars[P.LY2_por],pars[P.LY2_z]); //liquid + frozen state +POOLS[S.H2O_LY3]=HYDROFUN_MOI2EWT(pars[P.i_LY3_SM],pars[P.LY3_por],pars[P.LY3_z]); //liquid + frozen state POOLS[S.H2O_SWE]=pars[P.i_SWE]; /*Energy pools*/ POOLS[S.E_LY1]=INITIALIZE_INTERNAL_SOIL_ENERGY(pars[P.i_LY1_E], POOLS[S.H2O_LY1], pars[P.LY1_vhc], pars[P.LY1_z] ); @@ -334,16 +334,9 @@ double LY2max=pars[P.LY2_por]*pars[P.LY2_z]*1000; //LY3 capacity in mm double LY3max=pars[P.LY3_por]*pars[P.LY3_z]*1000; //INITIALIZING soil moisture -POOLS[S.D_SM_LY1]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY1],pars[P.LY1_por],pars[P.LY1_z]); //soil moisture LY1 -POOLS[S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY2],pars[P.LY2_por],pars[P.LY2_z]);//soil moisture LY3 -POOLS[S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3 - // Convert to potential - //Min psi ensures large negative psis not resolved by model needlessly - double minpsi=-30; -POOLS[S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY1],psi_porosity,pars[P.retention]),minpsi); -POOLS[S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY2],psi_porosity,pars[P.retention]),minpsi); -POOLS[S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY3],psi_porosity,pars[P.retention]),minpsi); - +POOLS[S.D_SM_LY1]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY1],pars[P.LY1_por],pars[P.LY1_z]); //soil moisture LY1: liquid and frozen state +POOLS[S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY2],pars[P.LY2_por],pars[P.LY2_z]);//soil moisture LY3: liquid and frozen state +POOLS[S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3: liquid and frozen state //******************Declare SOIL_TEMP_AND_LIQUID_FRAC STRUCT********************* SOIL_TEMP_AND_LIQUID_FRAC_STRUCT LY1SOILTEMP, LY2SOILTEMP, LY3SOILTEMP; @@ -361,6 +354,7 @@ SOIL_TEMP_AND_LIQUID_FRAC(&LY1SOILTEMP); //Outputs are in K POOLS[S.D_TEMP_LY1]=LY1SOILTEMP.OUT.TEMP; //In K POOLS[S.D_LF_LY1]=LY1SOILTEMP.OUT.LF; + //LY2 LY2SOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.LY2_vhc]; ;//J/m3/K LY2SOILTEMP.IN.depth = pars[P.LY2_z];//m @@ -384,6 +378,14 @@ SOIL_TEMP_AND_LIQUID_FRAC(&LY3SOILTEMP);//Outputs are in K POOLS[S.D_TEMP_LY3]=LY3SOILTEMP.OUT.TEMP; //In K POOLS[S.D_LF_LY3]=LY3SOILTEMP.OUT.LF; + // Convert to water potential, respecting liquid state only; correcting porosity for ice-filled volume. + //Effectively this corrects MOI to (water frac)/(water + air frac) + //Min psi ensures large negative psis not resolved by model needlessly + double minpsi=-30; +POOLS[S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY1],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY1]),minpsi); //psi reflects liquid state only +POOLS[S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY2],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY2]),minpsi); //psi reflects liquid state only +POOLS[S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY3],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY3]),minpsi); //psi reflects liquid state only + //******************Declare KNORR STRUCT********************* KNORR_ALLOCATION_STRUCT KNORR; @@ -710,10 +712,10 @@ FLUXES[f+F.q_surf] = liquid_in - FLUXES[f+F.infil]; - // Calculate drainage -double drain_LY1 = POOLS[p+S.D_LF_LY1]*DRAINAGE(POOLS[p+S.D_SM_LY1],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); -double drain_LY2 = POOLS[p+S.D_LF_LY2]*DRAINAGE(POOLS[p+S.D_SM_LY2],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); -double drain_LY3 = POOLS[p+S.D_LF_LY3]*DRAINAGE(POOLS[p+S.D_SM_LY3],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + // Calculate drainage: correcting psi for presence of ice occurs within DRAINAGE function +double drain_LY1 = DRAINAGE(POOLS[p+S.D_SM_LY1],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention],POOLS[p+S.D_LF_LY1]); +double drain_LY2 = DRAINAGE(POOLS[p+S.D_SM_LY2],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention],POOLS[p+S.D_LF_LY2]); +double drain_LY3 = DRAINAGE(POOLS[p+S.D_SM_LY3],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention],POOLS[p+S.D_LF_LY3]); // Drainage becomes runoff from pools FLUXES[f+F.q_ly1] = HYDROFUN_MOI2EWT(drain_LY1,pars[P.LY1_por],pars[P.LY1_z])*one_over_deltat; @@ -723,16 +725,10 @@ FLUXES[f+F.q_ly3] = HYDROFUN_MOI2EWT(drain_LY3,pars[P.LY3_por],pars[P.LY3_z])*on /*printf("q_surf = %2.2f, q_ly1 = %2.2f, q_ly2 = %2.2f, q_ly3 = %2.2f\n", FLUXES[f+F.q_surf],FLUXES[f+F.q_ly1],FLUXES[f+F.q_ly2],FLUXES[f+F.q_ly3]);*/ - // Convert to conductivity -double k_LY1 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY1]*POOLS[p+S.D_LF_LY1])/ //water fraction - (1-POOLS[p+S.D_SM_LY1]+(POOLS[p+S.D_SM_LY1]*POOLS[p+S.D_LF_LY1])), //water + air fraction - pars[P.hydr_cond],pars[P.retention]); -double k_LY2 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY2]*POOLS[p+S.D_LF_LY2])/ - (1-POOLS[p+S.D_SM_LY2]+(POOLS[p+S.D_SM_LY2]*POOLS[p+S.D_LF_LY2])), - pars[P.hydr_cond],pars[P.retention]); -double k_LY3 = HYDROFUN_MOI2CON((POOLS[p+S.D_SM_LY3]*POOLS[p+S.D_LF_LY3])/ - (1-POOLS[p+S.D_SM_LY3]+(POOLS[p+S.D_SM_LY3]*POOLS[p+S.D_LF_LY3])), - pars[P.hydr_cond],pars[P.retention]); + // Convert to conductivity: correcting for presence of ice occurs within MOI2CON function +double k_LY1 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY1],pars[P.hydr_cond],pars[P.retention],POOLS[p+S.D_LF_LY1]); +double k_LY2 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY2],pars[P.hydr_cond],pars[P.retention],POOLS[p+S.D_LF_LY2]); +double k_LY3 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY3],pars[P.hydr_cond],pars[P.retention],POOLS[p+S.D_LF_LY3]); // Calculate inter-pool transfer in m/s (positive is LY1 to LY2) double pot_xfer = 1000 * sqrt(k_LY1*k_LY2) * (1e-9*(POOLS[p+S.D_PSI_LY1]-POOLS[p+S.D_PSI_LY2])/(9.8*0.5*(pars[P.LY1_z]+pars[P.LY2_z])) + 1); @@ -743,7 +739,7 @@ SPACEavail=fmax(pars[P.LY2_z]*pars[P.LY2_por]*1e3 - POOLS[p+S.H2O_LY2] + (FLUXES // Available water in LY1 (after runoff, et, and infiltration) H2Oavail=fmax(POOLS[p+S.D_LF_LY1]*POOLS[p+S.H2O_LY1] + (FLUXES[f+F.infil] - FLUXES[f+F.q_ly1] - FLUXES[f+F.evap] - FLUXES[f+F.transp1])*deltat,0); // Maximum transfer flux in mm (actual transfer may be less due to water or space availability) -Max_H2O_xfer= POOLS[p+S.D_LF_LY1]*pot_xfer*DGCM_SEC_DAY*deltat; +Max_H2O_xfer= pot_xfer*DGCM_SEC_DAY*deltat; //liquid fraction accounted for in PSI calculation directly; no need to correct for it here //Minimum of three terms for LY1->LY2 //1. Max_H2O_xfer //2. Available space in LY2 (after runoff) @@ -757,16 +753,14 @@ SPACEavail=fmax(pars[P.LY1_z]*pars[P.LY1_por]*1e3 - POOLS[p+S.H2O_LY1] - (FLUXES // Available water in LY2 after runoff H2Oavail= fmax(POOLS[p+S.D_LF_LY2]*POOLS[p+S.H2O_LY2] - (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); // Maximum transfer flux in mm (actual transfer may be less due to water or space availability) -Max_H2O_xfer= POOLS[p+S.D_LF_LY2]*pot_xfer*DGCM_SEC_DAY*deltat; +Max_H2O_xfer= pot_xfer*DGCM_SEC_DAY*deltat; //liquid fraction accounted for in PSI calculation directly; no need to correct for it here // Reverse sign of previous case FLUXES[f+F.ly1xly2] = -fmin(-Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; TEMPxfer_1to2= POOLS[p+S.D_TEMP_LY2];//In K } - - - // Calculate inter-pool transfer in m/s (positive is LY1 to LY3) + // Calculate inter-pool transfer in m/s (positive is LY2 to LY3) pot_xfer = 1000 * sqrt(k_LY2*k_LY3) * (1e-9*(POOLS[p+S.D_PSI_LY2]-POOLS[p+S.D_PSI_LY3])/(9.8*0.5*(pars[P.LY2_z]+pars[P.LY3_z])) + 1); double TEMPxfer_2to3; if (pot_xfer>0) {//Water is going LY2->LY3 (down) @@ -775,7 +769,7 @@ SPACEavail=fmax(pars[P.LY3_z]*pars[P.LY3_por]*1e3 - POOLS[p+S.H2O_LY3] + FLUXES[ // Available water in LY2 (after runoff, et, and infiltration) H2Oavail=fmax(POOLS[p+S.D_LF_LY2]*POOLS[p+S.H2O_LY2] - (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); // Maximum transfer flux in mm (actual transfer may be less due to water or space availability) -Max_H2O_xfer= POOLS[p+S.D_LF_LY2]*pot_xfer*DGCM_SEC_DAY*deltat; +Max_H2O_xfer= pot_xfer*DGCM_SEC_DAY*deltat; //liquid fraction accounted for in PSI calculation directly; no need to correct for it here //Minimum of three terms for LY2->LY3 //1. Max_H2O_xfer //2. Available space in LY3 (after runoff) @@ -789,7 +783,7 @@ SPACEavail=fmax(pars[P.LY2_z]*pars[P.LY2_por]*1e3 - POOLS[p+S.H2O_LY2] + (FLUXES // Available water in LY3 after runoff H2Oavail= fmax(POOLS[p+S.D_LF_LY3]*POOLS[p+S.H2O_LY3] - FLUXES[f+F.q_ly3]*deltat,0); // Maximum transfer flux in mm (actual transfer may be less due to water or space availability) -Max_H2O_xfer= POOLS[p+S.D_LF_LY3]*pot_xfer*DGCM_SEC_DAY*deltat; +Max_H2O_xfer= pot_xfer*DGCM_SEC_DAY*deltat; //liquid fraction accounted for in PSI calculation directly; no need to correct for it here // Reverse sign of previous case FLUXES[f+F.ly2xly3] = -fmin(-Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; TEMPxfer_2to3= POOLS[p+S.D_TEMP_LY3];//In K @@ -1156,10 +1150,10 @@ POOLS[nxp+S.D_LF_LY3]=LY3SOILTEMP.OUT.LF; POOLS[nxp+S.D_SM_LY1]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY1],pars[P.LY1_por],pars[P.LY1_z]); //soil moisture LY1 POOLS[nxp+S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY2],pars[P.LY2_por],pars[P.LY2_z]);//soil moisture LY2 POOLS[nxp+S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3 - -POOLS[nxp+S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY1],psi_porosity,pars[P.retention]),minpsi); -POOLS[nxp+S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY2],psi_porosity,pars[P.retention]),minpsi); -POOLS[nxp+S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY3],psi_porosity,pars[P.retention]),minpsi); +//Correcting PSI for presence of ice occurs within MOI2PSI function +POOLS[nxp+S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY1],psi_porosity,pars[P.retention], POOLS[nxp+S.D_LF_LY1]),minpsi); +POOLS[nxp+S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY2],psi_porosity,pars[P.retention], POOLS[nxp+S.D_LF_LY2]),minpsi); +POOLS[nxp+S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY3],psi_porosity,pars[P.retention], POOLS[nxp+S.D_LF_LY3]),minpsi); //Isfinite check for 14 progronstic pools only diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c index 2ebeb484..8b676a7e 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c @@ -6,11 +6,25 @@ Convert volumetric soil moisture (m3/m3) to conductivity (m/s) moi - Soil moisture (m3/m3) k0 - saturated hydraulic conductivity (m/s) b - retention parameter +lf - liquid fraction */ -double HYDROFUN_MOI2CON(double moi, double k0, double b){ +double HYDROFUN_MOI2CON(double moi, double k0, double b, double lf){ -double con=k0*pow(moi,2*b+3); +if (lf<=1e-4){ + return 0.0; +} + + // 1. Calculate effective pore volume (fraction of pore volume not occupied by ice) + double ice_sat_tv = moi * (1.0 - lf); + double effective_porosity = 1.0 - ice_sat_tv; + + // 2. Calculate effective liquid saturation + double liq_sat_tv = moi * lf; + double moi_eff = liq_sat_tv / effective_porosity; + + // 3. Calculate unsaturated hydraulic conductivity based on available liquid space + double con = k0 * pow(moi_eff, 2.0 * b + 3.0); return con; } \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c index 539746e9..15f8a7a5 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c @@ -1,4 +1,5 @@ #pragma once +#include /* Convert volumetric soil moisture (m3/m3) to potential (MPa) @@ -6,11 +7,24 @@ Convert volumetric soil moisture (m3/m3) to potential (MPa) moi - Soil moisture (m3/m3) psi_porosity - porosity potential (MPa) b - retention parameter +lf - liquid fraction */ -double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b){ +double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf){ -double psi=psi_porosity*(pow((1/moi),b)); + // Safety check to prevent divide-by-zero + if (lf<=1e-4) return -9999.0; + + // 1. Calculate effective pore volume (fraction of por volume not occupied by ice) + double ice_sat_tv= moi * (1.0 - lf); // Ice fraction of the total pore volume + double effective_porosity = 1.0 - ice_sat_tv; // ice-adjusted pore volume as fraction of total pore volume + + // 2. Calculate effective liquid saturation + double liq_sat_tv = moi * lf; // liquid water fraction of the total pore space volume + double moi_eff = liq_sat_tv / effective_porosity; // liquid water fraction of the ice-adjusted pore space + +// 3. Calculate effective psi +double psi=psi_porosity*(pow((1.0/(moi_eff)),b)); return psi; } \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2LIQ.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2LIQ.c new file mode 100644 index 00000000..f759a71b --- /dev/null +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2LIQ.c @@ -0,0 +1,19 @@ +#pragma once +#include +/* +Convert effective water potential (MPa) to volumetric soil liquid (m3/m3) relative to pore space not occupied by ice +Inputs: +psi_eff - effective water potential (MPa) of the liquid-saturated state (i.e. corrected for ice volume) +psi_porosity - porosity potential (MPa) +b - retention parameter + +***NOTE this is mathematically the same as previous PSI2MOI; rename PSI2LIQ intended to clarify its use case in DRAINAGE.c, +the only place that it appears. +*/ + +double HYDROFUN_PSI2LIQ(double psi, double psi_porosity, double b){ + +double moi = pow(psi/psi_porosity,(-1.0/b)); + +return moi; +} \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2MOI.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2MOI.c index b8d6b67a..0f23e09e 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2MOI.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2MOI.c @@ -3,14 +3,14 @@ /* Convert potential (MPa) to volumetric soil moisture (m3/m3) Inputs: -psi - potential (MPa) +psi_eff - effective water potential (MPa) of the liquid-saturated state (i.e. corrected for ice volume) psi_porosity - porosity potential (MPa) b - retention parameter */ double HYDROFUN_PSI2MOI(double psi, double psi_porosity, double b){ -double moi = pow(psi/psi_porosity,(-1/b)); +double moi = pow(psi/psi_porosity,(-1.0/b)); return moi; } \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c index 22183e65..1b6ea3b0 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c @@ -1,6 +1,6 @@ #pragma once #include "math.h" -#include "./CONVERTERS/HYDROFUN_PSI2MOI.c" +#include "./CONVERTERS/HYDROFUN_PSI2LIQ.c" #include "./CONVERTERS/HYDROFUN_MOI2PSI.c" @@ -12,28 +12,43 @@ Qexcess - Excess runoff factor psi_field - field capacity potential (MPa) psi_porosity - porosity potential (MPa) b - retention parameter +lf - liquid fraction of H2O content */ -double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity, double b){ - -// soil moisture at field capacity -double sm_field = HYDROFUN_PSI2MOI(psi_field,psi_porosity,b); - -// check for excessive soil moisture -double excess_drainage = 0; -if (sm > 1) { - excess_drainage = sm - 1; - sm = 1;} - -// change in soil moisture (zero if soil moisture is less than field capacity) -double delta_sm = fmax(sm - sm_field,0); - -// potential of layer -double psi = HYDROFUN_MOI2PSI(sm,psi_porosity,b); +double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity, double b, double lf){ + + // 1. check for excessive soil moisture: drain out sm>1 so that all sm values are <=1, and won't break psi_eff. + // (note that sm>1 only occurs transiently in between time steps and must be in a liquid/drainable state) + double excess_drainage = 0.0; + if (sm > 1.0) { + excess_drainage = sm - 1.0; + sm = 1.0;} + + // 2. Calculate current effective potential of the liquid-saturated state + double psi_eff = HYDROFUN_MOI2PSI(sm, psi_porosity, b, lf); + + // 3. Check for excessive soil moisture: + if (psi_eff <= psi_field) { + return excess_drainage; // Soil is at or drier than field capacity; only excess drainage can leave. + } + + // 4. Calculate drainable liquid volume: + // Calculate effective porosity (fraction of pore space that is ice-free) + double ice_sat_tv = sm * (1.0 - lf); + double effective_porosity = 1.0 - ice_sat_tv; + // Current effective liquid saturation + double sm_eff = HYDROFUN_PSI2LIQ(psi_eff, psi_porosity, b); + // liquid saturation at field capacity + double sm_field = HYDROFUN_PSI2LIQ(psi_field, psi_porosity, b); + + // drainable water in units of effective saturation (zero if soil liquid is less than field capacity) + double delta_sm = fmax(sm_eff - sm_field,0.0); + // drainable water as volume + double delta_sm_liq = delta_sm * effective_porosity; //Matlab line Massoud et al. D= frac_Qexcess * (1- (PARS.psiporosity-min(max(STATES.PSI(t,:),PARS.psifield),PARS.psiporosity))./(PARS.psiporosity-PARS.psifield)).*(SMdelta); // calculate drainage (equals zero if change in soil moisture is zero) -double drainage = excess_drainage + delta_sm * Qexcess * (1 - (psi_porosity - fmin(fmax(psi,psi_field),psi_porosity))/(psi_porosity-psi_field)); +double drainage = excess_drainage + delta_sm_liq * Qexcess * (1.0 - (psi_porosity - fmin(fmax(psi_eff,psi_field),psi_porosity))/(psi_porosity-psi_field)); return drainage; From 8049d7707eaeb235f8dea2f72e723ca255e4f4d8 Mon Sep 17 00:00:00 2001 From: ebilir Date: Mon, 30 Mar 2026 16:59:47 -0700 Subject: [PATCH 11/30] Add new state proximity EDC for constraining thermal gradients --- .../DALEC/DALEC_1100/DALEC_1100.c | 20 +++++- .../DALEC/DALEC_1100/DALEC_1100_INDICES.c | 3 +- .../DALEC/DALEC_EDCs/DALEC_EDC_FUNCTIONS.c | 2 +- .../DALEC_EDCs/DALEC_EDC_STATE_PROXIMITY.c | 72 +++++++++++++++++++ .../DALEC/DALEC_EDCs/DALEC_STATE_PROXIMITY.c | 72 +++++++++++++++++++ 5 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_PROXIMITY.c create mode 100644 C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_STATE_PROXIMITY.c diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 7b5d5d0c..c83703f5 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -1189,7 +1189,7 @@ DALECmodel->nopools=30; DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ DALECmodel->nopars=89; DALECmodel->nofluxes=100; -DALECmodel->noedcs=15; +DALECmodel->noedcs=16; DALEC_1100_FLUX_SOURCES_SINKS(DALECmodel); @@ -1447,7 +1447,25 @@ static DALEC_EDC_MEAN_TEMP_STRUCT EDC_mean_ly1_temp, EDC_mean_ly2_temp, EDC_mean EDCs[E.mean_ly3_temp].function=&DALEC_EDC_MEAN_TEMP; EDCs[E.mean_ly3_temp].prerun=false; +//*************** Set up State Proximity EDC *************** +static DALEC_EDC_STATE_PROXIMITY_STRUCT EDC_prox; +static int prox_pool_indices[3]; // We are checking 3 layers +EDC_prox.pool_indices = prox_pool_indices; +EDC_prox.no_pools_to_check = 3; + +// Assign the diagnostic temperature pools +EDC_prox.pool_indices[0] = S.D_TEMP_LY1; +EDC_prox.pool_indices[1] = S.D_TEMP_LY2; +EDC_prox.pool_indices[2] = S.D_TEMP_LY3; + +// Set your penalty thresholds +EDC_prox.max_allowed_diff = 2.0; // Max allowed difference in degrees K (or C) +EDC_prox.penalty_scale = 1.5; // Steepness of the penalty curve (smaller is more strict) + +EDCs[E.state_proximity].data = &EDC_prox; +EDCs[E.state_proximity].function = &DALEC_EDC_STATE_PROXIMITY; +EDCs[E.state_proximity].prerun = false; //ecological //EDCOPE.SUPPORT_LITCWDSOM_trpar_EDC=true; diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100_INDICES.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100_INDICES.c index 1eba097a..b7902766 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100_INDICES.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100_INDICES.c @@ -286,8 +286,9 @@ int fffr_ratio; int mean_ly1_temp; int mean_ly2_temp; int mean_ly3_temp; +int state_proximity; } DALEC_1100_EDCs={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, - 14 + 14, 15 }; \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_FUNCTIONS.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_FUNCTIONS.c index 15417013..1ef4f95f 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_FUNCTIONS.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_FUNCTIONS.c @@ -14,7 +14,7 @@ #include "DALEC_EDC_FLUX_RATIO.c" #include "DALEC_EDC_MEAN_PAW_TEMP.c" #include "DALEC_EDC_PARAMETER_ZEROONE.c" - +#include "DALEC_EDC_STATE_PROXIMITY.c" diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_PROXIMITY.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_PROXIMITY.c new file mode 100644 index 00000000..aaa2e5fe --- /dev/null +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_PROXIMITY.c @@ -0,0 +1,72 @@ +#pragma once +#include +#include +#include + +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" + +//*************** State Proximity EDC ****************** +// Penalizes the model if the max-min difference among specified pools +// (e.g., annual mean soil temperatures) exceeds a defined threshold. + +typedef struct { + int no_pools_to_check; + int *pool_indices; + double max_allowed_diff; // E.g., 4.0 (degrees C) + double penalty_scale; // E.g., 1.0 (controls steepness of the quadratic penalty) +} DALEC_EDC_STATE_PROXIMITY_STRUCT; + +// General state proximity function +double DALEC_EDC_STATE_PROXIMITY(DATA * DATA, void * EDCstruct){ + + // Correctly cast the generic void pointer to your specific struct pointer + DALEC_EDC_STATE_PROXIMITY_STRUCT * E = (DALEC_EDC_STATE_PROXIMITY_STRUCT *) EDCstruct; + double PEDC = 0.0; + + double *TIME_INDEX = DATA->ncdf_data.TIME_INDEX.values; + DALEC *DALECmodel = (DALEC *)DATA->MODEL; + + int N_timesteps = DATA->ncdf_data.TIME_INDEX.length; + int nopools = DALECmodel->nopools; + double * POOLS = DATA->M_POOLS; + + // Derive deltat from TIME_INDEX (assuming continuous daily or monthly steps) + double deltat_double = TIME_INDEX[1] - TIME_INDEX[0]; + + // mean_annual_pool.c expects an integer deltat (e.g., 1 for daily data) + int deltat = (int)round(deltat_double); + if (deltat < 1) deltat = 1; // Failsafe + + // Calculate total number of complete years to evaluate + int num_years = (int)floor((N_timesteps * deltat_double) / 365.25); + + int yr, s, p; + + // Loop through each complete year + for (yr = 0; yr < num_years; yr++) { + + double min_mean = 1e9; + double max_mean = -1e9; + + // Check each pool for this specific year (using -> operator for pointer access) + for (s = 0; s < E->no_pools_to_check; s++) { + p = E->pool_indices[s]; + double mean_pool_yr = mean_annual_pool(POOLS, yr, p, nopools, deltat); + + // Track the maximum and minimum annual means across the layers + if (mean_pool_yr > max_mean) max_mean = mean_pool_yr; + if (mean_pool_yr < min_mean) min_mean = mean_pool_yr; + } + + double diff = max_mean - min_mean; + + // If the gradient exceeds your physical threshold, apply quadratic penalty + if (diff > E->max_allowed_diff) { + // Evaluates as: -0.5 * ((diff - threshold) / scale)^2 + PEDC += -0.5 * pow((diff - E->max_allowed_diff) / E->penalty_scale, 2.0); + } + } + + return PEDC; +} \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_STATE_PROXIMITY.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_STATE_PROXIMITY.c new file mode 100644 index 00000000..b4d3ab08 --- /dev/null +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_STATE_PROXIMITY.c @@ -0,0 +1,72 @@ +#pragma once +#include +#include +#include + +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" + +//*************** State Proximity EDC ****************** +// Penalizes the model if the max-min difference among specified pools +// (e.g., annual mean soil temperatures) exceeds a defined threshold. + +typedef struct { + int no_pools_to_check; + int *pool_indices; + double max_allowed_diff; // E.g., 4.0 (degrees C) + double penalty_scale; // E.g., 1.0 (controls steepness of the quadratic penalty) +} DALEC_EDC_STATE_PROXIMITY_STRUCT; + +// General state proximity function +double DALEC_EDC_STATE_PROXIMITY(void * data, DATA * DATA, int prerun){ + + // Correctly cast the generic void pointer to your specific struct pointer + DALEC_EDC_STATE_PROXIMITY_STRUCT * E = (DALEC_EDC_STATE_PROXIMITY_STRUCT *) data; + double PEDC = 0.0; + + double *TIME_INDEX = DATA->ncdf_data.TIME_INDEX.values; + DALEC *DALECmodel = (DALEC *)DATA->MODEL; + + int N_timesteps = DATA->ncdf_data.TIME_INDEX.length; + int nopools = DALECmodel->nopools; + double * POOLS = DATA->M_POOLS; + + // Derive deltat from TIME_INDEX (assuming continuous daily or monthly steps) + double deltat_double = TIME_INDEX[1] - TIME_INDEX[0]; + + // mean_annual_pool.c expects an integer deltat (e.g., 1 for daily data) + int deltat = (int)round(deltat_double); + if (deltat < 1) deltat = 1; // Failsafe + + // Calculate total number of complete years to evaluate + int num_years = (int)floor((N_timesteps * deltat_double) / 365.25); + + int yr, s, p; + + // Loop through each complete year + for (yr = 0; yr < num_years; yr++) { + + double min_mean = 1e9; + double max_mean = -1e9; + + // Check each pool for this specific year (using -> operator for pointer access) + for (s = 0; s < E->no_pools_to_check; s++) { + p = E->pool_indices[s]; + double mean_pool_yr = mean_annual_pool(POOLS, yr, p, nopools, deltat); + + // Track the maximum and minimum annual means across the layers + if (mean_pool_yr > max_mean) max_mean = mean_pool_yr; + if (mean_pool_yr < min_mean) min_mean = mean_pool_yr; + } + + double diff = max_mean - min_mean; + + // If the gradient exceeds your physical threshold, apply quadratic penalty + if (diff > E->max_allowed_diff) { + // Evaluates as: -0.5 * ((diff - threshold) / scale)^2 + PEDC += -0.5 * pow((diff - E->max_allowed_diff) / E->penalty_scale, 2.0); + } + } + + return PEDC; +} \ No newline at end of file From 1021b63a46d69fbf42c651e478f64ca6d5c4442b Mon Sep 17 00:00:00 2001 From: ebilir Date: Mon, 30 Mar 2026 18:59:25 -0700 Subject: [PATCH 12/30] try w/o ST EDC for E pools --- C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index c83703f5..d6504a29 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -1372,9 +1372,9 @@ EDC_st.pool_indices[7]=S.H2O_LY1; EDC_st.pool_indices[8]=S.H2O_LY2; EDC_st.pool_indices[9]=S.H2O_LY3; EDC_st.pool_indices[10]=S.H2O_SWE; -EDC_st.pool_indices[11]=S.E_LY1; -EDC_st.pool_indices[12]=S.E_LY2; -EDC_st.pool_indices[13]=S.E_LY3; +// EDC_st.pool_indices[11]=S.E_LY1; +// EDC_st.pool_indices[12]=S.E_LY2; +// EDC_st.pool_indices[13]=S.E_LY3; //EDC_st.pool_indices[12]=S.M_LAI_MAX;``` //EDC_st.pool_indices[13]=S.M_LAI_TEMP; From be00af286d8be290c2e9e2a298b89e7e9c25c40b Mon Sep 17 00:00:00 2001 From: ebilir Date: Thu, 2 Apr 2026 15:11:24 -0700 Subject: [PATCH 13/30] ST EDC update for bidirectional fluxes --- .../DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c index 09e89ee0..c0fbef60 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c @@ -95,9 +95,16 @@ for (s=0;sSIOMATRIX[p].N_STATE_INPUT_FLUXES;i++){Fin += FT[DALECmodel->SIOMATRIX[p].STATE_INPUT_FLUXES[i]];} - for (i=0;iSIOMATRIX[p].N_STATE_OUTPUT_FLUXES;i++){Fout += FT[DALECmodel->SIOMATRIX[p].STATE_OUTPUT_FLUXES[i]];} + double Fin=0, Fout=0, Ftemp=0; + for (i=0;iSIOMATRIX[p].N_STATE_INPUT_FLUXES;i++){ + double Ftemp = FT[DALECmodel->SIOMATRIX[p].STATE_INPUT_FLUXES[i]]; + if (Ftemp<0){Fout +=Ftemp;} + else {Fin += Ftemp;}} + + for (i=0;iSIOMATRIX[p].N_STATE_OUTPUT_FLUXES;i++){ + double Ftemp= FT[DALECmodel->SIOMATRIX[p].STATE_OUTPUT_FLUXES[i]]; + if (Ftemp<0){Fin +=Ftemp;} + else {Fout += Ftemp;}} // // double Fin[10]; From 519d97bdfd4bd5c9a793c879eefb6496d133d580 Mon Sep 17 00:00:00 2001 From: Renato Braghiere Date: Fri, 3 Apr 2026 15:56:53 -0700 Subject: [PATCH 14/30] refactor(LIU_AN_ET): canopy scaling fixes + full documentation Issues: - canopy_scale denominator: /(VegK) -> /(VegK*clumping) Beer's law integral requires 1/(k*Omega), not 1/k; de Pury & Farquhar (1997) PCE 20:537; Bonan (2019) Ch.14 Eq.14.6 - Introduce PAR_leaf = PAR*(1-refl)*k*Omega (leaf-level) replacing PAR *= (1-refl)*(1-exp(-k*Omega*L)) (canopy APAR); keeps a2 (RuBP-limited) at leaf level, consistent with a1 (Rubisco-limited) - J uses PAR_leaf instead of canopy APAR; single canopy_scale applied at output Documentation pass (no numerical changes): - Physical constants (rho_air, Cp_air, eps_mol) extracted and named - All magic numbers explained with units and references: 1.6 (H2O/CO2 diffusivity ratio; Jones 1992), 0.02405 (molar volume of air at 20 C; mol->m/s conversion), 1.26 (Priestley-Taylor alpha; Priestley & Taylor 1972), kai1=0.9 / kai2=0.3 (FvCB curvature/quantum yield), 12e-6 (g C per umol CO2), 86400 s/day, 209 mmol/mol O2 - Variable declarations annotated with units and physical meaning - Section headers for FvCB, canopy scaling, Vcmax/Jmax, C3/C4, PM - References: Farquhar et al. 1980, Bernacchi et al. 2001, Leuning 1997, Medlyn et al. 2011, Monteith 1965, Bonan 2019 --- .../DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c | 297 +++++++++--------- 1 file changed, 157 insertions(+), 140 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c index d0506942..4c6e6ccc 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LIU_AN_ET_REFACTOR.c @@ -64,201 +64,218 @@ double leaf_refl_nir=A->IN.leaf_refl_nir; double maxPevap=A->IN.maxPevap; double precip=A->IN.precip; -//CONSTS -double Ephoton = 2.0e-25/500.0e-9;// Planck constant times speed of light (J.s*m.s-1) divided by light wavelength (m) -double NA = 6.02e23;// Avogadro's constant /mol -double R = 8.31e-3;//Gas constant, kJ/mol/K -double lambda0 = 2.26e6; -double gammaV = 100*1005/(lambda0*0.622); - - -//DATA contains all met forcings - -double PAR; //incident PAR (?) review -double T_C; // air temperature in C -double Kc; //Michaelis-Menten parameter temperature dependent -double Ko; //Michaelis-Menten parameter temperature dependent -double cp; //specific heat capacity of air - -double Vcmax; //the maximum rate of carboxylation of Rubisco -double Jmax; //the maximum rate of electron transport -double J; -double medlyn_term; -double ci; +/* --- Physical and thermodynamic constants --- */ +double Ephoton = 2.0e-25/500.0e-9; // Energy per photon at 500 nm: h*c/lambda (J); h=6.626e-34 J.s, c=3e8 m/s +double NA = 6.02e23; // Avogadro's constant (mol-1) +double R = 8.31e-3; // Universal gas constant (kJ mol-1 K-1) +double lambda0 = 2.26e6; // Latent heat of vaporization of water (J kg-1) +double rho_air = 1.225; // Dry air density at sea level (kg m-3) +double Cp_air = 1005.; // Specific heat of dry air at constant pressure (J kg-1 K-1) +double eps_mol = 0.622; // Ratio of molar mass of water vapour to dry air: Mw/Md = 18.015/28.97 (-) +/* Psychrometric constant gamma = rho_air * Cp_air / (lambda0 * eps_mol) (Pa K-1); + here expressed as a dimensionless coefficient for use with kPa and m s-1 units */ +double gammaV = 100.*Cp_air/(lambda0*eps_mol); // ~0.067 kPa K-1; Monteith & Unsworth 2008 + + +/* --- FvCB photosynthesis state variables --- */ +double PAR; // Incident PAR at canopy top (umol photons m-2 s-1) +double T_C; // Air temperature (deg C) +double Kc; // Michaelis-Menten constant for CO2 (umol mol-1), temperature-dependent +double Ko; // Michaelis-Menten constant for O2 (mmol mol-1), temperature-dependent +double cp; // CO2 compensation point in absence of Rd, Gamma* (umol mol-1) +double Vcmax; // Maximum rate of Rubisco carboxylation at T_C (umol CO2 m-2 s-1) +double Jmax; // Maximum rate of electron transport at T_C (umol e- m-2 s-1) +double J; // Actual electron transport rate (umol e- m-2 s-1) +double medlyn_term; // Medlyn optimal stomatal model factor: 1 + g1/sqrt(VPD); Medlyn et al. 2011 +double ci; // Leaf intercellular CO2 concentration (umol mol-1) //double C3_frac = 1.; //Fraction of C3 per gridcell -double a1; -double a2; - -double Ag_C3; -double Ag_C4; - -double Ag; -double An; - -double Rd_C3; -double Rd_C4; - -double Rd; - -//Array of results with 3 positions for An, E, and Transpiration; -//static double r[3]; - - -PAR = SRAD/(2*Ephoton*NA)*1e6; - - -double canopy_scale = (1. - exp(-VegK*LAI*clumping))/(VegK); +double a1; // Rubisco-limited (co-limited) gross assimilation term (umol CO2 m-2 s-1) +double a2; // Electron-transport-limited gross assimilation term (umol CO2 m-2 s-1) + +double Ag_C3; // Gross assimilation, C3 pathway (leaf-level, umol CO2 m-2 s-1) +double Ag_C4; // Gross assimilation, C4 pathway (leaf-level, umol CO2 m-2 s-1) +double Ag; // Blended gross assimilation (leaf-level, umol CO2 m-2 s-1) +double An; // Net assimilation = Ag - Rd (leaf-level, umol CO2 m-2 s-1) + +double Rd_C3; // Dark respiration, C3 (umol CO2 m-2 s-1) +double Rd_C4; // Dark respiration, C4 (umol CO2 m-2 s-1) +double Rd; // Blended dark respiration (umol CO2 m-2 s-1) + +/* Convert incoming shortwave to incident PAR. + SRAD is total shortwave (W m-2); ~50% is PAR (400-700 nm); dividing by Ephoton*NA + converts W m-2 (= J s-1 m-2) to mol photons m-2 s-1, then *1e6 -> umol photons m-2 s-1. + The factor of 2 accounts for the ~50% PAR fraction of shortwave; Liu et al. myFun.py. */ +PAR = SRAD/(2.*Ephoton*NA)*1e6; + +/* --- Canopy radiation interception --- */ +/* canopy_scale: integral of Beer's law profile int_0^LAI exp(-k*Omega*l) dl + = (1 - exp(-k*Omega*LAI)) / (k*Omega); denominator requires both k AND Omega (clumping); + de Pury & Farquhar (1997) Plant Cell Environ. 20:537; Bonan (2019) Ch. 14 Eq. 14.6 */ +double canopy_scale = (1. - exp(-VegK*LAI*clumping))/(VegK*clumping); // Beer's law integral /(k*Omega), not /(k); de Pury & Farquhar 1997; Bonan Ch. 14 Eq. 14.6 //printf(" \n Initial LAI %f \n ", LAI); -//absorbed PAR assuming black canopy. -//PAR = PAR*(1. - exp(-LAI*VegK)); - -PAR *= (1. - leaf_refl_par)*(1. - exp(-VegK*LAI*clumping)); +/* PAR_leaf: effective leaf-level absorbed PAR for the big-leaf model. + Derived as APAR_canopy / canopy_scale = I_0*(1-rho)*k*Omega; this keeps + all FvCB quantities (a1, a2) at leaf level so canopy_scale is applied only once at output. + Bonan (2019) Ch. 14; Liu et al. myFun.py f_carbon() */ +double PAR_leaf = PAR * (1. - leaf_refl_par) * VegK * clumping; // leaf-level PAR = APAR/canopy_scale = I_0*(1-rho)*k*Omega; Bonan Ch. 14 T_C = TEMP - DGCM_TK0C; // Convert temperature to degrees C -Kc = 300.*exp(0.074*(T_C - 25.)); -Ko = 300.*exp(0.015*(T_C - 25.)); -cp = 36.9 + 1.18*(T_C - 25.) + 0.036*pow((T_C - 25.), 2.); +/* Temperature-dependent Michaelis-Menten kinetics; Q10-type fits to Bernacchi et al. (2001) data. + Kc ref = 300 umol mol-1, Ko ref = 300 mmol mol-1, both at 25 C. */ +Kc = 300.*exp(0.074*(T_C - 25.)); // Michaelis constant for CO2 (umol mol-1) +Ko = 300.*exp(0.015*(T_C - 25.)); // Michaelis constant for O2 (mmol mol-1) +cp = 36.9 + 1.18*(T_C - 25.) + 0.036*pow((T_C - 25.), 2.); // CO2 compensation point Gamma* (umol mol-1); Bernacchi et al. 2001; Liu et al. myFun.py - -//Vcmax = vcmax25*exp(50.*(TEMP - 298.)/(298.*R*TEMP)); +/* --- Vcmax temperature response (Q10 formulation with upper/lower inhibition) --- + Vcmax(T) = Vcmax25 * Q10^(0.1*(T-25)) / [(1+exp(0.3*(T-Tupp))) * (1+exp(0.3*(Tdown-T)))] + Tupp, Tdown: upper/lower thermal inhibition thresholds (K); inverted by MCMC. */ double q_10 = A->IN.q10canopy; +double fT = pow(A->IN.q10canopyRd,(T_C-25.)/10.); // Q10 temperature scaling for Rd; reference T = 25 C -double fT = pow(A->IN.q10canopyRd,(T_C-25.)/10); // reference temperature is 25 degrees C - - - -Vcmax = vcmax25*pow(q_10,0.1*(T_C-25.))/((1 + exp(0.3*(T_C-(Tupp-DGCM_TK0C))))*(1 +exp(0.3*((Tdown-DGCM_TK0C)-T_C)))); +Vcmax = vcmax25*pow(q_10,0.1*(T_C-25.))/((1. + exp(0.3*(T_C-(Tupp-DGCM_TK0C))))*(1. + exp(0.3*((Tdown-DGCM_TK0C)-T_C)))); +/* Jmax/Vcmax ~ e ≈ 2.72 at 25 C; Leuning (1997) J. Exp. Bot. 48:345 + (Wullschleger 1993 109-species dataset rescaled to 25 C: slope = 2.68, r2 = 0.87) + Fixed ratio minimises MCMC parameter space; temperature response of Jmax tracks Vcmax. */ Jmax = Vcmax*exp(1.); -J = (0.3*PAR + Jmax - sqrt(pow(0.3*PAR + Jmax,2) - 4.*0.9*0.3*PAR*Jmax))/2./0.9; - +/* Electron transport rate J: non-rectangular hyperbola (Farquhar & Wong 1984). + kai1 = 0.9 (curvature parameter), kai2 = 0.3 (quantum yield, mol e- per mol photon); + Bonan (2019) Ch. 11 Eq. 11.33; Liu et al. myFun.py */ +J = (0.3*PAR_leaf + Jmax - sqrt(pow(0.3*PAR_leaf + Jmax,2) - 4.*0.9*0.3*PAR_leaf*Jmax))/2./0.9; // PAR_leaf keeps a2 leaf-level (consistent with a1); single canopy_scale at output; Bonan Ch. 11 +/* Medlyn et al. (2011) optimal stomatal conductance model: gs/g0 ~ 1 + g1/sqrt(VPD). + ci derived analytically from gs = An/(co2-ci)*1.6, giving ci = co2*(1 - 1/medlyn_term). + Medlyn et al. (2011) Glob. Change Biol. 17:2134 */ medlyn_term = 1. + g1/sqrt(VPD); ci = co2*(1. - 1./medlyn_term); - //CLM 4.5 does this - if (ciIN.canopyRdsf*vcmax25*fT; - - - -//Two terms for C4 photosynthesis + if (ciIN.canopyRdsf*vcmax25*fT; // C3 dark respiration = canopyRdsf * Vcmax25 * Q10(T) + +/* --- C4 photosynthesis: simplified two-term co-limitation --- + C4 plants have a CO2-concentrating mechanism (CCM), so Rubisco is not CO2-limited; + a1 ~ Vcmax (enzyme-limited), a2 ~ J (light-limited). + C3_frac is prescribed per pixel from remote-sensing products, not inverted by MCMC. */ a1 = Vcmax; a2 = J; -// An_C4 = fmax(0., fmin(a1*beta_factor,a2) - 0.015*Vcmax*beta_factor); -Ag_C4 = fmin(a1*beta_factor,a2); -Rd_C4 =A->IN.canopyRdsf*vcmax25*fT; - -//Total photosynthesis +Ag_C4 = fmin(a1*beta_factor, a2); // C4 gross assimilation +Rd_C4 = A->IN.canopyRdsf*vcmax25*fT; // C4 dark respiration -Ag = C3_frac*(Ag_C3) + (1. - C3_frac)*(Ag_C4); -Rd = C3_frac*(Rd_C3) + (1. - C3_frac)*(Rd_C4); +/* Fractional C3/C4 mix (C3_frac prescribed, not MCMC-inverted) */ +Ag = C3_frac*(Ag_C3) + (1. - C3_frac)*(Ag_C4); // blended gross assimilation (leaf-level, umol CO2 m-2 s-1) +Rd = C3_frac*(Rd_C3) + (1. - C3_frac)*(Rd_C4); // blended dark respiration (leaf-level, umol CO2 m-2 s-1) - //Potential Rd +/* Potential canopy Rd (g C m-2 day-1): + leaf-level Rd * canopy_scale (leaf->canopy) * 12e-6 (g C per umol CO2) * 86400 (s day-1) */ double Rd_daily_potential = Rd*canopy_scale*(12.e-6)*(24.*60.*60.); -//Ensures NSCs available -//A->OUT.LEAF_MORTALITY_FACTOR=fmax( 1- A->IN.NSC/(Rd_daily_potential * A->IN.deltat) ,0); +/* Leaf mortality from NSC (non-structural carbohydrates) limitation. + Exponential formulation: LEAF_MORTALITY_FACTOR -> 0 when NSC >> Rd*deltat (no stress), + -> 1 when NSC -> 0 (full mortality); updated to exponential form 11/1/2023. */ if (Rd_daily_potential==0){ A->OUT.LEAF_MORTALITY_FACTOR=0; } else { -A->OUT.LEAF_MORTALITY_FACTOR=(1/(exp(A->IN.NSC/(Rd_daily_potential * A->IN.deltat)))); // new exponential formulation 11/1/2023 + A->OUT.LEAF_MORTALITY_FACTOR=(1./(exp(A->IN.NSC/(Rd_daily_potential * A->IN.deltat)))); } -// printf(" \n Rd_pot and NSC: %f %f \n ", Rd_daily_potential * A->IN.deltat, A->IN.NSC); -//Actual daily Rd -A->OUT.Rd =Rd_daily_potential*(1 - A->OUT.LEAF_MORTALITY_FACTOR); -//Scaling Rd to available NSCs - Rd = Rd *(1 - A->OUT.LEAF_MORTALITY_FACTOR); +/* Actual daily canopy Rd, scaled by leaf survival fraction */ +A->OUT.Rd = Rd_daily_potential*(1. - A->OUT.LEAF_MORTALITY_FACTOR); +/* Scale leaf-level Rd by survival fraction before computing leaf-level An */ +Rd = Rd*(1. - A->OUT.LEAF_MORTALITY_FACTOR); - //Net A +/* Net assimilation (leaf-level); both Ag and Rd are leaf-level here. + canopy_scale applied once below when writing to output. */ An = Ag - Rd; - - -//To scale from leaf to canopy, comment out the following line and uncomment the one after -//double canopy_scale = 1.; - -//r[0] = An*canopy_scale*(12.e-6)*(24.*60.*60.); //from umolCO2m-2s-1 to gCm-2day-1 +/* Scale leaf -> canopy and convert units: umol CO2 m-2 s-1 -> g C m-2 day-1 + 12e-6: molecular mass of C in g per umol CO2 (12 g mol-1 * 1e-6 mol umol-1) + 86400: seconds per day */ +//double canopy_scale = 1.; // uncomment to disable canopy scaling (diagnostic) A->OUT.Ag = Ag*canopy_scale*(12.e-6)*(24.*60.*60.); A->OUT.An = An*canopy_scale*(12.e-6)*(24.*60.*60.); -//##################Transpiration################# - -double SRADg; -double sV; // sV is the rate of change of saturated vapor pressure with air temperature in degC. -double petVnum; -double petVnumB; -double gs; //stomatal conductance -double transp; // transpiration -double evap; // evaporation -double Psurf = 100.0; //Surface pressure in kPa -double VPD_kPa = VPD;//*Psurf; //100.0 kPa = 1000.0 hPa => Surface pressure +/* ===================== Transpiration: Penman-Monteith (Monteith 1965) ===================== + Canopy transpiration E = [Delta*(Rn_veg) + rho_air*Cp*(VPD)*ga] / [lambda*(Delta + gamma*(1 + ga/gs))] + where Delta = d(esat)/dT (kPa K-1), gamma = psychrometric constant (kPa K-1), + ga = aerodynamic conductance (m s-1), gs = canopy stomatal conductance (m s-1). + Reference: Monteith & Unsworth (2008) "Principles of Environmental Physics", Ch. 13; + Liu et al. myFun.py PenmanMonteith(). */ + +double SRADg; // Shortwave radiation reaching the ground surface (W m-2) +double sV; // Slope of saturation vapour pressure curve, d(esat)/dT (kPa K-1) +double petVnum; // PM numerator for canopy transpiration (W m-2 equivalent) +double petVnumB; // PT numerator for ground evaporation (Priestley-Taylor 1972) +double gs; // Canopy stomatal conductance (m s-1) +double transp; // Canopy transpiration (mm hr-1) +double evap; // Ground evaporation (mm hr-1) +double VPD_kPa = VPD; // VPD already in kPa double evap_scale_factpr; -sV = 0.04145*exp(0.06088*T_C); +/* Slope of saturation vapour pressure curve (kPa K-1); empirical fit to Magnus equation */ +sV = 0.04145*exp(0.06088*T_C); +/* Canopy and ground radiation partitioning using Beer's law: + SRADg = below-canopy shortwave (W m-2); (1-0.5*(rho_PAR+rho_NIR)) = broadband canopy absorptance */ SRADg = (1. - 0.5*(leaf_refl_par+leaf_refl_nir))*SRAD*exp(-VegK*LAI*clumping); +SRAD = (1. - 0.5*(leaf_refl_par+leaf_refl_nir))*SRAD; // absorbed canopy shortwave (W m-2) -SRAD = (1. - 0.5*(leaf_refl_par+leaf_refl_nir))*SRAD; - -petVnum = (sV*(SRAD-SRADg)+1.225*1005*VPD_kPa*ga)/lambda0*60*60; -petVnumB = 1.26*(sV*SRADg)/(sV+gammaV)/lambda0*60*60; //from mm.hr-1 -if(beta_factor > 0 && SRAD >0){ +/* PM numerator for canopy transpiration (mm hr-1): + numerator = [Delta*(Rn_canopy) + rho_air*Cp*VPD*ga] / lambda * 3600 + rho_air = 1.225 kg m-3; Cp_air = 1005 J kg-1 K-1; lambda0 = 2.26e6 J kg-1 */ +petVnum = (sV*(SRAD-SRADg) + rho_air*Cp_air*VPD_kPa*ga)/lambda0*60.*60.; // mm hr-1 -//Option 1. gs = 1.6*Ag/(co2-ci)*LAI*0.02405; - //Option 1. gs = 1.6*An/(co2-ci)*LAI*0.02405; -gs = fmax(0,1.6*An/(co2-ci)*LAI*0.02405); - +/* Priestley-Taylor ground evaporation (mm hr-1): + alpha_PT = 1.26 (empirical coefficient; Priestley & Taylor 1972 Mon. Wea. Rev. 100:81); + uses below-canopy radiation SRADg; assumes soil evaporation ~ equilibrium */ +petVnumB = 1.26*(sV*SRADg)/(sV+gammaV)/lambda0*60.*60.; // mm hr-1; alpha_PT=1.26; Priestley & Taylor 1972 -//transp = petVnum/(sV+gammaV*(1+ga*(1/ga+1/gs))); -transp = petVnum/(sV+gammaV*(ga*(1/ga+1/gs))); +if(beta_factor > 0 && SRAD > 0){ + /* Canopy stomatal conductance to water vapour (m s-1): + Based on leaf-level gs_CO2 = An/(co2-ci) (mol CO2 m-2 s-1 per umol mol-1); + 1.6: ratio of diffusivity of H2O to CO2 in air (dimensionless; Jones 1992 "Plants and Microclimate"); + LAI: leaf-to-canopy upscaling (m2 leaf m-2 ground); + 0.02405: molar volume of air at ~20 C = RT/P = 8.314*293/101325 = 0.02406 m3 mol-1, + converts mol CO2 m-2 s-1 -> m s-1. */ + gs = fmax(0., 1.6*An/(co2-ci)*LAI*0.02405); + /* Penman-Monteith transpiration (mm hr-1). + Denominator: sV + gamma*(1 + ga/gs) = sV + gamma*ga*(1/ga + 1/gs); Monteith 1965. + Liu et al. myFun.py PenmanMonteith() */ + transp = petVnum/(sV + gammaV*(ga*(1./ga + 1./gs))); -} -else{ -transp = 0.0; +} else { + transp = 0.0; } -//r[1] = transp*24; //from mm.hr-1 to mm.day-1 - -A->OUT.transp = transp*24; - - +A->OUT.transp = transp*24.; // mm hr-1 -> mm day-1 +/* Ground evaporation: scale by precipitation availability (evap <= precip/maxPevap) */ evap_scale_factpr = fmin(precip/maxPevap, 1.); - evap = petVnumB*evap_scale_factpr; -//evap = petVnumB; - -//r[2] = evap*24; //from mm.hr-1 to mm.day-1 - -A->OUT.evap = evap*24; - - - -//printf("SRADg = %f, VegK = %f, LAI = %f\n", (SRADg/SRAD), VegK, LAI); -//printf("transp = %f, evap = %f\n", r[1], r[2] ); +A->OUT.evap = evap*24.; // mm hr-1 -> mm day-1 return 0; } From 8b20477b242ab3e0f4024218d3a51fd93da33ca1 Mon Sep 17 00:00:00 2001 From: ebilir Date: Sat, 18 Apr 2026 08:04:37 -0700 Subject: [PATCH 15/30] fix merge --- .../DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c index 4a638cb6..1eb0f217 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c @@ -97,9 +97,14 @@ for (s=0;sSIOMATRIX[p].N_STATE_INPUT_FLUXES;i++){ - double Ftemp = FT[DALECmodel->SIOMATRIX[p].STATE_INPUT_FLUXES[i]]; - if (Ftemp<0){Fout +=Ftemp;} + double Ftemp = FT[DALECmodel->SIOMATRIX[p].STATE_INPUT_FLUXES[i]]; + if (Ftemp<0){Fout +=Ftemp;} //if any N_STATE_INPUT_FLUXES are negative, put them in Fout else {Fin += Ftemp;}} + + for (i=0;iSIOMATRIX[p].N_STATE_OUTPUT_FLUXES;i++){ + double Ftemp= FT[DALECmodel->SIOMATRIX[p].STATE_OUTPUT_FLUXES[i]]; + if (Ftemp<0){Fin +=Ftemp;} //if any N_STATE_OUTPUT_FLUXES are negative, put them in Fin + else {Fout += Ftemp;}} // // double Fin[10]; // double Fout[10]; From 7c21bd95545207af7af22998bbbe478208896fee Mon Sep 17 00:00:00 2001 From: ebilir Date: Mon, 20 Apr 2026 16:09:14 -0700 Subject: [PATCH 16/30] add impedance and cryosuction --- .../DALEC/DALEC_1100/DALEC_1100.c | 32 +++++++++++-------- .../CONVERTERS/HYDROFUN_MOI2CON.c | 13 +++++--- .../CONVERTERS/HYDROFUN_MOI2PSI.c | 15 +++++++-- .../DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c | 4 +-- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index d6504a29..ee297229 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -382,9 +382,9 @@ POOLS[S.D_LF_LY3]=LY3SOILTEMP.OUT.LF; //Effectively this corrects MOI to (water frac)/(water + air frac) //Min psi ensures large negative psis not resolved by model needlessly double minpsi=-30; -POOLS[S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY1],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY1]),minpsi); //psi reflects liquid state only -POOLS[S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY2],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY2]),minpsi); //psi reflects liquid state only -POOLS[S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY3],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY3]),minpsi); //psi reflects liquid state only +POOLS[S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY1],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY1],POOLS[S.D_TEMP_LY1]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction +POOLS[S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY2],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY2],POOLS[S.D_TEMP_LY2]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction +POOLS[S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY3],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY3],POOLS[S.D_TEMP_LY3]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction //******************Declare KNORR STRUCT********************* @@ -492,14 +492,14 @@ else { //stomatal closure factor -double beta1 = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_LY1]/pars[P.psi_50] - 1)))*POOLS[p+S.D_LF_LY1]; -double beta2 = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_LY2]/pars[P.psi_50] - 1)))*POOLS[p+S.D_LF_LY2]; +double beta1 = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_LY1]/pars[P.psi_50] - 1))); +double beta2 = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_LY2]/pars[P.psi_50] - 1))); double beta = (beta1*pars[P.LY1_z] + beta2*pars[P.LY2_z]*pars[P.root_frac])/(pars[P.LY1_z]+pars[P.LY2_z]*pars[P.root_frac]); //biomass mortality factor -double betaHMF_1 = 1/(1 + exp(pars[P.beta_lgrHMF]*(-1*POOLS[p+S.D_PSI_LY1]/pars[P.psi_50HMF] - 1)))*POOLS[p+S.D_LF_LY1]; -double betaHMF_2 = 1/(1 + exp(pars[P.beta_lgrHMF]*(-1*POOLS[p+S.D_PSI_LY2]/pars[P.psi_50HMF] - 1)))*POOLS[p+S.D_LF_LY2]; +double betaHMF_1 = 1/(1 + exp(pars[P.beta_lgrHMF]*(-1*POOLS[p+S.D_PSI_LY1]/pars[P.psi_50HMF] - 1))); +double betaHMF_2 = 1/(1 + exp(pars[P.beta_lgrHMF]*(-1*POOLS[p+S.D_PSI_LY2]/pars[P.psi_50HMF] - 1))); double betaHMF = (betaHMF_1*pars[P.LY1_z] + betaHMF_2*pars[P.LY2_z]*pars[P.root_frac])/(pars[P.LY1_z] +pars[P.LY2_z]*pars[P.root_frac]); double HMF; // Hydraulic mortality factor @@ -713,9 +713,12 @@ FLUXES[f+F.q_surf] = liquid_in - FLUXES[f+F.infil]; // Calculate drainage: correcting psi for presence of ice occurs within DRAINAGE function -double drain_LY1 = DRAINAGE(POOLS[p+S.D_SM_LY1],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention],POOLS[p+S.D_LF_LY1]); -double drain_LY2 = DRAINAGE(POOLS[p+S.D_SM_LY2],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention],POOLS[p+S.D_LF_LY2]); -double drain_LY3 = DRAINAGE(POOLS[p+S.D_SM_LY3],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention],POOLS[p+S.D_LF_LY3]); +double drain_LY1 = DRAINAGE(POOLS[p+S.D_SM_LY1],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, +pars[P.retention],POOLS[p+S.D_LF_LY1],POOLS[p+S.D_TEMP_LY1]); +double drain_LY2 = DRAINAGE(POOLS[p+S.D_SM_LY2],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, +pars[P.retention],POOLS[p+S.D_LF_LY2],POOLS[p+S.D_TEMP_LY2]); +double drain_LY3 = DRAINAGE(POOLS[p+S.D_SM_LY3],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, +pars[P.retention],POOLS[p+S.D_LF_LY3],POOLS[p+S.D_TEMP_LY3]); // Drainage becomes runoff from pools FLUXES[f+F.q_ly1] = HYDROFUN_MOI2EWT(drain_LY1,pars[P.LY1_por],pars[P.LY1_z])*one_over_deltat; @@ -1151,9 +1154,12 @@ POOLS[nxp+S.D_SM_LY1]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY1],pars[P.LY1_por],pars POOLS[nxp+S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY2],pars[P.LY2_por],pars[P.LY2_z]);//soil moisture LY2 POOLS[nxp+S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3 //Correcting PSI for presence of ice occurs within MOI2PSI function -POOLS[nxp+S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY1],psi_porosity,pars[P.retention], POOLS[nxp+S.D_LF_LY1]),minpsi); -POOLS[nxp+S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY2],psi_porosity,pars[P.retention], POOLS[nxp+S.D_LF_LY2]),minpsi); -POOLS[nxp+S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY3],psi_porosity,pars[P.retention], POOLS[nxp+S.D_LF_LY3]),minpsi); +POOLS[nxp+S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY1],psi_porosity,pars[P.retention], +POOLS[nxp+S.D_LF_LY1],POOLS[S.D_TEMP_LY1]),minpsi); +POOLS[nxp+S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY2],psi_porosity,pars[P.retention], +POOLS[nxp+S.D_LF_LY2],POOLS[S.D_TEMP_LY2]),minpsi); +POOLS[nxp+S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY3],psi_porosity,pars[P.retention], +POOLS[nxp+S.D_LF_LY3],POOLS[S.D_TEMP_LY3]),minpsi); //Isfinite check for 14 progronstic pools only diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c index 8b676a7e..396881ed 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c @@ -16,15 +16,18 @@ if (lf<=1e-4){ } // 1. Calculate effective pore volume (fraction of pore volume not occupied by ice) - double ice_sat_tv = moi * (1.0 - lf); - double effective_porosity = 1.0 - ice_sat_tv; + double ice_sat_tv = moi * (1.0 - lf); //fraction of pore volume occupied by ice + double effective_porosity = 1.0 - ice_sat_tv; //fraction of pore volume NOT occupied by ice // 2. Calculate effective liquid saturation - double liq_sat_tv = moi * lf; - double moi_eff = liq_sat_tv / effective_porosity; + double liq_sat_tv = moi * lf; //fraction of pore volume occupied by liquid water + double moi_eff = liq_sat_tv / effective_porosity; //fraction of occupied by liquid water // 3. Calculate unsaturated hydraulic conductivity based on available liquid space - double con = k0 * pow(moi_eff, 2.0 * b + 3.0); + double con_max = k0 * pow(moi_eff, 2.0 * b + 3.0); + double impedance = pow(10, ice_sat_tv*6.0); // from Swenson et al., 2012 https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2012MS000165 + + double con = con_max * impedance; return con; } \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c index 15f8a7a5..7f43c9da 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c @@ -10,7 +10,7 @@ b - retention parameter lf - liquid fraction */ -double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf){ +double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf, double soil_temp){ // Safety check to prevent divide-by-zero if (lf<=1e-4) return -9999.0; @@ -23,8 +23,17 @@ double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf){ double liq_sat_tv = moi * lf; // liquid water fraction of the total pore space volume double moi_eff = liq_sat_tv / effective_porosity; // liquid water fraction of the ice-adjusted pore space -// 3. Calculate effective psi -double psi=psi_porosity*(pow((1.0/(moi_eff)),b)); + // 3. Calculate effective psi based on capillary matric potential + double psi_capillary=psi_porosity*(pow((1.0/(moi_eff)),b)); + + // 4. Calculate cryosuction (Clapeyron equation) if frozen + double psi_cryo = 0.0; + if (lf < 1.0 && soil_temp < 273.15) { + // Latent heat of fusion = 3.34e5 J/kg. Equation yields MPa. + // As temperature drops further below 273.15, suction becomes more strongly negative + psi_cryo = (3.34e5 * (soil_temp - 273.15)) / (1000.0 * soil_temp); + } + double psi = fmin(psi_capillary, psi_cryo); return psi; } \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c index 1b6ea3b0..c2e04115 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c @@ -15,7 +15,7 @@ b - retention parameter lf - liquid fraction of H2O content */ -double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity, double b, double lf){ +double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity, double b, double lf, double soil_temp){ // 1. check for excessive soil moisture: drain out sm>1 so that all sm values are <=1, and won't break psi_eff. // (note that sm>1 only occurs transiently in between time steps and must be in a liquid/drainable state) @@ -25,7 +25,7 @@ double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity sm = 1.0;} // 2. Calculate current effective potential of the liquid-saturated state - double psi_eff = HYDROFUN_MOI2PSI(sm, psi_porosity, b, lf); + double psi_eff = HYDROFUN_MOI2PSI(sm, psi_porosity, b, lf, soil_temp); // 3. Check for excessive soil moisture: if (psi_eff <= psi_field) { From 3adb14d90a72104ddeb2250a36356b9159364ad8 Mon Sep 17 00:00:00 2001 From: ebilir Date: Mon, 20 Apr 2026 16:17:15 -0700 Subject: [PATCH 17/30] add impedance of infiltration, + correct previous errors --- .../CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 10 ++++++---- .../HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index ee297229..e0e308b1 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -704,7 +704,9 @@ FLUXES[f+F.sensible_heat] = Rn - FLUXES[f+F.ground_heat] - FLUXES[f+F.latent_hea // Infiltration (mm/day) double liquid_in = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]); -FLUXES[f+F.infil] = pars[P.max_infil]*(1 - exp(-liquid_in/pars[P.max_infil])); +double ice_sat_tv_surface = POOLS[p+S.D_SM_LY1] * (1.0 - POOLS[p+S.D_LF_LY1]); // volume of total pore space occupied by ice +double dynamic_max_infil = pars[P.max_infil] * pow(10.0, -6.0 * ice_sat_tv_surface); // impedance of infiltration due to ice blockage +FLUXES[f+F.infil] = dynamic_max_infil*(1 - exp(-liquid_in/dynamic_max_infil)); // Surface runoff (mm/day) @@ -1155,11 +1157,11 @@ POOLS[nxp+S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY2],pars[P.LY2_por],pars POOLS[nxp+S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3 //Correcting PSI for presence of ice occurs within MOI2PSI function POOLS[nxp+S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY1],psi_porosity,pars[P.retention], -POOLS[nxp+S.D_LF_LY1],POOLS[S.D_TEMP_LY1]),minpsi); +POOLS[nxp+S.D_LF_LY1],POOLS[nxp+S.D_TEMP_LY1]),minpsi); POOLS[nxp+S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY2],psi_porosity,pars[P.retention], -POOLS[nxp+S.D_LF_LY2],POOLS[S.D_TEMP_LY2]),minpsi); +POOLS[nxp+S.D_LF_LY2],POOLS[nxp+S.D_TEMP_LY2]),minpsi); POOLS[nxp+S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY3],psi_porosity,pars[P.retention], -POOLS[nxp+S.D_LF_LY3],POOLS[S.D_TEMP_LY3]),minpsi); +POOLS[nxp+S.D_LF_LY3],POOLS[nxp+S.D_TEMP_LY3]),minpsi); //Isfinite check for 14 progronstic pools only diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c index 396881ed..727e8707 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c @@ -25,7 +25,7 @@ if (lf<=1e-4){ // 3. Calculate unsaturated hydraulic conductivity based on available liquid space double con_max = k0 * pow(moi_eff, 2.0 * b + 3.0); - double impedance = pow(10, ice_sat_tv*6.0); // from Swenson et al., 2012 https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2012MS000165 + double impedance = pow(10, -ice_sat_tv*6.0); // from Swenson et al., 2012 https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2012MS000165 double con = con_max * impedance; From 184faf78b9508d28ca1b15f501af8c9dc6662c6c Mon Sep 17 00:00:00 2001 From: ebilir Date: Mon, 20 Apr 2026 16:37:56 -0700 Subject: [PATCH 18/30] safety around infiltration impedance --- .../DALEC/DALEC_1100/DALEC_1100.c | 2 +- combined_code.txt | 75638 ++++++++++++++++ 2 files changed, 75639 insertions(+), 1 deletion(-) create mode 100644 combined_code.txt diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index e0e308b1..77729000 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -705,7 +705,7 @@ FLUXES[f+F.sensible_heat] = Rn - FLUXES[f+F.ground_heat] - FLUXES[f+F.latent_hea // Infiltration (mm/day) double liquid_in = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]); double ice_sat_tv_surface = POOLS[p+S.D_SM_LY1] * (1.0 - POOLS[p+S.D_LF_LY1]); // volume of total pore space occupied by ice -double dynamic_max_infil = pars[P.max_infil] * pow(10.0, -6.0 * ice_sat_tv_surface); // impedance of infiltration due to ice blockage +double dynamic_max_infil = fmax(pars[P.max_infil] * pow(10.0, -6.0 * ice_sat_tv_surface), 1e-4); // impedance of infiltration due to ice blockage FLUXES[f+F.infil] = dynamic_max_infil*(1 - exp(-liquid_in/dynamic_max_infil)); diff --git a/combined_code.txt b/combined_code.txt new file mode 100644 index 00000000..2ed3cfbe --- /dev/null +++ b/combined_code.txt @@ -0,0 +1,75638 @@ + + +=== FILE: ./DALEC_EDC_NSC_ABGB_RATIO.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* + + + + + + +//Doing all pools +typedef struct { + int no_other_pool_indices; + int *other_pool_indices; + int nsc_pool_index; +} DALEC_EDC_NSC_ABGB_RATIO_STRUCT; + + +//General inequality function +double DALEC_EDC_NSC_ABGB_RATIO(DATA * DATA, void * EDCstruct){ + + + + + //Casting struct + + DALEC_EDC_NSC_ABGB_RATIO_STRUCT E = *(DALEC_EDC_NSC_ABGB_RATIO_STRUCT * ) EDCstruct; + + + + double *TIME_INDEX=DATA->ncdf_data.TIME_INDEX.values; + + DALEC *DALECmodel=(DALEC *)DATA->MODEL; + + + + + int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + +int nopools=DALECmodel->nopools; +int nofluxes=DALECmodel->nofluxes; + + //int nopools=DATA->nopools; + + + + //Looping through all pools + + //Pool inde + + +double M_NSC=mean_pool(DATA->M_POOLS,E.nsc_pool_index,N_timesteps+1,nopools); + + double M_ALL_ELSE=0; + +int n; + for (n=0;n< E.no_other_pool_indices;n++){M_ALL_ELSE+=mean_pool(DATA->M_POOLS,E.other_pool_indices[n],N_timesteps+1,nopools);} + + + double residual = (M_NSC/(M_NSC+M_ALL_ELSE) - 0.1)/0.05; +double PEDC=-0.5*residual*residual; + +//printf(" M_NSC = %2.2f, M_ALL_ELSE = %2.2f, PEDC = %2.2f\n", M_NSC,M_ALL_ELSE,PEDC); + + return PEDC; +} + + + + + +=== FILE: ./C/projects/DALEC_CODE/EDCs/EDCSETUP.c === + +#pragma once +int EDCSETUP(DATA DATA, struct EDCDIAGNOSTIC ** EDCD){ + +/*TO DO HERE: set EDCD.EDCSWITCHES to DATA.OTHERPRIORS fields 30 to 50*/ +/*DON'T FORGET TO DO THE SAME IN CDEA files*/ +/*see if it is possible to initiate both using the same function*/ +/*E.g. INITIATE_EDC_SWITCHES*/ + +static struct EDCDIAGNOSTIC EDCDmem; +EDCDmem.DIAG=DATA.ncdf_data.EDCDIAG; +int n; +/*EDC switches are stored in DATA->parpriors (positions 31-50);*/ +/*switch all on if EDCDIAG<2 , otherwise, switch on/off according to EDCSWITCH*/ +/*EDCSETUP function will be included in DALEC_ALL_LIKELIHOOD.c*/ + +/* +printf("*****") +printf("*****Note on status of DALEC EDC settings*******\n"); +printf("*****") +printf("*****") +printf("*****") +printf("******Only default values used for now, introduce EDC settings via netcdf system when needed\n"); +printf("*****") +*/ + + +for (n=0;n<100;n++){EDCDmem.SWITCH[n]=1;} +// if (EDCDmem.DIAG==2){for (n=0;n<20;n++){EDCDmem.SWITCH[n]=DATA.otherpriors[n+30];}} + +//if (EDCDmem.DIAG==2){for (n=0;n<20;n++){EDCDmem.SWITCH[n]=0;}} + + +/*EQF is stored in the "DATA.otherpriorunc" fields associated with EDCs 7-12*/ +/*default value is 2*/ +//EDCDmem.EQF=DATA.ncdf_data.EDC_EQF; + +//printf("EDCD->EQF* = %2.2f\n",EDCDmem.EQF); + + +/*Default structure has all EDC=1, and 100 EDCs*/ +EDCDmem.nedc=100; +for (n=0;n0){ +tot_exp=0; + +if (D.ch4_annual_unc<1){ +/*Standard NEE likelihood approach*/ +for (n=0;n-9999){ +//p=p-0.5*pow(log((PARS[17]+PARS[18]+PARS[19]+PARS[20])/D.otherpriors[0])/log(D.otherpriorunc[0]),2);} +P=P-0.5*pow(log((D.M_ABGB_t0[0])/D.otherpriors[0])/log(D.otherpriorunc[0]),2);} + + + + +/**Time resolved biomass**/ +if (D.nabgb>0){ +/*Looping through all available constraints*/ +for (n=0;nparpriors (positions 31-50);*/ +/*switch all on if EDCDIAG<2 , otherwise, switch on/off according to EDCSWITCH*/ +/*EDCSETUP function will be included in DALEC_ALL_LIKELIHOOD.c*/ +for (n=0;n<100;n++){EDCDmem.SWITCH[n]=1;} +if (EDCDmem.DIAG==2){for (n=0;n<20;n++){EDCDmem.SWITCH[n]=DATA.otherpriors[n+30];}} + +/*EQF is stored in the "DATA.otherpriorunc" fields associated with EDCs 7-12*/ +/*default value is 2*/ +EDCDmem.EQF=DATA.otherpriorunc[36]; if (EDCDmem.EQF==-9999){EDCDmem.EQF=2;} + +printf("EDCD->EQF = %2.2f\n",EDCDmem.EQF); +/*Double pointer = contents of EDCD reassigned to static struct*/ +*EDCD=&EDCDmem; + + +return 0; +} + + +double LIKELIHOOD_P(DATA DATA,double *PARS) +{ +/*remember - LOG likelihood*/ +double p=0,p_lma,pn; +int n; + +/*looping through all priors for P*/ +/*where no prior distribution is used, insert 9999*/ +for (n=0;n<50;n++){if (DATA.parpriors[n]>-9999 & DATA.parpriorunc[n]>-9999){p=p-0.5*pow(log(PARS[n]/DATA.parpriors[n])/log(DATA.parpriorunc[n]),2);}} + +/*for any other priors, explicitly define functions based on values in DATA.otherpriors*/ + +/*total biomass (pools 1:4) defined here - using first space of pappriors for total biomass*/ +if (DATA.otherpriors[0]>-9999){ +p=p-0.5*pow(log((PARS[17]+PARS[18]+PARS[19]+PARS[20])/DATA.otherpriors[0])/log(DATA.otherpriorunc[0]),2);} + +return p;} + + +double LIKELIHOOD(DATA D) +{ +int n,dn,m,f; +double P=0, Ps; +double tot_exp; +double CPG; +double mfire=0; +double msif=0; +double mgpp=0; +double mnpdf=0; +double mlai=0; +int npdfi[7]={9,10,11,23,24,25,26}; + +double mam=0; +double am=0; + + + +if (D.ngpp>0){ +tot_exp=0; +/*gppabs option = 1; directly assimilating GPP*/ +/*gppabs option = 0; assimilating relative GPP constraint (e.g. SIF)*/ +if (D.gppabs==1){ +/*GPP*/ +for (n=0;n0 & D.otherpriors[4]<0){for (n=0;n0 & D.otherpriors[4]>0){ +for (n=0;n0){for (n=0;n0){ +tot_exp=0; +if (D.etiav<1){ +/*Standard NEE likelihood approach*/ +for (n=0;n0){ +tot_exp=0; +if (D.neeiav<0){ +/*Standard NEE likelihood approach*/ +for (n=0;n0){ +for (n=0;n0){ +/*Relative volumetric constraint*/ +/*Note: constraint imposed on t+1 of H2O pools*/ +for (n=0;n0){ +/*Constraint on relative magnitudes of foliar and wood pools*/ +/*Step 1. Normalize time series*/ +/*Step 2. weigh and add time-series (MOD)*/ +/*Step 3. Compare normalized MOD anomalies vs normalized OBS anomalies*/ +bandmod=calloc(D.nband1,sizeof(double)); +/*Derive means*/ +for (n=0;n0){ +/*Constraint on relative magnitudes of foliar and wood pools*/ +/*Step 1. Normalize time series*/ +/*Step 2. weigh and add time-series (MOD)*/ +/*Step 3. Compare normalized MOD anomalies vs normalized OBS anomalies*/ +bandmod=calloc(D.nband2,sizeof(double)); +/*Derive means*/ +for (n=0;n-9999){ +/*Step 1. Sum fire emissions*/ +for (n=0;n0){P=P-0.5*pow(log(mfire/D.otherpriors[2])/log(D.otherpriorunc[2]),2);} +else {P=P-0.5*pow((mfire-D.otherpriors[2])/D.otherpriorunc[2],2);} +} + + + +/*Constrain mean GPP*/ +if (D.otherpriors[5]>-9999){mgpp=0; +/*Step 1. Sum fire emissions*/ +for (n=0;n-9999){mnpdf=0; +/*Step 1. Sum of biomass -> litter emissions (including fire)*/ +for (n=0;nt+1 LAI*/ +/*for (n=0;n0){for (n=0;n0){ + +//If timeseries data is provided, calculate model MLAI constraint during those points +if (D.nlai>0){ +for (n=0;n0){ +double tot_exp=0; +if (D.nbe_annual_unc<0){ + +if (D.nnbeunc==0){ +/*Standard NBE likelihood approach*/ +for (n=0;n0){ +/*Standard NBE likelihood approach*/ +for (n=0;n0){ +tot_exp=0; +if (D.et_annual_unc<1){ +/*Standard NEE likelihood approach*/ +for (n=0;n0){ +tot_exp=0; + +/*Normalization option for SIF*/ +if (D.gppabs==0){ +mgpp=0,msif=0; +for (n=0;n-9999){ +/*Step 1. Sum fire emissions*/ +for (n=0;n0){P=P-0.5*pow(log(D.M_MFIRE[0]/D.otherpriors[2])/log(D.otherpriorunc[2]),2);} +else {P=P-0.5*pow((D.M_MFIRE[0]-D.otherpriors[2])/D.otherpriorunc[2],2);} +} +} + + + + + + + + + + + + + + +return P; + +} + + +=== FILE: ./C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_LIKELIHOOD_GPP.c === + +double DALEC_LIKELIHOOD_GPP(DATA D){ +/*Data structure, includes model and data*/ + +/*EWT constraint*/ +double tot_exp=0; +double am=0, mam=0; +int n,m,dn; +double P=0; +double mgpp=1,msif=1; +/*General notes*/ +/* If D.et_annual_unc<1, then ET constraint is occurring on monthly basis*/ +/* For log_et_obs*/ +double th=D.gpp_obs_threshold; + +/*GPP likelyhood*/ +if (D.ngpp>0){ +tot_exp=0; + +/*Normalization option for SIF*/ +if (D.gppabs==0){ +mgpp=0,msif=0; +for (n=0;n-9999){mgpp=0; +/*Step 1. Sum gpp*/ +for (n=0;n0){P=P-0.5*pow(log(mgpp/D.otherpriors[5])/log(D.otherpriorunc[5]),2);} +else {P=P-0.5*pow((mgpp-D.otherpriors[5])/D.otherpriorunc[5],2);} +/*P=P-0.5*pow((mgpp-D.otherpriors[5])/D.otherpriorunc[5],2);*/ + +} + +//printf("Done with GPP cost function\n"); + + + + +return P; +} + + +=== FILE: ./C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_beta.c === + +#pragma once +#include +#include "DALEC_ALL_LIKELIHOOD.c" +#include "../../../math_fun/ipow.c" + + +double DALEC_MLF_beta(DATA DATA,double *PARS){ + +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + + +/*Setting probability to 0*/ +DATA.M_P[0]=0; + + +/*PARAMETER LOG LIKELIHOOD*/ +/*Eventually push to each function(?) OK here for now*/ +DATA.M_P[0]=DATA.M_P[0]+LIKELIHOOD_P(DATA,PARS); + + +/*running model*/ +/*For internal checks, i.e. EDCs, are mediated by DATA.M_P[0]*/ +DATA.M_P[0]=DATA.M_P[0]+MODEL->dalec(DATA, PARS); + +/*Only run likelihood calculation if model is physical*/ +if (isinf(DATA.M_P[0])>-1){ +/*storing GPP (this should really be done elsewhere)*/ +int n; +for (n=0;nEDCD;*/ +EDCD=*MODEL->EDCD; + +/*running model*/ +MODEL->dalec(DATA, PARS); + +/*LIKELIHOOD (log likelihood)*/ +/*EDCs are individually counted*/ +/*Only counted if EDCSWITCH is on*/ +double P; +int tot_exp=0,n; +for (n=0;nEDC==0 && (isinf(ML)==-1 || isnan(ML))){P=P-0.5*10;} +*/ + +return P; + +} + + + + + + +=== FILE: ./C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_LIKELIHOOD_ROFF.c === + +double DALEC_LIKELIHOOD_ROFF(DATA D){ +/*Data structure, includes model and data*/ + +/*EWT constraint*/ +double tot_exp=0; +double am=0, mam=0; +int n,m,dn; +double P=0; +/*General notes*/ +/* If D.et_annual_unc<1, then ROFF constraint is occurring on monthly basis*/ +/* For log_et_obs*/ +double th=D.et_obs_threshold; + +/*ROFF likelyhood*/ +if (D.net>0){ +tot_exp=0; +if (D.et_annual_unc<1){ +/*Standard NEE likelihood approach*/ +for (n=0;n0){ +/*Looping through all available constraints*/ +for (n=0;n0){ +/*Relative volumetric constraint*/ + +for (n=0;n +#include "DALEC_ALL_LIKELIHOOD.c" +#include "DALEC_ALL_MLF.c" +#include "../../../math_fun/ipow.c" + + + + + + + + + + +double DALEC_MLF(DATA DATA,double *PARS){ +//copy pars to M_PARS for export +int n; for (n=0;nEDCD;*/ +EDCD=*MODEL->EDCD; +/*EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +*/ +int EDC; +double P=0;//P_p; + +EDC=ipow(MODEL->edc1(PARS,DATA, &EDCD),DATA.ncdf_data.EDC); +P=P+log((double)EDC); + + +if (EDC==1 | EDCD.DIAG==1){ +/*PARAMETER LOG LIKELIHOOD*/ +//P=P+LIKELIHOOD_P(DATA,PARS); +//P_p=P; + +/*running model*/ +MODEL->dalec(DATA, PARS); + +/*storing GPP*/ +//for (n=0;nedc2(PARS, DATA, &EDCD); +EDC=ipow(EDC,DATA.ncdf_data.EDC); + +/*LIKELIHOOD*/ +P=P+log((double)EDC); + + + +if (EDC==1){P=P+LIKELIHOOD(DATA);}} + + + +/*saving EDCD if EDCDIAG==1*/ +if (DATA.ncdf_data.EDCDIAG==1){for (n=0;n<100;n++){DATA.M_EDCD[n]=EDCD.PASSFAIL[n];}} + + +/*saving likelihood P*/ +DATA.M_P[0]=P; + +/*Returning the log likelihood P*/ +return P; + + +} + + + + +int DALEC_MLF_MODCONFIG(MLF* MLF){ + + //Populate LS + LIKELIHOODinfo LIKELIHOODinfo; DALEC_ALL_LIKELIHOOD_MODCONFIG(&LIKELIHOODinfo); + //Store LS + MLF->nolikelihoods=LIKELIHOODinfo.nolikelihoods; + MLF->mlf= DALEC_MLF; + + return 0;} + + + + + + + + + + + + +double EDC_DALEC_MLF_STEPWISE(DATA DATA, double *PARS){ + +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +/*Independend EDCD structure: stores detailed EDC info, and provides DATA with result summary*/ +struct EDCDIAGNOSTIC EDCD; +/*initialize EDCD: copy default structure*/ +EDCD=*MODEL->EDCD; +/*enforce DIAGNOSTIC MODE: switches are still in place*/ +EDCD.DIAG=1; +int EDC, n; +double P=0; + + +EDC=MODEL->edc1(PARS,DATA,&EDCD); + +/*running model*/ +MODEL->dalec(DATA, PARS); + +/*EDC2 check*/ +EDC=EDC*MODEL->edc2(PARS, DATA, &EDCD); + + + +/*LIKELIHOOD (log likelihood)*/ +/*EDCs are individually counted*/ +/*Only counted if EDCSWITCH is on*/ +int tot_exp=0; +for (n=0;nEDC==0 && (isinf(ML)==-1 || isnan(ML))){P=P-0.5*10;} +*/ + + + +return P; + +} + + + + + +double EDC_DALEC_MLF_BINARY(DATA DATA, double *PARS){ + + +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +/*Independend EDCD structure: stores detailed EDC info, and provides DATA with result summary*/ +struct EDCDIAGNOSTIC EDCD; +/*initialize EDCD: copy default structure*/ +EDCD=*MODEL->EDCD; +/*enforce DIAGNOSTIC MODE: switches are still in place*/ +EDCD.DIAG=1; +int EDC, n; +double P=0; + +//EDC=MODEL->edc1(PARS,DATA,&EDCD); + +/*running model*/ +//MODEL->dalec(DATA, PARS); + +/*EDC2 check*/ +//EDC=EDC*MODEL->edc2(PARS, DATA, &EDCD); + + + +/*LIKELIHOOD (log likelihood)*/ +/*EDCs are individually counted*/ +/*Only counted if EDCSWITCH is on*/ +//for (n=0;nEDC==0 && (isinf(ML)==-1 || isnan(ML))){P=P-0.5*10;} +*/ + + + +return P; + +} + + + + + + + + +=== FILE: ./C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_LIKELIHOOD_ET.c === + +double DALEC_LIKELIHOOD_ET(DATA D){ +/*Data structure, includes model and data*/ + +/*EWT constraint*/ +double tot_exp=0; +double am=0, mam=0; +int n,m,dn; +double P=0; +/*General notes*/ +/* If D.et_annual_unc<1, then ET constraint is occurring on monthly basis*/ +/* For log_et_obs*/ +double th=D.et_obs_threshold; + +/*ET likelyhood*/ +if (D.net>0){ +tot_exp=0; +if (D.et_annual_unc<1){ +/*Standard NEE likelihood approach*/ +for (n=0;n +#include "DALEC_ALL_LIKELIHOOD.c" +#include "DALEC_ALL_MLF.c" +#include "../../CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_FUNCTIONS.c" +#include "../../../math_fun/ipow.c" + + + + + +double DALEC_MLF2(DATA DATA,double *PARS){ + + //Copy "DATA.M_PARS" for convenience + memcpy(DATA.M_PARS, PARS, DATA.nopars*sizeof(double)); + + +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +EDCs *EDCs=MODEL->EDCs; + + +//int EDC,n; +double P=0; + + + +if (DATA.ncdf_data.EDC==1){ + + + + //Call EDC function for prerun=1 models + double Pedc1 = RUN_DALEC_EDCs(&DATA, EDCs, true); +P=P+Pedc1; +} + + +//printf("EDC prerun P = %2.2f\n",P); +/*PARAMETER LOG LIKELIHOOD*/ +//P=P+LIKELIHOOD_P(DATA,PARS); + + + + +/*running model*/ + if (P>-INFINITY){MODEL->dalec(DATA, PARS);} + + +/*storing GPP*/ +//for (n=0;n-INFINITY){ + + //Call EDC function for prerun=0 edcs + double Pedc2 = RUN_DALEC_EDCs(&DATA, EDCs, false); + +P=P+Pedc2;} +// printf("EDC postrun P = %2.2f\n",P); +// printf("Inside run MLF2: DATA->M_EDCs[3] = %2.2f\n",DATA.M_EDCs[3] ); + + +/*Likelihood*/ + if (P>-INFINITY){ + //printf("Pre likelihood P = %2.2f\n",P); + P=P+LIKELIHOOD(DATA); + //printf("Post likelihood P = %2.2f\n",P); + } + + + +/*saving likelihood P*/ +DATA.M_P[0]=P; + + + + +/*Returning the log likelihood P*/ +return P; + + +} + + + +double EDC_DALEC_MLF2_BINARY(DATA DATA, double *PARS){ + +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + + +double P=0; + +double ML=DATA.MLF(DATA,PARS); + +/*overriding if model likelihood is zero or erroneous*/ +if (( isinf(ML)==-1 || isinf(ML)==1 || isnan(ML) )){P=-INFINITY;} + + +return P;} + + + + + +int DALEC_MLF2_MODCONFIG(MLF* MLF){ + printf("Using DALEC_MLF2_MODCONFIG...\n"); + //Populate LS + LIKELIHOODinfo LIKELIHOODinfo; DALEC_ALL_LIKELIHOOD_MODCONFIG(&LIKELIHOODinfo); + //Store LS + MLF->nolikelihoods=LIKELIHOODinfo.nolikelihoods; +//Store pointer to function + MLF->mlf= DALEC_MLF2; + + return 0;} + + + + + + + +=== FILE: ./C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c === + +#pragma once +#include +#include "DALEC_ALL_LIKELIHOOD.c" +#include "DALEC_ALL_MLF.c" +#include "../../../math_fun/ipow.c" + + + +double DALEC_MLF_DEDC(DATA DATA,double *PARS){ + + memcpy(DATA.M_PARS, PARS, DATA.nopars*sizeof(double)); + + + +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +struct EDCDIAGNOSTIC EDCD; +/*Copy default structure*/ +/*EDCD=*((DALEC *)DATA.MODEL)->EDCD;*/ +EDCD=*MODEL->EDCD; + +int EDC,n; +double P=0,P_p; +EDCD.pEDC=0; + + + +if (DATA.ncdf_data.EDC==1){ +MODEL->edc1(PARS,DATA, &EDCD); +P=P+EDCD.pEDC;} + + +/*PARAMETER LOG LIKELIHOOD*/ +//P=P+LIKELIHOOD_P(DATA,PARS); +P_p=P; + + +/*running model*/ +MODEL->dalec(DATA, PARS); +/*storing GPP*/ +//for (n=0;nedc2(PARS, DATA, &EDCD); +P=P+EDCD.pEDC; +} + + + +/*Likelihood*/ + +P=P+LIKELIHOOD(DATA); + + + + +/*saving likelihood P*/ +DATA.M_P[0]=P; + + + + +/*Returning the log likelihood P*/ +return P; + + +} + + + +int DALEC_MLF_DEDC_MODCONFIG(MLF* MLF){ + + //Populate LS + LIKELIHOODinfo LIKELIHOODinfo; DALEC_ALL_LIKELIHOOD_MODCONFIG(&LIKELIHOODinfo); + //Store LS + MLF->nolikelihoods=LIKELIHOODinfo.nolikelihoods; + MLF->mlf= DALEC_MLF_DEDC; + + return 0;} + + + + + + + +=== FILE: ./C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c === + +#pragma once +#include "../../../math_fun/std.c" +#include "../../../math_fun/mean.c" +#include "../../../math_fun/max.c" +#include "../CARDAMOM_LIKELIHOOD_FUNCTION.c" +#include "../../CARDAMOM_MODELS/DALEC/DALEC_OBSERVATION_OPERATORS/DALEC_OBSERVATION_OPERATORS.c" + + + + + //Time varying obs + //Mean obs + //PEQs + +typedef struct LIKELIHOODinfo{ + int nolikelihoods; +}LIKELIHOODinfo; + + + +struct LIKELIHOOD_INDICES{ + int ABGB; + int CH4; + int DOM; + int ET; + int LE; + int H; + int EWT; + int GPP; + int SIF; + int LAI; + int NBE; + int ROFF; + int SCF; + int FIR; + int SWE; + int Mean_ABGB; + int Mean_FIR; + int Mean_GPP; + int Mean_LAI; + int PEQ_Cefficiency; + int PEQ_CUE; + int PEQ_NBEmrg; + int PEQ_iniSnow; + int PEQ_iniSOM; + int PEQ_C3frac; + int PEQ_Vcmax25; + int PEQ_LCMA; + int PEQ_clumping; + int PEQ_r_ch4; + int PEQ_S_fv; + int PEQ_rhch4_rhco2; + } LIKELIHOOD_INDICES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30}; /*pMCMC*/ + + + + int DALEC_ALL_LIKELIHOOD_MODCONFIG(LIKELIHOODinfo * LI){ + LI->nolikelihoods=31; + return 0;} + + + + + + + + +/*Any likelihood functions used in multiple MLF functions are kept here!*/ + + + + + + +/*for any other priors, explicitly define functions based on values in DATA.otherpriors*/ + +/*total biomass (pools 1:4) defined here - using first space of pappriors for total biomass*/ + + +double LIKELIHOOD(DATA D){ + +//Step 1. Implement observarion operator on + + + + + +OBSOPE *O=&((DALEC *)D.MODEL)->OBSOPE; + +//printf("O->SUPPORT_LAI_OBS = %d\n",O->SUPPORT_LAI_OBS); + + +//Observation operator on DALEC variables. +DALEC_OBSOPE(&D,O); + +//printf("About to calculate likelihoods...\n"); + +//Abstracted likelihood indices +struct LIKELIHOOD_INDICES LI = LIKELIHOOD_INDICES; +double * ML=D.M_LIKELIHOODS; + + +//printf("O->SUPPORT_LAI_OBS = %d\n",O->SUPPORT_LAI_OBS); + +//if (O->SUPPORT_ET_OBS){ P=DALEC_LIKELIHOOD_ET(D);} +// shuang added SIF operator, to enable using two seperate observations to constrain GPP and SIF at the same time, evaluating performance +if (O->SUPPORT_ABGB_OBS){ ML[LI.ABGB]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.ABGB, D.M_ABGB);}; +if (O->SUPPORT_CH4_OBS){ ML[LI.CH4]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.CH4, D.M_CH4);}; +if (O->SUPPORT_DOM_OBS){ ML[LI.DOM]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.DOM, D.M_DOM);}; +if (O->SUPPORT_ET_OBS){ ML[LI.ET]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.ET, D.M_ET);}; +if (O->SUPPORT_LE_OBS){ ML[LI.LE]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.LE, D.M_LE);}; +if (O->SUPPORT_H_OBS){ ML[LI.H]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.H, D.M_H);}; +if (O->SUPPORT_EWT_OBS){ ML[LI.EWT]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.EWT, D.M_EWT);}; +if (O->SUPPORT_GPP_OBS){ ML[LI.GPP]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.GPP, D.M_GPP);}; +if (O->SUPPORT_SIF_OBS){ ML[LI.SIF]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.SIF, D.M_SIF);}; // shuang +if (O->SUPPORT_LAI_OBS){ ML[LI.LAI]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.LAI, D.M_LAI);}; +if (O->SUPPORT_NBE_OBS){ ML[LI.NBE]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.NBE, D.M_NBE);}; +if (O->SUPPORT_ROFF_OBS){ ML[LI.ROFF]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.ROFF, D.M_ROFF);}; +if (O->SUPPORT_SCF_OBS){ ML[LI.SCF]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.SCF, D.M_SCF);}; +if (O->SUPPORT_FIR_OBS){ ML[LI.FIR]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.FIR, D.M_FIR);}; +if (O->SUPPORT_SWE_OBS){ ML[LI.SWE]=CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(&D.ncdf_data.SWE, D.M_SWE);}; + +//Mean OBS + + +if (O->SUPPORT_ABGB_OBS){ ML[LI.Mean_ABGB]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.Mean_ABGB, D.M_Mean_ABGB);}; +if (O->SUPPORT_FIR_OBS){ ML[LI.Mean_FIR]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.Mean_FIR, D.M_Mean_FIR);}; +if (O->SUPPORT_GPP_OBS){ ML[LI.Mean_GPP]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.Mean_GPP, D.M_Mean_GPP);}; +if (O->SUPPORT_LAI_OBS){ ML[LI.Mean_LAI]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.Mean_LAI, D.M_Mean_LAI);}; + +//Parameters and emergent quantities +if (O->SUPPORT_NBEmrg_OBS){ ML[LI.PEQ_NBEmrg]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_NBEmrg, D.M_PEQ_NBEmrg);}; +if (O->SUPPORT_Cefficiency_OBS){ML[LI.PEQ_Cefficiency]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_Cefficiency, D.M_PEQ_Cefficiency);}; +if (O->SUPPORT_CUE_OBS){ ML[LI.PEQ_CUE]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_CUE, D.M_PEQ_CUE);}; +if (O->SUPPORT_iniSnow_OBS){ ML[LI.PEQ_iniSnow]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_iniSnow, D.M_PEQ_iniSnow);}; +if (O->SUPPORT_iniSOM_OBS){ ML[LI.PEQ_iniSOM]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_iniSOM, D.M_PEQ_iniSOM);}; +if (O->SUPPORT_Vcmax25_OBS){ ML[LI.PEQ_Vcmax25]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_Vcmax25, D.M_PEQ_Vcmax25);}; +if (O->SUPPORT_C3frac_OBS){ ML[LI.PEQ_C3frac]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_C3frac, D.M_PEQ_C3frac);}; +if (O->SUPPORT_CUEmrg_OBS){ ML[LI.PEQ_CUE]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_CUE, D.M_PEQ_CUE);}; +if (O->SUPPORT_LCMA_OBS){ ML[LI.PEQ_LCMA]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_LCMA, D.M_PEQ_LCMA);}; +if (O->SUPPORT_clumping_OBS){ ML[LI.PEQ_clumping]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_clumping, D.M_PEQ_clumping);}; + + +//add PEQ value and unc from previous MCMC *pMCMC* +if (O->SUPPORT_r_ch4_OBS){ ML[LI.PEQ_r_ch4]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_r_ch4, D.M_PEQ_r_ch4);}; +if (O->SUPPORT_S_fv_OBS){ ML[LI.PEQ_S_fv]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_S_fv, D.M_PEQ_S_fv);}; +if (O->SUPPORT_rhch4_rhco2_OBS){ML[LI.PEQ_rhch4_rhco2]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_rhch4_rhco2, D.M_PEQ_rhch4_rhco2);}; + +//Calculate sum here; + +int n; +double P=0; + for (n=0;n-9999){mnpdf=0; +/*Step 1. Sum of biomass -> litter emissions (including fire)*/ +//for (n=0;n0){ +tot_exp=0; +if (D.et_annual_unc<1){ +/*Standard NEE likelihood approach*/ +for (n=0;n + +//#include "../CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c" + + +typedef struct TIMESERIES_OBS_STRUCT{ +double * values;//Timeseries of observation values +//**********Variable attributes, as provided in netcf input file************* +int opt_unc_type;//(0 = absolute sigma, 1 = uncertainty factor, 2 = sigma as fraction of value) +int opt_normalization;//(0 = none, 1 = remove mean, 2 = divide by mean) +int opt_filter;//(0 = no filter, 1 = mean only, 2==annual mean & monthly anomaly, 3 = annual only). +double min_threshold;//Minimum value threshold: model and/or data will be rounded up to this value (default = -inf) +double single_monthly_unc;//Fields to be used only with Filter=2 AND opt_unc_type=0; +double single_annual_unc;//Fields to be used only with Filters=2 & 3 (AND opt_unc_type=0 or opt_unc_type=2 for filter = 2); +double single_mean_unc;//Fields to be used only with Filter = 1; +double single_decadal_unc;//Field for Filter = 7; +double trend_unc;//Fields to be used only with Filter = 9 ; +double single_unc;//Fields to be used only with Filter = 0 ; +double structural_unc;//this gets added to uncertainty in quadrature. +//****Auxiliary variables, separate from timeseries variable**** +double * unc;//Timeseries of uncertainty values +//expand as needed +size_t length;// +size_t unc_length;// +int valid_obs_length;//number of non-empty obs +int * valid_obs_indices;//indices of non-empty obs +bool validobs;//True/false whether no usable data provided +}TIMESERIES_OBS_STRUCT; + + + +typedef struct SINGLE_OBS_STRUCT{ +double value; +double unc; +int opt_unc_type;//(0 = absolute sigma, 1 = uncertainty factor, 2 = sigma as fraction of value) +double min_threshold; +double min_value; +double max_value; +bool validobs;//True/false whether no usable data provided +}SINGLE_OBS_STRUCT; + + + + + + + + +double TIMESERIES_OBS_STRUCT_PREPROCESS(TIMESERIES_OBS_STRUCT * OBS){ +//OBS_STRUCT_DEFAULT_VALUES(OBS); +//Loop through obs and find valid obs + + //Global defaults for timeseries obs... these are only defined if they haven't been defined earlier +default_int_value(&OBS->opt_unc_type,0); +default_int_value(&OBS->opt_normalization,0); +default_int_value(&OBS->opt_filter,0); +default_double_value(&OBS->min_threshold,log(0));//minus infinity +default_double_value(&OBS->structural_unc,0); + +int n; +int N=(int)OBS->length; +printf("obs length: %2d, ", N); +if (N==0){ + printf("(Obs not included)\n"); + } +OBS->valid_obs_length=0; +for (n=0;nvalues[n]!=DEFAULT_DOUBLE_VAL){ + OBS->valid_obs_length=OBS->valid_obs_length+1; + } + } +if (N!=0){ + printf("%2d Valid obs\n", OBS->valid_obs_length); + } +OBS->valid_obs_indices=calloc(OBS->valid_obs_length,sizeof(int)); +int k=0; +for (n=0;nvalues[n]!=DEFAULT_DOUBLE_VAL){ + OBS->valid_obs_indices[k]=n;k=k+1;} + } + +//Populate uncertainty if no values are provided +for (k=0;kvalid_obs_length;k++){ + if (OBS->unc[OBS->valid_obs_indices[k]]==DEFAULT_DOUBLE_VAL){ + if (OBS->opt_unc_type<2){ + OBS->unc[OBS->valid_obs_indices[k]]=OBS->single_unc; + } + else if (OBS->opt_unc_type==2){ + OBS->unc[OBS->valid_obs_indices[k]]=max(OBS->single_unc*OBS->values[OBS->valid_obs_indices[k]],OBS->single_unc*OBS->min_threshold); + } + } + } +//Scale uncertainty with structural error +if (OBS->structural_unc==DEFAULT_DOUBLE_VAL){ + OBS->structural_unc=0; + } +//Adding structural error +for (k=0;kvalid_obs_length;k++){ + OBS->unc[OBS->valid_obs_indices[k]]=sqrt(pow(OBS->unc[OBS->valid_obs_indices[k]],2) + pow(OBS->structural_unc,2)); + } +//isempty flag +OBS->validobs=false; +if (OBS->valid_obs_length>0){OBS->validobs=true;} + +return 0;} + +//Function for reading these +TIMESERIES_OBS_STRUCT READ_NETCDF_TIMESERIES_OBS_FIELDS(int ncid, char * OBSNAME){ +TIMESERIES_OBS_STRUCT OBS; +printf("Struct declared OK\n"); + +printf("OBSNAME = %s\n",OBSNAME); + + +char uncsf[50],OBSunc[50]; +strcpy(OBSunc,OBSNAME); +strcpy(uncsf,"unc"); +strcat(OBSunc,uncsf); + + +OBS.values = ncdf_read_double_var(ncid, OBSNAME , &(OBS.length)); +OBS.unc = ncdf_read_double_var(ncid, OBSunc , &(OBS.unc_length)); + +//Empty array with same dims guaranteed +if (OBS.unc_length==0){ + OBS.unc = ncdf_read_double_var(ncid, OBSNAME , &(OBS.unc_length)); + int n;for (n=0;nmin_value,log(0));//-INFINITY +//MINMAX LIMITS: default_double_value(&OBS->max_value,-log(0));//INFINITY + +//isempty flag +OBS.validobs=false; +if(OBS.min_value!=DEFAULT_DOUBLE_VAL){OBS.validobs=true;} +if(OBS.max_value!=DEFAULT_DOUBLE_VAL){OBS.validobs=true;} +if(OBS.value!=DEFAULT_DOUBLE_VAL){OBS.validobs=true;} + + +return OBS; +} + + + + + + +double CARDAMOM_TIMESERIES_OBS_LIKELIHOOD(TIMESERIES_OBS_STRUCT * OBS,double * MOD){ + +/*Data structure, includes model and data*/ +/*EWT constraint*/ + double P=0; + if (OBS->valid_obs_length>0){ +double tot_exp=0; +int n,m,dn; +/*General notes*/ +/* If D.et_annual_unc<1, then ET constraint is occurring on monthly basis*/ +/* For log_et_obs*/ + +/* +typedef struct OBS_STRUCT{ +size_t length; +double * values; +double * unc; +int opt_log_transform;//log-transform data +int opt_normalization;//(0 = none, 1 = remove mean, 2 = divide by mean) +int opt_structural_error; +double min_threshold; +double single_monthly_unc; +double single_annual_unc; +double single_mean_unc; +double structural_unc; +//expand as needed +int valid_obs_length;//number of non-empty obs +int * valid_obs_indices;//indices of non-empty obs +}OBS_STRUCT; +*/ + + + + +int N=OBS->valid_obs_length; +double * mod = calloc(sizeof(double),N); +double * obs = calloc(sizeof(double),N); +double * unc = calloc(sizeof(double),N); + + +//Copying memory + +for (n=0;nvalid_obs_indices[n]]; +obs[n] = OBS->values[OBS->valid_obs_indices[n]]; +unc[n] = OBS->unc[OBS->valid_obs_indices[n]]; +} +//Filter uncertainty copies +double single_mean_unc=OBS->single_mean_unc; +double single_monthly_unc=OBS->single_monthly_unc; +double single_annual_unc=OBS->single_annual_unc; +double single_decadal_unc=OBS->single_decadal_unc; +double trend_unc=OBS->trend_unc; + + +double mean_mod=0, mean_obs=0; + + +//calculation of mean where obs are available +//Only calculate means for opt nomormalization +//Recalculate later for opt_filter=1 +if (OBS->opt_normalization>0){ +for (n=0;nopt_normalization==1){ +for (n=0;nopt_normalization==2){ +for (n=0;nmin_threshold)==0){ +for (n=0;nmin_threshold); +obs[n] = max(obs[n],OBS->min_threshold);}} + + +//log transform + +if (OBS->opt_unc_type==1){ +for (n=0;nopt_filter==0){//no filter + for (n=0;nopt_filter==1){//mean only + + double mean_mod_of1=0, mean_obs_of1=0; + + for (n=0;nopt_filter==2 | OBS->opt_filter==3 ){//monthly and annual flux + /*Decoupling seasonal from interannual variations*/ + /*Only use with monthly resolution fluxes, complete years & no missing data*/ + /*Step 1. Mean model & data annual NBE*/ + /*Step 2. Compare means*/ + /*Step 3. Remove means from months for cost function*/ + int m, dn; + //Looping through all years + for (m=0;mopt_filter==2){ + for (n=0;n<12;n++){ + dn=n+m*12; + tot_exp+=pow((mod[dn]-obs[dn]-mam+oam)/single_monthly_unc,2); + } + } + /*Calculate annual cost function*/ + /*TEST: normalize model likelihood by normal distribution with mean zero and unc = x2 annual unc.*/ + tot_exp+=pow((oam-mam)/single_annual_unc,2); + + } +} + + +else if (OBS->opt_filter==4 | OBS->opt_filter==5){//climatology and inter-annual variability, only to use with monthly data + //Decoupling climatological seasonal cycle from inter-anual variations*/ + //Only use with monthly resolution fluxes, complete years & no missing data*/ + //Step 1. Mean model & data annual NBE*/ + //Step 2. Compare means*/ + //Step 3. Remove means from months for cost function*/ + int m, dn,i; + double * modcm = calloc(sizeof(double),12); + double * obscm = calloc(sizeof(double),12); + int * countcm = calloc(sizeof(int),12); + int * icm = calloc(sizeof(double),N); + + //Step 1. + //Loop through valid_obs_indices, and bin into mod(I,12) + for (m=0;mvalid_obs_indices[m] % 12;i=icm[m]; + //Average model and obs + modcm[i] +=mod[m]; + obscm[i] +=obs[m]; + countcm[i]+=1; + } + //Climatological cost function component: Avoid averaging by scaling cost function uncertainties accordingly! + for (i=0;i<12;i++){ + if (countcm[i]>0){ + obscm[i]/=(double)countcm[i]; + modcm[i]/=(double)countcm[i]; + tot_exp+=pow((modcm[i]-obscm[i])/single_monthly_unc,2); + } + } + //Inter-annual cost function component: Avoid averaging by scaling cost function uncertainties accordingly! + if (OBS->opt_filter==4){ + for (m=0;m1){ + tot_exp+=pow((mod[m] - modcm[i] - obs[m] + obscm[i])/single_annual_unc,2); + } + } + } +//Free pointers + free(modcm);free(obscm);free(countcm);free(icm); +} + +else if (OBS->opt_filter==6){//three-year rolling mean + //EB added 12.12.22 as a test to constrain biomass trend with reduced noise: constrain fit to 3 year rolling mean obs/ + int m, dn; + //Looping through years [1:-1] (except first and last) + for (m=1;m<(N/12)-1;m++){ + /*1) Calculate 3 year mean of monthly values*/ + double m3yrm=0, o3yrm=0; + //Looping through 3 years worth of months + for (n=0;n<36;n++){ + dn=n+(m-1)*12; + m3yrm=m3yrm+mod[dn]; + o3yrm=o3yrm+obs[dn]; + } + /*2) normalize means*/ + m3yrm=m3yrm/36;o3yrm=o3yrm/36; + /*3) Calculate 3-year mean cost function*/ + tot_exp+=pow((o3yrm-m3yrm)/single_annual_unc,2); + } +} + +else if (OBS->opt_filter==7){ //EB added 8.4.23 as a test to constrain biomass + /*This cost function separately considers: + 1) time series mean; + 2) decadal anomaly from the time series mean; + 3) annual anomaly from the decadal mean. + Notes: + 1) Only use with more than 10 years of data; Future plans to generalize this ... + 2) Only use with complete time series; missing months/years will undermine the calculation. + 3) provide 3 separate uncertainties: single_mean_unc, single_decadal_unc, single_annual_unc + 4) ensure observation uncertainty type is *not* log-transformed (to handle negative or small anomalies)*/ + + //1) compute total mean + double tot_mean_mod=0, tot_mean_obs=0; + + for (n=0;nopt_filter==8 ){/* copy of opt filters 1 + 2, i.e. now with mean included; + *time series mean flux, annual mean flux, and monthly flux + *Decoupling seasonal from interannual variations + *Only use with monthly resolution fluxes, complete years & no missing data + *Step 1. Compare NBE Mean + *Step 2. Compare NBE annual anomaly + *Step 3. Compare NBE seasonal anomaly relative to annual mean*/ + + //Compute total mean + double mean_mod_of1=0, mean_obs_of1=0; + for (n=0;nopt_filter==9){//opt_filter 0 plus trend + for (n=0;nopt_filter = %i\n",OBS->opt_filter); +// printf("OBS->opt_unc_type = %i\n",OBS->opt_unc_type); + +return P; + +} + + + + +// typedef struct SINGLE_OBS_STRUCT{ +// double value; +// double unc;//(0 = absolute sigma, 1 = uncertainty factor, 2 = sigma as fraction of value) +// int opt_unc_type;//log-transform data +// double min_threshold; +// }SINGLE_OBS_STRUCT; +// + + + + +double CARDAMOM_SINGLE_OBS_LIKELIHOOD(SINGLE_OBS_STRUCT * OBS,double MOD){ + + +double P=0; + +if (OBS->value!=DEFAULT_DOUBLE_VAL){ + +/*Data structure, includes model and data*/ +/*EWT constraint*/ +double tot_exp=0; +int n,m,dn; +/*General notes*/ +/* If D.et_annual_unc<1, then ET constraint is occurring on monthly basis*/ +/* For log_et_obs*/ + + + + + +//Copying memory + +double mod = MOD; +double obs = OBS->value; +double unc= OBS->unc; + +//Setting threshold + +if (isinf(OBS->min_threshold)==0){ +mod = max(mod,OBS->min_threshold); +obs = max(obs,OBS->min_threshold);} + + +if (OBS->opt_unc_type==1){ +mod=log(mod); +obs=log(obs); +unc=log(unc);} + + +//Cost function +//This is the only option available for single value (e.g. time invariant) observations +tot_exp = pow((mod- obs)/unc,2); + + +P=-0.5*tot_exp; + +//MINMAX LIMITS if (mod < OBS->min_value || mod > OBS->max_value ){P=log(0);} + +} + + +// printf("Completed likelihood function...P = %2.2f\n",P); +// printf("OBS->opt_filter = %i\n",OBS->opt_filter); +// printf("OBS->opt_unc_type = %i\n",OBS->opt_unc_type); + +return P; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1130/DALEC_1130.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "DALEC_1130_INDICES.c" +#include "PARS_INFO_1130.c" +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../DALEC_ALL/LIU_AN_ET_REFACTOR.c" +#include "../DALEC_ALL/CH4_MODULES/HET_RESP_RATES_JCR.c" +#include "../DALEC_ALL/KNORR_ALLOCATION.c" +#include "../DALEC_ALL/SOIL_TEMP_AND_LIQUID_FRAC.c" +#include "../DALEC_ALL/INITIALIZE_INTERNAL_SOIL_ENERGY.c" +#include "../DALEC_ALL/INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS.c" +#include "../DALEC_ALL/NLM_AND_ALLOC.c" + + + +typedef struct DALEC_1130_DATA_STRUCT{ +double * VegK; +double example_const; +}DALEC_1130_DATA_STRUCT; + + +int PREDERIVE_DALEC_1130_DATA(DALEC * DALECmodel, DATA * DATA){ + + //Step 1. Define function here +static DALEC_1130_DATA_STRUCT DALEC_1130_DATA; +//Step 2. Populate with any datasets that will be used repeatedly. + + + //******VegK calculcation******** + + + + + + // + + double * DOY=DATA->ncdf_data.DOY.values; + double LAT = DATA->ncdf_data.LAT; + int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + double pi=DGCM_PI; + +//Declare VegK + double * VegK = calloc(N_timesteps, sizeof(double)); + + +int n; + +for (n=0; n < N_timesteps; n++){ + +/*Calculate light extinction coefficient for each timestep*/ +double B = (DOY[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +double LST = (int) (DOY[n]*24*60) % (24*60); +LST=0.5*24*60; +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*LAT)*sin(pi/180*DA)+cos(pi/180*LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +double zenith_angle = 90-alpha; + +//printf("SZA local = %2.2f, SZA global = %2.2f, SZA diff = %2.2f\n", zenith_angle,DATA.ncdf_data.SZA.values,DATA.ncdf_data.SZA.values - zenith_angle); +//double LAD = 1.0; //leaf angle distribution +//double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 + +double LAD = 0.5; //leaf angle distribution// optimize leaf angle distribution. + + + VegK[n] = LAD/cos(zenith_angle/180*pi); + + + + +} + + + +//Store data in DALEC_1130_DATA + DALEC_1130_DATA.VegK=VegK; + + + //Store for later use + DALECmodel->MODEL_DATA=&DALEC_1130_DATA; + +return 0; +} + + +//Returns structure with sources and sinks, matches number of fluxes +int DALEC_1130_FLUX_SOURCES_SINKS(DALEC * DALECmodel){ + + + struct DALEC_1130_FLUXES F=DALEC_1130_FLUXES; + struct DALEC_1130_POOLS S=DALEC_1130_POOLS; + + // /Step 1. Declare & initialize + DALEC_FLUX_SOURCE_SINK_MATRIX FIOMATRIX; + // external source or pool sink, or not conserved quantity + //Default = -1 + + FIOMATRIX.SOURCE=calloc(DALECmodel->nofluxes, sizeof(int)); + FIOMATRIX.SINK=calloc(DALECmodel->nofluxes, sizeof(int)); + + + int n; + for (n=0;nnofluxes; n++){FIOMATRIX.SOURCE[n]=-1;FIOMATRIX.SINK[n]=-1;} + + + //Step 2. Define + + + // C_lab + FIOMATRIX.SINK[F.gpp]=S.C_lab; + FIOMATRIX.SOURCE[F.resp_auto_maint]=S.C_lab; + FIOMATRIX.SOURCE[F.Rd]=S.C_lab; + FIOMATRIX.SOURCE[F.foliar_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.root_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.wood_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.resp_auto_growth]=S.C_lab; + FIOMATRIX.SOURCE[F.f_lab]=S.C_lab; + FIOMATRIX.SOURCE[F.lab2lit]=S.C_lab; + FIOMATRIX.SOURCE[F.fx_lab2lit]=S.C_lab; + FIOMATRIX.SOURCE[F.dist_lab]=S.C_lab; + + + // C_fol + FIOMATRIX.SINK[F.foliar_prod]=S.C_fol; + FIOMATRIX.SOURCE[F.fol2lit]=S.C_fol; + FIOMATRIX.SOURCE[F.ph_fol2lit]=S.C_fol; + FIOMATRIX.SOURCE[F.f_fol]=S.C_fol; + FIOMATRIX.SOURCE[F.fx_fol2lit]=S.C_fol; + FIOMATRIX.SOURCE[F.dist_fol]=S.C_fol; + + // C_roo + FIOMATRIX.SINK[F.root_prod]=S.C_roo; + FIOMATRIX.SOURCE[F.roo2lit]=S.C_roo; + FIOMATRIX.SOURCE[F.f_roo]=S.C_roo; + FIOMATRIX.SOURCE[F.fx_roo2lit]=S.C_roo; + FIOMATRIX.SOURCE[F.dist_roo]=S.C_roo; + + // C_woo + FIOMATRIX.SINK[F.wood_prod]=S.C_woo; + FIOMATRIX.SOURCE[F.woo2cwd]=S.C_woo; + FIOMATRIX.SOURCE[F.f_woo]=S.C_woo; + FIOMATRIX.SOURCE[F.fx_woo2cwd]=S.C_woo; + FIOMATRIX.SOURCE[F.dist_woo]=S.C_woo; + + // C_lit + FIOMATRIX.SINK[F.lab2lit]=S.C_lit; + FIOMATRIX.SINK[F.fx_lab2lit]=S.C_lit; + FIOMATRIX.SINK[F.ph_fol2lit]=S.C_lit; + FIOMATRIX.SINK[F.fol2lit]=S.C_lit; + FIOMATRIX.SINK[F.fx_fol2lit]=S.C_lit; + FIOMATRIX.SINK[F.roo2lit]=S.C_lit; + FIOMATRIX.SINK[F.fx_roo2lit]=S.C_lit; + FIOMATRIX.SOURCE[F.ae_rh_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.an_rh_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.f_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.lit2som]=S.C_lit; + FIOMATRIX.SOURCE[F.fx_lit2som]=S.C_lit; + + // C_cwd + FIOMATRIX.SINK[F.woo2cwd]=S.C_cwd; + FIOMATRIX.SINK[F.fx_woo2cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.ae_rh_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.an_rh_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.f_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.cwd2som]=S.C_cwd; + FIOMATRIX.SOURCE[F.fx_cwd2som]=S.C_cwd; + + // C_som + FIOMATRIX.SINK[F.cwd2som]=S.C_som; + FIOMATRIX.SINK[F.fx_cwd2som]=S.C_som; + FIOMATRIX.SINK[F.lit2som]=S.C_som; + FIOMATRIX.SINK[F.fx_lit2som]=S.C_som; + FIOMATRIX.SOURCE[F.ae_rh_som]=S.C_som; + FIOMATRIX.SOURCE[F.an_rh_som]=S.C_som; + FIOMATRIX.SOURCE[F.f_som]=S.C_som; + + // H2O_SWE + FIOMATRIX.SOURCE[F.melt]=S.H2O_SWE; + FIOMATRIX.SOURCE[F.sublimation]=S.H2O_SWE; + FIOMATRIX.SINK[F.snowfall]=S.H2O_SWE; + + // H2O_LY1 + FIOMATRIX.SINK[F.infil]=S.H2O_LY1; + FIOMATRIX.SOURCE[F.evap]=S.H2O_LY1; + FIOMATRIX.SOURCE[F.transp1]=S.H2O_LY1; + FIOMATRIX.SOURCE[F.ly1xly2]=S.H2O_LY1; + FIOMATRIX.SOURCE[F.q_ly1]=S.H2O_LY1; + + // H2O_LY2 + FIOMATRIX.SINK[F.ly1xly2]=S.H2O_LY2; + FIOMATRIX.SOURCE[F.transp2]=S.H2O_LY2; + FIOMATRIX.SOURCE[F.ly2xly3]=S.H2O_LY2; + FIOMATRIX.SOURCE[F.q_ly2]=S.H2O_LY2; + + // H2O_LY3 + FIOMATRIX.SOURCE[F.q_ly3]=S.H2O_LY3; + FIOMATRIX.SINK[F.ly2xly3]=S.H2O_LY3; + + // E_LY1 + FIOMATRIX.SINK[F.gh_in]=S.E_LY1; + FIOMATRIX.SINK[F.infil_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.evap_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.transp1_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.q_ly1_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.ly1xly2_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.ly1xly2_th_e]=S.E_LY1; + + // E_LY2 + FIOMATRIX.SINK[F.ly1xly2_e]=S.E_LY2; + FIOMATRIX.SINK[F.ly1xly2_th_e]=S.E_LY2; + FIOMATRIX.SOURCE[F.transp2_e]=S.E_LY2; + FIOMATRIX.SOURCE[F.q_ly2_e]=S.E_LY2; + FIOMATRIX.SOURCE[F.ly2xly3_e]=S.E_LY2; + FIOMATRIX.SOURCE[F.ly2xly3_th_e]=S.E_LY2; + + // E_LY3 + FIOMATRIX.SINK[F.ly2xly3_e]=S.E_LY3; + FIOMATRIX.SINK[F.geological]=S.E_LY3; + FIOMATRIX.SINK[F.ly2xly3_th_e]=S.E_LY3; + FIOMATRIX.SOURCE[F.q_ly3_e]=S.E_LY3; + + + +DALECmodel->FIOMATRIX = FIOMATRIX; + + +//DALEC flux indices + +//Calculate State source sink matrix +DALEC_STATE_SOURCE_SINK_MATRIX_CONFIG(DALECmodel); +return 0; + +} + + + + + + + + + +int DALEC_1130(DATA DATA, double const *pars){ + + + + + +struct DALEC_1130_PARAMETERS P=DALEC_1130_PARAMETERS; +struct DALEC_1130_FLUXES F=DALEC_1130_FLUXES; +struct DALEC_1130_POOLS S=DALEC_1130_POOLS; + + + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *SKT=DATA.ncdf_data.SKT.values; +double *STRD=DATA.ncdf_data.STRD.values; +double *DIST=DATA.ncdf_data.DISTURBANCE_FLUX.values; + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +//double pi=3.1415927; +double pi=DGCM_PI; + +//PREDERIVED TERMS + + double PREDERIVED_GEO_FLUX=0.105*3600*24; + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +double one_over_deltat=1/deltat; + +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + + + + /*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_cwd]=pars[P.i_cwd]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_LY1]=HYDROFUN_MOI2EWT(pars[P.i_LY1_SM],pars[P.LY1_por],pars[P.LY1_z]); + POOLS[S.H2O_LY2]=HYDROFUN_MOI2EWT(pars[P.i_LY2_SM],pars[P.LY2_por],pars[P.LY2_z]); + POOLS[S.H2O_LY3]=HYDROFUN_MOI2EWT(pars[P.i_LY3_SM],pars[P.LY3_por],pars[P.LY3_z]); + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + /*Energy pools*/ + //Step 1. derive temperature based on i_LY1_E (which will represent energy per mm H2O). + //INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(infiltemp); + //Declare stryct +// SOIL_TEMP_AND_LIQUID_FRAC_STRUCT LY1SOILTEMP, LY2SOILTEMP, LY3SOILTEMP; +// //Populate with run-specific constrants +// //LY1 +// LY1SOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.LY1_vhc]; ;//J/m3/K +// LY1SOILTEMP.IN.depth = pars[P.LY1_z];//m +// LY1SOILTEMP.IN.soil_water = POOLS[S.H2O_LY1];//mm (or kg/m2) +// LY1SOILTEMP.IN.internal_energy = POOLS[S.E_LY1];//Joules +// //Pass pointer to function +// SOIL_TEMP_AND_LIQUID_FRAC(&LY1SOILTEMP); //Outputs are in K + // + + + + //double INITIALIZE_INTERNAL_SOIL_ENERGY(double internal_energy_per_mm_H2O, double H2O_mm, double dry_soil_vol_heat_capacity, double depth ) + POOLS[S.E_LY1]=INITIALIZE_INTERNAL_SOIL_ENERGY(pars[P.i_LY1_E], POOLS[S.H2O_LY1], pars[P.LY1_vhc], pars[P.LY1_z] ); + POOLS[S.E_LY2]=INITIALIZE_INTERNAL_SOIL_ENERGY(pars[P.i_LY2_E], POOLS[S.H2O_LY2], pars[P.LY2_vhc], pars[P.LY2_z] ); + POOLS[S.E_LY3]=INITIALIZE_INTERNAL_SOIL_ENERGY(pars[P.i_LY3_E], POOLS[S.H2O_LY3], pars[P.LY3_vhc], pars[P.LY3_z] ); + + + //---INITIALIZING DIAGNOSTIC STATES--- + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; //LAI + + if (POOLS[S.H2O_SWE]>0){ + POOLS[S.D_SCF]=POOLS[S.H2O_SWE]/(POOLS[S.H2O_SWE]+pars[P.scf_scalar]);} //snow cover fraction} + else + {POOLS[S.D_SCF]=0;}; + + + //Diagnostic time-invariant quantities + // Porosity scaling factor (see line 124 of HESS paper) + double psi_porosity = -0.117/100; + double LY1max=pars[P.LY1_por]*pars[P.LY1_z]*1000; //LY1 capacity in mm + double LY2max=pars[P.LY2_por]*pars[P.LY2_z]*1000; //LY3 capacity in mm + double LY3max=pars[P.LY3_por]*pars[P.LY3_z]*1000; //LY3 capacity in mm + + + + //INITIALIZING soil moisture + POOLS[S.D_SM_LY1]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY1],pars[P.LY1_por],pars[P.LY1_z]); //soil moisture LY1 + POOLS[S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY2],pars[P.LY2_por],pars[P.LY2_z]);//soil moisture LY3 + POOLS[S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3 +// Convert to potential +//Min psi ensures large negative psis not resolved by model needlessly + double minpsi=-30; + POOLS[S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY1],psi_porosity,pars[P.retention]),minpsi); + POOLS[S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY2],psi_porosity,pars[P.retention]),minpsi); + POOLS[S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[S.D_SM_LY3],psi_porosity,pars[P.retention]),minpsi); + + + + + //Declare struct + SOIL_TEMP_AND_LIQUID_FRAC_STRUCT LY1SOILTEMP, LY2SOILTEMP, LY3SOILTEMP; + //Populate with run-specific constrants + //LY1 + LY1SOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.LY1_vhc]; ;//J/m3/K + LY1SOILTEMP.IN.depth = pars[P.LY1_z];//m + LY1SOILTEMP.IN.soil_water = POOLS[S.H2O_LY1];//mm (or kg/m2) + LY1SOILTEMP.IN.internal_energy = POOLS[S.E_LY1];//Joules + //Pass pointer to function + SOIL_TEMP_AND_LIQUID_FRAC(&LY1SOILTEMP); //Outputs are in K + //Store outputs + POOLS[S.D_TEMP_LY1]=LY1SOILTEMP.OUT.TEMP; //In K + POOLS[S.D_LF_LY1]=LY1SOILTEMP.OUT.LF; + + //LY2 + LY2SOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.LY2_vhc]; ;//J/m3/K + LY2SOILTEMP.IN.depth = pars[P.LY2_z];//m + LY2SOILTEMP.IN.soil_water = POOLS[S.H2O_LY2];//mm (or kg/m2) + LY2SOILTEMP.IN.internal_energy = POOLS[S.E_LY2];//Joules + //Pass pointer to function + SOIL_TEMP_AND_LIQUID_FRAC(&LY2SOILTEMP); //Outputs are in K + //Store outputs + POOLS[S.D_TEMP_LY2]=LY2SOILTEMP.OUT.TEMP; //In K + POOLS[S.D_LF_LY2]=LY2SOILTEMP.OUT.LF; + + //LY3 + LY3SOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.LY3_vhc]; ;//J/m3/K + LY3SOILTEMP.IN.depth = pars[P.LY3_z];//m + LY3SOILTEMP.IN.soil_water = POOLS[S.H2O_LY3];//mm (or kg/m2) + LY3SOILTEMP.IN.internal_energy = POOLS[S.E_LY3];//Joules + //Pass pointer to function + SOIL_TEMP_AND_LIQUID_FRAC(&LY3SOILTEMP);//Outputs are in K + //Store outputs + POOLS[S.D_TEMP_LY3]=LY3SOILTEMP.OUT.TEMP; //In K + POOLS[S.D_LF_LY3]=LY3SOILTEMP.OUT.LF; + + + + + + //******************Declare KNORR STRUCT********************* + KNORR_ALLOCATION_STRUCT KNORR; +//define time-invariant parameters + KNORR.IN.deltat=deltat; + KNORR.IN.n=0; + KNORR.IN.latitude=DATA.ncdf_data.LAT; + KNORR.IN.T_phi=pars[P.T_phi]; + KNORR.IN.T_r=pars[P.T_range]; + KNORR.IN.plgr=pars[P.plgr]; + KNORR.IN.k_L=pars[P.k_leaf]; + KNORR.IN.tau_W=pars[P.tau_W];//0.00000001;// + KNORR.IN.t_c=pars[P.time_c]; + KNORR.IN.t_r=pars[P.time_r];; + KNORR.IN.lambda_max=pars[P.lambda_max]; + //Initialize memory states + + POOLS[S.M_LAI_TEMP]=pars[P.init_T_mem]; + POOLS[S.M_LAI_MAX]=pars[P.init_LAIW_mem]*pars[P.lambda_max]; + + + //******************Allocation fluxes struct********************** +// +// typedef struct { +// struct { +// double TEMP;//deg C +// double SRAD;//MJ m2 d +// double NSC;//Clab +// double LY1_SM;//m3/m3 +// double parameter1;//replace with any name, no constraints on naming convention +// double parameter2;//replace with any name, no constraints on naming convention +// } IN; +// struct { +// double * AUTO_RESP_MAINTENANCE; +// double * AUTO_RESP_GROWTH; +// double * ALLOC_FOL; +// double * ALLOC_WOO; +// double * ALLOC_ROO;}OUT; +// }ALLOC_AND_AUTO_RESP_FLUXES_STRUCT; + + + + //Declare + //Plant carbon allocation. + NLM_AND_ALLOC_STRUCT ARFLUXES; + //define time-invariant parameters here + ARFLUXES.IN.mr_r=pars[P.rauto_mr_r];// + ARFLUXES.IN.mr_w=pars[P.rauto_mr_w];// + ARFLUXES.IN.Q10mr=pars[P.rauto_mr_q10];// + + + ARFLUXES.IN.k_growth=pars[P.k]; + ARFLUXES.IN.W_o=pars[P.W_o]; + ARFLUXES.IN.s_ar=pars[P.s_ar]; + ARFLUXES.IN.s_wood=pars[P.s_wood]; + ARFLUXES.IN.s_root=pars[P.s_root]; + ARFLUXES.IN.e_ar=pars[P.e_ar]; + ARFLUXES.IN.e_wood=pars[P.e_wood]; + ARFLUXES.IN.e_root=pars[P.e_root]; + + //Heterotrophic respiration module + HET_RESP_RATES_JCR_STRUCT HRJCR; + //define time invariant parameters here + + /* jc prep input for methane module*/ + HRJCR.IN.S_FV=pars[P.S_fv]; + HRJCR.IN.SM_OPT=pars[P.thetas_opt]; + HRJCR.IN.FWC=pars[P.fwc]; + HRJCR.IN.R_CH4=pars[P.r_ch4]; + HRJCR.IN.Q10CH4=pars[P.Q10ch4]; + HRJCR.IN.Q10CO2=pars[P.Q10rhco2]; + + + + + + +/*Combustion factors*/ +double CF[7];//AAB changed this +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=(pars[P.cf_foliar]+pars[P.cf_ligneous])*0.5; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + +/*foliar carbon transfer intermediate variables*/ +double Fcfolavailable; + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + + +//********MAIN LOOP*********** + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +// if (n == 20){ exit(0); } + +// printf("\n---------- %d ---------- n ",n ); +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +double LAI=POOLS[p+S.D_LAI]; +//printf("\n C_fol %f \n ", POOLS[p+S.C_fol]); + + + +// printf("\n D_LAI %f \n ", POOLS[p+S.D_LAI]); + +// printf("\n LAI to LIU %f \n ", LAI); +// +// /*Calculate light extinction coefficient*/ +// double B = (DOY[n]-81)*2*pi/365.; +// double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +// double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +// double LST = (int) (DOY[n]*24*60) % (24*60); +// LST=0.5*24*60; +// double AST = LST+ET1; +// double h = (AST-12*60)/4; //hour angle +// double alpha = asin((sin(pi/180*DATA.ncdf_data.LAT)*sin(pi/180*DA)+cos(pi/180*DATA.ncdf_data.LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +// double zenith_angle = 90-alpha; +// +// //printf("SZA local = %2.2f, SZA global = %2.2f, SZA diff = %2.2f\n", zenith_angle,DATA.ncdf_data.SZA.values,DATA.ncdf_data.SZA.values - zenith_angle); +// //double LAD = 1.0; //leaf angle distribution +// //double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 +// +// double LAD = 0.5; //leaf angle distribution// optimize leaf angle distribution. +// double VegK0 = LAD/cos(zenith_angle/180*pi); +// + + DALEC * DALECmodel=(DALEC *)DATA.MODEL; + +DALEC_1130_DATA_STRUCT * DALEC_1130_DATA=(DALEC_1130_DATA_STRUCT *)DALECmodel->MODEL_DATA; + + double VegK=DALEC_1130_DATA->VegK[n]; +//CONTINUE FROM HERE( + //printf("VegK internal, external = %2.2f, %2.2f\n",VegK, DALEC_1130_DATA->VegK[n]); + + + + + + + +/*Temp scaling factor*/ +double g; +double Tminmin = pars[P.Tminmin] - DGCM_TK0C; +double Tminmax = pars[P.Tminmax] - DGCM_TK0C; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor + //We're also multiplying beta by cold-weather stress +//double psi_LY10 = HYDROFUN_MOI2PSI(max(POOLS[p+S.D_SM_LY1],0),psi_porosity,pars[P.retention]); +//double psi_LY10 = HYDROFUN_MOI2PSI(POOLS[p+S.D_SM_LY1],psi_porosity,pars[P.retention_ly1]); + +double beta1 = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_LY1]/pars[P.psi_50] - 1)))*POOLS[p+S.D_LF_LY1]; +double beta2 = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_LY2]/pars[P.psi_50] - 1)))*POOLS[p+S.D_LF_LY2]; +double beta = (beta1*pars[P.LY1_z] + beta2*pars[P.LY2_z]*pars[P.root_frac])/(pars[P.LY1_z]+pars[P.LY2_z]*pars[P.root_frac]); + +// H2O stress biomass mortality factor: parallel structure to GPP scaling factor above + +double betaHMF_1 = 1/(1 + exp(pars[P.beta_lgrHMF]*(-1*POOLS[p+S.D_PSI_LY1]/pars[P.psi_50HMF] - 1)))*POOLS[p+S.D_LF_LY1]; +double betaHMF_2 = 1/(1 + exp(pars[P.beta_lgrHMF]*(-1*POOLS[p+S.D_PSI_LY2]/pars[P.psi_50HMF] - 1)))*POOLS[p+S.D_LF_LY2]; +double betaHMF = (betaHMF_1*pars[P.LY1_z] + betaHMF_2*pars[P.LY2_z]*pars[P.root_frac])/(pars[P.LY1_z] +pars[P.LY2_z]*pars[P.root_frac]); + +//if (betaHMF>1 | betaHMF<0) {printf("error in HMF, =%2.2f \n",betaHMF);} + +double HMF; // Hydraulic mortality factor + +if( (POOLS[p+S.D_LF_LY1] + POOLS[p+S.D_LF_LY2]) == 2 ) { //no frozen water + HMF = (1-betaHMF); +} +else { + HMF = 0; //no hydraulic mortality when soils are frozen +} + +// mean air temperature (K) +double air_temp_k = DGCM_TK0C+0.5*(T2M_MIN[n]+T2M_MAX[n]); + + FLUXES[f+F.beta_factor]=fmin(beta,g); + FLUXES[f+F.soil_beta_factor]=beta; + FLUXES[f+F.hydraulic_mortality_factor]=HMF; + +//******************Declare LIU STRUCT********************* +LIU_AN_ET_STRUCT LIU; + +//define time-invariant parameters +LIU.IN.SRAD=SSRD[n]*1e6/DGCM_SEC_DAY; +LIU.IN.VPD=VPD[n]/10; +LIU.IN.TEMP=air_temp_k; +LIU.IN.vcmax25=pars[P.Vcmax25]; +LIU.IN.co2=CO2[n]; +LIU.IN.beta_factor= FLUXES[f+F.beta_factor]; +LIU.IN.g1=pars[P.Med_g1]; +LIU.IN.LAI=LAI; +LIU.IN.ga=pars[P.ga]; +LIU.IN.VegK=VegK; +LIU.IN.Tupp=pars[P.Tupp]; +LIU.IN.Tdown=pars[P.Tdown]; +LIU.IN.C3_frac=1.; // pars[P.C3_frac] +LIU.IN.clumping=pars[P.clumping]; +LIU.IN.leaf_refl_par=pars[P.leaf_refl_par]; +LIU.IN.leaf_refl_nir=pars[P.leaf_refl_nir]; +LIU.IN.maxPevap=pars[P.maxPevap]; +LIU.IN.precip=PREC[n]; +LIU.IN.q10canopy=pars[P.q10canopy]; +LIU.IN.q10canopyRd=pars[P.rauto_mrd_q10]; +LIU.IN.canopyRdsf=pars[P.canopyRdsf]; +LIU.IN.NSC=POOLS[p+S.C_lab]; +LIU.IN.deltat=deltat; + + + +//Call function: uses LIU->IN to update LIU->OUT +LIU_AN_ET(&LIU); + + + +//printf("\n LIU %f %f \n", LIU.IN.NSC,LIU.OUT.Rd); + +double LEAF_MORTALITY_FACTOR=LIU.OUT.LEAF_MORTALITY_FACTOR; + +//printf("\n LMF %f \n", LEAF_MORTALITY_FACTOR); + + /*track C starvation here*/ +FLUXES[f+F.leaf_mortality_factor]=LEAF_MORTALITY_FACTOR; + +// GPP--- gross +FLUXES[f+F.gpp] = LIU.OUT.Ag; +//Rd Canopy +FLUXES[f+F.Rd] = LIU.OUT.Rd; +// GPP net, i.e. GPP- Rd +FLUXES[f+F.gppnet] = LIU.OUT.An; +//transpiration// +double transp = LIU.OUT.transp; +if (beta1>0 || beta2>0){ +FLUXES[f+F.transp1] = transp*beta1*pars[P.LY1_z]/(beta1*pars[P.LY1_z]+beta2*pars[P.LY2_z]*pars[P.root_frac]); +// FLUXES[f+F.transp2] = transp*beta2*pars[P.LY2_z]*pars[P.root_frac]/(beta1*pars[P.LY1_z]+beta2*pars[P.LY2_z]*pars[P.root_frac]); +FLUXES[f+F.transp2] = transp - FLUXES[f+F.transp1];} +else { +FLUXES[f+F.transp1] =0; +FLUXES[f+F.transp2] =0;} + +//evaporation// +FLUXES[f+F.evap] = LIU.OUT.evap; + + +/*Snow water equivalent*/ +FLUXES[f+F.snowfall] = SNOWFALL[n]; +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+FLUXES[f+F.snowfall]*deltat; /*first step snowfall to SWE*/ +//transient_SCF +double SCFtemp = POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); + //Snow melt, based on new SWE + double SNOWMELT=fmin(fmax((DGCM_TK0C+SKT[n]-pars[P.min_melt])*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]*one_over_deltat; /*melted snow per day*/ +double SUBLIMATION = pars[P.sublimation_rate]*SSRD[n]*SCFtemp; + +double slf=(SNOWMELT + SUBLIMATION)*deltat/POOLS[nxp+S.H2O_SWE]; + if (slf>1){ + FLUXES[f+F.melt]=SNOWMELT/slf; + FLUXES[f+F.sublimation]=SUBLIMATION/slf;} + else{ + FLUXES[f+F.melt]=SNOWMELT; + FLUXES[f+F.sublimation]=SUBLIMATION;} + + +// +// //Splitting snow loss into sublimation and snow melt with constant frac +// FLUXES[f+F.melt]=SNOWMELT; +// // POOLS[nxp+S.D_SCF]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); //snow cover fraction +// +// FLUXES[f+F.sublimation]=fmax( pars[P.sublimation_rate]*VPD[n]*SRAD[n]*POOLS[nxp+S.D_SCF]); +// + + +/*Insure SWE does not go negative due to machine error*/ +POOLS[nxp+S.H2O_SWE]=fmax(POOLS[nxp+S.H2O_SWE]-(FLUXES[f+F.melt] + FLUXES[f+F.sublimation])*deltat,0); +/*second step remove snowmelt from SWE*/ +FLUXES[f+F.ets]=FLUXES[f+F.evap] + FLUXES[f+F.transp1] + FLUXES[f+F.transp2] + FLUXES[f+F.sublimation]; + +//Energy balance: Rn = LE + H - G +// Rn = SWin - SWout + LWin - LWout + + +double SWin = SSRD[n]*1e6/DGCM_SEC_DAY; // W m-2 + +//Snow free +double SWout_snowfree =(SWin*0.5*(pars[P.leaf_refl_par]+pars[P.leaf_refl_nir])); // W m-2 +//Weighted average of surface albedo considering SW snow albedo as 0.9 +double snow_albedo=0.9;//Consider age-dependent albedo. + +//SW out +double SWout = (1. - POOLS[p+S.D_SCF])*SWout_snowfree + POOLS[p+S.D_SCF]*(SWin*snow_albedo); // W m-2 + + + + +//Stefan-Boltzmann constant W.m-2.K-4 +double sigma = 5.67*1e-8; +//Incident LW radiation - calculated +//double LWin = sigma*pow(air_temp_k,4.); +double LWin = STRD[n]*1e6/DGCM_SEC_DAY; // W m-2 +//Outgoing LW radiation +double tskin_k = SKT[n]+DGCM_TK0C; +double LWout = sigma*(tskin_k*tskin_k)*(tskin_k*tskin_k); // W m-2 +//Net radiation at the top of the canopy-soil continuum +// +// +double Rn = SWin - SWout + LWin - LWout; // W m-2 +//Rnet only into soil +FLUXES[f+F.net_radiation] = Rn; // W m-2 + +//Rnet snow free +double Rn_snowfree = SWin - SWout_snowfree + LWin - LWout; // W m-2 + + +//These are only fluxes into LY1 and out of LY1 +FLUXES[f+F.SWin]=SWin;//flag for redundancy and deletion +FLUXES[f+F.LWin]=LWin;//flag for redundancy and deletion +FLUXES[f+F.SWout]=SWout; +FLUXES[f+F.LWout]=LWout; + +//Latent heat of Vaporization J kg-1 +double lambda = DGCM_LATENT_HEAT_VAPORIZATION; //2.501*1e6 J kg-1 +//Latent heat (W.m-2) +double LE = lambda*(FLUXES[f+F.evap]+FLUXES[f+F.transp1]+FLUXES[f+F.transp2])/DGCM_SEC_DAY; // W m-2 +FLUXES[f+F.latent_heat] = LE; // W m-2 +//specific heat capacity of dry air is 1.00464 KJ kg -1 K -1 +// Consider surface pressure as forcing for more accurate conversion from mol to m3 +// Consider explicitly calculating cp based on humidity (derived from VPD and pressure) +double cp = 29.2; // J mol-1 K-1 representative specific heat of moist air at const pressure from Bonan book +double Psurf = 1e5; // Pa (representative surface pressure) +double Rgas = 8.31; // Universal gas constant (J mol-1 K-1) +// Pa / (J mol-1 K-1 * K) = mol m-3 +double moles_per_m3 = Psurf/(Rgas*air_temp_k); +//Sensible heat +// double H = cp*(tskin_k - air_temp_k)*pars[P.ga]*moles_per_m3; // ga in m s-1, +// FLUXES[f+F.sensible_heat] = H; // W m-2 +//Ground heat flux ONLY for energy in&out of vegetation-soil continuum +//Rn is scaled by snow free area, because we exclude snow energy balance from energy ODEs +//H is scaled by snow free area, because we exclude snow energy balance from energy ODEs +//LE is fully included, as evaporation and transpiration are assumed to come fully from snow-free areas (caveat: snow evaporation is a thing, btut we assume it's zero for this model) + +//Ideally, Rn should be snow-free vs snow-covered. + +// double G = Rn*(1. - POOLS[p+S.D_SCF]) - H*(1. - POOLS[p+S.D_SCF]) - LE; // W m-2 +// FLUXES[f+F.ground_heat] = G; // W m-2 +// FLUXES[f+F.gh_in] = G*DGCM_SEC_DAY; // J m-2 d-1 + +//Gh_in approach 2 based on soil and LST +FLUXES[f+F.ground_heat] =(pars[P.thermal_cond_surf]* (tskin_k - POOLS[p+S.D_TEMP_LY1])/(pars[P.LY1_z]*0.5))*(1. - POOLS[p+S.D_SCF]); +FLUXES[f+F.gh_in] =FLUXES[f+F.ground_heat] *DGCM_SEC_DAY; +//Using G, Rn and LE to derive H +// H = Rn - G - LE +FLUXES[f+F.sensible_heat] = Rn - FLUXES[f+F.ground_heat] - FLUXES[f+F.latent_heat]; + + +// Infiltration (mm/day) +double liquid_in = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]); +FLUXES[f+F.infil] = pars[P.max_infil]*(1 - exp(-liquid_in/pars[P.max_infil])); + + + +// Surface runoff (mm/day) + +FLUXES[f+F.q_surf] = liquid_in - FLUXES[f+F.infil]; + +// Volumetric soil moisture from water pools +// Include infiltration into LY1 () +// double sm_LY1 = HYDROFUN_EWT2MOI(POOLS[p+S.H2O_LY1],pars[P.LY1_por],pars[P.LY1_z]); +// double sm_LY3 = HYDROFUN_EWT2MOI(POOLS[p+S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]); + +// Update LY1 SM with infiltration +//sm_LY1 += HYDROFUN_EWT2MOI(infil*deltat,pars[P.LY1_por],pars[P.LY1_z]); + +// Calculate drainage + +//printf("POOLS[p+S.D_LF_LY1] = %2.2f\n",POOLS[p+S.D_LF_LY1]); +double drain_LY1 = POOLS[p+S.D_LF_LY1]*DRAINAGE(POOLS[p+S.D_SM_LY1],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_LY2 = POOLS[p+S.D_LF_LY2]*DRAINAGE(POOLS[p+S.D_SM_LY2],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_LY3 = POOLS[p+S.D_LF_LY3]*DRAINAGE(POOLS[p+S.D_SM_LY3],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_ly1] = HYDROFUN_MOI2EWT(drain_LY1,pars[P.LY1_por],pars[P.LY1_z])*one_over_deltat; +FLUXES[f+F.q_ly2] = HYDROFUN_MOI2EWT(drain_LY2,pars[P.LY2_por],pars[P.LY2_z])*one_over_deltat; +FLUXES[f+F.q_ly3] = HYDROFUN_MOI2EWT(drain_LY3,pars[P.LY3_por],pars[P.LY3_z])*one_over_deltat; + + +// Convert to conductivity +double k_LY1 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY1],pars[P.hydr_cond],pars[P.retention]); +double k_LY2 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY2],pars[P.hydr_cond],pars[P.retention]); +double k_LY3 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY3],pars[P.hydr_cond],pars[P.retention]); + + + +// Calculate inter-pool transfer in m/s (positive is LY1 to LY2) +double pot_xfer = 1000 * sqrt(k_LY1*k_LY2) * (1e-9*(POOLS[p+S.D_PSI_LY1]-POOLS[p+S.D_PSI_LY2])/(9.8*0.5*(pars[P.LY1_z]+pars[P.LY2_z])) + 1); +double SPACEavail, H2Oavail, Max_H2O_xfer, TEMPxfer_1to2; +if (pot_xfer>0) {//Water is going LY1->LY2 (down) +// Available space in LY2 (after runoff) +SPACEavail=fmax(pars[P.LY2_z]*pars[P.LY2_por]*1e3 - POOLS[p+S.H2O_LY2] + (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); +// Available water in LY1 (after runoff, et, and infiltration) +H2Oavail=fmax(POOLS[p+S.D_LF_LY1]*POOLS[p+S.H2O_LY1] + (FLUXES[f+F.infil] - FLUXES[f+F.q_ly1] - FLUXES[f+F.evap] - FLUXES[f+F.transp1])*deltat,0); +// Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +Max_H2O_xfer= POOLS[p+S.D_LF_LY1]*pot_xfer*DGCM_SEC_DAY*deltat; +//Minimum of three terms for LY1->LY2 +//1. Max_H2O_xfer +//2. Available space in LY2 (after runoff) +//3. LY1*LF (after runoff, et, and infiltration) +FLUXES[f+F.ly1xly2] =fmin(Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; +TEMPxfer_1to2= POOLS[p+S.D_TEMP_LY1];//In K +} +else { //Water is going LY2->LY1 (up) +// Available space in LY1 after runoff, et, and infiltration +SPACEavail=fmax(pars[P.LY1_z]*pars[P.LY1_por]*1e3 - POOLS[p+S.H2O_LY1] - (FLUXES[f+F.infil] - FLUXES[f+F.q_ly1] - FLUXES[f+F.evap] - FLUXES[f+F.transp1])*deltat,0); +// Available water in LY2 after runoff +H2Oavail= fmax(POOLS[p+S.D_LF_LY2]*POOLS[p+S.H2O_LY2] - (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); +// Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +Max_H2O_xfer= POOLS[p+S.D_LF_LY2]*pot_xfer*DGCM_SEC_DAY*deltat; +// Reverse sign of previous case +FLUXES[f+F.ly1xly2] = -fmin(-Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; +TEMPxfer_1to2= POOLS[p+S.D_TEMP_LY2];//In K +} + + + + +// Calculate inter-pool transfer in m/s (positive is LY1 to LY3) +pot_xfer = 1000 * sqrt(k_LY2*k_LY3) * (1e-9*(POOLS[p+S.D_PSI_LY2]-POOLS[p+S.D_PSI_LY3])/(9.8*0.5*(pars[P.LY2_z]+pars[P.LY3_z])) + 1); +double TEMPxfer_2to3; +if (pot_xfer>0) {//Water is going LY2->LY3 (down) +// Available space in LY3 (after runoff) +SPACEavail=fmax(pars[P.LY3_z]*pars[P.LY3_por]*1e3 - POOLS[p+S.H2O_LY3] + FLUXES[f+F.q_ly3]*deltat,0); +// Available water in LY2 (after runoff, et, and infiltration) +H2Oavail=fmax(POOLS[p+S.D_LF_LY2]*POOLS[p+S.H2O_LY2] - (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); +// Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +Max_H2O_xfer= POOLS[p+S.D_LF_LY2]*pot_xfer*DGCM_SEC_DAY*deltat; +//Minimum of three terms for LY2->LY3 +//1. Max_H2O_xfer +//2. Available space in LY3 (after runoff) +//3. LY2*LF (after runoff, et, and infiltration) +FLUXES[f+F.ly2xly3] =fmin(Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; +TEMPxfer_2to3= POOLS[p+S.D_TEMP_LY2];//In K +} +else { //Water is going LY3->LY2 (up) +// Available space in LY2 after runoff, et, and infiltration +SPACEavail=fmax(pars[P.LY2_z]*pars[P.LY2_por]*1e3 - POOLS[p+S.H2O_LY2] + (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); +// Available water in LY3 after runoff +H2Oavail= fmax(POOLS[p+S.D_LF_LY3]*POOLS[p+S.H2O_LY3] - FLUXES[f+F.q_ly3]*deltat,0); +// Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +Max_H2O_xfer= POOLS[p+S.D_LF_LY3]*pot_xfer*DGCM_SEC_DAY*deltat; +// Reverse sign of previous case +FLUXES[f+F.ly2xly3] = -fmin(-Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; +TEMPxfer_2to3= POOLS[p+S.D_TEMP_LY3];//In K +} + + +// Update pools, including ET from LY1 + //Ensure all pools greater or equal to zero + +POOLS[nxp+S.H2O_LY1] = POOLS[p+S.H2O_LY1] + (FLUXES[f+F.infil] - FLUXES[f+F.ly1xly2] - FLUXES[f+F.q_ly1] - FLUXES[f+F.evap] - FLUXES[f+F.transp1])*deltat; +POOLS[nxp+S.H2O_LY2] = POOLS[p+S.H2O_LY2] + (FLUXES[f+F.ly1xly2] - FLUXES[f+F.ly2xly3] - FLUXES[f+F.q_ly2] - FLUXES[f+F.transp2])*deltat; +POOLS[nxp+S.H2O_LY3] = POOLS[p+S.H2O_LY3] + (FLUXES[f+F.ly2xly3] - FLUXES[f+F.q_ly3])*deltat; + + + + +if (POOLS[nxp+S.H2O_LY1]>LY1max){ +//Dump excess into LY1 Q +FLUXES[f+F.q_ly1] +=(POOLS[nxp+S.H2O_LY1]-LY1max)*one_over_deltat; +POOLS[nxp+S.H2O_LY1]=LY1max;} + +if (POOLS[nxp+S.H2O_LY2]>LY2max){ +//Dump excess into LY2 Q +FLUXES[f+F.q_ly1] +=(POOLS[nxp+S.H2O_LY2]-LY2max)*one_over_deltat; +POOLS[nxp+S.H2O_LY2]=LY2max;} + +if (POOLS[nxp+S.H2O_LY3]>LY3max){ +//Dump excess into LY3 Q +FLUXES[f+F.q_ly3] +=(POOLS[nxp+S.H2O_LY3]-LY3max)*one_over_deltat; +POOLS[nxp+S.H2O_LY3]=LY3max;} + + +//**********INTERNAL ENERGT FLUXES FOR ALL H2O FLUXES*************** +//Add INFILTRATION, LY1, LY3, LY1xLY3, ET +double infiltemp = air_temp_k ;//Infiltemp needs to be in degrees celcius for IF statement to work +if (FLUXES[f+F.melt]>0){infiltemp = (infiltemp-DGCM_TK0C)*(PREC[n] - SNOWFALL[n])/(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])+DGCM_TK0C;}//snowmelt temp = 0, so term multiplied by zero in weighted average + + +//All energy fluxes + +FLUXES[f+F.infil_e] = FLUXES[f+F.infil]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(infiltemp); +FLUXES[f+F.evap_e] = FLUXES[f+F.evap]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY1]); +FLUXES[f+F.transp1_e] = FLUXES[f+F.transp1]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY1]); +FLUXES[f+F.transp2_e] = FLUXES[f+F.transp2]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY2]); +FLUXES[f+F.ly1xly2_e] = FLUXES[f+F.ly1xly2]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(TEMPxfer_1to2); +FLUXES[f+F.ly2xly3_e] = FLUXES[f+F.ly2xly3]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(TEMPxfer_2to3); +FLUXES[f+F.q_ly1_e] = FLUXES[f+F.q_ly1]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY1]); +FLUXES[f+F.q_ly2_e] = FLUXES[f+F.q_ly2]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY2]); +FLUXES[f+F.q_ly3_e] = FLUXES[f+F.q_ly3]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY3]); +//Thermal conductivity = k*dT/dz, units are W/m2, converting to J/m2/d +FLUXES[f+F.ly1xly2_th_e] = 2*pars[P.thermal_cond]* (POOLS[p+S.D_TEMP_LY1] - POOLS[p+S.D_TEMP_LY2])/(pars[P.LY1_z] + pars[P.LY2_z])*DGCM_SEC_DAY; +FLUXES[f+F.ly2xly3_th_e] = 2*pars[P.thermal_cond]* (POOLS[p+S.D_TEMP_LY2] - POOLS[p+S.D_TEMP_LY3])/(pars[P.LY2_z] + pars[P.LY3_z])*DGCM_SEC_DAY; + + +//Thermal energy flux only +//FLUXES[f+F.ly1xly3_e_thermal] = + +//Energy states +//fraction of water in soil that is available +//double frac_ly1 = POOLS[nxp+S.H2O_LY1]/(POOLS[nxp+S.H2O_LY1]+POOLS[nxp+S.H2O_LY3]); + // E_LY1 + + + FLUXES[f+F.geological]=PREDERIVED_GEO_FLUX;//In J/m2/d //105mW/m2 +POOLS[nxp+S.E_LY1] = POOLS[p+S.E_LY1] + (FLUXES[f+F.gh_in] + FLUXES[f+F.infil_e] - FLUXES[f+F.evap_e] - FLUXES[f+F.transp1_e] - FLUXES[f+F.q_ly1_e] - FLUXES[f+F.ly1xly2_e] - FLUXES[f+F.ly1xly2_th_e])*deltat; +POOLS[nxp+S.E_LY2] = POOLS[p+S.E_LY2] + (FLUXES[f+F.ly1xly2_e] + FLUXES[f+F.ly1xly2_th_e] - FLUXES[f+F.transp2_e] - FLUXES[f+F.q_ly2_e] - FLUXES[f+F.ly2xly3_e] - FLUXES[f+F.ly2xly3_th_e])*deltat; +POOLS[nxp+S.E_LY3] = POOLS[p+S.E_LY3] + (FLUXES[f+F.ly2xly3_e] - FLUXES[f+F.q_ly3_e] + FLUXES[f+F.ly2xly3_th_e] + FLUXES[f + F.geological])*deltat; + +// +// + + +//*************KNORR LAI************** + + +//Time varying KNORR function terms + +KNORR.IN.lambda_max_memory= POOLS[p+S.M_LAI_MAX]; +KNORR.IN.T_memory=POOLS[p+S.M_LAI_TEMP]; +KNORR.IN.temp=air_temp_k; +KNORR.IN.n=n; +KNORR.IN.DOY=DOY[n]; +KNORR.IN.lambda=LAI; +KNORR.IN.pasm=(POOLS[p+S.H2O_LY1]+POOLS[nxp+S.H2O_LY1]+POOLS[p+S.H2O_LY2]+POOLS[nxp+S.H2O_LY2])*0.5;//Note: soil moisture also available here +//KNORR.IN.transp= FLUXES[f+F.transp1]+FLUXES[f+F.transp2]; +KNORR.IN.transp= transp; +//Call function: uses KNORR->IN to update KNORR->OUT +KNORR_ALLOCATION(&KNORR); + +FLUXES[f+F.target_LAI]=KNORR.OUT.lambda_next; +//KNORR.OUT.dlambdadt is in units per timestep; converting thest to units per day (as required for CARDAMOM) +//"FLUXES" have to be in "per day" units +FLUXES[f+F.dlambda_dt]=KNORR.OUT.dlambdadt*one_over_deltat; + +//printf( " target LAI, current LAI, dlambda_dt: %f %f %f", FLUXES[f+F.target_LAI]*pars[P.LCMA], LAI*pars[P.LCMA], FLUXES[f+F.dlambda_dt]*pars[P.LCMA]*deltat); + +FLUXES[f+F.f_temp_thresh]= KNORR.OUT.f_T; +FLUXES[f+F.f_dayl_thresh]= KNORR.OUT.f_d; + +//Update KNORR memory variables for next iteration +POOLS[nxp+S.M_LAI_MAX]=KNORR.OUT.laim; +POOLS[nxp+S.M_LAI_TEMP]=KNORR.OUT.T; + + + +//************Allocation******************* + +ARFLUXES.IN.deltat=deltat; +ARFLUXES.IN.GPP=FLUXES[f+F.gpp]; +ARFLUXES.IN.Rd=LIU.OUT.Rd; +ARFLUXES.IN.TEMP=air_temp_k; +ARFLUXES.IN.NSC=POOLS[p+S.C_lab]; +ARFLUXES.IN.C_LIVE_W=POOLS[p+S.C_woo]; +ARFLUXES.IN.C_LIVE_R= POOLS[p+S.C_roo]; +// Potential plant allocation (growth) fluxes +ARFLUXES.IN.ALLOC_FOL_POT=fmax(0, ((FLUXES[f+F.target_LAI] * pars[P.LCMA]) - POOLS[p+S.C_fol])*one_over_deltat); + + +double Paweffect = (POOLS[p+S.D_SM_LY1]*pars[P.LY1_z] + POOLS[p+S.D_SM_LY2]*pars[P.LY2_z]*pars[P.root_frac])/(pars[P.LY1_z]+pars[P.LY2_z]*pars[P.root_frac]); +ARFLUXES.IN.Paw_norm =Paweffect; + +NLM_AND_ALLOC(&ARFLUXES); + +double NONLEAF_MORTALITY_FACTOR=ARFLUXES.OUT.NONLEAF_MORTALITY_FACTOR; + + + /*track C starvation here*/ +FLUXES[f+F.nonleaf_mortality_factor]=NONLEAF_MORTALITY_FACTOR; + + +/*respiration auto*/ +FLUXES[f+F.resp_auto]=ARFLUXES.OUT.AUTO_RESP_TOTAL; +/*growth respiration*/ +FLUXES[f+F.resp_auto_growth]=ARFLUXES.OUT.AUTO_RESP_GROWTH; +/*maintenance respiration*/ +FLUXES[f+F.resp_auto_maint]=ARFLUXES.OUT.AUTO_RESP_MAINTENANCE; +FLUXES[f+F.resp_auto_maint_dark]=LIU.OUT.Rd; + + + +/*Compute leaf senescence: +this is a C_fol removal based on Knorr output dlambda_dt, +which itself is computed based on the LAI passed to Knorr module, +which is based on start-of-month C_fol; hence subsequent removals +based on this flux should also go first into C_fol, to maintain +compatible pool size */ +if (FLUXES[f+F.dlambda_dt] > 0){ // i.e. when leaf growth is occuring + FLUXES[f+F.ph_fol2lit]=0; +} +else { // i.e. when leaf fall is occuring + //FLUXES[f+F.dlambda_dt] is in m2/m2/day + //LCMA = gC/m2/m2 + FLUXES[f+F.ph_fol2lit]=-FLUXES[f+F.dlambda_dt]*pars[P.LCMA]; +} + + + + +/*labile production*/ +// FLUXES[f+F.lab_prod] = ARFLUXES.OUT.F_LABPROD; //Could also be LIUET.OUT.An? +/*labile production*/ +//FLUXES[f+F.lab_release] = ARFLUXES.OUT.F_LABREL_ACTUAL; +/*foliar production*/ +FLUXES[f+F.foliar_prod] = ARFLUXES.OUT.ALLOC_FOL_ACTUAL; +/*root production*/ +FLUXES[f+F.root_prod] = ARFLUXES.OUT.ALLOC_ROO_ACTUAL; +/*wood production*/ +FLUXES[f+F.wood_prod] = ARFLUXES.OUT.ALLOC_WOO_ACTUAL; + +/*-----------------------------------------------------------------------*/ + + + //TIME-VARYING INPUTS + HRJCR.IN.SM=POOLS[p+S.D_SM_LY1]; + HRJCR.IN.TEMP=POOLS[p+S.D_TEMP_LY1];; // Input in degrees K + HRJCR.IN.LF=POOLS[p+S.D_LF_LY1];; // Input in degrees + + //JCR + HET_RESP_RATES_JCR(&HRJCR); + //OUtputs --- store anything we want here--- + FLUXES[f+F.aetr]=HRJCR.OUT.aerobic_tr;//Aerobic turnover rate scalar + FLUXES[f+F.antr]=HRJCR.OUT.anaerobic_tr;//Anaerobic turnover rate scalar + FLUXES[f+F.an_co2_c_ratio]=HRJCR.OUT.anaerobic_co2_c_ratio;//CO2_C_ratio + FLUXES[f+F.an_ch4_c_ratio]=HRJCR.OUT.anaerobic_ch4_c_ratio;//CH4_C_ratio + + + +//outputformat +//jcr_o 0-3 fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +double ae_loss_cwd = POOLS[p+S.C_cwd]*HRJCR.OUT.aerobic_tr*pars[P.t_cwd]; +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = ae_loss_cwd*(1-pars[P.tr_cwd2som]); +double ae_loss_lit = POOLS[p+S.C_lit]*HRJCR.OUT.aerobic_tr*pars[P.t_lit]; +/* aerobic Rh from litter*/ +FLUXES[f+F.ae_rh_lit] = ae_loss_lit*(1-pars[P.tr_lit2som]); +/* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*HRJCR.OUT.aerobic_tr*pars[P.t_som]; + +//******Anaerobic fluxes +double an_loss_cwd = POOLS[p+S.C_cwd]*HRJCR.OUT.anaerobic_tr*pars[P.t_cwd]; +/* anaerobic Rh from coarse woody debris*/ +FLUXES[f+F.an_rh_cwd] = an_loss_cwd*(1-pars[P.tr_cwd2som]); +/* anaerobic Rh from litter*/ +double an_loss_lit = POOLS[p+S.C_lit]*HRJCR.OUT.anaerobic_tr*pars[P.t_lit]; +FLUXES[f+F.an_rh_lit] = an_loss_lit*(1-pars[P.tr_lit2som]); +/* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*HRJCR.OUT.anaerobic_tr*pars[P.t_som]; +/*CWD to SOM*/ +FLUXES[f+F.cwd2som] = (an_loss_cwd + ae_loss_cwd)*pars[P.tr_cwd2som]; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = (an_loss_lit + ae_loss_lit)*pars[P.tr_lit2som]; +/* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*HRJCR.OUT.anaerobic_co2_c_ratio + (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som]); +/* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*HRJCR.OUT.anaerobic_ch4_c_ratio; + +/*---------------------- end of JCR --------------------------------------------*/ + + +/*total pool transfers (no fires yet)*/ + +/*CARBON POOL GROWTH AND PHENOLOGICAL LEAF FLUX*/ + /*LIVE POOLS*/ + + // printf("\n lab %f \n" ,POOLS[p+S.C_lab]); + // printf("\n fol %f \n" ,POOLS[p+S.C_fol]); + // printf("\n roo %f \n" ,POOLS[p+S.C_roo]); + // printf("\n woo %f \n" ,POOLS[p+S.C_woo]); + // printf("\n cwd %f \n" ,POOLS[p+S.C_cwd]); + // printf("\n lit %f \n" ,POOLS[p+S.C_lit]); + // printf("\n som %f \n" ,POOLS[p+S.C_som]); + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.gpp]-FLUXES[f+F.Rd]-FLUXES[f+F.resp_auto_maint]-FLUXES[f+F.foliar_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.wood_prod]-FLUXES[f+F.resp_auto_growth])*deltat; + + //printf("\n foliar0 %f \n" ,POOLS[p+S.C_fol]); + //printf("\n prod-lit %f \n" ,(FLUXES[f+F.foliar_prod]-FLUXES[f+F.ph_fol2lit])*deltat); + //printf("\n prod %f \n" ,(FLUXES[f+F.foliar_prod])*deltat); + //printf("\n lit %f \n" ,(FLUXES[f+F.ph_fol2lit])*deltat); + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.foliar_prod]-FLUXES[f+F.ph_fol2lit])*deltat; + //printf("\n foliar %f \n" ,POOLS[nxp+S.C_fol]); + // printf("\n C_fol_phenology %f \n ", POOLS[nxp+S.C_fol]); + // printf(" \n Next pool, prod, phenological flux %f %f %f ", POOLS[nxp+S.C_fol], FLUXES[f+F.foliar_prod]*deltat,FLUXES[f+F.ph_fol2lit]*deltat ); + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + FLUXES[f+F.root_prod]*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + FLUXES[f+F.wood_prod]*deltat; + /*DEAD POOLS*/ + POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] - (FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.cwd2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.ph_fol2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + + /*Carbon pool transfers - + WITH FIRES, + HYDRAULIC FAILURE, + CARBON STARVATION, + HUMAN DISTURBANCE, + AND BACKGROUND MORTALITY*/ + /*first fluxes*/ + + /*Calculating disturbance flux as percent of live biomass*/ + /*NB: p=index of current pool timestep; nxp=index of next pool timestep; + removals are scaled by pool(nxp) which has received additions from growth, above*/ + double TotalABGB=POOLS[nxp+S.C_lab]+POOLS[nxp+S.C_fol]+POOLS[nxp+S.C_roo]+POOLS[nxp+S.C_woo]; + double DMF = DIST[n]/TotalABGB; //DIST[n]=disturbance flux at current flux timestep, halfway in between p and nxp + + //Store fluxes for FIOMATRIX balance checks + FLUXES[f+F.dist_lab] = POOLS[nxp+S.C_lab]*DMF*one_over_deltat; + FLUXES[f+F.dist_fol] = POOLS[nxp+S.C_fol]*DMF*one_over_deltat; + FLUXES[f+F.dist_roo] = POOLS[nxp+S.C_roo]*DMF*one_over_deltat; + FLUXES[f+F.dist_woo] = POOLS[nxp+S.C_woo]*DMF*one_over_deltat; + +/*DIRECT LIVE CARBON POOL REMOVALS PART 1 of 4: Removing ABGB disturbance from live pools here*/ + /*Note: these are lateral fluxes, and are discarded, not transferred!*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-FLUXES[f+F.dist_lab]*deltat; + //printf("\n foliarpred %f \n" ,POOLS[nxp+S.C_fol]); + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-FLUXES[f+F.dist_fol]*deltat; + // printf("\n foliarpostd %f \n" ,POOLS[nxp+S.C_fol]); + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-FLUXES[f+F.dist_roo]*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-FLUXES[f+F.dist_woo]*deltat; + + /*Calculating all fire transfers from C pools to atmosphere via combustion*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]*one_over_deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]*one_over_deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]*one_over_deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]*one_over_deltat; + FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]*one_over_deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]*one_over_deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]*one_over_deltat; + + +/*LIVE CARBON POOL REMOVALS PART 2 of 4: Removing fire fluxes from live pools here*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-FLUXES[f+F.f_lab]*deltat; + //printf("\n foliarprefire %f \n" ,POOLS[nxp+S.C_fol]); + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-FLUXES[f+F.f_fol]*deltat; + // printf("\n foliarpostfire %f \n" ,POOLS[nxp+S.C_fol]); + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-FLUXES[f+F.f_roo]*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-FLUXES[f+F.f_woo]*deltat; + /*DEAD CARBON POOL removals for fire*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]-FLUXES[f+F.f_cwd]*deltat; + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]-FLUXES[f+F.f_lit]*deltat; + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]-FLUXES[f+F.f_som]*deltat; + + //LIVE BIOMASS MORTALITY FLUXES + /* Compute aggregate mortality factor by pool from competing environmental stress: + -C starvation + -Hydraulic Failure + -Fire injury mortality*/ + double AMF_C_lab = (1 - (1-NONLEAF_MORTALITY_FACTOR) * (1-(BURNED_AREA[n]*(1-pars[P.resilience]))) * (1-HMF)); + double AMF_C_fol = (1 - (1-LEAF_MORTALITY_FACTOR) * (1-(BURNED_AREA[n]*(1-pars[P.resilience]))) * (1-HMF)); + double AMF_C_roo = (1 - (1-NONLEAF_MORTALITY_FACTOR) * (1-(BURNED_AREA[n]*(1-pars[P.resilience]))) * (1-HMF)); + double AMF_C_woo = (1 - (1-NONLEAF_MORTALITY_FACTOR) * (1-(BURNED_AREA[n]*(1-pars[P.resilience]))) * (1-HMF)); + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*(AMF_C_lab)*one_over_deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*(AMF_C_fol)*one_over_deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*(AMF_C_roo)*one_over_deltat; + FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*(AMF_C_woo)*one_over_deltat; + //No mortality in these pools + FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-pars[P.resilience])*one_over_deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-pars[P.resilience])*one_over_deltat; + +/*LIVE CARBON POOL TRANSFERS PART 3 of 4: environmental stress mortality fluxes to dead pools*/ + + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-FLUXES[f+F.fx_lab2lit]*deltat; + //printf("\n foliarpreenv %f \n" ,POOLS[nxp+S.C_fol]); + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-FLUXES[f+F.fx_fol2lit]*deltat; + // printf("\n foliarpostenv %f \n" ,POOLS[nxp+S.C_fol]); + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-FLUXES[f+F.fx_roo2lit]*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-FLUXES[f+F.fx_woo2cwd]*deltat; + +/*Calculating background mortality (age/herbivory/impact) flux as percent of remaining live biomass*/ +/*wood CWD production*/ +FLUXES[f+F.woo2cwd] = POOLS[nxp+S.C_woo]*pars[P.t_wood]; +/*root litter production*/ +FLUXES[f+F.roo2lit] = POOLS[nxp+S.C_roo]*pars[P.t_root]; +/*labile litter production*/ +FLUXES[f+F.lab2lit] = POOLS[nxp+S.C_lab]*pars[P.t_lab]; + +// Fcfolavailable=FLUXES[f+F.lab_prod] + POOLS[p+S.C_lab]*one_over_deltat; +if (FLUXES[f+F.dlambda_dt] > 0){ + FLUXES[f+F.fol2lit]=POOLS[nxp+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))*one_over_deltat; +// printf("\n growing leaves :( ) %f \n" ,FLUXES[f+F.fol2lit]); +} +else { + //FLUXES[f+F.dlambda_dt] is in m2/m2/day + //LCMA = gC/m2/m2 + FLUXES[f+F.fol2lit]=POOLS[nxp+S.C_fol]*pars[P.t_foliar]; + +// printf("\n h1lp paraamter %f \n" ,pars[P.t_foliar]); +// printf("\n send help pool %f \n" ,POOLS[nxp+S.C_fol]); +// printf("\n dieing leaves :( ) %f \n" ,FLUXES[f+F.fol2lit]); +} + +/*LIVE CARBON POOL TRANSFERS PART 4 of 4: background mortality fluxes to dead pools*/ + + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-FLUXES[f+F.lab2lit]*deltat; + //printf("\n foliarprebgm %f \n" ,POOLS[nxp+S.C_fol]); + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-FLUXES[f+F.fol2lit]*deltat; + // printf("\n foliarpostbgm %f \n" ,POOLS[nxp+S.C_fol]); + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-FLUXES[f+F.roo2lit]*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-FLUXES[f+F.woo2cwd]*deltat; + +/*DEAD C POOLS TRANSFERS PART 1 of 1: Adding fire removals here together with additions from live pools*/ + /*CWD*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.woo2cwd]+FLUXES[f+F.fx_woo2cwd]-FLUXES[f+F.fx_cwd2som])*deltat; + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.lab2lit]+FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fol2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.roo2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som])*deltat; + + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + /*Fraction of C-foliar lost due to fires*/ + FLUXES[f+F.foliar_fire_frac] = BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Calculate LAI (lambda) lost due to fire + - we lose the same fraction of LAI as we do C-foliar + - FE_\Lambda^{(t+1)} = \Lambda^{(t+1)'} * BA ( k_{factor(i)} + (1 - k_{factor(i)}) r )*/ + FLUXES[f+F.lai_fire] = (POOLS[p+S.C_fol]/pars[P.LCMA])*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + + /****************************RECORD t+1 DIAGNOSTIC STATES*************************/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + POOLS[nxp+S.D_SCF]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); //snow cover fraction + + + + + //Update time-varying inputs + LY1SOILTEMP.IN.soil_water = POOLS[nxp+S.H2O_LY1];//mm (or kg/m2) + LY2SOILTEMP.IN.soil_water = POOLS[nxp+S.H2O_LY2];//mm (or kg/m2) + LY3SOILTEMP.IN.soil_water = POOLS[nxp+S.H2O_LY3];//mm (or kg/m2) + LY1SOILTEMP.IN.internal_energy = POOLS[nxp+S.E_LY1];//Joules + LY2SOILTEMP.IN.internal_energy = POOLS[nxp+S.E_LY2];//Joules + LY3SOILTEMP.IN.internal_energy = POOLS[nxp+S.E_LY3];//Joules + + SOIL_TEMP_AND_LIQUID_FRAC(&LY1SOILTEMP); + SOIL_TEMP_AND_LIQUID_FRAC(&LY2SOILTEMP); + SOIL_TEMP_AND_LIQUID_FRAC(&LY3SOILTEMP); + + POOLS[nxp+S.D_TEMP_LY1]=LY1SOILTEMP.OUT.TEMP;//In K + POOLS[nxp+S.D_TEMP_LY2]=LY2SOILTEMP.OUT.TEMP;//In K + POOLS[nxp+S.D_TEMP_LY3]=LY3SOILTEMP.OUT.TEMP;//In K + + POOLS[nxp+S.D_LF_LY1]=LY1SOILTEMP.OUT.LF; + POOLS[nxp+S.D_LF_LY2]=LY2SOILTEMP.OUT.LF; + POOLS[nxp+S.D_LF_LY3]=LY3SOILTEMP.OUT.LF; + + + //Pass pointers to function + + + //Soil moisture + + POOLS[nxp+S.D_SM_LY1]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY1],pars[P.LY1_por],pars[P.LY1_z]); //soil moisture LY1 + POOLS[nxp+S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY2],pars[P.LY2_por],pars[P.LY2_z]);//soil moisture LY2 + POOLS[nxp+S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3 + + + POOLS[nxp+S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY1],psi_porosity,pars[P.retention]),minpsi); + POOLS[nxp+S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY2],psi_porosity,pars[P.retention]),minpsi); + POOLS[nxp+S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY3],psi_porosity,pars[P.retention]),minpsi); + + +// //Isfinite check for 14 progronstic pools only + int nnn, isfinitecheck=1; + for (nnn=0;nnn<14;nnn++){if ( isfinite(POOLS[nxp+nnn])==false){isfinitecheck=0;}}; + if (isfinitecheck==0){break;}; + +} + + + +return 0; +} + + +int DALEC_1130_MODCONFIG(DALEC * DALECmodel, DATA * DATA){ + + + PREDERIVE_DALEC_1130_DATA(DALECmodel, DATA); + +struct DALEC_1130_PARAMETERS P=DALEC_1130_PARAMETERS; +struct DALEC_1130_FLUXES F=DALEC_1130_FLUXES; +struct DALEC_1130_POOLS S=DALEC_1130_POOLS; +struct DALEC_1130_EDCs E=DALEC_1130_EDCs; + + + + + //DALECmodel->data=DALEC_1130_DATA; +DALECmodel->dalec=DALEC_1130; +DALECmodel->nopools=30; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=94; +DALECmodel->nofluxes=94; +DALECmodel->noedcs=17; + +DALEC_1130_FLUX_SOURCES_SINKS(DALECmodel); + + + + +//Define PARS_INFO here (ranges, and eventually names, etc) +PARS_INFO_1130(DALECmodel); + +//EDC operator +//Make sure has same number as number of EDCs +//This is generic EDCs structure defined in ../DALEC_EDCs/DALEC_EDC_FUNCTIONS.c +//Has three args, data (void), function (in "DATA", and "void *", and "double" out), and "boolean" prerun. + + + + + +DALECmodel->EDCs=calloc(DALECmodel->noedcs,sizeof(EDCs)); +//Abbrieviate +EDCs * EDCs=DALECmodel->EDCs; + +//Som lit turnover rate + +//EDC: litter tor > cwd tor +//List all inequality calls here +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_litcwdtor; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_cwdsomtor; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_rootwoodtor; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_mr_rates; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_fol2lig_cf; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_relativepsi50; + +//EDC: lit tor > cwd tor +EDC_litcwdtor.big_par_index=P.t_lit; +EDC_litcwdtor.small_par_index=P.t_cwd; +EDCs[E.litcwdtor].data=&EDC_litcwdtor; +EDCs[E.litcwdtor].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.litcwdtor].prerun=true; + +//EDC: cwd tor > som tor +EDC_cwdsomtor.big_par_index=P.t_cwd; +EDC_cwdsomtor.small_par_index=P.t_som; +EDCs[E.cwdsomtor].data=&EDC_cwdsomtor; +EDCs[E.cwdsomtor].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.cwdsomtor].prerun=true; + +//EDC: root tor > wood tor +EDC_rootwoodtor.big_par_index=P.t_root; +EDC_rootwoodtor.small_par_index=P.t_wood; +EDCs[E.rootwoodtor].data=&EDC_rootwoodtor; +EDCs[E.rootwoodtor].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.rootwoodtor].prerun=true; + +//EDC: foliar and root mr > wood mr +EDC_mr_rates.big_par_index=P.rauto_mr_r; +EDC_mr_rates.small_par_index=P.rauto_mr_w; +EDCs[E.mr_rates].data=&EDC_mr_rates; +EDCs[E.mr_rates].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.mr_rates].prerun=true; + +//EDC: cf_foliar > cf_ligneous +EDC_fol2lig_cf.big_par_index=P.cf_foliar; +EDC_fol2lig_cf.small_par_index=P.cf_ligneous; +EDCs[E.fol2lig_cf].data=&EDC_fol2lig_cf; +EDCs[E.fol2lig_cf].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.fol2lig_cf].prerun=true; + +//EDC: psi50HMF > psi50 +EDC_relativepsi50.big_par_index=P.psi_50HMF; +EDC_relativepsi50.small_par_index=P.psi_50; +EDCs[E.relativepsi50].data=&EDC_relativepsi50; +EDCs[E.relativepsi50].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.relativepsi50].prerun=true; + +static DALEC_EDC_PARAMETER_LOG_RATIO_STRUCT EDC_vcmax_lcma; +//EDC: ratio of Vcmax25 to LCMA +EDC_vcmax_lcma.numerator_index=P.Vcmax25; +EDC_vcmax_lcma.denominator_index=P.LCMA; +EDC_vcmax_lcma.mean_ratio = 1.0399; // From TRY database +EDC_vcmax_lcma.std_ratio = 0.1956; // From TRY database +EDCs[E.vcmax_lcma].data=&EDC_vcmax_lcma; +EDCs[E.vcmax_lcma].function=&DALEC_EDC_PARAMETER_LOG_RATIO; +EDCs[E.vcmax_lcma].prerun=true; + + + + + +//State ranges + static DALEC_EDC_STATE_RANGES_STRUCT EDC_sr; + + //Create array (1x number of pools) for minimum and max values + //Index exactly corresponds to "POOLS" indices + + EDC_sr.min_val=calloc(DALECmodel->nopools,sizeof(double)); + + EDC_sr.max_val=calloc(DALECmodel->nopools,sizeof(double)); + + int n; + for (n=0;nnopools;n++){ + EDC_sr.min_val[n]=-INFINITY; + EDC_sr.max_val[n]=INFINITY;} + + EDC_sr.min_val[S.C_lab]=0; + EDC_sr.max_val[S.C_lab]=(DALECmodel->PARS_INFO.parmax[P.i_labile]); + + EDC_sr.min_val[S.C_fol]=0; + EDC_sr.max_val[S.C_fol]=(DALECmodel->PARS_INFO.parmax[P.i_foliar]); + + EDC_sr.min_val[S.C_roo]=0; + EDC_sr.max_val[S.C_roo]=(DALECmodel->PARS_INFO.parmax[P.i_root]); + + EDC_sr.min_val[S.C_woo]=0; + EDC_sr.max_val[S.C_woo]=(DALECmodel->PARS_INFO.parmax[P.i_wood]); + + EDC_sr.min_val[S.C_cwd]=0; + EDC_sr.max_val[S.C_cwd]=(DALECmodel->PARS_INFO.parmax[P.i_cwd]); + + EDC_sr.min_val[S.C_lit]=0; + EDC_sr.max_val[S.C_lit]=(DALECmodel->PARS_INFO.parmax[P.i_lit]); + + EDC_sr.min_val[S.C_som]=0; + EDC_sr.max_val[S.C_som]=(DALECmodel->PARS_INFO.parmax[P.i_som]); + + EDC_sr.min_val[S.H2O_LY1]=0; + // + + EDC_sr.min_val[S.H2O_LY2]=0; + // + + EDC_sr.min_val[S.H2O_LY3]=0; + // + + EDC_sr.min_val[S.H2O_SWE]=0; +// EDC_sr.max_val[S.H2O_SWE]=DALECmodel->PARS_INFO.parmax[P.i_SWE]; +// + EDC_sr.min_val[S.E_LY1]=0; +// + EDC_sr.min_val[S.E_LY2]=0; +// + EDC_sr.min_val[S.E_LY3]=0; +// + EDC_sr.min_val[S.D_LAI]=0; + EDC_sr.max_val[S.D_LAI]=DALECmodel->PARS_INFO.parmax[P.lambda_max]; +// + EDC_sr.min_val[S.D_SCF]=0; + EDC_sr.max_val[S.D_SCF]=1; +// + EDC_sr.min_val[S.D_TEMP_LY1]=173.15; + EDC_sr.max_val[S.D_TEMP_LY1]=373.15; +// + EDC_sr.min_val[S.D_TEMP_LY2]=173.15; + EDC_sr.max_val[S.D_TEMP_LY2]=373.15; +// + EDC_sr.min_val[S.D_TEMP_LY3]=173.15; + EDC_sr.max_val[S.D_TEMP_LY3]=373.15; +// + EDC_sr.min_val[S.D_LF_LY1]=0; + EDC_sr.max_val[S.D_LF_LY1]=1; +// + EDC_sr.min_val[S.D_LF_LY3]=0; + EDC_sr.max_val[S.D_LF_LY3]=1; +// + EDC_sr.min_val[S.D_SM_LY1]=0; + EDC_sr.max_val[S.D_SM_LY1]=1; +// + EDC_sr.min_val[S.D_SM_LY2]=0; + EDC_sr.max_val[S.D_SM_LY2]=1; +// + EDC_sr.min_val[S.D_SM_LY3]=0; + EDC_sr.max_val[S.D_SM_LY3]=1; + +// EDC_sr.min_val[S.M_LAI_MAX]=-INFINITY; // get a better value from Alex N. +// EDC_sr.max_val[S.M_LAI_MAX]=INFINITY; // get a better value from Alex N. + +// EDC_sr.min_val[S.M_LAI_TEMP]=-INFINITY; // get a better value from Alex N. +// EDC_sr.max_val[S.M_LAI_TEMP]=INFINITY; // get a better value from Alex N. + + + + + +//Adding EDC to the EDCs list + + + EDCs[E.state_ranges].data=&EDC_sr; + EDCs[E.state_ranges].function=&DALEC_EDC_STATE_RANGES; + EDCs[E.state_ranges].prerun=false; + + + + + + + + static DALEC_EDC_TRAJECTORY_STRUCT EDC_st; + + static int edc_pool_indices[14]; + static double edc_pool_eqf[14]; +EDC_st.pool_indices=edc_pool_indices; +EDC_st.pool_eqf=edc_pool_eqf; +EDC_st.no_pools_to_check=14; + +EDC_st.pool_indices[0]=S.C_lab; +EDC_st.pool_indices[1]=S.C_fol; +EDC_st.pool_indices[2]=S.C_roo; +EDC_st.pool_indices[3]=S.C_woo; +EDC_st.pool_indices[4]=S.C_cwd; +EDC_st.pool_indices[5]=S.C_lit; +EDC_st.pool_indices[6]=S.C_som; +EDC_st.pool_indices[7]=S.H2O_LY1; +EDC_st.pool_indices[8]=S.H2O_LY2; +EDC_st.pool_indices[9]=S.H2O_LY3; +EDC_st.pool_indices[10]=S.H2O_SWE; +EDC_st.pool_indices[11]=S.E_LY1; +EDC_st.pool_indices[12]=S.E_LY2; +EDC_st.pool_indices[13]=S.E_LY3; +//EDC_st.pool_indices[12]=S.M_LAI_MAX;``` +//EDC_st.pool_indices[13]=S.M_LAI_TEMP; + + + +for (n=0;nncdf_data.EDC_EQF;printf("DATA->ncdf_data.EDC_EQF = %2.2f\n",DATA->ncdf_data.EDC_EQF);} +// EDC_st.pool_eqf[9]=10; +// EDC_st.pool_eqf[10]=10; + +// //Rest can be done by code without additional input + +EDCs[E.state_trajectories].data=&EDC_st; +EDCs[E.state_trajectories].function=&DALEC_EDC_TRAJECTORY; +EDCs[E.state_trajectories].prerun=false; + +//Eventually adopt more succinct notation (to consider) +//e.g. INEQUALITY_EDC(P.t_cwd,P.t_som,EDCs[E.cwdsomtor]) + + static DALEC_EDC_NSC_ABGB_RATIO_STRUCT EDC_nscr; + + // + EDC_nscr.no_other_pool_indices=3; + static int nscratio_other_pool_indices[3]; + + EDC_nscr.other_pool_indices=nscratio_other_pool_indices; + EDC_nscr.other_pool_indices[0]=S.C_fol; + EDC_nscr.other_pool_indices[1]=S.C_roo; + EDC_nscr.other_pool_indices[2]=S.C_woo; + EDC_nscr.nsc_pool_index=S.C_lab; + + + EDCs[E.nsc_ratio].data=&EDC_nscr; + EDCs[E.nsc_ratio].function=&DALEC_EDC_NSC_ABGB_RATIO; + EDCs[E.nsc_ratio].prerun=false; + +static DALEC_EDC_POOL_RATIO_STRUCT EDC_cfcrr; + // + EDC_cfcrr.numerator_index=S.C_fol; + EDC_cfcrr.denominator_index=S.C_roo; + + EDCs[E.cfcr_ratio].data=&EDC_cfcrr; + EDCs[E.cfcr_ratio].function=&DALEC_EDC_POOL_RATIO; + EDCs[E.cfcr_ratio].prerun=false; + +static DALEC_EDC_FLUX_RATIO_STRUCT EDC_fffrr; + // + EDC_fffrr.numerator_flux_index=F.foliar_prod; + EDC_fffrr.denominator_flux_index=F.root_prod; + + EDCs[E.fffr_ratio].data=&EDC_fffrr; + EDCs[E.fffr_ratio].function=&DALEC_EDC_FLUX_RATIO; + EDCs[E.fffr_ratio].prerun=false; + +static DALEC_EDC_MEAN_TEMP_STRUCT EDC_mean_ly1_temp, EDC_mean_ly2_temp, EDC_mean_ly3_temp; + + // + EDC_mean_ly1_temp.temp_index=S.D_TEMP_LY1; + EDCs[E.mean_ly1_temp].data=&EDC_mean_ly1_temp; + EDCs[E.mean_ly1_temp].function=&DALEC_EDC_MEAN_TEMP; + EDCs[E.mean_ly1_temp].prerun=false; + + + EDC_mean_ly2_temp.temp_index=S.D_TEMP_LY2; + EDCs[E.mean_ly2_temp].data=&EDC_mean_ly2_temp; + EDCs[E.mean_ly2_temp].function=&DALEC_EDC_MEAN_TEMP; + EDCs[E.mean_ly2_temp].prerun=false; + + + EDC_mean_ly3_temp.temp_index=S.D_TEMP_LY3; + EDCs[E.mean_ly3_temp].data=&EDC_mean_ly3_temp; + EDCs[E.mean_ly3_temp].function=&DALEC_EDC_MEAN_TEMP; + EDCs[E.mean_ly3_temp].prerun=false; + +static DALEC_EDC_PARAMETER_ZEROONE_STRUCT EDC_wetalloc; +static DALEC_EDC_PARAMETER_ZEROONE_STRUCT EDC_dryalloc; + +EDC_wetalloc.parone=P.s_ar; +EDC_wetalloc.partwo=P.s_wood; +EDC_wetalloc.parthree=P.s_root; +EDCs[E.EDC_wetalloc].data=&EDC_wetalloc; +EDCs[E.EDC_wetalloc].function=&DALEC_EDC_PARAMETER_ZEROONE; +EDCs[E.EDC_wetalloc].prerun=true; + + +EDC_dryalloc.parone=P.e_ar; +EDC_dryalloc.partwo=P.e_wood; +EDC_dryalloc.parthree=P.e_root; +EDCs[E.EDC_dryalloc].data=&EDC_dryalloc; +EDCs[E.EDC_dryalloc].function=&DALEC_EDC_PARAMETER_ZEROONE; +EDCs[E.EDC_dryalloc].prerun=true; + + + +//ecological +//EDCOPE.SUPPORT_LITCWDSOM_trpar_EDC=true; +//dynamical +//EDCOPE.SUPPORT_POOL_SSP_EDC=true; +//Numerical checks +//EDCOPE.SUPPORT_FINITE_EDC=true; + + + + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + + +//Set SUPPORT_OBS values to true if model supports external observation operations. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_SIF_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; +OBSOPE.SUPPORT_SCF_OBS=true; + + + + +// OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Vcmax25_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +OBSOPE.SUPPORT_CUEmrg_OBS=true; +OBSOPE.SUPPORT_LCMA_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables//Assuming FLUXNET GPP is assumed to be Ag. + //Wohlfahrt & Gu, 2015 +OBSOPE.GPP_flux=F.gpp; +// For constraint on emergent autotrophic fraction +OBSOPE.Rauto_flux=F.resp_auto; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variables +OBSOPE.ET_flux=F.ets; +//Runoff variables +static int ROFF_fluxes[4]; +ROFF_fluxes[0]=F.q_ly1; +ROFF_fluxes[1]=F.q_ly2; +ROFF_fluxes[2]=F.q_ly3; +ROFF_fluxes[3]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=4; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[4]; +EWT_h2o_pools[0]=S.H2O_LY1; +EWT_h2o_pools[1]=S.H2O_LY2; +EWT_h2o_pools[2]=S.H2O_LY3; +EWT_h2o_pools[3]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=4; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//SCF-specific variables +OBSOPE.SCF_pool=S.D_SCF; + + +//Vcmax25 parameters +OBSOPE.Vcmax25_PARAM=P.Vcmax25; +// //C3frac parameters +// OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_som; +OBSOPE.LCMA_PARAM=P.LCMA; + +//CH4-specific variables +OBSOPE.CH4_flux = F.rh_ch4; + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1130/PARS_INFO_1130.c === + +#pragma once +#include "DALEC_1130_INDICES.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + + +int PARS_INFO_1130(DALEC * DALECmodel){ + +struct DALEC_1130_PARAMETERS P=DALEC_1130_PARAMETERS; + + +DALECmodel->PARS_INFO.parmin= calloc(DALECmodel->nopars, sizeof(double)); +DALECmodel->PARS_INFO.parmax= calloc(DALECmodel->nopars, sizeof(double)); +//Abbreviate + +double * parmin = DALECmodel->PARS_INFO.parmin; +double * parmax =DALECmodel->PARS_INFO.parmax; +/*Litter decomposition rate*/ +parmin[P.tr_lit2som]=0.01; +parmax[P.tr_lit2som]=0.99; + +/*CWD decomposition rate*/ +parmin[P.tr_cwd2som]=0.01; +parmax[P.tr_cwd2som]=0.99; + +/*Autotrophic maintenance respiration coefficient for roots - turnover rate at 25oC (d-1)*/ +parmin[P.rauto_mr_r]=0.0001; +parmax[P.rauto_mr_r]=0.01; + +/*Autotrophic maintenance respiration coefficient for wood - turnover rate at 25oC (d-1)*/ +parmin[P.rauto_mr_w]=0.000001; +parmax[P.rauto_mr_w]=0.005; + +/*Autotrophic maintenance respiration Q10 parameter*/ +parmin[P.rauto_mr_q10]=1.0; +parmax[P.rauto_mr_q10]=5.0; + +/*Dark respiration Q10 parameter*/ +parmin[P.rauto_mrd_q10]=1.0; +parmax[P.rauto_mrd_q10]=5.0; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.01; + +/*TOR labile C*/ //Setting to be equal to roots as first guess (10.21.23) +parmin[P.t_lab]=0.0001; +parmax[P.t_lab]=0.01; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.1; + +/*TOR CWD*/ +parmin[P.t_cwd]=0.00005; +parmax[P.t_cwd]=0.05; + +/*TOR SOM*/ +parmin[P.t_som]=0.0000001; +parmax[P.t_som]=0.01; + +/*\Q10 = 1.2-2.0*/ +parmin[P.Q10rhco2]=1; +parmax[P.Q10rhco2]=5.0; + +/*LMCA*; Kattge et al. 2011*;*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=100000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C CWD*/ +parmin[P.i_cwd]=1.0; +parmax[P.i_cwd]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*Retention parameter (b)*/ +parmin[P.retention]=1.5; +parmax[P.retention]=10; + +/*"LY1 SM at t0"*/ +parmin[P.i_LY1_SM]=0.01; +parmax[P.i_LY1_SM]=1; + +/*"LY2 SM at t0"*/ +parmin[P.i_LY2_SM]=0.01; +parmax[P.i_LY2_SM]=1; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +parmin[P.hydr_cond]=1e-9; +parmax[P.hydr_cond]=1e-4; + +/*Maximum infiltration (mm/day)*/ +parmin[P.max_infil]=1; +parmax[P.max_infil]=100; + +/*LY3 SM at t=0*/ +parmin[P.i_LY3_SM]=0.01; +parmax[P.i_LY3_SM]=1; + +/*LY1 porosity*/ +parmin[P.LY1_por]=0.2; +parmax[P.LY1_por]=0.8; + +/*LY2 porosity*/ +parmin[P.LY2_por]=0.2; +parmax[P.LY2_por]=0.8; + +/*LY3 porosity*/ +parmin[P.LY3_por]=0.2; +parmax[P.LY3_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +parmin[P.field_cap]=0.01; +parmax[P.field_cap]=0.1; + +/*LY1 depth (m)*/ +parmin[P.LY1_z]=0.01; +parmax[P.LY1_z]=1; + +/*LY2 depth (m)*/ +parmin[P.LY2_z]=0.01; +parmax[P.LY2_z]=20; + +/*LY3 depth (m)*/ +parmin[P.LY3_z]=0.01; +parmax[P.LY3_z]=100; + +/*LY1 volumetric heat capacity (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)*/ +parmin[P.LY1_vhc]=1.3e6; +parmax[P.LY1_vhc]=3e6; + +/*LY2 volumetric heat capacity (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)*/ +parmin[P.LY2_vhc]=1.3e6; +parmax[P.LY2_vhc]=3e6; + +/*LY3 volumetric heat capacity (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)*/ +parmin[P.LY3_vhc]=1.3e6; +parmax[P.LY3_vhc]=3e6; + +/*Runoff excess*/ +parmin[P.Q_excess]=0.01; +parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +parmin[P.Med_g1]=1.79; +parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +parmin[P.Vcmax25]=1; +parmax[P.Vcmax25]=150; + +/*Tminmin scaling factor*/ +parmin[P.Tminmin]=258.15; +parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +parmin[P.Tminmax]=273.15; +parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance (m/s)*/ +parmin[P.ga]=0.001; +parmax[P.ga]=10.0; + +/*Tupp*/ +parmin[P.Tupp]=249.15; // 299.15-50 +parmax[P.Tupp]=318.15; + +/*Tdown*/ +parmin[P.Tdown]=213.15; // 263.15-50 +parmax[P.Tdown]=286.15; + +/*Clumping index*/ +parmin[P.clumping]=0.35; +parmax[P.clumping]=1.0; + +/*PAR reflectance*/ +parmin[P.leaf_refl_par]=0.05; +parmax[P.leaf_refl_par]=0.5; + +/*NIR reflectance*/ +parmin[P.leaf_refl_nir]=0.3; +parmax[P.leaf_refl_nir]=0.7; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +parmin[P.i_SWE]=0.000001; +parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +parmin[P.min_melt]=263.15; +parmax[P.min_melt]=283.15; + +/*sn2: slope*/ +parmin[P.melt_slope]=0.00001; +parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar; SCF = SWE/(SWE +SWEcritical_par) */ +parmin[P.scf_scalar]=10; +parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (LY1/LY1_fs)\n jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +parmin[P.S_fv]=1; +parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +parmin[P.thetas_opt]=0.2; +parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +parmin[P.fwc]=0.01; +parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +parmin[P.r_ch4]=0.001; +parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +parmin[P.Q10ch4]=1.0; +parmax[P.Q10ch4]=5.0; + +/* maxPevap in mm/day*/ +parmin[P.maxPevap]=0.01; +parmax[P.maxPevap]=100; + +/*Mean temperature at leaf onset (T_phi) (degrees kelvin)*/ +parmin[P.T_phi]=268.15; +parmax[P.T_phi]=323.15; + +/*Spatial range of mean temperature at leaf onset (T_r) (degrees C or degrees kelvin)*/ +parmin[P.T_range]=0.1; +parmax[P.T_range]=10.0; + +/*LAI linear growth constant (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.plgr]=0.001; +parmax[P.plgr]=0.5; + +/*Inverse of leaf longevity during senescence period (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.k_leaf]=0.001; +parmax[P.k_leaf]=0.5; + +/*Intrinsic maximum LAI (m^2 m^-2)*/ +parmin[P.lambda_max]=0.1; +parmax[P.lambda_max]=10.0; + +/*Target survival time for LAI under water-deficit conditions (days; or same unit as ET and LY1)*/ +parmin[P.tau_W]=0.1; +parmax[P.tau_W]=300; + +/*Mean daylength at leaf shedding (t_c; in units of hours sunlight per day)*/ +parmin[P.time_c]=2; +parmax[P.time_c]=22; + +/*Spatial range of mean daylength at leaf shedding (t_r)*/ +parmin[P.time_r]=0.1; +parmax[P.time_r]=6.0; + +/*initialization of temperature memory at t=0 (in absolute temperature units)*/ +parmin[P.init_T_mem]=268.14; +parmax[P.init_T_mem]=323.15; + +/*initialization of water/structural memory (fractional value of intrinsic maximum LAI)*/ +parmin[P.init_LAIW_mem]=0.01; +parmax[P.init_LAIW_mem]=1; + +/*Inverse of leaf longevity at any period i.e. background turnover (days-1)*/ +parmin[P.t_foliar]=0.001; +parmax[P.t_foliar]=0.1; + + +/*LY1 energy per mm H2O (~ Energy in 1mm H2O @ -50C to 1mm H2O@ +50C)*/ +parmin[P.i_LY1_E]=4.67e+05; +parmax[P.i_LY1_E]=1.11e+06; + +/*LY2 energy per mm H2O(~ Energy in 1mm H2O @ -50C to 1mm H2O@ +50C)*/ +parmin[P.i_LY2_E]=4.67e+05; +parmax[P.i_LY2_E]=1.11e+06; + +/*LY3 energy per mm H2O (~ Energy in 1mm H2O @ -50C to 1mm H2O@ +50C)*/ +parmin[P.i_LY3_E]=4.67e+05; +parmax[P.i_LY3_E]=1.11e+06; + +/*PSI 50: water potential when soil-plant continuum is at 50% hydraulic conductivity (-MPa) due to stomatal closure*/ +parmin[P.psi_50]=0.1; +parmax[P.psi_50]=30; + +/*PSI 50 HMF: water potential triggering 50% biomass mortality due to cavitation(-MPa)*/ +parmin[P.psi_50HMF]=0.1; +parmax[P.psi_50HMF]=30; + +/*Beta function normalized logistic growth rate */ +parmin[P.beta_lgr]=4.1; +parmax[P.beta_lgr]=50; + +/*HMFBeta function normalized logistic growth rate */ +parmin[P.beta_lgrHMF]=4.1; +parmax[P.beta_lgrHMF]=50; + +/*Deep thermal conductivity in W/m/K */ +parmin[P.thermal_cond]=0.3; +parmax[P.thermal_cond]=2; + + +/*Surface soil thermal conductivity in W/m/K */ +parmin[P.thermal_cond_surf]=0.03; +parmax[P.thermal_cond_surf]=2; + + +/*Surface soil thermal conductivity in W/m/K */ +parmin[P.q10canopy]=1; +parmax[P.q10canopy]=5; + + /*Surface soil thermal conductivity in W/m/K */ +parmin[P.canopyRdsf]=0.005; +parmax[P.canopyRdsf]=0.025; + + /*Sublimation rate: mm/day/SCF/kPha/(MJ/m2/d) Biggest = 1/0.5/2/2; Smallest = 1/1/10/10/*/ +parmin[P.sublimation_rate]=0.001; +parmax[P.sublimation_rate]=10; + +/*Fraction of LY2 to LY1 root biomass*/ +parmin[P.root_frac]=0.001; +parmax[P.root_frac]=1; + + + + +/* wet resp allocation*/ +parmin[P.s_ar]=.05; +parmax[P.s_ar]=.40; + +/* wet NSC allocation*/ +parmin[P.s_wood]= .001; +parmax[P.s_wood]= .998; + +/* wet root allocation*/ +parmin[P.s_root]= .001; +parmax[P.s_root]= .998; + + +/* dry resp allocation*/ +parmin[P.e_ar]=.05; +parmax[P.e_ar]=.40; + +/* dry NSC allocation*/ +parmin[P.e_wood]= .001; +parmax[P.e_wood]= .998; + +/* dry root allocation*/ +parmin[P.e_root]= .001; +parmax[P.e_root]= .998; + + +/*W_o Midpoint of logistic function*/ +parmin[P.W_o]=0.001; +parmax[P.W_o]=1; + +/*k growth rate for allocation logistic function*/ +parmin[P.k]=0.001; +parmax[P.k]=50; + + + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1130/DALEC_1130_NC_INFO.c === + + + +// Carbon, Water, Energy Fluxes +FLUX_INFO.NAME[F.gpp]='Gross Primary productivity'; +FLUX_INFO.ABBREVIATION[F.gpp]='GPP'; +FLUX_INFO.UNITS[F.gpp]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.gpp]='GPP, doesn't include maintenance respiration'; + +FLUX_INFO.NAME[F.gppnet]='Net Gross Primary Productivity'; +FLUX_INFO.ABBREVIATION[F.gppnet]='gppnet'; +FLUX_INFO.UNITS[F.gppnet]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.gppnet]='GPP, including maintenance respiration'; + +FLUX_INFO.NAME[F.resp_auto]='Total autotrophic respiration'; +FLUX_INFO.ABBREVIATION[F.resp_auto]='resp_auto'; +FLUX_INFO.UNITS[F.resp_auto]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.resp_auto]='Includes maintenance respiration and growth respiration'; + +FLUX_INFO.NAME[F.lab_prod]='Labile production'; +FLUX_INFO.ABBREVIATION[F.lab_prod]='lab_prod'; +FLUX_INFO.UNITS[F.lab_prod]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.lab_prod]='TBD'; + +FLUX_INFO.NAME[F.foliar_prod]='Labile release'; +FLUX_INFO.ABBREVIATION[F.foliar_prod]='foliar_prod'; +FLUX_INFO.UNITS[F.foliar_prod]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.foliar_prod]='TBD'; + +FLUX_INFO.NAME[F.root_prod]='Root production'; +FLUX_INFO.ABBREVIATION[F.root_prod]='root_prod'; +FLUX_INFO.UNITS[F.root_prod]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.root_prod]='TBD'; + +FLUX_INFO.NAME[F.wood_prod]='Wood production'; +FLUX_INFO.ABBREVIATION[F.wood_prod]='wood_prod'; +FLUX_INFO.UNITS[F.wood_prod]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.wood_prod]='TBD'; + +FLUX_INFO.NAME[F.fol2lit]='Foliar decomposition'; +FLUX_INFO.ABBREVIATION[F.fol2lit]='fol2lit'; +FLUX_INFO.UNITS[F.fol2lit]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.fol2lit]='TBD'; + +FLUX_INFO.NAME[F.woo2cwd]='Wood decomposition'; +FLUX_INFO.ABBREVIATION[F.woo2cwd]='woo2cwd'; +FLUX_INFO.UNITS[F.woo2cwd]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.woo2cwd]='TBD'; + +FLUX_INFO.NAME[F.roo2lit]='Root decomposition'; +FLUX_INFO.ABBREVIATION[F.roo2lit]='roo2lit'; +FLUX_INFO.UNITS[F.roo2lit]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.roo2lit]='TBD'; + +FLUX_INFO.NAME[F.cwd2som]='CWD decomposition'; +FLUX_INFO.ABBREVIATION[F.cwd2som]='cwd2som'; +FLUX_INFO.UNITS[F.cwd2som]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.cwd2som]='TBD'; + +FLUX_INFO.NAME[F.lit2som]='Litter decomposition'; +FLUX_INFO.ABBREVIATION[F.lit2som]='lit2som'; +FLUX_INFO.UNITS[F.lit2som]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.lit2som]='TBD'; + +FLUX_INFO.NAME[F.f_total]='Total Fire Flux'; +FLUX_INFO.ABBREVIATION[F.f_total]='f_total'; +FLUX_INFO.UNITS[F.f_total]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.f_total]='TBD'; + +FLUX_INFO.NAME[F.f_lab]='Labile fire loss'; +FLUX_INFO.ABBREVIATION[F.f_lab]='f_lab'; +FLUX_INFO.UNITS[F.f_lab]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.f_lab]='TBD'; + +FLUX_INFO.NAME[F.f_fol]='Foliar fire loss'; +FLUX_INFO.ABBREVIATION[F.f_fol]='f_fol'; +FLUX_INFO.UNITS[F.f_fol]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.f_fol]='TBD'; + +FLUX_INFO.NAME[F.f_roo]='Root fire loss'; +FLUX_INFO.ABBREVIATION[F.f_roo]='f_roo'; +FLUX_INFO.UNITS[F.f_roo]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.f_roo]='TBD'; + +FLUX_INFO.NAME[F.f_woo]='Wood fire loss'; +FLUX_INFO.ABBREVIATION[F.f_woo]='f_woo'; +FLUX_INFO.UNITS[F.f_woo]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.f_woo]='TBD'; + +FLUX_INFO.NAME[F.f_cwd]='CWD fire loss'; +FLUX_INFO.ABBREVIATION[F.f_cwd]='f_cwd'; +FLUX_INFO.UNITS[F.f_cwd]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.f_cwd]='TBD'; + +FLUX_INFO.NAME[F.f_lit]='Litter fire loss'; +FLUX_INFO.ABBREVIATION[F.f_lit]='f_lit'; +FLUX_INFO.UNITS[F.f_lit]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.f_lit]='TBD'; + +FLUX_INFO.NAME[F.f_som]='Soil fire loss'; +FLUX_INFO.ABBREVIATION[F.f_som]='f_som'; +FLUX_INFO.UNITS[F.f_som]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.f_som]='TBD'; + +FLUX_INFO.NAME[F.fx_lab2lit]='Fire labile to litter'; +FLUX_INFO.ABBREVIATION[F.fx_lab2lit]='fx_lab2lit'; +FLUX_INFO.UNITS[F.fx_lab2lit]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.fx_lab2lit]='Fire transfer labile to litter'; + +FLUX_INFO.NAME[F.fx_fol2lit]='Fire foliar to litter'; +FLUX_INFO.ABBREVIATION[F.fx_fol2lit]='fx_fol2lit'; +FLUX_INFO.UNITS[F.fx_fol2lit]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.fx_fol2lit]='Fire transfer foliar to litter'; + +FLUX_INFO.NAME[F.fx_roo2lit]='Fire root to litter'; +FLUX_INFO.ABBREVIATION[F.fx_roo2lit]='fx_roo2lit'; +FLUX_INFO.UNITS[F.fx_roo2lit]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.fx_roo2lit]='Fire transfer root to litter'; + +FLUX_INFO.NAME[F.fx_woo2cwd]='Fire wood to CWD'; +FLUX_INFO.ABBREVIATION[F.fx_woo2cwd]='fx_woo2cwd'; +FLUX_INFO.UNITS[F.fx_woo2cwd]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.fx_woo2cwd]='Fire transfer wood to CWD'; + +FLUX_INFO.NAME[F.fx_cwd2som]='Fire CWD to soil'; +FLUX_INFO.ABBREVIATION[F.fx_cwd2som]='fx_cwd2som'; +FLUX_INFO.UNITS[F.fx_cwd2som]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.fx_cwd2som]='Fire transfer CWD to soil'; + +FLUX_INFO.NAME[F.fx_lit2som]='Fire litter to soil'; +FLUX_INFO.ABBREVIATION[F.fx_lit2som]='fx_lit2som'; +FLUX_INFO.UNITS[F.fx_lit2som]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.fx_lit2som]='Fire transfer litter to soil'; + +FLUX_INFO.NAME[F.q_ly1]='LY1 runoff'; +FLUX_INFO.ABBREVIATION[F.q_ly1]='q_ly1'; +FLUX_INFO.UNITS[F.q_ly1]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.q_ly1]='LY1 runoff'; + +FLUX_INFO.NAME[F.q_ly2]='LY2 runoff'; +FLUX_INFO.ABBREVIATION[F.q_ly2]='q_ly2'; +FLUX_INFO.UNITS[F.q_ly2]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.q_ly2]='LY2 runoff'; + +FLUX_INFO.NAME[F.ly1xly2]='LY1 to LY2 transfer'; +FLUX_INFO.ABBREVIATION[F.ly1xly2]='ly1xly2'; +FLUX_INFO.UNITS[F.ly1xly2]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.ly1xly2]='LY1->LY2 transfer'; + +FLUX_INFO.NAME[F.ly2xly3]='LY2 to LY3 transfer'; +FLUX_INFO.ABBREVIATION[F.ly2xly3]='ly2xly3'; +FLUX_INFO.UNITS[F.ly2xly3]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.ly2xly3]='LY2->LY3 transfer'; + +FLUX_INFO.NAME[F.q_ly3]='LY3 runoff'; +FLUX_INFO.ABBREVIATION[F.q_ly3]='q_ly3'; +FLUX_INFO.UNITS[F.q_ly3]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.q_ly3]='LY3 runoff'; + +FLUX_INFO.NAME[F.q_surf]='Surface runoff'; +FLUX_INFO.ABBREVIATION[F.q_surf]='q_surf'; +FLUX_INFO.UNITS[F.q_surf]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.q_surf]='Surface runoff'; + +FLUX_INFO.NAME[F.infil]='Infiltration'; +FLUX_INFO.ABBREVIATION[F.infil]='infil'; +FLUX_INFO.UNITS[F.infil]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.infil]='INFILTRATION'; + +FLUX_INFO.NAME[F.infil_e]='Infiltration IE'; +FLUX_INFO.ABBREVIATION[F.infil_e]='infil_e'; +FLUX_INFO.UNITS[F.infil_e]='TBD'; +FLUX_INFO.DESCRIPTION[F.infil_e]='INFILTRATION IE: temp = weight average of snow melt (0C) + liquid precip (@air temp)'; + +FLUX_INFO.NAME[F.q_ly1_e]='Q LY1 IE'; +FLUX_INFO.ABBREVIATION[F.q_ly1_e]='q_ly1_e'; +FLUX_INFO.UNITS[F.q_ly1_e]='TBD'; +FLUX_INFO.DESCRIPTION[F.q_ly1_e]='Q LY1 IE: temp = LY1 temp'; + +FLUX_INFO.NAME[F.q_ly2_e]='Q LY2 IE'; +FLUX_INFO.ABBREVIATION[F.q_ly2_e]='q_ly2_e'; +FLUX_INFO.UNITS[F.q_ly2_e]='TBD'; +FLUX_INFO.DESCRIPTION[F.q_ly2_e]='Q LY2 IE: temp = LY2 temp'; + +FLUX_INFO.NAME[F.q_ly3_e]='Q LY3 IE'; +FLUX_INFO.ABBREVIATION[F.resq_ly3_ep_auto]='q_ly3_e'; +FLUX_INFO.UNITS[F.q_ly3_e]='TBDy'; +FLUX_INFO.DESCRIPTION[F.q_ly3_e]='Q LY3 IE: temp = LY3 temp'; + +FLUX_INFO.NAME[F.ly1xly2_e]='LY1 to NDZ IE'; +FLUX_INFO.ABBREVIATION[F.ly1xly2_e]='ly1xly2_e'; +FLUX_INFO.UNITS[F.ly1xly2_e]='TBD'; +FLUX_INFO.DESCRIPTION[F.ly1xly2_e]='LY1 to NDZ transfer IE: temp of donor'; + +FLUX_INFO.NAME[F.ly2xly3_e]='LY2 to LY3 IE'; +FLUX_INFO.ABBREVIATION[F.ly2xly3_e]='ly2xly3_e'; +FLUX_INFO.UNITS[F.ly2xly3_e]='TBD'; +FLUX_INFO.DESCRIPTION[F.ly2xly3_e]='LY2 to LY3 transfer IE: temp of donor'; + +FLUX_INFO.NAME[F.evap_e]='Evaporation E'; +FLUX_INFO.ABBREVIATION[F.evap_e]='evap_e'; +FLUX_INFO.UNITS[F.evap_e]='TBD'; +FLUX_INFO.DESCRIPTION[F.evap_e]='See Retano calculation'; + +FLUX_INFO.NAME[F.transp1_e]='Transpiration 1 E'; +FLUX_INFO.ABBREVIATION[F.transp1_e]='transp1_e'; +FLUX_INFO.UNITS[F.transp1_e]='TBD'; +FLUX_INFO.DESCRIPTION[F.transp1_e]='See Retano calculation'; + +FLUX_INFO.NAME[F.transp2_e]='Transpiration 2 E'; +FLUX_INFO.ABBREVIATION[F.transp2_e]='transp2_e'; +FLUX_INFO.UNITS[F.transp2_e]='TBD'; +FLUX_INFO.DESCRIPTION[F.transp2_e]='See Retano calculation'; + +FLUX_INFO.NAME[F.transp1]='Transpiration 1'; +FLUX_INFO.ABBREVIATION[F.transp1]='transp1'; +FLUX_INFO.UNITS[F.transp1]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.transp1]='Transpiration'; + +FLUX_INFO.NAME[F.transp2]='Transpiration 2'; +FLUX_INFO.ABBREVIATION[F.transp2]='transp2'; +FLUX_INFO.UNITS[F.transp2]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.transp2]='Transpiration'; + +FLUX_INFO.NAME[F.evap]='Evaporation'; +FLUX_INFO.ABBREVIATION[F.evap]='evap'; +FLUX_INFO.UNITS[F.evap]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.evap]='Evaporation'; + +FLUX_INFO.NAME[F.snowfall]='Snowfall'; +FLUX_INFO.ABBREVIATION[F.snowfall]='snowfall'; +FLUX_INFO.UNITS[F.snowfall]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.snowfall]='Snowfall'; + +FLUX_INFO.NAME[F.melt]='Melt'; +FLUX_INFO.ABBREVIATION[F.melt]='melt'; +FLUX_INFO.UNITS[F.melt]='kgH20/m2/day'; +FLUX_INFO.DESCRIPTION[F.melt]='melt'; + +FLUX_INFO.NAME[F.ae_rh_cwd]='Aerobic heterotrophic respiration coarse woody debris'; +FLUX_INFO.ABBREVIATION[F.ae_rh_cwd]='ae_rh_cwd'; +FLUX_INFO.UNITS[F.ae_rh_cwd]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.ae_rh_cwd]='Aerobic heterotrophic respiration from coarse woody debris pool'; + +FLUX_INFO.NAME[F.ae_rh_lit]='Aerobic heterotrophic respiration coarse woody litter'; +FLUX_INFO.ABBREVIATION[F.ae_rh_lit]='ae_rh_lit'; +FLUX_INFO.UNITS[F.ae_rh_lit]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.ae_rh_lit]='Aerobic heterotrophic respiration from litter pool'; + +FLUX_INFO.NAME[F.ae_rh_som]='Aerobic heterotrophic respiration soil organic matter'; +FLUX_INFO.ABBREVIATION[F.ae_rh_som]='ae_rh_som'; +FLUX_INFO.UNITS[F.ae_rh_som]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.ae_rh_som]='Aerobic heterotrophic respiration from soil organic matter pool'; + +FLUX_INFO.NAME[F.an_rh_cwd]='Anaerobic heterotrophic respiration coarse woody debris'; +FLUX_INFO.ABBREVIATION[F.an_rh_cwd]='an_rh_cwd'; +FLUX_INFO.UNITS[F.an_rh_cwd]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.an_rh_cwd]='Anaerobic heterotrophic respiration from coarse woody debris pool'; + +FLUX_INFO.NAME[F.an_rh_lit]='Anaerobic heterotrophic respiration litter'; +FLUX_INFO.ABBREVIATION[F.an_rh_lit]='an_rh_lit'; +FLUX_INFO.UNITS[F.an_rh_lit]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.an_rh_lit]='Anaerobic heterotrophic respiration from litter pool'; + +FLUX_INFO.NAME[F.an_rh_som]='Anaerobic heterotrophic respiration soil organic matter'; +FLUX_INFO.ABBREVIATION[F.an_rh_som]='an_rh_som'; +FLUX_INFO.UNITS[F.an_rh_som]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.an_rh_som]='Anaerobic heterotrophic respiration from soil organic matter pool'; + +FLUX_INFO.NAME[F.rh_co2]='Heterotrophic respiration CO2 flux'; +FLUX_INFO.ABBREVIATION[F.rh_co2]='rh_co2'; +FLUX_INFO.UNITS[F.rh_co2]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.rh_co2]='Total CO2 flux from heterotrophic respiration'; + +FLUX_INFO.NAME[F.rh_ch4]='Heterotrophic respiration CH4 flux'; +FLUX_INFO.ABBREVIATION[F.rh_ch4]='rh_ch4'; +FLUX_INFO.UNITS[F.rh_ch4]='gCH4/m2/day'; +FLUX_INFO.DESCRIPTION[F.rh_ch4]='Total CH4 flux from heterotrophic respiration'; + +FLUX_INFO.NAME[F.aetr]='Aerobic turnover scalar'; +FLUX_INFO.ABBREVIATION[F.aetr]='aetr'; +FLUX_INFO.UNITS[F.aetr]='scalar*'; +FLUX_INFO.DESCRIPTION[F.aetr]='Aerobic turnover scalar*'; + +FLUX_INFO.NAME[F.antr]='Anaerobic turnover scalar'; +FLUX_INFO.ABBREVIATION[F.antr]='antr'; +FLUX_INFO.UNITS[F.antr]='scalar*'; +FLUX_INFO.DESCRIPTION[F.antr]='Anaerobic turnover scalar*'; + +FLUX_INFO.NAME[F.an_co2_c_ratio]='Anaerobic CO2 C ratio'; +FLUX_INFO.ABBREVIATION[F.an_co2_c_ratio]='an_co2_c_ratio'; +FLUX_INFO.UNITS[F.an_co2_c_ratio]='fraction*'; +FLUX_INFO.DESCRIPTION[F.an_co2_c_ratio]='CO2 fraction in anaerobic C decomposition*'; + +FLUX_INFO.NAME[F.an_ch4_c_ratio]='Anaerobic CH4 C ratio'; +FLUX_INFO.ABBREVIATION[F.an_ch4_c_ratio]='an_ch4_c_ratio'; +FLUX_INFO.UNITS[F.an_ch4_c_ratio]='fraction*'; +FLUX_INFO.DESCRIPTION[F.an_ch4_c_ratio]='CH4 fraction in anaerobic C decomposition*'; + +FLUX_INFO.NAME[F.target_LAI]='Target leaf area index'; +FLUX_INFO.ABBREVIATION[F.target_LAI]='target_LAI'; +FLUX_INFO.UNITS[F.target_LAI]='m2/m2'; +FLUX_INFO.DESCRIPTION[F.target_LAI]='Target LAI calculated based on KNORR phenology scheme influenced by water, light, and temperature. Coded in KNORR_ALLOCATION.c'; + +FLUX_INFO.NAME[F.dlambda_dt]='Delta leaf area index'; +FLUX_INFO.ABBREVIATION[F.dlambda_dt]='dlambda_dt'; +FLUX_INFO.UNITS[F.dlambda_dt]='m2/m2'; +FLUX_INFO.DESCRIPTION[F.dlambda_dt]='Difference between Target leaf area index (target_LAI) and current leaf area index. Coded in KNORR_ALLOCATION.c '; + +FLUX_INFO.NAME[F.f_temp_thresh]='Temperature threshold'; +FLUX_INFO.ABBREVIATION[F.f_temp_thresh]='f_temp_thresh'; +FLUX_INFO.UNITS[F.f_temp_thresh]='fraction'; +FLUX_INFO.DESCRIPTION[F.f_temp_thresh]='Fraction of plants within pixel able to grow foliage on temperature threshold. Coded in KNORR_ALLOCATION.c'; + +FLUX_INFO.NAME[F.f_dayl_thresh]='Daylight threshold'; +FLUX_INFO.ABBREVIATION[F.f_dayl_thresh]='f_dayl_thresh'; +FLUX_INFO.UNITS[F.f_dayl_thresh]='fraction'; +FLUX_INFO.DESCRIPTION[F.f_dayl_thresh]='Fraction of plants within pixel able to grow foliage based on daylight threshold. Coded in KNORR_ALLOCATION.c'; + +FLUX_INFO.NAME[F.lai_fire]='Leaf area index fire loss'; +FLUX_INFO.ABBREVIATION[F.lai_fire]='lai_fire'; +FLUX_INFO.UNITS[F.lai_fire]='m2/m2'; +FLUX_INFO.DESCRIPTION[F.lai_fire]='Leaf area index fire lost to fire*'; + +FLUX_INFO.NAME[F.foliar_fire_frac]='C_fol fire loss fraction'; +FLUX_INFO.ABBREVIATION[F.foliar_fire_frac]='foliar_fire_frac'; +FLUX_INFO.UNITS[F.foliar_fire_frac]='fraction'; +FLUX_INFO.DESCRIPTION[F.foliar_fire_frac]='Foliage pool lost due to fire*'; + +FLUX_INFO.NAME[F.net_radiation]='Net radiation flux'; +FLUX_INFO.ABBREVIATION[F.net_radiation]='net_radiation'; +FLUX_INFO.UNITS[F.net_radiation]='W/m2'; +FLUX_INFO.DESCRIPTION[F.net_radiation]='Net radiation flux defined as incoming shortwave radiation (SWin) - outgoing shortwave radiation (SWout) + incoming longwave radiation (LWin) - outgoing longwave radiation (LWout)'; + +FLUX_INFO.NAME[F.latent_heat]='Latent heat flux'; +FLUX_INFO.ABBREVIATION[F.latent_heat]='latent_heat'; +FLUX_INFO.UNITS[F.latent_heat]='W/m2'; +FLUX_INFO.DESCRIPTION[F.latent_heat]='Latent heat flux'; + +FLUX_INFO.NAME[F.sensible_heat]='Sensible heat flux'; +FLUX_INFO.ABBREVIATION[F.sensible_heat]='sensible_heat'; +FLUX_INFO.UNITS[F.sensible_heat]='W/m2'; +FLUX_INFO.DESCRIPTION[F.sensible_heat]='Sensible heat flux'; + +FLUX_INFO.NAME[F.ground_heat]='Ground heat flux'; +FLUX_INFO.ABBREVIATION[F.ground_heat]='ground_heat'; +FLUX_INFO.UNITS[F.ground_heat]='W/m2'; +FLUX_INFO.DESCRIPTION[F.ground_heat]='Ground heat flux'; + +FLUX_INFO.NAME[F.gh_in]='Ground heat flux in converted units'; +FLUX_INFO.ABBREVIATION[F.gh_in]='gh_in'; +FLUX_INFO.UNITS[F.gh_in]='J/m2/day'; +FLUX_INFO.DESCRIPTION[F.gh_in]='Ground heat flux in converted units'; + +FLUX_INFO.NAME[F.resp_auto_growth]='Autotrophic growth respiration'; +FLUX_INFO.ABBREVIATION[F.resp_auto_growth]='resp_auto_growth'; +FLUX_INFO.UNITS[F.resp_auto_growth]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.resp_auto_growth]='Autotrophic growth respiration'; + +FLUX_INFO.NAME[F.resp_auto_maint]='Autotrophic maintenance respiration'; +FLUX_INFO.ABBREVIATION[F.resp_auto_maint]='resp_auto_maint'; +FLUX_INFO.UNITS[F.resp_auto_maint]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.resp_auto_maint]='Autotrophic maintenance respiration'; + +FLUX_INFO.NAME[F.SWin]='Incoming shortwave radiation'; +FLUX_INFO.ABBREVIATION[F.SWin]='SWin'; +FLUX_INFO.UNITS[F.SWin]='W/m2'; +FLUX_INFO.DESCRIPTION[F.SWin]='Incoming shortwave radiation'; + +FLUX_INFO.NAME[F.SWout]='Outgoing shortwave radiation'; +FLUX_INFO.ABBREVIATION[F.SWout]='SWout'; +FLUX_INFO.UNITS[F.SWout]='W/m2'; +FLUX_INFO.DESCRIPTION[F.SWout]='Outgoing shortwave radiation'; + +FLUX_INFO.NAME[F.LWin]='Incoming longwave radiation'; +FLUX_INFO.ABBREVIATION[F.LWin]='LWin'; +FLUX_INFO.UNITS[F.LWin]='W/m2'; +FLUX_INFO.DESCRIPTION[F.LWin]='Incoming longwave radiation'; + +FLUX_INFO.NAME[F.LWout]='Outgoing longwave radiation'; +FLUX_INFO.ABBREVIATION[F.LWout]='LWout'; +FLUX_INFO.UNITS[F.LWout]='W/m2'; +FLUX_INFO.DESCRIPTION[F.LWout]='Outgoing longwave radiation'; + +FLUX_INFO.NAME[F.ly1xly2_th_e]='Thermal conductivity layer one to layer two*'; +FLUX_INFO.ABBREVIATION[F.ly1xly2_th_e]='ly1xly2_th_e'; +FLUX_INFO.UNITS[F.ly1xly2_th_e]='J/m2/day'; +FLUX_INFO.DESCRIPTION[F.ly1xly2_th_e]='Thermal conductivity between layer one and layer two*'; + +FLUX_INFO.NAME[F.ly2xly3_th_e]='Thermal conductivity layer two to layer three*'; +FLUX_INFO.ABBREVIATION[F.ly2xly3_th_e]='ly2xly3_th_e'; +FLUX_INFO.UNITS[F.ly2xly3_th_e]='J/m2/day'; +FLUX_INFO.DESCRIPTION[F.ly2xly3_th_e]='Thermal conductivity between layer two and layer three*'; + +FLUX_INFO.NAME[F.resp_auto_maint_dark]='Autotrophic maintenance dark respiration'; +FLUX_INFO.ABBREVIATION[F.resp_auto_maint_dark]='resp_auto_maint_dark'; +FLUX_INFO.UNITS[F.resp_auto_maint_dark]='gC/m2/day'; +FLUX_INFO.DESCRIPTION[F.resp_auto_maint_dark]='Autotrophic maintenance dark respiration from foliage*'; + +FLUX_INFO.NAME[F.sublimation]='Sublimation'; +FLUX_INFO.ABBREVIATION[F.sublimation]='sublimation'; +FLUX_INFO.UNITS[F.sublimation]='kgH2O/m2/day'; +FLUX_INFO.DESCRIPTION[F.sublimation]='Sublimation*'; + +FLUX_INFO.NAME[F.geological]='Geological'; +FLUX_INFO.ABBREVIATION[F.geological]='geological'; +FLUX_INFO.UNITS[F.geological]='J/m2/day'; +FLUX_INFO.DESCRIPTION[F.geological]='Prederived geological flux in J/m2/day(105mW/m2)'; + +FLUX_INFO.NAME[F.ets]='Total land-atmosphere water'; +FLUX_INFO.ABBREVIATION[F.ets]='ets'; +FLUX_INFO.UNITS[F.ets]='kgH2O/m2/day'; +FLUX_INFO.DESCRIPTION[F.ets]='Total land-atmosphere water flux (evaporation + transpiration + sublimation)'; + +FLUX_INFO.NAME[F.beta_factor]='Stress scaling factor'; +FLUX_INFO.ABBREVIATION[F.beta_factor]='beta_factor'; +FLUX_INFO.UNITS[F.beta_factor]='fraction'; +FLUX_INFO.DESCRIPTION[F.beta_factor]='Stress due to cold weather and water availability'; + +FLUX_INFO.NAME[F.soil_beta_factor]='H2O stress scaling factor'; +FLUX_INFO.ABBREVIATION[F.soil_beta_factor]='soil_beta_factor'; +FLUX_INFO.UNITS[F.soil_beta_factor]='fraction'; +FLUX_INFO.DESCRIPTION[F.soil_beta_factor]='Stress due to soil water availability'; + +//Parameter info + +PARS_INFO.NAME[P.twood]='Turnover rate of wood'; +PARS_INFO.ABBREVIATION[P.twood]='twood'; +PARS_INFO.UNITS[P.twood]='gC/m2/day'; +PARS_INFO.DESCRIPTION[P.twood]='Includes maintenance respiration and growth respiration'; + +PARS_INFO.NAME[P.tr_lit2som]='Litter decomposition rate'; +PARS_INFO.ABBREVIATION[P.tr_lit2som]='lit2som'; +PARS_INFO.UNITS[P.tr_lit2som]='fraction'; +PARS_INFO.DESCRIPTION[P.tr_lit2som]='Fraction of litter lost to soil organic matter per day'; + +PARS_INFO.NAME[P.tr_cwd2som]='CWD decomposition rate'; +PARS_INFO.ABBREVIATION[P.tr_cwd2som]='cwd2som'; +PARS_INFO.UNITS[P.tr_cwd2som]='fraction'; +PARS_INFO.DESCRIPTION[P.tr_cwd2som]='Fraction of course woody debris lost to soil organic matter per day'; + +PARS_INFO.NAME[P.rauto_mr_r]='Autotrophic maintenance respiration coefficient for roots'; +PARS_INFO.ABBREVIATION[P.rauto_mr_r]='rauto_mr_r]'; +PARS_INFO.UNITS[P.rauto_mr_r]=''; +PARS_INFO.DESCRIPTION[P.rauto_mr_r]='Autotrophic maintenance respiration coefficient for roots - turnover rate at 25oC (d-1)'; + +PARS_INFO.NAME[P.rauto_mr_w]='Autotrophic maintenance respiration coefficient for wood'; +PARS_INFO.ABBREVIATION[P.rauto_mr_w]='rauto_mr_w'; +PARS_INFO.UNITS[P.rauto_mr_w]=''; +PARS_INFO.DESCRIPTION[]='Autotrophic maintenance respiration coefficient for wood - turnover rate at 25oC (d-1)'; + +PARS_INFO.NAME[P.rauto_mr_q10]='Autotrophic maintenance respiration Q10 parameter'; +PARS_INFO.ABBREVIATION[P.rauto_mr_q10]='rauto_mr_q10'; +PARS_INFO.UNITS[P.rauto_mr_q10]=''; +PARS_INFO.DESCRIPTION[P.rauto_mr_q10]='Autotrophic maintenance respiration Q10 parameter'; + +PARS_INFO.NAME[P.rauto_mrd_q10]='Dark respiration Q10 parameter'; +PARS_INFO.ABBREVIATION[P.rauto_mrd_q10]='rauto_mrd_q10'; +PARS_INFO.UNITS[P.rauto_mrd_q10]=''; +PARS_INFO.DESCRIPTION[P.rauto_mrd_q10]='Dark respiration Q10 parameter'; + +PARS_INFO.NAME[P.rauto_gr]='Growth yield'; +PARS_INFO.ABBREVIATION[P.rauto_gr]='rauto_gr'; +PARS_INFO.UNITS[P.rauto_gr]='g C'; +PARS_INFO.DESCRIPTION[P.rauto_gr]='Growth yield (g C appearing in new biomass per g C used for growth; "growth yield" in Cannell and Thornley 2000)'; + +PARS_INFO.NAME[P.t_wood]='Turnover rate of wood'; +PARS_INFO.ABBREVIATION[P.t_wood]='t_wood'; +PARS_INFO.UNITS[P.t_wood]='gC/m2/day'; +PARS_INFO.DESCRIPTION[P.t_wood]='Rate of wood loss per day* - 1% loss per year value'; + +PARS_INFO.NAME[P.t_root]='Turnover rate of roots'; +PARS_INFO.ABBREVIATION[P.t_root]='t_root'; +PARS_INFO.UNITS[P.t_root]='gC/m2/day'; +PARS_INFO.DESCRIPTION[P.t_root]='Rate of root loss per day'; + +PARS_INFO.NAME[P.t_lit]='Turnover rate of litter'; +PARS_INFO.ABBREVIATION[P.t_lit]='t_lit'; +PARS_INFO.UNITS[P.t_lit]='gC/m2/day'; +PARS_INFO.DESCRIPTION[P.t_lit]='Rate of litter turnover per day'; + +PARS_INFO.NAME[P.t_cwd]='Turnover rate of coarse woody debris'; +PARS_INFO.ABBREVIATION[P.t_cwd]='t_cwd'; +PARS_INFO.UNITS[P.t_cwd]='gC/m2/day'; +PARS_INFO.DESCRIPTION[P.t_cwd]='Rate of coarse woody debris turnover per day'; + +PARS_INFO.NAME[P.t_som]='Turnover rate of soil organic matter'; +PARS_INFO.ABBREVIATION[P.t_som]='t_som'; +PARS_INFO.UNITS[P.t_som]='gC/m2/day'; +PARS_INFO.DESCRIPTION[P.t_som]='Rate of soil turnover to heterotrophic respiration'; + +PARS_INFO.NAME[P.Q10rhco2]='Q10'; +PARS_INFO.ABBREVIATION[P.Q10rhco2]=''; +PARS_INFO.UNITS[P.Q10rhco2]=''; +PARS_INFO.DESCRIPTION[P.Q10rhco2]=''; + +PARS_INFO.NAME[P.LCMA]='Leaf mass carbon per area'; +PARS_INFO.ABBREVIATION[P.LCMA]='LCMA'; +PARS_INFO.UNITS[P.LCMA]='gC/m2'; +PARS_INFO.DESCRIPTION[P.LCMA]=' Leaf mass carbon per unit leaf area; Kattge et al. 2011*;*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*'; + +PARS_INFO.NAME[P.i_labile]='Initial labile'; +PARS_INFO.ABBREVIATION[P.i_labile]='i_labile'; +PARS_INFO.UNITS[P.i_labile]='gC/m2'; +PARS_INFO.DESCRIPTION[P.i_labile]='Size of labile C pool at time step 1'; + +PARS_INFO.NAME[P.i_foliar]='Initial foliar'; +PARS_INFO.ABBREVIATION[P.i_foliar]='i_foliar'; +PARS_INFO.UNITS[P.i_foliar]='gC/m2'; +PARS_INFO.DESCRIPTION[P.i_labile]='Size of foliar C pool at time step 1'; + +PARS_INFO.NAME[P.i_root]='Initial roots'; +PARS_INFO.ABBREVIATION[P.i_root]='i_root'; +PARS_INFO.UNITS[P.i_root]='gC/m2'; +PARS_INFO.DESCRIPTION[P.i_root]='Size of roots C pool at time step 1'; + +PARS_INFO.NAME[P.i_wood]='Initial wood'; +PARS_INFO.ABBREVIATION[P.i_wood]='i_wood'; +PARS_INFO.UNITS[P.i_wood]='gC/m2'; +PARS_INFO.DESCRIPTION[P.i_wood]='Size of wood C pool at time step 1'; + +PARS_INFO.NAME[P.i_cwd]='Initial CWD'; +PARS_INFO.ABBREVIATION[P.i_cwd]='i_cwd'; +PARS_INFO.UNITS[P.i_cwd]='gC/m2'; +PARS_INFO.DESCRIPTION[P.i_cwd]='Size of coarse woody debris C pool at time step 1'; + +PARS_INFO.NAME[P.i_lit]='Initial litter'; +PARS_INFO.ABBREVIATION[P.i_lit]='i_lit'; +PARS_INFO.UNITS[P.i_lit]='gC/m2'; +PARS_INFO.DESCRIPTION[P.i_lit]='Size of litter C pool at time step 1'; + +PARS_INFO.NAME[P.i_som]='Initial soil organic matter'; +PARS_INFO.ABBREVIATION[P.i_som]='i_som'; +PARS_INFO.UNITS[P.i_som]='gC/m2'; +PARS_INFO.DESCRIPTION[P.i_som]='Size of soil organic matter C pool at time step 1'; + +PARS_INFO.NAME[P.retention]='Retention parameter'; +PARS_INFO.ABBREVIATION[P.retention]='retention'; +PARS_INFO.UNITS[P.retention]=''; +PARS_INFO.DESCRIPTION[P.retention]='Retention parameter (b)'; + +PARS_INFO.NAME[P.i_LY1_SM]='LY1 SM at t0'; +PARS_INFO.ABBREVIATION[P.i_LY1_SM]='i_LY1_SM'; +PARS_INFO.UNITS[P.i_LY1_SM]=''; +PARS_INFO.DESCRIPTION[P.i_LY1_SM]='LY1 SM at t0'; + +PARS_INFO.NAME[P.cf_foliar]='Foliar biomass CF'; +PARS_INFO.ABBREVIATION[P.cf_foliar]='cf_foliar'; +PARS_INFO.UNITS[P.cf_foliar]='%'; +PARS_INFO.DESCRIPTION[P.cf_foliar]='Foliar biomass combustion factor'; + +PARS_INFO.NAME[P.cf_ligneous]='Ligneous biomass CF'; +PARS_INFO.ABBREVIATION[P.cf_ligneous]='cf_ligneous'; +PARS_INFO.UNITS[P.cf_ligneous]='%'; +PARS_INFO.DESCRIPTION[P.cf_ligneous]='Ligneous biomass combustion factor'; + +PARS_INFO.NAME[P.cf_DOM]='DOM CF'; +PARS_INFO.ABBREVIATION[P.cf_DOM]='cf_DOM'; +PARS_INFO.UNITS[P.cf_DOM]='%'; +PARS_INFO.DESCRIPTION[P.cf_DOM]='Dead organic matter combustion factor'; + +PARS_INFO.NAME[P.resilience]='Resilience factor'; +PARS_INFO.ABBREVIATION[P.resilience]='resilience'; +PARS_INFO.UNITS[P.resilience]='%'; +PARS_INFO.DESCRIPTION[P.resilience]='Resilience factor (since transfer to litter is represented as (1-pars[30]))'; + +PARS_INFO.NAME[P.hydr_cond]='Saturated hydraulic conductivity'; +PARS_INFO.ABBREVIATION[P.hydr_cond]='hydr_cond'; +PARS_INFO.UNITS[P.hydr_cond]='m/s'; +PARS_INFO.DESCRIPTION[P.hydr_cond]='Saturated hydraulic conductivity'; + +PARS_INFO.NAME[P.max_infil]='Maximum infiltration'; +PARS_INFO.ABBREVIATION[P.max_infil]='max_infil'; +PARS_INFO.UNITS[P.max_infil]='mm/day'; +PARS_INFO.DESCRIPTION[P.max_infil]='Maximum infiltration'; + +PARS_INFO.NAME[P.i_LY3_SM]='LY3 SM at t=0'; +PARS_INFO.ABBREVIATION[P.i_LY3_SM]='i_LY3_SM'; +PARS_INFO.UNITS[P.i_LY3_SM]=''; +PARS_INFO.DESCRIPTION[P.i_LY3_SM]='LY3 SM at t=0'; + +PARS_INFO.NAME[P.LY1_por]='LY1 porosity'; +PARS_INFO.ABBREVIATION[P.LY1_por]='LY1_por'; +PARS_INFO.UNITS[P.LY1_por]=''; +PARS_INFO.DESCRIPTION[P.LY1_por]='LY1 porosity'; + +PARS_INFO.NAME[P.LY2_por]='LY2 porosity'; +PARS_INFO.ABBREVIATION[P.LY2_por]='LY2_por'; +PARS_INFO.UNITS[P.LY2_por]=''; +PARS_INFO.DESCRIPTION[P.LY2_por]='LY2 porosity'; + +PARS_INFO.NAME[P.LY3_por]='LY3 porosity'; +PARS_INFO.ABBREVIATION[P.LY3_por]=''; +PARS_INFO.UNITS[P.LY3_por]=''; +PARS_INFO.DESCRIPTION[P.LY3_por]='LY3 porosity'; + +PARS_INFO.NAME[P.field_cap]='Field capacity (negative) potential'; +PARS_INFO.ABBREVIATION[P.field_cap]='field_cap'; +PARS_INFO.UNITS[P.field_cap]='-Mpa'; +PARS_INFO.DESCRIPTION[P.field_cap]='Field capacity (negative) potential'; + +PARS_INFO.NAME[P.LY1_z]='LY1 depth'; +PARS_INFO.ABBREVIATION[P.LY1_z]='LY1_z'; +PARS_INFO.UNITS[P.LY1_z]='m'; +PARS_INFO.DESCRIPTION[P.LY1_z]='LY1 depth'; + +PARS_INFO.NAME[P.LY2_z]='LY2 depth'; +PARS_INFO.ABBREVIATION[P.LY2_z]='LY2_z'; +PARS_INFO.UNITS[P.LY2_z]='m'; +PARS_INFO.DESCRIPTION[P.LY2_z]='LY2 depth'; + +PARS_INFO.NAME[P.LY3_z]='LY3 depth'; +PARS_INFO.ABBREVIATION[P.LY3_z]='LY3_z'; +PARS_INFO.UNITS[P.LY3_z]='m'; +PARS_INFO.DESCRIPTION[P.LY3_z]='LY3 depth'; + +PARS_INFO.NAME[P.LY1_vhc]='LY1 volumetric heat capacity'; +PARS_INFO.ABBREVIATION[P.LY1_vhc]=''; +PARS_INFO.UNITS[P.LY1_vhc]=''; +PARS_INFO.DESCRIPTION[P.LY1_vhc]='LY1 the change in heat content of a unit bulk volume of soil per unit change in temperature (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)'; + +PARS_INFO.NAME[P.LY2_vhc]='LY2 volumetric heat capacity'; +PARS_INFO.ABBREVIATION[P.LY2_vhc]=''; +PARS_INFO.UNITS[P.LY2_vhc]=''; +PARS_INFO.DESCRIPTION[P.LY2_vhc]='LY2 the change in heat content of a unit bulk volume of soil per unit change in temperature (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)'; + +PARS_INFO.NAME[P.LY3_vhc]='LY3 volumetric heat capacity'; +PARS_INFO.ABBREVIATION[P.LY3_vhc]=''; +PARS_INFO.UNITS[P.LY3_vhc]=''; +PARS_INFO.DESCRIPTION[P.LY3_vhc]='LY3 the change in heat content of a unit bulk volume of soil per unit change in temperature (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)'; + +PARS_INFO.NAME[P.Q_excess]='Runoff excess'; +PARS_INFO.ABBREVIATION[P.Q_excess]='Q_excess'; +PARS_INFO.UNITS[P.Q_excess]=''; +PARS_INFO.DESCRIPTION[P.Q_excess]='Runoff excess'; + +//Pool info {Eren Bilir added this section 9/15/2023} + +POOLS_INFO.NAME[S.C_lab]='Labile carbon pool'; +POOLS_INFO.ABBREVIATION[S.C_lab]='C_lab'; +POOLS_INFO.UNITS[S.C_lab]='gC/m2'; +POOLS_INFO.DESCRIPTION[S.C_lab]='Stored non-structural carbohydrate (NSC) pool; also includes any structural C that is not wood, root, or leaf, e.g. flowers/fruit/seeds'; + +POOLS_INFO.NAME[S.C_fol]='Foliar carbon pool'; +POOLS_INFO.ABBREVIATION[S.C_fol]='C_fol'; +POOLS_INFO.UNITS[S.C_fol]='gC/m2'; +POOLS_INFO.DESCRIPTION[S.C_fol]='Leaf carbon pool'; + +POOLS_INFO.NAME[S.C_roo]='Fine root carbon pool'; +POOLS_INFO.ABBREVIATION[S.C_roo]='C_roo'; +POOLS_INFO.UNITS[S.C_roo]='gC/m2'; +POOLS_INFO.DESCRIPTION[S.C_roo]='Fine root carbon pool; does not include woody root biomass'; + +POOLS_INFO.NAME[S.C_woo]='Wood/ligneous carbon pool'; +POOLS_INFO.ABBREVIATION[S.C_woo]='C_woo'; +POOLS_INFO.UNITS[S.C_woo]='gC/m2'; +POOLS_INFO.DESCRIPTION[S.C_woo]='Wood/ligneous carbon pool; includes woody root biomass'; + +POOLS_INFO.NAME[S.C_cwd]='Coarse woody debris carbon pool'; +POOLS_INFO.ABBREVIATION[S.C_cwd]='C_cwd'; +POOLS_INFO.UNITS[S.C_cwd]='gC/m2'; +POOLS_INFO.DESCRIPTION[S.C_cwd]='Coarse woody debris carbon pool'; + +POOLS_INFO.NAME[S.C_lit]='Litter carbon pool'; +POOLS_INFO.ABBREVIATION[S.C_lit]='C_lit'; +POOLS_INFO.UNITS[S.C_lit]='gC/m2'; +POOLS_INFO.DESCRIPTION[S.C_lit]='Litter carbon pool'; + +POOLS_INFO.NAME[S.C_som]='soil organic matter carbon pool'; +POOLS_INFO.ABBREVIATION[S.C_som]='C_som'; +POOLS_INFO.UNITS[S.C_som]='gC/m2'; +POOLS_INFO.DESCRIPTION[S.C_som]='soil organic matter carbon pool'; + +POOLS_INFO.NAME[S.H2O_LY1]='Layer 1 water content'; +POOLS_INFO.ABBREVIATION[S.H2O_LY1]='H2O_LY1'; +POOLS_INFO.UNITS[S.H2O_LY1]='(kg H2O)/m2'; +POOLS_INFO.DESCRIPTION[S.H2O_LY1]='Bulk water content of the first belowground layer. This layer hosts shallow vegetation roots and supplies water for transpiration, evaporation, runoff, and infiltration to LY2.'; + +POOLS_INFO.NAME[S.H2O_LY2]='Layer 2 water content'; +POOLS_INFO.ABBREVIATION[S.H2O_LY2]='H2O_LY2'; +POOLS_INFO.UNITS[S.H2O_LY2]='(kg H2O)/m2'; +POOLS_INFO.DESCRIPTION[S.H2O_LY2]='Bulk water content of the second belowground layer. This layer hosts deep vegetation roots and supplies water for transpiration), runoff, and infiltration to LY3.'; + +POOLS_INFO.NAME[S.H2O_LY3]='Layer 3 water content'; +POOLS_INFO.ABBREVIATION[S.H2O_LY3]='H2O_LY3'; +POOLS_INFO.UNITS[S.H2O_LY3]='(kg H2O)/m2'; +POOLS_INFO.DESCRIPTION[S.H2O_LY3]='Bulk water content of the third belowground layer. This layer is inaccessible to vegetation roots, and supplies water for runoff only.'; + +POOLS_INFO.NAME[S.H2O_SWE]='Snow Water Equivalent'; +POOLS_INFO.ABBREVIATION[S.H2O_SWE]='H2O_SWE'; +POOLS_INFO.UNITS[S.H2O_SWE]='(kg H2O)/m2'; +POOLS_INFO.DESCRIPTION[S.H2O_SWE]='Bulk water content of the snow pack layer. '; + +POOLS_INFO.NAME[S.E_LY1]='Layer 1 energy content'; +POOLS_INFO.ABBREVIATION[S.E_LY1]='E_LY1'; +POOLS_INFO.UNITS[S.E_LY1]='J/m2'; +POOLS_INFO.DESCRIPTION[S.E_LY1]='Energy content of the first belowground layer. '; + +POOLS_INFO.NAME[S.E_LY2]='Layer 2 energy content'; +POOLS_INFO.ABBREVIATION[S.E_LY2]='E_LY2'; +POOLS_INFO.UNITS[S.E_LY2]='J/m2'; +POOLS_INFO.DESCRIPTION[S.E_LY2]='Energy content of the second belowground layer. '; + +POOLS_INFO.NAME[S.E_LY3]='Layer 3 energy content'; +POOLS_INFO.ABBREVIATION[S.E_LY3]='E_LY3'; +POOLS_INFO.UNITS[S.E_LY3]='J/m2'; +POOLS_INFO.DESCRIPTION[S.E_LY3]='Energy content of the third belowground layer. '; + +POOLS_INFO.NAME[S.D_LAI]='Leaf Area Index'; +POOLS_INFO.ABBREVIATION[S.D_LAI]='D_LAI'; +POOLS_INFO.UNITS[S.D_LAI]='m2/m2'; +POOLS_INFO.DESCRIPTION[S.D_LAI]='Leaf Area Index. \'D_\' flag denotes a diagnostic variable, which is stored for the user but is not passed to downstream model calculations.'; + +POOLS_INFO.NAME[S.D_SCF]='Snow Covered Fraction'; +POOLS_INFO.ABBREVIATION[S.D_SCF]='D_SCF'; +POOLS_INFO.UNITS[S.D_SCF]='m2/m2'; +POOLS_INFO.DESCRIPTION[S.D_SCF]='Fraction of non-vegetation-covered land surface (gap fraction) that is covered by a layer of snow. '; + +POOLS_INFO.NAME[S.D_TEMP_LY1]='Layer 1 temperature'; +POOLS_INFO.ABBREVIATION[S.D_TEMP_LY1]='D_TEMP_LY1'; +POOLS_INFO.UNITS[S.D_TEMP_LY1]='K'; +POOLS_INFO.DESCRIPTION[S.D_TEMP_LY1]='Temperature (K) of the first belowground layer. '; + +POOLS_INFO.NAME[S.D_TEMP_LY2]='Layer 2 temperature'; +POOLS_INFO.ABBREVIATION[S.D_TEMP_LY2]='D_TEMP_LY2'; +POOLS_INFO.UNITS[S.D_TEMP_LY2]='K'; +POOLS_INFO.DESCRIPTION[S.D_TEMP_LY2]='Temperature (K) of the second belowground layer. '; + +POOLS_INFO.NAME[S.D_TEMP_LY3]='Layer 3 temperature'; +POOLS_INFO.ABBREVIATION[S.D_TEMP_LY3]='D_TEMP_LY3'; +POOLS_INFO.UNITS[S.D_TEMP_LY3]='K'; +POOLS_INFO.DESCRIPTION[S.D_TEMP_LY3]='Temperature (K) of the third belowground layer. '; + +POOLS_INFO.NAME[S.D_LF_LY1]='Layer 1 Liquid Fraction'; +POOLS_INFO.ABBREVIATION[S.D_LF_LY1]='D_LF_LY1'; +POOLS_INFO.UNITS[S.D_LF_LY1]='(kg H20 liquid water)/(kg H20 total water)'; +POOLS_INFO.DESCRIPTION[S.D_LF_LY1]='Fraction of the bulk water content existing in liquid state in the first belowground layer. '; + +POOLS_INFO.NAME[S.D_LF_LY2]='Layer 2 Liquid Fraction'; +POOLS_INFO.ABBREVIATION[S.D_LF_LY2]='D_LF_LY2'; +POOLS_INFO.UNITS[S.D_LF_LY2]='(kg H20 liquid water)/(kg H20 total water)'; +POOLS_INFO.DESCRIPTION[S.D_LF_LY2]='Fraction of the bulk water content existing in liquid state in the second belowground layer. '; + +POOLS_INFO.NAME[S.D_LF_LY3]='Layer 3 Liquid Fraction'; +POOLS_INFO.ABBREVIATION[S.D_LF_LY3]='D_LF_LY3'; +POOLS_INFO.UNITS[S.D_LF_LY3]='(kg H20 liquid water)/(kg H20 total water)'; +POOLS_INFO.DESCRIPTION[S.D_LF_LY3]='Fraction of the bulk water content existing in liquid state in the third belowground layer. '; + +POOLS_INFO.NAME[S.D_SM_LY1]='Layer 1 soil moisture'; +POOLS_INFO.ABBREVIATION[S.D_SM_LY1]='D_SM_LY1'; +POOLS_INFO.UNITS[S.D_SM_LY1]='((m3 H20)/(m3 total volume of pore space in soil volume)'; +POOLS_INFO.DESCRIPTION[S.D_SM_LY1]='Volumetric water content relative to available pore space in the first belowground layer.'; + +POOLS_INFO.NAME[S.D_SM_LY2]='Layer 2 soil moisture'; +POOLS_INFO.ABBREVIATION[S.D_SM_LY2]='D_SM_LY2'; +POOLS_INFO.UNITS[S.D_SM_LY2]='((m3 H20)/(m3 total volume of pore space in soil volume)'; +POOLS_INFO.DESCRIPTION[S.D_SM_LY2]='Volumetric water content relative to available pore space in the second belowground layer.'; + +POOLS_INFO.NAME[S.D_SM_LY3]='Layer 3 soil moisture'; +POOLS_INFO.ABBREVIATION[S.D_SM_LY3]='D_SM_LY3'; +POOLS_INFO.UNITS[S.D_SM_LY3]='((m3 H20)/(m3 total volume of pore space in soil volume)'; +POOLS_INFO.DESCRIPTION[S.D_SM_LY3]='Volumetric water content relative to available pore space in the third belowground layer.'; + +POOLS_INFO.NAME[S.D_PSI_LY1]='Layer 1 water potential'; +POOLS_INFO.ABBREVIATION[S.D_PSI_LY1]='D_PSI_LY1'; +POOLS_INFO.UNITS[S.D_PSI_LY1]='MPa'; +POOLS_INFO.DESCRIPTION[S.D_PSI_LY1]='Water potential of the first belowground layer'; + +POOLS_INFO.NAME[S.D_PSI_LY2]='Layer 2 water potential'; +POOLS_INFO.ABBREVIATION[S.D_PSI_LY2]='D_PSI_LY2'; +POOLS_INFO.UNITS[S.D_PSI_LY2]='MPa'; +POOLS_INFO.DESCRIPTION[S.D_PSI_LY2]='Water potential of the second belowground layer'; + +POOLS_INFO.NAME[S.D_PSI_LY3]='Layer 3 water potential'; +POOLS_INFO.ABBREVIATION[S.D_PSI_LY3]='D_PSI_LY3'; +POOLS_INFO.UNITS[S.D_PSI_LY3]='MPa'; +POOLS_INFO.DESCRIPTION[S.D_PSI_LY3]='Water potential of the third belowground layer'; + +POOLS_INFO.NAME[S.M_LAI_MAX]='Past Maximum Leaf Area Index in vegetation memory'; +POOLS_INFO.ABBREVIATION[S.M_LAI_MAX]='M_LAI_MAX'; +POOLS_INFO.UNITS[S.M_LAI_MAX]='m2/m2'; +POOLS_INFO.DESCRIPTION[S.M_LAI_MAX]='Exponentially declining term encoding vegetation \'memory\' of past water/structural limitations for LAI, to capture lagged effects of past stress.'; + +POOLS_INFO.NAME[S.M_LAI_TEMP]='Past Leaf temperature in vegetation memory'; +POOLS_INFO.ABBREVIATION[S.M_LAI_TEMP]='M_LAI_TEMP'; +POOLS_INFO.UNITS[S.M_LAI_TEMP]='K'; +POOLS_INFO.DESCRIPTION[S.M_LAI_TEMP]='Exponentially declining term encoding vegetation \'memory\' of past temperature limitations for LAI, to capture lagged effects of past stress.'; + +//EDC info + +EDCs_INFO.NAME[twood]='Turnover rate of wood'; +EDCs_INFO.ABBREVIATION[twood]='twood'; +EDCs_INFO.UNITS[gpp]='gC/m2/day'; +EDCs_INFO.DESCRIPTION[F.gpp]='Includes maintenance respiration and growth respiration'; + +... + +... + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1130/MODEL_INFO_1130.c === + +#pragma once +#include "PARS_INFO_1130.c" +#include "DALEC_1130.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF2.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1130(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1130_MODCONFIG(&DALECmodel,DATA); +static MLF MLF;DALEC_MLF2_MODCONFIG(&MLF); + +/*Step 2: Fill structure with model-specific info*/ + +//Corresponding likelihood function + + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->noedcs=DALECmodel.noedcs; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +//DALECmodel.edc1=EDC1_1130; +//DALECmodel.edc2=EDC2_1130; + + + + + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + + + //Copying pointers + DATA->parmin=DALECmodel.PARS_INFO.parmin; + DATA->parmax=DALECmodel.PARS_INFO.parmax; + + +//oksofar("about to declare EDCD"); +//printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +//EDCSETUP(*DATA,&DALECmodel.EDCD); + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +/*Pointing to MLF*/ +DATA->MLF=MLF.mlf; + +/*Pointing to EMLF*/ +DATA->EMLF=EDC_DALEC_MLF2_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1130/DALEC_1130_INDICES.c === + +#pragma once +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1130_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2som; +int tr_cwd2som; +int rauto_mr_r; +int rauto_mr_w; +int rauto_mr_q10; +int rauto_mrd_q10; +int rauto_gr; +int t_wood; +int t_root; +int t_lit; +int t_cwd; +int t_som; +int Q10rhco2; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_cwd; +int i_lit; +int i_som; +int retention; +int i_LY1_SM; +int i_LY2_SM; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int hydr_cond; +int max_infil; +int i_LY3_SM; +int LY1_por; +int LY2_por; +int LY3_por; +int field_cap; +int LY1_z;//LY1 depth +int LY2_z;//LY2 depth +int LY3_z;//LY3 depth +int LY1_vhc;//LY1 volumetric heat capacity +int LY2_vhc;//LY2 volumetric heat capacity +int LY3_vhc;//LY3 volumetric heat capacity +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int clumping; +int leaf_refl_par; +int leaf_refl_nir; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +int S_fv; +int thetas_opt; +int fwc; +int r_ch4; +int Q10ch4; +int maxPevap; +int T_phi; +int T_range; +int plgr; +int k_leaf; +int lambda_max; +int tau_W; +int time_c; +int time_r; +int init_T_mem; +int init_LAIW_mem; +int t_foliar; +int i_LY1_E; +int i_LY2_E; +int i_LY3_E; +int psi_50; +int beta_lgr; +int thermal_cond; +int thermal_cond_surf; +int q10canopy; +int canopyRdsf; +int sublimation_rate; +int root_frac; +int beta_lgrHMF; +int psi_50HMF; +int t_lab; + + +int s_ar; +int s_wood; +int s_root; +int e_ar; +int e_wood; +int e_root; +int W_o; +int k; +} DALEC_1130_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69, + 70,71,72,73,74,75,76,77,78,79, + 80,81,82,83,84,85, + + 86,87,88,89,90,91,92,93 +}; + +struct DALEC_1130_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int gppnet; /*GPP*/ +int resp_auto; /*Autotrophic respiration*/ +int lab_prod; /*Labile production*/ +int foliar_prod; /*Labile release*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int ph_fol2lit; /*Foliar phenological senescence*/ +int fol2lit; /*Foliar decomposition*/ +int woo2cwd; /*Wood decomposition*/ +int roo2lit; /*Root decomposition*/ +int lab2lit; /*Labile C decomposition*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int q_ly1; /*LY1 runoff*/ +int q_ly2; /*LY2 runoff*/ +int ly1xly2; /*LY1->LY2 transfer*/ +int ly2xly3; /*LY2->LY3 transfer*/ +int q_ly3; /*LY3 runoff*/ +int q_surf; /*Surface runoff*/ +int infil; /*INFILTRATION*/ +int infil_e; /*INFILTRATION IE: temp = weight average of snow melt (0C) + liquid precip (@air temp)*/ +int q_ly1_e; /*Q LY1 IE: temp = LY1 temp*/ +int q_ly2_e; /*Q LY2 IE: temp = LY2 temp*/ +int q_ly3_e; /*Q LY3 IE: temp = LY3 temp*/ +int ly1xly2_e; /*LY1->NDZ transfer IE: temp of donor*/ +int ly2xly3_e; /*LY2->LY3 transfer IE: temp of donor*/ +int evap_e; /* See Retano's calculation*/ +int transp1_e; /* See Retano's calculation*/ +int transp2_e; /* See Retano's calculation*/ +int transp1; /*Transpiration*/ +int transp2; /*Transpiration*/ +int evap; /*Evaporation*/ +int snowfall; /*Snowfall to SWE*/ +int melt; /*Snow melt*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int aetr; /*aerobic turnover scalar*/ +int antr; /*anaerobic turnover scalar*/ +int an_co2_c_ratio; /*CO2 fraction in anaerobic C decomposition*/ +int an_ch4_c_ratio; /*CH4 fraction in anaerobic C decomposition*/ +int target_LAI; /*LAI environmental target*/ +int dlambda_dt; /*dLAI/dt*/ +int f_temp_thresh; /*f_temp_thres*/ +int f_dayl_thresh; /*f_dayl_thres*/ +int lai_fire; /*LAI fire loss*/ +int foliar_fire_frac; /*C_fol fire loss frac*/ +int net_radiation; /*Net radiation flux*/ +int latent_heat; /*latent heat flux*/ +int sensible_heat; /*sensible heat flux*/ +int ground_heat; /*ground heat flux*/ +int gh_in; /*ground heat flux in converted units*/ +int resp_auto_growth; /*autotrophic growth respiration*/ +int resp_auto_maint; /*autotrophic maintenance respiration*/ +int SWin; +int SWout; +int LWin; +int LWout; +int ly1xly2_th_e; +int ly2xly3_th_e; +int resp_auto_maint_dark; +int sublimation; +int geological; +int ets; /* Total land-atmosphere water flux (evaporation + transpiration + sublimation) */ +int beta_factor; +int soil_beta_factor; +int hydraulic_mortality_factor; +int nonleaf_mortality_factor; +int leaf_mortality_factor; +int dist_lab; +int dist_fol; +int dist_roo; +int dist_woo; +int Rd; +} DALEC_1130_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69, + 70,71,72,73,74,75,76,77,78,79, + 80,81,82,83,84,85,86,87,88,89, + 90,91,92, 93 +}; + + + +/*Prognostic states and Diagnostic states (dependent on other states)*/ + + +struct DALEC_1130_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_LY1; /*Layer 1 H2O*/ +int H2O_LY2; /*Layer 2 H2O*/ +int H2O_LY3; /*Layer 3 H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +int E_LY1; /*LY1 thermal energy state*/ +int E_LY2; /*LY2 thermal energy state*/ +int E_LY3; /*LY3 thermal energy state*/ +int D_LAI;//leaf area index +int D_SCF;//snow-covered fraction +int D_TEMP_LY1;//LY1 temp in K +int D_TEMP_LY2;//LY2 temp in K +int D_TEMP_LY3;//LY3 temp in K +int D_LF_LY1;//LY1 liquid h2o frac +int D_LF_LY2;//LY2 liquid h2o frac +int D_LF_LY3;//LY3 liquid h2o frac +int D_SM_LY1;//LY1 soil moisture +int D_SM_LY2;//LY2 soil moisture +int D_SM_LY3;//LY3 soil moisture +int D_PSI_LY1;//LY1 soil moisture +int D_PSI_LY2;//LY2 soil moisture +int D_PSI_LY3;//LY3 soil moisture +int M_LAI_MAX;//KNORR LAI module max LAI memory +int M_LAI_TEMP;//KNORR LAI module temp memory +} DALEC_1130_POOLS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29 +}; + +struct DALEC_1130_EDCs{ +int vcmax_lcma; +int litcwdtor; +int cwdsomtor; +int mr_rates; +int rootwoodtor; +int fol2lig_cf; +int relativepsi50; +int state_ranges; +int state_trajectories; +int nsc_ratio; +int cfcr_ratio; +int fffr_ratio; +int mean_ly1_temp; +int mean_ly2_temp; +int mean_ly3_temp; + +int EDC_wetalloc; +int EDC_dryalloc; +} DALEC_1130_EDCs={ + 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9,10,11,12,13, + 14, + + 15,16 +}; + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1106/EDC2_1106.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1106(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1106_PARAMETERS P=DALEC_1106_PARAMETERS; +struct DALEC_1106_FLUXES F=DALEC_1106_FLUXES; +struct DALEC_1106_POOLS S=DALEC_1106_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=10;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +//double EQF=EDCD->EQF; +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +if (Fin[n] > 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_cwd,P.i_lit,P.i_som,P.i_PAW,P.i_PUW,P.i_SWE}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1106/DALEC_1106.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../DALEC_ALL/LIU_AN_ET_REFACTOR.c" +#include "../DALEC_ALL/CH4_MODULES/JCR.c" +#include "../DALEC_ALL/LAI_KNORR.c" +#include "../DALEC_ALL/LAI_KNORR_funcs.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1106_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2som; +int tr_cwd2som; +int f_auto; +int f_root; +int t_wood; +int t_root; +int t_lit; +int t_cwd; +int t_som; +int Q10rhco2; +int f_lab; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_cwd; +int i_lit; +int i_som; +int retention; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int hydr_cond; +int max_infil; +int i_PUW; +int PAW_por; +int PUW_por; +int field_cap; +int PAW_z; +int PUW_z; +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int C3_frac; +int clumping; +int leaf_refl; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +int S_fv; +int thetas_opt; +int fwc; +int r_ch4; +int Q10ch4; +int maxPevap; +int T_phi; +int T_range; +int tau_m; +int plgr; +int k_leaf; +int lambda_max; +int tau_W; +int time_c; +int time_r; +int init_T_mem; +int init_LAIW_mem; +int t_foliar; +} DALEC_1106_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66 +}; + +struct DALEC_1106_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int resp_auto; /*Autotrophic respiration*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int fol2lit; /*Foliar decomposition*/ +int wood2cwd; /*Wood decomposition*/ +int root2lit; /*Root decomposition*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int q_surf; /*Surface runoff*/ +int transp; /*Transpiration*/ +int evap; /*Evaporation*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int fV; /* Volumetric fraction of aerobic Rh */ +int fT; /*Temperature scaler*/ +int fW; /*Water scaler*/ +int fCH4; /*CH4 fraction in anaerobic C decomposition*/ +int soil_moist; /*thetas = PAW/PAW_fs fraction*/ +int target_LAI; /*LAI environmental target*/ +int T_memory; /*LAI temp memory*/ +int lambda_max_memory; /*LAI max memory*/ +int dlambda_dt; /*dLAI/dt*/ +int f_temp_thresh; /*f_temp_thres*/ +int f_dayl_thresh; /*f_dayl_thres*/ +int c_lim_flag; /*LAI carbon limitation flag*/ +int lai_fire; /*LAI fire loss*/ +int foliar_fire_frac; /*C_fol fire loss frac*/ +} DALEC_1106_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55 +}; + + + +/*Prognostic states and Diagnostic states (dependent on other states)*/ + + +struct DALEC_1106_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +int E_PAW; /*Snow water equivalent*/ +int E_PUW; /*Snow water equivalent*/ +int D_LAI;//leaf area index +int D_SCF;//snow-covered fraction +} DALEC_1106_POOLS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13 +}; + +/* +struct POOLS_INFO{ +int n_input_fluxes +int n_output_fluxes +int * input_fluxes +int * output_fluxes} +*/ + + + +int DALEC_1106(DATA DATA, double const *pars){ + + +struct DALEC_1106_PARAMETERS P=DALEC_1106_PARAMETERS; +struct DALEC_1106_FLUXES F=DALEC_1106_FLUXES; +struct DALEC_1106_POOLS S=DALEC_1106_POOLS; + + + + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +double pi=3.1415927; +double lai_met_list[1],lai_var_list[20]; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + + /*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_cwd]=pars[P.i_cwd]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + //---DIAGNOSTIC STATES--- + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; //LAI + POOLS[S.D_SCF]=POOLS[S.H2O_SWE]/(POOLS[S.H2O_SWE]+pars[P.scf_scalar]); //snow cover fraction + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/* jc prep input for methane module*/ +double ch4pars[7]={pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.Q10rhco2],meantemp}; + +// Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117/100; + +/*Combustion factors*/ +double CF[7];//AAB changed this +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + +/*foliar carbon transfer intermediate variables*/ +double Fcfolavailable; + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + +double LAI=POOLS[p+S.D_LAI]; + + +/*Calculate light extinction coefficient*/ +double B = (DOY[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +double LST = (int) (DOY[n]*24*60) % (24*60); +LST=0.5*24*60; +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*DATA.ncdf_data.LAT)*sin(pi/180*DA)+cos(pi/180*DATA.ncdf_data.LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +double zenith_angle = 90-alpha; + +//printf("SZA local = %2.2f, SZA global = %2.2f, SZA diff = %2.2f\n", zenith_angle,DATA.ncdf_data.SZA.values,DATA.ncdf_data.SZA.values - zenith_angle); +//double LAD = 1.0; //leaf angle distribution +//double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 + +double LAD = 0.5; //leaf angle distribution +double VegK = LAD/cos(zenith_angle/180*pi); + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor + //We're also multiplying beta by cold-weather stress +double beta = fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1.); + beta = fmin(beta,g); + +// GPP, T, and E from LIU_An_et +// Annual radiation, VPD in kPa, mean T in K +//C3 frac hardcoded to 1 for now. Recommendation for re-integration of C3 frac = integrate distinct C3 and C4 GPP pars to avoid representation issues. +double *LIU_An_et_out = LIU_An_et(SSRD[n]*1e6/(24*3600), VPD[n]/10, + 273.15+0.5*(T2M_MIN[n]+T2M_MAX[n]), pars[P.Vcmax25], CO2[n], beta, pars[P.Med_g1], + LAI, pars[P.ga], VegK, pars[P.Tupp], pars[P.Tdown], 1., // pars[P.C3_frac], + pars[P.clumping], pars[P.leaf_refl], pars[P.maxPevap], PREC[n]); +// GPP +FLUXES[f+F.gpp] = LIU_An_et_out[0]; +//transpiration// +FLUXES[f+F.transp] = LIU_An_et_out[1]; +//evaporation// +FLUXES[f+F.evap] = LIU_An_et_out[2]; +// Evapotranspiration +FLUXES[f+F.et]=FLUXES[f+F.evap]+FLUXES[f+F.transp]; + +/*Snow water equivalent*/ +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ +FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ +POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ + + +// Infiltration (mm/day) +double infil = pars[P.max_infil]*(1 - exp(-(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])/pars[P.max_infil])); + +// Surface runoff (mm/day) +FLUXES[f+F.q_surf] = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]) - infil; + +// Update pools, including infiltration +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + deltat*infil; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW]; + +// Volumetric soil moisture from water pools +double sm_PAW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double sm_PUW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage +double drain_PAW = DRAINAGE(sm_PAW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = DRAINAGE(sm_PUW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + +// Remove drainage from layers +sm_PAW -= drain_PAW; +sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(sm_PAW,pars[P.hydr_cond],pars[P.retention]); +double k_PUW = HYDROFUN_MOI2CON(sm_PUW,pars[P.hydr_cond],pars[P.retention]); + +// Convert to potential +double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.retention]); +double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.retention]); + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(psi_PAW-psi_PUW)/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); + +// Transfer flux in mm/day +FLUXES[f+F.paw2puw] = xfer*1000*3600*24; + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] += (-FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat; +POOLS[nxp+S.H2O_PUW] += (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*(pars[P.f_lab]); + +//KNORR LAI// +if (n==0){ + /*Initialize phenology memory of air-temperature as some value within mintemp and maxtemp*/ + lai_var_list[5]=pars[P.init_T_mem]*(T2M_MAX[n]-T2M_MIN[n])+T2M_MIN[n]; + /*Initialize phenology memory of water/structural limitation */ + lai_var_list[11]=pars[P.init_LAIW_mem]*pars[P.lambda_max]; +} +lai_met_list[0]=(T2M_MAX[n]+T2M_MIN[n])/2.0; +// lai_var_list[0]=1; +lai_var_list[19]=deltat; +lai_var_list[1]=LAI; +lai_var_list[2]=LAI; +lai_var_list[3]=pars[P.T_phi]; +lai_var_list[4]=pars[P.T_range]; +lai_var_list[6]=pars[P.tau_m]; +lai_var_list[7]=pars[P.plgr]; +lai_var_list[8]=pars[P.k_leaf]; +lai_var_list[9]=pars[P.lambda_max]; +lai_var_list[10]=pars[P.tau_W]; +lai_var_list[12]=DATA.ncdf_data.LAT; +lai_var_list[13]=DOY[n]; +lai_var_list[14]=pi; +lai_var_list[15]=pars[P.time_c]; +lai_var_list[16]=pars[P.time_r]; +lai_var_list[17]=(POOLS[p+S.H2O_PAW]+POOLS[nxp+S.H2O_PAW])/2.0; +lai_var_list[18]=FLUXES[f+F.et]; +// // Run Knorr LAI module +double *LAI_KNORR_OUTPUT = LAI_KNORR(lai_met_list,lai_var_list); +FLUXES[f+F.target_LAI]=LAI_KNORR_OUTPUT[0]; +FLUXES[f+F.T_memory]=LAI_KNORR_OUTPUT[1]; +FLUXES[f+F.lambda_max_memory]=LAI_KNORR_OUTPUT[2]; +FLUXES[f+F.dlambda_dt]=LAI_KNORR_OUTPUT[3]/deltat; +FLUXES[f+F.f_temp_thresh]=LAI_KNORR_OUTPUT[4]; +FLUXES[f+F.f_dayl_thresh]=LAI_KNORR_OUTPUT[5]; +lai_var_list[5]=FLUXES[f+F.T_memory]; /*Update LAI temperature memory state for next iteration*/ +lai_var_list[11]=FLUXES[f+F.lambda_max_memory]; /*Update water/structural memory state for next iteration*/ + +Fcfolavailable=FLUXES[f+F.lab_prod] + POOLS[p+S.C_lab]/deltat; +if (FLUXES[f+F.dlambda_dt] > 0){ + /* labile release: flux from labile pool to foliar pool */ + FLUXES[f+F.lab_release]=MinQuadraticSmooth(Fcfolavailable, FLUXES[f+F.dlambda_dt]*pars[P.LCMA], 0.99); + /* flag for carbon availability limitation (0=canopy in senescence, 1=labile C does not limit growth, 2=labile C limits LAI growth) */ + FLUXES[f+F.c_lim_flag]=2.0; + /* leaf litter production: flux from foliar pool to litter pool */ + FLUXES[f+F.fol2lit]=POOLS[p+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))/deltat; +} +else { + FLUXES[f+F.c_lim_flag]=0.0; + /* labile release: flux from labile pool to foliar pool */ + FLUXES[f+F.lab_release]=0; + /* leaf litter production: flux from foliar pool to litter pool */ + FLUXES[f+F.fol2lit]=-FLUXES[f+F.dlambda_dt]*pars[P.LCMA]+POOLS[p+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))/deltat; +} + + +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*wood CWD production*/ +FLUXES[f+F.wood2cwd] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; + +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +double thetas = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double *jcr_o = JCR(ch4pars,T2M_MIN[n],T2M_MAX[n],thetas); +//outputformat +//jcr_o 0-3 fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +double ae_loss_cwd = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_cwd],deltat))/deltat; +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = ae_loss_cwd*(1-pars[P.tr_cwd2som]); +double ae_loss_lit = POOLS[p+S.C_lit]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_lit],deltat))/deltat; +/* aerobic Rh from litter*/ +FLUXES[f+F.ae_rh_lit] = ae_loss_lit*(1-pars[P.tr_lit2som]); +/* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_som],deltat))/deltat; +double an_loss_cwd = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from coarse woody debris*/ +FLUXES[f+F.an_rh_cwd] = an_loss_cwd*(1-pars[P.tr_cwd2som]); +/* anaerobic Rh from litter*/ +double an_loss_lit = POOLS[p+S.C_lit]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_lit],deltat))/deltat; +FLUXES[f+F.an_rh_lit] = an_loss_lit*(1-pars[P.tr_lit2som]); +/* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_som],deltat))/deltat; +/*CWD to SOM*/ +FLUXES[f+F.cwd2som] = (an_loss_cwd + ae_loss_cwd)*pars[P.tr_cwd2som]; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = (an_loss_lit + ae_loss_lit)*pars[P.tr_lit2som]; +/* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*1+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*(1-jcr_o[3]); +/* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*0+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*jcr_o[3]; +/* fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+F.fV] = jcr_o[1]; +/* fT Temperature scaler*/ +FLUXES[f+F.fT] = jcr_o[0]; +/* fW Water scaler*/ +FLUXES[f+F.fW] = jcr_o[2]; +/* fCH4 CH4 fraction*/ +FLUXES[f+F.fCH4] = jcr_o[3]; +/* PAW/PAW_fs thetas*/ +FLUXES[f+F.soil_moist] = thetas; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*---------------------- end of JCR --------------------------------------------*/ + + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.lab_release] - FLUXES[f+F.fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2cwd])*deltat; + POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] + (FLUXES[f+F.wood2cwd] - FLUXES[f+F.ae_rh_cwd]-FLUXES[f+F.an_rh_cwd]-FLUXES[f+F.cwd2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + + + //Energy ppols + //Root zone + //POOLS[nxp+S.E_PAW] = POOLS[p+S.E_PAW] + (Renato's ground heat flux, inc LWup, etc.)*deltaT - Runoff terms - Marcos' evaporation terms + Precip energ + + //POOLS[nxp+S.E_PUW] = POOLS[p+S.E_PAW] + (Renato's ground heat flux)*deltaT + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-CF[S.C_cwd])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2cwd])*deltat; + /*dead C pools*/ + /*CWD*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.fx_woo2cwd]-FLUXES[f+F.f_cwd]-FLUXES[f+F.fx_cwd2som])*deltat; + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + /*Fraction of C-foliar lost due to fires*/ + FLUXES[f+F.foliar_fire_frac] = BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Calculate LAI (lambda) lost due to fire + - we lose the same fraction of LAI as we do C-foliar + - FE_\Lambda^{(t+1)} = \Lambda^{(t+1)'} * BA ( k_{factor(i)} + (1 - k_{factor(i)}) r )*/ + FLUXES[f+F.lai_fire] = (POOLS[p+S.C_fol]/pars[P.LCMA])*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + POOLS[nxp+S.D_SCF]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); //snow cover fraction + +} + + + +return 0; +} + + + +int DALEC_1106_MODCONFIG(DALEC * DALECmodel){ + + +struct DALEC_1106_PARAMETERS P=DALEC_1106_PARAMETERS; +struct DALEC_1106_FLUXES F=DALEC_1106_FLUXES; +struct DALEC_1106_POOLS S=DALEC_1106_POOLS; + +DALECmodel->nopools=14; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=67; +DALECmodel->nofluxes=56; +DALECmodel->dalec=DALEC_1106; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports external observation operations. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; +OBSOPE.SUPPORT_SCF_OBS=true; + + + + + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.et; +//Runoff variables +static int ROFF_fluxes[3]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +ROFF_fluxes[2]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=3; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//SCF-specific variables +OBSOPE.SCF_pool=S.D_SCF; + + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +//C3frac parameters +OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_som; + + + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1106/MODEL_INFO_1106.c === + +#pragma once +#include "PARS_INFO_1106.c" +#include "DALEC_1106.c" +#include "EDC1_1106.c" +#include "EDC2_1106.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1106(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1106_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_DEDC_MODCONFIG(&MLF); + +/*Step 2: Fill structure with model-specific info*/ + +//Corresponding likelihood function + + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1106; +DALECmodel.edc2=EDC2_1106; + + + + + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1106(DATA->parmin, DATA->parmax); + +//oksofar("about to declare EDCD"); +//printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +/*Pointing to MLF*/ +DATA->MLF=MLF.mlf; +/*Pointing to EMLF*/ +DATA->EMLF=EDC_DALEC_MLF_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1106/EDC1_1106.c === + +#pragma once +int EDC1_1106(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1106_PARAMETERS P=DALEC_1106_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +// double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto)*pars[P.f_lab]; +double const froot=(1-fauto-flab)*pars[P.f_root]; +double const fwood=1-fauto-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab)*pars[P.tr_lit2som]/(pars[P.tr_lit2som]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +// double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_som]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2som]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((flab)>5*froot | (flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1106/PARS_INFO_1106.c === + +#pragma once +#include "DALEC_1106.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1106(double *parmin, double *parmax) +{ + + +struct DALEC_1106_PARAMETERS P=DALEC_1106_PARAMETERS; + +/*Litter decomposition rate*/ +parmin[P.tr_lit2som]=0.01; +parmax[P.tr_lit2som]=0.99; + +/*CWD decomposition rate*/ +parmin[P.tr_cwd2som]=0.01; +parmax[P.tr_cwd2som]=0.99; + +/*Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/*TOR CWD*/ +parmin[P.t_cwd]=0.00005; +parmax[P.t_cwd]=0.005; + +/*TOR SOM*/ +parmin[P.t_som]=0.0000001; +parmax[P.t_som]=0.001; + +/*\Q10 = 1.2-2.0*/ +parmin[P.Q10rhco2]=1.2; +parmax[P.Q10rhco2]=2.0; + +/*Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C CWD*/ +parmin[P.i_cwd]=1.0; +parmax[P.i_cwd]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*Retention parameter (b)*/ +parmin[P.retention]=1.5; +parmax[P.retention]=10; + +/*"Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +parmin[P.hydr_cond]=0.0000001; +parmax[P.hydr_cond]=0.00001; + +/*Maximum infiltration (mm/day)*/ +parmin[P.max_infil]=1; +parmax[P.max_infil]=100; + +/*PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/*PAW porosity*/ +parmin[P.PAW_por]=0.2; +parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +parmin[P.PUW_por]=0.2; +parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +parmin[P.field_cap]=0.01; +parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +parmin[P.PAW_z]=0.01; +parmax[P.PAW_z]=100; + +/*PUW depth (m)*/ +parmin[P.PUW_z]=0.01; +parmax[P.PUW_z]=100; + +/*Runoff excess*/ +parmin[P.Q_excess]=0.01; +parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +parmin[P.Med_g1]=1.79; +parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +parmin[P.Vcmax25]=1e-8; +parmax[P.Vcmax25]=140; + +/*Tminmin scaling factor*/ +parmin[P.Tminmin]=258.15; +parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +parmin[P.Tminmax]=273.15; +parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance*/ +parmin[P.ga]=0.01; +parmax[P.ga]=10.0; + +/*Tupp*/ +parmin[P.Tupp]=299.15; +parmax[P.Tupp]=318.15; + +/*Tdown*/ +parmin[P.Tdown]=263.15; +parmax[P.Tdown]=286.15; + +/*C3_frac*/ +parmin[P.C3_frac]=1e-8; +parmax[P.C3_frac]=1.0; + +/*Clumping index*/ +parmin[P.clumping]=0.35; +parmax[P.clumping]=1.0; + +/*Leaf single scattering albedo*/ +parmin[P.leaf_refl]=1e-8; +parmax[P.leaf_refl]=1.0; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +parmin[P.i_SWE]=0.000001; +parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +parmin[P.min_melt]=240; +parmax[P.min_melt]=270; + +/*sn2: slope*/ +parmin[P.melt_slope]=0.00001; +parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar; SCF = SWE/(SWE +SWEcritical_par) */ +parmin[P.scf_scalar]=10; +parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +/*jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +parmin[P.S_fv]=1; +parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +parmin[P.thetas_opt]=0.2; +parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +parmin[P.fwc]=0.01; +parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +parmin[P.r_ch4]=0.001; +parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +parmin[P.Q10ch4]=1.0; +parmax[P.Q10ch4]=3.0; + +/* maxPevap in mm/day*/ +parmin[P.maxPevap]=0.01; +parmax[P.maxPevap]=20; + +/*Mean temperature at leaf onset (T_phi) (degrees kelvin)*/ +parmin[P.T_phi]=268.15; +parmax[P.T_phi]=323.15; + +/*Spatial range of mean temperature at leaf onset (T_r) (degrees C or degrees kelvin)*/ +parmin[P.T_range]=0.1; +parmax[P.T_range]=10.0; + +/*Averaging period for temperature growth trigger T (time units of model), usually kept constant*/ +parmin[P.tau_m]=1.0; +parmax[P.tau_m]=1.01; + +/*LAI linear growth constant (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.plgr]=0.001; +parmax[P.plgr]=0.5; + +/*Inverse of leaf longevity during senescence period (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.k_leaf]=0.001; +parmax[P.k_leaf]=0.5; + +/*Intrinsic maximum LAI (m^2 m^-2)*/ +parmin[P.lambda_max]=0.1; +parmax[P.lambda_max]=10.0; + +/*Target survival time for LAI under water-deficit conditions (days; or same unit as ET and PAW)*/ +parmin[P.tau_W]=0.1; +parmax[P.tau_W]=300; + +/*Mean daylength at leaf shedding (t_c; in units of hours sunlight per day)*/ +parmin[P.time_c]=2; +parmax[P.time_c]=22; + +/*Spatial range of mean daylength at leaf shedding (t_r)*/ +parmin[P.time_r]=0.1; +parmax[P.time_r]=6.0; + +/*initialization of temperature memory (fractional value between mintemp and maxtemp at t=0)*/ +parmin[P.init_T_mem]=0.01; +parmax[P.init_T_mem]=1; + +/*initialization of water/structural memory (fractional value of intrinsic maximum LAI)*/ +parmin[P.init_LAIW_mem]=0.01; +parmax[P.init_LAIW_mem]=1; + +/*Inverse of leaf longevity at any period i.e. background turnover (days-1)*/ +parmin[P.t_foliar]=0.001; +parmax[P.t_foliar]=0.1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1101/DALEC_1101.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../../../DALEC_CODE/DALEC_ALL/LIU_An_et.c" +#include "../../../DALEC_CODE/DALEC_ALL/CH4_MODULES/JCR.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + + +struct DALEC_1101_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2som; +int tr_cwd2som; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_cwd; +int t_som; +int Q10rhco2; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_cwd; +int i_lit; +int i_som; +int retention; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int hydr_cond; +int max_infil; +int i_PUW; +int PAW_por; +int PUW_por; +int field_cap; +int PAW_z; +int PUW_z; +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int C3_frac; +int clumping; +int leaf_refl; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +int S_fv; +int thetas_opt; +int fwc; +int r_ch4; +int Q10ch4; +int maxPevap; +} DALEC_1101_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62 +}; + +struct DALEC_1101_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2cwd; /*Wood decomposition*/ +int root2lit; /*Root decomposition*/ +int resp_het_cwd; /*Coarse woody debris heterotrophic respiration*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int q_surf; /*Surface runoff*/ +int transp; /*Transpiration*/ +int evap; /*Evaporation*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int fV; /* Volumetric fraction of aerobic Rh */ +int fT; /*Temperature scaler*/ +int fW; /*Water scaler*/ +int fCH4; /*CH4 fraction in anaerobic C decomposition*/ +int soil_moist; /*thetas = PAW/PAW_fs fraction*/ + +} DALEC_1101_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53 +}; + + + + + +struct DALEC_1101_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +} DALEC_1101_POOLS={ + 0,1,2,3,4,5,6,7,8,9 +}; + +/* +struct POOLS_INFO{ +int n_input_fluxes +int n_output_fluxes +int * input_fluxes +int * output_fluxes} +*/ + + + +int DALEC_1101_MODCONFIG(DALEC * DALECmodel){ + + +struct DALEC_1101_PARAMETERS P=DALEC_1101_PARAMETERS; +struct DALEC_1101_FLUXES F=DALEC_1101_FLUXES; +struct DALEC_1101_POOLS S=DALEC_1101_POOLS; + +DALECmodel->nopools=10; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=63; +DALECmodel->nofluxes=54; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; + + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//Runoff variables +static int ROFF_fluxes[3]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +ROFF_fluxes[2]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=3; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +//C3frac parameters +OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_som; + + + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + + +int DALEC_1101(DATA DATA, double const *pars){ + + + +struct DALEC_1101_PARAMETERS P=DALEC_1101_PARAMETERS; +struct DALEC_1101_FLUXES F=DALEC_1101_FLUXES; +struct DALEC_1101_POOLS S=DALEC_1101_POOLS; + + + + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +double pi=3.1415927; + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +// double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_cwd]=pars[P.i_cwd]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + +/* jc prep input for methane module*/ +double ch4pars[7]={pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.Q10rhco2],meantemp}; + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + +// Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117/100; + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[7];//AAB changed this +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; + + +double zenith_angle=DATA.ncdf_data.SZA[n]; +double LAD = 0.5; //leaf angle distribution +double VegK = LAD/cos(zenith_angle/180*pi); + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor + //We're also multiplying beta by cold-weather stress +double beta = fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1.); + beta = fmin(beta,g); + +// GPP, T, and E from LIU_An_et +// Annual radiation, VPD in kPa, mean T in K +double *LIU_An_et_out = LIU_An_et(SSRD[n]*1e6/(24*3600), VPD[n]/10, + 273.15+0.5*(T2M_MIN[n]+T2M_MAX[n]), pars[P.Vcmax25], CO2[n], beta, pars[P.Med_g1], + LAI[n], pars[P.ga], VegK, pars[P.Tupp], pars[P.Tdown], 1., // pars[P.C3_frac], + pars[P.clumping], pars[P.leaf_refl], pars[P.maxPevap], PREC[n]); +// GPP +FLUXES[f+F.gpp] = LIU_An_et_out[0]; +//transpiration// +FLUXES[f+F.transp] = LIU_An_et_out[1]; +//evaporation// +FLUXES[f+F.evap] = LIU_An_et_out[2]; +// Evapotranspiration +FLUXES[f+F.et]=FLUXES[f+F.evap]+FLUXES[f+F.transp]; + +/*Snow water equivalent*/ +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ +FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ +POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ +FLUXES[f+F.scf]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); /*snow cover fraction*/ + +// Infiltration (mm/day) +double infil = pars[P.max_infil]*(1 - exp(-(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])/pars[P.max_infil])); + +// Surface runoff (mm/day) +FLUXES[f+F.q_surf] = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]) - infil; + +// Update pools, including infiltration +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + deltat*infil; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW]; + +// Volumetric soil moisture from water pools +double sm_PAW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double sm_PUW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage +double drain_PAW = DRAINAGE(sm_PAW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = DRAINAGE(sm_PUW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + +// Remove drainage from layers +sm_PAW -= drain_PAW; +sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(sm_PAW,pars[P.hydr_cond],pars[P.retention]); +double k_PUW = HYDROFUN_MOI2CON(sm_PUW,pars[P.hydr_cond],pars[P.retention]); + +// Convert to potential +double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.retention]); +double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.retention]); + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(psi_PAW-psi_PUW)/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); + +// Transfer flux in mm/day +FLUXES[f+F.paw2puw] = xfer*1000*3600*24; + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] += (-FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat; +POOLS[nxp+S.H2O_PUW] += (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=pow(pars[P.Q10rhco2],(0.5*(T2M_MIN[n]+T2M_MAX[n])-meantemp)/10)*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood CWD production*/ +FLUXES[f+F.wood2cwd] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic CWD*/ +FLUXES[f+F.resp_het_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_cwd],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_som],deltat))/deltat; + +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +double thetas = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double *jcr_o = JCR(ch4pars,T2M_MIN[n],T2M_MAX[n],thetas); +//outputformat +//jcr_o 0-3 fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_cwd],deltat))/deltat; +/* aerobic Rh from litter*/ +FLUXES[f+F.ae_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_lit],deltat))/deltat; +/* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_som],deltat))/deltat; +/* anaerobic Rh from coarse woody debris*/ +FLUXES[f+F.an_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from litter*/ +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_lit],deltat))/deltat; +/* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_som],deltat))/deltat; +/* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*1+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*(1-jcr_o[3]); +/* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*0+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*jcr_o[3]; +/* fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+F.fV] = jcr_o[1]; +/* fT Temperature scaler*/ +FLUXES[f+F.fT] = jcr_o[0]; +/* fW Water scaler*/ +FLUXES[f+F.fW] = jcr_o[2]; +/* fCH4 CH4 fraction*/ +FLUXES[f+F.fCH4] = jcr_o[3]; +/* PAW/PAW_fs thetas*/ +FLUXES[f+F.soil_moist] = thetas; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*---------------------- end of JCR --------------------------------------------*/ + +/*CWD to SOM*/ +FLUXES[f+F.cwd2som] = POOLS[p+S.C_cwd]*(1-pow(1-pars[P.tr_cwd2som]*FLUXES[f+F.temprate],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2som]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2cwd])*deltat; + POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] + (FLUXES[f+F.wood2cwd] - FLUXES[f+F.ae_rh_cwd]-FLUXES[f+F.an_rh_cwd]-FLUXES[f+F.cwd2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + + + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-CF[S.C_cwd])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2cwd])*deltat; + /*dead C pools*/ + /*CWD*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.fx_woo2cwd]-FLUXES[f+F.f_cwd]-FLUXES[f+F.fx_cwd2som])*deltat; + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + +} + + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1101/EDC2_1101.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1101(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1101_PARAMETERS P=DALEC_1101_PARAMETERS; +struct DALEC_1101_FLUXES F=DALEC_1101_FLUXES; +struct DALEC_1101_POOLS S=DALEC_1101_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +if (Fin[n] > 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_cwd,P.i_lit,P.i_som,P.i_PAW,P.i_PUW,P.i_SWE}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1101/PARS_INFO_1101.c === + +#pragma once +#include "DALEC_1101.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1101(DATA *CARDADATA) +{ + + +struct DALEC_1101_PARAMETERS P=DALEC_1101_PARAMETERS; + +/*Litter decomposition rate*/ +CARDADATA->parmin[P.tr_lit2som]=0.00001; +CARDADATA->parmax[P.tr_lit2som]=0.01; + +/*CWD decomposition rate*/ +CARDADATA->parmin[P.tr_cwd2som]=0.00001; +CARDADATA->parmax[P.tr_cwd2som]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR CWD*/ +CARDADATA->parmin[P.t_cwd]=0.00005; +CARDADATA->parmax[P.t_cwd]=0.005; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_som]=0.0000001; +CARDADATA->parmax[P.t_som]=0.001; + +/*\Q10 = 1.2-2.0*/ +CARDADATA->parmin[P.Q10rhco2]=1.2; +CARDADATA->parmax[P.Q10rhco2]=2.0; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C CWD*/ +CARDADATA->parmin[P.i_cwd]=1.0; +CARDADATA->parmax[P.i_cwd]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_som]=1.0; +CARDADATA->parmax[P.i_som]=200000.0; + +/*Retention parameter (b)*/ +CARDADATA->parmin[P.retention]=1.5; +CARDADATA->parmax[P.retention]=10; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +CARDADATA->parmin[P.hydr_cond]=0.0000001; +CARDADATA->parmax[P.hydr_cond]=0.00001; + +/*Maximum infiltration (mm/day)*/ +CARDADATA->parmin[P.max_infil]=1; +CARDADATA->parmax[P.max_infil]=100; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*PAW porosity*/ +CARDADATA->parmin[P.PAW_por]=0.2; +CARDADATA->parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +CARDADATA->parmin[P.PUW_por]=0.2; +CARDADATA->parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +CARDADATA->parmin[P.field_cap]=0.01; +CARDADATA->parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +CARDADATA->parmin[P.PAW_z]=0.01; +CARDADATA->parmax[P.PAW_z]=100; + +/*PUW depth (m)*/ +CARDADATA->parmin[P.PUW_z]=0.01; +CARDADATA->parmax[P.PUW_z]=100; + +/*Runoff excess*/ +CARDADATA->parmin[P.Q_excess]=0.01; +CARDADATA->parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +CARDADATA->parmin[P.Med_g1]=1.79; +CARDADATA->parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +CARDADATA->parmin[P.Vcmax25]=1e-8; +CARDADATA->parmax[P.Vcmax25]=140; + +/*Tminmin scaling factor*/ +CARDADATA->parmin[P.Tminmin]=258.15; +CARDADATA->parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +CARDADATA->parmin[P.Tminmax]=273.15; +CARDADATA->parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance*/ +CARDADATA->parmin[P.ga]=0.01; +CARDADATA->parmax[P.ga]=10.0; + +/*Tupp*/ +CARDADATA->parmin[P.Tupp]=299.15; +CARDADATA->parmax[P.Tupp]=318.15; + +/*Tdown*/ +CARDADATA->parmin[P.Tdown]=263.15; +CARDADATA->parmax[P.Tdown]=286.15; + +/*C3_frac*/ +CARDADATA->parmin[P.C3_frac]=1e-8; +CARDADATA->parmax[P.C3_frac]=1.0; + +/*Clumping index*/ +CARDADATA->parmin[P.clumping]=0.35; +CARDADATA->parmax[P.clumping]=1.0; + +/*Leaf single scattering albedo*/ +CARDADATA->parmin[P.leaf_refl]=1e-8; +CARDADATA->parmax[P.leaf_refl]=1.0; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +CARDADATA->parmin[P.i_SWE]=0.000001; +CARDADATA->parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +CARDADATA->parmin[P.min_melt]=240; +CARDADATA->parmax[P.min_melt]=270; + +/*sn2: slope*/ +CARDADATA->parmin[P.melt_slope]=0.00001; +CARDADATA->parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar*/ +CARDADATA->parmin[P.scf_scalar]=0.001; +CARDADATA->parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +/*jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +CARDADATA->parmin[P.S_fv]=1; +CARDADATA->parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +CARDADATA->parmin[P.thetas_opt]=0.2; +CARDADATA->parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +CARDADATA->parmin[P.fwc]=0.01; +CARDADATA->parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +CARDADATA->parmin[P.r_ch4]=0.001; +CARDADATA->parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +CARDADATA->parmin[P.Q10ch4]=1.0; +CARDADATA->parmax[P.Q10ch4]=3.0; + +/* maxPevap in mm/day*/ +CARDADATA->parmin[P.maxPevap]=0.01; +CARDADATA->parmax[P.maxPevap]=20; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1101/EDC1_1101.c === + +#pragma once +int EDC1_1101(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1101_PARAMETERS P=DALEC_1101_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2som]/(pars[P.tr_lit2som]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_som]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2som]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1101/MODEL_INFO_1101.c === + +#pragma once +#include "PARS_INFO_1101.c" +#include "DALEC_1101.c" +#include "EDC1_1101.c" +#include "EDC2_1101.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1101(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1101_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1101; +DALECmodel.edc1=EDC1_1101; +DALECmodel.edc2=EDC2_1101; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1101(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_DEDC; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/MODEL_INFO_1100.c === + +#pragma once +#include "PARS_INFO_1100.c" +#include "DALEC_1100.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF2.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1100(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +printf("Runing modconfig------------------------"); +static DALEC DALECmodel;DALEC_1100_MODCONFIG(&DALECmodel,DATA); +static MLF MLF;DALEC_MLF2_MODCONFIG(&MLF); + +/*Step 2: Fill structure with model-specific info*/ + +//Corresponding likelihood function + + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->noedcs=DALECmodel.noedcs; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +//DALECmodel.edc1=EDC1_1100; +//DALECmodel.edc2=EDC2_1100; + + + + + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + + + //Copying pointers + DATA->parmin=DALECmodel.PARS_INFO.parmin; + DATA->parmax=DALECmodel.PARS_INFO.parmax; + + +//oksofar("about to declare EDCD"); +//printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +//EDCSETUP(*DATA,&DALECmodel.EDCD); + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +/*Pointing to MLF*/ +DATA->MLF=MLF.mlf; + +/*Pointing to EMLF*/ +DATA->EMLF=EDC_DALEC_MLF2_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/EDC1_1100.c === + +#pragma once +int EDC1_1100(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1100_PARAMETERS P=DALEC_1100_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +// double const fauto=pars[P.f_auto]; +// double const ffol=(1-fauto)*pars[P.f_foliar]; +// double const flab=(1-fauto)*pars[P.f_lab]; +// double const froot=(1-fauto-flab)*pars[P.f_root]; +// double const fwood=1-fauto-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +// double const fsom=fwood+(froot+flab)*pars[P.tr_lit2som]/(pars[P.tr_lit2som]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +// double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_som]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2som]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +//We can remove this, H2O controls on RHCO2 make it difficult to justify +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +//Will want to remove this at some point when Alex's new scheme kicks in! +/*Allocation to canopy is comparable to allocation to fine roots*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((flab)>5*froot | (flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100_INDICES.c === + +#pragma once +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1100_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2som; +int tr_cwd2som; +int rauto_mr_r; +int rauto_mr_w; +int rauto_mr_q10; +int rauto_mrd_q10; +int rauto_gr; +int t_wood; +int t_root; +int t_lit; +int t_cwd; +int t_som; +int Q10rhco2; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_cwd; +int i_lit; +int i_som; +int retention; +int i_LY1_SM; +int i_LY2_SM; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int hydr_cond; +int max_infil; +int i_LY3_SM; +int LY1_por; +int LY2_por; +int LY3_por; +int field_cap; +int LY1_z;//LY1 depth +int LY2_z;//LY2 depth +int LY3_z;//LY3 depth +int LY1_vhc;//LY1 volumetric heat capacity +int LY2_vhc;//LY2 volumetric heat capacity +int LY3_vhc;//LY3 volumetric heat capacity +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int clumping; +int leaf_refl_par; +int leaf_refl_nir; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +int S_fv; +int thetas_opt; +int fwc; +int r_ch4; +int Q10ch4; +int T_phi; +int T_range; +int plgr; +int k_leaf; +int lambda_max; +int tau_W; +int time_c; +int time_r; +int init_T_mem; +int init_LAIW_mem; +int t_foliar; +int i_LY1_E; +int i_LY2_E; +int i_LY3_E; +int psi_50; +int beta_lgr; +int phi_RL; +int phi_WL; +int thermal_cond; +int thermal_cond_surf; +int q10canopy; +int canopyRdsf; +int sublimation_rate; +int root_frac; +int beta_lgrHMF; +int psi_50HMF; +int t_lab; +int maxPevap; +} DALEC_1100_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69, + 70,71,72,73,74,75,76,77,78,79, + 80,81,82,83,84,85,86,87,88, +}; + +struct DALEC_1100_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int gppnet; /*GPP*/ +int resp_auto; /*Autotrophic respiration*/ +int lab_prod; /*Labile production*/ +int foliar_prod; /*Labile release*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int ph_fol2lit; /*Foliar phenological senescence*/ +int fol2lit; /*Foliar decomposition*/ +int woo2cwd; /*Wood decomposition*/ +int roo2lit; /*Root decomposition*/ +int lab2lit; /*Labile C decomposition*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int q_ly1; /*LY1 runoff*/ +int q_ly2; /*LY2 runoff*/ +int ly1xly2; /*LY1->LY2 transfer*/ +int ly2xly3; /*LY2->LY3 transfer*/ +int q_ly3; /*LY3 runoff*/ +int q_surf; /*Surface runoff*/ +int infil; /*INFILTRATION*/ +int infil_e; /*INFILTRATION IE: temp = weight average of snow melt (0C) + liquid precip (@air temp)*/ +int q_ly1_e; /*Q LY1 IE: temp = LY1 temp*/ +int q_ly2_e; /*Q LY2 IE: temp = LY2 temp*/ +int q_ly3_e; /*Q LY3 IE: temp = LY3 temp*/ +int ly1xly2_e; /*LY1->NDZ transfer IE: temp of donor*/ +int ly2xly3_e; /*LY2->LY3 transfer IE: temp of donor*/ +int evap_e; /* See Renato's calculation*/ +int transp1_e; /* See Renato's calculation*/ +int transp2_e; /* See Renato's calculation*/ +int transp1; /*Transpiration*/ +int transp2; /*Transpiration*/ +int evap; /*Evaporation*/ +int snowfall; /*Snowfall to SWE*/ +int melt; /*Snow melt*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int aetr; /*aerobic turnover scalar*/ +int antr; /*anaerobic turnover scalar*/ +int an_co2_c_ratio; /*CO2 fraction in anaerobic C decomposition*/ +int an_ch4_c_ratio; /*CH4 fraction in anaerobic C decomposition*/ +int target_LAI; /*LAI environmental target*/ +int dlambda_dt; /*dLAI/dt*/ +int f_temp_thresh; /*f_temp_thres*/ +int f_dayl_thresh; /*f_dayl_thres*/ +int lai_fire; /*LAI fire loss*/ +int foliar_fire_frac; /*C_fol fire loss frac*/ +int net_radiation; /*Net radiation flux*/ +int latent_heat; /*latent heat flux*/ +int sensible_heat; /*sensible heat flux*/ +int ground_heat; /*ground heat flux*/ +int gh_in; /*ground heat flux in converted units*/ +int resp_auto_growth; /*autotrophic growth respiration*/ +int resp_auto_maint; /*autotrophic maintenance respiration*/ +int SWin; +int SWout; +int LWin; +int LWout; +int ly1xly2_th_e; +int ly2xly3_th_e; +int resp_auto_maint_dark; +int sublimation; +int geological; +int ets; /* Total land-atmosphere water flux (evaporation + transpiration + sublimation) */ +int beta_factor; +int soil_beta_factor; +int hydraulic_mortality_factor; +int nonleaf_mortality_factor; +int leaf_mortality_factor; +int dist_lab; +int dist_fol; +int dist_roo; +int dist_woo; +int Rd; +int lambda_tilde_max; +int lambda_W; +int labyield2lit; +int folyield2lit; +int rooyield2lit; +int wooyield2cwd; +} DALEC_1100_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69, + 70,71,72,73,74,75,76,77,78,79, + 80,81,82,83,84,85,86,87,88,89, + 90,91,92,93,94,95,96,97,98,99, +}; + + + +/*Prognostic states and Diagnostic states (dependent on other states)*/ + + +struct DALEC_1100_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_LY1; /*Layer 1 H2O*/ +int H2O_LY2; /*Layer 2 H2O*/ +int H2O_LY3; /*Layer 3 H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +int E_LY1; /*LY1 thermal energy state*/ +int E_LY2; /*LY2 thermal energy state*/ +int E_LY3; /*LY3 thermal energy state*/ +int D_LAI;//leaf area index +int D_SCF;//snow-covered fraction +int D_TEMP_LY1;//LY1 temp in K +int D_TEMP_LY2;//LY2 temp in K +int D_TEMP_LY3;//LY3 temp in K +int D_LF_LY1;//LY1 liquid h2o frac +int D_LF_LY2;//LY2 liquid h2o frac +int D_LF_LY3;//LY3 liquid h2o frac +int D_SM_LY1;//LY1 soil moisture +int D_SM_LY2;//LY2 soil moisture +int D_SM_LY3;//LY3 soil moisture +int D_PSI_LY1;//LY1 soil moisture +int D_PSI_LY2;//LY2 soil moisture +int D_PSI_LY3;//LY3 soil moisture +int M_LAI_MAX;//KNORR LAI module max LAI memory +int M_LAI_TEMP;//KNORR LAI module temp memory +} DALEC_1100_POOLS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29 +}; + +struct DALEC_1100_EDCs{ +int vcmax_lcma; +int litcwdtor; +int cwdsomtor; +int mr_rates; +int rootwoodtor; +int fol2lig_cf; +int relativepsi50; +int state_ranges; +int state_trajectories; +int nsc_ratio; +int cfcr_ratio; +int fffr_ratio; +int mean_ly1_temp; +int mean_ly2_temp; +int mean_ly3_temp; +int state_proximity; +} DALEC_1100_EDCs={ + 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9,10,11,12,13, + 14, 15 +}; + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100_NC_INFO.c === + +#pragma once + +#include "DALEC_1100_INDICES.c" +//#include "CARDAMOM_DATA_STRUCTURE.c" +void POPULATE_INFO_STRUCTS(DALEC * DALECmodel){ + + struct DALEC_1100_FLUXES F=DALEC_1100_FLUXES; + struct DALEC_1100_PARAMETERS P=DALEC_1100_PARAMETERS; + struct DALEC_1100_POOLS S=DALEC_1100_POOLS; + struct DALEC_1100_EDCs E=DALEC_1100_EDCs; + + + //Populate the arrays with valid memory blocks, so we are writing to something real! + //Warning: this part of the code is likely not going to need to be modified, skip ahead to "METADATA DEFINITIONS" + DALECmodel->FLUX_META.NAME= calloc(DALECmodel->nofluxes, sizeof(char *)); + DALECmodel->FLUX_META.ABBREVIATION= calloc(DALECmodel->nofluxes, sizeof(char *)); + DALECmodel->FLUX_META.UNITS= calloc(DALECmodel->nofluxes, sizeof(char *)); + DALECmodel->FLUX_META.DESCRIPTION= calloc(DALECmodel->nofluxes, sizeof(char *)); + + DALECmodel->PARS_META.NAME= calloc(DALECmodel->nopars, sizeof(char *)); + DALECmodel->PARS_META.ABBREVIATION= calloc(DALECmodel->nopars, sizeof(char *)); + DALECmodel->PARS_META.UNITS= calloc(DALECmodel->nopars, sizeof(char *)); + DALECmodel->PARS_META.DESCRIPTION= calloc(DALECmodel->nopars, sizeof(char *)); + + DALECmodel->POOLS_META.NAME= calloc(DALECmodel->nopools, sizeof(char *)); + DALECmodel->POOLS_META.ABBREVIATION= calloc(DALECmodel->nopools, sizeof(char *)); + DALECmodel->POOLS_META.UNITS= calloc(DALECmodel->nopools, sizeof(char *)); + DALECmodel->POOLS_META.DESCRIPTION= calloc(DALECmodel->nopools, sizeof(char *)); + + /* --NOT YET IMPLEMENTED-- + DALECmodel->EDC_META.NAME= calloc(DALECmodel->noedcs, sizeof(char *)); + DALECmodel->EDC_META.ABBREVIATION= calloc(DALECmodel->noedcs, sizeof(char *)); + DALECmodel->EDC_META.UNITS= calloc(DALECmodel->noedcs, sizeof(char *)); + DALECmodel->EDC_META.DESCRIPTION= calloc(DALECmodel->noedcs, sizeof(char *)); + */ + + + //----------------METADATA DEFINITIONS---------------- + // This block contains the actual metadata itself + // NOTE: While ABBREVIATION is required, NAME, UNITS and DESCRIPTION are optional + // + // WARNING: if you are adding a whole new item, you must also add the new item to DALEC_####_INDICES.c + // + // EXAMPLE: the flux "Banana crop yield" with abbreviation "banana" needs to be added to DALEC 1234 + // The following would be added to this current file: + // + //++ DALECmodel->FLUX_META.NAME[F.banana]="Banana crop yield"; + //++ DALECmodel->FLUX_META.ABBREVIATION[F.banana]="banana"; --I strongly advise keeping the abbreviation the same as the name in DALEC_####_INDICES.c + //++ DALECmodel->FLUX_META.UNITS[F.banana]="KiloBanana"; + //++ DALECmodel->FLUX_META.DESCRIPTION[F.banana]="Number of bananas harvested, in industry standard KiloBananas"; + // + // + // In addition, one would need to change the struct DALEC_1234_FLUXES in DALEC_1234_INDICES.c + // + // struct DALEC_1234_FLUXES{ + // /*DALEC FLUXES*/ + // int gpp; /*GPP*/ + // int gppnet; /*GPP*/ + // int resp_auto; /*Autotrophic respiration*/ + //++ int banana; /*Bananas harvested*/ + // } DALEC_1234_FLUXES={ + //++ 0, 1, 2, 3, 4 + // }; + // + + + + // Carbon, Water, Energy Fluxes + DALECmodel->FLUX_META.NAME[F.gpp]="Gross Primary productivity"; + DALECmodel->FLUX_META.ABBREVIATION[F.gpp]="GPP"; + DALECmodel->FLUX_META.UNITS[F.gpp]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.gpp]="GPP, doesn\"t include maintenance respiration"; + + DALECmodel->FLUX_META.NAME[F.gppnet]="Net Gross Primary Productivity"; + DALECmodel->FLUX_META.ABBREVIATION[F.gppnet]="gppnet"; + DALECmodel->FLUX_META.UNITS[F.gppnet]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.gppnet]="GPP, including maintenance respiration"; + + DALECmodel->FLUX_META.NAME[F.resp_auto]="Total autotrophic respiration"; + DALECmodel->FLUX_META.ABBREVIATION[F.resp_auto]="resp_auto"; + DALECmodel->FLUX_META.UNITS[F.resp_auto]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.resp_auto]="Includes maintenance respiration and growth respiration"; + + DALECmodel->FLUX_META.NAME[F.lab_prod]="Labile production"; + DALECmodel->FLUX_META.ABBREVIATION[F.lab_prod]="lab_prod"; + DALECmodel->FLUX_META.UNITS[F.lab_prod]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.lab_prod]="TBD"; + + DALECmodel->FLUX_META.NAME[F.foliar_prod]="Labile release"; + DALECmodel->FLUX_META.ABBREVIATION[F.foliar_prod]="foliar_prod"; + DALECmodel->FLUX_META.UNITS[F.foliar_prod]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.foliar_prod]="TBD"; + + DALECmodel->FLUX_META.NAME[F.root_prod]="Root production"; + DALECmodel->FLUX_META.ABBREVIATION[F.root_prod]="root_prod"; + DALECmodel->FLUX_META.UNITS[F.root_prod]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.root_prod]="TBD"; + + DALECmodel->FLUX_META.NAME[F.wood_prod]="Wood production"; + DALECmodel->FLUX_META.ABBREVIATION[F.wood_prod]="wood_prod"; + DALECmodel->FLUX_META.UNITS[F.wood_prod]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.wood_prod]="TBD"; + + DALECmodel->FLUX_META.NAME[F.fol2lit]="Foliar decomposition"; + DALECmodel->FLUX_META.ABBREVIATION[F.fol2lit]="fol2lit"; + DALECmodel->FLUX_META.UNITS[F.fol2lit]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.fol2lit]="TBD"; + + DALECmodel->FLUX_META.NAME[F.woo2cwd]="Wood decomposition"; + DALECmodel->FLUX_META.ABBREVIATION[F.woo2cwd]="woo2cwd"; + DALECmodel->FLUX_META.UNITS[F.woo2cwd]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.woo2cwd]="TBD"; + + DALECmodel->FLUX_META.NAME[F.roo2lit]="Root decomposition"; + DALECmodel->FLUX_META.ABBREVIATION[F.roo2lit]="roo2lit"; + DALECmodel->FLUX_META.UNITS[F.roo2lit]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.roo2lit]="TBD"; + + DALECmodel->FLUX_META.NAME[F.cwd2som]="CWD decomposition"; + DALECmodel->FLUX_META.ABBREVIATION[F.cwd2som]="cwd2som"; + DALECmodel->FLUX_META.UNITS[F.cwd2som]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.cwd2som]="TBD"; + + DALECmodel->FLUX_META.NAME[F.lit2som]="Litter decomposition"; + DALECmodel->FLUX_META.ABBREVIATION[F.lit2som]="lit2som"; + DALECmodel->FLUX_META.UNITS[F.lit2som]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.lit2som]="TBD"; + + DALECmodel->FLUX_META.NAME[F.f_total]="Total Fire Flux"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_total]="f_total"; + DALECmodel->FLUX_META.UNITS[F.f_total]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_total]="TBD"; + + DALECmodel->FLUX_META.NAME[F.f_lab]="Labile fire loss"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_lab]="f_lab"; + DALECmodel->FLUX_META.UNITS[F.f_lab]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_lab]="TBD"; + + DALECmodel->FLUX_META.NAME[F.f_fol]="Foliar fire loss"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_fol]="f_fol"; + DALECmodel->FLUX_META.UNITS[F.f_fol]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_fol]="TBD"; + + DALECmodel->FLUX_META.NAME[F.f_roo]="Root fire loss"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_roo]="f_roo"; + DALECmodel->FLUX_META.UNITS[F.f_roo]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_roo]="TBD"; + + DALECmodel->FLUX_META.NAME[F.f_woo]="Wood fire loss"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_woo]="f_woo"; + DALECmodel->FLUX_META.UNITS[F.f_woo]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_woo]="TBD"; + + DALECmodel->FLUX_META.NAME[F.f_cwd]="CWD fire loss"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_cwd]="f_cwd"; + DALECmodel->FLUX_META.UNITS[F.f_cwd]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_cwd]="TBD"; + + DALECmodel->FLUX_META.NAME[F.f_lit]="Litter fire loss"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_lit]="f_lit"; + DALECmodel->FLUX_META.UNITS[F.f_lit]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_lit]="TBD"; + + DALECmodel->FLUX_META.NAME[F.f_som]="Soil fire loss"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_som]="f_som"; + DALECmodel->FLUX_META.UNITS[F.f_som]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_som]="TBD"; + + DALECmodel->FLUX_META.NAME[F.fx_lab2lit]="Fire labile to litter"; + DALECmodel->FLUX_META.ABBREVIATION[F.fx_lab2lit]="fx_lab2lit"; + DALECmodel->FLUX_META.UNITS[F.fx_lab2lit]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.fx_lab2lit]="Fire transfer labile to litter"; + + DALECmodel->FLUX_META.NAME[F.fx_fol2lit]="Fire foliar to litter"; + DALECmodel->FLUX_META.ABBREVIATION[F.fx_fol2lit]="fx_fol2lit"; + DALECmodel->FLUX_META.UNITS[F.fx_fol2lit]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.fx_fol2lit]="Fire transfer foliar to litter"; + + DALECmodel->FLUX_META.NAME[F.fx_roo2lit]="Fire root to litter"; + DALECmodel->FLUX_META.ABBREVIATION[F.fx_roo2lit]="fx_roo2lit"; + DALECmodel->FLUX_META.UNITS[F.fx_roo2lit]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.fx_roo2lit]="Fire transfer root to litter"; + + DALECmodel->FLUX_META.NAME[F.fx_woo2cwd]="Fire wood to CWD"; + DALECmodel->FLUX_META.ABBREVIATION[F.fx_woo2cwd]="fx_woo2cwd"; + DALECmodel->FLUX_META.UNITS[F.fx_woo2cwd]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.fx_woo2cwd]="Fire transfer wood to CWD"; + + DALECmodel->FLUX_META.NAME[F.fx_cwd2som]="Fire CWD to soil"; + DALECmodel->FLUX_META.ABBREVIATION[F.fx_cwd2som]="fx_cwd2som"; + DALECmodel->FLUX_META.UNITS[F.fx_cwd2som]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.fx_cwd2som]="Fire transfer CWD to soil"; + + DALECmodel->FLUX_META.NAME[F.fx_lit2som]="Fire litter to soil"; + DALECmodel->FLUX_META.ABBREVIATION[F.fx_lit2som]="fx_lit2som"; + DALECmodel->FLUX_META.UNITS[F.fx_lit2som]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.fx_lit2som]="Fire transfer litter to soil"; + + DALECmodel->FLUX_META.NAME[F.q_ly1]="LY1 runoff"; + DALECmodel->FLUX_META.ABBREVIATION[F.q_ly1]="q_ly1"; + DALECmodel->FLUX_META.UNITS[F.q_ly1]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.q_ly1]="LY1 runoff"; + + DALECmodel->FLUX_META.NAME[F.q_ly2]="LY2 runoff"; + DALECmodel->FLUX_META.ABBREVIATION[F.q_ly2]="q_ly2"; + DALECmodel->FLUX_META.UNITS[F.q_ly2]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.q_ly2]="LY2 runoff"; + + DALECmodel->FLUX_META.NAME[F.ly1xly2]="LY1 to LY2 transfer"; + DALECmodel->FLUX_META.ABBREVIATION[F.ly1xly2]="ly1xly2"; + DALECmodel->FLUX_META.UNITS[F.ly1xly2]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.ly1xly2]="LY1->LY2 transfer"; + + DALECmodel->FLUX_META.NAME[F.ly2xly3]="LY2 to LY3 transfer"; + DALECmodel->FLUX_META.ABBREVIATION[F.ly2xly3]="ly2xly3"; + DALECmodel->FLUX_META.UNITS[F.ly2xly3]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.ly2xly3]="LY2->LY3 transfer"; + + DALECmodel->FLUX_META.NAME[F.q_ly3]="LY3 runoff"; + DALECmodel->FLUX_META.ABBREVIATION[F.q_ly3]="q_ly3"; + DALECmodel->FLUX_META.UNITS[F.q_ly3]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.q_ly3]="LY3 runoff"; + + DALECmodel->FLUX_META.NAME[F.q_surf]="Surface runoff"; + DALECmodel->FLUX_META.ABBREVIATION[F.q_surf]="q_surf"; + DALECmodel->FLUX_META.UNITS[F.q_surf]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.q_surf]="Surface runoff"; + + DALECmodel->FLUX_META.NAME[F.infil]="Infiltration"; + DALECmodel->FLUX_META.ABBREVIATION[F.infil]="infil"; + DALECmodel->FLUX_META.UNITS[F.infil]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.infil]="INFILTRATION"; + + DALECmodel->FLUX_META.NAME[F.infil_e]="Infiltration IE"; + DALECmodel->FLUX_META.ABBREVIATION[F.infil_e]="infil_e"; + DALECmodel->FLUX_META.UNITS[F.infil_e]="TBD"; + DALECmodel->FLUX_META.DESCRIPTION[F.infil_e]="INFILTRATION IE: temp = weight average of snow melt (0C) + liquid precip (@air temp)"; + + DALECmodel->FLUX_META.NAME[F.q_ly1_e]="Q LY1 IE"; + DALECmodel->FLUX_META.ABBREVIATION[F.q_ly1_e]="q_ly1_e"; + DALECmodel->FLUX_META.UNITS[F.q_ly1_e]="TBD"; + DALECmodel->FLUX_META.DESCRIPTION[F.q_ly1_e]="Q LY1 IE: temp = LY1 temp"; + + DALECmodel->FLUX_META.NAME[F.q_ly2_e]="Q LY2 IE"; + DALECmodel->FLUX_META.ABBREVIATION[F.q_ly2_e]="q_ly2_e"; + DALECmodel->FLUX_META.UNITS[F.q_ly2_e]="TBD"; + DALECmodel->FLUX_META.DESCRIPTION[F.q_ly2_e]="Q LY2 IE: temp = LY2 temp"; + + DALECmodel->FLUX_META.NAME[F.q_ly3_e]="Q LY3 IE"; + DALECmodel->FLUX_META.ABBREVIATION[F.q_ly3_e]="q_ly3_e"; + DALECmodel->FLUX_META.UNITS[F.q_ly3_e]="TBDy"; + DALECmodel->FLUX_META.DESCRIPTION[F.q_ly3_e]="Q LY3 IE: temp = LY3 temp"; + + DALECmodel->FLUX_META.NAME[F.ly1xly2_e]="LY1 to NDZ IE"; + DALECmodel->FLUX_META.ABBREVIATION[F.ly1xly2_e]="ly1xly2_e"; + DALECmodel->FLUX_META.UNITS[F.ly1xly2_e]="TBD"; + DALECmodel->FLUX_META.DESCRIPTION[F.ly1xly2_e]="LY1 to NDZ transfer IE: temp of donor"; + + DALECmodel->FLUX_META.NAME[F.ly2xly3_e]="LY2 to LY3 IE"; + DALECmodel->FLUX_META.ABBREVIATION[F.ly2xly3_e]="ly2xly3_e"; + DALECmodel->FLUX_META.UNITS[F.ly2xly3_e]="TBD"; + DALECmodel->FLUX_META.DESCRIPTION[F.ly2xly3_e]="LY2 to LY3 transfer IE: temp of donor"; + + DALECmodel->FLUX_META.NAME[F.evap_e]="Evaporation E"; + DALECmodel->FLUX_META.ABBREVIATION[F.evap_e]="evap_e"; + DALECmodel->FLUX_META.UNITS[F.evap_e]="TBD"; + DALECmodel->FLUX_META.DESCRIPTION[F.evap_e]="See Retano calculation"; + + DALECmodel->FLUX_META.NAME[F.transp1_e]="Transpiration 1 E"; + DALECmodel->FLUX_META.ABBREVIATION[F.transp1_e]="transp1_e"; + DALECmodel->FLUX_META.UNITS[F.transp1_e]="TBD"; + DALECmodel->FLUX_META.DESCRIPTION[F.transp1_e]="See Retano calculation"; + + DALECmodel->FLUX_META.NAME[F.transp2_e]="Transpiration 2 E"; + DALECmodel->FLUX_META.ABBREVIATION[F.transp2_e]="transp2_e"; + DALECmodel->FLUX_META.UNITS[F.transp2_e]="TBD"; + DALECmodel->FLUX_META.DESCRIPTION[F.transp2_e]="See Retano calculation"; + + DALECmodel->FLUX_META.NAME[F.transp1]="Transpiration 1"; + DALECmodel->FLUX_META.ABBREVIATION[F.transp1]="transp1"; + DALECmodel->FLUX_META.UNITS[F.transp1]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.transp1]="Transpiration"; + + DALECmodel->FLUX_META.NAME[F.transp2]="Transpiration 2"; + DALECmodel->FLUX_META.ABBREVIATION[F.transp2]="transp2"; + DALECmodel->FLUX_META.UNITS[F.transp2]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.transp2]="Transpiration"; + + DALECmodel->FLUX_META.NAME[F.evap]="Evaporation"; + DALECmodel->FLUX_META.ABBREVIATION[F.evap]="evap"; + DALECmodel->FLUX_META.UNITS[F.evap]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.evap]="Evaporation"; + + DALECmodel->FLUX_META.NAME[F.snowfall]="Snowfall"; + DALECmodel->FLUX_META.ABBREVIATION[F.snowfall]="snowfall"; + DALECmodel->FLUX_META.UNITS[F.snowfall]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.snowfall]="Snowfall"; + + DALECmodel->FLUX_META.NAME[F.melt]="Melt"; + DALECmodel->FLUX_META.ABBREVIATION[F.melt]="melt"; + DALECmodel->FLUX_META.UNITS[F.melt]="kgH20/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.melt]="melt"; + + DALECmodel->FLUX_META.NAME[F.ae_rh_cwd]="Aerobic heterotrophic respiration coarse woody debris"; + DALECmodel->FLUX_META.ABBREVIATION[F.ae_rh_cwd]="ae_rh_cwd"; + DALECmodel->FLUX_META.UNITS[F.ae_rh_cwd]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.ae_rh_cwd]="Aerobic heterotrophic respiration from coarse woody debris pool"; + + DALECmodel->FLUX_META.NAME[F.ae_rh_lit]="Aerobic heterotrophic respiration coarse woody litter"; + DALECmodel->FLUX_META.ABBREVIATION[F.ae_rh_lit]="ae_rh_lit"; + DALECmodel->FLUX_META.UNITS[F.ae_rh_lit]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.ae_rh_lit]="Aerobic heterotrophic respiration from litter pool"; + + DALECmodel->FLUX_META.NAME[F.ae_rh_som]="Aerobic heterotrophic respiration soil organic matter"; + DALECmodel->FLUX_META.ABBREVIATION[F.ae_rh_som]="ae_rh_som"; + DALECmodel->FLUX_META.UNITS[F.ae_rh_som]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.ae_rh_som]="Aerobic heterotrophic respiration from soil organic matter pool"; + + DALECmodel->FLUX_META.NAME[F.an_rh_cwd]="Anaerobic heterotrophic respiration coarse woody debris"; + DALECmodel->FLUX_META.ABBREVIATION[F.an_rh_cwd]="an_rh_cwd"; + DALECmodel->FLUX_META.UNITS[F.an_rh_cwd]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.an_rh_cwd]="Anaerobic heterotrophic respiration from coarse woody debris pool"; + + DALECmodel->FLUX_META.NAME[F.an_rh_lit]="Anaerobic heterotrophic respiration litter"; + DALECmodel->FLUX_META.ABBREVIATION[F.an_rh_lit]="an_rh_lit"; + DALECmodel->FLUX_META.UNITS[F.an_rh_lit]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.an_rh_lit]="Anaerobic heterotrophic respiration from litter pool"; + + DALECmodel->FLUX_META.NAME[F.an_rh_som]="Anaerobic heterotrophic respiration soil organic matter"; + DALECmodel->FLUX_META.ABBREVIATION[F.an_rh_som]="an_rh_som"; + DALECmodel->FLUX_META.UNITS[F.an_rh_som]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.an_rh_som]="Anaerobic heterotrophic respiration from soil organic matter pool"; + + DALECmodel->FLUX_META.NAME[F.rh_co2]="Heterotrophic respiration CO2 flux"; + DALECmodel->FLUX_META.ABBREVIATION[F.rh_co2]="rh_co2"; + DALECmodel->FLUX_META.UNITS[F.rh_co2]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.rh_co2]="Total CO2 flux from heterotrophic respiration"; + + DALECmodel->FLUX_META.NAME[F.rh_ch4]="Heterotrophic respiration CH4 flux"; + DALECmodel->FLUX_META.ABBREVIATION[F.rh_ch4]="rh_ch4"; + DALECmodel->FLUX_META.UNITS[F.rh_ch4]="gCH4/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.rh_ch4]="Total CH4 flux from heterotrophic respiration"; + + DALECmodel->FLUX_META.NAME[F.aetr]="Aerobic turnover scalar"; + DALECmodel->FLUX_META.ABBREVIATION[F.aetr]="aetr"; + DALECmodel->FLUX_META.UNITS[F.aetr]="scalar*"; + DALECmodel->FLUX_META.DESCRIPTION[F.aetr]="Aerobic turnover scalar*"; + + DALECmodel->FLUX_META.NAME[F.antr]="Anaerobic turnover scalar"; + DALECmodel->FLUX_META.ABBREVIATION[F.antr]="antr"; + DALECmodel->FLUX_META.UNITS[F.antr]="scalar*"; + DALECmodel->FLUX_META.DESCRIPTION[F.antr]="Anaerobic turnover scalar*"; + + DALECmodel->FLUX_META.NAME[F.an_co2_c_ratio]="Anaerobic CO2 C ratio"; + DALECmodel->FLUX_META.ABBREVIATION[F.an_co2_c_ratio]="an_co2_c_ratio"; + DALECmodel->FLUX_META.UNITS[F.an_co2_c_ratio]="fraction*"; + DALECmodel->FLUX_META.DESCRIPTION[F.an_co2_c_ratio]="CO2 fraction in anaerobic C decomposition*"; + + DALECmodel->FLUX_META.NAME[F.an_ch4_c_ratio]="Anaerobic CH4 C ratio"; + DALECmodel->FLUX_META.ABBREVIATION[F.an_ch4_c_ratio]="an_ch4_c_ratio"; + DALECmodel->FLUX_META.UNITS[F.an_ch4_c_ratio]="fraction*"; + DALECmodel->FLUX_META.DESCRIPTION[F.an_ch4_c_ratio]="CH4 fraction in anaerobic C decomposition*"; + + DALECmodel->FLUX_META.NAME[F.target_LAI]="Target leaf area index"; + DALECmodel->FLUX_META.ABBREVIATION[F.target_LAI]="target_LAI"; + DALECmodel->FLUX_META.UNITS[F.target_LAI]="m2/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.target_LAI]="Target LAI calculated based on KNORR phenology scheme influenced by water, light, and temperature. Coded in KNORR_ALLOCATION.c"; + + DALECmodel->FLUX_META.NAME[F.dlambda_dt]="Delta leaf area index"; + DALECmodel->FLUX_META.ABBREVIATION[F.dlambda_dt]="dlambda_dt"; + DALECmodel->FLUX_META.UNITS[F.dlambda_dt]="m2/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.dlambda_dt]="Difference between Target leaf area index (target_LAI) and current leaf area index. Coded in KNORR_ALLOCATION.c "; + + DALECmodel->FLUX_META.NAME[F.f_temp_thresh]="Temperature threshold"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_temp_thresh]="f_temp_thresh"; + DALECmodel->FLUX_META.UNITS[F.f_temp_thresh]="fraction"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_temp_thresh]="Fraction of plants within pixel able to grow foliage on temperature threshold. Coded in KNORR_ALLOCATION.c"; + + DALECmodel->FLUX_META.NAME[F.f_dayl_thresh]="Daylight threshold"; + DALECmodel->FLUX_META.ABBREVIATION[F.f_dayl_thresh]="f_dayl_thresh"; + DALECmodel->FLUX_META.UNITS[F.f_dayl_thresh]="fraction"; + DALECmodel->FLUX_META.DESCRIPTION[F.f_dayl_thresh]="Fraction of plants within pixel able to grow foliage based on daylight threshold. Coded in KNORR_ALLOCATION.c"; + + DALECmodel->FLUX_META.NAME[F.lai_fire]="Leaf area index fire loss"; + DALECmodel->FLUX_META.ABBREVIATION[F.lai_fire]="lai_fire"; + DALECmodel->FLUX_META.UNITS[F.lai_fire]="m2/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.lai_fire]="Leaf area index fire lost to fire*"; + + DALECmodel->FLUX_META.NAME[F.foliar_fire_frac]="C_fol fire loss fraction"; + DALECmodel->FLUX_META.ABBREVIATION[F.foliar_fire_frac]="foliar_fire_frac"; + DALECmodel->FLUX_META.UNITS[F.foliar_fire_frac]="fraction"; + DALECmodel->FLUX_META.DESCRIPTION[F.foliar_fire_frac]="Foliage pool lost due to fire*"; + + DALECmodel->FLUX_META.NAME[F.net_radiation]="Net radiation flux"; + DALECmodel->FLUX_META.ABBREVIATION[F.net_radiation]="net_radiation"; + DALECmodel->FLUX_META.UNITS[F.net_radiation]="W/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.net_radiation]="Net radiation flux defined as incoming shortwave radiation (SWin) - outgoing shortwave radiation (SWout) + incoming longwave radiation (LWin) - outgoing longwave radiation (LWout)"; + + DALECmodel->FLUX_META.NAME[F.latent_heat]="Latent heat flux"; + DALECmodel->FLUX_META.ABBREVIATION[F.latent_heat]="latent_heat"; + DALECmodel->FLUX_META.UNITS[F.latent_heat]="W/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.latent_heat]="Latent heat flux, including sublimation"; + + DALECmodel->FLUX_META.NAME[F.sensible_heat]="Sensible heat flux"; + DALECmodel->FLUX_META.ABBREVIATION[F.sensible_heat]="sensible_heat"; + DALECmodel->FLUX_META.UNITS[F.sensible_heat]="W/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.sensible_heat]="Sensible heat flux"; + + DALECmodel->FLUX_META.NAME[F.ground_heat]="Ground heat flux"; + DALECmodel->FLUX_META.ABBREVIATION[F.ground_heat]="ground_heat"; + DALECmodel->FLUX_META.UNITS[F.ground_heat]="W/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.ground_heat]="Ground heat flux"; + + DALECmodel->FLUX_META.NAME[F.gh_in]="Ground heat flux in converted units"; + DALECmodel->FLUX_META.ABBREVIATION[F.gh_in]="gh_in"; + DALECmodel->FLUX_META.UNITS[F.gh_in]="J/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.gh_in]="Ground heat flux in converted units"; + + DALECmodel->FLUX_META.NAME[F.resp_auto_growth]="Autotrophic growth respiration"; + DALECmodel->FLUX_META.ABBREVIATION[F.resp_auto_growth]="resp_auto_growth"; + DALECmodel->FLUX_META.UNITS[F.resp_auto_growth]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.resp_auto_growth]="Autotrophic growth respiration"; + + DALECmodel->FLUX_META.NAME[F.resp_auto_maint]="Autotrophic maintenance respiration"; + DALECmodel->FLUX_META.ABBREVIATION[F.resp_auto_maint]="resp_auto_maint"; + DALECmodel->FLUX_META.UNITS[F.resp_auto_maint]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.resp_auto_maint]="Autotrophic maintenance respiration"; + + DALECmodel->FLUX_META.NAME[F.SWin]="Incoming shortwave radiation"; + DALECmodel->FLUX_META.ABBREVIATION[F.SWin]="SWin"; + DALECmodel->FLUX_META.UNITS[F.SWin]="W/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.SWin]="Incoming shortwave radiation"; + + DALECmodel->FLUX_META.NAME[F.SWout]="Outgoing shortwave radiation"; + DALECmodel->FLUX_META.ABBREVIATION[F.SWout]="SWout"; + DALECmodel->FLUX_META.UNITS[F.SWout]="W/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.SWout]="Outgoing shortwave radiation"; + + DALECmodel->FLUX_META.NAME[F.LWin]="Incoming longwave radiation"; + DALECmodel->FLUX_META.ABBREVIATION[F.LWin]="LWin"; + DALECmodel->FLUX_META.UNITS[F.LWin]="W/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.LWin]="Incoming longwave radiation"; + + DALECmodel->FLUX_META.NAME[F.LWout]="Outgoing longwave radiation"; + DALECmodel->FLUX_META.ABBREVIATION[F.LWout]="LWout"; + DALECmodel->FLUX_META.UNITS[F.LWout]="W/m2"; + DALECmodel->FLUX_META.DESCRIPTION[F.LWout]="Outgoing longwave radiation"; + + DALECmodel->FLUX_META.NAME[F.ly1xly2_th_e]="Thermal conductivity layer one to layer two*"; + DALECmodel->FLUX_META.ABBREVIATION[F.ly1xly2_th_e]="ly1xly2_th_e"; + DALECmodel->FLUX_META.UNITS[F.ly1xly2_th_e]="J/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.ly1xly2_th_e]="Thermal conductivity between layer one and layer two*"; + + DALECmodel->FLUX_META.NAME[F.ly2xly3_th_e]="Thermal conductivity layer two to layer three*"; + DALECmodel->FLUX_META.ABBREVIATION[F.ly2xly3_th_e]="ly2xly3_th_e"; + DALECmodel->FLUX_META.UNITS[F.ly2xly3_th_e]="J/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.ly2xly3_th_e]="Thermal conductivity between layer two and layer three*"; + + DALECmodel->FLUX_META.NAME[F.resp_auto_maint_dark]="Autotrophic maintenance dark respiration"; + DALECmodel->FLUX_META.ABBREVIATION[F.resp_auto_maint_dark]="resp_auto_maint_dark"; + DALECmodel->FLUX_META.UNITS[F.resp_auto_maint_dark]="gC/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.resp_auto_maint_dark]="Autotrophic maintenance dark respiration from foliage*"; + + DALECmodel->FLUX_META.NAME[F.sublimation]="Sublimation"; + DALECmodel->FLUX_META.ABBREVIATION[F.sublimation]="sublimation"; + DALECmodel->FLUX_META.UNITS[F.sublimation]="kgH2O/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.sublimation]="Sublimation*"; + + DALECmodel->FLUX_META.NAME[F.geological]="Geological"; + DALECmodel->FLUX_META.ABBREVIATION[F.geological]="geological"; + DALECmodel->FLUX_META.UNITS[F.geological]="J/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.geological]="Prederived geological flux in J/m2/day(105mW/m2)"; + + DALECmodel->FLUX_META.NAME[F.ets]="Total land-atmosphere water"; + DALECmodel->FLUX_META.ABBREVIATION[F.ets]="ets"; + DALECmodel->FLUX_META.UNITS[F.ets]="kgH2O/m2/day"; + DALECmodel->FLUX_META.DESCRIPTION[F.ets]="Total land-atmosphere water flux (evaporation + transpiration + sublimation)"; + + DALECmodel->FLUX_META.NAME[F.beta_factor]="Stress scaling factor"; + DALECmodel->FLUX_META.ABBREVIATION[F.beta_factor]="beta_factor"; + DALECmodel->FLUX_META.UNITS[F.beta_factor]="fraction"; + DALECmodel->FLUX_META.DESCRIPTION[F.beta_factor]="Stress due to cold weather and water availability"; + + DALECmodel->FLUX_META.NAME[F.soil_beta_factor]="H2O stress scaling factor"; + DALECmodel->FLUX_META.ABBREVIATION[F.soil_beta_factor]="soil_beta_factor"; + DALECmodel->FLUX_META.UNITS[F.soil_beta_factor]="fraction"; + DALECmodel->FLUX_META.DESCRIPTION[F.soil_beta_factor]="Stress due to soil water availability"; + + //Parameter info + + //TODO: Anthony, this entry seems inconsistent with the rest of the code, was it in error? + //DALECmodel->PARS_META.NAME[P.twood]="Turnover rate of wood"; + //DALECmodel->PARS_META.ABBREVIATION[P.twood]="twood"; + //DALECmodel->PARS_META.UNITS[P.twood]="gC/m2/day"; + //DALECmodel->PARS_META.DESCRIPTION[P.twood]="Includes maintenance respiration and growth respiration"; + + DALECmodel->PARS_META.NAME[P.tr_lit2som]="Litter decomposition rate"; + DALECmodel->PARS_META.ABBREVIATION[P.tr_lit2som]="lit2som"; + DALECmodel->PARS_META.UNITS[P.tr_lit2som]="fraction"; + DALECmodel->PARS_META.DESCRIPTION[P.tr_lit2som]="Fraction of litter lost to soil organic matter per day"; + + DALECmodel->PARS_META.NAME[P.tr_cwd2som]="CWD decomposition rate"; + DALECmodel->PARS_META.ABBREVIATION[P.tr_cwd2som]="cwd2som"; + DALECmodel->PARS_META.UNITS[P.tr_cwd2som]="fraction"; + DALECmodel->PARS_META.DESCRIPTION[P.tr_cwd2som]="Fraction of course woody debris lost to soil organic matter per day"; + + DALECmodel->PARS_META.NAME[P.rauto_mr_r]="Autotrophic maintenance respiration coefficient for roots"; + DALECmodel->PARS_META.ABBREVIATION[P.rauto_mr_r]="rauto_mr_r]"; + //DALECmodel->PARS_META.UNITS[P.rauto_mr_r]=""; + DALECmodel->PARS_META.DESCRIPTION[P.rauto_mr_r]="Autotrophic maintenance respiration coefficient for roots - turnover rate at 25oC (d-1)"; + + DALECmodel->PARS_META.NAME[P.rauto_mr_w]="Autotrophic maintenance respiration coefficient for wood"; + DALECmodel->PARS_META.ABBREVIATION[P.rauto_mr_w]="rauto_mr_w"; + //DALECmodel->PARS_META.UNITS[P.rauto_mr_w]=""; + DALECmodel->PARS_META.DESCRIPTION[P.rauto_mr_w]="Autotrophic maintenance respiration coefficient for wood - turnover rate at 25oC (d-1)"; + + DALECmodel->PARS_META.NAME[P.rauto_mr_q10]="Autotrophic maintenance respiration Q10 parameter"; + DALECmodel->PARS_META.ABBREVIATION[P.rauto_mr_q10]="rauto_mr_q10"; + //DALECmodel->PARS_META.UNITS[P.rauto_mr_q10]=""; + DALECmodel->PARS_META.DESCRIPTION[P.rauto_mr_q10]="Autotrophic maintenance respiration Q10 parameter"; + + DALECmodel->PARS_META.NAME[P.rauto_mrd_q10]="Dark respiration Q10 parameter"; + DALECmodel->PARS_META.ABBREVIATION[P.rauto_mrd_q10]="rauto_mrd_q10"; + //DALECmodel->PARS_META.UNITS[P.rauto_mrd_q10]=""; + DALECmodel->PARS_META.DESCRIPTION[P.rauto_mrd_q10]="Dark respiration Q10 parameter"; + + DALECmodel->PARS_META.NAME[P.rauto_gr]="Growth yield"; + DALECmodel->PARS_META.ABBREVIATION[P.rauto_gr]="rauto_gr"; + DALECmodel->PARS_META.UNITS[P.rauto_gr]="g C"; + DALECmodel->PARS_META.DESCRIPTION[P.rauto_gr]="Growth yield (g C appearing in new biomass per g C used for growth; \"growth yield\" in Cannell and Thornley 2000)"; + + DALECmodel->PARS_META.NAME[P.t_wood]="Turnover rate of wood"; + DALECmodel->PARS_META.ABBREVIATION[P.t_wood]="t_wood"; + DALECmodel->PARS_META.UNITS[P.t_wood]="gC/m2/day"; + DALECmodel->PARS_META.DESCRIPTION[P.t_wood]="Rate of wood loss per day* - 1% loss per year value"; + + DALECmodel->PARS_META.NAME[P.t_root]="Turnover rate of roots"; + DALECmodel->PARS_META.ABBREVIATION[P.t_root]="t_root"; + DALECmodel->PARS_META.UNITS[P.t_root]="gC/m2/day"; + DALECmodel->PARS_META.DESCRIPTION[P.t_root]="Rate of root loss per day"; + + DALECmodel->PARS_META.NAME[P.t_lit]="Turnover rate of litter"; + DALECmodel->PARS_META.ABBREVIATION[P.t_lit]="t_lit"; + DALECmodel->PARS_META.UNITS[P.t_lit]="gC/m2/day"; + DALECmodel->PARS_META.DESCRIPTION[P.t_lit]="Rate of litter turnover per day"; + + DALECmodel->PARS_META.NAME[P.t_cwd]="Turnover rate of coarse woody debris"; + DALECmodel->PARS_META.ABBREVIATION[P.t_cwd]="t_cwd"; + DALECmodel->PARS_META.UNITS[P.t_cwd]="gC/m2/day"; + DALECmodel->PARS_META.DESCRIPTION[P.t_cwd]="Rate of coarse woody debris turnover per day"; + + DALECmodel->PARS_META.NAME[P.t_som]="Turnover rate of soil organic matter"; + DALECmodel->PARS_META.ABBREVIATION[P.t_som]="t_som"; + DALECmodel->PARS_META.UNITS[P.t_som]="gC/m2/day"; + DALECmodel->PARS_META.DESCRIPTION[P.t_som]="Rate of soil turnover to heterotrophic respiration"; + + DALECmodel->PARS_META.NAME[P.Q10rhco2]="Q10"; + DALECmodel->PARS_META.ABBREVIATION[P.Q10rhco2]="Q10"; + //DALECmodel->PARS_META.UNITS[P.Q10rhco2]=""; + //DALECmodel->PARS_META.DESCRIPTION[P.Q10rhco2]=""; + + DALECmodel->PARS_META.NAME[P.LCMA]="Leaf mass carbon per area"; + DALECmodel->PARS_META.ABBREVIATION[P.LCMA]="LCMA"; + DALECmodel->PARS_META.UNITS[P.LCMA]="gC/m2"; + DALECmodel->PARS_META.DESCRIPTION[P.LCMA]=" Leaf mass carbon per unit leaf area; Kattge et al. 2011*;*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*"; + + DALECmodel->PARS_META.NAME[P.i_labile]="Initial labile"; + DALECmodel->PARS_META.ABBREVIATION[P.i_labile]="i_labile"; + DALECmodel->PARS_META.UNITS[P.i_labile]="gC/m2"; + DALECmodel->PARS_META.DESCRIPTION[P.i_labile]="Size of labile C pool at time step 1"; + + DALECmodel->PARS_META.NAME[P.i_foliar]="Initial foliar"; + DALECmodel->PARS_META.ABBREVIATION[P.i_foliar]="i_foliar"; + DALECmodel->PARS_META.UNITS[P.i_foliar]="gC/m2"; + DALECmodel->PARS_META.DESCRIPTION[P.i_labile]="Size of foliar C pool at time step 1"; + + DALECmodel->PARS_META.NAME[P.i_root]="Initial roots"; + DALECmodel->PARS_META.ABBREVIATION[P.i_root]="i_root"; + DALECmodel->PARS_META.UNITS[P.i_root]="gC/m2"; + DALECmodel->PARS_META.DESCRIPTION[P.i_root]="Size of roots C pool at time step 1"; + + DALECmodel->PARS_META.NAME[P.i_wood]="Initial wood"; + DALECmodel->PARS_META.ABBREVIATION[P.i_wood]="i_wood"; + DALECmodel->PARS_META.UNITS[P.i_wood]="gC/m2"; + DALECmodel->PARS_META.DESCRIPTION[P.i_wood]="Size of wood C pool at time step 1"; + + DALECmodel->PARS_META.NAME[P.i_cwd]="Initial CWD"; + DALECmodel->PARS_META.ABBREVIATION[P.i_cwd]="i_cwd"; + DALECmodel->PARS_META.UNITS[P.i_cwd]="gC/m2"; + DALECmodel->PARS_META.DESCRIPTION[P.i_cwd]="Size of coarse woody debris C pool at time step 1"; + + DALECmodel->PARS_META.NAME[P.i_lit]="Initial litter"; + DALECmodel->PARS_META.ABBREVIATION[P.i_lit]="i_lit"; + DALECmodel->PARS_META.UNITS[P.i_lit]="gC/m2"; + DALECmodel->PARS_META.DESCRIPTION[P.i_lit]="Size of litter C pool at time step 1"; + + DALECmodel->PARS_META.NAME[P.i_som]="Initial soil organic matter"; + DALECmodel->PARS_META.ABBREVIATION[P.i_som]="i_som"; + DALECmodel->PARS_META.UNITS[P.i_som]="gC/m2"; + DALECmodel->PARS_META.DESCRIPTION[P.i_som]="Size of soil organic matter C pool at time step 1"; + + DALECmodel->PARS_META.NAME[P.retention]="Retention parameter"; + DALECmodel->PARS_META.ABBREVIATION[P.retention]="retention"; + //DALECmodel->PARS_META.UNITS[P.retention]=""; + DALECmodel->PARS_META.DESCRIPTION[P.retention]="Retention parameter (b)"; + + DALECmodel->PARS_META.NAME[P.i_LY1_SM]="LY1 SM at t0"; + DALECmodel->PARS_META.ABBREVIATION[P.i_LY1_SM]="i_LY1_SM"; + //DALECmodel->PARS_META.UNITS[P.i_LY1_SM]=""; + DALECmodel->PARS_META.DESCRIPTION[P.i_LY1_SM]="LY1 SM at t0"; + + DALECmodel->PARS_META.NAME[P.cf_foliar]="Foliar biomass CF"; + DALECmodel->PARS_META.ABBREVIATION[P.cf_foliar]="cf_foliar"; + DALECmodel->PARS_META.UNITS[P.cf_foliar]="%"; + DALECmodel->PARS_META.DESCRIPTION[P.cf_foliar]="Foliar biomass combustion factor"; + + DALECmodel->PARS_META.NAME[P.cf_ligneous]="Ligneous biomass CF"; + DALECmodel->PARS_META.ABBREVIATION[P.cf_ligneous]="cf_ligneous"; + DALECmodel->PARS_META.UNITS[P.cf_ligneous]="%"; + DALECmodel->PARS_META.DESCRIPTION[P.cf_ligneous]="Ligneous biomass combustion factor"; + + DALECmodel->PARS_META.NAME[P.cf_DOM]="DOM CF"; + DALECmodel->PARS_META.ABBREVIATION[P.cf_DOM]="cf_DOM"; + DALECmodel->PARS_META.UNITS[P.cf_DOM]="%"; + DALECmodel->PARS_META.DESCRIPTION[P.cf_DOM]="Dead organic matter combustion factor"; + + DALECmodel->PARS_META.NAME[P.resilience]="Resilience factor"; + DALECmodel->PARS_META.ABBREVIATION[P.resilience]="resilience"; + DALECmodel->PARS_META.UNITS[P.resilience]="%"; + DALECmodel->PARS_META.DESCRIPTION[P.resilience]="Resilience factor (since transfer to litter is represented as (1-pars[30]))"; + + DALECmodel->PARS_META.NAME[P.hydr_cond]="Saturated hydraulic conductivity"; + DALECmodel->PARS_META.ABBREVIATION[P.hydr_cond]="hydr_cond"; + DALECmodel->PARS_META.UNITS[P.hydr_cond]="m/s"; + DALECmodel->PARS_META.DESCRIPTION[P.hydr_cond]="Saturated hydraulic conductivity"; + + DALECmodel->PARS_META.NAME[P.max_infil]="Maximum infiltration"; + DALECmodel->PARS_META.ABBREVIATION[P.max_infil]="max_infil"; + DALECmodel->PARS_META.UNITS[P.max_infil]="mm/day"; + DALECmodel->PARS_META.DESCRIPTION[P.max_infil]="Maximum infiltration"; + + DALECmodel->PARS_META.NAME[P.i_LY3_SM]="LY3 SM at t=0"; + DALECmodel->PARS_META.ABBREVIATION[P.i_LY3_SM]="i_LY3_SM"; + //DALECmodel->PARS_META.UNITS[P.i_LY3_SM]=""; + DALECmodel->PARS_META.DESCRIPTION[P.i_LY3_SM]="LY3 SM at t=0"; + + DALECmodel->PARS_META.NAME[P.LY1_por]="LY1 porosity"; + DALECmodel->PARS_META.ABBREVIATION[P.LY1_por]="LY1_por"; + //DALECmodel->PARS_META.UNITS[P.LY1_por]=""; + DALECmodel->PARS_META.DESCRIPTION[P.LY1_por]="LY1 porosity"; + + DALECmodel->PARS_META.NAME[P.LY2_por]="LY2 porosity"; + DALECmodel->PARS_META.ABBREVIATION[P.LY2_por]="LY2_por"; + //DALECmodel->PARS_META.UNITS[P.LY2_por]=""; + DALECmodel->PARS_META.DESCRIPTION[P.LY2_por]="LY2 porosity"; + + DALECmodel->PARS_META.NAME[P.LY3_por]="LY3 porosity"; + DALECmodel->PARS_META.ABBREVIATION[P.LY3_por]="LY3_por"; + //DALECmodel->PARS_META.UNITS[P.LY3_por]=""; + DALECmodel->PARS_META.DESCRIPTION[P.LY3_por]="LY3 porosity"; + + DALECmodel->PARS_META.NAME[P.field_cap]="Field capacity (negative) potential"; + DALECmodel->PARS_META.ABBREVIATION[P.field_cap]="field_cap"; + DALECmodel->PARS_META.UNITS[P.field_cap]="-Mpa"; + DALECmodel->PARS_META.DESCRIPTION[P.field_cap]="Field capacity (negative) potential"; + + DALECmodel->PARS_META.NAME[P.LY1_z]="LY1 depth"; + DALECmodel->PARS_META.ABBREVIATION[P.LY1_z]="LY1_z"; + DALECmodel->PARS_META.UNITS[P.LY1_z]="m"; + DALECmodel->PARS_META.DESCRIPTION[P.LY1_z]="LY1 depth"; + + DALECmodel->PARS_META.NAME[P.LY2_z]="LY2 depth"; + DALECmodel->PARS_META.ABBREVIATION[P.LY2_z]="LY2_z"; + DALECmodel->PARS_META.UNITS[P.LY2_z]="m"; + DALECmodel->PARS_META.DESCRIPTION[P.LY2_z]="LY2 depth"; + + DALECmodel->PARS_META.NAME[P.LY3_z]="LY3 depth"; + DALECmodel->PARS_META.ABBREVIATION[P.LY3_z]="LY3_z"; + DALECmodel->PARS_META.UNITS[P.LY3_z]="m"; + DALECmodel->PARS_META.DESCRIPTION[P.LY3_z]="LY3 depth"; + + DALECmodel->PARS_META.NAME[P.LY1_vhc]="LY1 volumetric heat capacity"; + DALECmodel->PARS_META.ABBREVIATION[P.LY1_vhc]="LY1_vhc"; + //DALECmodel->PARS_META.UNITS[P.LY1_vhc]=""; + DALECmodel->PARS_META.DESCRIPTION[P.LY1_vhc]="LY1 the change in heat content of a unit bulk volume of soil per unit change in temperature (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)"; + + DALECmodel->PARS_META.NAME[P.LY2_vhc]="LY2 volumetric heat capacity"; + DALECmodel->PARS_META.ABBREVIATION[P.LY2_vhc]="LY2_vhc"; + //DALECmodel->PARS_META.UNITS[P.LY2_vhc]=""; + DALECmodel->PARS_META.DESCRIPTION[P.LY2_vhc]="LY2 the change in heat content of a unit bulk volume of soil per unit change in temperature (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)"; + + DALECmodel->PARS_META.NAME[P.LY3_vhc]="LY3 volumetric heat capacity"; + DALECmodel->PARS_META.ABBREVIATION[P.LY3_vhc]="LY3_vhc"; + //DALECmodel->PARS_META.UNITS[P.LY3_vhc]=""; + DALECmodel->PARS_META.DESCRIPTION[P.LY3_vhc]="LY3 the change in heat content of a unit bulk volume of soil per unit change in temperature (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)"; + + DALECmodel->PARS_META.NAME[P.Q_excess]="Runoff excess"; + DALECmodel->PARS_META.ABBREVIATION[P.Q_excess]="Q_excess"; + //DALECmodel->PARS_META.UNITS[P.Q_excess]=""; + DALECmodel->PARS_META.DESCRIPTION[P.Q_excess]="Runoff excess"; + + //Pool info {Eren Bilir added this section 9/15/2023} + + DALECmodel->POOLS_META.NAME[S.C_lab]="Labile carbon pool"; + DALECmodel->POOLS_META.ABBREVIATION[S.C_lab]="C_lab"; + DALECmodel->POOLS_META.UNITS[S.C_lab]="gC/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.C_lab]="Stored non-structural carbohydrate (NSC) pool; also includes any structural C that is not wood, root, or leaf, e.g. flowers/fruit/seeds"; + + DALECmodel->POOLS_META.NAME[S.C_fol]="Foliar carbon pool"; + DALECmodel->POOLS_META.ABBREVIATION[S.C_fol]="C_fol"; + DALECmodel->POOLS_META.UNITS[S.C_fol]="gC/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.C_fol]="Leaf carbon pool"; + + DALECmodel->POOLS_META.NAME[S.C_roo]="Fine root carbon pool"; + DALECmodel->POOLS_META.ABBREVIATION[S.C_roo]="C_roo"; + DALECmodel->POOLS_META.UNITS[S.C_roo]="gC/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.C_roo]="Fine root carbon pool; does not include woody root biomass"; + + DALECmodel->POOLS_META.NAME[S.C_woo]="Wood/ligneous carbon pool"; + DALECmodel->POOLS_META.ABBREVIATION[S.C_woo]="C_woo"; + DALECmodel->POOLS_META.UNITS[S.C_woo]="gC/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.C_woo]="Wood/ligneous carbon pool; includes woody root biomass"; + + DALECmodel->POOLS_META.NAME[S.C_cwd]="Coarse woody debris carbon pool"; + DALECmodel->POOLS_META.ABBREVIATION[S.C_cwd]="C_cwd"; + DALECmodel->POOLS_META.UNITS[S.C_cwd]="gC/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.C_cwd]="Coarse woody debris carbon pool"; + + DALECmodel->POOLS_META.NAME[S.C_lit]="Litter carbon pool"; + DALECmodel->POOLS_META.ABBREVIATION[S.C_lit]="C_lit"; + DALECmodel->POOLS_META.UNITS[S.C_lit]="gC/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.C_lit]="Litter carbon pool"; + + DALECmodel->POOLS_META.NAME[S.C_som]="soil organic matter carbon pool"; + DALECmodel->POOLS_META.ABBREVIATION[S.C_som]="C_som"; + DALECmodel->POOLS_META.UNITS[S.C_som]="gC/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.C_som]="soil organic matter carbon pool"; + + DALECmodel->POOLS_META.NAME[S.H2O_LY1]="Layer 1 water content"; + DALECmodel->POOLS_META.ABBREVIATION[S.H2O_LY1]="H2O_LY1"; + DALECmodel->POOLS_META.UNITS[S.H2O_LY1]="(kg H2O)/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.H2O_LY1]="Bulk water content of the first belowground layer. This layer hosts shallow vegetation roots and supplies water for transpiration, evaporation, runoff, and infiltration to LY2."; + + DALECmodel->POOLS_META.NAME[S.H2O_LY2]="Layer 2 water content"; + DALECmodel->POOLS_META.ABBREVIATION[S.H2O_LY2]="H2O_LY2"; + DALECmodel->POOLS_META.UNITS[S.H2O_LY2]="(kg H2O)/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.H2O_LY2]="Bulk water content of the second belowground layer. This layer hosts deep vegetation roots and supplies water for transpiration), runoff, and infiltration to LY3."; + + DALECmodel->POOLS_META.NAME[S.H2O_LY3]="Layer 3 water content"; + DALECmodel->POOLS_META.ABBREVIATION[S.H2O_LY3]="H2O_LY3"; + DALECmodel->POOLS_META.UNITS[S.H2O_LY3]="(kg H2O)/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.H2O_LY3]="Bulk water content of the third belowground layer. This layer is inaccessible to vegetation roots, and supplies water for runoff only."; + + DALECmodel->POOLS_META.NAME[S.H2O_SWE]="Snow Water Equivalent"; + DALECmodel->POOLS_META.ABBREVIATION[S.H2O_SWE]="H2O_SWE"; + DALECmodel->POOLS_META.UNITS[S.H2O_SWE]="(kg H2O)/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.H2O_SWE]="Bulk water content of the snow pack layer. "; + + DALECmodel->POOLS_META.NAME[S.E_LY1]="Layer 1 energy content"; + DALECmodel->POOLS_META.ABBREVIATION[S.E_LY1]="E_LY1"; + DALECmodel->POOLS_META.UNITS[S.E_LY1]="J/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.E_LY1]="Energy content of the first belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.E_LY2]="Layer 2 energy content"; + DALECmodel->POOLS_META.ABBREVIATION[S.E_LY2]="E_LY2"; + DALECmodel->POOLS_META.UNITS[S.E_LY2]="J/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.E_LY2]="Energy content of the second belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.E_LY3]="Layer 3 energy content"; + DALECmodel->POOLS_META.ABBREVIATION[S.E_LY3]="E_LY3"; + DALECmodel->POOLS_META.UNITS[S.E_LY3]="J/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.E_LY3]="Energy content of the third belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.D_LAI]="Leaf Area Index"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_LAI]="D_LAI"; + DALECmodel->POOLS_META.UNITS[S.D_LAI]="m2/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_LAI]="Leaf Area Index. \"D_\" flag denotes a diagnostic variable, which is stored for the user but is not passed to downstream model calculations."; + + DALECmodel->POOLS_META.NAME[S.D_SCF]="Snow Covered Fraction"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_SCF]="D_SCF"; + DALECmodel->POOLS_META.UNITS[S.D_SCF]="m2/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_SCF]="Fraction of non-vegetation-covered land surface (gap fraction) that is covered by a layer of snow. "; + + DALECmodel->POOLS_META.NAME[S.D_TEMP_LY1]="Layer 1 temperature"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_TEMP_LY1]="D_TEMP_LY1"; + DALECmodel->POOLS_META.UNITS[S.D_TEMP_LY1]="K"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_TEMP_LY1]="Temperature (K) of the first belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.D_TEMP_LY2]="Layer 2 temperature"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_TEMP_LY2]="D_TEMP_LY2"; + DALECmodel->POOLS_META.UNITS[S.D_TEMP_LY2]="K"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_TEMP_LY2]="Temperature (K) of the second belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.D_TEMP_LY3]="Layer 3 temperature"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_TEMP_LY3]="D_TEMP_LY3"; + DALECmodel->POOLS_META.UNITS[S.D_TEMP_LY3]="K"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_TEMP_LY3]="Temperature (K) of the third belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.D_LF_LY1]="Layer 1 Liquid Fraction"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_LF_LY1]="D_LF_LY1"; + DALECmodel->POOLS_META.UNITS[S.D_LF_LY1]="(kg H20 liquid water)/(kg H20 total water)"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_LF_LY1]="Fraction of the bulk water content existing in liquid state in the first belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.D_LF_LY2]="Layer 2 Liquid Fraction"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_LF_LY2]="D_LF_LY2"; + DALECmodel->POOLS_META.UNITS[S.D_LF_LY2]="(kg H20 liquid water)/(kg H20 total water)"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_LF_LY2]="Fraction of the bulk water content existing in liquid state in the second belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.D_LF_LY3]="Layer 3 Liquid Fraction"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_LF_LY3]="D_LF_LY3"; + DALECmodel->POOLS_META.UNITS[S.D_LF_LY3]="(kg H20 liquid water)/(kg H20 total water)"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_LF_LY3]="Fraction of the bulk water content existing in liquid state in the third belowground layer. "; + + DALECmodel->POOLS_META.NAME[S.D_SM_LY1]="Layer 1 soil moisture"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_SM_LY1]="D_SM_LY1"; + DALECmodel->POOLS_META.UNITS[S.D_SM_LY1]="((m3 H20)/(m3 total volume of pore space in soil volume)"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_SM_LY1]="Volumetric water content relative to available pore space in the first belowground layer."; + + DALECmodel->POOLS_META.NAME[S.D_SM_LY2]="Layer 2 soil moisture"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_SM_LY2]="D_SM_LY2"; + DALECmodel->POOLS_META.UNITS[S.D_SM_LY2]="((m3 H20)/(m3 total volume of pore space in soil volume)"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_SM_LY2]="Volumetric water content relative to available pore space in the second belowground layer."; + + DALECmodel->POOLS_META.NAME[S.D_SM_LY3]="Layer 3 soil moisture"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_SM_LY3]="D_SM_LY3"; + DALECmodel->POOLS_META.UNITS[S.D_SM_LY3]="((m3 H20)/(m3 total volume of pore space in soil volume)"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_SM_LY3]="Volumetric water content relative to available pore space in the third belowground layer."; + + DALECmodel->POOLS_META.NAME[S.D_PSI_LY1]="Layer 1 water potential"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_PSI_LY1]="D_PSI_LY1"; + DALECmodel->POOLS_META.UNITS[S.D_PSI_LY1]="MPa"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_PSI_LY1]="Water potential of the first belowground layer"; + + DALECmodel->POOLS_META.NAME[S.D_PSI_LY2]="Layer 2 water potential"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_PSI_LY2]="D_PSI_LY2"; + DALECmodel->POOLS_META.UNITS[S.D_PSI_LY2]="MPa"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_PSI_LY2]="Water potential of the second belowground layer"; + + DALECmodel->POOLS_META.NAME[S.D_PSI_LY3]="Layer 3 water potential"; + DALECmodel->POOLS_META.ABBREVIATION[S.D_PSI_LY3]="D_PSI_LY3"; + DALECmodel->POOLS_META.UNITS[S.D_PSI_LY3]="MPa"; + DALECmodel->POOLS_META.DESCRIPTION[S.D_PSI_LY3]="Water potential of the third belowground layer"; + + DALECmodel->POOLS_META.NAME[S.M_LAI_MAX]="Past Maximum Leaf Area Index in vegetation memory"; + DALECmodel->POOLS_META.ABBREVIATION[S.M_LAI_MAX]="M_LAI_MAX"; + DALECmodel->POOLS_META.UNITS[S.M_LAI_MAX]="m2/m2"; + DALECmodel->POOLS_META.DESCRIPTION[S.M_LAI_MAX]="Exponentially declining term encoding vegetation \"memory\" of past water/structural limitations for LAI, to capture lagged effects of past stress."; + + DALECmodel->POOLS_META.NAME[S.M_LAI_TEMP]="Past Leaf temperature in vegetation memory"; + DALECmodel->POOLS_META.ABBREVIATION[S.M_LAI_TEMP]="M_LAI_TEMP"; + DALECmodel->POOLS_META.UNITS[S.M_LAI_TEMP]="K"; + DALECmodel->POOLS_META.DESCRIPTION[S.M_LAI_TEMP]="Exponentially declining term encoding vegetation \"memory\" of past temperature limitations for LAI, to capture lagged effects of past stress."; + +//EDC info + /* + DALECmodel->EDC_META.NAME[E.twood]="Turnover rate of wood"; + DALECmodel->EDC_META.ABBREVIATION[E.twood]="twood"; + DALECmodel->EDC_META.UNITS[E.twood]="gC/m2/day"; + DALECmodel->EDC_META.DESCRIPTION[E.twood]="Includes maintenance respiration and growth respiration"; + + /*/ + + + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/PARS_INFO_1100.c === + +#pragma once +#include "DALEC_1100_INDICES.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + + +int PARS_INFO_1100(DALEC * DALECmodel){ + +struct DALEC_1100_PARAMETERS P=DALEC_1100_PARAMETERS; + + +DALECmodel->PARS_INFO.parmin= calloc(DALECmodel->nopars, sizeof(double)); +DALECmodel->PARS_INFO.parmax= calloc(DALECmodel->nopars, sizeof(double)); +//Abbreviate + +double * parmin = DALECmodel->PARS_INFO.parmin; +double * parmax =DALECmodel->PARS_INFO.parmax; +/*Litter decomposition rate*/ +parmin[P.tr_lit2som]=0.01; +parmax[P.tr_lit2som]=0.99; + +/*CWD decomposition rate*/ +parmin[P.tr_cwd2som]=0.01; +parmax[P.tr_cwd2som]=0.99; + +/*Autotrophic maintenance respiration coefficient for roots - turnover rate at 25oC (d-1)*/ +parmin[P.rauto_mr_r]=0.0001; +parmax[P.rauto_mr_r]=0.01; + +/*Autotrophic maintenance respiration coefficient for wood - turnover rate at 25oC (d-1)*/ +parmin[P.rauto_mr_w]=0.000001; +parmax[P.rauto_mr_w]=0.005; + +/*Autotrophic maintenance respiration Q10 parameter*/ +parmin[P.rauto_mr_q10]=1.0; +parmax[P.rauto_mr_q10]=5.0; + +/*Dark respiration Q10 parameter*/ +parmin[P.rauto_mrd_q10]=1.0; +parmax[P.rauto_mrd_q10]=5.0; + +/*Growth yield (g C appearing in new biomass per g C used for growth; "growth yield" in Cannell and Thornley 2000)*/ +parmin[P.rauto_gr]=0.60; +parmax[P.rauto_gr]=0.95; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.01; + +/*TOR labile C*/ //Setting to be equal to roots as first guess (10.21.23) +parmin[P.t_lab]=0.0001; +parmax[P.t_lab]=0.01; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*Inverse of undisturbed, non-phenological leaf longevity, + i.e. background turnover (days-1)*/ +parmin[P.t_foliar]=0.00068; /*around 4 yrs*/ +parmax[P.t_foliar]=0.0334; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.1; + +/*TOR CWD*/ +parmin[P.t_cwd]=0.00005; +parmax[P.t_cwd]=0.05; + +/*TOR SOM*/ +parmin[P.t_som]=0.0000001; +parmax[P.t_som]=0.01; + +/*\Q10 = 1.2-2.0*/ +parmin[P.Q10rhco2]=1; +parmax[P.Q10rhco2]=5.0; + +/*LMCA*; Kattge et al. 2011*;*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=100000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C CWD*/ +parmin[P.i_cwd]=1.0; +parmax[P.i_cwd]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=4000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*Retention parameter (b)*/ +parmin[P.retention]=1.5; +parmax[P.retention]=10; + +/*"LY1 SM at t0"*/ +parmin[P.i_LY1_SM]=0.01; +parmax[P.i_LY1_SM]=1; + +/*"LY2 SM at t0"*/ +parmin[P.i_LY2_SM]=0.01; +parmax[P.i_LY2_SM]=1; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +parmin[P.hydr_cond]=1e-9; +parmax[P.hydr_cond]=1e-4; + +/*Maximum infiltration (mm/day)*/ +parmin[P.max_infil]=1; +parmax[P.max_infil]=100; + +/*LY3 SM at t=0*/ +parmin[P.i_LY3_SM]=0.01; +parmax[P.i_LY3_SM]=1; + +/*LY1 porosity*/ +parmin[P.LY1_por]=0.2; +parmax[P.LY1_por]=0.98; + +/*LY2 porosity*/ +parmin[P.LY2_por]=0.2; +parmax[P.LY2_por]=0.98; + +/*LY3 porosity*/ +parmin[P.LY3_por]=0.2; +parmax[P.LY3_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +parmin[P.field_cap]=0.01; +parmax[P.field_cap]=0.1; + +/*LY1 depth (m)*/ +parmin[P.LY1_z]=0.01; +parmax[P.LY1_z]=1; + +/*LY2 depth (m)*/ +parmin[P.LY2_z]=0.01; +parmax[P.LY2_z]=20; + +/*LY3 depth (m)*/ +parmin[P.LY3_z]=0.01; +parmax[P.LY3_z]=100; + +/*LY1 volumetric heat capacity (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)*/ +parmin[P.LY1_vhc]=1.3e6; +parmax[P.LY1_vhc]=3e6; + +/*LY2 volumetric heat capacity (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)*/ +parmin[P.LY2_vhc]=1.3e6; +parmax[P.LY2_vhc]=3e6; + +/*LY3 volumetric heat capacity (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)*/ +parmin[P.LY3_vhc]=1.3e6; +parmax[P.LY3_vhc]=3e6; + +/*Runoff excess*/ +parmin[P.Q_excess]=0.01; +parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +parmin[P.Med_g1]=1.79; +parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +parmin[P.Vcmax25]=1; +parmax[P.Vcmax25]=150; + +/*Tminmin scaling factor*/ +parmin[P.Tminmin]=258.15; +parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +parmin[P.Tminmax]=273.15; +parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance (m/s)*/ +parmin[P.ga]=0.001; +parmax[P.ga]=10.0; + +/*Tupp*/ +parmin[P.Tupp]=249.15; // 299.15-50 +parmax[P.Tupp]=318.15; + +/*Tdown*/ +parmin[P.Tdown]=213.15; // 263.15-50 +parmax[P.Tdown]=286.15; + +/*Clumping index*/ +parmin[P.clumping]=0.35; +parmax[P.clumping]=1.0; + +/*PAR reflectance*/ +parmin[P.leaf_refl_par]=0.05; +parmax[P.leaf_refl_par]=0.5; + +/*NIR reflectance*/ +parmin[P.leaf_refl_nir]=0.3; +parmax[P.leaf_refl_nir]=0.7; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +parmin[P.i_SWE]=0.000001; +parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +parmin[P.min_melt]=263.15; +parmax[P.min_melt]=283.15; + +/*sn2: slope*/ +parmin[P.melt_slope]=0.00001; +parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar; SCF = SWE/(SWE +SWEcritical_par) */ +parmin[P.scf_scalar]=10; +parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (LY1/LY1_fs)\n jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +parmin[P.S_fv]=1; +parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +parmin[P.thetas_opt]=0.2; +parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +parmin[P.fwc]=0.01; +parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +parmin[P.r_ch4]=0.001; +parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +parmin[P.Q10ch4]=1.0; +parmax[P.Q10ch4]=5.0; + +/* maxPevap in mm/day*/ +parmin[P.maxPevap]=0.01; +parmax[P.maxPevap]=100; + +/*Mean temperature at leaf onset (T_phi) (degrees kelvin)*/ +parmin[P.T_phi]=268.15; +parmax[P.T_phi]=323.15; + +/*Spatial range of mean temperature at leaf onset (T_r) (degrees C or degrees kelvin)*/ +parmin[P.T_range]=0.1; +parmax[P.T_range]=10.0; + +/*LAI linear growth constant (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.plgr]=0.001; +parmax[P.plgr]=0.5; + +/*Inverse of leaf longevity during senescence period (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.k_leaf]=0.001; +parmax[P.k_leaf]=0.5; + +/*Intrinsic maximum LAI (m^2 m^-2)*/ +parmin[P.lambda_max]=0.1; +parmax[P.lambda_max]=10.0; + +/*Target survival time for LAI under water-deficit conditions (days; or same unit as ET and LY1)*/ +parmin[P.tau_W]=0.1; +parmax[P.tau_W]=300; + +/*Mean daylength at leaf shedding (t_c; in units of hours sunlight per day)*/ +parmin[P.time_c]=2; +parmax[P.time_c]=22; + +/*Spatial range of mean daylength at leaf shedding (t_r)*/ +parmin[P.time_r]=0.1; +parmax[P.time_r]=6.0; + +/*initialization of temperature memory at t=0 (in absolute temperature units)*/ +parmin[P.init_T_mem]=268.14; +parmax[P.init_T_mem]=323.15; + +/*initialization of water/structural memory (fractional value of intrinsic maximum LAI)*/ +parmin[P.init_LAIW_mem]=0.01; +parmax[P.init_LAIW_mem]=1; + + + + +/*LY1 energy per mm H2O (~ Energy in 1mm H2O @ -50C to 1mm H2O@ +50C)*/ +parmin[P.i_LY1_E]=4.67e+05; +parmax[P.i_LY1_E]=1.11e+06; + +/*LY2 energy per mm H2O(~ Energy in 1mm H2O @ -50C to 1mm H2O@ +50C)*/ +parmin[P.i_LY2_E]=4.67e+05; +parmax[P.i_LY2_E]=1.11e+06; + +/*LY3 energy per mm H2O (~ Energy in 1mm H2O @ -50C to 1mm H2O@ +50C)*/ +parmin[P.i_LY3_E]=4.67e+05; +parmax[P.i_LY3_E]=1.11e+06; + +/*PSI 50: water potential when soil-plant continuum is at 50% hydraulic conductivity (-MPa) due to stomatal closure*/ +parmin[P.psi_50]=0.1; +parmax[P.psi_50]=30; + +/*PSI 50 HMF: water potential triggering 50% biomass mortality due to cavitation(-MPa)*/ +parmin[P.psi_50HMF]=0.1; +parmax[P.psi_50HMF]=30; + +/*Beta function normalized logistic growth rate */ +parmin[P.beta_lgr]=4.1; +parmax[P.beta_lgr]=50; + +/*HMFBeta function normalized logistic growth rate */ +parmin[P.beta_lgrHMF]=4.1; +parmax[P.beta_lgrHMF]=50; + +/*Ratio of carbon allocation to root per target foliar pool size (gC/gC)*/ +parmin[P.phi_RL]=0.0001; +parmax[P.phi_RL]=5.; + + +/*Ratio of carbon allocation to wood per target foliar pool size (gC/gC)*/ +parmin[P.phi_WL]=0.0001; +parmax[P.phi_WL]=50.; + + +/*Deep thermal conductivity in W/m/K */ +parmin[P.thermal_cond]=0.3; +parmax[P.thermal_cond]=2; + + +/*Surface soil thermal conductivity in W/m/K */ +parmin[P.thermal_cond_surf]=0.3; +parmax[P.thermal_cond_surf]=2; + + +/*Surface soil thermal conductivity in W/m/K */ +parmin[P.q10canopy]=1; +parmax[P.q10canopy]=5; + + /*Surface soil thermal conductivity in W/m/K */ +parmin[P.canopyRdsf]=0.005; +parmax[P.canopyRdsf]=0.025; + + /*Sublimation rate: mm/day/SCF/kPha/(MJ/m2/d) Biggest = 1/0.5/2/2; Smallest = 1/1/10/10/*/ +parmin[P.sublimation_rate]=0.001; +parmax[P.sublimation_rate]=10; + +/*Fraction of LY2 to LY1 root biomass*/ +parmin[P.root_frac]=0.001; +parmax[P.root_frac]=1; + +return 0; + +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/EDC2_1100.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1100(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1100_PARAMETERS P=DALEC_1100_PARAMETERS; +struct DALEC_1100_FLUXES F=DALEC_1100_FLUXES; +struct DALEC_1100_POOLS S=DALEC_1100_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=10;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +//double EQF=EDCD->EQF; +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +if (Fin[n] > 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14 (No longer applicable)*/ +//EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_cwd,P.i_lit,P.i_som,P.i_PAW,P.i_PUW,P.i_SWE}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "DALEC_1100_INDICES.c" +#include "PARS_INFO_1100.c" +#include "DALEC_1100_NC_INFO.c" + +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../DALEC_ALL/LIU_AN_ET_REFACTOR.c" +#include "../DALEC_ALL/CH4_MODULES/HET_RESP_RATES_JCR.c" +#include "../DALEC_ALL/KNORR_ALLOCATION.c" +#include "../DALEC_ALL/SOIL_TEMP_AND_LIQUID_FRAC.c" +#include "../DALEC_ALL/INITIALIZE_INTERNAL_SOIL_ENERGY.c" +#include "../DALEC_ALL/INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS.c" +#include "../DALEC_ALL/ALLOC_AND_AUTO_RESP_FLUXES.c" +#include "../DALEC_ALL/THERMAL_CONDUCTIVITY.c" + +typedef struct DALEC_1100_DATA_STRUCT{ +double * VegK; +double example_const; +}DALEC_1100_DATA_STRUCT; + + +int PREDERIVE_DALEC_1100_DATA(DALEC * DALECmodel, DATA * DATA){ + + //Step 1. Define function here +static DALEC_1100_DATA_STRUCT DALEC_1100_DATA; +//Step 2. Populate with any datasets that will be used repeatedly. + + //******VegK calculcation******** + + double * DOY=DATA->ncdf_data.DOY.values; + double LAT = DATA->ncdf_data.LAT; + int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + double pi=DGCM_PI; + +//Declare VegK + double * VegK = calloc(N_timesteps, sizeof(double)); + +int n; + +for (n=0; n < N_timesteps; n++){ + +/*Calculate light extinction coefficient for each timestep*/ +double B = (DOY[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +double LST = (int) (DOY[n]*24*60) % (24*60); +LST=0.5*24*60; +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*LAT)*sin(pi/180*DA)+cos(pi/180*LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +double zenith_angle = fmin(89,90-alpha); + +//printf("SZA local = %2.2f, SZA global = %2.2f, SZA diff = %2.2f\n", zenith_angle,DATA.ncdf_data.SZA.values,DATA.ncdf_data.SZA.values - zenith_angle); +//double LAD = 1.0; //leaf angle distribution +//double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 + +double LAD = 0.5; //leaf angle distribution// optimize leaf angle distribution. + + VegK[n] = LAD / cos(zenith_angle/180*pi); + +} + +//Store data in DALEC_1100_DATA + DALEC_1100_DATA.VegK=VegK; + + + //Store for later use + DALECmodel->MODEL_DATA=&DALEC_1100_DATA; + +return 0; +} + + +//Returns structure with sources and sinks, matches number of fluxes +int DALEC_1100_FLUX_SOURCES_SINKS(DALEC * DALECmodel){ + + + struct DALEC_1100_FLUXES F=DALEC_1100_FLUXES; + struct DALEC_1100_POOLS S=DALEC_1100_POOLS; + + // /Step 1. Declare & initialize + DALEC_FLUX_SOURCE_SINK_MATRIX FIOMATRIX; + // external source or pool sink, or not conserved quantity + //Default = -1 + + FIOMATRIX.SOURCE=calloc(DALECmodel->nofluxes, sizeof(int)); + FIOMATRIX.SINK=calloc(DALECmodel->nofluxes, sizeof(int)); + + + int n; + for (n=0;nnofluxes; n++){FIOMATRIX.SOURCE[n]=-1;FIOMATRIX.SINK[n]=-1;} + + + //Step 2. Define + + + // C_lab + FIOMATRIX.SINK[F.gpp]=S.C_lab; + FIOMATRIX.SOURCE[F.resp_auto_maint]=S.C_lab; + FIOMATRIX.SOURCE[F.Rd]=S.C_lab; + FIOMATRIX.SOURCE[F.foliar_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.root_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.wood_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.resp_auto_growth]=S.C_lab; + FIOMATRIX.SOURCE[F.f_lab]=S.C_lab; + FIOMATRIX.SOURCE[F.lab2lit]=S.C_lab; + FIOMATRIX.SOURCE[F.labyield2lit]=S.C_lab; + FIOMATRIX.SOURCE[F.fx_lab2lit]=S.C_lab; + FIOMATRIX.SOURCE[F.dist_lab]=S.C_lab; + + + // C_fol + FIOMATRIX.SINK[F.foliar_prod]=S.C_fol; + FIOMATRIX.SOURCE[F.fol2lit]=S.C_fol; + FIOMATRIX.SOURCE[F.ph_fol2lit]=S.C_fol; + FIOMATRIX.SOURCE[F.folyield2lit]=S.C_fol; + FIOMATRIX.SOURCE[F.f_fol]=S.C_fol; + FIOMATRIX.SOURCE[F.fx_fol2lit]=S.C_fol; + FIOMATRIX.SOURCE[F.dist_fol]=S.C_fol; + + // C_roo + FIOMATRIX.SINK[F.root_prod]=S.C_roo; + FIOMATRIX.SOURCE[F.roo2lit]=S.C_roo; + FIOMATRIX.SOURCE[F.rooyield2lit]=S.C_roo; + FIOMATRIX.SOURCE[F.f_roo]=S.C_roo; + FIOMATRIX.SOURCE[F.fx_roo2lit]=S.C_roo; + FIOMATRIX.SOURCE[F.dist_roo]=S.C_roo; + + // C_woo + FIOMATRIX.SINK[F.wood_prod]=S.C_woo; + FIOMATRIX.SOURCE[F.woo2cwd]=S.C_woo; + FIOMATRIX.SOURCE[F.wooyield2cwd]=S.C_woo; + FIOMATRIX.SOURCE[F.f_woo]=S.C_woo; + FIOMATRIX.SOURCE[F.fx_woo2cwd]=S.C_woo; + FIOMATRIX.SOURCE[F.dist_woo]=S.C_woo; + + // C_lit + FIOMATRIX.SINK[F.labyield2lit]=S.C_lit; + FIOMATRIX.SINK[F.lab2lit]=S.C_lit; + FIOMATRIX.SINK[F.fx_lab2lit]=S.C_lit; + FIOMATRIX.SINK[F.ph_fol2lit]=S.C_lit; + FIOMATRIX.SINK[F.folyield2lit]=S.C_lit; + FIOMATRIX.SINK[F.fol2lit]=S.C_lit; + FIOMATRIX.SINK[F.fx_fol2lit]=S.C_lit; + FIOMATRIX.SINK[F.rooyield2lit]=S.C_lit; + FIOMATRIX.SINK[F.roo2lit]=S.C_lit; + FIOMATRIX.SINK[F.fx_roo2lit]=S.C_lit; + FIOMATRIX.SOURCE[F.ae_rh_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.an_rh_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.f_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.lit2som]=S.C_lit; + FIOMATRIX.SOURCE[F.fx_lit2som]=S.C_lit; + + // C_cwd + FIOMATRIX.SINK[F.wooyield2cwd]=S.C_cwd; + FIOMATRIX.SINK[F.woo2cwd]=S.C_cwd; + FIOMATRIX.SINK[F.fx_woo2cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.ae_rh_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.an_rh_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.f_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.cwd2som]=S.C_cwd; + FIOMATRIX.SOURCE[F.fx_cwd2som]=S.C_cwd; + + // C_som + FIOMATRIX.SINK[F.cwd2som]=S.C_som; + FIOMATRIX.SINK[F.fx_cwd2som]=S.C_som; + FIOMATRIX.SINK[F.lit2som]=S.C_som; + FIOMATRIX.SINK[F.fx_lit2som]=S.C_som; + FIOMATRIX.SOURCE[F.ae_rh_som]=S.C_som; + FIOMATRIX.SOURCE[F.an_rh_som]=S.C_som; + FIOMATRIX.SOURCE[F.f_som]=S.C_som; + + // H2O_SWE + FIOMATRIX.SINK[F.snowfall]=S.H2O_SWE; + FIOMATRIX.SOURCE[F.melt]=S.H2O_SWE; + FIOMATRIX.SOURCE[F.sublimation]=S.H2O_SWE; + + // H2O_LY1 + FIOMATRIX.SINK[F.infil]=S.H2O_LY1; + FIOMATRIX.SOURCE[F.evap]=S.H2O_LY1; + FIOMATRIX.SOURCE[F.transp1]=S.H2O_LY1; + FIOMATRIX.SOURCE[F.ly1xly2]=S.H2O_LY1; + FIOMATRIX.SOURCE[F.q_ly1]=S.H2O_LY1; + + // H2O_LY2 + FIOMATRIX.SINK[F.ly1xly2]=S.H2O_LY2; + FIOMATRIX.SOURCE[F.transp2]=S.H2O_LY2; + FIOMATRIX.SOURCE[F.ly2xly3]=S.H2O_LY2; + FIOMATRIX.SOURCE[F.q_ly2]=S.H2O_LY2; + + // H2O_LY3 + FIOMATRIX.SINK[F.ly2xly3]=S.H2O_LY3; + FIOMATRIX.SOURCE[F.q_ly3]=S.H2O_LY3; + + // E_LY1 + FIOMATRIX.SINK[F.gh_in]=S.E_LY1; + FIOMATRIX.SINK[F.infil_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.evap_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.transp1_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.q_ly1_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.ly1xly2_e]=S.E_LY1; + FIOMATRIX.SOURCE[F.ly1xly2_th_e]=S.E_LY1; + + // E_LY2 + FIOMATRIX.SINK[F.ly1xly2_e]=S.E_LY2; + FIOMATRIX.SINK[F.ly1xly2_th_e]=S.E_LY2; + FIOMATRIX.SOURCE[F.transp2_e]=S.E_LY2; + FIOMATRIX.SOURCE[F.q_ly2_e]=S.E_LY2; + FIOMATRIX.SOURCE[F.ly2xly3_e]=S.E_LY2; + FIOMATRIX.SOURCE[F.ly2xly3_th_e]=S.E_LY2; + + // E_LY3 + FIOMATRIX.SINK[F.ly2xly3_e]=S.E_LY3; + FIOMATRIX.SINK[F.geological]=S.E_LY3; + FIOMATRIX.SINK[F.ly2xly3_th_e]=S.E_LY3; + FIOMATRIX.SOURCE[F.q_ly3_e]=S.E_LY3; + + + +DALECmodel->FIOMATRIX = FIOMATRIX; + + +//DALEC flux indices + +//Calculate State source sink matrix +DALEC_STATE_SOURCE_SINK_MATRIX_CONFIG(DALECmodel); +return 0; + +} + + + + + + + + + +int DALEC_1100(DATA DATA, double const *pars){ + + + + + +struct DALEC_1100_PARAMETERS P=DALEC_1100_PARAMETERS; +struct DALEC_1100_FLUXES F=DALEC_1100_FLUXES; +struct DALEC_1100_POOLS S=DALEC_1100_POOLS; + + + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *SKT=DATA.ncdf_data.SKT.values; +double *STRD=DATA.ncdf_data.STRD.values; +double *DIST=DATA.ncdf_data.DISTURBANCE_FLUX.values; +double *YIELD=DATA.ncdf_data.YIELD.values; + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +//double pi=3.1415927; +double pi=DGCM_PI; + +//PREDERIVED TERMS + + double PREDERIVED_GEO_FLUX=0.065*3600*24; /*try values from https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/93rg01249*/ + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +double one_over_deltat=1/deltat; + +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + + + +//******************INITIALIZING POOLS****************** + + /*Carbon pools: + Live: labile, foliar, root, wood, + Dead: litter, coarse woody debris, soil organic matter*/ +POOLS[S.C_lab]=pars[P.i_labile]; +POOLS[S.C_fol]=pars[P.i_foliar]; +POOLS[S.C_roo]=pars[P.i_root]; +POOLS[S.C_woo]=pars[P.i_wood]; +POOLS[S.C_cwd]=pars[P.i_cwd]; +POOLS[S.C_lit]=pars[P.i_lit]; +POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ +POOLS[S.H2O_LY1]=HYDROFUN_MOI2EWT(pars[P.i_LY1_SM],pars[P.LY1_por],pars[P.LY1_z]); //liquid + frozen state +POOLS[S.H2O_LY2]=HYDROFUN_MOI2EWT(pars[P.i_LY2_SM],pars[P.LY2_por],pars[P.LY2_z]); //liquid + frozen state +POOLS[S.H2O_LY3]=HYDROFUN_MOI2EWT(pars[P.i_LY3_SM],pars[P.LY3_por],pars[P.LY3_z]); //liquid + frozen state +POOLS[S.H2O_SWE]=pars[P.i_SWE]; + /*Energy pools*/ +POOLS[S.E_LY1]=INITIALIZE_INTERNAL_SOIL_ENERGY(pars[P.i_LY1_E], POOLS[S.H2O_LY1], pars[P.LY1_vhc], pars[P.LY1_z] ); +POOLS[S.E_LY2]=INITIALIZE_INTERNAL_SOIL_ENERGY(pars[P.i_LY2_E], POOLS[S.H2O_LY2], pars[P.LY2_vhc], pars[P.LY2_z] ); +POOLS[S.E_LY3]=INITIALIZE_INTERNAL_SOIL_ENERGY(pars[P.i_LY3_E], POOLS[S.H2O_LY3], pars[P.LY3_vhc], pars[P.LY3_z] ); + + +//******************INITIALIZING DIAGNOSTIC STATES****************** + //LAI +POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; + //snow cover fraction +if (POOLS[S.H2O_SWE]>0){ +POOLS[S.D_SCF]=POOLS[S.H2O_SWE]/(POOLS[S.H2O_SWE]+pars[P.scf_scalar]);} +else +{POOLS[S.D_SCF]=0;}; + //Diagnostic time-invariant quantities: + // Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117/100; + //LY1 capacity in mm +double LY1max=pars[P.LY1_por]*pars[P.LY1_z]*1000; + //LY2 capacity in mm +double LY2max=pars[P.LY2_por]*pars[P.LY2_z]*1000; + //LY3 capacity in mm +double LY3max=pars[P.LY3_por]*pars[P.LY3_z]*1000; + //INITIALIZING soil moisture +POOLS[S.D_SM_LY1]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY1],pars[P.LY1_por],pars[P.LY1_z]); //soil moisture LY1: liquid and frozen state +POOLS[S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY2],pars[P.LY2_por],pars[P.LY2_z]);//soil moisture LY3: liquid and frozen state +POOLS[S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3: liquid and frozen state + +//******************Declare SOIL_TEMP_AND_LIQUID_FRAC STRUCT********************* +SOIL_TEMP_AND_LIQUID_FRAC_STRUCT LY1SOILTEMP, LY2SOILTEMP, LY3SOILTEMP; + //Populate with run-specific constrants + //LY1 + LY1SOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.LY1_vhc]; ;//J/m3/K + LY1SOILTEMP.IN.depth = pars[P.LY1_z];//m + LY1SOILTEMP.IN.soil_water = POOLS[S.H2O_LY1];//mm (or kg/m2) + LY1SOILTEMP.IN.internal_energy = POOLS[S.E_LY1];//Joules + + //Pass pointer to function +SOIL_TEMP_AND_LIQUID_FRAC(&LY1SOILTEMP); //Outputs are in K + + //Store outputs +POOLS[S.D_TEMP_LY1]=LY1SOILTEMP.OUT.TEMP; //In K +POOLS[S.D_LF_LY1]=LY1SOILTEMP.OUT.LF; + + + //LY2 + LY2SOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.LY2_vhc]; ;//J/m3/K + LY2SOILTEMP.IN.depth = pars[P.LY2_z];//m + LY2SOILTEMP.IN.soil_water = POOLS[S.H2O_LY2];//mm (or kg/m2) + LY2SOILTEMP.IN.internal_energy = POOLS[S.E_LY2];//Joules + //Pass pointer to function +SOIL_TEMP_AND_LIQUID_FRAC(&LY2SOILTEMP); //Outputs are in K + + //Store outputs +POOLS[S.D_TEMP_LY2]=LY2SOILTEMP.OUT.TEMP; //In K +POOLS[S.D_LF_LY2]=LY2SOILTEMP.OUT.LF; + + //LY3 + LY3SOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.LY3_vhc]; ;//J/m3/K + LY3SOILTEMP.IN.depth = pars[P.LY3_z];//m + LY3SOILTEMP.IN.soil_water = POOLS[S.H2O_LY3];//mm (or kg/m2) + LY3SOILTEMP.IN.internal_energy = POOLS[S.E_LY3];//Joules + //Pass pointer to function +SOIL_TEMP_AND_LIQUID_FRAC(&LY3SOILTEMP);//Outputs are in K + //Store outputs +POOLS[S.D_TEMP_LY3]=LY3SOILTEMP.OUT.TEMP; //In K +POOLS[S.D_LF_LY3]=LY3SOILTEMP.OUT.LF; + + // Convert to water potential, respecting liquid state only; correcting porosity for ice-filled volume. + //Effectively this corrects MOI to (water frac)/(water + air frac) + //Min psi ensures large negative psis not resolved by model needlessly + double minpsi=-30; +POOLS[S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY1],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY1],POOLS[S.D_TEMP_LY1]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction +POOLS[S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY2],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY2],POOLS[S.D_TEMP_LY2]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction +POOLS[S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY3],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY3],POOLS[S.D_TEMP_LY3]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction + + +//******************Declare KNORR STRUCT********************* +KNORR_ALLOCATION_STRUCT KNORR; +//define time-invariant parameters + KNORR.IN.deltat=deltat; + KNORR.IN.n=0; + KNORR.IN.latitude=DATA.ncdf_data.LAT; + KNORR.IN.T_phi=pars[P.T_phi]; + KNORR.IN.T_r=pars[P.T_range]; + KNORR.IN.plgr=pars[P.plgr]; + KNORR.IN.k_L=pars[P.k_leaf]; + KNORR.IN.tau_W=pars[P.tau_W];//0.00000001;// + KNORR.IN.t_c=pars[P.time_c]; + KNORR.IN.t_r=pars[P.time_r];; + KNORR.IN.lambda_max=pars[P.lambda_max]; + //Initialize memory states + + POOLS[S.M_LAI_TEMP]=pars[P.init_T_mem]; + POOLS[S.M_LAI_MAX]=pars[P.init_LAIW_mem]*pars[P.lambda_max]; + + +//******************Allocation fluxes struct********************** + +ALLOC_AND_AUTO_RESP_FLUXES_STRUCT ARFLUXES; + //define time-invariant parameters here +ARFLUXES.IN.mr_r=pars[P.rauto_mr_r];// +ARFLUXES.IN.mr_w=pars[P.rauto_mr_w];// +ARFLUXES.IN.gr=pars[P.rauto_gr];// +ARFLUXES.IN.Q10mr=pars[P.rauto_mr_q10];// + + +//******************Heterotrophic respiration module********************* +HET_RESP_RATES_JCR_STRUCT HRJCR; + //define time invariant parameters here + + /* jc prep input for methane module*/ +HRJCR.IN.S_FV=pars[P.S_fv]; +HRJCR.IN.SM_OPT=pars[P.thetas_opt]; +HRJCR.IN.FWC=pars[P.fwc]; +HRJCR.IN.R_CH4=pars[P.r_ch4]; +HRJCR.IN.Q10CH4=pars[P.Q10ch4]; +HRJCR.IN.Q10CO2=pars[P.Q10rhco2]; + + +//******************Combustion factors********************* +double CF[7]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=(pars[P.cf_foliar]+pars[P.cf_ligneous])*0.5; +CF[S.C_som]=pars[P.cf_DOM]; + +//******************Misc********************* + /*foliar carbon transfer intermediate variables*/ +double Fcfolavailable; + /*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + /*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +//****************************************************************************** +//------------------------------------------------------------------------------ +//************************************ Main Loop ********************************* +//------------------------------------------------------------------------------ +//****************************************************************************** + + + /*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ + /*pool index*/ +p=nopools*n; + /*next pool index*/ +nxp=nopools*(n+1); + /*flux array index*/ +f=nofluxes*n; + + +double LAI=POOLS[p+S.D_LAI]; + +DALEC * DALECmodel=(DALEC *)DATA.MODEL; + +DALEC_1100_DATA_STRUCT * DALEC_1100_DATA=(DALEC_1100_DATA_STRUCT *)DALECmodel->MODEL_DATA; + +double VegK=DALEC_1100_DATA->VegK[n]; + +//******************Cold temperature stress factor********************* +double g; +double Tminmin = pars[P.Tminmin] - DGCM_TK0C; +double Tminmax = pars[P.Tminmax] - DGCM_TK0C; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +//*****************************Water stress******************************** + + //stomatal closure factor + +double beta1 = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_LY1]/pars[P.psi_50] - 1))); +double beta2 = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_LY2]/pars[P.psi_50] - 1))); +double beta = (beta1*pars[P.LY1_z] + beta2*pars[P.LY2_z]*pars[P.root_frac])/(pars[P.LY1_z]+pars[P.LY2_z]*pars[P.root_frac]); + + //biomass mortality factor + +double betaHMF_1 = 1/(1 + exp(pars[P.beta_lgrHMF]*(-1*POOLS[p+S.D_PSI_LY1]/pars[P.psi_50HMF] - 1))); +double betaHMF_2 = 1/(1 + exp(pars[P.beta_lgrHMF]*(-1*POOLS[p+S.D_PSI_LY2]/pars[P.psi_50HMF] - 1))); +double betaHMF = (betaHMF_1*pars[P.LY1_z] + betaHMF_2*pars[P.LY2_z]*pars[P.root_frac])/(pars[P.LY1_z] +pars[P.LY2_z]*pars[P.root_frac]); + +double HMF; // Hydraulic mortality factor + +if( (POOLS[p+S.D_LF_LY1] + POOLS[p+S.D_LF_LY2]) == 2 ) { //no frozen water + HMF = (1-betaHMF); +} +else { + HMF = 0; //no hydraulic mortality when soils are frozen +} + //store values +FLUXES[f+F.beta_factor]=fmin(beta,g); +FLUXES[f+F.soil_beta_factor]=beta; +FLUXES[f+F.hydraulic_mortality_factor]=HMF; + + + // mean air temperature (K) +double air_temp_k = DGCM_TK0C+0.5*(T2M_MIN[n]+T2M_MAX[n]); + + +//******************Declare LIU STRUCT********************* +LIU_AN_ET_STRUCT LIU; + + //define time-invariant parameters +LIU.IN.SRAD=SSRD[n]*1e6/DGCM_SEC_DAY; +LIU.IN.VPD=VPD[n]/10; +LIU.IN.precip=PREC[n]; +LIU.IN.TEMP=air_temp_k; +LIU.IN.vcmax25=pars[P.Vcmax25]; +LIU.IN.co2=CO2[n]; +LIU.IN.beta_factor= FLUXES[f+F.beta_factor]; +LIU.IN.g1=pars[P.Med_g1]; +LIU.IN.LAI=LAI; +LIU.IN.ga=pars[P.ga]; +LIU.IN.VegK=VegK; +LIU.IN.Tupp=pars[P.Tupp]; +LIU.IN.Tdown=pars[P.Tdown]; +LIU.IN.C3_frac=1.; // pars[P.C3_frac] +LIU.IN.clumping=pars[P.clumping]; +LIU.IN.leaf_refl_par=pars[P.leaf_refl_par]; +LIU.IN.leaf_refl_nir=pars[P.leaf_refl_nir]; +LIU.IN.q10canopy=pars[P.q10canopy]; +LIU.IN.q10canopyRd=pars[P.rauto_mrd_q10]; +LIU.IN.canopyRdsf=pars[P.canopyRdsf]; +LIU.IN.maxPevap=pars[P.maxPevap]; +LIU.IN.NSC=POOLS[p+S.C_lab]; +LIU.IN.deltat=deltat; + + + + //Call function: uses LIU->IN to update LIU->OUT +LIU_AN_ET(&LIU); + +double LEAF_MORTALITY_FACTOR=LIU.OUT.LEAF_MORTALITY_FACTOR; + + /*track C starvation here*/ +FLUXES[f+F.leaf_mortality_factor]=LEAF_MORTALITY_FACTOR; + + // GPP--- gross +FLUXES[f+F.gpp] = LIU.OUT.Ag; + // Rd--- Canopy +FLUXES[f+F.Rd] = LIU.OUT.Rd; + // GPP net, i.e. GPP- Rd +FLUXES[f+F.gppnet] = LIU.OUT.An; + //transpiration// +double transp = LIU.OUT.transp; + //partition transp between two soil layers +if (beta1>0 || beta2>0){ +FLUXES[f+F.transp1] = transp*beta1*pars[P.LY1_z]/(beta1*pars[P.LY1_z]+beta2*pars[P.LY2_z]*pars[P.root_frac]); +FLUXES[f+F.transp2] = transp - FLUXES[f+F.transp1];} +else { +FLUXES[f+F.transp1] =0; +FLUXES[f+F.transp2] =0;} + + //evaporation// +FLUXES[f+F.evap] = LIU.OUT.evap; + + /*Snow water equivalent*/ +FLUXES[f+F.snowfall] = SNOWFALL[n]; +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+FLUXES[f+F.snowfall]*deltat; /*first step snowfall to SWE*/ + //transient_SCF +double SCFtemp = POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); + //Snow melt, based on new SWE +double SNOWMELT=fmin(fmax((DGCM_TK0C+SKT[n]-pars[P.min_melt])*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]*one_over_deltat; /*melted snow per day*/ +double SUBLIMATION = pars[P.sublimation_rate]*SSRD[n]*SCFtemp; + +double slf=(SNOWMELT + SUBLIMATION)*deltat/POOLS[nxp+S.H2O_SWE]; + if (slf>1){ + FLUXES[f+F.melt]=SNOWMELT/slf; + FLUXES[f+F.sublimation]=SUBLIMATION/slf;} + else{ + FLUXES[f+F.melt]=SNOWMELT; + FLUXES[f+F.sublimation]=SUBLIMATION;} + + /*second step: remove snowmelt from SWE*/ + /*Ensure SWE does not go negative due to machine error*/ +POOLS[nxp+S.H2O_SWE]=fmax(POOLS[nxp+S.H2O_SWE]-(FLUXES[f+F.melt] + FLUXES[f+F.sublimation])*deltat,0); + //Store total land-to-atmosphere water flux +FLUXES[f+F.ets]=FLUXES[f+F.evap] + FLUXES[f+F.transp1] + FLUXES[f+F.transp2] + FLUXES[f+F.sublimation]; + +//Energy balance: Rn = LE + H - G +// Rn = SWin - SWout + LWin - LWout + +double SWin = SSRD[n]*1e6/DGCM_SEC_DAY; // W m-2 + + //Snow free +double SWout_snowfree =(SWin*0.5*(pars[P.leaf_refl_par]+pars[P.leaf_refl_nir])); // W m-2 + //Weighted average of surface albedo considering SW snow albedo as 0.9 +double snow_albedo=0.9;//Consider age-dependent albedo. + + //SW out +double SWout = (1. - POOLS[p+S.D_SCF])*SWout_snowfree + POOLS[p+S.D_SCF]*(SWin*snow_albedo); // W m-2 + + //Stefan-Boltzmann constant W.m-2.K-4 +double sigma = 5.67*1e-8; + //Incident LW radiation - calculated + //double LWin = sigma*pow(air_temp_k,4.); +double LWin = STRD[n]*1e6/DGCM_SEC_DAY; // W m-2 + //Outgoing LW radiation +double tskin_k = SKT[n]+DGCM_TK0C; +double LWout = sigma*(tskin_k*tskin_k)*(tskin_k*tskin_k); // W m-2 + + //Net radiation at the top of the canopy-soil continuum +double Rn = SWin - SWout + LWin - LWout; // W m-2 + //Rnet only into soil +FLUXES[f+F.net_radiation] = Rn; // W m-2 + + //Rnet snow free +double Rn_snowfree = SWin - SWout_snowfree + LWin - LWout; // W m-2 + + + //These are only fluxes into LY1 and out of LY1 +FLUXES[f+F.SWin]=SWin;//flag for redundancy and deletion +FLUXES[f+F.LWin]=LWin;//flag for redundancy and deletion +FLUXES[f+F.SWout]=SWout; +FLUXES[f+F.LWout]=LWout; + + //Flag for submodule maybe eventually +//latent heat exchanges +double lambda_liquid = DGCM_LATENT_HEAT_VAPORIZATION;// +double lambda_solid = DGCM_LATENT_HEAT_FUSION_3 + DGCM_LATENT_HEAT_VAPORIZATION;// + +//Total liquid-vapor and solid-vapor h2o fluxes +double From_Liquid=FLUXES[f+F.evap]+FLUXES[f+F.transp1]+FLUXES[f+F.transp2]; +double From_Solid=FLUXES[f+F.sublimation]; + +//Calculating total latent heat in W/2 +double LE = (lambda_liquid*From_Liquid + lambda_solid *From_Solid)/DGCM_SEC_DAY; + +FLUXES[f+F.latent_heat] = LE; // W m-2 + + //specific heat capacity of dry air is 1.00464 KJ kg -1 K -1 + // Consider surface pressure as forcing for more accurate conversion from mol to m3 + // Consider explicitly calculating cp based on humidity (derived from VPD and pressure) +double cp = 29.2; // J mol-1 K-1 representative specific heat of moist air at const pressure from Bonan book +double Psurf = 1e5; // Pa (representative surface pressure) +double Rgas = 8.31; // Universal gas constant (J mol-1 K-1) + // Pa / (J mol-1 K-1 * K) = mol m-3 +double moles_per_m3 = Psurf/(Rgas*air_temp_k); +//Sensible heat +// double H = cp*(tskin_k - air_temp_k)*pars[P.ga]*moles_per_m3; // ga in m s-1, +// FLUXES[f+F.sensible_heat] = H; // W m-2 +//Ground heat flux ONLY for energy in&out of vegetation-soil continuum +//Rn is scaled by snow free area, because we exclude snow energy balance from energy ODEs +//H is scaled by snow free area, because we exclude snow energy balance from energy ODEs +//LE is fully included, as evaporation and transpiration are assumed to come fully from snow-free areas (caveat: snow evaporation is a thing, btut we assume it's zero for this model) + +//Ideally, Rn should be snow-free vs snow-covered. + +// double G = Rn*(1. - POOLS[p+S.D_SCF]) - H*(1. - POOLS[p+S.D_SCF]) - LE; // W m-2 +// FLUXES[f+F.ground_heat] = G; // W m-2 +// FLUXES[f+F.gh_in] = G*DGCM_SEC_DAY; // J m-2 d-1 + +//******************Declare THERM STRUCT********************* +Thermal_struct THERM; + + //define time-invariant parameters +THERM.IN.surf_por=pars[P.LY1_por]; +THERM.IN.mid_por=0.5*(pars[P.LY2_por]+pars[P.LY1_por]); +THERM.IN.deep_por=0.5*(pars[P.LY3_por]+pars[P.LY2_por]); +THERM.IN.soil_VWC_surf=POOLS[p+S.D_SM_LY1]; +THERM.IN.soil_VWC_mid=0.5*(POOLS[p+S.D_SM_LY1]+POOLS[p+S.D_SM_LY2]); +THERM.IN.soil_VWC_deep=0.5*(POOLS[p+S.D_SM_LY2]+POOLS[p+S.D_SM_LY3]); +THERM.IN.LF_surf=POOLS[p+S.D_LF_LY1]; +THERM.IN.LF_mid=0.5*(POOLS[p+S.D_LF_LY1]+POOLS[p+S.D_LF_LY2]); +THERM.IN.LF_deep=0.5*(POOLS[p+S.D_LF_LY2]+POOLS[p+S.D_LF_LY3]); +THERM.IN.soil_thermal_conductivity_surf=pars[P.thermal_cond_surf]; +THERM.IN.soil_thermal_conductivity_middeep=pars[P.thermal_cond]; + + //Call function: uses THERM->IN to update THERM->OUT +THERMAL_COND(&THERM); +double therm_cond_surf=THERM.OUT.THERMAL_COND_SURF; +double therm_cond_mid=THERM.OUT.THERMAL_COND_MID; +double therm_cond_deep=THERM.OUT.THERMAL_COND_DEEP; + +//Gh_in approach 2 based on soil and LST +FLUXES[f+F.ground_heat] =(therm_cond_surf* (tskin_k - POOLS[p+S.D_TEMP_LY1])/(pars[P.LY1_z]*0.5))*(1. - POOLS[p+S.D_SCF]); +FLUXES[f+F.gh_in] =FLUXES[f+F.ground_heat] *DGCM_SEC_DAY; +//Using G, Rn and LE to derive H +// H = Rn - G - LE +FLUXES[f+F.sensible_heat] = Rn - FLUXES[f+F.ground_heat] - FLUXES[f+F.latent_heat]; + + // Infiltration (mm/day) +double liquid_in = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]); +double ice_sat_tv_surface = POOLS[p+S.D_SM_LY1] * (1.0 - POOLS[p+S.D_LF_LY1]); // volume of total pore space occupied by ice +double dynamic_max_infil = pars[P.max_infil] * pow(10.0, -6.0 * ice_sat_tv_surface); // impedance of infiltration due to ice blockage +FLUXES[f+F.infil] = dynamic_max_infil*(1 - exp(-liquid_in/dynamic_max_infil)); + + + // Surface runoff (mm/day) +FLUXES[f+F.q_surf] = liquid_in - FLUXES[f+F.infil]; + + + + // Calculate drainage: correcting psi for presence of ice occurs within DRAINAGE function +double drain_LY1 = DRAINAGE(POOLS[p+S.D_SM_LY1],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, +pars[P.retention],POOLS[p+S.D_LF_LY1],POOLS[p+S.D_TEMP_LY1]); +double drain_LY2 = DRAINAGE(POOLS[p+S.D_SM_LY2],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, +pars[P.retention],POOLS[p+S.D_LF_LY2],POOLS[p+S.D_TEMP_LY2]); +double drain_LY3 = DRAINAGE(POOLS[p+S.D_SM_LY3],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, +pars[P.retention],POOLS[p+S.D_LF_LY3],POOLS[p+S.D_TEMP_LY3]); + + // Drainage becomes runoff from pools +FLUXES[f+F.q_ly1] = HYDROFUN_MOI2EWT(drain_LY1,pars[P.LY1_por],pars[P.LY1_z])*one_over_deltat; +FLUXES[f+F.q_ly2] = HYDROFUN_MOI2EWT(drain_LY2,pars[P.LY2_por],pars[P.LY2_z])*one_over_deltat; +FLUXES[f+F.q_ly3] = HYDROFUN_MOI2EWT(drain_LY3,pars[P.LY3_por],pars[P.LY3_z])*one_over_deltat; + +/*printf("q_surf = %2.2f, q_ly1 = %2.2f, q_ly2 = %2.2f, q_ly3 = %2.2f\n", +FLUXES[f+F.q_surf],FLUXES[f+F.q_ly1],FLUXES[f+F.q_ly2],FLUXES[f+F.q_ly3]);*/ + + // Convert to conductivity: correcting for presence of ice occurs within MOI2CON function +double k_LY1 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY1],pars[P.hydr_cond],pars[P.retention],POOLS[p+S.D_LF_LY1]); +double k_LY2 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY2],pars[P.hydr_cond],pars[P.retention],POOLS[p+S.D_LF_LY2]); +double k_LY3 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY3],pars[P.hydr_cond],pars[P.retention],POOLS[p+S.D_LF_LY3]); + + // Calculate inter-pool transfer in m/s (positive is LY1 to LY2) +double pot_xfer = 1000 * sqrt(k_LY1*k_LY2) * (1e-9*(POOLS[p+S.D_PSI_LY1]-POOLS[p+S.D_PSI_LY2])/(9.8*0.5*(pars[P.LY1_z]+pars[P.LY2_z])) + 1); +double SPACEavail, H2Oavail, Max_H2O_xfer, TEMPxfer_1to2; +if (pot_xfer>0) {//Water is going LY1->LY2 (down) + // Available space in LY2 (after runoff) +SPACEavail=fmax(pars[P.LY2_z]*pars[P.LY2_por]*1e3 - POOLS[p+S.H2O_LY2] + (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); + // Available water in LY1 (after runoff, et, and infiltration) +H2Oavail=fmax(POOLS[p+S.D_LF_LY1]*POOLS[p+S.H2O_LY1] + (FLUXES[f+F.infil] - FLUXES[f+F.q_ly1] - FLUXES[f+F.evap] - FLUXES[f+F.transp1])*deltat,0); + // Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +Max_H2O_xfer= pot_xfer*DGCM_SEC_DAY*deltat; //liquid fraction accounted for in PSI calculation directly; no need to correct for it here + //Minimum of three terms for LY1->LY2 + //1. Max_H2O_xfer + //2. Available space in LY2 (after runoff) + //3. LY1*LF (after runoff, et, and infiltration) +FLUXES[f+F.ly1xly2] =fmin(Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; +TEMPxfer_1to2= POOLS[p+S.D_TEMP_LY1];//In K +} +else { //Water is going LY2->LY1 (up) + // Available space in LY1 after runoff, et, and infiltration +SPACEavail=fmax(pars[P.LY1_z]*pars[P.LY1_por]*1e3 - POOLS[p+S.H2O_LY1] - (FLUXES[f+F.infil] - FLUXES[f+F.q_ly1] - FLUXES[f+F.evap] - FLUXES[f+F.transp1])*deltat,0); + // Available water in LY2 after runoff +H2Oavail= fmax(POOLS[p+S.D_LF_LY2]*POOLS[p+S.H2O_LY2] - (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); + // Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +Max_H2O_xfer= pot_xfer*DGCM_SEC_DAY*deltat; //liquid fraction accounted for in PSI calculation directly; no need to correct for it here + // Reverse sign of previous case +FLUXES[f+F.ly1xly2] = -fmin(-Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; +TEMPxfer_1to2= POOLS[p+S.D_TEMP_LY2];//In K +} + + + // Calculate inter-pool transfer in m/s (positive is LY2 to LY3) +pot_xfer = 1000 * sqrt(k_LY2*k_LY3) * (1e-9*(POOLS[p+S.D_PSI_LY2]-POOLS[p+S.D_PSI_LY3])/(9.8*0.5*(pars[P.LY2_z]+pars[P.LY3_z])) + 1); +double TEMPxfer_2to3; +if (pot_xfer>0) {//Water is going LY2->LY3 (down) + // Available space in LY3 (after runoff) +SPACEavail=fmax(pars[P.LY3_z]*pars[P.LY3_por]*1e3 - POOLS[p+S.H2O_LY3] + FLUXES[f+F.q_ly3]*deltat,0); + // Available water in LY2 (after runoff, et, and infiltration) +H2Oavail=fmax(POOLS[p+S.D_LF_LY2]*POOLS[p+S.H2O_LY2] - (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); + // Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +Max_H2O_xfer= pot_xfer*DGCM_SEC_DAY*deltat; //liquid fraction accounted for in PSI calculation directly; no need to correct for it here + //Minimum of three terms for LY2->LY3 + //1. Max_H2O_xfer + //2. Available space in LY3 (after runoff) + //3. LY2*LF (after runoff, et, and infiltration) +FLUXES[f+F.ly2xly3] =fmin(Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; +TEMPxfer_2to3= POOLS[p+S.D_TEMP_LY2];//In K +} +else { //Water is going LY3->LY2 (up) + // Available space in LY2 after runoff, et, and infiltration +SPACEavail=fmax(pars[P.LY2_z]*pars[P.LY2_por]*1e3 - POOLS[p+S.H2O_LY2] + (FLUXES[f+F.q_ly2] + FLUXES[f+F.transp2])*deltat,0); + // Available water in LY3 after runoff +H2Oavail= fmax(POOLS[p+S.D_LF_LY3]*POOLS[p+S.H2O_LY3] - FLUXES[f+F.q_ly3]*deltat,0); + // Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +Max_H2O_xfer= pot_xfer*DGCM_SEC_DAY*deltat; //liquid fraction accounted for in PSI calculation directly; no need to correct for it here + // Reverse sign of previous case +FLUXES[f+F.ly2xly3] = -fmin(-Max_H2O_xfer , fmin(SPACEavail, H2Oavail))*one_over_deltat; +TEMPxfer_2to3= POOLS[p+S.D_TEMP_LY3];//In K +} + + +// Update pools, including ET from LY1 + //Ensure all pools greater or equal to zero + +POOLS[nxp+S.H2O_LY1] = POOLS[p+S.H2O_LY1] + (FLUXES[f+F.infil] - FLUXES[f+F.ly1xly2] - FLUXES[f+F.q_ly1] - FLUXES[f+F.evap] - FLUXES[f+F.transp1])*deltat; +POOLS[nxp+S.H2O_LY2] = POOLS[p+S.H2O_LY2] + (FLUXES[f+F.ly1xly2] - FLUXES[f+F.ly2xly3] - FLUXES[f+F.q_ly2] - FLUXES[f+F.transp2])*deltat; +POOLS[nxp+S.H2O_LY3] = POOLS[p+S.H2O_LY3] + (FLUXES[f+F.ly2xly3] - FLUXES[f+F.q_ly3])*deltat; + + +if (POOLS[nxp+S.H2O_LY1]>LY1max){//Dump excess into LY1 Q +FLUXES[f+F.q_ly1] +=(POOLS[nxp+S.H2O_LY1]-LY1max)*one_over_deltat; +POOLS[nxp+S.H2O_LY1]=LY1max;} + +if (POOLS[nxp+S.H2O_LY2]>LY2max){//Dump excess into LY2 Q +FLUXES[f+F.q_ly1] +=(POOLS[nxp+S.H2O_LY2]-LY2max)*one_over_deltat; +POOLS[nxp+S.H2O_LY2]=LY2max;} + +if (POOLS[nxp+S.H2O_LY3]>LY3max){//Dump excess into LY3 Q +FLUXES[f+F.q_ly3] +=(POOLS[nxp+S.H2O_LY3]-LY3max)*one_over_deltat; +POOLS[nxp+S.H2O_LY3]=LY3max;} + +/*printf("q_surf2 = %2.2f, q_ly12 = %2.2f, q_ly22 = %2.2f, q_ly32 = %2.2f\n", +FLUXES[f+F.q_surf],FLUXES[f+F.q_ly1],FLUXES[f+F.q_ly2],FLUXES[f+F.q_ly3]);*/ + + +//**********INTERNAL ENERGY FLUXES FOR ALL H2O FLUXES*************** +double infiltemp = air_temp_k ;//Infiltemp needs to be in degrees C for IF statement to work +if (FLUXES[f+F.melt]>0){infiltemp = (infiltemp-DGCM_TK0C)*(PREC[n] - SNOWFALL[n])/(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])+DGCM_TK0C;}//snowmelt temp = 0, so term multiplied by zero in weighted average + + + //All energy fluxes +FLUXES[f+F.infil_e] = FLUXES[f+F.infil]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(infiltemp); +FLUXES[f+F.evap_e] = FLUXES[f+F.evap]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY1]); +FLUXES[f+F.transp1_e] = FLUXES[f+F.transp1]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY1]); +FLUXES[f+F.transp2_e] = FLUXES[f+F.transp2]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY2]); +FLUXES[f+F.ly1xly2_e] = FLUXES[f+F.ly1xly2]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(TEMPxfer_1to2); +FLUXES[f+F.ly2xly3_e] = FLUXES[f+F.ly2xly3]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(TEMPxfer_2to3); +FLUXES[f+F.q_ly1_e] = FLUXES[f+F.q_ly1]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY1]); +FLUXES[f+F.q_ly2_e] = FLUXES[f+F.q_ly2]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY2]); +FLUXES[f+F.q_ly3_e] = FLUXES[f+F.q_ly3]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_LY3]); + //Thermal conductivity = k*dT/dz, units are W/m2, converting to J/m2/d +FLUXES[f+F.ly1xly2_th_e] = 2*therm_cond_mid* (POOLS[p+S.D_TEMP_LY1] - POOLS[p+S.D_TEMP_LY2])/(pars[P.LY1_z] + pars[P.LY2_z])*DGCM_SEC_DAY; +FLUXES[f+F.ly2xly3_th_e] = 2*therm_cond_deep* (POOLS[p+S.D_TEMP_LY2] - POOLS[p+S.D_TEMP_LY3])/(pars[P.LY2_z] + pars[P.LY3_z])*DGCM_SEC_DAY; + + +FLUXES[f+F.geological]=PREDERIVED_GEO_FLUX;//In J/m2/d //105mW/m2 +POOLS[nxp+S.E_LY1] = POOLS[p+S.E_LY1] + (FLUXES[f+F.gh_in] + FLUXES[f+F.infil_e] - FLUXES[f+F.evap_e] - FLUXES[f+F.transp1_e] - FLUXES[f+F.q_ly1_e] - FLUXES[f+F.ly1xly2_e] - FLUXES[f+F.ly1xly2_th_e])*deltat; +POOLS[nxp+S.E_LY2] = POOLS[p+S.E_LY2] + (FLUXES[f+F.ly1xly2_e] + FLUXES[f+F.ly1xly2_th_e] - FLUXES[f+F.transp2_e] - FLUXES[f+F.q_ly2_e] - FLUXES[f+F.ly2xly3_e] - FLUXES[f+F.ly2xly3_th_e])*deltat; +POOLS[nxp+S.E_LY3] = POOLS[p+S.E_LY3] + (FLUXES[f+F.ly2xly3_e] - FLUXES[f+F.q_ly3_e] + FLUXES[f+F.ly2xly3_th_e] + FLUXES[f + F.geological])*deltat; + + +//**************************KNORR LAI*************************** + //Time varying KNORR function terms + +KNORR.IN.lambda_max_memory= POOLS[p+S.M_LAI_MAX]; +KNORR.IN.T_memory=POOLS[p+S.M_LAI_TEMP]; +KNORR.IN.temp=air_temp_k; +KNORR.IN.n=n; +KNORR.IN.DOY=DOY[n]; +KNORR.IN.lambda=LAI; +KNORR.IN.pasm=(POOLS[p+S.H2O_LY1]+POOLS[nxp+S.H2O_LY1]+POOLS[p+S.H2O_LY2]+POOLS[nxp+S.H2O_LY2])*0.5;//Note: soil moisture also available here +KNORR.IN.transp= transp; + //Call function: uses KNORR->IN to update KNORR->OUT +KNORR_ALLOCATION(&KNORR); + +FLUXES[f+F.target_LAI]=KNORR.OUT.lambda_next; + //KNORR.OUT.dlambdadt is in units per timestep; converting thest to units per day (as required for CARDAMOM) + //"FLUXES" have to be in "per day" units +FLUXES[f+F.dlambda_dt]=KNORR.OUT.dlambdadt*one_over_deltat; +FLUXES[f+F.f_temp_thresh]= KNORR.OUT.f_T; +FLUXES[f+F.f_dayl_thresh]= KNORR.OUT.f_d; +FLUXES[f+F.lambda_tilde_max]= KNORR.OUT.lambda_tilde_max; +FLUXES[f+F.lambda_W]= KNORR.OUT.lambda_W; + + //Update KNORR memory variables for next iteration +POOLS[nxp+S.M_LAI_MAX]=KNORR.OUT.laim; +POOLS[nxp+S.M_LAI_TEMP]=KNORR.OUT.T; + + + +//************************************Allocation******************************* + +ARFLUXES.IN.deltat=deltat; +ARFLUXES.IN.GPP=FLUXES[f+F.gpp]; +ARFLUXES.IN.Rd=LIU.OUT.Rd; +ARFLUXES.IN.TEMP=air_temp_k; +ARFLUXES.IN.NSC=POOLS[p+S.C_lab]; +ARFLUXES.IN.C_LIVE_W=POOLS[p+S.C_woo]; +ARFLUXES.IN.C_LIVE_R= POOLS[p+S.C_roo]; +// Potential plant allocation (growth) fluxes +ARFLUXES.IN.ALLOC_FOL_POT=fmax(0, ((FLUXES[f+F.target_LAI] * pars[P.LCMA]) - POOLS[p+S.C_fol])*one_over_deltat); +ARFLUXES.IN.ALLOC_ROO_POT=fmax(0, (pars[P.phi_RL] * (FLUXES[f+F.target_LAI] * pars[P.LCMA]))*one_over_deltat); +ARFLUXES.IN.ALLOC_WOO_POT=fmax(0, (pars[P.phi_WL] * (FLUXES[f+F.target_LAI] * pars[P.LCMA]))*one_over_deltat); + +ALLOC_AND_AUTO_RESP_FLUXES(&ARFLUXES); + + double NONLEAF_MORTALITY_FACTOR=ARFLUXES.OUT.NONLEAF_MORTALITY_FACTOR; + + + /*track C starvation here*/ +FLUXES[f+F.nonleaf_mortality_factor]=NONLEAF_MORTALITY_FACTOR; + + + /*respiration auto: note, at some point fix the names*/ +FLUXES[f+F.resp_auto]=ARFLUXES.OUT.AUTO_RESP_TOTAL+LIU.OUT.Rd; + /*growth respiration*/ +FLUXES[f+F.resp_auto_growth]=ARFLUXES.OUT.AUTO_RESP_GROWTH; + /*maintenance respiration*/ +FLUXES[f+F.resp_auto_maint]=ARFLUXES.OUT.AUTO_RESP_MAINTENANCE; +FLUXES[f+F.resp_auto_maint_dark]=LIU.OUT.Rd; + + + +/*Compute leaf senescence: + this is a C_fol removal based on Knorr output dlambda_dt, + which itself is computed based on the LAI passed to Knorr module, + which is based on start-of-month C_fol; hence subsequent removals + based on this flux should also go first into C_fol, to maintain + compatible pool size */ +if (FLUXES[f+F.dlambda_dt] > 0){ // i.e. when leaf growth is occuring + FLUXES[f+F.ph_fol2lit]=0; +} +else { // i.e. when leaf fall is occuring + //FLUXES[f+F.dlambda_dt] is in m2/m2/day + //LCMA = gC/m2/m2 + FLUXES[f+F.ph_fol2lit]=-FLUXES[f+F.dlambda_dt]*pars[P.LCMA]; +} + + /*labile production*/ +FLUXES[f+F.lab_prod] = ARFLUXES.OUT.F_LABPROD; //Could also be LIUET.OUT.An? + /*foliar production*/ +FLUXES[f+F.foliar_prod] = ARFLUXES.OUT.ALLOC_FOL_ACTUAL; + /*root production*/ +FLUXES[f+F.root_prod] = ARFLUXES.OUT.ALLOC_ROO_ACTUAL; + /*wood production*/ +FLUXES[f+F.wood_prod] = ARFLUXES.OUT.ALLOC_WOO_ACTUAL; + +/*--------------------Heterotrophic Respiration-------------------------------*/ + //TIME-VARYING INPUTS +HRJCR.IN.SM=POOLS[p+S.D_SM_LY1]; +HRJCR.IN.TEMP=POOLS[p+S.D_TEMP_LY1];; // Input in degrees K +HRJCR.IN.LF=POOLS[p+S.D_LF_LY1];; // Input in degrees + + //JCR +HET_RESP_RATES_JCR(&HRJCR); + /* output from JCR module */ +FLUXES[f+F.aetr]=HRJCR.OUT.aerobic_tr;//Aerobic turnover rate scalar +FLUXES[f+F.antr]=HRJCR.OUT.anaerobic_tr;//Anaerobic turnover rate scalar +FLUXES[f+F.an_co2_c_ratio]=HRJCR.OUT.anaerobic_co2_c_ratio;//CO2_C_ratio +FLUXES[f+F.an_ch4_c_ratio]=HRJCR.OUT.anaerobic_ch4_c_ratio;//CH4_C_ratio + +//**********Aerobic fluxes********** +double ae_loss_cwd = POOLS[p+S.C_cwd]*HRJCR.OUT.aerobic_tr*pars[P.t_cwd]; + /* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = ae_loss_cwd*(1-pars[P.tr_cwd2som]); +double ae_loss_lit = POOLS[p+S.C_lit]*HRJCR.OUT.aerobic_tr*pars[P.t_lit]; + /* aerobic Rh from litter*/ +FLUXES[f+F.ae_rh_lit] = ae_loss_lit*(1-pars[P.tr_lit2som]); + /* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*HRJCR.OUT.aerobic_tr*pars[P.t_som]; + +//**********Anaerobic fluxes********** +double an_loss_cwd = POOLS[p+S.C_cwd]*HRJCR.OUT.anaerobic_tr*pars[P.t_cwd]; + /* anaerobic Rh from coarse woody debris*/ +FLUXES[f+F.an_rh_cwd] = an_loss_cwd*(1-pars[P.tr_cwd2som]); + /* anaerobic Rh from litter*/ +double an_loss_lit = POOLS[p+S.C_lit]*HRJCR.OUT.anaerobic_tr*pars[P.t_lit]; +FLUXES[f+F.an_rh_lit] = an_loss_lit*(1-pars[P.tr_lit2som]); + /* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*HRJCR.OUT.anaerobic_tr*pars[P.t_som]; + /*CWD to SOM*/ +FLUXES[f+F.cwd2som] = (an_loss_cwd + ae_loss_cwd)*pars[P.tr_cwd2som]; + /*litter to SOM*/ +FLUXES[f+F.lit2som] = (an_loss_lit + ae_loss_lit)*pars[P.tr_lit2som]; + /* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*HRJCR.OUT.anaerobic_co2_c_ratio + (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som]); + /* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*HRJCR.OUT.anaerobic_ch4_c_ratio; + +/*---------------------- end of JCR --------------------------------------------*/ + +/*---------------------- Begin carbon pool transfers --------------------------------------------*/ + +/*CARBON POOL GROWTH AND PHENOLOGICAL LEAF FLUX*/ + /*LIVE POOLS*/ +POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.gpp]-FLUXES[f+F.Rd]-FLUXES[f+F.resp_auto_maint]-FLUXES[f+F.foliar_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.wood_prod]-FLUXES[f+F.resp_auto_growth])*deltat; +POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.foliar_prod]-FLUXES[f+F.ph_fol2lit])*deltat; +POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + FLUXES[f+F.root_prod]*deltat; +POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + FLUXES[f+F.wood_prod]*deltat; + /*DEAD POOLS*/ +POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] - (FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.cwd2som])*deltat; +POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.ph_fol2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; +POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + +/*CARBON POOL MORTALITY REDUCTRIONS - + WITH FIRES, + HYDRAULIC FAILURE, + CARBON STARVATION, + HUMAN DISTURBANCE, + AND BACKGROUND MORTALITY*/ +/****Disturbance (i.e. Deforestation & Degradation & Cropping)*****/ + /*Calculating Deforestation & Degradation flux DMF as percent of live biomass: + p=index of current pool timestep; nxp=index of next pool timestep; + removals are scaled by pool(nxp) which has received additions from growth, above + Calculating total Crop disturbance as 200% of YIELD: + Crop NPP = Crop Yield + Crop Residue + Crop yield ~ Crop Residue (from literature sources that have Crop NPP at ~1000gC/yr and Crop Yield at ~450gC/yr).*/ + +double TotalABGB=POOLS[nxp+S.C_lab]+POOLS[nxp+S.C_fol]+POOLS[nxp+S.C_roo]+POOLS[nxp+S.C_woo]; +double DMF = DIST[n]/TotalABGB; //DIST[n]=disturbance flux at current flux timestep, halfway in between p and nxp +double CROPYIELD_factor=YIELD[n]/TotalABGB; //applied to the wood pool +// double CROPRESIDUE_factor=YIELD[n]/TotalABGB; //applied to all pools + +FLUXES[f+F.dist_lab] = POOLS[nxp+S.C_lab]*(2*CROPYIELD_factor+DMF)*one_over_deltat; +FLUXES[f+F.dist_fol] = POOLS[nxp+S.C_fol]*(2*CROPYIELD_factor+DMF)*one_over_deltat; +FLUXES[f+F.dist_roo] = POOLS[nxp+S.C_roo]*(2*CROPYIELD_factor+DMF)*one_over_deltat; +FLUXES[f+F.dist_woo] = POOLS[nxp+S.C_woo]*(2*CROPYIELD_factor+DMF)*one_over_deltat; + +//This portion is transfered to dead pools +FLUXES[f+F.labyield2lit] = POOLS[nxp+S.C_lab]*CROPYIELD_factor*one_over_deltat; +FLUXES[f+F.folyield2lit] = POOLS[nxp+S.C_fol]*CROPYIELD_factor*one_over_deltat; +FLUXES[f+F.rooyield2lit] = POOLS[nxp+S.C_roo]*CROPYIELD_factor*one_over_deltat; +FLUXES[f+F.wooyield2cwd] = POOLS[nxp+S.C_woo]*CROPYIELD_factor*one_over_deltat; + + + /*LIVE CARBON POOL REMOVALS PART 1 of 4: + Removing ABGB disturbance from live pools here; + these are lateral fluxes, and are discarded, not transferred!*/ +POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-FLUXES[f+F.dist_lab]*deltat; +POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-FLUXES[f+F.dist_fol]*deltat; +POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-FLUXES[f+F.dist_roo]*deltat; +POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-FLUXES[f+F.dist_woo]*deltat; + +/****Fire combustion*****/ + /*Calculating all fire transfers from C pools to atmosphere via combustion*/ + /*note: all fluxes are in gC m-2 day-1*/ +FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]*one_over_deltat; +FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]*one_over_deltat; +FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]*one_over_deltat; +FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]*one_over_deltat; +FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]*one_over_deltat; +FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]*one_over_deltat; +FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]*one_over_deltat; + + /*LIVE CARBON POOL REMOVALS PART 2 of 4: + Removing fire combustion fluxes from live pools here*/ +POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-FLUXES[f+F.f_lab]*deltat; +POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-FLUXES[f+F.f_fol]*deltat; +POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-FLUXES[f+F.f_roo]*deltat; +POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-FLUXES[f+F.f_woo]*deltat; + /*DEAD CARBON POOL removals PART 1 of 2: + Removing fire combustion fluxes from live pools here*/ +POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]-FLUXES[f+F.f_cwd]*deltat; +POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]-FLUXES[f+F.f_lit]*deltat; +POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]-FLUXES[f+F.f_som]*deltat; + +/****Aggregate Mortality Factor*****/ + /* Compute aggregate mortality factor by pool from competing environmental stress: + -C starvation + -Hydraulic Failure + -Fire injury mortality*/ +double AMF_C_lab = (1 - (1-NONLEAF_MORTALITY_FACTOR) * (1-(BURNED_AREA[n]*(1-pars[P.resilience]))) * (1-HMF)); +double AMF_C_fol = (1 - (1-LEAF_MORTALITY_FACTOR) * (1-(BURNED_AREA[n]*(1-pars[P.resilience]))) * (1-HMF)); +double AMF_C_roo = (1 - (1-NONLEAF_MORTALITY_FACTOR) * (1-(BURNED_AREA[n]*(1-pars[P.resilience]))) * (1-HMF)); +double AMF_C_woo = (1 - (1-NONLEAF_MORTALITY_FACTOR) * (1-(BURNED_AREA[n]*(1-pars[P.resilience]))) * (1-HMF)); + +FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*(AMF_C_lab)*one_over_deltat; +FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*(AMF_C_fol)*one_over_deltat; +FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*(AMF_C_roo)*one_over_deltat; +FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*(AMF_C_woo)*one_over_deltat; + //Fire-accelerated decomposition in dead pools +FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-pars[P.resilience])*one_over_deltat; +FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-pars[P.resilience])*one_over_deltat; + + /*LIVE CARBON POOL REMOVALS PART 3 of 4: + environmental stress mortality fluxes to dead pools*/ +POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-FLUXES[f+F.fx_lab2lit]*deltat; +POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-FLUXES[f+F.fx_fol2lit]*deltat; +POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-FLUXES[f+F.fx_roo2lit]*deltat; +POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-FLUXES[f+F.fx_woo2cwd]*deltat; + +/****Background Mortality Factor*****/ + /*Calculating background mortality (age/herbivory/impact) flux as percent of remaining live biomass*/ +FLUXES[f+F.woo2cwd] = POOLS[nxp+S.C_woo]*pars[P.t_wood]; +FLUXES[f+F.roo2lit] = POOLS[nxp+S.C_roo]*pars[P.t_root]; +FLUXES[f+F.lab2lit] = POOLS[nxp+S.C_lab]*pars[P.t_lab]; +FLUXES[f+F.fol2lit]=POOLS[nxp+S.C_fol]*pars[P.t_foliar]; +// if (FLUXES[f+F.dlambda_dt] > 0){ +// FLUXES[f+F.fol2lit]=POOLS[nxp+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))*one_over_deltat; +// } +// else { + +// } + + /*LIVE CARBON POOL REMOVALS PART 4 of 4: + background mortality fluxes to dead pools*/ +POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-FLUXES[f+F.lab2lit]*deltat; +POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-FLUXES[f+F.fol2lit]*deltat; +POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-FLUXES[f+F.roo2lit]*deltat; +POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-FLUXES[f+F.woo2cwd]*deltat; + + /*DEAD C POOLS TRANSFERS PART 2 of 2: + Adding fire decomposition removals here together with additions from live pools*/ +POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.wooyield2cwd]+ + FLUXES[f+F.woo2cwd]+ + FLUXES[f+F.fx_woo2cwd]- + FLUXES[f+F.fx_cwd2som])*deltat; +POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.labyield2lit]+ + FLUXES[f+F.lab2lit]+ + FLUXES[f+F.fx_lab2lit]+ + FLUXES[f+F.folyield2lit]+ + FLUXES[f+F.fol2lit]+ + FLUXES[f+F.fx_fol2lit]+ + FLUXES[f+F.rooyield2lit]+ + FLUXES[f+F.roo2lit]+ + FLUXES[f+F.fx_roo2lit]- + FLUXES[f+F.fx_lit2som])*deltat; +POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ +FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + /*Fraction of C-foliar lost due to fires*/ +FLUXES[f+F.foliar_fire_frac] = BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Calculate LAI (lambda) lost due to fire + - we lose the same fraction of LAI as we do C-foliar + - FE_\Lambda^{(t+1)} = \Lambda^{(t+1)'} * BA ( k_{factor(i)} + (1 - k_{factor(i)}) r )*/ +FLUXES[f+F.lai_fire] = (POOLS[p+S.C_fol]/pars[P.LCMA])*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + +/****************************RECORD t+1 DIAGNOSTIC STATES*************************/ +POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI +POOLS[nxp+S.D_SCF]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); //snow cover fraction + +/*printf("H2Oly1 = %2.2f, H2Oly2 = %2.2f, H2Oly3 = %2.2f\n", +POOLS[nxp+S.H2O_LY1],POOLS[nxp+S.H2O_LY2],POOLS[nxp+S.H2O_LY3]);*/ + + //Update time-varying inputs +LY1SOILTEMP.IN.soil_water = POOLS[nxp+S.H2O_LY1];//mm (or kg/m2) +LY2SOILTEMP.IN.soil_water = POOLS[nxp+S.H2O_LY2];//mm (or kg/m2) +LY3SOILTEMP.IN.soil_water = POOLS[nxp+S.H2O_LY3];//mm (or kg/m2) +LY1SOILTEMP.IN.internal_energy = POOLS[nxp+S.E_LY1];//Joules +LY2SOILTEMP.IN.internal_energy = POOLS[nxp+S.E_LY2];//Joules +LY3SOILTEMP.IN.internal_energy = POOLS[nxp+S.E_LY3];//Joules + + SOIL_TEMP_AND_LIQUID_FRAC(&LY1SOILTEMP); + SOIL_TEMP_AND_LIQUID_FRAC(&LY2SOILTEMP); + SOIL_TEMP_AND_LIQUID_FRAC(&LY3SOILTEMP); + +POOLS[nxp+S.D_TEMP_LY1]=LY1SOILTEMP.OUT.TEMP;//In K +POOLS[nxp+S.D_TEMP_LY2]=LY2SOILTEMP.OUT.TEMP;//In K +POOLS[nxp+S.D_TEMP_LY3]=LY3SOILTEMP.OUT.TEMP;//In K + +POOLS[nxp+S.D_LF_LY1]=LY1SOILTEMP.OUT.LF; +POOLS[nxp+S.D_LF_LY2]=LY2SOILTEMP.OUT.LF; +POOLS[nxp+S.D_LF_LY3]=LY3SOILTEMP.OUT.LF; + + + //Soil moisture +POOLS[nxp+S.D_SM_LY1]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY1],pars[P.LY1_por],pars[P.LY1_z]); //soil moisture LY1 +POOLS[nxp+S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY2],pars[P.LY2_por],pars[P.LY2_z]);//soil moisture LY2 +POOLS[nxp+S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3 +//Correcting PSI for presence of ice occurs within MOI2PSI function +POOLS[nxp+S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY1],psi_porosity,pars[P.retention], +POOLS[nxp+S.D_LF_LY1],POOLS[nxp+S.D_TEMP_LY1]),minpsi); +POOLS[nxp+S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY2],psi_porosity,pars[P.retention], +POOLS[nxp+S.D_LF_LY2],POOLS[nxp+S.D_TEMP_LY2]),minpsi); +POOLS[nxp+S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY3],psi_porosity,pars[P.retention], +POOLS[nxp+S.D_LF_LY3],POOLS[nxp+S.D_TEMP_LY3]),minpsi); + + +//Isfinite check for 14 progronstic pools only + int nnn, isfinitecheck=1; + for (nnn=0;nnn<14;nnn++){if ( isfinite(POOLS[nxp+nnn])==false){isfinitecheck=0;}}; + if (isfinitecheck==0){break;}; + +} + + + + +return 0; +} + + +int DALEC_1100_MODCONFIG(DALEC * DALECmodel, DATA * DATA){ + + + PREDERIVE_DALEC_1100_DATA(DALECmodel, DATA); + +struct DALEC_1100_PARAMETERS P=DALEC_1100_PARAMETERS; +struct DALEC_1100_FLUXES F=DALEC_1100_FLUXES; +struct DALEC_1100_POOLS S=DALEC_1100_POOLS; +struct DALEC_1100_EDCs E=DALEC_1100_EDCs; + + + + + //DALECmodel->data=DALEC_1100_DATA; +DALECmodel->dalec=DALEC_1100; +DALECmodel->nopools=30; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=89; +DALECmodel->nofluxes=100; +DALECmodel->noedcs=16; + +DALEC_1100_FLUX_SOURCES_SINKS(DALECmodel); + +//Define PARS_INFO here (ranges, and eventually names, etc) +PARS_INFO_1100(DALECmodel); +POPULATE_INFO_STRUCTS(DALECmodel); + +//EDC operator +//Make sure has same number as number of EDCs +//This is generic EDCs structure defined in ../DALEC_EDCs/DALEC_EDC_FUNCTIONS.c +//Has three args, data (void), function (in "DATA", and "void *", and "double" out), and "boolean" prerun. + +DALECmodel->EDCs=calloc(DALECmodel->noedcs,sizeof(EDCs)); +//Abbrieviate +EDCs * EDCs=DALECmodel->EDCs; + //List all inequality calls here +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_litcwdtor; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_cwdsomtor; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_rootwoodtor; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_mr_rates; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_fol2lig_cf; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_relativepsi50; + //EDC: lit tor > cwd tor +EDC_litcwdtor.big_par_index=P.t_lit; +EDC_litcwdtor.small_par_index=P.t_cwd; +EDCs[E.litcwdtor].data=&EDC_litcwdtor; +EDCs[E.litcwdtor].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.litcwdtor].prerun=true; + //EDC: cwd tor > som tor +EDC_cwdsomtor.big_par_index=P.t_cwd; +EDC_cwdsomtor.small_par_index=P.t_som; +EDCs[E.cwdsomtor].data=&EDC_cwdsomtor; +EDCs[E.cwdsomtor].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.cwdsomtor].prerun=true; + //EDC: root tor > wood tor +EDC_rootwoodtor.big_par_index=P.t_root; +EDC_rootwoodtor.small_par_index=P.t_wood; +EDCs[E.rootwoodtor].data=&EDC_rootwoodtor; +EDCs[E.rootwoodtor].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.rootwoodtor].prerun=true; + //EDC: foliar and root mr > wood mr +EDC_mr_rates.big_par_index=P.rauto_mr_r; +EDC_mr_rates.small_par_index=P.rauto_mr_w; +EDCs[E.mr_rates].data=&EDC_mr_rates; +EDCs[E.mr_rates].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.mr_rates].prerun=true; + //EDC: cf_foliar > cf_ligneous +EDC_fol2lig_cf.big_par_index=P.cf_foliar; +EDC_fol2lig_cf.small_par_index=P.cf_ligneous; +EDCs[E.fol2lig_cf].data=&EDC_fol2lig_cf; +EDCs[E.fol2lig_cf].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.fol2lig_cf].prerun=true; + //EDC: psi50HMF > psi50 +EDC_relativepsi50.big_par_index=P.psi_50HMF; +EDC_relativepsi50.small_par_index=P.psi_50; +EDCs[E.relativepsi50].data=&EDC_relativepsi50; +EDCs[E.relativepsi50].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.relativepsi50].prerun=true; + +static DALEC_EDC_PARAMETER_LOG_RATIO_STRUCT EDC_vcmax_lcma; + //EDC: ratio of Vcmax25 to LCMA +EDC_vcmax_lcma.numerator_index=P.Vcmax25; +EDC_vcmax_lcma.denominator_index=P.LCMA; +EDC_vcmax_lcma.mean_ratio = 1.0399; // From TRY database +EDC_vcmax_lcma.std_ratio = 0.1956; // From TRY database +EDCs[E.vcmax_lcma].data=&EDC_vcmax_lcma; +EDCs[E.vcmax_lcma].function=&DALEC_EDC_PARAMETER_LOG_RATIO; +EDCs[E.vcmax_lcma].prerun=true; + +//State ranges + static DALEC_EDC_STATE_RANGES_STRUCT EDC_sr; + + //Create array (1x number of pools) for minimum and max values + //Index exactly corresponds to "POOLS" indices + + EDC_sr.min_val=calloc(DALECmodel->nopools,sizeof(double)); + + EDC_sr.max_val=calloc(DALECmodel->nopools,sizeof(double)); + + int n; + for (n=0;nnopools;n++){ + EDC_sr.min_val[n]=-INFINITY; + EDC_sr.max_val[n]=INFINITY;} + + EDC_sr.min_val[S.C_lab]=0; + EDC_sr.max_val[S.C_lab]=(DALECmodel->PARS_INFO.parmax[P.i_labile]); + + EDC_sr.min_val[S.C_fol]=0; + EDC_sr.max_val[S.C_fol]=(DALECmodel->PARS_INFO.parmax[P.i_foliar]); + + EDC_sr.min_val[S.C_roo]=0; + EDC_sr.max_val[S.C_roo]=(DALECmodel->PARS_INFO.parmax[P.i_root]); + + EDC_sr.min_val[S.C_woo]=0; + EDC_sr.max_val[S.C_woo]=(DALECmodel->PARS_INFO.parmax[P.i_wood]); + + EDC_sr.min_val[S.C_cwd]=0; + EDC_sr.max_val[S.C_cwd]=(DALECmodel->PARS_INFO.parmax[P.i_cwd]); + + EDC_sr.min_val[S.C_lit]=0; + EDC_sr.max_val[S.C_lit]=(DALECmodel->PARS_INFO.parmax[P.i_lit]); + + EDC_sr.min_val[S.C_som]=0; + EDC_sr.max_val[S.C_som]=(DALECmodel->PARS_INFO.parmax[P.i_som]); + + EDC_sr.min_val[S.H2O_LY1]=0; + + + EDC_sr.min_val[S.H2O_LY2]=0; + + + EDC_sr.min_val[S.H2O_LY3]=0; + + + EDC_sr.min_val[S.H2O_SWE]=0; +// EDC_sr.max_val[S.H2O_SWE]=DALECmodel->PARS_INFO.parmax[P.i_SWE]; + + EDC_sr.min_val[S.E_LY1]=0; + EDC_sr.min_val[S.E_LY2]=0; + EDC_sr.min_val[S.E_LY3]=0; + + EDC_sr.min_val[S.D_LAI]=0; + EDC_sr.max_val[S.D_LAI]=DALECmodel->PARS_INFO.parmax[P.lambda_max]; + + EDC_sr.min_val[S.D_SCF]=0; + EDC_sr.max_val[S.D_SCF]=1; + + EDC_sr.min_val[S.D_TEMP_LY1]=173.15; + EDC_sr.max_val[S.D_TEMP_LY1]=373.15; + + EDC_sr.min_val[S.D_TEMP_LY2]=173.15; + EDC_sr.max_val[S.D_TEMP_LY2]=373.15; + + EDC_sr.min_val[S.D_TEMP_LY3]=173.15; + EDC_sr.max_val[S.D_TEMP_LY3]=373.15; + + EDC_sr.min_val[S.D_LF_LY1]=0; + EDC_sr.max_val[S.D_LF_LY1]=1; + + EDC_sr.min_val[S.D_LF_LY3]=0; + EDC_sr.max_val[S.D_LF_LY3]=1; + + EDC_sr.min_val[S.D_SM_LY1]=0; + EDC_sr.max_val[S.D_SM_LY1]=1; + + EDC_sr.min_val[S.D_SM_LY2]=0; + EDC_sr.max_val[S.D_SM_LY2]=1; + + EDC_sr.min_val[S.D_SM_LY3]=0; + EDC_sr.max_val[S.D_SM_LY3]=1; + +// EDC_sr.min_val[S.M_LAI_MAX]=-INFINITY; // get a better value from Alex N. +// EDC_sr.max_val[S.M_LAI_MAX]=INFINITY; // get a better value from Alex N. + +// EDC_sr.min_val[S.M_LAI_TEMP]=-INFINITY; // get a better value from Alex N. +// EDC_sr.max_val[S.M_LAI_TEMP]=INFINITY; // get a better value from Alex N. + +//Adding EDC to the EDCs list + + EDCs[E.state_ranges].data=&EDC_sr; + EDCs[E.state_ranges].function=&DALEC_EDC_STATE_RANGES; + EDCs[E.state_ranges].prerun=false; + + static DALEC_EDC_TRAJECTORY_STRUCT EDC_st; + + static int edc_pool_indices[14]; + static double edc_pool_eqf[14]; +EDC_st.pool_indices=edc_pool_indices; +EDC_st.pool_eqf=edc_pool_eqf; +EDC_st.no_pools_to_check=14; + +EDC_st.pool_indices[0]=S.C_lab; +EDC_st.pool_indices[1]=S.C_fol; +EDC_st.pool_indices[2]=S.C_roo; +EDC_st.pool_indices[3]=S.C_woo; +EDC_st.pool_indices[4]=S.C_cwd; +EDC_st.pool_indices[5]=S.C_lit; +EDC_st.pool_indices[6]=S.C_som; +EDC_st.pool_indices[7]=S.H2O_LY1; +EDC_st.pool_indices[8]=S.H2O_LY2; +EDC_st.pool_indices[9]=S.H2O_LY3; +EDC_st.pool_indices[10]=S.H2O_SWE; +// EDC_st.pool_indices[11]=S.E_LY1; +// EDC_st.pool_indices[12]=S.E_LY2; +// EDC_st.pool_indices[13]=S.E_LY3; +//EDC_st.pool_indices[12]=S.M_LAI_MAX;``` +//EDC_st.pool_indices[13]=S.M_LAI_TEMP; + + +for (n=0;nncdf_data.EDC_EQF;printf("DATA->ncdf_data.EDC_EQF = %2.2f\n",DATA->ncdf_data.EDC_EQF);} +// EDC_st.pool_eqf[9]=10; +// EDC_st.pool_eqf[10]=10; + +// //Rest can be done by code without additional input + +EDCs[E.state_trajectories].data=&EDC_st; +EDCs[E.state_trajectories].function=&DALEC_EDC_TRAJECTORY; +EDCs[E.state_trajectories].prerun=false; + +//Eventually adopt more succinct notation (to consider) +//e.g. INEQUALITY_EDC(P.t_cwd,P.t_som,EDCs[E.cwdsomtor]) + + static DALEC_EDC_NSC_ABGB_RATIO_STRUCT EDC_nscr; + + // + EDC_nscr.no_other_pool_indices=3; + static int nscratio_other_pool_indices[3]; + + EDC_nscr.other_pool_indices=nscratio_other_pool_indices; + EDC_nscr.other_pool_indices[0]=S.C_fol; + EDC_nscr.other_pool_indices[1]=S.C_roo; + EDC_nscr.other_pool_indices[2]=S.C_woo; + EDC_nscr.nsc_pool_index=S.C_lab; + + + EDCs[E.nsc_ratio].data=&EDC_nscr; + EDCs[E.nsc_ratio].function=&DALEC_EDC_NSC_ABGB_RATIO; + EDCs[E.nsc_ratio].prerun=false; + +static DALEC_EDC_POOL_RATIO_STRUCT EDC_cfcrr; + // + EDC_cfcrr.numerator_index=S.C_fol; + EDC_cfcrr.denominator_index=S.C_roo; + + EDCs[E.cfcr_ratio].data=&EDC_cfcrr; + EDCs[E.cfcr_ratio].function=&DALEC_EDC_POOL_RATIO; + EDCs[E.cfcr_ratio].prerun=false; + +static DALEC_EDC_FLUX_RATIO_STRUCT EDC_fffrr; + // + EDC_fffrr.numerator_flux_index=F.foliar_prod; + EDC_fffrr.denominator_flux_index=F.root_prod; + + EDCs[E.fffr_ratio].data=&EDC_fffrr; + EDCs[E.fffr_ratio].function=&DALEC_EDC_FLUX_RATIO; + EDCs[E.fffr_ratio].prerun=false; + +static DALEC_EDC_MEAN_TEMP_STRUCT EDC_mean_ly1_temp, EDC_mean_ly2_temp, EDC_mean_ly3_temp; + + // + EDC_mean_ly1_temp.temp_index=S.D_TEMP_LY1; + EDCs[E.mean_ly1_temp].data=&EDC_mean_ly1_temp; + EDCs[E.mean_ly1_temp].function=&DALEC_EDC_MEAN_TEMP; + EDCs[E.mean_ly1_temp].prerun=false; + + + EDC_mean_ly2_temp.temp_index=S.D_TEMP_LY2; + EDCs[E.mean_ly2_temp].data=&EDC_mean_ly2_temp; + EDCs[E.mean_ly2_temp].function=&DALEC_EDC_MEAN_TEMP; + EDCs[E.mean_ly2_temp].prerun=false; + + + EDC_mean_ly3_temp.temp_index=S.D_TEMP_LY3; + EDCs[E.mean_ly3_temp].data=&EDC_mean_ly3_temp; + EDCs[E.mean_ly3_temp].function=&DALEC_EDC_MEAN_TEMP; + EDCs[E.mean_ly3_temp].prerun=false; + +//*************** Set up State Proximity EDC *************** +static DALEC_EDC_STATE_PROXIMITY_STRUCT EDC_prox; +static int prox_pool_indices[3]; // We are checking 3 layers + +EDC_prox.pool_indices = prox_pool_indices; +EDC_prox.no_pools_to_check = 3; + +// Assign the diagnostic temperature pools +EDC_prox.pool_indices[0] = S.D_TEMP_LY1; +EDC_prox.pool_indices[1] = S.D_TEMP_LY2; +EDC_prox.pool_indices[2] = S.D_TEMP_LY3; + +// Set your penalty thresholds +EDC_prox.max_allowed_diff = 2.0; // Max allowed difference in degrees K (or C) +EDC_prox.penalty_scale = 1.5; // Steepness of the penalty curve (smaller is more strict) + +EDCs[E.state_proximity].data = &EDC_prox; +EDCs[E.state_proximity].function = &DALEC_EDC_STATE_PROXIMITY; +EDCs[E.state_proximity].prerun = false; + +//ecological +//EDCOPE.SUPPORT_LITCWDSOM_trpar_EDC=true; +//dynamical +//EDCOPE.SUPPORT_POOL_SSP_EDC=true; +//Numerical checks +//EDCOPE.SUPPORT_FINITE_EDC=true; + + + + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + + +//Set SUPPORT_OBS values to true if model supports external observation operations. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_SIF_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_H_OBS=true; +OBSOPE.SUPPORT_LE_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; +OBSOPE.SUPPORT_SCF_OBS=true; +OBSOPE.SUPPORT_SWE_OBS=true; + + + + +// OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Vcmax25_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +OBSOPE.SUPPORT_NBEmrg_OBS=true; +OBSOPE.SUPPORT_CUEmrg_OBS=true; +OBSOPE.SUPPORT_LCMA_OBS=true; +OBSOPE.SUPPORT_clumping_OBS=true; +// OBSOPE.SUPPORT_LAD_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//add PEQ value and unc based on previous MCMC, all the changes are marked with "*pMCMC*" +OBSOPE.SUPPORT_r_ch4_OBS=true; +OBSOPE.SUPPORT_S_fv_OBS=true; +OBSOPE.SUPPORT_rhch4_rhco2_OBS=true; + +//GPP-specific variables//Assuming FLUXNET GPP is assumed to be Ag. + //Wohlfahrt & Gu, 2015 +OBSOPE.GPP_flux=F.gpp; +// For constraint on emergent autotrophic fraction +OBSOPE.Rauto_flux=F.resp_auto; +// For constraint on emergent heterotrophic & fire fraction +OBSOPE.Rhet_flux=F.rh_co2; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variables +OBSOPE.ET_flux=F.ets; +//LE variables +OBSOPE.LE_flux=F.latent_heat; +//H variables +OBSOPE.H_flux=F.sensible_heat; +//Runoff variables +static int ROFF_fluxes[4]; +ROFF_fluxes[0]=F.q_ly1; +ROFF_fluxes[1]=F.q_ly2; +ROFF_fluxes[2]=F.q_ly3; +ROFF_fluxes[3]=F.q_surf; + +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=4; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[4]; +EWT_h2o_pools[0]=S.H2O_LY1; +EWT_h2o_pools[1]=S.H2O_LY2; +EWT_h2o_pools[2]=S.H2O_LY3; +EWT_h2o_pools[3]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=4; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//SCF-specific variables +OBSOPE.SCF_pool=S.D_SCF; + +//SWE-specific variables +OBSOPE.SWE_pool=S.H2O_SWE; + +//Vcmax25 parameters +OBSOPE.Vcmax25_PARAM=P.Vcmax25; +// //C3frac parameters +// OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_som; +OBSOPE.LCMA_PARAM=P.LCMA; +OBSOPE.clumping_PARAM=P.clumping; +//OBSOPE.LAD_PARAM=P.LAD; + +//CH4-specific variables +OBSOPE.CH4_flux = F.rh_ch4; + +//add PEQ value and unc from previous MCMC *pMCMC* +OBSOPE.r_ch4_PARAM = P.r_ch4; +OBSOPE.S_fv_PARAM = P.S_fv; +OBSOPE.rhch4_rhco2_flux = F.rh_ch4/F.rh_co2; + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1109/PARS_INFO_1109.c === + +#pragma once +#include "DALEC_1109_INDICES.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + + +int PARS_INFO_1109(DALEC * DALECmodel){ + +struct DALEC_1109_PARAMETERS P=DALEC_1109_PARAMETERS; + + +DALECmodel->PARS_INFO.parmin= calloc(DALECmodel->nopars, sizeof(double)); +DALECmodel->PARS_INFO.parmax= calloc(DALECmodel->nopars, sizeof(double)); +//Abbreviate + +double * parmin = DALECmodel->PARS_INFO.parmin; +double * parmax =DALECmodel->PARS_INFO.parmax; +/*Litter decomposition rate*/ +parmin[P.tr_lit2som]=0.01; +parmax[P.tr_lit2som]=0.99; + +/*CWD decomposition rate*/ +parmin[P.tr_cwd2som]=0.01; +parmax[P.tr_cwd2som]=0.99; + +/*Autotrophic maintenance respiration coefficient for roots - turnover rate at 25oC (d-1)*/ +parmin[P.rauto_mr_r]=0.0001; +parmax[P.rauto_mr_r]=0.01; + +/*Autotrophic maintenance respiration coefficient for wood - turnover rate at 25oC (d-1)*/ +parmin[P.rauto_mr_w]=0.000001; +parmax[P.rauto_mr_w]=0.005; + +/*Autotrophic maintenance respiration Q10 parameter*/ +parmin[P.rauto_mr_q10]=1.0; +parmax[P.rauto_mr_q10]=5.0; + +/*Dark respiration Q10 parameter*/ +parmin[P.rauto_mrd_q10]=1.0; +parmax[P.rauto_mrd_q10]=5.0; + +/*Growth yield (g C appearing in new biomass per g C used for growth; "growth yield" in Cannell and Thornley 2000)*/ +parmin[P.rauto_gr]=0.60; +parmax[P.rauto_gr]=0.95; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.01; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.1; + +/*TOR CWD*/ +parmin[P.t_cwd]=0.00005; +parmax[P.t_cwd]=0.05; + +/*TOR SOM*/ +parmin[P.t_som]=0.0000001; +parmax[P.t_som]=0.01; + +/*\Q10 = 1.2-2.0*/ +parmin[P.Q10rhco2]=1; +parmax[P.Q10rhco2]=5.0; + +/*LMCA*; Kattge et al. 2011*;*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=100000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C CWD*/ +parmin[P.i_cwd]=1.0; +parmax[P.i_cwd]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*Retention parameter (b)*/ +parmin[P.retention]=1.5; +parmax[P.retention]=10; + +/*"PAW SM at t0"*/ +parmin[P.i_PAW_SM]=0.01; +parmax[P.i_PAW_SM]=1; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +parmin[P.hydr_cond]=1e-9; +parmax[P.hydr_cond]=1e-4; + +/*Maximum infiltration (mm/day)*/ +parmin[P.max_infil]=1; +parmax[P.max_infil]=100; + +/*PUW SM at t=0*/ +parmin[P.i_PUW_SM]=0.01; +parmax[P.i_PUW_SM]=1; + +/*PAW porosity*/ +parmin[P.PAW_por]=0.2; +parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +parmin[P.PUW_por]=0.2; +parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +parmin[P.field_cap]=0.01; +parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +parmin[P.PAW_z]=0.01; +parmax[P.PAW_z]=20; + +/*PUW depth (m)*/ +parmin[P.PUW_z]=0.01; +parmax[P.PUW_z]=100; + +/*PAW volumetric heat capacity (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)*/ +parmin[P.PAW_vhc]=1.3e6; +parmax[P.PAW_vhc]=3e6; + +/*PUW volumetric heat capacity (https://www.sciencedirect.com/topics/engineering/volumetric-heat-capacity)*/ +parmin[P.PUW_vhc]=1.3e6; +parmax[P.PUW_vhc]=3e6; + +/*Runoff excess*/ +parmin[P.Q_excess]=0.01; +parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +parmin[P.Med_g1]=1.79; +parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +parmin[P.Vcmax25]=1; +parmax[P.Vcmax25]=150; + +/*Tminmin scaling factor*/ +parmin[P.Tminmin]=258.15; +parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +parmin[P.Tminmax]=273.15; +parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance (m/s)*/ +parmin[P.ga]=0.001; +parmax[P.ga]=10.0; + +/*Tupp*/ +parmin[P.Tupp]=249.15; // 299.15-50 +parmax[P.Tupp]=318.15; + +/*Tdown*/ +parmin[P.Tdown]=213.15; // 263.15-50 +parmax[P.Tdown]=286.15; + +/*Clumping index*/ +parmin[P.clumping]=0.35; +parmax[P.clumping]=1.0; + +/*PAR reflectance*/ +parmin[P.leaf_refl_par]=0.05; +parmax[P.leaf_refl_par]=0.5; + +/*NIR reflectance*/ +parmin[P.leaf_refl_nir]=0.3; +parmax[P.leaf_refl_nir]=0.7; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +parmin[P.i_SWE]=0.000001; +parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +parmin[P.min_melt]=263.15; +parmax[P.min_melt]=283.15; + +/*sn2: slope*/ +parmin[P.melt_slope]=0.00001; +parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar; SCF = SWE/(SWE +SWEcritical_par) */ +parmin[P.scf_scalar]=10; +parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)\n jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +parmin[P.S_fv]=1; +parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +parmin[P.thetas_opt]=0.2; +parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +parmin[P.fwc]=0.01; +parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +parmin[P.r_ch4]=0.001; +parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +parmin[P.Q10ch4]=1.0; +parmax[P.Q10ch4]=5.0; + +/* maxPevap in mm/day*/ +parmin[P.maxPevap]=0.01; +parmax[P.maxPevap]=100; + +/*Mean temperature at leaf onset (T_phi) (degrees kelvin)*/ +parmin[P.T_phi]=268.15; +parmax[P.T_phi]=323.15; + +/*Spatial range of mean temperature at leaf onset (T_r) (degrees C or degrees kelvin)*/ +parmin[P.T_range]=0.1; +parmax[P.T_range]=10.0; + +/*LAI linear growth constant (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.plgr]=0.001; +parmax[P.plgr]=0.5; + +/*Inverse of leaf longevity during senescence period (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.k_leaf]=0.001; +parmax[P.k_leaf]=0.5; + +/*Intrinsic maximum LAI (m^2 m^-2)*/ +parmin[P.lambda_max]=0.1; +parmax[P.lambda_max]=10.0; + +/*Target survival time for LAI under water-deficit conditions (days; or same unit as ET and PAW)*/ +parmin[P.tau_W]=0.1; +parmax[P.tau_W]=300; + +/*Mean daylength at leaf shedding (t_c; in units of hours sunlight per day)*/ +parmin[P.time_c]=2; +parmax[P.time_c]=22; + +/*Spatial range of mean daylength at leaf shedding (t_r)*/ +parmin[P.time_r]=0.1; +parmax[P.time_r]=6.0; + +/*initialization of temperature memory at t=0 (in absolute temperature units)*/ +parmin[P.init_T_mem]=268.14; +parmax[P.init_T_mem]=323.15; + +/*initialization of water/structural memory (fractional value of intrinsic maximum LAI)*/ +parmin[P.init_LAIW_mem]=0.01; +parmax[P.init_LAIW_mem]=1; + +/*Inverse of leaf longevity at any period i.e. background turnover (days-1)*/ +parmin[P.t_foliar]=0.001; +parmax[P.t_foliar]=0.1; + +/*PAW energy per meter soil (~ dry at -50C to wet at 50C)*/ +parmin[P.i_PAW_E]=2e8; +parmax[P.i_PAW_E]=2e9; + +/*PUW energy pool (SWdown Wm2* seconds in year for very very rough OOM estimate)*/ +parmin[P.i_PUW_E]=2e8; +parmax[P.i_PUW_E]=2e9; + +/*PSI 50: water potential when soil-plant continum is at 50% hydraulic conductivity (-MPa)*/ +parmin[P.psi_50]=0.1; +parmax[P.psi_50]=30; + +/*Beta function normalized logistic growth rate */ +parmin[P.beta_lgr]=4.1; +parmax[P.beta_lgr]=50; + +/*Ratio of carbon allocation to root per target foliar pool size (gC/gC)*/ +parmin[P.phi_RL]=0.0001; +parmax[P.phi_RL]=5.; + + +/*Ratio of carbon allocation to wood per target foliar pool size (gC/gC)*/ +parmin[P.phi_WL]=0.0001; +parmax[P.phi_WL]=50.; + + +/*Deep thermal conductivity in W/m/K */ +parmin[P.thermal_cond]=0.3; +parmax[P.thermal_cond]=2; + + +/*Surface soil thermal conductivity in W/m/K */ +parmin[P.thermal_cond_surf]=0.03; +parmax[P.thermal_cond_surf]=2; + + +/*Surface soil thermal conductivity in W/m/K */ +parmin[P.q10canopy]=1; +parmax[P.q10canopy]=5; + + /*Surface soil thermal conductivity in W/m/K */ +parmin[P.canopyRdsf]=0.005; +parmax[P.canopyRdsf]=0.025; + + /*Sublimation rate: mm/day/SCF/kPha/(MJ/m2/d) Biggest = 1/0.5/2/2; Smallest = 1/1/10/10/*/ +parmin[P.sublimation_rate]=0.001; +parmax[P.sublimation_rate]=10; + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1109/EDC1_1109.c === + +#pragma once +int EDC1_1109(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1109_PARAMETERS P=DALEC_1109_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +// double const fauto=pars[P.f_auto]; +// double const ffol=(1-fauto)*pars[P.f_foliar]; +// double const flab=(1-fauto)*pars[P.f_lab]; +// double const froot=(1-fauto-flab)*pars[P.f_root]; +// double const fwood=1-fauto-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +// double const fsom=fwood+(froot+flab)*pars[P.tr_lit2som]/(pars[P.tr_lit2som]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +// double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_som]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2som]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +//We can remove this, H2O controls on RHCO2 make it difficult to justify +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +//Will want to remove this at some point when Alex's new scheme kicks in! +/*Allocation to canopy is comparable to allocation to fine roots*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((flab)>5*froot | (flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1109/MODEL_INFO_1109.c === + +#pragma once +#include "PARS_INFO_1109.c" +#include "DALEC_1109.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF2.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1109(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1109_MODCONFIG(&DALECmodel,DATA); +static MLF MLF;DALEC_MLF2_MODCONFIG(&MLF); + +/*Step 2: Fill structure with model-specific info*/ + +//Corresponding likelihood function + + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->noedcs=DALECmodel.noedcs; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +//DALECmodel.edc1=EDC1_1109; +//DALECmodel.edc2=EDC2_1109; + + + + + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + + + //Copying pointers + DATA->parmin=DALECmodel.PARS_INFO.parmin; + DATA->parmax=DALECmodel.PARS_INFO.parmax; + + +//oksofar("about to declare EDCD"); +//printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +//EDCSETUP(*DATA,&DALECmodel.EDCD); + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +/*Pointing to MLF*/ +DATA->MLF=MLF.mlf; + +/*Pointing to EMLF*/ +DATA->EMLF=EDC_DALEC_MLF2_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1109/DALEC_1109.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "DALEC_1109_INDICES.c" +#include "PARS_INFO_1109.c" +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../DALEC_ALL/LIU_AN_ET_REFACTOR.c" +#include "../DALEC_ALL/CH4_MODULES/HET_RESP_RATES_JCR.c" +#include "../DALEC_ALL/KNORR_ALLOCATION.c" +#include "../DALEC_ALL/SOIL_TEMP_AND_LIQUID_FRAC.c" +#include "../DALEC_ALL/INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS.c" +#include "../DALEC_ALL/ALLOC_AND_AUTO_RESP_FLUXES.c" + + +//Returns structure with sources and sinks, matches number of fluxes +int DALEC_1109_FLUX_SOURCES_SINKS(DALEC * DALECmodel){ + + + struct DALEC_1109_FLUXES F=DALEC_1109_FLUXES; + struct DALEC_1109_POOLS S=DALEC_1109_POOLS; + + // /Step 1. Declare & initialize + DALEC_FLUX_SOURCE_SINK_MATRIX FIOMATRIX; + // external source or pool sink, or not conserved quantity + //Default = -1 + + FIOMATRIX.SOURCE=calloc(DALECmodel->nofluxes, sizeof(int)); + FIOMATRIX.SINK=calloc(DALECmodel->nofluxes, sizeof(int)); + + + int n; + for (n=0;nnofluxes; n++){FIOMATRIX.SOURCE[n]=-1;FIOMATRIX.SINK[n]=-1;} + + + //Step 2. Define + + + // C_lab + FIOMATRIX.SINK[F.gpp]=S.C_lab; + FIOMATRIX.SOURCE[F.resp_auto_maint]=S.C_lab; + FIOMATRIX.SOURCE[F.foliar_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.root_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.wood_prod]=S.C_lab; + FIOMATRIX.SOURCE[F.resp_auto_growth]=S.C_lab; + FIOMATRIX.SOURCE[F.f_lab]=S.C_lab; + FIOMATRIX.SOURCE[F.fx_lab2lit]=S.C_lab; + + + // C_fol + FIOMATRIX.SINK[F.foliar_prod]=S.C_fol; + FIOMATRIX.SOURCE[F.fol2lit]=S.C_fol; + FIOMATRIX.SOURCE[F.f_fol]=S.C_fol; + FIOMATRIX.SOURCE[F.fx_fol2lit]=S.C_fol; + + // C_roo + FIOMATRIX.SINK[F.root_prod]=S.C_roo; + FIOMATRIX.SOURCE[F.roo2lit]=S.C_roo; + FIOMATRIX.SOURCE[F.f_roo]=S.C_roo; + FIOMATRIX.SOURCE[F.fx_roo2lit]=S.C_roo; + + // C_woo + FIOMATRIX.SINK[F.wood_prod]=S.C_woo; + FIOMATRIX.SOURCE[F.woo2cwd]=S.C_woo; + FIOMATRIX.SOURCE[F.f_woo]=S.C_woo; + FIOMATRIX.SOURCE[F.fx_woo2cwd]=S.C_woo; + + + // C_lit + FIOMATRIX.SINK[F.fx_lab2lit]=S.C_lit; + FIOMATRIX.SINK[F.fol2lit]=S.C_lit; + FIOMATRIX.SINK[F.fx_fol2lit]=S.C_lit; + FIOMATRIX.SINK[F.roo2lit]=S.C_lit; + FIOMATRIX.SINK[F.fx_roo2lit]=S.C_lit; + FIOMATRIX.SOURCE[F.ae_rh_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.an_rh_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.f_lit]=S.C_lit; + FIOMATRIX.SOURCE[F.lit2som]=S.C_lit; + FIOMATRIX.SOURCE[F.fx_lit2som]=S.C_lit; + + // C_cwd + FIOMATRIX.SINK[F.woo2cwd]=S.C_cwd; + FIOMATRIX.SINK[F.fx_woo2cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.ae_rh_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.an_rh_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.f_cwd]=S.C_cwd; + FIOMATRIX.SOURCE[F.cwd2som]=S.C_cwd; + FIOMATRIX.SOURCE[F.fx_cwd2som]=S.C_cwd; + + // C_som + FIOMATRIX.SINK[F.cwd2som]=S.C_som; + FIOMATRIX.SINK[F.fx_cwd2som]=S.C_som; + FIOMATRIX.SINK[F.lit2som]=S.C_som; + FIOMATRIX.SINK[F.fx_lit2som]=S.C_som; + FIOMATRIX.SOURCE[F.ae_rh_som]=S.C_som; + FIOMATRIX.SOURCE[F.an_rh_som]=S.C_som; + FIOMATRIX.SOURCE[F.f_som]=S.C_som; + + // H2O_SWE + FIOMATRIX.SOURCE[F.melt]=S.H2O_SWE; + FIOMATRIX.SOURCE[F.sublimation]=S.H2O_SWE; + FIOMATRIX.SINK[F.snowfall]=S.H2O_SWE; + + // H2O_PAW + FIOMATRIX.SINK[F.infil]=S.H2O_PAW; + FIOMATRIX.SOURCE[F.et]=S.H2O_PAW; + FIOMATRIX.SOURCE[F.paw2puw]=S.H2O_PAW; + FIOMATRIX.SOURCE[F.q_paw]=S.H2O_PAW; + + // H2O_PUW + FIOMATRIX.SOURCE[F.q_puw]=S.H2O_PUW; + FIOMATRIX.SINK[F.paw2puw]=S.H2O_PUW; + + // E_PAW + FIOMATRIX.SINK[F.gh_in]=S.E_PAW; + FIOMATRIX.SINK[F.infil_e]=S.E_PAW; + FIOMATRIX.SOURCE[F.et_e]=S.E_PAW; + FIOMATRIX.SOURCE[F.q_paw_e]=S.E_PAW; + FIOMATRIX.SOURCE[F.paw2puw_e]=S.E_PAW; + FIOMATRIX.SOURCE[F.paw2puw_th_e]=S.E_PAW; + + // E_PUW + FIOMATRIX.SINK[F.paw2puw_e]=S.E_PUW; + FIOMATRIX.SINK[F.geological]=S.E_PUW; + FIOMATRIX.SINK[F.paw2puw_th_e]=S.E_PUW; + FIOMATRIX.SOURCE[F.q_puw_e]=S.E_PUW; + + + +DALECmodel->FIOMATRIX = FIOMATRIX; + + +//DALEC flux indices + +//Calculate State source sink matrix +DALEC_STATE_SOURCE_SINK_MATRIX_CONFIG(DALECmodel); +return 0; + +} + + + + + + + + + +int DALEC_1109(DATA DATA, double const *pars){ + + + + + +struct DALEC_1109_PARAMETERS P=DALEC_1109_PARAMETERS; +struct DALEC_1109_FLUXES F=DALEC_1109_FLUXES; +struct DALEC_1109_POOLS S=DALEC_1109_POOLS; + + + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *SKT=DATA.ncdf_data.SKT.values; +double *STRD=DATA.ncdf_data.STRD.values; + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +//double pi=3.1415927; +double pi=DGCM_PI; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + + /*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_cwd]=pars[P.i_cwd]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=HYDROFUN_MOI2EWT(pars[P.i_PAW_SM],pars[P.PAW_por],pars[P.PAW_z]); + POOLS[S.H2O_PUW]=HYDROFUN_MOI2EWT(pars[P.i_PUW_SM],pars[P.PUW_por],pars[P.PUW_z]); + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + /*Energy pools*/ + POOLS[S.E_PAW]=pars[P.i_PAW_E]*pars[P.PAW_z]; + POOLS[S.E_PUW]=pars[P.i_PUW_E]*pars[P.PUW_z]; + + + //---INITIALIZING DIAGNOSTIC STATES--- + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; //LAI + + if (POOLS[S.H2O_SWE]>0){ + POOLS[S.D_SCF]=POOLS[S.H2O_SWE]/(POOLS[S.H2O_SWE]+pars[P.scf_scalar]);} //snow cover fraction} + else + {POOLS[S.D_SCF]=0;}; + + + //Diagnostic time-invariant quantities + // Porosity scaling factor (see line 124 of HESS paper) + double psi_porosity = -0.117/100; + double PAWmax=pars[P.PAW_por]*pars[P.PAW_z]*1000; //PAW capacity in mm + double PUWmax=pars[P.PUW_por]*pars[P.PUW_z]*1000; //PUW capacity in mm + + + + //INITIALIZING PAW and PUW soil moisture + POOLS[S.D_SM_PAW]=HYDROFUN_EWT2MOI(POOLS[S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); //soil moisture PAW + POOLS[S.D_SM_PUW]=HYDROFUN_EWT2MOI(POOLS[S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]);//soil moisture PUW +// Convert to potential + + POOLS[S.D_PSI_PAW]=HYDROFUN_MOI2PSI( POOLS[S.D_SM_PAW],psi_porosity,pars[P.retention]); + POOLS[S.D_PSI_PUW]=HYDROFUN_MOI2PSI( POOLS[S.D_SM_PUW],psi_porosity,pars[P.retention]); + + + + + //Declare stryct + SOIL_TEMP_AND_LIQUID_FRAC_STRUCT PAWSOILTEMP, PUWSOILTEMP; + //Populate with run-specific constrants + //PAW + PAWSOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.PAW_vhc]; ;//J/m3/K + PAWSOILTEMP.IN.depth = pars[P.PAW_z];//m + PAWSOILTEMP.IN.soil_water = POOLS[S.H2O_PAW];//mm (or kg/m2) + PAWSOILTEMP.IN.internal_energy = POOLS[S.E_PAW];//Joules + //Pass pointer to function + SOIL_TEMP_AND_LIQUID_FRAC(&PAWSOILTEMP); //Outputs are in K + + //Store outputs + POOLS[S.D_TEMP_PAW]=PAWSOILTEMP.OUT.TEMP; //In K + POOLS[S.D_LF_PAW]=PAWSOILTEMP.OUT.LF; + + //PUW + PUWSOILTEMP.IN.dry_soil_vol_heat_capacity =pars[P.PUW_vhc]; ;//J/m3/K + PUWSOILTEMP.IN.depth = pars[P.PUW_z];//m + PUWSOILTEMP.IN.soil_water = POOLS[S.H2O_PUW];//mm (or kg/m2) + PUWSOILTEMP.IN.internal_energy = POOLS[S.E_PUW];//Joules + //Pass pointer to function + SOIL_TEMP_AND_LIQUID_FRAC(&PUWSOILTEMP);//Outputs are in K + //Store outputs + POOLS[S.D_TEMP_PUW]=PUWSOILTEMP.OUT.TEMP; //In K + POOLS[S.D_LF_PUW]=PUWSOILTEMP.OUT.LF; + + + + + + //******************Delcare KNORR STRUCT********************* + KNORR_ALLOCATION_STRUCT KNORR; +//define time-invariant parameters + KNORR.IN.deltat=deltat; + KNORR.IN.n=0; + KNORR.IN.latitude=DATA.ncdf_data.LAT; + KNORR.IN.T_phi=pars[P.T_phi]; + KNORR.IN.T_r=pars[P.T_range]; + KNORR.IN.plgr=pars[P.plgr]; + KNORR.IN.k_L=pars[P.k_leaf]; + KNORR.IN.tau_W=pars[P.tau_W];//0.00000001;// + KNORR.IN.t_c=pars[P.time_c]; + KNORR.IN.t_r=pars[P.time_r];; + KNORR.IN.lambda_max=pars[P.lambda_max]; + //Initialize memory states + + POOLS[S.M_LAI_TEMP]=pars[P.init_T_mem]; + POOLS[S.M_LAI_MAX]=pars[P.init_LAIW_mem]*pars[P.lambda_max]; + + + //******************Allocation fluxes struct********************** +// +// typedef struct { +// struct { +// double TEMP;//deg C +// double SRAD;//MJ m2 d +// double NSC;//Clab +// double PAW_SM;//m3/m3 +// double parameter1;//replace with any name, no constraints on naming convention +// double parameter2;//replace with any name, no constraints on naming convention +// } IN; +// struct { +// double * AUTO_RESP_MAINTENANCE; +// double * AUTO_RESP_GROWTH; +// double * ALLOC_FOL; +// double * ALLOC_WOO; +// double * ALLOC_ROO;}OUT; +// }ALLOC_AND_AUTO_RESP_FLUXES_STRUCT; + + + + //Declare + //Plant carbon allocation. + ALLOC_AND_AUTO_RESP_FLUXES_STRUCT ARFLUXES; + //define time-invariant parameters here + ARFLUXES.IN.mr_r=pars[P.rauto_mr_r];// + ARFLUXES.IN.mr_w=pars[P.rauto_mr_w];// + ARFLUXES.IN.gr=pars[P.rauto_gr];// + ARFLUXES.IN.Q10mr=pars[P.rauto_mr_q10];// + + + //Heterotrophic respiration module + HET_RESP_RATES_JCR_STRUCT HRJCR; + //define time invariant parameters here + +/* jc prep input for methane module*/ + HRJCR.IN.S_FV=pars[P.S_fv]; + HRJCR.IN.SM_OPT=pars[P.thetas_opt]; + HRJCR.IN.FWC=pars[P.fwc]; + HRJCR.IN.R_CH4=pars[P.r_ch4]; + HRJCR.IN.Q10CH4=pars[P.Q10ch4]; + HRJCR.IN.Q10CO2=pars[P.Q10rhco2]; + + + + + + +/*Combustion factors*/ +double CF[7];//AAB changed this +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + +/*foliar carbon transfer intermediate variables*/ +double Fcfolavailable; + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + +double LAI=POOLS[p+S.D_LAI]; + + +/*Calculate light extinction coefficient*/ +double B = (DOY[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +double LST = (int) (DOY[n]*24*60) % (24*60); +LST=0.5*24*60; +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*DATA.ncdf_data.LAT)*sin(pi/180*DA)+cos(pi/180*DATA.ncdf_data.LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +double zenith_angle = 90-alpha; + +//printf("SZA local = %2.2f, SZA global = %2.2f, SZA diff = %2.2f\n", zenith_angle,DATA.ncdf_data.SZA.values,DATA.ncdf_data.SZA.values - zenith_angle); +//double LAD = 1.0; //leaf angle distribution +//double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 + +double LAD = 0.5; //leaf angle distribution// optimize leaf angle distribution. +double VegK = LAD/cos(zenith_angle/180*pi); + +/*Temp scaling factor*/ +double g; +double Tminmin = pars[P.Tminmin] - DGCM_TK0C; +double Tminmax = pars[P.Tminmax] - DGCM_TK0C; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor + //We're also multiplying beta by cold-weather stress +//double psi_PAW0 = HYDROFUN_MOI2PSI(max(POOLS[p+S.D_SM_PAW],0),psi_porosity,pars[P.retention]); +//double psi_PAW0 = HYDROFUN_MOI2PSI(POOLS[p+S.D_SM_PAW],psi_porosity,pars[P.retention_paw]); +double beta = 1/(1 + exp(pars[P.beta_lgr]*(-1*POOLS[p+S.D_PSI_PAW]/pars[P.psi_50] - 1))); + +// mean air temperature (K) +double air_temp_k = DGCM_TK0C+0.5*(T2M_MIN[n]+T2M_MAX[n]); + +//******************Declare LIU STRUCT********************* +LIU_AN_ET_STRUCT LIU; + +//define time-invariant parameters +LIU.IN.SRAD=SSRD[n]*1e6/DGCM_SEC_DAY; +LIU.IN.VPD=VPD[n]/10; +LIU.IN.TEMP=air_temp_k; +LIU.IN.vcmax25=pars[P.Vcmax25]; +LIU.IN.co2=CO2[n]; +LIU.IN.beta_factor=fmin(beta,g)*POOLS[p+S.D_LF_PAW]; +LIU.IN.g1=pars[P.Med_g1]; +LIU.IN.LAI=LAI; +LIU.IN.ga=pars[P.ga]; +LIU.IN.VegK=VegK; +LIU.IN.Tupp=pars[P.Tupp]; +LIU.IN.Tdown=pars[P.Tdown]; +LIU.IN.C3_frac=1., // pars[P.C3_frac] +LIU.IN.clumping=pars[P.clumping]; +LIU.IN.leaf_refl_par=pars[P.leaf_refl_par]; +LIU.IN.leaf_refl_nir=pars[P.leaf_refl_nir]; +LIU.IN.maxPevap=pars[P.maxPevap]; +LIU.IN.precip=PREC[n]; +LIU.IN.q10canopy=pars[P.q10canopy]; +LIU.IN.q10canopyRd=pars[P.rauto_mrd_q10]; +LIU.IN.canopyRdsf=pars[P.canopyRdsf]; +LIU.IN.NSC=POOLS[p+S.C_lab]; +LIU.IN.deltat=deltat; + + +//Call function: uses LIU->IN to update LIU->OUT +LIU_AN_ET(&LIU); + +double LEAF_MORTALITY_FACTOR=LIU.OUT.LEAF_MORTALITY_FACTOR; + +// GPP--- gross +FLUXES[f+F.gpp] = LIU.OUT.Ag; +// GPP net, i.e. GPP- Rd +FLUXES[f+F.gppnet] = LIU.OUT.An; +//transpiration// +FLUXES[f+F.transp] = LIU.OUT.transp; +//evaporation// +FLUXES[f+F.evap] = LIU.OUT.evap; + + +/*Snow water equivalent*/ +FLUXES[f+F.snowfall] = SNOWFALL[n]; +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+FLUXES[f+F.snowfall]*deltat; /*first step snowfall to SWE*/ +//transient_SCF +double SCFtemp = POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); + //Snow melt, based on new SWE + double SNOWMELT=fmin(fmax((DGCM_TK0C+SKT[n]-pars[P.min_melt])*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ +double SUBLIMATION = pars[P.sublimation_rate]*SSRD[n]*SCFtemp; + +double slf=(SNOWMELT + SUBLIMATION)*deltat/POOLS[nxp+S.H2O_SWE]; + if (slf>1){ + FLUXES[f+F.melt]=SNOWMELT/slf; + FLUXES[f+F.sublimation]=SUBLIMATION/slf;} + else{ + FLUXES[f+F.melt]=SNOWMELT; + FLUXES[f+F.sublimation]=SUBLIMATION;} + + +// +// //Splitting snow loss into sublimation and snow melt with constant frac +// FLUXES[f+F.melt]=SNOWMELT; +// // POOLS[nxp+S.D_SCF]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); //snow cover fraction +// +// FLUXES[f+F.sublimation]=fmax( pars[P.sublimation_rate]*VPD[n]*SRAD[n]*POOLS[nxp+S.D_SCF]); +// + + + +// Evapotranspiration +FLUXES[f+F.et]=FLUXES[f+F.evap]+FLUXES[f+F.transp]; +FLUXES[f+F.ets]=FLUXES[f+F.et] + FLUXES[f+F.sublimation]; + +POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-(FLUXES[f+F.melt] + FLUXES[f+F.sublimation])*deltat; /*second step remove snowmelt from SWE*/ + + +//Energy balance: Rn = LE + H - G +// Rn = SWin - SWout + LWin - LWout + + +double SWin = SSRD[n]*1e6/DGCM_SEC_DAY; // W m-2 + +//Snow free +double SWout_snowfree =(SWin*0.5*(pars[P.leaf_refl_par]+pars[P.leaf_refl_nir])); // W m-2 +//Weighted average of surface albedo considering SW snow albedo as 0.9 +double snow_albedo=0.9;//Consider age-dependent albedo. + +//SW out +double SWout = (1. - POOLS[p+S.D_SCF])*SWout_snowfree + POOLS[p+S.D_SCF]*(SWin*snow_albedo); // W m-2 + + + + +//Stefan-Boltzmann constant W.m-2.K-4 +double sigma = 5.67*1e-8; +//Incident LW radiation - calculated +//double LWin = sigma*pow(air_temp_k,4.); +double LWin = STRD[n]*1e6/DGCM_SEC_DAY; // W m-2 +//Outgoing LW radiation +double tskin_k = SKT[n]+DGCM_TK0C; +double LWout = sigma*(tskin_k*tskin_k)*(tskin_k*tskin_k); // W m-2 +//Net radiation at the top of the canopy-soil continuum +// +// +double Rn = SWin - SWout + LWin - LWout; // W m-2 +//Rnet only into soil +FLUXES[f+F.net_radiation] = Rn; // W m-2 + +//Rnet snow free +double Rn_snowfree = SWin - SWout_snowfree + LWin - LWout; // W m-2 + + +//These are only fluxes into PAW and out of PAW +FLUXES[f+F.SWin]=SWin;//flag for redundancy and deletion +FLUXES[f+F.LWin]=LWin;//flag for redundancy and deletion +FLUXES[f+F.SWout]=SWout; +FLUXES[f+F.LWout]=LWout; + +//Latent heat of Vaporization J kg-1 +double lambda = DGCM_LATENT_HEAT_VAPORIZATION; //2.501*1e6 J kg-1 +//Latent heat (W.m-2) +double LE = lambda*FLUXES[f+F.et]/DGCM_SEC_DAY; // W m-2 +FLUXES[f+F.latent_heat] = LE; // W m-2 +//specific heat capacity of dry air is 1.00464 KJ kg -1 K -1 +// Consider surface pressure as forcing for more accurate conversion from mol to m3 +// Consider explicitly calculating cp based on humidity (derived from VPD and pressure) +double cp = 29.2; // J mol-1 K-1 representative specific heat of moist air at const pressure from Bonan book +double Psurf = 1e5; // Pa (representative surface pressure) +double Rgas = 8.31; // Universal gas constant (J mol-1 K-1) +// Pa / (J mol-1 K-1 * K) = mol m-3 +double moles_per_m3 = Psurf/(Rgas*air_temp_k); +//Sensible heat +// double H = cp*(tskin_k - air_temp_k)*pars[P.ga]*moles_per_m3; // ga in m s-1, +// FLUXES[f+F.sensible_heat] = H; // W m-2 +//Ground heat flux ONLY for energy in&out of vegetation-soil continuum +//Rn is scaled by snow free area, because we exclude snow energy balance from energy ODEs +//H is scaled by snow free area, because we exclude snow energy balance from energy ODEs +//LE is fully included, as evaporation and transpiration are assumed to come fully from snow-free areas (caveat: snow evaporation is a thing, btut we assume it's zero for this model) + +//Ideally, Rn should be snow-free vs snow-covered. + +// double G = Rn*(1. - POOLS[p+S.D_SCF]) - H*(1. - POOLS[p+S.D_SCF]) - LE; // W m-2 +// FLUXES[f+F.ground_heat] = G; // W m-2 +// FLUXES[f+F.gh_in] = G*DGCM_SEC_DAY; // J m-2 d-1 + +//Gh_in approach 2 based on soil and LST +FLUXES[f+F.ground_heat] =(pars[P.thermal_cond_surf]* (tskin_k - POOLS[p+S.D_TEMP_PAW])/(pars[P.PAW_z]*0.5))*(1. - POOLS[p+S.D_SCF]); +FLUXES[f+F.gh_in] =FLUXES[f+F.ground_heat] *DGCM_SEC_DAY; +//Using G, Rn and LE to derive H +// H = Rn - G - LE +FLUXES[f+F.sensible_heat] = Rn - FLUXES[f+F.ground_heat] - FLUXES[f+F.latent_heat]; + + +// Infiltration (mm/day) +double liquid_in = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]); +FLUXES[f+F.infil] = pars[P.max_infil]*(1 - exp(-liquid_in/pars[P.max_infil])); + + + +// Surface runoff (mm/day) + +FLUXES[f+F.q_surf] = liquid_in - FLUXES[f+F.infil]; + +// Volumetric soil moisture from water pools +// Include infiltration into PAW () +// double sm_PAW = HYDROFUN_EWT2MOI(POOLS[p+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +// double sm_PUW = HYDROFUN_EWT2MOI(POOLS[p+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage + +//printf("POOLS[p+S.D_LF_PAW] = %2.2f\n",POOLS[p+S.D_LF_PAW]); +double drain_PAW = POOLS[p+S.D_LF_PAW]*DRAINAGE(POOLS[p+S.D_SM_PAW],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = POOLS[p+S.D_LF_PUW]*DRAINAGE(POOLS[p+S.D_SM_PUW],pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + + +// // Remove drainage from layers +// sm_PAW -= drain_PAW; +// sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_PAW],pars[P.hydr_cond],pars[P.retention]); +double k_PUW = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_PUW],pars[P.hydr_cond],pars[P.retention]); + +// // Convert to potential +// double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.retention_paw]); +// double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.retention_puw]); + + + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double pot_xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(POOLS[p+S.D_PSI_PAW]-POOLS[p+S.D_PSI_PUW])/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); +double SPACEavail, H2Oavail, PAW2PUWmax, TEMPxfer; +if (pot_xfer>0) {//Water is going PAW->PUW (down) +// Available space in PUW (after runoff) +SPACEavail=fmax(pars[P.PUW_z]*pars[P.PUW_por]*1e3 - POOLS[p+S.H2O_PUW] + FLUXES[f+F.q_puw]*deltat,0); +// Available water in PAW (after runoff, et, and infiltration) +H2Oavail=fmax(POOLS[p+S.D_LF_PAW]*POOLS[p+S.H2O_PAW] + (FLUXES[f+F.infil] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat,0); +// Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +PAW2PUWmax= POOLS[p+S.D_LF_PAW]*pot_xfer*1000*DGCM_SEC_DAY*deltat; +//Minimum of three terms for PAW->PUW +//1. PAW2PUWmax +//2. Available space in PUW (after runoff) +//3. PAW*LF (after runoff, et, and infiltration) +FLUXES[f+F.paw2puw] =fmin(PAW2PUWmax , fmin(SPACEavail, H2Oavail))/deltat; +TEMPxfer= POOLS[p+S.D_TEMP_PAW];//In K +} +else { //Water is going PUW->PAW (up) +// Available space in PAW after runoff, et, and infiltration +SPACEavail=fmax(pars[P.PAW_z]*pars[P.PAW_por]*1e3 - POOLS[p+S.H2O_PAW] - (FLUXES[f+F.infil] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat,0); +// Available water in PUW after runoff +H2Oavail= fmax(POOLS[p+S.D_LF_PUW]*POOLS[p+S.H2O_PUW] - FLUXES[f+F.q_puw]*deltat,0); +// Maximum transfer flux in mm (actual transfer may be less due to water or space availability) +PAW2PUWmax= POOLS[p+S.D_LF_PUW]*pot_xfer*1000*DGCM_SEC_DAY*deltat; +// Reverse sign of previous case +FLUXES[f+F.paw2puw] = -fmin(-PAW2PUWmax , fmin(SPACEavail, H2Oavail))/deltat; +TEMPxfer= POOLS[p+S.D_TEMP_PUW];//In K +} + + + + + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + (FLUXES[f+F.infil] - FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.evap] - FLUXES[f+F.transp])*deltat; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + +if (POOLS[nxp+S.H2O_PAW]>PAWmax){ +//Dump excess into PAW Q +FLUXES[f+F.q_paw] +=(POOLS[nxp+S.H2O_PAW]-PAWmax)/deltat; +POOLS[nxp+S.H2O_PAW]=PAWmax;} + +if (POOLS[nxp+S.H2O_PUW]>PUWmax){ +//Dump excess into PUW Q +FLUXES[f+F.q_puw] +=(POOLS[nxp+S.H2O_PUW]-PUWmax)/deltat; +POOLS[nxp+S.H2O_PUW]=PUWmax;} + + +//**********INTERNAL ENERGT FLUXES FOR ALL H2O FLUXES*************** +//Add INFILTRATION, PAW, PUW, PAW2PUW, ET +double infiltemp = air_temp_k ;//Infiltemp needs to be in degrees celcius for IF statement to work +if (FLUXES[f+F.melt]>0){infiltemp = (infiltemp-DGCM_TK0C)*(PREC[n] - SNOWFALL[n])/(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])+DGCM_TK0C;}//snowmelt temp = 0, so term multiplied by zero in weighted average + + +//All energy fluxes + +FLUXES[f+F.infil_e] = FLUXES[f+F.infil]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(infiltemp); +FLUXES[f+F.et_e] = (FLUXES[f+F.transp]+FLUXES[f+F.evap])*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_PAW]); +FLUXES[f+F.paw2puw_e] = FLUXES[f+F.paw2puw]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(TEMPxfer); +FLUXES[f+F.q_paw_e] = FLUXES[f+F.q_paw]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_PAW]); +FLUXES[f+F.q_puw_e] = FLUXES[f+F.q_puw]*INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(POOLS[p+S.D_TEMP_PUW]); +//Thermal conductivity = k*dT/dz, units are W/m2, converting to J/m2/d +FLUXES[f+F.paw2puw_th_e] = 2*pars[P.thermal_cond]* (POOLS[p+S.D_TEMP_PAW] - POOLS[p+S.D_TEMP_PUW])/(pars[P.PAW_z] + pars[P.PUW_z])*DGCM_SEC_DAY; + + +//Thermal energy flux only +//FLUXES[f+F.paw2puw_e_thermal] = + +//Energy states +//fraction of water in soil that is available +//double frac_paw = POOLS[nxp+S.H2O_PAW]/(POOLS[nxp+S.H2O_PAW]+POOLS[nxp+S.H2O_PUW]); + // E_PAW + + + FLUXES[f+F.geological]=0.105*3600*24;//In J/m2/d //105mW/m2 +POOLS[nxp+S.E_PAW] = POOLS[p+S.E_PAW] + (FLUXES[f+F.gh_in] + FLUXES[f+F.infil_e] - FLUXES[f+F.et_e] - FLUXES[f+F.q_paw_e] - FLUXES[f+F.paw2puw_e] - FLUXES[f+F.paw2puw_th_e])*deltat; +POOLS[nxp+S.E_PUW] = POOLS[p+S.E_PUW] + (FLUXES[f+F.paw2puw_e] - FLUXES[f+F.q_puw_e] +FLUXES[f+F.paw2puw_th_e] + FLUXES[f + F.geological])*deltat; + + + +//*************KNORR LAI************** + + +//Time varying KNORR function terms + +KNORR.IN.lambda_max_memory= POOLS[p+S.M_LAI_MAX]; +KNORR.IN.T_memory=POOLS[p+S.M_LAI_TEMP]; +KNORR.IN.temp=air_temp_k; +KNORR.IN.n=n; +KNORR.IN.DOY=DOY[n]; +KNORR.IN.lambda=LAI; +KNORR.IN.pasm=(POOLS[p+S.H2O_PAW]+POOLS[nxp+S.H2O_PAW])/2.0;//Note: soil moisture also available here +KNORR.IN.transp= FLUXES[f+F.transp]; +//Call function: uses KNORR->IN to update KNORR->OUT +KNORR_ALLOCATION(&KNORR); + +FLUXES[f+F.target_LAI]=KNORR.OUT.lambda_next; +//KNORR.OUT.dlambdadt is in units per timestep; converting thest to units per day (as required for CARDAMOM) +//"FLUXES" have to be in "per day" units +FLUXES[f+F.dlambda_dt]=KNORR.OUT.dlambdadt/deltat; +FLUXES[f+F.f_temp_thresh]= KNORR.OUT.f_T; +FLUXES[f+F.f_dayl_thresh]= KNORR.OUT.f_d; + +//Update KNORR memory variables for next iteration +POOLS[nxp+S.M_LAI_MAX]=KNORR.OUT.laim; +POOLS[nxp+S.M_LAI_TEMP]=KNORR.OUT.T; + + + +//************Allocation******************* + +ARFLUXES.IN.deltat=deltat; +ARFLUXES.IN.GPP=FLUXES[f+F.gpp]; +ARFLUXES.IN.Rd=LIU.OUT.Rd; +ARFLUXES.IN.TEMP=air_temp_k; +ARFLUXES.IN.NSC=POOLS[p+S.C_lab]; +ARFLUXES.IN.C_LIVE_W=POOLS[p+S.C_woo]; +ARFLUXES.IN.C_LIVE_R= POOLS[p+S.C_roo]; +// Potential plant allocation (growth) fluxes +ARFLUXES.IN.ALLOC_FOL_POT=fmax(0, ((FLUXES[f+F.target_LAI] * pars[P.LCMA]) - POOLS[p+S.C_fol])/deltat); +ARFLUXES.IN.ALLOC_ROO_POT=fmax(0, (pars[P.phi_RL] * (FLUXES[f+F.target_LAI] * pars[P.LCMA]))/deltat); +ARFLUXES.IN.ALLOC_WOO_POT=fmax(0, (pars[P.phi_WL] * (FLUXES[f+F.target_LAI] * pars[P.LCMA]))/deltat); + +ALLOC_AND_AUTO_RESP_FLUXES(&ARFLUXES); + + double NONLEAF_MORTALITY_FACTOR=ARFLUXES.OUT.NONLEAF_MORTALITY_FACTOR; + + + + + +/*respiration auto*/ +FLUXES[f+F.resp_auto]=ARFLUXES.OUT.AUTO_RESP_TOTAL; +/*growth respiration*/ +FLUXES[f+F.resp_auto_growth]=ARFLUXES.OUT.AUTO_RESP_GROWTH; +/*maintenance respiration*/ +FLUXES[f+F.resp_auto_maint]=ARFLUXES.OUT.AUTO_RESP_MAINTENANCE; +FLUXES[f+F.resp_auto_maint_dark]=LIU.OUT.Rd; + + + +// Fcfolavailable=FLUXES[f+F.lab_prod] + POOLS[p+S.C_lab]/deltat; +if (FLUXES[f+F.dlambda_dt] > 0){ + FLUXES[f+F.fol2lit]=POOLS[p+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))/deltat; +} +else { + //FLUXES[f+F.dlambda_dt] is in m2/m2/day + //LCMA = gC/m2/m2 + FLUXES[f+F.fol2lit]=-FLUXES[f+F.dlambda_dt]*pars[P.LCMA]+POOLS[p+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))/deltat; +} + +/*labile production*/ +FLUXES[f+F.lab_prod] = ARFLUXES.OUT.F_LABPROD; +/*labile production*/ +//FLUXES[f+F.lab_release] = ARFLUXES.OUT.F_LABREL_ACTUAL; +/*foliar production*/ +FLUXES[f+F.foliar_prod] = ARFLUXES.OUT.ALLOC_FOL_ACTUAL; +/*root production*/ +FLUXES[f+F.root_prod] = ARFLUXES.OUT.ALLOC_ROO_ACTUAL; +/*wood production*/ +FLUXES[f+F.wood_prod] = ARFLUXES.OUT.ALLOC_WOO_ACTUAL; +/*wood CWD production*/ +FLUXES[f+F.woo2cwd] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.roo2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; + +/*-----------------------------------------------------------------------*/ + + + //TIME-VARYING INPUTS + HRJCR.IN.SM=POOLS[p+S.D_SM_PAW]; + HRJCR.IN.TEMP=POOLS[p+S.D_TEMP_PAW];; // Input in degrees K + HRJCR.IN.LF=POOLS[p+S.D_LF_PAW];; // Input in degrees + + //JCR + HET_RESP_RATES_JCR(&HRJCR); + //OUtputs --- store anything we want here--- + FLUXES[f+F.aetr]=HRJCR.OUT.aerobic_tr;//Aerobic turnover rate scalar + FLUXES[f+F.antr]=HRJCR.OUT.anaerobic_tr;//Anaerobic turnover rate scalar + FLUXES[f+F.an_co2_c_ratio]=HRJCR.OUT.anaerobic_co2_c_ratio;//CO2_C_ratio + FLUXES[f+F.an_ch4_c_ratio]=HRJCR.OUT.anaerobic_ch4_c_ratio;//CH4_C_ratio + + + +//outputformat +//jcr_o 0-3 fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +double ae_loss_cwd = POOLS[p+S.C_cwd]*(1-pow(1-HRJCR.OUT.aerobic_tr*pars[P.t_cwd],deltat))/deltat; +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = ae_loss_cwd*(1-pars[P.tr_cwd2som]); +double ae_loss_lit = POOLS[p+S.C_lit]*(1-pow(1-HRJCR.OUT.aerobic_tr*pars[P.t_lit],deltat))/deltat; +/* aerobic Rh from litter*/ +FLUXES[f+F.ae_rh_lit] = ae_loss_lit*(1-pars[P.tr_lit2som]); +/* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*(1-pow(1-HRJCR.OUT.aerobic_tr*pars[P.t_som],deltat))/deltat; + +//******Anaerobic fluxes +double an_loss_cwd = POOLS[p+S.C_cwd]*(1-pow(1-HRJCR.OUT.anaerobic_tr*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from coarse woody debris*/ +FLUXES[f+F.an_rh_cwd] = an_loss_cwd*(1-pars[P.tr_cwd2som]); +/* anaerobic Rh from litter*/ +double an_loss_lit = POOLS[p+S.C_lit]*(1-pow(1-HRJCR.OUT.anaerobic_tr*pars[P.t_lit],deltat))/deltat; +FLUXES[f+F.an_rh_lit] = an_loss_lit*(1-pars[P.tr_lit2som]); +/* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*(1-pow(1-HRJCR.OUT.anaerobic_tr*pars[P.t_som],deltat))/deltat; +/*CWD to SOM*/ +FLUXES[f+F.cwd2som] = (an_loss_cwd + ae_loss_cwd)*pars[P.tr_cwd2som]; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = (an_loss_lit + ae_loss_lit)*pars[P.tr_lit2som]; +/* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*HRJCR.OUT.anaerobic_co2_c_ratio + (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som]); +/* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*HRJCR.OUT.anaerobic_ch4_c_ratio; + +/*---------------------- end of JCR --------------------------------------------*/ + + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto_maint]-FLUXES[f+F.foliar_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.wood_prod]-FLUXES[f+F.resp_auto_growth])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.foliar_prod] - FLUXES[f+F.fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.woo2cwd])*deltat; + POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] + (FLUXES[f+F.woo2cwd] - FLUXES[f+F.ae_rh_cwd]-FLUXES[f+F.an_rh_cwd]-FLUXES[f+F.cwd2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.roo2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + + + //Energy ppols + //Root zone + //POOLS[nxp+S.E_PAW] = POOLS[p+S.E_PAW] + (Renato's ground heat flux, inc LWup, etc.)*deltaT - Runoff terms - Marcos' evaporation terms + Precip energ + + //POOLS[nxp+S.E_PUW] = POOLS[p+S.E_PAW] + (Renato's ground heat flux)*deltaT + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat ; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + +//P*M + P*(1-M)*BAf = P*M + P*BAf - P*M*BAf = P*(M + BAf - M*BAf) = P*(BAf*(1 - M) + M) + + //LIVE BIOMASS MORTALITY FLUXES + //if MORTALITY + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*(NONLEAF_MORTALITY_FACTOR + (1-NONLEAF_MORTALITY_FACTOR)*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience]))/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*(LEAF_MORTALITY_FACTOR + (1-LEAF_MORTALITY_FACTOR)*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience]))/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*(NONLEAF_MORTALITY_FACTOR + (1-NONLEAF_MORTALITY_FACTOR)*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience]))/deltat; + FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*(NONLEAF_MORTALITY_FACTOR + (1-NONLEAF_MORTALITY_FACTOR)*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience]))/deltat; + //No mortality in these pools + FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-CF[S.C_cwd])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2cwd])*deltat; + /*dead C pools*/ + /*CWD*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.fx_woo2cwd]-FLUXES[f+F.f_cwd]-FLUXES[f+F.fx_cwd2som])*deltat; + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + /*Fraction of C-foliar lost due to fires*/ + FLUXES[f+F.foliar_fire_frac] = BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Calculate LAI (lambda) lost due to fire + - we lose the same fraction of LAI as we do C-foliar + - FE_\Lambda^{(t+1)} = \Lambda^{(t+1)'} * BA ( k_{factor(i)} + (1 - k_{factor(i)}) r )*/ + FLUXES[f+F.lai_fire] = (POOLS[p+S.C_fol]/pars[P.LCMA])*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + + /****************************RECORD t+1 DIAGNOSTIC STATES*************************/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + POOLS[nxp+S.D_SCF]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); //snow cover fraction + + + + //Update time-varying inputs + PAWSOILTEMP.IN.soil_water = POOLS[nxp+S.H2O_PAW];//mm (or kg/m2) + PUWSOILTEMP.IN.soil_water = POOLS[nxp+S.H2O_PUW];//mm (or kg/m2) + PAWSOILTEMP.IN.internal_energy = POOLS[nxp+S.E_PAW];//Joules + PUWSOILTEMP.IN.internal_energy = POOLS[nxp+S.E_PUW];//Joules + + SOIL_TEMP_AND_LIQUID_FRAC(&PAWSOILTEMP); + SOIL_TEMP_AND_LIQUID_FRAC(&PUWSOILTEMP); + + POOLS[nxp+S.D_TEMP_PAW]=PAWSOILTEMP.OUT.TEMP;//In K + POOLS[nxp+S.D_TEMP_PUW]=PUWSOILTEMP.OUT.TEMP;//In K + + POOLS[nxp+S.D_LF_PAW]=PAWSOILTEMP.OUT.LF; + POOLS[nxp+S.D_LF_PUW]=PUWSOILTEMP.OUT.LF; + + + //Pass pointers to function + + + //Soil moisture + + POOLS[nxp+S.D_SM_PAW]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); //soil moisture PAW + POOLS[nxp+S.D_SM_PUW]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]);//soil moisture PUW + + + POOLS[nxp+S.D_PSI_PAW]=HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_PAW],psi_porosity,pars[P.retention]); + POOLS[nxp+S.D_PSI_PUW]=HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_PUW],psi_porosity,pars[P.retention]); + + +} + + + +return 0; +} + + +int DALEC_1109_MODCONFIG(DALEC * DALECmodel, DATA * DATA){ + + +struct DALEC_1109_PARAMETERS P=DALEC_1109_PARAMETERS; +struct DALEC_1109_FLUXES F=DALEC_1109_FLUXES; +struct DALEC_1109_POOLS S=DALEC_1109_POOLS; +struct DALEC_1109_EDCs E=DALEC_1109_EDCs; + + + + +DALECmodel->dalec=DALEC_1109; +DALECmodel->nopools=24; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=80; +DALECmodel->nofluxes=75; +DALECmodel->noedcs=11; + +DALEC_1109_FLUX_SOURCES_SINKS(DALECmodel); + + + + +//Define PARS_INFO here (ranges, and eventually names, etc) +PARS_INFO_1109(DALECmodel); + +//EDC operator +//Make sure has same number as number of EDCs +//This is generic EDCs structure defined in ../DALEC_EDCs/DALEC_EDC_FUNCTIONS.c +//Has three args, data (void), function (in "DATA", and "void *", and "double" out), and "boolean" prerun. + + + + + +DALECmodel->EDCs=calloc(DALECmodel->noedcs,sizeof(EDCs)); +//Abbrieviate +EDCs * EDCs=DALECmodel->EDCs; + +//Som lit turnover rate + +//EDC: litter tor > cwd tor +//List all inequality calls here +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_litcwdtor; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_cwdsomtor; +static DALEC_EDC_PARAMETER_INEQUALITY_STRUCT EDC_mr_rates; + +EDC_litcwdtor.big_par_index=P.t_lit; +EDC_litcwdtor.small_par_index=P.t_cwd; +EDCs[E.litcwdtor].data=&EDC_litcwdtor; +EDCs[E.litcwdtor].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.litcwdtor].prerun=true; + +//EDC: cwd tor > som tor +EDC_cwdsomtor.big_par_index=P.t_cwd; +EDC_cwdsomtor.small_par_index=P.t_som; +EDCs[E.cwdsomtor].data=&EDC_cwdsomtor; +EDCs[E.cwdsomtor].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.cwdsomtor].prerun=true; + +//EDC: foliar and root mr > wood mr +EDC_mr_rates.big_par_index=P.rauto_mr_r; +EDC_mr_rates.small_par_index=P.rauto_mr_w; +EDCs[E.mr_rates].data=&EDC_mr_rates; +EDCs[E.mr_rates].function=&DALEC_EDC_PARAMETER_INEQUALITY; +EDCs[E.mr_rates].prerun=true; + +static DALEC_EDC_PARAMETER_LOG_RATIO_STRUCT EDC_vcmax_lcma; +//EDC: ratio of Vcmax25 to LCMA +EDC_vcmax_lcma.numerator_index=P.Vcmax25; +EDC_vcmax_lcma.denominator_index=P.LCMA; +EDC_vcmax_lcma.mean_ratio = 1.0399; // From TRY database +EDC_vcmax_lcma.std_ratio = 0.1956; // From TRY database +EDCs[E.vcmax_lcma].data=&EDC_vcmax_lcma; +EDCs[E.vcmax_lcma].function=&DALEC_EDC_PARAMETER_LOG_RATIO; +EDCs[E.vcmax_lcma].prerun=true; + + + + + +//State ranges + static DALEC_EDC_STATE_RANGES_STRUCT EDC_sr; + + //Create array (1x number of pools) for minimum and max values + //Index exactly corresponds to "POOLS" indices + + EDC_sr.min_val=calloc(DALECmodel->nopools,sizeof(double)); + + EDC_sr.max_val=calloc(DALECmodel->nopools,sizeof(double)); + + int n; + for (n=0;nnopools;n++){ + EDC_sr.min_val[n]=-INFINITY; + EDC_sr.max_val[n]=INFINITY;} + + EDC_sr.min_val[S.C_lab]=0; + EDC_sr.max_val[S.C_lab]=DALECmodel->PARS_INFO.parmax[P.i_labile]; + + EDC_sr.min_val[S.C_fol]=0; + EDC_sr.max_val[S.C_fol]=DALECmodel->PARS_INFO.parmax[P.i_foliar]; + + EDC_sr.min_val[S.C_roo]=0; + EDC_sr.max_val[S.C_roo]=DALECmodel->PARS_INFO.parmax[P.i_root]; + + EDC_sr.min_val[S.C_woo]=0; + EDC_sr.max_val[S.C_woo]=DALECmodel->PARS_INFO.parmax[P.i_wood]; + + EDC_sr.min_val[S.C_cwd]=0; + EDC_sr.max_val[S.C_cwd]=DALECmodel->PARS_INFO.parmax[P.i_cwd]; + + EDC_sr.min_val[S.C_lit]=0; + EDC_sr.max_val[S.C_lit]=DALECmodel->PARS_INFO.parmax[P.i_lit]; + + EDC_sr.min_val[S.C_som]=0; + EDC_sr.max_val[S.C_som]=DALECmodel->PARS_INFO.parmax[P.i_som]; + + EDC_sr.min_val[S.H2O_PAW]=0; + // + + EDC_sr.min_val[S.H2O_PUW]=0; + // + + EDC_sr.min_val[S.H2O_SWE]=0; +// EDC_sr.max_val[S.H2O_SWE]=DALECmodel->PARS_INFO.parmax[P.i_SWE]; +// + EDC_sr.min_val[S.E_PAW]=0; +// + EDC_sr.min_val[S.E_PUW]=0; +// + EDC_sr.min_val[S.D_LAI]=0; + EDC_sr.max_val[S.D_LAI]=DALECmodel->PARS_INFO.parmax[P.lambda_max]; +// +// EDC_sr.min_val[S.D_SCF]=0; +// EDC_sr.max_val[S.D_SCF]=1; +// + EDC_sr.min_val[S.D_TEMP_PAW]=173.15; + EDC_sr.max_val[S.D_TEMP_PAW]=373.15; +// + EDC_sr.min_val[S.D_TEMP_PUW]=173.15; + EDC_sr.max_val[S.D_TEMP_PUW]=373.15; +// // +// EDC_sr.min_val[S.D_LF_PAW]=0; +// EDC_sr.max_val[S.D_LF_PAW]=1; +// // +// EDC_sr.min_val[S.D_LF_PUW]=0; +// EDC_sr.max_val[S.D_LF_PUW]=1; +// + EDC_sr.min_val[S.D_SM_PAW]=0; + EDC_sr.max_val[S.D_SM_PAW]=1; +// + EDC_sr.min_val[S.D_SM_PUW]=0; + EDC_sr.max_val[S.D_SM_PUW]=1; + + EDC_sr.min_val[S.M_LAI_MAX]=-INFINITY; // get a better value from Alex N. + EDC_sr.max_val[S.M_LAI_MAX]=INFINITY; // get a better value from Alex N. + + EDC_sr.min_val[S.M_LAI_TEMP]=-INFINITY; // get a better value from Alex N. + EDC_sr.max_val[S.M_LAI_TEMP]=INFINITY; // get a better value from Alex N. + + + + + +//Adding EDC to the EDCs list + + + EDCs[E.state_ranges].data=&EDC_sr; + EDCs[E.state_ranges].function=&DALEC_EDC_STATE_RANGES; + EDCs[E.state_ranges].prerun=false; + + + + static DALEC_EDC_START_TEMP_STRUCT EDC_paw_start_temp, EDC_puw_start_temp; + + +//Calculating min LST and MAX LST + double minlst=DATA->ncdf_data.SKT.values[0]; + double maxlst=DATA->ncdf_data.SKT.values[0]; +for (n=1;nncdf_data.TIME_INDEX.length;n++){ +minlst=fmin(minlst,DATA->ncdf_data.SKT.values[n]); +maxlst=fmax(maxlst,DATA->ncdf_data.SKT.values[n]);} + + + EDC_paw_start_temp.min_temp=minlst+DGCM_TK0C; +EDC_paw_start_temp.max_temp=maxlst+DGCM_TK0C; +EDC_paw_start_temp.vhc_idx=P.PAW_vhc; +EDC_paw_start_temp.por_idx=P.PAW_por; + EDC_paw_start_temp.z_idx=P.PAW_z; + EDC_paw_start_temp.i_SM_idx=P.i_PAW_SM; +EDC_paw_start_temp.i_E_idx=P.i_PAW_E; + + + + EDCs[E.paw_start_temp].data=&EDC_paw_start_temp; + EDCs[E.paw_start_temp].function=&DALEC_EDC_START_TEMP; +EDCs[E.paw_start_temp].prerun=true; +// + + + EDC_puw_start_temp.min_temp=minlst+DGCM_TK0C; +EDC_puw_start_temp.max_temp=maxlst+DGCM_TK0C; +EDC_puw_start_temp.vhc_idx=P.PUW_vhc; +EDC_puw_start_temp.por_idx=P.PUW_por; + EDC_puw_start_temp.z_idx=P.PUW_z; + EDC_puw_start_temp.i_SM_idx=P.i_PUW_SM; +EDC_puw_start_temp.i_E_idx=P.i_PUW_E; + + + +EDCs[E.puw_start_temp].data=&EDC_puw_start_temp; + EDCs[E.puw_start_temp].function=&DALEC_EDC_START_TEMP; +EDCs[E.puw_start_temp].prerun=true; +// // + + + + +//Start temperatures for PAW and PUW + + + + + static DALEC_EDC_TRAJECTORY_STRUCT EDC_st; + + static int edc_pool_indices[12]; + static double edc_pool_eqf[12]; +EDC_st.pool_indices=edc_pool_indices; +EDC_st.pool_eqf=edc_pool_eqf; +EDC_st.no_pools_to_check=12; + +//EDC_st.pool_indices[0]=S.E_PAW; +//EDC_st.pool_indices[1]=S.E_PUW; +//EDC_st.pool_indices[2]=S.H2O_PAW; +//EDC_st.pool_indices[3]=S.H2O_PUW; +//EDC_st.pool_indices[4]=S.H2O_SWE; + + + +EDC_st.pool_indices[0]=S.C_lab; +EDC_st.pool_indices[1]=S.C_fol; +EDC_st.pool_indices[2]=S.C_roo; +EDC_st.pool_indices[3]=S.C_woo; +EDC_st.pool_indices[4]=S.C_cwd; +EDC_st.pool_indices[5]=S.C_lit; +EDC_st.pool_indices[6]=S.C_som; +EDC_st.pool_indices[7]=S.H2O_PAW; +EDC_st.pool_indices[8]=S.E_PAW; +EDC_st.pool_indices[9]=S.H2O_PUW; +EDC_st.pool_indices[10]=S.E_PUW; +EDC_st.pool_indices[11]=S.H2O_SWE; +//EDC_st.pool_indices[12]=S.M_LAI_MAX;``` +//EDC_st.pool_indices[13]=S.M_LAI_TEMP; + + + +for (n=0;nncdf_data.EDC_EQF;printf("DATA->ncdf_data.EDC_EQF = %2.2f\n",DATA->ncdf_data.EDC_EQF);} +// EDC_st.pool_eqf[9]=10; +// EDC_st.pool_eqf[10]=10; + +// //Rest can be done by code without additional input + +EDCs[E.state_trajectories].data=&EDC_st; +EDCs[E.state_trajectories].function=&DALEC_EDC_TRAJECTORY; +EDCs[E.state_trajectories].prerun=false; + +//Eventually adopt more succinct notation (to consider) +//e.g. INEQUALITY_EDC(P.t_cwd,P.t_som,EDCs[E.cwdsomtor]) + + + + + static DALEC_EDC_NSC_ABGB_RATIO_STRUCT EDC_nscr; + + // + EDC_nscr.no_other_pool_indices=3; + static int nscratio_other_pool_indices[3]; + + EDC_nscr.other_pool_indices=nscratio_other_pool_indices; + EDC_nscr.other_pool_indices[0]=S.C_fol; + EDC_nscr.other_pool_indices[1]=S.C_roo; + EDC_nscr.other_pool_indices[2]=S.C_woo; + EDC_nscr.nsc_pool_index=S.C_lab; + + + EDCs[E.nsc_ratio].data=&EDC_nscr; + EDCs[E.nsc_ratio].function=&DALEC_EDC_NSC_ABGB_RATIO; + EDCs[E.nsc_ratio].prerun=false; + + + +static DALEC_EDC_MEAN_TEMP_STRUCT EDC_mean_paw_temp, EDC_mean_puw_temp; + + // + EDC_mean_paw_temp.temp_index=S.D_TEMP_PAW; + EDCs[E.mean_paw_temp].data=&EDC_mean_paw_temp; + EDCs[E.mean_paw_temp].function=&DALEC_EDC_MEAN_TEMP; + EDCs[E.mean_paw_temp].prerun=false; + + + EDC_mean_puw_temp.temp_index=S.D_TEMP_PUW; + EDCs[E.mean_puw_temp].data=&EDC_mean_puw_temp; + EDCs[E.mean_puw_temp].function=&DALEC_EDC_MEAN_TEMP; + EDCs[E.mean_puw_temp].prerun=false; + + + +//ecological +//EDCOPE.SUPPORT_LITCWDSOM_trpar_EDC=true; +//dynamical +//EDCOPE.SUPPORT_POOL_SSP_EDC=true; +//Numerical checks +//EDCOPE.SUPPORT_FINITE_EDC=true; + + + + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + + +//Set SUPPORT_OBS values to true if model supports external observation operations. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_SIF_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; +OBSOPE.SUPPORT_SCF_OBS=true; + + + + +// OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Vcmax25_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +OBSOPE.SUPPORT_CUEmrg_OBS=true; +OBSOPE.SUPPORT_LCMA_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables//Assuming FLUXNET GPP is assumed to be Ag. + //Wohlfahrt & Gu, 2015 +OBSOPE.GPP_flux=F.gpp; +// For constraint on emergent autotrophic fraction +OBSOPE.Rauto_flux=F.resp_auto; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.ets; +//Runoff variables +static int ROFF_fluxes[3]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +ROFF_fluxes[2]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=3; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//SCF-specific variables +OBSOPE.SCF_pool=S.D_SCF; + + +//Vcmax25 parameters +OBSOPE.Vcmax25_PARAM=P.Vcmax25; +// //C3frac parameters +// OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_som; +OBSOPE.LCMA_PARAM=P.LCMA; + +//CH4-specific variables +OBSOPE.CH4_flux = F.rh_ch4; + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1109/DALEC_1109_INDICES.c === + +#pragma once +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1109_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2som; +int tr_cwd2som; +int rauto_mr_r; +int rauto_mr_w; +int rauto_mr_q10; +int rauto_mrd_q10; +int rauto_gr; +int t_wood; +int t_root; +int t_lit; +int t_cwd; +int t_som; +int Q10rhco2; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_cwd; +int i_lit; +int i_som; +int retention; +int i_PAW_SM; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int hydr_cond; +int max_infil; +int i_PUW_SM; +int PAW_por; +int PUW_por; +int field_cap; +int PAW_z;//PAW depth +int PUW_z;//PUW depth +int PAW_vhc;//PAW volumetric heat capacity +int PUW_vhc;//PUW volumetric heat capacity +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int clumping; +int leaf_refl_par; +int leaf_refl_nir; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +int S_fv; +int thetas_opt; +int fwc; +int r_ch4; +int Q10ch4; +int maxPevap; +int T_phi; +int T_range; +int plgr; +int k_leaf; +int lambda_max; +int tau_W; +int time_c; +int time_r; +int init_T_mem; +int init_LAIW_mem; +int t_foliar; +int i_PAW_E; +int i_PUW_E; +int psi_50; +int beta_lgr; +int phi_RL; +int phi_WL; +int thermal_cond; +int thermal_cond_surf; +int q10canopy; +int canopyRdsf; +int sublimation_rate; +} DALEC_1109_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69, + 70,71,72,73,74,75,76,77,78,79, +}; + +struct DALEC_1109_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int gppnet; /*GPP*/ +int resp_auto; /*Autotrophic respiration*/ +int lab_prod; /*Labile production*/ +int foliar_prod; /*Labile release*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int fol2lit; /*Foliar decomposition*/ +int woo2cwd; /*Wood decomposition*/ +int roo2lit; /*Root decomposition*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int ets; /*Evapotranspiration + sublimation*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int q_surf; /*Surface runoff*/ +int infil; /*INFILTRATION*/ +int infil_e; /*INFILTRATION IE: temp = weight average of snow melt (0C) + liquid precip (@air temp)*/ +int q_paw_e; /*Q PAW IE: temp = PAW temp*/ +int q_puw_e; /*Q PUW IE: temp = PUW temp*/ +int paw2puw_e; /*PAW->PUW transfer IE: temp of donor*/ +int et_e; /* See Retano's calculation*/ +int transp; /*Transpiration*/ +int evap; /*Evaporation*/ +int snowfall; /*Snowfall to SWE*/ +int melt; /*Snow melt*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int aetr; /*aerobic turnover scalar*/ +int antr; /*anaerobic turnover scalar*/ +int an_co2_c_ratio; /*CO2 fraction in anaerobic C decomposition*/ +int an_ch4_c_ratio; /*CH4 fraction in anaerobic C decomposition*/ +int target_LAI; /*LAI environmental target*/ +int dlambda_dt; /*dLAI/dt*/ +int f_temp_thresh; /*f_temp_thres*/ +int f_dayl_thresh; /*f_dayl_thres*/ +int lai_fire; /*LAI fire loss*/ +int foliar_fire_frac; /*C_fol fire loss frac*/ +int net_radiation; /*Net radiation flux*/ +int latent_heat; /*latent heat flux*/ +int sensible_heat; /*sensible heat flux*/ +int ground_heat; /*ground heat flux*/ +int gh_in; /*ground heat flux in converted units*/ +int resp_auto_growth; /*autotrophic growth respiration*/ +int resp_auto_maint; /*autotrophic maintenance respiration*/ +int SWin; +int SWout; +int LWin; +int LWout; +int paw2puw_th_e; +int resp_auto_maint_dark; +int sublimation; +int geological; +} DALEC_1109_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69, + 70,71,72,73,74 +}; + + + +/*Prognostic states and Diagnostic states (dependent on other states)*/ + + +struct DALEC_1109_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +int E_PAW; /*PAW thermal energy state*/ +int E_PUW; /*PUW thermal energy state*/ +int D_LAI;//leaf area index +int D_SCF;//snow-covered fraction +int D_TEMP_PAW;//PAW temp in K +int D_TEMP_PUW;//PUW temp in K +int D_LF_PAW;//PAW liquid h2o frac +int D_LF_PUW;//PUW liquid h2o frac +int D_SM_PAW;//PAW soil moisture +int D_SM_PUW;//PUW soil moisture +int D_PSI_PAW;//PAW soil moisture +int D_PSI_PUW;//PUW soil moisture +int M_LAI_MAX;//KNORR LAI module max LAI memory +int M_LAI_TEMP;//KNORR LAI module temp memory +} DALEC_1109_POOLS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23 +}; + +struct DALEC_1109_EDCs{ +int paw_start_temp; +int puw_start_temp; +int litcwdtor; +int cwdsomtor; +int mr_rates; +int mean_paw_temp; +int mean_puw_temp; +int nsc_ratio; +int state_ranges; +int state_trajectories; +int vcmax_lcma; +} DALEC_1109_EDCs={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10 +}; + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1109/EDC2_1109.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1109(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1109_PARAMETERS P=DALEC_1109_PARAMETERS; +struct DALEC_1109_FLUXES F=DALEC_1109_FLUXES; +struct DALEC_1109_POOLS S=DALEC_1109_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=10;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +//double EQF=EDCD->EQF; +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +if (Fin[n] > 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14 (No longer applicable)*/ +//EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_cwd,P.i_lit,P.i_som,P.i_PAW,P.i_PUW,P.i_SWE}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1026/PARS_INFO_1026.c === + +#pragma once +#include "DALEC_1026.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1026(DATA *CARDADATA) +{ + +struct DALEC_1026_PARAMETERS P=DALEC_1026_PARAMETERS; + +/*Decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[P.temp_factor]=0.018; +CARDADATA->parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[P.canopy_eff]=5; +CARDADATA->parmax[P.canopy_eff]=50; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +CARDADATA->parmin[P.uWUE]=0.5; +CARDADATA->parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[P.PAW_Qmax]=1; +CARDADATA->parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[P.h2o_xfer]=0.01; +CARDADATA->parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[P.PUW_Qmax]=1; +CARDADATA->parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +CARDADATA->parmin[P.boese_r]=0.01; +CARDADATA->parmax[P.boese_r]=0.3; + +/*Mean temperature at leaf onset (T_phi) (degrees kelvin)*/ +CARDADATA->parmin[P.T_phi]=268.15; +CARDADATA->parmax[P.T_phi]=323.15; + +/*Spatial range of mean temperature at leaf onset (T_r) (degrees C or degrees kelvin)*/ +CARDADATA->parmin[P.T_range]=0.1; +CARDADATA->parmax[P.T_range]=10.0; + +/*Averaging period for temperature growth trigger T (time units of model), usually kept constant*/ +CARDADATA->parmin[P.tau_m]=1.0; +CARDADATA->parmax[P.tau_m]=1.01; + +/*LAI linear growth constant (inverse of model time units; e.g. days-1 or months-1)*/ +CARDADATA->parmin[P.plgr]=0.001; +CARDADATA->parmax[P.plgr]=0.5; + +/*Inverse of leaf longevity during senescence period (inverse of model time units; e.g. days-1 or months-1)*/ +CARDADATA->parmin[P.k_leaf]=0.001; +CARDADATA->parmax[P.k_leaf]=0.5; + +/*Intrinsic maximum LAI (m^2 m^-2)*/ +CARDADATA->parmin[P.lambda_max]=0.1; +CARDADATA->parmax[P.lambda_max]=10.0; + +/*Target survival time for LAI under water-deficit conditions (days; or same unit as ET and PAW)*/ +CARDADATA->parmin[P.tau_W]=0.1; +CARDADATA->parmax[P.tau_W]=300; + +/*Mean daylength at leaf shedding (t_c; in units of hours sunlight per day)*/ +CARDADATA->parmin[P.time_c]=2; +CARDADATA->parmax[P.time_c]=22; + +/*Spatial range of mean daylength at leaf shedding (t_r)*/ +CARDADATA->parmin[P.time_r]=0.1; +CARDADATA->parmax[P.time_r]=6.0; + +/*initialization of temperature memory at t=0 (in absolute temperature units)*/ +CARDADATA->parmin[P.init_T_mem]=268.14; +CARDADATA->parmax[P.init_T_mem]=323.15; + +/*initialization of water/structural memory (fractional value of intrinsic maximum LAI)*/ +CARDADATA->parmin[P.init_LAIW_mem]=0.01; +CARDADATA->parmax[P.init_LAIW_mem]=1; + +/*Inverse of leaf longevity at any period i.e. background turnover (days-1)*/ +CARDADATA->parmin[P.t_foliar]=0.001; +CARDADATA->parmax[P.t_foliar]=0.1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1026/EDC1_1026.c === + +#pragma once +int EDC1_1026(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1026_PARAMETERS P=DALEC_1026_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +EDCD->pEDC=log((double)EDC); + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1026/MODEL_INFO_1026.c === + +#pragma once +#include "PARS_INFO_1026.c" +#include "DALEC_1026.c" +#include "EDC1_1026.c" +#include "EDC2_1026.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1026(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1026_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_DEDC_MODCONFIG(&MLF); + + +/*Step 2: Fill structure with model-specific info*/ + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1026; +DALECmodel.edc2=EDC2_1026; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1026(DATA); + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1026/DALEC_1026.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "../DALEC_ALL/LAI_KNORR.c" +#include "../DALEC_ALL/LAI_KNORR_funcs.c" +#include "../DALEC_ALL/LAI_GSI.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1026_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_soil; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +int T_phi; +int T_range; +int tau_m; +int plgr; +int k_leaf; +int lambda_max; +int tau_W; +int time_c; +int time_r; +int init_T_mem; +int init_LAIW_mem; +int t_foliar; +} DALEC_1026_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47 +}; + +struct DALEC_1026_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2lit; /*Wood description*/ +int root2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int target_LAI; /*LAI environmental target*/ +int T_memory; /*LAI temp memory*/ +int lambda_max_memory; /*LAI max memory*/ +int dlambda_dt; /*dLAI/dt*/ +int f_temp_thresh; /*f_temp_thres*/ +int f_dayl_thresh; /*f_dayl_thres*/ +int c_lim_flag; /*LAI carbon limitation flag*/ +int lai_fire; /*LAI fire loss*/ +int foliar_fire_frac; /*C_fol fire loss frac*/ +} DALEC_1026_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40, +}; + +struct DALEC_1026_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1026_POOLS={0,1,2,3,4,5,6,7,8}; + + +int DALEC_1026(DATA DATA, double const *pars) +{ + +struct DALEC_1026_PARAMETERS P=DALEC_1026_PARAMETERS; +struct DALEC_1026_FLUXES F=DALEC_1026_FLUXES; +struct DALEC_1026_POOLS S=DALEC_1026_POOLS; + +double gpppars[11],pi,lai_met_list[1],lai_var_list[21]; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + //Diagnostic states + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; + //printf("POOLS[S.D_LAI] = %2.2f\n",POOLS[S.D_LAI]); + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +// double wf=pars[P.leaf_fall]*sqrt(2)/2; +// double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +// double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +// double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +// double osf=offset(pars[P.t_foliar],wf); +// double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + +/*foliar carbon transfer intermediate variables*/ +double Fcfolavailable; + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + +//KNORR LAI// +if (n==0){ + /*Initialize phenology memory of air-temperature as some value within mintemp and maxtemp*/ + lai_var_list[5]=pars[P.init_T_mem]; + /*Initialize phenology memory of water/structural limitation */ + lai_var_list[11]=pars[P.init_LAIW_mem]*pars[P.lambda_max]; +} +lai_met_list[0]=(T2M_MAX[n]+T2M_MIN[n])/2.0; +lai_met_list[1]=VPD; + +lai_var_list[0]=DATA.ncdf_data.LAT; /*latitude*/ +lai_var_list[1]=DOY[n]; /*day of year*/ +lai_var_list[2]=pi; /*pi*/ +lai_var_list[3]=pars[P.T_phi]-5.0; +lai_var_list[4]=pars[P.T_phi]+5.0; +lai_var_list[5]=pars[P.time_c]-3.0; +lai_var_list[6]=pars[P.time_c]+3.0; +lai_var_list[7]=3.0; +lai_var_list[8]=10.0; +// Run Knorr LAI module +// double *LAI_KNORR_OUTPUT = LAI_KNORR(lai_met_list,lai_var_list); +// FLUXES[f+F.target_LAI]=LAI_KNORR_OUTPUT[0]; +// FLUXES[f+F.T_memory]=LAI_KNORR_OUTPUT[1]; +// FLUXES[f+F.lambda_max_memory]=LAI_KNORR_OUTPUT[2]; +// FLUXES[f+F.dlambda_dt]=LAI_KNORR_OUTPUT[3]/deltat; +FLUXES[f+F.dlambda_dt]=0.0; +// FLUXES[f+F.f_temp_thresh]=LAI_KNORR_OUTPUT[4]; +// FLUXES[f+F.f_dayl_thresh]=LAI_KNORR_OUTPUT[5]; +// lai_var_list[5]=FLUXES[f+F.T_memory]; /*Update LAI temperature memory state for next iteration*/ +// lai_var_list[11]=FLUXES[f+F.lambda_max_memory]; /*Update water/structural memory state for next iteration*/ +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=0; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*(pars[P.f_lab]+pars[P.f_foliar]); +Fcfolavailable=FLUXES[f+F.lab_prod] + POOLS[p+S.C_lab]/deltat; +if (FLUXES[f+F.dlambda_dt] > 0){ + FLUXES[f+F.lab_release]=MinQuadraticSmooth(Fcfolavailable, FLUXES[f+F.dlambda_dt]*pars[P.LCMA], 0.99); + /* flag for carbon availability limitation (0=canopy in senescence, 1=labile C does not limit growth, 2=labile C limits LAI growth) */ + FLUXES[f+F.c_lim_flag]=2.0; + /* leaf litter production: flux from foliar pool to litter pool */ + FLUXES[f+F.fol2lit]=POOLS[p+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))/deltat; +} +else { + FLUXES[f+F.c_lim_flag]=0.0; + /* labile release: flux from labile pool to foliar pool */ + FLUXES[f+F.lab_release]=0; + /* leaf litter production: flux from foliar pool to litter pool */ + FLUXES[f+F.fol2lit]=-FLUXES[f+F.dlambda_dt]*pars[P.LCMA]+POOLS[p+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))/deltat; +} +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +// FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +// FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.lab_release] - FLUXES[f+F.fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + /*Fraction of C-foliar lost due to fires*/ + FLUXES[f+F.foliar_fire_frac] = BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Calculate LAI (lambda) lost due to fire + - we lose the same fraction of LAI as we do C-foliar + - FE_\Lambda^{(t+1)} = \Lambda^{(t+1)'} * BA ( k_{factor(i)} + (1 - k_{factor(i)}) r )*/ + // FLUXES[f+F.lai_fire] = FLUXES[f+F.target_LAI]*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + FLUXES[f+F.lai_fire] = (POOLS[p+S.C_fol]/pars[P.LCMA])*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Subtract fire loss LAI from current LAI*/ + // FLUXES[f+34] = FLUXES[f+34] - FLUXES[f+39]; + + + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + //printf(" POOLS[nxp+S.D_LAI] = %2.2f\n", POOLS[nxp+S.D_LAI]); + + } + + +return 0; +} + + + +int DALEC_1026_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1026_PARAMETERS P=DALEC_1026_PARAMETERS; +struct DALEC_1026_FLUXES F=DALEC_1026_FLUXES; +struct DALEC_1026_POOLS S=DALEC_1026_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=48; +DALECmodel->nofluxes=41; +DALECmodel->dalec=DALEC_1026; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +// printf("DALEC_1026_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; + +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//SOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1026/EDC2_1026.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1026(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1026_PARAMETERS P=DALEC_1026_PARAMETERS; +struct DALEC_1026_FLUXES F=DALEC_1026_FLUXES; +struct DALEC_1026_POOLS S=DALEC_1026_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +// & ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +// {EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW}; + +// for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_831/DALEC_831.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_831(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + +double g; +/*SGS 7/17/19: Temp scaling factor*/ +/* local variable definition */ +/* PARS34 AND 35 */ +int Tminmin = pars[33] - 273.15; +int Tminmax = pars[34] - 273.15; /* optimization Sept. 17, 2019*/ + /* check the boolean condition */ + if( DATA.MET[m+1] < Tminmin ) { + /* if condition is true then do the following */ + g=0; + } + else if (DATA.MET[m+1] > Tminmax) { + g=1; + } + else { + g=(DATA.MET[m+1] - Tminmin)/(Tminmax - Tminmin); + } +/*printf("%2.2f\n",g);*/ +/*int length = sizeof(DATA.MET[m+1])/sizeof(int); */ +/*printf("length = %d",length);*/ + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1)*g; /*edit code here; times g?*/ +/*printf("GPP = %2.2f\n",FLUXES[f+0]);*/ + +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; + +/*double length = sizeof(FLUXES[f+28]);*/ +/*printf("length = %2.2f\n",length);*/ + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_831/MODEL_INFO_831.c === + +#pragma once +#include "PARS_INFO_831.c" +#include "DALEC_831.c" +#include "EDC1_831.c" +#include "EDC2_831.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_831(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=35; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_831; +DALECmodel.edc1=EDC1_831; +DALECmodel.edc2=EDC2_831; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_831(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_831/EDC1_831.c === + +#pragma once +int EDC1_831(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_831/EDC2_831.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_831(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_831/PARS_INFO_831.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_831(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/* Tminmin and Tminmax scaling factor*/ +CARDADATA->parmin[33]=258.15; +CARDADATA->parmax[33]=273.15; + +CARDADATA->parmin[34]=273.15; +CARDADATA->parmax[34]=288.15; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_809/EDC2_809.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_809(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_809/DALEC_809.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +int DALEC_809_MODCONFIG(DALEC * DALECmodel){ + + +DALECmodel->nopools=7; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=33; +DALECmodel->nofluxes=30; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_SOM_OBS=true; +OBSOPE.SUPPORT_GRACE_EWT_OBS=false; +OBSOPE.SUPPORT_FIR_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=0; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=1; +OBSOPE.LAI_LCMA=16; +//ET variabiles +OBSOPE.ET_flux=28; +//NBE-specific variables +static int NBE_fluxes[]={0,2,12,13,16}; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[]={0,1,2,3}; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//SOM-specific variables +static int SOM_pools[]={4,5}; +OBSOPE.SOM_pools=SOM_pools; +OBSOPE.SOM_n_pools=2; +//H2O-specific variables +//static int GRACE_EWT_h2o_pools[]={6,7}; +//OBSOPE.GRACE_EWT_h2o_pools=GRACE_EWT_h2o_pools; +//OBSOPE.GRACE_EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=16; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + + + +int DALEC_809(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + //NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_809/EDC1_809.c === + +#pragma once +int EDC1_809(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_809/MODEL_INFO_809.c === + +#pragma once +#include "PARS_INFO_809.c" +#include "DALEC_809.c" +#include "EDC1_809.c" +#include "EDC2_809.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_809(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +DALEC_809_MODCONFIG(&DALECmodel); + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_809; +DALECmodel.edc1=EDC1_809; +DALECmodel.edc2=EDC2_809; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_809(DATA); + + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_809/PARS_INFO_809.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_809(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1017/PARS_INFO_1017.c === + +#pragma once +#include "DALEC_1017.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1017(DATA *CARDADATA) +{ + +struct DALEC_1017_PARAMETERS P=DALEC_1017_PARAMETERS; + +/*Decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[P.temp_factor]=0.018; +CARDADATA->parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[P.canopy_eff]=5; +CARDADATA->parmax[P.canopy_eff]=50; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ + +CARDADATA->parmin[P.uWUE]=0.5; +CARDADATA->parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[P.PAW_Qmax]=1; +CARDADATA->parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[P.h2o_xfer]=0.01; +CARDADATA->parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[P.PUW_Qmax]=1; +CARDADATA->parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +CARDADATA->parmin[P.boese_r]=0.01; +CARDADATA->parmax[P.boese_r]=0.3; + +/*Tminmin scaling factor*/ +CARDADATA->parmin[P.Tminmin]=258.15; +CARDADATA->parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +CARDADATA->parmin[P.Tminmax]=273.15; +CARDADATA->parmax[P.Tminmax]=288.15; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +CARDADATA->parmin[P.i_SWE]=0.000001; +CARDADATA->parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +CARDADATA->parmin[P.min_melt]=240; +CARDADATA->parmax[P.min_melt]=270; + +/*sn2: slope*/ +CARDADATA->parmin[P.melt_slope]=0.00001; +CARDADATA->parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar*/ +CARDADATA->parmin[P.scf_scalar]=0.001; +CARDADATA->parmax[P.scf_scalar]=1000.0; + +/*Reference VPD */ +CARDADATA->parmin[P.vpd_ref]=10; +CARDADATA->parmax[P.vpd_ref]=10000; + +/*VPD curvature exponent */ +CARDADATA->parmin[P.vpd_exp]=0.001; +CARDADATA->parmax[P.vpd_exp]=1000; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1017/MODEL_INFO_1017.c === + +#pragma once +#include "PARS_INFO_1017.c" +#include "DALEC_1017.c" +#include "EDC1_1017.c" +#include "EDC2_1017.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1017(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1017_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1017; +DALECmodel.edc1=EDC1_1017; +DALECmodel.edc2=EDC2_1017; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1017(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_DEDC; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1017/EDC1_1017.c === + +#pragma once +int EDC1_1017(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1017_PARAMETERS P=DALEC_1017_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +EDCD->pEDC=log((double)EDC); + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1017/DALEC_1017.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1017_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_soil; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +int vpd_ref; +int vpd_exp; +int Tminmin; +int Tminmax; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +} DALEC_1017_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44 +}; + +struct DALEC_1017_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2lit; /*Wood description*/ +int root2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +int gpp_max; /*Potential GPP*/ +} DALEC_1017_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34 +}; + +struct DALEC_1017_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +} DALEC_1017_POOLS={ + 0,1,2,3,4,5,6,7,8 +}; + +int DALEC_1017_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1017_PARAMETERS P=DALEC_1017_PARAMETERS; +struct DALEC_1017_FLUXES F=DALEC_1017_FLUXES; +struct DALEC_1017_POOLS S=DALEC_1017_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=45; +DALECmodel->nofluxes=35; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1017_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + +int DALEC_1017(DATA DATA, double const *pars) +{ + +struct DALEC_1017_PARAMETERS P=DALEC_1017_PARAMETERS; +struct DALEC_1017_FLUXES F=DALEC_1017_FLUXES; +struct DALEC_1017_POOLS S=DALEC_1017_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +/*GPP*/ +FLUXES[f+F.gpp_max]=ACM(gpppars,constants); +FLUXES[f+F.gpp]=FLUXES[f+F.gpp_max]*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1)*(1-pow(fmin(fmax(VPD[n],0),pars[P.vpd_ref])/pars[P.vpd_ref],pars[P.vpd_exp]));; +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*Snow water equivalent*/ + POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ + FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ + POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ + FLUXES[f+F.scf]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); /*snow cover fraction*/ + /*PAW total runoff*/ + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1017/EDC2_1017.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1017(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1017_PARAMETERS P=DALEC_1017_PARAMETERS; +struct DALEC_1017_FLUXES F=DALEC_1017_FLUXES; +struct DALEC_1017_POOLS S=DALEC_1017_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +// & ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +// {EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW,P.i_SWE}; + +// for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1010/EDC1_1010.c === + +#pragma once +int EDC1_1010(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;}*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;}*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1010/MODEL_INFO_1010.c === + +#pragma once +#include "PARS_INFO_1010.c" +#include "DALEC_1010.c" +#include "EDC1_1010.c" +#include "EDC2_1010.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_1010(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=42; +DALECmodel.nofluxes=43; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1010; +DALECmodel.edc1=EDC1_1010; +DALECmodel.edc2=EDC2_1010; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1010(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1010/PARS_INFO_1010.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1010(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +//CARDADATA->parmin[9]=0.018; +//CARDADATA->parmax[9]=0.08; +CARDADATA->parmin[9]=1.2; +CARDADATA->parmax[9]=2; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + +/*jc PAW_fs fully saturated PAW*/ +CARDADATA->parmin[36]=10.0; +CARDADATA->parmax[36]=100000.0; + +/*jc N statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +CARDADATA->parmin[37]=1; +CARDADATA->parmax[37]=100.0; + +/*jc thetas_opt optimum thetas for water scaler fW*/ +CARDADATA->parmin[38]=0.2; +CARDADATA->parmax[38]=1.0; + +/*jc fwc the water scaler fW value at the end point C */ +CARDADATA->parmin[39]=0.01; +CARDADATA->parmax[39]=1.0; + +/*jc r_me CH4:CO2 conversion ratio*/ +CARDADATA->parmin[40]=0.001; +CARDADATA->parmax[40]=0.9; + +/*jc Q10ch4 Q10 for CH4 production */ +CARDADATA->parmin[41]=1.0; +CARDADATA->parmax[41]=3.0; + + + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1010/EDC2_1010.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1010(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} +/*EDC JointC: PAW < PAW_fs jc */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[18-1]==1)) & (pars[36]<(POOLS[6]*1))){EDC=ipow(0,EDCD->SWITCH[18-1]);EDCD->PASSFAIL[18-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1010/DALEC_1010.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_1010(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +double PAW_fs,N,thetas_opt,fwc,r_me,Q10ch4; /*jc*/ +double thetas,fT,fW,fV,theta_ae,fW1,fW2,fCH4,fT_ch4; /*jc*/ +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; /*shuang Labile C pool*/ + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + POOLS[0,6]=PAW; + POOLS[0,7]=PUW; + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. PAW runoff + 30. PAW -> PUW transfer + 31. PUW runoff + 32. Aerobic Rh from litter + 33. aerobic Rh from SOM + 34. anaerobic Rh from litter + 35. anaerobic Rh from SOM + 36. Rh_CO2 + 37. Rh_CH4 + 38. fV Volumetric fraction of aerobic Rh + 39. fT Temperature scaler + 40. fW Water scaler + 41. fCH4 CH4 fraction + 42. thetas=PAW/PAW_fs +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + +/*-----------------------------------------------------------------------*/ +/*jc get env. scalers ready*/ + /*Plant available water when the soil is fully saturated*/ + PAW_fs=pars[36]; + /*Apprximate for soil mointure percentage = PAW/PAW_fs*/ + thetas = POOLS[p+6]/PAW_fs; + /*tunable scaler describing the shape of the curve: PAW/PAW_fs against fractional volume of aerobic respiratio*/ + N=pars[37]; + /*optimum water scaler (fW), where the maximum respiration is achieved without limitation from water + it is the highest point in the function of PAW/PAW_fs against water scaler (fW)*/ + thetas_opt=pars[38]; + /*the lowest point of water scaler when the soil is fully saturated, + in the function of PAW/PAW_fs against water scaler (fW)*/ + fwc=pars[39]; + /*potential ratio of CO2 converted to CH4*/ + r_me=pars[40]; + /*Q10 of methane production*/ + Q10ch4=pars[41]; + + // if (thetas>=0 && thetas<=1){ + // // printf("thetas is between 0-1\n");} + // printf("\n");} + // else{ + // printf("ERROR 1: thetas is not between 0-1\n"); + // printf("Value of POOLS[p+6] = %f\n", POOLS[p+6]); + // printf("Value of PAW_fs = %f\n", PAW_fs); + // } + /* fT Temperature factor on respiration */ + // fT = fmin(1,exp(pars[9]*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp))); + //arrhenius + //fT = exp(pars[9]*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)); + //Q10 + fT = pow(pars[9],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)/10); + //fT = pow(pars[9],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)/10); + /* fV Volumetric factor seperating aerobic and anaerobic respiration */ + /* statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs) */ + fV = fmax(0,(1-pow(thetas,N))); + /* fW soil moisture scaler is a function of theta_ae*/ + theta_ae = ((thetas-1)/fV +1); + fW1 = 1/thetas_opt*theta_ae; + fW2 = ((1-fwc)/(thetas_opt-1)*theta_ae + (fwc-(1-fwc)/(thetas_opt-1))); + if (theta_ae>=0 && theta_ae < thetas_opt){ + fW = fW1;} + else if(theta_ae>=thetas_opt && theta_ae<=1){ + fW = fW2;} + else{ + fW = 0; + // printf("ERROR 2: theta_ae is larger than 1 or smaller than 0\n"); + // // printf("Value of theta_ae = %f\n", theta_ae); + // // printf("Value of thetas = %f\n", thetas); + // // printf("Value of fV = %f\n", fV); + // // printf("Value of POOLS[p+6] = %f\n", POOLS[p+6]); + // // printf("Value of PAW_fs = %f\n", PAW_fs); + } + /* fCH4*/ + // fT_ch4 = exp(Q10ch4*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)); + fT_ch4 = pow(Q10ch4,(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)/10); + fCH4 = fmin(r_me * fT_ch4,1); + // fCH4 = r_me * fT_ch4; + /* fmin() won't be needed once CH4 data is assimilated, as CH4 portion of CO2 should be very small, + manually put the upper limit 1 here mainly based on the mass balance, but notice that DIC is not + considered to contribute when the current timestep Rh is depeleted by CH4. I think it's good for + now. Can think about DIC pool meanwhile */ +/*-----------------------------------------------------------------------*/ + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=pow(pars[9],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)/10)*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +/*32 aerobic Rh from litter*/ +FLUXES[f+32] = POOLS[p+4]*(1-pow(1-fW*fT*fV*pars[8-1],deltat))/deltat; +/*33 aerobic Rh from SOM*/ +FLUXES[f+33] = POOLS[p+5]*(1-pow(1-fW*fT*fV*pars[9-1],deltat))/deltat; +/*34 anaerobic Rh from litter*/ +//FLUXES[f+34] = POOLS[p+4]*(1-pow(1-1*fT*(1-fV)*pars[8-1],deltat))/deltat; +FLUXES[f+34] = POOLS[p+4]*(1-pow(1-fwc*fT*(1-fV)*pars[8-1],deltat))/deltat; +/*35 anaerobic Rh from SOM*/ +//FLUXES[f+35] = POOLS[p+5]*(1-pow(1-1*fT*(1-fV)*pars[9-1],deltat))/deltat; +FLUXES[f+35] = POOLS[p+5]*(1-pow(1-fwc*fT*(1-fV)*pars[9-1],deltat))/deltat; +/*36 Rh_CO2*/ +FLUXES[f+36] = (FLUXES[f+32]+FLUXES[f+33])*1+(FLUXES[f+34]+FLUXES[f+35])*(1-fCH4); +/*37 Rh_CH4*/ +FLUXES[f+37] = (FLUXES[f+32]+FLUXES[f+33])*0+(FLUXES[f+34]+FLUXES[f+35])*fCH4; +/*38 fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+38] = fV; +/*39 fT Temperature scaler*/ +FLUXES[f+39] = fT; +/*40 fW Water scaler*/ +FLUXES[f+40] = fW; +/*41 fCH4 CH4 fraction*/ +FLUXES[f+41] = fCH4; +/*42 PAW/PAW_fs thetas*/ +FLUXES[f+42] = thetas; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*-----------------------------------------------------------------------*/ +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; +/*-----------------------------------------------------------------------*/ + /*jc*/ + /* POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat;*/ + POOLS[nxp+4]=POOLS[p+4]+(FLUXES[f+9]+FLUXES[f+11]-FLUXES[f+32]-FLUXES[f+34]-FLUXES[f+14])*deltat; + /*POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat;*/ + POOLS[nxp+5]=POOLS[p+5]+(FLUXES[f+14]-FLUXES[f+33]-FLUXES[f+35]+FLUXES[f+10])*deltat; +/*-----------------------------------------------------------------------*/ +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ +/*jc*/ +/* NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16];*/ +/* did not count for CH4 for a direct mapping to the observation NEE*/ +NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+36]+FLUXES[f+16]; + + +} + +return 0; +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_807/EDC2_807.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_807(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + + + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*Model info*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_807/MODEL_INFO_807.c === + +#pragma once +#include "PARS_INFO_807.c" +#include "DALEC_807.c" +#include "EDC1_807.c" +#include "EDC2_807.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + + + +int MODEL_INFO_807(DATA * DATA){ + + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33+8; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_807; +DALECmodel.edc1=EDC1_807; +DALECmodel.edc2=EDC2_807; + +/*Initialize parameter fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_807(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_807/EDC1_807.c === + +#pragma once +int EDC1_807(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + +/*Band checks here*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[33]>pars[34])){EDC=0;EDCD->PASSFAIL[16-1]=0;}*/ + + + +/*7 parameters*/ +/*PARS[33 - 39]*/ +/*Pband (band 1)*/ +double Pband_h2o_rz=pars[33]; +double Pband_h2o_ns=(1 - Pband_h2o_rz)*pars[34]; +double Pband_woo=1-Pband_h2o_rz-Pband_h2o_ns; +/*Lband (band 2)*/ +double Lband_h2o_rz=pars[35]; +double Lband_h2o_ns=(1 - Lband_h2o_rz)*pars[36]; +double Lband_woo=(1-Lband_h2o_rz-Lband_h2o_ns)*pars[37]; +double Lband_fol=1- Lband_h2o_rz - Lband_h2o_ns - Lband_woo; +/*Cband (band 3)*/ +double Cband_h2o_ns=pars[38]; +double Cband_woo=(1-Cband_h2o_ns)*pars[39]; +double Cband_fol=1-Cband_woo - Cband_h2o_ns; +/*Kuband (band 4)*/ +double Kuband_fol=pars[40]; +double Kuband_prec=1-Kuband_fol; +int allbandpass=1; +/* +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[33]>pars[34])){EDC=0;EDCD->PASSFAIL[16-1]=0;} +*/ + +if ((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)){ + +if (Pband_h2o_rzLband_h2o_ns){allbandpass=0;} +if (Pband_wooCband_h2o_ns){allbandpass=0;} +if (Lband_fol>Cband_fol){allbandpass=0;} +if (Kuband_folPASSFAIL[16-1]=0;} +} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +/*EDC 17 is up for grabs*/ + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_807/DALEC_807.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_807(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; +/*Copying "pars" into DATA.M_PARS*/ +for (n=0;nnomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_807/PARS_INFO_807.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ +/*TOR = turnover rate*/ + +int PARS_INFO_807(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired (fauto)*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fauto) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fauto-ffol) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR (turnover rate) wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temperature dependence factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE (inherent water-use efficiency): GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0 [mm]"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Fire-induced mortality".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*NS moisture pool*/ +CARDADATA->parmin[33]=0.1; +CARDADATA->parmax[33]=50; + +/*NS moisture focal point*/ +CARDADATA->parmin[34]=0.1; +CARDADATA->parmax[34]=500; + + + +/*Note: see below for definitions (work in progress)*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; +CARDADATA->parmin[34]=0.01; +CARDADATA->parmax[34]=1; +CARDADATA->parmin[35]=0.01; +CARDADATA->parmax[35]=1; +CARDADATA->parmin[36]=0.01; +CARDADATA->parmax[36]=1; +CARDADATA->parmin[37]=0.01; +CARDADATA->parmax[37]=1; +CARDADATA->parmin[38]=0.01; +CARDADATA->parmax[38]=1; +CARDADATA->parmin[39]=0.01; +CARDADATA->parmax[39]=1; +CARDADATA->parmin[40]=0.01; +CARDADATA->parmax[40]=1; + +/*7 parameters*/ +/*PARS[33 - 39]*/ +/*Pband (band 1)*/ +/*double Pband_h2o_rz=D.M_PARS[33]; +double Pband_h2o_ns=(1 - Pband_h2o_rz)*D.M_PARS[34]; +double Pband_woo=1-Pband_h2o_rz-Pband_h2o_ns; +*/ +/*Lband (band 2)*/ +/*double Lband_h2o_rz=D.M_PARS[35]; +double Lband_h2o_ns=(1 - Lband_h2o_rz)*D.M_PARS[36]; +double Lband_woo=(1-Lband_h2o_rz-Lband_h2o_ns)*D.M_PARS[37]; +double Lband_fol=1- Lband_h2o_rz - Lband_h2o_ns - Lband_woo; +*/ +/*Cband (band 3)*/ +/* +double Cband_h2o_ns=D.M_PARS[38]; +double Cband_woo=(1-Cband_h2o_ns)*D.M_PARS[39]; +double Cband_fol=1-Cband_woo - Cband_h2o_ns; +*/ +/*Kuband (band 4)*/ +/* +double Kuband_fol=D.M_PARS[40]; +double Kuband_prec=1-Kuband_fol; +*/ + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1080/EDC2_1080.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1080(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1080_PARAMETERS P=DALEC_1080_PARAMETERS; +struct DALEC_1080_FLUXES F=DALEC_1080_FLUXES; +struct DALEC_1080_POOLS S=DALEC_1080_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +// if (psw==1){ +// printf("****\n"); +// printf("DIAG = %i\n", DIAG); +// printf("EDC = %i\n",EDC); +// printf("EDCD->SWITCH[7-1+n] = %i\n",EDCD->SWITCH[7-1+n]); +// printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +// printf("Pool %i Fin = %f,Fout = %f\n",n,Fin[n],Fout[n]); +// printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n,Pstart,Pend,MPOOLSjan[n]); +// printf("fabs(log(Rs)) = %f\n",fabs(log(Rs))); +// printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +// printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +// printf("Rm = %f\n",Rm); +// printf("Rs = %f\n",Rs); +// printf("log(EQF) = %f\n",log(EQF)); +// printf("etol = %f\n",etol); +// printf("****\n");} +} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[23-1]==1)) & (pars[P.wilting_1]>MPOOLS[S.H2O_PAW_1])){EDC=ipow(0,EDCD->SWITCH[23-1]);EDCD->PASSFAIL[23-1]=0;} +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[24-1]==1)) & (pars[P.wilting_2]>MPOOLS[S.H2O_PAW_2])){EDC=ipow(0,EDCD->SWITCH[24-1]);EDCD->PASSFAIL[24-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile_1, P.i_labile_2, + P.i_foliar_1 ,P.i_foliar_2, + P.i_root_1,P.i_root_2, + P.i_wood_1,P.i_wood_2, + P.i_lit_1,P.i_lit_2, + P.i_soil_1,P.i_soil_2, + P.i_PAW_1,P.i_PAW_2, + P.i_PUW_1,P.i_PUW_2}; + +for (n=0;n<14;n++){if ((EDC==1 || DIAG==1) & ((MPOOLS[n])>parmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;};} + + + + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[36+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1080/DALEC_1080.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "DALEC_1080_INDICES.c" + +int DALEC_1080_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1080_PARAMETERS P=DALEC_1080_PARAMETERS; +struct DALEC_1080_FLUXES F=DALEC_1080_FLUXES; +struct DALEC_1080_POOLS S=DALEC_1080_POOLS; + +DALECmodel->nopools=8*3+1; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=37*2; +DALECmodel->nofluxes=32*2+4; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_CWOO_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_GPP_OBS=true; +//OBSOPE.SUPPORT_LAI_OBS=false; +OBSOPE.SUPPORT_iLAI_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; + +// OBSOPE.SUPPORT_CUE_OBS=true; +// OBSOPE.SUPPORT_Cefficiency_OBS=true; +// OBSOPE.SUPPORT_iniSOM_OBS=true; + + + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +//OBSOPE.LAI_foliar_pool=S.C_fol; +//OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[1]; +NBE_fluxes[0]=F.nbe; + +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={1}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=1; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//ABGB-specific variables +static int CWOO_pools[1]; +CWOO_pools[0]=S.C_woo; +OBSOPE.CWOO_pools=CWOO_pools; +OBSOPE.CWOO_n_pools=1; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +// OBSOPE.CUE_PARAM=P.f_auto; +// OBSOPE.Cefficiency_PARAM=P.canopy_eff; +// OBSOPE.iniSOM_PARAM=P.i_soil; + + + + + +DALECmodel->OBSOPE=OBSOPE; +return 0;} + + + +int DALEC_1080(DATA DATA, double const *pars) +{ + +struct DALEC_1080_PARAMETERS P=DALEC_1080_PARAMETERS; +struct DALEC_1080_FLUXES F=DALEC_1080_FLUXES; +struct DALEC_1080_POOLS S=DALEC_1080_POOLS; + +double gpppars[11]; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +double pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants_1[10]={pars[P.canopy_eff_1],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + double constants_2[10]={pars[P.canopy_eff_2],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab_1]=pars[P.i_labile_1]; + POOLS[S.C_lab_2]=pars[P.i_labile_2]; + POOLS[S.C_fol_1]=pars[P.i_foliar_1]; + POOLS[S.C_fol_2]=pars[P.i_foliar_2]; + POOLS[S.C_roo_1]=pars[P.i_root_1]; + POOLS[S.C_roo_2]=pars[P.i_root_2]; + POOLS[S.C_woo_1]=pars[P.i_wood_1]; + POOLS[S.C_woo_2]=pars[P.i_wood_2]; + POOLS[S.C_lit_1]=pars[P.i_lit_1]; + POOLS[S.C_lit_2]=pars[P.i_lit_2]; + POOLS[S.C_som_1]=pars[P.i_soil_1]; + POOLS[S.C_som_2]=pars[P.i_soil_2]; + /*water pools*/ + POOLS[S.H2O_PAW_1]=pars[P.i_PAW_1]; + POOLS[S.H2O_PAW_2]=pars[P.i_PAW_2]; + POOLS[S.H2O_PUW_1]=pars[P.i_PUW_1]; + POOLS[S.H2O_PUW_2]=pars[P.i_PUW_2]; + + +POOLS[S.C_lab]=( POOLS[S.C_lab_1]+ POOLS[S.C_lab_2])/2; +POOLS[S.C_fol]=(POOLS[S.C_fol_1]+POOLS[S.C_fol_2])/2; +POOLS[S.C_roo]=( POOLS[S.C_roo_1]+ POOLS[S.C_roo_2])/2; +POOLS[S.C_woo]=( POOLS[S.C_woo_1]+ POOLS[S.C_woo_2])/2; +POOLS[S.C_lit]=( POOLS[S.C_lit_1]+ POOLS[S.C_lit_2])/2; +POOLS[S.C_som]=( POOLS[S.C_som_1]+ POOLS[S.C_som_2])/2; +POOLS[S.H2O_PAW]=( POOLS[S.H2O_PAW_1]+ POOLS[S.H2O_PAW_2])/2; +POOLS[S.H2O_PUW]=( POOLS[S.H2O_PUW_1]+ POOLS[S.H2O_PUW_2])/2; + + + POOLS[S.LAI]=(POOLS[S.C_fol_1]/pars[P.LCMA_1] + POOLS[S.C_fol_2]/pars[P.LCMA_2])/2; + + + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + +double sf=365.25/pi; + + +double wf[2], wl[2],ff[2],fl[2],osf[2],osl[2]; +double CF[16]; + +for (m=0;m<2;m++){ +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ + +wf[m]=pars[P.leaf_fall_1+m]*sqrt(2)/2; +wl[m]=pars[P.labile_rel_1+m]*sqrt(2)/2; + ff[m]=(log(pars[P.t_foliar_1+m])-log(pars[P.t_foliar_1+m]-1))/2; +fl[m]=(log(pars[P.t_labile_1+m])-log(pars[P.t_labile_1+m]-1))/2; +osf[m]=offset(pars[P.t_foliar_1+m],wf[m]); +osl[m]=offset(pars[P.t_labile_1+m],wl[m]); + + +/*scaling to biyearly sine curve*/ + +/*Combustion factors*/ +CF[S.C_lab_1+m]=pars[P.cf_ligneous_1+m]; + +CF[S.C_fol_1+m]=pars[P.cf_foliar_1+m]; + +CF[S.C_roo_1+m]=pars[P.cf_ligneous_1+m]; + + +CF[S.C_woo_1+m]=pars[P.cf_ligneous_1+m]; + + +CF[S.C_lit_1+m]=pars[P.cf_foliar_1+m]/2+pars[P.cf_ligneous_1+m]/2; + +CF[S.C_som_1+m]=pars[P.cf_DOM_1+m]; + + + +} + + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + + +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + +/*LAI*/ + + +/*GPP*/ + + +/*GPP*/ +gpppars[0]=POOLS[p+S.C_fol_1]/pars[P.LCMA_2]; +FLUXES[f+F.gpp_1]=ACM(gpppars,constants_1)*fmin(POOLS[p+S.H2O_PAW_1]/pars[P.wilting_1],1); +gpppars[0]=POOLS[p+S.C_fol_2]/pars[P.LCMA_2]; +FLUXES[f+F.gpp_2]=ACM(gpppars,constants_2)*fmin(POOLS[p+S.H2O_PAW_2]/pars[P.wilting_2],1); + +FLUXES[f+F.gpp]=FLUXES[f+F.gpp_1]/2+FLUXES[f+F.gpp_2]/2; + +for (m=0;m<2;m++){ + +/*Evapotranspiration*/ +FLUXES[f+F.et_1+m]=FLUXES[f+F.gpp_1+m]*sqrt(VPD[n])/pars[P.uWUE_1+m]+SSRD[n]*pars[P.boese_r_1+m]; + + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate_1+m]=exp(pars[P.temp_factor_1+m]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture_1+m]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto_1+m]=pars[P.f_auto_1+m]*FLUXES[f+F.gpp_1+m]; +/*leaf production*/ +FLUXES[f+F.fol_prod_1+m]=(FLUXES[f+F.gpp_1+m]-FLUXES[f+F.resp_auto_1+m])*pars[P.f_foliar_1+m]; +/*labile production*/ +FLUXES[f+F.lab_prod_1+m] = (FLUXES[f+F.gpp_1+m]-FLUXES[f+F.resp_auto_1+m]-FLUXES[f+F.fol_prod_1+m])*pars[P.f_lab_1+m]; +/*root production*/ +FLUXES[f+F.root_prod_1+m] = (FLUXES[f+F.gpp_1+m]-FLUXES[f+F.resp_auto_1+m]-FLUXES[f+F.fol_prod_1+m]-FLUXES[f+F.lab_prod_1+m])*pars[P.f_root_1+m]; +/*wood production*/ +FLUXES[f+F.wood_prod_1+m] = FLUXES[f+F.gpp_1+m]-FLUXES[f+F.resp_auto_1+m]-FLUXES[f+F.fol_prod_1+m]-FLUXES[f+F.root_prod_1+m]-FLUXES[f+F.lab_prod_1+m]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact_1+m] = (2/sqrt(pi))*(ff[m]/wf[m])*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday_1+m]+osf[m])/sf)*sf/wf[m],2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact_1+m]=(2/sqrt(pi))*(fl[m]/wl[m])*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday_1+m]+osl[m])/sf)*sf/wl[m],2)); + +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release_1+m] = POOLS[p+S.C_lab_1+m]*(1-pow(1-FLUXES[f+F.lab_release_fact_1+m],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit_1+m] = POOLS[p+S.C_fol_1+m]*(1-pow(1-FLUXES[f+F.leaffall_fact_1+m],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.wood2lit_1+m] = POOLS[p+S.C_woo_1+m]*(1-pow(1-pars[P.t_wood_1+m],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit_1+m] = POOLS[p+S.C_roo_1+m]*(1-pow(1-pars[P.t_root_1+m],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit_1+m] = POOLS[p+S.C_lit_1+m]*(1-pow(1-FLUXES[f+F.temprate_1+m]*pars[P.t_lit_1+m],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som_1+m] = POOLS[p+S.C_som_1+m]*(1-pow(1-FLUXES[f+F.temprate_1+m]*pars[P.t_soil_1+m],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som_1+m] = POOLS[p+S.C_lit_1+m]*(1-pow(1-pars[P.tr_lit2soil_1+m]*FLUXES[f+F.temprate_1+m],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab_1+m] = POOLS[p+S.C_lab_1+m] + (FLUXES[f+F.lab_prod_1+m]-FLUXES[f+F.lab_release_1+m])*deltat; + POOLS[nxp+S.C_fol_1+m] = POOLS[p+S.C_fol_1+m] + (FLUXES[f+F.fol_prod_1+m] - FLUXES[f+F.fol2lit_1+m] + FLUXES[f+F.lab_release_1+m])*deltat; + POOLS[nxp+S.C_roo_1+m] = POOLS[p+S.C_roo_1+m] + (FLUXES[f+F.root_prod_1+m] - FLUXES[f+F.root2lit_1+m])*deltat; + POOLS[nxp+S.C_woo_1+m] = POOLS[p+S.C_woo_1+m] + (FLUXES[f+F.wood_prod_1+m] - FLUXES[f+F.wood2lit_1+m])*deltat; + POOLS[nxp+S.C_lit_1+m] = POOLS[p+S.C_lit_1+m] + (FLUXES[f+F.fol2lit_1+m] + FLUXES[f+F.root2lit_1+m] - FLUXES[f+F.resp_het_lit_1+m] - FLUXES[f+F.lit2som_1+m])*deltat; + POOLS[nxp+S.C_som_1+m]= POOLS[p+S.C_som_1+m]+ (FLUXES[f+F.lit2som_1+m] - FLUXES[f+F.resp_het_som_1+m]+FLUXES[f+F.wood2lit_1+m])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw_1+m]=pow(POOLS[p+S.H2O_PAW_1+m],2)/pars[P.PAW_Qmax_1+m]/deltat*(1-pars[P.h2o_xfer_1+m]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw_1+m]=FLUXES[f+F.q_paw_1+m]*pars[P.h2o_xfer_1+m]/(1-pars[P.h2o_xfer_1+m]); + /*PUW runoff*/ + FLUXES[f+F.q_puw_1+m]=pow(POOLS[p+S.H2O_PUW_1+m],2)/pars[P.PUW_Qmax_1+m]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW_1+m]>pars[P.PAW_Qmax_1+m]/2){FLUXES[f+F.q_paw_1+m]=(POOLS[p+S.H2O_PAW_1+m]-pars[P.PAW_Qmax_1+m]/4)/deltat*(1-pars[P.h2o_xfer_1+m]); + FLUXES[f+F.paw2puw_1+m]=(POOLS[p+S.H2O_PAW_1+m]-pars[P.PAW_Qmax_1+m]/4)/deltat*pars[P.h2o_xfer_1+m]/(1-pars[P.h2o_xfer_1+m]);} + if (POOLS[p+S.H2O_PUW_1+m]>pars[P.PUW_Qmax_1+m]/2){FLUXES[f+F.q_puw_1+m]=(POOLS[p+S.H2O_PUW_1+m]-pars[P.PUW_Qmax_1+m]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW_1+m]=POOLS[p+S.H2O_PAW_1+m] + (-FLUXES[f+F.q_paw_1+m] - FLUXES[f+F.paw2puw_1+m] + PREC[n] - FLUXES[f+F.et_1+m])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW_1+m]=POOLS[p+S.H2O_PUW_1+m] + (FLUXES[f+F.paw2puw_1+m] - FLUXES[f+F.q_puw_1+m])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + double BA=BURNED_AREA[n]; + FLUXES[f+F.f_lab_1+m] = POOLS[nxp+S.C_lab_1+m]*BA*CF[S.C_lab_1+m]/deltat; + FLUXES[f+F.f_fol_1+m] = POOLS[nxp+S.C_fol_1+m]*BA*CF[S.C_fol_1+m]/deltat; + FLUXES[f+F.f_roo_1+m] = POOLS[nxp+S.C_roo_1+m]*BA*CF[S.C_roo_1+m]/deltat; + FLUXES[f+F.f_woo_1+m] = POOLS[nxp+S.C_woo_1+m]*BA*CF[S.C_woo_1+m]/deltat; + FLUXES[f+F.f_lit_1+m] = POOLS[nxp+S.C_lit_1+m]*BA*CF[S.C_lit_1+m]/deltat; + FLUXES[f+F.f_som_1+m] = POOLS[nxp+S.C_som_1+m]*BA*CF[S.C_som_1+m]/deltat; + + FLUXES[f+F.fx_lab2lit_1+m] = POOLS[nxp+S.C_lab_1+m]*BA*(1-CF[S.C_lab_1+m])*(1-pars[P.resilience_1+m])/deltat; + FLUXES[f+F.fx_fol2lit_1+m] = POOLS[nxp+S.C_fol_1+m]*BA*(1-CF[S.C_fol_1+m])*(1-pars[P.resilience_1+m])/deltat; + FLUXES[f+F.fx_roo2lit_1+m] = POOLS[nxp+S.C_roo_1+m]*BA*(1-CF[S.C_roo_1+m])*(1-pars[P.resilience_1+m])/deltat; + FLUXES[f+F.fx_woo2som_1+m] = POOLS[nxp+S.C_woo_1+m]*BA*(1-CF[S.C_woo_1+m])*(1-pars[P.resilience_1+m])/deltat; + FLUXES[f+F.fx_lit2som_1+m] = POOLS[nxp+S.C_lit_1+m]*BA*(1-CF[S.C_lit_1+m])*(1-pars[P.resilience_1+m])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab_1+m] = POOLS[nxp+S.C_lab_1+m]-(FLUXES[f+F.f_lab_1+m]+FLUXES[f+F.fx_lab2lit_1+m])*deltat; + POOLS[nxp+S.C_fol_1+m] = POOLS[nxp+S.C_fol_1+m]-(FLUXES[f+F.f_fol_1+m]+FLUXES[f+F.fx_fol2lit_1+m])*deltat; + POOLS[nxp+S.C_roo_1+m] = POOLS[nxp+S.C_roo_1+m]-(FLUXES[f+F.f_roo_1+m]+FLUXES[f+F.fx_roo2lit_1+m])*deltat; + POOLS[nxp+S.C_woo_1+m] = POOLS[nxp+S.C_woo_1+m]-(FLUXES[f+F.f_woo_1+m]+FLUXES[f+F.fx_woo2som_1+m])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit_1+m] = POOLS[nxp+S.C_lit_1+m]+(FLUXES[f+F.fx_lab2lit_1+m]+FLUXES[f+F.fx_fol2lit_1+m]+FLUXES[f+F.fx_roo2lit_1+m]-FLUXES[f+F.f_lit_1+m]-FLUXES[f+F.fx_lit2som_1+m])*deltat; + /*som*/ + POOLS[nxp+S.C_som_1+m] = POOLS[nxp+S.C_som_1+m]+(FLUXES[f+F.fx_woo2som_1+m]+FLUXES[f+F.fx_lit2som_1+m]-FLUXES[f+F.f_som_1+m])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total_1+m] = FLUXES[f+F.f_lab_1+m] + FLUXES[f+F.f_fol_1+m] + FLUXES[f+F.f_roo_1+m] + FLUXES[f+F.f_woo_1+m] + FLUXES[f+F.f_lit_1+m] + FLUXES[f+F.f_som_1+m]; + + +} + + + FLUXES[f+F.f_total] =(FLUXES[f+F.f_total_1] + FLUXES[f+F.f_total_2])/2; + FLUXES[f+F.nbe]=(FLUXES[f+F.resp_auto_1] + FLUXES[f+F.resp_het_lit_1] + FLUXES[f+F.resp_het_som_1] + FLUXES[f+F.f_total_1] - FLUXES[f+F.gpp_1])/2 + + (FLUXES[f+F.resp_auto_2] + FLUXES[f+F.resp_het_lit_2] + FLUXES[f+F.resp_het_som_2] + FLUXES[f+F.f_total_2] - FLUXES[f+F.gpp_2])/2; + + FLUXES[f+F.et]=(FLUXES[f+F.et_1] + FLUXES[f+F.et_2])/2; + POOLS[nxp+S.C_lab]=(POOLS[nxp+S.C_lab_1]+POOLS[nxp+S.C_lab_2])/2; + POOLS[nxp+S.C_fol]=(POOLS[nxp+S.C_fol_1]+POOLS[nxp+S.C_fol_2])/2; + POOLS[nxp+S.C_roo]=(POOLS[nxp+S.C_roo_1]+POOLS[nxp+S.C_roo_2])/2; + POOLS[nxp+S.C_woo]=(POOLS[nxp+S.C_woo_1]+POOLS[nxp+S.C_woo_2])/2; + POOLS[nxp+S.C_lit]=(POOLS[nxp+S.C_lit_1]+POOLS[nxp+S.C_lit_2])/2; + POOLS[nxp+S.C_som]=(POOLS[nxp+S.C_som_1]+POOLS[nxp+S.C_som_2])/2; + POOLS[nxp+S.H2O_PAW]=(POOLS[nxp+S.H2O_PAW_1]+POOLS[nxp+S.H2O_PAW_2])/2; + POOLS[nxp+S.H2O_PUW]= (POOLS[nxp+S.H2O_PUW_1]+POOLS[nxp+S.H2O_PUW_2])/2; +//Derive LAI + + POOLS[nxp+S.LAI]=(POOLS[nxp+S.C_fol_1]/pars[P.LCMA_1] + POOLS[nxp+S.C_fol_2]/pars[P.LCMA_2])/2; + //inline (inbuilt) LAI observartion operator + LAI[n]=(POOLS[nxp+S.LAI] + POOLS[p+S.LAI])/2; + + +} + + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1080/DALEC_1080_INDICES.c === + + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1080_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil_1; +int tr_lit2soil_2; +int f_auto_1; +int f_auto_2; +int f_foliar_1; +int f_foliar_2; +int f_root_1; +int f_root_2; +int t_foliar_1; +int t_foliar_2; +int t_wood_1; +int t_wood_2; +int t_root_1; +int t_root_2; +int t_lit_1; +int t_lit_2; +int t_soil_1; +int t_soil_2; +int temp_factor_1; +int temp_factor_2; +int canopy_eff_1; +int canopy_eff_2; +int Bday_1; +int Bday_2; +int f_lab_1; +int f_lab_2; +int labile_rel_1; +int labile_rel_2; +int Fday_1; +int Fday_2; +int leaf_fall_1; +int leaf_fall_2; +int LCMA_1; +int LCMA_2; +int i_labile_1; +int i_labile_2; +int i_foliar_1; +int i_foliar_2; +int i_root_1; +int i_root_2; +int i_wood_1; +int i_wood_2; +int i_lit_1; +int i_lit_2; +int i_soil_1; +int i_soil_2; +int uWUE_1; +int uWUE_2; +int PAW_Qmax_1; +int PAW_Qmax_2; +int wilting_1; +int wilting_2; +int i_PAW_1; +int i_PAW_2; +int cf_foliar_1; +int cf_foliar_2; +int cf_ligneous_1; +int cf_ligneous_2; +int cf_DOM_1; +int cf_DOM_2; +int resilience_1; +int resilience_2; +int t_labile_1; +int t_labile_2; +int moisture_1; +int moisture_2; +int h2o_xfer_1; +int h2o_xfer_2; +int PUW_Qmax_1; +int PUW_Qmax_2; +int i_PUW_1; +int i_PUW_2; +int boese_r_1; +int boese_r_2; +} DALEC_1080_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69, + 70,71,72,73 +};//37*2 = 74 + +struct DALEC_1080_FLUXES{ +/*DALEC FLUXES*/ +int gpp_1; /*GPP*/ +int gpp_2; /*GPP*/ +int temprate_1; /*Temprate*/ +int temprate_2; /*Temprate*/ +int resp_auto_1; /*Autotrophic respiration*/ +int resp_auto_2; /*Autotrophic respiration*/ +int fol_prod_1; /*Foliar production*/ +int fol_prod_2; /*Foliar production*/ +int lab_prod_1; /*Labile production*/ +int lab_prod_2; /*Labile production*/ +int root_prod_1; /*Root production*/ +int root_prod_2; /*Root production*/ +int wood_prod_1; /*Wood production*/ +int wood_prod_2; /*Wood production*/ +int lab_release_1; /*Labile release*/ +int lab_release_2; /*Labile release*/ +int leaffall_fact_1; /*Leaffall factor*/ +int leaffall_fact_2; /*Leaffall factor*/ +int fol2lit_1; /*Foliar decomposition*/ +int fol2lit_2; /*Foliar decomposition*/ +int wood2lit_1; /*Wood description*/ +int wood2lit_2; /*Wood description*/ +int root2lit_1; /*Root decomposition*/ +int root2lit_2; /*Root decomposition*/ +int resp_het_lit_1; /*Litter heterotrophic respiration*/ +int resp_het_lit_2; /*Litter heterotrophic respiration*/ +int resp_het_som_1; /*Soil heterotrophic respiration*/ +int resp_het_som_2; /*Soil heterotrophic respiration*/ +int lit2som_1; /*Litter decomposition*/ +int lit2som_2; /*Litter decomposition*/ +int lab_release_fact_1; /*Labile release factor*/ +int lab_release_fact_2; /*Labile release factor*/ +int f_total_1; /*Flux description*/ +int f_total_2; /*Flux description*/ +int f_lab_1; /*Labile fire loss*/ +int f_lab_2; /*Labile fire loss*/ +int f_fol_1; /*Foliar fire loss*/ +int f_fol_2; /*Foliar fire loss*/ +int f_roo_1; /*Wood fire loss*/ +int f_roo_2; /*Wood fire loss*/ +int f_woo_1; /*Root fire loss*/ +int f_woo_2; /*Root fire loss*/ +int f_lit_1; /*Litter fire loss*/ +int f_lit_2; /*Litter fire loss*/ +int f_som_1; /*Soil fire loss*/ +int f_som_2; /*Soil fire loss*/ +int fx_lab2lit_1; /*Fire transfer labile to litter*/ +int fx_lab2lit_2; /*Fire transfer labile to litter*/ +int fx_fol2lit_1; /*Fire transfer foliar to litter*/ +int fx_fol2lit_2; /*Fire transfer foliar to litter*/ +int fx_roo2lit_1; /*Fire transfer root to litter*/ +int fx_roo2lit_2; /*Fire transfer root to litter*/ +int fx_woo2som_1; /*Fire transfer wood to soil*/ +int fx_woo2som_2; /*Fire transfer wood to soil*/ +int fx_lit2som_1; /*Fire transfer litter to soil*/ +int fx_lit2som_2; /*Fire transfer litter to soil*/ +int et_1; /*Evapotranspiration*/ +int et_2; /*Evapotranspiration*/ +int q_paw_1; /*Plant-available water drainage*/ +int q_paw_2; /*Plant-available water drainage*/ +int paw2puw_1; /*Plant-available water to plant-unavailable water transfer*/ +int paw2puw_2; /*Plant-available water to plant-unavailable water transfer*/ +int q_puw_1; /*Plant-unavailable water runoff*/ +int q_puw_2; /*Plant-unavailable water runoff*/ +int gpp; /*GPP*/ +int et; /*ET*/ +int f_total;//FTotal +int nbe; +} DALEC_1080_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63, + //aggregates + 64,65,66,67}; + +struct DALEC_1080_POOLS{ +/*DALEC POOLS*/ +int C_lab_1; /*Labile C*/ +int C_lab_2; /*Labile C*/ +int C_fol_1; /*Foliar C*/ +int C_fol_2; /*Foliar C*/ +int C_roo_1; /*Root C*/ +int C_roo_2; /*Root C*/ +int C_woo_1; /*Wood C*/ +int C_woo_2; /*Wood C*/ +int C_lit_1; /*Litter C*/ +int C_lit_2; /*Litter C*/ +int C_som_1; /*Soil C*/ +int C_som_2; /*Soil C*/ +int H2O_PAW_1; /*Plant available H2O*/ +int H2O_PAW_2; /*Plant available H2O*/ +int H2O_PUW_1; /*Plant unavailable H2O*/ +int H2O_PUW_2; /*Plant unavailable H2O*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int LAI; /*LAI*/ +} DALEC_1080_POOLS={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15, +//aggregates +16,17,18,19,20,21,22,23, + //ancillary + 24}; + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1080/MODEL_INFO_1080.c === + +#pragma once +#include "PARS_INFO_1080.c" +#include "DALEC_1080.c" +#include "EDC1_1080.c" +#include "EDC2_1080.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1080(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1080_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1080; +DALECmodel.edc1=EDC1_1080; +DALECmodel.edc2=EDC2_1080; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1080(DATA); + + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1080/EDC1_1080.c === + +#pragma once +int EDC1_1080(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1080_PARAMETERS P=DALEC_1080_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; + +int m; +for (m=0;m<2;m++){ + int edco=50*m; + +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto_1+m]; +double const ffol=(1-fauto)*pars[P.f_foliar_1+m]; +double const flab=(1-fauto-ffol)*pars[P.f_lab_1+m]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root_1+m]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil_1+m]/(pars[P.tr_lit2soil_1+m]+pars[P.t_lit_1+m]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar_1+m]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[edco+1-1]==1)) & (pars[P.t_soil_1+m]>pars[P.t_lit_1+m])){EDC=0;EDCD->PASSFAIL[edco+1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[edco+2-1]==1)) & (pars[P.tr_lit2soil_1+m]PASSFAIL[edco+2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[edco+3-1]==1)) & (pars[P.t_wood_1+m]>torfol)){EDC=0;EDCD->PASSFAIL[edco+3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[edco+4-1]==1)) & (pars[P.t_root_1+m]PASSFAIL[edco+4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[edco+6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[edco+5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[edco+5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[edco+40-1]==1)) & (pars[P.cf_foliar_1+m]PASSFAIL[edco+40-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[edco+17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[edco+17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + +} + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1080/PARS_INFO_1080.c === + +#pragma once +#include "DALEC_1080.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1080(DATA *CARDADATA) +{ + +struct DALEC_1080_PARAMETERS P=DALEC_1080_PARAMETERS; + +double * parmin=CARDADATA->parmin; +double * parmax=CARDADATA->parmax; +/*Decomposition rate*/ +parmin[P.tr_lit2soil_1]=0.00001; +parmax[P.tr_lit2soil_1]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto_1]=0.2; +parmax[P.f_auto_1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar_1]=0.01; +parmax[P.f_foliar_1]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root_1]=0.01; +parmax[P.f_root_1]=1; + +/*Leaf Lifespan*/ +parmin[P.t_foliar_1]=1.001; +parmax[P.t_foliar_1]=8; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood_1]=0.000025; +parmax[P.t_wood_1]=0.001; + +/*TOR roots*/ +parmin[P.t_root_1]=0.0001; +parmax[P.t_root_1]=0.01; + +/*TOR litter*/ +parmin[P.t_lit_1]=0.0001; +parmax[P.t_lit_1]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil_1]=0.0000001; +parmax[P.t_soil_1]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor_1]=0.018; +parmax[P.temp_factor_1]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff_1]=5; +parmax[P.canopy_eff_1]=50; + +/*Bday*/ +parmin[P.Bday_1]=365.25; +parmax[P.Bday_1]=365.25*4; + +/*Fraction to Clab*/ +parmin[P.f_lab_1]=0.01; +parmax[P.f_lab_1]=0.5; + +/*Clab Release period*/ +parmin[P.labile_rel_1]=365.25/12; +parmax[P.labile_rel_1]=100; + +/*Fday*/ +parmin[P.Fday_1]=365.25; +parmax[P.Fday_1]=365.25*4; + +/*Leaf fall period*/ +parmin[P.leaf_fall_1]=365.25/12; +parmax[P.leaf_fall_1]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA_1]=5; +parmax[P.LCMA_1]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile_1]=1.0; +parmax[P.i_labile_1]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar_1]=1.0; +parmax[P.i_foliar_1]=2000.0; + +/*C roots*/ +parmin[P.i_root_1]=1.0; +parmax[P.i_root_1]=2000.0; + +/*C_wood*/ +parmin[P.i_wood_1]=1.0; +parmax[P.i_wood_1]=100000.0; + +/*C litter*/ +parmin[P.i_lit_1]=1.0; +parmax[P.i_lit_1]=2000.0; + +/*C_som*/ +parmin[P.i_soil_1]=1.0; +parmax[P.i_soil_1]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ + +parmin[P.uWUE_1]=0.5; +parmax[P.uWUE_1]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax_1]=1; +parmax[P.PAW_Qmax_1]=100000; + +/*"Wilting point"*/ +parmin[P.wilting_1]=1; +parmax[P.wilting_1]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW_1]=1; +parmax[P.i_PAW_1]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar_1]=0.01; +parmax[P.cf_foliar_1]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous_1]=0.01; +parmax[P.cf_ligneous_1]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM_1]=0.01; +parmax[P.cf_DOM_1]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30_1])) ".*/ +parmin[P.resilience_1]=0.01; +parmax[P.resilience_1]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile_1]=1.001; +parmax[P.t_labile_1]=8; + +/*Moisture factor*/ +parmin[P.moisture_1]=0.01; +parmax[P.moisture_1]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer_1]=0.01; +parmax[P.h2o_xfer_1]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax_1]=1; +parmax[P.PUW_Qmax_1]=100000; + +/*PUW pool*/ +parmin[P.i_PUW_1]=1; +parmax[P.i_PUW_1]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r_1]=0.01; +parmax[P.boese_r_1]=0.3; + + + + +/*Decomposition rate*/ +parmin[P.tr_lit2soil_2]=0.00001; +parmax[P.tr_lit2soil_2]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto_2]=0.2; +parmax[P.f_auto_2]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar_2]=0.01; +parmax[P.f_foliar_2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root_2]=0.01; +parmax[P.f_root_2]=1; + +/*Leaf Lifespan*/ +parmin[P.t_foliar_2]=1.001; +parmax[P.t_foliar_2]=8; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood_2]=0.000025; +parmax[P.t_wood_2]=0.001; + +/*TOR roots*/ +parmin[P.t_root_2]=0.0001; +parmax[P.t_root_2]=0.01; + +/*TOR litter*/ +parmin[P.t_lit_2]=0.0001; +parmax[P.t_lit_2]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil_2]=0.0000001; +parmax[P.t_soil_2]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor_2]=0.018; +parmax[P.temp_factor_2]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff_2]=5; +parmax[P.canopy_eff_2]=50; + +/*Bday*/ +parmin[P.Bday_2]=365.25; +parmax[P.Bday_2]=365.25*4; + +/*Fraction to Clab*/ +parmin[P.f_lab_2]=0.01; +parmax[P.f_lab_2]=0.5; + +/*Clab Release period*/ +parmin[P.labile_rel_2]=365.25/12; +parmax[P.labile_rel_2]=100; + +/*Fday*/ +parmin[P.Fday_2]=365.25; +parmax[P.Fday_2]=365.25*4; + +/*Leaf fall period*/ +parmin[P.leaf_fall_2]=365.25/12; +parmax[P.leaf_fall_2]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA_2]=5; +parmax[P.LCMA_2]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile_2]=1.0; +parmax[P.i_labile_2]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar_2]=1.0; +parmax[P.i_foliar_2]=2000.0; + +/*C roots*/ +parmin[P.i_root_2]=1.0; +parmax[P.i_root_2]=2000.0; + +/*C_wood*/ +parmin[P.i_wood_2]=1.0; +parmax[P.i_wood_2]=100000.0; + +/*C litter*/ +parmin[P.i_lit_2]=1.0; +parmax[P.i_lit_2]=2000.0; + +/*C_som*/ +parmin[P.i_soil_2]=1.0; +parmax[P.i_soil_2]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ + +parmin[P.uWUE_2]=0.5; +parmax[P.uWUE_2]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax_2]=1; +parmax[P.PAW_Qmax_2]=100000; + +/*"Wilting point"*/ +parmin[P.wilting_2]=1; +parmax[P.wilting_2]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW_2]=1; +parmax[P.i_PAW_2]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar_2]=0.01; +parmax[P.cf_foliar_2]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous_2]=0.01; +parmax[P.cf_ligneous_2]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM_2]=0.01; +parmax[P.cf_DOM_2]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30_2])) ".*/ +parmin[P.resilience_2]=0.01; +parmax[P.resilience_2]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile_2]=1.001; +parmax[P.t_labile_2]=8; + +/*Moisture factor*/ +parmin[P.moisture_2]=0.01; +parmax[P.moisture_2]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer_2]=0.01; +parmax[P.h2o_xfer_2]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax_2]=1; +parmax[P.PUW_Qmax_2]=100000; + +/*PUW pool*/ +parmin[P.i_PUW_2]=1; +parmax[P.i_PUW_2]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r_2]=0.01; +parmax[P.boese_r_2]=0.3; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1045/DALEC_1045.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "DALEC_1045_INDICES.c" + +int DALEC_1045(DATA DATA, double const *pars) +{ + +struct DALEC_1045_PARAMETERS P=DALEC_1045_PARAMETERS; +struct DALEC_1045_FLUXES F=DALEC_1045_FLUXES; +struct DALEC_1045_POOLS S=DALEC_1045_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +//double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + /****Diagnostic states***/ + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; //LAI + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *YIELD=DATA.ncdf_data.YIELD.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; +//LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.woo2som] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.woo2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.woo2som])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + +//Removing YIELD; using fixed fracs for pools + + + POOLS[nxp+S.C_lab] += - YIELD[n]*0.4; + POOLS[nxp+S.C_fol] += - YIELD[n]*0.1; + POOLS[nxp+S.C_roo] += - YIELD[n]*0.1; + POOLS[nxp+S.C_woo] += - YIELD[n]*0.4; + + + + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + + POOLS[nxp+S.C_lit] += YIELD[n]*0.1; + POOLS[nxp+S.C_som] +=YIELD[n]*0.4; + + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + +} + +return 0; +} + + + + + +int DALEC_1045_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1045_PARAMETERS P=DALEC_1045_PARAMETERS; +struct DALEC_1045_FLUXES F=DALEC_1045_FLUXES; +struct DALEC_1045_POOLS S=DALEC_1045_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=37; +DALECmodel->nofluxes=32; +DALECmodel->dalec=DALEC_1045; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1045_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_CWOO_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; + + + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//ABGB-specific variables +static int CWOO_pools[1]; +CWOO_pools[0]=S.C_woo; +OBSOPE.CWOO_pools=CWOO_pools; +OBSOPE.CWOO_n_pools=1; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; +OBSOPE.iniSOM_PARAM=P.i_som; + + + + + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1045/EDC2_1045.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1045(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1045_PARAMETERS P=DALEC_1045_PARAMETERS; +struct DALEC_1045_FLUXES F=DALEC_1045_FLUXES; +struct DALEC_1045_POOLS S=DALEC_1045_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("DIAG = %i\n", DIAG); +printf("EDC = %i\n",EDC); +printf("EDCD->SWITCH[7-1+n] = %i\n",EDCD->SWITCH[7-1+n]); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Rs)) = %f\n",fabs(log(Rs))); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_som,P.i_PAW,P.i_PUW}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1045/PARS_INFO_1045.c === + +#pragma once +#include "DALEC_1045.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1045(DATA *CARDADATA) +{ + +struct DALEC_1045_PARAMETERS P=DALEC_1045_PARAMETERS; + +double * parmin=CARDADATA->parmin; +double * parmax=CARDADATA->parmax; + +/*Decomposition rate*/ +parmin[P.tr_lit2soil]=0.00001; +parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar]=0.01; +parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +parmin[P.t_foliar]=1.001; +parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil]=0.0000001; +parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor]=0.018; +parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff]=5; +parmax[P.canopy_eff]=50; + +/*Bday*/ +parmin[P.Bday]=365.25; +parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +parmin[P.labile_rel]=365.25/12; +parmax[P.labile_rel]=100; + +/*Fday*/ +parmin[P.Fday]=365.25; +parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +parmin[P.leaf_fall]=365.25/12; +parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*;The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.uWUE]=0.5; +parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax]=1; +parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile]=1.001; +parmax[P.t_labile]=8; + +/*Moisture factor*/ +parmin[P.moisture]=0.01; +parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer]=0.01; +parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax]=1; +parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r]=0.01; +parmax[P.boese_r]=0.3; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1045/EDC1_1045.c === + +#pragma once +int EDC1_1045(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1045_PARAMETERS P=DALEC_1045_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1045/MODEL_INFO_1045.c === + +#pragma once +#include "PARS_INFO_1045.c" +#include "DALEC_1045.c" +#include "EDC1_1045.c" +#include "EDC2_1045.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1045(DATA * DATA){ +printf("*****************MADE IT*****************\n"); +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1045_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_MODCONFIG(&MLF); + + +/*Step 2: Fill structure with model-specific info*/ + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1045; +DALECmodel.edc2=EDC2_1045; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1045(DATA); + + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_STEPWISE; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1045/DALEC_1045_INDICES.c === + + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1045_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_som; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +} DALEC_1045_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36 +}; + +struct DALEC_1045_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int woo2som; /*Wood description*/ +int root2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*Plant-available water drainage*/ +int paw2puw; /*Plant-available water to plant-unavailable water transfer*/ +int q_puw; /*Plant-unavailable water runoff*/ +} DALEC_1045_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31 +}; + +struct DALEC_1045_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1045_POOLS={0,1,2,3,4,5,6,7,8}; + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1011/DALEC_1011.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ +/*DALEC 1011 is DALEC-JCR v2, updated ET and replaced Prec with Infiltration for PAW balance equation, two new output fluxes and two new pars*/ + +int DALEC_1011(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +double PAW_fs,N,thetas_opt,fwc,r_me,Q10ch4; /*jc*/ +double thetas,fT,fW,fV,theta_ae,fW1,fW2,fCH4,fT_ch4; /*jc*/ +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; /*shuang Labile C pool*/ + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET updated method from Boese et al 2017 and Yan et al 2021 + 29. Runoff + 30. PAW -> PUW transfer + 31. PUW runoff + 32. Aerobic Rh from litter + 33. aerobic Rh from SOM + 34. anaerobic Rh from litter + 35. anaerobic Rh from SOM + 36. Rh_CO2 + 37. Rh_CH4 + 38. fV Volumetric fraction of aerobic Rh + 39. fT Temperature scaler + 40. fW Water scaler + 41. fCH4 CH4 fraction + 42. thetas=PAW/PAW_fs + 43. Infiltration rate, mm/day + 44. Runoff rate, mm/day +*/ + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + +/*-----------------------------------------------------------------------*/ +/*jc get env. scalers ready*/ + /*Plant available water when the soil is fully saturated*/ + PAW_fs=pars[36]; + /*Apprximate for soil mointure percentage = PAW/PAW_fs*/ + thetas = POOLS[p+6]/PAW_fs; + /*tunable scaler describing the shape of the curve: PAW/PAW_fs against fractional volume of aerobic respiratio*/ + N=pars[37]; + /*optimum water scaler (fW), where the maximum respiration is achieved without limitation from water + it is the highest point in the function of PAW/PAW_fs against water scaler (fW)*/ + thetas_opt=pars[38]; + /*the lowest point of water scaler when the soil is fully saturated, + in the function of PAW/PAW_fs against water scaler (fW)*/ + fwc=pars[39]; + /*potential ratio of CO2 converted to CH4*/ + r_me=pars[40]; + /*Q10 of methane production*/ + Q10ch4=pars[41]; + + // if (thetas>=0 && thetas<=1){ + // // printf("thetas is between 0-1\n");} + // printf("\n");} + // else{ + // printf("ERROR 1: thetas is not between 0-1\n"); + // printf("Value of POOLS[p+6] = %f\n", POOLS[p+6]); + // printf("Value of PAW_fs = %f\n", PAW_fs); + // } + /* fT Temperature factor on respiration */ + // fT = fmin(1,exp(pars[9]*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp))); + //arrhenius + //fT = exp(pars[9]*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)); + //Q10 + fT = pow(pars[9],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)/10); + //fT = pow(pars[9],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)/10); + /* fV Volumetric factor seperating aerobic and anaerobic respiration */ + /* statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs) */ + fV = fmax(0,(1-pow(thetas,N))); + /* fW soil moisture scaler is a function of theta_ae*/ + theta_ae = ((thetas-1)/fV +1); + fW1 = 1/thetas_opt*theta_ae; + fW2 = ((1-fwc)/(thetas_opt-1)*theta_ae + (fwc-(1-fwc)/(thetas_opt-1))); + if (theta_ae>=0 && theta_ae < thetas_opt){ + fW = fW1;} + else if(theta_ae>=thetas_opt && theta_ae<=1){ + fW = fW2;} + else{ + fW = 0; + // printf("ERROR 2: theta_ae is larger than 1 or smaller than 0\n"); + // // printf("Value of theta_ae = %f\n", theta_ae); + // // printf("Value of thetas = %f\n", thetas); + // // printf("Value of fV = %f\n", fV); + // // printf("Value of POOLS[p+6] = %f\n", POOLS[p+6]); + // // printf("Value of PAW_fs = %f\n", PAW_fs); + } + /* fCH4*/ + // fT_ch4 = exp(Q10ch4*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)); + fT_ch4 = pow(Q10ch4,(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)/10); + fCH4 = fmin(r_me * fT_ch4,1); + // fCH4 = r_me * fT_ch4; + /* fmin() won't be needed once CH4 data is assimilated, as CH4 portion of CO2 should be very small, + manually put the upper limit 1 here mainly based on the mass balance, but notice that DIC is not + considered to contribute when the current timestep Rh is depeleted by CH4. I think it's good for + now. Can think about DIC pool meanwhile */ +/*-----------------------------------------------------------------------*/ + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7]) DALEC-JCR v2 updated with radiantion residual component, from Boese and Yan et al 2021*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]+DATA.MET[m+3]*pars[42]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=pow(pars[9],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-DATA.meantemp)/10)*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +/*32 aerobic Rh from litter*/ +FLUXES[f+32] = POOLS[p+4]*(1-pow(1-fW*fT*fV*pars[8-1],deltat))/deltat; +/*33 aerobic Rh from SOM*/ +FLUXES[f+33] = POOLS[p+5]*(1-pow(1-fW*fT*fV*pars[9-1],deltat))/deltat; +/*34 anaerobic Rh from litter*/ +//FLUXES[f+34] = POOLS[p+4]*(1-pow(1-1*fT*(1-fV)*pars[8-1],deltat))/deltat; +FLUXES[f+34] = POOLS[p+4]*(1-pow(1-fwc*fT*(1-fV)*pars[8-1],deltat))/deltat; +/*35 anaerobic Rh from SOM*/ +//FLUXES[f+35] = POOLS[p+5]*(1-pow(1-1*fT*(1-fV)*pars[9-1],deltat))/deltat; +FLUXES[f+35] = POOLS[p+5]*(1-pow(1-fwc*fT*(1-fV)*pars[9-1],deltat))/deltat; +/*36 Rh_CO2*/ +FLUXES[f+36] = (FLUXES[f+32]+FLUXES[f+33])*1+(FLUXES[f+34]+FLUXES[f+35])*(1-fCH4); +/*37 Rh_CH4*/ +FLUXES[f+37] = (FLUXES[f+32]+FLUXES[f+33])*0+(FLUXES[f+34]+FLUXES[f+35])*fCH4; +/*38 fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+38] = fV; +/*39 fT Temperature scaler*/ +FLUXES[f+39] = fT; +/*40 fW Water scaler*/ +FLUXES[f+40] = fW; +/*41 fCH4 CH4 fraction*/ +FLUXES[f+41] = fCH4; +/*42 PAW/PAW_fs thetas*/ +FLUXES[f+42] = thetas; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*-----------------------------------------------------------------------*/ +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; +/*-----------------------------------------------------------------------*/ + /*jc*/ + /* POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat;*/ + POOLS[nxp+4]=POOLS[p+4]+(FLUXES[f+9]+FLUXES[f+11]-FLUXES[f+32]-FLUXES[f+34]-FLUXES[f+14])*deltat; + /*POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat;*/ + POOLS[nxp+5]=POOLS[p+5]+(FLUXES[f+14]-FLUXES[f+33]-FLUXES[f+35]+FLUXES[f+10])*deltat; +/*-----------------------------------------------------------------------*/ +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} +/*updates in DALEC-JCR v2*/ +/*I =Imax *(1-exp(-Pt/Imax)) +PAW = PAW + (-PAWrunoff – PAW->PUWtransfer + I- ET)*deltat;*/ +/*Infiltration rate*/ + FLUXES[f+43]=pars[43]*(1-exp(-DATA.MET[m+8]/pars[43])); +/*runoff rate*/ + FLUXES[f+44]=DATA.MET[m+8]-FLUXES[f+43]; + /*Plant-available water budget*/ + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + FLUXES[f+43] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ +/*jc*/ +/* NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16];*/ +/* did not count for CH4 for a direct mapping to the observation NEE*/ +NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+36]+FLUXES[f+16]; + + +} + +return 0; +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1011/EDC2_1011.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1011(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} +/*EDC JointC: PAW < PAW_fs jc */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[18-1]==1)) & (pars[36]<(POOLS[6]*1))){EDC=ipow(0,EDCD->SWITCH[18-1]);EDCD->PASSFAIL[18-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1011/PARS_INFO_1011.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1011(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +//CARDADATA->parmin[9]=0.018; +//CARDADATA->parmax[9]=0.08; +CARDADATA->parmin[9]=1.2; +CARDADATA->parmax[9]=2; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + +/*jc PAW_fs fully saturated PAW*/ +CARDADATA->parmin[36]=10.0; +CARDADATA->parmax[36]=100000.0; + +/*jc N statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +CARDADATA->parmin[37]=1; +CARDADATA->parmax[37]=100.0; + +/*jc thetas_opt optimum thetas for water scaler fW*/ +CARDADATA->parmin[38]=0.2; +CARDADATA->parmax[38]=1.0; + +/*jc fwc the water scaler fW value at the end point C */ +CARDADATA->parmin[39]=0.01; +CARDADATA->parmax[39]=1.0; + +/*jc r_me CH4:CO2 conversion ratio*/ +CARDADATA->parmin[40]=0.001; +CARDADATA->parmax[40]=0.9; + +/*jc Q10ch4 Q10 for CH4 production */ +CARDADATA->parmin[41]=1.0; +CARDADATA->parmax[41]=3.0; + +/*jc v2 rET radiation coefficient in ET, unitless*/ +CARDADATA->parmin[42]=0.01; +CARDADATA->parmax[42]=0.3; + +/*jc v2 Imax maximum infiltration rate, mm/day same with prec */ +CARDADATA->parmin[43]=100/(365.25/12); +CARDADATA->parmax[43]=2000/(365.25/12); + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1011/MODEL_INFO_1011.c === + +#pragma once +#include "PARS_INFO_1011.c" +#include "DALEC_1011.c" +#include "EDC1_1011.c" +#include "EDC2_1011.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_1011(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=44; +DALECmodel.nofluxes=45; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1011; +DALECmodel.edc1=EDC1_1011; +DALECmodel.edc2=EDC2_1011; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1011(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1011/EDC1_1011.c === + +#pragma once +int EDC1_1011(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;}*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;}*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_806/PARS_INFO_806.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ +/*TOR = turnover rate*/ + +int PARS_INFO_806(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired (fauto)*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fauto) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fauto-ffol) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR (turnover rate) wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temperature dependence factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE (inherent water-use efficiency): GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Fire-induced mortality".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*Note: definitions not 100% clear yet (work in progress)*/ +/*Band 1 = lowest freq*/ +/*Band 1 sensitivity to Foliage (from 100%, remainder is to be partitioned)*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; +/*Band 2 sensitivity to Foliage (from 100%, remainder is to be partitioned)*/ +CARDADATA->parmin[34]=0.01; +CARDADATA->parmax[34]=1; +/*b1fb1wb2fb2w*/ + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_806/MODEL_INFO_806.c === + +#pragma once +#include "PARS_INFO_806.c" +#include "DALEC_806.c" +#include "EDC1_806.c" +#include "EDC2_806.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + + + +int MODEL_INFO_806(DATA * DATA){ + + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33+2; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_806; +DALECmodel.edc1=EDC1_806; +DALECmodel.edc2=EDC2_806; + +/*Initialize parameter fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_806(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_806/EDC1_806.c === + +#pragma once +int EDC1_806(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[33]>pars[34])){EDC=0;EDCD->PASSFAIL[16-1]=0;} + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +/*EDC 17 is up for grabs*/ + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_806/DALEC_806.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_806(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; +/*Copying "pars" into DATA.M_PARS*/ +for (n=0;nnomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_806/EDC2_806.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_806(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + + + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*Model info*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1016/EDC2_1016.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1016(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1016_PARAMETERS P=DALEC_1016_PARAMETERS; +struct DALEC_1016_FLUXES F=DALEC_1016_FLUXES; +struct DALEC_1016_POOLS S=DALEC_1016_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOW=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW,P.i_SWE}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1016/DALEC_1016.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1016_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_soil; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +int Tminmin; +int Tminmax; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +} DALEC_1016_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42 +}; + +struct DALEC_1016_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2lit; /*Wood description*/ +int root2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +} DALEC_1016_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33 +}; + +struct DALEC_1016_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +} DALEC_1016_POOLS={ + 0,1,2,3,4,5,6,7,8 +}; + +int DALEC_1016_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1016_PARAMETERS P=DALEC_1016_PARAMETERS; +struct DALEC_1016_FLUXES F=DALEC_1016_FLUXES; +struct DALEC_1016_POOLS S=DALEC_1016_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=43; +DALECmodel->nofluxes=34; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1016_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + +int DALEC_1016(DATA DATA, double const *pars) +{ + +struct DALEC_1016_PARAMETERS P=DALEC_1016_PARAMETERS; +struct DALEC_1016_FLUXES F=DALEC_1016_FLUXES; +struct DALEC_1016_POOLS S=DALEC_1016_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1)*g; +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*Snow water equivalent*/ + POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ + FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ + POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ + FLUXES[f+F.scf]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); /*snow cover fraction*/ + /*PAW total runoff*/ + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1016/EDC1_1016.c === + +#pragma once +int EDC1_1016(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1016_PARAMETERS P=DALEC_1016_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1016/MODEL_INFO_1016.c === + +#pragma once +#include "PARS_INFO_1016.c" +#include "DALEC_1016.c" +#include "EDC1_1016.c" +#include "EDC2_1016.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1016(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1016_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1016; +DALECmodel.edc1=EDC1_1016; +DALECmodel.edc2=EDC2_1016; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1016(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1016/PARS_INFO_1016.c === + +#pragma once +#include "DALEC_1016.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1016(DATA *CARDADATA) +{ + +struct DALEC_1016_PARAMETERS P=DALEC_1016_PARAMETERS; + +/*Decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[P.temp_factor]=0.018; +CARDADATA->parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[P.canopy_eff]=5; +CARDADATA->parmax[P.canopy_eff]=50; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ + +CARDADATA->parmin[P.uWUE]=0.5; +CARDADATA->parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[P.PAW_Qmax]=1; +CARDADATA->parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[P.h2o_xfer]=0.01; +CARDADATA->parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[P.PUW_Qmax]=1; +CARDADATA->parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +CARDADATA->parmin[P.boese_r]=0.01; +CARDADATA->parmax[P.boese_r]=0.3; + +/*Tminmin scaling factor*/ +CARDADATA->parmin[P.Tminmin]=258.15; +CARDADATA->parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +CARDADATA->parmin[P.Tminmax]=273.15; +CARDADATA->parmax[P.Tminmax]=288.15; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +CARDADATA->parmin[P.i_SWE]=0.000001; +CARDADATA->parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +CARDADATA->parmin[P.min_melt]=240; +CARDADATA->parmax[P.min_melt]=270; + +/*sn2: slope*/ +CARDADATA->parmin[P.melt_slope]=0.00001; +CARDADATA->parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar*/ +CARDADATA->parmin[P.scf_scalar]=0.001; +CARDADATA->parmax[P.scf_scalar]=1000.0; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_808/PARS_INFO_808.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ +/*TOR = turnover rate*/ + +int PARS_INFO_808(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired (fauto)*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fauto) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fauto-ffol) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR (turnover rate) wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temperature dependence factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE (inherent water-use efficiency): GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0 [mm]"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Fire-induced mortality".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*NS moisture pool*/ +CARDADATA->parmin[33]=0.1; +CARDADATA->parmax[33]=50; + +/*NS moisture focal point*/ +CARDADATA->parmin[34]=0.1; +CARDADATA->parmax[34]=500; + + + +/*Note: see below for definitions (work in progress)*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; +CARDADATA->parmin[34]=0.01; +CARDADATA->parmax[34]=1; +CARDADATA->parmin[35]=0.01; +CARDADATA->parmax[35]=1; +CARDADATA->parmin[36]=0.01; +CARDADATA->parmax[36]=1; +CARDADATA->parmin[37]=0.01; +CARDADATA->parmax[37]=1; +CARDADATA->parmin[38]=0.01; +CARDADATA->parmax[38]=1; +CARDADATA->parmin[39]=0.01; +CARDADATA->parmax[39]=1; +CARDADATA->parmin[40]=0.01; +CARDADATA->parmax[40]=1; + +/*7 parameters*/ +/*PARS[33 - 39]*/ +/*Pband (band 1)*/ +/*double Pband_h2o_rz=D.M_PARS[33]; +double Pband_h2o_ns=(1 - Pband_h2o_rz)*D.M_PARS[34]; +double Pband_woo=1-Pband_h2o_rz-Pband_h2o_ns; +*/ +/*Lband (band 2)*/ +/*double Lband_h2o_rz=D.M_PARS[35]; +double Lband_h2o_ns=(1 - Lband_h2o_rz)*D.M_PARS[36]; +double Lband_woo=(1-Lband_h2o_rz-Lband_h2o_ns)*D.M_PARS[37]; +double Lband_fol=1- Lband_h2o_rz - Lband_h2o_ns - Lband_woo; +*/ +/*Cband (band 3)*/ +/* +double Cband_h2o_ns=D.M_PARS[38]; +double Cband_woo=(1-Cband_h2o_ns)*D.M_PARS[39]; +double Cband_fol=1-Cband_woo - Cband_h2o_ns; +*/ +/*Kuband (band 4)*/ +/* +double Kuband_fol=D.M_PARS[40]; +double Kuband_prec=1-Kuband_fol; +*/ + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_808/DALEC_808.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_808(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; +/*Copying "pars" into DATA.M_PARS*/ +for (n=0;nnomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_808/EDC1_808.c === + +#pragma once +int EDC1_808(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + +/*Band checks here*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[33]>pars[34])){EDC=0;EDCD->PASSFAIL[16-1]=0;}*/ + + + +/*7 parameters*/ +/*PARS[33 - 39]*/ +/*Pband (band 1)*/ +double Pband_h2o_rz=pars[33]; +double Pband_h2o_ns=(1 - Pband_h2o_rz)*pars[34]; +double Pband_woo=1-Pband_h2o_rz-Pband_h2o_ns; +/*Lband (band 2)*/ +double Lband_h2o_rz=pars[35]; +double Lband_h2o_ns=(1 - Lband_h2o_rz)*pars[36]; +double Lband_woo=(1-Lband_h2o_rz-Lband_h2o_ns)*pars[37]; +double Lband_fol=1- Lband_h2o_rz - Lband_h2o_ns - Lband_woo; +/*Cband (band 3)*/ +double Cband_h2o_ns=pars[38]; +double Cband_woo=(1-Cband_h2o_ns)*pars[39]; +double Cband_fol=1-Cband_woo - Cband_h2o_ns; +/*Kuband (band 4)*/ +double Kuband_fol=pars[40]; +double Kuband_prec=1-Kuband_fol; +int allbandpass=1; +/* +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[33]>pars[34])){EDC=0;EDCD->PASSFAIL[16-1]=0;} +*/ + +if ((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)){ + +if (Pband_h2o_ns/Pband_h2o_rz>Lband_h2o_ns/Lband_h2o_rz){allbandpass=0;} +if (Pband_h2o_ns/Pband_woo>Lband_h2o_ns/Lband_woo){allbandpass=0;} +if (Lband_h2o_ns/Lband_woo>Cband_h2o_ns/Cband_woo){allbandpass=0;} +if (Lband_fol/Lband_woo>Cband_fol/Cband_woo){allbandpass=0;} + +/* +if (Pband_h2o_rzLband_h2o_ns){allbandpass=0;} +if (Pband_wooCband_h2o_ns){allbandpass=0;} +if (Lband_fol>Cband_fol){allbandpass=0;} +if (Kuband_folPASSFAIL[16-1]=0;} +} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +/*EDC 17 is up for grabs*/ + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_808/MODEL_INFO_808.c === + +#pragma once +#include "PARS_INFO_808.c" +#include "DALEC_808.c" +#include "EDC1_808.c" +#include "EDC2_808.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + + + +int MODEL_INFO_808(DATA * DATA){ + + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33+8; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_808; +DALECmodel.edc1=EDC1_808; +DALECmodel.edc2=EDC2_808; + +/*Initialize parameter fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_808(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_808/EDC2_808.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_808(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + + + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*Model info*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_830/PARS_INFO_830.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_830(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_830/EDC2_830.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_830(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_830/DALEC_830.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_830(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + +double g; +/*SGS 7/17/19: Temp scaling factor*/ +/* local variable definition */ +/* PARS34 AND 35 */ +int Tminmin = -3; +int Tminmax = 3; /* sensitivity test Sept. 12 2019 */ + /* check the boolean condition */ + if( DATA.MET[m+1] < Tminmin ) { + /* if condition is true then do the following */ + g=0; + } + else if (DATA.MET[m+1] > Tminmax) { + g=1; + } + else { + g=(DATA.MET[m+1] - Tminmin)/(Tminmax - Tminmin); + } +/*printf("%2.2f\n",g);*/ +/*int length = sizeof(DATA.MET[m+1])/sizeof(int); */ +/*printf("length = %d",length);*/ + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1)*g; /*edit code here; times g?*/ +/*printf("GPP = %2.2f\n",FLUXES[f+0]);*/ + +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; + +/*double length = sizeof(FLUXES[f+28]);*/ +/*printf("length = %2.2f\n",length);*/ + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_830/MODEL_INFO_830.c === + +#pragma once +#include "PARS_INFO_830.c" +#include "DALEC_830.c" +#include "EDC1_830.c" +#include "EDC2_830.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_830(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_830; +DALECmodel.edc1=EDC1_830; +DALECmodel.edc2=EDC2_830; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_830(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_830/EDC1_830.c === + +#pragma once +int EDC1_830(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_812/PARS_INFO_812.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_812(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*uWUE: GPP*VPD/ET: gC/kgH2o *hPa^0.5*/ +CARDADATA->parmin[23]=6; +CARDADATA->parmax[23]=12; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_812/EDC1_812.c === + +#pragma once +int EDC1_812(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_812/MODEL_INFO_812.c === + +#pragma once +#include "PARS_INFO_812.c" +#include "DALEC_812.c" +#include "EDC1_812.c" +#include "EDC2_812.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_812(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_812; +DALECmodel.edc1=EDC1_812; +DALECmodel.edc2=EDC2_812; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_812(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_812/DALEC_812.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_812(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*sqrt(DATA.MET[m+7])/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*(DATA.MET[m+2]*0.5+DATA.MET[m+1]*0.5-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_812/EDC2_812.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_812(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1005/DALEC_1005.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "DALEC_1005_INDICES.c" + + +int DALEC_1005(DATA DATA, double const *pars) +{ + +struct DALEC_1005_PARAMETERS P=DALEC_1005_PARAMETERS; +struct DALEC_1005_FLUXES F=DALEC_1005_FLUXES; +struct DALEC_1005_POOLS S=DALEC_1005_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +//double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + /****Diagnostic states***/ + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; //LAI + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; +//LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.woo2som] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.roo2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.woo2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.roo2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.woo2som])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + +} + +return 0; +} + + + + + +int DALEC_1005_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1005_PARAMETERS P=DALEC_1005_PARAMETERS; +struct DALEC_1005_FLUXES F=DALEC_1005_FLUXES; +struct DALEC_1005_POOLS S=DALEC_1005_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=37; +DALECmodel->nofluxes=32; +DALECmodel->dalec=DALEC_1005; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1005_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_CWOO_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; + + + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//ABGB-specific variables +static int CWOO_pools[1]; +CWOO_pools[0]=S.C_woo; +OBSOPE.CWOO_pools=CWOO_pools; +OBSOPE.CWOO_n_pools=1; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; +OBSOPE.iniSOM_PARAM=P.i_som; + + + + + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1005/DALEC_1005_INDICES.c === + + +struct DALEC_1005_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_som; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +} DALEC_1005_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36 +}; + +struct DALEC_1005_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int woo2som; /*Wood description*/ +int roo2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*Plant-available water drainage*/ +int paw2puw; /*Plant-available water to plant-unavailable water transfer*/ +int q_puw; /*Plant-unavailable water runoff*/ +} DALEC_1005_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31 +}; + +struct DALEC_1005_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1005_POOLS={0,1,2,3,4,5,6,7,8}; + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1005/EDC2_1005.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1005(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1005_PARAMETERS P=DALEC_1005_PARAMETERS; +struct DALEC_1005_FLUXES F=DALEC_1005_FLUXES; +struct DALEC_1005_POOLS S=DALEC_1005_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("DIAG = %i\n", DIAG); +printf("EDC = %i\n",EDC); +printf("EDCD->SWITCH[7-1+n] = %i\n",EDCD->SWITCH[7-1+n]); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Rs)) = %f\n",fabs(log(Rs))); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_som,P.i_PAW,P.i_PUW}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1005/PARS_INFO_1005.c === + +#pragma once +#include "DALEC_1005.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1005(double *parmin, double *parmax) +{ + +struct DALEC_1005_PARAMETERS P=DALEC_1005_PARAMETERS; + + +/*Decomposition rate*/ +parmin[P.tr_lit2soil]=0.00001; +parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar]=0.01; +parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +parmin[P.t_foliar]=1.001; +parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil]=0.0000001; +parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor]=0.018; +parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff]=5; +parmax[P.canopy_eff]=50; + +/*Bday*/ +parmin[P.Bday]=365.25; +parmax[P.Bday]=1461.0; // 365.25*4; + +/*Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +parmin[P.labile_rel]=30.4375; // 365.25/12; +parmax[P.labile_rel]=100; + +/*Fday*/ +parmin[P.Fday]=365.25; +parmax[P.Fday]=1461.0; // 365.25*4; + +/*Leaf fall period*/ +parmin[P.leaf_fall]=30.4375; // 365.25/12; +parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*;The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.uWUE]=0.5; +parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax]=1; +parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile]=1.001; +parmax[P.t_labile]=8; + +/*Moisture factor*/ +parmin[P.moisture]=0.01; +parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer]=0.01; +parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax]=1; +parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r]=0.01; +parmax[P.boese_r]=0.3; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1005/EDC1_1005.c === + +#pragma once +int EDC1_1005(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1005_PARAMETERS P=DALEC_1005_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1005/MODEL_INFO_1005.c === + +#pragma once +#include "PARS_INFO_1005.c" +#include "DALEC_1005.c" +#include "EDC1_1005.c" +#include "EDC2_1005.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1005(DATA * DATA){ +printf("*****************MADE IT*****************\n"); +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1005_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_MODCONFIG(&MLF); + + +/*Step 2: Fill structure with model-specific info*/ + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1005; +DALECmodel.edc2=EDC2_1005; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1005(DATA->parmin, DATA->parmax); + + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_STEPWISE; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1002/EDC2_1002.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1002(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1002/DALEC_1002.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +int DALEC_1002(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*sqrt(DATA.MET[m+7])/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + /*Plant-available water ODE*/ + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1002/MODEL_INFO_1002.c === + +#pragma once +#include "PARS_INFO_1002.c" +#include "DALEC_1002.c" +#include "EDC1_1002.c" +#include "EDC2_1002.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1002(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=36; +DALECmodel.nofluxes=32; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1002; +DALECmodel.edc1=EDC1_1002; +DALECmodel.edc2=EDC2_1002; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1002(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1002/EDC1_1002.c === + +#pragma once +int EDC1_1002(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1002/PARS_INFO_1002.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1002(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*uWUE: GPP*VPD/ET: gC/kgH2o *hPa^0.5*/ +CARDADATA->parmin[23]=6; +CARDADATA->parmax[23]=12; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_410/PARS_INFO_400.c === + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_410(DATA *CARDADATA) +{ + +CARDADATA->nopars=33; + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + + +/*TOR wood*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + + +/*Temp factor*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 410 g m-2, i.e. 5 200 gC m-2*/ + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile @ t=0*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar @ t=0*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots @ t=0*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C wood @ t=0*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter @ t=0*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C som @ t=0*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_410/EDC2_400.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + + + + + +int EDC2_410(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + + + + + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + + + +/*THESE EDC2 checks are for DALEC_FIRES2*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + +/*FIRES*/ +int nomet=7,nopools=6; +int nofluxes=28; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nLAImax){EDC=0;EDCD->PASSFAIL[5-1]=0;}}}*/ +/*MLAI=mean_pointer_vector(LAI,nodays);*/ + + + +/*EDC no 6*/ +/*0.2*Cf < Cr < 5*Cf*/ +/*Cfoliar : Croot = 5:1 or 1:5*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*EDC 7*/ +/*G10 = 2 - growth factor in 10 years*/ +/*for any further constraint please incorporate in likelyhood*/ +/*int noyears=floor(nodays*deltat/365); +double G=0.1; +int y;*/ + + +/*mean annual pool array*/ +/*double *MAPOOL=calloc(noyears,sizeof(double)); +for (n=0;nG*(double)noyears)){EDC=0;EDCD->PASSFAIL[7-1]=0;}}*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1]==1)) & (MAPOOL[noyears-1]/MAPOOL[0]>(1+G*(double)noyears))){EDC=pow(0,EDCD->SWITCH[7-1]);;EDCD->PASSFAIL[7-1]=0;} + +} +*/ + + + +/*EDC no 8*/ +/*POOL EXPONENTIAL DECAY*/ +/*Performed on all seven pools*/ + +/*exporting the decay coefficient here*/ +/*double C;double cyears=3; +for (n=0;nSWITCH[8-1]==1)) { +C=expdecay2(POOLS,n,nodays+1,deltat,nopools); +if (fabs(-log(2)/C)<(365.25*cyears) & C<0 & isfinite(C)){EDC=pow(0,EDCD->SWITCH[8-1]);;EDCD->PASSFAIL[8-1]=0;}}}; +*/ + + + +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; + +/*fraction of GPP to som and lit under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); +double const flit=(froot+flab+ffol); + + + +/*SOM attractor - must be within a factor of 2 from Csom0*/ +/*half the TR is balanced by x2 Csom*/ + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; +/*No longer need mean GPP estimate*/ +/*double meangpp=0;for (n=0;nSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=pow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + + + + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ + +for (n=0;n<6;n++){if ((EDC==1 || DIAG==1) & ((MPOOLS[n])>parmax[n+17])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1;}} + + + + + + + + + +/*FREE MEMORY*/ +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + +/*Returning EDC */ +return EDC; + + + + + + + + + + + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_410/MODEL_INFO_400.c === + +#pragma once +#include "PARS_INFO_410.c" +#include "DALEC_410.c" +#include "EDC1_410.c" +#include "EDC2_410.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_410(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=6; +DALECmodel.nomet=7;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=23; +DALECmodel.nofluxes=28; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_410; +DALECmodel.edc1=EDC1_410; +DALECmodel.edc2=EDC2_410; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_410(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_410/EDC1_400.c === + +#pragma once +int EDC1_410(double const *pars, DATA DATA,struct EDCDIAGNOSTIC *EDCD) +{ + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*ALL EDCs set as 1 initially*/ +/*EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +*//*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIRES.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 8*/ + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_410/DALEC_400.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_410(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + + + +/* NOTES FOR POOLS AND FLUXES +MET[:,0]: projday +MET[:,1]: mintemp +MET[:,2]: maxtemp +MET[:,3]: rad +MET[:,4]: co2 +MET[:,5]: yearday + + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +double fl=(log(1.001)-log(0.001))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(1.001,wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]={0.1,0.9,0.1,0.1,0.5,0.01}; +/*resilience factor*/ +double rfac=0.5; + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + +int nr=DATA.nodays; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + + +FLUXES[f+0]=ACM(gpppars,constants); +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1])); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<5;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-rfac)/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_OBSERVATION_OPERATORS/DALEC_OBSERVATION_OPERATORS.c === + +#pragma once +#include + +/// + + +//observation operator structure// +typedef struct OBSOPE{ +bool SUPPORT_CH4_OBS; +//Need to fill this out... +int CH4_flux; +//Woody C (CWOO) +bool SUPPORT_CWOO_OBS; +int * CWOO_pools; +int CWOO_n_pools; +//Gross primary productivity (GPP) +bool SUPPORT_GPP_OBS; +int GPP_flux; +// shuang added SIF operator so that both GPP and SIF can be compared at the same time, with different observation datasets, eg. TROPOMI SIF and FluxSat GPP +bool SUPPORT_SIF_OBS; +bool SUPPORT_LAI_OBS; +int LAI_pool; +bool SUPPORT_ET_OBS; +int ET_flux; +bool SUPPORT_LE_OBS; +int LE_flux; +bool SUPPORT_H_OBS; +int H_flux; +bool SUPPORT_ROFF_OBS; +int * ROFF_fluxes; +double *ROFF_flux_signs; +int ROFF_n_fluxes; +bool SUPPORT_NBE_OBS; +int * NBE_fluxes; +double *NBE_flux_signs; +int NBE_n_fluxes; +//ABove and below ground biomass +bool SUPPORT_ABGB_OBS; +int * ABGB_pools; +int ABGB_n_pools; +//Total dead organic matter +bool SUPPORT_DOM_OBS; +int * DOM_pools; +int DOM_n_pools; +//Total water storage (equivalent water thickness) +bool SUPPORT_EWT_OBS; +int * EWT_h2o_pools; +int EWT_n_h2o_pools; +//Total fire C emissions +bool SUPPORT_FIR_OBS; +int FIR_flux; +bool SUPPORT_SCF_OBS; +int SCF_pool; +bool SUPPORT_SWE_OBS; +int SWE_pool; + + +// +//Parameters and emergent quantities +//Can add more parameters OR options + + +bool SUPPORT_Cefficiency_OBS; +int Cefficiency_PARAM;///This is assuming it's a single parameter + +bool SUPPORT_CUE_OBS; +int CUE_PARAM;//This is assuming it's a single parameter +//Can add more parameters OR options + +bool SUPPORT_C3frac_OBS; +int C3frac_PARAM;//This is assuming it's a single parameter +//Can add more parameters OR options + +bool SUPPORT_Vcmax25_OBS; +int Vcmax25_PARAM;//This is assuming it's a single parameter +//Can add more parameters OR options + +bool SUPPORT_iniSnow_OBS; +int iniSnow_PARAM;//This is assuming it's a single parameter +//Can add more parameters OR options + +bool SUPPORT_iniSOM_OBS; +int iniSOM_PARAM;//This is assuming it's a single parameter +//Can add more parameters OR options + +bool SUPPORT_LCMA_OBS; +int LCMA_PARAM;//This is assuming it's a single parameter +//Can add more parameters OR options + +bool SUPPORT_clumping_OBS; +int clumping_PARAM; + + +bool SUPPORT_CUEmrg_OBS; //Emergent CUE (Rauto/GPP) +int Rauto_flux; //Requires GPP_flux to be set in SUPPORT_GPP_OBS + +bool SUPPORT_NBEmrg_OBS; //Emergent land sink (GPP/(reco+fire)) +int Rhet_flux; //Requires GPP_flux to be set in SUPPORT_GPP_OBS, Rauto_flux to be set in SUPPORT_CUEmrg_OBS, FIR_flux to be set in SUPPORT_FIR_OBS. + +//add PEQ value and unc from previous MCMC *pMCMC* +bool SUPPORT_r_ch4_OBS; +int r_ch4_PARAM; +bool SUPPORT_S_fv_OBS; +int S_fv_PARAM; +bool SUPPORT_rhch4_rhco2_OBS; +int rhch4_rhco2_flux; + +}OBSOPE; + + +int INITIALIZE_OBSOPE_SUPPORT(OBSOPE * OBSOPE){ + +OBSOPE->SUPPORT_ABGB_OBS=false; +OBSOPE->SUPPORT_CH4_OBS=false; +OBSOPE->SUPPORT_CWOO_OBS=false; +OBSOPE->SUPPORT_DOM_OBS=false; +OBSOPE->SUPPORT_ET_OBS=false; +OBSOPE->SUPPORT_LE_OBS=false; +OBSOPE->SUPPORT_H_OBS=false; +OBSOPE->SUPPORT_EWT_OBS=false; +OBSOPE->SUPPORT_FIR_OBS=false; +OBSOPE->SUPPORT_GPP_OBS=false; +OBSOPE->SUPPORT_LAI_OBS=false; +OBSOPE->SUPPORT_NBE_OBS=false; +OBSOPE->SUPPORT_ROFF_OBS=false; +OBSOPE->SUPPORT_SCF_OBS=false; +OBSOPE->SUPPORT_SIF_OBS=false; +OBSOPE->SUPPORT_SWE_OBS=false; + + +OBSOPE->SUPPORT_NBEmrg_OBS=false; +OBSOPE->SUPPORT_CUEmrg_OBS=false; +OBSOPE->SUPPORT_Cefficiency_OBS=false; +OBSOPE->SUPPORT_CUE_OBS=false; +OBSOPE->SUPPORT_C3frac_OBS=false; +OBSOPE->SUPPORT_Vcmax25_OBS=false; +OBSOPE->SUPPORT_iniSnow_OBS=false; +OBSOPE->SUPPORT_iniSOM_OBS=false; +OBSOPE->SUPPORT_LCMA_OBS=false; +OBSOPE->SUPPORT_clumping_OBS=false; +//In-built observation operators + +//add PEQ value and unc from previous MCMC *pMCMC* +OBSOPE->SUPPORT_r_ch4_OBS=false; +OBSOPE->SUPPORT_S_fv_OBS=false; +OBSOPE->SUPPORT_rhch4_rhco2_OBS=false; + +return 0; +} + + + + +//ABGB observation operator +int DALEC_OBSOPE_ABGB(DATA * D, OBSOPE * O){ +//int folc_pool,double lcma_pars_index + +//ABGB timeseries length +int N=D->ncdf_data.TIME_INDEX.length; + +//Time varying GPP and mean GPP +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.ABGB; +SINGLE_OBS_STRUCT SOBS=D->ncdf_data.Mean_ABGB; + +//Calculating full time series +if (TOBS.valid_obs_length>0 || SOBS.value!=DEFAULT_DOUBLE_VAL){ + //declarations + int p,nxp,n,nn; + //Looping through timesteps + for (n=0;nnopools*(n+1);p=D->nopools*n; + //inialize + D->M_ABGB[n]=0; + //loop through pools + for (nn=0;nnABGB_n_pools;nn++){ + D->M_ABGB[n]+=(D->M_POOLS[p+O->ABGB_pools[nn]]+D->M_POOLS[nxp+O->ABGB_pools[nn]])*0.5; + } + } + } + +//Mean ABGB +if (SOBS.validobs){ + int n;D->M_Mean_ABGB=0; + for (n=0;nM_Mean_ABGB+=D->M_ABGB[n];};D->M_Mean_ABGB=D->M_Mean_ABGB/(double)N; + }; + +return 0;} + +//Methane observation operator +int DALEC_OBSOPE_CH4(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.CH4; + +if (TOBS.validobs){ + int n;for (n=0;nM_CH4[n]=D->M_FLUXES[D->nofluxes*n+O->CH4_flux]; + } + }; + +return 0;} + +//Wood pool +int DALEC_OBSOPE_CWOO(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.CWOO; + +if (TOBS.valid_obs_length>0){ + //declare constants + int p,nxp,n,nn; + //loop through days + for (n=0;nnopools*(n+1);p=D->nopools*n; + //inialize + D->M_CWOO[n]=0; + //loop through pools + for (nn=0;nnCWOO_n_pools;nn++){ + D->M_CWOO[n]+=(D->M_CWOO[p+O->CWOO_pools[nn]]+D->M_CWOO[nxp+O->CWOO_pools[nn]])*0.5; + } + } + } +return 0;} + +//Dead organic matter +int DALEC_OBSOPE_DOM(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.DOM; + + if (TOBS.valid_obs_length>0){ + //declare constanta + int p,nxp,n,nn; + //loop through days + for (n=0;nnopools*(n+1);p=D->nopools*n; + //inialize + D->M_DOM[n]=0; + //loop through pools + for (nn=0;nnDOM_n_pools;nn++){ + D->M_DOM[n]+=(D->M_POOLS[p+O->DOM_pools[nn]]+D->M_POOLS[nxp+O->DOM_pools[nn]])*0.5; + } + } + } + +return 0; +} + +//ET observation operator, assuming one flux +int DALEC_OBSOPE_ET(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.ET; + +if (TOBS.validobs){ + int n; + for (n=0;nM_ET[n]=D->M_FLUXES[D->nofluxes*n+O->ET_flux]; + } + }; + +return 0;} + +//LE observation operator, assuming one flux +int DALEC_OBSOPE_LE(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.LE; + +if (TOBS.validobs){ + int n; + for (n=0;nM_LE[n]=D->M_FLUXES[D->nofluxes*n+O->LE_flux]; + } + }; + +return 0;} + +//H observation operator, assuming one flux +int DALEC_OBSOPE_H(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.H; + +if (TOBS.validobs){ + int n; + for (n=0;nM_H[n]=D->M_FLUXES[D->nofluxes*n+O->H_flux]; + } + }; + +return 0;} + + +//GRACE H2O timeseries (Terrestrial Water Storage) +int DALEC_OBSOPE_EWT(DATA * D, OBSOPE * O){ + +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.EWT; + +if (TOBS.validobs){ + int n,nn; + + int N=D->ncdf_data.TIME_INDEX.length; + int * h2op=O->EWT_h2o_pools; + + for (n=0;nM_EWT[n]=0; + for (nn=0;nnEWT_n_h2o_pools;nn++){ + D->M_EWT[n]+=(D->M_POOLS[D->nopools*n+h2op[nn]] +D->M_POOLS[D->nopools*(n+1)+h2op[nn]])*0.5; + } + } + } + +return 0;} + + +//Mean and time series fire co2 flux +int DALEC_OBSOPE_FIR(DATA * D, OBSOPE * O){ + +//FIR timeseries length +int N=D->ncdf_data.TIME_INDEX.length; + +//Time-varying FIR obs +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.FIR; + +if (TOBS.validobs){ + int n; + D->M_FIR[n]=0; + for (n=0;nM_FIR[n]=D->M_FLUXES[D->nofluxes*n+O->FIR_flux]; + } + }; + +//Mean FIR +SINGLE_OBS_STRUCT SOBS=D->ncdf_data.Mean_FIR; +if (SOBS.validobs){ + int n; + D->M_Mean_FIR=0; + for (n=0;nM_Mean_FIR+=D->M_FLUXES[n*D->nofluxes+O->FIR_flux]; + }; + D->M_Mean_FIR=D->M_Mean_FIR/(double)N; + } +return 0; +} + + +//GPP observation operator, +int DALEC_OBSOPE_GPP(DATA * D, OBSOPE * O){ + +//GPP timeseries length +int N=D->ncdf_data.TIME_INDEX.length; + +//Time varying GPP +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.GPP; +if (TOBS.validobs){int n; + for (n=0;nM_GPP[n]=D->M_FLUXES[D->nofluxes*n+O->GPP_flux]; + } + }; + +//Mean GPP +SINGLE_OBS_STRUCT SOBS=D->ncdf_data.Mean_GPP; +if (SOBS.validobs){ + int n; + D->M_Mean_GPP=0; + for (n=0;nM_Mean_GPP+=D->M_FLUXES[n*D->nofluxes+O->GPP_flux]; + }; + D->M_Mean_GPP=D->M_Mean_GPP/(double)N; + } + +return 0; +} + +//LAI observation operator +int DALEC_OBSOPE_LAI(DATA * D, OBSOPE * O){ + +//int folc_pool,double lcma_pars_index + +//Run length +int N=D->ncdf_data.TIME_INDEX.length; + +//Time varying GPP and mean GPP +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.LAI; +SINGLE_OBS_STRUCT SOBS=D->ncdf_data.Mean_LAI; + + +if ((TOBS.valid_obs_length>0 || SOBS.value!=DEFAULT_DOUBLE_VAL) ){ + int n; + for (n=0;nM_LAI[n]=(D->M_POOLS[D->nopools*n+O->LAI_pool]+D->M_POOLS[D->nopools*(n+1)+O->LAI_pool])*0.5; + } + } + +//Mean LAI +if (SOBS.validobs){ + int n;D->M_Mean_LAI=0; + for (n=0;nM_Mean_LAI+=D->M_LAI[n]; + } + D->M_Mean_LAI=D->M_Mean_LAI/(double)N; + } + +return 0;} + +//NBE observation operator +int DALEC_OBSOPE_NBE(DATA * D, OBSOPE * O){ + + +int N=D->ncdf_data.TIME_INDEX.length; +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.NBE; + + +if (TOBS.validobs){ + int n,nn; + for (n=0;nM_NBE[n]=0; + for (nn=0;nnNBE_n_fluxes;nn++){ + D->M_NBE[n]+=D->M_FLUXES[D->nofluxes*n+O->NBE_fluxes[nn]]*O->NBE_flux_signs[nn]; + } + } +}; + +return 0;} + +// Runoff operator +int DALEC_OBSOPE_ROFF(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.ROFF; + +if (TOBS.validobs){ + int n,nn; + for (n=0;nM_ROFF[n]=0; + for (nn=0;nnROFF_n_fluxes;nn++){ + D->M_ROFF[n]+=D->M_FLUXES[D->nofluxes*n+O->ROFF_fluxes[nn]]; + } + } + }; + +return 0;} + + +//SCF observation operator +int DALEC_OBSOPE_SCF(DATA * D, OBSOPE * O){ +//int folc_pool,double lcma_pars_index + +//Run length +int N=D->ncdf_data.TIME_INDEX.length; + +//Time varying GPP and mean GPP +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.SCF; + +if ((TOBS.valid_obs_length>0) ){int n; + for (n=0;nM_SCF[n]=(D->M_POOLS[D->nopools*n+O->SCF_pool]+D->M_POOLS[D->nopools*(n+1)+O->SCF_pool])*0.5; + } + } + +return 0;} + +//SWE observation operator +int DALEC_OBSOPE_SWE(DATA * D, OBSOPE * O){ +//int folc_pool,double lcma_pars_index + +//Run length +int N=D->ncdf_data.TIME_INDEX.length; + +//Time varying GPP and mean GPP +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.SWE; + +if ((TOBS.valid_obs_length>0) ){int n; + for (n=0;nM_SWE[n]=(D->M_POOLS[D->nopools*n+O->SWE_pool]+D->M_POOLS[D->nopools*(n+1)+O->SWE_pool])*0.5; + } + } + +return 0;} + +// SIF operator is made the same as GPP, be careful with its opt_filter and opt_normalization set up - shuang +// Mean_SIF is not available since current model does not yet simulate SIF - shuang + +int DALEC_OBSOPE_SIF(DATA * D, OBSOPE * O){ + +//SIF timeseries length, here DATA refer to input obs, OBSOPE refer to model output mapped to mathch data +int N=D->ncdf_data.TIME_INDEX.length; + +//Time varying SIF +TIMESERIES_OBS_STRUCT TOBS=D->ncdf_data.SIF; +if (TOBS.validobs){ + int n; + for (n=0;nM_SIF[n]=D->M_FLUXES[D->nofluxes*n+O->GPP_flux]; + } + }; + +return 0;} + +//Parameter and emergent quantity observation operators + +// Rauto fraction operator +int DALEC_OBSOPE_CUEmrg(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; + +double MGPP=0;//Initializing as zero, to allow for loop averaging calculation +double MRauto=0;//Initializing as zero, to allow for loop averaging calculation + //Note: consider using standard averaging function to avoid bugs +SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_CUE; +if (SOBS.validobs){ + int n;D->M_PEQ_CUE=0; + for (n=0;nM_FLUXES[n*D->nofluxes+O->GPP_flux]; + MRauto+=D->M_FLUXES[n*D->nofluxes+O->Rauto_flux]; + }; + MGPP=MGPP/(double)N; + MRauto=MRauto/(double)N; + D->M_PEQ_CUE=1-(MRauto/MGPP); + } + +return 0;} + +// GPP/(r_eco + fire) balance operator +int DALEC_OBSOPE_NBEmrg(DATA * D, OBSOPE * O){ + +int N=D->ncdf_data.TIME_INDEX.length; + +double MGPP=0;//Initializing as zero, to allow for loop averaging calculation +double MReco=0;//Initializing as zero, to allow for loop averaging calculation +double Mfire=0;//Initializing as zero, to allow for loop averaging calculation + //Note: consider using standard averaging function to avoid bugs +SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_NBEmrg; +if (SOBS.validobs){ + int n;D->M_PEQ_NBEmrg=0; + for (n=0;nM_FLUXES[n*D->nofluxes+O->GPP_flux]; + MReco+=(D->M_FLUXES[n*D->nofluxes+O->Rhet_flux]+D->M_FLUXES[n*D->nofluxes+O->Rauto_flux]); + Mfire+=D->M_FLUXES[n*D->nofluxes+O->FIR_flux]; + }; + MGPP=MGPP/(double)N; + MReco=MReco/(double)N; + Mfire=Mfire/(double)N; + D->M_PEQ_NBEmrg=(MGPP/(MReco+Mfire)); + } + +return 0;} + +int DALEC_OBSOPE_Cefficiency(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_Cefficiency; +if (SOBS.validobs){ + D->M_PEQ_Cefficiency=D->M_PARS[O->Cefficiency_PARAM]; + } +return 0;} + +int DALEC_OBSOPE_CUE(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_CUE; + +if (SOBS.validobs){ + D->M_PEQ_CUE=1-D->M_PARS[O->CUE_PARAM]; + } // modeled CUE = 1-par(f_auto) +return 0;} + +int DALEC_OBSOPE_C3frac(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_C3frac; +if (SOBS.validobs){ + D->M_PEQ_C3frac=D->M_PARS[O->C3frac_PARAM]; + } +return 0;} + +int DALEC_OBSOPE_Vcmax25(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_Vcmax25; +if (SOBS.validobs){ + D->M_PEQ_Vcmax25=D->M_PARS[O->Vcmax25_PARAM]; + } +return 0;} + +int DALEC_OBSOPE_iniSnow(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_iniSnow; +if (SOBS.validobs){ + D->M_PEQ_iniSnow=D->M_PARS[O->iniSnow_PARAM]; + } +return 0;} + +int DALEC_OBSOPE_iniSOM(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_iniSOM; +if (SOBS.validobs){ + D->M_PEQ_iniSOM=D->M_PARS[O->iniSOM_PARAM]; + } +return 0;} + +int DALEC_OBSOPE_LCMA(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_LCMA; +if (SOBS.validobs){ + D->M_PEQ_LCMA=D->M_PARS[O->LCMA_PARAM]; + } +return 0;} + +int DALEC_OBSOPE_clumping(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_clumping; +if (SOBS.validobs){ + D->M_PEQ_clumping=D->M_PARS[O->clumping_PARAM]; + } +return 0;} + +//add PEQ value and unc from previous MCMC *pMCMC* +int DALEC_OBSOPE_r_ch4(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_r_ch4; +if (SOBS.validobs){ + D->M_PEQ_r_ch4=D->M_PARS[O->r_ch4_PARAM]; + } +//D->M_PEQ_r_ch4=D->M_PARS[O->r_ch4_PARAM]; +return 0;} + +int DALEC_OBSOPE_S_fv(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_S_fv; +if (SOBS.validobs){ + D->M_PEQ_S_fv=D->M_PARS[O->S_fv_PARAM]; + } +//D->M_PEQ_S_fv=D->M_PARS[O->S_fv_PARAM]; +return 0;} + +int DALEC_OBSOPE_rhch4_rhco2(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_rhch4_rhco2; +if (SOBS.validobs){ + D->M_PEQ_rhch4_rhco2=1-D->M_PARS[O->rhch4_rhco2_flux]; + } +return 0;} + +///Full observation operator +int DALEC_OBSOPE(DATA * D, OBSOPE * O){ + +if (O->SUPPORT_ABGB_OBS){DALEC_OBSOPE_ABGB(D, O);} +if (O->SUPPORT_CH4_OBS){DALEC_OBSOPE_CH4(D, O);} +if (O->SUPPORT_CWOO_OBS){DALEC_OBSOPE_CWOO(D, O);} +if (O->SUPPORT_ET_OBS){DALEC_OBSOPE_ET(D, O);} +if (O->SUPPORT_LE_OBS){DALEC_OBSOPE_LE(D, O);} +if (O->SUPPORT_H_OBS){DALEC_OBSOPE_H(D, O);} +if (O->SUPPORT_EWT_OBS){DALEC_OBSOPE_EWT(D, O);} +if (O->SUPPORT_FIR_OBS){DALEC_OBSOPE_FIR(D, O);} +if (O->SUPPORT_GPP_OBS){DALEC_OBSOPE_GPP(D, O);} +if (O->SUPPORT_LAI_OBS ){DALEC_OBSOPE_LAI(D, O);} +if (O->SUPPORT_NBE_OBS){DALEC_OBSOPE_NBE(D, O);} +if (O->SUPPORT_ROFF_OBS){DALEC_OBSOPE_ROFF(D, O);} +if (O->SUPPORT_SCF_OBS ){DALEC_OBSOPE_SCF(D, O);} +if (O->SUPPORT_SIF_OBS ){DALEC_OBSOPE_SIF(D, O);} +if (O->SUPPORT_SWE_OBS ){DALEC_OBSOPE_SWE(D, O);} + +// Emergent quantities +if (O->SUPPORT_CUEmrg_OBS){DALEC_OBSOPE_CUEmrg(D, O);} +if (O->SUPPORT_NBEmrg_OBS){DALEC_OBSOPE_NBEmrg(D, O);} + +//Parameters +if (O->SUPPORT_Cefficiency_OBS){DALEC_OBSOPE_Cefficiency(D, O);} +if (O->SUPPORT_CUE_OBS){DALEC_OBSOPE_CUE(D, O);} +if (O->SUPPORT_C3frac_OBS){DALEC_OBSOPE_C3frac(D, O);} +if (O->SUPPORT_Vcmax25_OBS){DALEC_OBSOPE_Vcmax25(D, O);} +if (O->SUPPORT_iniSnow_OBS){DALEC_OBSOPE_iniSnow(D, O);} +if (O->SUPPORT_iniSOM_OBS){DALEC_OBSOPE_iniSOM(D, O);} +if (O->SUPPORT_LCMA_OBS){DALEC_OBSOPE_LCMA(D, O);} +if (O->SUPPORT_clumping_OBS){DALEC_OBSOPE_clumping(D, O);} +if (O->SUPPORT_r_ch4_OBS){DALEC_OBSOPE_r_ch4(D, O);} /*pMCMC*/ +if (O->SUPPORT_S_fv_OBS){DALEC_OBSOPE_S_fv(D, O);} +if (O->SUPPORT_rhch4_rhco2_OBS){DALEC_OBSOPE_rhch4_rhco2(D, O);} + +return 0;} + + +// + + + + + + + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1060/DALEC_1060.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1060_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_soil; +int uWUE; +int retention; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int hydr_cond; +int max_infil; +int i_PUW; +int boese_r; +int vpd_ref; +int vpd_exp; +int PAW_por; +int PUW_por; +int field_cap; +int PAW_z; +int PUW_z; +int Q_excess; +} DALEC_1060_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44 +}; + +struct DALEC_1060_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2lit; /*Wood description*/ +int root2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int q_surf; /*Surface runoff*/ +int gpp_max; /*Potential GPP*/ +} DALEC_1060_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33 +}; + +struct DALEC_1060_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +} DALEC_1060_POOLS={0,1,2,3,4,5,6,7}; + +int DALEC_1060_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1060_PARAMETERS P=DALEC_1060_PARAMETERS; +struct DALEC_1060_FLUXES F=DALEC_1060_FLUXES; +struct DALEC_1060_POOLS S=DALEC_1060_POOLS; + +DALECmodel->nopools=8; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=45; +DALECmodel->nofluxes=34; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1060_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; + + + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//Runoff variables +static int ROFF_fluxes[3]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +ROFF_fluxes[2]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=3; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; +OBSOPE.iniSOM_PARAM=P.i_soil; + + + + + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + +int DALEC_1060(DATA DATA, double const *pars) +{ + +struct DALEC_1060_PARAMETERS P=DALEC_1060_PARAMETERS; +struct DALEC_1060_FLUXES F=DALEC_1060_FLUXES; +struct DALEC_1060_POOLS S=DALEC_1060_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + +// Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117*9.8/1000; + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp_max]=ACM(gpppars,constants); +FLUXES[f+F.gpp]=FLUXES[f+F.gpp_max]*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1)*(1-pow(fmin(fmax(VPD[n],0),pars[P.vpd_ref])/pars[P.vpd_ref],pars[P.vpd_exp]));; +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; + + +// Infiltration (mm/day) +double infil = pars[P.max_infil]*(1 - exp(-PREC[n]/pars[P.max_infil])); + +// Surface runoff (mm/day) +FLUXES[f+F.q_surf] = PREC[n] - infil; + +// Update pools, including infiltration +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + deltat*infil; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW]; + +// Volumetric soil moisture from water pools +double sm_PAW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double sm_PUW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage +double drain_PAW = DRAINAGE(sm_PAW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = DRAINAGE(sm_PUW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + +// Remove drainage from layers +sm_PAW -= drain_PAW; +sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(sm_PAW,pars[P.hydr_cond],pars[P.retention]); +double k_PUW = HYDROFUN_MOI2CON(sm_PUW,pars[P.hydr_cond],pars[P.retention]); + +// Convert to potential +double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.hydr_cond]); +double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.hydr_cond]); + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(psi_PAW-psi_PUW)/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); + +// Transfer flux in mm/day +FLUXES[f+F.paw2puw] = xfer*1000*3600*24; + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] += (-FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat; +POOLS[nxp+S.H2O_PUW] += (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1060/EDC2_1060.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1060(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1060_PARAMETERS P=DALEC_1060_PARAMETERS; +struct DALEC_1060_FLUXES F=DALEC_1060_FLUXES; +struct DALEC_1060_POOLS S=DALEC_1060_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("DIAG = %i\n", DIAG); +printf("EDC = %i\n",EDC); +printf("EDCD->SWITCH[7-1+n] = %i\n",EDCD->SWITCH[7-1+n]); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Rs)) = %f\n",fabs(log(Rs))); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1060/PARS_INFO_1060.c === + +#pragma once +#include "DALEC_1060.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1060(DATA *CARDADATA) +{ + +struct DALEC_1060_PARAMETERS P=DALEC_1060_PARAMETERS; + +/*Decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[P.temp_factor]=0.018; +CARDADATA->parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[P.canopy_eff]=5; +CARDADATA->parmax[P.canopy_eff]=50; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[P.uWUE]=0.5; +CARDADATA->parmax[P.uWUE]=30; + +/*Retention parameter (b)*/ +CARDADATA->parmin[P.retention]=1.5; +CARDADATA->parmax[P.retention]=10; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +CARDADATA->parmin[P.hydr_cond]=0.0000001; +CARDADATA->parmax[P.hydr_cond]=0.00001; + +/*Maximum infiltration (mm/day)*/ +CARDADATA->parmin[P.max_infil]=0.01; +CARDADATA->parmax[P.max_infil]=100; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +CARDADATA->parmin[P.boese_r]=0.01; +CARDADATA->parmax[P.boese_r]=0.3; + +/*Reference VPD */ +CARDADATA->parmin[P.vpd_ref]=10; +CARDADATA->parmax[P.vpd_ref]=10000; + +/*VPD curvature exponent */ +CARDADATA->parmin[P.vpd_exp]=0.001; +CARDADATA->parmax[P.vpd_exp]=1000; + +/*PAW porosity*/ +CARDADATA->parmin[P.PAW_por]=0.2; +CARDADATA->parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +CARDADATA->parmin[P.PUW_por]=0.2; +CARDADATA->parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +CARDADATA->parmin[P.field_cap]=0.01; +CARDADATA->parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +CARDADATA->parmin[P.PAW_z]=0.01; +CARDADATA->parmax[P.PAW_z]=100; + +/*PUW depth (m)*/ +CARDADATA->parmin[P.PUW_z]=0.01; +CARDADATA->parmax[P.PUW_z]=100; + +/*Runoff excess*/ +CARDADATA->parmin[P.Q_excess]=0.01; +CARDADATA->parmax[P.Q_excess]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1060/EDC1_1060.c === + +#pragma once +int EDC1_1060(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1060_PARAMETERS P=DALEC_1060_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1060/MODEL_INFO_1060.c === + +#pragma once +#include "PARS_INFO_1060.c" +#include "DALEC_1060.c" +#include "EDC1_1060.c" +#include "EDC2_1060.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1060(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1060_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1060; +DALECmodel.edc1=EDC1_1060; +DALECmodel.edc2=EDC2_1060; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1060(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1200/MODEL_INFO_1200.c === + +#pragma once +#include "PARS_INFO_1200.c" +#include "DALEC_1200.c" +#include "EDC1_1200.c" +#include "EDC2_1200.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + + + +int MODEL_INFO_1200(DATA * DATA){ +/*Branched from ID=805 on Jun 15 2018*/ +/*Difference = include fossil fuel mean & trend parameters*/ +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33+2; +DALECmodel.nofluxes=30+1; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1200; +DALECmodel.edc1=EDC1_1200; +DALECmodel.edc2=EDC2_1200; + +/*Initialize parameter fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1200(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1200/EDC1_1200.c === + +#pragma once +int EDC1_1200(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1200/PARS_INFO_1200.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1200(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Fire-induced mortality".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*Fossil fuel emissions (gC/m2/day)*/ +CARDADATA->parmin[33]=0.001; +CARDADATA->parmax[33]=1000; + +/*Fossil fuel trend (frac/day)*/ +CARDADATA->parmin[34]=exp(-0.25); +CARDADATA->parmax[34]=exp(0.25); + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1200/EDC2_1200.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1200(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1200/DALEC_1200.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_1200(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff + 30. Fossil Fuel emissions +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(1.001,wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + + /*FOSSIL FUEL*/ + /*Trend = % per day*/ + FLUXES[f+30] =pars[33]*(1 + log(pars[34])*deltat*n); + /*Net ecosystem exchange + Fires + FF*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16] + FLUXES[f+30]; + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1032/PARS_INFO_1032.c === + +#pragma once +#include "DALEC_1032.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1032(double *parmin, double *parmax) +{ + +struct DALEC_1032_PARAMETERS P=DALEC_1032_PARAMETERS; + +/*Decomposition rate*/ +parmin[P.tr_lit2soil]=0.00001; +parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar]=0.01; +parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +parmin[P.t_foliar]=1.001; +parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil]=0.0000001; +parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor]=0.018; +parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff]=5; +parmax[P.canopy_eff]=50; + +/*Bday*/ +parmin[P.Bday]=365.25; +parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +parmin[P.labile_rel]=365.25/12; +parmax[P.labile_rel]=100; + +/*Fday*/ +parmin[P.Fday]=365.25; +parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +parmin[P.leaf_fall]=365.25/12; +parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_soil]=1.0; +parmax[P.i_soil]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +parmin[P.uWUE]=0.5; +parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax]=1; +parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile]=1.001; +parmax[P.t_labile]=8; + +/*Moisture factor*/ +parmin[P.moisture]=0.01; +parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer]=0.01; +parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax]=1; +parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r]=0.01; +parmax[P.boese_r]=0.3; + +/*Reference VPD */ +parmin[P.vpd_ref]=10; +parmax[P.vpd_ref]=10000; + +/*VPD curvature exponent */ +parmin[P.vpd_exp]=0.001; +parmax[P.vpd_exp]=1000; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1032/MODEL_INFO_1032.c === + +#pragma once +#include "PARS_INFO_1032.c" +#include "DALEC_1032.c" +#include "EDC1_1032.c" +#include "EDC2_1032.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1032(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1032_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_DEDC_MODCONFIG(&MLF); + + +/*Step 2: Fill structure with model-specific info*/ + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1032; +DALECmodel.edc2=EDC2_1032; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1032(DATA->parmin, DATA->parmax); + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_STEPWISE; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1032/EDC1_1032.c === + +#pragma once +int EDC1_1032(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1032_PARAMETERS P=DALEC_1032_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1032/DALEC_1032.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1032_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_soil; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +int vpd_ref; +int vpd_exp; +} DALEC_1032_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38 +}; + +struct DALEC_1032_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2lit; /*Wood description*/ +int root2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int gpp_max; /*Potential GPP*/ +} DALEC_1032_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32 +}; + +struct DALEC_1032_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1032_POOLS={0,1,2,3,4,5,6,7,8}; + + +int DALEC_1032(DATA DATA, double const *pars) +{ + +struct DALEC_1032_PARAMETERS P=DALEC_1032_PARAMETERS; +struct DALEC_1032_FLUXES F=DALEC_1032_FLUXES; +struct DALEC_1032_POOLS S=DALEC_1032_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + //Diagnostic states + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; + /*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp_max]=ACM(gpppars,constants); +FLUXES[f+F.gpp]=FLUXES[f+F.gpp_max]*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1)*(1-pow(fmin(fmax(VPD[n],0),pars[P.vpd_ref])/pars[P.vpd_ref],pars[P.vpd_exp]));; +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + + + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI +} + +return 0; +} + + + +int DALEC_1032_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1032_PARAMETERS P=DALEC_1032_PARAMETERS; +struct DALEC_1032_FLUXES F=DALEC_1032_FLUXES; +struct DALEC_1032_POOLS S=DALEC_1032_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=39; +DALECmodel->nofluxes=33; +DALECmodel->dalec=DALEC_1032; + + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1032_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.et; +//Runoff variables +static int ROFF_fluxes[2]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +OBSOPE.ROFF_n_fluxes=2; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +//Cefficiency parameters +OBSOPE.Cefficiency_PARAM=P.canopy_eff; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_soil; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1032/EDC2_1032.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1032(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1032_PARAMETERS P=DALEC_1032_PARAMETERS; +struct DALEC_1032_FLUXES F=DALEC_1032_FLUXES; +struct DALEC_1032_POOLS S=DALEC_1032_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDC +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1003/PARS_INFO_1003.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1003(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + +/*Surface runoff*/ +CARDADATA->parmin[36]=0.01; +CARDADATA->parmax[36]=1; + + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1003/EDC1_1003.c === + +#pragma once +int EDC1_1003(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1003/MODEL_INFO_1003.c === + +#pragma once +#include "PARS_INFO_1003.c" +#include "DALEC_1003.c" +#include "EDC1_1003.c" +#include "EDC2_1003.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_1003(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=37; +DALECmodel.nofluxes=33; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1003; +DALECmodel.edc1=EDC1_1003; +DALECmodel.edc2=EDC2_1003; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); +PARS_INFO_1003(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1003/DALEC_1003.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_1003(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*Surface runoff*/ + FLUXES[f+32] = DATA.MET[m+8]*deltat*pars[36]; + /*PAW total runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8]*(1-pars[36]) - FLUXES[f+28])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1003/EDC2_1003.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1003(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_813/EDC2_813.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_813(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_813/EDC1_813.c === + +#pragma once +int EDC1_813(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_813/MODEL_INFO_813.c === + +#pragma once +#include "PARS_INFO_813.c" +#include "DALEC_813.c" +#include "EDC1_813.c" +#include "EDC2_813.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_813(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_813; +DALECmodel.edc1=EDC1_813; +DALECmodel.edc2=EDC2_813; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_813(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_813/DALEC_813.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_813(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*(DATA.MET[m+2]*0.5+DATA.MET[m+1]*0.5-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_813/PARS_INFO_813.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_813(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1004/MODEL_INFO_1004.c === + +#pragma once +#include "DALEC_1004.c" +#include "EDC1_1004.c" +#include "EDC2_1004.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_beta.c" + + +int MODEL_INFO_1004(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + + +DATA->assemble_model=1; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +/*DALECmodel.nopars=36;*/ +DALECmodel.nofluxes=32; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +/*DATA->nopars=DALECmodel.nopars;*/ +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1004; +/*THESE NEED TO BE LEFT HERE UNTIL EDC_DALEC_MLF and/or EDC_DALEC_MLF_beta made obsolete*/ +DALECmodel.edc1=EDC1_1004; +DALECmodel.edc2=EDC2_1004; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ + +/*Mount EDC checks here*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + +DALECmodel.nopars=0; +DATA->nopars=0; + +INITIALIZE_PARAMETER_FIELDS(DATA); + +/*Mount DALEC 1004 module parameters*/ +MOUNT_DALEC_1004_PARS(DATA);DALECmodel.nopars=DATA->nopars; + +printf("DATA->nopars = %i\n",DALECmodel.nopars); +/*Write pars to file*/ + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_beta; + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1004/EDC1_1004.c === + +#pragma once +int EDC1_1004(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){DATA.M_EDCD[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;DATA.M_EDCD[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;DATA.M_EDCD[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5 wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27] RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1004/EDC2_1004.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1004(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);DATA.M_EDCD[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);DATA.M_EDCD[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +psw=1; +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("DATA.M_EDCD[7-1+n] = %i\n",DATA.M_EDCD[7-1+n]); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);DATA.M_EDCD[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;DATA.M_EDCD[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nMODULE_IDX.MODELS.dalec_1004=DATA->nopars; + +/*Populate with module parameters*/ +double parmin[36], parmax[36]; +char *parname[36]; + +parname[0]="Decomposition rate"; +parmin[0]=0.00001; +parmax[0]=0.01; + +parname[1]="Fraction of GPP repsired"; +parmin[1]=0.2; +parmax[1]=0.8; + +parname[2]="Fraction of (1-fgpp) to foliage"; +parmin[2]=0.01; +parmax[2]=0.5; + +parname[3]="Fraction to roots"; +parmin[3]=0.01; +parmax[3]=1; + +parname[4]="Leaf Lifespan"; +parmin[4]=1.001; +parmax[4]=8; + +parname[5]="TOR wood [yr-1]"; +parmin[5]=0.000025; +parmax[5]=0.001; + +parname[6]="TOR roots"; +parmin[6]=0.0001; +parmax[6]=0.01; + +parname[7]="TOR litter"; +parmin[7]=0.0001; +parmax[7]=0.01; + +parname[8]="TOR SOM"; +parmin[8]=0.0000001; +parmax[8]=0.001; + +parname[9]="Temp factor (Q10)"; +parmin[9]=0.018; +parmax[9]=0.08; + +parname[10]="ACM canopy efficiency"; +parmin[10]=5; +parmax[10]=50; + +parname[11]="Leaf onset day"; +parmin[11]=365.25; +parmax[11]=365.25*4; + +parname[12]="Fraction to Clab"; +parmin[12]=0.01; +parmax[12]=0.5; + +parname[13]="Clab Release period"; +parmin[13]=365.25/12; +parmax[13]=100; + + +parname[14]="Leaf fall day"; +parmin[14]=365.25; +parmax[14]=365.25*4; + +parname[15]="Leaf fall period"; +parmin[15]=365.25/12; +parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parname[16]="LCMA [gC/m2]"; +parmin[16]=5; +parmax[16]=200; + +/*C labile*/ +parname[17]="C labile @ t=0"; +parmin[17]=1.0; +parmax[17]=2000.0; + +/*C foliar*/ +parname[18]="C foliar @ t=0"; +parmin[18]=1.0; +parmax[18]=2000.0; + +/*C roots*/ +parname[19]="C roots @ t=0"; +parmin[19]=1.0; +parmax[19]=2000.0; + +/*C_wood*/ +parname[20]="C wood @ t=0"; +parmin[20]=1.0; +parmax[20]=100000.0; + +/*C litter*/ +parname[21]="C litter @ t=0 [gC]"; +parmin[21]=1.0; +parmax[21]=2000.0; + +/*C_som*/ +parname[22]="C som @ t=0 [gC]"; +parmin[22]=1.0; +parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +parname[23]="iWUE"; +parmin[23]=10; +parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parname[24]="Q focal point [mm]"; +parmin[24]=1; +parmax[24]=100000; + +/*"Wilting point"*/ +parname[25]="Wilting point [mm]"; +parmin[25]=1; +parmax[25]=10000; + +/*"Bucket at t0"*/ +parname[26]="PAW @ t=0 [mm]"; +parmin[26]=1; +parmax[26]=10000; + +parname[27]="Foliar biomass CF"; +parmin[27]=0.01; +parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +parname[28]="Stem biomass CF"; +parmin[28]=0.01; +parmax[28]=1; + +parname[29]="DOM CF"; +parmin[29]=0.01; +parmax[29]=1; + +parname[30]="Fire resilience factor"; +parmin[30]=0.01; +parmax[30]=1; + +parname[31]="Lab pool lifespan (yrs)"; +parmin[31]=1.001; +parmax[31]=8; + +parname[32]="Moisture factor"; +parmin[32]=0.01; +parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +parname[33]="PAW->PUW Q fraction"; +parmin[33]=0.01; +parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parname[34]="Runoff focal point [mm]"; +parmin[34]=1; +parmax[34]=100000; + +parname[35]="PUW pool"; +parmin[35]=1; +parmax[35]=10000; + +int n; +for (n=0;n<36;n++){ +ADD_PARAMETER_TO_STACK(DATA,parname[n],parmin[n],parmax[n]);} + + +return 0; +} + + + +int DALEC_1004(DATA DATA, double const *pars) +{ + + +/*Step 1. Calculate EDC1, chec +*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +/*Copy default structure*/ +/*EDCD=*((DALEC *)DATA.MODEL)->EDCD;*/ +int k; +double P=0; +int EDC=1; +EDC=ipow(EDC1_1004(pars,DATA, MODEL->EDCD),DATA.EDC); +P=P+log((double)EDC); + + +if (EDC==1 | MODEL->EDCD->DIAG>0){ +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + + +EDC=ipow(EDC2_1004(pars,DATA, MODEL->EDCD),DATA.EDC); +P=P+log((double)EDC); +for (k=0;k<100;k++){printf("%i ",DATA.M_EDCD[k]);} +printf("\n"); + +} +printf("***"); + +return P; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_840/MODEL_INFO_840.c === + +#pragma once +#include "PARS_INFO_840.c" +#include "DALEC_840.c" +#include "EDC1_840.c" +#include "EDC2_840.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_840(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_840; +DALECmodel.edc1=EDC1_840; +DALECmodel.edc2=EDC2_840; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_840(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_840/EDC1_840.c === + +#pragma once +int EDC1_840(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_840/DALEC_840.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_840(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; /*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; + + +/*seasonal biomass mortality factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*seasonal biomass release factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*TO DO: allocate labile release to pools, using same allocation scheme as above*/ +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; + + +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_840/EDC2_840.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_840(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_840/PARS_INFO_840.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_840(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_101/DALEC_101.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_101(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; + + double constants[10]={pars[4],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[11]; + POOLS[1]=pars[12]; + POOLS[2]=pars[13]; + + + +/* NOTES FOR POOLS AND FLUXES +MET[:,0]: projday +MET[:,1]: mintemp +MET[:,2]: maxtemp +MET[:,3]: rad +MET[:,4]: co2 +MET[:,5]: yearday + + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);other + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[9]*sqrt(2)/2; +double wl=pars[7]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[2])-log(pars[2]-1))/2; +double fl=(log(1.001)-log(0.001))/2; + + +/*additional offset*/ +double osf=offset(pars[2],wf); +double osl=offset(1.001,wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]={0.1,0.9,0.1}; +/*resilience factor*/ +double rfac=0.5; + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + +int nr=DATA.nodays; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[10]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + +FLUXES[f+0]=ACM(gpppars,constants); +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +FLUXES[f+1]=exp(pars[3]*0.5*(DATA.MET[m+2]+DATA.MET[m+1])); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]= 0;/*(FLUXES[f+0]-FLUXES[f+2])*pars[2]*/; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2])*pars[6]; +/*root production [no explicit root production]*/ +FLUXES[f+5] = 0; /*(FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*0*/; +/*wood AND root production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[8]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[5]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = 0/* POOLS[p+3]*(1-pow(1-pars[6-1],deltat))*0/deltat*/; +/*root litter production*/ +FLUXES[f+11] = 0/*POOLS[p+2]*(1-pow(1-pars[7-1],deltat))*0/deltat*/; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = 0; /*POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat*/; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = 0; /*POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat*/; +FLUXES[f+13] = POOLS[p+2]*(1-pow(1-FLUXES[f+1]*pars[0],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = 0; /*POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat;*/ + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (- FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+6] + FLUXES[f+9]- FLUXES[f+13])*deltat; + /*POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +*/ + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + /*dead C pools*/ + /*litter*/ + /*som*/ + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + + /*Net ecosystem exchange*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+13]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_101/MODEL_INFO_101.c === + +#pragma once +#include "PARS_INFO_101.c" +#include "DALEC_101.c" +#include "EDC1_101.c" +#include "EDC2_101.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_101(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=3; +DALECmodel.nomet=7;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=14; +DALECmodel.nofluxes=28; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_101; +DALECmodel.edc1=EDC1_101; +DALECmodel.edc2=EDC2_101; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_101(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_101/EDC1_101.c === + +#pragma once +int EDC1_101(double const *pars, DATA DATA,struct EDCDIAGNOSTIC *EDCD) +{ +int EDC=1; +return EDC; +} + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + +/* +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; +*/ + + + + + + +/*ALL EDCs set as 1 initially*/ +/*EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +*//*declaring variables and constants for subsequent EDCs*/ +/*int EDC=1; +int DIAG=EDCD->DIAG; +*//*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +/*double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +*//*fraction of GPP som under equilibrium conditions*/ +/*double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); +*/ +/*yearly leaf loss fraction*/ +/*double torfol=1/(pars[4]*365.25); + + +*/ +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} +*/ +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} +*/ +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} +*/ +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} +*/ +/*EDC no 5 is addressed in EDC2_FIRES.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} +*/ +/*EDC No 8*/ + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + + +/*return EDC; + + +} +*/ + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_101/EDC2_101.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + + + + + +int EDC2_101(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + + + + + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + + + +/*THESE EDC2 checks are for DALEC_FIRES2*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + +/*FIRES*/ +int nomet=7,nopools=3; +int nofluxes=28; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nLAImax){EDC=0;EDCD->PASSFAIL[5-1]=0;}}}*/ +/*MLAI=mean_pointer_vector(LAI,nodays);*/ + + + +/*EDC no 6*/ +/*0.2*Cf < Cr < 5*Cf*/ +/*Cfoliar : Croot = 5:1 or 1:5*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } +*/ + +/*EDC 7*/ +/*G10 = 2 - growth factor in 10 years*/ +/*for any further constraint please incorporate in likelyhood*/ +/*int noyears=floor(nodays*deltat/365); +double G=0.1; +int y;*/ + + +/*mean annual pool array*/ +/*double *MAPOOL=calloc(noyears,sizeof(double)); +for (n=0;nG*(double)noyears)){EDC=0;EDCD->PASSFAIL[7-1]=0;}}*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1]==1)) & (MAPOOL[noyears-1]/MAPOOL[0]>(1+G*(double)noyears))){EDC=pow(0,EDCD->SWITCH[7-1]);;EDCD->PASSFAIL[7-1]=0;} + +} +*/ + + + +/*EDC no 8*/ +/*POOL EXPONENTIAL DECAY*/ +/*Performed on all seven pools*/ + +/*exporting the decay coefficient here*/ +/*double C;double cyears=3; +for (n=0;nSWITCH[8-1]==1)) { +C=expdecay2(POOLS,n,nodays+1,deltat,nopools); +if (fabs(-log(2)/C)<(365.25*cyears) & C<0 & isfinite(C)){EDC=pow(0,EDCD->SWITCH[8-1]);;EDCD->PASSFAIL[8-1]=0;}}}; +*/ + + +/* +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +*/ + + +/*fraction of GPP to som and lit under equilibrium conditions*/ +/*double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); +double const flit=(froot+flab+ffol); +*/ + + +/*SOM attractor - must be within a factor of 2 from Csom0*/ +/*half the TR is balanced by x2 Csom*/ + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; +/*No longer need mean GPP estimate*/ +/*double meangpp=0;for (n=0;nSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=pow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n+1,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("fabs(log(Rs)) = %2.2f\n",fabs(log(Rs))); +printf("fabs(Rs-Rm) = %2.2f\n",fabs(Rs-Rm)); +printf("EDCD->SWITCH[7-1+n] = %i\n",EDCD->SWITCH[7-1+n]); +printf("EDC = %i\n",EDC); +printf("****\n");}} + + +if (psw==1){ +printf("EDC(2) = %i\n",EDC);} + + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ + + +for (n=0;nparmax[n+11])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1;}} + + + + + + + + + +/*FREE MEMORY*/ +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + +/*Returning EDC */ +return EDC;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_101/PARS_INFO_101.c === + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_101(DATA *CARDADATA) +{ + +CARDADATA->nopars=14; + +/*Total ecosystem RT*/ +CARDADATA->parmin[0]=0.000001; +CARDADATA->parmax[0]=0.1; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Leaf Lifespan*/ +CARDADATA->parmin[2]=1.001; +CARDADATA->parmax[2]=8; + +/*Temp factor* = Q10 = 1.2(0.018)-1.6(0.08)*/ +CARDADATA->parmin[3]=0.018; +CARDADATA->parmax[3]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[4]=5; +CARDADATA->parmax[4]=50; + +/*Bday*/ +CARDADATA->parmin[5]=365.25; +CARDADATA->parmax[5]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[6]=0.01; +CARDADATA->parmax[6]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[7]=10; +CARDADATA->parmax[7]=100; + +/*Fday*/ +CARDADATA->parmin[8]=365.25; +CARDADATA->parmax[8]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[9]=20; +CARDADATA->parmax[9]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[11]=1.0; +CARDADATA->parmax[11]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[12]=1.0; +CARDADATA->parmax[12]=2000.0; + +/*C other*/ +CARDADATA->parmin[13]=1.0; +CARDADATA->parmax[13]=200000.0; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1102/EDC2_1102.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1102(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1102_PARAMETERS P=DALEC_1102_PARAMETERS; +struct DALEC_1102_FLUXES F=DALEC_1102_FLUXES; +struct DALEC_1102_POOLS S=DALEC_1102_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +if (Fin[n] > 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_cwd,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW,P.i_SWE}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1102/DALEC_1102.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../../../DALEC_CODE/DALEC_ALL/LIU_An_et.c" +#include "../../../DALEC_CODE/DALEC_ALL/CH4_MODULES/JCR.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + + +struct DALEC_1102_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int tr_cwd2som; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_cwd; +int t_soil; +int Q10rhco2; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_cwd; +int i_lit; +int i_soil; +int retention; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int hydr_cond; +int max_infil; +int i_PUW; +int PAW_por; +int PUW_por; +int field_cap; +int PAW_z; +int PUW_z; +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int C3_frac; +int clumping; +int leaf_refl; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +int S_fv; +int thetas_opt; +int fwc; +int r_ch4; +int Q10ch4; +int maxPevap; +} DALEC_1102_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62 +}; + +struct DALEC_1102_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2cwd; /*Wood decomposition*/ +int root2lit; /*Root decomposition*/ +int resp_het_cwd; /*Coarse woody debris heterotrophic respiration*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int q_surf; /*Surface runoff*/ +int transp; /*Transpiration*/ +int evap; /*Evaporation*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int fV; /* Volumetric fraction of aerobic Rh */ +int fT; /*Temperature scaler*/ +int fW; /*Water scaler*/ +int fCH4; /*CH4 fraction in anaerobic C decomposition*/ +int soil_moist; /*thetas = PAW/PAW_fs fraction*/ + +} DALEC_1102_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53 +}; + + + + + +struct DALEC_1102_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +} DALEC_1102_POOLS={ + 0,1,2,3,4,5,6,7,8,9 +}; + +/* +struct POOLS_INFO{ +int n_input_fluxes +int n_output_fluxes +int * input_fluxes +int * output_fluxes} +*/ + + + +int DALEC_1102_MODCONFIG(DALEC * DALECmodel){ + + +struct DALEC_1102_PARAMETERS P=DALEC_1102_PARAMETERS; +struct DALEC_1102_FLUXES F=DALEC_1102_FLUXES; +struct DALEC_1102_POOLS S=DALEC_1102_POOLS; + +DALECmodel->nopools=10; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=63; +DALECmodel->nofluxes=54; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; + + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//Runoff variables +static int ROFF_fluxes[3]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +ROFF_fluxes[2]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=3; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +//C3frac parameters +OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_soil; + + + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + + +int DALEC_1102(DATA DATA, double const *pars){ + + + +struct DALEC_1102_PARAMETERS P=DALEC_1102_PARAMETERS; +struct DALEC_1102_FLUXES F=DALEC_1102_FLUXES; +struct DALEC_1102_POOLS S=DALEC_1102_POOLS; + + + + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +double pi=3.1415927; + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +// double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_cwd]=pars[P.i_cwd]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + +/* jc prep input for methane module*/ +double PAW_fs = HYDROFUN_MOI2EWT(1,pars[P.PAW_por],pars[P.PAW_z]); +double ch4pars[8]={PAW_fs,pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.Q10rhco2],meantemp}; + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + +// Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117; + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[7];//AAB changed this +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; + + +/*Calculate light extinction coefficient*/ +double B = (DOY[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +double LST = (int) (DOY[n]*24*60) % (24*60); +LST=0.5*24*60; +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*DATA.ncdf_data.LAT)*sin(pi/180*DA)+cos(pi/180*DATA.ncdf_data.LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +double zenith_angle = 90-alpha; +//double LAD = 1.0; //leaf angle distribution +//double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 + +double LAD = 0.5; //leaf angle distribution +double VegK = LAD/cos(zenith_angle/180*pi); + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor + //We're also multiplying beta by cold-weather stress +double beta = fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1.); + beta = fmin(beta,g); + +// GPP, T, and E from LIU_An_et +// Annual radiation, VPD in kPa, mean T in K +double *LIU_An_et_out = LIU_An_et(SSRD[n]*1e6/(24*3600), VPD[n]/10, + 273.15+0.5*(T2M_MIN[n]+T2M_MAX[n]), pars[P.Vcmax25], CO2[n], beta, pars[P.Med_g1], + LAI[n], pars[P.ga], VegK, pars[P.Tupp], pars[P.Tdown], 1., // pars[P.C3_frac], + pars[P.clumping], pars[P.leaf_refl], pars[P.maxPevap], PREC[n]); +// GPP +FLUXES[f+F.gpp] = LIU_An_et_out[0]; +//transpiration// +FLUXES[f+F.transp] = LIU_An_et_out[1]; +//evaporation// +FLUXES[f+F.evap] = LIU_An_et_out[2]; +// Evapotranspiration +FLUXES[f+F.et]=FLUXES[f+F.evap]+FLUXES[f+F.transp]; + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=pow(pars[P.Q10rhco2],(0.5*(T2M_MIN[n]+T2M_MAX[n])-meantemp)/10)*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood CWD production*/ +FLUXES[f+F.wood2cwd] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic CWD*/ +FLUXES[f+F.resp_het_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_cwd],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; + +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +double *jcr_o = JCR(ch4pars,T2M_MIN[n],T2M_MAX[n],POOLS[S.H2O_PAW]); +//outputformat +//jcr_o 0-4 thetas,fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from litter*/ +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_lit],deltat))/deltat; +/* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_soil],deltat))/deltat; +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from litter*/ +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_lit],deltat))/deltat; +/* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_soil],deltat))/deltat; +/* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*1+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*(1-jcr_o[4]); +/* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*0+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*jcr_o[4]; +/* fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+F.fV] = jcr_o[2]; +/* fT Temperature scaler*/ +FLUXES[f+F.fT] = jcr_o[1]; +/* fW Water scaler*/ +FLUXES[f+F.fW] = jcr_o[3]; +/* fCH4 CH4 fraction*/ +FLUXES[f+F.fCH4] = jcr_o[4]; +/* PAW/PAW_fs thetas*/ +FLUXES[f+F.soil_moist] = jcr_o[0]; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*---------------------- end of JCR --------------------------------------------*/ + +/*CWD to SOM*/ +FLUXES[f+F.cwd2som] = POOLS[p+S.C_cwd]*(1-pow(1-pars[P.tr_cwd2som]*FLUXES[f+F.temprate],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2cwd])*deltat; + POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] + (FLUXES[f+F.wood2cwd] - FLUXES[f+F.ae_rh_cwd]-FLUXES[f+F.an_rh_cwd]-FLUXES[f+F.cwd2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + + + + +/*Snow water equivalent*/ +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ +FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ +POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ +FLUXES[f+F.scf]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); /*snow cover fraction*/ + +// Infiltration (mm/day) +double infil = pars[P.max_infil]*(1 - exp(-(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])/pars[P.max_infil])); + +// Surface runoff (mm/day) +FLUXES[f+F.q_surf] = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]) - infil; + +// Update pools, including infiltration +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + deltat*infil; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW]; + +// Volumetric soil moisture from water pools +double sm_PAW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double sm_PUW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage +double drain_PAW = DRAINAGE(sm_PAW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = DRAINAGE(sm_PUW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + +// Remove drainage from layers +sm_PAW -= drain_PAW; +sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(sm_PAW,pars[P.hydr_cond],pars[P.retention]); +double k_PUW = HYDROFUN_MOI2CON(sm_PUW,pars[P.hydr_cond],pars[P.retention]); + +// Convert to potential +double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.retention]); +double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.retention]); + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(psi_PAW-psi_PUW)/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); + +// Transfer flux in mm/day +FLUXES[f+F.paw2puw] = xfer*1000*3600*24; + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] += (-FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat; +POOLS[nxp+S.H2O_PUW] += (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-CF[S.C_cwd])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2cwd])*deltat; + /*dead C pools*/ + /*CWD*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.fx_woo2cwd]-FLUXES[f+F.f_cwd]-FLUXES[f+F.fx_cwd2som])*deltat; + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + +} + + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1102/EDC1_1102.c === + +#pragma once +int EDC1_1102(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1102_PARAMETERS P=DALEC_1102_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1102/MODEL_INFO_1102.c === + +#pragma once +#include "PARS_INFO_1102.c" +#include "DALEC_1102.c" +#include "EDC1_1102.c" +#include "EDC2_1102.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1102(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1102_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1102; +DALECmodel.edc1=EDC1_1102; +DALECmodel.edc2=EDC2_1102; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1102(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_DEDC; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1102/PARS_INFO_1102.c === + +#pragma once +#include "DALEC_1102.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1102(DATA *CARDADATA) +{ + + +struct DALEC_1102_PARAMETERS P=DALEC_1102_PARAMETERS; + +/*Litter decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*CWD decomposition rate*/ +CARDADATA->parmin[P.tr_cwd2som]=0.00001; +CARDADATA->parmax[P.tr_cwd2som]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR CWD*/ +CARDADATA->parmin[P.t_cwd]=0.00005; +CARDADATA->parmax[P.t_cwd]=0.005; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*\Q10 = 1.2-2.0*/ +CARDADATA->parmin[P.Q10rhco2]=1.2; +CARDADATA->parmax[P.Q10rhco2]=2.0; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C CWD*/ +CARDADATA->parmin[P.i_cwd]=1.0; +CARDADATA->parmax[P.i_cwd]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*Retention parameter (b)*/ +CARDADATA->parmin[P.retention]=1.5; +CARDADATA->parmax[P.retention]=10; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +CARDADATA->parmin[P.hydr_cond]=0.0000001; +CARDADATA->parmax[P.hydr_cond]=0.00001; + +/*Maximum infiltration (mm/day)*/ +CARDADATA->parmin[P.max_infil]=1; +CARDADATA->parmax[P.max_infil]=100; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*PAW porosity*/ +CARDADATA->parmin[P.PAW_por]=0.2; +CARDADATA->parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +CARDADATA->parmin[P.PUW_por]=0.2; +CARDADATA->parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +CARDADATA->parmin[P.field_cap]=0.01; +CARDADATA->parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +CARDADATA->parmin[P.PAW_z]=0.01; +CARDADATA->parmax[P.PAW_z]=100; + +/*PUW depth (m)*/ +CARDADATA->parmin[P.PUW_z]=0.01; +CARDADATA->parmax[P.PUW_z]=100; + +/*Runoff excess*/ +CARDADATA->parmin[P.Q_excess]=0.01; +CARDADATA->parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +CARDADATA->parmin[P.Med_g1]=1.79; +CARDADATA->parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +CARDADATA->parmin[P.Vcmax25]=1e-8; +CARDADATA->parmax[P.Vcmax25]=140; + +/*Tminmin scaling factor*/ +CARDADATA->parmin[P.Tminmin]=258.15; +CARDADATA->parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +CARDADATA->parmin[P.Tminmax]=273.15; +CARDADATA->parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance*/ +CARDADATA->parmin[P.ga]=0.01; +CARDADATA->parmax[P.ga]=10.0; + +/*Tupp*/ +CARDADATA->parmin[P.Tupp]=299.15; +CARDADATA->parmax[P.Tupp]=318.15; + +/*Tdown*/ +CARDADATA->parmin[P.Tdown]=263.15; +CARDADATA->parmax[P.Tdown]=286.15; + +/*C3_frac*/ +CARDADATA->parmin[P.C3_frac]=1e-8; +CARDADATA->parmax[P.C3_frac]=1.0; + +/*Clumping index*/ +CARDADATA->parmin[P.clumping]=0.35; +CARDADATA->parmax[P.clumping]=1.0; + +/*Leaf single scattering albedo*/ +CARDADATA->parmin[P.leaf_refl]=1e-8; +CARDADATA->parmax[P.leaf_refl]=1.0; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +CARDADATA->parmin[P.i_SWE]=0.000001; +CARDADATA->parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +CARDADATA->parmin[P.min_melt]=240; +CARDADATA->parmax[P.min_melt]=270; + +/*sn2: slope*/ +CARDADATA->parmin[P.melt_slope]=0.00001; +CARDADATA->parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar*/ +CARDADATA->parmin[P.scf_scalar]=0.001; +CARDADATA->parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +/*jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +CARDADATA->parmin[P.S_fv]=1; +CARDADATA->parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +CARDADATA->parmin[P.thetas_opt]=0.2; +CARDADATA->parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +CARDADATA->parmin[P.fwc]=0.01; +CARDADATA->parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +CARDADATA->parmin[P.r_ch4]=0.001; +CARDADATA->parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +CARDADATA->parmin[P.Q10ch4]=1.0; +CARDADATA->parmax[P.Q10ch4]=3.0; + +/* maxPevap in mm/day*/ +CARDADATA->parmin[P.maxPevap]=0.01; +CARDADATA->parmax[P.maxPevap]=20; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1105/DALEC_1105.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../../../DALEC_CODE/DALEC_ALL/LIU_An_et.c" +#include "../../../DALEC_CODE/DALEC_ALL/CH4_MODULES/JCR.c" +#include "../../../DALEC_CODE/DALEC_ALL/LAI_KNORR.c" +#include "../../../DALEC_CODE/DALEC_ALL/LAI_KNORR_funcs.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + + +struct DALEC_1105_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2som; +int tr_cwd2som; +int f_auto; +int f_root; +int t_wood; +int t_root; +int t_lit; +int t_cwd; +int t_som; +int Q10rhco2; +int f_lab; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_cwd; +int i_lit; +int i_som; +int retention; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int moisture; +int hydr_cond; +int max_infil; +int i_PUW; +int PAW_por; +int PUW_por; +int field_cap; +int PAW_z; +int PUW_z; +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int C3_frac; +int clumping; +int leaf_refl; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +int S_fv; +int thetas_opt; +int fwc; +int r_ch4; +int Q10ch4; +int maxPevap; +int T_phi; +int T_range; +int tau_m; +int plgr; +int k_leaf; +int lambda_max; +int tau_W; +int time_c; +int time_r; +int init_T_mem; +int init_LAIW_mem; +} DALEC_1105_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66 +}; + +struct DALEC_1105_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int fol2lit; /*Foliar decomposition*/ +int wood2cwd; /*Wood decomposition*/ +int root2lit; /*Root decomposition*/ +int resp_het_cwd; /*Coarse woody debris heterotrophic respiration*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int q_surf; /*Surface runoff*/ +int transp; /*Transpiration*/ +int evap; /*Evaporation*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int fV; /* Volumetric fraction of aerobic Rh */ +int fT; /*Temperature scaler*/ +int fW; /*Water scaler*/ +int fCH4; /*CH4 fraction in anaerobic C decomposition*/ +int soil_moist; /*thetas = PAW/PAW_fs fraction*/ +int target_LAI; /*LAI environmental target*/ +int T_memory; /*LAI temp memory*/ +int lambda_max_memory; /*LAI max memory*/ +int dlambda_dt; /*dLAI/dt*/ +int f_temp_thresh; /*f_temp_thres*/ +int f_dayl_thresh; /*f_dayl_thres*/ +int c_lim_flag; /*LAI carbon limitation flag*/ +int lai_fire; /*LAI fire loss*/ +int foliar_fire_frac; /*C_fol fire loss frac*/ +} DALEC_1105_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59 +}; + + + + + +struct DALEC_1105_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +} DALEC_1105_POOLS={ + 0,1,2,3,4,5,6,7,8,9 +}; + +/* +struct POOLS_INFO{ +int n_input_fluxes +int n_output_fluxes +int * input_fluxes +int * output_fluxes} +*/ + + + +int DALEC_1105_MODCONFIG(DALEC * DALECmodel){ + + +struct DALEC_1105_PARAMETERS P=DALEC_1105_PARAMETERS; +struct DALEC_1105_FLUXES F=DALEC_1105_FLUXES; +struct DALEC_1105_POOLS S=DALEC_1105_POOLS; + +DALECmodel->nopools=10; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=67; +DALECmodel->nofluxes=60; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; + + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//Runoff variables +static int ROFF_fluxes[3]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +ROFF_fluxes[2]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=3; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +//C3frac parameters +OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_som; + + + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + + +int DALEC_1105(DATA DATA, double const *pars){ + + + +struct DALEC_1105_PARAMETERS P=DALEC_1105_PARAMETERS; +struct DALEC_1105_FLUXES F=DALEC_1105_FLUXES; +struct DALEC_1105_POOLS S=DALEC_1105_POOLS; + + + + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +double pi=3.1415927; +double lai_met_list[1],lai_var_list[20]; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +// double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_cwd]=pars[P.i_cwd]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + +/* jc prep input for methane module*/ +double ch4pars[7]={pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.Q10rhco2],meantemp}; + +// Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117/100; + +/*Combustion factors*/ +double CF[7];//AAB changed this +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + +/*foliar carbon transfer intermediate variables*/ +double Fcfolavailable; + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; + + +/*Calculate light extinction coefficient*/ +double B = (DOY[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +double LST = (int) (DOY[n]*24*60) % (24*60); +LST=0.5*24*60; +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*DATA.ncdf_data.LAT)*sin(pi/180*DA)+cos(pi/180*DATA.ncdf_data.LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +double zenith_angle = 90-alpha; + +//printf("SZA local = %2.2f, SZA global = %2.2f, SZA diff = %2.2f\n", zenith_angle,DATA.ncdf_data.SZA.values,DATA.ncdf_data.SZA.values - zenith_angle); +//double LAD = 1.0; //leaf angle distribution +//double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 + +double LAD = 0.5; //leaf angle distribution +double VegK = LAD/cos(zenith_angle/180*pi); + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor + //We're also multiplying beta by cold-weather stress +double beta = fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1.); + beta = fmin(beta,g); + +// GPP, T, and E from LIU_An_et +// Annual radiation, VPD in kPa, mean T in K +double *LIU_An_et_out = LIU_An_et(SSRD[n]*1e6/(24*3600), VPD[n]/10, + 273.15+0.5*(T2M_MIN[n]+T2M_MAX[n]), pars[P.Vcmax25], CO2[n], beta, pars[P.Med_g1], + LAI[n], pars[P.ga], VegK, pars[P.Tupp], pars[P.Tdown], 1., // pars[P.C3_frac], + pars[P.clumping], pars[P.leaf_refl], pars[P.maxPevap], PREC[n]); +// GPP +FLUXES[f+F.gpp] = LIU_An_et_out[0]; +//transpiration// +FLUXES[f+F.transp] = LIU_An_et_out[1]; +//evaporation// +FLUXES[f+F.evap] = LIU_An_et_out[2]; +// Evapotranspiration +FLUXES[f+F.et]=FLUXES[f+F.evap]+FLUXES[f+F.transp]; + +/*Snow water equivalent*/ +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ +FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ +POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ +FLUXES[f+F.scf]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); /*snow cover fraction*/ + +// Infiltration (mm/day) +double infil = pars[P.max_infil]*(1 - exp(-(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])/pars[P.max_infil])); + +// Surface runoff (mm/day) +FLUXES[f+F.q_surf] = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]) - infil; + +// Update pools, including infiltration +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + deltat*infil; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW]; + +// Volumetric soil moisture from water pools +double sm_PAW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double sm_PUW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage +double drain_PAW = DRAINAGE(sm_PAW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = DRAINAGE(sm_PUW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + +// Remove drainage from layers +sm_PAW -= drain_PAW; +sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(sm_PAW,pars[P.hydr_cond],pars[P.retention]); +double k_PUW = HYDROFUN_MOI2CON(sm_PUW,pars[P.hydr_cond],pars[P.retention]); + +// Convert to potential +double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.retention]); +double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.retention]); + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(psi_PAW-psi_PUW)/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); + +// Transfer flux in mm/day +FLUXES[f+F.paw2puw] = xfer*1000*3600*24; + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] += (-FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat; +POOLS[nxp+S.H2O_PUW] += (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=pow(pars[P.Q10rhco2],(0.5*(T2M_MIN[n]+T2M_MAX[n])-meantemp)/10)*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*(pars[P.f_lab]); + +//KNORR LAI// +if (n==0){ + /*Initialize phenology memory of air-temperature as some value within mintemp and maxtemp*/ + lai_var_list[5]=pars[P.init_T_mem]*(T2M_MAX[n]-T2M_MIN[n])+T2M_MIN[n]; + /*Initialize phenology memory of water/structural limitation */ + lai_var_list[11]=pars[P.init_LAIW_mem]*pars[P.lambda_max]; +} +lai_met_list[0]=(T2M_MAX[n]+T2M_MIN[n])/2.0; +// lai_var_list[0]=1; +lai_var_list[19]=deltat; +lai_var_list[1]=LAI[n]; +lai_var_list[2]=LAI[n]; +lai_var_list[3]=pars[P.T_phi]; +lai_var_list[4]=pars[P.T_range]; +lai_var_list[6]=pars[P.tau_m]; +lai_var_list[7]=pars[P.plgr]; +lai_var_list[8]=pars[P.k_leaf]; +lai_var_list[9]=pars[P.lambda_max]; +lai_var_list[10]=pars[P.tau_W]; +lai_var_list[12]=DATA.ncdf_data.LAT; +lai_var_list[13]=DOY[n]; +lai_var_list[14]=pi; +lai_var_list[15]=pars[P.time_c]; +lai_var_list[16]=pars[P.time_r]; +lai_var_list[17]=(POOLS[p+S.H2O_PAW]+POOLS[nxp+S.H2O_PAW])/2.0; +lai_var_list[18]=FLUXES[f+F.et]; +// // Run Knorr LAI module +double *LAI_KNORR_OUTPUT = LAI_KNORR(lai_met_list,lai_var_list); +FLUXES[f+F.target_LAI]=LAI_KNORR_OUTPUT[0]; +FLUXES[f+F.T_memory]=LAI_KNORR_OUTPUT[1]; +FLUXES[f+F.lambda_max_memory]=LAI_KNORR_OUTPUT[2]; +FLUXES[f+F.dlambda_dt]=LAI_KNORR_OUTPUT[3]/deltat; +FLUXES[f+F.f_temp_thresh]=LAI_KNORR_OUTPUT[4]; +FLUXES[f+F.f_dayl_thresh]=LAI_KNORR_OUTPUT[5]; +lai_var_list[5]=FLUXES[f+F.T_memory]; /*Update LAI temperature memory state for next iteration*/ +lai_var_list[11]=FLUXES[f+F.lambda_max_memory]; /*Update water/structural memory state for next iteration*/ + +Fcfolavailable=FLUXES[f+F.lab_prod] + POOLS[p+S.C_lab]/deltat; +if (FLUXES[f+F.dlambda_dt] > 0){ + /* labile release: flux from labile pool to foliar pool */ + FLUXES[f+F.lab_release]=MinQuadraticSmooth(Fcfolavailable, FLUXES[f+F.dlambda_dt]*pars[P.LCMA], 0.99); + /* flag for carbon availability limitation (0=canopy in senescence, 1=labile C does not limit growth, 2=labile C limits LAI growth) */ + FLUXES[f+F.c_lim_flag]=2.0; + /* leaf litter production: flux from foliar pool to litter pool */ + FLUXES[f+F.fol2lit]=0; +} +else { + FLUXES[f+F.c_lim_flag]=0.0; + /* labile release: flux from labile pool to foliar pool */ + FLUXES[f+F.lab_release]=0; + /* leaf litter production: flux from foliar pool to litter pool */ + FLUXES[f+F.fol2lit]=-FLUXES[f+F.dlambda_dt]*pars[P.LCMA]; +} + + +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*wood CWD production*/ +FLUXES[f+F.wood2cwd] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic CWD*/ +FLUXES[f+F.resp_het_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_cwd],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_som],deltat))/deltat; + +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +double thetas = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double *jcr_o = JCR(ch4pars,T2M_MIN[n],T2M_MAX[n],thetas); +//outputformat +//jcr_o 0-3 fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_cwd],deltat))/deltat; +/* aerobic Rh from litter*/ +FLUXES[f+F.ae_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_lit],deltat))/deltat; +/* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_som],deltat))/deltat; +/* anaerobic Rh from coarse woody debris*/ +FLUXES[f+F.an_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from litter*/ +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_lit],deltat))/deltat; +/* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_som],deltat))/deltat; +/* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*1+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*(1-jcr_o[3]); +/* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*0+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*jcr_o[3]; +/* fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+F.fV] = jcr_o[1]; +/* fT Temperature scaler*/ +FLUXES[f+F.fT] = jcr_o[0]; +/* fW Water scaler*/ +FLUXES[f+F.fW] = jcr_o[2]; +/* fCH4 CH4 fraction*/ +FLUXES[f+F.fCH4] = jcr_o[3]; +/* PAW/PAW_fs thetas*/ +FLUXES[f+F.soil_moist] = thetas; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*---------------------- end of JCR --------------------------------------------*/ + +/*CWD to SOM*/ +FLUXES[f+F.cwd2som] = POOLS[p+S.C_cwd]*(1-pow(1-pars[P.tr_cwd2som]*FLUXES[f+F.temprate],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2som]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.lab_release] - FLUXES[f+F.fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2cwd])*deltat; + POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] + (FLUXES[f+F.wood2cwd] - FLUXES[f+F.ae_rh_cwd]-FLUXES[f+F.an_rh_cwd]-FLUXES[f+F.cwd2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-CF[S.C_cwd])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2cwd])*deltat; + /*dead C pools*/ + /*CWD*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.fx_woo2cwd]-FLUXES[f+F.f_cwd]-FLUXES[f+F.fx_cwd2som])*deltat; + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + /*Fraction of C-foliar lost due to fires*/ + FLUXES[f+F.foliar_fire_frac] = BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Calculate LAI (lambda) lost due to fire + - we lose the same fraction of LAI as we do C-foliar + - FE_\Lambda^{(t+1)} = \Lambda^{(t+1)'} * BA ( k_{factor(i)} + (1 - k_{factor(i)}) r )*/ + FLUXES[f+F.lai_fire] = (POOLS[p+S.C_fol]/pars[P.LCMA])*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + + +} + +/*LAI is a CARDAMOM-wide state variable, ensuring available at first/last timestep in general (LAI) form, rather than only as "Cfol/LCMA"*/ +LAI[n+1]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1105/EDC2_1105.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1105(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1105_PARAMETERS P=DALEC_1105_PARAMETERS; +struct DALEC_1105_FLUXES F=DALEC_1105_FLUXES; +struct DALEC_1105_POOLS S=DALEC_1105_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +if (Fin[n] > 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_cwd,P.i_lit,P.i_som,P.i_PAW,P.i_PUW,P.i_SWE}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1105/PARS_INFO_1105.c === + +#pragma once +#include "DALEC_1105.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1105(DATA *CARDADATA) +{ + + +struct DALEC_1105_PARAMETERS P=DALEC_1105_PARAMETERS; + +/*Litter decomposition rate*/ +CARDADATA->parmin[P.tr_lit2som]=0.00001; +CARDADATA->parmax[P.tr_lit2som]=0.01; + +/*CWD decomposition rate*/ +CARDADATA->parmin[P.tr_cwd2som]=0.00001; +CARDADATA->parmax[P.tr_cwd2som]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR CWD*/ +CARDADATA->parmin[P.t_cwd]=0.00005; +CARDADATA->parmax[P.t_cwd]=0.005; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_som]=0.0000001; +CARDADATA->parmax[P.t_som]=0.001; + +/*\Q10 = 1.2-2.0*/ +CARDADATA->parmin[P.Q10rhco2]=1.2; +CARDADATA->parmax[P.Q10rhco2]=2.0; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C CWD*/ +CARDADATA->parmin[P.i_cwd]=1.0; +CARDADATA->parmax[P.i_cwd]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_som]=1.0; +CARDADATA->parmax[P.i_som]=200000.0; + +/*Retention parameter (b)*/ +CARDADATA->parmin[P.retention]=1.5; +CARDADATA->parmax[P.retention]=10; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +CARDADATA->parmin[P.hydr_cond]=0.0000001; +CARDADATA->parmax[P.hydr_cond]=0.00001; + +/*Maximum infiltration (mm/day)*/ +CARDADATA->parmin[P.max_infil]=1; +CARDADATA->parmax[P.max_infil]=100; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*PAW porosity*/ +CARDADATA->parmin[P.PAW_por]=0.2; +CARDADATA->parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +CARDADATA->parmin[P.PUW_por]=0.2; +CARDADATA->parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +CARDADATA->parmin[P.field_cap]=0.01; +CARDADATA->parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +CARDADATA->parmin[P.PAW_z]=0.01; +CARDADATA->parmax[P.PAW_z]=100; + +/*PUW depth (m)*/ +CARDADATA->parmin[P.PUW_z]=0.01; +CARDADATA->parmax[P.PUW_z]=100; + +/*Runoff excess*/ +CARDADATA->parmin[P.Q_excess]=0.01; +CARDADATA->parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +CARDADATA->parmin[P.Med_g1]=1.79; +CARDADATA->parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +CARDADATA->parmin[P.Vcmax25]=1e-8; +CARDADATA->parmax[P.Vcmax25]=140; + +/*Tminmin scaling factor*/ +CARDADATA->parmin[P.Tminmin]=258.15; +CARDADATA->parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +CARDADATA->parmin[P.Tminmax]=273.15; +CARDADATA->parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance*/ +CARDADATA->parmin[P.ga]=0.01; +CARDADATA->parmax[P.ga]=10.0; + +/*Tupp*/ +CARDADATA->parmin[P.Tupp]=299.15; +CARDADATA->parmax[P.Tupp]=318.15; + +/*Tdown*/ +CARDADATA->parmin[P.Tdown]=263.15; +CARDADATA->parmax[P.Tdown]=286.15; + +/*C3_frac*/ +CARDADATA->parmin[P.C3_frac]=1e-8; +CARDADATA->parmax[P.C3_frac]=1.0; + +/*Clumping index*/ +CARDADATA->parmin[P.clumping]=0.35; +CARDADATA->parmax[P.clumping]=1.0; + +/*Leaf single scattering albedo*/ +CARDADATA->parmin[P.leaf_refl]=1e-8; +CARDADATA->parmax[P.leaf_refl]=1.0; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +CARDADATA->parmin[P.i_SWE]=0.000001; +CARDADATA->parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +CARDADATA->parmin[P.min_melt]=240; +CARDADATA->parmax[P.min_melt]=270; + +/*sn2: slope*/ +CARDADATA->parmin[P.melt_slope]=0.00001; +CARDADATA->parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar*/ +CARDADATA->parmin[P.scf_scalar]=0.001; +CARDADATA->parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +/*jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +CARDADATA->parmin[P.S_fv]=1; +CARDADATA->parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +CARDADATA->parmin[P.thetas_opt]=0.2; +CARDADATA->parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +CARDADATA->parmin[P.fwc]=0.01; +CARDADATA->parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +CARDADATA->parmin[P.r_ch4]=0.001; +CARDADATA->parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +CARDADATA->parmin[P.Q10ch4]=1.0; +CARDADATA->parmax[P.Q10ch4]=3.0; + +/* maxPevap in mm/day*/ +CARDADATA->parmin[P.maxPevap]=0.01; +CARDADATA->parmax[P.maxPevap]=20; + +/*Mean temperature at leaf onset (T_phi) (degrees kelvin)*/ +CARDADATA->parmin[P.T_phi]=268.15; +CARDADATA->parmax[P.T_phi]=323.15; + +/*Spatial range of mean temperature at leaf onset (T_r) (degrees C or degrees kelvin)*/ +CARDADATA->parmin[P.T_range]=0.1; +CARDADATA->parmax[P.T_range]=10.0; + +/*Averaging period for temperature growth trigger T (time units of model), usually kept constant*/ +CARDADATA->parmin[P.tau_m]=1.0; +CARDADATA->parmax[P.tau_m]=1.01; + +/*LAI linear growth constant (inverse of model time units; e.g. days-1 or months-1)*/ +CARDADATA->parmin[P.plgr]=0.001; +CARDADATA->parmax[P.plgr]=0.5; + +/*Inverse of leaf longevity during senescence period (inverse of model time units; e.g. days-1 or months-1)*/ +CARDADATA->parmin[P.k_leaf]=0.001; +CARDADATA->parmax[P.k_leaf]=0.5; + +/*Intrinsic maximum LAI (m^2 m^-2)*/ +CARDADATA->parmin[P.lambda_max]=0.1; +CARDADATA->parmax[P.lambda_max]=10.0; + +/*Target survival time for LAI under water-deficit conditions (days; or same unit as ET and PAW)*/ +CARDADATA->parmin[P.tau_W]=0.1; +CARDADATA->parmax[P.tau_W]=300; + +/*Mean daylength at leaf shedding (t_c; in units of hours sunlight per day)*/ +CARDADATA->parmin[P.time_c]=2; +CARDADATA->parmax[P.time_c]=22; + +/*Spatial range of mean daylength at leaf shedding (t_r)*/ +CARDADATA->parmin[P.time_r]=0.1; +CARDADATA->parmax[P.time_r]=6.0; + +/*initialization of temperature memory (fractional value between mintemp and maxtemp at t=0)*/ +CARDADATA->parmin[P.init_T_mem]=0.01; +CARDADATA->parmax[P.init_T_mem]=1; + +/*initialization of water/structural memory (fractional value of intrinsic maximum LAI)*/ +CARDADATA->parmin[P.init_LAIW_mem]=0.01; +CARDADATA->parmax[P.init_LAIW_mem]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1105/MODEL_INFO_1105.c === + +#pragma once +#include "PARS_INFO_1105.c" +#include "DALEC_1105.c" +#include "EDC1_1105.c" +#include "EDC2_1105.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1105(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1105_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1105; +DALECmodel.edc1=EDC1_1105; +DALECmodel.edc2=EDC2_1105; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1105(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_DEDC; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1105/EDC1_1105.c === + +#pragma once +int EDC1_1105(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1105_PARAMETERS P=DALEC_1105_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +// double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto)*pars[P.f_lab]; +double const froot=(1-fauto-flab)*pars[P.f_root]; +double const fwood=1-fauto-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab)*pars[P.tr_lit2som]/(pars[P.tr_lit2som]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +// double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_som]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2som]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((flab)>5*froot | (flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/mean_pool.c === + +#pragma once + + +/*mean matrix from double pointer routine*/ +double mean_pool(double *PA,int p,int nc, int nopools){ +/*declarations*/ +int c; +double meanpool=0; +/*deriving mean of pool p*/ +for (c=0;cstart){ + return start + (end-start)/(1+exp(k*(x-x_o))); + } + else{ + return end + (start-end)/(1+exp(-k*(x-x_o))); + } +} + +//Main function +int NLM_AND_ALLOC(NLM_AND_ALLOC_STRUCT * S){ + + double fT; // temperature scaling for maintenance respiration + double F_LABREL_SUPPLY; // + double F_LABREL_DEMAND; // + double TOTAL_GROWTH_POT; // + double TOTAL_GROWTH_ACTUAL; // + double SCALE_ALLOC_FLUXES; // + + //Maintenance respiration + fT = pow(S->IN.Q10mr,(S->IN.TEMP-(25+DGCM_TK0C))/10); // reference temperature is 25 degrees C + //Autotrophic maintenance for wood and non-wood + double POTENTIAL_AUTO_RESP_MAINTENANCE = S->IN.mr_w * fT * S->IN.C_LIVE_W + S->IN.mr_r * fT * S->IN.C_LIVE_R; + + + + double NSC_PLUS_GPP_RATE = S->IN.NSC/S->IN.deltat + (S->IN.GPP - S->IN.Rd); + + S->OUT.NONLEAF_MORTALITY_FACTOR=0; + + + + //IF maintenance + //Spend all NSC on maintenance + S->OUT.NONLEAF_MORTALITY_FACTOR=1/exp(NSC_PLUS_GPP_RATE/POTENTIAL_AUTO_RESP_MAINTENANCE); + + + + + + + S->OUT.AUTO_RESP_MAINTENANCE = POTENTIAL_AUTO_RESP_MAINTENANCE * (1- S->OUT.NONLEAF_MORTALITY_FACTOR); + + //Calculate leftover NSCs + //Only use available NSC after maintenance resp accounted for + double LEFTOVER_NSC_RATE = NSC_PLUS_GPP_RATE - S->OUT.AUTO_RESP_MAINTENANCE ; + + S->OUT.growth_carbon = LEFTOVER_NSC_RATE; + + + S->OUT.resep_alloc = sigmoid(S->IN.s_ar,S->IN.k_growth,S->IN.Paw_norm,S->IN.W_o,S->IN.e_ar); + S->OUT.AUTO_RESP_GROWTH = S->OUT.resep_alloc * LEFTOVER_NSC_RATE; + + + double growth_yield = LEFTOVER_NSC_RATE - S->OUT.AUTO_RESP_GROWTH; + + + S->OUT.ALLOC_FOL_ACTUAL = fmin(growth_yield, fmax(0, S->IN.ALLOC_FOL_POT ) ); + S->OUT.fol_alloc = S->OUT.ALLOC_FOL_ACTUAL/S->OUT.growth_carbon; + + + double growth_yield_nofoliar = growth_yield - S->OUT.ALLOC_FOL_ACTUAL; + + + S->OUT.wood_alloc = sigmoid(S->IN.s_wood,S->IN.k_growth,S->IN.Paw_norm,S->IN.W_o,S->IN.e_wood); + S->OUT.ALLOC_WOO_ACTUAL = S->OUT.wood_alloc * growth_yield_nofoliar; + + + S->OUT.root_alloc = sigmoid(S->IN.s_root,S->IN.k_growth,S->IN.Paw_norm,S->IN.W_o,S->IN.e_root); + S->OUT.ALLOC_ROO_ACTUAL = S->OUT.root_alloc * growth_yield_nofoliar; + + S->OUT.nsc_alloc = 1- S->OUT.wood_alloc - S->OUT.root_alloc; + S->OUT.ALLOC_NSC_ACTUAL = growth_yield_nofoliar - S->OUT.ALLOC_WOO_ACTUAL - S->OUT.ALLOC_ROO_ACTUAL ; + + // printf("F_LABREL_ACTUAL: %f\n", S->OUT.F_LABREL_ACTUAL); + // printf("ALLOC_WOO_ACTUAL: %f\n", S->OUT.ALLOC_WOO_ACTUAL); + // printf("ALLOC_ROO_ACTUAL: %f\n", S->OUT.ALLOC_ROO_ACTUAL); + + + + //Diagnostic variables + S->OUT.AUTO_RESP_TOTAL = S->OUT.AUTO_RESP_MAINTENANCE + S->OUT.AUTO_RESP_GROWTH; + S->OUT.NPP = S->IN.GPP - S->OUT.AUTO_RESP_TOTAL; + S->OUT.CUE = S->OUT.NPP/S->IN.GPP; + + + + + + + return 0; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/UT_H2O_TEMP_2_ENERGY.c === + +#include +//#include "INTERNAL_ENERGY_PER_H2O_UNIT_MASS.c" + +#define DGCM_PI 3.1415927 //pi +#define DGCM_T3 273.16 //Triple point temp, K +#define DGCM_TK0C 273.15 //Kelvin at 0C +// Specific heat of ice +#define DGCM_SPECIFIC_HEAT_ICE 2093.// 2093 J kg?1 K +#define DGCM_SPECIFIC_HEAT_WATER 4186.// 4186 J kg?1 K +//Latent heat of vaporization +#define DGCM_LATENT_HEAT_VAPORIZATION 2.501e6; // J kg-1 +#define DGCM_LATENT_HEAT_FUSION_3 3.34e5 +#define DGCM_T_LIQUID_H2O_ZERO_ENERGY 56.79//Zero-energy temperature of super-cooled liquid water 56.79 K +#define DGCM_SEC_DAY (24*60*60)//Seconds per day + +int main(){ + +//Minimnum temp +//Energy for 1m dry soil at -50C + +//1mm H2O at -50C + double LF, TEMP, U; + + LF = 0; + TEMP=-50+273.15; + U=(1 - LF) * DGCM_SPECIFIC_HEAT_ICE* TEMP + LF * DGCM_SPECIFIC_HEAT_WATER* (TEMP - DGCM_T_LIQUID_H2O_ZERO_ENERGY); +//1mm H2O at + 50C +printf("1mm H2O LF = 0 @ -50C = %2.2e\n",U); + + LF = 1; + TEMP=50+273.15; + U=(1 - LF) * DGCM_SPECIFIC_HEAT_ICE* TEMP + LF * DGCM_SPECIFIC_HEAT_WATER* (TEMP - DGCM_T_LIQUID_H2O_ZERO_ENERGY); + +printf("1mm H2O LF = 0 @ +50C = %2.2e\n",U); + + + +//Max IE for 1m soil = + + + + + +printf("hello\n"); + +return 0; +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LAI_GSI.c === + +#pragma once +#include "./LAI_KNORR_funcs.c" +/* Leaf Phenology Model of Knorr et al. (2010, doi: 10.1029/2009JG001119)*/ +double* LAI_GSI(double const *met_list, double const *var_list) +{ +/*Notes: DALEC code passes the following *consts and *pars pointers: + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +Forcing inputs: + latitude + day of year + pi + Temperature + VPD + +Parameter inputs: + Tmnmin # parameter: minimum temperature threshold for GSI + Tmnmax # parameter: maximum temperature threshold for GSI + Photoperiodmin # parameter: minimum photoperiod threshold for GSI + Photoperiodmax # parameter: maximum photoperiod threshold for GSI + VPDmin # parameter: minimum VPD threshold for GSI + VPDmax # parameter: maximum VPD threshold for GSI + +*/ + + /*initialize intermediate variables*/ + double daylengthpars[3]; + double daylength; + double Tmn, VPD; + double Tmnmin, Tmnmax; + double Photoperiodmin, Photoperiodmax; + double VPDmin, VPDmax; + double Tfac, PHOTOfac, VPDfac; + double GSI; + + // Forcings/drivers + Tmn=(double)met_list[0]; // Original DALEC model, Tmn is the 21 day average Tmn, MET[m+9] + VPD=(double)met_list[1]; // Original DALEC model, this is the 21 day average VPD, MET[m+11] + + // Parameters + Tmnmin=(double)var_list[3]; // Original DALEC model, pars[13]; + Tmnmax=(double)var_list[4]; // Original DALEC model, pars[14]; + Photoperiodmin=(double)var_list[5]; // Original DALEC model, pars[15]; + Photoperiodmax=(double)var_list[6]; // Original DALEC model, pars[23]; + VPDmin=(double)var_list[7]; // Original DALEC model, pars[24]; + VPDmax=(double)var_list[8]; // Original DALEC model, pars[25]; + + /* compute daylight hours (hours of sunlight per day) */ + daylengthpars[0]=var_list[0]; /* latitude */ + daylengthpars[1]=var_list[1]; /* day of year */ + daylengthpars[2]=var_list[2]; /* pi */ + daylength = ComputeDaylightHours(daylengthpars); // Original DALEC model, this is the 21 day average photoperiod, MET[m+10] + + /* 25/09/14 - JFE + Here we calculate the Growing Season Index based on + Jolly et al. A generalized, bioclimatic index to predict foliar phenology in response to climate Global Change Biology, Volume 11, page 619-632 - 2005 (doi: 10.1111/j.1365-2486.2005.00930.x) + - Stoeckli, R., T. Rutishauser, I. Baker, M. A. Liniger, and A. S. Denning (2011), A global reanalysis of vegetation phenology, J. Geophys. Res., 116, G03020, doi:10.1029/2010JG001545. + + It is the product of 3 limiting factors for temperature, photoperiod and vapour pressure deficit + that grow linearly from 0 to 1 between a calibrated min and max value. + Temperature, photoperiod and VPD are direct input + */ + + + // calculate the temperature based limiting factor + if (Tmn > Tmnmax) // Tmin larger than parameter Tmmax + { + Tfac = 1.; + } + else if (Tmn < (Tmnmin)) // Tmin lower than parameter Tmmin + { + Tfac = 0.; + } + else + { + Tfac = (Tmn-(Tmnmin))/(Tmnmax-(Tmnmin)); + } + + // calculate the photoperiod limiting factor + if (daylength > Photoperiodmax) // photoperiod larger than parameter PHOTOmax + { + PHOTOfac = 1.; + } + else if (daylength < Photoperiodmin) // photoperiod lower than parameter PHOTOmin + { + PHOTOfac = 0.; + } + else + { + PHOTOfac = (daylength-Photoperiodmin)/(Photoperiodmax-Photoperiodmin); + } + + // calculate the VPD based limiting factor - high VPD is limiting + if (VPD>VPDmax) // VPD larger than parameter VPDmax + { + VPDfac = 0.; + } + else if (VPDIN.n; + deltat=(double)K->IN.deltat; + lambda=(double)K->IN.lambda; + T_init=(double)0.0; + T_phi=K->IN.T_phi ; // mean temp at leaf onset (K) + T_r=K->IN.T_r; // spatial range of T_phi (K) + T_memory=K->IN.T_memory; // temperature memory (K) + meantemp=K->IN.temp; // mean surface air temperature (K) + tau_m=30.0; //var_list[6]; + plgr=K->IN.plgr;// + k_L=K->IN.k_L; + pasm=K->IN.pasm; + transp=K->IN.transp; + lambda_max=K->IN.lambda_max; + tau_W=K->IN.tau_W; + lambda_max_memory=K->IN.lambda_max_memory; //TIME-DEPENDENT I.E. SAVE IN MEMORY + tau_s=30.0; // Averaging period for water/structural memory (units of days; must be in same units as deltat), usually kept constant but could potentially be a tuneable parameter + t_c=K->IN.t_c; + t_r=K->IN.t_r; + + + daylengthpars[0]=K->IN.latitude; /* latitude */ + daylengthpars[1]=K->IN.DOY; /* day of year */ + daylengthpars[2]=DGCM_PI; /* pi */ + + // /* Initialization: only run this on the first time step! */ + // if (n==0) { + // lambda_max_memory=lambda_max; + // laim=lambda_max_memory; + // } + // if (n < 2){ + // printf("\n"); + // printf("KNORR n = %2f\n",n); + // } + + // if (n==0){printf("> in LAI_KNORR: T_memory = %2.1f\n",T_memory);} + // if (n==0){T_memory=T_phi+3*T_r;} /* set the temperature memory to be high so that we start in growth phase */ + // Exponentially declining memory of temperature + T = exp(- deltat / tau_m)*T_memory + meantemp * (1 - exp(- deltat / tau_m)); + T_deviation=(T-T_phi)/T_r; + /* fraction of plants above temperature threshold: using cumulative normal distribution function (derived from the intrinsic c-function erfc) */ + f_T = 0.5*erfc(-T_deviation*sqrt(0.5)); + + /* compute daylight hours (hours of sunlight per day) */ + + daylength = ComputeDaylightHours(daylengthpars); + td_deviation = (daylength-t_c)/t_r; + /* fraction of plants above daylength threshold: using cumulative normal distribution function (derived from the intrinsic c-function erfc) */ + f_d = 0.5*erfc(-td_deviation*sqrt(0.5)); + + /* fraction of plants above temperature and daylength thresholds */ + f = f_T * f_d; + /* compute current growth rate */ + r = plgr * f + (1 - f)*k_L; + + /* compute water-limited maximum LAI */ + lambda_W = (pasm * lambda) / (tau_W * MaxExponentialSmooth(transp, 1e-3, 2e-2)); + /* compute smoothed maximum LAI */ + lambda_tilde_max = MinQuadraticSmooth(lambda_max, lambda_W, 0.99); + /* update LAI water/structural memory using an exponentially declining memory of water/structural limitation over the time period tau_s */ + laim = exp(- deltat / tau_s)*lambda_max_memory + lambda_tilde_max * (1.0 - exp(- deltat / tau_s)); + lambda_lim = MaxExponentialSmooth(plgr * laim * f / r, 1e-9, 5e-3); + + // lambda_next is the updated target LAI (units of m2/m2) + lambda_next = lambda_lim - (lambda_lim - lambda)*exp(-r*deltat); + + // dlambdadt is the change in LAI over the period deltat (units of m2/m2) + dlambdadt = (lambda_next - lambda); + + + + //Store outputs in struct + K->OUT.lambda_next = lambda_next; + K->OUT.T= T; + K->OUT.laim = laim; + K->OUT.dlambdadt = dlambdadt;//dLAI/dt units = change of LAI per timestep + K->OUT.f_T=f_T; + K->OUT.f_d= f_d; + K->OUT.lambda_tilde_max= lambda_tilde_max; + K->OUT.lambda_W= lambda_W; + + + + + + + return 0; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/mean_annual_pool.c === + +#pragma once +/*mean matrix from double pointer routine*/ +double mean_annual_pool(double *POOLS, int year, int pool, int nopools,int deltat){ +/*inputs + * POOLS: Pools double pointer, as output from DALEC + * year: year for which to average (first year = 0) + * pool: the specific pool + * nc +declarations*/ +int r,c; +double meanpool=0; +/*deriving mean of pool p*/ +int stday=floor(365.25*year/deltat); +int enday=floor(365.25*(year+1)/deltat); +for (c=stday;cIN.SRAD; +double VPD=A->IN.VPD; +double TEMP=A->IN.TEMP; // Temperature (K) +double vcmax25=A->IN.vcmax25; +double co2=A->IN.co2; +double beta_factor=A->IN.beta_factor; +double g1=A->IN.g1; +double LAI=A->IN.LAI; +double ga=A->IN.ga; +double VegK=A->IN.VegK; +double Tupp=A->IN.Tupp; // Units are K +double Tdown=A->IN.Tdown; // Units are K +double C3_frac=A->IN.C3_frac; +double clumping=A->IN.clumping; +double leaf_refl_par=A->IN.leaf_refl_par; +double leaf_refl_nir=A->IN.leaf_refl_nir; +double maxPevap=A->IN.maxPevap; +double precip=A->IN.precip; + +/* --- Physical and thermodynamic constants --- */ +double Ephoton = 2.0e-25/500.0e-9; // Energy per photon at 500 nm: h*c/lambda (J); h=6.626e-34 J.s, c=3e8 m/s +double NA = 6.02e23; // Avogadro's constant (mol-1) +double R = 8.31e-3; // Universal gas constant (kJ mol-1 K-1) +double lambda0 = 2.26e6; // Latent heat of vaporization of water (J kg-1) +double rho_air = 1.225; // Dry air density at sea level (kg m-3) +double Cp_air = 1005.; // Specific heat of dry air at constant pressure (J kg-1 K-1) +double eps_mol = 0.622; // Ratio of molar mass of water vapour to dry air: Mw/Md = 18.015/28.97 (-) +/* Psychrometric constant gamma = rho_air * Cp_air / (lambda0 * eps_mol) (Pa K-1); + here expressed as a dimensionless coefficient for use with kPa and m s-1 units */ +double gammaV = 100.*Cp_air/(lambda0*eps_mol); // ~0.067 kPa K-1; Monteith & Unsworth 2008 + + +/* --- FvCB photosynthesis state variables --- */ +double PAR; // Incident PAR at canopy top (umol photons m-2 s-1) +double T_C; // Air temperature (deg C) +double Kc; // Michaelis-Menten constant for CO2 (umol mol-1), temperature-dependent +double Ko; // Michaelis-Menten constant for O2 (mmol mol-1), temperature-dependent +double cp; // CO2 compensation point in absence of Rd, Gamma* (umol mol-1) +double Vcmax; // Maximum rate of Rubisco carboxylation at T_C (umol CO2 m-2 s-1) +double Jmax; // Maximum rate of electron transport at T_C (umol e- m-2 s-1) +double J; // Actual electron transport rate (umol e- m-2 s-1) +double medlyn_term; // Medlyn optimal stomatal model factor: 1 + g1/sqrt(VPD); Medlyn et al. 2011 +double ci; // Leaf intercellular CO2 concentration (umol mol-1) +//double C3_frac = 1.; //Fraction of C3 per gridcell +double a1; // Rubisco-limited (co-limited) gross assimilation term (umol CO2 m-2 s-1) +double a2; // Electron-transport-limited gross assimilation term (umol CO2 m-2 s-1) + +double Ag_C3; // Gross assimilation, C3 pathway (leaf-level, umol CO2 m-2 s-1) +double Ag_C4; // Gross assimilation, C4 pathway (leaf-level, umol CO2 m-2 s-1) +double Ag; // Blended gross assimilation (leaf-level, umol CO2 m-2 s-1) +double An; // Net assimilation = Ag - Rd (leaf-level, umol CO2 m-2 s-1) + +double Rd_C3; // Dark respiration, C3 (umol CO2 m-2 s-1) +double Rd_C4; // Dark respiration, C4 (umol CO2 m-2 s-1) +double Rd; // Blended dark respiration (umol CO2 m-2 s-1) + +/* Convert incoming shortwave to incident PAR. + SRAD is total shortwave (W m-2); ~50% is PAR (400-700 nm); dividing by Ephoton*NA + converts W m-2 (= J s-1 m-2) to mol photons m-2 s-1, then *1e6 -> umol photons m-2 s-1. + The factor of 2 accounts for the ~50% PAR fraction of shortwave; Liu et al. myFun.py. */ +PAR = SRAD/(2.*Ephoton*NA)*1e6; + +/* --- Canopy radiation interception --- */ +/* canopy_scale: integral of Beer's law profile int_0^LAI exp(-k*Omega*l) dl + = (1 - exp(-k*Omega*LAI)) / (k*Omega); denominator requires both k AND Omega (clumping); + de Pury & Farquhar (1997) Plant Cell Environ. 20:537; Bonan (2019) Ch. 14 Eq. 14.6 */ +double canopy_scale = (1. - exp(-VegK*LAI*clumping))/(VegK*clumping); // Beer's law integral /(k*Omega), not /(k); de Pury & Farquhar 1997; Bonan Ch. 14 Eq. 14.6 + +//printf(" \n Initial LAI %f \n ", LAI); + +/* PAR_leaf: effective leaf-level absorbed PAR for the big-leaf model. + Derived as APAR_canopy / canopy_scale = I_0*(1-rho)*k*Omega; this keeps + all FvCB quantities (a1, a2) at leaf level so canopy_scale is applied only once at output. + Bonan (2019) Ch. 14; Liu et al. myFun.py f_carbon() */ +double PAR_leaf = PAR * (1. - leaf_refl_par) * VegK * clumping; // leaf-level PAR = APAR/canopy_scale = I_0*(1-rho)*k*Omega; Bonan Ch. 14 + + +T_C = TEMP - DGCM_TK0C; // Convert temperature to degrees C + + +/* Temperature-dependent Michaelis-Menten kinetics; Q10-type fits to Bernacchi et al. (2001) data. + Kc ref = 300 umol mol-1, Ko ref = 300 mmol mol-1, both at 25 C. */ +Kc = 300.*exp(0.074*(T_C - 25.)); // Michaelis constant for CO2 (umol mol-1) +Ko = 300.*exp(0.015*(T_C - 25.)); // Michaelis constant for O2 (mmol mol-1) +cp = 36.9 + 1.18*(T_C - 25.) + 0.036*pow((T_C - 25.), 2.); // CO2 compensation point Gamma* (umol mol-1); Bernacchi et al. 2001; Liu et al. myFun.py + +/* --- Vcmax temperature response (Q10 formulation with upper/lower inhibition) --- + Vcmax(T) = Vcmax25 * Q10^(0.1*(T-25)) / [(1+exp(0.3*(T-Tupp))) * (1+exp(0.3*(Tdown-T)))] + Tupp, Tdown: upper/lower thermal inhibition thresholds (K); inverted by MCMC. */ +double q_10 = A->IN.q10canopy; +double fT = pow(A->IN.q10canopyRd,(T_C-25.)/10.); // Q10 temperature scaling for Rd; reference T = 25 C + +Vcmax = vcmax25*pow(q_10,0.1*(T_C-25.))/((1. + exp(0.3*(T_C-(Tupp-DGCM_TK0C))))*(1. + exp(0.3*((Tdown-DGCM_TK0C)-T_C)))); + +/* Jmax/Vcmax ~ e ≈ 2.72 at 25 C; Leuning (1997) J. Exp. Bot. 48:345 + (Wullschleger 1993 109-species dataset rescaled to 25 C: slope = 2.68, r2 = 0.87) + Fixed ratio minimises MCMC parameter space; temperature response of Jmax tracks Vcmax. */ +Jmax = Vcmax*exp(1.); + +/* Electron transport rate J: non-rectangular hyperbola (Farquhar & Wong 1984). + kai1 = 0.9 (curvature parameter), kai2 = 0.3 (quantum yield, mol e- per mol photon); + Bonan (2019) Ch. 11 Eq. 11.33; Liu et al. myFun.py */ +J = (0.3*PAR_leaf + Jmax - sqrt(pow(0.3*PAR_leaf + Jmax,2) - 4.*0.9*0.3*PAR_leaf*Jmax))/2./0.9; // PAR_leaf keeps a2 leaf-level (consistent with a1); single canopy_scale at output; Bonan Ch. 11 + +/* Medlyn et al. (2011) optimal stomatal conductance model: gs/g0 ~ 1 + g1/sqrt(VPD). + ci derived analytically from gs = An/(co2-ci)*1.6, giving ci = co2*(1 - 1/medlyn_term). + Medlyn et al. (2011) Glob. Change Biol. 17:2134 */ +medlyn_term = 1. + g1/sqrt(VPD); + +ci = co2*(1. - 1./medlyn_term); + + if (ciIN.canopyRdsf*vcmax25*fT; // C3 dark respiration = canopyRdsf * Vcmax25 * Q10(T) + +/* --- C4 photosynthesis: simplified two-term co-limitation --- + C4 plants have a CO2-concentrating mechanism (CCM), so Rubisco is not CO2-limited; + a1 ~ Vcmax (enzyme-limited), a2 ~ J (light-limited). + C3_frac is prescribed per pixel from remote-sensing products, not inverted by MCMC. */ +a1 = Vcmax; +a2 = J; + +Ag_C4 = fmin(a1*beta_factor, a2); // C4 gross assimilation +Rd_C4 = A->IN.canopyRdsf*vcmax25*fT; // C4 dark respiration + +/* Fractional C3/C4 mix (C3_frac prescribed, not MCMC-inverted) */ +Ag = C3_frac*(Ag_C3) + (1. - C3_frac)*(Ag_C4); // blended gross assimilation (leaf-level, umol CO2 m-2 s-1) +Rd = C3_frac*(Rd_C3) + (1. - C3_frac)*(Rd_C4); // blended dark respiration (leaf-level, umol CO2 m-2 s-1) + +/* Potential canopy Rd (g C m-2 day-1): + leaf-level Rd * canopy_scale (leaf->canopy) * 12e-6 (g C per umol CO2) * 86400 (s day-1) */ +double Rd_daily_potential = Rd*canopy_scale*(12.e-6)*(24.*60.*60.); + +/* Leaf mortality from NSC (non-structural carbohydrates) limitation. + Exponential formulation: LEAF_MORTALITY_FACTOR -> 0 when NSC >> Rd*deltat (no stress), + -> 1 when NSC -> 0 (full mortality); updated to exponential form 11/1/2023. */ +if (Rd_daily_potential==0){ + A->OUT.LEAF_MORTALITY_FACTOR=0; +} else { + A->OUT.LEAF_MORTALITY_FACTOR=(1./(exp(A->IN.NSC/(Rd_daily_potential * A->IN.deltat)))); +} + +/* Actual daily canopy Rd, scaled by leaf survival fraction */ +A->OUT.Rd = Rd_daily_potential*(1. - A->OUT.LEAF_MORTALITY_FACTOR); + +/* Scale leaf-level Rd by survival fraction before computing leaf-level An */ +Rd = Rd*(1. - A->OUT.LEAF_MORTALITY_FACTOR); + +/* Net assimilation (leaf-level); both Ag and Rd are leaf-level here. + canopy_scale applied once below when writing to output. */ +An = Ag - Rd; + +/* Scale leaf -> canopy and convert units: umol CO2 m-2 s-1 -> g C m-2 day-1 + 12e-6: molecular mass of C in g per umol CO2 (12 g mol-1 * 1e-6 mol umol-1) + 86400: seconds per day */ +//double canopy_scale = 1.; // uncomment to disable canopy scaling (diagnostic) +A->OUT.Ag = Ag*canopy_scale*(12.e-6)*(24.*60.*60.); +A->OUT.An = An*canopy_scale*(12.e-6)*(24.*60.*60.); + +/* ===================== Transpiration: Penman-Monteith (Monteith 1965) ===================== + Canopy transpiration E = [Delta*(Rn_veg) + rho_air*Cp*(VPD)*ga] / [lambda*(Delta + gamma*(1 + ga/gs))] + where Delta = d(esat)/dT (kPa K-1), gamma = psychrometric constant (kPa K-1), + ga = aerodynamic conductance (m s-1), gs = canopy stomatal conductance (m s-1). + Reference: Monteith & Unsworth (2008) "Principles of Environmental Physics", Ch. 13; + Liu et al. myFun.py PenmanMonteith(). */ + +double SRADg; // Shortwave radiation reaching the ground surface (W m-2) +double sV; // Slope of saturation vapour pressure curve, d(esat)/dT (kPa K-1) +double petVnum; // PM numerator for canopy transpiration (W m-2 equivalent) +double petVnumB; // PT numerator for ground evaporation (Priestley-Taylor 1972) +double gs; // Canopy stomatal conductance (m s-1) +double transp; // Canopy transpiration (mm hr-1) +double evap; // Ground evaporation (mm hr-1) +double VPD_kPa = VPD; // VPD already in kPa +double evap_scale_factpr; + +/* Slope of saturation vapour pressure curve (kPa K-1); empirical fit to Magnus equation */ +sV = 0.04145*exp(0.06088*T_C); + +/* Canopy and ground radiation partitioning using Beer's law: + SRADg = below-canopy shortwave (W m-2); (1-0.5*(rho_PAR+rho_NIR)) = broadband canopy absorptance */ +SRADg = (1. - 0.5*(leaf_refl_par+leaf_refl_nir))*SRAD*exp(-VegK*LAI*clumping); +SRAD = (1. - 0.5*(leaf_refl_par+leaf_refl_nir))*SRAD; // absorbed canopy shortwave (W m-2) + +/* PM numerator for canopy transpiration (mm hr-1): + numerator = [Delta*(Rn_canopy) + rho_air*Cp*VPD*ga] / lambda * 3600 + rho_air = 1.225 kg m-3; Cp_air = 1005 J kg-1 K-1; lambda0 = 2.26e6 J kg-1 */ +petVnum = (sV*(SRAD-SRADg) + rho_air*Cp_air*VPD_kPa*ga)/lambda0*60.*60.; // mm hr-1 + +/* Priestley-Taylor ground evaporation (mm hr-1): + alpha_PT = 1.26 (empirical coefficient; Priestley & Taylor 1972 Mon. Wea. Rev. 100:81); + uses below-canopy radiation SRADg; assumes soil evaporation ~ equilibrium */ +petVnumB = 1.26*(sV*SRADg)/(sV+gammaV)/lambda0*60.*60.; // mm hr-1; alpha_PT=1.26; Priestley & Taylor 1972 + +if(beta_factor > 0 && SRAD > 0){ + + /* Canopy stomatal conductance to water vapour (m s-1): + Based on leaf-level gs_CO2 = An/(co2-ci) (mol CO2 m-2 s-1 per umol mol-1); + 1.6: ratio of diffusivity of H2O to CO2 in air (dimensionless; Jones 1992 "Plants and Microclimate"); + LAI: leaf-to-canopy upscaling (m2 leaf m-2 ground); + 0.02405: molar volume of air at ~20 C = RT/P = 8.314*293/101325 = 0.02406 m3 mol-1, + converts mol CO2 m-2 s-1 -> m s-1. */ + gs = fmax(0., 1.6*An/(co2-ci)*LAI*0.02405); + + /* Penman-Monteith transpiration (mm hr-1). + Denominator: sV + gamma*(1 + ga/gs) = sV + gamma*ga*(1/ga + 1/gs); Monteith 1965. + Liu et al. myFun.py PenmanMonteith() */ + transp = petVnum/(sV + gammaV*(ga*(1./ga + 1./gs))); + +} else { + transp = 0.0; +} + +A->OUT.transp = transp*24.; // mm hr-1 -> mm day-1 + +/* Ground evaporation: scale by precipitation availability (evap <= precip/maxPevap) */ +evap_scale_factpr = fmin(precip/maxPevap, 1.); +evap = petVnumB*evap_scale_factpr; + +A->OUT.evap = evap*24.; // mm hr-1 -> mm day-1 + +return 0; +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/ANALYTICALSOLVER_BALDOCCHI.c === + +#pragma once + +double ANALYTICALSOLVER_BALDOCCHI(double const *met_list, double const *var_list, double const *wc_adeb_list, double const *wj_adeb_list, double const Rd, double const RH, double const ROOT_CALC) +{ + /****************** INPUTS *****************/ + /* met_list[0] = mintemp */ + /* met_list[1] = maxtemp */ + /* met_list[2] = co2 */ + /* met_list[3] = rad */ + /* met_list[4] = VPD */ + + /* var_list[0] = m */ + /* var_list[1] = b */ + /* var_list[2] = gb */ + /* var_list[3] = Jmax */ + /* var_list[4] = Vmax */ + /* var_list[5] = LAI */ + /* var_list[6] = k */ + /* var_list[7] = c1 */ + /* var_list[8] = c2 */ + + + /* wj_adeb_list[0] = aj */ + /* wj_adeb_list[1] = dj */ + /* wj_adeb_list[2] = ej */ + /* wj_adeb_list[3] = bj */ + /* wc_adeb_list[0] = ac */ + /* wc_adeb_list[1] = dc */ + /* wc_adeb_list[2] = ec */ + /* wc_adeb_list[3] = bc */ + + /******************************************/ + double aj, dj, ej, bj, ac, dc, ec, bc; + + aj = (double)wj_adeb_list[0]; + dj = (double)wj_adeb_list[1]; + ej = (double)wj_adeb_list[2]; + bj = (double)wj_adeb_list[3]; + ac = (double)wc_adeb_list[0]; + dc = (double)wc_adeb_list[1]; + ec = (double)wc_adeb_list[2]; + bc = (double)wc_adeb_list[3]; + + + /***********************************************/ + /*ANALYTICAL SETUP*/ + + /*initialize analytical setup variables*/ + double alpha, beta, sgamma, theta1; + double pj, qj, rj, pc, qc, rc, Assim_j, Assim_c, GPP; + double pi=3.1415927; + double diffusion_scale; + + diffusion_scale = (double)1.0; /*changed from 1.647*/ + + /*compute combined variables*/ + alpha=(double)diffusion_scale + var_list[1]/var_list[2] - var_list[0]*RH; + beta=(double)met_list[2]*(var_list[2]*(var_list[0]*RH-diffusion_scale) - 2.*var_list[1]); + sgamma=(double)pow(met_list[2],2.)*var_list[1]*var_list[2]; + theta1=(double)var_list[2]*var_list[0]*RH - var_list[1]; + + /*compute coefficients for cubic (wj)*/ + pj=(double)(ej*beta + bj*theta1 - aj*alpha + ej*alpha*Rd) * (1/(ej*alpha)); + qj=(double)(ej*sgamma + (bj*sgamma)/met_list[2] - aj*beta + aj*dj*theta1 + ej*Rd*beta + Rd*bj*theta1) * (1./(ej*alpha)); + rj=(double)(-aj*sgamma + (aj*dj*sgamma)/met_list[2] + ej*Rd*sgamma + (Rd*bj*sgamma)/met_list[2]) * (1./(ej*alpha)); + + /*compute coefficients for cubic (wc)*/ + pc=(double)(ec*beta + bc*theta1 - ac*alpha + ec*alpha*Rd) * (1/(ec*alpha)); + qc=(double)(ec*sgamma + (bc*sgamma)/met_list[2] - ac*beta + ac*dc*theta1 + ec*Rd*beta + Rd*bc*theta1) * (1./(ec*alpha)); + rc=(double)(-ac*sgamma + (ac*dc*sgamma)/met_list[2] + ec*Rd*sgamma + (Rd*bc*sgamma)/met_list[2]) * (1./(ec*alpha)); + + /*compute assimilation rates for wj and wc separately, according to analytical solution*/ + /* Update 04.07.2020 by G. Quetin to calculate multiple roots and switch */ + + /* Root 1*/ + if (ROOT_CALC == 1){ + Assim_j=(double)-2.*pow((pow(pj,2.)-3.*qj)/9.,0.5) * cos( (acos((2.*pow(pj,3.) - 9.*pj*qj + 27.*rj)/(2.*pow((pow(pj,2.) - 3.*qj),1.5))) + 4.*pi) /3. ) - pj/3.; + Assim_c=(double)-2.*pow((pow(pc,2.)-3.*qc)/9.,0.5) * cos( (acos((2.*pow(pc,3.) - 9.*pc*qc + 27.*rc)/(2.*pow((pow(pc,2.) - 3.*qc),1.5))) + 4.*pi) /3. ) - pc/3.; + + /* pick the smaller A to be GPP */ + /* GPP UNITS ARE umol m^-2 s^-1 */ + GPP = (Assim_j<=Assim_c) ? Assim_j : Assim_c; + } + + + if (ROOT_CALC == 2){ + Assim_j=(double)-2.*pow((pow(pj,2.)-3.*qj)/9.,0.5) * cos( (acos((2.*pow(pj,3.) - 9.*pj*qj + 27.*rj)/(2.*pow((pow(pj,2.) - 3.*qj),1.5))) + 2.*pi) /3. ) - pj/3.; + Assim_c=(double)-2.*pow((pow(pc,2.)-3.*qc)/9.,0.5) * cos( (acos((2.*pow(pc,3.) - 9.*pc*qc + 27.*rc)/(2.*pow((pow(pc,2.) - 3.*qc),1.5))) + 2.*pi) /3. ) - pc/3.; + + /* pick the smaller A to be GPP */ + /* GPP UNITS ARE umol m^-2 s^-1 */ + GPP = (Assim_j<=Assim_c) ? Assim_j : Assim_c; + } + + + if (ROOT_CALC == 3){ + Assim_j=(double)-2.*pow((pow(pj,2.)-3.*qj)/9.,0.5) * cos( (acos((2.*pow(pj,3.) - 9.*pj*qj + 27.*rj)/(2.*pow((pow(pj,2.) - 3.*qj),1.5))) + 0.*pi) /3. ) - pj/3.; + Assim_c=(double)-2.*pow((pow(pc,2.)-3.*qc)/9.,0.5) * cos( (acos((2.*pow(pc,3.) - 9.*pc*qc + 27.*rc)/(2.*pow((pow(pc,2.) - 3.*qc),1.5))) + 0.*pi) /3. ) - pc/3.; + + /* pick the smaller A to be GPP */ + /* GPP UNITS ARE umol m^-2 s^-1 */ + GPP = (Assim_j<=Assim_c) ? Assim_j : Assim_c; + } + + + return GPP; + + } + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/DALEC_EDCS_OLD.c === + + +/*This function contains to model-specific structure*/ +/*starting with constant terms showing up across scripts*/ +/*unclear where this should be declared, but "pragma once" solves problem for now*/ + +/*EDCdiagnostic structure*/ +/*While this structure type is declared as part of the "DALEC" structure, should include here*/ +struct EDCDIAGNOSTIC{ +int EDC; +double pEDC; +int DIAG; +/*allocating space for 100 checks (in case future additions are made, etc.).*/ +int PASSFAIL[100]; +/*SWITCH determines which EDCs are tested*/ +/*SWITCH values are read from DATA.otherpriors*/ +/*SWITCH values that are not 1 (e.g. -9999) are assumed to be zero*/ +int SWITCH[100]; +/*EDCPROB: this term is a 0 - 1 assessment (currently qualitative) to determine +the viability of individual EDCs*/ +double EDCPROB[100]; +/*nedc is the number of EDCs to be tested*/ +int nedc; +/*Temporary value - EQF - steady state proximity factor*/ +/*Currently stored in OTHERPRIORUNC (39:42)*/ +double EQF;}; + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/INITIALIZE_INTERNAL_SOIL_ENERGY.c === + +#pragma once +#include "SOIL_TEMP_AND_LIQUID_FRAC.c" + + +//Main function +double INITIALIZE_INTERNAL_SOIL_ENERGY(double internal_energy_per_mm_H2O, double H2O_mm, double dry_soil_vol_heat_capacity, double depth ){ + +// +// double internal_energy_per_mm_h2o; +// double soil_water;//mm (or kg/m2) +// double dry_soil_vol_heat_capacity;//J/m3/K +// double depth;//m +// + + + SOIL_TEMP_AND_LIQUID_FRAC_STRUCT LY_H2O_TEMP; + //1mm, no soil + LY_H2O_TEMP.IN.dry_soil_vol_heat_capacity =0 ;//J/m3/K + LY_H2O_TEMP.IN.depth = 0;//m + LY_H2O_TEMP.IN.soil_water = 1;//mm (or kg/m2) + LY_H2O_TEMP.IN.internal_energy = internal_energy_per_mm_H2O;//Joules + //Calculate H2O temp + SOIL_TEMP_AND_LIQUID_FRAC(&LY_H2O_TEMP); + //Now calculate internal energy + //Energy in dry soil = + double SOIL_E = dry_soil_vol_heat_capacity* depth*LY_H2O_TEMP.OUT.TEMP; + //Energy in H2O = mm* E/mm; + double H2O_E = internal_energy_per_mm_H2O*H2O_mm; + //Total energy + double TOTAL_E= SOIL_E + H2O_E; +//Calculate temp based on total energy (just to check) + +// +// double TEMP=LY_H2O_TEMP.OUT.TEMP; +// LY_H2O_TEMP.IN.dry_soil_vol_heat_capacity =dry_soil_vol_heat_capacity ;//J/m3/K +// LY_H2O_TEMP.IN.depth = depth;//m +// LY_H2O_TEMP.IN.soil_water = H2O_mm;//mm (or kg/m2) +// LY_H2O_TEMP.IN.internal_energy = TOTAL_E;//Joules +// SOIL_TEMP_AND_LIQUID_FRAC(&LY_H2O_TEMP); + + + + +return TOTAL_E; + +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LAI_KNORR_funcs.c === + +#pragma once +/* Functions to support the Leaf Phenology Model of Knorr et al. (2010, doi: 10.1029/2009JG001119)*/ +// +// Minimum function with quadratic transition (smoothed) between two values. Example: +// x = (double)0.1; +// y = (double)1e-6; +// x0 = 5e-3 +// z = MinimumQuadraticSmooth(x, y, x0) +/* x = first value */ +/* y = second value */ +/* eta = degree of smoothing */ +double MinQuadraticSmooth(double const x, double const y, double const eta) +{ + double z, mins; + + z = pow(x+y,2) - 4.0 * eta * x * y; + z = fmax(z,1e-18); + mins = (x + y - sqrt(z)) / (2.0*eta); + return mins; +} + + +// Maximum function with exponential transition (smoothed) between two values. Example: +/* x = first value */ +/* y = second value */ +/* x0 = degree of smoothing */ +double MaxExponentialSmooth(double const x, double const y, double const x0) +{ + double maxx; + + if (x >= (y-x0)) { + maxx = x + x0*exp(-(x-y)/x0 - 1.0); // statements to be executed if the test expression is true + } + else { + maxx = y; // statements to be executed if the test expression is false + } + return maxx; +} + +// Day length function - hours of sunlight per day // +double ComputeDaylightHours(double const *pars) +{ + /*double mult=0,dayl=0,dec=0;*/ + double mult,dayl,dec; +/*Notes: DALEC code passes the following *pars pointers: +constant pars terms +pars[0]=latitude; +pars[1]=day of year; +pars[2]=pi; +*/ + + + /*pars= &pars; + * consts= &consts; + * */ + dec=(double)-23.4*cos((360.*(pars[1]+10.)/365.)*pars[2]/180.)*pars[2]/180.; + mult=(double)tan(pars[0]*pars[2]/180)*tan(dec); + if (mult>=1){ + dayl=24.;} + else if(mult<=-1) + dayl=0.; + else{ + dayl=(double)24.*acos(-mult) / pars[2];} + + return dayl; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/DALEC_MODULE.c === + +#pragma once +#include "ACM.c" +#include "offset.c" +#include "../DALEC_OBSERVATION_OPERATORS/DALEC_OBSERVATION_OPERATORS.c" +#include "DALEC_EDCS_OLD.c" +typedef struct { +double (*function) (DATA * , void *); + void * data; + bool prerun; +}EDCs; + + + +typedef struct DALEC_FLUX_SOURCE_SINK_MATRIX{ + int *SOURCE; + int *SINK; +}DALEC_FLUX_SOURCE_SINK_MATRIX; + + + typedef struct DALEC_STATE_SOURCE_SINK_MATRIX{ + int N_STATE_INPUT_FLUXES; + int *STATE_INPUT_FLUXES; + int N_STATE_OUTPUT_FLUXES; + int *STATE_OUTPUT_FLUXES;}DALEC_STATE_SOURCE_SINK_MATRIX; + + +typedef struct DALEC{ +int nopools; +int nopars; +int nofluxes; +int nomet; +int noedcs; +int * testvec;//Flag for deletion (isn't supposed to do anything) +struct PARS_INFO { + double * parmin; + double * parmax;} PARS_INFO; +//struct POOL_INFO; +struct PARS_META_STRUCT { + char ** NAME; + char ** ABBREVIATION; + char ** UNITS; + char ** DESCRIPTION;} PARS_META; + +struct FLUX_META_STRUCT { + char ** NAME; + char ** ABBREVIATION; + char ** UNITS; + char ** DESCRIPTION;} FLUX_META; + +struct POOLS_META_STRUCT { + char ** NAME; + char ** ABBREVIATION; + char ** UNITS; + char ** DESCRIPTION;} POOLS_META; + +/* +struct EDC_META_STRUCT { + char ** NAME; + char ** ABBREVIATION; + char ** UNITS; + char ** DESCRIPTION;} EDC_META; + */ + +int (*dalec)(DATA,const double *); +//To become obsolete, once EDCs refactored +int (*edc1)(const double *, DATA, struct EDCDIAGNOSTIC * EDCD); +int (*edc2)(const double *, DATA, struct EDCDIAGNOSTIC * EDCD); +/*contains all the EDCD relevant info*/ +struct EDCDIAGNOSTIC * EDCD; + + DALEC_FLUX_SOURCE_SINK_MATRIX FIOMATRIX; + DALEC_STATE_SOURCE_SINK_MATRIX * SIOMATRIX; + OBSOPE OBSOPE; + EDCs * EDCs;//Pointer, as each element is a unique EDC + void * MODEL_DATA; +} DALEC; + +#include "../DALEC_EDCs/DALEC_EDC_FUNCTIONS.c" +#include "DALEC_STATE_SOURCE_SINK_MATRIX_CONFIG.c" + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/expdecay2.c === + +#pragma once + + +/*Component of expdecay (next function)*/ +double expdecay2(double const *POOLS, int pool, int nodays,int deltat,int nopools) +/*only accepting pool and number of days, the rest done here*/ +{ +/*using 365 day averaging window for each year!*/ + +/*explicitly calculating number of years*/ +int noyears=floor(nodays*deltat/365); +int EDC=1,n,count,y; + +/*yearly means and yearly means with offset Ds = 100 days*/ +double P0=POOLS[pool]; +/*Deriving exponential decay coefficients a,b and c in equation + * Cexp = a + b*exp(c*t)*/ +/*four mean pool values to be derived*/ +/* MP0 = mean pool (year 1 to year end-2) + * MP1 = mean pool (year 2 to year end-1) + * MP0os = mean pool (year 1+os to year end-2+os) + * MP1os = mean pool (year 1+os to year end-2+os)*/ +double MP0=0,MP1=0,MP0os=0,MP1os=0; +/*averaging window*/ +int aw=floor(365./(double)deltat); +/*offset in days*/ +/*OFFSET = 1 is ideal to capture rapid exponential decay without compromising quality of fit*/ +int os=1; +/*deriving coefficients to * + * in Cexp = A + B exp(C*t);*/ +double A,B,b,C; + +/*mean pool within each averaging window*/ +for (n=0;nabs(A)*0.01){EDC=0;}*/ +return C;} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/CH4_MODULES/HET_RESP_RATES_JCR.c === + +#pragma once +/* This join-co2-ch4 respiration model, originally described in +Ma et al 2021 in prep +*/ + +//ch4pars[7]={pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.q10rhco2],meantemp}; + +//in the brackets are input fed from main module, use pointer to a double if output is an array + + + + +typedef struct{ + + struct { + double TEMP;//Input in K + double SM;//Soil moisture, 0-1 + double LF;//0-1 + double S_FV; + double SM_OPT; + double FWC; + double R_CH4; + double Q10CH4; + double Q10CO2; + }IN; + + struct { + double aerobic_tr;//Aerobic turnover rate scalar + double anaerobic_tr;//Anaerobic turnover rate scalar + double anaerobic_co2_c_ratio;//CO2_C_ratio + double anaerobic_ch4_c_ratio;//CH4_C_ratio + double fT; + double fV; + double fW; + }OUT; + +} HET_RESP_RATES_JCR_STRUCT; + + + + +int HET_RESP_RATES_JCR(HET_RESP_RATES_JCR_STRUCT * S) +{ + /* input array already defined above, + define names for ch4pars elements to be convenient in the JCR module*/ + //double PAW_fs,S_fv,thetas_opt,fwc,r_ch4,Q10ch4,Q10rhco2,meantemp; /*jc*/ + double reftemp= 298.15;//25+DGCM_TK0C; + // output array and corresponding elements + static double jcr_o[4]; + // + double fT,fV,fW,fCH4; /*jc*/ + // the rest in JCR + double fW1,fW2,fT_ch4,theta_ae; +//double ch4pars[7]={pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.Q10rhco2],meantemp}; + + //Soil moisture + double thetas=S->IN.SM; + /*-----------------------------------------------------------------------*/ + /*jc get env. scalers ready*/ + /*tunable scaler describing the shape of the curve: PAW/PAW_fs against fractional volume of aerobic respiratio*/ + double S_fv=S->IN.S_FV; + /*optimum water scaler (fW), where the maximum respiration is achieved without limitation from water + it is the highest point in the function of PAW/PAW_fs against water scaler (fW)*/ + double thetas_opt=S->IN.SM_OPT; + /*the lowest point of water scaler when the soil is fully saturated, + in the function of PAW/PAW_fs against water scaler (fW)*/ + double fwc=S->IN.FWC; + /*potential ratio of CO2 converted to CH4*/ + double r_ch4=S->IN.R_CH4; + /*Q10 of methane production*/ + double Q10ch4=S->IN.Q10CH4; + double Q10rhco2=S->IN.Q10CO2; + /* fT Temperature factor on respiration */ + // fT = fmin(1,exp(pars[9]*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-meantemp))); + //arrhenius method + //fT = exp(pars[9]*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-meantemp)); + //Q10 method + fT = pow(Q10rhco2,(S->IN.TEMP-reftemp)/10)*S->IN.LF; + jcr_o[0] = fT; + //fT = pow(pars[9],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-meantemp)/10); + /* fV Volumetric factor seperating aerobic and anaerobic respiration */ + /* statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs) */ + fV = fmax(0,(1-pow(thetas,S_fv))); + jcr_o[1] = fV; + /* fW soil moisture scaler is a function of theta_ae*/ + theta_ae = ((thetas-1)/fV +1); + fW1 = 1/thetas_opt*theta_ae; + fW2 = ((1-fwc)/(thetas_opt-1)*theta_ae + (fwc-(1-fwc)/(thetas_opt-1))); + if (theta_ae>=0 && theta_ae < thetas_opt){ + fW = fW1;} + else if(theta_ae>=thetas_opt && theta_ae<=1){ + fW = fW2;} + else{ + fW = 0;} + jcr_o[2] = fW; + /* fCH4*/ + // fT_ch4 = exp(Q10ch4*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-meantemp)); + fT_ch4 = pow(Q10ch4,(S->IN.TEMP-reftemp)/10)*S->IN.LF; + fCH4 = fmin(r_ch4 * fT_ch4,1); + // fCH4 = r_ch4 * fT_ch4; + /* fmin() won't be needed once CH4 data is assimilated, as CH4 portion of CO2 should be very small, + manually put the upper limit 1 here mainly based on the mass balance, but notice that DIC is not + considered to contribute when the current timestep Rh is depeleted by CH4. I think it's good for + now. Can think about DIC pool meanwhile */ + jcr_o[3] = fCH4; +/*-------------------------------OUTPUTS----------------------------------------*/ + +S->OUT.aerobic_tr=jcr_o[2]*jcr_o[0]*jcr_o[1]; +S->OUT.anaerobic_tr=fwc*jcr_o[0]*(1-jcr_o[1]); +S->OUT.anaerobic_ch4_c_ratio=jcr_o[3]; +S->OUT.anaerobic_co2_c_ratio=(1-jcr_o[3]); +S->OUT.fT = jcr_o[0]; +S->OUT.fV = jcr_o[1]; +S->OUT.fW = jcr_o[2]; +//printf(" %2.2f %2.2f %2.2f %2.2f\n",S->OUT.fT,S->OUT.fV,S->OUT.fW,S->IN.LF ); + + + + +return 0; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/CH4_MODULES/JCR.c === + +#pragma once +/* This join-co2-ch4 respiration model, originally described in +Ma et al 2021 in prep +*/ + +//ch4pars[7]={pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.q10rhco2],meantemp}; + +//in the brackets are input fed from main module, use pointer to a double if output is an array + + + + + + + +double *JCR(double const *ch4pars, double T2M_MIN, double T2M_MAX, double thetas) +{ + /* input array already defined above, + define names for ch4pars elements to be convenient in the JCR module*/ + double PAW_fs,S_fv,thetas_opt,fwc,r_ch4,Q10ch4,Q10rhco2,meantemp; /*jc*/ + // output array and corresponding elements + static double jcr_o[4]; + double fT,fV,fW,fCH4; /*jc*/ + // the rest in JCR + double fW1,fW2,fT_ch4,theta_ae; + + /*-----------------------------------------------------------------------*/ + /*jc get env. scalers ready*/ + /*tunable scaler describing the shape of the curve: PAW/PAW_fs against fractional volume of aerobic respiratio*/ + S_fv=ch4pars[0]; + /*optimum water scaler (fW), where the maximum respiration is achieved without limitation from water + it is the highest point in the function of PAW/PAW_fs against water scaler (fW)*/ + thetas_opt=ch4pars[1]; + /*the lowest point of water scaler when the soil is fully saturated, + in the function of PAW/PAW_fs against water scaler (fW)*/ + fwc=ch4pars[2]; + /*potential ratio of CO2 converted to CH4*/ + r_ch4=ch4pars[3]; + /*Q10 of methane production*/ + Q10ch4=ch4pars[4]; + Q10rhco2=ch4pars[5]; + meantemp=ch4pars[6]; + /* fT Temperature factor on respiration */ + // fT = fmin(1,exp(pars[9]*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-meantemp))); + //arrhenius method + //fT = exp(pars[9]*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-meantemp)); + //Q10 method + fT = pow(Q10rhco2,(0.5*(T2M_MIN+T2M_MAX)-meantemp)/10); + jcr_o[0] = fT; + //fT = pow(pars[9],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-meantemp)/10); + /* fV Volumetric factor seperating aerobic and anaerobic respiration */ + /* statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs) */ + fV = fmax(0,(1-pow(thetas,S_fv))); + jcr_o[1] = fV; + /* fW soil moisture scaler is a function of theta_ae*/ + theta_ae = ((thetas-1)/fV +1); + fW1 = 1/thetas_opt*theta_ae; + fW2 = ((1-fwc)/(thetas_opt-1)*theta_ae + (fwc-(1-fwc)/(thetas_opt-1))); + if (theta_ae>=0 && theta_ae < thetas_opt){ + fW = fW1;} + else if(theta_ae>=thetas_opt && theta_ae<=1){ + fW = fW2;} + else{ + fW = 0;} + jcr_o[2] = fW; + /* fCH4*/ + // fT_ch4 = exp(Q10ch4*(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-meantemp)); + fT_ch4 = pow(Q10ch4,(0.5*(T2M_MIN+T2M_MAX)-meantemp)/10); + fCH4 = fmin(r_ch4 * fT_ch4,1); + // fCH4 = r_ch4 * fT_ch4; + /* fmin() won't be needed once CH4 data is assimilated, as CH4 portion of CO2 should be very small, + manually put the upper limit 1 here mainly based on the mass balance, but notice that DIC is not + considered to contribute when the current timestep Rh is depeleted by CH4. I think it's good for + now. Can think about DIC pool meanwhile */ + jcr_o[3] = fCH4; +/*-----------------------------------------------------------------------*/ + + +return jcr_o; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/LAI_KNORR.c === + +#pragma once +#include "./LAI_KNORR_funcs.c" +/* Leaf Phenology Model of Knorr et al. (2010, doi: 10.1029/2009JG001119)*/ +double* LAI_KNORR(double const *met_list, double const *var_list) +{ +/*Notes: DALEC code passes the following *consts and *pars pointers: + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +constants terms: +consts[0] = T_Phi = 12.5 # parameter: temperature at leaf onset (degrees C) +consts[1] = T_r = 2.0 # parameter: spatial range (1 sigma) of T_Phi (degrees C) +consts[2] = t_c = 10.0 # parameter: day length at leaf shedding (hours) +consts[3] = t_r = 0.5 # parameter: spatial range (1 sigma) of t_c (hours) +consts[4] = xi = 0.5 # parameter: initial linear leaf growth (1/days) +consts[5] = k_L = 0.1 # parameter: inverse of leaf longevity from start of senscence (1/days) +consts[6] = lambda_max = 6.0. # parameter: maximum potential leaf area index (m2/m2) +*/ + + /*initialize intermediate variables*/ + double daylengthpars[3]; + double daylength; + double n, deltat; + double meantemp; + double t_c, t_r, f_d, td_deviation; + double T_init, T_phi, T_r; + double T, T_memory, T_deviation, f_T, tau_m; + double plgr, k_L; + double f, r; + double pasm, ET; + double lambda, lambda_W, lambda_tilde_max, lambda_max; + double dlambdadt, lambda_lim, laim, lambda_max_memory; + double tau_W, tau_s; + double lambda_next, lambda_input, lambda_output; + + if (met_list[0] < 100.0) { + // assume temperature forcing at time t is in degrees C, then convert to degrees K + meantemp=(double)met_list[0]+273.15; + } + else { + // assume temperature forcing at time t is in degrees K + meantemp=(double)met_list[0]; + } + n=1.0; /*(double)var_list[0];*/ + deltat=(double)var_list[19]; + lambda=(double)var_list[2]; + T_init=(double)0.0; + T_phi=(double)var_list[3]; // degrees K + T_r=(double)var_list[4]; // degrees K + T_memory=(double)var_list[5]; // degrees K + tau_m=(double)30.0; // Averaging period for temperature growth trigger T (units of days; must be in same units as deltat), usually kept constant but could potentially be a tuneable parameter + plgr=(double)var_list[7]; + k_L=(double)var_list[8]; + pasm=(double)var_list[17]; + ET=(double)var_list[18]; + lambda_max=(double)var_list[9]; + tau_W=(double)var_list[10]; + lambda_max_memory=(double)var_list[11]; //TIME-DEPENDENT I.E. SAVE IN MEMORY + tau_s=(double)30.0; // Averaging period for water/structural memory (units of days; must be in same units as deltat), usually kept constant but could potentially be a tuneable parameter + t_c=(double)var_list[15]; + t_r=(double)var_list[16]; + + /* Initialization: only run this on the first time step! */ + if (n==0) { + lambda_max_memory=lambda_max; + laim=lambda_max_memory; + } + // if (n==0){printf("> in LAI_KNORR: T_memory = %2.1f\n",T_memory);} + // if (n==0){T_memory=T_phi+3*T_r;} /* set the temperature memory to be high so that we start in growth phase */ + // Exponentially declining memory of temperature + T = exp(- deltat / tau_m)*T_memory + meantemp * (1 - exp(- deltat / tau_m)); + T_deviation=(T-T_phi)/T_r; + /* fraction of plants above temperature threshold: using cumulative normal distribution function (derived from the intrinsic c-function erfc) */ + f_T = 0.5*erfc(-T_deviation*sqrt(0.5)); + + /* compute daylight hours (hours of sunlight per day) */ + daylengthpars[0]=var_list[12]; /* latitude */ + daylengthpars[1]=var_list[13]; /* day of year */ + daylengthpars[2]=var_list[14]; /* pi */ + daylength = ComputeDaylightHours(daylengthpars); + td_deviation = (daylength-t_c)/t_r; + /* fraction of plants above daylength threshold: using cumulative normal distribution function (derived from the intrinsic c-function erfc) */ + f_d = 0.5*erfc(-td_deviation*sqrt(0.5)); + + /* fraction of plants above temperature and daylength thresholds */ + f = f_T * f_d; + /* compute current growth rate */ + r = plgr * f + (1 - f)*k_L; + + /* compute water-limited maximum LAI */ + lambda_W = (pasm * lambda) / (tau_W * MaxExponentialSmooth(ET, 1e-3, 2e-2)); + /* compute smoothed maximum LAI */ + lambda_tilde_max = MinQuadraticSmooth(lambda_max, lambda_W, 0.99); + /* update LAI water/structural memory using an exponentially declining memory of water/structural limitation over the time period tau_s */ + laim = exp(- deltat / tau_s)*lambda_max_memory + lambda_tilde_max * (1.0 - exp(- deltat / tau_s)); + + lambda_lim = MaxExponentialSmooth(plgr * laim * f / r, 1e-9, 5e-3); + + // lambda_next is the updated target LAI (units of m2/m2) + lambda_next = lambda_lim - (lambda_lim - lambda)*exp(-r*deltat); + + // dlambdadt is the change in LAI over the period deltat (units of m2/m2) + dlambdadt = lambda_next - lambda; + + lambda_input = plgr * (laim - lambda) * f; + lambda_output = lambda * k_L * (1 - f); + + + static double return_arr[8]; + return_arr[0] = lambda_next; + return_arr[1] = T; + return_arr[2] = laim; + return_arr[3] = dlambdadt; + return_arr[4] = f_T; + return_arr[5] = f_d; + return_arr[6] = lambda_input; + return_arr[7] = lambda_output; + return return_arr; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/ACM.c === + +#pragma once +/* This is the Aggregated Canopy Model (ACM), originally described in Williams et al. (1997), and coupled to DALEC models in Williams et al., (2005). Code implementation based on code and materials from Fox et al. (2009) "REFLEX" experiment, and subsequently adapted for Bloom & Williams 2015. + +Williams, M., Rastetter, E. B., Fernandes, D. N., Goulden, M. L.,Shaver, G. R., and Johnson, L. C.: Predicting gross primaryproductivity in terrestrial ecosystems, Ecol. Appl., 7, 882–894,1997. +Williams, M., Schwarz, P. A., Law, B. E., Irvine, J., andKurpius, M. R.: An improved analysis of forest carbon dynamicsusing data assimilation, Glob. Change Biol., 11, 89–105, 2005. +Fox, A., Williams, M., Richardson, A. D., Cameron, D., Gove,J. H., Quaife, T., Ricciuto, D., Re- ichstein, M., Tomelleri, E.,Trudinger, C. M., and van Wijk, M. T.: The reflex project: com-paring different algorithms and implementations for the inversionof a terrestrial ecosystem model against eddy covariance data,Agr. Forest. Meteorol., 149, 1597–1615, 2009. +Bloom, A.A. and Williams, M., 2015. Constraining ecosystem carbon dynamics in a data-limited world: integrating ecological" common sense" in a model–data fusion framework. Biogeosciences, 12(5), pp.1299-1315. + +*/ +double ACM(double const *pars, double const *consts) +{ + /*double gc=0,pp=0,qq=0,ci=0,e0=0,mult=0,dayl=0,cps=0,dec=0;*/ + double gc,pp,qq,ci,e0,mult,dayl,cps,dec,GPP; +/*Notes: DALEC code passes the following *consts and *pars pointers: + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; +constant gpppars terms +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; +*/ + + + /*pars= &pars; + * consts= &consts; + * */ + gc=(double)pow(fabs(pars[8]),consts[9])/(consts[5] * pars[9] + 0.5 * ( pars[1]- pars[2])); + pp=(double)pars[0]*pars[3]/gc*consts[0]*exp(consts[7]*pars[1]); + qq=(double)consts[2]-consts[3]; + ci=(double)0.5*(pars[4]+qq-pp+pow(pow(pars[4]+qq-pp,2)-4*(pars[4]*qq-pp*consts[2]),0.5)); + e0=(double)consts[6]*pow(pars[0],2)/(pow(pars[0],2)+consts[8]); + dec=(double)-23.4*cos((360.*(pars[5]+10.)/365.)*pars[10]/180.)*pars[10]/180.; + mult=(double)tan(pars[6]*pars[10]/180)*tan(dec); + if (mult>=1){ + dayl=24.;} + else if(mult<=-1) + dayl=0.; + else{ + dayl=(double)24.*acos(-mult) / pars[10];} + + + cps=(double)e0*pars[7]*gc*(pars[4]-ci)/(e0*pars[7]+gc*(pars[4]-ci)); + GPP=cps*(consts[1]*dayl+consts[4]); + return GPP; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/THERMAL_CONDUCTIVITY.c === + +#pragma once +//***Main function*** +typedef struct { + struct {double surf_por; + double mid_por; + double deep_por; + double soil_VWC_surf; + double soil_VWC_mid; + double soil_VWC_deep; + double LF_surf; + double LF_mid; + double LF_deep; + double soil_thermal_conductivity_surf; + double soil_thermal_conductivity_middeep;} IN; + struct {double THERMAL_COND_SURF; + double THERMAL_COND_MID; + double THERMAL_COND_DEEP;} OUT; + }Thermal_struct; + +int THERMAL_COND(Thermal_struct * S){ + +const double air_cond=0.026;//Conductivity of ar at 0C +const double water_cond=0.57;//Conductivity of water at 0C +const double ice_cond=2.22;//Conductivity of water at 0C + +S->OUT.THERMAL_COND_SURF =0; +S->OUT.THERMAL_COND_MID =0; +S->OUT.THERMAL_COND_DEEP =0; + +S->OUT.THERMAL_COND_SURF=((S->IN.surf_por-S->IN.soil_VWC_surf*S->IN.surf_por)*air_cond + // Air contribution + S->IN.surf_por*S->IN.soil_VWC_surf*S->IN.LF_surf*water_cond + // water contribution + S->IN.surf_por*S->IN.soil_VWC_surf*(1-S->IN.LF_surf)*ice_cond + // ice contribution + (1-S->IN.surf_por)*S->IN.soil_thermal_conductivity_surf); // soil contribution + +S->OUT.THERMAL_COND_MID=((S->IN.mid_por-S->IN.soil_VWC_mid*S->IN.mid_por)*air_cond + // Air contribution + S->IN.mid_por*S->IN.soil_VWC_mid*S->IN.LF_mid*water_cond + // water contribution + S->IN.mid_por*S->IN.soil_VWC_mid*(1-S->IN.LF_mid)*ice_cond + // ice contribution + (1-S->IN.mid_por)*S->IN.soil_thermal_conductivity_middeep); // soil contribution + +S->OUT.THERMAL_COND_DEEP=((S->IN.deep_por-S->IN.soil_VWC_deep*S->IN.deep_por)*air_cond + // Air contribution + S->IN.deep_por*S->IN.soil_VWC_deep*S->IN.LF_deep*water_cond + // water contribution + S->IN.deep_por*S->IN.soil_VWC_deep*(1-S->IN.LF_deep)*ice_cond + // ice contribution + (1-S->IN.deep_por)*S->IN.soil_thermal_conductivity_middeep); // soil contribution + + return 0; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/mean_flux.c === + +#pragma once + + +/*mean matrix from double pointer routine*/ +double mean_flux(double *FA,int f,int nc, int nofluxes){ +/*declarations*/ +int c; +double meanflux=0; +/*deriving mean of flux p*/ +for (c=0;c=1){ + dayl=24.;} + else if(mult<=-1) + dayl=0.001; + else{ + dayl=(double)24.*acos(-mult) / pi_here;} + + + + /*initialize intermediate variables*/ + double Oi, psfc, T, RH, tau, gamma, Kc, Ko; + double cold_inhibition, heat_inhibition, Vm; + double PAR, APAR, Vmax, Jmax, a, b, c, J1, J2, J, Rd; + double GPP, GPP_root1, GPP_root2, GPP_root3; + double aj, dj, ej, bj, ac, dc, ec, bc; + double par_frac, Wm2_umol, second_per_day, parts_ppm, gram_per_mol_C, gram_per_mol_H20,gram_per_kg, diffusionH2OtoCO2; + double tset_cold, tset_hot; + + + /* conversion constants */ + par_frac = (double)0.45; /*fraction of insolation that is PAR - Mavi & Tupper (2004)*/ + Wm2_umol = (double)4.56; /*conversion of solar radiation (W/m2) to umol/s/m2 photosynthetically active radiation*/ + second_per_day = (double)dayl*3600.; /* seconds per day length of day in hours and seconds per hour */ + parts_ppm=(double)1e6; /* parts to ppm*/ + gram_per_mol_C = (double)12.0107; /* grams per mol Carbon */ + gram_per_mol_H20 = (double)18.01528; /* grams per mol H2O */ + gram_per_kg = (double)1000.; /* grams per kilogram */ + diffusionH2OtoCO2 = (double)1.6; /* ratio of diffusion H2O to CO2 */ + + /*calculate pressure terms in parts per rather than pascal*/ + /*set up so that all values are in ppm to match Vmax, Jmax, and APAR*/ + psfc = (double)101325; /* [Pa] */ + + Oi=(double)0.209*parts_ppm; /*oxygen at surface umol/mol to match Vmax, Jmax*/ + T=(double)met_list[1];/*max temperature*/ /*replaced: (double)0.5*(met_list[1]+met_list[0]);*/ /* mean temperature */ + RH=(double)1.-met_list[4]/(6.1094*exp( (17.625*T) / (T+243.04) )); /*relative humidity, <1*/ + + tau=(double)2600.*pow(0.57,((T-25.)/10.)); + gamma=(double)Oi/(2.*tau); /*co2 compensation point in ppm, umol/mol to match Vmax, Jmax*/ + + + Kc=(double)30.*pow(2.1,((T-25.)/10.))/psfc*parts_ppm; /*michaelis constant for carboxylation in ppm, umol/mol to match Vmax, Jmax*/ + Ko=(double)30000.*pow(1.2,((T-25.)/10.))/psfc*parts_ppm; /*michaelis constant for oxidation in ppm, umol/mol to match Vmax, Jmax*/ + + /*compute temperature-adjusted carboxylation rate, apply temperature limitations to Vmax25, Jmax25*/ + tset_cold = (double)10.; /*temperature for cold limitation [C], could be optimized*/ + tset_hot = (double)40.; /*temperature for hot limitation [C], could be optimized*/ + cold_inhibition=(double)1+exp(0.25*(tset_cold-T)); + heat_inhibition=(double)1+exp(0.4*(T-tset_hot)); + Vmax=(double)var_list[4]*pow(2.1,((T-25.)/10.))/(cold_inhibition*heat_inhibition); + Jmax=(double)var_list[3]*pow(2.1,((T-25.)/10.))/(cold_inhibition*heat_inhibition); + + /*convert insolation (full shortwave from meteorology) to PAR absorbed by the canopy*/ + PAR = (double)met_list[3]*1e6/second_per_day*Wm2_umol*par_frac; /* convert insolation from MJ m^-2 d^-1 to umol m^-2 s^-1 of PAR, units for analytical setup*/ + + /* Controlled by LAI and k, k = 0.6 picked from literature, could be optimized */ + APAR = (double)PAR*(1-exp(-var_list[6]*var_list[5])); /* calculate absorbed PAR as a exponential absorption in the canopy */ + + /*solve quadratic to get J value*/ + a=(double)0.7; + b=(double)-(Jmax+0.385*APAR); + c=(double)0.385*Jmax*APAR; + J1=(double)(-b+pow((pow(b,2.)-4*a*c),0.5)) / (2*a); + J2=(double)(-b-pow((pow(b,2.)-4*a*c),0.5)) / (2*a); + J = (J1<=J2) ? J1 : J2; + + /*compute temperature-adjusted leaf respiration*/ + Rd=(double)0.015*Vmax*pow(2.4,((T-25.)/10.)) / (1.+exp((1.3*(T-55.)))); + + /*set the a,d,e,b parameters for wj*/ + aj=(double)J; + dj=(double)gamma; + ej=(double)4.5; + bj=(double)10.5*gamma; + + /*set the a,d,e,b parameters for wc*/ + ac=(double)Vmax; + dc=(double)gamma; + ec=(double)1.; + bc=(double)Kc*(1.+Oi/Ko); + + + double wj_adeb_list[] = {aj,dj,ej,bj}; + double wc_adeb_list[] = {ac,dc,ec,bc}; + + /**************************/ + /* calculate GPP in polynomial solver */ + double ROOT_CALC, GPP_leaf_now; + ROOT_CALC = 1.; /* primary root solution */ + + GPP_leaf_now = ANALYTICALSOLVER_BALDOCCHI(met_list, var_list, wc_adeb_list, wj_adeb_list, Rd, RH, ROOT_CALC); + + /**************************/ + /* check dGPP/dCa */ + + double GPP_Ca_high, dGPPdCa; + + /* For screening: calculate GPP with higher value of Ca, + 60 ppm */ + double met_list_high[] = {met_list[0],met_list[1],met_list[2]+60.,met_list[3],met_list[4]}; /* Switch in high value atmospheric CO2 */ + GPP_Ca_high = ANALYTICALSOLVER_BALDOCCHI(met_list_high, var_list, wc_adeb_list, wj_adeb_list, Rd, RH, ROOT_CALC); + + /* Response of GPP solution to CO2 */ + dGPPdCa = GPP_Ca_high - GPP_leaf_now; + + + + /***************************************/ + /* Screen for bad behavior of GPP, negative values or negative sensitivity to CO2 slope*/ + + if ((GPP_leaf_now > 0.001) & (dGPPdCa > 0.)){ + GPP = GPP_leaf_now; + /*printf("Root1: %f\n",GPP);*/ + } else { + + /* Do not allow negative values of GPP */ + GPP = (double)0.001; + + } + + /*printf("Good after GPP leaf level");*/ + + /************************************************/ + /* Calculate leaf level stomatal conductance for water */ + double Cs, gs_H20; + + /* Calculate the CO2 at the leaf surface */ + Cs=(double)met_list[2] - GPP/var_list[2]; /*Cs is in umol mol^-1*/ + + /* as a function of m, GPP, RH, and CO2 at leaf + intercept, calc stomatal conductance H20*/ + gs_H20 = (double)diffusionH2OtoCO2 * var_list[0]*GPP*RH/Cs+var_list[1]; /*gs is in mol m^-2 s^-1 of water*/ + + + /***********************************************/ + /*SCALE TO CANOPY LEVEL*/ + + double GPP_canopy, GPP_canopy_gC, lai_scaling; + + /* scaling based on big leaf theory and LAI */ + lai_scaling = (double)(1-exp(-var_list[6]*var_list[5]))/var_list[6]; /* unitless or m2/m2 */ + + /* Scale leaf level GPP to canopy level using a big leaf exponential approximation*/ + GPP_canopy=(double)GPP * lai_scaling; /* umol m^-2 s^-1 */ + + /* convert umol of GPP at canopy scale to gC/day/m2 */ + /* Note: could apply the day length here in place of seconds per day*/ + GPP_canopy_gC = (double)GPP_canopy*gram_per_mol_C*second_per_day/1e6; /*1.03775, convert from umol m^-2 s^-1 to gC m^-2 d^-1*/ + + + /***********************************************/ + /*CALCULATE Canopy level stomatal conductance for water*/ + double Gs_canopy_H20, Gs_canopy_kgH20; + + /* Canopy scaling */ + Gs_canopy_H20 = (double)gs_H20 * lai_scaling; + + /* unit conversion mol H2O to kgH2O */ + /* Note: could apply the day length here in place of seconds per day*/ + Gs_canopy_kgH20 = (double)Gs_canopy_H20*gram_per_mol_H20*second_per_day/gram_per_kg; //units of kg H2O m^-2 day^-1 + + /* Calculate canopy evapotranspiration */ + + double ET_canopy_kgH20, psfc_hpa; + psfc_hpa = psfc/100.; /* surface pressure in hPa to match VPD units */ + + ET_canopy_kgH20 = (double)(met_list[4]/psfc_hpa)*Gs_canopy_kgH20; + + + /***********************************************/ + /*RETURN AN ARRAY*/ + + + + //iWUE=(double)GPP_scaled/(Gs_canopy*18.01528*86400./1000.); /*iWUE is in gC / kgH2O + + static double return_arr[2]; /*need static variable to be able to return array?*/ + return_arr[0] = GPP_canopy_gC; + //return_arr[1]=iWUE; + return_arr[1] = ET_canopy_kgH20; + + return return_arr; +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS.c === + +#pragma once +double INTERNAL_ENERGY_PER_LIQUID_H2O_UNIT_MASS(double TEMP){ + //Internal energy per mm (or kg) H2O + //Temp is in kelvin + //Assumes liquid fraction is = 1 + + + double U= DGCM_SPECIFIC_HEAT_WATER* (TEMP - DGCM_T_LIQUID_H2O_ZERO_ENERGY); + + + return U; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/SOIL_TEMP_AND_LIQUID_FRAC.c === + +#pragma once +//***IN-OUT form structure*** +typedef struct { +struct{ + double dry_soil_vol_heat_capacity;//J/m3/K + double depth;//m + double soil_water;//mm (or kg/m2) + double internal_energy;} IN;//Joules + struct { + double TEMP;// Temperature in K + double LF;} OUT;// Liquid fraction +}SOIL_TEMP_AND_LIQUID_FRAC_STRUCT; + +//***Main function*** +int SOIL_TEMP_AND_LIQUID_FRAC(SOIL_TEMP_AND_LIQUID_FRAC_STRUCT * S){ + +double dry_soil_sh=S->IN.dry_soil_vol_heat_capacity * S->IN.depth; +double UI3 = ( dry_soil_sh + S->IN.soil_water *DGCM_SPECIFIC_HEAT_ICE)*DGCM_T3 ; +double UL3 = UI3 + S->IN.soil_water*DGCM_LATENT_HEAT_FUSION_3; + +if (S->IN.internal_energyOUT.TEMP = (S->IN.internal_energy/UI3)*DGCM_T3 ;S->OUT.LF = 0;} +else if (S->IN.internal_energy>UL3){ + S->OUT.TEMP = (S->IN.internal_energy + S->IN.soil_water*DGCM_SPECIFIC_HEAT_WATER*DGCM_T_LIQUID_H2O_ZERO_ENERGY)/(dry_soil_sh + S->IN.soil_water*DGCM_SPECIFIC_HEAT_WATER) ; + S->OUT.LF = 1;} +else { + S->OUT.TEMP = DGCM_TK0C; + S->OUT.LF =(S->IN.internal_energy - UI3) /(S->IN.soil_water*DGCM_LATENT_HEAT_FUSION_3); +} +return 0; +} + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/DALEC_STATE_SOURCE_SINK_MATRIX_CONFIG.c === + + + + +int DALEC_STATE_SOURCE_SINK_MATRIX_CONFIG(DALEC * DALEC){ + + +printf("********\n"); +printf("********\n"); +printf("****SO FAR SO GOOD DALEC_STATE_SOURCE_SINK_MATRIX_CONFIG start****\n"); +printf("********\n"); +printf("********\n"); +printf("DALEC->nopools = %2i\n",DALEC->nopools); + + + int nopools=DALEC->nopools; + int nofluxes=DALEC->nofluxes; + DALEC_FLUX_SOURCE_SINK_MATRIX FIOMATRIX=DALEC->FIOMATRIX; + int f,s; + + +//static EDCs * EDCs;EDCs=calloc(DALECmodel->noedcs,sizeof( * EDCs)); + + DALEC_STATE_SOURCE_SINK_MATRIX * SIOMATRIX; + + + +SIOMATRIX=calloc(nopools,sizeof(DALEC_STATE_SOURCE_SINK_MATRIX)); + + + + + + for (s=0;sSIOMATRIX= SIOMATRIX; + //Step 3. + + + + return 0; + +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/INFILTRATION.c === + +#pragma once +double infiltration_imax(double P, double IMAX){ + + + + +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c === + +#pragma once +#include "math.h" +#include "./CONVERTERS/HYDROFUN_PSI2LIQ.c" +#include "./CONVERTERS/HYDROFUN_MOI2PSI.c" + + +/* +Calculate drainage for soil layer +Inputs: +sm - soil moisture (m3/m3) +Qexcess - Excess runoff factor +psi_field - field capacity potential (MPa) +psi_porosity - porosity potential (MPa) +b - retention parameter +lf - liquid fraction of H2O content +*/ + +double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity, double b, double lf, double soil_temp){ + + // 1. check for excessive soil moisture: drain out sm>1 so that all sm values are <=1, and won't break psi_eff. + // (note that sm>1 only occurs transiently in between time steps and must be in a liquid/drainable state) + double excess_drainage = 0.0; + if (sm > 1.0) { + excess_drainage = sm - 1.0; + sm = 1.0;} + + // 2. Calculate current effective potential of the liquid-saturated state + double psi_eff = HYDROFUN_MOI2PSI(sm, psi_porosity, b, lf, soil_temp); + + // 3. Check for excessive soil moisture: + if (psi_eff <= psi_field) { + return excess_drainage; // Soil is at or drier than field capacity; only excess drainage can leave. + } + + // 4. Calculate drainable liquid volume: + // Calculate effective porosity (fraction of pore space that is ice-free) + double ice_sat_tv = sm * (1.0 - lf); + double effective_porosity = 1.0 - ice_sat_tv; + // Current effective liquid saturation + double sm_eff = HYDROFUN_PSI2LIQ(psi_eff, psi_porosity, b); + // liquid saturation at field capacity + double sm_field = HYDROFUN_PSI2LIQ(psi_field, psi_porosity, b); + + // drainable water in units of effective saturation (zero if soil liquid is less than field capacity) + double delta_sm = fmax(sm_eff - sm_field,0.0); + // drainable water as volume + double delta_sm_liq = delta_sm * effective_porosity; + + //Matlab line Massoud et al. D= frac_Qexcess * (1- (PARS.psiporosity-min(max(STATES.PSI(t,:),PARS.psifield),PARS.psiporosity))./(PARS.psiporosity-PARS.psifield)).*(SMdelta); +// calculate drainage (equals zero if change in soil moisture is zero) +double drainage = excess_drainage + delta_sm_liq * Qexcess * (1.0 - (psi_porosity - fmin(fmax(psi_eff,psi_field),psi_porosity))/(psi_porosity-psi_field)); + +return drainage; + +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/hydrofun_moi2con.c === + +double hydrofun_moi2con(double sm,double k0, double b){ + + +//m3/m3 to m/s +double moi2con=pow(k0*sm,2*b+3); + + +return moi2con; +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c === + +#pragma once +#include + +/* +Convert volumetric soil moisture (m3/m3) to potential (MPa) +Inputs: +moi - Soil moisture (m3/m3) +psi_porosity - porosity potential (MPa) +b - retention parameter +lf - liquid fraction +*/ + +double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf, double soil_temp){ + + // Safety check to prevent divide-by-zero + if (lf<=1e-4) return -9999.0; + + // 1. Calculate effective pore volume (fraction of por volume not occupied by ice) + double ice_sat_tv= moi * (1.0 - lf); // Ice fraction of the total pore volume + double effective_porosity = 1.0 - ice_sat_tv; // ice-adjusted pore volume as fraction of total pore volume + + // 2. Calculate effective liquid saturation + double liq_sat_tv = moi * lf; // liquid water fraction of the total pore space volume + double moi_eff = liq_sat_tv / effective_porosity; // liquid water fraction of the ice-adjusted pore space + + // 3. Calculate effective psi based on capillary matric potential + double psi_capillary=psi_porosity*(pow((1.0/(moi_eff)),b)); + + // 4. Calculate cryosuction (Clapeyron equation) if frozen + double psi_cryo = 0.0; + if (lf < 1.0 && soil_temp < 273.15) { + // Latent heat of fusion = 3.34e5 J/kg. Equation yields MPa. + // As temperature drops further below 273.15, suction becomes more strongly negative + psi_cryo = (3.34e5 * (soil_temp - 273.15)) / (1000.0 * soil_temp); + } + double psi = fmin(psi_capillary, psi_cryo); + +return psi; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c === + +#pragma once + +/* +Convert volumetric soil moisture (m3/m3) to conductivity (m/s) +Inputs: +moi - Soil moisture (m3/m3) +k0 - saturated hydraulic conductivity (m/s) +b - retention parameter +lf - liquid fraction +*/ + +double HYDROFUN_MOI2CON(double moi, double k0, double b, double lf){ + +if (lf<=1e-4){ + return 0.0; +} + + // 1. Calculate effective pore volume (fraction of pore volume not occupied by ice) + double ice_sat_tv = moi * (1.0 - lf); //fraction of pore volume occupied by ice + double effective_porosity = 1.0 - ice_sat_tv; //fraction of pore volume NOT occupied by ice + + // 2. Calculate effective liquid saturation + double liq_sat_tv = moi * lf; //fraction of pore volume occupied by liquid water + double moi_eff = liq_sat_tv / effective_porosity; //fraction of occupied by liquid water + + // 3. Calculate unsaturated hydraulic conductivity based on available liquid space + double con_max = k0 * pow(moi_eff, 2.0 * b + 3.0); + double impedance = pow(10, -ice_sat_tv*6.0); // from Swenson et al., 2012 https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2012MS000165 + + double con = con_max * impedance; + +return con; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2LIQ.c === + +#pragma once +#include +/* +Convert effective water potential (MPa) to volumetric soil liquid (m3/m3) relative to pore space not occupied by ice +Inputs: +psi_eff - effective water potential (MPa) of the liquid-saturated state (i.e. corrected for ice volume) +psi_porosity - porosity potential (MPa) +b - retention parameter + +***NOTE this is mathematically the same as previous PSI2MOI; rename PSI2LIQ intended to clarify its use case in DRAINAGE.c, +the only place that it appears. +*/ + +double HYDROFUN_PSI2LIQ(double psi, double psi_porosity, double b){ + +double moi = pow(psi/psi_porosity,(-1.0/b)); + +return moi; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_PSI2MOI.c === + +#pragma once + +/* +Convert potential (MPa) to volumetric soil moisture (m3/m3) +Inputs: +psi_eff - effective water potential (MPa) of the liquid-saturated state (i.e. corrected for ice volume) +psi_porosity - porosity potential (MPa) +b - retention parameter +*/ + +double HYDROFUN_PSI2MOI(double psi, double psi_porosity, double b){ + +double moi = pow(psi/psi_porosity,(-1.0/b)); + +return moi; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c === + +#pragma once + +/* +Convert equivalent water thickness (mm or kg/m2) to volumetric soil moisture (m3/m3) +Inputs: +ewt - equivalent water thickness (mm) +p - layer porosity (1) +z - layer thickness (m) +*/ + +double HYDROFUN_EWT2MOI(double ewt, double p, double z){ + +double moi=ewt/(1000*p*z); + +return moi; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI_WITH_SALINITY.c === + +#pragma once +/* This innovation is undertaken and led by the University of Riverside team, including Holly P, Medha Yasa, Anuradha Garg and Saverio Perri, +/* with participation of A. Bloom, Eren Bilir and Matthew Worden in testing steps. +/* [UCR please add any request for acknowledgment for anyone who uses this function, this would be nice until we can reference a publication or product with DOI] +/* Estimate osmotic potential as a function of soil moisture + +double HYDROFUN_MOI2PSI_WITH_SALINITY(double moi, double psi_porosity, double b, double temp, double m_NaCl, double n){ +/*depth parameter can be added and changed if necessary (calculations are currently set for 1 m of soil profile) */ +/*Inputs: +Matric Potential +moi - Soil moisture (units: m3/m3) +psi_porosity - porosity potential (units: MPa) +b - retention parameter +temp - soil water temperature (units: K) + +Osmotic potential +psi_pi - Osmotic potential (units: MPa) +temp - Soil water temperature (units: K) +v_hoff - Vant Hoff coefficient +g_const - gas constant (units: J/mol·K) +m_NaCl - mass of sodium chloride per unit area (units: g/m2) +Mm_NaCl - molar mass of sodium chloride (units: g/mol) +n - soil porosity (units: m3/m3) +*/ + +double psi=psi_porosity*(pow((1/moi),b)); +double v_hoff = 2.0; +double g_const = 8.314; +double Mm_NaCl = 58.44; +/* osmotic potential equation */ +double psi_pi_interm = -(v_hoff * g_const * temp * m_NaCl)/(Mm_NaCl * moi * n * 1000000); +double psi_pi = fmax(psi_pi_interm, -30.12); +/* setting the minimum osmotic potential so it doesn’t drop below -30.12 MPa. This value corresponds to the osmotic potential at the maximum dissolvable NaCl concentration */ +/* We divided the psi_pi formulation by 10^6 to convert osmotic potential unit from Pa to MPa */ + +/*summing two psi terms*/ +double psi_total = psi + psi_pi; + +return psi_total; +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c === + +#pragma once + +/* +Convert volumetric soil moisture (m3/m3) to equivalent water thickness (mm or kg/m2) +Inputs: +moi - volumetric soil moisture (m3/m3) +p - layer porosity (1) +z - layer thickness (m) +*/ + +double HYDROFUN_MOI2EWT(double moi, double p, double z){ + +double ewt=moi*1000*p*z; + +return ewt; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/van_genuchten.c === + +#pragma once + + +/*Van genuchten conversion*/ +double van_genuchten(double *SM, double *b) +/*SOil moisture: mm/mm (or m3/m3) + +PSI= + + + +return PSI;} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/UT_TEMP_2_ENERGY.c === + +#include +//#include "INTERNAL_ENERGY_PER_H2O_UNIT_MASS.c" +int main(){ + +//Minimnum temp +//Energy for 1m dry soil at -50C + + +//double IE=INTERNAL_ENERGY_PER_H2O_UNIT_MASS(273.15-50, 0); +//Volumetric heat capacity +double vhc=1.3e6; + +printf("1m soil, por = 0.8, SM=0, @ -50C = %2.2e",vhc*(273.15-50)); + +//Max IE for 1m soil = + + +//energy per kg h2o +double U = 4186*(273.15+50 - 56.79); + +//energy per m +printf("1m soil, por = 0.8, SM=1, @ +50C = %2.2e",0.8*1000*U + vhc*(273.15+50)); + + +printf("hello\n"); + +return 0; +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/offset.c === + + +#pragma once +/*This function is called by DALEC_FIRE.c DALEC_CDEA.c DALEC_BUCKET.c, etc.*/ + +double offset(double const L, double const w) +{ + +/*solution to t = f*exp(-t^2)*/ +/*see dalecstepfunction2*/ + +double mxc[7]={0.000023599784710, 0.000332730053021, 0.000901865258885, -0.005437736864888, -0.020836027517787, 0.126972018064287, -0.188459767342504}; + +double lf=log(L-1); +double os=mxc[0]*pow(lf,6) + mxc[1]*pow(lf,5) + mxc[2]*pow(lf,4) + mxc[3]*pow(lf,3) + mxc[4]*pow(lf,2) + mxc[5]*lf +mxc[6]; + +os=os*w; + +return os; +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/ALLOC_AND_AUTO_RESP_FLUXES.c === + +#pragma once + +typedef struct { + struct { + double deltat;//model timestep + double TEMP; //K + double C_LIVE_W;// Live C in wood only. Note that this includes heartwood C, and overall maintenance respiration reflects bulk cost of live + dead wood. + double C_LIVE_R;// Live C in other pools (other live pools, exluding NSCs themselves). + double NSC; //labile carbon pool, Clab, non-structural carbohydrates (gC) + double GPP; + double Rd; // Canopy level dark/day respiration + double mr_r; // parameter: maintenance respiration coefficient for root (gC/gC/d) - see Cannell and Thornley (2000, doi: 10.1006/anbo.1999.0996) + double mr_w; // parameter: maintenance respiration coefficient for wood (gC/gC/d) - will be smaller than mr_r from EDC. + double gr; // parameter: growth yield parameter (gC/gC) - see "growth yield" (Y_g) in Cannell and Thornley (2000, doi: 10.1006/anbo.1999.0996) + double Q10mr; // parameter: Q10 parameter for maintenance respiration (unitless) + double ALLOC_FOL_POT; // potential allocation flux to foliar pool (gC/m2/d) + double ALLOC_WOO_POT; // potential allocation flux to wood pool (gC/m2/d) + double ALLOC_ROO_POT; // potential allocation flux to root pool (gC/m2/d) + //Add any extra inputs here + } IN; + struct { + double F_LABPROD; //Labile C production + double F_LABREL_ACTUAL; //Labile C production + double AUTO_RESP_MAINTENANCE;// autotrophic maintenance respiration flux (gC/m2/d) + double AUTO_RESP_GROWTH;// autotrophic growth respiration flux (gC/m2/d) + double ALLOC_FOL_ACTUAL; // actual allocation flux to root pool (gC/m2/d) + double ALLOC_WOO_ACTUAL; // actual allocation flux to root pool (gC/m2/d) + double ALLOC_ROO_ACTUAL; // actual allocation flux to root pool (gC/m2/d) + double AUTO_RESP_TOTAL; // autotrophic respiration (gC/m2/d) + double NPP; // net primary productivity, GPP - Rauto (gC/m2/d) + double CUE; // plant carbon use efficiency, NPP/GPP (gC/m2/d) + double NONLEAF_MORTALITY_FACTOR; //Proportional removal from all three pools. + }OUT; + }ALLOC_AND_AUTO_RESP_FLUXES_STRUCT; + + + +//Main function +int ALLOC_AND_AUTO_RESP_FLUXES(ALLOC_AND_AUTO_RESP_FLUXES_STRUCT * S){ + + double fT; // temperature scaling for maintenance respiration + double F_LABREL_SUPPLY; // + double F_LABREL_DEMAND; // + double TOTAL_GROWTH_POT; // + double TOTAL_GROWTH_ACTUAL; // + double SCALE_ALLOC_FLUXES; // + + //Maintenance respiration + fT = pow(S->IN.Q10mr,(S->IN.TEMP-(25+DGCM_TK0C))/10); // reference temperature is 25 degrees C + //Autotrophic maintenance for wood and non-wood + double POTENTIAL_AUTO_RESP_MAINTENANCE = S->IN.mr_w * fT * S->IN.C_LIVE_W + S->IN.mr_r * fT * S->IN.C_LIVE_R; + +// Can be negative -- accounting for net Co2 loss in Ag - Rd -- but can't exceed NSC availability + S->OUT.F_LABPROD = S->IN.GPP - S->IN.Rd; + //- S->OUT.AUTO_RESP_MAINTENANCE; + //Calculate actual maintenance respiration, based on available NSCs + + //Full available resources + // Most land models + //We're using GPP for whole timesteo with rest of NSC + //Basically GPP + NSC available on daily basis... + //Removes Rd, which is accounted for separately + double NSC_PLUS_GPP_RATE = S->IN.NSC/S->IN.deltat + (S->IN.GPP - S->IN.Rd); +if (POTENTIAL_AUTO_RESP_MAINTENANCE==0){ + S->OUT.NONLEAF_MORTALITY_FACTOR=0; +} else { +S->OUT.NONLEAF_MORTALITY_FACTOR=1/exp(NSC_PLUS_GPP_RATE/POTENTIAL_AUTO_RESP_MAINTENANCE); //new +} +// //IF maintenance +// //Spend all NSC on maintenance +// if (POTENTIAL_AUTO_RESP_MAINTENANCE>NSC_PLUS_GPP_RATE) +// {S->OUT.AUTO_RESP_MAINTENANCE = NSC_PLUS_GPP_RATE + S->IN.Rd; +// //Basically a carbon starvation factor +// //Insufficient NSCs to maintain tissues. +// //Alternative: +// //if NSC_PLUS_GPP_RATE = 0; MORTALITY = 1; all biomass is lost. +// //if NSC_PLUS_GPP_RATE = POTENTIAL_AUTO_RESP_MAINTENANCE; MORTALITY = 0; all biomass is lost. + +// //MORTALITY_FACTOR = 1 - NSC_PLUS_GPP_RATE/POTENTIAL_AUTO_RESP_MAINTENANCE; +// //MORTALITY_FACTOR = 1 - NSC_PLUS_GPP_RATE/POTENTIAL_AUTO_RESP_MAINTENANCE; +// //Current model: if % maintenance resp not available, then lose same % of biomass. +// //Alernative model: remobilize foliar and fine root sugars (if at all possible, check literature) +// S->OUT.NONLEAF_MORTALITY_FACTOR = fmin(1 - NSC_PLUS_GPP_RATE/POTENTIAL_AUTO_RESP_MAINTENANCE,1);} + +// else + +//Spend full amount on maintenance resp + //{S->OUT.AUTO_RESP_MAINTENANCE = POTENTIAL_AUTO_RESP_MAINTENANCE + S->IN.Rd;} //new + S->OUT.AUTO_RESP_MAINTENANCE = POTENTIAL_AUTO_RESP_MAINTENANCE * ( 1 - S->OUT.NONLEAF_MORTALITY_FACTOR) ; //new + + //Calculate leftover NSCs + //Only use available NSC after maintenance resp accounted for + + + + + + S->OUT.F_LABREL_ACTUAL =0; + S->OUT.AUTO_RESP_GROWTH = 0; + S->OUT.ALLOC_FOL_ACTUAL =0; + S->OUT.ALLOC_WOO_ACTUAL =0; + S->OUT.ALLOC_ROO_ACTUAL =0; + + // if (S->OUT.NONLEAF_MORTALITY_FACTOR==0){ + + + double LEFTOVER_NSC_RATE = NSC_PLUS_GPP_RATE - S->OUT.AUTO_RESP_MAINTENANCE; // + + + //Only proceed if AUTO_RESP_MAINTENANCE>=NSC + // + //NEW_PSEUDOCODE + + //Potential supply of labile carbon for plant growth + F_LABREL_SUPPLY = fmax(0, S->IN.gr * (LEFTOVER_NSC_RATE)); + + //NEW PSEUDOCODE: F_LABREL_SUPPLY = fmax(0, (1 - S->IN.gr) * (LEFTOVER_NSC/ S->IN.deltat)); + + //Potential demand of labile carbon by plant growth + TOTAL_GROWTH_POT = S->IN.ALLOC_FOL_POT + S->IN.ALLOC_WOO_POT + S->IN.ALLOC_ROO_POT; + F_LABREL_DEMAND = fmax(0, TOTAL_GROWTH_POT); + + // Compute exponential growth factor representing amount of growth resources mobilizable + double GF=0; + if (F_LABREL_DEMAND!=0){ + GF = 1/exp(F_LABREL_SUPPLY/F_LABREL_DEMAND); + } + //Actual release of labile carbon (before growth respiration costs subtracted) + //S->OUT.F_LABREL_ACTUAL = fmin(F_LABREL_SUPPLY, F_LABREL_DEMAND); + S->OUT.F_LABREL_ACTUAL = F_LABREL_DEMAND * (1 -GF); + + + //Scaling factor for allocation fluxes, accounts for NSC limitation and growth respiration cost + // - if actual growth is smaller than potential growth, we down-scale plant allocation fluxes + //SCALE_ALLOC_FLUXES = fmin(1, S->OUT.F_LABREL_ACTUAL / TOTAL_GROWTH_POT);//rid + S->OUT.ALLOC_FOL_ACTUAL = S->IN.ALLOC_FOL_POT * (1 - GF); + S->OUT.ALLOC_WOO_ACTUAL = S->IN.ALLOC_WOO_POT * (1 - GF); + S->OUT.ALLOC_ROO_ACTUAL = S->IN.ALLOC_ROO_POT * (1 - GF); + + //Actual release of labile carbon i.e. growth flux (after subtracting growth respiration costs) + //TOTAL_GROWTH_ACTUAL = TOTAL_GROWTH_POT * SCALE_ALLOC_FLUXES; + TOTAL_GROWTH_ACTUAL = S->OUT.ALLOC_FOL_ACTUAL + S->OUT.ALLOC_WOO_ACTUAL + S->OUT.ALLOC_ROO_ACTUAL; + //Growth respiration + S->OUT.AUTO_RESP_GROWTH = (1-S->IN.gr)/S->IN.gr * TOTAL_GROWTH_ACTUAL; + + + //Diagnostic variables + S->OUT.AUTO_RESP_TOTAL = S->OUT.AUTO_RESP_MAINTENANCE + S->OUT.AUTO_RESP_GROWTH; + S->OUT.NPP = S->IN.GPP - S->OUT.AUTO_RESP_TOTAL; + S->OUT.CUE = S->OUT.NPP/S->IN.GPP; + + + +return 0; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1103/PARS_INFO_1103.c === + +#pragma once +#include "DALEC_1103.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1103(DATA *CARDADATA) +{ + + +struct DALEC_1103_PARAMETERS P=DALEC_1103_PARAMETERS; + +/*Litter decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*CWD decomposition rate*/ +CARDADATA->parmin[P.tr_cwd2som]=0.00001; +CARDADATA->parmax[P.tr_cwd2som]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR CWD*/ +CARDADATA->parmin[P.t_cwd]=0.00005; +CARDADATA->parmax[P.t_cwd]=0.005; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*\Q10 = 1.2-2.0*/ +CARDADATA->parmin[P.Q10rhco2]=1.2; +CARDADATA->parmax[P.Q10rhco2]=2.0; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C CWD*/ +CARDADATA->parmin[P.i_cwd]=1.0; +CARDADATA->parmax[P.i_cwd]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*Retention parameter (b)*/ +CARDADATA->parmin[P.retention]=1.5; +CARDADATA->parmax[P.retention]=10; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +CARDADATA->parmin[P.hydr_cond]=0.0000001; +CARDADATA->parmax[P.hydr_cond]=0.00001; + +/*Maximum infiltration (mm/day)*/ +CARDADATA->parmin[P.max_infil]=1; +CARDADATA->parmax[P.max_infil]=100; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*PAW porosity*/ +CARDADATA->parmin[P.PAW_por]=0.2; +CARDADATA->parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +CARDADATA->parmin[P.PUW_por]=0.2; +CARDADATA->parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +CARDADATA->parmin[P.field_cap]=0.01; +CARDADATA->parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +CARDADATA->parmin[P.PAW_z]=0.01; +CARDADATA->parmax[P.PAW_z]=100; + +/*PUW depth (m)*/ +CARDADATA->parmin[P.PUW_z]=0.01; +CARDADATA->parmax[P.PUW_z]=100; + +/*Runoff excess*/ +CARDADATA->parmin[P.Q_excess]=0.01; +CARDADATA->parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +CARDADATA->parmin[P.Med_g1]=1.79; +CARDADATA->parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +CARDADATA->parmin[P.Vcmax25]=1e-8; +CARDADATA->parmax[P.Vcmax25]=140; + +/*Tminmin scaling factor*/ +CARDADATA->parmin[P.Tminmin]=258.15; +CARDADATA->parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +CARDADATA->parmin[P.Tminmax]=273.15; +CARDADATA->parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance*/ +CARDADATA->parmin[P.ga]=0.01; +CARDADATA->parmax[P.ga]=10.0; + +/*Tupp*/ +CARDADATA->parmin[P.Tupp]=299.15; +CARDADATA->parmax[P.Tupp]=318.15; + +/*Tdown*/ +CARDADATA->parmin[P.Tdown]=263.15; +CARDADATA->parmax[P.Tdown]=286.15; + +/*C3_frac*/ +CARDADATA->parmin[P.C3_frac]=1e-8; +CARDADATA->parmax[P.C3_frac]=1.0; + +/*Clumping index*/ +CARDADATA->parmin[P.clumping]=0.35; +CARDADATA->parmax[P.clumping]=1.0; + +/*Leaf single scattering albedo*/ +CARDADATA->parmin[P.leaf_refl]=1e-8; +CARDADATA->parmax[P.leaf_refl]=1.0; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +CARDADATA->parmin[P.i_SWE]=0.000001; +CARDADATA->parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +CARDADATA->parmin[P.min_melt]=240; +CARDADATA->parmax[P.min_melt]=270; + +/*sn2: slope*/ +CARDADATA->parmin[P.melt_slope]=0.00001; +CARDADATA->parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar*/ +CARDADATA->parmin[P.scf_scalar]=0.001; +CARDADATA->parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +/*jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +CARDADATA->parmin[P.S_fv]=1; +CARDADATA->parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +CARDADATA->parmin[P.thetas_opt]=0.2; +CARDADATA->parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +CARDADATA->parmin[P.fwc]=0.01; +CARDADATA->parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +CARDADATA->parmin[P.r_ch4]=0.001; +CARDADATA->parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +CARDADATA->parmin[P.Q10ch4]=1.0; +CARDADATA->parmax[P.Q10ch4]=3.0; + +/* maxPevap in mm/day*/ +CARDADATA->parmin[P.maxPevap]=0.01; +CARDADATA->parmax[P.maxPevap]=20; + +/*Reference VPD */ +CARDADATA->parmin[P.vpd_ref]=10; +CARDADATA->parmax[P.vpd_ref]=10000; + +/*VPD curvature exponent */ +CARDADATA->parmin[P.vpd_exp]=0.001; +CARDADATA->parmax[P.vpd_exp]=1000; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1103/MODEL_INFO_1103.c === + +#pragma once +#include "PARS_INFO_1103.c" +#include "DALEC_1103.c" +#include "EDC1_1103.c" +#include "EDC2_1103.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1103(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1103_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1103; +DALECmodel.edc1=EDC1_1103; +DALECmodel.edc2=EDC2_1103; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1103(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_DEDC; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1103/EDC1_1103.c === + +#pragma once +int EDC1_1103(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1103_PARAMETERS P=DALEC_1103_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1103/DALEC_1103.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../../../DALEC_CODE/DALEC_ALL/LIU_An_et.c" +#include "../../../DALEC_CODE/DALEC_ALL/CH4_MODULES/JCR.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + + +struct DALEC_1103_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int tr_cwd2som; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_cwd; +int t_soil; +int Q10rhco2; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_cwd; +int i_lit; +int i_soil; +int retention; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int hydr_cond; +int max_infil; +int i_PUW; +int PAW_por; +int PUW_por; +int field_cap; +int PAW_z; +int PUW_z; +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int C3_frac; +int clumping; +int leaf_refl; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +int S_fv; +int thetas_opt; +int fwc; +int r_ch4; +int Q10ch4; +int maxPevap; +int vpd_ref; +int vpd_exp; +} DALEC_1103_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64 +}; + +struct DALEC_1103_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2cwd; /*Wood decomposition*/ +int root2lit; /*Root decomposition*/ +int resp_het_cwd; /*Coarse woody debris heterotrophic respiration*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int q_surf; /*Surface runoff*/ +int transp; /*Transpiration*/ +int evap; /*Evaporation*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int fV; /* Volumetric fraction of aerobic Rh */ +int fT; /*Temperature scaler*/ +int fW; /*Water scaler*/ +int fCH4; /*CH4 fraction in anaerobic C decomposition*/ +int soil_moist; /*thetas = PAW/PAW_fs fraction*/ + +} DALEC_1103_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53 +}; + + + + + +struct DALEC_1103_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +} DALEC_1103_POOLS={ + 0,1,2,3,4,5,6,7,8,9 +}; + +/* +struct POOLS_INFO{ +int n_input_fluxes +int n_output_fluxes +int * input_fluxes +int * output_fluxes} +*/ + + + +int DALEC_1103_MODCONFIG(DALEC * DALECmodel){ + + +struct DALEC_1103_PARAMETERS P=DALEC_1103_PARAMETERS; +struct DALEC_1103_FLUXES F=DALEC_1103_FLUXES; +struct DALEC_1103_POOLS S=DALEC_1103_POOLS; + +DALECmodel->nopools=10; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=65; +DALECmodel->nofluxes=54; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; + + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//Runoff variables +static int ROFF_fluxes[3]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +ROFF_fluxes[2]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=3; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +//C3frac parameters +OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_soil; + + + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + + +int DALEC_1103(DATA DATA, double const *pars){ + + + +struct DALEC_1103_PARAMETERS P=DALEC_1103_PARAMETERS; +struct DALEC_1103_FLUXES F=DALEC_1103_FLUXES; +struct DALEC_1103_POOLS S=DALEC_1103_POOLS; + + + + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +double pi=3.1415927; + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +// double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_cwd]=pars[P.i_cwd]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + +/* jc prep input for methane module*/ +double PAW_fs = HYDROFUN_MOI2EWT(1,pars[P.PAW_por],pars[P.PAW_z]); +double ch4pars[8]={PAW_fs,pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.Q10rhco2],meantemp}; + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + +// Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117/100; + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[7];//AAB changed this +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; + + +/*Calculate light extinction coefficient*/ +double B = (DOY[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +double LST = (int) (DOY[n]*24*60) % (24*60); +LST=0.5*24*60; +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*DATA.ncdf_data.LAT)*sin(pi/180*DA)+cos(pi/180*DATA.ncdf_data.LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +double zenith_angle = 90-alpha; +//double LAD = 1.0; //leaf angle distribution +//double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 + +double LAD = 0.5; //leaf angle distribution +double VegK = LAD/cos(zenith_angle/180*pi); + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor + //We're also multiplying beta by cold-weather stress +double beta = fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1.)*(1-pow(fmin(fmax(VPD[n],0),pars[P.vpd_ref])/pars[P.vpd_ref],pars[P.vpd_exp])); + // beta = fmin(beta,g); + +// GPP, T, and E from LIU_An_et +// Annual radiation, VPD in kPa, mean T in K +double *LIU_An_et_out = LIU_An_et(SSRD[n]*1e6/(24*3600), VPD[n]/10, + 273.15+0.5*(T2M_MIN[n]+T2M_MAX[n]), pars[P.Vcmax25], CO2[n], beta, pars[P.Med_g1], + LAI[n], pars[P.ga], VegK, pars[P.Tupp], pars[P.Tdown], 1., // pars[P.C3_frac], + pars[P.clumping], pars[P.leaf_refl], pars[P.maxPevap], PREC[n]); +// GPP +FLUXES[f+F.gpp] = LIU_An_et_out[0]; +//transpiration// +FLUXES[f+F.transp] = LIU_An_et_out[1]; +//evaporation// +FLUXES[f+F.evap] = LIU_An_et_out[2]; +// Evapotranspiration +FLUXES[f+F.et]=FLUXES[f+F.evap]+FLUXES[f+F.transp]; + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=pow(pars[P.Q10rhco2],(0.5*(T2M_MIN[n]+T2M_MAX[n])-meantemp)/10)*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood CWD production*/ +FLUXES[f+F.wood2cwd] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic CWD*/ +FLUXES[f+F.resp_het_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_cwd],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; + +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +double *jcr_o = JCR(ch4pars,T2M_MIN[n],T2M_MAX[n],POOLS[S.H2O_PAW]); +//outputformat +//jcr_o 0-4 thetas,fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from litter*/ +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_lit],deltat))/deltat; +/* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_soil],deltat))/deltat; +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from litter*/ +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_lit],deltat))/deltat; +/* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_soil],deltat))/deltat; +/* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*1+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*(1-jcr_o[4]); +/* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*0+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*jcr_o[4]; +/* fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+F.fV] = jcr_o[2]; +/* fT Temperature scaler*/ +FLUXES[f+F.fT] = jcr_o[1]; +/* fW Water scaler*/ +FLUXES[f+F.fW] = jcr_o[3]; +/* fCH4 CH4 fraction*/ +FLUXES[f+F.fCH4] = jcr_o[4]; +/* PAW/PAW_fs thetas*/ +FLUXES[f+F.soil_moist] = jcr_o[0]; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*---------------------- end of JCR --------------------------------------------*/ + +/*CWD to SOM*/ +FLUXES[f+F.cwd2som] = POOLS[p+S.C_cwd]*(1-pow(1-pars[P.tr_cwd2som]*FLUXES[f+F.temprate],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2cwd])*deltat; + POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] + (FLUXES[f+F.wood2cwd] - FLUXES[f+F.ae_rh_cwd]-FLUXES[f+F.an_rh_cwd]-FLUXES[f+F.cwd2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + + + + +/*Snow water equivalent*/ +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ +FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ +POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ +FLUXES[f+F.scf]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); /*snow cover fraction*/ + +// Infiltration (mm/day) +double infil = pars[P.max_infil]*(1 - exp(-(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])/pars[P.max_infil])); + +// Surface runoff (mm/day) +FLUXES[f+F.q_surf] = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]) - infil; + +// Update pools, including infiltration +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + deltat*infil; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW]; + +// Volumetric soil moisture from water pools +double sm_PAW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double sm_PUW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage +double drain_PAW = DRAINAGE(sm_PAW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = DRAINAGE(sm_PUW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + +// Remove drainage from layers +sm_PAW -= drain_PAW; +sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(sm_PAW,pars[P.hydr_cond],pars[P.retention]); +double k_PUW = HYDROFUN_MOI2CON(sm_PUW,pars[P.hydr_cond],pars[P.retention]); + +// Convert to potential +double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.retention]); +double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.retention]); + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(psi_PAW-psi_PUW)/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); + +// Transfer flux in mm/day +FLUXES[f+F.paw2puw] = xfer*1000*3600*24; + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] += (-FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat; +POOLS[nxp+S.H2O_PUW] += (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-CF[S.C_cwd])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2cwd])*deltat; + /*dead C pools*/ + /*CWD*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.fx_woo2cwd]-FLUXES[f+F.f_cwd]-FLUXES[f+F.fx_cwd2som])*deltat; + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + +} + + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1103/EDC2_1103.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1103(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1103_PARAMETERS P=DALEC_1103_PARAMETERS; +struct DALEC_1103_FLUXES F=DALEC_1103_FLUXES; +struct DALEC_1103_POOLS S=DALEC_1103_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +if (Fin[n] > 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_cwd,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW,P.i_SWE}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1025/EDC1_1025.c === + +#pragma once +int EDC1_1025(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1025_PARAMETERS P=DALEC_1025_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +// double const ffol=(1-fauto)*pars[P.f_foliar]; // Removed this as there is no longer a direct flux from NPP -> Cfol, it all goes via Clab +double const flab=(1-fauto)*pars[P.f_lab]; +double const froot=(1-fauto-flab)*pars[P.f_root]; +double const fwood=1-fauto-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +// double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((flab)>5*froot | (flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +EDCD->pEDC=log((double)EDC); + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1025/MODEL_INFO_1025.c === + +#pragma once +#include "PARS_INFO_1025.c" +#include "DALEC_1025.c" +#include "EDC1_1025.c" +#include "EDC2_1025.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1025(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1025_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_DEDC_MODCONFIG(&MLF); + + +/*Step 2: Fill structure with model-specific info*/ + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1025; +DALECmodel.edc2=EDC2_1025; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1025(DATA->parmin, DATA->parmax); + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1025/PARS_INFO_1025.c === + +#pragma once +#include "DALEC_1025.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1025(double *parmin, double *parmax) +{ + +struct DALEC_1025_PARAMETERS P=DALEC_1025_PARAMETERS; + +/*Decomposition rate*/ +parmin[P.tr_lit2soil]=0.00001; +parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil]=0.0000001; +parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor]=0.018; +parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff]=5; +parmax[P.canopy_eff]=50; + +/*Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_soil]=1.0; +parmax[P.i_soil]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.uWUE]=0.5; +parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax]=1; +parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile]=1.001; +parmax[P.t_labile]=8; + +/*Moisture factor*/ +parmin[P.moisture]=0.01; +parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer]=0.01; +parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax]=1; +parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r]=0.01; +parmax[P.boese_r]=0.3; + +/*Mean temperature at leaf onset (T_phi) (degrees kelvin)*/ +parmin[P.T_phi]=268.15; +parmax[P.T_phi]=323.15; + +/*Spatial range of mean temperature at leaf onset (T_r) (degrees C or degrees kelvin)*/ +parmin[P.T_range]=0.1; +parmax[P.T_range]=10.0; + +/*LAI linear growth constant (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.plgr]=0.001; +parmax[P.plgr]=0.5; + +/*Inverse of leaf longevity during senescence period (inverse of model time units; e.g. days-1 or months-1)*/ +parmin[P.k_leaf]=0.001; +parmax[P.k_leaf]=0.5; + +/*Intrinsic maximum LAI (m^2 m^-2)*/ +parmin[P.lambda_max]=0.1; +parmax[P.lambda_max]=10.0; + +/*Target survival time for LAI under water-deficit conditions (days; or same unit as ET and PAW)*/ +parmin[P.tau_W]=0.1; +parmax[P.tau_W]=300; + +/*Mean daylength at leaf shedding (t_c; in units of hours sunlight per day)*/ +parmin[P.time_c]=2; +parmax[P.time_c]=22; + +/*Spatial range of mean daylength at leaf shedding (t_r)*/ +parmin[P.time_r]=0.1; +parmax[P.time_r]=6.0; + +/*initialization of temperature memory at t=0 (in absolute temperature units)*/ +parmin[P.init_T_mem]=268.14; +parmax[P.init_T_mem]=323.15; + +/*initialization of water/structural memory (fractional value of intrinsic maximum LAI)*/ +parmin[P.init_LAIW_mem]=0.01; +parmax[P.init_LAIW_mem]=1; + +/*Inverse of leaf longevity at any period i.e. background turnover (days-1)*/ +parmin[P.t_foliar]=0.001; +parmax[P.t_foliar]=0.1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1025/EDC2_1025.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1025(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1025_PARAMETERS P=DALEC_1025_PARAMETERS; +struct DALEC_1025_FLUXES F=DALEC_1025_FLUXES; +struct DALEC_1025_POOLS S=DALEC_1025_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +// & ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +// {EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW}; + +// for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1025/DALEC_1025.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "../DALEC_ALL/LAI_KNORR.c" +#include "../DALEC_ALL/LAI_KNORR_funcs.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1025_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_root; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int f_lab; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_soil; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +int T_phi; +int T_range; +int plgr; +int k_leaf; +int lambda_max; +int tau_W; +int time_c; +int time_r; +int init_T_mem; +int init_LAIW_mem; +int t_foliar; +} DALEC_1025_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41 +}; + +struct DALEC_1025_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2lit; /*Wood description*/ +int root2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int target_LAI; /*LAI environmental target*/ +int T_memory; /*LAI temp memory*/ +int lambda_max_memory; /*LAI max memory*/ +int dlambda_dt; /*dLAI/dt*/ +int f_temp_thresh; /*f_temp_thres*/ +int f_dayl_thresh; /*f_dayl_thres*/ +int c_lim_flag; /*LAI carbon limitation flag*/ +int lai_fire; /*LAI fire loss*/ +int foliar_fire_frac; /*C_fol fire loss frac*/ +int lambda_ode_input; /*C_fol fire loss frac*/ +int lambda_ode_output; /*C_fol fire loss frac*/ +} DALEC_1025_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42 +}; + +struct DALEC_1025_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1025_POOLS={0,1,2,3,4,5,6,7,8}; + + +int DALEC_1025(DATA DATA, double const *pars) +{ + +struct DALEC_1025_PARAMETERS P=DALEC_1025_PARAMETERS; +struct DALEC_1025_FLUXES F=DALEC_1025_FLUXES; +struct DALEC_1025_POOLS S=DALEC_1025_POOLS; + +double gpppars[11],pi,lai_met_list[1],lai_var_list[21]; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + //Diagnostic states + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; + //printf("POOLS[S.D_LAI] = %2.2f\n",POOLS[S.D_LAI]); + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +// double wf=pars[P.leaf_fall]*sqrt(2)/2; +// double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +// double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +// double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +// double osf=offset(pars[P.t_foliar],wf); +// double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + +/*foliar carbon transfer intermediate variables*/ +double Fcfolavailable; + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + +//KNORR LAI// +if (n==0){ + /*Initialize phenology memory of air-temperature as some value within mintemp and maxtemp*/ + lai_var_list[5]=pars[P.init_T_mem]; + /*Initialize phenology memory of water/structural limitation */ + lai_var_list[11]=pars[P.init_LAIW_mem]*pars[P.lambda_max]; +} +lai_met_list[0]=(T2M_MAX[n]+T2M_MIN[n])/2.0; +// lai_var_list[0]=n; +lai_var_list[19]=deltat; +lai_var_list[1]=LAI; +lai_var_list[2]=LAI; +lai_var_list[3]=pars[P.T_phi]; +lai_var_list[4]=pars[P.T_range]; +lai_var_list[6]=30.0; /*tau_m*/ +lai_var_list[7]=pars[P.plgr]; /*plgr*/ +lai_var_list[8]=pars[P.k_leaf]; /*k_L*/ +lai_var_list[9]=pars[P.lambda_max]; /*lambda_max*/ +lai_var_list[10]=pars[P.tau_W]; /*tau_W*/ +lai_var_list[12]=DATA.ncdf_data.LAT; /*latitude*/ +lai_var_list[13]=DOY[n]; /*day of year*/ +lai_var_list[14]=pi; /*pi*/ +lai_var_list[15]=pars[P.time_c]; /*t_c*/ +lai_var_list[16]=pars[P.time_r]; /*t_r*/ +lai_var_list[17]=(POOLS[p+S.H2O_PAW]+POOLS[nxp+S.H2O_PAW])/2.0; +lai_var_list[18]=FLUXES[f+F.et]; +// Run Knorr LAI module +double *LAI_KNORR_OUTPUT = LAI_KNORR(lai_met_list,lai_var_list); +FLUXES[f+F.target_LAI]=LAI_KNORR_OUTPUT[0]; +FLUXES[f+F.T_memory]=LAI_KNORR_OUTPUT[1]; +FLUXES[f+F.lambda_max_memory]=LAI_KNORR_OUTPUT[2]; +FLUXES[f+F.dlambda_dt]=LAI_KNORR_OUTPUT[3]/deltat; +FLUXES[f+F.f_temp_thresh]=LAI_KNORR_OUTPUT[4]; +FLUXES[f+F.f_dayl_thresh]=LAI_KNORR_OUTPUT[5]; +FLUXES[f+F.lambda_ode_input]=LAI_KNORR_OUTPUT[6]; +FLUXES[f+F.lambda_ode_output]=LAI_KNORR_OUTPUT[7]; +lai_var_list[5]=FLUXES[f+F.T_memory]; /*Update LAI temperature memory state for next iteration*/ +lai_var_list[11]=FLUXES[f+F.lambda_max_memory]; /*Update water/structural memory state for next iteration*/ +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=0; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*(pars[P.f_lab]); +Fcfolavailable=FLUXES[f+F.lab_prod] + POOLS[p+S.C_lab]/deltat; +if (FLUXES[f+F.dlambda_dt] > 0){ + FLUXES[f+F.lab_release]=MinQuadraticSmooth(Fcfolavailable, FLUXES[f+F.dlambda_dt]*pars[P.LCMA], 0.99); + /* flag for carbon availability limitation (0=canopy in senescence, 1=labile C does not limit growth, 2=labile C limits LAI growth) */ + FLUXES[f+F.c_lim_flag]=2.0; + /* leaf litter production: flux from foliar pool to litter pool */ + FLUXES[f+F.fol2lit]=POOLS[p+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))/deltat; +} +else { + FLUXES[f+F.c_lim_flag]=0.0; + /* labile release: flux from labile pool to foliar pool */ + FLUXES[f+F.lab_release]=0; + /* leaf litter production: flux from foliar pool to litter pool */ + FLUXES[f+F.fol2lit]=-FLUXES[f+F.dlambda_dt]*pars[P.LCMA]+POOLS[p+S.C_fol]*(1-pow(1-pars[P.t_foliar],deltat))/deltat; +} +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +// FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +// FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.lab_release] - FLUXES[f+F.fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + /*Fraction of C-foliar lost due to fires*/ + FLUXES[f+F.foliar_fire_frac] = BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Calculate LAI (lambda) lost due to fire + - we lose the same fraction of LAI as we do C-foliar + - FE_\Lambda^{(t+1)} = \Lambda^{(t+1)'} * BA ( k_{factor(i)} + (1 - k_{factor(i)}) r )*/ + // FLUXES[f+F.lai_fire] = FLUXES[f+F.target_LAI]*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + FLUXES[f+F.lai_fire] = (POOLS[p+S.C_fol]/pars[P.LCMA])*BURNED_AREA[n]*(CF[S.C_lab] + (1-CF[S.C_lab])*(1-pars[P.resilience])); + /*Subtract fire loss LAI from current LAI*/ + // FLUXES[f+34] = FLUXES[f+34] - FLUXES[f+39]; + + + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + //printf(" POOLS[nxp+S.D_LAI] = %2.2f\n", POOLS[nxp+S.D_LAI]); + + } + + +return 0; +} + + + +int DALEC_1025_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1025_PARAMETERS P=DALEC_1025_PARAMETERS; +struct DALEC_1025_FLUXES F=DALEC_1025_FLUXES; +struct DALEC_1025_POOLS S=DALEC_1025_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=42; +DALECmodel->nofluxes=43; +DALECmodel->dalec=DALEC_1025; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +// printf("DALEC_1025_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; + +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//SOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_804/EDC1_804.c === + +#pragma once +int EDC1_804(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 8*/ + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_804/MODEL_INFO_804.c === + +#pragma once +#include "PARS_INFO_804.c" +#include "DALEC_804.c" +#include "EDC1_804.c" +#include "EDC2_804.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_804(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9; +DALECmodel.nopars=32; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_804; +DALECmodel.edc1=EDC1_804; +DALECmodel.edc2=EDC2_804; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_804(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_804/DALEC_804.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_804(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[30])-log(pars[30]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(1.001,wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=0.9*pars[27]; +CF[1]=0.9; +CF[2]=0.9*pars[27]; +CF[3]=0.9*pars[27]; +CF[4]=0.45; +CF[5]=0.9*pars[28]; + + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[31]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[29])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_804/EDC2_804.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_804(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + + + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=9,nopools=7; +int nofluxes=30; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_804/PARS_INFO_804.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_804(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point*/ +CARDADATA->parmin[24]=10; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*DOM CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*Fire-induced mortality".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[30]=1.001; +CARDADATA->parmax[30]=8; + +/*Moisture factor*/ +CARDADATA->parmin[31]=0.01; +CARDADATA->parmax[31]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_803/EDC2_803.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_803(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + + + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=9,nopools=7; +int nofluxes=30; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_803/DALEC_803.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_803(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[30])-log(pars[30]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(1.001,wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=0.9*pars[27]; +CF[1]=0.9; +CF[2]=0.9*pars[27]; +CF[3]=0.9*pars[27]; +CF[4]=0.45; +CF[5]=0.9*pars[28]; + + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[31]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[29])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_803/EDC1_803.c === + +#pragma once +int EDC1_803(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 8*/ + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_803/MODEL_INFO_803.c === + +#pragma once +#include "PARS_INFO_803.c" +#include "DALEC_803.c" +#include "EDC1_803.c" +#include "EDC2_803.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + + + +int MODEL_INFO_803(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9; +DALECmodel.nopars=32; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_803; +DALECmodel.edc1=EDC1_803; +DALECmodel.edc2=EDC2_803; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_803(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_803/PARS_INFO_803.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_803(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point*/ +CARDADATA->parmin[24]=10; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*DOM CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*Fire-induced mortality".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[30]=1.001; +CARDADATA->parmax[30]=8; + +/*Moisture factor*/ +CARDADATA->parmin[31]=0.01; +CARDADATA->parmax[31]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1040/EDC1_1040.c === + +#pragma once +int EDC1_1040(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1040/MODEL_INFO_1040.c === + +#pragma once +#include "PARS_INFO_1040.c" +#include "DALEC_1040.c" +#include "EDC1_1040.c" +#include "EDC2_1040.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1040(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=38; +DALECmodel.nofluxes=32; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1040; +DALECmodel.edc1=EDC1_1040; +DALECmodel.edc2=EDC2_1040; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1040(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1040/PARS_INFO_1040.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1040(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ + +CARDADATA->parmin[23]=0.5; +CARDADATA->parmax[23]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +CARDADATA->parmin[36]=0.01; +CARDADATA->parmax[36]=0.3; + +/*Max nutrients in LAI equivalent*/ +CARDADATA->parmin[37]=0.1; +CARDADATA->parmax[37]=1000; + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1040/EDC2_1040.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1040(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1040/DALEC_1040.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_1040(DATA DATA, double const *pars) +{ + +double CE, gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; +double LAIe; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + +/*Canopy efficiency based on maximum canopy efficiency*/ +LAIe=(POOLS[p+1]+POOLS[p+0])/pars[16]; +CE = pars[10] * pars[37]*(1 - exp( - LAIe/pars[37]))/LAIe; +/*placing in GPP constants*/ +constants[0]=CE; +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*sqrt(DATA.MET[m+7])/pars[23]+DATA.MET[m+3]*pars[36]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8] - FLUXES[f+28])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1047/PARS_INFO_1047.c === + +#pragma once +#include "DALEC_1047.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1047(double *parmin, double *parmax) +{ + +struct DALEC_1047_PARAMETERS P=DALEC_1047_PARAMETERS; + +/*Decomposition rate*/ +parmin[P.tr_lit2soil]=0.00001; +parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar]=0.01; +parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +parmin[P.t_foliar]=1.001; +parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil]=0.0000001; +parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor]=0.018; +parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff]=5; +parmax[P.canopy_eff]=50; + +/*Bday*/ +parmin[P.Bday]=365.25; +parmax[P.Bday]=1461.0;//365.25*4 + +/*Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +parmin[P.labile_rel]=30.4375; //365.25/12 +parmax[P.labile_rel]=100; + +/*Fday*/ +parmin[P.Fday]=365.25; +parmax[P.Fday]=1461.0;//365.25*4 + +/*Leaf fall period*/ +parmin[P.leaf_fall]=30.4375; //365.25/12 +parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.uWUE]=0.5; +parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax]=1; +parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile]=1.001; +parmax[P.t_labile]=8; + +/*Moisture factor*/ +parmin[P.moisture]=0.01; +parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer]=0.01; +parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax]=1; +parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r]=0.01; +parmax[P.boese_r]=0.3; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1047/MODEL_INFO_1047.c === + +#pragma once +#include "PARS_INFO_1047.c" +#include "DALEC_1047.c" +#include "EDC1_1047.c" +#include "EDC2_1047.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1047(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1047_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_MODCONFIG(&MLF); + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1047; +DALECmodel.edc2=EDC2_1047; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1047(DATA->parmin, DATA->parmax); + + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1047/EDC1_1047.c === + +#pragma once +int EDC1_1047(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1047_PARAMETERS P=DALEC_1047_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1047/DALEC_1047_INDICES.c === + + +struct DALEC_1047_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_som; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +} DALEC_1047_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36 +}; + +struct DALEC_1047_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int woo2som; /*Wood description*/ +int roo2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int a_lab; /*Labile fire loss*/ +int a_fol; /*Foliar fire loss*/ +int a_roo; /*Wood fire loss*/ +int a_woo; /*Root fire loss*/ +int ax_lab2lit; /*Fire transfer labile to litter*/ +int ax_fol2lit; /*Fire transfer foliar to litter*/ +int ax_roo2lit; /*Fire transfer root to litter*/ +int ax_woo2som; /*Fire transfer wood to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*Plant-available water drainage*/ +int paw2puw; /*Plant-available water to plant-unavailable water transfer*/ +int q_puw; /*Plant-unavailable water runoff*/ +} DALEC_1047_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39 +}; + +struct DALEC_1047_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1047_POOLS={0,1,2,3,4,5,6,7,8}; + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1047/DALEC_1047.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "DALEC_1047_INDICES.c" + +int DALEC_1047(DATA DATA, double const *pars) +{ + +struct DALEC_1047_PARAMETERS P=DALEC_1047_PARAMETERS; +struct DALEC_1047_FLUXES F=DALEC_1047_FLUXES; +struct DALEC_1047_POOLS S=DALEC_1047_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +//double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + /****Diagnostic states***/ + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; //LAI + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *YIELD=DATA.ncdf_data.YIELD.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; +//LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.woo2som] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.roo2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.woo2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.roo2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.woo2som])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + +//Direct removals + FLUXES[f+F.a_lab]= YIELD[n]*0.1; + FLUXES[f+F.a_fol]= YIELD[n]*0.05; + FLUXES[f+F.a_roo]= YIELD[n]*0.05; + FLUXES[f+F.a_woo]= YIELD[n]*0.3; +//Transfers + + FLUXES[f+F.ax_lab2lit]= YIELD[n]*0.1; + FLUXES[f+F.ax_fol2lit]= YIELD[n]*0.05; + FLUXES[f+F.ax_roo2lit]= YIELD[n]*0.05; + FLUXES[f+F.ax_woo2som]= YIELD[n]*0.3; + +//Total disturbance + + FLUXES[f+F.f_lab] = (POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab] + FLUXES[f+F.a_lab])/deltat; + FLUXES[f+F.f_fol] = (POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol] + FLUXES[f+F.a_fol])/deltat; + FLUXES[f+F.f_roo] = (POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo] + FLUXES[f+F.a_roo])/deltat; + FLUXES[f+F.f_woo] = (POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo] + FLUXES[f+F.a_woo])/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = (POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])+FLUXES[f+F.ax_lab2lit])/deltat; + FLUXES[f+F.fx_fol2lit] = (POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])+FLUXES[f+F.ax_fol2lit])/deltat; + FLUXES[f+F.fx_roo2lit] = (POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])+FLUXES[f+F.ax_roo2lit])/deltat; + FLUXES[f+F.fx_woo2som] = (POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])+FLUXES[f+F.ax_woo2som])/deltat; + FLUXES[f+F.fx_lit2som] = (POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience]))/deltat; + + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit]) *deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit] )*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som] )*deltat; + +//Removing YIELD; using fixed fracs for pools + + + + + + + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + + + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + +} + +return 0; +} + + + + + +int DALEC_1047_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1047_PARAMETERS P=DALEC_1047_PARAMETERS; +struct DALEC_1047_FLUXES F=DALEC_1047_FLUXES; +struct DALEC_1047_POOLS S=DALEC_1047_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=37; +DALECmodel->nofluxes=40; +DALECmodel->dalec=DALEC_1047; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1047_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_CWOO_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; + + + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +//NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//ABGB-specific variables +static int CWOO_pools[1]; +CWOO_pools[0]=S.C_woo; +OBSOPE.CWOO_pools=CWOO_pools; +OBSOPE.CWOO_n_pools=1; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; +OBSOPE.iniSOM_PARAM=P.i_som; + + + + + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1047/EDC2_1047.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1047(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1047_PARAMETERS P=DALEC_1047_PARAMETERS; +struct DALEC_1047_FLUXES F=DALEC_1047_FLUXES; +struct DALEC_1047_POOLS S=DALEC_1047_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;npEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;f 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("DIAG = %i\n", DIAG); +printf("EDC = %i\n",EDC); +printf("EDCD->SWITCH[7-1+n] = %i\n",EDCD->SWITCH[7-1+n]); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Rs)) = %f\n",fabs(log(Rs))); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_som,P.i_PAW,P.i_PUW}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1015/DALEC_1015.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +struct DALEC_1015_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_soil; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +int i_SWE; +int min_melt; +int melt_slope; +int scf_scalar; +} DALEC_1015_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40 +}; + +struct DALEC_1015_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int wood2lit; /*Wood description*/ +int root2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +} DALEC_1015_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33 +}; + +struct DALEC_1015_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +} DALEC_1015_POOLS={ + 0,1,2,3,4,5,6,7,8 +}; + +int DALEC_1015_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1015_PARAMETERS P=DALEC_1015_PARAMETERS; +struct DALEC_1015_FLUXES F=DALEC_1015_FLUXES; +struct DALEC_1015_POOLS S=DALEC_1015_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=10;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=41; +DALECmodel->nofluxes=34; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1015_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + +int DALEC_1015(DATA DATA, double const *pars) +{ + +struct DALEC_1015_PARAMETERS P=DALEC_1015_PARAMETERS; +struct DALEC_1015_FLUXES F=DALEC_1015_FLUXES; +struct DALEC_1015_POOLS S=DALEC_1015_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*Snow water equivalent*/ + POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ + FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ + POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ + FLUXES[f+F.scf]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); /*snow cover fraction*/ + /*PAW total runoff*/ + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1015/EDC2_1015.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1015(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1015_PARAMETERS P=DALEC_1015_PARAMETERS; +struct DALEC_1015_FLUXES F=DALEC_1015_FLUXES; +struct DALEC_1015_POOLS S=DALEC_1015_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOW=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW,P.i_SWE}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1015/PARS_INFO_1015.c === + +#pragma once +#include "DALEC_1015.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1015(DATA *CARDADATA) +{ + +struct DALEC_1015_PARAMETERS P=DALEC_1015_PARAMETERS; + +/*Decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[P.temp_factor]=0.018; +CARDADATA->parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[P.canopy_eff]=5; +CARDADATA->parmax[P.canopy_eff]=50; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ + +CARDADATA->parmin[P.uWUE]=0.5; +CARDADATA->parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[P.PAW_Qmax]=1; +CARDADATA->parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[P.h2o_xfer]=0.01; +CARDADATA->parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[P.PUW_Qmax]=1; +CARDADATA->parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +CARDADATA->parmin[P.boese_r]=0.01; +CARDADATA->parmax[P.boese_r]=0.3; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +CARDADATA->parmin[P.i_SWE]=0.000001; +CARDADATA->parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +CARDADATA->parmin[P.min_melt]=240; +CARDADATA->parmax[P.min_melt]=270; + +/*sn2: slope*/ +CARDADATA->parmin[P.melt_slope]=0.00001; +CARDADATA->parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar*/ +CARDADATA->parmin[P.scf_scalar]=0.001; +CARDADATA->parmax[P.scf_scalar]=1000.0; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1015/EDC1_1015.c === + +#pragma once +int EDC1_1015(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1015_PARAMETERS P=DALEC_1015_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1015/MODEL_INFO_1015.c === + +#pragma once +#include "PARS_INFO_1015.c" +#include "DALEC_1015.c" +#include "EDC1_1015.c" +#include "EDC2_1015.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1015(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1015_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1015; +DALECmodel.edc1=EDC1_1015; +DALECmodel.edc2=EDC2_1015; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1015(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1012/EDC2_1012.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1012(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1012_PARAMETERS P=DALEC_1012_PARAMETERS; +struct DALEC_1012_FLUXES F=DALEC_1012_FLUXES; +struct DALEC_1012_POOLS S=DALEC_1012_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +// /*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +// EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +// /***********************EDCs done here****************************/ + + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +// /*EDC jc shuang add changes: PAW < PAW_fs jc */ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[18-1]==1)) & (pars[P.PAW_fs]SWITCH[18-1]);EDCD->PASSFAIL[18-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_som,P.i_PAW,P.i_PUW}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1012/DALEC_1012.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "../DALEC_ALL/ACM.c" +#include "../DALEC_ALL/offset.c" +#include "../DALEC_ALL/CH4_MODULES/JCR.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997 +DALEC 1010 is DALEC-JCR v1, +DALEC 1011 is DALEC-JCR v2, with updated ET and replaced Prec with Infiltration +for PAW balance equation, two new output fluxes and two new pars +DALEC 1012 is revised v2, with corrected ET (not sure if this is a correction), using uWUE instead of iWUE*/ + + +struct DALEC_1012_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2som;/*Decomposition rate*/ +int f_auto;/*Fraction of GPP respired*/ +int f_foliar;/*Fraction of (1-fgpp) to foliage*/ +int f_root;/*Fraction of (1-fgpp) to roots*/ +int t_foliar;/*Leaf Lifespan*/ +int t_wood;/*TOR wood* - 1% loss per year value*/ +int t_root;/*TOR roots*/ +int t_lit;/*TOR litter*/ +int t_som;/*TOR SOM*/ +int Q10rhco2;/*Q10_rhco2*/ +int canopy_eff;/*Canopy Efficiency*/ +int Bday;/*Bday*/ +int f_lab;/*Fraction to Clab*/ +int labile_rel;/*Clab Release period*/ +int Fday;/*Fday*/ +int leaf_fall;/*Leaf fall period*/ +int LCMA;/*LMCA*/ +int i_labile;/*C labile*/ +int i_foliar;/*C foliar*/ +int i_root;/*C roots*/ +int i_wood;/*C_wood*/ +int i_lit;/*C litter*/ +int i_som;/*C_som*/ +int uWUE;/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +int PAW_Qmax;/*Runoff focal point (~maximum soil storage capacity x 4)*/ +int wilting;/*"Wilting point"*/ +int i_PAW;/*"Bucket at t0"*/ +int cf_foliar;/*Foliar biomass CF*/ +int cf_ligneous;/*"Ligneous" biomass CF".*/ +int cf_DOM;/*DOM CF".*/ +int resilience;/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +int t_labile; /*Lab pool lifespan*/ +int moisture;/*Moisture factor*/ +int h2o_xfer; /*PAW->PUW runoff fraction*/ +int PUW_Qmax; /*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +int i_PUW;/*PUW pool*/ +int PAW_fs;/*jc PAW_fs fully saturated PAW*/ +int S_fv;/*S_fv, scalar for aerobic volumetric fraction */ +int thetas_opt;/*jc thetas_opt optimum thetas for water scaler fW*/ +int fwc;/*jc fwc the water scaler fW value at the end point C */ +int r_ch4;/*jc r_ch4 CH4:CO2 conversion ratio*/ +int Q10ch4;/*jc Q10ch4 Q10 for CH4 production */ +int boese_r;/*jc v2 rET radiation coefficient in ET, unitless, follow Yan's ET scheme */ +int Imax;/*jc v2 Imax maximum infiltration rate, mm/day same with prec, partially follow Elias's hydrology */ +} DALEC_1012_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43 +}; + +struct DALEC_1012_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*leaflitter_production 10 */ +int wood2lit; /*woodlitter_production*/ +int root2lit; /*rootlitter_production*/ +int resp_het_lit; /*nominaly there, not actual fluxes Litter heterotrophic respiration*/ +int resp_het_som; /*nominaly there, not actual fluxes Soil heterotrophic respiration*/ +int lit2som; /*lit2som*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux total*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss 20 */ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration Boese et al 2017 and Yan et al 2021*/ +int q_paw; /*PAW runoff 30 */ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int fV; /* Volumetric fraction of aerobic Rh */ +int fT; /*Temperature scaler 40 */ +int fW; /*Water scaler*/ +int fCH4; /*CH4 fraction in anaerobic C decomposition*/ +int soil_moist; /*thetas = PAW/PAW_fs fraction*/ +int infilt_rate; /*Infiltration rate; mm/day*/ +int runoff_rate; /*Runoff rate, mm/day*/ +} DALEC_1012_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44 +}; + + + +struct DALEC_1012_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1012_POOLS={ + 0,1,2,3,4,5,6,7,8 +}; + + + + + +int DALEC_1012(DATA DATA, double const *pars){ + +struct DALEC_1012_PARAMETERS P=DALEC_1012_PARAMETERS; +struct DALEC_1012_FLUXES F=DALEC_1012_FLUXES; +struct DALEC_1012_POOLS S=DALEC_1012_POOLS; + +double gpppars[11]; /* jc */ + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; /* added =0 mk */ +int n=0,nn=0; +double pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; + + +/*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + //Diagnostic states + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; + +/* bring in drivers mk new in main jc */ +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + +/* jc prep input for methane module*/ +double ch4pars[7]={pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.Q10rhco2],meantemp}; + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; + + +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +//FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +FLUXES[f+F.temprate]=pow(pars[P.Q10rhco2],(0.5*(T2M_MIN[n]+T2M_MAX[n])-meantemp)/10)*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_som],deltat))/deltat; +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +double thetas = fmin(POOLS[p+S.H2O_PAW]/pars[P.PAW_fs],1); +double *jcr_o = JCR(ch4pars,T2M_MIN[n],T2M_MAX[n],thetas); +//outputformat +//jcr_o 0-3 fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +/*32 aerobic Rh from litter*/ +FLUXES[f+F.ae_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_lit],deltat))/deltat; +/*33 aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*(1-pow(1-jcr_o[2]*jcr_o[0]*jcr_o[1]*pars[P.t_som],deltat))/deltat; +/*34 anaerobic Rh from litter*/ +//FLUXES[f+34] = POOLS[p+S.C_lit]*(1-pow(1-1*fT*(1-jcr_o[1])*pars[P.t_lit],deltat))/deltat; +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_lit],deltat))/deltat; +/*35 anaerobic Rh from SOM*/ +//FLUXES[f+] = POOLS[p+S.C_som]*(1-pow(1-1*fT*(1-jcr_o[1])*pars[P.t_som],deltat))/deltat; +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*(1-pow(1-pars[P.fwc]*jcr_o[0]*(1-jcr_o[1])*pars[P.t_som],deltat))/deltat; +/*36 Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_som])*1+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_som])*(1-jcr_o[3]); +/*37 Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_som])*0+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_som])*jcr_o[3]; +/*38 fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+F.fV] = jcr_o[1]; +/*39 fT Temperature scaler*/ +FLUXES[f+F.fT] = jcr_o[0]; +/*40 fW Water scaler*/ +FLUXES[f+F.fW] = jcr_o[2]; +/*41 fCH4 CH4 fraction*/ +FLUXES[f+F.fCH4] = jcr_o[3]; +/*42 PAW/PAW_fs thetas*/ +FLUXES[f+F.soil_moist] = thetas; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*---------------------- end of JCR --------------------------------------------*/ +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2som]*FLUXES[f+F.temprate],deltat))/deltat; + + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; +/*-----------------------------------------------------------------------*/ + /*jc*/ + //POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit]+FLUXES[f+F.root2lit]-FLUXES[f+F.ae_rh_lit]-FLUXES[f+F.an_rh_lit]-FLUXES[f+F.lit2som])*deltat; + // POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som]-FLUXES[f+F.ae_rh_som]-FLUXES[f+F.an_rh_som]+FLUXES[f+F.wood2lit])*deltat; +/*-----------------------------------------------------------------------*/ + /*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + /*-----------------------------------------------------------------------*/ + /*updates in DALEC-JCR v2*/ + /*I =Imax *(1-exp(-Pt/Imax)) + PAW = PAW + (-PAWrunoff – PAW->PUWtransfer + I- ET)*deltat;*/ + /*Infiltration rate*/ + FLUXES[f+F.infilt_rate]=pars[P.Imax]*(1-exp(-PREC[n]/pars[43])); + /*runoff rate*/ + FLUXES[f+F.runoff_rate]=PREC[n]-FLUXES[f+F.infilt_rate]; + /*Plant-available water budget*/ + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + FLUXES[f+F.infilt_rate] - FLUXES[f+F.et])*deltat; + /*---- end of updates in JCR v2 ---------------------------------------------------*/ + + /*Plant-unavailable water budget*/ + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + + +} + +return 0; +} + + +int DALEC_1012_MODCONFIG(DALEC * DALECmodel){ + + +struct DALEC_1012_PARAMETERS P=DALEC_1012_PARAMETERS; +struct DALEC_1012_FLUXES F=DALEC_1012_FLUXES; +struct DALEC_1012_POOLS S=DALEC_1012_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=44; +DALECmodel->nofluxes=45; +DALECmodel->dalec=DALEC_1012; + + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_SIF_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[4]; /* jc special changes */ +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; + +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.};/* jc special changes */ +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4;/* jc special changes */ + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2];/* jc special changes */ +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; + +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; + +//CH4-specific variables +OBSOPE.CH4_flux = F.rh_ch4; + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1012/MODEL_INFO_1012.c === + +#pragma once +#include "PARS_INFO_1012.c" +#include "DALEC_1012.c" +#include "EDC1_1012.c" +#include "EDC2_1012.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1012(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1012_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_DEDC_MODCONFIG(&MLF); + + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1012; +DALECmodel.edc2=EDC2_1012; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1012(DATA->parmin, DATA->parmax); + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_STEPWISE; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1012/EDC1_1012.c === + +#pragma once +int EDC1_1012(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1012_PARAMETERS P=DALEC_1012_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions shuang jc change soil to som*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2som]/(pars[P.tr_lit2som]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_som]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2som]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +/* jc shuang add changes*/ +//if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1012/PARS_INFO_1012.c === + +#pragma once +#include "DALEC_1012.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1012(double *parmin, double *parmax) +{ + + +struct DALEC_1012_PARAMETERS P=DALEC_1012_PARAMETERS; + +/* 0 Decomposition rate*/ +parmin[P.tr_lit2som]=0.00001; +parmax[P.tr_lit2som]=0.01; + +/* 1 Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/* 2 Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar]=0.01; +parmax[P.f_foliar]=0.5; + +/* 3 Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/* 4 Leaf Lifespan*/ +parmin[P.t_foliar]=1.001; +parmax[P.t_foliar]=8; + +/* 5 TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/* 6 TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/* 7 TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/* 8 TOR SOM*/ +parmin[P.t_som]=0.0000001; +parmax[P.t_som]=0.001; + +/* 9 Temp factor* convert to Q10_rhco2 = 1.2-1.6*/ +//parmin[P.temp_factor]=0.018; +//parmax[P.temp_factor]=0.08; +parmin[P.Q10rhco2]=1.2; +parmax[P.Q10rhco2]=2; + +/* 10 Canopy Efficiency*/ +parmin[P.canopy_eff]=5; +parmax[P.canopy_eff]=50; + +/* 11 Bday*/ +parmin[P.Bday]=365.25; +parmax[P.Bday]=365.25*4; + +/* 12 Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/* 13 Clab Release period*/ +parmin[P.labile_rel]=365.25/12; +parmax[P.labile_rel]=100; + +/* 14 Fday*/ +parmin[P.Fday]=365.25; +parmax[P.Fday]=365.25*4; + +/* 15 Leaf fall period*/ +parmin[P.leaf_fall]=365.25/12; +parmax[P.leaf_fall]=150; + +/* 16 LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/* 17 C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/* 18 C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/* 19 C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/* 20 C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/* 21 C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/* 22 C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/* 23 uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.uWUE]=0.5; +parmax[P.uWUE]=30; + +/* 24 Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax]=1; +parmax[P.PAW_Qmax]=100000; + +/* 25 "Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/* 26 "Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/* 27 Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/* 28 "Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/* 29 DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/* 30 Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/* 31 Lab pool lifespan*/ +parmin[P.t_labile]=1.001; +parmax[P.t_labile]=8; + +/* 32 Moisture factor*/ +parmin[P.moisture]=0.01; +parmax[P.moisture]=1; + +/* 33 PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer]=0.01; +parmax[P.h2o_xfer]=1; + +/* 34 PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax]=1; +parmax[P.PUW_Qmax]=100000; + +/* 35 PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/* 36 jc PAW_fs fully saturated PAW*/ +parmin[P.PAW_fs]=10.0; +parmax[P.PAW_fs]=100000.0; + +/* 37 jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +/*jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +parmin[P.S_fv]=1; +parmax[P.S_fv]=100.0; + +/* 38 jc thetas_opt optimum thetas for water scaler fW*/ +parmin[P.thetas_opt]=0.2; +parmax[P.thetas_opt]=1.0; + +/* 39 jc fwc the water scaler fW value at the end point C */ +parmin[P.fwc]=0.01; +parmax[P.fwc]=1.0; + +/* 40 jc r_ch4 CH4:CO2 conversion ratio*/ +parmin[P.r_ch4]=0.001; +parmax[P.r_ch4]=0.9; + +/* 41 jc Q10ch4 Q10 for CH4 production */ +parmin[P.Q10ch4]=1.0; +parmax[P.Q10ch4]=3.0; + +/* 42 jc v2 rET radiation coefficient in ET, unitless, follow Yan's ET scheme */ +parmin[P.boese_r]=0.01; +parmax[P.boese_r]=0.3; + +/* 43 jc v2 Imax maximum infiltration rate, mm/day same with prec, partially follow Elias's hydrology */ +parmin[P.Imax]=100/(365.25/12); +parmax[P.Imax]=2000/(365.25/12); + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_805/PARS_INFO_805.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_805(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_805/EDC2_805.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_805(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_805/EDC1_805.c === + +#pragma once +int EDC1_805(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_805/MODEL_INFO_805.c === + +#pragma once +#include "PARS_INFO_805.c" +#include "DALEC_805.c" +#include "EDC1_805.c" +#include "EDC2_805.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_805(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_805; +DALECmodel.edc1=EDC1_805; +DALECmodel.edc2=EDC2_805; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_805(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_805/DALEC_805.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_805(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(1.001,wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/EDC1_811_OBS.c === + +#pragma once +int EDC1_811(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/PARS_INFO_400.c === + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_400(DATA *CARDADATA) +{ + +CARDADATA->nopars=23; + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + + +/*TOR wood*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + + +/*Temp factor*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile @ t=0*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar @ t=0*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots @ t=0*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C wood @ t=0*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter @ t=0*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C som @ t=0*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/EDC2_400.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + + + + + +int EDC2_400(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + + + + + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + + + +/*THESE EDC2 checks are for DALEC_FIRES2*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + +/*FIRES*/ +int nomet=7,nopools=6; +int nofluxes=28; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nLAImax){EDC=0;EDCD->PASSFAIL[5-1]=0;}}}*/ +/*MLAI=mean_pointer_vector(LAI,nodays);*/ + + + +/*EDC no 6*/ +/*0.2*Cf < Cr < 5*Cf*/ +/*Cfoliar : Croot = 5:1 or 1:5*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*EDC 7*/ +/*G10 = 2 - growth factor in 10 years*/ +/*for any further constraint please incorporate in likelyhood*/ +/*int noyears=floor(nodays*deltat/365); +double G=0.1; +int y;*/ + + +/*mean annual pool array*/ +/*double *MAPOOL=calloc(noyears,sizeof(double)); +for (n=0;nG*(double)noyears)){EDC=0;EDCD->PASSFAIL[7-1]=0;}}*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1]==1)) & (MAPOOL[noyears-1]/MAPOOL[0]>(1+G*(double)noyears))){EDC=pow(0,EDCD->SWITCH[7-1]);;EDCD->PASSFAIL[7-1]=0;} + +} +*/ + + + +/*EDC no 8*/ +/*POOL EXPONENTIAL DECAY*/ +/*Performed on all seven pools*/ + +/*exporting the decay coefficient here*/ +/*double C;double cyears=3; +for (n=0;nSWITCH[8-1]==1)) { +C=expdecay2(POOLS,n,nodays+1,deltat,nopools); +if (fabs(-log(2)/C)<(365.25*cyears) & C<0 & isfinite(C)){EDC=pow(0,EDCD->SWITCH[8-1]);;EDCD->PASSFAIL[8-1]=0;}}}; +*/ + + + +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; + +/*fraction of GPP to som and lit under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); +double const flit=(froot+flab+ffol); + + + +/*SOM attractor - must be within a factor of 2 from Csom0*/ +/*half the TR is balanced by x2 Csom*/ + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; +/*No longer need mean GPP estimate*/ +/*double meangpp=0;for (n=0;nSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=pow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + + + + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ + +for (n=0;n<6;n++){if ((EDC==1 || DIAG==1) & ((MPOOLS[n])>parmax[n+17])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1;}} + + + + + + + + + +/*FREE MEMORY*/ +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + +/*Returning EDC */ +return EDC; + + + + + + + + + + + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/EDC2_811_OBS.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_811(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/DALEC_811_OBS.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_811(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nt nomet=((DALEC *)DATA.MODEL)->nomet; +nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/MODEL_INFO_400.c === + +#pragma once +#include "PARS_INFO_400.c" +#include "DALEC_400.c" +#include "EDC1_400.c" +#include "EDC2_400.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_400(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=6; +DALECmodel.nomet=7;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=23; +DALECmodel.nofluxes=28; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_400; +DALECmodel.edc1=EDC1_400; +DALECmodel.edc2=EDC2_400; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_400(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/EDC1_400.c === + +#pragma once +int EDC1_400(double const *pars, DATA DATA,struct EDCDIAGNOSTIC *EDCD) +{ + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*ALL EDCs set as 1 initially*/ +/*EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +*//*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIRES.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 8*/ + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/DALEC_400.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_400(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + + + +/* NOTES FOR POOLS AND FLUXES +MET[:,0]: projday +MET[:,1]: mintemp +MET[:,2]: maxtemp +MET[:,3]: rad +MET[:,4]: co2 +MET[:,5]: yearday + + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +double fl=(log(1.001)-log(0.001))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(1.001,wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]={0.1,0.9,0.1,0.1,0.5,0.01}; +/*resilience factor*/ +double rfac=0.5; + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + +int nr=DATA.nodays; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + + +FLUXES[f+0]=ACM(gpppars,constants); +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1])); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<5;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-rfac)/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_400/PARS_INFO_811_OBS.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_811(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1046/DALEC_1046_INDICES.c === + + +struct DALEC_1046_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_som; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +} DALEC_1046_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36 +}; + +struct DALEC_1046_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int woo2som; /*Wood description*/ +int roo2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int a_lab; /*Labile fire loss*/ +int a_fol; /*Foliar fire loss*/ +int a_roo; /*Wood fire loss*/ +int a_woo; /*Root fire loss*/ +int ax_lab2lit; /*Fire transfer labile to litter*/ +int ax_fol2lit; /*Fire transfer foliar to litter*/ +int ax_roo2lit; /*Fire transfer root to litter*/ +int ax_woo2som; /*Fire transfer wood to soil*/ +int d_lab; /*Labile disturbance loss*/ +int d_fol; /*Foliar disturbance loss*/ +int d_roo; /*Wood disturbance loss*/ +int d_woo; /*Root disturbance loss*/ +int d_lit; /*Litter disturbance loss*/ +int d_som; /*Soil disturbance loss*/ +int dx_lab2lit; /*Fire transfer labile to litter*/ +int dx_fol2lit; /*Fire transfer foliar to litter*/ +int dx_roo2lit; /*Fire transfer root to litter*/ +int dx_woo2som; /*Fire transfer wood to soil*/ +int dx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*Plant-available water drainage*/ +int paw2puw; /*Plant-available water to plant-unavailable water transfer*/ +int q_puw; /*Plant-unavailable water runoff*/ +} DALEC_1046_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50 +}; + +struct DALEC_1046_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1046_POOLS={0,1,2,3,4,5,6,7,8}; + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1046/EDC2_1046.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1046(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1046_PARAMETERS P=DALEC_1046_PARAMETERS; +struct DALEC_1046_FLUXES F=DALEC_1046_FLUXES; +struct DALEC_1046_POOLS S=DALEC_1046_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;npEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;f 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("DIAG = %i\n", DIAG); +printf("EDC = %i\n",EDC); +printf("EDCD->SWITCH[7-1+n] = %i\n",EDCD->SWITCH[7-1+n]); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Rs)) = %f\n",fabs(log(Rs))); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_som,P.i_PAW,P.i_PUW}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1046/DALEC_1046.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "DALEC_1046_INDICES.c" + +int DALEC_1046(DATA DATA, double const *pars) +{ + +struct DALEC_1046_PARAMETERS P=DALEC_1046_PARAMETERS; +struct DALEC_1046_FLUXES F=DALEC_1046_FLUXES; +struct DALEC_1046_POOLS S=DALEC_1046_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +//double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + /****Diagnostic states***/ + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; //LAI + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *YIELD=DATA.ncdf_data.YIELD.values; +double *DISTURBANCE_FLUX=DATA.ncdf_data.DISTURBANCE_FLUX.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; +//LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.woo2som] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.roo2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.woo2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.roo2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.woo2som])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + +//Proportional removals for deforestation & degradation + + double frac_lab, frac_fol, frac_roo, frac_woo, tot_abgb; + tot_abgb=POOLS[nxp+S.C_lab]+POOLS[nxp+S.C_fol] +POOLS[nxp+S.C_roo] + POOLS[nxp+S.C_woo]; + frac_lab=POOLS[nxp+S.C_lab]/tot_abgb; + frac_fol=POOLS[nxp+S.C_fol]/tot_abgb; + frac_roo=POOLS[nxp+S.C_roo]/tot_abgb; + frac_woo=POOLS[nxp+S.C_woo]/tot_abgb; + + +// printf("DISTURBANCE_FLUX[n] = %2.2f\n", DISTURBANCE_FLUX[n]); +//Direct removals + FLUXES[f+F.a_lab]= (YIELD[n]*0 + DISTURBANCE_FLUX[n]*frac_lab)/deltat; + FLUXES[f+F.a_fol]= (YIELD[n]*0 + DISTURBANCE_FLUX[n]*frac_fol)/deltat; + FLUXES[f+F.a_roo]= (YIELD[n]*0 + DISTURBANCE_FLUX[n]*frac_roo)/deltat; + FLUXES[f+F.a_woo]= (YIELD[n]*1 + DISTURBANCE_FLUX[n]*frac_woo)/deltat; + +//Transfers + FLUXES[f+F.ax_lab2lit]= YIELD[n]*0.2/deltat; + FLUXES[f+F.ax_fol2lit]= YIELD[n]*0.2/deltat; + FLUXES[f+F.ax_roo2lit]= YIELD[n]*0.2/deltat; + FLUXES[f+F.ax_woo2som]= YIELD[n]*0.4/deltat; + + + //Land-to-atmoshere flux disturbance + FLUXES[f+F.f_lab] = (POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab] )/deltat; + FLUXES[f+F.f_fol] = (POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol] )/deltat; + FLUXES[f+F.f_roo] = (POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo] )/deltat; + FLUXES[f+F.f_woo] = (POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo] )/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; +//Total disturbance + + FLUXES[f+F.d_lab] = FLUXES[f+F.f_lab] + FLUXES[f+F.a_lab]; + FLUXES[f+F.d_fol] =FLUXES[f+F.f_fol] + FLUXES[f+F.a_fol]; + FLUXES[f+F.d_roo] = FLUXES[f+F.f_roo] + FLUXES[f+F.a_roo]; + FLUXES[f+F.d_woo] = FLUXES[f+F.f_woo] + FLUXES[f+F.a_woo]; + FLUXES[f+F.d_lit] = FLUXES[f+F.f_lit]; + FLUXES[f+F.d_som] = FLUXES[f+F.f_som]; + +//Fire transfers + FLUXES[f+F.fx_lab2lit] = (POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])+FLUXES[f+F.ax_lab2lit])/deltat; + FLUXES[f+F.fx_fol2lit] = (POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])+FLUXES[f+F.ax_fol2lit])/deltat; + FLUXES[f+F.fx_roo2lit] = (POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])+FLUXES[f+F.ax_roo2lit])/deltat; + FLUXES[f+F.fx_woo2som] = (POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])+FLUXES[f+F.ax_woo2som])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + //Total transfers + FLUXES[f+F.dx_lab2lit] = FLUXES[f+F.fx_lab2lit] + FLUXES[f+F.ax_lab2lit]; + FLUXES[f+F.dx_fol2lit] = FLUXES[f+F.fx_fol2lit] + FLUXES[f+F.ax_fol2lit]; + FLUXES[f+F.dx_roo2lit] = FLUXES[f+F.fx_roo2lit] + FLUXES[f+F.ax_roo2lit]; + FLUXES[f+F.dx_woo2som] = FLUXES[f+F.fx_woo2som] + FLUXES[f+F.ax_woo2som]; + FLUXES[f+F.dx_lit2som] = FLUXES[f+F.fx_lit2som]; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.d_lab]+FLUXES[f+F.dx_lab2lit]) *deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.d_fol]+FLUXES[f+F.dx_fol2lit] )*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.d_roo]+FLUXES[f+F.dx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.d_woo]+FLUXES[f+F.dx_woo2som] )*deltat; + /*dead C pools*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.dx_lab2lit]+FLUXES[f+F.dx_fol2lit]+FLUXES[f+F.dx_roo2lit]-FLUXES[f+F.d_lit]-FLUXES[f+F.dx_lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.dx_woo2som]+FLUXES[f+F.dx_lit2som]-FLUXES[f+F.d_som])*deltat; + + + + + /*fires - total flux in gC m-2 day-1*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + +} + +return 0; +} + + + + + +int DALEC_1046_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1046_PARAMETERS P=DALEC_1046_PARAMETERS; +struct DALEC_1046_FLUXES F=DALEC_1046_FLUXES; +struct DALEC_1046_POOLS S=DALEC_1046_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=37; +DALECmodel->nofluxes=40; +DALECmodel->dalec=DALEC_1046; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1046_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_CWOO_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; + + + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//ABGB-specific variables +static int CWOO_pools[1]; +CWOO_pools[0]=S.C_woo; +OBSOPE.CWOO_pools=CWOO_pools; +OBSOPE.CWOO_n_pools=1; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; +OBSOPE.iniSOM_PARAM=P.i_som; + + + + + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1046/EDC1_1046.c === + +#pragma once +int EDC1_1046(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1046_PARAMETERS P=DALEC_1046_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1046/MODEL_INFO_1046.c === + +#pragma once +#include "PARS_INFO_1046.c" +#include "DALEC_1046.c" +#include "EDC1_1046.c" +#include "EDC2_1046.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF2.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1046(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1046_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_DEDC_MODCONFIG(&MLF); + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1046; +DALECmodel.edc2=EDC2_1046; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1046(DATA->parmin, DATA->parmax); + + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1046/PARS_INFO_1046.c === + +#pragma once +#include "DALEC_1046.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1046(double *parmin, double *parmax) +{ + +struct DALEC_1046_PARAMETERS P=DALEC_1046_PARAMETERS; + +/*Decomposition rate*/ +parmin[P.tr_lit2soil]=0.00001; +parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar]=0.01; +parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +parmin[P.t_foliar]=1.001; +parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil]=0.0000001; +parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor]=0.018; +parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff]=5; +parmax[P.canopy_eff]=50; + +/*Bday*/ +parmin[P.Bday]=365.25; +parmax[P.Bday]=1461.0;//365.25*4 + +/*Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +parmin[P.labile_rel]=30.4375; //365.25/12 +parmax[P.labile_rel]=100; + +/*Fday*/ +parmin[P.Fday]=365.25; +parmax[P.Fday]=1461.0;//365.25*4 + +/*Leaf fall period*/ +parmin[P.leaf_fall]=30.4375; //365.25/12 +parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.uWUE]=0.5; +parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax]=1; +parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile]=1.001; +parmax[P.t_labile]=8; + +/*Moisture factor*/ +parmin[P.moisture]=0.01; +parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer]=0.01; +parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax]=1; +parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r]=0.01; +parmax[P.boese_r]=0.3; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1090/EDC2_1090.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1090(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1090_PARAMETERS P=DALEC_1090_PARAMETERS; +struct DALEC_1090_POOLS S=DALEC_1090_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[P.wilting]>MPOOLS[S.H2O_PAW])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;}*/ + +/***********************EDCs done here****************************/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1090/DALEC_1090.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../../../DALEC_CODE/DALEC_ALL/LIU_An_et.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + + +struct DALEC_1090_PARAMETERS{ +//***DALEC PARAMETERS*** +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_soil; +int retention; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int hydr_cond; +int max_infil; +int i_PUW; +int PAW_por; +int PUW_por; +int field_cap; +int PAW_z; +int PUW_z; +int Q_excess; +int Med_g1; +int Vcmax25; +int Tminmin; +int Tminmax; +int ga; +int Tupp; +int Tdown; +int C3_frac; +} DALEC_1090_PARAMETERS={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48}; + +struct DALEC_1090_FLUXES{ +//***DALEC FLUXES*** +int gpp; +int temprate; +int resp_auto; +int leaf_prod; +int lab_prod; +int root_prod; +int wood_prod; +int lab_release; +int leaffall_fact; +int leaf2lit; +int wood2lit; +int root2lit; +int resp_het_lit; +int resp_het_som; +int lit2som; +int lab_release_fact; +int f_total; +int f_lab; +int f_fol; +int f_roo; +int f_woo; +int f_lit; +int f_som; +int fx_lab2lit; +int fx_fol2lit; +int fx_roo2lit; +int fx_woo2som; +int fx_lit2som; +int et; +int q_paw; +int paw2puw; +int q_puw; +int q_surf; +int transp; +int evap;} DALEC_1090_FLUXES={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34}; + +struct DALEC_1090_POOLS{ +//***DALEC POOLS*** +int C_lab; +int C_fol; +int C_roo; +int C_woo; +int C_lit; +int C_som; +int H2O_PAW; +int H2O_PUW; +int H2O_SWE;} DALEC_1090_POOLS={0,1,2,3,4,5,6,7,8}; + + + +int DALEC_1090_MODCONFIG(DALEC * DALECmodel){ + + +struct DALEC_1090_PARAMETERS P=DALEC_1090_PARAMETERS; +struct DALEC_1090_FLUXES F=DALEC_1090_FLUXES; +struct DALEC_1090_POOLS S=DALEC_1090_POOLS; + +DALECmodel->nopools=8; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=49; +DALECmodel->nofluxes=35; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1090_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_SOM_OBS=true; +OBSOPE.SUPPORT_GRACE_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//SOM-specific variables +static int SOM_pools[2]; +SOM_pools[0]=S.C_lit; +SOM_pools[1]=S.C_som; +OBSOPE.SOM_pools=SOM_pools; +OBSOPE.SOM_n_pools=2; +//H2O-specific variables +static int GRACE_EWT_h2o_pools[2]; +GRACE_EWT_h2o_pools[0]=S.H2O_PAW; +GRACE_EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.GRACE_EWT_h2o_pools=GRACE_EWT_h2o_pools; +OBSOPE.GRACE_EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + +int DALEC_1090(DATA DATA, double const *pars) +{ + + + +struct DALEC_1090_PARAMETERS P=DALEC_1090_PARAMETERS; +struct DALEC_1090_FLUXES F=DALEC_1090_FLUXES; +struct DALEC_1090_POOLS S=DALEC_1090_POOLS; + + + + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +double pi=3.1415927; + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +// double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + +// Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117*9.8/1000; + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; + + +/*Calculate light extinction coefficient*/ +double B = (DOY[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DOY[n])*2*pi/365); //Deviation angle +double LST = (int) (DOY[n]*24*60) % (24*60); +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*DATA.ncdf_data.LAT)*sin(pi/180*DA)+cos(pi/180*DATA.ncdf_data.LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude +double zenith_angle = 90-alpha; +double LAD = 1.0; //leaf angle distribution +double VegK = sqrt(pow(LAD,2)+ pow(tan(zenith_angle/180*pi),2))/(LAD+1.774*pow((1+1.182),-0.733)); //Campbell and Norman 1998 + + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor +double beta = fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); + +// GPP, T, and E from LIU_An_et +// Annual radiation, VPD in kPa, mean T in K +double *LIU_An_et_out = LIU_An_et(SSRD[n]*1e6/(24*3600), VPD[n]/10, + 273.15+0.5*(T2M_MIN[n]+T2M_MAX[n]), pars[P.Vcmax25], CO2[n], beta, pars[P.Med_g1], + LAI[n], pars[P.ga], VegK, pars[P.Tupp], pars[P.Tdown], pars[P.C3_frac]); +// GPP +FLUXES[f+F.gpp] = LIU_An_et_out[0]*g; +//transpiration// +FLUXES[f+F.transp] = LIU_An_et_out[1]; +//evaporation// +FLUXES[f+F.evap] = LIU_An_et_out[2]; +// Evapotranspiration +FLUXES[f+F.et]=FLUXES[f+F.evap]+FLUXES[f+F.transp]; + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.leaf_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.leaf_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.leaf_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.leaf_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.leaf2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.wood2lit] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.leaf_prod] - FLUXES[f+F.leaf2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2lit])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.leaf2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.wood2lit])*deltat; + +// Infiltration (mm/day) +double infil = pars[P.max_infil]*(1 - exp(-PREC[n]/pars[P.max_infil])); + +// Surface runoff (mm/day) +FLUXES[f+F.q_surf] = PREC[n] - infil; + +// Update pools, including infiltration +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + deltat*infil; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW]; + +// Volumetric soil moisture from water pools +double sm_PAW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double sm_PUW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage +double drain_PAW = DRAINAGE(sm_PAW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = DRAINAGE(sm_PUW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + +// Remove drainage from layers +sm_PAW -= drain_PAW; +sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(sm_PAW,pars[P.hydr_cond],pars[P.hydr_cond]); +double k_PUW = HYDROFUN_MOI2CON(sm_PUW,pars[P.hydr_cond],pars[P.hydr_cond]); + +// Convert to potential +double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.hydr_cond]); +double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.hydr_cond]); + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(psi_PAW-psi_PUW)/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); + +// Transfer flux in mm/day +FLUXES[f+F.paw2puw] = xfer*1000*3600*24; + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] += (-FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat; +POOLS[nxp+S.H2O_PUW] += (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1090/MODEL_INFO_1090.c === + +#pragma once +#include "PARS_INFO_1090.c" +#include "DALEC_1090.c" +#include "EDC1_1090.c" +#include "EDC2_1090.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1090(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1090_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1090; +DALECmodel.edc1=EDC1_1090; +DALECmodel.edc2=EDC2_1090; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1090(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_DEDC; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1090/EDC1_1090.c === + +#pragma once +int EDC1_1090(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1090_PARAMETERS P=DALEC_1090_PARAMETERS; + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1090/PARS_INFO_1090.c === + +#pragma once +#include "DALEC_1090.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1090(DATA *CARDADATA) +{ + + +struct DALEC_1090_PARAMETERS P=DALEC_1090_PARAMETERS; + +/*Decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[P.temp_factor]=0.018; +CARDADATA->parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[P.canopy_eff]=5; +CARDADATA->parmax[P.canopy_eff]=50; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*Retention parameter (b)*/ +CARDADATA->parmin[P.retention]=1.5; +CARDADATA->parmax[P.retention]=10; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +CARDADATA->parmin[P.hydr_cond]=0.0000001; +CARDADATA->parmax[P.hydr_cond]=0.00001; + +/*Maximum infiltration (mm/day)*/ +CARDADATA->parmin[P.max_infil]=1; +CARDADATA->parmax[P.max_infil]=1e4; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*PAW porosity*/ +CARDADATA->parmin[P.PAW_por]=0.2; +CARDADATA->parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +CARDADATA->parmin[P.PUW_por]=0.2; +CARDADATA->parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +CARDADATA->parmin[P.field_cap]=0.01; +CARDADATA->parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +CARDADATA->parmin[P.PAW_z]=0.01; +CARDADATA->parmax[P.PAW_z]=100; + +/*PUW depth (m)*/ +CARDADATA->parmin[P.PUW_z]=0.01; +CARDADATA->parmax[P.PUW_z]=100; + +/*Runoff excess*/ +CARDADATA->parmin[P.Q_excess]=0.01; +CARDADATA->parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +CARDADATA->parmin[P.Med_g1]=1.79; +CARDADATA->parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +CARDADATA->parmin[P.Vcmax25]=1e-8; +CARDADATA->parmax[P.Vcmax25]=140; + +/*Tminmin scaling factor*/ +CARDADATA->parmin[P.Tminmin]=258.15; +CARDADATA->parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +CARDADATA->parmin[P.Tminmax]=273.15; +CARDADATA->parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance*/ +CARDADATA->parmin[P.ga]=1.e-6; +CARDADATA->parmax[P.ga]=2.0; + +/*Tupp*/ +CARDADATA->parmin[P.Tupp]=299.15; +CARDADATA->parmax[P.Tupp]=318.15; + +/*Tdown*/ +CARDADATA->parmin[P.Tdown]=263.15; +CARDADATA->parmax[P.Tdown]=286.15; + +/*C3_frac*/ +CARDADATA->parmin[P.C3_frac]=1e-8; +CARDADATA->parmax[P.C3_frac]=1.0; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1001/DALEC_1001.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_1001(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*Surface runoff*/ + FLUXES[f+32] = deltat*(DATA.MET[m+8] - pars[36]*(1 - exp(-DATA.MET[m+8]/pars[36]))); + /*PAW total runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + /*Plant-available water ODE*/ + POOLS[nxp+6]=POOLS[p+6] + (DATA.MET[m+8] - FLUXES[f+28] - FLUXES[f+29] - FLUXES[f+30] - FLUXES[f+32])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1001/EDC2_1001.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1001(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1001/PARS_INFO_1001.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1001(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + +/*Maximum infiltration (mm/day)*/ +CARDADATA->parmin[36]=1; +CARDADATA->parmax[36]=300; + + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1001/MODEL_INFO_1001.c === + +#pragma once +#include "PARS_INFO_1001.c" +#include "DALEC_1001.c" +#include "EDC1_1001.c" +#include "EDC2_1001.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_1001(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=37; +DALECmodel.nofluxes=33; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1001; +DALECmodel.edc1=EDC1_1001; +DALECmodel.edc2=EDC2_1001; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); +PARS_INFO_1001(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1001/EDC1_1001.c === + +#pragma once +int EDC1_1001(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_PROXIMITY.c === + +#pragma once +#include +#include +#include + +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" + +//*************** State Proximity EDC ****************** +// Penalizes the model if the max-min difference among specified pools +// (e.g., annual mean soil temperatures) exceeds a defined threshold. + +typedef struct { + int no_pools_to_check; + int *pool_indices; + double max_allowed_diff; // E.g., 4.0 (degrees C) + double penalty_scale; // E.g., 1.0 (controls steepness of the quadratic penalty) +} DALEC_EDC_STATE_PROXIMITY_STRUCT; + +// General state proximity function +double DALEC_EDC_STATE_PROXIMITY(DATA * DATA, void * EDCstruct){ + + // Correctly cast the generic void pointer to your specific struct pointer + DALEC_EDC_STATE_PROXIMITY_STRUCT * E = (DALEC_EDC_STATE_PROXIMITY_STRUCT *) EDCstruct; + double PEDC = 0.0; + + double *TIME_INDEX = DATA->ncdf_data.TIME_INDEX.values; + DALEC *DALECmodel = (DALEC *)DATA->MODEL; + + int N_timesteps = DATA->ncdf_data.TIME_INDEX.length; + int nopools = DALECmodel->nopools; + double * POOLS = DATA->M_POOLS; + + // Derive deltat from TIME_INDEX (assuming continuous daily or monthly steps) + double deltat_double = TIME_INDEX[1] - TIME_INDEX[0]; + + // mean_annual_pool.c expects an integer deltat (e.g., 1 for daily data) + int deltat = (int)round(deltat_double); + if (deltat < 1) deltat = 1; // Failsafe + + // Calculate total number of complete years to evaluate + int num_years = (int)floor((N_timesteps * deltat_double) / 365.25); + + int yr, s, p; + + // Loop through each complete year + for (yr = 0; yr < num_years; yr++) { + + double min_mean = 1e9; + double max_mean = -1e9; + + // Check each pool for this specific year (using -> operator for pointer access) + for (s = 0; s < E->no_pools_to_check; s++) { + p = E->pool_indices[s]; + double mean_pool_yr = mean_annual_pool(POOLS, yr, p, nopools, deltat); + + // Track the maximum and minimum annual means across the layers + if (mean_pool_yr > max_mean) max_mean = mean_pool_yr; + if (mean_pool_yr < min_mean) min_mean = mean_pool_yr; + } + + double diff = max_mean - min_mean; + + // If the gradient exceeds your physical threshold, apply quadratic penalty + if (diff > E->max_allowed_diff) { + // Evaluates as: -0.5 * ((diff - threshold) / scale)^2 + PEDC += -0.5 * pow((diff - E->max_allowed_diff) / E->penalty_scale, 2.0); + } + } + + return PEDC; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_START_TEMP.c === + + +#pragma once +#include "../DALEC_ALL/SOIL_TEMP_AND_LIQUID_FRAC.c" +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" + + +typedef struct { + double min_temp;//Kelvin + double max_temp;//Kelvin + int vhc_idx; + int z_idx; + int por_idx; + + int i_SM_idx; + int i_E_idx;}DALEC_EDC_START_TEMP_STRUCT; + + + + + +//General inequality function +double DALEC_EDC_START_TEMP(DATA * DATA, void * EDCstruct){ + + + + DALEC_EDC_START_TEMP_STRUCT E = *(DALEC_EDC_START_TEMP_STRUCT * ) EDCstruct; + + //Declare stryct + SOIL_TEMP_AND_LIQUID_FRAC_STRUCT SOILTEMP; + //Populate with run-specific constrants + SOILTEMP.IN.dry_soil_vol_heat_capacity=DATA->M_PARS[E.vhc_idx] ;//J/m3/K + SOILTEMP.IN.depth = DATA->M_PARS[E.z_idx];//m + SOILTEMP.IN.soil_water =HYDROFUN_MOI2EWT(DATA->M_PARS[E.i_SM_idx],DATA->M_PARS[E.por_idx],DATA->M_PARS[E.z_idx]); + SOILTEMP.IN.internal_energy =DATA->M_PARS[E.i_E_idx]*DATA->M_PARS[E.z_idx];;//Joules + //Pass pointer to function + SOIL_TEMP_AND_LIQUID_FRAC(&SOILTEMP); //Outputs are in K + + + + //loop through all timesteps + + double PEDC=0; + + if (SOILTEMP.OUT.TEMPE.max_temp){PEDC = -INFINITY;} + + + + + + return PEDC; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_START_SM.c === + + +#pragma once +#include "../DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" + + + +typedef struct { + int z_idx; + int por_idx; + int i_H2O_idx;}DALEC_EDC_START_SM_STRUCT; + + + + + +//General inequality function +double DALEC_EDC_START_SM(DATA * DATA, void * EDCstruct){ + + + + DALEC_EDC_START_SM_STRUCT E = *(DALEC_EDC_START_SM_STRUCT * ) EDCstruct; + + + +double SM=HYDROFUN_EWT2MOI(DATA->M_PARS[E.i_H2O_idx],DATA->M_PARS[E.por_idx],DATA->M_PARS[E.z_idx]); + + + + //loop through all timesteps + + double PEDC=0; + + if (SM>1){PEDC = -INFINITY;} + + + + + + return PEDC; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_STATE_PROXIMITY.c === + +#pragma once +#include +#include +#include + +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" + +//*************** State Proximity EDC ****************** +// Penalizes the model if the max-min difference among specified pools +// (e.g., annual mean soil temperatures) exceeds a defined threshold. + +typedef struct { + int no_pools_to_check; + int *pool_indices; + double max_allowed_diff; // E.g., 4.0 (degrees C) + double penalty_scale; // E.g., 1.0 (controls steepness of the quadratic penalty) +} DALEC_EDC_STATE_PROXIMITY_STRUCT; + +// General state proximity function +double DALEC_EDC_STATE_PROXIMITY(void * data, DATA * DATA, int prerun){ + + // Correctly cast the generic void pointer to your specific struct pointer + DALEC_EDC_STATE_PROXIMITY_STRUCT * E = (DALEC_EDC_STATE_PROXIMITY_STRUCT *) data; + double PEDC = 0.0; + + double *TIME_INDEX = DATA->ncdf_data.TIME_INDEX.values; + DALEC *DALECmodel = (DALEC *)DATA->MODEL; + + int N_timesteps = DATA->ncdf_data.TIME_INDEX.length; + int nopools = DALECmodel->nopools; + double * POOLS = DATA->M_POOLS; + + // Derive deltat from TIME_INDEX (assuming continuous daily or monthly steps) + double deltat_double = TIME_INDEX[1] - TIME_INDEX[0]; + + // mean_annual_pool.c expects an integer deltat (e.g., 1 for daily data) + int deltat = (int)round(deltat_double); + if (deltat < 1) deltat = 1; // Failsafe + + // Calculate total number of complete years to evaluate + int num_years = (int)floor((N_timesteps * deltat_double) / 365.25); + + int yr, s, p; + + // Loop through each complete year + for (yr = 0; yr < num_years; yr++) { + + double min_mean = 1e9; + double max_mean = -1e9; + + // Check each pool for this specific year (using -> operator for pointer access) + for (s = 0; s < E->no_pools_to_check; s++) { + p = E->pool_indices[s]; + double mean_pool_yr = mean_annual_pool(POOLS, yr, p, nopools, deltat); + + // Track the maximum and minimum annual means across the layers + if (mean_pool_yr > max_mean) max_mean = mean_pool_yr; + if (mean_pool_yr < min_mean) min_mean = mean_pool_yr; + } + + double diff = max_mean - min_mean; + + // If the gradient exceeds your physical threshold, apply quadratic penalty + if (diff > E->max_allowed_diff) { + // Evaluates as: -0.5 * ((diff - threshold) / scale)^2 + PEDC += -0.5 * pow((diff - E->max_allowed_diff) / E->penalty_scale, 2.0); + } + } + + return PEDC; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_NSC_ABGB_RATIO.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* + + + + + + +//Doing all pools +typedef struct { + int no_other_pool_indices; + int *other_pool_indices; + int nsc_pool_index; +} DALEC_EDC_NSC_ABGB_RATIO_STRUCT; + + +//General inequality function +double DALEC_EDC_NSC_ABGB_RATIO(DATA * DATA, void * EDCstruct){ + + + + + //Casting struct + + DALEC_EDC_NSC_ABGB_RATIO_STRUCT E = *(DALEC_EDC_NSC_ABGB_RATIO_STRUCT * ) EDCstruct; + + + + double *TIME_INDEX=DATA->ncdf_data.TIME_INDEX.values; + + DALEC *DALECmodel=(DALEC *)DATA->MODEL; + + + + + int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + +int nopools=DALECmodel->nopools; +int nofluxes=DALECmodel->nofluxes; + + //int nopools=DATA->nopools; + + + + //Looping through all pools + + //Pool inde + + +double M_NSC=mean_pool(DATA->M_POOLS,E.nsc_pool_index,N_timesteps+1,nopools); + + double M_ALL_ELSE=0; + +int n; + for (n=0;n< E.no_other_pool_indices;n++){M_ALL_ELSE+=mean_pool(DATA->M_POOLS,E.other_pool_indices[n],N_timesteps+1,nopools);} + + + double residual = (M_NSC/(M_NSC+M_ALL_ELSE) - 0.1)/0.05; +double PEDC=-0.5*residual*residual; + +//printf(" M_NSC = %2.2f, M_ALL_ELSE = %2.2f, PEDC = %2.2f\n", M_NSC,M_ALL_ELSE,PEDC); + + return PEDC; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c === + +// static int attempt_count[100]; +// static int pass_count[100]; + + +typedef struct { + double * min_val; + double * max_val; +}DALEC_EDC_STATE_RANGES_STRUCT; + + +//General inequality function +double DALEC_EDC_STATE_RANGES(DATA * DATA, void * EDCstruct){ + + + double PEDC = 0; + //Reading by casting void pointer to "DALEC_EDC_PARS_INEQUALITY_STRUCT" format + DALEC_EDC_STATE_RANGES_STRUCT E = *(DALEC_EDC_STATE_RANGES_STRUCT * ) EDCstruct; + //Checking range + + //loop through all timesteps + int p=0,k=0; + +while (PEDC==0 & pnopools & k==0 ){ + //looping through timesteps + int n=0; + //attempt_count[p]+=1; + +while (PEDC==0 & nncdf_data.TIME_INDEX.length & k==0){ + + + + if (DATA->M_POOLS[p+n*DATA->nopools]M_POOLS[p+n*DATA->nopools]>E.max_val[p]){PEDC = -INFINITY;k=-1;} + + + //if (p == 18){printf("E.max_val[p] = %2.2f, E.min_val[p] = %2.2f, SM = %2.2f\n",E.max_val[p], E.min_val[p],DATA->M_POOLS[p+n*DATA->nopools]);} + + n+=1;} + //if(k==0){pass_count[p]+=1;} + + + p+=1; + +} +// if (k==0){ +// for (p=0;pnopools;p++){ +// printf("pool %i; Attempt = %i, Pass = %i, Percent = %2.2f\%\n",p,attempt_count[p], pass_count[p], 100*(double)pass_count[p]/(double)attempt_count[p]); +// }} + //printf("Fail check = %2.2i\n",p); + + + + return PEDC; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* + + + + + + +//Doing all pools +typedef struct { + int no_pools_to_check; + int *pool_indices; + double *pool_eqf; +} DALEC_EDC_TRAJECTORY_STRUCT; + + +//General inequality function +double DALEC_EDC_TRAJECTORY(DATA * DATA, void * EDCstruct){ + + + + + //Casting struct + + DALEC_EDC_TRAJECTORY_STRUCT E = *(DALEC_EDC_TRAJECTORY_STRUCT * ) EDCstruct; + + + double PEDC = 0; + +double *TIME_INDEX=DATA->ncdf_data.TIME_INDEX.values; + +DALEC *DALECmodel=(DALEC *)DATA->MODEL; + + +int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + +int nopools=DALECmodel->nopools; +int nofluxes=DALECmodel->nofluxes; + + //Looping through all pools + +/*deriving mean pools here!*/ +int s,n,m,i,p; +PEDC=0; + +double * FLUXES = DATA->M_FLUXES; +double * POOLS = DATA->M_POOLS; + +double *FT; +FT=calloc(nofluxes,sizeof(double)); + +int f=0; +for (f=0;fM_POOLS,p,N_timesteps+1,nopools); + + /*deriving mean January pools*/ + /*Assuming COMPLETE years*/ + + /*pool interval*/ + int dint=(int)floor(N_timesteps/(TIME_INDEX[N_timesteps-1]-TIME_INDEX[0])*365.25); + /*declaring mean pool array*/ + + /*deriving mean jan pools*/ + /*based on all jan pools except initial conditions*/ + + + + for (m=0;m<(N_timesteps/dint+1);m++){ + MPOOLSjan=MPOOLSjan+POOLS[nopools*(m*dint)+p]/(N_timesteps/dint+1);} + + + //Next step: + //Loop through all fluxes + //For each pool create "Fin" and "Fout", and add these to fluxe + double Fin=0, Fout=0, Ftemp=0; + for (i=0;iSIOMATRIX[p].N_STATE_INPUT_FLUXES;i++){ + double Ftemp = FT[DALECmodel->SIOMATRIX[p].STATE_INPUT_FLUXES[i]]; + if (Ftemp<0){Fout +=Ftemp;} //if any N_STATE_INPUT_FLUXES are negative, put them in Fout + else {Fin += Ftemp;}} + + for (i=0;iSIOMATRIX[p].N_STATE_OUTPUT_FLUXES;i++){ + double Ftemp= FT[DALECmodel->SIOMATRIX[p].STATE_OUTPUT_FLUXES[i]]; + if (Ftemp<0){Fin +=Ftemp;} //if any N_STATE_OUTPUT_FLUXES are negative, put them in Fin + else {Fout += Ftemp;}} + // + // double Fin[10]; + // double Fout[10]; + double Pstart; + double Pend; + /*temporary print switch*/ + int psw=0; + /*exponential decay tolerance*/ + double etol=.1; + + /*Inlcuding H2O pool*/ + /*EDCs 7-13 - inputs, outputs and exponential tolerance*/ + + /*mean input/output ratio and start ratio*/ + double Rm, Rs; + + /*start and end pools*/ + Pstart=POOLS[p]; + Pend=POOLS[nopools*N_timesteps+p]; + /*mean input/output*/ + Rm=Fin/Fout; + /*Theoretical starting input/output*/ + Rs=Rm*MPOOLSjan/Pstart; + /*EB test version*/ + // Rs=MPOOLSjan/Pstart; + +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ + +// PEDC+=-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + /*EB test version*/ + PEDC+=-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow(log(Rs/Rm)/log(1+etol),2); + +// printf("******Pool p = %i *********\n",p); +// +// printf("p = %i\n",s); +// printf("-0.5*pow(log(Rs)/log(EQF),2) = %2.2f\n",-0.5*pow(log(Rs)/log(EQF),2)); +// printf("- 0.5 *pow((Rs-Rm)/etol,2) = %2.2f\n",- 0.5 *pow((Rs-Rm)/etol,2)); +// // +// +// printf("Rs = %2.2f\n",Rs); +// printf("Rm = %2.2f\n",Rm); +// +// printf("log(Rs) = %2.2f\n",log(Rs)); +// +// printf("-0.5*pow(log(Rs)/log(EQF),2) = %2.2f\n",-0.5*pow(log(Rs)/log(EQF),2)); +// printf("Fin = %2.2f\n", Fin); +// printf("dint = %i\n", dint); +// printf("Fout = %2.2f\n", Fout); +// printf("Pstart = %2.2f\n", Pstart); +// printf("Pend = %2.2f\n", Pend); +// printf("MPOOLSjan= %2.2f\n", MPOOLSjan); +// +// printf("EQF P = %2.2f\n", -0.5*pow(log(Rs)/log(EQF),2)); +// printf("Etol P = %2.2f\n", - 0.5 *pow((Rs-Rm)/etol,2)); +// printf("PEDC = %2.2f\n",PEDC); + + } + free(FT); + // printf("PEDC = %2.2f\n",PEDC); + return PEDC; +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_MEAN_POOL_INEQUALITY.c === + + +/*EDC no 6*/ +/*0.2*Cf < Cr < 5*Cf*/ +/*Cfoliar : Croot = 5:1 or 1:5*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ + + + +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_PARAMETER_INEQUALITY.c === + + + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* +typedef struct { + int big_par_index; + int small_par_index;}DALEC_EDC_PARAMETER_INEQUALITY_STRUCT; + + +//General inequality function +double DALEC_EDC_PARAMETER_INEQUALITY(DATA * DATA, void * EDCstruct){ + + double PEDC = 0; + + //Reading by casting void pointer to "DALEC_EDC_PARS_INEQUALITY_STRUCT" format + DALEC_EDC_PARAMETER_INEQUALITY_STRUCT E = *(DALEC_EDC_PARAMETER_INEQUALITY_STRUCT * ) EDCstruct; + //Checking inequality + + + if (DATA->M_PARS[E.big_par_index]M_PARS[E.small_par_index]){PEDC = -INFINITY;} ; + + + + return PEDC; + + +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_MEAN_STATE.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* + + + + + + +//Doing all pools +typedef struct { + int state_index; + double mean_state; + double mean_state_unc; +} DALEC_EDC_MEAN_STATE_STRUCT; + + +//General inequality function +double DALEC_EDC_MEAN_STATE(DATA * DATA, void * EDCstruct){ + + + //Casting struct + + DALEC_EDC_MEAN_STATE_STRUCT E = *(DALEC_EDC_MEAN_STATE_STRUCT * ) EDCstruct; + + + + double *TIME_INDEX=DATA->ncdf_data.TIME_INDEX.values; + + DALEC *DALECmodel=(DALEC *)DATA->MODEL; + + + + +int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + +int nopools=DALECmodel->nopools; + + + + +double MEAN_STATE=mean_pool(DATA->M_POOLS,E.state_index,N_timesteps+1,nopools); + + + double residual = (MEAN_STATE - E.mean_state)/E.mean_state_unc; +double PEDC=-0.5*residual*residual; + +//printf(" M_NSC = %2.2f, M_ALL_ELSE = %2.2f, PEDC = %2.2f\n", M_NSC,M_ALL_ELSE,PEDC); + + return PEDC; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_MEAN_PAW_TEMP.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* + + + + + + +//Doing all pools +typedef struct { + int temp_index; +} DALEC_EDC_MEAN_TEMP_STRUCT; + + +//General inequality function +double DALEC_EDC_MEAN_TEMP(DATA * DATA, void * EDCstruct){ + + //Casting struct + + DALEC_EDC_MEAN_TEMP_STRUCT E = *(DALEC_EDC_MEAN_TEMP_STRUCT * ) EDCstruct; + + + + double *TIME_INDEX=DATA->ncdf_data.TIME_INDEX.values; + + DALEC *DALECmodel=(DALEC *)DATA->MODEL; + + + + +int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + +int nopools=DALECmodel->nopools; + + + + +double MEAN_TEMP=mean_pool(DATA->M_POOLS,E.temp_index,N_timesteps+1,nopools); + + + double residual = (MEAN_TEMP - DATA->ncdf_data.SKT.reference_mean - DGCM_TK0C)/5; + + + +double PEDC=-0.5*residual*residual; + +//printf(" M_NSC = %2.2f, M_ALL_ELSE = %2.2f, PEDC = %2.2f\n", M_NSC,M_ALL_ELSE,PEDC); + return PEDC; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_FUNCTIONS.c === + +//List functions here + + +#pragma once +#include "DALEC_EDC_PARAMETER_INEQUALITY.c" +#include "DALEC_EDC_PARAMETER_LOG_RATIO.c" +#include "DALEC_EDC_STATE_RANGES.c" +#include "DALEC_EDC_TRAJECTORY.c" +#include "DALEC_EDC_START_TEMP.c" +#include "DALEC_EDC_START_SM.c" +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "DALEC_EDC_NSC_ABGB_RATIO.c" +#include "DALEC_EDC_POOL_RATIO.c" +#include "DALEC_EDC_FLUX_RATIO.c" +#include "DALEC_EDC_MEAN_PAW_TEMP.c" +#include "DALEC_EDC_PARAMETER_ZEROONE.c" +#include "DALEC_EDC_STATE_PROXIMITY.c" + + + + + + +// +double RUN_DALEC_EDCs(DATA * DATA, EDCs * EDCs, bool prerun){ + + //Step 0; back out EDC structure. + //Continue from here: need to probably allow for EDCs to be standalone DATA field to allow for more versatile code(maybe) later on + + + int n=0; + + + + double P=0; + for (n=0;nnoedcs;n++){ + + + //Run function + if (EDCs[n].prerun==prerun){ + +//Add EDC.diagnostic_mode = 1 here + if (P>-INFINITY){ + DATA->M_EDCs[n]=EDCs[n].function(DATA, EDCs[n].data); + DATA->EDC_INSTANCE_COUNTER[n]+=1; + + //Add all probs up + P+=DATA->M_EDCs[n]; + //if (EDCs[n].prerun==0){ printf("n = %i; DATA->M_EDCs[n] = %2.2f; P = %2.2f\n",n,DATA->M_EDCs[n],P);}; + + //counting EDC passes + if (isfinite(DATA->M_EDCs[n])){DATA->EDC_PASS_COUNTER[n]+=1;} + + //printf("Inside run EDCs: DATA->M_EDCs[%i] = %2.2f\n",n,DATA->M_EDCs[n] ); + + + } +// else { if (EDCs[n].prerun==false){ printf("EDC fail = %i\n",n);}} + + }} + + + + + + + + return P; + + + + } + + + + + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_FLUX_IN_OUT_RATIO.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* + + + + + + +//Doing all pools +typedef struct { + int no_input_pools; + int *input_pool_indices; + int no_output_pools; + int *output_pool_indices; +} DALEC_EDC_FLUX_IN_OUT_RATIO_STRUCT; + + +//General inequality function +double DALEC_EDC_FLUX_IN_OUT_RATIO(DATA * DATA, void * EDCstruct){ + + + + + //Casting struct + + DALEC_EDC_NSC_ABGB_RATIO_STRUCT E = *(DALEC_EDC_NSC_ABGB_RATIO_STRUCT * ) EDCstruct; + + + + double *TIME_INDEX=DATA->ncdf_data.TIME_INDEX.values; + + DALEC *DALECmodel=(DALEC *)DATA->MODEL; + + + + + int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + +int nopools=DALECmodel->nopools; +int nofluxes=DALECmodel->nofluxes; + + //int nopools=DATA->nopools; + + + + //Looping through all pools + + //Pool inde + + +double M_NSC=mean_pool(DATA->M_POOLS,E.nsc_pool_index,N_timesteps+1,nopools); + + double M_ALL_ELSE=0; + +int n; + for (n=0;n< E.no_other_pool_indices;n++){M_ALL_ELSE+=mean_pool(DATA->M_POOLS,E.other_pool_indices[n],N_timesteps+1,nopools);} + + + double residual = (M_NSC/(M_NSC+M_ALL_ELSE) - 0.1)/0.05; +double PEDC=-0.5*residual*residual; + +//printf(" M_NSC = %2.2f, M_ALL_ELSE = %2.2f, PEDC = %2.2f\n", M_NSC,M_ALL_ELSE,PEDC); + + return PEDC; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_PARAMETER_ZEROONE.c === + + + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_ZEROONE********* +typedef struct { + int parone; + int partwo; + int parthree;}DALEC_EDC_PARAMETER_ZEROONE_STRUCT; + + +//General inequality function +double DALEC_EDC_PARAMETER_ZEROONE(DATA * DATA, void * EDCstruct){ + + double PEDC = 0; + + //Reading by casting void pointer to "DALEC_EDC_PARS_INEQUALITY_STRUCT" format + DALEC_EDC_PARAMETER_ZEROONE_STRUCT E = *(DALEC_EDC_PARAMETER_ZEROONE_STRUCT * ) EDCstruct; + //Checking inequality + + + if (DATA->M_PARS[E.parone]+DATA->M_PARS[E.partwo]+DATA->M_PARS[E.parthree] >= 1 ){ + PEDC = -INFINITY; + } ; + + + + return PEDC; + + +} + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_PARAMETER_LOG_RATIO.c === + + + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* +typedef struct { + int numerator_index; + int denominator_index; + double mean_ratio; + double std_ratio; + }DALEC_EDC_PARAMETER_LOG_RATIO_STRUCT; + + +//General inequality function +double DALEC_EDC_PARAMETER_LOG_RATIO(DATA * DATA, void * EDCstruct){ + + + //Reading by casting void pointer to "DALEC_EDC_PARS_INEQUALITY_STRUCT" format + DALEC_EDC_PARAMETER_LOG_RATIO_STRUCT E = *(DALEC_EDC_PARAMETER_LOG_RATIO_STRUCT * ) EDCstruct; + + double mod_ratio = log(DATA->M_PARS[E.numerator_index])/log(DATA->M_PARS[E.denominator_index]); + double residual = (mod_ratio - E.mean_ratio)/E.std_ratio; + double PEDC=-0.5*residual*residual; + + + return PEDC; + + +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_POOL_RATIO.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c"//Includes all calls to DALEC-compatible EDC functions +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + +//***************Constrain ratio of Croot:Cfol to be within 1:5 to 5:1 ****************** + + +//Get indices for root and foliar C pools +typedef struct { + int numerator_index; + int denominator_index; +} DALEC_EDC_POOL_RATIO_STRUCT; + + +double DALEC_EDC_POOL_RATIO(DATA * DATA, void * EDCstruct){ + + //Casting struct + + DALEC_EDC_POOL_RATIO_STRUCT E = *(DALEC_EDC_POOL_RATIO_STRUCT * ) EDCstruct; + + + double *TIME_INDEX=DATA->ncdf_data.TIME_INDEX.values; + + DALEC *DALECmodel=(DALEC *)DATA->MODEL; + + + int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + +int nopools=DALECmodel->nopools; + +//compute mean foliar and mean root pool sizes + +double M_NUMERATOR=mean_pool(DATA->M_POOLS,E.numerator_index,N_timesteps+1,nopools); +double M_DENOMINATOR=mean_pool(DATA->M_POOLS,E.denominator_index,N_timesteps+1,nopools); + +double residual= log(M_NUMERATOR/M_DENOMINATOR)/log(2); + +double PEDC=-0.5*residual*residual; + + return PEDC; +} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/NSC_RATIO_init.c === + + + +//***************General inequality EDC****************** +//***************DALEC_EDC_PARS_INEQUALITY********* +typedef struct { + int big_par_index; + int small_par_index;}DALEC_EDC_PARAMETER_INEQUALITY_STRUCT; + + +//General inequality function +double DALEC_EDC_PARAMETER_INEQUALITY(DATA * DATA, void * EDCstruct){ + + double PEDC = 0; + + //Reading by casting void pointer to "DALEC_EDC_PARS_INEQUALITY_STRUCT" format + DALEC_EDC_PARAMETER_INEQUALITY_STRUCT E = *(DALEC_EDC_PARAMETER_INEQUALITY_STRUCT * ) EDCstruct; + //Checking inequality + + + if (DATA->M_PARS[E.big_par_index]M_PARS[E.small_par_index]){PEDC = -INFINITY;} ; + + + + return PEDC; + + +} + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_FLUX_RATIO.c === + +#pragma once +#include "../DALEC_ALL/mean_flux.c" + + +/* Constraining ratios of C allocation: in v1006, there was: +"EDC CHECK NO 5: Allocation to canopy is comparable to allocation to fine roots +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;}" + +Comparable formulation of ((ffol+flab)>5*froot | (ffol+flab)*5ARFLUXES.ALLOC_ROO_ACTUAL || (ARFLUXES.ALLOC_FOL_ACTUAL+(ARFLUXES.F_LABPROD-ARFLUXES.F_LABREL_ACTUAL))*5ncdf_data.TIME_INDEX.values; + + DALEC *DALECmodel=(DALEC *)DATA->MODEL; + + int N_timesteps=DATA->ncdf_data.TIME_INDEX.length; + +int nofluxes=DALECmodel->nofluxes; + +//compute mean foliar and mean root allocation fluxes + +double M_FNUMERATOR=mean_flux(DATA->M_FLUXES,E.numerator_flux_index,N_timesteps,nofluxes); +double M_FDENOMINATOR=mean_flux(DATA->M_FLUXES,E.denominator_flux_index,N_timesteps,nofluxes); + +double residual= log(M_FNUMERATOR/M_FDENOMINATOR)/log(2); + +double PEDC=-0.5*residual*residual; + + return PEDC; +} + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_811/PARS_INFO_811.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_811(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_811/EDC2_811.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_811(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_811/MODEL_INFO_811.c === + +#pragma once +#include "PARS_INFO_811.c" +#include "DALEC_811.c" +#include "EDC1_811.c" +#include "EDC2_811.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_811(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_811; +DALECmodel.edc1=EDC1_811; +DALECmodel.edc2=EDC2_811; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_811(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_811/EDC1_811.c === + +#pragma once +int EDC1_811(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_811/DALEC_811.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_811(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1006/EDC2_1006.c === + +#pragma once +#include "../DALEC_ALL/mean_pool.c" +#include "../DALEC_ALL/mean_annual_pool.c" +#include "../DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1006(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1006_PARAMETERS P=DALEC_1006_PARAMETERS; +struct DALEC_1006_FLUXES F=DALEC_1006_FLUXES; +struct DALEC_1006_POOLS S=DALEC_1006_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int noprogpools=8;//Prognostic pools only for EDCs +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;npEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=DATA.ncdf_data.EDC_EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;f 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + + +if (psw==1){ +printf("****\n"); +printf("DIAG = %i\n", DIAG); +printf("EDC = %i\n",EDC); +printf("EDCD->SWITCH[7-1+n] = %i\n",EDCD->SWITCH[7-1+n]); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Rs)) = %f\n",fabs(log(Rs))); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_lit,P.i_som,P.i_PAW,P.i_PUW}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + +/*Returning EDC */ +return EDC; + + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1006/DALEC_1006.c === + +#pragma once +#include "../DALEC_ALL/DALEC_MODULE.c" +#include "DALEC_1006_INDICES.c" + + +int DALEC_1006(DATA DATA, double const *pars) +{ + +struct DALEC_1006_PARAMETERS P=DALEC_1006_PARAMETERS; +struct DALEC_1006_FLUXES F=DALEC_1006_FLUXES; +struct DALEC_1006_POOLS S=DALEC_1006_POOLS; + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[P.canopy_eff],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +//double *LAI=DATA.M_LAI; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_som]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + /****Diagnostic states***/ + POOLS[S.D_LAI]=POOLS[S.C_fol]/pars[P.LCMA]; //LAI + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +double LAI=POOLS[p+S.D_LAI]; +//LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; +/*GPP*/ +gpppars[0]=LAI; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + + +/*GPP*/ +FLUXES[f+F.gpp]=ACM(gpppars,constants)*fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1); +/*Evapotranspiration*/ +FLUXES[f+F.et]=FLUXES[f+F.gpp]*sqrt(VPD[n])/pars[P.uWUE]+SSRD[n]*pars[P.boese_r]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=exp(pars[P.temp_factor]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+F.woo2som] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.roo2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.woo2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.roo2lit] - FLUXES[f+F.resp_het_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som]= POOLS[p+S.C_som]+ (FLUXES[f+F.lit2som] - FLUXES[f+F.resp_het_som]+FLUXES[f+F.woo2som])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+S.H2O_PAW]);*/ + /*PAW total runoff*/ + + FLUXES[f+F.q_paw]=pow(POOLS[p+S.H2O_PAW],2)/pars[P.PAW_Qmax]/deltat*(1-pars[P.h2o_xfer]); + /*PAW -> PUW transfer*/ + FLUXES[f+F.paw2puw]=FLUXES[f+F.q_paw]*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]); + /*PUW runoff*/ + FLUXES[f+F.q_puw]=pow(POOLS[p+S.H2O_PUW],2)/pars[P.PUW_Qmax]/deltat; + /*Maximum water loss at W = pars[P.PAW_Qmax]/2;*/ + if (POOLS[p+S.H2O_PAW]>pars[P.PAW_Qmax]/2){FLUXES[f+F.q_paw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*(1-pars[P.h2o_xfer]); + FLUXES[f+F.paw2puw]=(POOLS[p+S.H2O_PAW]-pars[P.PAW_Qmax]/4)/deltat*pars[P.h2o_xfer]/(1-pars[P.h2o_xfer]);} + if (POOLS[p+S.H2O_PUW]>pars[P.PUW_Qmax]/2){FLUXES[f+F.q_puw]=(POOLS[p+S.H2O_PUW]-pars[P.PUW_Qmax]/4)/deltat;} + + POOLS[nxp+S.H2O_PAW]=POOLS[p+S.H2O_PAW] + (-FLUXES[f+F.q_paw] - FLUXES[f+F.paw2puw] + PREC[n] - FLUXES[f+F.et])*deltat; + + + /*Plant-unavailable water budget*/ + + POOLS[nxp+S.H2O_PUW]=POOLS[p+S.H2O_PUW] + (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2som] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2som])*deltat; + /*dead C pools*/ + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_woo2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + + + /***RECORD t+1 DIAGNOSTIC STATES*****/ + POOLS[nxp+S.D_LAI]=POOLS[nxp+S.C_fol]/pars[P.LCMA]; //LAI + +} + +return 0; +} + + + + + +int DALEC_1006_MODCONFIG(DALEC * DALECmodel){ + +struct DALEC_1006_PARAMETERS P=DALEC_1006_PARAMETERS; +struct DALEC_1006_FLUXES F=DALEC_1006_FLUXES; +struct DALEC_1006_POOLS S=DALEC_1006_POOLS; + +DALECmodel->nopools=9; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=37; +DALECmodel->nofluxes=32; +DALECmodel->dalec=DALEC_1006; + + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1006_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_CWOO_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_Cefficiency_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; + + + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_pool=S.D_LAI; +//ET variabiles +OBSOPE.ET_flux=F.et; +//NBE-specific variables +static int NBE_fluxes[5]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.resp_het_lit; +NBE_fluxes[3]=F.resp_het_som; +NBE_fluxes[4]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//ABGB-specific variables +static int CWOO_pools[1]; +CWOO_pools[0]=S.C_woo; +OBSOPE.CWOO_pools=CWOO_pools; +OBSOPE.CWOO_n_pools=1; + +//DOM-specific variables +static int DOM_pools[2]; +DOM_pools[0]=S.C_lit; +DOM_pools[1]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[2]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; + +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +OBSOPE.Cefficiency_PARAM=P.canopy_eff; +OBSOPE.iniSOM_PARAM=P.i_som; + + + + + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1006/DALEC_1006_INDICES.c === + + +struct DALEC_1006_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int f_auto; +int f_foliar; +int f_root; +int t_foliar; +int t_wood; +int t_root; +int t_lit; +int t_soil; +int temp_factor; +int canopy_eff; +int Bday; +int f_lab; +int labile_rel; +int Fday; +int leaf_fall; +int LCMA; +int i_labile; +int i_foliar; +int i_root; +int i_wood; +int i_lit; +int i_som; +int uWUE; +int PAW_Qmax; +int wilting; +int i_PAW; +int cf_foliar; +int cf_ligneous; +int cf_DOM; +int resilience; +int t_labile; +int moisture; +int h2o_xfer; +int PUW_Qmax; +int i_PUW; +int boese_r; +} DALEC_1006_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36 +}; + +struct DALEC_1006_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int woo2som; /*Wood description*/ +int roo2lit; /*Root decomposition*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2som; /*Fire transfer wood to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*Plant-available water drainage*/ +int paw2puw; /*Plant-available water to plant-unavailable water transfer*/ +int q_puw; /*Plant-unavailable water runoff*/ +} DALEC_1006_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31 +}; + +struct DALEC_1006_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int D_LAI;//leaf area index +} DALEC_1006_POOLS={0,1,2,3,4,5,6,7,8}; + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1006/EDC1_1006.c === + +#pragma once +int EDC1_1006(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1006_PARAMETERS P=DALEC_1006_PARAMETERS; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +// if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[P.PAW_Qmax]PASSFAIL[17-1]=0;} + + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1006/MODEL_INFO_1006.c === + +#pragma once +#include "PARS_INFO_1006.c" +#include "DALEC_1006.c" +#include "EDC1_1006.c" +#include "EDC2_1006.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../DALEC_CODE/EDCs/EDCSETUP.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1006(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel;DALEC_1006_MODCONFIG(&DALECmodel); +static MLF MLF;DALEC_MLF_DEDC_MODCONFIG(&MLF); + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; +DATA->nolikelihoods=MLF.nolikelihoods; + + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.edc1=EDC1_1006; +DALECmodel.edc2=EDC2_1006; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1006(DATA->parmin, DATA->parmax); + + +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=MLF.mlf; +DATA->EMLF=EDC_DALEC_MLF_BINARY; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1006/PARS_INFO_1006.c === + +#pragma once +#include "DALEC_1006.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1006(double *parmin, double *parmax) +{ + +struct DALEC_1006_PARAMETERS P=DALEC_1006_PARAMETERS; + +/*Decomposition rate*/ +parmin[P.tr_lit2soil]=0.00001; +parmax[P.tr_lit2soil]=0.01; + +/*Fraction of GPP respired*/ +parmin[P.f_auto]=0.2; +parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +parmin[P.f_foliar]=0.01; +parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +parmin[P.f_root]=0.01; +parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +parmin[P.t_foliar]=1.001; +parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +parmin[P.t_wood]=0.000025; +parmax[P.t_wood]=0.001; + +/*TOR roots*/ +parmin[P.t_root]=0.0001; +parmax[P.t_root]=0.01; + +/*TOR litter*/ +parmin[P.t_lit]=0.0001; +parmax[P.t_lit]=0.01; + +/*TOR SOM*/ +parmin[P.t_soil]=0.0000001; +parmax[P.t_soil]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +parmin[P.temp_factor]=0.018; +parmax[P.temp_factor]=0.08; + +/*Canopy Efficiency*/ +parmin[P.canopy_eff]=5; +parmax[P.canopy_eff]=50; + +/*Bday*/ +parmin[P.Bday]=365.25; +parmax[P.Bday]=1461.0;//365.25*4 + +/*Fraction to Clab*/ +parmin[P.f_lab]=0.01; +parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +parmin[P.labile_rel]=30.4375; //365.25/12 +parmax[P.labile_rel]=100; + +/*Fday*/ +parmin[P.Fday]=365.25; +parmax[P.Fday]=1461.0;//365.25*4 + +/*Leaf fall period*/ +parmin[P.leaf_fall]=30.4375; //365.25/12 +parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parmin[P.LCMA]=5; +parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parmin[P.i_labile]=1.0; +parmax[P.i_labile]=2000.0; + +/*C foliar*/ +parmin[P.i_foliar]=1.0; +parmax[P.i_foliar]=2000.0; + +/*C roots*/ +parmin[P.i_root]=1.0; +parmax[P.i_root]=2000.0; + +/*C_wood*/ +parmin[P.i_wood]=1.0; +parmax[P.i_wood]=100000.0; + +/*C litter*/ +parmin[P.i_lit]=1.0; +parmax[P.i_lit]=2000.0; + +/*C_som*/ +parmin[P.i_som]=1.0; +parmax[P.i_som]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +/*The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.uWUE]=0.5; +parmax[P.uWUE]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PAW_Qmax]=1; +parmax[P.PAW_Qmax]=100000; + +/*"Wilting point"*/ +parmin[P.wilting]=1; +parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +parmin[P.i_PAW]=1; +parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +parmin[P.cf_foliar]=0.01; +parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +parmin[P.cf_ligneous]=0.01; +parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +parmin[P.cf_DOM]=0.01; +parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +parmin[P.resilience]=0.01; +parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +parmin[P.t_labile]=1.001; +parmax[P.t_labile]=8; + +/*Moisture factor*/ +parmin[P.moisture]=0.01; +parmax[P.moisture]=1; + +/*PAW->PUW runoff fraction*/ +parmin[P.h2o_xfer]=0.01; +parmax[P.h2o_xfer]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parmin[P.PUW_Qmax]=1; +parmax[P.PUW_Qmax]=100000; + +/*PUW pool*/ +parmin[P.i_PUW]=1; +parmax[P.i_PUW]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +parmin[P.boese_r]=0.01; +parmax[P.boese_r]=0.3; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1030/DALEC_1030.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +int DALEC_1030(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff + 32. Potential GPP +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+32]=ACM(gpppars,constants); +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1)*(1/(1+DATA.MET[m+7]/pars[36])); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + /*Plant-available water ODE*/ + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1030/EDC2_1030.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1030(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1030/PARS_INFO_1030.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1030(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + +/*Reference VPD*/ +/* for Leuning et al, 1995 eq. 7*/ +CARDADATA->parmin[36]=1; +CARDADATA->parmax[36]=10000; + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1030/EDC1_1030.c === + +#pragma once +int EDC1_1030(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1030/MODEL_INFO_1030.c === + +#pragma once +#include "PARS_INFO_1030.c" +#include "DALEC_1030.c" +#include "EDC1_1030.c" +#include "EDC2_1030.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1030(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=37; +DALECmodel.nofluxes=33; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1030; +DALECmodel.edc1=EDC1_1030; +DALECmodel.edc2=EDC2_1030; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1030(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_820/PARS_INFO_820.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_820(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*Mortality onset (as scale-factor of wilting point)*/ +CARDADATA->parmin[33]=0.1; +CARDADATA->parmax[33]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_820/EDC2_820.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_820(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_820/MODEL_INFO_820.c === + +#pragma once +#include "PARS_INFO_820.c" +#include "DALEC_820.c" +#include "EDC1_820.c" +#include "EDC2_820.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_820(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=34; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_820; +DALECmodel.edc1=EDC1_820; +DALECmodel.edc2=EDC2_820; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_820(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_820/EDC1_820.c === + +#pragma once +int EDC1_820(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_820/DALEC_820.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_820(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + +/*mortality factor*/ +double mf; + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Mortality factor*/ +mf=fmin(POOLS[p+6]/(pars[25]*pars[33]),1); + +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/mf/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/mf/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/mf/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1009/PARS_INFO_1009.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1009(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*uWUE: GPP*sqrt(VPD)/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=0.5; +CARDADATA->parmax[23]=30; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + +/*r: The chosen prior range in r conservatively captures the range of values by Boese et al.(2017)*/ +CARDADATA->parmin[36]=0.01; +CARDADATA->parmax[36]=0.3; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1009/MODEL_INFO_1009.c === + +#pragma once +#include "PARS_INFO_1009.c" +#include "DALEC_1009.c" +#include "EDC1_1009.c" +#include "EDC2_1009.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1009(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=37; +DALECmodel.nofluxes=32; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1009; +DALECmodel.edc1=EDC1_1009; +DALECmodel.edc2=EDC2_1009; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1009(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1009/EDC1_1009.c === + +#pragma once +int EDC1_1009(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1009/DALEC_1009.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +int DALEC_1009(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*sqrt(DATA.MET[m+7])/pars[23]+DATA.MET[m+3]*pars[36]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + /*Plant-available water ODE*/ + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1009/EDC2_1009.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1009(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_821/MODEL_INFO_821.c === + +#pragma once +#include "PARS_INFO_821.c" +#include "DALEC_821.c" +#include "EDC1_821.c" +#include "EDC2_821.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_821(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_821_MODCONFIG(&DALECmodel); + + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_821; +DALECmodel.edc1=EDC1_821; +DALECmodel.edc2=EDC2_821; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_821(DATA); + + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_821/EDC1_821.c === + +#pragma once +int EDC1_821(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +/* Additional EDC1 on the ratio of Jmax/Vmax for ID 821 by gquetin 04/07/2020*/ +/*17. Jmax/Vmax > .8 and Jmax/Vmax < 1.25*/ + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[11]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + +/*EDC CHECK NO 17*/ +/*Jmax and Vmax related to each other, by G. Quetin 04.07.2020*/ +/*Updated by G. Quetin 06.05.2021, after bug fix update to higher value of Jmax per Vmax*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & ((pars[34]/pars[35]< 0.8) || (pars[34]/pars[35]> 2.2))){EDC=0;EDCD->PASSFAIL[17-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_821/DALEC_821.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/BALDOCCHI_ANALYTICAL.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +int DALEC_821_MODCONFIG(DALEC * DALECmodel){ + + + +DALECmodel->nopools=7; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=36; +DALECmodel->nofluxes=30; + + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_821_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=0; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=1; +OBSOPE.LAI_LCMA=15; +//ET variabiles +OBSOPE.ET_flux=28; +//NBE-specific variables +static int NBE_fluxes[]={0,2,12,13,16}; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[]={0,1,2,3}; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//SOM-specific variables +static int DOM_pools[]={4,5}; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[]={6}; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=1; +//Fire-specific variables +OBSOPE.FIR_flux=16; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + + +int DALEC_821(DATA DATA, double const *pars) +{ + +double met_list[6],var_list[10],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; + + +//double *LAI=DATA.M_LAI; +//double *NEE=DATA.M_NEE; + +/*assigning values to pools*/ +/*L,F,R,W,Lit,SOM*/ +POOLS[0]=pars[16]; +POOLS[1]=pars[17]; +POOLS[2]=pars[18]; +POOLS[3]=pars[19]; +POOLS[4]=pars[20]; +POOLS[5]=pars[21]; + +/*water pool*/ +POOLS[6]=pars[24]; + + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + + + +/* NOTES FOR POOLS AND FLUXES + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + +var_list[0]=pars[31]; /*m*/ +var_list[1]=pars[32]; /*b*/ +var_list[2]=pars[33]; /*gb*/ +var_list[3]=pars[34]; /*Jmax*/ +var_list[4]=pars[35]; /*Vmax*/ +var_list[7]=7.19298; /*c1*/ +var_list[8]=2.1001; /*c2*/ +var_list[9]=DATA.ncdf_data.LAT; /*LAT*/ + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[14]*sqrt(2)/2; +double wl=pars[12]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[29])-log(pars[29]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[29],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[26]; +CF[1]=pars[25]; +CF[2]=pars[26]; +CF[3]=pars[26]; +CF[4]=pars[25]/2+pars[26]/2; +CF[5]=pars[27]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +//int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +//m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[15]; + +var_list[5]=LAI[n]; +var_list[6]=0.5;//1.0//208.868; /* k */ + +met_list[0]=T2M_MIN[n]; /*mintemp, deg C*/ +met_list[1]=T2M_MAX[n]; /*maxtemp, deg C*/ +met_list[2]=CO2[n]; /*co2 in ppm*/ +met_list[3]=SSRD[n]; /*rad (swdown)*/ +met_list[4]=VPD[n]; /*VPD*/ +met_list[5]=DOY[n]; /*DOY*/ + +double psfc=1013.25; /*hPa*/ + + +double *BALDOCCHI_ANALYTICAL_OUTPUT = BALDOCCHI_ANALYTICAL(met_list,var_list); + +/*GPP*/ +/* GPP * soil water limitation */ +FLUXES[f+0]=BALDOCCHI_ANALYTICAL_OUTPUT[0]*fmin(POOLS[p+6]/pars[23],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +/* ET * soil water limitation */ +FLUXES[f+28]=BALDOCCHI_ANALYTICAL_OUTPUT[1]*fmin(POOLS[p+6]/pars[23],1); + +/*calculate water use efficiency*/ +double WUE=FLUXES[f+0]/FLUXES[f+28]; + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*(0.5*(T2M_MIN[n]+T2M_MAX[n])-meantemp))*((PREC[n]/meanprec-1)*pars[30]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[12-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[13]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[10]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[22]/deltat; + /*Maximum water loss at W = pars[22]/2;*/ + if (POOLS[p+6]>pars[22]/2){FLUXES[f+29]=(POOLS[p+6]-pars[22]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + PREC[n]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*BURNED_AREA[n]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*BURNED_AREA[n]*(1-CF[nn])*(1-pars[28])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + //Inline observation operators + //DATA.M_NBE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + +} + +return 0; +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_821/EDC2_821.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_821(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQFnew)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQFnew),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQFnew)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[23]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={16,17,18,19,20,21,24}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/* G. Quetin added a minimum pool size check to negative check*/ +double minpool = .0001; + +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + +int gppcheck = 0; +if(gppcheck == 1){ +double minflux = 0.0; + +/*ensuring minimum of GPP is zero & finite*/ +if (EDC==1 || DIAG==1){ + + double min; int nn; + while ((EDC==1 || DIAG==1)){ + nn=0; + PEDC=1; + while ((nnPASSFAIL[36+n]=0;} + nn=nn+1; + }; + } +} +} + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_821/PARS_INFO_821.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_821(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Bday*/ +CARDADATA->parmin[10]=365.25; +CARDADATA->parmax[10]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[11]=0.01; +CARDADATA->parmax[11]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[12]=10; +CARDADATA->parmax[12]=100; + +/*Fday*/ +CARDADATA->parmin[13]=365.25; +CARDADATA->parmax[13]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[14]=20; +CARDADATA->parmax[14]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[15]=5; +CARDADATA->parmax[15]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[16]=1.0; +CARDADATA->parmax[16]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C roots*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=100000.0; + +/*C litter*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=2000.0; + +/*C_som*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=200000.0; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[22]=1; +CARDADATA->parmax[22]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[23]=1; +CARDADATA->parmax[23]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[25]=0.01; +CARDADATA->parmax[25]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[26]=0.01; +CARDADATA->parmax[26]=1; + +/*DOM CF".*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[29]=1.001; +CARDADATA->parmax[29]=8; + +/*Moisture factor*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/* ball-berry slope m [unitless]*/ +CARDADATA->parmin[31]=5; //Olsen et al. 2010 +CARDADATA->parmax[31]=30;//50; + +/* ball-berry intercept b [mol m^-2 s^-1]*/ +CARDADATA->parmin[32]=0.001; //Olsen et al. 2010 +CARDADATA->parmax[32]=0.1;//1; + +/* leaf boundary layer conductance gb,CO2 [mol m^-2 s^-1]*/ +CARDADATA->parmin[33]=0.4; //Martin et al. 1999 +CARDADATA->parmax[33]=10; + +/* Jmax [umol m^-2 s^-1]*/ +CARDADATA->parmin[34]=3;//10; Walker et al. 2014 +CARDADATA->parmax[34]=400;//500; + +/* Vmax [umol m^-2 s^-1]*/ +CARDADATA->parmin[35]=3;//10; Walker et al. 2014 +CARDADATA->parmax[35]=400;//200; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +//CARDADATA->parmin[36]=10; +//CARDADATA->parmax[36]=50; + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1031/MODEL_INFO_1031.c === + +#pragma once +#include "PARS_INFO_1031.c" +#include "DALEC_1031.c" +#include "EDC1_1031.c" +#include "EDC2_1031.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1031(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=38; +DALECmodel.nofluxes=33; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1031; +DALECmodel.edc1=EDC1_1031; +DALECmodel.edc2=EDC2_1031; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1031(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1031/EDC1_1031.c === + +#pragma once +int EDC1_1031(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1031/PARS_INFO_1031.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1031(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + +/*Reference VPD */ +CARDADATA->parmin[36]=10; +CARDADATA->parmax[36]=10000; + +/*VPD curvature exponent */ +CARDADATA->parmin[37]=0.001; +CARDADATA->parmax[37]=1000; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1031/EDC2_1031.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1031(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1031/DALEC_1031.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +int DALEC_1031(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff + 32. Potential GPP +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+32]=ACM(gpppars,constants); +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1)*(1-pow(fmin(fmax(DATA.MET[m+7],0),pars[36])/pars[36],pars[37])); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + /*Plant-available water ODE*/ + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_810/MODEL_INFO_810.c === + +#pragma once +#include "PARS_INFO_810.c" +#include "DALEC_810.c" +#include "EDC1_810.c" +#include "EDC2_810.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" + + +int MODEL_INFO_810(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=7; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nopars=33; +DALECmodel.nofluxes=30; + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_810; +DALECmodel.edc1=EDC1_810; +DALECmodel.edc2=EDC2_810; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +INITIALIZE_PARAMETER_FIELDS(DATA); +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +PARS_INFO_810(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_DEDC; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_810/EDC1_810.c === + +#pragma once +int EDC1_810(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-14. Taken up by EDC2 +15. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 15* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[27]PASSFAIL[15-1]=0;} + +/*EDC No 16: Field capacity > wilting point*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[24]PASSFAIL[16-1]=0;} +*/ + + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + +EDCD->pEDC=log(EDC); + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_810/DALEC_810.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + +int DALEC_810(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*runoff*/ + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6]-FLUXES[f+29]*deltat + DATA.MET[m+8]*deltat - FLUXES[f+28]*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_810/EDC2_810.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_810(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-13. Pool trajectory EDCs +14. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } +*/ + +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[1]/MPOOLS[2])/log(2),2); + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0; +} +*/ + + +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[7-1+n]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[14-1]);EDCD->PASSFAIL[14-1]=0;} +*/ +/***********************EDCs done here****************************/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[25]-MPOOLS[6])/MPOOLS[6]))); + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0; +EDCD->pEDC=log(0); +} +} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0; +EDCD->pEDC=log(0); +}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_810/PARS_INFO_810.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_810(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*2; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=10; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*2; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=20; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1000/EDC1_1000.c === + +#pragma once +int EDC1_1000(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1000/MODEL_INFO_1000.c === + +#pragma once +#include "PARS_INFO_1000.c" +#include "DALEC_1000.c" +#include "EDC1_1000.c" +#include "EDC2_1000.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + + + + +int MODEL_INFO_1000(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + + + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1000_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1000; +DALECmodel.edc1=EDC1_1000; +DALECmodel.edc2=EDC2_1000; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1000(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1000/PARS_INFO_1000.c === + +#pragma once +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1000(DATA *CARDADATA) +{ + +/*Decomposition rate*/ +CARDADATA->parmin[0]=0.00001; +CARDADATA->parmax[0]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[1]=0.2; +CARDADATA->parmax[1]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[2]=0.01; +CARDADATA->parmax[2]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[3]=0.01; +CARDADATA->parmax[3]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[4]=1.001; +CARDADATA->parmax[4]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[5]=0.000025; +CARDADATA->parmax[5]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[6]=0.0001; +CARDADATA->parmax[6]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[7]=0.0001; +CARDADATA->parmax[7]=0.01; + +/*TOR SOM*/ +CARDADATA->parmin[8]=0.0000001; +CARDADATA->parmax[8]=0.001; + +/*Temp factor* = Q10 = 1.2-1.6*/ +CARDADATA->parmin[9]=0.018; +CARDADATA->parmax[9]=0.08; + +/*Canopy Efficiency*/ +CARDADATA->parmin[10]=5; +CARDADATA->parmax[10]=50; + +/*Bday*/ +CARDADATA->parmin[11]=365.25; +CARDADATA->parmax[11]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[12]=0.01; +CARDADATA->parmax[12]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[13]=365.25/12; +CARDADATA->parmax[13]=100; + +/*Fday*/ +CARDADATA->parmin[14]=365.25; +CARDADATA->parmax[14]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[15]=365.25/12; +CARDADATA->parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[16]=5; +CARDADATA->parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[17]=1.0; +CARDADATA->parmax[17]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[18]=1.0; +CARDADATA->parmax[18]=2000.0; + +/*C roots*/ +CARDADATA->parmin[19]=1.0; +CARDADATA->parmax[19]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[20]=1.0; +CARDADATA->parmax[20]=100000.0; + +/*C litter*/ +CARDADATA->parmin[21]=1.0; +CARDADATA->parmax[21]=2000.0; + +/*C_som*/ +CARDADATA->parmin[22]=1.0; +CARDADATA->parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +CARDADATA->parmin[23]=10; +CARDADATA->parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[24]=1; +CARDADATA->parmax[24]=100000; + +/*"Wilting point"*/ +CARDADATA->parmin[25]=1; +CARDADATA->parmax[25]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[26]=1; +CARDADATA->parmax[26]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[27]=0.01; +CARDADATA->parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[28]=0.01; +CARDADATA->parmax[28]=1; + +/*DOM CF".*/ +CARDADATA->parmin[29]=0.01; +CARDADATA->parmax[29]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[30]=0.01; +CARDADATA->parmax[30]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[31]=1.001; +CARDADATA->parmax[31]=8; + +/*Moisture factor*/ +CARDADATA->parmin[32]=0.01; +CARDADATA->parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +CARDADATA->parmin[33]=0.01; +CARDADATA->parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +CARDADATA->parmin[34]=1; +CARDADATA->parmax[34]=100000; + +/*PUW pool*/ +CARDADATA->parmin[35]=1; +CARDADATA->parmax[35]=10000; + + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1000/EDC2_1000.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1000(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol);}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1000/DALEC_1000.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + +int DALEC_1000_MODCONFIG(DALEC * DALECmodel){ + + +DALECmodel->nopools=8; +DALECmodel->nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel->nopars=36; +DALECmodel->nofluxes=32; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +printf("DALEC_1000_MODCONFIG, Line 22...\n"); +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; + +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=0; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=1; +OBSOPE.LAI_LCMA=16; +//ET variabiles +OBSOPE.ET_flux=28; +//NBE-specific variables +static int NBE_fluxes[]={0,2,12,13,16}; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=5; + +//ABGB-specific variables +static int ABGB_pools[]={0,1,2,3}; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + +//DOM-specific variables +static int DOM_pools[]={4,5}; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=2; +//H2O-specific variables +static int EWT_h2o_pools[]={6,7}; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=2; +//Fire-specific variables +OBSOPE.FIR_flux=16; + +DALECmodel->OBSOPE=OBSOPE; + +return 0;} + + + +int DALEC_1000(DATA DATA, double const *pars) +{ + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.ncdf_data.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + + double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; + + +//double *LAI=DATA.M_LAI; +//double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + /*L,F,R,W,Lit,DOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pools*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + +/* NOTES FOR POOLS AND FLUXES + + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +//int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +//m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +/*Continue from here, check with previous code!!*/ +gpppars[0]=LAI[n]; +gpppars[1]=T2M_MAX[n]; +gpppars[2]=T2M_MIN[n]; +gpppars[4]=CO2[n]; +gpppars[5]=DOY[n]; +gpppars[7]=SSRD[n]; + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*VPD[n]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(T2M_MIN[n]+T2M_MAX[n]-meantemp))*((PREC[n]/meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + /*Plant-available water ODE*/ + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + PREC[n] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*BURNED_AREA[n]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*BURNED_AREA[n]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + + /*Net ecosystem exchange + Fires*/ + //Inline observation operators + //DATA.M_NBE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1110/MODEL_INFO_1110.c === + +#pragma once +#include "PARS_INFO_1110.c" +#include "DALEC_1110.c" +#include "EDC1_1110.c" +#include "EDC2_1110.c" +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_DEDC.c" +#include "../../../CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c" + +int MODEL_INFO_1110(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALEC_1110_MODCONFIG(&DALECmodel); + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nopars=DALECmodel.nopars; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1110; +DALECmodel.edc1=EDC1_1110; +DALECmodel.edc2=EDC2_1110; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/* +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +*/ +INITIALIZE_PARAMETER_FIELDS(DATA); + +PARS_INFO_1110(DATA); + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); //DALECmodel.EDCD Needs to be initilized! +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); +printf("DALECmodel.EDCD->EQF = %2.2f\n",DALECmodel.EDCD->EQF); + + + +/*initializing model*/ +DATA->MODEL=&DALECmodel; +DATA->MLF=DALEC_MLF_DEDC; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1110/EDC1_1110.c === + +#pragma once +int EDC1_1110(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + +struct DALEC_1110_PARAMETERS P=DALEC_1110_PARAMETERS; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[P.f_auto]; +double const ffol=(1-fauto)*pars[P.f_foliar]; +double const flab=(1-fauto-ffol)*pars[P.f_lab]; +double const froot=(1-fauto-ffol-flab)*pars[P.f_root]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[P.tr_lit2soil]/(pars[P.tr_lit2soil]+pars[P.t_lit]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[P.t_foliar]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[P.t_soil]>pars[P.t_lit])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[P.tr_lit2soil]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[P.t_wood]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[P.t_root]PASSFAIL[4-1]=0;} +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[P.Fday] - pars[P.Bday])<45 | fabs(pars[P.Fday]-pars[P.Bday])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[P.cf_foliar]PASSFAIL[16-1]=0;} + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + +EDCD->pEDC=log((double)EDC); + + +return EDC; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1110/PARS_INFO_1110.c === + +#pragma once +#include "DALEC_1110.c" + +/*PARAMETER_INFO (typedef struct) must have at least 3 fields + * * npars, + * * parmax + * * parmin*/ +/*where is it defined?*/ +/*For DALEC_FIRES: as all GPP allocation fractions are inter-dependent (sum = 1)*/ +/*MCMC sampling of GPP allocation priors approximated as 0.01-0.5 NPP for*/ +/*photosynthetic pools and 0.01-1 of remaining NPP for root and wood pool*/ + +int PARS_INFO_1110(DATA *CARDADATA) +{ + + +struct DALEC_1110_PARAMETERS P=DALEC_1110_PARAMETERS; + +/*Litter decomposition rate*/ +CARDADATA->parmin[P.tr_lit2soil]=0.00001; +CARDADATA->parmax[P.tr_lit2soil]=0.01; + +/*CWD decomposition rate*/ +CARDADATA->parmin[P.tr_cwd2som]=0.00001; +CARDADATA->parmax[P.tr_cwd2som]=0.01; + +/*Fraction of GPP respired*/ +CARDADATA->parmin[P.f_auto]=0.2; +CARDADATA->parmax[P.f_auto]=0.8; + +/*Fraction of (1-fgpp) to foliage*/ +CARDADATA->parmin[P.f_foliar]=0.01; +CARDADATA->parmax[P.f_foliar]=0.5; + +/*Fraction of (1-fgpp) to roots*/ +CARDADATA->parmin[P.f_root]=0.01; +CARDADATA->parmax[P.f_root]=1; + +/*Leaf Lifespan*/ +CARDADATA->parmin[P.t_foliar]=1.001; +CARDADATA->parmax[P.t_foliar]=8; + +/*TOR wood* - 1% loss per year value*/ +CARDADATA->parmin[P.t_wood]=0.000025; +CARDADATA->parmax[P.t_wood]=0.001; + +/*TOR roots*/ +CARDADATA->parmin[P.t_root]=0.0001; +CARDADATA->parmax[P.t_root]=0.01; + +/*TOR litter*/ +CARDADATA->parmin[P.t_lit]=0.0001; +CARDADATA->parmax[P.t_lit]=0.01; + +/*TOR CWD*/ +CARDADATA->parmin[P.t_cwd]=0.00005; +CARDADATA->parmax[P.t_cwd]=0.005; + +/*TOR SOM*/ +CARDADATA->parmin[P.t_soil]=0.0000001; +CARDADATA->parmax[P.t_soil]=0.001; + +/*\Q10 = 1.2-2.0*/ +CARDADATA->parmin[P.Q10rhco2]=1.2; +CARDADATA->parmax[P.Q10rhco2]=2.0; + +/*Bday*/ +CARDADATA->parmin[P.Bday]=365.25; +CARDADATA->parmax[P.Bday]=365.25*4; + +/*Fraction to Clab*/ +CARDADATA->parmin[P.f_lab]=0.01; +CARDADATA->parmax[P.f_lab]=0.5; + +/*Clab Release period*/ +CARDADATA->parmin[P.labile_rel]=365.25/12; +CARDADATA->parmax[P.labile_rel]=100; + +/*Fday*/ +CARDADATA->parmin[P.Fday]=365.25; +CARDADATA->parmax[P.Fday]=365.25*4; + +/*Leaf fall period*/ +CARDADATA->parmin[P.leaf_fall]=365.25/12; +CARDADATA->parmax[P.leaf_fall]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +CARDADATA->parmin[P.LCMA]=5; +CARDADATA->parmax[P.LCMA]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +CARDADATA->parmin[P.i_labile]=1.0; +CARDADATA->parmax[P.i_labile]=2000.0; + +/*C foliar*/ +CARDADATA->parmin[P.i_foliar]=1.0; +CARDADATA->parmax[P.i_foliar]=2000.0; + +/*C roots*/ +CARDADATA->parmin[P.i_root]=1.0; +CARDADATA->parmax[P.i_root]=2000.0; + +/*C_wood*/ +CARDADATA->parmin[P.i_wood]=1.0; +CARDADATA->parmax[P.i_wood]=100000.0; + +/*C CWD*/ +CARDADATA->parmin[P.i_cwd]=1.0; +CARDADATA->parmax[P.i_cwd]=100000.0; + +/*C litter*/ +CARDADATA->parmin[P.i_lit]=1.0; +CARDADATA->parmax[P.i_lit]=2000.0; + +/*C_som*/ +CARDADATA->parmin[P.i_soil]=1.0; +CARDADATA->parmax[P.i_soil]=200000.0; + +/*Retention parameter (b)*/ +CARDADATA->parmin[P.retention]=1.5; +CARDADATA->parmax[P.retention]=10; + +/*"Wilting point"*/ +CARDADATA->parmin[P.wilting]=1; +CARDADATA->parmax[P.wilting]=10000; + +/*"Bucket at t0"*/ +CARDADATA->parmin[P.i_PAW]=1; +CARDADATA->parmax[P.i_PAW]=10000; + +/*Foliar biomass CF*/ +CARDADATA->parmin[P.cf_foliar]=0.01; +CARDADATA->parmax[P.cf_foliar]=1; + +/*"Ligneous" biomass CF".*/ +CARDADATA->parmin[P.cf_ligneous]=0.01; +CARDADATA->parmax[P.cf_ligneous]=1; + +/*DOM CF".*/ +CARDADATA->parmin[P.cf_DOM]=0.01; +CARDADATA->parmax[P.cf_DOM]=1; + +/*Resilience factor (since transfer to litter is represented as (1-pars[30])) ".*/ +CARDADATA->parmin[P.resilience]=0.01; +CARDADATA->parmax[P.resilience]=1; + +/*Lab pool lifespan*/ +CARDADATA->parmin[P.t_labile]=1.001; +CARDADATA->parmax[P.t_labile]=8; + +/*Moisture factor*/ +CARDADATA->parmin[P.moisture]=0.01; +CARDADATA->parmax[P.moisture]=1; + +/*Saturated hydraulic conductivity (m/s)*/ +CARDADATA->parmin[P.hydr_cond]=0.0000001; +CARDADATA->parmax[P.hydr_cond]=0.00001; + +/*Maximum infiltration (mm/day)*/ +CARDADATA->parmin[P.max_infil]=1; +CARDADATA->parmax[P.max_infil]=100; + +/*PUW pool*/ +CARDADATA->parmin[P.i_PUW]=1; +CARDADATA->parmax[P.i_PUW]=10000; + +/*PAW porosity*/ +CARDADATA->parmin[P.PAW_por]=0.2; +CARDADATA->parmax[P.PAW_por]=0.8; + +/*PUW porosity*/ +CARDADATA->parmin[P.PUW_por]=0.2; +CARDADATA->parmax[P.PUW_por]=0.8; + +/*Field capacity (negative) potential (-Mpa)*/ +CARDADATA->parmin[P.field_cap]=0.01; +CARDADATA->parmax[P.field_cap]=0.1; + +/*PAW depth (m)*/ +CARDADATA->parmin[P.PAW_z]=0.01; +CARDADATA->parmax[P.PAW_z]=100; + +/*PUW depth (m)*/ +CARDADATA->parmin[P.PUW_z]=0.01; +CARDADATA->parmax[P.PUW_z]=100; + +/*Runoff excess*/ +CARDADATA->parmin[P.Q_excess]=0.01; +CARDADATA->parmax[P.Q_excess]=1; + +/*Medlyn g1*/ +CARDADATA->parmin[P.Med_g1]=1.79; +CARDADATA->parmax[P.Med_g1]=5.79; + +/*Vcmax25*/ +CARDADATA->parmin[P.Vcmax25]=1e-8; +CARDADATA->parmax[P.Vcmax25]=140; + +/*Tminmin scaling factor*/ +CARDADATA->parmin[P.Tminmin]=258.15; +CARDADATA->parmax[P.Tminmin]=273.15; + +/*Tminmax scaling factor*/ +CARDADATA->parmin[P.Tminmax]=273.15; +CARDADATA->parmax[P.Tminmax]=288.15; + +/*aerodynamic conductance*/ +CARDADATA->parmin[P.ga]=0.01; +CARDADATA->parmax[P.ga]=10.0; + +/*Tupp*/ +CARDADATA->parmin[P.Tupp]=299.15; +CARDADATA->parmax[P.Tupp]=318.15; + +/*Tdown*/ +CARDADATA->parmin[P.Tdown]=263.15; +CARDADATA->parmax[P.Tdown]=286.15; + +/*C3_frac*/ +CARDADATA->parmin[P.C3_frac]=1e-8; +CARDADATA->parmax[P.C3_frac]=1.0; + +/*Clumping index*/ +CARDADATA->parmin[P.clumping]=0.35; +CARDADATA->parmax[P.clumping]=1.0; + +/*Leaf single scattering albedo*/ +CARDADATA->parmin[P.leaf_refl]=1e-8; +CARDADATA->parmax[P.leaf_refl]=1.0; + +/*iSWE: initial for state variable SWE snow water equivalent*/ +CARDADATA->parmin[P.i_SWE]=0.000001; +CARDADATA->parmax[P.i_SWE]=10000; + +/*sn1: min threshold for melt*/ +CARDADATA->parmin[P.min_melt]=240; +CARDADATA->parmax[P.min_melt]=270; + +/*sn2: slope*/ +CARDADATA->parmin[P.melt_slope]=0.00001; +CARDADATA->parmax[P.melt_slope]=1; + +/*sn3: snow cover fraction scalar*/ +CARDADATA->parmin[P.scf_scalar]=0.001; +CARDADATA->parmax[P.scf_scalar]=1000.0; + +/* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (PAW/PAW_fs)*/ +/*jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ +CARDADATA->parmin[P.S_fv]=1; +CARDADATA->parmax[P.S_fv]=100.0; + +/* jc thetas_opt optimum thetas for water scaler fW*/ +CARDADATA->parmin[P.thetas_opt]=0.2; +CARDADATA->parmax[P.thetas_opt]=1.0; + +/* jc fwc the water scaler fW value at the end point C */ +CARDADATA->parmin[P.fwc]=0.01; +CARDADATA->parmax[P.fwc]=1.0; + +/* jc r_ch4 CH4:CO2 conversion ratio*/ +CARDADATA->parmin[P.r_ch4]=0.001; +CARDADATA->parmax[P.r_ch4]=0.9; + +/* jc Q10ch4 Q10 for CH4 production */ +CARDADATA->parmin[P.Q10ch4]=1.0; +CARDADATA->parmax[P.Q10ch4]=3.0; + +/* maxPevap in mm/day*/ +CARDADATA->parmin[P.maxPevap]=0.01; +CARDADATA->parmax[P.maxPevap]=20; + +return 0; + +} + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1110/EDC2_1110.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1110(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +struct DALEC_1110_PARAMETERS P=DALEC_1110_PARAMETERS; +struct DALEC_1110_FLUXES F=DALEC_1110_FLUXES; +struct DALEC_1110_POOLS S=DALEC_1110_POOLS; + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; +double *parmax=DATA.parmax; + + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[S.C_fol]>MPOOLS[S.C_roo]*5 | MPOOLS[S.C_fol]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; }*/ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(MPOOLS[S.C_fol]/MPOOLS[S.C_roo])/log(2),2); + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;}*/ +if (Fin[n] > 0){ +EDCD->pEDC=EDCD->pEDC-0.5*pow(log(Rs)/log(EQF),2) - 0.5 *pow((Rs-Rm)/etol,2); + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ +} + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +EDCD->pEDC=EDCD->pEDC+log(1/(1+exp(10*(pars[P.wilting]-MPOOLS[S.H2O_PAW])/MPOOLS[S.H2O_PAW]))); + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={P.i_labile,P.i_foliar,P.i_root,P.i_wood,P.i_cwd,P.i_lit,P.i_soil,P.i_PAW,P.i_PUW,P.i_SWE}; + +/*for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}}*/ +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;EDCD->pEDC=log(0);}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;};*/ +{EDC=0;PEDC=0;EDCD->PASSFAIL[35+n]=0;EDCD->pEDC=log(0);}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1110/DALEC_1110.c === + +#pragma once +//Note: DALEC_OBSERVATION_OPERATORS.c included in DALEC_MODULE. +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_EWT2MOI.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2EWT.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c" +#include "../../../DALEC_CODE/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c" +#include "../../../DALEC_CODE/DALEC_ALL/LIU_An_et.c" +#include "../../../DALEC_CODE/DALEC_ALL/CH4_MODULES/JCR.c" + +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ + + + +struct DALEC_1110_PARAMETERS{ +/*DALEC PARAMETERS*/ +int tr_lit2soil; +int tr_lit2soil2; +int tr_cwd2som; +int tr_cwd2som2; +int f_auto; +int f_auto2; +int f_foliar; +int f_foliar2; +int f_root; +int f_root2; +int t_foliar; +int t_foliar2; +int t_wood; +int t_wood2; +int t_root; +int t_root2; +int t_lit; +int t_lit2; +int t_cwd; +int t_cwd2; +int t_soil; +int t_soil2; +int Q10rhco2; +int Q10rhco22; +int Bday; +int Bday2; +int f_lab; +int f_lab2; +int labile_rel; +int labile_rel2; +int Fday; +int Fday2; +int leaf_fall; +int leaf_fall2; +int LCMA; +int LCMA2; +int i_labile; +int i_labile2; +int i_foliar; +int i_foliar2; +int i_root; +int i_root2; +int i_wood; +int i_wood2; +int i_cwd; +int i_cwd2; +int i_lit; +int i_lit2; +int i_soil; +int i_soil2; +int retention; +int retention2; +int wilting; +int wilting2; +int i_PAW; +int i_PAW2; +int cf_foliar; +int cf_foliar2; +int cf_ligneous; +int cf_ligneous2; +int cf_DOM; +int cf_DOM2; +int resilience; +int resilience2; +int t_labile; +int t_labile2; +int moisture; +int moisture2; +int hydr_cond; +int hydr_cond2; +int max_infil; +int max_infil2; +int i_PUW; +int i_PUW2; +int PAW_por; +int PAW_por2; +int PUW_por; +int PUW_por2; +int field_cap; +int field_cap2; +int PAW_z; +int PAW_z2; +int PUW_z; +int PUW_z2; +int Q_excess; +int Q_excess2; +int Med_g1; +int Med_g12; +int Vcmax25; +int Vcmax252; +int Tminmin; +int Tminmin2; +int Tminmax; +int Tminmax2; +int ga; +int ga2; +int Tupp; +int Tupp2; +int Tdown; +int Tdown2; +int C3_frac; +int C3_frac2; +int clumping; +int clumping2; +int leaf_refl; +int leaf_refl2; +int i_SWE; +int i_SWE2; +int min_melt; +int min_melt2; +int melt_slope; +int melt_slope2; +int scf_scalar; +int scf_scalar2; +int S_fv; +int S_fv2; +int thetas_opt; +int thetas_opt2; +int fwc; +int fwc2; +int r_ch4; +int r_ch42; +int Q10ch4; +int Q10ch42; +int maxPevap; +int maxPevap2; +} DALEC_1110_PARAMETERS={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69, + 70,71,72,73,74,75,76,77,78,79, + 80,81,82,83,84,85,86,87,88,89, + 90,91,92,93,94,95,96,97,98,99, + 100,101,102,103,104,105,106,107,108,109, + 110,111,112,113,114,115,116,117,118,119, + 120,121,122,123,124,125 + +}; + +struct DALEC_1110_FLUXES{ +/*DALEC FLUXES*/ +int gpp; /*GPP*/ +int gpp; /*GPP*/ +int temprate; /*Temprate*/ +int temprate; /*Temprate*/ +int resp_auto; /*Autotrophic respiration*/ +int resp_auto; /*Autotrophic respiration*/ +int fol_prod; /*Foliar production*/ +int fol_prod; /*Foliar production*/ +int lab_prod; /*Labile production*/ +int lab_prod; /*Labile production*/ +int root_prod; /*Root production*/ +int root_prod; /*Root production*/ +int wood_prod; /*Wood production*/ +int wood_prod; /*Wood production*/ +int lab_release; /*Labile release*/ +int lab_release; /*Labile release*/ +int leaffall_fact; /*Leaffall factor*/ +int leaffall_fact; /*Leaffall factor*/ +int fol2lit; /*Foliar decomposition*/ +int fol2lit; /*Foliar decomposition*/ +int wood2cwd; /*Wood decomposition*/ +int wood2cwd; /*Wood decomposition*/ +int root2lit; /*Root decomposition*/ +int root2lit; /*Root decomposition*/ +int resp_het_cwd; /*Coarse woody debris heterotrophic respiration*/ +int resp_het_lit; /*Litter heterotrophic respiration*/ +int resp_het_som; /*Soil heterotrophic respiration*/ +int cwd2som; /*CWD decomposition*/ +int lit2som; /*Litter decomposition*/ +int lab_release_fact; /*Labile release factor*/ +int f_total; /*Flux description*/ +int f_lab; /*Labile fire loss*/ +int f_fol; /*Foliar fire loss*/ +int f_roo; /*Wood fire loss*/ +int f_woo; /*Root fire loss*/ +int f_cwd; /*CWD fire loss*/ +int f_lit; /*Litter fire loss*/ +int f_som; /*Soil fire loss*/ +int fx_lab2lit; /*Fire transfer labile to litter*/ +int fx_fol2lit; /*Fire transfer foliar to litter*/ +int fx_roo2lit; /*Fire transfer root to litter*/ +int fx_woo2cwd; /*Fire transfer wood to CWD*/ +int fx_cwd2som; /*Fire transfer CWD to soil*/ +int fx_lit2som; /*Fire transfer litter to soil*/ +int et; /*Evapotranspiration*/ +int q_paw; /*PAW runoff*/ +int paw2puw; /*PAW->PUW transfer*/ +int q_puw; /*PUW runoff*/ +int q_surf; /*Surface runoff*/ +int transp; /*Transpiration*/ +int evap; /*Evaporation*/ +int melt; /*Snow melt*/ +int scf; /*Snow cover fraction*/ +int ae_rh_cwd; /*Aerobic Rh from coarse woody debris*/ +int ae_rh_lit; /*Aerobic Rh from litter*/ +int ae_rh_som; /*aerobic Rh from SOM*/ +int an_rh_cwd; /*anaerobic Rh from coarse woody debris*/ +int an_rh_lit; /*anaerobic Rh from litter*/ +int an_rh_som; /*anaerobic Rh from SOM*/ +int rh_co2; /* */ +int rh_ch4; /* */ +int fV; /* Volumetric fraction of aerobic Rh */ +int fT; /*Temperature scaler*/ +int fW; /*Water scaler*/ +int fCH4; /*CH4 fraction in anaerobic C decomposition*/ +int soil_moist; /*thetas = PAW/PAW_fs fraction*/ + +} DALEC_1110_FLUXES={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,49, + 50,51,52,53 +}; + + + + + +struct DALEC_1110_POOLS{ +/*DALEC POOLS*/ +int C_lab; /*Labile C*/ +int C_fol; /*Foliar C*/ +int C_roo; /*Root C*/ +int C_woo; /*Wood C*/ +int C_cwd; /*Coarse woody debris C*/ +int C_lit; /*Litter C*/ +int C_som; /*Soil C*/ +int H2O_PAW; /*Plant available H2O*/ +int H2O_PUW; /*Plant unavailable H2O*/ +int H2O_SWE; /*Snow water equivalent*/ +} DALEC_1110_POOLS={ + 0,1,2,3,4,5,6,7,8,9 +}; + +/* +struct POOLS_INFO{ +int n_input_fluxes +int n_output_fluxes +int * input_fluxes +int * output_fluxes} +*/ + + + +int DALEC_1110_MODCONFIG(DALEC * DALECmodel){ + + +struct DALEC_1110_PARAMETERS P=DALEC_1110_PARAMETERS; +struct DALEC_1110_FLUXES F=DALEC_1110_FLUXES; +struct DALEC_1110_POOLS S=DALEC_1110_POOLS; + +DALECmodel->nopools=10*2; +DALECmodel->nopars=63*2; +DALECmodel->nofluxes=54*2; + +//declaring observation operator structure, and filling with DALEC configurations +static OBSOPE OBSOPE; +//Initialize all SUPPORT OBS values (default value = false). +INITIALIZE_OBSOPE_SUPPORT(&OBSOPE); + +//Set SUPPORT_OBS values to true if model supports observation operation. +OBSOPE.SUPPORT_GPP_OBS=true; +OBSOPE.SUPPORT_LAI_OBS=true; +OBSOPE.SUPPORT_ET_OBS=true; +OBSOPE.SUPPORT_NBE_OBS=true; +OBSOPE.SUPPORT_ABGB_OBS=true; +OBSOPE.SUPPORT_DOM_OBS=true; +OBSOPE.SUPPORT_EWT_OBS=true; +OBSOPE.SUPPORT_FIR_OBS=true; +OBSOPE.SUPPORT_CH4_OBS=true; +OBSOPE.SUPPORT_ROFF_OBS=true; + + +OBSOPE.SUPPORT_CUE_OBS=true; +OBSOPE.SUPPORT_C3frac_OBS=true; +OBSOPE.SUPPORT_iniSnow_OBS=true; +OBSOPE.SUPPORT_iniSOM_OBS=true; +//Provide values required by each OBS operator +//Note: each OBS operator requirements are unique, see individual observation operator functions to see what's required +//Note: no values required for any SUPPORT_*_OBS quantity set to false. + +//GPP-specific variables +OBSOPE.GPP_flux=F.gpp; +//LAI-specific variables +OBSOPE.LAI_foliar_pool=S.C_fol; +OBSOPE.LAI_LCMA=P.LCMA; +//ET variabiles +OBSOPE.ET_flux=F.et; +//Runoff variables +static int ROFF_fluxes[3]; +ROFF_fluxes[0]=F.q_paw; +ROFF_fluxes[1]=F.q_puw; +ROFF_fluxes[2]=F.q_surf; +OBSOPE.ROFF_fluxes=ROFF_fluxes; +static double ROFF_flux_signs[]={1.,1.,1.}; +OBSOPE.ROFF_flux_signs=ROFF_flux_signs; +OBSOPE.ROFF_n_fluxes=3; +//NBE-specific variables +static int NBE_fluxes[4]; +NBE_fluxes[0]=F.gpp; +NBE_fluxes[1]=F.resp_auto; +NBE_fluxes[2]=F.rh_co2; +NBE_fluxes[3]=F.f_total; +OBSOPE.NBE_fluxes=NBE_fluxes; +static double NBE_flux_signs[]={-1.,1.,1.,1.}; +OBSOPE.NBE_flux_signs=NBE_flux_signs; +OBSOPE.NBE_n_fluxes=4; + +//ABGB-specific variables +static int ABGB_pools[4]; +ABGB_pools[0]=S.C_lab; +ABGB_pools[1]=S.C_fol; +ABGB_pools[2]=S.C_roo; +ABGB_pools[3]=S.C_woo; +OBSOPE.ABGB_pools=ABGB_pools; +OBSOPE.ABGB_n_pools=4; + + +//SOM-specific variables +static int DOM_pools[3]; +DOM_pools[0]=S.C_cwd; +DOM_pools[1]=S.C_lit; +DOM_pools[2]=S.C_som; +OBSOPE.DOM_pools=DOM_pools; +OBSOPE.DOM_n_pools=3; +//H2O-specific variables +static int EWT_h2o_pools[3]; +EWT_h2o_pools[0]=S.H2O_PAW; +EWT_h2o_pools[1]=S.H2O_PUW; +EWT_h2o_pools[2]=S.H2O_SWE; +OBSOPE.EWT_h2o_pools=EWT_h2o_pools; +OBSOPE.EWT_n_h2o_pools=3; +//Fire-specific variables +OBSOPE.FIR_flux=F.f_total; +//CUE parameters +OBSOPE.CUE_PARAM=P.f_auto; +//C3frac parameters +OBSOPE.C3frac_PARAM=P.C3_frac; +//Initial Snow parameter +OBSOPE.iniSnow_PARAM=P.i_SWE; +//Initial SOM parameter +OBSOPE.iniSOM_PARAM=P.i_soil; + + + +DALECmodel->OBSOPE=OBSOPE; + + + +return 0;} + + + +int DALEC_1110(DATA DATA, double const *pars){ + + + +struct DALEC_1110_PARAMETERS P=DALEC_1110_PARAMETERS; +struct DALEC_1110_FLUXES F=DALEC_1110_FLUXES; +struct DALEC_1110_POOLS S=DALEC_1110_POOLS; + + + + +/*C-pools, fluxes, meteorology indices*/ +int p=0,f,m,nxp, i; +int n=0,nn=0; +double pi=3.1415927; + + +double deltat=DATA.ncdf_data.TIME_INDEX.values[1] - DATA.ncdf_data.TIME_INDEX.values[0]; +int N_timesteps=DATA.ncdf_data.TIME_INDEX.length; + + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +// double *NEE=DATA.M_NEE; + + /*assigning values to pools*/ + + /*L,F,R,W,Lit,SOM*/ + POOLS[S.C_lab]=pars[P.i_labile]; + POOLS[S.C_fol]=pars[P.i_foliar]; + POOLS[S.C_roo]=pars[P.i_root]; + POOLS[S.C_woo]=pars[P.i_wood]; + POOLS[S.C_cwd]=pars[P.i_cwd]; + POOLS[S.C_lit]=pars[P.i_lit]; + POOLS[S.C_som]=pars[P.i_soil]; + /*water pools*/ + POOLS[S.H2O_PAW]=pars[P.i_PAW]; + POOLS[S.H2O_PUW]=pars[P.i_PUW]; + POOLS[S.H2O_SWE]=pars[P.i_SWE]; + +double *SSRD=DATA.ncdf_data.SSRD.values; +double *T2M_MIN=DATA.ncdf_data.T2M_MIN.values; +double *T2M_MAX=DATA.ncdf_data.T2M_MAX.values; +double *CO2=DATA.ncdf_data.CO2.values; +double *DOY=DATA.ncdf_data.DOY.values; +double *PREC=DATA.ncdf_data.TOTAL_PREC.values; +double *VPD=DATA.ncdf_data.VPD.values; +double *BURNED_AREA=DATA.ncdf_data.BURNED_AREA.values; +double *TIME_INDEX=DATA.ncdf_data.TIME_INDEX.values; +double *SNOWFALL=DATA.ncdf_data.SNOWFALL.values; + +double meantemp = (DATA.ncdf_data.T2M_MAX.reference_mean + DATA.ncdf_data.T2M_MIN.reference_mean)/2; +double meanrad = DATA.ncdf_data.SSRD.reference_mean; +double meanprec = DATA.ncdf_data.TOTAL_PREC.reference_mean; + +/* jc prep input for methane module*/ +double PAW_fs = HYDROFUN_MOI2EWT(1,pars[P.PAW_por],pars[P.PAW_z]); +double ch4pars[8]={PAW_fs,pars[P.S_fv],pars[P.thetas_opt],pars[P.fwc],pars[P.r_ch4],pars[P.Q10ch4],pars[P.Q10rhco2],meantemp}; + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[P.leaf_fall]*sqrt(2)/2; +double wl=pars[P.labile_rel]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[P.t_foliar])-log(pars[P.t_foliar]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[P.t_labile])-log(pars[P.t_labile]-1))/2; + + +// Porosity scaling factor (see line 124 of HESS paper) +double psi_porosity = -0.117/100; + +/*additional offset*/ +double osf=offset(pars[P.t_foliar],wf); +double osl=offset(pars[P.t_labile],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[7];//AAB changed this +CF[S.C_lab]=pars[P.cf_ligneous]; +CF[S.C_fol]=pars[P.cf_foliar]; +CF[S.C_roo]=pars[P.cf_ligneous]; +CF[S.C_woo]=pars[P.cf_ligneous]; +CF[S.C_cwd]=pars[P.cf_ligneous]; +CF[S.C_lit]=pars[P.cf_foliar]/2+pars[P.cf_ligneous]/2; +CF[S.C_som]=pars[P.cf_DOM]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +// int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < N_timesteps; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +// m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+S.C_fol]/pars[P.LCMA]; + + +double zenith_angle=DATA.ncdf_data.SZA[n]; +double LAD = 0.5; //leaf angle distribution +double VegK = LAD/cos(zenith_angle/180*pi); + +/*Temp scaling factor*/ +double g; +int Tminmin = pars[P.Tminmin] - 273.15; +int Tminmax = pars[P.Tminmax] - 273.15; +if( T2M_MIN[n] < Tminmin ) { + g=0; +} +else if (T2M_MIN[n] > Tminmax) { + g=1; +} +else { + g=(T2M_MIN[n] - Tminmin)/(Tminmax - Tminmin); +} + +// H2O stress scaling factor + //We're also multiplying beta by cold-weather stress +double beta = fmin(POOLS[p+S.H2O_PAW]/pars[P.wilting],1.); + beta = fmin(beta,g); + +// GPP, T, and E from LIU_An_et +// Annual radiation, VPD in kPa, mean T in K +double *LIU_An_et_out = LIU_An_et(SSRD[n]*1e6/(24*3600), VPD[n]/10, + 273.15+0.5*(T2M_MIN[n]+T2M_MAX[n]), pars[P.Vcmax25], CO2[n], beta, pars[P.Med_g1], + LAI[n], pars[P.ga], VegK, pars[P.Tupp], pars[P.Tdown], 1., // pars[P.C3_frac], + pars[P.clumping], pars[P.leaf_refl], pars[P.maxPevap], PREC[n]); +// GPP +FLUXES[f+F.gpp] = LIU_An_et_out[0]; +//transpiration// +FLUXES[f+F.transp] = LIU_An_et_out[1]; +//evaporation// +FLUXES[f+F.evap] = LIU_An_et_out[2]; +// Evapotranspiration +FLUXES[f+F.et]=FLUXES[f+F.evap]+FLUXES[f+F.transp]; + +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+F.temprate]=pow(pars[P.Q10rhco2],(0.5*(T2M_MIN[n]+T2M_MAX[n])-meantemp)/10)*((PREC[n]/meanprec-1)*pars[P.moisture]+1); +/*respiration auto*/ +FLUXES[f+F.resp_auto]=pars[P.f_auto]*FLUXES[f+F.gpp]; +/*leaf production*/ +FLUXES[f+F.fol_prod]=(FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto])*pars[P.f_foliar]; +/*labile production*/ +FLUXES[f+F.lab_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod])*pars[P.f_lab]; +/*root production*/ +FLUXES[f+F.root_prod] = (FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.lab_prod])*pars[P.f_root]; +/*wood production*/ +FLUXES[f+F.wood_prod] = FLUXES[f+F.gpp]-FLUXES[f+F.resp_auto]-FLUXES[f+F.fol_prod]-FLUXES[f+F.root_prod]-FLUXES[f+F.lab_prod]; +/*leaf fall factor*/ +FLUXES[f+F.leaffall_fact] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Fday]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+F.lab_release_fact]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((TIME_INDEX[n]-pars[P.Bday]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+F.lab_release] = POOLS[p+S.C_lab]*(1-pow(1-FLUXES[f+F.lab_release_fact],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+F.fol2lit] = POOLS[p+S.C_fol]*(1-pow(1-FLUXES[f+F.leaffall_fact],deltat))/deltat; +/*wood CWD production*/ +FLUXES[f+F.wood2cwd] = POOLS[p+S.C_woo]*(1-pow(1-pars[P.t_wood],deltat))/deltat; +/*root litter production*/ +FLUXES[f+F.root2lit] = POOLS[p+S.C_roo]*(1-pow(1-pars[P.t_root],deltat))/deltat; +/*respiration heterotrophic CWD*/ +FLUXES[f+F.resp_het_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_cwd],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic litter*/ +FLUXES[f+F.resp_het_lit] = POOLS[p+S.C_lit]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_lit],deltat))/deltat; +/*nominaly there, not actual fluxes respiration heterotrophic SOM*/ +FLUXES[f+F.resp_het_som] = POOLS[p+S.C_som]*(1-pow(1-FLUXES[f+F.temprate]*pars[P.t_soil],deltat))/deltat; + +/*-----------------------------------------------------------------------*/ +/*jc calculate aerobic and anaerobic respirations*/ +double *jcr_o = JCR(ch4pars,T2M_MIN[n],T2M_MAX[n],POOLS[S.H2O_PAW]); +//outputformat +//jcr_o 0-4 thetas,fT,fV,fW,fCH4; /*jc*/ /* output from JCR module */ +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from litter*/ +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_lit],deltat))/deltat; +/* aerobic Rh from SOM*/ +FLUXES[f+F.ae_rh_som] = POOLS[p+S.C_som]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_soil],deltat))/deltat; +/* aerobic Rh from coarse woody debris*/ +FLUXES[f+F.ae_rh_cwd] = POOLS[p+S.C_cwd]*(1-pow(1-jcr_o[3]*jcr_o[1]*jcr_o[2]*pars[P.t_cwd],deltat))/deltat; +/* anaerobic Rh from litter*/ +FLUXES[f+F.an_rh_lit] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_lit],deltat))/deltat; +/* anaerobic Rh from SOM*/ +FLUXES[f+F.an_rh_som] = POOLS[p+S.C_som]*(1-pow(1-pars[P.fwc]*jcr_o[1]*(1-jcr_o[2])*pars[P.t_soil],deltat))/deltat; +/* Rh_CO2*/ +FLUXES[f+F.rh_co2] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*1+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*(1-jcr_o[4]); +/* Rh_CH4*/ +FLUXES[f+F.rh_ch4] = (FLUXES[f+F.ae_rh_lit]+FLUXES[f+F.ae_rh_cwd]+FLUXES[f+F.ae_rh_som])*0+(FLUXES[f+F.an_rh_lit]+FLUXES[f+F.an_rh_cwd]+FLUXES[f+F.an_rh_som])*jcr_o[4]; +/* fV Volumetric fraction of aerobic Rh*/ +FLUXES[f+F.fV] = jcr_o[2]; +/* fT Temperature scaler*/ +FLUXES[f+F.fT] = jcr_o[1]; +/* fW Water scaler*/ +FLUXES[f+F.fW] = jcr_o[3]; +/* fCH4 CH4 fraction*/ +FLUXES[f+F.fCH4] = jcr_o[4]; +/* PAW/PAW_fs thetas*/ +FLUXES[f+F.soil_moist] = jcr_o[0]; +/* CH4 production=TEMP*RH*WEXT*Q10 */ +/*FLUXES[f+32] = ch4pars[0]*(FLUXES[f+12]+FLUXES[f+13])*pow(ch4pars[1],(0.5*(DATA.MET[m+2]+DATA.MET[m+1])-15)/10)*ch4pars[2];*/ +/*---------------------- end of JCR --------------------------------------------*/ + +/*CWD to SOM*/ +FLUXES[f+F.cwd2som] = POOLS[p+S.C_cwd]*(1-pow(1-pars[P.tr_cwd2som]*FLUXES[f+F.temprate],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+F.lit2som] = POOLS[p+S.C_lit]*(1-pow(1-pars[P.tr_lit2soil]*FLUXES[f+F.temprate],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+S.C_lab] = POOLS[p+S.C_lab] + (FLUXES[f+F.lab_prod]-FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_fol] = POOLS[p+S.C_fol] + (FLUXES[f+F.fol_prod] - FLUXES[f+F.fol2lit] + FLUXES[f+F.lab_release])*deltat; + POOLS[nxp+S.C_roo] = POOLS[p+S.C_roo] + (FLUXES[f+F.root_prod] - FLUXES[f+F.root2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[p+S.C_woo] + (FLUXES[f+F.wood_prod] - FLUXES[f+F.wood2cwd])*deltat; + POOLS[nxp+S.C_cwd] = POOLS[p+S.C_cwd] + (FLUXES[f+F.wood2cwd] - FLUXES[f+F.ae_rh_cwd]-FLUXES[f+F.an_rh_cwd]-FLUXES[f+F.cwd2som])*deltat; + POOLS[nxp+S.C_lit] = POOLS[p+S.C_lit] + (FLUXES[f+F.fol2lit] + FLUXES[f+F.root2lit] - FLUXES[f+F.ae_rh_lit] - FLUXES[f+F.an_rh_lit] - FLUXES[f+F.lit2som])*deltat; + POOLS[nxp+S.C_som] = POOLS[p+S.C_som] + (FLUXES[f+F.lit2som] - FLUXES[f+F.ae_rh_som] - FLUXES[f+F.an_rh_som] + FLUXES[f+F.cwd2som])*deltat; + + + + +/*Snow water equivalent*/ +POOLS[nxp+S.H2O_SWE]=POOLS[p+S.H2O_SWE]+SNOWFALL[n]*deltat; /*first step snowfall to SWE*/ +FLUXES[f+F.melt]=fmin(fmax(((T2M_MIN[n]+T2M_MAX[n])/2-(pars[P.min_melt]-273.15))*pars[P.melt_slope],0),1)*POOLS[nxp+S.H2O_SWE]/deltat; /*melted snow per day*/ +POOLS[nxp+S.H2O_SWE]=POOLS[nxp+S.H2O_SWE]-FLUXES[f+F.melt]*deltat; /*second step remove snowmelt from SWE*/ +FLUXES[f+F.scf]=POOLS[nxp+S.H2O_SWE]/(POOLS[nxp+S.H2O_SWE]+pars[P.scf_scalar]); /*snow cover fraction*/ + +// Infiltration (mm/day) +double infil = pars[P.max_infil]*(1 - exp(-(PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt])/pars[P.max_infil])); + +// Surface runoff (mm/day) +FLUXES[f+F.q_surf] = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]) - infil; + +// Update pools, including infiltration +POOLS[nxp+S.H2O_PAW] = POOLS[p+S.H2O_PAW] + deltat*infil; +POOLS[nxp+S.H2O_PUW] = POOLS[p+S.H2O_PUW]; + +// Volumetric soil moisture from water pools +double sm_PAW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PAW],pars[P.PAW_por],pars[P.PAW_z]); +double sm_PUW = HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_PUW],pars[P.PUW_por],pars[P.PUW_z]); + +// Update PAW SM with infiltration +//sm_PAW += HYDROFUN_EWT2MOI(infil*deltat,pars[P.PAW_por],pars[P.PAW_z]); + +// Calculate drainage +double drain_PAW = DRAINAGE(sm_PAW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); +double drain_PUW = DRAINAGE(sm_PUW,pars[P.Q_excess],-pars[P.field_cap],psi_porosity,pars[P.retention]); + +// Drainage becomes runoff from pools +FLUXES[f+F.q_paw] = HYDROFUN_MOI2EWT(drain_PAW,pars[P.PAW_por],pars[P.PAW_z])/deltat; +FLUXES[f+F.q_puw] = HYDROFUN_MOI2EWT(drain_PUW,pars[P.PUW_por],pars[P.PUW_z])/deltat; + +// Remove drainage from layers +sm_PAW -= drain_PAW; +sm_PUW -= drain_PUW; + +// Convert to conductivity +double k_PAW = HYDROFUN_MOI2CON(sm_PAW,pars[P.hydr_cond],pars[P.retention]); +double k_PUW = HYDROFUN_MOI2CON(sm_PUW,pars[P.hydr_cond],pars[P.retention]); + +// Convert to potential +double psi_PAW = HYDROFUN_MOI2PSI(sm_PAW,psi_porosity,pars[P.retention]); +double psi_PUW = HYDROFUN_MOI2PSI(sm_PUW,psi_porosity,pars[P.retention]); + +// Calculate inter-pool transfer in m/s (positive is PAW to PUW) +double xfer = 1000 * sqrt(k_PAW*k_PUW) * (1000*(psi_PAW-psi_PUW)/(9.8*0.5*(pars[P.PAW_z]+pars[P.PUW_z])) + 1); + +// Transfer flux in mm/day +FLUXES[f+F.paw2puw] = xfer*1000*3600*24; + +// Update pools, including ET from PAW +POOLS[nxp+S.H2O_PAW] += (-FLUXES[f+F.paw2puw] - FLUXES[f+F.q_paw] - FLUXES[f+F.et])*deltat; +POOLS[nxp+S.H2O_PUW] += (FLUXES[f+F.paw2puw] - FLUXES[f+F.q_puw])*deltat; + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + + FLUXES[f+F.f_lab] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*CF[S.C_lab]/deltat; + FLUXES[f+F.f_fol] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*CF[S.C_fol]/deltat; + FLUXES[f+F.f_roo] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*CF[S.C_roo]/deltat; + FLUXES[f+F.f_woo] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*CF[S.C_woo]/deltat; + FLUXES[f+F.f_cwd] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*CF[S.C_cwd]/deltat; + FLUXES[f+F.f_lit] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*CF[S.C_lit]/deltat; + FLUXES[f+F.f_som] = POOLS[nxp+S.C_som]*BURNED_AREA[n]*CF[S.C_som]/deltat; + + FLUXES[f+F.fx_lab2lit] = POOLS[nxp+S.C_lab]*BURNED_AREA[n]*(1-CF[S.C_lab])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_fol2lit] = POOLS[nxp+S.C_fol]*BURNED_AREA[n]*(1-CF[S.C_fol])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_roo2lit] = POOLS[nxp+S.C_roo]*BURNED_AREA[n]*(1-CF[S.C_roo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_woo2cwd] = POOLS[nxp+S.C_woo]*BURNED_AREA[n]*(1-CF[S.C_woo])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_cwd2som] = POOLS[nxp+S.C_cwd]*BURNED_AREA[n]*(1-CF[S.C_cwd])*(1-pars[P.resilience])/deltat; + FLUXES[f+F.fx_lit2som] = POOLS[nxp+S.C_lit]*BURNED_AREA[n]*(1-CF[S.C_lit])*(1-pars[P.resilience])/deltat; + + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + POOLS[nxp+S.C_lab] = POOLS[nxp+S.C_lab]-(FLUXES[f+F.f_lab]+FLUXES[f+F.fx_lab2lit])*deltat; + POOLS[nxp+S.C_fol] = POOLS[nxp+S.C_fol]-(FLUXES[f+F.f_fol]+FLUXES[f+F.fx_fol2lit])*deltat; + POOLS[nxp+S.C_roo] = POOLS[nxp+S.C_roo]-(FLUXES[f+F.f_roo]+FLUXES[f+F.fx_roo2lit])*deltat; + POOLS[nxp+S.C_woo] = POOLS[nxp+S.C_woo]-(FLUXES[f+F.f_woo]+FLUXES[f+F.fx_woo2cwd])*deltat; + /*dead C pools*/ + /*CWD*/ + POOLS[nxp+S.C_cwd] = POOLS[nxp+S.C_cwd]+(FLUXES[f+F.fx_woo2cwd]-FLUXES[f+F.f_cwd]-FLUXES[f+F.fx_cwd2som])*deltat; + /*litter*/ + POOLS[nxp+S.C_lit] = POOLS[nxp+S.C_lit]+(FLUXES[f+F.fx_lab2lit]+FLUXES[f+F.fx_fol2lit]+FLUXES[f+F.fx_roo2lit]-FLUXES[f+F.f_lit]-FLUXES[f+F.fx_lit2som])*deltat; + /*som*/ + POOLS[nxp+S.C_som] = POOLS[nxp+S.C_som]+(FLUXES[f+F.fx_cwd2som]+FLUXES[f+F.fx_lit2som]-FLUXES[f+F.f_som])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+F.f_total] = FLUXES[f+F.f_lab] + FLUXES[f+F.f_fol] + FLUXES[f+F.f_roo] + FLUXES[f+F.f_woo] + FLUXES[f+F.f_cwd] + FLUXES[f+F.f_lit] + FLUXES[f+F.f_som]; + +} + + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1004_obs/MODEL_INFO_1004.c === + +#include "DALEC_1004.c" +#include "EDC1_1004.c" +#include "EDC2_1004.c" +#include "../../../DALEC_CODE/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" + + +int MODEL_INFO_1004(DATA * DATA){ + +/*Step 1. Declare structure*/ +/*"static" ensures that the memory is declared in one instance and visible to all functions (I think)*/ +static DALEC DALECmodel; + +/*Step 2: Fill structure with model-specific info*/ +DALECmodel.nopools=8; +DALECmodel.nomet=9;/*This should be compatible with CBF file, if not then disp error*/ +DALECmodel.nofluxes=32; +/****CONTINUE FROM HERE: "MODULES" is a generic*/ +/*DATA.MODULES=*/ + +/*Short-term: copy quantities into DATA structure to reduce dependencies in CARDAMOM_MODEL_LIBRARY.c*/ +/*Long-term: remove dependencies on DATA.nofluxes... etc. in CARDAMOM_READ_BINARY_DATA and DALEC_ALL_LIKELIHOOD.c*/ +DATA->nopools=DALECmodel.nopools; +DATA->nofluxes=DALECmodel.nofluxes; + +/*All model functions*/ +/*User is able to add further functions as deemed necessary*/ +/*Function names are declared in ../DALEC_ALL/DALEC_MODULE.c*/ +/*Consider starting new module for radically different model structures*/ +DALECmodel.dalec=DALEC_1004; + +/*Initialize parameter fields*/ +/*initializing parmin and parmax fields*/ +/*Currently assigned to "DATA", since MCMC needs info separately*/ + +/*DALECmodel.nopars = potentially obsolete as modules mounted directly onto DATA stack */ +DALECmodel.nopars=0; + +DATA->parmin=NULL; /*calloc(DATA->nopars,sizeof(double));*/ +DATA->parmax=NULL;/*calloc(DATA->nopars,sizeof(double));*/ + + +/*Mount DALEC 1004 module parameters*/ +MOUNT_DALEC_1004_PARS(DATA); + + +printf("DALECmodel.nopars = %i\n",DALECmodel.nopars); + +/*DALECmodel.nopars = potentially obsolete as modules mounted directly onto DATA stack */ + +oksofar("about to declare EDCD"); +printf("DALECmodel.EDCD = %p\n",DALECmodel.EDCD); +/*Initialize the EDCD structure*/ +EDCSETUP(*DATA,&DALECmodel.EDCD); +oksofar("done with declaration"); + + +/*initializing model*/ +DATA->MODEL=DALEC_1004; +DATA->MLF=DALEC_MLF_beta; + + + + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1004_obs/EDC1_1004.c === + +#pragma once +double EDC1_1004(double const *pars, DATA DATA) +{ + + + +/******NOTES: NEW APPROACH*****/ + +/*Counting EDCs dynamically to allow for multi-module EDC issue*/ +/*Storing outputs in DATA.M_EDCD*/ +/*Introduce "DATA.edccount" which is set to zero for every model run*/ +/*Diagnostic flags etc. can be used in final "P" calculation*/ +/*Function now returns probability P*/ + + +/*EDCD=EDCD2;*/ +/*List of EDCs in this file*/ +/*1. TOR_LIT faster than TOR_SOM +2. Litter2SOM greater than SOM to Atm. rate +3. TOR_FOL faster than TOR_WOOD +4. Root turnover greater than SOM turnover at meantemp +5. Allocation to canopy is comparable to allocation to fine roots +6-15. Taken up by EDC2 +16. Foliage CF> wood CF & Foliage CF > Soil CF +*/ + + + +double meantemp=DATA.meantemp; +double meanrad=DATA.meanrad; + + +/*This function was created on 7 Jan 2014*/ +/*Rules here are specified as in Bloom et al., 2014 paper*/ +/*EDC1 contains all checks that do not require a full DALEC_CDEA (DALEC2) model run*/ + + +/*ALL EDCs set as 1 initially*/ +EDCD->nedc=100; +int n; for (n=0;nnedc;n++){EDCD->PASSFAIL[n]=1;} +/*declaring variables and constants for subsequent EDCs*/ +int EDC=1; +int DIAG=EDCD->DIAG; +/*obsolete edcc constant was kept here*/ +/*deriving true allocation fractions*/ +double const fauto=pars[1]; +double const ffol=(1-fauto)*pars[2]; +double const flab=(1-fauto-ffol)*pars[12]; +double const froot=(1-fauto-ffol-flab)*pars[3]; +double const fwood=1-fauto-ffol-flab-froot; +/*fraction of GPP som under equilibrium conditions*/ +double const fsom=fwood+(froot+flab+ffol)*pars[0]/(pars[0]+pars[7]); + +/*yearly leaf loss fraction*/ +double torfol=1/(pars[4]*365.25); + + + +/*EDC CHECK NO 1*/ +/*TOR_LIT faster than TOR_SOM*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[1-1]==1)) & (pars[8]>pars[7])){EDC=0;EDCD->PASSFAIL[1-1]=0;} + +/*EDC CHECK NO 2*/ +/*Litter2SOM greater than SOM to Atm. rate*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[2-1]==1)) & (pars[0]PASSFAIL[2-1]=0;} + +/*EDC CHECK NO 3*/ +/*TOR_FOL faster than TOR_WOOD */ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[3-1]==1)) & (pars[5]>torfol)){EDC=0;EDCD->PASSFAIL[3-1]=0;} + +/*EDC CHECK NO 4*/ +/*Root turnover greater than SOM turnover at meantemp*/ +/*same as this*/ +/*\text{EDC 4: }(1-\pavii)^{365} > \Pi_{i=1}^{365} (1-\paix \tratei)*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[4-1]==1)) & (pars[6]PASSFAIL[4-1]=0;} + +/*EDC no 5 is addressed in EDC2_FIREBUCKET.c*/ + +/*EDC CHECK NO 6*/ +/*Bday Fday difference>45 days */ +/*if (((EDC==1 & DIAG==0) || DIAG==1) & (fabs(pars[14] - pars[11])<45 | fabs(pars[14]-pars[11])>320.25)){EDC=0;EDCD->PASSFAIL[6-1]=0;}*/ +/*now obsolete!*/ + +/*EDC CHECK NO 5*/ +/*Allocation to canopy is comparable to allocation to fine roots*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[5-1]==1)) & ((ffol+flab)>5*froot | (ffol+flab)*5PASSFAIL[5-1]=0;} + +/*EDC No 16* Foliage CF> wood CF & SOM CF*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[16-1]==1)) & (pars[27]PASSFAIL[16-1]=0;} + +/*EDC No 17: RD_puw > RD_paw*/ +/*if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[17-1]==1)) & (pars[24]PASSFAIL[17-1]=0;} + +*/ + +/*Add any generalisations derivable from EDC2 (post-run checks) here*/ +/*Note: these must be tested to ensure that DALEC2 run is NOT needed */ + + + + + + +return P; + + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1004_obs/INFILTRATION.c === + + +/*Script needs to include*/ +/*(1) MOUNT script: defines all data-optimizable parameters*/ +/*(2) PROB script: defines all probability calculations (EDCs etc)*/ +/*(3) MODULE script: contains all model calculations*/ + + + +int MOUNT_INFILTRATION_MODULE(DATA *DATA){ + +/*Step 1. Index module*/ +DATA->MODULE_IDX.HYDROLOGY.infiltration_imax=DATA->nopars; + +/*PARNAME: Imax [mm/day]*/ +ADD_PARAMETER_TO_STACK(DATA,"Imax",1,1000);/*pars[0]*/ + +return 0; + +} + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1004_obs/EDC2_1004.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/mean_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/mean_annual_pool.c" +#include "../../../DALEC_CODE/DALEC_ALL/expdecay2.c" +#include "../../../../math_fun/std.c" +#include "../../../../math_fun/ipow.c" +#include "stdlib.h" +#include "stdio.h" + + +int EDC2_1004(double const *pars, DATA DATA, struct EDCDIAGNOSTIC *EDCD) +{ + +/*Extract DALEC model here*/ +/*Copy model pointer for brevity*/ +DALEC *MODEL=(DALEC *)DATA.MODEL; + +double *MET=DATA.MET; +double *POOLS=DATA.M_POOLS; +double *FLUXES=DATA.M_FLUXES; +int nodays=DATA.nodays; +double *parmax=DATA.parmax; +double meantemp=DATA.meantemp; + +/*EDCD=EDCD2;*/ + +/* EDC2_SUMMARY +6. Cfol:Croo +7-14. Pool trajectory EDCs +15. Ensuring that wilting point is at or below the mean H2O pool +35. +*/ + +/*THESE EDC2 checks are for DALEC_FIREBUCKET3d*/ +int EDC=1,n=0,m=0,edc=0; +int DIAG=EDCD->DIAG;/*1 or 0*/ + + + +/*FIREBUCKET*/ +int nomet=MODEL->nomet; +int nopools=MODEL->nopools; +int nofluxes=MODEL->nofluxes; +int done=0; +int k=0; + + + +/*deriving mean pools here!*/ +double *MPOOLS; +MPOOLS=calloc(nopools,sizeof(double)); +if (MPOOLS==0){printf("WARNING NULL POINTER");} +for (n=0;nSWITCH[6-1]==1)) & (MPOOLS[1]>MPOOLS[2]*5 | MPOOLS[1]*5SWITCH[6-1]);EDCD->PASSFAIL[6-1]=0; } + + +/*equilibrium factor (in comparison to C_initial)*/ +double EQF=EDCD->EQF; + +/*Total fluxes*/ +double *FT; +FT=calloc(nofluxes,sizeof(double)); +int f=0; +for (f=0;fSWITCH[7-1+n]==1)) +& ((fabs(log(Rs))>log(EQF)) || (fabs(Rs-Rm)>etol))) +{EDC=ipow(0,EDCD->SWITCH[7-1+n]);EDCD->PASSFAIL[7-1+n]=0;} + + +/*storing EDCPROB: i.e. the log probability of each EDC based on a gaussian representation*/ +/*of each constraint*/ +EDCD->EDCPROB[7-1+n]=-0.5*pow(log(Rs)/log(EQF),2);/*-0.5*pow((Rs-Rm)/etol,2);*/ + +if (psw==1){ +printf("****\n"); +printf("Pool %i EDCDPROB = %f\n",n,EDCD->EDCPROB[7-1+n]); +printf("Pool %i Fin = %f,Fout = %f\n",n+1,Fin[n],Fout[n]); +printf("Pool %i Pstart = %f,Pend = %f\n, Pmeanjan=%f\n",n+1,Pstart,Pend,MPOOLSjan[n]); +printf("fabs(log(Fin/Fout)) = %f\n",fabs(log(Fin[n]/Fout[n]))); +printf("fabs(log(Pend/Pstart)) = %f\n",fabs(log(Pend/Pstart))); +printf("Rm = %f\n",Rm); +printf("Rs = %f\n",Rs); +printf("log(EQF) = %f\n",log(EQF)); +printf("etol = %f\n",etol); +printf("****\n");}} + + +/*Ensuring that wilting point is at or below the mean H2O pool EDC14*/ +if (((EDC==1 & DIAG==0) || DIAG==1 || (EDC==1 & DIAG==2 & EDCD->SWITCH[15-1]==1)) & (pars[25]>MPOOLS[6])){EDC=ipow(0,EDCD->SWITCH[15-1]);EDCD->PASSFAIL[15-1]=0;} + +/***********************EDCs done here****************************/ + + + +/*Additional faults can be stored in positions 35-40*/ + +/*PRIOR RANGES - ALL POOLS MUST CONFORM*/ +int pidx[]={17,18,19,20,21,22,26,35}; + +for (n=0;nparmax[pidx[n]])){EDC=0;EDCD->PASSFAIL[35-1]=0;}} + + +int PEDC; +/*ensuring minimum of each pool is zero & finite*/ +if (EDC==1 || DIAG==1) +{double min; int nn;n=0; +while ((nPASSFAIL[35+n]=0;}nn=nn+1;}; +n=n+1; +} +} +/* +if (EDC==1){printf("\n");oksofar("EDC(36-43) passed");} +*/ + + + + + + + + +/*FREE MEMORY*/ +free(FT); +free(MPOOLS); +free(MPOOLSjan); + + + + + +/*final check confirming EDC = 1 or 0*/ +int Num_EDC=100; +if (DIAG==1){for (n=0;nPASSFAIL[n]==0){EDC=0;}}} + + + + +/*Returning EDC */ +return EDC; + +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MODELS/DALEC/DALEC_1004_obs/DALEC_1004.c === + +#pragma once +#include "../../../DALEC_CODE/DALEC_ALL/ACM.c" +#include "../../../DALEC_CODE/DALEC_ALL/offset.c" +#include "../../../DALEC_CODE/DALEC_ALL/DALEC_MODULE.c" +#include "INFILTRATION.c"; +/*Code used by Bloom et al., 2016 +See also Bloom & Williams 2015, Fox et al., 2009; Williams et al., 1997*/ +/*NOTES*/ +/*Each *MODULE* can have the same size type*/ +/*Using "union" we can call fields by name or by index*/ +/*All pointers can be initialized as NULL*/ +/*Mounted volumes will be accessed to back out parmin, parmax, npars*/ + + + + + +int MOUNT_DALEC_1004_PARS(DATA * DATA){ + +/*Step 1. Index MODULE*/ +DATA->MODULE_IDX.MODELS.dalec_1004=DATA->nopars; + +/*Populate with module parameters*/ + +double parmin[36], parmax[36]; +char *parname[36]; + +parname[0]="Decomposition rate"; +parmin[0]=0.00001; +parmax[0]=0.01; + +parname[1]="Fraction of GPP repsired"; +parmin[1]=0.2; +parmax[1]=0.8; + +parname[2]="Fraction of (1-fgpp) to foliage"; +parmin[2]=0.01; +parmax[2]=0.5; + +parname[3]="Fraction to roots"; +parmin[3]=0.01; +parmax[3]=1; + +parname[4]="Leaf Lifespan"; +parmin[4]=1.001; +parmax[4]=8; + +parname[5]="TOR wood [yr-1]"; +parmin[5]=0.000025; +parmax[5]=0.001; + +parname[6]="TOR roots"; +parmin[6]=0.0001; +parmax[6]=0.01; + +parname[7]="TOR litter"; +parmin[7]=0.0001; +parmax[7]=0.01; + +parname[8]="TOR SOM"; +parmin[8]=0.0000001; +parmax[8]=0.001; + +parname[9]="Temp factor (Q10)"; +parmin[9]=0.018; +parmax[9]=0.08; + +parname[10]="ACM canopy efficiency"; +parmin[10]=5; +parmax[10]=50; + +parname[11]="Leaf onset day"; +parmin[11]=365.25; +parmax[11]=365.25*4; + +parname[12]="Fraction to Clab"; +parmin[12]=0.01; +parmax[12]=0.5; + +parname[13]="Clab Release period"; +parmin[13]=365.25/12; +parmax[13]=100; + + +parname[14]="Leaf fall day"; +parmin[14]=365.25; +parmax[14]=365.25*4; + +parname[15]="Leaf fall period"; +parmin[15]=365.25/12; +parmax[15]=150; + +/*LMCA*/ +/*Kattge et al. 2011*/ +/*Kattge et al., provide a range of 10 400 g m-2, i.e. 5 200 gC m-2*/ +parname[16]="LCMA [gC/m2]"; +parmin[16]=5; +parmax[16]=200; + +/*INITIAL VALUES DECLARED HERE*/ + +/*C labile*/ +parname[17]="C labile @ t=0"; +parmin[17]=1.0; +parmax[17]=2000.0; + +/*C foliar*/ +parname[18]="C foliar @ t=0"; +parmin[18]=1.0; +parmax[18]=2000.0; + +/*C roots*/ +parname[19]="C roots @ t=0"; +parmin[19]=1.0; +parmax[19]=2000.0; + +/*C_wood*/ +parname[20]="C wood @ t=0"; +parmin[20]=1.0; +parmax[20]=100000.0; + +/*C litter*/ +parname[21]="C litter @ t=0 [gC]"; +parmin[21]=1.0; +parmax[21]=2000.0; + +/*C_som*/ +parname[22]="C som @ t=0 [gC]"; +parmin[22]=1.0; +parmax[22]=200000.0; + +/*IWUE: GPP*VPD/ET: gC/kgH2o *hPa*/ +parname[23]="iWUE"; +parmin[23]=10; +parmax[23]=50; + +/*Runoff focal point (~maximum soil storage capacity x 4)*/ +parname[24]="Q focal point [mm]"; +parmin[24]=1; +parmax[24]=100000; + +/*"Wilting point"*/ +parname[25]="Wilting point [mm]"; +parmin[25]=1; +parmax[25]=10000; + +/*"Bucket at t0"*/ +parname[26]="PAW @ t=0 [mm]"; +parmin[26]=1; +parmax[26]=10000; + +parname[27]="Foliar biomass CF"; +parmin[27]=0.01; +parmax[27]=1; + +/*"Ligneous" biomass CF".*/ +parname[28]="Stem biomass CF"; +parmin[28]=0.01; +parmax[28]=1; + +parname[29]="DOM CF"; +parmin[29]=0.01; +parmax[29]=1; + +parname[30]="Fire resilience factor"; +parmin[30]=0.01; +parmax[30]=1; + +parname[31]="Lab pool lifespan (yrs)"; +parmin[31]=1.001; +parmax[31]=8; + +parname[32]="Moisture factor"; +parmin[32]=0.01; +parmax[32]=1; + +/*PAW->PUW runoff fraction*/ +parname[33]="PAW->PUW Q fraction"; +parmin[33]=0.01; +parmax[33]=1; + +/*PUW Runoff focal point (~maximum soil storage capacity x 4)*/ +parname[34]="Runoff focal point [mm]"; +parmin[34]=1; +parmax[34]=100000; + +parname[35]="PUW pool"; +parmin[35]=1; +parmax[35]=10000; + + + +int n; +for (n=0;n<36;n++){ +ADD_PARAMETER_TO_STACK(DATA,parname[n],parmin[n],parmax[n]);} + + + +/*Declare & mount sub-modules*/ +MOUNT_INFILTRATION_MODULE(DATA); + + +return 0; +} + + + + + + +int DALEC_1004(DATA DATA, double const *pars_global) +{ + +/*extract parameters from DALEC modules*/ +double const *pars=&pars_global[DATA.MODULE_IDX.MODELS.dalec_1004]; + + +double gpppars[11],pi; +/*C-pools, fluxes, meteorology indices*/ +int p,f,m,nxp, i; +int n=0,nn=0; +pi=3.1415927; + + +/*constant gpppars terms*/ +gpppars[3]=1; +gpppars[6]=DATA.LAT; +gpppars[8]=-2.0; +gpppars[9]=1.0; +gpppars[10]=pi; + +double deltat=DATA.deltat; +int nr=DATA.nodays; + + +double constants[10]={pars[10],0.0156935,4.22273,208.868,0.0453194,0.37836,7.19298, 0.011136,2.1001,0.789798}; + +/*Pointer transfer - all data stored in fluxes and pools will be passed to DATA*/ +double *FLUXES=DATA.M_FLUXES; +double *POOLS=DATA.M_POOLS; +double *LAI=DATA.M_LAI; +double *NEE=DATA.M_NEE; +/*New feature: DALEC can populate its own DATA.M_P[0] value.*/ +/*EDCs can therefore be internally calculated with little (if any) external definitions necessary*/ +/*This will be accompanied by a new MLF function to support reduced external EDC representation*/ + + +/*Calculate EDC1 probability here +...DATA.M_P[0] will mediate probability +...*/ +EDC1_1004(pars, DATA); + +/* +... +...*/ + + + + + + /*assigning values to pools*/ + /*L,F,R,W,Lit,SOM*/ + POOLS[0]=pars[17]; + POOLS[1]=pars[18]; + POOLS[2]=pars[19]; + POOLS[3]=pars[20]; + POOLS[4]=pars[21]; + POOLS[5]=pars[22]; + /*water pool*/ + +POOLS[6]=pars[26]; +POOLS[7]=pars[35]; + + +/* NOTES FOR POOLS AND FLUXES +DATA.MET[:,0]: projday +DATA.MET[:,1]: mintemp +DATA.MET[:,2]: maxtemp +DATA.MET[:,3]: rad +DATA.MET[:,4]: co2 +DATA.MET[:,5]: yearday +DATA.MET[:,6]: burned area +DATA.MET[:,7]: VPD +DATA.MET[:,8]: precipitation + + + POOLS[0,0]=pars(8);Lab + POOLS[0,1]=pars(5);Fol + POOLS[0,2]=pars(6);Roo + POOLS[0,3]=pars(3);Woo + POOLS[0,4]=pars(2);Litter + POOLS[0,5]=pars(2);Som + + + %fluxes - other********* + 0.GPP + 1.temprate + 2.respiration_auto + 3.leaf_production + 4.labile_production + 5.root_production + 6.wood_production + 7.labile_release + 8.leaffall_factor + 9.leaflitter_production + 10.woodlitter_production + 11.rootlitter_production + 12.respiration_het_litter + 13.respiration_het_som + 14.litter2som + 15.labrelease_factor + 16. Fires (total) + 17-22. Fires (C pools to atmosphere) + 23-27. Fires (C pool transfers) + 28. ET + 29. Runoff +*/ + + + +/*constants for exponents of leaffall and labrelease factors*/ +/*width*/ +double wf=pars[15]*sqrt(2)/2; +double wl=pars[13]*sqrt(2)/2; + + +/*factor*/ +double ff=(log(pars[4])-log(pars[4]-1))/2; +/*double fl=(log(1.001)-log(0.001))/2;*/ +double fl=(log(pars[31])-log(pars[31]-1))/2; + + + + +/*additional offset*/ +double osf=offset(pars[4],wf); +double osl=offset(pars[31],wl); + + +/*scaling to biyearly sine curve*/ +double sf=365.25/pi; + +/*Combustion factors*/ +double CF[6]; +CF[0]=pars[28]; +CF[1]=pars[27]; +CF[2]=pars[28]; +CF[3]=pars[28]; +CF[4]=pars[27]/2+pars[28]/2; +CF[5]=pars[29]; + + +/*resilience factor*/ + + +/*number of MET drivers*/ +int nomet=((DALEC *)DATA.MODEL)->nomet; + +/*number of DALEC pools*/ +int nopools=((DALEC *)DATA.MODEL)->nopools; + +/*number of DALEC fluxes to store*/ +int nofluxes=((DALEC *)DATA.MODEL)->nofluxes; + + +/*repeating loop for each timestep*/ +for (n=0; n < nr; n++){ +/*ppol index*/ +p=nopools*n; +/*next pool index*/ +nxp=nopools*(n+1); +/*met index*/ +m=nomet*n; +/*flux array index*/ +f=nofluxes*n; + + + +/*LAI*/ +LAI[n]=POOLS[p+1]/pars[16]; +/*GPP*/ +gpppars[0]=LAI[n]; +gpppars[1]=DATA.MET[m+2]; +gpppars[2]=DATA.MET[m+1]; +gpppars[4]=DATA.MET[m+4]; +gpppars[5]=DATA.MET[m+5]; +gpppars[7]=DATA.MET[m+3]; + + + +/*GPP*/ +FLUXES[f+0]=ACM(gpppars,constants)*fmin(POOLS[p+6]/pars[25],1); +/*Evapotranspiration (VPD = DATA.MET[m+7])*/ +FLUXES[f+28]=FLUXES[f+0]*DATA.MET[m+7]/pars[23]; +/*temprate - now comparable to Q10 - factor at 0C is 1*/ +/* x (1 + a* P/P0)/(1+a)*/ +FLUXES[f+1]=exp(pars[9]*0.5*(DATA.MET[m+2]+DATA.MET[m+1]-DATA.meantemp))*((DATA.MET[m+8]/DATA.meanprec-1)*pars[32]+1); +/*respiration auto*/ +FLUXES[f+2]=pars[1]*FLUXES[f+0]; +/*leaf production*/ +FLUXES[f+3]=(FLUXES[f+0]-FLUXES[f+2])*pars[2]; +/*labile production*/ +FLUXES[f+4] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3])*pars[13-1]; +/*root production*/ +FLUXES[f+5] = (FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+4])*pars[4-1]; +/*wood production*/ +FLUXES[f+6] = FLUXES[f+0]-FLUXES[f+2]-FLUXES[f+3]-FLUXES[f+5]-FLUXES[f+4]; +/*leaf fall factor*/ +FLUXES[f+8] = (2/sqrt(pi))*(ff/wf)*exp(-pow(sin((DATA.MET[m+0]-pars[14]+osf)/sf)*sf/wf,2)); +/*Labrelease factor*/ +FLUXES[f+15]=(2/sqrt(pi))*(fl/wl)*exp(-pow(sin((DATA.MET[m+0]-pars[11]+osl)/sf)*sf/wl,2)); +/*labile release - re-arrange order in next versions*/ +FLUXES[f+7] = POOLS[p+0]*(1-pow(1-FLUXES[f+15],deltat))/deltat; +/*leaf litter production*/ +FLUXES[f+9] = POOLS[p+1]*(1-pow(1-FLUXES[f+8],deltat))/deltat; +/*wood litter production*/ +FLUXES[f+10] = POOLS[p+3]*(1-pow(1-pars[6-1],deltat))/deltat; +/*root litter production*/ +FLUXES[f+11] = POOLS[p+2]*(1-pow(1-pars[7-1],deltat))/deltat; +/*respiration heterotrophic litter*/ +FLUXES[f+12] = POOLS[p+4]*(1-pow(1-FLUXES[f+1]*pars[8-1],deltat))/deltat; +/*respiration heterotrophic SOM*/ +FLUXES[f+13] = POOLS[p+5]*(1-pow(1-FLUXES[f+1]*pars[9-1],deltat))/deltat; +/*litter to SOM*/ +FLUXES[f+14] = POOLS[p+4]*(1-pow(1-pars[1-1]*FLUXES[f+1],deltat))/deltat; + +/*total pool transfers (no fires yet)*/ + + POOLS[nxp+0] = POOLS[p+0] + (FLUXES[f+4]-FLUXES[f+7])*deltat; + POOLS[nxp+1] = POOLS[p+1] + (FLUXES[f+3] - FLUXES[f+9] + FLUXES[f+7])*deltat; + POOLS[nxp+2] = POOLS[p+2] + (FLUXES[f+5] - FLUXES[f+11])*deltat; + POOLS[nxp+3] = POOLS[p+3] + (FLUXES[f+6] - FLUXES[f+10])*deltat; + POOLS[nxp+4] = POOLS[p+4] + (FLUXES[f+9] + FLUXES[f+11] - FLUXES[f+12] - FLUXES[f+14])*deltat; + POOLS[nxp+5]= POOLS[p+5]+ (FLUXES[f+14] - FLUXES[f+13]+FLUXES[f+10])*deltat; +/*Water pool = Water pool - runoff + prec (mm/day) - ET*/ + /*printf("%2.1f\n",POOLS[p+6]);*/ + /*PAW total runoff*/ + + FLUXES[f+29]=pow(POOLS[p+6],2)/pars[24]/deltat*(1-pars[33]); + /*PAW -> PUW transfer*/ + FLUXES[f+30]=FLUXES[f+29]*pars[33]/(1-pars[33]); + /*PUW runoff*/ + FLUXES[f+31]=pow(POOLS[p+7],2)/pars[34]/deltat; + /*Maximum water loss at W = pars[24]/2;*/ + if (POOLS[p+6]>pars[24]/2){FLUXES[f+29]=(POOLS[p+6]-pars[24]/4)/deltat*(1-pars[33]); + FLUXES[f+30]=(POOLS[p+6]-pars[24]/4)/deltat*pars[33]/(1-pars[33]);} + if (POOLS[p+7]>pars[34]/2){FLUXES[f+31]=(POOLS[p+7]-pars[34]/4)/deltat;} + + POOLS[nxp+6]=POOLS[p+6] + (-FLUXES[f+29] - FLUXES[f+30] + DATA.MET[m+8] - FLUXES[f+28])*deltat; + /*Plant-unavailable water budget*/ + + POOLS[nxp+7]=POOLS[p+7] + (FLUXES[f+30] - FLUXES[f+31])*deltat; + + + + /*total pool transfers - WITH FIRES*/ + /*first fluxes*/ + + /*CFF = Combusted C fire flux + NCFF = Non-combusted C fire flux*/ + + /*Calculating all fire transfers (1. combustion, and 2. litter transfer)*/ + /*note: all fluxes are in gC m-2 day-1*/ + for (nn=0;nn<6;nn++){FLUXES[f+17+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*CF[nn]/deltat;} + for (nn=0;nn<4;nn++){FLUXES[f+23+nn] = POOLS[nxp+nn]*DATA.MET[m+6]*(1-CF[nn])*(1-pars[30])/deltat;} + + /*Adding all fire pool transfers here*/ + /*live C pools*/ + for (nn=0;nn<4;nn++){POOLS[nxp+nn]=POOLS[nxp+nn]-(FLUXES[f+17+nn]+FLUXES[f+23+nn])*deltat;} + /*dead C pools*/ + /*litter*/ + POOLS[nxp+4]=POOLS[nxp+4]+(FLUXES[f+23]+FLUXES[f+23+1]+FLUXES[f+23+2]-FLUXES[f+17+4]-FLUXES[f+23+4])*deltat; + /*som*/ + POOLS[nxp+5]=POOLS[nxp+5]+(FLUXES[f+23+3]+FLUXES[f+23+4]-FLUXES[f+17+5])*deltat; + + /*fires - total flux in gC m-2 day-1*/ + /*this term is now (essentially) obsolete*/ + /*replace in next version of DALEC_FIRES*/ + FLUXES[f+16]=0;for (nn=0;nn<6;nn++){FLUXES[f+16]+=FLUXES[f+17+nn];} + + /*Net ecosystem exchange + Fires*/ + NEE[n]=-FLUXES[f+0]+FLUXES[f+2]+FLUXES[f+12]+FLUXES[f+13]+FLUXES[f+16]; + + +} + + + + + + +return 0; +} + + + + + + + + + +=== FILE: ./C/projects/CARDAMOM_MDF/MCMC_SETUP/PROJECT_FUN/FIND_EDC_INITIAL_VALUES.c === + + +#pragma once +#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF.c" +//#include "../../../COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_MLF_beta.c" +#include "../../../../mcmc_fun/MHMCMC/MCMC_FUN/MHMCMC_119.c" +#include "../../../../mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c" +#include "../../../../mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c" +#include "../../../../math_fun/int_max.c" + +int FIND_EDC_INITIAL_VALUES(DATA CARDADATA,PARAMETER_INFO *PI, MCMC_OPTIONS *MCOPT_CARDAMOM){ + +/*First: choosing the correct EDC MODEL LIKELIHOOD FUNCTION (EMLF)*/ + + + printf("*********made it to here FIND_EDC_INITIAL_VALUES********\n"); + +//double (*EMLF)(DATA, double *); +//double (*MLF)(DATA, double *); + + +//EMLF=EDC_DALEC_MLF; +//MLF=DALEC_MLF; + +/*This MCMC is designed to find the best-fit DALEC parameters ONLY*/ + +MCMC_OPTIONS MCOPT; +MCMC_OUTPUT MCOUT; + + +int PEDCC,nn; + + +//option for mcmcid = 3 +int nstartchains=10; + + +MCOPT.APPEND=0; +MCOPT.nADAPT=10;/*was 20*/ +MCOPT.fADAPT=0.5; +MCOPT.nOUT=1000;/*was 2000*/ +MCOPT.nPRINT=100;/*was*/ +MCOPT.nWRITE=0; +MCOPT.nSTART=0; +/*randparini = 0*/ +/*this means all PI.parini values must either be given values or entered as -9999*/ +MCOPT.randparini=1; +MCOPT.returnpars=1; +/*setting fixedpars option to 1*/ +MCOPT.fixedpars=1; +MCOPT.mcmcid=119;/*Using metropolis-hastings to find initial parameters*/ +MCOPT.nchains=1; +MCOPT.minstepsize=1e-2; + + +if (MCOPT_CARDAMOM->mcmcid==3){ +MCOPT.mcmcid=3; +default_int_value(&CARDADATA.ncdf_data.MCMCID.nSAMPLES_EDC_SEARCH ,200000); +MCOPT.nOUT=CARDADATA.ncdf_data.MCMCID.nSAMPLES_EDC_SEARCH ;/*Default = 20000*/ +MCOPT.nPRINT=2000;/*1;was 2000*/ +MCOPT.minstepsize=1e-5; +MCOPT.nchains=400; +MCOPT.fixedpars=0; +MCOPT.fADAPT=0; +//declaring best_pars +MCOUT.best_pars=calloc(MCOPT.nchains*PI->npars,sizeof(double));} + + +int OK=INITIALIZE_MCMC_OUTPUT(*PI,&MCOUT,MCOPT); +printf("C/projects/CARDAMOM_MDF/MCMC_SETUP/PROJECT_FUN/FIND_EDC_INITIAL_VALUES.c: MCOUT structure initialized\n"); + + + +int n,nnn; + +printf("PI->npars (INSIDE FIND_EDC_INITIAL_VALUES.c)= %d\n",PI->npars); + + + + +for (n=0;nnpars;n++){ +PI->stepsize[n]=0.02; +/*PI->stepsize[n]=0.00005;*/ +PI->parini[n]=DEFAULT_DOUBLE_VAL; +PI->parfix[n]=0; +/* +if (PI->parini[n]!=-9999 & CARDADATA.edc_random_search<1) {PI->parfix[n]=1;}*/} + + + + +/*done*/ + +double PEDC=log(0); +int count=0; +while (PEDC!=0){ + printf("EDC Attempt no %d\n",count);oksofar("---"); + + for (n=0;nnpars;n++){PI->stepsize[n]=0.0005;} + /*insert prior value option here!*/ + + oksofar("Running short MCMC to find x_{EDC} = 1"); + + if (MCOPT.mcmcid==119){MHMCMC_119(CARDADATA.EMLF,CARDADATA,*PI,MCOPT,&MCOUT);}; + if (MCOPT.mcmcid==2){DEMCMC(CARDADATA.EMLF,CARDADATA,*PI,MCOPT,&MCOUT);}; + if (MCOPT.mcmcid==3){ADEMCMC(CARDADATA.EMLF,CARDADATA,*PI,MCOPT,&MCOUT);}; + + /*if (MCOPT.mcmcid==2){DEMCMC(EMLF,CARDADATA,*PI,MCOPT,&MCOUT);}; + */ + oksofar("Short MCMC complete"); + for (n=0;nnpars*MCOPT.nchains;n++){PI->parini[n]=MCOUT.best_pars[n];} + + PEDCC=0; + for (nn=0;nnparini + nn*PI->npars);double P; + P=CARDADATA.MLF(CARDADATA, PI->parini + nn*PI->npars); + printf("PEDC for chain %i = %2.1f (%2.1f)\n",nn,PEDC,P); + if (PEDC==0){PEDCC=PEDCC+1;}} + + + printf("*******\n"); + printf("*******\n"); + printf("%i out of %i chains have non-zero prob\n",PEDCC,MCOPT.nchains); + printf("EDC stats\n"); + for (nnn=0;nnnMCOPT.nchains){PEDC=0;} + //Guarantee that at least half of chains have non-zero starting probabilities + if (MCOPT.mcmcid==3){if (PEDCC>nstartchains){PEDC=0;}else{PEDC=-1;}} + if (MCOPT.mcmcid==2 || MCOPT.mcmcid==3){MCOPT.randparini=0;} + /*Hard coding*/ + + /*in case one EDC missing*/ + if (MCOPT.mcmcid==119 && PEDC!=0 && count%3==0){for (n=0;nnpars;n++){PI->parini[n]=CARDADATA.parpriors[n];}} + +} + +//Probs would make more sense as a memcpy but I am keeping it like this for now +for (n=0;nnpars*MCOPT.nchains;n++){ + + PI->parini[n]=MCOUT.best_pars[n]; +} + + + +/*Sampling new/more parameters*/ + + /* + for (n=0;nnpars;n++){printf("%8.6f ",PI->parini[n]);}printf("\n"); + printf("EDC Probability of starting parameters = %4.4f\n",EMLF(CARDADATA, PI->parini)); + printf("Probability of starting parameters = %4.4f\n",CARDADATA.MLF(CARDADATA, PI->parini)); + */ + /*for (n=0;nnpars;n++){PI->stepsize[n]=0.01;}*/ + + /*SOON-TO-BE-OBSOLETE: resetting fixed pars to zero for main r*/ + //for (n=0;nnpars;n++){PI->parfix[n]=0;} + //THIS WAS MOVED TO MCMC_MODULES! + +/*clearing MCOUT fields*/ +free(MCOUT.best_pars); +/*Done either (a) reading parameters from file, or (b) sampling parameters +*/ + +return 0;} + + + +=== FILE: ./C/projects/CARDAMOM_MDF/MCMC_SETUP/MCMC_MODULES.c === + + + +#pragma once +#include +#include +#include +#include "../../CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c" +#include "PROJECT_FUN/FIND_EDC_INITIAL_VALUES.c" +#include "../../../math_fun/declare_matrix.c" +#include "../../CARDAMOM_GENERAL/NETCDF_AUXILLIARY_FUNCTIONS.c" + + +////TODO: break this into it's own shared file! See cardamom_run_model.c +/* Handle netCDF library errors by printing an error message and exiting with a + * non-zero status.*/ +#define ERREXITCODE 2 +#define NCDFERR(e) {printf("Error in %s at %d: %s\n", __FILE__, __LINE__, nc_strerror(e));} +#define FILE_NAME_MAX_LEN 1000 + +//This is a tiny macro used to do error handeling for netCDF methods with the standard format of returning a result code. +//It helps make the code look less insane by allowing one-line calls +//This as a macro because we want the __FILE__ and __LINE__ macros to work +#define FAILONERROR(ncretval) if (ncretval != NC_NOERR) {NCDFERR(ncretval); exit(ERREXITCODE);} +//This variant will not die, but will still thow a message at the user about the problem. +#define WARNONERROR(ncretval) if (ncretval != NC_NOERR) {NCDFERR(ncretval);} + +/*DALEC_SYNTHETIC SETUP*/ + + + + + + + + + + +int READ_PARI_DATA(PARAMETER_INFO *PI, DATA *DATA,MCMC_OUTPUT *MCOUT,MCMC_OPTIONS *MCOPT, char *CLA[]){ +/*READING IN DALEC_SYNTHETIC DATA*/ +/*opening file*/ + + +/*CHANGE4EDDIE*/ +/*this only applies to the native environment - change accordingly to add default file!*/ +char filename[1000];strcpy(filename,CLA[1]); + + + +printf("MCMC_MODULES.c READ_PARI_DATA(): file read and copied\n"); + + + +/*defining initial values* + * Need to perform MCMC run to determine this, or we need a startfile. Either: + * -netcdf start file is present and has right amount of data, use data inside that file + * -NO FILE is present at all, just build a new solution and store it + */ + + + + + + + +/*Reading file (if available)*/ +/*if number of parameters x number of chains available are contained in file, then OK*/ +/*Otherwise search for new parameters*/ +/* +FILE *fileout0=fopen(MCOPT_CARDAMOM->startfile,"r"); +int filelength; +if (fileout0!=NULL){ +fseek(fileout0, 0, SEEK_END);filelength = ftell(fileout0)/sizeof(double);fclose(fileout0);} +else{filelength=0;} +*/ +/*Two choices: +(1) read parameters from file if these are sufficient +(2) sample/store parameter vectors from file otherwise*/ + + +/*Sampling M=N-N0 chains, where N0 is the number of existing chains in the file*/ +/* +int m,M=MCOPT_CARDAMOM->nchains - filelength/PI->npars; +printf("Number of starting parameter vectors saved in file: %i\n",filelength/PI->npars); +printf("Number of required starting parameters vectors: %i\n", MCOPT_CARDAMOM->nchains); +printf("Number of starting parameter vectors to be sampled here: %i\n", int_max(M,0)); + +if (PI->npars>filelength){ + printf("Initial parameters already sampled & saved"); + */ +/*Read file values into PARS chains (only as many as needed)*/ +/* +fileout0=fopen(MCOPT_CARDAMOM->startfile,"r"); +fread(PI->parini,sizeof(double),PI->npars*MCOPT_CARDAMOM->nchains,fileout0); +fclose(fileout0); +*/ + + +int ncid = 0; +int ncRetVal = nc_open(MCOPT->startfile,NC_NOWRITE, &ncid ); +int failedStartfile = 0; //bool, set if the startfile could not be found. +if (ncRetVal != NC_NOERR) { + printf("%s at %d NOTE: got error (%s) when opening the startfile, ignoring it.\n", __FILE__, __LINE__, nc_strerror(ncRetVal)); + failedStartfile=1; +}else{ + int paramDimID,sampleDimID; //Dim ID number, must be populated each invocation + int parsVarID; // Variable ID numbers, also must be repopulated each invocation + + FAILONERROR(nc_inq_dimid(ncid,"Parameter",¶mDimID)); + FAILONERROR(nc_inq_dimid(ncid,"Sample", &sampleDimID)); + FAILONERROR(nc_inq_varid(ncid,"Parameters",&parsVarID)); + + //Check dimension sizes to make sure they match our expectations! + size_t currentSamples, currentParameters; + FAILONERROR(nc_inq_dimlen(ncid,sampleDimID, ¤tSamples)); + FAILONERROR(nc_inq_dimlen(ncid,paramDimID, ¤tParameters)); + if (currentSamples != MCOPT->nchains || currentParameters != PI->npars) { + printf("%s at %d NOTE: We selected (%s) as our startfile but the data does not match our model! CHECK YOUR STARTFILE!\nThe model expects %d samples over %d params, and the startfile has %zu samples over %zu params.\n", __FILE__, __LINE__, MCOPT->startfile,MCOPT->nchains,PI->npars,currentSamples,currentParameters); + failedStartfile=1; + }else{ + FAILONERROR(nc_get_vara_double(ncid,parsVarID,(const size_t[]){0,0}, (const size_t[]){currentSamples,currentParameters},PI->parini )); + int proposedN = 0; + FAILONERROR(nc_get_att_int(ncid,parsVarID,"N",&proposedN)); + MCOPT->nSTART=proposedN; + FAILONERROR(nc_close(ncid)); + printf("%s at %d NOTE: We selected (%s) as our startfile (%d iterations already done), with %d samples over %d params.\n", __FILE__, __LINE__, MCOPT->startfile,proposedN,MCOPT->nchains,PI->npars); + } +} + +if (failedStartfile){ + FIND_EDC_INITIAL_VALUES(*DATA,PI,MCOPT); +} + + +/*Originally in FIND_EDC_INITAL_VALUES, had comment that follows. Anthony confirmed this is needed for legacy support. +SOON-TO-BE-OBSOLETE: resetting fixed pars to zero for main r*/ +int n; +for (n=0;nnpars;n++){PI->parfix[n]=0;} +/*resetting PI-stepsize (as this has been changed)*/ +for (n=0;nnpars;n++){PI->stepsize[n]=0.0001;} + +printf("CARDAMOM_MDF/MCMC_SETUP/MCMC_MODULES.c: Done with initial parameters"); + + +/*This function is in the MCMC folder*/ +INITIALIZE_MCMC_OUTPUT(*PI,MCOUT,*MCOPT); + +for (n=0;nnpars;n++){PI->stepsize[n]=0.0001;} + +return 0; +} + + +// /*MCMC OPTIONS*/ +// int READ_MCOPT_OBS(MCMC_OPTIONS *MCOPT, char *CLA[]){ +// /*number of command line imputs*/ +// int ncli=atoi(CLA[0]); +// +// /*defining MCMC_OPTIONS structure*/ +// MCOPT->APPEND=0; +// MCOPT->nADAPT=100; +// MCOPT->fADAPT=0.5; +// /*command line (or default) values*/ +// if (ncli<3){MCOPT->nOUT=1000;}else{MCOPT->nOUT=atoi(CLA[3]);}; +// if (ncli<4){MCOPT->nPRINT=1000;}else{MCOPT->nPRINT=atoi(CLA[4]);}; +// if (ncli<5){MCOPT->nWRITE=10;}else{MCOPT->nWRITE=atoi(CLA[5]);}; +// if (ncli<6){MCOPT->minstepsize=1e-7;}else{MCOPT->minstepsize=atof(CLA[6]);}; +// if (ncli<7){MCOPT->mcmcid=1;}else{MCOPT->mcmcid=atof(CLA[7]);}; +// if (ncli<8){MCOPT->nADAPT=100;}else{MCOPT->nADAPT=atoi(CLA[8]);}; +// +// MCOPT->randparini=0; +// MCOPT->returnpars=0; +// MCOPT->fixedpars=0; +// char outfile[200], stepfile[200],startfile[200]; +// if (ncli<2){strcpy(outfile,"MOUT_");strcpy(stepfile,"MOUT_");} +// else{strcpy(outfile,CLA[2]); strcpy(stepfile,CLA[2]); strcpy(startfile,CLA[2]);} +// /*STEP file comes with SUFFIX*/ +// /*PARS file no longer does!*/ +// /*strcat(outfile,"PARS");*/ +// strcat(stepfile,"STEP"); +// strcat(startfile,"START"); +// /*directory*/ +// strcpy(MCOPT->outfile,outfile); +// strcpy(MCOPT->stepfile,stepfile); +// strcpy(MCOPT->startfile,startfile); +// +// return 0; +// +// } + + + + +// #define DEFAULT_DOUBLE_VAL -9999.0 +// #define DEFAULT_INT_VAL -9999 + + + +/*Enter all fields originally defined with MALLOC*/ +int MEMORY_CLEANUP(DATA DATA, PARAMETER_INFO PI, MCMC_OPTIONS MCOPT, MCMC_OUTPUT MCOUT){ + +free(PI.parmin); +free(PI.parmax); +free(PI.parini); +free(PI.parfix); +free(PI.stepsize); +free(PI.transform); + +FREE_DATA_STRUCT(DATA); +/* +free(DATA.MET); +free(DATA.LAI); +free(DATA.NEE); +free(DATA.WOO); +free(DATA.GPP); + + +free(DATA.M_FLUXES); +free(DATA.M_LAI); +free(DATA.M_NEE); +free(DATA.M_POOLS); +free(DATA.M_GPP); + +free(DATA.parmin); +free(DATA.parmax); + +if (DATA.ngpp>0){free(DATA.gpppts);} +if (DATA.nlai>0){free(DATA.laipts);} +if (DATA.nnee>0){free(DATA.neepts);} +if (DATA.nwoo>0){free(DATA.woopts);} + +*/ +free(MCOUT.best_pars); + + +return 0;} + + + + +/*this function initializes the PI fields +It is called from DALEC_ALL_TEMPLATE or equivalent higher level function*/ +int INITIALIZE_PI_STRUCT(PARAMETER_INFO * PI, DATA * DATA, MCMC_OPTIONS *MCO){ +oksofar("CARDAMOM_MDF/MCMC_SETUP/MCMC_MODULES.c INITIALIZE_PI_STRUCT(): initializing PI stucture"); +/*contains 6 fields with min max log for par and par*/ +PI->parmin=calloc(DATA->nopars,sizeof(double)); +PI->parmax=calloc(DATA->nopars,sizeof(double)); +PI->parini=calloc(DATA->nopars*MCO->nchains,sizeof(double)); +PI->parfix=calloc(DATA->nopars,sizeof(double)); +PI->stepsize=calloc(DATA->nopars,sizeof(double)); +PI->transform=calloc(DATA->nopars,sizeof(int)); +/*MAtrix double-pointer allocation*/ +oksofar("CARDAMOM_MDF/MCMC_SETUP/MCMC_MODULES.c INITIALIZE_PI_STRUCT(): about to declare matrix"); + + +/*defining step size*/ + +int n,m; +PI->npars=DATA->nopars; +for (n=0;nnopars;n++){ +/*copying minimum and maximum parameter values from DATA*/ +PI->parmin[n]=DATA->parmin[n]; +PI->parmax[n]=DATA->parmax[n]; +PI->stepsize[n]=0.01;} + +/*Try first hardcoding transform*/ +/*PI->transform[11]=2; +PI->transform[14]=2; +*/ + + +oksofar("CARDAMOM_MDF/MCMC_SETUP/MCMC_MODULES.c INITIALIZE_PI_STRUCT(): stepsizes initialized"); +return 0;} + + + + + +=== FILE: ./C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c === + +#include +#include "../../auxi_fun/oksofar.c" +#include "../../auxi_fun/okcheck.c" +#include "../../auxi_fun/seedrandomnumber.c" + +/*defines all the structures, i.e. DATA, MCOPT, PI*/ + +#include "../../mcmc_fun/MHMCMC/MCMC_FUN/MCMCOPT.c" +#include "MCMC_SETUP/MCMC_MODULES.c" + + +/*Temporarily de-activating to write EDC sampler*/ +#include "../../mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c" +#include "../../mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c" +#include "../../mcmc_fun/MHMCMC/MCMC_FUN/MHMCMC_119.c" +#include + +/*MCMC OPTIONS*/ +int READ_MCOPT(MCMC_OPTIONS *MCOPT, DATA DATA, char *outfile){ +/*number of command line imputs*/ + +/*defining MCMC_OPTIONS structure*/ +MCOPT->APPEND=0; +//MCOPT->nADAPT=100; +MCOPT->fADAPT=0.5; + + +MCOPT->nOUT=DATA.ncdf_data.MCMCID.nITERATIONS; +MCOPT->nSTART=0; +MCOPT->nPRINT=DATA.ncdf_data.MCMCID.nPRINT; +MCOPT->minstepsize=DATA.ncdf_data.MCMCID.minstepsize; +MCOPT->mcmcid=DATA.ncdf_data.MCMCID.value; +MCOPT->nADAPT=DATA.ncdf_data.MCMCID.nADAPT; +MCOPT->fADAPT=DATA.ncdf_data.MCMCID.fADAPT; + +if (DATA.ncdf_data.MCMCID.nSAMPLES==DEFAULT_INT_VAL){DATA.ncdf_data.MCMCID.nSAMPLES=2000;} +if (MCOPT->nOUT==DEFAULT_INT_VAL){MCOPT->nOUT=10000;} +if (MCOPT->nPRINT==DEFAULT_INT_VAL){MCOPT->nPRINT=1000;} +if (MCOPT->minstepsize==DEFAULT_DOUBLE_VAL){MCOPT->minstepsize=1e-5;} +if (MCOPT->mcmcid==DEFAULT_INT_VAL){MCOPT->mcmcid=119;} +if (MCOPT->nADAPT==DEFAULT_INT_VAL){MCOPT->nADAPT=100;} +if (MCOPT->fADAPT==DEFAULT_DOUBLE_VAL){MCOPT->fADAPT=0.05;} + +//Derive nWRITE from fields +MCOPT->nWRITE=MCOPT->nOUT/DATA.ncdf_data.MCMCID.nSAMPLES; + + +printf("**********MCMCOPT SUMMARY*******\n"); + +printf("Starting iteration = %i\n",MCOPT->nSTART); +printf("Number of iterations = %i\n",MCOPT->nOUT); +printf("Print status every %i iterations \n",MCOPT->nPRINT); +printf("Write parameters every %i iterations \n",MCOPT->nWRITE); +printf("Number of samples requested (including burn-in) = %i\n",DATA.ncdf_data.MCMCID.nSAMPLES); +printf("Burn in fraction = %2.2f\n",MCOPT->fADAPT); +printf("MCMC ID= %i\n",MCOPT->mcmcid); + + +printf("***********************************\n"); + +MCOPT->randparini=0; +MCOPT->returnpars=0; +MCOPT->fixedpars=0; +char stepfile[1000],startfile[1000]; +strcpy(stepfile,outfile); strcpy(startfile,outfile); +/*STEP file comes with SUFFIX*/ +/*PARS file no longer does!*/ +/*strcat(outfile,"PARS");*/ +strcat(stepfile,"STEP"); +strcat(startfile,"START"); +/*directory*/ +strcpy(MCOPT->outfile,outfile); +strcpy(MCOPT->stepfile,stepfile); +strcpy(MCOPT->startfile,startfile); + + + +return 0; + +} + + + +int main(int argc,char *CLA[]){ +/*To correctly set-up the MHMCMC*/ + +/*inputs*/ +/*1. met file in*/ +/*2. results file out*/ + //Rest is now obsolete + + + +/*3. number of MCMC solutions requested*/ +/*4. print-to-screen frequency*/ +/*5. write-to-file frequency*/ + + +/*OK is output flag from all functions*/ +int OK = 0; //Need to initilize! + + +/*SETTING number of command line inputs as char in CLA[0]*/ +sprintf(CLA[0],"%d",argc-1); +/*declaring CARDAMOM Binary Format (.cbf) file*/ +char CBFfile[1000], CBRfile[1000]; +//Setting CBF file to equal first argument +strcpy(CBFfile,CLA[1]); +strcpy(CBRfile,CLA[2]); + + + +/***********CARDATA STRUCTURE*************/ + +/*defining data structure*/ +DATA DATA; +/*Initialize data structure - this function is found in CARDAMOM_READ_BINARY_DATA*/ +//OK=INITIALIZE_DATA_STRUCT(&DATA); +//okcheck(OK,"Main data structure initialized"); + +/*read cardamom data from file*/ +/*Function also performs and displays basic checks*/ +CARDAMOM_READ_BINARY_DATA(CBFfile,&DATA); +//okcheck(OK,"Main data structure read successfully"); + +//********************************************// + + + +/*defining MCMC_OPTIONS structure*/ +MCMC_OPTIONS MCOPT; + +/*ID=1 adaptive MHMCMC*/ +/*ID=2 DE-MCMC*/ +/*Hard-coding number of chains for now (for DEMCMC)*/ + +READ_MCOPT(&MCOPT,DATA, CBRfile); + +if (MCOPT.mcmcid==119){MCOPT.nchains=1;} +if (MCOPT.mcmcid==3){MCOPT.nchains=400;} +else if (MCOPT.mcmcid==2){MCOPT.nchains=100;} + + +printf("MDF options structure read successfully"); + + + +printf("CARDAMOM_MDF.c: CARDAMOM MODEL ID = %i\n",DATA.ncdf_data.ID); +printf("CARDAMOM_MDF.c: MCMC ID = %i\n",MCOPT.mcmcid); + +/*defining the MCMC output structure*/ +MCMC_OUTPUT MCOUT; + +/*These lines guarantee high frequency random generator seeding*/ + +//if (argc-1<2){seedrandomnumber(CBFfile);}else{seedrandomnumber(CLA[2]);} + +if (DATA.ncdf_data.MCMCID.seed_number==DEFAULT_INT_VAL){DATA.ncdf_data.MCMCID.seed_number=0;} +srandom(DATA.ncdf_data.MCMCID.seed_number); +printf("*******RANDOM NUMBER SEED**********\n"); +printf("Read in from DATA.ncdf_data.MCMCID.seed_number\n"); +printf("(Default value = 0)\n"); +printf("*******Seed = %i**********\n",DATA.ncdf_data.MCMCID.seed_number); +printf("*******DONE WITH RANDOM NUMBER SEED**********\n"); + + +/*Defining all MCMC components*/ +/*USER DEFINED: SETUP MCMC - templates provides*/ +/*NOTE : READ_PARI_DATA function is stored in DALEC_CDEA_TEMPLATE/MCMC_SETUP/MCMC_MODULES.c*/ +/*TO DO : (a) read DATA first - note that this includes model specific fields, such as nomet, nopars, etc. + these are all loaded via the CARDAMOM_MODEL_LIBRARY(DATA) function*/ +/* : (b) read PI based on DATA*/ + + + + +/***************PI STRUCTURE AND MLF*****************/ + + +/*defining parameter structure*/ +/*this structure is defined as part of the MCMC +Full function can be found in mcmc_fun/MHMCMC/MCMC_FUN/MCMC_OPT.c*/ +PARAMETER_INFO PI; + +/*initializing structure with correct PI fields (as required by MHMCMC)*/ +/*Function is in MCMC_MODULES.c*/ +INITIALIZE_PI_STRUCT(&PI,&DATA,&MCOPT); +printf("CARDAMOM_MDF.c: Parameter info structure initialized\n"); + + +/*choose model likelihood here*/ +/*the MLF function determines the probability of any model output based on data and/or other constraints*/ +/*In future versions: this should be done inside CARDAMOM_READ_BINARY_DATA*/ + + + +/*READ_PARI_DATA and READ_MCOPT should now be generic for all model types*/ +/*CONTAINS "FIND_EDC_INITIAL_VALUES(*DATA,PI);"*/ + + + + + + printf("DATA.ncdf_data.MCMCID.nSAMPLES_EDC_SEARCH=%i\n",DATA.ncdf_data.MCMCID.nSAMPLES_EDC_SEARCH); + + + + + + +clock_t start = clock();//Start timer + + DATA.edcsearch=1; +READ_PARI_DATA(&PI, &DATA, &MCOUT, &MCOPT,CLA); +printf("CARDAMOM_MDF.c: READ_PARI_DATA successfully executed\n"); +// Check whether this is a restart, and if so, set APPEND to 1 +if (MCOPT.nSTART>0){MCOPT.APPEND=1;} + +clock_t end = clock();//Stop timer +double cpu_time_used_search = ((double) (end - start)) / CLOCKS_PER_SEC; + +/*calling the MHMCMC here*/ + + start = clock();//Start timer + + +DATA.edcsearch=0; + +printf("CARDAMOM_MDF.c: about to start MCMC\n"); +printf("CARDAMOM_MDF.c: Prescribed option = %i\n",MCOPT.mcmcid); +switch (MCOPT.mcmcid){ + +case 119: +printf("CARDAMOM_MDF.c: about to start MHMCMC (id = 119)\n"); +MHMCMC_119(DATA.MLF,DATA,PI,MCOPT,&MCOUT); +printf("CARDAMOM_MDF.c: completed MHMCMC 119\n"); +break; +case 2: +printf("CARDAMOM_MDF.c: about to start DEMCMC\n"); +DEMCMC(DATA.MLF,DATA,PI,MCOPT,&MCOUT); +break; +case 3: +//MCOPT.fADAPT=0.05; + //MCOPT.fADAPT=1; +printf(" CARDAMOM_MDF.c: about to start ADEMCMC\n"); +ADEMCMC(DATA.MLF,DATA,PI,MCOPT,&MCOUT); +break; + + +/*printf("CARDAMOM_MDF.c: DEMCMC temporarily disconnected, need to de-bug, correct and re-introduce"); +printf("CARDAMOM_MDF.c: completed DEMCMC\n"); +break;*/ +default: +printf("CARDAMOM_MDF.c: Error: no valid mcmcid value prescribed...\n"); + +} +// printf("CARDAMOM_MDF.c: MCMC complete\n"); +// printf("DATA.M_P[0] = %2.2f\n",DATA.M_P[0]); +// printf("DATA.LAI.values[0] = %2.2f\n",DATA.ncdf_data.LAI.values[0]); +// printf("DATA.LAI.values[24] = %2.2f\n",DATA.ncdf_data.LAI.values[24]); +// printf("DATA.M_POOLS[1] = %2.2f\n",DATA.M_POOLS[1]); +// printf("DATA.ncdf_data.LAI.opt_unc_type=%i\n",DATA.ncdf_data.LAI.opt_unc_type); +// printf("DATA.ncdf_data.LAI.opt_normalization=%i\n",DATA.ncdf_data.LAI.opt_normalization); +// printf("DATA.ncdf_data.LAI.opt_filter=%i\n",DATA.ncdf_data.LAI.opt_filter); +// printf("DATA.ncdf_data.LAI.min_threshold=%2.2f\n",DATA.ncdf_data.LAI.min_threshold); +// printf("DATA.ncdf_data.LAI.single_monthly_unc=%2.2f\n",DATA.ncdf_data.LAI.single_monthly_unc); +// printf("DATA.ncdf_data.LAI.single_annual_unc=%2.2f\n",DATA.ncdf_data.LAI.single_annual_unc); +// printf("DATA.ncdf_data.LAI.single_mean_unc=%2.2f\n",DATA.ncdf_data.LAI.single_mean_unc); +// printf("DATA.ncdf_data.LAI.single_unc=%2.2f\n",DATA.ncdf_data.LAI.single_unc); +// printf("DATA.ncdf_data.LAI.structural_unc=%2.2f\n",DATA.ncdf_data.LAI.structural_unc); +// printf("DATA.ncdf_data.LAI.unc[24]=%f\n",DATA.ncdf_data.LAI.unc[24]); +// printf("DATA.ncdf_data.LAI.length=%i\n",(int)DATA.ncdf_data.LAI.length); +// printf("DATA.ncdf_data.LAI.unc_length=%i\n",(int)DATA.ncdf_data.LAI.unc_length); +// printf("DATA.ncdf_data.LAI.valid_obs_length=%i\n",(int)DATA.ncdf_data.LAI.valid_obs_length); +// double * values;//Timeseries of observation values + + +end = clock();//Stop timer + +double cpu_time_used_main = ((double) (end - start)) / CLOCKS_PER_SEC; +printf("***********************\n"); +printf("***********************\n"); +printf("Done with EDC>0 search MCMC, time used = %6.2f seconds\n",cpu_time_used_search); +printf("Done with main MCMC, time used = %6.2f seconds\n",cpu_time_used_main); +printf("***********************\n"); +printf("***********************\n"); + +/*???????*/ +/*User Defined function needed to clean up memory*/ +MEMORY_CLEANUP(DATA,PI,MCOPT,MCOUT); + + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_DATA_STRUCTURE.c === + +#pragma once +#include "CARDAMOM_MODULE_IDX.c" +#include "CARDAMOM_NETCDF_DATA_STRUCTURE.c" + +typedef struct DATA{ +//This is the netCDF data struct. See CARDAMOM_NETCDF_DATA_STRUCTURE.c for details on all the things contained therein +NETCDF_DATA ncdf_data; + +/****Diagnostics****/ +int edcsearch; + + +/*OBS*/ +/*Number of non-empty points in observation timeseries*/ +/*Number of indices can be stored in single obs vector in the future*/ +double *M_PARS; + +/*saving computational speed by allocating memory to model output*/ +/*Model fluxes*/ +//MODEL FIELDS: these need to be consistent with cost function terms +double *M_ABGB; +double *M_CH4; +double *M_CWOO; +double *M_DOM; +double *M_ET; +double *M_LE; +double *M_H; +double *M_EWT; +double *M_FIR; +double *M_GPP; +double *M_LAI; +double *M_NBE; +double *M_ROFF; +double *M_SCF; +double *M_SIF; +double *M_SWE; + +//Mean values +double M_Mean_ABGB; +double M_Mean_FIR; +double M_Mean_GPP; +double M_Mean_LAI; +//Miscelaneous +double M_ABGB_t0; +//Parameters and emergent quantities +double M_PEQ_NBEmrg; +double M_PEQ_Cefficiency; +double M_PEQ_CUE; +double M_PEQ_Vcmax25; +double M_PEQ_C3frac; +double M_PEQ_iniSnow; +double M_PEQ_iniSOM; +double M_PEQ_LCMA; +double M_PEQ_clumping; +//add PEQ value and unc from previous MCMC *pMCMC* +double M_PEQ_r_ch4; +double M_PEQ_S_fv; +double M_PEQ_rhch4_rhco2; // add '*' if it's timeseries + + +//Full state variables +double *M_FLUXES; +double *M_POOLS; +/*even though sizes are known, memory needs to be explicitly allocated*/ +int *M_EDCD;//Very very obsolete +double *M_P; +double *M_LIKELIHOODS; +double *M_EDCs; + +int *EDC_INSTANCE_COUNTER; +int *EDC_PASS_COUNTER; + +/*static data*/ +// int nodays; +// double deltat; +// double LAT; +// int ID; +// int noobs; +//These quantities are autofilled based on model ID +int nopools; +int nofluxes; +int nopars; +int nolikelihoods; +int noedcs; +// + + + +/*TO DO: include parameter info and model likelihood function fields HERE +These can then be assigned during call to CARDAMOM_MODEL_LIBRARY*/ +double (*MLF)(struct DATA,double *); +double (*EMLF)(struct DATA,double *); +/*parameter & optimization info - add all required fields here*/ +double *parpriors; +double *parmin; +double *parmax; +char **parname; +// int assemble_model; +/*Development in progress: this structure will contain all model-specific fields and memory declarations, making it therefore a flexible storage field for non-global "DATA" fields*/ +void *MODEL; + +//EDCs struct +void *EDCs; + + + +}DATA; + + + + + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_MODEL_LIBRARY.c === + +#pragma once + +int INITIALIZE_PARAMETER_FIELDS(DATA *DATA){ +/*initializing parmin and parmax fields*/ +DATA->parmin=NULL; +DATA->parmax=NULL; +DATA->parname=NULL; +DATA->parmin=calloc(DATA->nopars,sizeof(double)); +DATA->parmax=calloc(DATA->nopars,sizeof(double)); +DATA->parname=calloc(DATA->nopars,sizeof(char *)); +return 0;} + +//#include "ADD_PARAMETER_TO_STACK.c" +//#include "WRITE_MODEL_STACKS_TO_FILE.c" +/*Including all model PARS_INFO_MMMM (model) files*/ +//#include "../CARDAMOM_MODELS/DALEC/DALEC_101/MODEL_INFO_101.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_400/MODEL_INFO_400.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_803/MODEL_INFO_803.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_804/MODEL_INFO_804.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_805/MODEL_INFO_805.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_806/MODEL_INFO_806.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_807/MODEL_INFO_807.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_808/MODEL_INFO_808.c" + +//#include "../CARDAMOM_MODELS/DALEC/DALEC_809/MODEL_INFO_809.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_811/MODEL_INFO_811.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_812/MODEL_INFO_812.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_813/MODEL_INFO_813.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_810/MODEL_INFO_810.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_820/MODEL_INFO_820.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_821/MODEL_INFO_821.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_830/MODEL_INFO_830.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_831/MODEL_INFO_831.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_840/MODEL_INFO_840.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1200/MODEL_INFO_1200.c" + +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1000/MODEL_INFO_1000.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1001/MODEL_INFO_1001.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1002/MODEL_INFO_1002.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1003/MODEL_INFO_1003.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1004/MODEL_INFO_1004.c" +#include "../CARDAMOM_MODELS/DALEC/DALEC_1005/MODEL_INFO_1005.c" +#include "../CARDAMOM_MODELS/DALEC/DALEC_1006/MODEL_INFO_1006.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1009/MODEL_INFO_1009.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1010/MODEL_INFO_1010.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1011/MODEL_INFO_1011.c" + #include "../CARDAMOM_MODELS/DALEC/DALEC_1012/MODEL_INFO_1012.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1015/MODEL_INFO_1015.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1016/MODEL_INFO_1016.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1017/MODEL_INFO_1017.c" + #include "../CARDAMOM_MODELS/DALEC/DALEC_1025/MODEL_INFO_1025.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1030/MODEL_INFO_1030.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1031/MODEL_INFO_1031.c" + #include "../CARDAMOM_MODELS/DALEC/DALEC_1032/MODEL_INFO_1032.c" +//#include "../CARDAMOM_MODELS/DALEC/DALEC_1040/MODEL_INFO_1040.c" + + #include "../CARDAMOM_MODELS/DALEC/DALEC_1045/MODEL_INFO_1045.c" + #include "../CARDAMOM_MODELS/DALEC/DALEC_1046/MODEL_INFO_1046.c" + #include "../CARDAMOM_MODELS/DALEC/DALEC_1047/MODEL_INFO_1047.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1060/MODEL_INFO_1060.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1080/MODEL_INFO_1080.c" + #include "../CARDAMOM_MODELS/DALEC/DALEC_1100/MODEL_INFO_1100.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1101/MODEL_INFO_1101.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1102/MODEL_INFO_1102.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1103/MODEL_INFO_1103.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1105/MODEL_INFO_1105.c" + //#include "../CARDAMOM_MODELS/DALEC/DALEC_1106/MODEL_INFO_1106.c" + // #include "../CARDAMOM_MODELS/DALEC/DALEC_1107/MODEL_INFO_1107.c" + // #include "../CARDAMOM_MODELS/DALEC/DALEC_1108/MODEL_INFO_1108.c" + // #include "../CARDAMOM_MODELS/DALEC/DALEC_1109/MODEL_INFO_1109.c" + // #include "../CARDAMOM_MODELS/DALEC/DALEC_1130/MODEL_INFO_1130.c" + +/*This function attributes model specific variables based + * on the ID number stored in ID*/ +/*General note: The code IDxMA (where x is the model ID) is kept above the model attribute +line. The reason for this is to ensure that Matlab can easily access this code*/ + + + +int CARDAMOM_MODEL_LIBRARY(DATA *DATA){ + + +int status=0; +int ID = DATA->ncdf_data.ID; +if (ID==0){printf("No model prescribed, expect error!");} +//if (ID==101 ){MODEL_INFO_101(DATA);} +//else if (ID==400 ){MODEL_INFO_400(DATA);} +//else if (ID==803 ){MODEL_INFO_803(DATA);} +//else if (ID==804 ){MODEL_INFO_804(DATA);} +//else if (ID==805 ){MODEL_INFO_805(DATA);} +//else if (ID==806 ){MODEL_INFO_806(DATA);} +//else if (ID==807 ){MODEL_INFO_807(DATA);} +//else if (ID==808 ){MODEL_INFO_808(DATA);} +//else if (ID==809 ){MODEL_INFO_809(DATA);} +//else if (ID==810 ){MODEL_INFO_810(DATA);} +//else if (ID==811 ){MODEL_INFO_811(DATA);} +//else if (ID==812 ){MODEL_INFO_812(DATA);} +//else if (ID==813 ){MODEL_INFO_813(DATA);} +//else if (ID==820 ){MODEL_INFO_820(DATA);} + //else if (ID==821 ){MODEL_INFO_821(DATA);} +//else if (ID==830 ){MODEL_INFO_830(DATA);} +//else if (ID==831 ){MODEL_INFO_831(DATA);} +//else if (ID==840 ){MODEL_INFO_840(DATA);} +//else if (ID==1000 ){MODEL_INFO_1000(DATA);} +//else if (ID==1001 ){MODEL_INFO_1001(DATA);} +//else if (ID==1002 ){MODEL_INFO_1002(DATA);} +//else if (ID==1003 ){MODEL_INFO_1003(DATA);} +//else if (ID==1004 ){MODEL_INFO_1004(DATA);} + else if (ID==1005 ){MODEL_INFO_1005(DATA);} + else if (ID==1006 ){MODEL_INFO_1006(DATA);} +//else if (ID==1009 ){MODEL_INFO_1009(DATA);} + else if (ID==1012 ){MODEL_INFO_1012(DATA);} +//else if (ID==1015 ){MODEL_INFO_1015(DATA);} +//else if (ID==1016 ){MODEL_INFO_1016(DATA);} +//else if (ID==1017 ){MODEL_INFO_1017(DATA);} + else if (ID==1025 ){MODEL_INFO_1025(DATA);} +//else if (ID==1030 ){MODEL_INFO_1030(DATA);} +//else if (ID==1031 ){MODEL_INFO_1031(DATA);} + else if (ID==1032 ){MODEL_INFO_1032(DATA);} +//else if (ID==1040 ){MODEL_INFO_1040(DATA);} + + +else if (ID==1045 ){MODEL_INFO_1045(DATA);} +else if (ID==1046 ){MODEL_INFO_1046(DATA);} +else if (ID==1047 ){MODEL_INFO_1047(DATA);} +//else if (ID==1060 ){MODEL_INFO_1060(DATA);} +//else if (ID==1080 ){MODEL_INFO_1080(DATA);} +//else if (ID==1010 ){MODEL_INFO_1010(DATA);} +//else if (ID==1011 ){MODEL_INFO_1011(DATA);} +//else if (ID==1200 ){MODEL_INFO_1200(DATA);} + else if (ID==1100 ){MODEL_INFO_1100(DATA);} + //else if (ID==1101 ){MODEL_INFO_1101(DATA);} + //else if (ID==1102 ){MODEL_INFO_1102(DATA);} + //else if (ID==1103 ){MODEL_INFO_1103(DATA);} + //else if (ID==1105 ){MODEL_INFO_1105(DATA);} + //else if (ID==1106 ){MODEL_INFO_1106(DATA);} + // else if (ID==1107 ){MODEL_INFO_1107(DATA);} + // else if (ID==1108 ){MODEL_INFO_1108(DATA);} + // else if (ID==1109 ){MODEL_INFO_1109(DATA);} + // else if (ID==1130 ){MODEL_INFO_1130(DATA);} + else {status=1; + printf("*********************************************\n"); + printf("No loaded in CARDAMOM_MODEL_LIBRARY.c, expect error!\n"); + printf("*********************************************\n"); + } +printf("*******CARDAMOM MODEL LIBRARY DONE****************\n"); +printf("Model ID = %i loaded & configured...", ID); +printf("****************************************************\n"); + +return status;} + + + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_ASSEMBLE_MODELS.c === + + +#include "../../auxi_fun/okcheck.c" +#include "math.h" +#include +#include "CARDAMOM_READ_BINARY_DATA.c" +/*syntax CARDAMOM_READ_BINARY_CARDADATA(char *filename,CARDADATA *CARDADATA)*/ + + + + +/* the gateway function */ +/*NOTE: this function can be used with any valid model ID (stored in CARDADATA.ID)*/ +int main(int argc, char * arg[]) +{ + +/*declaring loop variable n*/ + +/*storing command line inputs as 2 files*/ + + + +/*declaring data structure*/ +DATA DATA; + +/*Runs all model info functions to assemble models and generate outputs*/ +int id=0,cml; +for (id=0;id<10000;id++){ +DATA.ID=id; +DATA.assemble_model=0; + +CARDAMOM_MODEL_LIBRARY(&DATA); + +if (DATA.assemble_model==1){WRITE_MODEL_STACKS_TO_FILE(&DATA,arg[1]);} +} + +/*make file with output summary*/ + + + +/* +CARDAMOM_READ_BINARY_DATA(metfile,&CARDADATA); +*/ + + + + +FREE_DATA_STRUCT(DATA); + + + + + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/NETCDF_AUXILLIARY_FUNCTIONS.c === + +#pragma once +#include + + + +#define DEFAULT_DOUBLE_VAL -9999.0 +#define DEFAULT_INT_VAL -9999 + + +//NOTE ABOUT THIS MACRO: +//If set to 1, netCDF methods will continue to run and return with default values if they fail to find the requested variable or attribute +//if set to 0, they will instantly die on failing to find any variable or attribute +//This is meant as a debugging tool more than anything else, and can be used with a "fully complete" netcdf cardamom file containing every variable in order to check if there were typeos in the c code. +//In the production enviroment, this should always be set to 1 +#define ALLOW_DEFAULTS 1 + + + + +/* Handle errors by printing an error message and exiting with a + * non-zero status.*/ + +#define ERRCODE 2 +#define ERR(e) {printf("Error in %s at %d: %s\n", __FILE__, __LINE__, nc_strerror(e)); exit(ERRCODE);} +//Helper for errors in variable-getting methods +#define ERR_VAR(e, var) {printf("Error in %s at %d with variable \"%s\": %s\n", __FILE__, __LINE__, var, nc_strerror(e)); exit(ERRCODE);} +//Helper for errors in attribute-getting methods +#define ERR_ATTR_AND_CONTEXT(e, attr, context, varID) {printf("Error in %s at %d with attribute \"%s\" in the context \"%s\" (%d): %s\n", __FILE__, __LINE__, attr,context,varID, nc_strerror(e)); exit(ERRCODE);} + + + + +/* + * Function: ncdf_read_int_attr + * -------------------- + * Attempts to read a single int that is stored under a particular name in the netCDF file's attributes + * + * ncid: netCDF file ID to pull the data from. This is the id given by nc_open after the netCDF file is opened + * context: this is the context in which the attribute was stored. Can be a variable name, or '/' if it is a global attribute + * attrName: This is the name of the attibute to read + * + * returns: the int attribute read, or DEFAULT_INT_VAL if the requested attribute does not exsist. + * if there is an error, the program exits after displaying a message. + */ + + + +int ncdf_read_int_attr(int ncid, const char* context, const char * attrName){ + int retval =0; //Return value variable for NCDF calls. + int attrResult; + int varID=NC_GLOBAL; + if ((context != NULL) && (context[0] != '/')){ + //Attempt to locate the id of the approprate variable + if ((retval = nc_inq_varid(ncid, context, &varID))){ + if (retval ==NC_ENOTVAR && ALLOW_DEFAULTS){ + //we failed to find the context (and so we never even looked for the attribute!) + //we will return the default double value + return DEFAULT_INT_VAL; + } + //The failure was in locating the context, not the arttr + ERR_ATTR_AND_CONTEXT(retval,attrName, context,varID ); + } + } + if ((retval = nc_get_att_int(ncid, varID, attrName, &attrResult))){ + if (retval ==NC_ENOTATT && ALLOW_DEFAULTS ){ + return DEFAULT_INT_VAL; + } + ERR_ATTR_AND_CONTEXT(retval,attrName, context, varID); + } + return attrResult; +} +/* + * Function: ncdf_read_double_attr + * -------------------- + * Attempts to read a single double that is stored under a particular name in the netCDF file's attributes + * + * ncid: netCDF file ID to pull the data from. This is the id given by nc_open after the netCDF file is opened + * context: this is the context in which the attribute was stored. Can be a variable name, or '/' if it is a global attribute + * attrName: This is the name of the attibute to read + * + * returns: the double attribute read. if there is an error, the program exits after displaying a message. + */ +double ncdf_read_double_attr(int ncid, const char* context, const char * attrName ){ + int retval =0; //Return value variable for NCDF calls. + double attrResult; + int varID=NC_GLOBAL; + if ((context != NULL) && (context[0] != '/')){ + //Attempt to locate the id of the approprate variable + if ((retval = nc_inq_varid(ncid, context, &varID))){ + if (retval ==NC_ENOTVAR && ALLOW_DEFAULTS){ + //we failed to find the context (and so we never even looked for the attribute!) + //we will return the default double value + return DEFAULT_DOUBLE_VAL; + } + //Note that The failure was in locating the context, not the attr + ERR_ATTR_AND_CONTEXT(retval,attrName, context,varID ); + } + } + if ((retval = nc_get_att_double(ncid, varID, attrName, &attrResult))){ + if (retval ==NC_ENOTATT && ALLOW_DEFAULTS){ + //we failed to find the attribute, so we should return the default double value + return DEFAULT_DOUBLE_VAL; + } + ERR_ATTR_AND_CONTEXT(retval,attrName, context,varID); + } + return attrResult; +} + + + + + +/* + * Function: ncfd_get_var_info + * -------------------- + * Helper method that Attempts to read the length and varID of a 1 or 0 dimensional variable that is stored under a particular name in the netCDF file's variables + * + * ncid: netCDF file ID to pull the data from. This is the id given by nc_open after the netCDF file is opened + * varName: This is the name of the variable to read + * arrayLen: pointer where the total length in number of elements of the resulting array will be written (NOT MEMORY SIZE) + * varID: Pointer to where the varID of the requested var will be written + * + * returns: 0 if the variable does not exsist (and the macro ALLOW_DEFAULTS is set), 1 if we found the variable and functioned normally + * if there is an error, the program exits after displaying a message. + */ + + +int ncfd_get_var_info(int ncid, const char * varName, size_t * arrayLen, int * varID) { + int retval =0; //Return value variable for NCDF calls. + int numberOfDims; + int dimensionID; + //Attempt to locate the id of the approprate variable + if ((retval = nc_inq_varid(ncid, varName, varID))){ + //Test if the variable just does not exsist, and if we are allowed to just give a default. + if (retval ==NC_ENOTVAR && ALLOW_DEFAULTS){ + //We did not find anything, but this is still a valid result. Make sure everything is set. + *arrayLen = 0; + *varID=-1; + return 0; //Return false to note our failure to find something + }else{ + ERR_VAR(retval, varName); //Die. either we did not find anything and that was marked as unacceptable in the macro ALLOW_DEFAULTS, or something else wrong happened. + } + } + //check to make sure the variable has only one dim (Critial to assure well-defined behavior for all other ncdf function calls!!!) + if ((retval = nc_inq_varndims(ncid, *varID, &numberOfDims))){ + ERR_VAR(retval, varName); + } + if (numberOfDims>1 || numberOfDims<0){ + printf("Error in %s at %d while trying to read var %s: CARDAMOM ncfd_get_var_info only supports 1 and 0 dimensional variables, but var has %d dimensions.\n", __FILE__, __LINE__, varName,numberOfDims); + exit(1); + } + //begin work in preperation for allocating the array where the variable data will be stored. + if (numberOfDims==0){ + //special case, var is a scalar, so we know the length of the array is 1 + *arrayLen=1; + //No need to inspect dimensions or anything else, we have a scalar + return 1; + } + if ((retval = nc_inq_vardimid(ncid, *varID, &dimensionID))){ + ERR_VAR(retval, varName); + } + if ((retval = nc_inq_dimlen(ncid, dimensionID, arrayLen))){ + ERR_VAR(retval, varName); + } + //If we got here, we were sucessful, so return true + return 1; +} + + + +/* + * Function: ncdf_read_int_var + * -------------------- + * Attempts to read a 1 dimensional int variable that is stored under a particular name in the netCDF file's variables + * + * ncid: netCDF file ID to pull the data from. This is the id given by nc_open after the netCDF file is opened + * varName: This is the name of the variable to read + * arrayLen: pointer where the total length in number of elements of the resulting array will be written (NOT MEMORY SIZE) + * + * returns: an array of all the values of the variable, + * if there is an error, the program exits after displaying a message. + */ +int * ncdf_read_int_var(int ncid, const char * varName, size_t * arrayLen ){ + int retval =0; //Return value variable for NCDF calls. + int varID; + if ( !ncfd_get_var_info(ncid, varName, arrayLen, &varID)){ + //Return a null pointer due to no content + return NULL; + } + //allocate the actual array we will be returning + int * resultArray= (int*)calloc(*arrayLen, sizeof(int)); + + if ((retval = nc_get_var_int(ncid, varID, resultArray))){ + ERR_VAR(retval, varName); + } + return resultArray; +} + +/* + * Function: ncdf_read_double_var + * -------------------- + * Attempts to read a 1 dimensional double variable that is stored under a particular name in the netCDF file's variables + * + * ncid: netCDF file ID to pull the data from. This is the id given by nc_open after the netCDF file is opened + * varName: This is the name of the variable to read + * arrayLen: pointer where the total length in number of elements of the resulting array will be written (NOT MEMORY SIZE) + * + * returns: an array of all the values of the variable, + * if there is an error, the program exits after displaying a message. + */ +double * ncdf_read_double_var(int ncid, const char * varName, size_t * arrayLen ){ + int retval =0; //Return value variable for NCDF calls. + int varID; + if ( !ncfd_get_var_info(ncid, varName, arrayLen, &varID)){ + //Return a null pointer due to no content + return NULL; + } + //allocate the actual array we will be returning + double * resultArray= (double*)calloc(*arrayLen, sizeof(double)); + + if ((retval = nc_get_var_double(ncid, varID, resultArray))){ + ERR_VAR(retval, varName); + } + return resultArray; +} + + + + +/* + * Function: ncdf_read_double_2D + * -------------------- + * Attempts to read a 2 dimensional double variable that is stored under a particular name in the netCDF file's variables + * + * ncid: netCDF file ID to pull the data from. This is the id given by nc_open after the netCDF file is opened + * varName: This is the name of the variable to read + * dimLen: pointer to a 2 element array where the total length in number of elements of the resulting arrays will be written (NOT MEMORY SIZE) + Note: this memory MUST be allocated allready, and should be of type size_t[2]. + * + * returns: a 2D array of all the values of the variable, represented by an array of pointers to arrays. (IE, a double**, or double[][]) + * if the requested var does not exsist (and ALLOW_DEFAULTS is set), the return value will be + * if there is an error, the program exits after displaying a message. + */ +double ** ncdf_read_double_2D(int ncid, const char * varName, size_t * dimLen ){ + int retval =0; //Return value variable for NCDF calls. + int varID; + int numberOfDims; + int dimensionIDs[2] = {-1,-1}; //array where we store the dimensionIDs. default to -1 + //Attempt to locate the id of the approprate variable + if ((retval = nc_inq_varid(ncid, varName, &varID))){ + //Test if the variable just does not exsist, and if we are allowed to just give a default. + if (retval ==NC_ENOTVAR && ALLOW_DEFAULTS){ + //We did not find anything, but this is still a valid result. Make sure lengths are set to 0 + dimLen[0]=0; + dimLen[1]=0; + return NULL; //Return null to mark failure + }else{ + ERR_VAR(retval, varName); //Die. either we did not find anything and that was marked as unacceptable in the macro ALLOW_DEFAULTS, or something else wrong happened. + } + } + //check to make sure the variable has only one dim (Critial to assure well-defined behavior for all other ncdf function calls!!!) + if ((retval = nc_inq_varndims(ncid, varID, &numberOfDims))){ + ERR_VAR(retval, varName); + } + if (numberOfDims!=2){ + printf("Error in %s at %d while trying to read var %s: CARDAMOM netCDF was trying to read 2D var, but var has %d dimensions.\n", __FILE__, __LINE__, varName,numberOfDims); + exit(1); + } + //Now store all the dimensionIDs (There should be 2) + if ((retval = nc_inq_vardimid(ncid, varID, dimensionIDs))){ + ERR_VAR(retval, varName); + } + //Dim 1 + if ((retval = nc_inq_dimlen(ncid, dimensionIDs[0], dimLen))){ + ERR_VAR(retval, varName); + } + //Dim 2 + if ((retval = nc_inq_dimlen(ncid, dimensionIDs[1], dimLen+1))){ //Beware, dimLen+1 is pointer arithmatic, NOT normal addition + ERR_VAR(retval, varName); + } + + size_t startIndexes[2] = {0,0}; //This is just the indexes we want to start at, which we pass to nc_get_vara. We will begin at 0,0, and increment only the first dim + size_t readCount[2] = {1,-1}; //This is just the number of elements we want to read at a time, which we pass to nc_get_vara. + readCount[1]= dimLen[1]; //We want to read all the elements that are there, so we set it to the len of the second dim + //allocate the array we will be returning + double ** resultArray= (double**)calloc(dimLen[0], sizeof(double*)); + for(int idx=0; idx1){ + printf("Error in %s at %d while trying to read var %s: ncdf_read_single_int_var only supports one value, but var has %lu values.\n", __FILE__, __LINE__, varName,arrayLen); + exit(1); + } + + if ((retval = nc_get_var_int(ncid, varID, &result))){ + ERR_VAR(retval, varName); + } + return result; +} + + +/* + * Function: ncdf_read_single_double_var + * -------------------- + * Attempts to read a scalar double variable that is stored under a particular name in the netCDF file's variables + * + * ncid: netCDF file ID to pull the data from. This is the id given by nc_open after the netCDF file is opened + * varName: This is the name of the variable to read + * + * returns: the value of the variable, + * if there is an error, the program exits after displaying a message. + */ +double ncdf_read_single_double_var(int ncid, const char * varName ){ + int retval =0; //Return value variable for NCDF calls. + int varID; + double result; + if ((retval = nc_inq_varid(ncid, varName, &varID))){ + if (retval ==NC_ENOTVAR && ALLOW_DEFAULTS ){ + return DEFAULT_DOUBLE_VAL; + }else{ + ERR_VAR(retval, varName); + } + } + size_t arrayLen; + ncfd_get_var_info(ncid, varName, &arrayLen, &varID); + //No need to allocate an array, just check the size and die if it is wrong + if (arrayLen>1){ + printf("Error in %s at %d while trying to read var %s: ncdf_read_single_double_var only supports one value, but var has %lu values.\n", __FILE__, __LINE__, varName,arrayLen); + exit(1); + } + if ((retval = nc_get_var_double(ncid, varID, &result))){ + ERR_VAR(retval, varName); + } + return result; +} + + + + +int default_int_value(int * A, int B){ + if (*A==DEFAULT_DOUBLE_VAL){*A=B;} + return 0;} + + +int default_double_value(double * A, double B){ + if (*A==DEFAULT_INT_VAL){*A=B;} + return 0;} + + + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/ADD_PARAMETER_TO_STACK.c === + +#include "CARDAMOM_DATA_STRUCTURE.c" +int ADD_PARAMETER_TO_STACK(DATA * DATA, char *parname,double parmin,double parmax){ +/*TO DO: add "parnames" to DATA*/ +/*Use realloc*/ +/*Step 1. add more parameters*/ +int N=DATA->nopars; + +/*Step 2. re-allocate memory to accomodate more parameters*/ + +DATA->parname=realloc(DATA->parname,(N+1)*sizeof(char*)); +DATA->parmin=realloc(DATA->parmin,(N+1)*sizeof(double)); +DATA->parmax=realloc(DATA->parmax,(N+1)*sizeof(double)); + +/*Populate with new parameter entry*/ +DATA->parmin[N]=parmin; +DATA->parmax[N]=parmax; +DATA->parname[N]=parname; +DATA->nopars=N+1; + +return 0;} + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_MODULE_IDX.c === + +#pragma once +typedef struct MODELS{ +int dalec_1004;}MODELS; + + +typedef struct HYDROLOGY{ +int infiltration_imax; +int van_genuchten;}HYDROLOGY; + +typedef struct MODULE_IDX{ +MODELS MODELS; +HYDROLOGY HYDROLOGY;}MODULE_IDX; + + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_NCDF_TESTS.c === + + +#include "../../auxi_fun/okcheck.c" +#include "math.h" +#include +#include "CARDAMOM_READ_NETCDF_DATA.c" +/*syntax CARDAMOM_READ_BINARY_CARDADATA(char *filename,CARDADATA *CARDADATA)*/ + + + + +/* the gateway function */ +/*NOTE: this function can be used with any valid model ID (stored in CARDADATA.ID)*/ +int main(int argc, char *files[]) +{ + + +/*storing command line inputs as 2 files*/ +char metfile[200];strcpy(metfile,files[1]); +//printf("reading %s",metfile ); + + +/*declaring data structure*/ +NETCDF_DATA CARDADATA; + +CARDAMOM_READ_NETCDF_DATA(metfile,&CARDADATA); + +printf("CH4_STRUCT has uncer: %f first 3 vals are: %f %f %f",CARDADATA.CH4.Uncertainty, CARDADATA.CH4.values[0],CARDADATA.CH4.values[1],CARDADATA.CH4.values[2] ); + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c === + +//This file was moddified from CARDAMOM_READ_BINARY_DATA.c +//it attepts to read in a netcdf file and store it +//Note that a lot of this is derived from https://www.unidata.ucar.edu/software/netcdf/docs/simple_nc4_rd_8c-example.html + +#pragma once +#include "../../auxi_fun/filediag.c" +#include "stdlib.h" +#include "stdio.h" +#include "memory.h" +#include +#include "CARDAMOM_NETCDF_DATA_STRUCTURE.c" +//Data +#include "../COST_FUNCTION/CARDAMOM_LIKELIHOOD_FUNCTION.c" +#include "NETCDF_AUXILLIARY_FUNCTIONS.c" +//Fusion + + +#include + + +//NOTE ABOUT THIS MACRO: +//If set to 1, netCDF methods will continue to run and return with default values if they fail to find the requested variable or attribute +//if set to 0, they will instantly die on failing to find any variable or attribute +//This is meant as a debugging tool more than anything else, and can be used with a "fully complete" netcdf cardamom file containing every variable in order to check if there were typeos in the c code. +//In the production enviroment, this should always be set to 1 +#define ALLOW_DEFAULTS 1 + + +//#include "CARDAMOM_MODEL_LIBRARY.c" + + + + +/* Handle errors by printing an error message and exiting with a + * non-zero status.*/ + +#define ERRCODE 2 +#define ERR(e) {printf("Error in %s at %d: %s\n", __FILE__, __LINE__, nc_strerror(e)); exit(ERRCODE);} +//Helper for errors in variable-getting methods +#define ERR_VAR(e, var) {printf("Error in %s at %d with variable \"%s\": %s\n", __FILE__, __LINE__, var, nc_strerror(e)); exit(ERRCODE);} +//Helper for errors in attribute-getting methods +#define ERR_ATTR_AND_CONTEXT(e, attr, context, varID) {printf("Error in %s at %d with attribute \"%s\" in the context \"%s\" (%d): %s\n", __FILE__, __LINE__, attr,context,varID, nc_strerror(e)); exit(ERRCODE);} + + + + +/* + * Function: CARDAMOM_READ_NETCDF_DATA + * -------------------- + * Attempts to read in the cardamom netcdf file + * + * filename: The path of the file to be read + * DATA: The DATA struct to read the data into + * + * + * NOTE: if you intend to modify what is read in when reading a netCDF file, + * You MUST edit both this method, and the DATA struct in CARDAMOM/C/projects/CARDAMOM_GENERAL/CARDAMOM_DATA_STRUCTURE.c + */ + + + + + + int DEFAULT_REFERENCE_MEAN(TIMESERIES_DRIVER_STRUCT * DRI){ + if (DRI->reference_mean==DEFAULT_DOUBLE_VAL){ + int n;DRI->reference_mean=0; + for (n=0;nlength;n++){ + DRI->reference_mean+=DRI->values[n]/(double)DRI->length;} + } + + return 0; + } + + + +int CARDAMOM_READ_NETCDF_DATA(char *filename,NETCDF_DATA *DATA) +{ + int retval =0; //Return value variable for NCDF calls. + int ncid; + if ((retval = nc_open(filename, NC_NOWRITE, &ncid))){ + ERR(retval); + } + + + + + + +// +// //Global defaults +// default_int_value(OBS.opt_unc_type,0); +// default_int_value(OBS.opt_normalization,0);//(0 = none, 1 = remove mean, 2 = divide by mean) +// default_int_value(OBS.opt_filter,0); +// default_double_value(OBS.opt_min_threshold,log(0));//minus infinity +// default_double_value(OBS.structural_unc,0); + + + +//Read data +DATA->ABGB=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "ABGB"); +DATA->CH4=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "CH4"); +DATA->CWOO=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "CWOO"); +DATA->DOM=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "DOM"); +DATA->ET=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "ET"); +DATA->LE=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "LE"); +DATA->H=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "H"); +DATA->EWT=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "EWT"); +DATA->FIR=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "FIR"); +DATA->GPP=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "GPP"); +DATA->LAI=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "LAI"); +DATA->NBE=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "NBE"); +DATA->ROFF=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "ROFF"); +DATA->SCF=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "SCF"); +DATA->SIF=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "SIF"); +DATA->SWE=READ_NETCDF_TIMESERIES_OBS_FIELDS(ncid, "SWE"); + + +// printf("Just read NBE...\n"); +// printf("DATA->NBE.values[0] = %2.2f\n",DATA->NBE.values[0]); + + +//Read time-averaged data + +DATA->Mean_ABGB=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "Mean_ABGB"); +DATA->Mean_GPP=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "Mean_GPP"); +DATA->Mean_LAI=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "Mean_LAI"); +DATA->Mean_FIR=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "Mean_FIR"); + + +//Read parameters and single observations +DATA->PEQ_NBEmrg=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_NBEmrg"); +DATA->PEQ_Cefficiency=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_Cefficiency"); +DATA->PEQ_CUE=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_CUE"); +DATA->PEQ_C3frac=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_C3frac"); +DATA->PEQ_Vcmax25=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_Vcmax25"); +DATA->PEQ_iniSOM=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_iniSOM"); +DATA->PEQ_iniSnow=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_iniSnow"); +DATA->PEQ_LCMA=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_LCMA"); +DATA->PEQ_clumping=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_clumping"); + +//add PEQ value and unc from previous MCMC *pMCMC* +DATA->PEQ_r_ch4=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_r_ch4"); +DATA->PEQ_S_fv=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_S_fv"); +DATA->PEQ_rhch4_rhco2=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_rhch4_rhco2"); + +//Global defaults: these are set in pre-process if not defined below +// default_int_value(&OBS->opt_unc_type,0); +// default_int_value(&OBS->opt_normalization,0); +// default_int_value(&OBS->opt_filter,0); +// default_double_value(&OBS->opt_min_threshold,log(0));//minus infinity +// default_double_value(&OBS->structural_unc,0); + + +printf("Warning: No longer assigning default uncertainty values. Please double check your driver file contains uncertainties for all observations used.\n"); +// printf("Example uncertainty values (used in the past) per variable:\n"); +// // Default ABGB options +// printf("ABGB.opt_unc_type=1; ABGB.single_unc=2; ABGB.min_threshold=10 gC/m2;\n"); +// default_int_value(&DATA->ABGB.opt_unc_type,1); +// default_double_value(&DATA->ABGB.single_unc,2); +// default_double_value(&DATA->ABGB.min_threshold,10);//gC/m2 + +// // Default CH4 options +// printf("CH4.opt_unc_type=1; CH4.single_unc=2; CH4.min_threshold=1e-5 mgCH4/m2/d;\n"); +// default_int_value(&DATA->CH4.opt_unc_type,1); +// default_double_value(&DATA->CH4.single_unc,2); +// default_double_value(&DATA->CH4.min_threshold,1e-5);//mgCH4/m2/d + +// //Default ET options +// printf("ET.opt_unc_type=1; ET.single_unc=2; ET.min_threshold=0.1 mm/d;\n"); +// default_int_value(&DATA->ET.opt_unc_type,1); +// default_double_value(&DATA->ET.single_unc,2); +// default_double_value(&DATA->ET.min_threshold,0.1); + +// //Default ROFF options +// printf("ROFF.opt_unc_type=1; ROFF.single_unc=2; ROFF.min_threshold=0.1 mm/d;\n"); +// default_int_value(&DATA->ROFF.opt_unc_type,1); +// default_double_value(&DATA->ROFF.single_unc,2); +// default_double_value(&DATA->ROFF.min_threshold,0.1); + +// //Default EWT options; +// printf("EWT.single_unc=2; EWT.opt_normalization=1;\n"); +// default_double_value(&DATA->EWT.single_unc,50);//mm +// default_int_value(&DATA->EWT.opt_normalization,1); + +// //Default GPP options +// printf("GPP.opt_unc_type=1; GPP.single_unc=2; GPP.min_threshold=0.1 gC/m2/d;\n"); +// default_int_value(&DATA->GPP.opt_unc_type,1); +// default_double_value(&DATA->GPP.single_unc,2); +// default_double_value(&DATA->GPP.min_threshold,0.1);//gC/m2/d + +// //Default SIF options - shuang added +// printf("SIF.opt_unc_type=1; SIF.single_unc=2; SIF.min_threshold=0.1 gC/m2/d;\n"); +// default_int_value(&DATA->SIF.opt_unc_type,1); +// default_double_value(&DATA->SIF.single_unc,2); +// default_double_value(&DATA->SIF.min_threshold,0.1);//gC/m2/d + +// //Default LAI options +// printf("LAI.opt_unc_type=1; LAI.single_unc=2; LAI.min_threshold=0.1 m2/m2;\n"); +// default_int_value(&DATA->LAI.opt_unc_type,1); +// default_double_value(&DATA->LAI.single_unc,2); +// default_double_value(&DATA->LAI.min_threshold,0.1);//m2/m2 + +// // //Default FIR options +// // printf("FIR.opt_unc_type=0; FIR.single_unc=0.2; FIR.min_threshold=0.001 gC/m2/day;\n"); +// // default_int_value(&DATA->FIR.opt_unc_type,0); +// // default_double_value(&DATA->FIR.single_unc,0.2); +// // default_double_value(&DATA->FIR.min_threshold,0.001);//m2/m2 + +// //Default NBE options; +// printf("NBE.single_unc=1 gC/m2/d;\n"); +// default_double_value(&DATA->NBE.single_unc,1);//gC/m2/d + +// //Default DOM options +// printf("DOM.opt_unc_type=1; DOM.single_unc=2; DOM.min_threshold=10 gC/m2;\n"); +// default_int_value(&DATA->DOM.opt_unc_type,1); +// default_double_value(&DATA->DOM.single_unc,2); +// default_double_value(&DATA->DOM.min_threshold,10);//gC/m2 + + +// //Default SCF options +// printf("SCF.opt_unc_type=0; SCF.single_unc=0.1; SCF.min_threshold=0.1 m2/m2;\n"); +// default_int_value(&DATA->SCF.opt_unc_type,0); +// default_double_value(&DATA->SCF.single_unc,0.1); +// default_double_value(&DATA->SCF.min_threshold,0.1);//m2/m2 + +//pre-process obs to save time +//Only required for timeseries obs + //Keep alphabetical order if possible +printf("Preprocess ABGB: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->ABGB); +printf("Preprocess CH4: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->CH4); +printf("Preprocess CWOO: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->CWOO); +printf("Preprocess DOM: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->DOM); +printf("Preprocess ET: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->ET); +printf("Preprocess LE: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->LE); +printf("Preprocess H: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->H); +printf("Preprocess EWT: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->EWT); +printf("Preprocess GPP: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->GPP); +printf("Preprocess FIR: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->FIR); +printf("Preprocess LAI: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->LAI); +printf("Preprocess NBE: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->NBE); +printf("Preprocess ROFF: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->ROFF); +printf("Preprocess SCF: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->SCF); +printf("Preprocess SIF: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->SIF); +printf("Preprocess SWE: "); +TIMESERIES_OBS_STRUCT_PREPROCESS(&DATA->SWE); + + +printf("Done preprocess"); + + + + + +printf("Done reading all other edc "); + + + DATA->BURNED_AREA.values=ncdf_read_double_var(ncid, "BURNED_AREA", &(DATA->BURNED_AREA.length)); + DATA->BURNED_AREA.reference_mean=ncdf_read_double_attr(ncid, "BURNED_AREA","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->BURNED_AREA); + + + DATA->CO2.values=ncdf_read_double_var(ncid, "CO2", &(DATA->CO2.length)); + DATA->CO2.reference_mean=ncdf_read_double_attr(ncid, "CO2","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->CO2); + + DATA->DISTURBANCE_FLUX.values=ncdf_read_double_var(ncid, "DISTURBANCE_FLUX", &(DATA->DISTURBANCE_FLUX.length)); + DATA->DISTURBANCE_FLUX.reference_mean=ncdf_read_double_attr(ncid, "DISTURBANCE_FLUX","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->DISTURBANCE_FLUX); + + DATA->DOY.values=ncdf_read_double_var(ncid, "DOY", &(DATA->DOY.length)); + //DATA->DOY.reference_mean=ncdf_read_double_attr(ncid, "DOY","reference_mean"); + + DATA->SKT.values=ncdf_read_double_var(ncid, "SKT", &(DATA->SKT.length)); + DATA->SKT.reference_mean=ncdf_read_double_attr(ncid, "SKT","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->SKT); + + DATA->SNOWFALL.values=ncdf_read_double_var(ncid, "SNOWFALL", &(DATA->SNOWFALL.length)); + DATA->SNOWFALL.reference_mean=ncdf_read_double_attr(ncid, "SNOWFALL","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->SNOWFALL); + + DATA->SSRD.values=ncdf_read_double_var(ncid, "SSRD", &(DATA->SSRD.length)); + DATA->SSRD.reference_mean=ncdf_read_double_attr(ncid, "SSRD","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->SSRD); + + DATA->STRD.values=ncdf_read_double_var(ncid, "STRD", &(DATA->STRD.length)); + DATA->STRD.reference_mean=ncdf_read_double_attr(ncid, "STRD","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->STRD); + + + DATA->T2M_MAX.values=ncdf_read_double_var(ncid, "T2M_MAX", &(DATA->T2M_MAX.length)); + DATA->T2M_MAX.reference_mean=ncdf_read_double_attr(ncid, "T2M_MAX","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->T2M_MAX); + + + DATA->T2M_MIN.values=ncdf_read_double_var(ncid, "T2M_MIN", &(DATA->T2M_MIN.length)); + DATA->T2M_MIN.reference_mean=ncdf_read_double_attr(ncid, "T2M_MIN","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->T2M_MIN); + + + DATA->TIME_INDEX.values=ncdf_read_double_var(ncid, "time", &(DATA->TIME_INDEX.length)); + //DATA->TIME_INDEX.reference_mean=ncdf_read_double_attr(ncid, "time","reference_mean"); + + + DATA->TOTAL_PREC.values=ncdf_read_double_var(ncid, "TOTAL_PREC", &(DATA->TOTAL_PREC.length)); + DATA->TOTAL_PREC.reference_mean=ncdf_read_double_attr(ncid, "TOTAL_PREC","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->TOTAL_PREC); + + + DATA->VPD.values=ncdf_read_double_var(ncid, "VPD", &(DATA->VPD.length)); + DATA->VPD.reference_mean=ncdf_read_double_attr(ncid, "VPD","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->VPD); + + + DATA->YIELD.values=ncdf_read_double_var(ncid, "YIELD", &(DATA->YIELD.length)); + DATA->YIELD.reference_mean=ncdf_read_double_attr(ncid, "YIELD","reference_mean"); + DEFAULT_REFERENCE_MEAN(&DATA->YIELD); + + + + + //Summary & derived variables +// double EDC; +// double EDCDIAG; +// double EDC_EQF; +// double ID; +// double LAT; +// double Ntimesteps; +// double deltat; + + DATA->EDC=ncdf_read_single_double_var(ncid, "EDC"); + + DATA->EDCDIAG=ncdf_read_single_int_var(ncid, "EDCDIAG"); + default_int_value(&DATA->EDCDIAG,0); + + + DATA->EDC_EQF=ncdf_read_single_double_var(ncid, "EDC_EQF"); + + default_double_value(&DATA->EDC_EQF,2.0); + printf("EDC_EQF = %2.2f\n",DATA->EDC_EQF); + + + DATA->ID=ncdf_read_single_double_var(ncid, "ID" ); + DATA->LAT=ncdf_read_single_double_var(ncid, "LAT" ); + + //Pre-processing + //Ntimesteps + //The deltat and DATA->Ntimesteps calculations are highly implicit and code prone to bugs. Need to replace with more explicit definitions of time and deltat + DATA->Ntimesteps=DATA->TIME_INDEX.length; + //Delta T + if ( DATA->Ntimesteps>1){ + DATA->deltat=DATA->TIME_INDEX.values[1]-DATA->TIME_INDEX.values[0];} + else { + DATA->deltat=DATA->TIME_INDEX.values[0];} + + //Mean temp + DATA->meantemp=DATA->T2M_MIN.reference_mean*0.5 + DATA->T2M_MAX.reference_mean*0.5; + //Solar Zenith Angle + DATA->SZA=(double *)calloc(DATA->Ntimesteps, sizeof(double)); + int n; + double pi=3.1415927; + for (n=0;nNtimesteps;n++){ + /*Calculate light extinction coefficient*/ +double B = (DATA->DOY.values[n]-81)*2*pi/365.; +double ET1 = 9.87*sin(2*B)-7.53*cos(B)-1.5*sin(B); +double DA = 23.45*sin((284+DATA->DOY.values[n])*2*pi/365); //Deviation angle +//double LST = (int) (DOY[n]*24*60) % (24*60); +double LST=0.5*24*60; +double AST = LST+ET1; +double h = (AST-12*60)/4; //hour angle +double alpha = asin((sin(pi/180*DATA->LAT)*sin(pi/180*DA)+cos(pi/180*DATA->LAT)*cos(pi/180.*DA)*cos(pi/180*h)))*180/pi; //solar altitude + DATA->SZA[n] = 90-alpha;} + + +printf("Done reading all data"); + + + + +MCMCID_STRUCT MCMCID; + +// MCOPT->nOUT=DATA.ncdf_data.MCMCID.nOUT; +// MCOPT->nPRINT=DATA.ncdf_data.MCMCID.nPRINT; +// MCOPT->nWRITE=DATA.ncdf_data.MCMCID.nWRITE; +// MCOPT->minstepsize=DATA.ncdf_data.MCMCID.minstepsize; +// MCOPT->mcmcid=DATA.ncdf_data.MCMCID.value; +// MCOPT->nADAPT=DATA.ncdf_data.MCMCID.nADAPT; + + + +MCMCID.value = ncdf_read_single_double_var(ncid, "MCMCID"); +MCMCID.nITERATIONS = ncdf_read_int_attr(ncid, "MCMCID","nITERATIONS"); +MCMCID.nPRINT = ncdf_read_int_attr(ncid, "MCMCID","nPRINT"); +MCMCID.nSAMPLES= ncdf_read_int_attr(ncid, "MCMCID","nSAMPLES"); +MCMCID.nSAMPLES_EDC_SEARCH= ncdf_read_int_attr(ncid, "MCMCID","nSAMPLES_EDC_SEARCH"); +MCMCID.nADAPT= ncdf_read_int_attr(ncid, "MCMCID","nADAPT"); +MCMCID.fADAPT= ncdf_read_double_attr(ncid, "MCMCID","fADAPT"); +MCMCID.minstepsize=ncdf_read_double_attr(ncid, "MCMCID","minstepsize"); +MCMCID.seed_number=ncdf_read_double_attr(ncid, "MCMCID","seed_number"); + +if (isnan(MCMCID.value)){MCMCID.value=DEFAULT_DOUBLE_VAL;} + + + +DATA->MCMCID=MCMCID; + +// + +printf("Done reading MCMC valuea and attributes"); + + + return 0; +} + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_RUN_MODEL.c === + +#include "../../auxi_fun/okcheck.c" +#include "math.h" +#include +#include "CARDAMOM_READ_BINARY_DATA.c" +#include +#include + + +//Maximum length of metadata strings that will be allowed when writing to netcdf. +#define METADATA_MAX_LEN 100 + +/* Handle netCDF library errors by printing an error message and exiting with a + * non-zero status.*/ +#define ERREXITCODE 2 +#define NCDFERR(e) {printf("Error in %s at %d: %s\n", __FILE__, __LINE__, nc_strerror(e));} +#define FILE_NAME_MAX_LEN 1000 + + +//This is a tiny macro used to do error handeling for netCDF methods with the standard format of returning a result code. +//It helps make the code look less insane by allowing one-line calls +//This as a macro because we want the __FILE__ and __LINE__ macros to work +#define FAILONERROR(ncretval) if (ncretval != NC_NOERR) {NCDFERR(ncretval); exit(ERREXITCODE);} +//This variant will not die, but will still thow a message at the user about the problem. +#define WARNONERROR(ncretval) if (ncretval != NC_NOERR) {NCDFERR(ncretval);} + + +//Typesafe min macro without double evaluation +#define min(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) + + +//This scans the string and removes all instances of the string toFind, and replaces them with the single char toReplace. +void str_inplace_replace(char * str, const char * toFind, const char toReplace){ + //Yeah this implementation is N^2... but we have a small fixed max N, so don't @ me. + char* substring=str; + while ((substring = strstr(substring, toFind))){ + memmove(substring, substring+1,strlen(substring)); //Memmove needed due to overlapping strings. Move the whole string, with null term + substring[0]=toReplace; //put in the filler char + } + +} + + + +/*syntax CARDAMOM_READ_BINARY_CARDADATA(char *filename,CARDADATA *CARDADATA)*/ + +/* the gateway function */ +/*NOTE: this function can be used with any valid model ID (stored in CARDADATA.ID)*/ +int main(int argc, char *files[]) +{ + printf("In 'main'\n"); + +/*declaring loop variable n*/ +int n, nn; + +/*storing command line inputs as 2 files*/ +char metfile[FILE_NAME_MAX_LEN];strncpy(metfile,files[1],FILE_NAME_MAX_LEN-1); +char parfile[FILE_NAME_MAX_LEN];strncpy(parfile,files[2],FILE_NAME_MAX_LEN-1); +char ncdffile[FILE_NAME_MAX_LEN]; +if (argc-1>2){strncpy(ncdffile,files[3],FILE_NAME_MAX_LEN-1);} +else{ + int ncFilenameLen=strlen(parfile)-4; + if (ncFilenameLen > FILE_NAME_MAX_LEN-8){ + printf("Error on input validation, parfile name too long to create netCDF file name from.\n"); + exit(1); + } + strncpy(ncdffile, parfile,ncFilenameLen); + strncpy(ncdffile+ncFilenameLen, ".cbr.nc",ncFilenameLen+1); //Write an extra char so strncpy adds a null + str_inplace_replace(ncdffile, "//", '/'); //Remove double-slashes + str_inplace_replace(ncdffile, ":", '-'); //Remove colons +} + +//Add manditory null terminators just in case we used every char +metfile[FILE_NAME_MAX_LEN-1]=0; +parfile[FILE_NAME_MAX_LEN-1]=0; +ncdffile[FILE_NAME_MAX_LEN-1]=0; + + + +/*declaring data structure*/ +DATA CARDADATA; + +/*if (&CARDADATA==0){printf("CARDADATA not assigned, expect error!\n");} +*//*Initialize data structure*/ +int OK; +printf("About to read data structure..."); +//OK=INITIALIZE_DATA_STRUCT(&CARDADATA); +okcheck(OK,"CHECK: DATA structure successfully initialized"); +printf("Done with initializing data structure!\n"); +/*step 1 - read the met file & initialize model fields here*/ +/*NOTE: metfile contains information on which CARDAMOM model is being run*/ +/*therefore this function is transferable to any model type*/ +/*NOTE: parameter minimum and maximum values also loaded as a function of CARDADATA.ID by +the CARDAMOM_MODEL_LIBRARY.c function*/ + +printf("About to read cbf data..."); +CARDAMOM_READ_BINARY_DATA(metfile,&CARDADATA); +printf("done with reading cbf data!\n"); +//CARDAMOM_READ_NETCDF_DATA("DEFAULT/FILE/NETCDF", &(CARDADATA.ncdf_data)); + + +/*step 2 - read (first time) parameter file here*/ + + +int cbrId = 0; //This is the netcdf id num for the cbfcbr file +int cbrParsVarID; // Variable ID number +int cbrParamDimID,cbrSampleDimID; //Dim ID numbers, must be populated each invocation +FAILONERROR(nc_open(parfile,NC_NOWRITE, &cbrId )); +FAILONERROR(nc_inq_dimid(cbrId,"Parameter",&cbrParamDimID)); +FAILONERROR(nc_inq_dimid(cbrId,"Sample", &cbrSampleDimID)); +FAILONERROR(nc_inq_varid(cbrId,"Parameters",&cbrParsVarID)); + +/*number of parameter vectors to run*/ +size_t N; +FAILONERROR(nc_inq_dimlen(cbrId,cbrSampleDimID, &N)); + + +/*comments for display*/ +int verbal=1; +if (verbal==1){printf("number of parvecs to run = %d\n",(int)N);} +/*declaring pars file*/ +double *pars=calloc(CARDADATA.nopars,sizeof(double)); +/*parameter file will be closed later - in the meantime parameters will simply be read N times*/ + + + + + +/*STEP 3 - declaring flux, pool and edc files*/ +/*note - these should be input at command line as variables*/ + + + +/*STEP 3.1 - create netCDF output file*/ +int ncid = 0; //This is the netcdf id num +int ncretval = 0; //This is a reused variable for the return value of ncdf methods. +ncretval = nc_create(ncdffile,NC_CLOBBER|NC_NETCDF4, &ncid ); +if (ncretval != NC_NOERR){ + //If nc_create did anything but return no error, then fail + ERR(ncretval); +} +int Ntimesteps=CARDADATA.ncdf_data.Ntimesteps; + + +/*STEP 3.2 - create netCDF output dimensions*/ +int sampleDimID, timePoolsDimID,timeFluxesDimID, probIdxDimID,edcIdxDimID, noLikelihoodsDimID; +FAILONERROR(nc_def_dim(ncid,"Sample",N,&sampleDimID)); + + +int poolDimID; +FAILONERROR(nc_def_dim(ncid,"Pool",CARDADATA.nopools,&poolDimID )); +int fluxDimID; +FAILONERROR(nc_def_dim(ncid,"Flux",CARDADATA.nofluxes,&fluxDimID )); +int noParsDimID; +FAILONERROR(nc_def_dim(ncid,"Parameter",CARDADATA.nopars,&noParsDimID )); + + +//NOTE: this was going to be the NC_UNLIMITED dimension, however due to concerns with support for netcdf classic, it is now fixed, and split into two +FAILONERROR(nc_def_dim(ncid,"Time_pools",Ntimesteps+1,&timePoolsDimID)); +FAILONERROR(nc_def_dim(ncid,"Time_fluxes",Ntimesteps,&timeFluxesDimID)); +//Hard coded to 1 +const size_t probIdxLen=1; +FAILONERROR(nc_def_dim(ncid,"Probability Index",probIdxLen,&probIdxDimID )); +//Hard coded to 100 +FAILONERROR(nc_def_dim(ncid,"EDC Index",CARDADATA.noedcs,&edcIdxDimID )); + +FAILONERROR(nc_def_dim(ncid,"Likelihood Index",CARDADATA.nolikelihoods,&noLikelihoodsDimID )); +int chidDimID; //This is the charicter position dimension. It is used for strings, and fixed to a max of 200 chars + +FAILONERROR(nc_def_dim(ncid,"chid",METADATA_MAX_LEN,&chidDimID )); + + +//size_t chunkSize = (size_t) Ntimesteps * sizeof(double); +/*STEP 3.3 - create netCDF variables in preparation for writing them later*/ +int edcsVarID, pVarID, likelihoodsVarID; + +//FLUXES DEFINITION +int fluxesVarID, fluxesNameVarID,fluxesDescriptionVarID, fluxesUnitVarID; +//This is the int array that gets re-used for each flux, letting the nc_def_var function know that each flux needs to be based on the sample and time dimensions +int fluxes_dems[] = {sampleDimID,timeFluxesDimID,fluxDimID}; +int fluxes_meta_dems[] = {fluxDimID, chidDimID}; + +FAILONERROR(nc_def_var( ncid,"FLUXES" , NC_DOUBLE, 3, fluxes_dems, &(fluxesVarID) )); + +//Create each flux's mapping as an attribute +struct FLUX_META_STRUCT fluxInfo = ((DALEC *)CARDADATA.MODEL)->FLUX_META; +for(int i = 0; i < CARDADATA.nofluxes; i++){ + const char* ncVarAbbreviation =(const char *) calloc(sizeof(char), METADATA_MAX_LEN );//WARNING: DO NOT FREE THIS ARRAY! Netcdf libs require a const char*, so whatever is inside the string should not change or be freed! + + if (fluxInfo.ABBREVIATION != NULL && fluxInfo.ABBREVIATION[i] != NULL){ + snprintf( (char *) ncVarAbbreviation,METADATA_MAX_LEN-1,"FLUX-%s", fluxInfo.ABBREVIATION[i] );//Write to it once, overriding the const qualifier so it is set + } else { + //just make up an abbrev + snprintf( (char *) ncVarAbbreviation,METADATA_MAX_LEN-1,"FLUX-%d", i);//Write to it once, overriding the const qualifier so it is set + printf("ERROR in %s at %d: Flux ID %d has no defined ABBREVIATION in it's FLUX_META. Add it to your DALEC_####_NC_INFO.c file! This flux will be called %s until you do!\n", __FILE__, __LINE__,i,ncVarAbbreviation); + + } + //FAILONERROR(nc_def_var( ncid,ncVarAbbreviation , NC_DOUBLE, 2, fluxes_dems, &(fluxesVarID[i]) )); + WARNONERROR(nc_put_att_int ( ncid,fluxesVarID,ncVarAbbreviation,NC_INT,1,&i)); +} +//metadata vars +FAILONERROR(nc_def_var( ncid,"FLUX_NAMES" , NC_CHAR, 2, fluxes_meta_dems, &(fluxesNameVarID) )); +FAILONERROR(nc_def_var( ncid,"FLUX_DESCRIPTIONS" , NC_CHAR, 2, fluxes_meta_dems, &(fluxesDescriptionVarID) )); +FAILONERROR(nc_def_var( ncid,"FLUX_UNITS" , NC_CHAR, 2, fluxes_meta_dems, &(fluxesUnitVarID) )); + + +//POOLS DEFINITION +//Create each pool variable as its own var inside +int poolsVarID,poolsNameVarID,poolsDescriptionVarID, poolsUnitVarID; +struct POOLS_META_STRUCT poolsInfo = ((DALEC *)CARDADATA.MODEL)->POOLS_META; +int pools_dems[] = {sampleDimID,timePoolsDimID, poolDimID}; //poolsDimId was last in the order +int pools_meta_dems[] = {poolDimID, chidDimID}; + +FAILONERROR(nc_def_var( ncid,"POOLS" , NC_DOUBLE, 3, pools_dems, &(poolsVarID) )); + + +for(int i = 0; i < CARDADATA.nopools; i++){ + const char* ncVarAbbreviation =(const char *) calloc(sizeof(char), METADATA_MAX_LEN );//WARNING: DO NOT FREE THIS ARRAY! Netcdf libs require a const char*, so whatever is inside the string should not change or be freed! + if (poolsInfo.ABBREVIATION != NULL && poolsInfo.ABBREVIATION[i] != NULL ){ + snprintf( (char *) ncVarAbbreviation,METADATA_MAX_LEN-1,"POOL-%s", poolsInfo.ABBREVIATION[i] );//Write to it once, overriding the const qualifier so it is set + } else { + //just make up a name + snprintf( (char *) ncVarAbbreviation,METADATA_MAX_LEN-1,"POOL-%d", i);//Write to it once, overriding the const qualifier so it is set + printf("ERROR in %s at %d: pool ID %d has no defined ABBREVIATION in it's POOLS_META. Add it to your DALEC_####_NC_INFO.c file! This pool will be called %s until you do!\n", __FILE__, __LINE__,i,ncVarAbbreviation); + + } + WARNONERROR(nc_put_att_int ( ncid,poolsVarID,ncVarAbbreviation,NC_INT,1,&i)); + + + /*if (poolsInfo.NAME != NULL && poolsInfo.NAME[i] != NULL){ + WARNONERROR(nc_put_att_text ( ncid,poolsVarID[i],"Name",strlen(poolsInfo.NAME[i]),poolsInfo.NAME[i])); + } + if (poolsInfo.DESCRIPTION != NULL && poolsInfo.DESCRIPTION[i] != NULL){ + WARNONERROR(nc_put_att_text ( ncid,poolsVarID[i],"Description",strlen(poolsInfo.DESCRIPTION[i]),poolsInfo.DESCRIPTION[i])); + } + if (poolsInfo.UNITS != NULL && poolsInfo.UNITS[i] != NULL){ + WARNONERROR(nc_put_att_text ( ncid,poolsVarID[i],"Units",strlen(poolsInfo.UNITS[i]),poolsInfo.UNITS[i])); + }*/ + +} +//metadata vars +FAILONERROR(nc_def_var( ncid,"POOL_NAMES" , NC_CHAR, 2, pools_meta_dems, &(poolsNameVarID) )); +FAILONERROR(nc_def_var( ncid,"POOL_DESCRIPTIONS" , NC_CHAR, 2, pools_meta_dems, &(poolsDescriptionVarID) )); +FAILONERROR(nc_def_var( ncid,"POOL_UNITS" , NC_CHAR, 2, pools_meta_dems, &(poolsUnitVarID) )); + + + +int prob_dems[] = {sampleDimID, probIdxDimID}; +FAILONERROR(nc_def_var( ncid,"PROB" , NC_DOUBLE, 2, prob_dems, &pVarID )); + +//PARS DEFINITION +//Create each paramater variable as its own var inside +int parsVarID, parsNameVarID,parsDescriptionVarID, parsUnitVarID; +struct PARS_META_STRUCT parsInfo = ((DALEC *)CARDADATA.MODEL)->PARS_META; +int pars_dems[] = {sampleDimID, noParsDimID}; //noParsDimID was last in the order +int pars_meta_dems[] = {noParsDimID, chidDimID}; + +FAILONERROR(nc_def_var( ncid, "PARS", NC_DOUBLE, 2, pars_dems, &(parsVarID) )); + + + +for(int i = 0; i < CARDADATA.nopars; i++){ + const char* ncVarAbbreviation =(const char *) calloc(sizeof(char), METADATA_MAX_LEN );//WARNING: DO NOT FREE THIS ARRAY! Netcdf libs require a const char*, so whatever is inside the string should not change or be freed! + if (parsInfo.ABBREVIATION != NULL && parsInfo.ABBREVIATION[i] != NULL){ + snprintf( (char *) ncVarAbbreviation,METADATA_MAX_LEN-1,"PAR-%s", parsInfo.ABBREVIATION[i] );//Write to it once, overriding the const qualifier so it is set + } else { + //just make up a name + snprintf( (char *) ncVarAbbreviation,METADATA_MAX_LEN-1,"PAR-%d", i); //Write to it once, overriding the const qualifier so it is set + printf("ERROR in %s at %d: paramater ID %d has no defined ABBREVIATION in it's PARS_META. Add it to your DALEC_####_NC_INFO.c file! This paramater will be called %s until you do!\n", __FILE__, __LINE__,i,ncVarAbbreviation ); + } + + WARNONERROR(nc_put_att_int ( ncid,parsVarID,ncVarAbbreviation,NC_INT,1,&i)); + /* + if (parsInfo.NAME != NULL && parsInfo.NAME[i] != NULL){ + WARNONERROR(nc_put_att_text ( ncid,parsVarID[i],"Name",strlen(parsInfo.NAME[i]),parsInfo.NAME[i])); + } + if (parsInfo.DESCRIPTION != NULL && parsInfo.DESCRIPTION[i] != NULL){ + WARNONERROR(nc_put_att_text ( ncid,parsVarID[i],"Description",strlen(parsInfo.DESCRIPTION[i]),parsInfo.DESCRIPTION[i])); + } + if (parsInfo.UNITS != NULL && parsInfo.UNITS[i] != NULL){ + WARNONERROR(nc_put_att_text ( ncid,parsVarID[i],"Units",strlen(parsInfo.UNITS[i]),parsInfo.UNITS[i])); + }*/ + +} +//metadata vars +FAILONERROR(nc_def_var( ncid,"PAR_NAMES" , NC_CHAR, 2, pars_meta_dems, &(parsNameVarID) )); +FAILONERROR(nc_def_var( ncid,"PAR_DESCRIPTIONS" , NC_CHAR, 2, pars_meta_dems, &(parsDescriptionVarID) )); +FAILONERROR(nc_def_var( ncid,"PAR_UNITS" , NC_CHAR, 2, pars_meta_dems, &(parsUnitVarID) )); + + +int likelihoods_dems[] = {sampleDimID, noLikelihoodsDimID}; +FAILONERROR(nc_def_var( ncid,"LIKELIHOODS" , NC_DOUBLE, 2, likelihoods_dems, &likelihoodsVarID )); + +int edcs_dems[] = {sampleDimID, edcIdxDimID }; +FAILONERROR(nc_def_var( ncid,"EDCs" , NC_DOUBLE, 2, edcs_dems, &edcsVarID )); + + +//End NetCDF definition phase, in order to allow for writting +nc_enddef(ncid); + + +//Insert Fluxes metadata +for(int i = 0; i < CARDADATA.nofluxes; i++){ + if (fluxInfo.NAME != NULL && fluxInfo.NAME[i] != NULL){ + //"Name" + WARNONERROR(nc_put_vara_text ( ncid,fluxesNameVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(fluxInfo.NAME[i]))},(const char *)fluxInfo.NAME[i])); + } + if (fluxInfo.DESCRIPTION != NULL && fluxInfo.DESCRIPTION[i] != NULL){ + //"Description" + WARNONERROR(nc_put_vara_text ( ncid,fluxesDescriptionVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(fluxInfo.DESCRIPTION[i]))},(const char *)fluxInfo.DESCRIPTION[i])); + } + if (fluxInfo.UNITS != NULL && fluxInfo.UNITS[i] != NULL){ + //"Units" + WARNONERROR(nc_put_vara_text ( ncid,fluxesUnitVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(fluxInfo.UNITS[i]))},(const char *)fluxInfo.UNITS[i])); + } +} + +//Insert Pools metadata +for(int i = 0; i < CARDADATA.nopools; i++){ + if (poolsInfo.NAME != NULL && poolsInfo.NAME[i] != NULL){ + //"Name" + WARNONERROR(nc_put_vara_text ( ncid,poolsNameVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(poolsInfo.NAME[i]))},(const char *)poolsInfo.NAME[i])); + } + if (poolsInfo.DESCRIPTION != NULL && poolsInfo.DESCRIPTION[i] != NULL){ + //"Description" + WARNONERROR(nc_put_vara_text ( ncid,poolsDescriptionVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(poolsInfo.DESCRIPTION[i]))},(const char *)poolsInfo.DESCRIPTION[i])); + } + if (poolsInfo.UNITS != NULL && poolsInfo.UNITS[i] != NULL){ + //"Units" + WARNONERROR(nc_put_vara_text ( ncid,poolsUnitVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(poolsInfo.UNITS[i]))},(const char *)poolsInfo.UNITS[i])); + } +} + +//Insert Pars metadata +for(int i = 0; i < CARDADATA.nopars; i++){ + if (parsInfo.NAME != NULL && parsInfo.NAME[i] != NULL){ + //"Name" + WARNONERROR(nc_put_vara_text ( ncid,parsNameVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(parsInfo.NAME[i]))},(const char *)parsInfo.NAME[i])); + } + if (parsInfo.DESCRIPTION != NULL && parsInfo.DESCRIPTION[i] != NULL){ + //"Description" + WARNONERROR(nc_put_vara_text ( ncid,parsDescriptionVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(parsInfo.DESCRIPTION[i]))},(const char *)parsInfo.DESCRIPTION[i])); + } + if (parsInfo.UNITS != NULL && parsInfo.UNITS[i] != NULL){ + //"Units" + WARNONERROR(nc_put_vara_text ( ncid,parsUnitVarID,(const size_t[]){i,0},(const size_t[]){1,min(METADATA_MAX_LEN-1,strlen(parsInfo.UNITS[i]))},(const char *)parsInfo.UNITS[i])); + } +} + + + + + + double cpu_time_used=0; +/*STEP 4 - RUNNING CARDADATA.MLF N TIMES*/ +for (n=0;n lenstr) + return 0; + return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0; +} + + + +int CARDAMOM_DATA_CHECKS(DATA *DATA){ +/*General Checks*/ +printf("***CBF FILE SUMMARY***\n"); +printf("MODEL ID = %d\n",(int)DATA->ncdf_data.ID); +printf("No days = %d\n",DATA->ncdf_data.Ntimesteps); +printf("Mean Snow = %f\n",DATA->ncdf_data.SNOWFALL.reference_mean); +printf("Mean Temp = %f\n",DATA->ncdf_data.T2M_MIN.reference_mean); +printf("Mean Prec = %f\n",DATA->ncdf_data.TOTAL_PREC.reference_mean); +printf("Latitude = %f\n",DATA->ncdf_data.LAT); + +printf("Ecological & Dynamic Constraints options\n"); +printf("EDC likelihood option = %d\n",DATA->ncdf_data.EDC); +printf("EDC diagnostics option = %d\n",DATA->ncdf_data.EDCDIAG); + + +printf("*****END OF CBF FILE SUMMARY***"); + + + +return 0;} + +int DYNAMIC_DATA_MEMORY_ALLOCATION(DATA * DATA){ + +int Ntimesteps=DATA->ncdf_data.Ntimesteps; +DATA->M_ABGB=calloc(Ntimesteps,sizeof(double)); +DATA->M_CH4=calloc(Ntimesteps,sizeof(double)); +DATA->M_CWOO=calloc(Ntimesteps,sizeof(double)); +DATA->M_DOM=calloc(Ntimesteps,sizeof(double)); +DATA->M_ET=calloc(Ntimesteps,sizeof(double)); +DATA->M_LE=calloc(Ntimesteps,sizeof(double)); +DATA->M_H=calloc(Ntimesteps,sizeof(double)); +DATA->M_EWT=calloc(Ntimesteps,sizeof(double)); +DATA->M_GPP=calloc(Ntimesteps,sizeof(double)); +DATA->M_SIF=calloc(Ntimesteps,sizeof(double)); +DATA->M_LAI=calloc(Ntimesteps,sizeof(double));//Warning, LAI larger than this! +DATA->M_FIR=calloc(Ntimesteps,sizeof(double)); +DATA->M_NBE=calloc(Ntimesteps,sizeof(double)); +DATA->M_ROFF=calloc(Ntimesteps,sizeof(double)); +DATA->M_SCF=calloc(Ntimesteps,sizeof(double)); +DATA->M_SWE=calloc(Ntimesteps,sizeof(double)); + + + + + + + +//Model variables + DATA->M_FLUXES=calloc(Ntimesteps*DATA->nofluxes,sizeof(double)); + DATA->M_POOLS=calloc((Ntimesteps+1)*DATA->nopools,sizeof(double)); + + int noedc=100, noprob=1; + DATA->M_EDCD=calloc(noedc,sizeof(int)); + DATA->M_P=calloc(noprob,sizeof(double)); + DATA->M_PARS=calloc(DATA->nopars,sizeof(double)); + DATA->M_LIKELIHOODS=calloc(DATA->nolikelihoods,sizeof(double)); + DATA->M_EDCs=calloc(DATA->noedcs,sizeof(double)); +//COunters for diagnostics + DATA->EDC_INSTANCE_COUNTER=calloc(DATA->noedcs,sizeof(int)); + DATA->EDC_PASS_COUNTER=calloc(DATA->noedcs,sizeof(int)); + + +printf("Done with dynamic memory declaration\n"); + +return 0; +}; + +int CARDAMOM_READ_BINARY_DATA(char *ncfilename,DATA *DATA) +{ + + int n,m; + + + + + + + + + //Step 1.Data file is of the newer NetCDF format + CARDAMOM_READ_NETCDF_DATA(ncfilename, &(DATA->ncdf_data)); + +printf("Successfully read NETCDF data...\n"); + + + +//Pre-process (to accelerate model) + + +// +// printf("DATA->ncdf_data.ET.opt_unc_type = %i\n",DATA->ncdf_data.ET.opt_unc_type); +// printf("DATA->ncdf_data.ET.opt_filter = %i\n",DATA->ncdf_data.ET.opt_filter); +// printf("DATA->ncdf_data.ET.single_unc = %2.2f\n",DATA->ncdf_data.ET.single_unc); +// printf("DATA->ncdf_data.ET.min_threshold = %2.2f\n", DATA->ncdf_data.ET.min_threshold); +// printf("Successfully pre-processed ET...\n"); + +// +// +// //Step 2. Default values +// DATA->ncdf_data->ET.obs_unc_type=1; +// DATA->ncdf_data->ET.single_unc=2; +// DATA->ncdf_data->ET.threshold=0; +// //Pre-process (to accelerate model) +// OBS_STRUCT_PREPROCESS(DATA->ncdf_data->ET); + + + //Setting number of EDCs to 100 as default. +DATA->noedcs=100; + + + CARDAMOM_MODEL_LIBRARY(DATA); + + + + + + + /*NEXT STEPS: figure out how to ceclafre MET and other memory*/ + // READ GPP, LAI, etc.: + + + + + + + + + +/*Placeholder: read netcdf fields here*/ + + +printf("***About to do dynamic allocation***\n"); + + + DYNAMIC_DATA_MEMORY_ALLOCATION(DATA); + + + + + CARDAMOM_DATA_CHECKS(DATA); + + +printf("DATA->noedcs = %i\n",DATA->noedcs); +printf("Done reading all data...\n"); + +return 0; + + + +} + + + +int FREE_DATA_STRUCT(DATA DATA){ + + +//Cost function observations +free(DATA.M_ABGB); +free(DATA.M_CH4); +free(DATA.M_DOM); +free(DATA.M_ET); +free(DATA.M_LE); +free(DATA.M_H); +free(DATA.M_ROFF); +free(DATA.M_EWT); +free(DATA.M_GPP); +free(DATA.M_SIF); +free(DATA.M_LAI); +free(DATA.M_FIR); +free(DATA.M_NBE); + + + + + + +free(DATA.M_PARS); +free(DATA.M_FLUXES); +free(DATA.M_POOLS); +free(DATA.M_P); +free(DATA.M_EDCD); + +free(DATA.parmin); +free(DATA.parmax); +free(DATA.parname); + +return 0; + +} + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_NETCDF_DATA_STRUCTURE.c === + +#pragma once +#include "CARDAMOM_MODULE_IDX.c" +#include "../COST_FUNCTION/CARDAMOM_LIKELIHOOD_FUNCTION.c" +//#include "../CARDAMOM_MDF/MCMC_SETUP/MCMC_MODULES.c" + +//This is a generic struct for a 1D var. +typedef struct ONE_DIM_VAR_STRUCT{ +double* values; //NULL if not present +size_t length; //Set to 0 if not present +}ONE_DIM_VAR_STRUCT; + +typedef struct TIMESERIES_DRIVER_STRUCT{ +double* values; //NULL if not present +size_t length; //Set to 0 if not present +double reference_mean;}TIMESERIES_DRIVER_STRUCT; + +//This is a generic struct that contains an additional uncertainty value, which is a common form for Cardamom variables +typedef struct ONE_DIM_VAR_WITH_UNCERTAINTY_STRUCT{ +double* values; //NULL if not present +size_t length; //Set to 0 if not present +double Uncertainty; +}ONE_DIM_VAR_WITH_UNCERTAINTY_STRUCT; + +//This is a generic struct for a 2D var +typedef struct TWO_DIM_VAR_STRUCT{ +double** values; +size_t dimensions[2]; //NOTE: This is NOT a length per row, but a length per dimension. This means this array will ALLWAYS have 2 elements for a 2D array. +}TWO_DIM_VAR_STRUCT; + + +//This is only structure for datasets read in externally +typedef struct MCMCID_STRUCT{ +double value; +int nITERATIONS; +int nPRINT; +int nSAMPLES; +int nADAPT; +int nSAMPLES_EDC_SEARCH; +double fADAPT; +double minstepsize; +int seed_number; +}MCMCID_STRUCT; + + + +typedef struct NETCDF_DATA{ + + + //MODEL +int ID; +int EDC; +int EDCDIAG; +double EDC_EQF; + + //DATA +double LAT; +double meantemp; +int Ntimesteps; +double deltat; + +//SZA +double * SZA; + + +TIMESERIES_OBS_STRUCT ABGB; +TIMESERIES_OBS_STRUCT CH4; +TIMESERIES_OBS_STRUCT CWOO; +TIMESERIES_OBS_STRUCT DOM; +TIMESERIES_OBS_STRUCT ET; +TIMESERIES_OBS_STRUCT LE; +TIMESERIES_OBS_STRUCT H; +TIMESERIES_OBS_STRUCT EWT; +TIMESERIES_OBS_STRUCT FIR; +TIMESERIES_OBS_STRUCT GPP; +TIMESERIES_OBS_STRUCT LAI; +TIMESERIES_OBS_STRUCT NBE; +TIMESERIES_OBS_STRUCT ROFF; +TIMESERIES_OBS_STRUCT SCF; +TIMESERIES_OBS_STRUCT SIF; // shuang added +TIMESERIES_OBS_STRUCT SWE; + + +// +SINGLE_OBS_STRUCT Mean_ABGB; +SINGLE_OBS_STRUCT Mean_FIR; +SINGLE_OBS_STRUCT Mean_GPP; +SINGLE_OBS_STRUCT Mean_LAI; +//Parameters and emergent quantities +SINGLE_OBS_STRUCT PEQ_NBEmrg; +SINGLE_OBS_STRUCT PEQ_Cefficiency; +SINGLE_OBS_STRUCT PEQ_CUE; +SINGLE_OBS_STRUCT PEQ_Vcmax25; +SINGLE_OBS_STRUCT PEQ_C3frac; +SINGLE_OBS_STRUCT PEQ_iniSnow; +SINGLE_OBS_STRUCT PEQ_iniSOM; +SINGLE_OBS_STRUCT PEQ_LCMA; +SINGLE_OBS_STRUCT PEQ_clumping; +//add PEQ value and unc from previous MCMC *pMCMC* +SINGLE_OBS_STRUCT PEQ_r_ch4; +SINGLE_OBS_STRUCT PEQ_S_fv; +SINGLE_OBS_STRUCT PEQ_rhch4_rhco2; + +//Drivers + +TIMESERIES_DRIVER_STRUCT BURNED_AREA; +TIMESERIES_DRIVER_STRUCT CO2; +TIMESERIES_DRIVER_STRUCT DISTURBANCE_FLUX; +TIMESERIES_DRIVER_STRUCT DOY; +TIMESERIES_DRIVER_STRUCT SKT; +TIMESERIES_DRIVER_STRUCT SNOWFALL; +TIMESERIES_DRIVER_STRUCT SSRD; +TIMESERIES_DRIVER_STRUCT STRD; +TIMESERIES_DRIVER_STRUCT T2M_MAX; +TIMESERIES_DRIVER_STRUCT T2M_MIN; +TIMESERIES_DRIVER_STRUCT TIME_INDEX; +TIMESERIES_DRIVER_STRUCT TOTAL_PREC; +TIMESERIES_DRIVER_STRUCT VPD; +TIMESERIES_DRIVER_STRUCT YIELD; + +//Summary variables + +//Derived variables (not prescribed) +//FUSION + +//MCMCID +MCMCID_STRUCT MCMCID; + + +}NETCDF_DATA; + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/GLOBAL_CONSTANTS.c === + +//Determine how to ensure code remains fast if we define global constants! +//Ensure all "define" statements with mathematical operations are bracketed + + +#define DGCM_PI 3.1415927 //pi +#define DGCM_T3 273.16 //Triple point temp, K +#define DGCM_TK0C 273.15 //Kelvin at 0C +// Specific heat of ice +#define DGCM_SPECIFIC_HEAT_ICE 2093.// 2093 J kg?1 K +#define DGCM_SPECIFIC_HEAT_WATER 4186.// 4186 J kg?1 K +//Latent heat of vaporization +#define DGCM_LATENT_HEAT_VAPORIZATION 2.501e6; // J kg-1 +#define DGCM_LATENT_HEAT_FUSION_3 3.34e5 +#define DGCM_T_LIQUID_H2O_ZERO_ENERGY 56.79//Zero-energy temperature of super-cooled liquid water 56.79 K +#define DGCM_SEC_DAY (24*60*60)//Seconds per day + + +=== FILE: ./C/projects/CARDAMOM_GENERAL/CARDAMOM_COMPILE_MODELS.c === + + +#include "../../auxi_fun/okcheck.c" +#include "math.h" +#include +#include "CARDAMOM_READ_BINARY_DATA.c" +/*syntax CARDAMOM_READ_BINARY_CARDADATA(char *filename,CARDADATA *CARDADATA)*/ + + + + +/* the gateway function */ +/*NOTE: this function can be used with any valid model ID (stored in CARDADATA.ID)*/ +int main() +{ + +/*declaring loop variable n*/ + +/*storing command line inputs as 2 files*/ + + + +/*declaring data structure*/ +DATA DATA; + + +CARDAMOM_MODEL_INFO(&DATA,1); + +/* +CARDAMOM_READ_BINARY_DATA(metfile,&CARDADATA); +*/ + + + + +FREE_DATA_STRUCT(DATA); + + + + + +return 0; + +} + + +=== FILE: ./C/math_fun/ipow.c === + + +#pragma once +int ipow(int base, int exp) +{ + int result = 1; + while (exp) + { + if (exp & 1) + result *= base; + exp >>= 1; + base *= base; + } + + return result; +} + + +=== FILE: ./C/math_fun/invmat.c === + +#include +#include +int invmat(double **MAT,double **INVMAT,int n) +{ + + double ratio,a; + int i, j, k; + + +printf("MAT = %i\n",MAT); +printf("MAT[0] = %i\n",MAT[0]); +printf("MAT[0][0] = %f\n",MAT[0][0]); + + +printf("IMAT = %i\n",INVMAT); +printf("IMAT[0] = %i\n",INVMAT[0]); +printf("IMAT[0][0] = %f\n",INVMAT[0][0]); + + +printf("OK done - now working it out\n"); + + + for(i = 0; i < n; i++){ + for(j = 0; j < n; j++){ + if(i==(j)) + INVMAT[i][j] = 1.0; + else + INVMAT[i][j] = 0.0; + } + } + for(i = 0; i < n; i++){ + for(j = 0; j < n; j++){ + if(i!=j){ + ratio = MAT[j][i]/MAT[i][i]; + for(k = 0; k < n; k++){ + MAT[j][k] -= ratio * MAT[i][k]; + INVMAT[j][k] -= ratio * INVMAT[i][k]; + } + } + } + } + for(i = 0; i < n; i++){ + a = MAT[i][i]; + for(j = 0; j < n; j++){ + MAT[i][j] /= a; + INVMAT[i][j] /= a; + } + } + return 0; +} + + +=== FILE: ./C/math_fun/cholesky.c === + +/* file: choesky.c */ + +/* Take the cholesky decomposition in the manner described in FA Graybill + * (1976). + * */ + +#include +#include +#include +#pragma once + + +int cholesky(double **orig, int n, double **chol) + /* + * Do the augmented cholesky decomposition as described in FA Graybill + * (1976) Theory and Application of the Linear Model. The original matrix + * must be symmetric positive definite. The augmentation matrix, or + * series of column vectors, are multiplied by C^-t, where C is the + * upper triangular cholesky matrix, ie C^t * C = M and M is the original + * matrix. Returns with a value of 0 if M is a non-positive definite + * matrix. Returns with a value of 1 with succesful completion. + * + * Arguments: + * + * orig (input) double n x n array. The matrix to take the Cholesky + * decomposition of. + * n (input) integer. Number of rows and columns in orig. + * aug (input) double n x mcol array. The matrix for the augmented + * part of the decomposition. + * mcol (input) integer. Number of columns in aug. + * chol (output) double n x n array. Holds the upper triangular matrix + * C on output. The lower triangular portion remains unchanged. + * This maybe the same as orig, in which case the upper triangular + * portion of orig is overwritten. + * cholaug (output) double n x mcol array. Holds the product C^-t * aug. + * May be the same as aug, in which case aug is over written. + * 0 (input) integer. The index of the first element in the matrices. + * Normally this is 0, but commonly is 1 (but may be any integer). + * */ +{ + int i, j, k; + int retval = 1; + + for (i=0; ib){b=a;} +return b;} + + +=== FILE: ./C/math_fun/mean.c === + +#pragma once +#include "math.h" + +double mean(double a[], int n) { + if(n == 0){return 0.0;} + double sum = 0; + int i; + for(i = 0; i < n; i++) + sum += a[i]; + return sum / n; +} + + +=== FILE: ./C/math_fun/covariance.c === + +#pragma once +#include "math.h" + + +double covariance(double a[], double b[], int n) { + if(n == 0){return 0.0;} + double sum_a = 0, sum_b=0; + int i; + for(i = 0; i < n; i++){ + sum_a += a[i]; + sum_b += b[i];} + + double mean_a = sum_a /(double)n; + double mean_b = sum_b /(double)n; + double sq_diff_sum = 0; + for(i=0;i= 0 + // stop the recursion when matrix is a single element + if( order == 1 ) + return mat[0][0]; + + // the determinant value + float det = 0; + + // allocate the cofactor matrix + float **minor; + minor = new float*[order-1]; + for(int i=0;i 1)){ + + sum_sq_x = 0; + sum_sq_y = 0; + sum_coproduct = 0; + mean_x = *x; + mean_y = *y; + for (i = 1; i < dimx; i++){ + + + sweep = (double) (i + 0.0) / (i + 1.0); + delta_x = *(x + i) - mean_x; + delta_y = *(y + i) - mean_y; + sum_sq_x = sum_sq_x + delta_x * delta_x * sweep; + sum_sq_y = sum_sq_y + delta_y * delta_y * sweep; + sum_coproduct = sum_coproduct + delta_x * delta_y * sweep; + mean_x = mean_x + delta_x / (i + 1.0); + mean_y = mean_y + delta_y / (i + 1.0); + } + pop_sd_x = sqrt(sum_sq_x / dimx); + pop_sd_y = sqrt(sum_sq_y / dimx); + cov_x_y = sum_coproduct / dimx; + correlation = cov_x_y / (pop_sd_x * pop_sd_y); +} + +/***************************************************************************************/ +/***************************************************************************************/ +return correlation; + +} + + +=== FILE: ./C/math_fun/int_max.c === + +#pragma once +#include "math.h" + +int int_max(int a, int b) { + if (a>b){b=a;} + return b; +} + + +=== FILE: ./C/math_fun/fastcorr.c === + +#include "mex.h" +#include "math.h" +/*************************************************************************/ +/* */ +/* This function computes the correlation between vectors x and y. */ +/* The algorithm is quite fast and is considered numerically stable. */ +/* */ +/*************************************************************************/ +/* */ +/* Author: Francesco Pozzi */ +/* E-Mail: francesco.pozzi@anu.edu.au */ +/* Date: 4 December 2008 */ +/* */ +/*************************************************************************/ + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + +int i; +double sum_sq_x, sum_sq_y, sum_coproduct, mean_x, mean_y, sweep, delta_x, delta_y, pop_sd_x, pop_sd_y, cov_x_y, correlation; +double *x, *y; +int dimx, dimy; +double *out; + +dimx = mxGetNumberOfElements(prhs[0]); +dimy = mxGetNumberOfElements(prhs[1]); + +if((dimx == dimy) && (dimx > 1)){ + + x = (double *) mxGetPr(prhs[0]); + y = (double *) mxGetPr(prhs[1]); + + sum_sq_x = 0; + sum_sq_y = 0; + sum_coproduct = 0; + mean_x = *x; + mean_y = *y; + for (i = 1; i < dimx; i++){ + sweep = (double) (i + 0.0) / (i + 1.0); + delta_x = *(x + i) - mean_x; + delta_y = *(y + i) - mean_y; + sum_sq_x = sum_sq_x + delta_x * delta_x * sweep; + sum_sq_y = sum_sq_y + delta_y * delta_y * sweep; + sum_coproduct = sum_coproduct + delta_x * delta_y * sweep; + mean_x = mean_x + delta_x / (i + 1.0); + mean_y = mean_y + delta_y / (i + 1.0); + } + pop_sd_x = sqrt(sum_sq_x / dimx); + pop_sd_y = sqrt(sum_sq_y / dimx); + cov_x_y = sum_coproduct / dimx; + correlation = cov_x_y / (pop_sd_x * pop_sd_y); +} + +/***************************************************************************************/ +/***************************************************************************************/ +plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); +out = mxGetPr(plhs[0]); +*(out) = correlation; + +} + + +=== FILE: ./C/math_fun/declare_matrix.c === + +#pragma once +#include + +int declare_matrix( double ***M, int num_rows, int num_columns) +{ + + double *pool; + double *curPtr; + //(step 1) allocate memory for array of elements of column + + M[0] = (double** )calloc(num_rows, sizeof(double* )); + + //(step 2) allocate memory for array of elements of each row + pool = (double *)calloc( num_columns * num_rows, sizeof(double)); + + // Now point the pointers in the right place + curPtr = pool; +int i; + for(i = 0; i < num_rows; i++) + { + *(M[0] + i) = curPtr; + curPtr += num_columns; + } + +return 0; + +} + + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c === + +#pragma once +#include + +////TODO: break this into it's own shared file! See cardamom_run_model.c +/* Handle netCDF library errors by printing an error message and exiting with a + * non-zero status.*/ +#define ERREXITCODE 2 +#define NCDFERR(e) {printf("Error in %s at %d: %s\n", __FILE__, __LINE__, nc_strerror(e));} +#define FILE_NAME_MAX_LEN 1000 + +//This is a tiny macro used to do error handeling for netCDF methods with the standard format of returning a result code. +//It helps make the code look less insane by allowing one-line calls +//This as a macro because we want the __FILE__ and __LINE__ macros to work +#define FAILONERROR(ncretval) if (ncretval != NC_NOERR) {NCDFERR(ncretval); exit(ERREXITCODE);} +//This variant will not die, but will still thow a message at the user about the problem. +#define WARNONERROR(ncretval) if (ncretval != NC_NOERR) {NCDFERR(ncretval);} + + +//This scans the string and removes all instances of the string toFind, and replaces them with the single char toReplace. +void str_inplace_replace(char * str, const char * toFind, const char toReplace){ + //Yeah this implementation is N^2... but we have a small fixed max N, so don't @ me. + char* substring=str; + while ((substring = strstr(substring, toFind))){ + memmove(substring, substring+1,strlen(substring)); //Memmove needed due to overlapping strings. Move the whole string, with null term + substring[0]=toReplace; //put in the filler char + } + +} + + + + + +int WRITE_DEMCMC_RESULTS(double *PARS,PARAMETER_INFO PI,MCMC_OPTIONS MCO, int ITER){ + + int ncid = 0; //This is the netcdf id num + int ncretval = 0; //This is a reused variable for the return value of ncdf methods. + static int inited = 0; + int paramDimID,sampleDimID; //Dim ID numbers, must be populated each invocation + + int parsVarID; // Variable ID numbers, also must be repopulated each invocation + + if (MCO.nSTART>0){inited=1;} //Check if it's a restart + if (!inited){ + inited=1; + FAILONERROR(nc_create(MCO.outfile,NC_CLOBBER, &ncid )); + FAILONERROR(nc_def_dim(ncid,"Parameter",PI.npars,¶mDimID)); + FAILONERROR(nc_def_dim(ncid,"Sample",NC_UNLIMITED,&sampleDimID)); + FAILONERROR(nc_def_var(ncid,"Parameters",NC_DOUBLE,2,(const int[]){sampleDimID,paramDimID},&parsVarID)); + + //End NetCDF definition phase, in order to allow for writting + nc_enddef(ncid); + + }else{ + //dims and data already exist, so we only need to reacquire the IDs + FAILONERROR(nc_open(MCO.outfile,NC_WRITE, &ncid )); + FAILONERROR(nc_inq_dimid(ncid,"Parameter",¶mDimID)); + FAILONERROR(nc_inq_dimid(ncid,"Sample", &sampleDimID)); + FAILONERROR(nc_inq_varid(ncid,"Parameters",&parsVarID)); + + } + //Decide on where to put our write based on the current length of the unlimited dimension Sample + size_t currentSamples; + FAILONERROR(nc_inq_dimlen(ncid,sampleDimID, ¤tSamples)); + //Do the write. Remember to start at currentSamples + FAILONERROR(nc_put_vara_double(ncid,parsVarID,(const size_t[]){currentSamples,0}, (const size_t[]){MCO.nchains,PI.npars},PARS )); + + FAILONERROR(nc_close(ncid)); + + return 0; + + +} + + + //Is identical function to WRITE_DEMCMC_RESULTS(PARS,PI,MCO);} + //Except it writes one instance of "PARS" and overwrites previous file + //Include also attribute with N.ITER + //If possible, include attribute with random seed (this is optional). +int WRITE_DEMCMC_RESTART(double *PARS,PARAMETER_INFO PI,MCMC_OPTIONS MCO, int ITER){ + + int ncid = 0; //This is the netcdf id num + int ncretval = 0; //This is a reused variable for the return value of ncdf methods. + int paramDimID,sampleDimID; //Dim ID number, must be populated each invocation + + int parsVarID; // Variable ID numbers, also must be repopulated each invocation + + FAILONERROR(nc_create(MCO.startfile,NC_CLOBBER, &ncid )); + FAILONERROR(nc_def_dim(ncid,"Parameter",PI.npars,¶mDimID)); + FAILONERROR(nc_def_dim(ncid,"Sample",NC_UNLIMITED,&sampleDimID)); + FAILONERROR(nc_def_var(ncid,"Parameters",NC_DOUBLE,2,(const int[]){sampleDimID,paramDimID},&parsVarID)); + //Note: it's a bit odd this is an int, and not a uint or long. Likely does not matter though. + FAILONERROR(nc_put_att_int(ncid,parsVarID,"N",NC_INT,sizeof(int),&ITER)); + + +//TODO: store N and rng seed ------------------------------------------------------ + + + //End NetCDF definition phase, in order to allow for writting + nc_enddef(ncid); + + //Do the write. + FAILONERROR(nc_put_vara_double(ncid,parsVarID,(const size_t[]){0,0}, (const size_t[]){MCO.nchains,PI.npars},PARS )); + + FAILONERROR(nc_close(ncid)); + + return 0; + + +} + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c === + +#pragma once +#include +#include "../../../math_fun/randn.c" + +int STEP_DEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C,int NC){ +/*DE_STEP takes a differential evolution style step*/ + +/*FIXEDPARS*/ +/*ones and zeros depending on whether parameters are kept fixed*/ +/*CONTINUE FROM HERE*/ +int n,fp,c1=-1,c2=-1; +double rn; + + +/*allocating memory for three normalized parameter vectors*/ +double *npar=calloc(PI.npars,sizeof(double)); +double *npar1=calloc(PI.npars,sizeof(double)); +double *npar2=calloc(PI.npars,sizeof(double)); +double *step=calloc(PI.npars,sizeof(double)); +/*using "*pars" to store sequential outputs*/ +for (n=0;n1){withinlim=0;} + +} + +for (n=0;n +/*CONVERTING PARAMETERS TO 0-1 range*/ + + +double par2nor(double p, double mn, double mx){ +return log(p/mn)/log(mx/mn);} + + +/*AND VISE VERSA*/ + + +double nor2par(double p, double mn, double mx){ +return mn*pow(mx/mn,p);} + + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c === + +#pragma once +#include +#include +#include +#include "../../../math_fun/std.c" +#include "NORMPARS.c" +#include "STEP_DEMCMC.c" +#include "WRITE_DEMCMC_RESULTS.c" + +/*here including additional functions needed to initialise and clear memory*/ +#include "INITIALIZE_MCMC_OUTPUT.c" +/*Same as MHMCMC, except following differences:*/ +/*N chains (N>=3)*/ + +double *DEMCMC( +double (MODEL_LIKELIHOOD)(DATA, double *), +DATA DATA, PARAMETER_INFO PI, MCMC_OPTIONS MCO, MCMC_OUTPUT *MCOUT){ + +/* ***********INPUTS************ + * + * MODEL_LIKELIHOOD: A function wholly responsible for + * (a) running the model given the DATA and parameters, + * (b) comparing it to observations,and + * (c) returning the (log) likelihood. + * The function will be run as MODEL_LIKELIHOOD(DATA,PARS); + * To facilitate this, ALL data can be + * passed to the MHMCMC function as a structure (in order to avoid + * repeated read/write computational time). + * + * DATA: All data needed for the MODEL_LIKELIHOOD. It can include + * drivers, observations, etc. + * + * PARINFO: This structure contains information on + * (a) pmin, pmax: parameter ranges (compulsory) + * (b) initpars: parameter starting values (optional/recommended). + * (c) npars: number of pars (compulsory) + * + * MCO: This structure contains option values for the MCMC run. + * These will be set to default values if empty. Options include: + * (a) number of runs + * (b) filename for writing file with results + * (c) step adaptation frequency + * (d) initial step size + * */ + +/* **************OUTPUTS************* + * + * RESULTS FILE: File includes (a) results (b) likelihood and (c) final step size + * + * */ + + + +/*NOTE: seeding must happen outside of the MHMCMC function*/ +/*if internal seeding is needed, use srandom(time(0));*/ +/*however this may result in repeat numbers over short timespan*/ + + +/*ERASING PREVIOUS FILE IF APPEND == 0 */ +if(MCO.APPEND==0 && MCO.nWRITE>0){FILE *fileout=fopen(MCO.outfile,"wb");fclose(fileout);} + + + +/*DECLARING*/ +double *P, P_new; +int NC=MCO.nchains;/*[DEMCMC] Number of chains*/ +P=calloc(NC,sizeof(double)); + +NC=MCO.nchains; + +/*initialising P as -inf */ +double Pmin=0; +int n=0,nn=0,m=0,withinrange,wrlocal=0; + +COUNTERS N; +N.ACC=0; +N.ITER=0; +N.ACCLOC=0; +N.ACCRATE=0; +/*New and default parameter vectors*/ +double *PARS,*pars_new,*BESTPARS; +PARS=calloc(PI.npars*NC,sizeof(double)); +pars_new=calloc(PI.npars,sizeof(double)); +BESTPARS=calloc(PI.npars*NC,sizeof(double)); +/*All accepted parameters*/ +/*This is now the last N parameter vectors + * where N is the adaptation frequency*/ +/*PARSALL is only used for adaptation*/ +/*PARSALL=calloc(MCO.nADAPT*PI.npars*NC,sizeof(double));*//*[DEMCMC: can comment this out]*/ + +/*Random starting parameters if MCO.randparini*/ +for (nn=0;nnP[nn]){Pmin=P[nn];} + + +printf("starting likelihood for chain %i = %e\n",nn,P[nn]); + +if (isinf(P[nn])==-1){printf("WARNING! P(0)=-inf - MHMCMC may get stuck - if so, please check your initial conditions\n");}} + +/*STEP 2 - BEGIN MCMC*/ +for (N.ITER=0;N.ITER log((double)random() / (double)RAND_MAX)) { N.ACC = N.ACC + 1; + if (isinf(P_new)==0 && isinf(P[nn])){printf("pnew = %2.1f, p = %2.1f, (P_new-P[nn]) = %2.1f\n",P_new,P[nn],P_new-P[nn]);} + + + for (n=0;nP[nn]){for (n=0;nP[nn] ){printf("Found bestpars, prob = %2.1f, chain = %i\n",P_new,nn);} + } + P[nn]=P_new;} + } + + /*regularly write results*/ + if (MCO.nWRITE>0 && (N.ITER % MCO.nWRITE)==0){ +WRITE_DEMCMC_RESULTS(PARS,PI,MCO,N.ITER);} + + /*Printing Info to Screen*/ + if (MCO.nPRINT>0 && N.ITER % MCO.nPRINT==0){ + printf("%d out of %d iterations)\n",N.ITER,MCO.nOUT); + printf("within range = %2.2f\n",wrlocal/((double)N.ITER*NC)*100); + printf("Local Acceptance rate %5.1f\n %%",100*(double)N.ACC/((double)N.ITER*NC)); + printf("PI.stepsize = %5.5f\n",PI.stepsize[0]); + printf("Log Likelihoods: "); + for (nn=0;nnbest_pars[n]=BESTPARS[n]; +//printf("MCOUT->best_pars[%i]=%2.1f",n,MCOUT->best_pars[n]); +} +/*MCMC completed*/ +MCOUT->complete=1; +/*done with MCMC completion*/ + +free(BESTPARS); +free(PARS); +free(P); +printf("DEMCMC DONE\n"); + + +return 0; + +/*END OF MHMCMC*/ +} + + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_ADEMCMC.c === + +#pragma once +#include +#include "../../../math_fun/randn.c" + +double STEP_ADEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C,int NC, double *gratio){ +/*DE_STEP takes a differential evolution style step*/ + +/*FIXEDPARS*/ +/*ones and zeros depending on whether parameters are kept fixed*/ +/*CONTINUE FROM HERE*/ +int n,fp,C1=-1,c2=-1; +double rn; + + +/*STep 1. Find random sample other than current chain*/ + +C1=C; +while (C1==C){C1=ceil((double)random()*NC/((double)RAND_MAX))-1;}; + +/*Step 2. FInd current chain, reference chain, and step between them*/ +/*allocating memory for three normalized parameter vectors*/ +double *cpar=calloc(PI.npars,sizeof(double)); +double *rpar=calloc(PI.npars,sizeof(double)); +double *npar=calloc(PI.npars,sizeof(double)); +double *step=calloc(PI.npars,sizeof(double)); +double *gamma=calloc(PI.npars,sizeof(double)); +/*using "*pars" to store sequential outputs*/ +for (n=0;n1){withinlim=0;} +} + +gratio[0]=0; +/* +printf("a = %4.4f, b =%4.4f, Dsig = %4.4f, Dccoff = %4.4f",a,b,Dsig,Dccoff); +printf("\n"); +printf("Dimo_a = %4.4f, Dimd_a = %4.4f\n",Dimo_a,Dimd_a); +printf("varline = %4.4f, varrand = %4.4f\n",varline, varrand); +*/ + + +/*Step 4. Transform to parameter space*/ +if (withinlim==1){ + +for (n=0;n +#include +#include +#include "../../../math_fun/std.c" +#include "NORMPARS.c" +#include "STEP_DEMCMC.c" +#include "STEP_ADEMCMC.c" +#include "WRITE_DEMCMC_RESULTS.c" + +/*here including additional functions needed to initialise and clear memory*/ +#include "INITIALIZE_MCMC_OUTPUT.c" +/*Same as MHMCMC, except following differences:*/ +/*N chains (N>=3)*/ + +double *ADEMCMC( +double (MODEL_LIKELIHOOD)(DATA, double *), +DATA DATA, PARAMETER_INFO PI, MCMC_OPTIONS MCO, MCMC_OUTPUT *MCOUT){ + +/* ***********INPUTS************ + * + * MODEL_LIKELIHOOD: A function wholly responsible for + * (a) running the model given the DATA and parameters, + * (b) comparing it to observations,and + * (c) returning the (log) likelihood. + * The function will be run as MODEL_LIKELIHOOD(DATA,PARS); + * To facilitate this, ALL data can be + * passed to the MHMCMC function as a structure (in order to avoid + * repeated read/write computational time). + * + * DATA: All data needed for the MODEL_LIKELIHOOD. It can include + * drivers, observations, etc. + * + * PARINFO: This structure contains information on + * (a) pmin, pmax: parameter ranges (compulsory) + * (b) initpars: parameter starting values (optional/recommended). + * (c) npars: number of pars (compulsory) + * + * MCO: This structure contains option values for the MCMC run. + * These will be set to default values if empty. Options include: + * (a) number of runs + * (b) filename for writing file with results + * (c) step adaptation frequency + * (d) initial step size + * */ + +/* **************OUTPUTS************* + * + * RESULTS FILE: File includes (a) results (b) likelihood and (c) final step size + * + * */ + + + +/*NOTE: seeding must happen outside of the MHMCMC function*/ +/*if internal seeding is needed, use srandom(time(0));*/ +/*however this may result in repeat numbers over short timespan*/ + + +/*ERASING PREVIOUS FILE IF APPEND == 0 */ +if(MCO.APPEND==0 && MCO.nWRITE>0){FILE *fileout=fopen(MCO.outfile,"wb");fclose(fileout);} + + + +/*DECLARING*/ +double *P, P_new; +int NC=MCO.nchains;/*[DEMCMC] Number of chains*/ +P=calloc(NC,sizeof(double)); + +NC=MCO.nchains; + +/*initialising P as -inf */ +double Pmin=0; +int n=0,nn=0,m=0,withinrange,wrlocal=0; + +COUNTERS N; +N.ACC=0; +N.ITER=MCO.nSTART; //Pick up our status from nSTART, as we might be resuming an existing run! +N.ACCLOC=0; +N.ACCRATE=0; +/*New and default parameter vectors*/ +double *PARS,*pars_new,*BESTPARS, *BESTP; +PARS=calloc(PI.npars*NC,sizeof(double)); +pars_new=calloc(PI.npars,sizeof(double)); +BESTPARS=calloc(PI.npars*NC,sizeof(double)); +BESTP=calloc(NC,sizeof(double)); +/*All accepted parameters*/ +/*This is now the last N parameter vectors + * where N is the adaptation frequency*/ +/*PARSALL is only used for adaptation*/ +/*PARSALL=calloc(MCO.nADAPT*PI.npars*NC,sizeof(double));*//*[DEMCMC: can comment this out]*/ + +/*Random starting parameters if MCO.randparini*/ +double par; +for (nn=0;nnPI.parmax[n] | parP[nn]){Pmin=P[nn];} + + +memcpy(BESTP,P,NC*sizeof(double)); + + +//printf("starting likelihood for chain %i = %e\n",nn,P[nn]); + +if (isinf(P[nn])==-1){ + printf("WARNING! P(0)=-inf - MHMCMC may get stuck - if so, please check your initial conditions\n"); + }} + +/*STEP 2 - BEGIN MCMC*/ +for ( ;N.ITERlr){ +wrlocal=wrlocal+1; + /*Calculate new likelihood*/ + P_new=MODEL_LIKELIHOOD(DATA,pars_new);} + else + {P_new=log(0);} + //printf("P_new = %2.2f\n, PI.stepsize = %2.2f\n",P_new, PI.stepsize[0]); + /*if (isinf(P_new)==0){oksofar("Found non-inf solution");} + */ + /*treating nans as -inf*/ + if (isnan(P_new)){P_new=log(0);} +//if (P_new-P[nn]+gratio>lr || (isinf(P_new)==0 && isinf(P[nn]) && withinrange==1) ){N.ACC=N.ACC+1; + if (P_new-P[nn]+gratio>lr || (isinf(P[nn]) && withinrange==1) ){N.ACC=N.ACC+1; + if (isinf(P_new)==0 && isinf(P[nn])){printf("pnew = %2.1f, p = %2.1f, (P_new-P[nn]) = %2.1f\n",P_new,P[nn],P_new-P[nn]);} + + + for (n=0;n=BESTP[nn]){for (n=0;nP[nn] ){printf("Found bestpars, prob = %2.1f, chain = %i\n",BESTP[nn],nn);} + } + P[nn]=P_new;} + } + + /*regularly write results*/ + if (MCO.nWRITE>0 && (N.ITER % MCO.nWRITE)==0){ + WRITE_DEMCMC_RESULTS(PARS,PI,MCO, N.ITER); + } + + /*******regularly write restart file***********/ + if (MCO.nWRITE>0 && (N.ITER % 1000)==0){ + WRITE_DEMCMC_RESTART(PARS,PI,MCO,N.ITER); + } + + + /*Printing Info to Screen*/ + if (MCO.nPRINT>0 && N.ITER % MCO.nPRINT==0){ + printf("%d out of %d iterations)\n",N.ITER,MCO.nOUT); + printf("within range = %2.2f\n",wrlocal/((double)N.ITER*NC)*100); + printf("Local Acceptance rate %5.1f\n %%",100*(double)N.ACC/((double)N.ITER*NC)); + printf("PI.stepsize = %5.5f\n",PI.stepsize[0]); + printf("Log Likelihoods: "); + for (nn=0;nnbest_pars[n]=BESTPARS[n]; +//printf("MCOUT->best_pars[%i]=%2.1f",n,MCOUT->best_pars[n]); +} +/*MCMC completed*/ +MCOUT->complete=1; +/*done with MCMC completion*/ + +free(BESTPARS); +free(BESTP); +free(PARS); +free(pars_new); +free(P); +printf("DEMCMC DONE\n"); + + +return 0; + +/*END OF MHMCMC*/ +} + + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/MHMCMC_119.c === + +#pragma once +#include +#include +#include +#include "../../../math_fun/std.c" +#include "../../../math_fun/covariance.c" +#include "NORMPARS.c" +#include "ADAPT_STEP_SIZE_119.c" +#include "STEP_119.c" +#include "WRITERESULTS.c" + +/*here including additional functions needed to initialise and clear memory*/ +#include "INITIALIZE_MCMC_OUTPUT.c" + + + +double *MHMCMC_119( +double (MODEL_LIKELIHOOD)(DATA, double *), +DATA DATA, PARAMETER_INFO PI, MCMC_OPTIONS MCO, MCMC_OUTPUT *MCOUT){ + +/* ***********INPUTS************ + * + * MODEL_LIKELIHOOD: A function wholly responsible for + * (a) running the model given the DATA and parameters, + * (b) comparing it to observations,and + * (c) returning the (log) likelihood. + * The function will be run as MODEL_LIKELIHOOD(DATA,PARS); + * To facilitate this, ALL data can be + * passed to the MHMCMC function as a structure (in order to avoid + * repeated read/write computational time). + * + * DATA: All data needed for the MODEL_LIKELIHOOD. It can include + * drivers, observations, etc. + * + * PARINFO: This structure contains information on + * (a) pmin, pmax: parameter ranges (compulsory) + * (b) initpars: parameter starting values (optional/recommended). + * (c) npars: number of pars (compulsory) + * + * MCO: This structure contains option values for the MCMC run. + * These will be set to default values if empty. Options include: + * (a) number of runs + * (b) filename for writing file with results + * (c) step adaptation frequency + * (d) initial step size + * */ + +/* **************OUTPUTS************* + * + * RESULTS FILE: File includes (a) results (b) likelihood and (c) final step size + * + * */ + + + +/*NOTE: seeding must happen outside of the MHMCMC function*/ +/*if internal seeding is needed, use srandom(time(0));*/ +/*however this may result in repeat numbers over short timespan*/ + + +/*ERASING PREVIOUS FILE IF APPEND == 0 */ +if(MCO.APPEND==0 && MCO.nWRITE>0){FILE *fileout=fopen(MCO.outfile,"wb");fclose(fileout);} + + + +/*DECLARING*/ +double P0; +/*initialising P as -inf */ +double P=log(0); +int n=0,m=0, asw=0; + +COUNTERS N; +N.ACC=0; +N.ITER=0; +N.ACCLOC=0; +N.ACCRATE=0; +/*Initializing parmean and stdev*/ + +N.parmean=calloc(PI.npars,sizeof(double)); +N.parstdev=calloc(PI.npars,sizeof(double)); +declare_matrix(&N.parcovariance,PI.npars,PI.npars); +declare_matrix(&N.parcholesky,PI.npars,PI.npars); +N.covsamplecount=0; + +N.amp=1; +/*New and default parameter vectors*/ +double *PARS,*PARS0, *PARSALL,*BESTPARS; +PARS0=calloc(PI.npars,sizeof(double)); +PARS=calloc(PI.npars,sizeof(double)); +BESTPARS=calloc(PI.npars,sizeof(double)); +/*All accepted parameters*/ +/*This is now the last N parameter vectors + * where N is the adaptation frequency*/ +/*PARSALL is only used for adaptation*/ +PARSALL=calloc(ceil((double)MCO.nOUT/(double)MCO.nADAPT)*PI.npars,sizeof(double)); +printf("ceil((double)MCO.nOUT/(double)MCO.nADAPT) = %3.3f\n",ceil((double)MCO.nOUT/(double)MCO.nADAPT)); +double meanstepsize; + +/*Random starting parameters if MCO.randparini*/ +for (n=0;nlog((double)random()/(double)RAND_MAX)){ + /*storing accepted solution*/ + for (n=0;nP0){BESTPARS[n]=PARS[n];}} + + N.ACC=N.ACC+1;asw=1; + accloc=accloc+1; + P0=P; + /*writing results: parameters and log likelihood*/ + /*writing ALL results! Changed on Sat 30 Nov 2013*/ + +} + + + /*Continuing in any case*/ + N.ITER=N.ITER+1; + iterloc=iterloc+1; +/*Writing results to file*/ +if (MCO.nWRITE>0 && (N.ITER % MCO.nWRITE)==0){WRITE_RESULTS(PARS0,P,PI,MCO);} + + + /*Adapting Step Size*/ + /*Critical difference is here (N.ITER as opposed to N.ACC)*/ + if (N.ITER % MCO.nADAPT==0){ + N.ACCLOC=N.ITER/MCO.nADAPT; + for (n=0;n(double)N.ITER){ + ADAPT_STEP_SIZE_119(PARSALL,PI,&N,MCO);} + } + /*Printing Info to Screen*/ + if (MCO.nPRINT>0 && N.ITER % MCO.nPRINT==0){ + printf("Total iterations (out of %d) = %d\n",MCO.nOUT, N.ITER); + printf("Total within range = %3.3f%%\n",(double)wrloc/(double)MCO.nPRINT*100);wrloc=0; + printf("Total Accepted = %d\n",N.ACC); + printf("Local Acceptance rate (acc,accloc,mco.nadapt) %3.1f%% (%8i, %8i, %8i)\n",N.ACCRATE*100, N.ACC, N.ACCLOC, MCO.nADAPT); + printf("Log Likelihood %e\n",P0); + meanstepsize=0; + for (n=0;nbest_pars[n]=BESTPARS[n];} +/*MCMC completed*/ +MCOUT->complete=1; +/*done with MCMC completion*/ + +free(BESTPARS); +free(PARS); +free(PARS0); +free(PARSALL); +free(N.parmean); +free(N.parstdev); +free(*(N.parcovariance)); +free(N.parcovariance); +free(*(N.parcholesky)); +free(N.parcholesky); + +printf("MHMCMC DONE\n"); + + +return 0; + +/*END OF MHMCMC*/ +} + + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/ADAPT_STEP_SIZE_119.c === + +#pragma once +#include "../../../math_fun/cholesky.c" +#include "../../../math_fun/declare_matrix.c" +int tempfun_print_mat(double **CM, int N){ +int p,pp; +for (p=0;pACC/(double)MCO.nOUT/2); +double adapfac=scfac*0.001+1; +/*ratio loc vs total*/ +/* +double adapfac=1.5;*/ + + +/*MAKE THIS COMPATIBLE WITH STRUCTS AND CODE*/ + + + +/*Scale factor adaptation*/ +if (N->ACCLOC>PI.npars*10){ + /*Growth in all dims if ACCRATE>0.23*/ + if (N->ACCRATE<0.23){N->amp=N->amp/adapfac;} + else {N->amp=N->amp*adapfac;}} +/*Done with scale factor adaptation*/ +N->amp=1; + + + +/*Only derive covariance once*/ +if (N->ACCLOC>PI.npars*10 & N->covsamplecount==0){ + + double **norparvec; + declare_matrix(&norparvec,PI.npars, N->ACCLOC); + int i, os; + /*Offset (gaining 2, losing 1)*/ + os=(int)floor((double)N->ACCLOC/2); + /*std of each parameter (for all recently N->ACCLOCepted parameters)*/ + for (p=0;pACCLOC-os);n++){ + /*transforming parameters and storing in pointer*/ + norparvec[p][n]=par2nor(PARSALL[PI.npars*(n+os)+p],PI.parmin[p],PI.parmax[p]);}} + + /*Calculare covariance of norparvec AND store*/ + for (p=0;pparcovariance[p][pp]=covariance(norparvec[p],norparvec[pp],N->ACCLOC-os);}} + + + /*Calculate and store mean*/ + for (p=0;pACCLOC-os);n++){ + N->parmean[p]=mean(norparvec[p],N->ACCLOC-os);}} + N->covsamplecount=N->ACCLOC-os; + + free(*(norparvec)); + free(norparvec); +} +/*Done with Covariance derivation*/ + + + +/*Now only deriving incremental covariance changes*/ +/*statfun_incremental_cov_mat(double **CM, int Npars, int Nsamples, double *CMmean, double *newsample, double ar)*/ + +else if (N->ACCLOC>PI.npars*10 & N->covsamplecount>0){ + + + + /*Derive terms needed for statfun*/ + /*Normalized parameter vector sample to add/remove*/ + double *norparveci=calloc(PI.npars,sizeof(double)); + /*add and (maybe) remove sample*/ + int isample=N->ACCLOC; + for (p=0;pparcovariance,PI.npars,N->covsamplecount,N->parmean,norparveci,1); + N->covsamplecount=N->covsamplecount+1; + + /*Step 4. Remove parameter if mod(N,2) is not zero*/ + if (N->ACCLOC % 2>0){ + /*Copying matrix*/ + + isample=(int)floor((double)N->ACCLOC/2); + for (p=0;pparcovariance,PI.npars,N->covsamplecount,N->parmean,norparveci,-1); + N->covsamplecount=N->covsamplecount-1; + + + + + } + + +} + +/* +if (N->ACCLOC>10*PI.npars){ +printf("N->ACCLOC = %i\n",N->ACCLOC); +printf(" N->parcovariance = %3.3f\n",N->parcovariance[0][0]); +}*/ +/*Now calculating cholesky and storing*/ + +if (N->ACCLOC>PI.npars*10){ + +double **CCM; +declare_matrix(&CCM,PI.npars,PI.npars); +int choldiag=cholesky(N->parcovariance,PI.npars,CCM); + +if (choldiag==1){ +for (p=0;pparcholesky[p][pp]=CCM[p][pp];}}} + + + free(*(CCM));free(CCM); +} +/*Done with Cholesky calculation*/ + + +return 0; + +} + + + + + + + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c === + +#pragma once +#include +#include +#include +#include "../../../math_fun/std.c" +#include "NORMPARS.c" +#include "STEP_DEMCMC.c" +#include "STEP_ADEMCMC.c" +#include "WRITE_DEMCMC_RESULTS.c" + +/*here including additional functions needed to initialise and clear memory*/ +#include "INITIALIZE_MCMC_OUTPUT.c" +/*Same as MHMCMC, except following differences:*/ +/*N chains (N>=3)*/ + +double *ADEMCMC_301( +double (MODEL_LIKELIHOOD)(DATA, double *), +DATA DATA, PARAMETER_INFO PI, MCMC_OPTIONS MCO, MCMC_OUTPUT *MCOUT){ + +/* ***********INPUTS************ + * + * MODEL_LIKELIHOOD: A function wholly responsible for + * (a) running the model given the DATA and parameters, + * (b) comparing it to observations,and + * (c) returning the (log) likelihood. + * The function will be run as MODEL_LIKELIHOOD(DATA,PARS); + * To facilitate this, ALL data can be + * passed to the MHMCMC function as a structure (in order to avoid + * repeated read/write computational time). + * + * DATA: All data needed for the MODEL_LIKELIHOOD. It can include + * drivers, observations, etc. + * + * PARINFO: This structure contains information on + * (a) pmin, pmax: parameter ranges (compulsory) + * (b) initpars: parameter starting values (optional/recommended). + * (c) npars: number of pars (compulsory) + * + * MCO: This structure contains option values for the MCMC run. + * These will be set to default values if empty. Options include: + * (a) number of runs + * (b) filename for writing file with results + * (c) step adaptation frequency + * (d) initial step size + * */ + +/* **************OUTPUTS************* + * + * RESULTS FILE: File includes (a) results (b) likelihood and (c) final step size + * + * */ + + + +/*NOTE: seeding must happen outside of the MHMCMC function*/ +/*if internal seeding is needed, use srandom(time(0));*/ +/*however this may result in repeat numbers over short timespan*/ + + +/*ERASING PREVIOUS FILE IF APPEND == 0 */ +if(MCO.APPEND==0 && MCO.nWRITE>0){FILE *fileout=fopen(MCO.outfile,"wb");fclose(fileout);} + + + +/*DECLARING*/ +double *P, P_new; +int NC=MCO.nchains;/*[DEMCMC] Number of chains*/ +P=calloc(NC,sizeof(double)); + +NC=MCO.nchains; + +/*initialising P as -inf */ +double Pmin=0; +int n=0,nn=0,m=0,withinrange,wrlocal=0; + +COUNTERS N; +N.ACC=0; +N.ITER=0; +N.ACCLOC=0; +N.ACCRATE=0; +/*New and default parameter vectors*/ +double *PARS,*pars_new,*BESTPARS, *BESTP; +PARS=calloc(PI.npars*NC,sizeof(double)); +pars_new=calloc(PI.npars,sizeof(double)); +BESTPARS=calloc(PI.npars*NC,sizeof(double)); +PARS0=calloc(PI.npars*NC,sizeof(double)); +BESTP=calloc(NC,sizeof(double)); +/*All accepted parameters*/ +/*This is now the last N parameter vectors + * where N is the adaptation frequency*/ +/*PARSALL is only used for adaptation*/ +/*PARSALL=calloc(MCO.nADAPT*PI.npars*NC,sizeof(double));*//*[DEMCMC: can comment this out]*/ + +/*Random starting parameters if MCO.randparini*/ +double par; +for (nn=0;nnPI.parmax[n] | parP[nn]){Pmin=P[nn];} + + +memcpy(BESTP,P,NC*sizeof(double)); + + +//printf("starting likelihood for chain %i = %e\n",nn,P[nn]); + +if (isinf(P[nn])==-1){printf("WARNING! P(0)=-inf - MHMCMC may get stuck - if so, please check your initial conditions\n");}} + +/*STEP 2 - BEGIN MCMC*/ +for (N.ITER=0;N.ITERlr){ +wrlocal=wrlocal+1; + /*Calculate new likelihood*/ + P_new=MODEL_LIKELIHOOD(DATA,pars_new);} + else + {P_new=log(0);} + //printf("P_new = %2.2f\n, PI.stepsize = %2.2f\n",P_new, PI.stepsize[0]); + /*if (isinf(P_new)==0){oksofar("Found non-inf solution");} + */ + /*treating nans as -inf*/ + if isnan(P_new){P_new=log(0);} +if (P_new-P[nn]+gratio>lr || (isinf(P_new)==0 && isinf(P[nn]) && withinrange==1)){N.ACC=N.ACC+1; + if (isinf(P_new)==0 && isinf(P[nn])){printf("pnew = %2.1f, p = %2.1f, (P_new-P[nn]) = %2.1f\n",P_new,P[nn],P_new-P[nn]);} + + + for (n=0;n=BESTP[nn]){for (n=0;nP[nn] ){printf("Found bestpars, prob = %2.1f, chain = %i\n",BESTP[nn],nn);} + } + } + } + + /*regularly write results*/ + if (MCO.nWRITE>0 && (N.ITER % MCO.nWRITE)==0){ +WRITE_DEMCMC_RESULTS(PARS,PI,MCO);} + + /*Printing Info to Screen*/ + if (MCO.nPRINT>0 && N.ITER % MCO.nPRINT==0){ + printf("%d out of %d iterations)\n",N.ITER,MCO.nOUT); + printf("within range = %2.2f\n",wrlocal/((double)N.ITER*NC)*100); + printf("Local Acceptance rate %5.1f\n %%",100*(double)N.ACC/((double)N.ITER*NC)); + printf("PI.stepsize = %5.5f\n",PI.stepsize[0]); + printf("Log Likelihoods: "); + for (nn=0;nnbest_pars[n]=BESTPARS[n]; +//printf("MCOUT->best_pars[%i]=%2.1f",n,MCOUT->best_pars[n]); +} +/*MCMC completed*/ +MCOUT->complete=1; +/*done with MCMC completion*/ + +free(BESTPARS); +free(BESTP); +free(PARS); +free(PARS0); +free(pars_new); +free(P); +printf("DEMCMC DONE\n"); + + +return 0; + +/*END OF MHMCMC*/ +} + + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_119.c === + +#pragma once +#include +#include "../../../math_fun/randn.c" + +int STEP_119(double *pars0, double *pars, PARAMETER_INFO PI,COUNTERS N, MCMC_OPTIONS MCO){ + +/*FIXEDPARS*/ +/*ones and zeros depending on whether parameters are kept fixed*/ + +int n,nn,fp,withinlim=1; +double npar,*rn,*rn0,step, npar_new, rn2; + + +rn0=calloc(PI.npars,sizeof(double)); +rn=calloc(PI.npars,sizeof(double)); + + +/*cholesky sampling here*/ +/*cholesky matrix = upper triangular*/ +/*correlated random numbers = rn * U*/ + +for (n=0;n1){withinlim=0;} +/*printf("rn/rn2/npar/step/new = %2.2f/%2.2f/%2.2f/%2.2f/%2.2f\n",rn[n],rn2,npar,step,npar_new);*/ + pars[n]=nor2par(npar_new,PI.parmin[n],PI.parmax[n]);} + +free(rn);free(rn0); +return withinlim; + + +} + + + + +=== FILE: ./C/mcmc_fun/MHMCMC/MCMC_FUN/INITIALIZE_MCMC_OUTPUT.c === + +#pragma once +int INITIALIZE_MCMC_OUTPUT(PARAMETER_INFO PI,MCMC_OUTPUT *MCOUT, MCMC_OPTIONS MCO){ + +/*defining MCMC output structure*/ +MCOUT->best_pars=calloc(PI.npars*MCO.nchains,sizeof(double)); +/*set to zero, will change to 1 when MCMC is complete!*/ +MCOUT->complete=0; + + +return 0; + + +} + + + +=== FILE: ./C/auxi_fun/oksofar.c === + +#pragma once +#include +int oksofar(char * msg){ +printf("%s\n",msg); +fflush(stdout); +return 0; + +} + + + +=== FILE: ./C/auxi_fun/meanptr.c === + +#pragma once +double meanptr(double *P,int ne){ +int n; +double meanP; +for (n=0;n +int okcheck(int OK, char * msg){ + +printf("OKCHECK:%s\n",msg); + + +if (OK!=0) +{printf("OKCHECK WARNING! EXPECT ERROR!");} + +fflush(stdout); +return 0; + +} + + + +=== FILE: ./C/auxi_fun/seedrandomnumber.c === + + +#pragma once +#include // rand(), srand() +#include +#include //for time +#include +#include +#include // For explicit integer types +/*triple-seeding in simple C code*/ + + +int my_strlen(const char *string) //Function to calculate length of given string +{ + int i; + for(i=0;string[i]!='\0';i++); + return i; +} + + +int charseed(const char *charinput){ +/*storing charinput contents in charmem*/ +/*loop index and initializing memtot*/ + int memtot=0, n; + /*adding up memory contents*/ + for (n=0; n Date: Mon, 20 Apr 2026 20:08:26 -0700 Subject: [PATCH 19/30] turn ST EDC back on for E pools --- C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 77729000..23668693 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -1380,9 +1380,9 @@ EDC_st.pool_indices[7]=S.H2O_LY1; EDC_st.pool_indices[8]=S.H2O_LY2; EDC_st.pool_indices[9]=S.H2O_LY3; EDC_st.pool_indices[10]=S.H2O_SWE; -// EDC_st.pool_indices[11]=S.E_LY1; -// EDC_st.pool_indices[12]=S.E_LY2; -// EDC_st.pool_indices[13]=S.E_LY3; +EDC_st.pool_indices[11]=S.E_LY1; +EDC_st.pool_indices[12]=S.E_LY2; +EDC_st.pool_indices[13]=S.E_LY3; //EDC_st.pool_indices[12]=S.M_LAI_MAX;``` //EDC_st.pool_indices[13]=S.M_LAI_TEMP; From e32f36ec7c4f37cf8b7769a46ee0ef66c50376e9 Mon Sep 17 00:00:00 2001 From: ebilir Date: Fri, 24 Apr 2026 17:11:36 -0700 Subject: [PATCH 20/30] potxfer, impedance update --- .../DALEC/DALEC_1100/DALEC_1100.c | 2 +- .../CONVERTERS/HYDROFUN_MOI2CON.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 23668693..b8b15d42 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -736,7 +736,7 @@ double k_LY2 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY2],pars[P.hydr_cond],pars[P.ret double k_LY3 = HYDROFUN_MOI2CON(POOLS[p+S.D_SM_LY3],pars[P.hydr_cond],pars[P.retention],POOLS[p+S.D_LF_LY3]); // Calculate inter-pool transfer in m/s (positive is LY1 to LY2) -double pot_xfer = 1000 * sqrt(k_LY1*k_LY2) * (1e-9*(POOLS[p+S.D_PSI_LY1]-POOLS[p+S.D_PSI_LY2])/(9.8*0.5*(pars[P.LY1_z]+pars[P.LY2_z])) + 1); +double pot_xfer = 1000 * sqrt(k_LY1*k_LY2) * (1000*(POOLS[p+S.D_PSI_LY1]-POOLS[p+S.D_PSI_LY2])/(9.8*0.5*(pars[P.LY1_z]+pars[P.LY2_z])) + 1); double SPACEavail, H2Oavail, Max_H2O_xfer, TEMPxfer_1to2; if (pot_xfer>0) {//Water is going LY1->LY2 (down) // Available space in LY2 (after runoff) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c index 727e8707..2a71749c 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2CON.c @@ -11,23 +11,23 @@ lf - liquid fraction double HYDROFUN_MOI2CON(double moi, double k0, double b, double lf){ -if (lf<=1e-4){ +if (lf<=1e-6 && moi>=0.999999){ return 0.0; } - + double min_cond_factor = 1e-14; // scales saturated conductivity // 1. Calculate effective pore volume (fraction of pore volume not occupied by ice) double ice_sat_tv = moi * (1.0 - lf); //fraction of pore volume occupied by ice double effective_porosity = 1.0 - ice_sat_tv; //fraction of pore volume NOT occupied by ice // 2. Calculate effective liquid saturation - double liq_sat_tv = moi * lf; //fraction of pore volume occupied by liquid water + double liq_sat_tv = moi * lf; //fraction of pore volume occupied by liquid water double moi_eff = liq_sat_tv / effective_porosity; //fraction of occupied by liquid water - // 3. Calculate unsaturated hydraulic conductivity based on available liquid space - double con_max = k0 * pow(moi_eff, 2.0 * b + 3.0); - double impedance = pow(10, -ice_sat_tv*6.0); // from Swenson et al., 2012 https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2012MS000165 - - double con = con_max * impedance; + // 3. Calculate unsaturated hydraulic conductivity based on available liquid space. + double con_campbell = k0 * pow(moi_eff, 2.0 * b + 3.0); /*CAMPBELL, GAYLON S. A SIMPLE METHOD FOR DETERMINING UNSATURATED CONDUCTIVITY FROM MOISTURE RETENTION DATA. Soil Science 117(6):p 311-314, June 1974.*/ + double con_min=k0*min_cond_factor; //allows nominal water movement for fully dry/frozen empty pore space + + double con=fmax(con_campbell, con_min); return con; } \ No newline at end of file From fb85d0f918c91b66db6ef0334a736570866c657f Mon Sep 17 00:00:00 2001 From: ebilir Date: Sat, 25 Apr 2026 21:16:20 -0700 Subject: [PATCH 21/30] remove surface impedance --- C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index b8b15d42..8b668968 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -704,9 +704,10 @@ FLUXES[f+F.sensible_heat] = Rn - FLUXES[f+F.ground_heat] - FLUXES[f+F.latent_hea // Infiltration (mm/day) double liquid_in = (PREC[n] - SNOWFALL[n] + FLUXES[f+F.melt]); -double ice_sat_tv_surface = POOLS[p+S.D_SM_LY1] * (1.0 - POOLS[p+S.D_LF_LY1]); // volume of total pore space occupied by ice -double dynamic_max_infil = fmax(pars[P.max_infil] * pow(10.0, -6.0 * ice_sat_tv_surface), 1e-4); // impedance of infiltration due to ice blockage -FLUXES[f+F.infil] = dynamic_max_infil*(1 - exp(-liquid_in/dynamic_max_infil)); +// double ice_sat_tv_surface = POOLS[p+S.D_SM_LY1] * (1.0 - POOLS[p+S.D_LF_LY1]); // volume of total pore space occupied by ice +// double dynamic_max_infil = fmax(pars[P.max_infil] * pow(10.0, -6.0 * ice_sat_tv_surface), 1e-4); // impedance of infiltration due to ice blockage +// FLUXES[f+F.infil] = dynamic_max_infil*(1 - exp(-liquid_in/dynamic_max_infil)); +FLUXES[f+F.infil] = pars[P.max_infil]*(1 - exp(-liquid_in/pars[P.max_infil])); // Surface runoff (mm/day) From b46a67fcca7d29459abdde3dc8582e083aceb432 Mon Sep 17 00:00:00 2001 From: ebilir Date: Thu, 14 May 2026 15:18:40 -0700 Subject: [PATCH 22/30] roll back cryosuction (temporary) --- .../DALEC/DALEC_1100/DALEC_1100.c | 12 ++++++------ .../CONVERTERS/HYDROFUN_MOI2PSI.c | 18 ++++++++++-------- .../DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c | 4 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 8b668968..75622faa 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -382,9 +382,9 @@ POOLS[S.D_LF_LY3]=LY3SOILTEMP.OUT.LF; //Effectively this corrects MOI to (water frac)/(water + air frac) //Min psi ensures large negative psis not resolved by model needlessly double minpsi=-30; -POOLS[S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY1],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY1],POOLS[S.D_TEMP_LY1]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction -POOLS[S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY2],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY2],POOLS[S.D_TEMP_LY2]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction -POOLS[S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY3],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY3],POOLS[S.D_TEMP_LY3]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction +POOLS[S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY1],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY1]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction +POOLS[S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY2],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY2]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction +POOLS[S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI(POOLS[S.D_SM_LY3],psi_porosity,pars[P.retention], POOLS[S.D_LF_LY3]),minpsi); //psi reflects ice-adjusted capillary tension + cryosuction //******************Declare KNORR STRUCT********************* @@ -1158,11 +1158,11 @@ POOLS[nxp+S.D_SM_LY2]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY2],pars[P.LY2_por],pars POOLS[nxp+S.D_SM_LY3]=HYDROFUN_EWT2MOI(POOLS[nxp+S.H2O_LY3],pars[P.LY3_por],pars[P.LY3_z]);//soil moisture LY3 //Correcting PSI for presence of ice occurs within MOI2PSI function POOLS[nxp+S.D_PSI_LY1]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY1],psi_porosity,pars[P.retention], -POOLS[nxp+S.D_LF_LY1],POOLS[nxp+S.D_TEMP_LY1]),minpsi); +POOLS[nxp+S.D_LF_LY1]),minpsi); POOLS[nxp+S.D_PSI_LY2]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY2],psi_porosity,pars[P.retention], -POOLS[nxp+S.D_LF_LY2],POOLS[nxp+S.D_TEMP_LY2]),minpsi); +POOLS[nxp+S.D_LF_LY2]),minpsi); POOLS[nxp+S.D_PSI_LY3]=fmax(HYDROFUN_MOI2PSI( POOLS[nxp+S.D_SM_LY3],psi_porosity,pars[P.retention], -POOLS[nxp+S.D_LF_LY3],POOLS[nxp+S.D_TEMP_LY3]),minpsi); +POOLS[nxp+S.D_LF_LY3]),minpsi); //Isfinite check for 14 progronstic pools only diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c index 7f43c9da..7c11385e 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/CONVERTERS/HYDROFUN_MOI2PSI.c @@ -10,7 +10,8 @@ b - retention parameter lf - liquid fraction */ -double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf, double soil_temp){ +double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf){ +// double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf, double soil_temp){ // Safety check to prevent divide-by-zero if (lf<=1e-4) return -9999.0; @@ -27,13 +28,14 @@ double HYDROFUN_MOI2PSI(double moi, double psi_porosity, double b, double lf, do double psi_capillary=psi_porosity*(pow((1.0/(moi_eff)),b)); // 4. Calculate cryosuction (Clapeyron equation) if frozen - double psi_cryo = 0.0; - if (lf < 1.0 && soil_temp < 273.15) { - // Latent heat of fusion = 3.34e5 J/kg. Equation yields MPa. - // As temperature drops further below 273.15, suction becomes more strongly negative - psi_cryo = (3.34e5 * (soil_temp - 273.15)) / (1000.0 * soil_temp); - } - double psi = fmin(psi_capillary, psi_cryo); + // double psi_cryo = 0.0; + // if (lf < 1.0 && soil_temp < 273.15) { + // // Latent heat of fusion = 3.34e5 J/kg. Equation yields MPa. + // // As temperature drops further below 273.15, suction becomes more strongly negative + // psi_cryo = (3.34e5 * (soil_temp - 273.15)) / (1000.0 * soil_temp); + // } + // double psi = fmin(psi_capillary, psi_cryo); + double psi = psi_capillary; return psi; } \ No newline at end of file diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c index c2e04115..1b6ea3b0 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_ALL/HYDROLOGY_MODULES/DRAINAGE.c @@ -15,7 +15,7 @@ b - retention parameter lf - liquid fraction of H2O content */ -double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity, double b, double lf, double soil_temp){ +double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity, double b, double lf){ // 1. check for excessive soil moisture: drain out sm>1 so that all sm values are <=1, and won't break psi_eff. // (note that sm>1 only occurs transiently in between time steps and must be in a liquid/drainable state) @@ -25,7 +25,7 @@ double DRAINAGE(double sm, double Qexcess, double psi_field, double psi_porosity sm = 1.0;} // 2. Calculate current effective potential of the liquid-saturated state - double psi_eff = HYDROFUN_MOI2PSI(sm, psi_porosity, b, lf, soil_temp); + double psi_eff = HYDROFUN_MOI2PSI(sm, psi_porosity, b, lf); // 3. Check for excessive soil moisture: if (psi_eff <= psi_field) { From dea20f4756f9f0ada37f9e4b1a8c5f7d0ee47a0f Mon Sep 17 00:00:00 2001 From: ebilir Date: Thu, 14 May 2026 15:28:50 -0700 Subject: [PATCH 23/30] again --- C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 75622faa..2a8290ba 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -717,11 +717,11 @@ FLUXES[f+F.q_surf] = liquid_in - FLUXES[f+F.infil]; // Calculate drainage: correcting psi for presence of ice occurs within DRAINAGE function double drain_LY1 = DRAINAGE(POOLS[p+S.D_SM_LY1],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, -pars[P.retention],POOLS[p+S.D_LF_LY1],POOLS[p+S.D_TEMP_LY1]); +pars[P.retention],POOLS[p+S.D_LF_LY1]); double drain_LY2 = DRAINAGE(POOLS[p+S.D_SM_LY2],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, -pars[P.retention],POOLS[p+S.D_LF_LY2],POOLS[p+S.D_TEMP_LY2]); +pars[P.retention],POOLS[p+S.D_LF_LY2]); double drain_LY3 = DRAINAGE(POOLS[p+S.D_SM_LY3],pars[P.Q_excess],-pars[P.field_cap],psi_porosity, -pars[P.retention],POOLS[p+S.D_LF_LY3],POOLS[p+S.D_TEMP_LY3]); +pars[P.retention],POOLS[p+S.D_LF_LY3]); // Drainage becomes runoff from pools FLUXES[f+F.q_ly1] = HYDROFUN_MOI2EWT(drain_LY1,pars[P.LY1_por],pars[P.LY1_z])*one_over_deltat; From 606f3dee3fe3752b4663e2dd2c2353a1b3043934 Mon Sep 17 00:00:00 2001 From: ebilir Date: Fri, 15 May 2026 23:33:30 -0700 Subject: [PATCH 24/30] 1) update scf_scalar to reconcile SWE,SCF obs; 2) add PEQ for lambda_max to nudge away from unrealistic LAI ceilings; --- .../CARDAMOM_GENERAL/CARDAMOM_DATA_STRUCTURE.c | 1 + .../CARDAMOM_NETCDF_DATA_STRUCTURE.c | 1 + .../CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c | 1 + .../CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c | 1 + .../CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c | 2 ++ .../DALEC/DALEC_1100/PARS_INFO_1100.c | 2 +- .../DALEC_OBSERVATION_OPERATORS.c | 13 +++++++++++++ .../DALEC_ALL_LIKELIHOOD.c | 4 +++- 8 files changed, 23 insertions(+), 2 deletions(-) diff --git a/C/projects/CARDAMOM_GENERAL/CARDAMOM_DATA_STRUCTURE.c b/C/projects/CARDAMOM_GENERAL/CARDAMOM_DATA_STRUCTURE.c index 0118bf29..b521f73b 100644 --- a/C/projects/CARDAMOM_GENERAL/CARDAMOM_DATA_STRUCTURE.c +++ b/C/projects/CARDAMOM_GENERAL/CARDAMOM_DATA_STRUCTURE.c @@ -50,6 +50,7 @@ double M_PEQ_Vcmax25; double M_PEQ_C3frac; double M_PEQ_iniSnow; double M_PEQ_iniSOM; +double M_PEQ_lambdamax; double M_PEQ_LCMA; double M_PEQ_clumping; //add PEQ value and unc from previous MCMC *pMCMC* diff --git a/C/projects/CARDAMOM_GENERAL/CARDAMOM_NETCDF_DATA_STRUCTURE.c b/C/projects/CARDAMOM_GENERAL/CARDAMOM_NETCDF_DATA_STRUCTURE.c index 667358b3..bb5029a0 100644 --- a/C/projects/CARDAMOM_GENERAL/CARDAMOM_NETCDF_DATA_STRUCTURE.c +++ b/C/projects/CARDAMOM_GENERAL/CARDAMOM_NETCDF_DATA_STRUCTURE.c @@ -93,6 +93,7 @@ SINGLE_OBS_STRUCT PEQ_Vcmax25; SINGLE_OBS_STRUCT PEQ_C3frac; SINGLE_OBS_STRUCT PEQ_iniSnow; SINGLE_OBS_STRUCT PEQ_iniSOM; +SINGLE_OBS_STRUCT PEQ_lambdamax; SINGLE_OBS_STRUCT PEQ_LCMA; SINGLE_OBS_STRUCT PEQ_clumping; //add PEQ value and unc from previous MCMC *pMCMC* diff --git a/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c b/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c index 7bd7fcdf..4f9a7ec6 100644 --- a/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c +++ b/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c @@ -208,6 +208,7 @@ free(DATA.M_SIF); free(DATA.M_LAI); free(DATA.M_FIR); free(DATA.M_NBE); +free(DATA.M_SWE); diff --git a/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c b/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c index 96dc9a4b..b6cd3fc1 100644 --- a/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c +++ b/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c @@ -134,6 +134,7 @@ DATA->PEQ_CUE=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_CUE"); DATA->PEQ_C3frac=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_C3frac"); DATA->PEQ_Vcmax25=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_Vcmax25"); DATA->PEQ_iniSOM=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_iniSOM"); +DATA->PEQ_lambdamax=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_lambdamax"); DATA->PEQ_iniSnow=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_iniSnow"); DATA->PEQ_LCMA=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_LCMA"); DATA->PEQ_clumping=READ_NETCDF_SINGLE_OBS_FIELDS(ncid, "PEQ_clumping"); diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 2a8290ba..6dcbe81e 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -1517,6 +1517,7 @@ OBSOPE.SUPPORT_Vcmax25_OBS=true; OBSOPE.SUPPORT_C3frac_OBS=true; OBSOPE.SUPPORT_iniSnow_OBS=true; OBSOPE.SUPPORT_iniSOM_OBS=true; +OBSOPE.SUPPORT_lambdamax_OBS=true; OBSOPE.SUPPORT_NBEmrg_OBS=true; OBSOPE.SUPPORT_CUEmrg_OBS=true; OBSOPE.SUPPORT_LCMA_OBS=true; @@ -1610,6 +1611,7 @@ OBSOPE.Vcmax25_PARAM=P.Vcmax25; OBSOPE.iniSnow_PARAM=P.i_SWE; //Initial SOM parameter OBSOPE.iniSOM_PARAM=P.i_som; +OBSOPE.lambdamax_PARAM=P.lambda_max; OBSOPE.LCMA_PARAM=P.LCMA; OBSOPE.clumping_PARAM=P.clumping; //OBSOPE.LAD_PARAM=P.LAD; diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/PARS_INFO_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/PARS_INFO_1100.c index 91667e64..8345009e 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/PARS_INFO_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/PARS_INFO_1100.c @@ -252,7 +252,7 @@ parmin[P.melt_slope]=0.00001; parmax[P.melt_slope]=1; /*sn3: snow cover fraction scalar; SCF = SWE/(SWE +SWEcritical_par) */ -parmin[P.scf_scalar]=10; +parmin[P.scf_scalar]=1.0; parmax[P.scf_scalar]=1000.0; /* jc S_fv statistically fitting the fV curves (S1,S2,S3 schemes) with total soil moisture (LY1/LY1_fs)\n jc new name for this par is S_fv, scalar for aerobic volumetric fraction */ diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_OBSERVATION_OPERATORS/DALEC_OBSERVATION_OPERATORS.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_OBSERVATION_OPERATORS/DALEC_OBSERVATION_OPERATORS.c index c3294bdf..262959c1 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_OBSERVATION_OPERATORS/DALEC_OBSERVATION_OPERATORS.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_OBSERVATION_OPERATORS/DALEC_OBSERVATION_OPERATORS.c @@ -83,6 +83,10 @@ bool SUPPORT_iniSOM_OBS; int iniSOM_PARAM;//This is assuming it's a single parameter //Can add more parameters OR options +bool SUPPORT_lambdamax_OBS; +int lambdamax_PARAM;//This is assuming it's a single parameter +//Can add more parameters OR options + bool SUPPORT_LCMA_OBS; int LCMA_PARAM;//This is assuming it's a single parameter //Can add more parameters OR options @@ -136,6 +140,7 @@ OBSOPE->SUPPORT_C3frac_OBS=false; OBSOPE->SUPPORT_Vcmax25_OBS=false; OBSOPE->SUPPORT_iniSnow_OBS=false; OBSOPE->SUPPORT_iniSOM_OBS=false; +OBSOPE->SUPPORT_lambdamax_OBS=false; OBSOPE->SUPPORT_LCMA_OBS=false; OBSOPE->SUPPORT_clumping_OBS=false; //In-built observation operators @@ -593,6 +598,13 @@ if (SOBS.validobs){ } return 0;} +int DALEC_OBSOPE_lambdamax(DATA * D, OBSOPE * O){ + SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_lambdamax; +if (SOBS.validobs){ + D->M_PEQ_lambdamax=D->M_PARS[O->lambdamax_PARAM]; + } +return 0;} + int DALEC_OBSOPE_LCMA(DATA * D, OBSOPE * O){ SINGLE_OBS_STRUCT SOBS=D->ncdf_data.PEQ_LCMA; if (SOBS.validobs){ @@ -661,6 +673,7 @@ if (O->SUPPORT_C3frac_OBS){DALEC_OBSOPE_C3frac(D, O);} if (O->SUPPORT_Vcmax25_OBS){DALEC_OBSOPE_Vcmax25(D, O);} if (O->SUPPORT_iniSnow_OBS){DALEC_OBSOPE_iniSnow(D, O);} if (O->SUPPORT_iniSOM_OBS){DALEC_OBSOPE_iniSOM(D, O);} +if (O->SUPPORT_lambdamax_OBS){DALEC_OBSOPE_lambdamax(D, O);} if (O->SUPPORT_LCMA_OBS){DALEC_OBSOPE_LCMA(D, O);} if (O->SUPPORT_clumping_OBS){DALEC_OBSOPE_clumping(D, O);} if (O->SUPPORT_r_ch4_OBS){DALEC_OBSOPE_r_ch4(D, O);} /*pMCMC*/ diff --git a/C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c b/C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c index e4aa9474..783dabd4 100644 --- a/C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c +++ b/C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c @@ -43,6 +43,7 @@ struct LIKELIHOOD_INDICES{ int PEQ_NBEmrg; int PEQ_iniSnow; int PEQ_iniSOM; + int PEQ_lambdamax; int PEQ_C3frac; int PEQ_Vcmax25; int PEQ_LCMA; @@ -54,7 +55,7 @@ struct LIKELIHOOD_INDICES{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19, 20,21,22,23,24,25,26,27,28,29, - 30}; /*pMCMC*/ + 30,31}; /*pMCMC*/ @@ -138,6 +139,7 @@ if (O->SUPPORT_Cefficiency_OBS){ML[LI.PEQ_Cefficiency]=CARDAMOM_SINGLE_OBS_LIKEL if (O->SUPPORT_CUE_OBS){ ML[LI.PEQ_CUE]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_CUE, D.M_PEQ_CUE);}; if (O->SUPPORT_iniSnow_OBS){ ML[LI.PEQ_iniSnow]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_iniSnow, D.M_PEQ_iniSnow);}; if (O->SUPPORT_iniSOM_OBS){ ML[LI.PEQ_iniSOM]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_iniSOM, D.M_PEQ_iniSOM);}; +if (O->SUPPORT_lambdamax_OBS){ ML[LI.PEQ_lambdamax]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_lambdamax, D.M_PEQ_lambdamax);}; if (O->SUPPORT_Vcmax25_OBS){ ML[LI.PEQ_Vcmax25]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_Vcmax25, D.M_PEQ_Vcmax25);}; if (O->SUPPORT_C3frac_OBS){ ML[LI.PEQ_C3frac]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_C3frac, D.M_PEQ_C3frac);}; if (O->SUPPORT_CUEmrg_OBS){ ML[LI.PEQ_CUE]=CARDAMOM_SINGLE_OBS_LIKELIHOOD(&D.ncdf_data.PEQ_CUE, D.M_PEQ_CUE);}; From 3c5b6fc79ab044bd74fe94dd0fef00a5495e6c86 Mon Sep 17 00:00:00 2001 From: ebilir Date: Sun, 24 May 2026 22:39:34 -0700 Subject: [PATCH 25/30] timing writeout + alloc opt --- C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c | 10 +++++++++- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_AFDEMCMC.c | 20 +++++++++---------- .../CARDAMOM_NETCDF_DATA_STRUCTURE.c | 1 + .../CARDAMOM_READ_BINARY_DATA.c | 1 + C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c | 2 +- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c index c0f4d379..9ebadfe0 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c @@ -140,6 +140,11 @@ if (isinf(P[nn])==-1){ printf("WARNING! P(0)=-inf - MHMCMC may get stuck - if so, please check your initial conditions\n"); }} +// Initialize memory +double *cpar = calloc(PI.npars, sizeof(double)); +double *rpar = calloc(PI.npars, sizeof(double)); +double *npar = calloc(PI.npars, sizeof(double)); + /*STEP 2 - BEGIN MCMC*/ for ( ;N.ITER #include "../../../math_fun/randn.c" -double STEP_AFDEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C, int NC, double *gratio){ +double STEP_AFDEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C, int NC, double *gratio, double *cpar, double *rpar, double *npar){ /* AFDEMCMC takes an Affine Invariant ensemble step (Goodman & Weare) */ int n, C1=-1; @@ -14,11 +14,11 @@ double STEP_AFDEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C, i C1 = ceil((double)random() * NC / ((double)RAND_MAX)) - 1; } - /* Step 2. Allocate memory for normalized parameter vectors */ - /* (Notice we deleted the heavy step and gamma arrays here!) */ - double *cpar = calloc(PI.npars, sizeof(double)); - double *rpar = calloc(PI.npars, sizeof(double)); - double *npar = calloc(PI.npars, sizeof(double)); + // /* Step 2. Allocate memory for normalized parameter vectors */ + // /* (Notice we deleted the heavy step and gamma arrays here!) */ + // double *cpar = calloc(PI.npars, sizeof(double)); + // double *rpar = calloc(PI.npars, sizeof(double)); + // double *npar = calloc(PI.npars, sizeof(double)); /* Normalize parameters into [0,1] space */ for (n=0; nncdf_data.SNOWFALL.reference_mean); printf("Mean Temp = %f\n",DATA->ncdf_data.T2M_MIN.reference_mean); printf("Mean Prec = %f\n",DATA->ncdf_data.TOTAL_PREC.reference_mean); printf("Latitude = %f\n",DATA->ncdf_data.LAT); +printf("Longitude = %f\n",DATA->ncdf_data.LON); printf("Ecological & Dynamic Constraints options\n"); printf("EDC likelihood option = %d\n",DATA->ncdf_data.EDC); diff --git a/C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c b/C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c index ca71dcc1..2107e240 100644 --- a/C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c +++ b/C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c @@ -292,7 +292,7 @@ printf("Done with EDC>0 search MCMC, time used = %6.2f seconds\n",cpu_time_used_ printf("Done with main MCMC, time used = %6.2f seconds\n",cpu_time_used_main); printf("***********************\n"); printf("***********************\n"); - +fflush(stdout); /*???????*/ /*User Defined function needed to clean up memory*/ MEMORY_CLEANUP(DATA,PI,MCOPT,MCOUT); From 0550780bf20e40fe7f42630eefd453dfdd4034fb Mon Sep 17 00:00:00 2001 From: ebilir Date: Sun, 24 May 2026 23:23:48 -0700 Subject: [PATCH 26/30] minor cleanup --- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_AFDEMCMC.c | 2 +- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c | 8 ++++---- C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_AFDEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_AFDEMCMC.c index 4c0e2f61..1b225ece 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_AFDEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_AFDEMCMC.c @@ -11,7 +11,7 @@ double STEP_AFDEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C, i /* Step 1. Find random sample (reference chain) other than current chain */ C1=C; while (C1==C){ - C1 = ceil((double)random() * NC / ((double)RAND_MAX)) - 1; + C1 = floor((double)random() * NC / ((double)RAND_MAX + 1.0)); } // /* Step 2. Allocate memory for normalized parameter vectors */ diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c index 3bef5d45..f0a65c08 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c @@ -27,9 +27,9 @@ int withinlim=1; /*first: pick c1 and c2, make sure that (a) they are between 1 and NC, and (b) they are not C*/ c1=C;c2=C; - while (c1==C | c2==C | c1==c2){ - c1=ceil((double)random()*NC/((double)RAND_MAX))-1; - c2=ceil((double)random()*NC/((double)RAND_MAX))-1;} + while (c1==C || c2==C || c1==c2){ + c1=floor((double)random() * NC / ((double)RAND_MAX + 1.0)); + c2=floor((double)random() * NC / ((double)RAND_MAX + 1.0));} mstep=0; /*SAMPLING PARAMETERS*/ for (n=0;n1){withinlim=0;} + if (npar[n]<0 || npar[n]>1){withinlim=0;} } diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c index 35aa91a2..22fd2871 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c @@ -90,7 +90,7 @@ int WRITE_DEMCMC_RESTART(double *PARS,PARAMETER_INFO PI,MCMC_OPTIONS MCO, int IT FAILONERROR(nc_def_dim(ncid,"Sample",NC_UNLIMITED,&sampleDimID)); FAILONERROR(nc_def_var(ncid,"Parameters",NC_DOUBLE,2,(const int[]){sampleDimID,paramDimID},&parsVarID)); //Note: it's a bit odd this is an int, and not a uint or long. Likely does not matter though. - FAILONERROR(nc_put_att_int(ncid,parsVarID,"N",NC_INT,sizeof(int),&ITER)); + FAILONERROR(nc_put_att_int(ncid,parsVarID,"N",NC_INT,1,&ITER)); //TODO: store N and rng seed ------------------------------------------------------ From 47f46763027c5add552283073f7e83791d748cf5 Mon Sep 17 00:00:00 2001 From: ebilir Date: Mon, 25 May 2026 21:08:50 -0700 Subject: [PATCH 27/30] memory opt update --- C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c | 25 +++++++++++++++++++--- C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c | 26 ++++++++++++++++++++--- C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c | 15 ++++++++++--- C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c | 10 ++++++++- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_ADEMCMC.c | 26 +++++++++++------------ C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c | 18 ++++++++-------- 6 files changed, 88 insertions(+), 32 deletions(-) diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c index 01409565..bdf70311 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c @@ -84,6 +84,15 @@ PARS=calloc(PI.npars*NC,sizeof(double)); pars_new=calloc(PI.npars,sizeof(double)); BESTPARS=calloc(PI.npars*NC,sizeof(double)); BESTP=calloc(NC,sizeof(double)); +double *npar_de=calloc(PI.npars,sizeof(double)); +double *npar1_de=calloc(PI.npars,sizeof(double)); +double *npar2_de=calloc(PI.npars,sizeof(double)); +double *step_de=calloc(PI.npars,sizeof(double)); +double *cpar_ade=calloc(PI.npars,sizeof(double)); +double *rpar_ade=calloc(PI.npars,sizeof(double)); +double *npar_ade=calloc(PI.npars,sizeof(double)); +double *step_ade=calloc(PI.npars,sizeof(double)); +double *gamma_ade=calloc(PI.npars,sizeof(double)); /*All accepted parameters*/ /*This is now the last N parameter vectors * where N is the adaptation frequency*/ @@ -153,7 +162,8 @@ for ( ;N.ITERlr){ + if (withinrange==1 && -P[nn]+gratio>lr){ wrlocal=wrlocal+1; /*Calculate new likelihood*/ P_new=MODEL_LIKELIHOOD(DATA,pars_new);} @@ -243,6 +253,15 @@ free(BESTP); free(PARS); free(pars_new); free(P); +free(npar_de); +free(npar1_de); +free(npar2_de); +free(step_de); +free(cpar_ade); +free(rpar_ade); +free(npar_ade); +free(step_ade); +free(gamma_ade); printf("DEMCMC DONE\n"); diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c index 17138472..9fdef6d8 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c @@ -85,6 +85,17 @@ pars_new=calloc(PI.npars,sizeof(double)); BESTPARS=calloc(PI.npars*NC,sizeof(double)); PARS0=calloc(PI.npars*NC,sizeof(double)); BESTP=calloc(NC,sizeof(double)); +// Initialize memory for STEP_DEMCMC.c +double *npar_de=calloc(PI.npars,sizeof(double)); +double *npar1_de=calloc(PI.npars,sizeof(double)); +double *npar2_de=calloc(PI.npars,sizeof(double)); +double *step_de=calloc(PI.npars,sizeof(double)); +//Intitialize memory for STEP_ADEMCMC.c: +double *cpar_ade=calloc(PI.npars,sizeof(double)); +double *rpar_ade=calloc(PI.npars,sizeof(double)); +double *npar_ade=calloc(PI.npars,sizeof(double)); +double *step_ade=calloc(PI.npars,sizeof(double)); +double *gamma_ade=calloc(PI.npars,sizeof(double)); /*All accepted parameters*/ /*This is now the last N parameter vectors * where N is the adaptation frequency*/ @@ -153,7 +164,7 @@ for (N.ITER=0;N.ITERlr){ + if (withinrange==1 && -P[nn]+gratio>lr){ wrlocal=wrlocal+1; /*Calculate new likelihood*/ P_new=MODEL_LIKELIHOOD(DATA,pars_new);} @@ -233,6 +244,15 @@ free(PARS); free(PARS0); free(pars_new); free(P); +free(npar_de); +free(npar1_de); +free(npar2_de); +free(step_de); +free(cpar_ade); +free(rpar_ade); +free(npar_ade); +free(step_ade); +free(gamma_ade); printf("DEMCMC DONE\n"); diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c index 9ebadfe0..95011eea 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c @@ -140,10 +140,15 @@ if (isinf(P[nn])==-1){ printf("WARNING! P(0)=-inf - MHMCMC may get stuck - if so, please check your initial conditions\n"); }} -// Initialize memory +// Initialize memory for STEP_AFDEMCMC.c double *cpar = calloc(PI.npars, sizeof(double)); double *rpar = calloc(PI.npars, sizeof(double)); double *npar = calloc(PI.npars, sizeof(double)); +// Initialize memory for STEP_DEMCMC.c +double *npar_de=calloc(PI.npars,sizeof(double)); +double *npar1_de=calloc(PI.npars,sizeof(double)); +double *npar2_de=calloc(PI.npars,sizeof(double)); +double *step_de=calloc(PI.npars,sizeof(double)); /*STEP 2 - BEGIN MCMC*/ for ( ;N.ITERlr){ + if (withinrange==1 && -P[nn]+gratio>lr){ wrlocal=wrlocal+1; /*Calculate new likelihood*/ P_new=MODEL_LIKELIHOOD(DATA,pars_new);} @@ -251,6 +256,10 @@ free(P); free(cpar); free(rpar); free(npar); +free(npar_de); +free(npar1_de); +free(npar2_de); +free(step_de); printf("DEMCMC DONE\n"); diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c index 6a46f118..de7b41ea 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c @@ -82,6 +82,10 @@ double *PARS,*pars_new,*BESTPARS; PARS=calloc(PI.npars*NC,sizeof(double)); pars_new=calloc(PI.npars,sizeof(double)); BESTPARS=calloc(PI.npars*NC,sizeof(double)); +double *npar_de=calloc(PI.npars,sizeof(double)); +double *npar1_de=calloc(PI.npars,sizeof(double)); +double *npar2_de=calloc(PI.npars,sizeof(double)); +double *step_de=calloc(PI.npars,sizeof(double)); /*All accepted parameters*/ /*This is now the last N parameter vectors * where N is the adaptation frequency*/ @@ -144,7 +148,7 @@ for (N.ITER=0;N.ITERcomplete=1; free(BESTPARS); free(PARS); free(P); +free(npar_de); +free(npar1_de); +free(npar2_de); +free(step_de); printf("DEMCMC DONE\n"); diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_ADEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_ADEMCMC.c index fd0cb954..4584462a 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_ADEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_ADEMCMC.c @@ -2,7 +2,7 @@ #include #include "../../../math_fun/randn.c" -double STEP_ADEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C,int NC, double *gratio){ +double STEP_ADEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C,int NC, double *gratio, double *cpar, double *rpar, double *npar, double *step, double *gamma){ /*DE_STEP takes a differential evolution style step*/ /*FIXEDPARS*/ @@ -15,15 +15,15 @@ double rn; /*STep 1. Find random sample other than current chain*/ C1=C; -while (C1==C){C1=ceil((double)random()*NC/((double)RAND_MAX))-1;}; +while (C1==C){C1=floor((double)random() * NC / ((double)RAND_MAX + 1.0));} /*Step 2. FInd current chain, reference chain, and step between them*/ /*allocating memory for three normalized parameter vectors*/ -double *cpar=calloc(PI.npars,sizeof(double)); -double *rpar=calloc(PI.npars,sizeof(double)); -double *npar=calloc(PI.npars,sizeof(double)); -double *step=calloc(PI.npars,sizeof(double)); -double *gamma=calloc(PI.npars,sizeof(double)); +// double *cpar=calloc(PI.npars,sizeof(double)); +// double *rpar=calloc(PI.npars,sizeof(double)); +// double *npar=calloc(PI.npars,sizeof(double)); +// double *step=calloc(PI.npars,sizeof(double)); +// double *gamma=calloc(PI.npars,sizeof(double)); /*using "*pars" to store sequential outputs*/ for (n=0;n1){withinlim=0;} + if (npar[n]<0 || npar[n]>1){withinlim=0;} } gratio[0]=0; @@ -138,11 +138,11 @@ printf("gn2c = %4.4f\n",gn2c); } -free(rpar); -free(cpar); -free(npar); -free(step); -free(gamma); +// free(rpar); +// free(cpar); +// free(npar); +// free(step); +// free(gamma); return withinlim; } diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c index f0a65c08..9372fa2d 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c @@ -2,7 +2,7 @@ #include #include "../../../math_fun/randn.c" -int STEP_DEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C,int NC){ +int STEP_DEMCMC(double *PARS, double *pars_new, PARAMETER_INFO PI, int C,int NC, double *npar, double *npar1, double *npar2, double *step){ /*DE_STEP takes a differential evolution style step*/ /*FIXEDPARS*/ @@ -13,10 +13,10 @@ double rn; /*allocating memory for three normalized parameter vectors*/ -double *npar=calloc(PI.npars,sizeof(double)); -double *npar1=calloc(PI.npars,sizeof(double)); -double *npar2=calloc(PI.npars,sizeof(double)); -double *step=calloc(PI.npars,sizeof(double)); +// double *npar=calloc(PI.npars,sizeof(double)); +// double *npar1=calloc(PI.npars,sizeof(double)); +// double *npar2=calloc(PI.npars,sizeof(double)); +// double *step=calloc(PI.npars,sizeof(double)); /*using "*pars" to store sequential outputs*/ for (n=0;n Date: Tue, 26 May 2026 12:09:17 -0700 Subject: [PATCH 28/30] fixed nolikelihoods-- expected cause of mystery error msg in met only run; + a few other cleanups. --- .../MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c | 28 ++++++++++++++----- .../CARDAMOM_READ_BINARY_DATA.c | 10 ++++--- .../CARDAMOM_GENERAL/CARDAMOM_RUN_MODEL.c | 28 ++++++++++++++----- .../DALEC_ALL_LIKELIHOOD.c | 2 +- 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c index 22fd2871..8debe317 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/WRITE_DEMCMC_RESULTS.c @@ -18,13 +18,27 @@ //This scans the string and removes all instances of the string toFind, and replaces them with the single char toReplace. void str_inplace_replace(char * str, const char * toFind, const char toReplace){ - //Yeah this implementation is N^2... but we have a small fixed max N, so don't @ me. - char* substring=str; - while ((substring = strstr(substring, toFind))){ - memmove(substring, substring+1,strlen(substring)); //Memmove needed due to overlapping strings. Move the whole string, with null term - substring[0]=toReplace; //put in the filler char - } - + // 1. Safety checks for null pointers + if (!str || !toFind) return; + + size_t findLen = strlen(toFind); + + // 2. Prevent infinite loops if toFind is an empty string + if (findLen == 0) return; + + char* substring = str; + while ((substring = strstr(substring, toFind))){ + // 3. Move the tail of the string (everything AFTER the found word). + // The +1 ensures we copy the null terminator at the end of the string. + memmove(substring + 1, substring + findLen, strlen(substring + findLen) + 1); + + // 4. Insert the replacement character + substring[0] = toReplace; + + // 5. Advance the pointer by 1 so we don't accidentally match the + // replacement character if it matches part of toFind + substring++; + } } diff --git a/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c b/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c index 2573888d..eac51a71 100644 --- a/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c +++ b/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_BINARY_DATA.c @@ -210,17 +210,19 @@ free(DATA.M_LAI); free(DATA.M_FIR); free(DATA.M_NBE); free(DATA.M_SWE); +free(DATA.M_CWOO); +free(DATA.M_SCF); - - - - +free(DATA.M_EDCs); +free(DATA.M_LIKELIHOODS); free(DATA.M_PARS); free(DATA.M_FLUXES); free(DATA.M_POOLS); free(DATA.M_P); free(DATA.M_EDCD); +free(DATA.EDC_INSTANCE_COUNTER); +free(DATA.EDC_PASS_COUNTER); free(DATA.parmin); free(DATA.parmax); diff --git a/C/projects/CARDAMOM_GENERAL/CARDAMOM_RUN_MODEL.c b/C/projects/CARDAMOM_GENERAL/CARDAMOM_RUN_MODEL.c index ec2eb6fd..c8824225 100644 --- a/C/projects/CARDAMOM_GENERAL/CARDAMOM_RUN_MODEL.c +++ b/C/projects/CARDAMOM_GENERAL/CARDAMOM_RUN_MODEL.c @@ -30,13 +30,27 @@ //This scans the string and removes all instances of the string toFind, and replaces them with the single char toReplace. void str_inplace_replace(char * str, const char * toFind, const char toReplace){ - //Yeah this implementation is N^2... but we have a small fixed max N, so don't @ me. - char* substring=str; - while ((substring = strstr(substring, toFind))){ - memmove(substring, substring+1,strlen(substring)); //Memmove needed due to overlapping strings. Move the whole string, with null term - substring[0]=toReplace; //put in the filler char - } - + // 1. Safety checks for null pointers + if (!str || !toFind) return; + + size_t findLen = strlen(toFind); + + // 2. Prevent infinite loops if toFind is an empty string + if (findLen == 0) return; + + char* substring = str; + while ((substring = strstr(substring, toFind))){ + // 3. Move the tail of the string (everything AFTER the found word). + // The +1 ensures we copy the null terminator at the end of the string. + memmove(substring + 1, substring + findLen, strlen(substring + findLen) + 1); + + // 4. Insert the replacement character + substring[0] = toReplace; + + // 5. Advance the pointer by 1 so we don't accidentally match the + // replacement character if it matches part of toFind + substring++; + } } diff --git a/C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c b/C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c index 783dabd4..11f8bb4d 100644 --- a/C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c +++ b/C/projects/COST_FUNCTION/MODEL_LIKELIHOOD_FUNCTIONS/DALEC_ALL_LIKELIHOOD.c @@ -60,7 +60,7 @@ struct LIKELIHOOD_INDICES{ int DALEC_ALL_LIKELIHOOD_MODCONFIG(LIKELIHOODinfo * LI){ - LI->nolikelihoods=31; + LI->nolikelihoods=32; return 0;} From b69a9bf7edeb71346f2d5ea8ce9919f0b05736ac Mon Sep 17 00:00:00 2001 From: ebilir Date: Thu, 28 May 2026 14:43:40 -0700 Subject: [PATCH 29/30] added longitude to CBF summary --- C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c | 1 + 1 file changed, 1 insertion(+) diff --git a/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c b/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c index b6cd3fc1..77b6646c 100644 --- a/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c +++ b/C/projects/CARDAMOM_GENERAL/CARDAMOM_READ_NETCDF_DATA.c @@ -357,6 +357,7 @@ printf("Done reading all other edc "); DATA->ID=ncdf_read_single_double_var(ncid, "ID" ); DATA->LAT=ncdf_read_single_double_var(ncid, "LAT" ); + DATA->LON=ncdf_read_single_double_var(ncid, "LON" ); //Pre-processing //Ntimesteps From ff1d75c28039fd9ff2846729f3c2423b93a3cadb Mon Sep 17 00:00:00 2001 From: ebilir Date: Sun, 31 May 2026 22:24:43 -0700 Subject: [PATCH 30/30] fix state trajectory implementation --- .../DALEC/DALEC_1100/DALEC_1100.c | 38 ++++++- .../DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c | 29 +++-- .../DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c | 101 +++++++++++------- 3 files changed, 114 insertions(+), 54 deletions(-) diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c index 6dcbe81e..30b36bfe 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_1100/DALEC_1100.c @@ -1363,11 +1363,21 @@ EDCs[E.vcmax_lcma].prerun=true; EDCs[E.state_ranges].prerun=false; static DALEC_EDC_TRAJECTORY_STRUCT EDC_st; - + +// Determine whether to include the snow pool + double maxsnow = 0.0; + for (int i = 0; i < DATA->ncdf_data.TIME_INDEX.length; i++) { + if (DATA->ncdf_data.SNOWFALL.values[i] > maxsnow) { + maxsnow = DATA->ncdf_data.SNOWFALL.values[i]; + } + } + static int edc_pool_indices[14]; static double edc_pool_eqf[14]; EDC_st.pool_indices=edc_pool_indices; EDC_st.pool_eqf=edc_pool_eqf; + +if (maxsnow > 0.0) { // include snow pool if there is snow EDC_st.no_pools_to_check=14; EDC_st.pool_indices[0]=S.C_lab; @@ -1383,12 +1393,32 @@ EDC_st.pool_indices[9]=S.H2O_LY3; EDC_st.pool_indices[10]=S.H2O_SWE; EDC_st.pool_indices[11]=S.E_LY1; EDC_st.pool_indices[12]=S.E_LY2; -EDC_st.pool_indices[13]=S.E_LY3; +EDC_st.pool_indices[13]=S.E_LY3;} + +else {//otherwise do not +EDC_st.no_pools_to_check=13; + +EDC_st.pool_indices[0]=S.C_lab; +EDC_st.pool_indices[1]=S.C_fol; +EDC_st.pool_indices[2]=S.C_roo; +EDC_st.pool_indices[3]=S.C_woo; +EDC_st.pool_indices[4]=S.C_cwd; +EDC_st.pool_indices[5]=S.C_lit; +EDC_st.pool_indices[6]=S.C_som; +EDC_st.pool_indices[7]=S.H2O_LY1; +EDC_st.pool_indices[8]=S.H2O_LY2; +EDC_st.pool_indices[9]=S.H2O_LY3; +//EDC_st.pool_indices[10]=S.H2O_SWE; +EDC_st.pool_indices[10]=S.E_LY1; +EDC_st.pool_indices[11]=S.E_LY2; +EDC_st.pool_indices[12]=S.E_LY3; //EDC_st.pool_indices[12]=S.M_LAI_MAX;``` //EDC_st.pool_indices[13]=S.M_LAI_TEMP; +} - -for (n=0;nncdf_data.EDC_EQF;printf("DATA->ncdf_data.EDC_EQF = %2.2f\n",DATA->ncdf_data.EDC_EQF);} +for (n=0;nncdf_data.EDC_EQF; + printf("DATA->ncdf_data.EDC_EQF = %2.2f\n",DATA->ncdf_data.EDC_EQF);} // EDC_st.pool_eqf[9]=10; // EDC_st.pool_eqf[10]=10; diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c index 623aa496..e7034eb7 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_STATE_RANGES.c @@ -1,6 +1,6 @@ // static int attempt_count[100]; // static int pass_count[100]; - +// static int total_iterations = 0; typedef struct { double * min_val; @@ -19,13 +19,13 @@ double DALEC_EDC_STATE_RANGES(DATA * DATA, void * EDCstruct){ //loop through all timesteps int p=0,k=0; - -while (PEDC==0 & pnopools & k==0 ){ + // total_iterations += 1; +while (PEDC==0 && pnopools && k==0 ){ //looping through timesteps int n=0; - //attempt_count[p]+=1; + // attempt_count[p]+=1; -while (PEDC==0 & nncdf_data.TIME_INDEX.length & k==0){ +while (PEDC==0 && nncdf_data.TIME_INDEX.length && k==0){ @@ -35,17 +35,24 @@ while (PEDC==0 & nncdf_data.TIME_INDEX.length & k==0){ //if (p == 18){printf("E.max_val[p] = %2.2f, E.min_val[p] = %2.2f, SM = %2.2f\n",E.max_val[p], E.min_val[p],DATA->M_POOLS[p+n*DATA->nopools]);} n+=1;} - //if(k==0){pass_count[p]+=1;} + // if(k==0){pass_count[p]+=1;} p+=1; } -// if (k==0){ -// for (p=0;pnopools;p++){ -// printf("pool %i; Attempt = %i, Pass = %i, Percent = %2.2f\%\n",p,attempt_count[p], pass_count[p], 100*(double)pass_count[p]/(double)attempt_count[p]); -// }} - //printf("Fail check = %2.2i\n",p); + // if (total_iterations % 50000 == 0){ + // printf("\n--- Cumulative Stats at Iteration %i ---\n", total_iterations); + + // // Changed loop variable to 'i' so it doesn't overwrite 'p' (which you use below for Fail check) + // for (int i = 0; i < DATA->nopools; i++){ + // // FIXED: Prevent divide-by-zero if a pool hasn't been attempted yet + // double percent = (attempt_count[i] == 0) ? 0.0 : 100 * (double)pass_count[i] / (double)attempt_count[i]; + + // printf("pool %i; Attempt = %i, Pass = %i, Percent = %2.2f%%\n", i, attempt_count[i], pass_count[i], percent); + // } + // } + // printf("Fail check = %2.2i\n",p-1); diff --git a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c index 1eb0f217..0f1ec864 100644 --- a/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c +++ b/C/projects/CARDAMOM_MODELS/DALEC/DALEC_EDCs/DALEC_EDC_TRAJECTORY.c @@ -7,11 +7,18 @@ #include "../../../../math_fun/ipow.c" #include "stdlib.h" #include "stdio.h" +#include +#include //***************General inequality EDC****************** //***************DALEC_EDC_PARS_INEQUALITY********* - +// static int traj_attempt_count[100] = {0}; +// static int traj_pass_count[100] = {0}; +// static int fin_zero_count[100] = {0}; +// static int fin_neg_count[100] = {0}; +// static int fout_zero_count[100] = {0}; +// static int fout_neg_count[100] = {0}; @@ -56,12 +63,18 @@ PEDC=0; double * FLUXES = DATA->M_FLUXES; double * POOLS = DATA->M_POOLS; -double *FT; -FT=calloc(nofluxes,sizeof(double)); +// double *FT; +// FT=calloc(nofluxes,sizeof(double)); + +// 1. Declare the Variable Length Array +double FT[nofluxes]; + +// 2. Zero it out using memset (requires #include at the top of your file) +memset(FT, 0, nofluxes * sizeof(double)); int f=0; for (f=0;fM_POOLS,p,N_timesteps+1,nopools); + // double MPOOLS=mean_pool(DATA->M_POOLS,p,N_timesteps+1,nopools); /*deriving mean January pools*/ /*Assuming COMPLETE years*/ @@ -88,22 +102,23 @@ for (s=0;sSIOMATRIX[p].N_STATE_INPUT_FLUXES;i++){ - double Ftemp = FT[DALECmodel->SIOMATRIX[p].STATE_INPUT_FLUXES[i]]; - if (Ftemp<0){Fout +=Ftemp;} //if any N_STATE_INPUT_FLUXES are negative, put them in Fout + Ftemp = FT[DALECmodel->SIOMATRIX[p].STATE_INPUT_FLUXES[i]]; + if (Ftemp<0){Fout -=Ftemp;} //if any N_STATE_INPUT_FLUXES are negative, put them in Fout else {Fin += Ftemp;}} for (i=0;iSIOMATRIX[p].N_STATE_OUTPUT_FLUXES;i++){ - double Ftemp= FT[DALECmodel->SIOMATRIX[p].STATE_OUTPUT_FLUXES[i]]; - if (Ftemp<0){Fin +=Ftemp;} //if any N_STATE_OUTPUT_FLUXES are negative, put them in Fin + Ftemp= FT[DALECmodel->SIOMATRIX[p].STATE_OUTPUT_FLUXES[i]]; + if (Ftemp<0){Fin -=Ftemp;} //if any N_STATE_OUTPUT_FLUXES are negative, put them in Fin else {Fout += Ftemp;}} // // double Fin[10]; @@ -137,34 +152,42 @@ for (s=0;snopools; j++) { +// if (traj_attempt_count[j] > 0) { +// double percent = (100.0 * (double)traj_pass_count[j] / (double)traj_attempt_count[j]); +// int total_fails = traj_attempt_count[j] - traj_pass_count[j]; + +// printf("pool %2i; Att = %6i, Pass = %6i (%5.2f%%) | Fails: %6i [Fin=0: %6i, Fin<0: %6i | Fout=0: %6i, Fout<0: %6i]\n", +// j, traj_attempt_count[j], traj_pass_count[j], percent, +// total_fails, fin_zero_count[j], fin_neg_count[j], fout_zero_count[j], fout_neg_count[j]); +// } +// } +// fflush(stdout); +// } + return PEDC; } \ No newline at end of file