Skip to content

Add Ai2's ACE as an emulator component #7957

Draft
andrewdnolan wants to merge 38 commits intomasterfrom
jonbob/add-eatm
Draft

Add Ai2's ACE as an emulator component #7957
andrewdnolan wants to merge 38 commits intomasterfrom
jonbob/add-eatm

Conversation

@andrewdnolan
Copy link
Copy Markdown
Contributor

This PR adds support for emulator components, starting with an emulator atmosphere based on Ai2's ACE.

Comment thread components/emulator_comps/eatm/src/ace_comp_mod.F90
vbot(i, j) = net_outputs(1, 32, i, j) ! V_0
tbot(i, j) = net_outputs(1, 8, i, j) ! T_0
ptem(i, j) = net_outputs(1, 8, i, j) ! T_0
shum(i, j) = 0.0_R8 ! TBD
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

datm calculates shum (bottom atm level spec humidity) here:

!--- specific humidity ---
tbot = a2x%rAttr(ktbot,n)
pbot = a2x%rAttr(kpbot,n)
if (sshum > 0) then
e = datm_shr_esat(tbot,tbot)
qsat = (0.622_R8 * e)/(pbot - 0.378_R8 * e)
if (qsat < a2x%rAttr(kshum,n)) then
a2x%rAttr(kshum,n) = qsat
endif
else if (srh > 0) then
e = avstrm%rAttr(srh,n) * 0.01_R8 * datm_shr_esat(tbot,tbot)
qsat = (0.622_R8 * e)/(pbot - 0.378_R8 * e)
a2x%rAttr(kshum,n) = qsat
if(wiso_datm) then
! isotopic forcing
! For tracer specific humidity, lnd_import_mct expects a delta, so
! just keep the delta from the input file - TW
a2x%rAttr(kshum_16O,n) = avstrm%rAttr(srh_16O,n)
a2x%rAttr(kshum_18O,n) = avstrm%rAttr(srh_18O,n)
a2x%rAttr(kshum_HDO,n) = avstrm%rAttr(srh_HDO,n)
end if
else if (stdew > 0) then
if (tdewmax < 50.0_R8) avstrm%rAttr(stdew,n) = avstrm%rAttr(stdew,n) + tkFrz
e = datm_shr_esat(avstrm%rAttr(stdew,n),tbot)
qsat = (0.622_R8 * e)/(pbot - 0.378_R8 * e)
a2x%rAttr(kshum,n) = qsat
else
call shr_sys_abort(subname//'ERROR: cannot compute shum')
endif

I figure we can probably use the specific_total_water_0 field to calculate shum, but I'm not certain about the details here...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

specific total water in ace is defined as qv+qc+qi+qr (basically all water), but I think specific humidity here is just qv (vapor). I think this is somewhat important, so we shouldn't use specific total water (except for prelim testing)

Comment thread components/emulator_comps/eatm/src/ace_comp_mod.F90 Outdated
Comment thread components/emulator_comps/eatm/src/ace_comp_mod.F90 Outdated
Comment thread components/emulator_comps/eatm/src/ace_comp_mod.F90
ubot(i, j) = net_outputs(1, 24, i, j) ! U_0
vbot(i, j) = net_outputs(1, 32, i, j) ! V_0
tbot(i, j) = net_outputs(1, 8, i, j) ! T_0
ptem(i, j) = net_outputs(1, 8, i, j) ! T_0
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we can also calculate the potential temperature, e.g., https://en.wikipedia.org/wiki/Potential_temperature

Where for the EAM specific compsets below the following is supported
TIME = Time period (e.g. 2000, HIST, RCP8...)
ATM = [EAM, EAMXX, SATM, SCREAM]
ATM = [EAM, EAMXX, DATM, EATM, SATM, SCREAM]
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.

What does "EATM" stand for?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Emulated atmosphere, following the c onvention of data, stub, etc. atmospheres --- this pr isn't ready for review yet, we are working on addressing a few items internally first, but wanted to start iterating publicly #open-dev

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we are calling them "emulator_comps"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

sort of parallel to data_comps

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.

That's a good name for the directory holding them. It doesn't have to be 4 letters so how about "EMATM" to make it more obvious.

Copy link
Copy Markdown
Contributor

@mahf708 mahf708 Dec 18, 2025

Choose a reason for hiding this comment

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

I would vote to keep the following convention:

comp purpose
cmp active, physics (flagship version)
ecmp active, emulated (fast version)
dcmp "data" or just reading files
scmp "stub" or no-op
xcmp "dead" (only in testing)

but I don't care what what each specific one is called; note that eatm will (in the longer term) represent several of the emulated atmosphere models, not a specific one

Copy link
Copy Markdown
Contributor

@mahf708 mahf708 Dec 18, 2025

Choose a reason for hiding this comment

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

In other words, I think it is less than ideal to have "eam", "eamxx" and "scream" etc. as components (replacing atm). Those all should be just called atm as comps, and then once in the atm comp, one can decide if they want to do one eam, eamxx, scream, etc. --- it makes better sense to organize components that way imho

@@ -0,0 +1,132 @@
#!/usr/bin/env python3
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.

Thank you for not copying one of the perl versions of buildnml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I assume you're joking, right? lol

see components/emulator_comps/eatm/bld/build-namelist, but ideally, we should get rid of this

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just cut-and-paste!

@@ -0,0 +1,589 @@
#!/usr/bin/env perl
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.

Is this a copy of the EAM build-namelist? Why didn't you just copy the datm one which is all python?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was just cutting-and-pasting to get something working. Our first task was to get something working for Luke's scidac as quickly as possible, with the intent of cleaning it up later

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.

The question still stands. Why not copy the datm one? You don't need the complexity of the EAM namelist.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm happy to replace it once we get something working

Copy link
Copy Markdown
Contributor

@mahf708 mahf708 left a comment

Choose a reason for hiding this comment

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

@andrewdnolan, this is excellent! Thanks for the PR and the dilligent work with @jonbob on putting it together. I responded to all your questions. In short, they are nuanced. We have two pathways:

  1. Take easiset shortcuts to demostrate things are working, without worrying about scientific validity, and only assess if ace starts crashing like crazy
  2. Preemptively start assembling utils in a shared location that can do these calculations in a documented way

I'd defer to you to decide; I would obviously prefer 2 longer term, but happy to wait for it.

If you decide we should go for 2, let's briefly discuss how we want to do this. A mild personal preference is that we write these utils in C++ (not F90). Again, that's a longer term issue for me: I want us to move to C++ as soon as we are able to do so, and I'd rather see close to 0% code in F90. We can write these small utils/things in Python too.

Another important todo item (that can also wait, so no pressure to get it done now) is to start writing docs about what we are doing alongside PRs, i.e., in components/emulator_comps/docs; I'm happy to put these docs together once we are closer to integrating (unless you'd rather take the lead on this).

