Skip to content

add stream field specific unit conversions in stream_defintion_MODEL.xml - #438

Open
mvertens wants to merge 3 commits into
ESCOMP:mainfrom
mvertens:feature/add_unit_conversion_escomp
Open

add stream field specific unit conversions in stream_defintion_MODEL.xml#438
mvertens wants to merge 3 commits into
ESCOMP:mainfrom
mvertens:feature/add_unit_conversion_escomp

Conversation

@mvertens

@mvertens mvertens commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Allow a unit conversion factor on stream variables

Description of changes

Adds an optional third token to a <var> line in a stream definition, giving a factor applied to that field as it is read. Uses it to fix nitrogen deposition, where the conversion was previously inferred from field names and got cplhist forcing wrong by a factor of 1000.

datm_pres_ndep_mod decided whether to convert nitrogen deposition from gN/m2/s to kgN/m2/s by looking at which stream fields were present: four fields meant no conversion, two fields meant divide by 1000.

A <var> line may now carry a conversion factor:

<var>drynhx  Faxa_ndep_nhx_dry</var>
<var>NDEP_NHx_month  Faxa_ndep_nhx  1.0e-3</var>
  • The factor is applied in dshr_strdata_mod as the field is read, so the data enters the system already in the units the model expects and no component carries conversion logic of its own.
  • Existing two-token entries are unaffected
  • The factor sits on the variable rather than the stream because units are a property of the field. A single stream may carry some fields needing conversion and others not, which a stream-wide factor could not express.
  • datm_pres_ndep_mod now only sums the fields it is given.

Specific notes

Contributors other than yourself, if any: claude

CDEPS Issues Fixed: #437

Are there dependencies on other component PRs:

Are changes expected to change answers: different to roundoff

  • Since we are now multiply by 1.0e-3 rather than dividing by 1000 - the answers are round off different
  • Testing was done in NorESM for the following compset/resolution:
    COMPSET: 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV_SESP
    GRID: a%1.9x2.5_l%1.9x2.5_oi%null_r%r05_w%null_z%null_g%gris4_m%tnx1v4
    And the following was obtained for the diffs:
atmImp_Faxa_ndep1   (atmImp_nx,atmImp_ny,time)  t_index =      1     1
      6630    13824  (    43,    55,     1) (    23,     6,     1) (    43,    56,     1) (   123,    15,     1)
              13824   3.338589824444479E-11   3.220082898594232E-16 6.5E-27  2.973562882264960E-11 8.1E-17  2.278254265933821E-13
              13824   3.338589824444479E-11   3.220082898594232E-16          2.973562882264959E-11          2.278254265933820E-13
              13824  (    43,    55,     1) (    23,     6,     1)
         avg abs field values:    6.873940049853111E-13    rms diff: 1.9E-28   avg rel diff(npos):  8.1E-17
                                  6.873940049853111E-13                        avg decimal digits(ndif): 15.8 worst: 15.4
RMS atmImp_Faxa_ndep1                1.8978E-28            NORMALIZED  2.7609E-16

atmImp_Faxa_ndep2   (atmImp_nx,atmImp_ny,time)  t_index =      1     1
      6683    13824  (     5,    50,     1) (    50,     8,     1) (    13,    50,     1) (   117,    28,     1)
              13824   6.316566797644321E-11   9.343714994332430E-15 1.3E-26  4.566923188557707E-11 8.1E-17  9.105195619604070E-13
              13824   6.316566797644321E-11   9.343714994332428E-15          4.566923188557706E-11          9.105195619604066E-13
              13824  (     5,    50,     1) (    50,     8,     1)
         avg abs field values:    6.168908270901164E-13    rms diff: 3.2E-28   avg rel diff(npos):  8.1E-17
                                  6.168908270901162E-13                        avg decimal digits(ndif): 15.8 worst: 15.4
RMS atmImp_Faxa_ndep2                3.1973E-28            NORMALIZED  5.1829E-16

Any User Interface Changes (namelist or namelist defaults changes):

Testing performed (e.g. aux_cdeps, CESM prealpha, etc):

Hashes used for testing:

@mvertens

mvertens commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator Author

@ekluzek @billsacks - the problem I ran into when I originally thought of doing this in the xml is that I was trying to put the unit conversion on a stream rather than on a field - and that of course will not work if the different stream fields have different units. With this PR now the unit conversion(s) are on stream field(s).

  • I have not tested this in ESCOMP - but I have tested this in NorESM successfully for the cmip6 forcing - which is where you wanted the conversion. I did not test the cplhist yet - but it should work.
  • This conversion can also be applied in other parts of CDEPS if units are expected to differ between what is read in and what is passed to the mediator. However, I only implemented the change for ndep.

@billsacks billsacks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks great - thanks a lot for implementing this! I just have a couple of requests about comments:

Comment thread datm/cime_config/stream_definition_datm.xml Outdated
Comment thread datm/datm_pres_ndep_mod.F90 Outdated

@ekluzek ekluzek 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.

There's a couple things I ask for. The one that's important is to upgrade the constants in the stream definition file from single to double precision. I think that's important enough to do. But, it still not make answers identical because of the conversion from a divide to a multiply, but certainly a good thing to have in place.

Comment thread datm/cime_config/stream_definition_datm.xml Outdated
Comment thread datm/cime_config/stream_definition_datm.xml Outdated
Comment thread datm/cime_config/stream_definition_datm.xml Outdated
Comment thread datm/datm_pres_ndep_mod.F90 Outdated
Comment thread streams/dshr_stream_mod.F90 Outdated
Comment thread streams/dshr_stream_mod.F90 Outdated
Comment thread streams/dshr_stream_mod.F90 Outdated
Comment thread datm/cime_config/stream_definition_datm.xml
@mvertens

mvertens commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

@ekluzek @billsacks - thanks for your review. I think I've addressed all of your comments.

@ekluzek ekluzek 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.

Awesome. Looks good.

@ekluzek ekluzek added enhancement New feature or request CESM Only labels Sep 2, 2026

@billsacks billsacks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good - thank you!

@billsacks

Copy link
Copy Markdown
Member

@mvertens - is it quick for you to redo your baseline test with the latest code (where you have changed the e to a d specifier)? I'm curious if you still see roundoff level diffs. I expect you probably will, but it would be good to know. If it would be at all of a pain to redo the testing, don't worry about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CESM Only enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CPLHIST ndep assumes the wrong units and so divides data by 1000 when it shouldn't

3 participants