Skip to content

Feat:Added Minimal energy balance check LE<SW#243

Closed
Labreo wants to merge 5 commits intoPecanProject:masterfrom
Labreo:feat/energy-balance-check
Closed

Feat:Added Minimal energy balance check LE<SW#243
Labreo wants to merge 5 commits intoPecanProject:masterfrom
Labreo:feat/energy-balance-check

Conversation

@Labreo
Copy link
Contributor

@Labreo Labreo commented Jan 30, 2026

Summary

  • Motivation: There was a need to implement a minimal energy checker as prior to this model wouldn't you warn if the incoming shortwave radiation was lesser than the latent energy which should not be possible.Now it throws an error at the user.(Though it doesn't close the process as i thought it would be a bit much).
  • What: Added a basic sanity checker which runs only if the incoming shortwave radiation is greater than 1.To restrict it from giving false positives since we cant assume latent energy wouldn't be greater when apt sunlight is not there.Added
    0<LE<SW or error,0<LE<alphaSW or warn logic where alpha represents absorbed sw, (1-albedo) and 0.8 is very conservative and can be hard coded,LE=ETlambda where lambda is latent heat of evaporation as laid out in Minimal energy balance check LE<SW #231.

Result:

There is something really weird going on with the latent energy being greater than the shortwave radiation by a huge difference,there seems to be some kind of divide-by-zero or small number instability.It only occurs at early mornings.Even if the check for error is too strict latent energy shouldn't posses such a huge difference.

How to test

Steps to reproduce and verify the change locally:
Step 1:

make clean && make

Step 2:

cd tests/smoke/niwot
../../../sipnet -i sipnet.in

Related issues

Checklist

  • Tests added for new features
  • Documentation updated (if applicable)
  • docs/CHANGELOG.md updated with noteworthy changes
  • Code formatted with clang-format (run git clang-format if needed)
  • Requested review from at least one CODEOWNER

For model structure changes:

  • Removed \fraktur font formatting from docs/model-structure.md for implemented features

Note: See CONTRIBUTING.md for additional guidance. This repository uses automated formatting checks; if the pre-commit hook blocks your commit, run git clang-format to format staged changes.

@Labreo
Copy link
Contributor Author

Labreo commented Jan 30, 2026

The errors in question.

        LE (455146.497810) > SW (38.862583)
[ERROR] Energy Balance Violation: Year 2004 Day 200 Time 5.00
        LE (710213.310786) > SW (68.069040)
[ERROR] Energy Balance Violation: Year 2004 Day 201 Time 5.00
        LE (984058.604548) > SW (53.147185)
[ERROR] Energy Balance Violation: Year 2004 Day 202 Time 5.00
        LE (787543.295803) > SW (47.431788)
[ERROR] Energy Balance Violation: Year 2004 Day 203 Time 5.00
        LE (1220415.852822) > SW (70.941722)
[ERROR] Energy Balance Violation: Year 2004 Day 204 Time 5.00
        LE (773667.066133) > SW (31.608062)
[ERROR] Energy Balance Violation: Year 2004 Day 205 Time 5.00
        LE (761964.178523) > SW (15.920069)
[ERROR] Energy Balance Violation: Year 2004 Day 206 Time 5.00
        LE (519620.480262) > SW (38.342882)
[ERROR] Energy Balance Violation: Year 2004 Day 207 Time 5.00
        LE (833680.342935) > SW (89.154889)
[ERROR] Energy Balance Violation: Year 2004 Day 208 Time 5.00
        LE (1409106.990897) > SW (62.550772)
[ERROR] Energy Balance Violation: Year 2004 Day 209 Time 5.00
        LE (1019626.567380) > SW (70.607376)
[ERROR] Energy Balance Violation: Year 2004 Day 210 Time 5.00
        LE (555280.535697) > SW (44.168954)
[ERROR] Energy Balance Violation: Year 2004 Day 211 Time 5.00
        LE (1522024.479271) > SW (85.579245)
[ERROR] Energy Balance Violation: Year 2004 Day 212 Time 5.00
        LE (1305678.282831) > SW (79.910120)
[ERROR] Energy Balance Violation: Year 2004 Day 213 Time 5.00
        LE (1707740.534573) > SW (80.440652)
