@@ -179,20 +179,30 @@ subroutine calculate_spec_vol_array_wright(T, S, pressure, specvol, start, npts,
179
179
! Local variables
180
180
real :: al0 ! The specific volume at 0 lambda in the Wright EOS [m3 kg-1]
181
181
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]
183
187
integer :: j
184
188
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
196
206
end subroutine calculate_spec_vol_array_wright
197
207
198
208
! > 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, &
793
803
real :: hWght ! A pressure-thickness below topography [R L2 T-2 ~> Pa].
794
804
real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [R L2 T-2 ~> Pa].
795
805
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].
796
807
real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim].
797
808
real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim].
798
809
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, &
866
877
al0 = al0_2d(i,j) ; p0 = p0_2d(i,j) ; lambda = lambda_2d(i,j)
867
878
dp = p_b(i,j) - p_t(i,j)
868
879
p_ave = 0.5 * (p_t(i,j)+ p_b(i,j))
880
+ I_pterm = 1.0 / (p0 + p_ave)
869
881
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
872
884
rem = (lambda * eps2) * (C1_3 + eps2* (0.2 + eps2* (C1_7 + C1_9* eps2)))
873
885
dza(i,j) = alpha_anom* dp + 2.0 * eps* rem
874
886
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, &
906
918
907
919
dp = wt_L* (p_b(i,j) - p_t(i,j)) + wt_R* (p_b(i+1 ,j) - p_t(i+1 ,j))
908
920
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)
909
922
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* &
912
925
lambda * eps2 * (C1_3 + eps2* (0.2 + eps2* (C1_7 + C1_9* eps2)))
913
926
enddo
914
927
! 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, &
947
960
948
961
dp = wt_L* (p_b(i,j) - p_t(i,j)) + wt_R* (p_b(i,j+1 ) - p_t(i,j+1 ))
949
962
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)
950
964
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* &
953
967
lambda * eps2 * (C1_3 + eps2* (0.2 + eps2* (C1_7 + C1_9* eps2)))
954
968
enddo
955
969
! Use Boole's rule to integrate the values.
0 commit comments