-
Notifications
You must be signed in to change notification settings - Fork 134
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
Refactor optional argument implementation for isotopes, snwgrain, therm1 and therm2 #423
Changes from all commits
fb45b9e
7b2ad22
0c57334
9e28d92
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,13 +13,14 @@ | |
module icepack_atmo | ||
|
||
use icepack_kinds | ||
use icepack_parameters, only: c0, c1, c2, c4, c5, c8, c10 | ||
use icepack_parameters, only: c16, c20, p001, p01, p2, p4, p5, p75, puny | ||
use icepack_parameters, only: senscoef, latncoef | ||
use icepack_parameters, only: cp_wv, cp_air, iceruf, zref, qqqice, TTTice, qqqocn, TTTocn | ||
use icepack_parameters, only: Lsub, Lvap, vonkar, Tffresh, zvir, gravit | ||
use icepack_parameters, only: pih, dragio, rhoi, rhos, rhow | ||
use icepack_parameters, only: c0, c1, c2, c4, c5, c8, c10 | ||
use icepack_parameters, only: c16, c20, p001, p01, p2, p4, p5, p75, puny | ||
use icepack_parameters, only: senscoef, latncoef | ||
use icepack_parameters, only: cp_wv, cp_air, iceruf, zref, qqqice, TTTice, qqqocn, TTTocn | ||
use icepack_parameters, only: Lsub, Lvap, vonkar, Tffresh, zvir, gravit | ||
use icepack_parameters, only: pih, dragio, rhoi, rhos, rhow | ||
use icepack_parameters, only: atmbndy, calc_strair, formdrag | ||
use icepack_parameters, only: icepack_chkoptargflag | ||
use icepack_tracers, only: n_iso | ||
use icepack_tracers, only: tr_iso | ||
use icepack_warnings, only: warnstr, icepack_warnings_add | ||
|
@@ -61,7 +62,6 @@ subroutine atmo_boundary_layer (sfctype, & | |
Cdn_atm, & | ||
Cdn_atm_ratio_n, & | ||
Qa_iso, Qref_iso, & | ||
iso_flag, & | ||
uvel, vvel, & | ||
Uref, zlvs ) | ||
|
||
|
@@ -103,13 +103,10 @@ subroutine atmo_boundary_layer (sfctype, & | |
shcoef , & ! transfer coefficient for sensible heat | ||
lhcoef ! transfer coefficient for latent heat | ||
|
||
logical (kind=log_kind), intent(in), optional :: & | ||
iso_flag ! flag to trigger iso calculations | ||
|
||
real (kind=dbl_kind), intent(in), optional, dimension(:) :: & | ||
real (kind=dbl_kind), intent(in), dimension(:), optional :: & | ||
Qa_iso ! specific isotopic humidity (kg/kg) | ||
|
||
real (kind=dbl_kind), intent(inout), optional, dimension(:) :: & | ||
real (kind=dbl_kind), intent(inout), dimension(:), optional :: & | ||
Qref_iso ! reference specific isotopic humidity (kg/kg) | ||
|
||
real (kind=dbl_kind), intent(in) :: & | ||
|
@@ -167,16 +164,8 @@ subroutine atmo_boundary_layer (sfctype, & | |
real (kind=dbl_kind), parameter :: & | ||
zTrf = c2 ! reference height for air temp (m) | ||
|
||
logical (kind=log_kind) :: & | ||
l_iso_flag ! local flag to trigger iso calculations | ||
|
||
character(len=*),parameter :: subname='(atmo_boundary_layer)' | ||
|
||
l_iso_flag = .false. | ||
if (present(iso_flag)) then | ||
l_iso_flag = iso_flag | ||
endif | ||
|
||
al2 = log(zref/zTrf) | ||
|
||
!------------------------------------------------------------ | ||
|
@@ -389,21 +378,13 @@ subroutine atmo_boundary_layer (sfctype, & | |
Uref = vmag * rd / rdn | ||
endif | ||
|
||
if (l_iso_flag) then | ||
if (present(Qref_iso) .and. present(Qa_iso)) then | ||
if (tr_iso .and. sfctype(1:3)=='ice') then | ||
Qref_iso(:) = c0 | ||
if (tr_iso) then | ||
do n = 1, n_iso | ||
ratio = c0 | ||
if (Qa_iso(2) > puny) ratio = Qa_iso(n)/Qa_iso(2) | ||
Qref_iso(n) = Qa_iso(n) - ratio*delq*fac | ||
enddo | ||
endif | ||
else | ||
call icepack_warnings_add(subname//' l_iso_flag true but optional arrays missing') | ||
call icepack_warnings_setabort(.true.,__FILE__,__LINE__) | ||
return | ||
endif | ||
do n = 1, n_iso | ||
ratio = c0 | ||
if (Qa_iso(2) > puny) ratio = Qa_iso(n)/Qa_iso(2) | ||
Qref_iso(n) = Qa_iso(n) - ratio*delq*fac | ||
enddo | ||
endif | ||
|
||
end subroutine atmo_boundary_layer | ||
|
@@ -895,18 +876,18 @@ subroutine icepack_atm_boundary(sfctype, & | |
shcoef , & ! transfer coefficient for sensible heat | ||
lhcoef ! transfer coefficient for latent heat | ||
|
||
real (kind=dbl_kind), intent(in), optional, dimension(:) :: & | ||
real (kind=dbl_kind), intent(in), dimension(:), optional :: & | ||
Qa_iso ! specific isotopic humidity (kg/kg) | ||
|
||
real (kind=dbl_kind), intent(inout), optional, dimension(:) :: & | ||
real (kind=dbl_kind), intent(inout), dimension(:), optional :: & | ||
Qref_iso ! reference specific isotopic humidity (kg/kg) | ||
|
||
real (kind=dbl_kind), optional, intent(in) :: & | ||
real (kind=dbl_kind), intent(in), optional :: & | ||
uvel , & ! x-direction ice speed (m/s) | ||
vvel , & ! y-direction ice speed (m/s) | ||
zlvs ! atm level height for scalars (if different than zlvl) (m) | ||
|
||
real (kind=dbl_kind), optional, intent(out) :: & | ||
real (kind=dbl_kind), intent(out), optional :: & | ||
Uref ! reference height wind speed (m/s) | ||
|
||
!autodocument_end | ||
|
@@ -916,14 +897,28 @@ subroutine icepack_atm_boundary(sfctype, & | |
real (kind=dbl_kind) :: & | ||
l_uvel, l_vvel, l_Uref | ||
|
||
real (kind=dbl_kind), dimension(:), allocatable :: & | ||
l_Qa_iso, l_Qref_iso ! local copies of Qa_iso, Qref_iso | ||
|
||
logical (kind=log_kind) :: & | ||
iso_flag ! flag to turn on iso calcs in other subroutines | ||
logical (kind=log_kind), save :: & | ||
first_call_ice = .true. ! first call flag | ||
|
||
character(len=*),parameter :: subname='(icepack_atm_boundary)' | ||
|
||
!------------------------------------------------------------ | ||
! Check optional arguments | ||
! Need separate first_call flags for 'ice' and 'ocn' sfctype | ||
!------------------------------------------------------------ | ||
|
||
if (sfctype == 'ice') then | ||
if (icepack_chkoptargflag(first_call_ice)) then | ||
if (tr_iso) then | ||
if (.not.(present(Qa_iso).and.present(Qref_iso))) then | ||
call icepack_warnings_add(subname//' error in fiso_ocn argument, tr_iso=T') | ||
call icepack_warnings_setabort(.true.,__FILE__,__LINE__) | ||
return | ||
endif | ||
endif | ||
endif | ||
endif | ||
|
||
l_uvel = c0 | ||
l_vvel = c0 | ||
l_Uref = c0 | ||
|
@@ -933,19 +928,6 @@ subroutine icepack_atm_boundary(sfctype, & | |
if (present(vvel)) then | ||
l_vvel = vvel | ||
endif | ||
if (present(Qa_iso) .and. present(Qref_iso)) then | ||
iso_flag = .true. | ||
allocate(l_Qa_iso(size(Qa_iso,dim=1))) | ||
allocate(l_Qref_iso(size(Qref_iso,dim=1))) | ||
l_Qa_iso = Qa_iso | ||
l_Qref_iso = Qref_iso | ||
else | ||
iso_flag = .false. | ||
allocate(l_Qa_iso(1)) | ||
allocate(l_Qref_iso(1)) | ||
l_Qa_iso = c0 | ||
l_Qref_iso = c0 | ||
endif | ||
|
||
Cdn_atm_ratio_n = c1 | ||
|
||
|
@@ -972,24 +954,21 @@ subroutine icepack_atm_boundary(sfctype, & | |
lhcoef, shcoef, & | ||
Cdn_atm, & | ||
Cdn_atm_ratio_n, & | ||
iso_flag = iso_flag, & | ||
Qa_iso=l_Qa_iso, & | ||
Qref_iso=l_Qref_iso, & | ||
uvel=l_uvel, vvel=l_vvel, & | ||
Uref=l_Uref, zlvs=zlvs) | ||
Qa_iso=Qa_iso, & | ||
Qref_iso=Qref_iso, & | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if present(Qref_iso)=F? Is this robust across all compilers/platforms? You probably tested that previously... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is robust. The optional attribute and "present" state is passed down the calling tree. As long as optional is set in the calling routine for this field if want to check it's "present" state (determined by the original caller) and/or the optional argument is not used unless it exists, all should be fine. You can definitely get into trouble if you pass the optional argument down the calling tree and use it if it wasn't passed. Hopefully, we'll avoid that with the logic we have setup. |
||
uvel=l_uvel, vvel=l_vvel,& | ||
Uref=l_Uref, zlvs=zlvs ) | ||
if (icepack_warnings_aborted(subname)) return | ||
endif ! atmbndy | ||
|
||
if (present(Uref)) then | ||
Uref = l_Uref | ||
endif | ||
|
||
if (present(Qref_iso)) then | ||
Qref_iso = l_Qref_iso | ||
if (sfctype == 'ice') then | ||
first_call_ice = .false. | ||
endif | ||
|
||
deallocate(l_Qa_iso,l_Qref_iso) | ||
|
||
end subroutine icepack_atm_boundary | ||
|
||
!======================================================================= | ||
|
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.
Farther down in the comments for this module, you say
So are Qa_iso and Qref_iso safe to use here without checking their 'present' status because the call to this subroutine isn't the first call in which those arguments are declared optional? It appears that you are checking it in what would be the first call into icepack,
icepack_atm_boundary
. Is there some easy way to track when an optional argument needs to be checked 'if present' and when it doesn't? It's probably not as simple as just checking in icepack's interface routines.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's right, we have already checked the arguments in the highest level Icepack interface. So they are safe to use here without checking. That's our current design. As I mentioned the other day, there are pros and cons to doing it this way. A pro is that we check all the optional arguments early leveraging parameter flags and then we should be OK after that without having to check over and over. A negative is that you have to keep track of what's going on in different layers of the code.
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.
Okay, thank you.