[ERROR] Energy Balance Violation: Year 2004 Day 214 Time 5.00
        LE (1625715.069598) > SW (72.939623)
[ERROR] Energy Balance Violation: Year 2004 Day 215 Time 5.00
        LE (1028762.237255) > SW (45.772899)
[ERROR] Energy Balance Violation: Year 2004 Day 216 Time 5.00
        LE (1187132.793504) > SW (85.569468)
[ERROR] Energy Balance Violation: Year 2004 Day 217 Time 5.00
        LE (970046.928046) > SW (80.814065)
[ERROR] Energy Balance Violation: Year 2004 Day 218 Time 5.00
        LE (922001.038964) > SW (52.716467)
[ERROR] Energy Balance Violation: Year 2004 Day 219 Time 5.00
        LE (1171778.352125) > SW (91.127273)

@Labreo
Copy link
Contributor Author

Labreo commented Jan 30, 2026

@dlebauer I think what is going is since the error seems to be primarily occurring in the early hours of the day.And since the numbers are comically large there seems to be some kind of divide by zero or a number close to 0 edge case where one of the fluxes has used to perform some kind of divison.It feels related to the time aswell.I have not looked into it but that is what it seems to be.

@dlebauer
Copy link
Member

I think this may be related to units. Model reads PAR in units of Einsteins * m^-2 ground area, summed over entire time step. I am not 100% certain what internal units are off hand, but I think this is the conversion

PAR * 2.35e5 / 0.486

But please check the math.

this is what the conversion looks like in R; can use the comments to explain. I don't think it is necessary to write a function in sipnet for a single assertion.

#' Convert PAR (Einsteins m^-2 s^-1) to shortwave radiation
#'
#' TODO take input units as arg
#' Converts photosynthetically active radiation (PAR) expressed as
#' photon flux (Einsteins m^-2 s^-1) to total shortwave radiation
#' (W m^-2). Assumes PAR is 0.486 of total shortwave radiation
#' (Campbell & Norman, 1998).
#'
#' @param par_einstein PAR in Einsteins m^-2 s^-1 (i.e., mol photons m^-2 s^-1).
#' @param par_fraction Fraction of total shortwave in PAR band. Default 0.486.
#' @return Shortwave radiation in W m^-2.
#' @export
#' @examples
#' # 0.001 Einsteins m^-2 s^-1 (1 mmol) -> ~484 W m^-2
#' par2sw(0.001)
par2sw <- function(par_einstein, par_fraction = 0.486) {
  # 1 mol photons (Einstein) in PAR ~ 2.35e5 J
  par_w_m2 <- par_einstein * 2.35e5
  sw_w_m2 <- par_w_m2 / par_fraction
  return(sw_w_m2)
}

@Labreo
Copy link
Contributor Author

Labreo commented Jan 31, 2026

Appreciate the reply.I definitely messed up the units.I have applied a fix for it now.

@Labreo
Copy link
Contributor Author

Labreo commented Feb 7, 2026

@dlebauer @Alomir Please have a look at the changes mades when you are free. Thanks in advance for your time.

Comment on lines +1925 to +1927
fluxes.evaporation + fluxes.sublimation;

double LE_check = ET_sum * LAMBDA;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think sublimation should be using LAMBDA_S, not LAMBDA.

@Alomir
Copy link
Collaborator

Alomir commented Mar 9, 2026

There may still be a units issue here; the R code above says that is converts PAR as (Einsteins m^-2 s^-1) to SW as (W m^-2) - that is, energy density, not flux (though I'm not sure how it does that without a period of time).

However:

  • climate.par is (Einsteins m^-2 d^-1) - that is, per-day instead of per-second
  • The LE calculation is still per-day, so our LE/SW comparison is comparing a flux to a non-flux (if it really is a non-flux)

@dlebauer for comment

@dlebauer
Copy link
Member

This PR was helpful in helping me realize that #231 was misguided. I wrote it up hoping to do something analogous to mass balance closure. But SIPNET doesn't track energy with sufficient detail to make such a check possible.

Apologies for not realizing this sooner.

@dlebauer dlebauer closed this Mar 10, 2026
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.

Minimal energy balance check LE<SW

3 participants