Skip to content

Commit 9631b05

Browse files
authored
Merge pull request #755 from JGCRI/dev
V3.5.0 Development * Minor documentation changes * Several variables/parameters were renamed, FCH4 -> RF_CH4, alpha -> aero_scalar, & volscl -> vol_scalar * Change RF vol implementation so it is not negative in the future period * Expose soil and detritus RH fluxes as possible Hector outputs, RH_DETRITUS() & RH_SOIL() * Add ALL_VARS() which helps users fetch all Hector output variables * Update [CH4] lifetime parameters * Allow for time varying historical N2O and CH4 natural emissions * New default parameter values for ocean heat diffusivity, CO2 fertilization, and heterotrophic respiration temperature sensitivity from calibrating Hector to historical observations of gmst (Morice et al. 2021), [CO2] (Meinshausen et al. 2020), and ocean heat content (Kuhlbrodt et al. 2023)
2 parents a61d64a + 9fa91b4 commit 9631b05

82 files changed

Lines changed: 11874 additions & 11239 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
name: Release
3+
about: Checklist!
4+
---
5+
6+
Since the dev branch only includes materials that have been peer-reviewed at least once this PR review process should be relatively smooth should. That being said, before merging this branch into main and the new release is created several things must be completed first.
7+
8+
* Open a PR into main branch, it should be titled with the new release number
9+
* Let Leeyabot generate a report detailing how the Hector output has changed!
10+
* Add text to the PR documenting the major model changes. The PR is going to serve as an important record
11+
* Pass automated checks
12+
* Change the version number in the DESCRIPTION file
13+
* Update the NEWS.md, are links additional materials necessary? Does the release need a new naming file?
14+
* Check to make sure the internal package data is up to date (fxntable, inputstable, unitstable)
15+
16+
After merging PR
17+
18+
* Create the release via zenodo
19+
* Add the zenodo links to README / NEWS & push directly to main
20+
* Create new dev branch & update the DESCRIPTION version number to support the pkgdown documentation for the developmental branch!
21+
* Add archived outputstreams to release assets!
22+