Let's keep iterating until we feel more confident. I have a few commits I'd like to push in the near future.

vbot(i, j) = net_outputs(1, 32, i, j) ! V_0
tbot(i, j) = net_outputs(1, 8, i, j) ! T_0
ptem(i, j) = net_outputs(1, 8, i, j) ! T_0
shum(i, j) = 0.0_R8 ! TBD
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

specific total water in ace is defined as qv+qc+qi+qr (basically all water), but I think specific humidity here is just qv (vapor). I think this is somewhat important, so we shouldn't use specific total water (except for prelim testing)

ubot(i, j) = net_outputs(1, 24, i, j) ! U_0
vbot(i, j) = net_outputs(1, 32, i, j) ! V_0
tbot(i, j) = net_outputs(1, 8, i, j) ! T_0
ptem(i, j) = net_outputs(1, 8, i, j) ! T_0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we can also calculate the potential temperature, e.g., https://en.wikipedia.org/wiki/Potential_temperature

Comment thread components/emulator_comps/eatm/src/ace_comp_mod.F90 Outdated
Comment thread components/emulator_comps/eatm/src/ace_comp_mod.F90 Outdated
Comment thread components/emulator_comps/eatm/src/ace_comp_mod.F90
Comment thread components/emulator_comps/eatm/src/ace_comp_mod.F90
@mahf708
Copy link
Copy Markdown
Contributor

mahf708 commented Jan 5, 2026

An alternative design of this, almost entirely in C++ is in: #7964

jonbob and others added 22 commits February 23, 2026 08:32
Switch to layer 7 (c.f. 0) for the "bottom" layer index
And load the ACE restart file as R4 array
stores eatm output at t_i-1 and t_i+1 emulator evaluation states
Needed b/c ACE provides data at 6-hour intervals, but coupling interval
can be much smaller than that (e.g. 30-minutes). Unles we linearly
interpolate the ACE prediction over the coupling interval the ACE
predicted changes are too large and cause stability issue for `ice`
model. Plus this ensure that the `net_output` array is synchronized with
the coupler clock.
Fixes issue where ACE output had large transience even
when forcing data was constant
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants