Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b3b248d
enable average fields
peverwhee Mar 2, 2026
a224991
write nstep0 separately
Mar 9, 2026
3c1ffa8
Merge branch 'development' of https://github.com/ESCOMP/CAM-SIMA into…
peverwhee Mar 9, 2026
342e6e2
Merge branch 'accumulated-fields' of https://github.com/peverwhee/CAM…
peverwhee Mar 9, 2026
ee32aa0
add min and max
peverwhee Mar 23, 2026
aa07873
Merge remote-tracking branch 'ESCOMP/development' into accumulated-fi…
peverwhee Mar 24, 2026
1788812
add fill value logic
peverwhee Apr 2, 2026
bb2308a
update buffers tag
peverwhee Apr 2, 2026
15d45e2
add stdev
peverwhee Apr 6, 2026
365d791
Merge remote-tracking branch 'ESCOMP/development' into accumulated-fi…
peverwhee Apr 6, 2026
d771fe7
do accumulation with r8 data
Apr 7, 2026
8283239
overwrite accum fields to inst when outputting every timestep
Apr 7, 2026
ad5b5a5
remove duplicated info in hist objects
Apr 9, 2026
248735b
fix bad field removal logic
Apr 9, 2026
6aa35a4
fix bad sampling logic
peverwhee Apr 14, 2026
5f977a7
add new history test
peverwhee Apr 16, 2026
311d80b
Merge remote-tracking branch 'ESCOMP/development' into accumulated-fi…
peverwhee Apr 20, 2026
216abc6
update history hash
peverwhee May 12, 2026
d064a55
address review comments; error during preview_namelist when duplicate…
May 14, 2026
4434be2
Merge remote-tracking branch 'ESCOMP/development' into accumulated-fi…
May 14, 2026
1fea7da
use history tag
May 14, 2026
8a29cbd
Merge branch 'development' of https://github.com/ESCOMP/CAM-SIMA into…
peverwhee May 14, 2026
070d1fe
Merge branch 'accumulated-fields' of https://github.com/peverwhee/CAM…
peverwhee May 14, 2026
dcd1dbf
remove unnecessary if
May 18, 2026
77d2e64
Merge branch 'accumulated-fields' of https://github.com/peverwhee/CAM…
peverwhee May 18, 2026
ee46125
Merge remote-tracking branch 'ESCOMP/development' into accumulated-fi…
peverwhee May 18, 2026
52df528
Merge remote-tracking branch 'ESCOMP/development' into accumulated-fi…
peverwhee May 18, 2026
e2b57eb
check for all possible one timestep options; fix typo
peverwhee May 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
fxrequired = AlwaysRequired
fxDONOTUSEurl = https://github.com/NCAR/ccpp-framework
[submodule "history"]
path = src/history/buffers
url = https://github.com/ESMCI/history_output
fxtag = history01_00
path = src/history/buffers
url = https://github.com/ESMCI/history_output
fxtag = history01_01
fxrequired = AlwaysRequired
fxDONOTUSEurl = https://github.com/ESMCI/history_output
[submodule "mpas"]
Expand All @@ -24,8 +24,8 @@
fxrequired = AlwaysRequired
fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics
[submodule "rrtmgp-data"]
path = src/physics/utils/rrtmgp-data
url = https://github.com/earth-system-radiation/rrtmgp-data.git
path = src/physics/utils/rrtmgp-data
url = https://github.com/earth-system-radiation/rrtmgp-data.git
fxrequired = AlwaysRequired
fxtag = v1.8
fxDONOTUSEurl = https://github.com/earth-system-radiation/rrtmgp-data.git
Expand Down Expand Up @@ -102,8 +102,8 @@
fxrequired = ToplevelRequired
fxDONOTUSEurl = https://github.com/ESCOMP/CESM_share
[submodule "tools/CUPiD"]
path = tools/CUPiD
url = https://github.com/NCAR/CUPiD.git
path = tools/CUPiD
url = https://github.com/NCAR/CUPiD.git
fxtag = v0.4.0
fxrequired = ToplevelRequired
fxDONOTUSEurl = https://github.com/NCAR/CUPiD.git
2 changes: 1 addition & 1 deletion cime_config/atm_in_paramgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -1410,7 +1410,7 @@ def append_user_nl_file(self, user_nl_file):
#End if (array indices)