DESCRIPTION

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: hector
22
Title: The Hector Simple Climate Model
3-
Version: 3.2.0
3+
Version: 3.5.0
44
Authors@R: c(person("Kalyn", "Dorheim",
55
email = "kalyn.dorheim@pnnl.gov",
66
role = c("aut", "cre"),
@@ -31,6 +31,10 @@ Authors@R: c(person("Kalyn", "Dorheim",
3131
email = "leeya.pressburger@pnnl.gov",
3232
role = c("ctb", "dtc"),
3333
comment = c(ORCID = "0000-0002-6850-2504")),
34+
person("Peter", "Scully",
35+
email = "ptrscll@gmail.com",
36+
role = "ctb",
37+
comment = c(ORCID = "0009-0007-0234-0366")),
3438
person("Alexey", "Shiklomanov",
3539
email = "alexey.shiklomanov@nasa.gov",
3640
role = "ctb",
@@ -47,7 +51,8 @@ Description: Provides an R interface for the Hector Simple Climate
4751
change model parameters and emissions inputs, run Hector, and
4852
retrieve model outputs. Note that the package authors are not
4953
identical to the C++ model authors.
50-
Depends: R (>= 3.3)
54+
Depends:
55+
R (>= 3.5)
5156
License: GPL-3
5257
Encoding: UTF-8
5358
LazyData: true
@@ -70,7 +75,7 @@ Collate:
7075
'units.R'
7176
VignetteBuilder: knitr
7277
Config/Needs/website: kableExtra, nleqslv
73-
RoxygenNote: 7.2.3
78+
RoxygenNote: 7.3.2
7479
SystemRequirements: GNU make
7580
URL: https://github.com/JGCRI/hector, https://jgcri.github.io/hector/
7681
BugReports: https://github.com/JGCRI/hector/issues

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
S3method(format,hcore)
44
S3method(print,hcore)
55
export(AERO_SCALE)
6+
export(ALL_VARS)
67
export(ATMOSPHERIC_CO2)
78
export(BETA)
89
export(C2F6_CONSTRAIN)
@@ -238,6 +239,8 @@ export(RHO_NH3)
238239
export(RHO_OC)
239240
export(RHO_SF6)
240241
export(RHO_SO2)
242+
export(RH_DETRITUS)
243+
export(RH_SOIL)
241244
export(SF6_CONSTRAIN)
242245
export(SOIL_C)
243246
export(SST)

NEWS.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
1+
# hector 3.5.0
2+
3+
* Minor documentation changes
4+
* Several variables/parameters were renamed, FCH4 -> RF_CH4, alpha -> aero_scalar, & volscl -> vol_scalar
5+
* Change RF vol implementation so it is not negative in the future period
6+
* Expose soil and detritus RH fluxes as possible Hector outputs, RH_DETRITUS() & RH_SOIL()
7+
* Add ALL_VARS() which helps users fetch all Hector output variables
8+
* Update [CH4] lifetime parameters
9+
* Allow for time varying historical N2O and CH4 natural emissions
10+
* New default parameter values for ocean heat diffusivity, CO2 fertilization, and heterotrophic respiration temperature sensitivity
11+
12+
13+
14+
15+
116
# hector 3.2.0
217
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.10698028.svg)](https://doi.org/10.5281/zenodo.10698028)
18+
19+
* Fully documented in Dorheim, K., Gering, S., Gieseke, R., Hartin, C., Pressburger, L., Shiklomanov, A. N., Smith, S. J., Tebaldi, C., Woodard, D. L., and Bond-Lamberty, B.: Hector V3.2.0: functionality and performance of a reduced-complexity climate model, Geosci. Model Dev., 17, 4855–4869, https://doi.org/10.5194/gmd-17-4855-2024, 2024.
320
* Correct aerosol forcing coefficients based on Zelinka et al. (2023)
421
* Enable permafrost module and recalibrate model's default parameterization
522

R/RcppExports.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,18 @@ RH <- function() {
12921292
.Call('_hector_RH', PACKAGE = 'hector')
12931293
}
12941294

1295+
#' @rdname carboncycle
1296+
#' @export
1297+
RH_DETRITUS <- function() {
1298+
.Call('_hector_RH_DETRITUS', PACKAGE = 'hector')
1299+
}
1300+
1301+
#' @rdname carboncycle
1302+
#' @export
1303+
RH_SOIL <- function() {
1304+
.Call('_hector_RH_SOIL', PACKAGE = 'hector')
1305+
}
1306+
12951307
#' @describeIn parameters Preindustrial CO2 concentration (\code{"ppmv CO2"})
12961308
#' @export
12971309
PREINDUSTRIAL_CO2 <- function() {

R/aadoc.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,3 +312,8 @@ NULL
312312
#' \item{string}{String of variable name}
313313
#' }
314314
"fxntable"
315+
316+
#' A vector containing all the hector output names.
317+
#'
318+
#' @format A vector of length 82.
319+
"all_vars"

R/biome.R

Lines changed: 93 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@ create_biome <- function(core, biome,
2222
npp_flux0,
2323
warmingfactor, beta, q10_rh,
2424
f_nppv, f_nppd, f_litterd) {
25-
create_biome_impl(core, biome)
26-
setvar(core, 0, VEG_C(biome), veg_c0, "Pg C")
27-
setvar(core, 0, DETRITUS_C(biome), detritus_c0, "Pg C")
28-
setvar(core, 0, SOIL_C(biome), soil_c0, "Pg C")
29-
setvar(core, 0, PERMAFROST_C(biome), permafrost_c0, "Pg C")
30-
setvar(core, NA, NPP_FLUX0(biome), npp_flux0, "Pg C/yr")
31-
setvar(core, NA, WARMINGFACTOR(biome), warmingfactor, NA)
32-
setvar(core, NA, BETA(biome), beta, NA)
33-
setvar(core, NA, Q10_RH(biome), q10_rh, NA)
34-
setvar(core, NA, F_NPPV(biome), f_nppv, NA)
35-
setvar(core, NA, F_NPPD(biome), f_nppd, NA)
36-
setvar(core, NA, F_LITTERD(biome), f_litterd, NA)
37-
invisible(core)
25+
create_biome_impl(core, biome)
26+
setvar(core, 0, VEG_C(biome), veg_c0, "Pg C")
27+
setvar(core, 0, DETRITUS_C(biome), detritus_c0, "Pg C")
28+
setvar(core, 0, SOIL_C(biome), soil_c0, "Pg C")
29+
setvar(core, 0, PERMAFROST_C(biome), permafrost_c0, "Pg C")
30+
setvar(core, NA, NPP_FLUX0(biome), npp_flux0, "Pg C/yr")
31+
setvar(core, NA, WARMINGFACTOR(biome), warmingfactor, NA)
32+
setvar(core, NA, BETA(biome), beta, NA)
33+
setvar(core, NA, Q10_RH(biome), q10_rh, NA)
34+
setvar(core, NA, F_NPPV(biome), f_nppv, NA)
35+
setvar(core, NA, F_NPPD(biome), f_nppd, NA)
36+
setvar(core, NA, F_LITTERD(biome), f_litterd, NA)
37+
invisible(core)
3838
}
3939

4040
#' Create new biomes by splitting up an existing biome
@@ -67,64 +67,66 @@ split_biome <- function(core,
6767
fpermafrost_c = fveg_c,
6868
fnpp_flux0 = fveg_c,
6969
...) {
70-
stopifnot(
71-
length(old_biome) == 1,
72-
old_biome %in% get_biome_list(core),
73-
!any(new_biomes %in% get_biome_list(core)),
74-
length(fveg_c) == length(new_biomes),
75-
length(fdetritus_c) == length(new_biomes),
76-
length(fsoil_c) == length(new_biomes),
77-
length(fpermafrost_c) == length(new_biomes),
78-
length(fnpp_flux0) == length(new_biomes),
79-
sum(fveg_c) == 1, all(fveg_c > 0),
80-
sum(fdetritus_c) == 1, all(fdetritus_c > 0),
81-
sum(fsoil_c) == 1, all(fsoil_c > 0),
82-
sum(fpermafrost_c) == 1, all(fpermafrost_c >= 0),
83-
sum(fnpp_flux0) == 1, all(fnpp_flux0 > 0)
84-
)
70+
stopifnot(
71+
length(old_biome) == 1,
72+
old_biome %in% get_biome_list(core),
73+
!any(new_biomes %in% get_biome_list(core)),
74+
length(fveg_c) == length(new_biomes),
75+
length(fdetritus_c) == length(new_biomes),
76+
length(fsoil_c) == length(new_biomes),
77+
length(fpermafrost_c) == length(new_biomes),
78+
length(fnpp_flux0) == length(new_biomes),
79+
sum(fveg_c) == 1, all(fveg_c > 0),
80+
sum(fdetritus_c) == 1, all(fdetritus_c > 0),
81+
sum(fsoil_c) == 1, all(fsoil_c > 0),
82+
sum(fpermafrost_c) == 1, all(fpermafrost_c >= 0),
83+
sum(fnpp_flux0) == 1, all(fnpp_flux0 > 0)
84+
)
8585

86-
# If user supplied values in ... for warmingfactor, etc., use those
87-
# Otherwise use the old biome's values
88-
cv <- get_biome_inits(core, old_biome) # current values
89-
dots <- list(...)
90-
# We can't use ifelse for this because return shape may differ
91-
pick <- function(x, y) { if (is.null(x)) y else x } # nolint
92-
warmingfactor <- pick(dots$warmingfactor, cv[["warmingfactor"]])
93-
beta <- pick(dots$beta, cv[["beta"]])
94-
q10_rh <- pick(dots$q10_rh, cv[["q10_rh"]])
95-
f_nppv <- pick(dots$f_nppv, cv[["f_nppv"]])
96-
f_nppd <- pick(dots$f_nppd, cv[["f_nppd"]])
97-
f_litterd <- pick(dots$f_litterd, cv[["f_litterd"]])
86+
# If user supplied values in ... for warmingfactor, etc., use those
87+
# Otherwise use the old biome's values
88+
cv <- get_biome_inits(core, old_biome) # current values
89+
dots <- list(...)
90+
# We can't use ifelse for this because return shape may differ
91+
pick <- function(x, y) {
92+
if (is.null(x)) y else x
93+
} # nolint
94+
warmingfactor <- pick(dots$warmingfactor, cv[["warmingfactor"]])
95+
beta <- pick(dots$beta, cv[["beta"]])
96+
q10_rh <- pick(dots$q10_rh, cv[["q10_rh"]])
97+
f_nppv <- pick(dots$f_nppv, cv[["f_nppv"]])
98+
f_nppd <- pick(dots$f_nppd, cv[["f_nppd"]])
99+
f_litterd <- pick(dots$f_litterd, cv[["f_litterd"]])
98100

99-
# This allows users to split the `global` biome without having to
100-
# rename it first. Otherwise, we hit an error about using non-global
101-
# biomes when a "global" biome is present.
102-
if (old_biome == "global") {
103-
invisible(rename_biome(core, "global", "_zzz"))
104-
old_biome <- "_zzz"
105-
}
101+
# This allows users to split the `global` biome without having to
102+
# rename it first. Otherwise, we hit an error about using non-global
103+
# biomes when a "global" biome is present.
104+
if (old_biome == "global") {
105+
invisible(rename_biome(core, "global", "_zzz"))
106+
old_biome <- "_zzz"
107+
}
106108

107-
mapply(
108-
create_biome,
109-
biome = new_biomes,
110-
veg_c0 = cv[["veg_c"]] * fveg_c,
111-
detritus_c0 = cv[["detritus_c"]] * fdetritus_c,
112-
soil_c0 = cv[["soil_c"]] * fsoil_c,
113-
permafrost_c0 = cv[["permafrost_c"]] * fpermafrost_c,
114-
npp_flux0 = cv[["npp_flux0"]] * fnpp_flux0,
115-
warmingfactor = warmingfactor,
116-
beta = beta,
117-
q10_rh = q10_rh,
118-
f_nppv = f_nppv,
119-
f_nppd = f_nppd,
120-
f_litterd = f_litterd,
121-
MoreArgs = list(core = core)
122-
)
109+
mapply(
110+
create_biome,
111+
biome = new_biomes,
112+
veg_c0 = cv[["veg_c"]] * fveg_c,
113+
detritus_c0 = cv[["detritus_c"]] * fdetritus_c,
114+
soil_c0 = cv[["soil_c"]] * fsoil_c,
115+
permafrost_c0 = cv[["permafrost_c"]] * fpermafrost_c,
116+
npp_flux0 = cv[["npp_flux0"]] * fnpp_flux0,
117+
warmingfactor = warmingfactor,
118+
beta = beta,
119+
q10_rh = q10_rh,
120+
f_nppv = f_nppv,
121+
f_nppd = f_nppd,
122+
f_litterd = f_litterd,
123+
MoreArgs = list(core = core)
124+
)
123125

124-
delete_biome_impl(core, old_biome)
126+
delete_biome_impl(core, old_biome)
125127

126-
reset(core, 0)
127-
invisible(core)
128+
reset(core, 0)
129+
invisible(core)
128130
}
129131

130132
#' Retrieve the initial conditions and parameters for a given biome
@@ -136,29 +138,29 @@ split_biome <- function(core,
136138
#' @return Named numeric vector of biome initial conditions and parameters
137139
#' @author Alexey Shiklomanov
138140
get_biome_inits <- function(core, biome) {
139-
# `fetchvars` requires date to be between start and end date, so
140-
# we need to call the lower-level `sendmessage` method here.
141-
current_data_1 <- rbind.data.frame(
142-
sendmessage(core, GETDATA(), VEG_C(biome), 0, NA, ""),
143-
sendmessage(core, GETDATA(), DETRITUS_C(biome), 0, NA, ""),
144-
sendmessage(core, GETDATA(), SOIL_C(biome), 0, NA, ""),
145-
sendmessage(core, GETDATA(), PERMAFROST_C(biome), 0, NA, ""),
146-
sendmessage(core, GETDATA(), THAWEDP_C(biome), 0, NA, "")
147-
)
148-
current_data_2 <- fetchvars(core, NA, c(
149-
NPP_FLUX0(biome),
150-
F_LITTERD(biome),
151-
F_NPPD(biome),
152-
F_NPPV(biome),
153-
BETA(biome),
154-
Q10_RH(biome),
155-
WARMINGFACTOR(biome)
156-
))[, -1]
157-
current_data <- rbind.data.frame(current_data_1, current_data_2)
158-
current_values <- current_data[["value"]]
159-
names(current_values) <- gsub(paste0(biome, BIOME_SPLIT_CHAR()), "",
160-
current_data[["variable"]],
161-
fixed = TRUE
162-
)
163-
current_values
141+
# `fetchvars` requires date to be between start and end date, so
142+
# we need to call the lower-level `sendmessage` method here.
143+
current_data_1 <- rbind.data.frame(
144+
sendmessage(core, GETDATA(), VEG_C(biome), 0, NA, ""),
145+
sendmessage(core, GETDATA(), DETRITUS_C(biome), 0, NA, ""),
146+
sendmessage(core, GETDATA(), SOIL_C(biome), 0, NA, ""),
147+
sendmessage(core, GETDATA(), PERMAFROST_C(biome), 0, NA, ""),
148+
sendmessage(core, GETDATA(), THAWEDP_C(biome), 0, NA, "")
149+
)
150+
current_data_2 <- fetchvars(core, NA, c(
151+
NPP_FLUX0(biome),
152+
F_LITTERD(biome),
153+
F_NPPD(biome),
154+
F_NPPV(biome),
155+
BETA(biome),
156+
Q10_RH(biome),
157+
WARMINGFACTOR(biome)
158+
))[, -1]
159+
current_data <- rbind.data.frame(current_data_1, current_data_2)
160+
current_values <- current_data[["value"]]
161+
names(current_values) <- gsub(paste0(biome, BIOME_SPLIT_CHAR()), "",
162+
current_data[["variable"]],
163+
fixed = TRUE
164+
)
165+
current_values
164166
}

R/fxns.R

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,33 @@
99
#' getfxn("beta")
1010
#' getfxn("q10_rh")
1111
getfxn <- function(str) {
12+
rows <- match(str, hector::fxntable$string)
13+
rslt <- hector::fxntable$fxn[rows]
14+
if (any(is.na(rows))) {
15+
warning(
16+
"Functions for the following are not found: ",
17+
paste(str[is.na(rslt)], collapse = ", ")
18+
)
19+
}
20+
as.character(rslt)
21+
}
22+
1223

13-
rows <- match(str, hector::fxntable$string)
14-
rslt <- hector::fxntable$fxn[rows]
15-
if (any(is.na(rows))) {
16-
warning(
17-
"Functions for the following are not found: ",
18-
paste(str[is.na(rslt)], collapse = ", ")
19-
)
20-
}
21-
as.character(rslt)
24+
#' Get all of the possible Hector output variables
25+
#'
26+
#' This function returns all of the possible hector output variables
27+
#' that can be accessed with \code{\link{fetchvars}}.
28+
#' @return Character vector of variable names.
29+
#' @export
30+
#' @family outputs
31+
#' @examples
32+
#' \dontrun{
33+
#' ini <- system.file(package = "hector", "input/hector_ssp245.ini")
34+
#' hc <- newcore(ini)
35+
#' run(hc)
36+
#' out <- fetchvars(core = hc, dates = 1900:2100, vars = ALL_VARS())
37+
#' print(out)
38+
#' }
39+
ALL_VARS <- function() {
40+
hector::all_vars
2241
}

0 commit comments

Comments
 (0)