From 6b9116304631bbd70b972c7cbb9fb4d7011608a9 Mon Sep 17 00:00:00 2001 From: "Kalyn R. Dorheim" Date: Wed, 17 Jul 2024 21:51:56 -0400 Subject: [PATCH] Alpha and Volscl impact RF output (#745) Here we change where the scalers are applied so that the vol, aerosol, and total forcing outputs are updated appropriately. While this PR does not change hector output or behavior between the parameter name change, there are code-breaking changes that have been made to the ini files. The ini files are not backward compatible. --------- Co-authored-by: ptrscll --- data-raw/input_params.csv | 4 +- data/inputstable.rda | Bin 4097 -> 4090 bytes data/unitstable.rda | Bin 964 -> 963 bytes inst/include/component_data.hpp | 4 +- inst/include/forcing_component.hpp | 5 +- inst/include/temperature_component.hpp | 2 - inst/input/hector_ssp119.ini | 4 +- inst/input/hector_ssp126.ini | 4 +- inst/input/hector_ssp245.ini | 4 +- inst/input/hector_ssp370.ini | 4 +- inst/input/hector_ssp434.ini | 4 +- inst/input/hector_ssp460.ini | 4 +- inst/input/hector_ssp534-over.ini | 4 +- inst/input/hector_ssp585.ini | 4 +- .../Xcode/hector.xcodeproj/project.pbxproj | 10 +-- src/carbon-cycle-model-74dba680.o.tmp | 0 src/forcing_component.cpp | 33 +++++++-- src/temperature_component.cpp | 49 +------------ tests/testthat/input/luc_pulse.ini | 4 +- tests/testthat/test_parameters.R | 67 +++++++++++++++--- 20 files changed, 118 insertions(+), 92 deletions(-) create mode 100644 src/carbon-cycle-model-74dba680.o.tmp diff --git a/data-raw/input_params.csv b/data-raw/input_params.csv index 798c5e02e..26bfd6354 100644 --- a/data-raw/input_params.csv +++ b/data-raw/input_params.csv @@ -100,10 +100,10 @@ forcing,rho_so2,n,n,y,-7.24E-06,W yr m-2 S Gg-1,IPCC AR6 radiative efficiency SO forcing,rho_nh3,n,n,y,-0.00208,W yr m-2 NH3 Tg-1,IPCC AR6 radiative efficiency NH3 (7.SM.1.3.1 of IPCC AR6) forcing,RF_misc,n,n,n,"""(csv)""",,Miscellaneous radiative forcings default set to 0 forcing,RF_misc,n,n,y,0,,"Miscellaneous radiative forcings default set to 0, or read in from a input table, may be used to read in additional forcings not modeled by Hector (i.e. solar, bc on snow , contrails from)" +forcing,aero_scalar,n,n,y,1,(unitless),scaling factor for aerosol forcing +forcing,vol_scalar,n,n,y,1,(unitless),scaling factor for volcanic forcing temperature,S,n,n,y,3,degC,equilibrium climate sensitivity for 2xCO2 temperature,diff,n,n,y,2.3,cm2 s-1,ocean heat diffusivity -temperature,alpha,n,n,y,1,(unitless),scaling factor for aerosol forcing -temperature,volscl,n,n,y,1,(unitless),scaling factor for volcanic forcing temperature,qco2,n,n,y,3.75,,CO2 RF (7.3.2 of IPCC AR6) temperature,tas_constrain,n,y,n,"""(csv)""",,"Optional global temperature constraint; If supplied, the model will use these data, ignoring what it calculates" bc,BC_emissions,n,y,y,"""(csv)""",, diff --git a/data/inputstable.rda b/data/inputstable.rda index 5c844f6675a0b4e2d9136bd80166ea021d487b90..8d51f4d553c1534d8d42cead8f1d3cce45484908 100644 GIT binary patch literal 4090 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 literal 4097 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 diff --git a/data/unitstable.rda b/data/unitstable.rda index 67ee825ddc4c27299ad6cf46af042e6e8d36d64b..9039257a803689139a258c583759500b273331bd 100644 GIT binary patch delta 951 zcmV;o14#VD2g3&rLRx4!F+o`-Q&}%FYFUvE9Dhz_&D@-v6ojUd8Y4!UBWRwKHlrYI zLm=8UGbr^mJx0{f8B9c;De9h6Luvp300001pa5p1qf=@FBlQzcPyhe`00Te`1B{t8 zF&LUK2*6Ar32m~oM_3pV1=maQ(cLnL7tAd#TpB}%UkGir&oZTO9?#?p7X``CvugnLFNiOyV z-}9btetK3o8@s=GFj5K^+Neui5U9yV7t0OlBf~(ey@duSxqUD<1k?1!5#80*W%yTR z4J0nBGOX?0g)=fD?KZAcgG^Yk5$!^)SbqQj6s)O8008$O0000mq5usPsv1eHHk(Nh zh_WG6kU)tjWdbUP<`D~_5PWdDfZrj47$EYZ7NQt>tPju{0$t?qRTIBMsmZLVJM>Z} zfG#nrA;X3=hUgQjKW9*9Bbn(ZM%WPZ5(JBi7nC$2QhcDy%+ohERr)gl3=GN~1b+x5 z6;)nX3WuxT0)W(9P{5{i&U2ltsfdWNq-6XsRPz{gk{wnEojjz5wh$JP9U?+TvC&%t zxV8z)fy)uuRrsi#T&+^~J8zwl{0d0w#eIK#3w~ghC{# zz*BiLg>7C3o$ykVSE#b=q^iozqkn7I_qy?4YQr0CHr;Qt!xu3qQXKoU&U3Rd$)m%r zK=0$(Y>@2NquDexI+=87g!D{yxULJ+e_tlAm6g&j7gm;1lvu@5r&yOF@mdE+Vkzyu zlfF2v)}pLjW$y38y^z2X%*?8)#9J6!fy9#V>5Xo30_rL@Y`jq<)aQBf+JBN%$CD{& zS(_wI;zD8q^A2lF%-HhOe0=z79O$-IN4a*8AUqOz7}Cl%>$5WOFn6}&PNx|PxrGa@ z(R{v$S;ORQ(UOb0cWyz3A|sFpSz$N}V<~4*5JVIP%cYYq4rN=79hOIw0{fTz^%)U@S(88tAz?T{4$^;Vxg|2K%>Q`U92w?f;HVw z6ws_ttya8Pmw#yG5$Ds8sA08BXZ4SwcRXMOb3X<9gs{1(Dharpd}@l%79`OU1Sv!+ z%bNK>p&Kc+5TsDH#ae2eRYrANF&)}3bV}qyj<5np%%Z^>uC(h!H6ZuuCA%|>H!0{5 Z#~xYcw!y#E?*|wBUC9*TLO{IDsbtlbvBCfV delta 952 zcmV;p14sPB2gC;sLRx4!F+o`-Q(30J(5;aU9DlQ%XJ=^qXlX=|DXvqztA;qeVYd@|bF927mwnXaE@ofHd_bA>|qxAE`Y|jRB)Z z5HSW5Kn8{f88T>MF*INifS5oS38sxQGy@2flO)2P6!A|}#F`#akZ1rh0MY6L$rN!* zxqm9ZQh|mX5m67k1t9?n&TgIekwdY^G+hEoUX`Gd52tqF3tZ#~_J1wmrm`bzxw}VR zB?&QnF^~=}$=j0-oSk{%e_xBqUN9W`jcV4SwT#H;bX$|=vLV@0wBRmGgC)cRb*Jf> zaA2}aU6U8AT~fTpXIn<|ywdB@mrhrbK!1O&6*_PL04PvUfB*sZH~;_uYCC`%oJ`D_ zSY*tSLo!Uzf~6!0njn=$RYPnbcIYzDehM7@6BHP4WeQnNuFt+BoDLni3;gY4X{NGjTio7ZWEkq-2uJ zC|pj|-nXz&sZheG zPG3AdAUixNB7_^v0_T$tC(_#^l8XgBhOz-eB?NQ3pi<$1;V1|3b97x1(MF diff --git a/inst/include/component_data.hpp b/inst/include/component_data.hpp index afa24bc02..de2a9efc4 100644 --- a/inst/include/component_data.hpp +++ b/inst/include/component_data.hpp @@ -65,6 +65,8 @@ #define D_RHO_OC "rho_oc" // BC radiative efficiency #define D_RHO_SO2 "rho_so2" // SO2 radiative efficiency #define D_RHO_NH3 "rho_nh3" // NH3 radiative efficiency +#define D_AERO_SCALE "aero_scalar" +#define D_VOLCANIC_SCALE "vol_scalar" // halocarbon components #define D_RF_CF4 D_RF_PREFIX CF4_COMPONENT_BASE @@ -397,8 +399,6 @@ #define D_GMST "gmst" #define D_LO_WARMING_RATIO "lo_warming_ratio" #define D_DIFFUSIVITY "diff" -#define D_AERO_SCALE "alpha" -#define D_VOLCANIC_SCALE "volscl" #define D_FLUX_MIXED "heatflux_mixed" #define D_FLUX_INTERIOR "heatflux_interior" #define D_HEAT_FLUX "heatflux" diff --git a/inst/include/forcing_component.hpp b/inst/include/forcing_component.hpp index be920c26d..ea21395c9 100644 --- a/inst/include/forcing_component.hpp +++ b/inst/include/forcing_component.hpp @@ -118,7 +118,10 @@ class ForcingComponent : public IModelComponent { unitval rho_nh3; // (W yr m–2 Tg–1) IPCC AR6 radiative efficiency SO2 7.SM.1.3.1 - // Aerosol parameters for aerosol-cloud interactions (RFaci) see equation + // Aerosol parameters + unitval alpha; // aerosol forcing factor, unitless + unitval volscl; // volcanic forcing scaling factor, unitless + // Parameters for aerosol-cloud interactions (RFaci) see equation // Equation 7.SM.1.2 of IPCC AR6 double const aci_beta = 2.279759; // Dorheim et al. 2024 double const s_BCOC = 111.05064063; // (Tg C yr-1) IPCC AR6 7.SM.1.3.1 diff --git a/inst/include/temperature_component.hpp b/inst/include/temperature_component.hpp index eeba1f1f2..df6d29946 100644 --- a/inst/include/temperature_component.hpp +++ b/inst/include/temperature_component.hpp @@ -145,8 +145,6 @@ class TemperatureComponent : public IModelComponent { // Model parameters unitval S; //!< climate sensitivity for 2xCO2, deg C unitval diff; //!< ocean heat diffusivity, cm2/s - unitval alpha; //!< aerosol forcing factor, unitless - unitval volscl; //!< volcanic forcing scaling factor, unitless // Model outputs unitval tas; //!< global average air temperature anomaly, deg C diff --git a/inst/input/hector_ssp119.ini b/inst/input/hector_ssp119.ini index 5f28e33a1..2702b101a 100644 --- a/inst/input/hector_ssp119.ini +++ b/inst/input/hector_ssp119.ini @@ -162,6 +162,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; (unitless) uncertainty scaling factor for volcanic forcing +vol_scalar=1.0 ; (unitless) uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -179,8 +181,6 @@ RF_misc[1750]=0 [temperature] S=3.0 ; equilibrium climate sensitivity for 2xCO2 degC (A.4.4 of IPCC AR6) diff=2.38 ; ocean heat diffusivity, cm2/s calibrated to historical observations Dorheim et al. 2024 for details -alpha=1.0 ; uncertainty scaling factor for aerosol forcing -volscl=1.0 ; uncertainty scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/inst/input/hector_ssp126.ini b/inst/input/hector_ssp126.ini index 5482e89e9..07fab5e48 100644 --- a/inst/input/hector_ssp126.ini +++ b/inst/input/hector_ssp126.ini @@ -162,6 +162,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; uncertainty scaling factor for aerosol forcing +vol_scalar=1.0 ; uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -179,8 +181,6 @@ RF_misc[1750]=0 [temperature] S=3.0 ; equilibrium climate sensitivity for 2xCO2 degC (A.4.4 of IPCC AR6) diff=2.38 ; ocean heat diffusivity, cm2/s calibrated to historical observations Dorheim et al. 2024 for details -alpha=1.0 ; uncertainty scaling factor for aerosol forcing -volscl=1.0 ; uncertainty scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/inst/input/hector_ssp245.ini b/inst/input/hector_ssp245.ini index d1eaf2b37..d0812152d 100644 --- a/inst/input/hector_ssp245.ini +++ b/inst/input/hector_ssp245.ini @@ -162,6 +162,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; (unitless) uncertainty scaling factor for volcanic forcing +vol_scalar=1.0 ; (unitless) uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -179,8 +181,6 @@ RF_misc[1750]=0 [temperature] S=3.0 ; equilibrium climate sensitivity for 2xCO2 degC (A.4.4 of IPCC AR6) diff=2.38 ; ocean heat diffusivity, cm2/s calibrated to historical observations Dorheim et al. 2024 for details -alpha=1.0 ; uncertainty scaling factor for aerosol forcing -volscl=1.0 ; uncertainty scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/inst/input/hector_ssp370.ini b/inst/input/hector_ssp370.ini index 58a13243b..c452bf24e 100644 --- a/inst/input/hector_ssp370.ini +++ b/inst/input/hector_ssp370.ini @@ -162,6 +162,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; uncertainty scaling factor for aerosol forcing +vol_scalar=1.0 ; uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -179,8 +181,6 @@ RF_misc[1750]=0 [temperature] S=3.0 ; equilibrium climate sensitivity for 2xCO2 degC (A.4.4 of IPCC AR6) diff=2.38 ; ocean heat diffusivity, cm2/s calibrated to historical observations Dorheim et al. 2024 for details -alpha=1.0 ; uncertainty scaling factor for aerosol forcing -volscl=1.0 ; uncertainty scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/inst/input/hector_ssp434.ini b/inst/input/hector_ssp434.ini index 217ab12ad..e0c47e36a 100644 --- a/inst/input/hector_ssp434.ini +++ b/inst/input/hector_ssp434.ini @@ -162,6 +162,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; uncertainty scaling factor for aerosol forcing +vol_scalar=1.0 ; uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -179,8 +181,6 @@ RF_misc[1750]=0 [temperature] S=3.0 ; equilibrium climate sensitivity for 2xCO2 degC (A.4.4 of IPCC AR6) diff=2.38 ; ocean heat diffusivity, cm2/s calibrated to historical observations Dorheim et al. 2024 for details -alpha=1.0 ; uncertainty scaling factor for aerosol forcing -volscl=1.0 ; uncertainty scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/inst/input/hector_ssp460.ini b/inst/input/hector_ssp460.ini index 50f4e2c7d..bdc8de847 100644 --- a/inst/input/hector_ssp460.ini +++ b/inst/input/hector_ssp460.ini @@ -162,6 +162,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; uncertainty scaling factor for aerosol forcing +vol_scalar=1.0 ; uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -179,8 +181,6 @@ RF_misc[1750]=0 [temperature] S=3.0 ; equilibrium climate sensitivity for 2xCO2 degC (A.4.4 of IPCC AR6) diff=2.38 ; ocean heat diffusivity, cm2/s calibrated to historical observations Dorheim et al. 2024 for details -alpha=1.0 ; uncertainty scaling factor for aerosol forcing -volscl=1.0 ; uncertainty scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/inst/input/hector_ssp534-over.ini b/inst/input/hector_ssp534-over.ini index 8c97b0d23..2729f1738 100644 --- a/inst/input/hector_ssp534-over.ini +++ b/inst/input/hector_ssp534-over.ini @@ -162,6 +162,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; uncertainty scaling factor for aerosol forcing +vol_scalar=1.0 ; uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -179,8 +181,6 @@ RF_misc[1750]=0 [temperature] S=3.0 ; equilibrium climate sensitivity for 2xCO2 degC (A.4.4 of IPCC AR6) diff=2.38 ; ocean heat diffusivity, cm2/s calibrated to historical observations Dorheim et al. 2024 for details -alpha=1.0 ; uncertainty scaling factor for aerosol forcing -volscl=1.0 ; uncertainty scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/inst/input/hector_ssp585.ini b/inst/input/hector_ssp585.ini index d41fbe7d6..3f70504f9 100644 --- a/inst/input/hector_ssp585.ini +++ b/inst/input/hector_ssp585.ini @@ -162,6 +162,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; uncertainty scaling factor for aerosol forcing +vol_scalar=1.0 ; uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -179,8 +181,6 @@ RF_misc[1750]=0 [temperature] S=3.0 ; equilibrium climate sensitivity for 2xCO2 degC (A.4.4 of IPCC AR6) diff=2.38 ; ocean heat diffusivity, cm2/s calibrated to historical observations Dorheim et al. 2024 for details -alpha=1.0 ; uncertainty scaling factor for aerosol forcing -volscl=1.0 ; uncertainty scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/project_files/Xcode/hector.xcodeproj/project.pbxproj b/project_files/Xcode/hector.xcodeproj/project.pbxproj index 7324eb645..dfb4d11b3 100644 --- a/project_files/Xcode/hector.xcodeproj/project.pbxproj +++ b/project_files/Xcode/hector.xcodeproj/project.pbxproj @@ -82,9 +82,9 @@ 27B2C270261511C8005DE26D /* spline_forsythe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27B2C24D261511C8005DE26D /* spline_forsythe.cpp */; }; 27B2C271261511C8005DE26D /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27B2C24E261511C8005DE26D /* main.cpp */; }; 27F2613726B55617004BDD47 /* csv_tracking_visitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27962904268F237200333AA3 /* csv_tracking_visitor.cpp */; }; - 354045FC2913D50A00CA297D /* test_dependency_finder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 273FC38F26A3570B00D5303E /* test_dependency_finder.cpp */; }; - 354045FB2913CF6600CA297D /* test_csv_file_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 273FC39126A3570B00D5303E /* test_csv_file_reader.cpp */; }; 354045FA2913C0F300CA297D /* test_core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 273FC38D26A3570B00D5303E /* test_core.cpp */; }; + 354045FB2913CF6600CA297D /* test_csv_file_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 273FC39126A3570B00D5303E /* test_csv_file_reader.cpp */; }; + 354045FC2913D50A00CA297D /* test_dependency_finder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 273FC38F26A3570B00D5303E /* test_dependency_finder.cpp */; }; 35ACB833285E4F4E0025928F /* h_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 275CBFF127AC7CC0009E2AF5 /* h_util.cpp */; }; 954D62AE278E005500840656 /* nh3_component.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 954D62AD278E005500840656 /* nh3_component.cpp */; }; 954D62AF278E005500840656 /* nh3_component.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 954D62AD278E005500840656 /* nh3_component.cpp */; }; @@ -607,7 +607,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = "${BOOSTROOT}"; + HEADER_SEARCH_PATHS = "${BOOSTINC}"; "HEADER_SEARCH_PATHS[arch=*]" = "${BOOSTROOT}"; LIBRARY_SEARCH_PATHS = "${BOOSTLIB}"; MACOSX_DEPLOYMENT_TARGET = 10.15; @@ -664,7 +664,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = "${BOOSTROOT}"; + HEADER_SEARCH_PATHS = "${BOOSTINC}"; LIBRARY_SEARCH_PATHS = "${BOOSTLIB}"; MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; @@ -681,6 +681,7 @@ buildSettings = { CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; + HEADER_SEARCH_PATHS = "${BOOSTINC}"; LIBRARY_SEARCH_PATHS = "${BOOSTLIB}"; "OTHER_LDFLAGS[arch=*]" = "$(inherited)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -692,6 +693,7 @@ buildSettings = { CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; + HEADER_SEARCH_PATHS = "${BOOSTINC}"; LIBRARY_SEARCH_PATHS = "${BOOSTLIB}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; diff --git a/src/carbon-cycle-model-74dba680.o.tmp b/src/carbon-cycle-model-74dba680.o.tmp new file mode 100644 index 000000000..e69de29bb diff --git a/src/forcing_component.cpp b/src/forcing_component.cpp index 203a805e4..d90334729 100644 --- a/src/forcing_component.cpp +++ b/src/forcing_component.cpp @@ -132,6 +132,9 @@ void ForcingComponent::init(Core *coreptr) { core->registerCapability(D_RHO_SO2, getComponentName()); core->registerCapability(D_RF_SO2, getComponentName()); core->registerCapability(D_RF_ACI, getComponentName()); + core->registerCapability(D_AERO_SCALE, getComponentName()); + core->registerCapability(D_VOLCANIC_SCALE, getComponentName()); + for (int i = 0; i < N_HALO_FORCINGS; ++i) { core->registerCapability(adjusted_halo_forcings[i], getComponentName()); forcing_name_map[adjusted_halo_forcings[i]] = halo_forcing_names[i]; @@ -183,6 +186,9 @@ void ForcingComponent::init(Core *coreptr) { core->registerInput(D_RHO_NH3, getComponentName()); core->registerInput(D_RF_MISC, getComponentName()); core->registerInput(D_FTOT_CONSTRAIN, getComponentName()); + core->registerInput(D_AERO_SCALE, getComponentName()); + core->registerInput(D_VOLCANIC_SCALE, getComponentName()); + } //------------------------------------------------------------------------------ @@ -237,6 +243,12 @@ void ForcingComponent::setData(const string &varName, } else if (varName == D_RHO_SO2) { H_ASSERT(data.date == Core::undefinedIndex(), "date not allowed"); rho_so2 = data.getUnitval(U_W_M2_GG); + } else if (varName == D_AERO_SCALE) { + H_ASSERT(data.date == Core::undefinedIndex(), "date not allowed"); + alpha = data.getUnitval(U_UNITLESS); + } else if (varName == D_VOLCANIC_SCALE) { + H_ASSERT(data.date == Core::undefinedIndex(), "date not allowed"); + volscl = data.getUnitval(U_UNITLESS); } else if (varName == D_FTOT_CONSTRAIN) { H_ASSERT(data.date != Core::undefinedIndex(), "date required"); Ftot_constrain.set(data.date, data.getUnitval(U_W_M2)); @@ -422,35 +434,37 @@ void ForcingComponent::run(const double runToDate) { double E_BC = core->sendMessage(M_GETDATA, D_EMISSIONS_BC, message_data(runToDate)) .value(U_TG); - double fbc = rho_bc * E_BC; + double fbc = alpha.value(U_UNITLESS) * rho_bc * E_BC; forcings[D_RF_BC].set(fbc, U_W_M2); // ---------- Organic carbon ---------- double E_OC = core->sendMessage(M_GETDATA, D_EMISSIONS_OC, message_data(runToDate)) .value(U_TG); - double foc = rho_oc * E_OC; + double foc = alpha.value(U_UNITLESS) * rho_oc * E_OC; forcings[D_RF_OC].set(foc, U_W_M2); // ---------- Sulphate Aerosols ---------- unitval SO2_emission = core->sendMessage(M_GETDATA, D_EMISSIONS_SO2, message_data(runToDate)); - double fso2 = rho_so2 * SO2_emission.value(U_GG_S); + double fso2 = alpha.value(U_UNITLESS) * rho_so2 * SO2_emission.value(U_GG_S); forcings[D_RF_SO2].set(fso2, U_W_M2); // ---------- NH3 ---------- double E_NH3 = core->sendMessage(M_GETDATA, D_EMISSIONS_NH3, message_data(runToDate)) .value(U_TG); - double fnh3 = rho_nh3 * E_NH3; + double fnh3 = alpha.value(U_UNITLESS) * rho_nh3 * E_NH3; forcings[D_RF_NH3].set(fnh3, U_W_M2); // ---------- RFaci ---------- // ERF from aerosol-cloud interactions (RFaci) // Based on Equation 7.SM.1.2 from IPCC AR6 where - double aci_rf = - -1 * aci_beta * - log(1 + (SO2_emission / s_SO2) + ((E_BC + E_OC) / s_BCOC)); + // The 0.2 value comes from equally distributing the alpha scalar to all 5 + // aerosol RF types. + double aci_rf = + alpha.value(U_UNITLESS) * (-1 * aci_beta * + log(1 + (SO2_emission / s_SO2) + ((E_BC + E_OC) / s_BCOC))); forcings[D_RF_ACI].set(aci_rf, U_W_M2); } @@ -464,6 +478,7 @@ void ForcingComponent::run(const double runToDate) { if (core->checkCapability(D_VOLCANIC_SO2)) { // The volcanic forcings are read in from an ini file. forcings[D_RF_VOL] = + volscl.value(U_UNITLESS) * core->sendMessage(M_GETDATA, D_VOLCANIC_SO2, message_data(runToDate)); } @@ -540,6 +555,10 @@ unitval ForcingComponent::getData(const std::string &varName, returnval = rho_so2; } else if (varName == D_RHO_NH3) { returnval = rho_nh3; + } else if (varName == D_AERO_SCALE) { + returnval = alpha; + } else if (varName == D_VOLCANIC_SCALE) { + returnval = volscl; } else if (varName == D_RF_BASEYEAR) { returnval.set(baseyear, U_UNITLESS); } else { diff --git a/src/temperature_component.cpp b/src/temperature_component.cpp index 790d7ae10..566d300ca 100644 --- a/src/temperature_component.cpp +++ b/src/temperature_component.cpp @@ -126,19 +126,11 @@ void TemperatureComponent::init(Core *coreptr) { // Register our dependencies core->registerDependency(D_RF_TOTAL, getComponentName()); - core->registerDependency(D_RF_BC, getComponentName()); - core->registerDependency(D_RF_OC, getComponentName()); - core->registerDependency(D_RF_NH3, getComponentName()); - core->registerDependency(D_RF_SO2, getComponentName()); - core->registerDependency(D_RF_ACI, getComponentName()); - core->registerDependency(D_RF_VOL, getComponentName()); // Register the inputs we can receive from outside core->registerInput(D_ECS, getComponentName()); core->registerInput(D_QCO2, getComponentName()); core->registerInput(D_DIFFUSIVITY, getComponentName()); - core->registerInput(D_AERO_SCALE, getComponentName()); - core->registerInput(D_VOLCANIC_SCALE, getComponentName()); core->registerInput(D_LO_WARMING_RATIO, getComponentName()); core->registerInput(D_TAS_CONSTRAIN, getComponentName()); } @@ -177,12 +169,6 @@ void TemperatureComponent::setData(const string &varName, } else if (varName == D_DIFFUSIVITY) { H_ASSERT(data.date == Core::undefinedIndex(), "date not allowed"); diff = data.getUnitval(U_CM2_S); - } else if (varName == D_AERO_SCALE) { - H_ASSERT(data.date == Core::undefinedIndex(), "date not allowed"); - alpha = data.getUnitval(U_UNITLESS); - } else if (varName == D_VOLCANIC_SCALE) { - H_ASSERT(data.date == Core::undefinedIndex(), "date not allowed"); - volscl = data.getUnitval(U_UNITLESS); } else if (varName == D_QCO2) { H_ASSERT(data.date == Core::undefinedIndex(), "date not allowed"); qco2 = data.getUnitval(U_UNITLESS).value(U_UNITLESS); @@ -447,32 +433,9 @@ void TemperatureComponent::run(const double runToDate) { // Some needed inputs int tstep = runToDate - core->getStartDate(); + forcing[tstep] = core->sendMessage(M_GETDATA, D_RF_TOTAL, message_data(runToDate)).value(U_W_M2); + - // Calculate the total aresol forcing from aerosol-radiation interactions and - // the aerosol-cloud interactions so that that total aerosol forcing can be - // adjusted by the aerosol forcing scaling factor. - double aero_forcing = - core->sendMessage(M_GETDATA, D_RF_BC, message_data(runToDate)) - .value(U_W_M2) + - core->sendMessage(M_GETDATA, D_RF_OC, message_data(runToDate)) - .value(U_W_M2) + - core->sendMessage(M_GETDATA, D_RF_NH3, message_data(runToDate)) - .value(U_W_M2) + - core->sendMessage(M_GETDATA, D_RF_SO2, message_data(runToDate)) - .value(U_W_M2) + - core->sendMessage(M_GETDATA, D_RF_ACI, message_data(runToDate)) - .value(U_W_M2); - - double volcanic_forcing = - double(core->sendMessage(M_GETDATA, D_RF_VOL, message_data(runToDate))); - - // Adjust total forcing to account for the aerosol and volcanic forcing - // scaling factor - const double ftot = core->sendMessage(M_GETDATA, D_RF_TOTAL, message_data(runToDate)).value(U_W_M2); - forcing[tstep] = - double(ftot) - - (1.0 - alpha) * aero_forcing - (1.0 - volscl) * volcanic_forcing; - // Initialize variables for time-stepping through the model double DQ1 = 0.0; double DQ2 = 0.0; @@ -695,17 +658,9 @@ unitval TemperatureComponent::getData(const std::string &varName, H_ASSERT(date == Core::undefinedIndex(), "Date not allowed for diffusivity"); returnval = diff; - } else if (varName == D_AERO_SCALE) { - H_ASSERT(date == Core::undefinedIndex(), - "Date not allowed for aero scaler"); - returnval = alpha; } else if (varName == D_ECS) { H_ASSERT(date == Core::undefinedIndex(), "Date not allowed for ECS"); returnval = S; - } else if (varName == D_VOLCANIC_SCALE) { - H_ASSERT(date == Core::undefinedIndex(), - "Date not allowed for volcanic scaler"); - returnval = volscl; } else if (varName == D_QCO2) { H_ASSERT(date == Core::undefinedIndex(), "Date not allowed for q2co2"); returnval = unitval(qco2, U_W_M2); diff --git a/tests/testthat/input/luc_pulse.ini b/tests/testthat/input/luc_pulse.ini index 98a3c2e45..18a7fad39 100644 --- a/tests/testthat/input/luc_pulse.ini +++ b/tests/testthat/input/luc_pulse.ini @@ -143,6 +143,8 @@ baseyear=1750 ; when to start reporting; by definition, all F=0 in this year ; Optional radiative forcing constraint ; If supplied, the model will use these data, ignoring what it calculates ;RF_tot_constrain=csv:tables/CONSTRAINT.csv +aero_scalar=1.0 ; uncertainty scaling factor for aerosol forcing +vol_scalar=1.0 ; uncertainty scaling factor for volcanic forcing delta_co2=0.05 ; (unitless) forcing tropospheric adjustments for CO2 (7.3.2.1 of IPCC AR6) delta_ch4=-.14 ; (unitless) forcing tropospheric adjustments for CH4 (7.3.2.2 of IPCC AR6) delta_n2o=0.07 ; (unitless) forcing tropospheric adjustments for N2O (7.3.2.3 of IPCC AR6) @@ -164,8 +166,6 @@ enabled=1 S=2.7 ; equilibrium climate sensitivity for 2xCO2, degC (calibrated to historical) diff=2.4 ; ocean heat diffusivity, cm2/s (calibrated to historical) -alpha=0.5 ; scaling factor for aerosol forcing, calibrated to historical observations -volscl=1.0 ; scaling factor for volcanic forcing qco2=3.75 ; 2×CO2 RF (7.3.2 of IPCC AR6) ; Optional global temperature constraint diff --git a/tests/testthat/test_parameters.R b/tests/testthat/test_parameters.R index 9282fa6ad..a5dba56be 100644 --- a/tests/testthat/test_parameters.R +++ b/tests/testthat/test_parameters.R @@ -6,6 +6,11 @@ sampledir <- system.file("output", package = "hector") testvars <- c(CONCENTRATIONS_CO2(), RF_TOTAL(), GLOBAL_TAS()) dates <- 1750:2100 + +# Limit the test dates to the future, where the historical +# variability won't impact the temp. +tdates <- 2000:2100 + ssp245 <- file.path(inputdir, "hector_ssp245.ini") @@ -87,9 +92,6 @@ test_that("Lowering initial CO2 lowers output CO2", { shutdown(hc) }) -# Limit the test dates to the future, where the historical -# variability won't impact the temp. -tdates <- 2000:2100 test_that("Lowering ECS lowers output Temperature", { @@ -176,7 +178,7 @@ test_that("Lowering diffusivity increases temperature", { test_that("Lowering aerosol forcing scaling factor increases temperature", { # Relevant vars to save and test. - vars <- c(GLOBAL_TAS()) + vars <- c(GLOBAL_TAS(), RF_BC(), RF_OC(), RF_SO2(), RF_NH3(), RF_ACI(), RF_TOTAL()) # Define Hector core. hc <- newcore(ssp245, suppresslogging = TRUE) @@ -193,11 +195,47 @@ test_that("Lowering aerosol forcing scaling factor increases temperature", { setvar(hc, NA, AERO_SCALE(), new_alpha, getunits(AERO_SCALE())) reset(hc, hc$reset_date) run(hc, 2100) - dd2 <- fetchvars(hc, tdates, GLOBAL_TAS()) + dd2 <- fetchvars(hc, tdates, vars) # Check to make sure that the temp and RF have changed. - diff <- dd2$value - dd1$value - expect_gt(min(diff), 0.0) + + # Checking that temperatures increase + temp1 <- dd1[dd1$variable == GLOBAL_TAS(),] + temp2 <- dd2[dd2$variable == GLOBAL_TAS(),] + temp_diff <- temp2$value - temp1$value + expect_gt(min(temp_diff), 0.0) + + # Checking that black carbon RF decreases + bc1 <- dd1[dd1$variable == RF_BC(),] + bc2 <- dd2[dd2$variable == RF_BC(),] + bc_diff <- bc2$value - bc1$value + expect_lt(max(bc_diff), 0.0) + + # Checking organic carbon RF magnitude decreases + oc1 <- dd1[dd1$variable == RF_OC(),] + oc2 <- dd2[dd2$variable == RF_OC(),] + oc_diff <- abs(oc2$value) - abs(oc1$value) + expect_lt(max(oc_diff), 0.0) + + # Checking that NH3 RF increases (becomes less negative) + nh3_1 <- dd1[dd1$variable == RF_NH3(),] + nh3_2 <- dd2[dd2$variable == RF_NH3(),] + nh3_diff <- nh3_2$value - nh3_1$value + expect_gt(min(nh3_diff), 0.0) + + # Checking that SO2 RF increases (becomes less negative) + so2_1 <- dd1[dd1$variable == RF_SO2(),] + so2_2 <- dd2[dd2$variable == RF_SO2(),] + so2_diff <- so2_2$value - so2_1$value + expect_gt(min(so2_diff), 0.0) + + # Checking that ACI RF increases (becomes less negative) + aci1 <- dd1[dd1$variable == RF_ACI(),] + aci2 <- dd2[dd2$variable == RF_ACI(),] + aci_diff <- aci2$value - aci1$value + expect_gt(min(aci_diff), 0.0) + + shutdown(hc) }) @@ -207,7 +245,7 @@ test_that("Increasing volcanic forcing scaling factor increases the effect of vo ## Because the volcanic forcing scaling factor only has an impact during the ## the volcanic events. Only check the temp during those years. tdates <- c(1960, 1965) - vars <- GLOBAL_TAS() + vars <- c(GLOBAL_TAS(), RF_VOL()) # Set up and run Hector hc <- newcore(ssp245, suppresslogging = TRUE) @@ -222,7 +260,18 @@ test_that("Increasing volcanic forcing scaling factor increases the effect of vo run(hc) new_out <- fetchvars(hc, tdates, vars) - expect_true(all(out$value != new_out$value)) + # Getting temperature and RF data + temps <- out[out$variable == GLOBAL_TAS(),] + rfs <- out[out$variable == RF_VOL(),] + + new_temps <- new_out[new_out$variable == GLOBAL_TAS(),] + new_rfs <- new_out[new_out$variable == RF_VOL(),] + + expect_true(all(temps$value != new_temps$value)) + + # Volcanic RF should decrease (become more negative) + rf_diff <- new_rfs$value - rfs$value + expect_lt(max(rf_diff), 0.0) }) test_that("Decreasing vegetation NPP fraction has down stream impacts", {