NCAR / ccpp-physics

GFS physics for CCPP
Other
58 stars 145 forks source link

Miscellaneous Bugfixes from NRL #954

Closed grantfirl closed 2 years ago

grantfirl commented 2 years ago

All of these changes originally came from https://github.com/NCAR/ccpp-physics/pull/772. These changes were split from the single precision work since they were unrelated, but they're still relevant and should be merged since they fix several bugs. @michalakes, @areinecke, and @matusmartini deserve the credit. My work was only to update it to the latest main and test it in FV3/SCM.

The first 4 commits do not change any UFS RT results. They represent the following:

  1. variable intent change and division by zero avoidance
  2. changes to LUNs to avoid errors with the Cray CCE compiler
  3. fix the LTP or extra top radiation layer functionality
  4. add capability to use host-provided random number seeds

The last commit introduces a change to SAS-based deep convection schemes to avoid negative qv. Any UFS RTs that use samfdeepcnv or sascnvn will need new baselines if this is merged. The following description is from @matusmartini:

This was a while back but if I remember correctly, it was to prevent negative QV resulting from overly deep overshooting mostly for relatively shallow updrafts with extremely deep overshoots. This change was before the parameter aafac was reduced from 10% to 5%, which helped but did not eliminate all of the negative values.

Digging through my notes with examples of updrafts with negative QV concentrations: Cloud base at 1.4 km above ground, level of neutral buoyancy ~3.5 km, with overshooting top is at 18 km! More points found with cloud base at ~0.6 km, level of neutral buoyancy ~2.5 km, with overshooting top at ~16 km!

The reason for the negative QV’s because of the approximations made in SAS:

First, the moisture content of the rising parcel if it was saturated (qrch) is approximated as the sum of saturated moisture (qeso) and a term that is directly proportional to buoyancy. Generally, overshooting layers are negatively buoyant, and so the sum of the two can < 0 if large buoyancies are present. Second, the convective overshooting level is estimated as the level where (0.1 * A_ktcon) < 0, where A_ktcon is the cloud work function at the level of neutral buoyancy (ktcon). The 0.1 is a tunable parameter (aafac) independent of the first approximation.

Moreover, there is no check that would stop this from happening in the overshooting layers. There is only a check on negative cloud mass flux (eta) in imfdeepcnv=2, but it only scans levels below the level of neutral buoyancy. There should strictly be a check for negative qrch also in overshooting layers in both options of imfdeepcnv 1 and 2. After playing around with both options 1 and 2 of SAS convection, I see several tuning knobs that can result in increased number of updrafts with negative qrch (all of them near the overshooting cloud top). The most important tuning parameter is the critical thickness of the calculated convection (cthk), which determines whether the convection is deep enough, otherwise it is inhibited. In option 1, this threshold is set to 150 hPa. In option 2, this threshold is increased to 200 hPa. Doing an experiment with the cthk increased to 200 hPa in option 1, eliminates most of the negatively moist parcels. And vice versa, decreasing cthk to 150 hPa in option 2, introduces a few negatively moist parcels. Similar result can be achieved by tuning the aafac parameter.

grantfirl commented 2 years ago

@JongilHan66 Please review the changes in SAS and see the description of the problem solved by @matusmartini in the PR description.

grantfirl commented 2 years ago

fixes https://github.com/NCAR/ccpp-physics/issues/955

JongilHan66 commented 2 years ago

@JongilHan66 Please review the changes in SAS and see the description of the problem solved by @matusmartini in the PR description. 1) to limit overshooting not to be deeper than the actual cloud, please initially set ktcon1(i)=ktcon(i) in addtion to matusmartini's changes [currrently ktcon1(i)=kmax(i) in samfdeepcnv.f and ktcon1(i)=kmax(i)-1 in sascnvn_run].

2) please do not limit q1, i.e., remove those changes in lines 3060-3061 of samfdeepcnv.f and lines 1882-1883 of sascnvn_run. This limit would cause a problem in global total water conservation. Also, any possible negative q1 is effectively removed in the latest samfdeepcnv version without hurting total water conservation.

grantfirl commented 2 years ago

@JongilHan66 Please review the changes in SAS and see the description of the problem solved by @matusmartini in the PR description.

  1. to limit overshooting not to be deeper than the actual cloud, please initially set ktcon1(i)=ktcon(i) in addtion to matusmartini's changes [currrently ktcon1(i)=kmax(i) in samfdeepcnv.f and ktcon1(i)=kmax(i)-1 in sascnvn_run].
  2. please do not limit q1, i.e., remove those changes in lines 3060-3061 of samfdeepcnv.f and lines 1882-1883 of sascnvn_run. This limit would cause a problem in global total water conservation. Also, any possible negative q1 is effectively removed in the latest samfdeepcnv version without hurting total water conservation.

Sure, @JongilHan66, I can make those changes. @matusmartini Do you think this modification will suit your purposes?

grantfirl commented 2 years ago

@JongilHan66 @matusmartini We could also potentially add a flag to control whether this overshooting limiter is active. Thoughts?

