Skip to content
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

sensible+latent heatfluxes using linear bulk formula #371

Merged
merged 21 commits into from
Sep 23, 2021

Conversation

mhrib
Copy link
Contributor

@mhrib mhrib commented Sep 14, 2021

See Also: CICE-Consortium/CICE#633

PR checklist

  • Short (1 sentence) summary of your PR:
    For stability boundary layer (atmbndy='default'): Use "traditional" linear bulk formula for sensible+latent heat fluxes but preserve stress formulation.
  • Developer(s):
    @mhrib
  • Suggest PR reviewers from list in the column to the right.
    @apcraig @eclare108213
  • Please copy the PR test results link or provide a summary of testing completed below.
    77 measured results of 77 total results
    77 of 77 tests PASSED
    0 of 77 tests PENDING
    0 of 77 tests MISSING data
    0 of 77 tests FAILED
  • How much do the PR code changes differ from the unmodified code?
    • bit for bit (for default settings)
    • different at roundoff level
    • more substantial
  • Does this PR create or have dependencies on CICE or any other models?
    • Yes ( affects both CICE and Icepack)
    • No
  • Does this PR add any new test cases?
    • Yes
    • No
  • Is the documentation being updated? ("Documentation" includes information on the wiki or in the .rst files from doc/source/, which are used to create the online technical docs at https://readthedocs.org/projects/cice-consortium-cice/.)
    • Yes
    • No, does the documentation need to be updated at a later time?
      • Yes
      • No
  • Please provide any additional information or relevant details below:

By introducing the "simpler" linear bulk formula for sensible+latent heat fluxes, but preserve the temperature/humidity formulation for stress, the DMI-HYCOM-CICE (ERA5) code got more stable for long runs (several of years) without significant changes in the overall sea-ice cover/thickness. Without these modifications, the "Flux Error" (ferr) - rarely - became very high in special circumstances with low wind speeds and Tair>Tocn. In these situations the Jordan et al (1999) formulation might have it's limitations. These high Flux Errors seems to dissapear with the simpler formulations for sensible and latent heatfluxes for our setup at least.

The results are not BFB with the new setting turned on. However it is implemented turned off, which results in BFB results compared to the unmodified code.

NOTE:

Copy link
Contributor

@eclare108213 eclare108213 left a comment

Choose a reason for hiding this comment

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

Let's discuss the namelist implementation. A couple other comments.

There should also be changes to Icepack's documentation, in particular noting the additional option where sensible and latent heat are presented. See sections 2.1.1 and 2.7.2. (edited to correct section number)

shcoef = (1.20e-3_dbl_kind)*cp_air*rhoa*vmag
lhcoef = (1.50e-3_dbl_kind)*Lheat *rhoa*vmag
else
!- Use Jordan et al (JGR, 1999) formulation
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the ref to Jordan in the comment. That's referring to a small modification of the overall turbulent heat flux calculation, which came from somewhere else (documented in readthedocs, I hope).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done...


logical (kind=log_kind), public :: &
calc_strair = .true. , & ! if true, calculate wind stress
formdrag = .false. , & ! if true, calculate form drag
heatflux_linear = .false. , & ! if true, calculate sensible+latent heatfluxes using traditional linear bulk formula
Copy link
Contributor

Choose a reason for hiding this comment

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

As noted in the CICE PR, maybe there could be a third option for atmbndy instead of the new heatflux_linear flag.

Copy link
Contributor

Choose a reason for hiding this comment

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

If a namelist/argument exists that we can leverage to set this new option, that's preferable to creating a new namelist/argument when it makes sense.

Copy link
Contributor Author

@mhrib mhrib Sep 15, 2021

Choose a reason for hiding this comment

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

Rewritten using 'atmbndy' namelist variable as suggested.

@eclare108213
Copy link
Contributor

Does this fix #149?

@mhrib
Copy link
Contributor Author

mhrib commented Sep 15, 2021

Not sure whether it fixes #149. But this specific implementation is also discussed further in #361 with figures pointing out the where the extreme values stems from.

@mhrib mhrib changed the title sensible+latent heatfluxes using traditional bulk formula sensible+latent heatfluxes using linear bulk formula Sep 15, 2021
@mhrib
Copy link
Contributor Author

mhrib commented Sep 15, 2021

Update code using 'atmnbdy' which now allows three options: 'similarity' (default), 'constant', or 'mixed'
Also update documentation section 3.4.3.9.forcing_nml with the above info

Copy link
Contributor

@eclare108213 eclare108213 left a comment

Choose a reason for hiding this comment

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

I like this much better, thanks. My only request is to provide a little more information in the documentation. In the “Atmosphere” section 2.1.1, add a note about the different options. E.g. at the end of the third paragraph (add/fix formatting for readthedocs)

… The resulting equations are provided here for the default boundary layer scheme, which is based on Monin-Obukhov theory (atmbndy = ‘stability’). Alternatively, atmbndy = ‘constant’ provides constant coefficients for wind stress, sensible heat and latent heat calculations; atmbndy = ‘mixed’ uses the stability based calculation for wind stress and constant coefficients for sensible and latent heat fluxes.

@mhrib
Copy link
Contributor Author

mhrib commented Sep 16, 2021

Updated:

  1. Update “Atmosphere” section 2.1.1 with almost the suggested text.
  2. Abort if 'atmbndy' setting is unknown
  3. For backward compability: 'atmbndy'=default is renamed to similarity

Copy link
Member

@phil-blain phil-blain left a comment

Choose a reason for hiding this comment

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

Hi @mhrib, I think this looks good in general; I left a few comments / suggestions below.

@@ -952,7 +960,7 @@ subroutine icepack_atm_boundary(sfctype, &
delt, delq, &
lhcoef, shcoef )
if (icepack_warnings_aborted(subname)) return
else ! default
else ! 'similarity' or 'mixed'
Copy link
Member

Choose a reason for hiding this comment

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

I notice that this change is backwards compatible, in the sense that if someone still has atmdndy=default in their namelist, the code will continue to work as before, since nowhere in the code do we check explicitely if (atmbndy == 'default'), it's in the  else branch of if (atmbndy == 'constant'). So I think this is nice.

@@ -250,7 +250,7 @@ module icepack_parameters
TTTocn = 5107.4_dbl_kind ! for qsat over ocn

character (len=char_len), public :: &
atmbndy = 'default' ! atmo boundary method, 'default' ('ccsm3') or 'constant'
atmbndy = 'similarity' ! atmo boundary method, 'similarity' ('ccsm3'), 'constant' or 'mixed'
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should use this opportunity ("while we're here" kind of thing) to remove the ('ccsm3') in the comment (and do the same in icepack_init_parameters.) It has been there ever since the first commit (6f98a36) but 'ccsm3' was never a value for 'atmbndy', at least not in Icepack.

In fact it dates back to this commit: CICE-Consortium/CICE-svn-trunk@dfa799d and so it was never an acceptable value at all!

@@ -646,12 +646,12 @@ subroutine icepack_init_parameters( &
TTTocn_in ! for qsat over ocn

character (len=*), intent(in), optional :: &
atmbndy_in ! atmo boundary method, 'default' ('ccsm3') or 'constant'
atmbndy_in ! atmo boundary method, 'default' ('ccsm3') or 'constant'
Copy link
Member

Choose a reason for hiding this comment

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

Sorry to be picky, would it be possible to not introduce whitespace changes ? It adds noise to the diff (even though we can hide it in the GitHub UI or with git diff options, it is still an additional step to take).

"``atmbndy``", "``constant``", "bulk transfer coefficients", "``default``"
"", "``default``", "stability-based boundary layer", ""
"``atmbndy``", "string", "bulk transfer coefficients", "``similarity``"
"", "``similarity``", "stability-based boundary layer", ""
Copy link
Member

Choose a reason for hiding this comment

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

Maybe here we could add something like

Suggested change
"", "``similarity``", "stability-based boundary layer", ""
"", "``similarity``", "stability-based boundary layer (previously: `default`)", ""

to help users that could be confused by their existing namelist having a now undocumented default value ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From CICE this is automatically changed from 'default' to 'similarity' together with a WARNING message printed to the log/stdout.

@phil-blain
Copy link
Member

Sorry, I sent my review as you were pushing an updated version, so some of my feedback is already addressed :)

Comment on lines 953 to 956
if (trim(atmbndy) == 'default') then
atmbndy = 'similarity' ! For backward compability only ...
endif

Copy link
Member

Choose a reason for hiding this comment

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

It's a good idea to keep backwards compatibility.
But I think that we now tend to do this kind of treatment directly in ice_init (in CICE, probably in Icepack the equivalent would be in icedrv_init)...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FYI. It is also done in CICE. So running CICE, you'll never ends up here - unless it is later changed in CICE.
If backward compatibility is only relevant for CICE, I'll suggest to remove this "default=similarity" from ICEPACK.

Comment on lines 987 to 990
else
call icepack_warnings_add( &
subname//' atmbndy = '//trim(atmbndy)//' : unknown value')
call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
Copy link
Member

Choose a reason for hiding this comment

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

... and the same thing here, maybe checking for unknown values should also be in icedrv_init ? @apcraig @eclare108213 do we want to standardize on that for new code also in Icepack ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I raised this issue too. We don't generally check "valid values" in Icepack. There is quite a bit of that in CICE and the icepack driver. However, users that incorporate Icepack in their own driver (like E3SM) will have to implement their own checking and won't be able to rely on Icepack to let them know if something is "off". We might want to think about implementing explicit checks for Icepack arguments where it makes sense and is easy. The would be a significant change but probably wouldn't change the model cost if done well (like checking values only when they are initialized/set or adding appropriate aborts in existing if logic). But I think that is something we should discuss more broadly, create an issue if needed, and agree on general strategy before moving forward.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree, no need to do this check here, or even in this PR. In my opinion it would be better to keep the original behavior (just the 'else' without values) so that 'similarity' or 'mixed' (or 'default' / anything else) would all work. Long ago, I treated default conditions in the code as exactly that -- it didn't matter what the flag was set to -- as long as it wasn't something specific (like 'constant') then the code would execute the default behavior. Setting the flag to 'default' in the namelist file only made that explicit. We seem to be moving to a more rigorous implementation, which is fine. I prefer to do namelist value checking upon initialization, for better efficiency during the timestepping. As @apcraig says, it's better for now to plan to address this value-checking issue more generally and not worry about it here. The easiest thing to do now is keep the original behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated without checking atmbndy valid setting: 'constant' or 'mixed'. Anything else end in 'similarity' behavior.

doc/source/science_guide/sg_boundary_forcing.rst Outdated Show resolved Hide resolved
Comment on lines 987 to 990
else
call icepack_warnings_add( &
subname//' atmbndy = '//trim(atmbndy)//' : unknown value')
call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree, no need to do this check here, or even in this PR. In my opinion it would be better to keep the original behavior (just the 'else' without values) so that 'similarity' or 'mixed' (or 'default' / anything else) would all work. Long ago, I treated default conditions in the code as exactly that -- it didn't matter what the flag was set to -- as long as it wasn't something specific (like 'constant') then the code would execute the default behavior. Setting the flag to 'default' in the namelist file only made that explicit. We seem to be moving to a more rigorous implementation, which is fine. I prefer to do namelist value checking upon initialization, for better efficiency during the timestepping. As @apcraig says, it's better for now to plan to address this value-checking issue more generally and not worry about it here. The easiest thing to do now is keep the original behavior.

@mhrib
Copy link
Contributor Author

mhrib commented Sep 17, 2021

Updated without checking atmbndy valid setting: Choices: 'constant' or 'mixed'. Anything else end in 'similarity' behavior.

NOTE: atmbndy is checked for valid settings within CICE (ice_init.F90). This includes changing 'default' to 'similarity' for backward compatibility. This does, somehow, follow the original treatment of 'default' settings as explained by @eclare108213 .

@@ -3,5 +3,5 @@ kstrength = 0
krdg_partic = 0
krdg_redist = 0
formdrag = .false.
atmbndy = 'constant'
atmbndy = 'similarity'
Copy link
Contributor

Choose a reason for hiding this comment

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

This changes the behavior of at least one test in the test suites. Is that intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was an error from my site. Will revert atmbndy to constant

!- Use constant coefficients for sensible and latent heat fluxes
! similar to atmo_boundary_const but using vmag instead of wind
shcoef = (1.20e-3_dbl_kind)*cp_air*rhoa*vmag
lhcoef = (1.50e-3_dbl_kind)*Lheat *rhoa*vmag
Copy link
Contributor

@proteanplanet proteanplanet Sep 17, 2021

Choose a reason for hiding this comment

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

If possible, please remove literal constants from the code (here 1.20e-3_dbl_kind and 1.50e-3_dbl_kind) and place them in the Icepack constants file. I appreciate this is already done in atmo_boundary_const, but if we leave two sets of identical literal constants in the code, the code is susceptible to errors creeping in if further changes are made by another developer to just one set of constants.

Copy link
Contributor Author

@mhrib mhrib Sep 20, 2021

Choose a reason for hiding this comment

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

Good point w.r.t. secure code for future errors by placing the identical parameters in one place.
Will introduce p0012 and p0015.

shcoef = (1.20e-3_dbl_kind)*cp_air*rhoa*wind
lhcoef = (1.50e-3_dbl_kind)*Lheat *rhoa*wind
shcoef = p0012*cp_air*rhoa*wind
lhcoef = p0015*Lheat *rhoa*wind
Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for changing these constants in both places - this one should have been done a long time ago. I want to ask @proteanplanet whether this is what he had in mind, or if he was thinking of using a general constant (like senscoef and latntcoef, for example) that could be included in namelist, rather than the numerical equivalents. I'm fine with it like this - we can change it later if desired.

Copy link
Contributor Author

@mhrib mhrib Sep 23, 2021

Choose a reason for hiding this comment

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

Good point, which I did not entirely catch from the start.
Changed "general constants" p0012, p0015 to "specific constants" senscoef, latncoef.
(p0012/p0015 not used elsewhere)

Copy link
Contributor

Choose a reason for hiding this comment

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

@eclare108213 @mhrib Yes, this is fine, and what I had in mind.

@eclare108213 eclare108213 merged commit f9c9e48 into CICE-Consortium:master Sep 23, 2021
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.

5 participants