#Extract value string:
val_str = ' '.join(line_ss[1:]) # the rest is the value string
val_str = ' '.join(line_ss[1:]).strip() # the rest is the value string

#Check if value string ends in array continuation:
if is_array:
Expand Down
76 changes: 60 additions & 16 deletions cime_config/hist_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,23 +345,34 @@ def __init__(self, volume, list_type, list_desc):
self.__field_names = []
self.__max_namelen = 0

def _add_item(self, item, pobj, logger):
def _add_item(self, item, pobj, full_field_list, logger):
"""Add field name, <item> to this object and return True if this
field name was added.
<item> is a single item to be added.
<pobj> is the ParseObject source of <items>.
<full_field_list> is the list of all fields for this volume
"""
if not _is_string(item)[0]:
errmsg = f"Bad diagnostic name, '{item}'"
pobj.add_syntax_err(errmsg)
return False
# end if
if item in self.__field_names:
# Field is a duplicate
ctx = context_string(pobj)
logger.warning(f"Field, '{item}' already in {self.desc} fields for hist volume, {self.volume}{ctx}")
return False
# end if
for field_list in full_field_list:
if item in field_list.__field_names:
if self == field_list:
# Field is a duplicate, same flag (so this is just a warning)
ctx = context_string(pobj)
logger.warning(f"Field, '{item}' already in {self.desc} fields for hist volume, {self.volume}{ctx}")
return False
else:
# Field is a duplicate, different flag (this is an error)
ctx = context_string(pobj)
emsg = f"Field, '{item}' already in {field_list.desc} fields for hist volume, {self.volume}. Cannot also add to {self.desc} fields for the same volume{ctx}"
pobj.add_syntax_err(emsg)
return False
# end if
# end if
# end for
self.__field_names.append(item)
self.__max_namelen = max(len(item), self.__max_namelen)
if logger.getEffectiveLevel() <= logging.DEBUG:
Expand All @@ -370,18 +381,19 @@ def _add_item(self, item, pobj, logger):
# end if
return True

def add_fields(self, items, pobj, logger):
def add_fields(self, items, pobj, full_field_list, logger):
"""Add <items> to this object and return True if all items were added.
<items> can be a single item or a list.
<pobj> is the ParseObject source of <items>
<full_field_list> is the list of all fields for this volume
"""
if isinstance(items, list):
do_add = True
for item in items:
do_add &= self._add_item(item, pobj, logger)
do_add &= self._add_item(item, pobj, full_field_list, logger)
# end for
else:
do_add = self._add_item(items, pobj, logger)
do_add = self._add_item(items, pobj, full_field_list, logger)
# end if
return do_add

Expand Down Expand Up @@ -409,7 +421,6 @@ def num_fields(self):
"""Return the number of fields in this HistFieldList object."""
return len(self.__field_names)


def output_nl_fieldlist(self, outfile, field_varname):
"""Output the field name of this HistFieldList object as a namelist
variable that is an array of strings.
Expand Down Expand Up @@ -633,36 +644,36 @@ def add_inst_fields(self, fields, pobj, logger):
HistoryVolConfig object.
Return True if it was okay to add <fields> to list of last fields.
"""
add_ok = self.__inst_fields.add_fields(fields, pobj, logger)
add_ok = self.__inst_fields.add_fields(fields, pobj, self.__all_fields, logger)
return add_ok

def add_avg_fields(self, fields, pobj, logger):
"""Add one or more time-averaged fields to this HistoryVolConfig
object.
Return True if it was okay to add <fields> to list of avg fields.
"""
add_ok = self.__avg_fields.add_fields(fields, pobj, logger)
add_ok = self.__avg_fields.add_fields(fields, pobj, self.__all_fields, logger)
return add_ok

def add_min_fields(self, fields, pobj, logger):
"""Add one or more min_fields to this HistoryVolConfig object.
Return True if it was okay to add <fields> to list of min fields.
"""
add_ok = self.__min_fields.add_fields(fields, pobj, logger)
add_ok = self.__min_fields.add_fields(fields, pobj, self.__all_fields, logger)
return add_ok

