@@ -91,16 +91,14 @@ module MOM_EOS
91
91
! > Calculates density of sea water from T, S and P
92
92
interface calculate_density
93
93
module procedure calculate_density_scalar
94
- module procedure calculate_density_array
95
94
module procedure calculate_density_1d
96
95
module procedure calculate_stanley_density_scalar
97
- module procedure calculate_stanley_density_array
98
96
module procedure calculate_stanley_density_1d
99
97
end interface calculate_density
100
98
101
99
! > Calculates specific volume of sea water from T, S and P
102
100
interface calculate_spec_vol
103
- module procedure calc_spec_vol_scalar, calculate_spec_vol_array
101
+ module procedure calc_spec_vol_scalar
104
102
module procedure calc_spec_vol_1d
105
103
end interface calculate_spec_vol
106
104
@@ -112,7 +110,7 @@ module MOM_EOS
112
110
113
111
! > Calculate the derivatives of specific volume with temperature and salinity from T, S, and P
114
112
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
116
114
end interface calculate_specific_vol_derivs
117
115
118
116
! > 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
262
260
real , optional , intent (in ) :: scale ! < A multiplicative factor by which to scale output density in
263
261
! ! combination with scaling stored in EOS [various]
264
262
! 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]
273
268
274
269
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)
315
271
316
272
! 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 ) )
319
274
320
275
if (present (scale)) rho = rho * scale
321
276
@@ -367,93 +322,6 @@ subroutine calculate_density_array(T, S, pressure, rho, start, npts, EOS, rho_re
367
322
368
323
end subroutine calculate_density_array
369
324
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
-
457
325
! > Calls the appropriate subroutine to calculate the density of sea water for 1-D array inputs,
458
326
! ! potentially limiting the domain of indices that are worked on.
459
327
! ! 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,
526
394
real , optional , intent (in ) :: scale ! < A multiplicative factor by which to scale density
527
395
! ! in combination with scaling stored in EOS [various]
528
396
! 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]
538
397
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]
544
403
integer :: i, is, ie, npts
545
404
546
405
if (present (dom)) then
@@ -549,79 +408,17 @@ subroutine calculate_stanley_density_1d(T, S, pressure, Tvar, TScov, Svar, rho,
549
408
is = 1 ; ie = size (rho) ; npts = 1 + ie - is
550
409
endif
551
410
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)
612
413
613
414
! Equation 25 of Stanley et al., 2020.
614
415
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) ) )
618
417
enddo
619
418
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
625
422
626
423
end subroutine calculate_stanley_density_1d
627
424
0 commit comments