Skip to content

[#411] Make carbon and nitrogen balance failures fatal - #414

Merged
Alomir merged 2 commits into
PecanProject:masterfrom
priyanshusky0:411-fatal-balance-check
Oct 28, 2026
Merged

Alomir merged 2 commits into
PecanProject:masterfrom
priyanshusky0:411-fatal-balance-check

Conversation

@priyanshusky0

Copy link
Copy Markdown
Contributor

Summary

  • What: checkBalance() now exits with EXIT_CODE_INTERNAL_ERROR when the C or N balance residual is >= EPS (1e-8) in magnitude, or is NaN/inf. Before it only logged a warning and kept going.
  • Motivation: See Make carbon and nitrogen balance failures fatal #411. Also noticed while doing this that a NaN residual was passing silently before, since both fabs(NaN) < EPS and fabs(NaN) > 0 are false.

Residuals below EPS are still zeroed and treated as noise, same as before. I didn't touch the balance equations or the clamping accounting.

On failure it now logs the element, residual, year/day/time, pre/post-update/final pool totals, inputs, outputs and the clamped amount. I used %.17g for these so you can actually see a ~1e-8 difference when the pool totals are large. If both C and N fail in the same step, both get reported before exiting.

How was this change tested?

  • Added tests/sipnet/test_modeling/testBalanceCheck.c. It sets up the balance tracker directly and checks, for both C and N: zero, +/- 0.5*EPS and the value just below EPS pass; +/- EPS and +/- 1e-3 exit; NaN, +inf and -inf exit. There's also a balanced case with a nonzero clamping adjustment.
  • To make sure the test actually catches things, I temporarily changed >= to > and removed the isfinite check in the source; the test failed in both cases.
  • make unit passes.
  • make smoke passes, with no changes to any sipnet.out. I also ran each smoke case with quiet off on master first, and none of them were hitting the balance warning, so nothing new should start failing. russell_4 has a skip file so I ran it by hand too, it exits 0.

Related issues

Checklist

  • Related issues are listed above. PRs without an approved, related issue may not get reviewed.
  • PR title has the issue number in it ("[#] <concise description of proposed change>")
  • Tests added/updated for new features (if applicable)
  • Documentation updated (if applicable)
  • docs/CHANGELOG.md updated with noteworthy changes
  • Code formatted with clang-format (run git clang-format if needed)

@Alomir Alomir left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for contributing! One minor change suggested.

Comment thread docs/CHANGELOG.md Outdated

### Changed
- SIPNET will now error instead of warning when an environment pool goes negative. This is a change from previous behavior where SIPNET would log a warning and continue running. (#398)
- SIPNET now exits with `EXIT_CODE_INTERNAL_ERROR` when a timestep fails the carbon or nitrogen balance check (residual magnitude >= 1e-8, or a NaN/infinite residual), instead of logging a warning and continuing. The error reports the residual, timestep, pool totals, inputs, outputs, and clamping adjustment at full precision. (#411)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too much detail. How about just:

Suggested change
- SIPNET now exits with `EXIT_CODE_INTERNAL_ERROR` when a timestep fails the carbon or nitrogen balance check (residual magnitude >= 1e-8, or a NaN/infinite residual), instead of logging a warning and continuing. The error reports the residual, timestep, pool totals, inputs, outputs, and clamping adjustment at full precision. (#411)
- SIPNET now errors and exits when a mass balance check failure occurs, instead of logging a warning and continuing (#414)

Note also that we have been putting the PR numbers in CHANGELOG instead of the issue numbers

checkBalance() now exits with EXIT_CODE_INTERNAL_ERROR when either
residual is NaN/inf or has magnitude >= EPS, instead of only logging a
warning. Finite residuals below EPS are still treated as noise.

The error message now includes the residual, timestep, pool totals,
inputs, outputs and clamping adjustment, printed with %.17g so values
near EPS are visible.

Added testBalanceCheck covering positive/negative imbalances, values
just below and at EPS, and NaN/inf for both carbon and nitrogen.

@Alomir Alomir left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks

@Alomir
Alomir merged commit c3479bd into PecanProject:master Oct 28, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make carbon and nitrogen balance failures fatal

2 participants