CAM computes enthalpy to send to BLOM#62
CAM computes enthalpy to send to BLOM#62mvertens wants to merge 8 commits intoNorESMhub:noresm_developfrom
Conversation
Resolve pcols / ncol conflict. Fix mismatch where some arrays in an equation used ':' as the first dimension while others used ':ncol'. This fails when ncol /= pcols which happens when there is an unfilled chunk on any task. Addresses NorESMhub/CAM#233 May fix NorESMhub/CAM#180
gold2718
left a comment
There was a problem hiding this comment.
Some questions, some optimization ideas, and at least one code section that does not look right.
src_cam/physpkg.F90
Outdated
| ifld = pbuf_get_index('ENTHALPY_PREC_AC', errcode=i) | ||
| if (ifld>0) call pbuf_set_field(pbuf, ifld, 0._r8) |
There was a problem hiding this comment.
Why ask for ifld when there is already a module variable for it? Also, if ifld <= 0, isn't that an error since the pbuf field is added using the same logical (computer_enthalpy_flux)?
| ifld = pbuf_get_index('ENTHALPY_PREC_AC', errcode=i) | |
| if (ifld>0) call pbuf_set_field(pbuf, ifld, 0._r8) | |
| if (enthalpy_prec_ac_idx > 0) then | |
| call pbuf_set_field(pbuf, ifld, 0._r8) | |
| else | |
| call endrun('pbuf field, ENTHALPY_PREC_AC, not defined') | |
| end if |
There was a problem hiding this comment.
I don't think we need the check for > 0 since the pbuf_add_field for ENTHALPY_PREC_AC is in this module and only occurs if compute_enthalpy_flux is .true.
src_cam/physpkg.F90
Outdated
| integer :: enthalpy_prec_bc_idx = 0 | ||
| integer :: enthalpy_prec_ac_idx = 0 | ||
| integer :: enthalpy_evop_idx = 0 |
There was a problem hiding this comment.
These variables should be public, protected and used from check_energy.F90 and camsrfexch.F90 instead of calling pbuf_get_index there (or later in this module).
There was a problem hiding this comment.
I have put these in phys_init.
src_cam/physpkg.F90
Outdated
| integer :: enthalpy_evop_idx = 0 | ||
| integer :: qcsedten_idx=0, qrsedten_idx=0 | ||
| integer :: qisedten_idx=0, qssedten_idx=0, qgsedten_idx=0 | ||
| integer :: qrain_mg_idx=0, qsnow_mg_idx=0 |
There was a problem hiding this comment.
These variables should be public, protected and used from check_energy.F90 instead of calling pbuf_get_index there (or later in this module).
There was a problem hiding this comment.
I have put setting this in phys_init.
src_cam/physpkg.F90
Outdated
| call pbuf_get_field(pbuf, qssedten_idx, qssedten) | ||
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:)-qssedten(:ncol,:) | ||
| endif | ||
| if (qgsedten_idx.gt.0) then |
There was a problem hiding this comment.
Please update syntax:
| if (qgsedten_idx.gt.0) then | |
| if (qgsedten_idx > 0) then |
src_cam/physpkg.F90
Outdated
| qrain_mg_idx = pbuf_get_index('qrain_mg' , errcode=i) | ||
| qsnow_mg_idx = pbuf_get_index('qsnow_mg' , errcode=i) |
There was a problem hiding this comment.
These should also be moved to phys_init. Also, I think the errcode=i optional input should be dropped since the return code is not being checked. Without that, a failure results in a call to endrun while this version would fail silently.
| endif | ||
| endif |
There was a problem hiding this comment.
Please restore spaces (nit pick):
| endif | |
| endif | |
| end if | |
| end if |
| call cnst_get_ind('Q', ixq) | ||
| call cnst_get_ind('CLDLIQ', ixcldliq) | ||
| call cnst_get_ind('CLDICE', ixcldice) |
There was a problem hiding this comment.
Bit of potential cleanup:
Move ixq, ixcldliq and ixcldice to be module variables, move the cnst_get_ind calls to phys_init (including from tphysbc), and remove them from the run-time routines.
src_cam/physpkg.F90
Outdated
| if (compute_enthalpy_flux) then | ||
| ! In first time-step tphysac variables need to be zero'd out | ||
| if (compute_enthalpy_flux) then |
There was a problem hiding this comment.
Something seems wrong here since the inner if statement is the same as the outer one. The comment mentions "first time-step" but the logic does not reflect that.
gold2718
left a comment
There was a problem hiding this comment.
Overall, this is much better!
There are still some items from the first review plus a few new ones.
| qcsedten_idx = pbuf_get_index('QCSEDTEN', ierr) | ||
| qrsedten_idx = pbuf_get_index('QRSEDTEN', ierr) | ||
| qisedten_idx = pbuf_get_index('QISEDTEN', ierr) | ||
| qssedten_idx = pbuf_get_index('QSSEDTEN', ierr) | ||
| qgsedten_idx = pbuf_get_index('QGSEDTEN', ierr) |
There was a problem hiding this comment.
You should either check the ierr return values or leave them out (which calls endrun for any field not found).
| qcsedten_idx = pbuf_get_index('QCSEDTEN', ierr) | |
| qrsedten_idx = pbuf_get_index('QRSEDTEN', ierr) | |
| qisedten_idx = pbuf_get_index('QISEDTEN', ierr) | |
| qssedten_idx = pbuf_get_index('QSSEDTEN', ierr) | |
| qgsedten_idx = pbuf_get_index('QGSEDTEN', ierr) | |
| qcsedten_idx = pbuf_get_index('QCSEDTEN') | |
| qrsedten_idx = pbuf_get_index('QRSEDTEN') | |
| qisedten_idx = pbuf_get_index('QISEDTEN') | |
| qssedten_idx = pbuf_get_index('QSSEDTEN') | |
| qgsedten_idx = pbuf_get_index('QGSEDTEN') |
| real(r8), dimension(pcols,pver) :: qrain_mg_macmic , qsnow_mg_macmic | ||
| integer :: m_cnst | ||
| real(r8):: hflx_iref(pcols) | ||
| character(50) :: physparname |
There was a problem hiding this comment.
This should use len= and maybe a standard value:
| character(50) :: physparname | |
| character(len=CS) :: physparname |
or
| character(50) :: physparname | |
| character(len=16) :: physparname |
| if (qcsedten_idx > 0) then | ||
| call pbuf_get_field(pbuf, qcsedten_idx, qcsedten) | ||
| qrain_mg_macmic(:ncol,:) = qrain_mg_macmic(:ncol,:) - qcsedten(:ncol,:) | ||
| endif | ||
| if (qrsedten_idx > 0) then | ||
| call pbuf_get_field(pbuf, qrsedten_idx, qrsedten) | ||
| qrain_mg_macmic(:ncol,:) = qrain_mg_macmic(:ncol,:) - qrsedten(:ncol,:) | ||
| endif | ||
| if (qisedten_idx > 0) then | ||
| call pbuf_get_field(pbuf, qisedten_idx, qisedten) | ||
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qisedten(:ncol,:) | ||
| endif | ||
| if (qssedten_idx > 0) then | ||
| call pbuf_get_field(pbuf, qssedten_idx, qssedten) | ||
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qssedten(:ncol,:) | ||
| endif | ||
| if (qgsedten_idx > 0) then | ||
| call pbuf_get_field(pbuf, qgsedten_idx, qgsedten) | ||
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qgsedten(:ncol,:) | ||
| endif |
There was a problem hiding this comment.
If you apply the suggestion back at 968 - 972, you can save a lot of logic here.
| if (qcsedten_idx > 0) then | |
| call pbuf_get_field(pbuf, qcsedten_idx, qcsedten) | |
| qrain_mg_macmic(:ncol,:) = qrain_mg_macmic(:ncol,:) - qcsedten(:ncol,:) | |
| endif | |
| if (qrsedten_idx > 0) then | |
| call pbuf_get_field(pbuf, qrsedten_idx, qrsedten) | |
| qrain_mg_macmic(:ncol,:) = qrain_mg_macmic(:ncol,:) - qrsedten(:ncol,:) | |
| endif | |
| if (qisedten_idx > 0) then | |
| call pbuf_get_field(pbuf, qisedten_idx, qisedten) | |
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qisedten(:ncol,:) | |
| endif | |
| if (qssedten_idx > 0) then | |
| call pbuf_get_field(pbuf, qssedten_idx, qssedten) | |
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qssedten(:ncol,:) | |
| endif | |
| if (qgsedten_idx > 0) then | |
| call pbuf_get_field(pbuf, qgsedten_idx, qgsedten) | |
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qgsedten(:ncol,:) | |
| endif | |
| call pbuf_get_field(pbuf, qcsedten_idx, qcsedten) | |
| qrain_mg_macmic(:ncol,:) = qrain_mg_macmic(:ncol,:) - qcsedten(:ncol,:) | |
| call pbuf_get_field(pbuf, qrsedten_idx, qrsedten) | |
| qrain_mg_macmic(:ncol,:) = qrain_mg_macmic(:ncol,:) - qrsedten(:ncol,:) | |
| call pbuf_get_field(pbuf, qisedten_idx, qisedten) | |
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qisedten(:ncol,:) | |
| call pbuf_get_field(pbuf, qssedten_idx, qssedten) | |
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qssedten(:ncol,:) | |
| call pbuf_get_field(pbuf, qgsedten_idx, qgsedten) | |
| qsnow_mg_macmic(:ncol,:) = qsnow_mg_macmic(:ncol,:) - qgsedten(:ncol,:) |
| call get_hydrostatic_energy(state%q(1:ncol,1:pver,1:pcnst),.true., & | ||
| state%pdel(1:ncol,1:pver), cp_or_cv_dycore(:ncol,:,lchnk), & | ||
| state%u(1:ncol,1:pver), state%v(1:ncol,1:pver), state%T(1:ncol,1:pver),& | ||
| vc_dycore, ptop=state%pintdry(1:ncol,1), phis = state%phis(1:ncol), & | ||
| te = te_init(:ncol,1,lchnk), se=te_init(:ncol,2,lchnk), po=te_init(:ncol,3,lchnk), ke=te_init(:ncol,4,lchnk)) |
There was a problem hiding this comment.
I do not think you need to pass the se, p0, or ke arguments as they are never used.
Only te_init(:,1,:) is used and I want to remove that second dimension (also see xxx comments in air_composition.F90). I realize this will not compile without also changing the CAM code but it seems reasonable.
Also, the lower bounds on some of these array references is not needed, can the use be made consistent?
| call get_hydrostatic_energy(state%q(1:ncol,1:pver,1:pcnst),.true., & | |
| state%pdel(1:ncol,1:pver), cp_or_cv_dycore(:ncol,:,lchnk), & | |
| state%u(1:ncol,1:pver), state%v(1:ncol,1:pver), state%T(1:ncol,1:pver),& | |
| vc_dycore, ptop=state%pintdry(1:ncol,1), phis = state%phis(1:ncol), & | |
| te = te_init(:ncol,1,lchnk), se=te_init(:ncol,2,lchnk), po=te_init(:ncol,3,lchnk), ke=te_init(:ncol,4,lchnk)) | |
| call get_hydrostatic_energy(state%q(:ncol,:pver,:pcnst),.true., & | |
| state%pdel(:ncol,1:pver), cp_or_cv_dycore(:ncol,:,lchnk), & | |
| state%u(:ncol,:pver), state%v(:ncol,:pver), state%T(:ncol,:pver),& | |
| vc_dycore, ptop=state%pintdry(:ncol,1), phis = state%phis(:ncol), & | |
| te = te_init(:ncol,lchnk)) |
|
|
||
| if (compute_enthalpy_flux) then | ||
| ! In first time-step tphysac variables need to be zero'd out | ||
| call pbuf_set_field(pbuf, ifld, 0._r8) |
There was a problem hiding this comment.
What is ifld supposed to be here? ifld is set to the index of different pbuf fields above, which is this? Should it be an enthalpy-specific pbuf? All of them? Right now, it is probably FRACIS but who knows for sure?
| if (compute_enthalpy_flux) then | ||
| call cam_export(state, cam_out, pbuf, cam_in=cam_in) | ||
| else | ||
| call cam_export(state, cam_out, pbuf) | ||
| end if |
There was a problem hiding this comment.
I am not a fan of this method of communicating the enthalpy flag to cam_export. Instead of using the passing of cam_in, can you make cam_in a required (not optional) input to cam_export and use compute_enthalpy_flux in place of present(cam_in)?
| if (compute_enthalpy_flux) then | |
| call cam_export(state, cam_out, pbuf, cam_in=cam_in) | |
| else | |
| call cam_export(state, cam_out, pbuf) | |
| end if | |
| call cam_export(state, cam_out, pbuf, cam_in) |
This PR supersedes PR #58