Skip to content

Commit ed58758

Browse files
Hallberg-NOAAmarshallward
authored andcommitted
+Make calculate_density_array private
Removed calculate_density_array from the overloaded public calculate_density interface, and similarly for the other EOS calculate_..._array routines, to help standardize how they are called. Calculate_density_derivs_array is the one exception is because it is being called from SIS2 and has to stay publicly visible for now. Additionally, the scalar and 1-d versions of the calculate_stanley_density routines were refactored to just use calculate_density and calculate_density_second_derivs call and avoid any EoS-specific logic, while the unused routine calculate_stanley_density_array is eliminated altogether. All answers are bitwise identical, including in extra tests that use the stanley_density routines.
1 parent 433ac30 commit ed58758

File tree

1 file changed

+20
-223
lines changed

1 file changed

+20
-223
lines changed

src/equation_of_state/MOM_EOS.F90

Lines changed: 20 additions & 223 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,14 @@ module MOM_EOS
9191
!> Calculates density of sea water from T, S and P
9292
interface calculate_density
9393
module procedure calculate_density_scalar
94-
module procedure calculate_density_array
9594
module procedure calculate_density_1d
9695
module procedure calculate_stanley_density_scalar
97-
module procedure calculate_stanley_density_array
9896
module procedure calculate_stanley_density_1d
9997
end interface calculate_density
10098

10199
!> Calculates specific volume of sea water from T, S and P
102100
interface calculate_spec_vol
103-
module procedure calc_spec_vol_scalar, calculate_spec_vol_array
101+
module procedure calc_spec_vol_scalar
104102
module procedure calc_spec_vol_1d
105103
end interface calculate_spec_vol
106104

@@ -112,7 +110,7 @@ module MOM_EOS
112110

113111
!> Calculate the derivatives of specific volume with temperature and salinity from T, S, and P
114112
interface calculate_specific_vol_derivs
115-
module procedure calc_spec_vol_derivs_1d, calculate_spec_vol_derivs_array
113+
module procedure calc_spec_vol_derivs_1d
116114
end interface calculate_specific_vol_derivs
117115