def add_max_fields(self, fields, pobj, logger):
"""Add one or more max_fields to this HistoryVolConfig object.
Return True if it was okay to add <fields> to list of max fields.
"""
add_ok = self.__max_fields.add_fields(fields, pobj, logger)
add_ok = self.__max_fields.add_fields(fields, pobj, self.__all_fields, logger)
return add_ok

def add_var_fields(self, fields, pobj, logger):
"""Add one or more var_fields to this HistoryVolConfig object.
Return True if it was okay to add <fields> to list of var fields.
"""
add_ok = self.__var_fields.add_fields(fields, pobj, logger)
add_ok = self.__var_fields.add_fields(fields, pobj, self.__all_fields, logger)
return add_ok

def remove_fields(self, fields, pobj, logger):
Expand All @@ -685,6 +696,32 @@ def remove_fields(self, fields, pobj, logger):
# end if
return all_removed

def convert_accumulated_fields(self, pobj, logger):
"""Move all accumulated fields to instantaneous field list"""
if self.__var_fields.num_fields() > 0:
self.__inst_fields.add_fields(self.__var_fields.field_names, pobj, [self.__inst_fields], logger)
var_field_list = list(self.__var_fields.field_names)
self.__var_fields.remove_fields(var_field_list, pobj, logger)
# end if

if self.__avg_fields.num_fields() > 0:
self.__inst_fields.add_fields(self.__avg_fields.field_names, pobj, [self.__inst_fields], logger)
avg_field_list = list(self.__avg_fields.field_names)
self.__avg_fields.remove_fields(avg_field_list, pobj, logger)
# end if

if self.__min_fields.num_fields() > 0:
self.__inst_fields.add_fields(self.__min_fields.field_names, pobj, [self.__inst_fields], logger)
min_field_list = list(self.__min_fields.field_names)
self.__min_fields.remove_fields(min_field_list, pobj, logger)
# end if

if self.__max_fields.num_fields() > 0:
self.__inst_fields.add_fields(self.__max_fields.field_names, pobj, [self.__inst_fields], logger)
max_field_list = list(self.__max_fields.field_names)
self.__max_fields.remove_fields(max_field_list, pobj, logger)
# end if

@property
def volume(self):
"""Return the volume for this HistoryVolConfig object"""
Expand Down Expand Up @@ -794,6 +831,13 @@ def set_output_frequency(self, ofreq, pobj, logger):
ctx = context_string(pobj)
logger.debug(f"Setting output_frequency to '{ofreq}'{ctx}")
# end if
# Convert accumulated fields to instantaneous fields if we're set
# to output every timestep
if (self.__output_freq == (1, 'nsteps') or
self.__output_freq == (1, 'nstep' ) or
self.__output_freq == (1, 'steps')):
self.convert_accumulated_fields(pobj, logger)
# end if
return True
# end if
emsg = f"Attempt to set unrecognized output_frequency, '{ofreq}'"
Expand Down
12 changes: 12 additions & 0 deletions cime_config/testdefs/testlist_cam.xml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,18 @@
</options>
</test>

<!-- History output test -->
<test compset="FKESSLER" grid="mpasa480_mpasa480" name="SMS_Ln9" testmods="cam/outfrq_kessler_mpas_derecho_history">
<machines>
<machine name="derecho" compiler="intel" category="aux_sima"/>
<machine name="derecho" compiler="gnu" category="aux_sima"/>
</machines>
<options>
<option name="wallclock">00:10:00</option>
<option name="comment">Test for both instantaneous and accumulated output.</option>
</options>
</test>

<!-- Multiple history tape test -->
<test compset="FKESSLER" grid="ne3pg3_ne3pg3_mg37" name="SMS_Ln9" testmods="cam/outfrq_se_cslam_multitape">
<machines>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./xmlchange CAM_LINKED_LIBS="-lmpas"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
debug_output=0
hist_add_inst_fields;h3: Q,T,U,V,PS
hist_add_avg_fields;h3: PSDRY
hist_add_max_fields;h3: PHIS
hist_add_min_fields;h3: PDEL, PDELDRY
hist_add_var_fields;h3: ZM, PRECT
Comment thread
nusbaume marked this conversation as resolved.
hist_output_frequency;h3: 2*nsteps
hist_write_nstep0;h3: .true.
2 changes: 1 addition & 1 deletion src/history/buffers
Loading
Loading