@@ -179,20 +179,30 @@ subroutine calculate_spec_vol_array_wright(T, S, pressure, specvol, start, npts,
179179 ! Local variables
180180 real :: al0 ! The specific volume at 0 lambda in the Wright EOS [m3 kg-1]
181181 real :: p0 ! The pressure offset in the Wright EOS [Pa]
182- real :: lambda ! The sound speed squared at 0 alpha in the Wright EOS [m2 s-2]
182+ real :: lambda ! The sound speed squared at 0 alpha in the Wright EOS [m2 s-2], perhaps with
183+ ! an offset to account for spv_ref
184+ real :: al_TS ! The contributions of temperature and salinity to al0 [m3 kg-1]
185+ real :: p_TSp ! A combination of the pressure and the temperature and salinity contributions to p0 [Pa]
186+ real :: lam_000 ! A corrected offset to lambda, including contributions from spv_ref [m2 s-2]
183187 integer :: j
184188
185- do j= start,start+ npts-1
186- al0 = a0 + (a1* T(j) + a2* S(j))
187- p0 = b0 + ( b4* S(j) + T(j) * (b1 + (T(j)* (b2 + b3* T(j)) + b5* S(j))) )
188- lambda = c0 + ( c4* S(j) + T(j) * (c1 + (T(j)* (c2 + c3* T(j)) + c5* S(j))) )
189-
190- if (present (spv_ref)) then
191- specvol(j) = (lambda + (al0 - spv_ref)* (pressure(j) + p0)) / (pressure(j) + p0)
192- else
193- specvol(j) = (lambda + al0* (pressure(j) + p0)) / (pressure(j) + p0)
194- endif
195- enddo
189+ if (present (spv_ref)) then
190+ lam_000 = c0 + (a0 - spv_ref)* b0
191+ do j= start,start+ npts-1
192+ al_TS = a1* T(j) + a2* S(j)
193+ p_TSp = pressure(j) + (b4* S(j) + T(j) * (b1 + (T(j)* (b2 + b3* T(j)) + b5* S(j))))
194+ lambda = lam_000 + ( c4* S(j) + T(j) * (c1 + (T(j)* (c2 + c3* T(j)) + c5* S(j))) )
195+ ! This is equivalent to the expression below minus spv_ref, but less sensitive to roundoff.
196+ specvol(j) = al_TS + (lambda + (a0 - spv_ref)* p_TSp) / (b0 + p_TSp)
197+ enddo
198+ else
199+ do j= start,start+ npts-1
200+ al0 = a0 + (a1* T(j) + a2* S(j))
201+ p0 = b0 + ( b4* S(j) + T(j) * (b1 + (T(j)* (b2 + b3* T(j)) + b5* S(j))) )
202+ lambda = c0 + ( c4* S(j) + T(j) * (c1 + (T(j)* (c2 + c3* T(j)) + c5* S(j))) )
203+ specvol(j) = al0 + lambda / (pressure(j) + p0)
204+ enddo
205+ endif
196206end subroutine calculate_spec_vol_array_wright
197207
198208! > Return the thermal/haline expansion coefficients for 1-d array inputs and outputs
@@ -793,6 +803,7 @@ subroutine int_spec_vol_dp_wright_full(T, S, p_t, p_b, spv_ref, HI, dza, &
793803 real :: hWght ! A pressure-thickness below topography [R L2 T-2 ~> Pa].
794804 real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [R L2 T-2 ~> Pa].
795805 real :: iDenom ! The inverse of the denominator in the weights [T4 R-2 L-4 ~> Pa-2].
806+ real :: I_pterm ! The inverse of p0 plus p_ave [T2 R-1 L-2 ~> Pa-1].
796807 real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim].
797808 real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim].
798809 real :: wt_L, wt_R ! The linear weights of the left and right columns [nondim].
@@ -866,9 +877,10 @@ subroutine int_spec_vol_dp_wright_full(T, S, p_t, p_b, spv_ref, HI, dza, &
866877 al0 = al0_2d(i,j) ; p0 = p0_2d(i,j) ; lambda = lambda_2d(i,j)
867878 dp = p_b(i,j) - p_t(i,j)
868879 p_ave = 0.5 * (p_t(i,j)+ p_b(i,j))
880+ I_pterm = 1.0 / (p0 + p_ave)
869881
870- eps = 0.5 * dp / (p0 + p_ave) ; eps2 = eps* eps
871- alpha_anom = (al0 - spv_ref) + lambda / (p0 + p_ave)
882+ eps = 0.5 * dp * I_pterm ; eps2 = eps* eps
883+ alpha_anom = (al0 - spv_ref) + lambda * I_pterm
872884 rem = (lambda * eps2) * (C1_3 + eps2* (0.2 + eps2* (C1_7 + C1_9* eps2)))
873885 dza(i,j) = alpha_anom* dp + 2.0 * eps* rem
874886 if (present (intp_dza)) &
@@ -906,9 +918,10 @@ subroutine int_spec_vol_dp_wright_full(T, S, p_t, p_b, spv_ref, HI, dza, &
906918
907919 dp = wt_L* (p_b(i,j) - p_t(i,j)) + wt_R* (p_b(i+1 ,j) - p_t(i+1 ,j))
908920 p_ave = 0.5 * (wt_L* (p_t(i,j)+ p_b(i,j)) + wt_R* (p_t(i+1 ,j)+ p_b(i+1 ,j)))
921+ I_pterm = 1.0 / (p0 + p_ave)
909922
910- eps = 0.5 * dp / (p0 + p_ave) ; eps2 = eps* eps
911- intp(m) = ((al0 - spv_ref) + lambda / (p0 + p_ave) )* dp + 2.0 * eps* &
923+ eps = 0.5 * dp * I_pterm ; eps2 = eps* eps
924+ intp(m) = ((al0 - spv_ref) + lambda * I_pterm )* dp + 2.0 * eps* &
912925 lambda * eps2 * (C1_3 + eps2* (0.2 + eps2* (C1_7 + C1_9* eps2)))
913926 enddo
914927 ! Use Boole's rule to integrate the values.
@@ -947,9 +960,10 @@ subroutine int_spec_vol_dp_wright_full(T, S, p_t, p_b, spv_ref, HI, dza, &
947960
948961 dp = wt_L* (p_b(i,j) - p_t(i,j)) + wt_R* (p_b(i,j+1 ) - p_t(i,j+1 ))
949962 p_ave = 0.5 * (wt_L* (p_t(i,j)+ p_b(i,j)) + wt_R* (p_t(i,j+1 )+ p_b(i,j+1 )))
963+ I_pterm = 1.0 / (p0 + p_ave)
950964
951- eps = 0.5 * dp / (p0 + p_ave) ; eps2 = eps* eps
952- intp(m) = ((al0 - spv_ref) + lambda / (p0 + p_ave) )* dp + 2.0 * eps* &
965+ eps = 0.5 * dp * I_pterm ; eps2 = eps* eps
966+ intp(m) = ((al0 - spv_ref) + lambda * I_pterm )* dp + 2.0 * eps* &
953967 lambda * eps2 * (C1_3 + eps2* (0.2 + eps2* (C1_7 + C1_9* eps2)))
954968 enddo
955969 ! Use Boole's rule to integrate the values.
0 commit comments