-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port SE dycore to CAMDEN #135
Conversation
…d_init' in SE dycore.
(Please note that this commit excludes a required Kessler physics and/or registry temperature tendency variable name change, which should be brought in separately. Until that change is implemented either registry.xml or kessler_update.meta must be modified manually.)
…ne namelist default value.
…fix namelist bug.
…process (Github issue #140).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, this turned out to be a huge project!
Lots of great work.
I have a bunch of questions, comments and some change requests.
@gold2718 this PR is ready to be reviewed again. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is my review based on 0f9daf1. My earlier comments were published prematurely by GitHub (I think it happened because I commented on a conversation while my review was in progress). Please add these changes to the previous ones and then ask for a re-review. Sorry for the confusion.
src/dynamics/utils/dyn_thermo.F90
Outdated
real(kind_phys) :: dp_dry_phys(i0:i1,j0:j1,k0:k1) | ||
real(kind_phys) :: dp_phys(i0:i1,j0:j1,k0:k1) | ||
real(kind_phys), allocatable :: ps(:,:) | ||
real(kind_phys), allocatable :: ptop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does a scalar real need to be allocatable
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, yes, because it is an optional input that needs to be converted, and so having it allocated (or not) is how the receiving subroutine knows whether the converted value is "present".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice technique but should probably document that intent in the code because I forgot and now I recall having the discussion a few weeks ago.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add this documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment has been added explaining why the scalar real variable is allocatable.
@gold2718 This code is ready for review again. Thanks! |
@@ -27,7 +29,7 @@ | |||
from cam_autogen import generate_init_routines | |||
|
|||
|
|||
# Determine regular rexpression type (for later usage in Config_string) | |||
# Determine regular rexpression type (for later usage in check_string_val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might be able to replace these checks with:
isinstance(<x>, re.Pattern)
which is more pythonic. Python seems to support this by documenting the re.Pattern class (https://docs.python.org/3/library/re.html#re-objects).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That re.Pattern
object doesn't appear to be available in Python 3.6 or earlier. We could restrict CAMDEN to Python 3.7 or later, but that would put us out-of-sync with CIME in terms of python requirements. I am already planning to create an issue describing the need to update the python version and listing all of the various associated code changes, so if you want I can include this change in that list.
Also, in terms of the python version, I have found that for a complete python version restriction to work we'll need to update the CIME tag to ensure that all shebangs are python3. Otherwise, at least on Izumi, there is at least one section in the CIME run sequence where the python version will automatically use the default python version (which is 2.7). I went ahead and added the code change needed for CAMDEN to still run on Izumi, which is also included in the python 3.7 modification list, but at this point I would like to avoid updating the CIME tag for this PR, given that we are so close already and most of these changes aren't really required for the SE dycore port. Let me know if you disagree, however. For now you can look at issue #156 for more info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed on #156 but I would say that we are overdue for a CIME upgrade so please make sure this is prioritized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is Xeno's review of a012973.
A few more tweaks please.
@gold2718 this PR is ready for re-review again. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of suggested changes but generally okay.
cime_config/cam_config.py
Outdated
# Check that all tuple elements are integers: | ||
for valid_val in valid_vals: | ||
if valid_val is not None and not isinstance(valid_val, int): | ||
emsg = ("ERROR: Valid value, '{}', for variable '{}', must be " | ||
"either None or an integer. Currently it is '{}'.") | ||
raise CamConfigTypeError(emsg.format(valid_val, name, type(valid_val))) | ||
# End if | ||
# End for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider checking all values:
# Check that all tuple elements are integers: | |
for valid_val in valid_vals: | |
if valid_val is not None and not isinstance(valid_val, int): | |
emsg = ("ERROR: Valid value, '{}', for variable '{}', must be " | |
"either None or an integer. Currently it is '{}'.") | |
raise CamConfigTypeError(emsg.format(valid_val, name, type(valid_val))) | |
# End if | |
# End for | |
# Check that all tuple elements are integers: | |
emsg = "" | |
for valid_val in valid_vals: | |
if valid_val is not None and not isinstance(valid_val, int): | |
emsg += ("ERROR: Valid value, '{}', for variable '{}', must be " | |
"either None or an integer. Currently it is '{}'.\n") | |
# End if | |
# End for | |
if emsg: | |
raise CamConfigTypeError(emsg.format(valid_val, name, type(valid_val))) | |
# end if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I swear that someday I'll remember to do this before the code review! All values are now checked.
cime_config/cam_config.py
Outdated
# Check that all tuple elements are integers: | ||
for valid_val in valid_vals: | ||
if valid_val is not None and not isinstance(valid_val, int): | ||
emsg = ("ERROR: Valid value, '{}', for variable '{}', must be " | ||
"either None or an integer. Currently it is '{}'.") | ||
raise CamConfigTypeError(emsg.format(valid_val, name, type(valid_val))) | ||
# End if | ||
# End for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nicer if you did "check that all tuple elements are integers".
# Check that all tuple elements are integers: | |
for valid_val in valid_vals: | |
if valid_val is not None and not isinstance(valid_val, int): | |
emsg = ("ERROR: Valid value, '{}', for variable '{}', must be " | |
"either None or an integer. Currently it is '{}'.") | |
raise CamConfigTypeError(emsg.format(valid_val, name, type(valid_val))) | |
# End if | |
# End for | |
emsg = "" | |
# Check that all tuple elements are integers: | |
for valid_val in valid_vals: | |
if valid_val is not None and not isinstance(valid_val, int): | |
emsg += ("ERROR: Valid value, '{}', for variable '{}', must be " | |
"either None or an integer. Currently it is '{}'.\n") | |
# End if | |
# End for | |
if emsg: | |
raise CamConfigTypeError(emsg.format(valid_val, name, type(valid_val))) | |
# end if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All elements are now checked (even if a bad value is found).
Adds the SE dycore to CAMDEN from CAM, including bug fixes that impacted the use of the dycore in CAMDEN.
Fixes #44
Fixes #71
Fixes #76
Fixes #78
Fixes #86
Fixes #136
Addresses #91
Addresses #123
Addresses #150
Tests ran:
Ran an
FKESSLER
compset atne5_ne5_mg37
andne5pg2_ne5pg2_mg37
(for CSLAM) resolution for five time steps for bothNTASKS=1
andNTASKS=2
pe layouts. Performed smoke tests with Intel, PGI, and NAG compilers, and ensured bit-for-bit reproducibility with CAM when using Intel. I also ran a regular null dycore kessler run to make sure I didn't break anything.It should be noted that in order to have bit-for-bit agreement the physics interfaces in CAM needed to be modified to more closely match CAMDEN (which was easier than modifying CAMDEN given that many of the interfaces were auto-generated). Those modifications (assuming you are using cam6_3_019) can be found on cheyenne here:
/glade/u/home/nusbaume/CAMDEN_backup_files/SE-dycore/bit-for-bit/cam_kessler
Finally, most of the lines of code being added by this PR are straight copies from CAM, particularly for files in the
dyn/se/dycore
directory. However, I did make minor modifications to most of those files, so it might be easiest to review this PR by diffing these files with the same files from CAM (tag = cam6_3_019). Of course if you really want to review the entire SE dycore then I certainly won't stop you.Anyways, thanks in advance for your comments and suggestions, and have a great day!