JongilHan66 commented 2 years ago

Since the overshooting layers are smaller than the cloud depth most of time, I don't think adding a flag for the overshooting limiter is necessary.

grantfirl commented 2 years ago

@JongilHan66 Can you verify that https://github.com/NCAR/ccpp-physics/pull/954/commits/19440817b331576b7696bd2cc2dd732f62ba9682 is what you had in mind please?

JongilHan66 commented 2 years ago

Yes, your modification is what I had in mind.

matusmartini commented 2 years ago

@JongilHan66 Please review the changes in SAS and see the description of the problem solved by @matusmartini in the PR description.

  1. to limit overshooting not to be deeper than the actual cloud, please initially set ktcon1(i)=ktcon(i) in addtion to matusmartini's changes [currrently ktcon1(i)=kmax(i) in samfdeepcnv.f and ktcon1(i)=kmax(i)-1 in sascnvn_run].
  2. please do not limit q1, i.e., remove those changes in lines 3060-3061 of samfdeepcnv.f and lines 1882-1883 of sascnvn_run. This limit would cause a problem in global total water conservation. Also, any possible negative q1 is effectively removed in the latest samfdeepcnv version without hurting total water conservation.

Sure, @JongilHan66, I can make those changes. @matusmartini Do you think this modification will suit your purposes?

This looks good! @grantfirl Thank you! @JongilHan66

JongilHan66 commented 2 years ago

@JongilHan66 Please review the changes in SAS and see the description of the problem solved by @matusmartini in the PR description.

  1. to limit overshooting not to be deeper than the actual cloud, please initially set ktcon1(i)=ktcon(i) in addtion to matusmartini's changes [currrently ktcon1(i)=kmax(i) in samfdeepcnv.f and ktcon1(i)=kmax(i)-1 in sascnvn_run].
  2. please do not limit q1, i.e., remove those changes in lines 3060-3061 of samfdeepcnv.f and lines 1882-1883 of sascnvn_run. This limit would cause a problem in global total water conservation. Also, any possible negative q1 is effectively removed in the latest samfdeepcnv version without hurting total water conservation.

Sure, @JongilHan66, I can make those changes. @matusmartini Do you think this modification will suit your purposes?

This looks good! @grantfirl Thank you! @JongilHan66

I've looked into the overshoot modification and found a problem. The line, 'tem1=zi(i,ktcon1(i))-zi(i,ktcon(i))', should be changed to 'tem1=zi(i,k)-zi(i,ktcon(i))' in both samfdeepcnv & sascnvn.

JongilHan66 commented 2 years ago

@JongilHan66 Please review the changes in SAS and see the description of the problem solved by @matusmartini in the PR description.

  1. to limit overshooting not to be deeper than the actual cloud, please initially set ktcon1(i)=ktcon(i) in addtion to matusmartini's changes [currrently ktcon1(i)=kmax(i) in samfdeepcnv.f and ktcon1(i)=kmax(i)-1 in sascnvn_run].
  2. please do not limit q1, i.e., remove those changes in lines 3060-3061 of samfdeepcnv.f and lines 1882-1883 of sascnvn_run. This limit would cause a problem in global total water conservation. Also, any possible negative q1 is effectively removed in the latest samfdeepcnv version without hurting total water conservation.

Sure, @JongilHan66, I can make those changes. @matusmartini Do you think this modification will suit your purposes?

This looks good! @grantfirl Thank you! @JongilHan66

I've looked into the overshoot modification and found a problem. The line, 'tem1=zi(i,ktcon1(i))-zi(i,ktcon(i))', should be changed to 'tem1=zi(i,k)-zi(i,ktcon(i))' in both samfdeepcnv & sascnvn.

Inboth samfdeepcnv & sascnvn, please modify them to more compact form and overshooting not to be deeper than half of the actual cloud as:

          if(aa2(i) < 0.) then
            ktcon1(i) = k
            flg(i) = .false.
          endif

!NRL MNM: Limit overshooting not to be deeper than the actual cloud
tem = zi(i,ktcon(i))-zi(i,kbcon(i)) tem1 = zi(i,ktcon1(i))-zi(i,ktcon(i)) if(tem1.ge.tem) then ktcon1(i) = k flg(i) = .false. endif

==>

          tem  = 0.5 * (zi(i,ktcon(i))-zi(i,kbcon(i)))
          tem1 = zi(i,k)-zi(i,ktcon(i))

!NRL MNM: Limit overshooting not to be deeper than half of the actual cloud if(aa2(i) < 0. .or. tem1 >= tem) then ktcon1(i) = k flg(i) = .false. endif

Thank you.

grantfirl commented 2 years ago

@JongilHan66 I think that I addressed your comments in https://github.com/NCAR/ccpp-physics/pull/954/commits/4cd35abbfca7f783e2e284ab1f597d15c6cb11bc if you'd like to verify.

JongilHan66 commented 2 years ago

@grantfirl I confirm the changes are correct and what I meant.