Skip to content

Latest commit

 

History

History
190 lines (182 loc) · 12.2 KB

NEWS.md

File metadata and controls

190 lines (182 loc) · 12.2 KB

rsofuncpp 0.1.0 (development)

  • Add explicit upstream attribution in README.md, DESCRIPTION and new inst/ATTRIBUTION.md, citing geco-bern/rsofun, Stocker et al. 2020 GMD and Paredes et al. 2025 GMD. Add settings_calib, logpath and the name/logpath/walltime return fields to calib_sofun() for API compatibility with rsofun::calib_sofun(). Add parallel and ncores arguments to runread_biomee() (kept for compatibility; BiomeE remains sequential). Set runread_pmodel() default ncores to 1. Document the full consistency-test protocol in inst/parity-notes/consistency-tests.md.

  • BiomeE parameter calibration is now supported through calib_sofun(). The dispatcher accepts metric = cost_rmse_biomee (or cost_likelihood_biomee) and a settings$par list for phiRL, LAI_light, tf_base and par_mort. Documentation and a testthat case using a short spin-up and max.call limit were added.

  • Add the vignettes/pmodel_use.Rmd vignette, replicating the rsofun P-model usage example with the rsofuncpp C++17 backend. The vignette runs runread_pmodel(), plots GPP with base R graphics, and calibrates kphio using calib_sofun() + GenSA. knitr and rmarkdown were added to Suggests and VignetteBuilder: knitr to DESCRIPTION.

  • Add multi-core site-level parallelism to runread_pmodel() and runread_pmodel_cpp() via the parallel and ncores arguments. On Unix parallel::mclapply() is used; on Windows a parallel::parLapply() cluster is created. Over 337 FluxDataKit sites the 8-core run is ~6x faster than sequential (~7.6 s vs ~1.3 s) and produces identical output.

  • Close the residual per-site kphio calibration divergence on FluxDataKit v3.4.2. The Fortran calc_optimal_chi local mj has an implicit SAVE attribute, so it retains its previous value when vbkg <= 0 (e.g. after the negative patm outlier in GL-Dsk). src/pmodel_bysite.cpp calc_optimal_chi_r() now uses a static double mj_prev to match this behaviour. Across 337 FluxDataKit sites the calibrated kphio differs by at most 2.3e-05 (mean 1.2e-06) and the final RMSE by at most 8.5e-06. Climate-memory variables are also stored/dampened in float to match Fortran's single-precision arithmetic, and the gpp_bysite guard matches the Fortran fpc_grid > 0, dayl > 0, temp_memory > -5 conditions. Benchmark scripts and results are in inst/benchmarks/.

  • Add tests and example script (inst/examples/rsofun_doc_pmodel_gpp.R) that exercise rsofuncpp with the daily GPP subset of the rsofun_doc data (https://github.com/geco-bern/rsofun_doc, Zenodo 17495564). The tests are skipped unless RSOFUN_DOC_DIR points to a local clone of rsofun_doc. They verify that runread_pmodel(), cost_rmse_pmodel() and calib_sofun() work with the real rsofun calibration drivers, and that GenSA can improve kphio on a five-site subset.

  • Add technical note inst/notes/stan-external-cpp-feasibility.md summarising the investigation into calling the C++17 BiomeE/P-model core from cmdstan / cmdstanr. The conclusion is that a plain external C++ wrapper works only for generated quantities; for HMC sampling the model must either be rewritten in Stan, templated with stan::math types, or supplied with manual reverse-mode gradients.

  • Add consolidated project status report (inst/notes/project-status.md) and update the README.md status table. The report summarises the P-model and BiomeE migration status, merged PRs, quality gates, known pending issues, and the next steps (BiomeE cost functions, Stan calibration, CRAN preflight).

  • Implement and validate gs_leuning photosynthesis and LULUC transitions in the C++17 BiomeE core. src/biomee_gpp_soil.cpp dispatches between P-model (pt == 1) and gs_leuning (pt != 1) daily photosynthesis, using the Farquhar/Leuning constants and canopy extinction from the Fortran original. src/biomee_aggregated.cpp adds update_lu_fractions() (pool transfers and cohort density adjustment across land-use units) and aligns the aggregated output_annual_cell layout with Fortran (empty LU tiles are NaN except lu_fraction, aggregated totC is intentionally left NaN, and the landscape-level MaxVolume/MaxDBH aggregates use the same MAX(max_age, ...) formula as the reference). src/biomee_bysite.cpp now passes the bundled luc_forcing array through populate_inputs(). The new tests are enabled in tests/testthat/test-biomee_cpp_vs_r.R with spin-up and per-column tolerances matching the documented rsofun snapshot levels.

  • Extend tests/testthat/test-biomee_cpp_vs_r.R with placeholder tests for biomee_gs_leuning_drivers and biomee_p_model_luluc_drivers.

  • Improve the BiomeE output_annual_tile$Density parity by aligning denominator guards in src/biomee_annual.cpp and src/biomee_gpp_soil.cpp with the Fortran > 0.0 / != 0.0 tests. The transient deviation in Density for biomee_p_model_drivers is reduced from ~6% to ~0.3% (year 54). The remaining residual is dominated by a single cohort that is removed by vegn_annual_starvation one year earlier in C++ than in the Fortran reference; it arises from real32 vs double arithmetic in the bl_max/plabl threshold, not from a P-model 1e-5 numerical mismatch. The residual is a numerical artifact of the Fortran real32 implementation, not an error in the C++17 migration: the C++ backend uses double precision and is therefore mathematically more accurate. Reaching the 1e-5 target would require intentionally emulating the older Fortran real32 arithmetic so the two binaries take the same threshold branches. A detailed parity report with concrete examples is added in inst/parity-notes/biomee-density-parity.md; the test tolerances in helper-biomee-compare.R intentionally allow this residual while work to reach 1e-5 continues on a separate branch.

  • Achieve BiomeE C++17 vs Fortran parity and enable the public C++ backend. Add unique cohort identifiers (uid) to Cohort, generate them in create_cohort/split_cohort, and match them to cID output rows. Fix post-mortality cohort output (deathrate, n_deadtrees, c_deadtrees) via uid lookup. Align cohort list insertion order with Fortran (prepend in create_cohort and split_cohort). Update parity-test tolerances to rsofun snapshot levels (0.05/0.08/0.09) and skip the internal cID column. biomee_cpp_ready() now returns TRUE and run_biomee_bysite() / runread_biomee() dispatch to the C++17 engine.

  • Port BiomeE daily/annual vegetation processes to C++17 (src/biomee_annual.cpp): vegn_CNW_budget orchestration, gpp and SoilWaterDynamicsLayer/water_supply_layer stubs, plant_respiration, SOMdecomposition, vegn_N_uptake, phenology, allocation/growth (vegn_growth_EW), tissue turnover, natural mortality/reproduction, starvation and old-grass cleanup. Adds VegetationTile::lu_props() and OrgPool three-argument constructor needed by the process code. (The GPP/soil-water fast-step routines were completed in later PRs #11 and #15.)

  • Align runread_pmodel() and runread_pmodel_cpp() output with rsofun::runread_pmodel_f(): a data frame with sitename, site_info and a list column data (instead of a named list). Update cost_rmse_pmodel() and cost_likelihood_pmodel() to consume the nested data frame.

  • BiomeE Stage 1 pure-R reference run_biomee_r_bysite() and runread_biomee_r(), plus the public API run_biomee_bysite() and runread_biomee() matching rsofun::run_biomee_f_bysite() / runread_biomee_f() signatures and nested output structure (output_daily_tile, output_annual_tile, output_annual_cohorts, and the aggregated output_annual_cell for LULUC). The R-level call chain (tc_home, build_*/prepare_* input preparation and the structured output builders) is reimplemented in base R with no tidyverse dependency; the numerical core is delegated to the compiled biomee_f_C Fortran routine of the installed rsofun package via getNativeSymbolInfo().

  • Add tests/testthat/helper-biomee-compare.R and tests/testthat/test-biomee_r_vs_fortran.R validating the reference against the bundled biomee_p_model_*, biomee_gs_leuning_* and biomee_p_model_luluc_* reference outputs (tolerances follow rsofun's own snapshot tests, which allow up to 0.04/0.085 relative for nitrogen fluxes).

  • BiomeE Stage 2 C++17/Rcpp backend scaffold. Adds the C++17 data model in src/biomee.h (mirroring md_interface_in_biomee, md_params_core, md_orgpool, md_cohort, md_interface_out_biomee) and the deterministic, self-contained pieces of the core: input population, species derived-parameter initialisation (init_pft_data / init_derived_species_data), simulation steering (get_steering / get_cycleyear), sub-daily to daily aggregation, and the output-array plumbing / year-driver loop.

  • Port the VegetationTile, LuTile and AggregatedTile data structures (src/biomee_tile.cpp and src/biomee_aggregated.cpp), including cohort create/merge/relayer/reduce/thin bookkeeping, pool aggregation, daily and annual diagnostics, and the biosphere_annual() driver skeleton. The per-step physiological processes (vegn_CNW_budget, vegn_phenology, vegn_growth_EW, mortality, reproduction, soil biogeochemistry, LULUC transitions) are still stubs; biomee_cpp_ready() stays FALSE and the public API still dispatches to the validated Stage 1 Fortran-backed reference.

  • Add tests/testthat/test-biomee_cpp_vs_r.R: unit tests for the ported deterministic pieces against base-R reimplementations of the same equations (species derived params match to ~1e-9; steering exact) plus output-shape checks; the full-model cross-language comparison is skipped until the C++ core lands and uses the project per-column tolerances (never the P-model 1e-10).

  • Add calib_sofun() dispatcher with method = "GenSA" and optional method = "BayesianTools", using pure-R cost functions cost_rmse_pmodel() and cost_likelihood_pmodel().

  • Input validation with checkmate in run_pmodel_bysite(), runread_pmodel(), cost_rmse_pmodel(), cost_likelihood_pmodel() and calib_sofun().

  • Bundle BiomeE example drivers and validation data (biomee_p_model_drivers, biomee_validation, etc.).

  • GitHub Actions workflows for R-CMD-check (Ubuntu, macOS, Windows), test-coverage, and pkgdown.

  • Add cran-comments.md and refine DESCRIPTION for CRAN preflight.

  • Stan calibration design in inst/stan/README.md and skeleton inst/stan/pmodel_calibration.stan.

  • C++17 time-series P-model backend run_pmodel_cpp_bysite() and runread_pmodel_cpp() (Rcpp export run_pmodel_cpp_bysite_impl()), porting the pure-R reference .run_pmodel_r_bysite() (solar, water balance, gpp, isotope tracking, soil temperature, daily diagnostics and the spinup/recycle year-doy driver loop) to C++ with machine-precision parity against run_pmodel_r_bysite() on the bundled p_model_drivers.

  • Rename src/pmodel.hpp to src/pmodel.h (CRAN-recognised header extension); it now also backs the time-series kernel.

  • Public P-model API run_pmodel_bysite() and runread_pmodel() matching rsofun::run_pmodel_f_bysite() / runread_pmodel_f() signatures and output columns.

  • Pure-R Stage 1 reference run_pmodel_r_bysite() and runread_pmodel_r() that reproduce Fortran outputs to ~1e-5 relative for the bundled p_model_drivers example (spinup + 6-year transient).

  • Bundle p_model_drivers example data and a Fortran reference output in inst/extdata/pmodel_f_ref.rds for regression tests.

  • Fix package-level constant collision that caused calc_patm_r() to use the wrong reference temperature when R/pmodel_r.R and R/pmodel_bysite_r.R were loaded together.

  • Add tests/testthat/helper-compare.R with a direct .Call to the rsofun Fortran .so and a test-pmodel_transparency.R test that compares rsofuncpp::run_pmodel_bysite() against the live rsofun Fortran output (the rsofun R wrappers depend on an older dplyr stack, so the helpers bypass them).

rsofuncpp 0.0.0.9000 (development)

  • Initial package skeleton with C++17 / Rcpp / RcppParallel build setup.