118116
!> Calculates the second derivatives of density with various combinations of temperature,
@@ -262,60 +260,17 @@ subroutine calculate_stanley_density_scalar(T, S, pressure, Tvar, TScov, Svar, r
262260
real, optional, intent(in) :: scale !< A multiplicative factor by which to scale output density in
263261
!! combination with scaling stored in EOS [various]
264262
! Local variables
265-
real :: d2RdTT ! Second derivative of density with temperature [kg m-3 degC-2]
266-
real :: d2RdST ! Second derivative of density with temperature and salinity [kg m-3 degC-1 ppt-1]
267-
real :: d2RdSS ! Second derivative of density with salinity [kg m-3 ppt-2]
268-
real :: d2RdSp ! Second derivative of density with salinity and pressure [kg m-3 ppt-1 Pa-1]
269-
real :: d2RdTp ! Second derivative of density with temperature and pressure [kg m-3 degC-1 Pa-1]
270-
real :: p_scale ! A factor to convert pressure to units of Pa [Pa T2 R-1 L-2 ~> 1]
271-
real :: T_scale ! A factor to convert temperature to units of degC [degC C-1 ~> 1]
272-
real :: S_scale ! A factor to convert salinity to units of ppt [ppt S-1 ~> 1]
263+
real :: d2RdTT ! Second derivative of density with temperature [R C-2 ~> kg m-3 degC-2]
264+
real :: d2RdST ! Second derivative of density with temperature and salinity [R S-1 C-1 ~> kg m-3 degC-1 ppt-1]
265+
real :: d2RdSS ! Second derivative of density with salinity [R S-2 ~> kg m-3 ppt-2]
266+
real :: d2RdSp ! Second derivative of density with salinity and pressure [T2 S-1 L-2 ~> kg m-3 ppt-1 Pa-1]
267+
real :: d2RdTp ! Second derivative of density with temperature and pressure [T2 C-1 L-2 ~> kg m-3 degC-1 Pa-1]
273268

274269
call calculate_density_scalar(T, S, pressure, rho, EOS, rho_ref)
275-
276-
p_scale = EOS%RL2_T2_to_Pa
277-
T_scale = EOS%C_to_degC
278-
S_scale = EOS%S_to_ppt
279-
select case (EOS%form_of_EOS)
280-
case (EOS_LINEAR)
281-
call calculate_density_second_derivs_linear(T_scale*T, S_scale*S, p_scale*pressure, &
282-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
283-
case (EOS_WRIGHT)
284-
if (EOS%use_Wright_2nd_deriv_bug) then
285-
call calc_density_second_derivs_wright_buggy(T_scale*T, S_scale*S, p_scale*pressure, &
286-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
287-
else
288-
call calculate_density_second_derivs_wright(T_scale*T, S_scale*S, p_scale*pressure, &
289-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
290-
endif
291-
case (EOS_WRIGHT_FULL)
292-
call calculate_density_second_derivs_wright_full(T_scale*T, S_scale*S, p_scale*pressure, &
293-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
294-
case (EOS_WRIGHT_RED)
295-
call calculate_density_second_derivs_wright_red(T_scale*T, S_scale*S, p_scale*pressure, &
296-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
297-
case (EOS_UNESCO)
298-
call calculate_density_second_derivs_UNESCO(T_scale*T, S_scale*S, p_scale*pressure, &
299-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
300-
case (EOS_ROQUET_RHO)
301-
call calculate_density_second_derivs_Roquet_rho(T_scale*T, S_scale*S, p_scale*pressure, &
302-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
303-
case (EOS_ROQUET_SPV)
304-
call calculate_density_second_derivs_Roquet_SpV(T_scale*T, S_scale*S, p_scale*pressure, &
305-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
306-
case (EOS_TEOS10)
307-
call calculate_density_second_derivs_teos10(T_scale*T, S_scale*S, p_scale*pressure, &
308-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
309-
case (EOS_JACKETT06)
310-
call calculate_density_second_derivs_Jackett06(T_scale*T, S_scale*S, p_scale*pressure, &
311-
d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP)
312-
case default
313-
call MOM_error(FATAL, "calculate_stanley_density_scalar: EOS is not valid.")
314-
end select
270+
call calculate_density_second_derivs_scalar(T, S, pressure, d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP, EOS)
315271

316272
! Equation 25 of Stanley et al., 2020.
317-
rho = rho + EOS%kg_m3_to_R * ( 0.5 * (T_scale**2 * d2RdTT) * Tvar + &
318-
( (S_scale*T_scale * d2RdST) * TScov + 0.5 * (S_scale**2 * d2RdSS) * Svar ) )
273+
rho = rho + ( 0.5 * d2RdTT * Tvar + ( d2RdST * TScov + 0.5 * d2RdSS * Svar ) )
319274

320275
if (present(scale)) rho = rho * scale
321276

@@ -367,93 +322,6 @@ subroutine calculate_density_array(T, S, pressure, rho, start, npts, EOS, rho_re
367322

368323
end subroutine calculate_density_array
369324

370-
!> Calls the appropriate subroutine to calculate the density of sea water for 1-D array inputs
371-
!! including the variance of T, S and covariance of T-S.
372-
!! The calculation uses only the second order correction in a series as discussed
373-
!! in Stanley et al., 2020.
374-
!! If rho_ref is present, the anomaly with respect to rho_ref is returned.
375-
subroutine calculate_stanley_density_array(T, S, pressure, Tvar, TScov, Svar, rho, start, npts, EOS, rho_ref, scale)
376-
real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface [degC]
377-
real, dimension(:), intent(in) :: S !< Salinity [ppt]
378-
real, dimension(:), intent(in) :: pressure !< Pressure [Pa]
379-
real, dimension(:), intent(in) :: Tvar !< Variance of potential temperature referenced to the surface [degC2]
380-
real, dimension(:), intent(in) :: TScov !< Covariance of potential temperature and salinity [degC ppt]
381-
real, dimension(:), intent(in) :: Svar !< Variance of salinity [ppt2]
382-
real, dimension(:), intent(inout) :: rho !< Density (in-situ if pressure is local) [kg m-3]
383-
integer, intent(in) :: start !< Start index for computation
384-
integer, intent(in) :: npts !< Number of point to compute
385-
type(EOS_type), intent(in) :: EOS !< Equation of state structure
386-
real, optional, intent(in) :: rho_ref !< A reference density [kg m-3].
387-
real, optional, intent(in) :: scale !< A multiplicative factor by which to scale the output
388-
!! density, perhaps to other units than kg m-3 [various]
389-
! Local variables
390-
real, dimension(size(T)) :: &
391-
d2RdTT, & ! Second derivative of density with temperature [kg m-3 degC-2]
392-
d2RdST, & ! Second derivative of density with temperature and salinity [kg m-3 degC-1 ppt-1]
393-
d2RdSS, & ! Second derivative of density with salinity [kg m-3 ppt-2]
394-
d2RdSp, & ! Second derivative of density with salinity and pressure [kg m-3 ppt-1 Pa-1]
395-
d2RdTp ! Second derivative of density with temperature and pressure [kg m-3 degC-1 Pa-1]
396-
integer :: j
397-
398-
select case (EOS%form_of_EOS)
399-
case (EOS_LINEAR)
400-
call calculate_density_linear(T, S, pressure, rho, start, npts, &
401-
EOS%Rho_T0_S0, EOS%dRho_dT, EOS%dRho_dS, rho_ref)
402-
call calculate_density_second_derivs_linear(T, S, pressure, d2RdSS, d2RdST, &
403-
d2RdTT, d2RdSp, d2RdTP, start, npts)
404-
case (EOS_WRIGHT)
405-
call calculate_density_wright(T, S, pressure, rho, start, npts, rho_ref)
406-
if (EOS%use_Wright_2nd_deriv_bug) then
407-
call calc_density_second_derivs_wright_buggy(T, S, pressure, d2RdSS, d2RdST, &
408-
d2RdTT, d2RdSp, d2RdTP, start, npts)
409-
else
410-
call calculate_density_second_derivs_wright(T, S, pressure, d2RdSS, d2RdST, &
411-
d2RdTT, d2RdSp, d2RdTP, start, npts)
412-
endif
413-
case (EOS_WRIGHT_FULL)
414-
call calculate_density_wright_full(T, S, pressure, rho, start, npts, rho_ref)
415-
call calculate_density_second_derivs_wright_full(T, S, pressure, d2RdSS, d2RdST, &
416-
d2RdTT, d2RdSp, d2RdTP, start, npts)
417-
case (EOS_WRIGHT_RED)
418-
call calculate_density_wright_red(T, S, pressure, rho, start, npts, rho_ref)
419-
call calculate_density_second_derivs_wright_red(T, S, pressure, d2RdSS, d2RdST, &
420-
d2RdTT, d2RdSp, d2RdTP, start, npts)
421-
case (EOS_UNESCO)
422-
call calculate_density_UNESCO(T, S, pressure, rho, start, npts, rho_ref)
423-
call calculate_density_second_derivs_UNESCO(T, S, pressure, d2RdSS, d2RdST, &
424-
d2RdTT, d2RdSp, d2RdTP, start, npts)
425-
case (EOS_ROQUET_RHO)
426-
call calculate_density_Roquet_rho(T, S, pressure, rho, start, npts, rho_ref)
427-
call calculate_density_second_derivs_Roquet_rho(T, S, pressure, d2RdSS, d2RdST, &
428-
d2RdTT, d2RdSp, d2RdTP, start, npts)
429-
case (EOS_ROQUET_SPV)
430-
call calculate_density_Roquet_SpV(T, S, pressure, rho, start, npts, rho_ref)
431-
call calculate_density_second_derivs_Roquet_SpV(T, S, pressure, d2RdSS, d2RdST, &
432-
d2RdTT, d2RdSp, d2RdTP, start, npts)
433-
case (EOS_TEOS10)
434-
call calculate_density_teos10(T, S, pressure, rho, start, npts, rho_ref)
435-
call calculate_density_second_derivs_teos10(T, S, pressure, d2RdSS, d2RdST, &
436-
d2RdTT, d2RdSp, d2RdTP, start, npts)
437-
case (EOS_JACKETT06)
438-
call calculate_density_Jackett06(T, S, pressure, rho, start, npts, rho_ref)
439-
call calculate_density_second_derivs_Jackett06(T, S, pressure, d2RdSS, d2RdST, &
440-
d2RdTT, d2RdSp, d2RdTP, start, npts)
441-
case default
442-
call MOM_error(FATAL, "calculate_stanley_density_array: EOS%form_of_EOS is not valid.")
443-
end select
444-
445-
! Equation 25 of Stanley et al., 2020.
446-
do j=start,start+npts-1
447-
rho(j) = rho(j) &
448-
+ ( 0.5 * d2RdTT(j) * Tvar(j) + ( d2RdST(j) * TScov(j) + 0.5 * d2RdSS(j) * Svar(j) ) )
449-
enddo
450-
451-
if (present(scale)) then ; if (scale /= 1.0) then ; do j=start,start+npts-1
452-
rho(j) = scale * rho(j)
453-
enddo ; endif ; endif
454-
455-
end subroutine calculate_stanley_density_array
456-
457325
!> Calls the appropriate subroutine to calculate the density of sea water for 1-D array inputs,
458326
!! potentially limiting the domain of indices that are worked on.
459327
!! If rho_ref is present, the anomaly with respect to rho_ref is returned.
@@ -526,21 +394,12 @@ subroutine calculate_stanley_density_1d(T, S, pressure, Tvar, TScov, Svar, rho,
526394
real, optional, intent(in) :: scale !< A multiplicative factor by which to scale density
527395
!! in combination with scaling stored in EOS [various]
528396
! Local variables
529-
real :: rho_scale ! A factor to convert density from kg m-3 to the desired units [R m3 kg-1 ~> 1]
530-
real :: T2_scale ! A factor to convert temperature variance to units of degC2 [degC2 C-2 ~> 1]
531-
real :: S2_scale ! A factor to convert salinity variance to units of ppt2 [ppt2 S-2 ~> 1]
532-
real :: TS_scale ! A factor to convert temperature-salinity covariance to units of
533-
! degC ppt [degC ppt C-1 S-1 ~> 1]
534-
real :: rho_reference ! rho_ref converted to [kg m-3]
535-
real, dimension(size(rho)) :: pres ! Pressure converted to [Pa]
536-
real, dimension(size(rho)) :: Ta ! Temperature converted to [degC]
537-
real, dimension(size(rho)) :: Sa ! Salinity converted to [ppt]
538397
real, dimension(size(T)) :: &
539-
d2RdTT, & ! Second derivative of density with temperature [kg m-3 degC-2]
540-
d2RdST, & ! Second derivative of density with temperature and salinity [kg m-3 degC-1 ppt-1]
541-
d2RdSS, & ! Second derivative of density with salinity [kg m-3 ppt-2]
542-
d2RdSp, & ! Second derivative of density with salinity and pressure [kg m-3 ppt-1 Pa-1]
543-
d2RdTp ! Second derivative of density with temperature and pressure [kg m-3 degC-1 Pa-1]
398+
d2RdTT, & ! Second derivative of density with temperature [R C-2 ~> kg m-3 degC-2]
399+
d2RdST, & ! Second derivative of density with temperature and salinity [R S-1 C-1 ~> kg m-3 degC-1 ppt-1]
400+
d2RdSS, & ! Second derivative of density with salinity [R S-2 ~> kg m-3 ppt-2]
401+
d2RdSp, & ! Second derivative of density with salinity and pressure [T2 S-1 L-2 ~> kg m-3 ppt-1 Pa-1]
402+
d2RdTp ! Second derivative of density with temperature and pressure [T2 C-1 L-2 ~> kg m-3 degC-1 Pa-1]
544403
integer :: i, is, ie, npts
545404

546405
if (present(dom)) then
@@ -549,79 +408,17 @@ subroutine calculate_stanley_density_1d(T, S, pressure, Tvar, TScov, Svar, rho,
549408
is = 1 ; ie = size(rho) ; npts = 1 + ie - is
550409
endif
551410

552-
do i=is,ie
553-
pres(i) = EOS%RL2_T2_to_Pa * pressure(i)
554-
Ta(i) = EOS%C_to_degC * T(i)
555-
Sa(i) = EOS%S_to_ppt * S(i)
556-
enddo
557-
T2_scale = EOS%C_to_degC**2
558-
S2_scale = EOS%S_to_ppt**2
559-
TS_scale = EOS%C_to_degC*EOS%S_to_ppt
560-
561-
! Rho_ref is seems like it is always present when calculate_Stanley_density is called, so
562-
! always set rho_reference, even though a 0 value can change answers at roundoff with
563-
! some equations of state.
564-
rho_reference = 0.0 ; if (present(rho_ref)) rho_reference = EOS%R_to_kg_m3*rho_ref
565-
566-
select case (EOS%form_of_EOS)
567-
case (EOS_LINEAR)
568-
call calculate_density_linear(Ta, Sa, pres, rho, is, npts, &
569-
EOS%Rho_T0_S0, EOS%dRho_dT, EOS%dRho_dS, rho_reference)
570-
call calculate_density_second_derivs_linear(Ta, Sa, pres, d2RdSS, d2RdST, &
571-
d2RdTT, d2RdSp, d2RdTP, is, npts)
572-
case (EOS_WRIGHT)
573-
call calculate_density_wright(Ta, Sa, pres, rho, is, npts, rho_reference)
574-
if (EOS%use_Wright_2nd_deriv_bug) then
575-
call calc_density_second_derivs_wright_buggy(Ta, Sa, pres, d2RdSS, d2RdST, &
576-
d2RdTT, d2RdSp, d2RdTP, is, npts)
577-
else
578-
call calculate_density_second_derivs_wright(Ta, Sa, pres, d2RdSS, d2RdST, &
579-
d2RdTT, d2RdSp, d2RdTP, is, npts)
580-
endif
581-
case (EOS_WRIGHT_FULL)
582-
call calculate_density_wright_full(Ta, Sa, pres, rho, is, npts, rho_reference)
583-
call calculate_density_second_derivs_wright_full(Ta, Sa, pres, d2RdSS, d2RdST, &
584-
d2RdTT, d2RdSp, d2RdTP, is, npts)
585-
case (EOS_WRIGHT_RED)
586-
call calculate_density_wright_red(Ta, Sa, pres, rho, is, npts, rho_reference)
587-
call calculate_density_second_derivs_wright_red(Ta, Sa, pres, d2RdSS, d2RdST, &
588-
d2RdTT, d2RdSp, d2RdTP, is, npts)
589-
case (EOS_UNESCO)
590-
call calculate_density_UNESCO(Ta, Sa, pres, rho, is, npts, rho_reference)
591-
call calculate_density_second_derivs_UNESCO(Ta, Sa, pres, d2RdSS, d2RdST, &
592-
d2RdTT, d2RdSp, d2RdTP, is, npts)
593-
case (EOS_ROQUET_RHO)
594-
call calculate_density_Roquet_rho(Ta, Sa, pres, rho, is, npts, rho_reference)
595-
call calculate_density_second_derivs_Roquet_rho(Ta, Sa, pres, d2RdSS, d2RdST, &
596-
d2RdTT, d2RdSp, d2RdTP, is, npts)
597-
case (EOS_ROQUET_SPV)
598-
call calculate_density_Roquet_SpV(Ta, Sa, pres, rho, is, npts, rho_reference)
599-
call calculate_density_second_derivs_Roquet_SpV(Ta, Sa, pres, d2RdSS, d2RdST, &
600-
d2RdTT, d2RdSp, d2RdTP, is, npts)
601-
case (EOS_TEOS10)
602-
call calculate_density_teos10(Ta, Sa, pres, rho, is, npts, rho_reference)
603-
call calculate_density_second_derivs_teos10(Ta, Sa, pres, d2RdSS, d2RdST, &
604-
d2RdTT, d2RdSp, d2RdTP, is, npts)
605-
case (EOS_JACKETT06)
606-
call calculate_density_Jackett06(Ta, Sa, pres, rho, is, npts, rho_reference)
607-
call calculate_density_second_derivs_Jackett06(Ta, Sa, pres, d2RdSS, d2RdST, &
608-
d2RdTT, d2RdSp, d2RdTP, is, npts)
609-
case default
610-
call MOM_error(FATAL, "calculate_stanley_density_1d: EOS is not valid.")
611-
end select
411+
call calculate_density_1d(T, S, pressure, rho, EOS, dom, rho_ref)
412+
call calculate_density_second_derivs_1d(T, S, pressure, d2RdSS, d2RdST, d2RdTT, d2RdSp, d2RdTP, EOS, dom)
612413

613414
! Equation 25 of Stanley et al., 2020.
614415
do i=is,ie
615-
rho(i) = rho(i) + ( 0.5 * (T2_scale * d2RdTT(i)) * Tvar(i) + &
616-
( (TS_scale * d2RdST(i)) * TScov(i) + &
617-
0.5 * (S2_scale * d2RdSS(i)) * Svar(i) ) )
416+
rho(i) = rho(i) + ( 0.5 * d2RdTT(i) * Tvar(i) + ( d2RdST(i) * TScov(i) + 0.5 * d2RdSS(i) * Svar(i) ) )
618417
enddo
619418

620-
rho_scale = EOS%kg_m3_to_R
621-
if (present(scale)) rho_scale = rho_scale * scale
622-
if (rho_scale /= 1.0) then ; do i=is,ie
623-
rho(i) = rho_scale * rho(i)
624-
enddo ; endif
419+
if (present(scale)) then ; if (scale /= 1.0) then ; do i=is,ie
420+
rho(i) = scale * rho(i)
421+
enddo ; endif ; endif
625422

626423
end subroutine calculate_stanley_density_1d
627424

0 commit comments

Comments
 (0)