8 use mom_eos_linear,
only : calculate_specvol_derivs_linear, int_density_dz_linear
10 use mom_eos_linear,
only : calculate_compress_linear, int_spec_vol_dp_linear
13 use mom_eos_wright,
only : calculate_specvol_derivs_wright, int_density_dz_wright
14 use mom_eos_wright,
only : calculate_compress_wright, int_spec_vol_dp_wright
36 implicit none ;
private
38 #include <MOM_memory.h>
44 public eos_manual_init
47 public analytic_int_density_dz
48 public analytic_int_specific_vol_dp
56 public convert_temp_salt_for_teos10
57 public extract_member_eos
60 public query_compressible
69 module procedure calculate_density_scalar, calculate_density_array, calculate_density_1d
70 module procedure calculate_stanley_density_scalar, calculate_stanley_density_array
71 module procedure calculate_stanley_density_1d
76 module procedure calc_spec_vol_scalar, calculate_spec_vol_array, &
82 module procedure calculate_density_derivs_scalar, calculate_density_derivs_array, &
83 calculate_density_derivs_1d
88 module procedure calculate_spec_vol_derivs_array, calc_spec_vol_derivs_1d
94 module procedure calculate_density_second_derivs_scalar, calculate_density_second_derivs_array
99 module procedure calculate_tfreeze_scalar, calculate_tfreeze_array
104 module procedure calculate_compress_scalar, calculate_compress_array
109 integer :: form_of_eos = 0
110 integer :: form_of_tfreeze = 0
112 logical :: eos_quadrature
114 logical :: compressible = .true.
128 real :: kg_m3_to_r = 1.
129 real :: r_to_kg_m3 = 1.
130 real :: rl2_t2_to_pa = 1.
131 real :: l_t_to_m_s = 1.
137 integer,
parameter,
public :: eos_linear = 1
138 integer,
parameter,
public :: eos_unesco = 2
139 integer,
parameter,
public :: eos_wright = 3
140 integer,
parameter,
public :: eos_teos10 = 4
141 integer,
parameter,
public :: eos_nemo = 5
143 character*(10),
parameter :: eos_linear_string =
"LINEAR"
144 character*(10),
parameter :: eos_unesco_string =
"UNESCO"
145 character*(10),
parameter :: eos_wright_string =
"WRIGHT"
146 character*(10),
parameter :: eos_teos10_string =
"TEOS10"
147 character*(10),
parameter :: eos_nemo_string =
"NEMO"
148 character*(10),
parameter :: eos_default = eos_wright_string
150 integer,
parameter :: tfreeze_linear = 1
151 integer,
parameter :: tfreeze_millero = 2
152 integer,
parameter :: tfreeze_teos10 = 3
153 character*(10),
parameter :: tfreeze_linear_string =
"LINEAR"
154 character*(10),
parameter :: tfreeze_millero_string =
"MILLERO_78"
156 character*(10),
parameter :: tfreeze_teos10_string =
"TEOS10"
157 character*(10),
parameter :: tfreeze_default = tfreeze_linear_string
165 subroutine calculate_density_scalar(T, S, pressure, rho, EOS, rho_ref, scale)
166 real,
intent(in) :: T
167 real,
intent(in) :: S
168 real,
intent(in) :: pressure
169 real,
intent(out) :: rho
171 real,
optional,
intent(in) :: rho_ref
172 real,
optional,
intent(in) :: scale
178 if (.not.
associated(eos))
call mom_error(fatal, &
179 "calculate_density_scalar called with an unassociated EOS_type EOS.")
181 p_scale = eos%RL2_T2_to_Pa
183 select case (eos%form_of_EOS)
186 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS, rho_ref)
196 call mom_error(fatal,
"calculate_density_scalar: EOS is not valid.")
199 rho_scale = eos%kg_m3_to_R
200 if (
present(scale)) rho_scale = rho_scale * scale
201 rho = rho_scale * rho
203 end subroutine calculate_density_scalar
211 subroutine calculate_stanley_density_scalar(T, S, pressure, Tvar, TScov, Svar, rho, EOS, rho_ref, scale)
212 real,
intent(in) :: T
213 real,
intent(in) :: S
214 real,
intent(in) :: Tvar
215 real,
intent(in) :: TScov
216 real,
intent(in) :: Svar
217 real,
intent(in) :: pressure
218 real,
intent(out) :: rho
220 real,
optional,
intent(in) :: rho_ref
221 real,
optional,
intent(in) :: scale
224 real :: d2RdTT, d2RdST, d2RdSS, d2RdSp, d2RdTp
228 if (.not.
associated(eos))
call mom_error(fatal, &
229 "calculate_stanley_density_scalar called with an unassociated EOS_type EOS.")
231 p_scale = eos%RL2_T2_to_Pa
233 select case (eos%form_of_EOS)
236 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS, rho_ref)
238 d2rdtt, d2rdsp, d2rdtp)
242 d2rdtt, d2rdsp, d2rdtp)
246 d2rdtt, d2rdsp, d2rdtp)
248 call mom_error(fatal,
"calculate_stanley_density_scalar: EOS is not valid.")
252 rho = rho + ( 0.5 * d2rdtt * tvar + ( d2rdst * tscov + 0.5 * d2rdss * svar ) )
254 rho_scale = eos%kg_m3_to_R
255 if (
present(scale)) rho_scale = rho_scale * scale
256 rho = rho_scale * rho
258 end subroutine calculate_stanley_density_scalar
262 subroutine calculate_density_array(T, S, pressure, rho, start, npts, EOS, rho_ref, scale)
263 real,
dimension(:),
intent(in) :: T
264 real,
dimension(:),
intent(in) :: S
265 real,
dimension(:),
intent(in) :: pressure
266 real,
dimension(:),
intent(inout) :: rho
267 integer,
intent(in) :: start
268 integer,
intent(in) :: npts
270 real,
optional,
intent(in) :: rho_ref
271 real,
optional,
intent(in) :: scale
275 if (.not.
associated(eos))
call mom_error(fatal, &
276 "calculate_density_array called with an unassociated EOS_type EOS.")
278 select case (eos%form_of_EOS)
281 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS, rho_ref)
291 call mom_error(fatal,
"calculate_density_array: EOS%form_of_EOS is not valid.")
294 if (
present(scale))
then ;
if (scale /= 1.0)
then ;
do j=start,start+npts-1
295 rho(j) = scale * rho(j)
296 enddo ;
endif ;
endif
298 end subroutine calculate_density_array
305 subroutine calculate_stanley_density_array(T, S, pressure, Tvar, TScov, Svar, rho, start, npts, EOS, rho_ref, scale)
306 real,
dimension(:),
intent(in) :: T
307 real,
dimension(:),
intent(in) :: S
308 real,
dimension(:),
intent(in) :: pressure
309 real,
dimension(:),
intent(in) :: Tvar
310 real,
dimension(:),
intent(in) :: TScov
311 real,
dimension(:),
intent(in) :: Svar
312 real,
dimension(:),
intent(inout) :: rho
313 integer,
intent(in) :: start
314 integer,
intent(in) :: npts
316 real,
optional,
intent(in) :: rho_ref
317 real,
optional,
intent(in) :: scale
320 real,
dimension(size(T)) :: d2RdTT, d2RdST, d2RdSS, d2RdSp, d2RdTp
323 if (.not.
associated(eos))
call mom_error(fatal, &
324 "calculate_density_array called with an unassociated EOS_type EOS.")
326 select case (eos%form_of_EOS)
329 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS, rho_ref)
331 d2rdtt, d2rdsp, d2rdtp, start, npts)
335 d2rdtt, d2rdsp, d2rdtp, start, npts)
339 d2rdtt, d2rdsp, d2rdtp, start, npts)
341 call mom_error(fatal,
"calculate_stanley_density_array: EOS%form_of_EOS is not valid.")
345 do j=start,start+npts-1
347 + ( 0.5 * d2rdtt(j) * tvar(j) + ( d2rdst(j) * tscov(j) + 0.5 * d2rdss(j) * svar(j) ) )
350 if (
present(scale))
then ;
if (scale /= 1.0)
then ;
do j=start,start+npts-1
351 rho(j) = scale * rho(j)
352 enddo ;
endif ;
endif
354 end subroutine calculate_stanley_density_array
359 subroutine calculate_density_1d(T, S, pressure, rho, EOS, dom, rho_ref, scale)
360 real,
dimension(:),
intent(in) :: T
361 real,
dimension(:),
intent(in) :: S
362 real,
dimension(:),
intent(in) :: pressure
363 real,
dimension(:),
intent(inout) :: rho
365 integer,
dimension(2),
optional,
intent(in) :: dom
367 real,
optional,
intent(in) :: rho_ref
368 real,
optional,
intent(in) :: scale
374 real :: rho_reference
375 real,
dimension(size(rho)) :: pres
376 integer :: i, is, ie, npts
378 if (.not.
associated(eos))
call mom_error(fatal, &
379 "calculate_density_1d called with an unassociated EOS_type EOS.")
381 if (
present(dom))
then
382 is = dom(1) ; ie = dom(2) ; npts = 1 + ie - is
384 is = 1 ; ie =
size(rho) ; npts = 1 + ie - is
387 p_scale = eos%RL2_T2_to_Pa
388 rho_unscale = eos%R_to_kg_m3
390 if ((p_scale == 1.0) .and. (rho_unscale == 1.0))
then
391 call calculate_density_array(t, s, pressure, rho, is, npts, eos, rho_ref=rho_ref)
392 elseif (
present(rho_ref))
then
393 do i=is,ie ; pres(i) = p_scale * pressure(i) ;
enddo
394 rho_reference = rho_unscale*rho_ref
395 call calculate_density_array(t, s, pres, rho, is, npts, eos, rho_ref=rho_reference)
398 do i=is,ie ; pres(i) = p_scale * pressure(i) ;
enddo
399 call calculate_density_array(t, s, pres, rho, is, npts, eos)
402 rho_scale = eos%kg_m3_to_R
403 if (
present(scale)) rho_scale = rho_scale * scale
404 if (rho_scale /= 1.0)
then ;
do i=is,ie
405 rho(i) = rho_scale * rho(i)
408 end subroutine calculate_density_1d
416 subroutine calculate_stanley_density_1d(T, S, pressure, Tvar, TScov, Svar, rho, EOS, dom, rho_ref, scale)
417 real,
dimension(:),
intent(in) :: T
418 real,
dimension(:),
intent(in) :: S
419 real,
dimension(:),
intent(in) :: pressure
420 real,
dimension(:),
intent(in) :: Tvar
421 real,
dimension(:),
intent(in) :: TScov
422 real,
dimension(:),
intent(in) :: Svar
423 real,
dimension(:),
intent(inout) :: rho
425 integer,
dimension(2),
optional,
intent(in) :: dom
427 real,
optional,
intent(in) :: rho_ref
428 real,
optional,
intent(in) :: scale
433 real,
dimension(size(rho)) :: pres
434 real,
dimension(size(T)) :: d2RdTT, d2RdST, d2RdSS, d2RdSp, d2RdTp
435 integer :: i, is, ie, npts
437 if (.not.
associated(eos))
call mom_error(fatal, &
438 "calculate_density_1d called with an unassociated EOS_type EOS.")
440 if (
present(dom))
then
441 is = dom(1) ; ie = dom(2) ; npts = 1 + ie - is
443 is = 1 ; ie =
size(rho) ; npts = 1 + ie - is
446 p_scale = eos%RL2_T2_to_Pa
448 pres(i) = p_scale * pressure(i)
451 select case (eos%form_of_EOS)
454 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS, rho_ref)
456 d2rdtt, d2rdsp, d2rdtp, 1, npts)
460 d2rdtt, d2rdsp, d2rdtp, 1, npts)
464 d2rdtt, d2rdsp, d2rdtp, 1, npts)
466 call mom_error(fatal,
"calculate_stanley_density_scalar: EOS is not valid.")
472 + ( 0.5 * d2rdtt(i) * tvar(i) + ( d2rdst(i) * tscov(i) + 0.5 * d2rdss(i) * svar(i) ) )
475 rho_scale = eos%kg_m3_to_R
476 if (
present(scale)) rho_scale = rho_scale * scale
477 if (rho_scale /= 1.0)
then ;
do i=is,ie
478 rho(i) = rho_scale * rho(i)
481 end subroutine calculate_stanley_density_1d
485 subroutine calculate_spec_vol_array(T, S, pressure, specvol, start, npts, EOS, spv_ref, scale)
486 real,
dimension(:),
intent(in) :: T
487 real,
dimension(:),
intent(in) :: S
488 real,
dimension(:),
intent(in) :: pressure
489 real,
dimension(:),
intent(inout) :: specvol
490 integer,
intent(in) :: start
491 integer,
intent(in) :: npts
493 real,
optional,
intent(in) :: spv_ref
494 real,
optional,
intent(in) :: scale
497 real,
dimension(size(specvol)) :: rho
500 if (.not.
associated(eos))
call mom_error(fatal, &
501 "calculate_spec_vol_array called with an unassociated EOS_type EOS.")
503 select case (eos%form_of_EOS)
506 eos%rho_T0_S0, eos%drho_dT, eos%drho_dS, spv_ref)
515 if (
present(spv_ref))
then
516 specvol(:) = 1.0 / rho(:) - spv_ref
518 specvol(:) = 1.0 / rho(:)
521 call mom_error(fatal,
"calculate_spec_vol_array: EOS%form_of_EOS is not valid.")
524 if (
present(scale))
then ;
if (scale /= 1.0)
then ;
do j=start,start+npts-1
525 specvol(j) = scale * specvol(j)
526 enddo ;
endif ;
endif
528 end subroutine calculate_spec_vol_array
532 subroutine calc_spec_vol_scalar(T, S, pressure, specvol, EOS, spv_ref, scale)
533 real,
intent(in) :: T
534 real,
intent(in) :: S
535 real,
intent(in) :: pressure
536 real,
intent(out) :: specvol
538 real,
optional,
intent(in) :: spv_ref
539 real,
optional,
intent(in) :: scale
542 real,
dimension(1) :: Ta, Sa, pres, spv
543 real :: spv_reference
546 if (.not.
associated(eos))
call mom_error(fatal, &
547 "calc_spec_vol_scalar called with an unassociated EOS_type EOS.")
549 pres(1) = eos%RL2_T2_to_Pa*pressure
550 ta(1) = t ; sa(1) = s
552 if (
present(spv_ref))
then
553 spv_reference = eos%kg_m3_to_R*spv_ref
554 call calculate_spec_vol_array(ta, sa, pres, spv, 1, 1, eos, spv_reference)
556 call calculate_spec_vol_array(ta, sa, pres, spv, 1, 1, eos)
560 spv_scale = eos%R_to_kg_m3
561 if (
present(scale)) spv_scale = spv_scale * scale
562 if (spv_scale /= 1.0)
then
563 specvol = spv_scale * specvol
566 end subroutine calc_spec_vol_scalar
570 subroutine calc_spec_vol_1d(T, S, pressure, specvol, EOS, dom, spv_ref, scale)
571 real,
dimension(:),
intent(in) :: T
572 real,
dimension(:),
intent(in) :: S
573 real,
dimension(:),
intent(in) :: pressure
574 real,
dimension(:),
intent(inout) :: specvol
576 integer,
dimension(2),
optional,
intent(in) :: dom
578 real,
optional,
intent(in) :: spv_ref
579 real,
optional,
intent(in) :: scale
583 real,
dimension(size(specvol)) :: pres
587 real :: spv_reference
588 integer :: i, is, ie, npts
590 if (.not.
associated(eos))
call mom_error(fatal, &
591 "calc_spec_vol_1d called with an unassociated EOS_type EOS.")
593 if (
present(dom))
then
594 is = dom(1) ; ie = dom(2) ; npts = 1 + ie - is
596 is = 1 ; ie =
size(specvol) ; npts = 1 + ie - is
599 p_scale = eos%RL2_T2_to_Pa
600 spv_unscale = eos%kg_m3_to_R
602 if ((p_scale == 1.0) .and. (spv_unscale == 1.0))
then
603 call calculate_spec_vol_array(t, s, pressure, specvol, is, npts, eos, spv_ref)
604 elseif (
present(spv_ref))
then
605 do i=is,ie ; pres(i) = p_scale * pressure(i) ;
enddo
606 spv_reference = spv_unscale*spv_ref
607 call calculate_spec_vol_array(t, s, pres, specvol, is, npts, eos, spv_reference)
610 do i=is,ie ; pres(i) = p_scale * pressure(i) ;
enddo
611 call calculate_spec_vol_array(t, s, pres, specvol, is, npts, eos)
614 spv_scale = eos%R_to_kg_m3
615 if (
present(scale)) spv_scale = spv_scale * scale
616 if (spv_scale /= 1.0)
then ;
do i=is,ie
617 specvol(i) = spv_scale * specvol(i)
620 end subroutine calc_spec_vol_1d
624 subroutine calculate_tfreeze_scalar(S, pressure, T_fr, EOS, pres_scale)
625 real,
intent(in) :: S
626 real,
intent(in) :: pressure
627 real,
intent(out) :: T_fr
630 real,
optional,
intent(in) :: pres_scale
635 if (.not.
associated(eos))
call mom_error(fatal, &
636 "calculate_TFreeze_scalar called with an unassociated EOS_type EOS.")
638 p_scale = 1.0 ;
if (
present(pres_scale)) p_scale = pres_scale
640 select case (eos%form_of_TFreeze)
641 case (tfreeze_linear)
643 eos%dTFr_dS, eos%dTFr_dp)
644 case (tfreeze_millero)
646 case (tfreeze_teos10)
649 call mom_error(fatal,
"calculate_TFreeze_scalar: form_of_TFreeze is not valid.")
652 end subroutine calculate_tfreeze_scalar
655 subroutine calculate_tfreeze_array(S, pressure, T_fr, start, npts, EOS, pres_scale)
656 real,
dimension(:),
intent(in) :: S
657 real,
dimension(:),
intent(in) :: pressure
658 real,
dimension(:),
intent(inout) :: T_fr
660 integer,
intent(in) :: start
661 integer,
intent(in) :: npts
663 real,
optional,
intent(in) :: pres_scale
666 real,
dimension(size(pressure)) :: pres
670 if (.not.
associated(eos))
call mom_error(fatal, &
671 "calculate_TFreeze_scalar called with an unassociated EOS_type EOS.")
673 p_scale = 1.0 ;
if (
present(pres_scale)) p_scale = pres_scale
675 if (p_scale == 1.0)
then
676 select case (eos%form_of_TFreeze)
677 case (tfreeze_linear)
679 eos%TFr_S0_P0, eos%dTFr_dS, eos%dTFr_dp)
680 case (tfreeze_millero)
682 case (tfreeze_teos10)
685 call mom_error(fatal,
"calculate_TFreeze_scalar: form_of_TFreeze is not valid.")
688 do j=start,start+npts-1 ; pres(j) = p_scale * pressure(j) ;
enddo
689 select case (eos%form_of_TFreeze)
690 case (tfreeze_linear)
692 eos%TFr_S0_P0, eos%dTFr_dS, eos%dTFr_dp)
693 case (tfreeze_millero)
695 case (tfreeze_teos10)
698 call mom_error(fatal,
"calculate_TFreeze_scalar: form_of_TFreeze is not valid.")
702 end subroutine calculate_tfreeze_array
705 subroutine calculate_density_derivs_array(T, S, pressure, drho_dT, drho_dS, start, npts, EOS, scale)
706 real,
dimension(:),
intent(in) :: T
707 real,
dimension(:),
intent(in) :: S
708 real,
dimension(:),
intent(in) :: pressure
709 real,
dimension(:),
intent(inout) :: drho_dT
711 real,
dimension(:),
intent(inout) :: drho_dS
713 integer,
intent(in) :: start
714 integer,
intent(in) :: npts
716 real,
optional,
intent(in) :: scale
722 if (.not.
associated(eos))
call mom_error(fatal, &
723 "calculate_density_derivs called with an unassociated EOS_type EOS.")
725 select case (eos%form_of_EOS)
728 eos%dRho_dT, eos%dRho_dS, start, npts)
730 call calculate_density_derivs_unesco(t, s, pressure, drho_dt, drho_ds, start, npts)
738 call mom_error(fatal,
"calculate_density_derivs_array: EOS%form_of_EOS is not valid.")
741 if (
present(scale))
then ;
if (scale /= 1.0)
then ;
do j=start,start+npts-1
742 drho_dt(j) = scale * drho_dt(j)
743 drho_ds(j) = scale * drho_ds(j)
744 enddo ;
endif ;
endif
746 end subroutine calculate_density_derivs_array
750 subroutine calculate_density_derivs_1d(T, S, pressure, drho_dT, drho_dS, EOS, dom, scale)
751 real,
dimension(:),
intent(in) :: T
752 real,
dimension(:),
intent(in) :: S
753 real,
dimension(:),
intent(in) :: pressure
754 real,
dimension(:),
intent(inout) :: drho_dT
756 real,
dimension(:),
intent(inout) :: drho_dS
759 integer,
dimension(2),
optional,
intent(in) :: dom
761 real,
optional,
intent(in) :: scale
764 real,
dimension(size(drho_dT)) :: pres
767 integer :: i, is, ie, npts
769 if (.not.
associated(eos))
call mom_error(fatal, &
770 "calculate_density_derivs called with an unassociated EOS_type EOS.")
772 if (
present(dom))
then
773 is = dom(1) ; ie = dom(2) ; npts = 1 + ie - is
775 is = 1 ; ie =
size(drho_dt) ; npts = 1 + ie - is
778 p_scale = eos%RL2_T2_to_Pa
780 if (p_scale == 1.0)
then
781 call calculate_density_derivs_array(t, s, pressure, drho_dt, drho_ds, is, npts, eos)
783 do i=is,ie ; pres(i) = p_scale * pressure(i) ;
enddo
784 call calculate_density_derivs_array(t, s, pres, drho_dt, drho_ds, is, npts, eos)
787 rho_scale = eos%kg_m3_to_R
788 if (
present(scale)) rho_scale = rho_scale * scale
789 if (rho_scale /= 1.0)
then ;
do i=is,ie
790 drho_dt(i) = rho_scale * drho_dt(i)
791 drho_ds(i) = rho_scale * drho_ds(i)
794 end subroutine calculate_density_derivs_1d
799 subroutine calculate_density_derivs_scalar(T, S, pressure, drho_dT, drho_dS, EOS, scale)
800 real,
intent(in) :: T
801 real,
intent(in) :: S
802 real,
intent(in) :: pressure
803 real,
intent(out) :: drho_dT
805 real,
intent(out) :: drho_dS
808 real,
optional,
intent(in) :: scale
815 if (.not.
associated(eos))
call mom_error(fatal, &
816 "calculate_density_derivs called with an unassociated EOS_type EOS.")
818 p_scale = eos%RL2_T2_to_Pa
820 select case (eos%form_of_EOS)
823 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS)
829 call mom_error(fatal,
"calculate_density_derivs_scalar: EOS%form_of_EOS is not valid.")
832 rho_scale = eos%kg_m3_to_R
833 if (
present(scale)) rho_scale = rho_scale * scale
834 if (rho_scale /= 1.0)
then
835 drho_dt = rho_scale * drho_dt
836 drho_ds = rho_scale * drho_ds
839 end subroutine calculate_density_derivs_scalar
842 subroutine calculate_density_second_derivs_array(T, S, pressure, drho_dS_dS, drho_dS_dT, drho_dT_dT, &
843 drho_dS_dP, drho_dT_dP, start, npts, EOS, scale)
844 real,
dimension(:),
intent(in) :: T
845 real,
dimension(:),
intent(in) :: S
846 real,
dimension(:),
intent(in) :: pressure
847 real,
dimension(:),
intent(inout) :: drho_dS_dS
849 real,
dimension(:),
intent(inout) :: drho_dS_dT
851 real,
dimension(:),
intent(inout) :: drho_dT_dT
853 real,
dimension(:),
intent(inout) :: drho_dS_dP
855 real,
dimension(:),
intent(inout) :: drho_dT_dP
857 integer,
intent(in) :: start
858 integer,
intent(in) :: npts
860 real,
optional,
intent(in) :: scale
863 real,
dimension(size(pressure)) :: pres
869 if (.not.
associated(eos))
call mom_error(fatal, &
870 "calculate_density_derivs called with an unassociated EOS_type EOS.")
872 p_scale = eos%RL2_T2_to_Pa
874 if (p_scale == 1.0)
then
875 select case (eos%form_of_EOS)
878 drho_dt_dt, drho_ds_dp, drho_dt_dp, start, npts)
881 drho_dt_dt, drho_ds_dp, drho_dt_dp, start, npts)
884 drho_dt_dt, drho_ds_dp, drho_dt_dp, start, npts)
886 call mom_error(fatal,
"calculate_density_derivs: EOS%form_of_EOS is not valid.")
889 do j=start,start+npts-1 ; pres(j) = p_scale * pressure(j) ;
enddo
890 select case (eos%form_of_EOS)
893 drho_dt_dt, drho_ds_dp, drho_dt_dp, start, npts)
896 drho_dt_dt, drho_ds_dp, drho_dt_dp, start, npts)
899 drho_dt_dt, drho_ds_dp, drho_dt_dp, start, npts)
901 call mom_error(fatal,
"calculate_density_derivs: EOS%form_of_EOS is not valid.")
905 rho_scale = eos%kg_m3_to_R
906 if (
present(scale)) rho_scale = rho_scale * scale
907 if (rho_scale /= 1.0)
then ;
do j=start,start+npts-1
908 drho_ds_ds(j) = rho_scale * drho_ds_ds(j)
909 drho_ds_dt(j) = rho_scale * drho_ds_dt(j)
910 drho_dt_dt(j) = rho_scale * drho_dt_dt(j)
911 drho_ds_dp(j) = rho_scale * drho_ds_dp(j)
912 drho_dt_dp(j) = rho_scale * drho_dt_dp(j)
915 if (p_scale /= 1.0)
then
916 i_p_scale = 1.0 / p_scale
917 do j=start,start+npts-1
918 drho_ds_dp(j) = i_p_scale * drho_ds_dp(j)
919 drho_dt_dp(j) = i_p_scale * drho_dt_dp(j)
923 end subroutine calculate_density_second_derivs_array
926 subroutine calculate_density_second_derivs_scalar(T, S, pressure, drho_dS_dS, drho_dS_dT, drho_dT_dT, &
927 drho_dS_dP, drho_dT_dP, EOS, scale)
928 real,
intent(in) :: T
929 real,
intent(in) :: S
930 real,
intent(in) :: pressure
931 real,
intent(out) :: drho_dS_dS
933 real,
intent(out) :: drho_dS_dT
935 real,
intent(out) :: drho_dT_dT
937 real,
intent(out) :: drho_dS_dP
939 real,
intent(out) :: drho_dT_dP
942 real,
optional,
intent(in) :: scale
949 if (.not.
associated(eos))
call mom_error(fatal, &
950 "calculate_density_derivs called with an unassociated EOS_type EOS.")
952 p_scale = eos%RL2_T2_to_Pa
954 select case (eos%form_of_EOS)
957 drho_dt_dt, drho_ds_dp, drho_dt_dp)
960 drho_dt_dt, drho_ds_dp, drho_dt_dp)
963 drho_dt_dt, drho_ds_dp, drho_dt_dp)
965 call mom_error(fatal,
"calculate_density_derivs: EOS%form_of_EOS is not valid.")
968 rho_scale = eos%kg_m3_to_R
969 if (
present(scale)) rho_scale = rho_scale * scale
970 if (rho_scale /= 1.0)
then
971 drho_ds_ds = rho_scale * drho_ds_ds
972 drho_ds_dt = rho_scale * drho_ds_dt
973 drho_dt_dt = rho_scale * drho_dt_dt
974 drho_ds_dp = rho_scale * drho_ds_dp
975 drho_dt_dp = rho_scale * drho_dt_dp
978 if (p_scale /= 1.0)
then
979 i_p_scale = 1.0 / p_scale
980 drho_ds_dp = i_p_scale * drho_ds_dp
981 drho_dt_dp = i_p_scale * drho_dt_dp
984 end subroutine calculate_density_second_derivs_scalar
987 subroutine calculate_spec_vol_derivs_array(T, S, pressure, dSV_dT, dSV_dS, start, npts, EOS)
988 real,
dimension(:),
intent(in) :: T
989 real,
dimension(:),
intent(in) :: S
990 real,
dimension(:),
intent(in) :: pressure
991 real,
dimension(:),
intent(inout) :: dSV_dT
993 real,
dimension(:),
intent(inout) :: dSV_dS
995 integer,
intent(in) :: start
996 integer,
intent(in) :: npts
1000 real,
dimension(size(T)) :: press
1001 real,
dimension(size(T)) :: rho
1002 real,
dimension(size(T)) :: dRho_dT
1003 real,
dimension(size(T)) :: dRho_dS
1006 if (.not.
associated(eos))
call mom_error(fatal, &
1007 "calculate_spec_vol_derivs_array called with an unassociated EOS_type EOS.")
1009 select case (eos%form_of_EOS)
1011 call calculate_specvol_derivs_linear(t, s, pressure, dsv_dt, dsv_ds, start, &
1012 npts, eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS)
1015 call calculate_density_derivs_unesco(t, s, pressure, drho_dt, drho_ds, start, npts)
1016 do j=start,start+npts-1
1017 dsv_dt(j) = -drho_dt(j)/(rho(j)**2)
1018 dsv_ds(j) = -drho_ds(j)/(rho(j)**2)
1021 call calculate_specvol_derivs_wright(t, s, pressure, dsv_dt, dsv_ds, start, npts)
1023 call calculate_specvol_derivs_teos10(t, s, pressure, dsv_dt, dsv_ds, start, npts)
1027 do j=start,start+npts-1
1028 dsv_dt(j) = -drho_dt(j)/(rho(j)**2)
1029 dsv_ds(j) = -drho_ds(j)/(rho(j)**2)
1032 call mom_error(fatal,
"calculate_spec_vol_derivs_array: EOS%form_of_EOS is not valid.")
1035 end subroutine calculate_spec_vol_derivs_array
1039 subroutine calc_spec_vol_derivs_1d(T, S, pressure, dSV_dT, dSV_dS, EOS, dom, scale)
1040 real,
dimension(:),
intent(in) :: T
1041 real,
dimension(:),
intent(in) :: S
1042 real,
dimension(:),
intent(in) :: pressure
1043 real,
dimension(:),
intent(inout) :: dSV_dT
1045 real,
dimension(:),
intent(inout) :: dSV_dS
1048 integer,
dimension(2),
optional,
intent(in) :: dom
1050 real,
optional,
intent(in) :: scale
1054 real,
dimension(size(dSV_dT)) :: press
1057 integer :: i, is, ie, npts
1059 if (.not.
associated(eos))
call mom_error(fatal, &
1060 "calculate_spec_vol_derivs_1d called with an unassociated EOS_type EOS.")
1062 if (
present(dom))
then
1063 is = dom(1) ; ie = dom(2) ; npts = 1 + ie - is
1065 is = 1 ; ie =
size(dsv_dt) ; npts = 1 + ie - is
1067 p_scale = eos%RL2_T2_to_Pa
1069 if (p_scale == 1.0)
then
1070 call calculate_spec_vol_derivs_array(t, s, pressure, dsv_dt, dsv_ds, is, npts, eos)
1072 do i=is,ie ; press(i) = p_scale * pressure(i) ;
enddo
1073 call calculate_spec_vol_derivs_array(t, s, press, dsv_dt, dsv_ds, is, npts, eos)
1076 spv_scale = eos%R_to_kg_m3
1077 if (
present(scale)) spv_scale = spv_scale * scale
1078 if (spv_scale /= 1.0)
then ;
do i=is,ie
1079 dsv_dt(i) = spv_scale * dsv_dt(i)
1080 dsv_ds(i) = spv_scale * dsv_ds(i)
1083 end subroutine calc_spec_vol_derivs_1d
1088 subroutine calculate_compress_array(T, S, press, rho, drho_dp, start, npts, EOS)
1089 real,
dimension(:),
intent(in) :: T
1090 real,
dimension(:),
intent(in) :: S
1091 real,
dimension(:),
intent(in) :: press
1092 real,
dimension(:),
intent(inout) :: rho
1093 real,
dimension(:),
intent(inout) :: drho_dp
1096 integer,
intent(in) :: start
1097 integer,
intent(in) :: npts
1101 real,
dimension(size(press)) :: pressure
1102 integer :: i, is, ie
1104 if (.not.
associated(eos))
call mom_error(fatal, &
1105 "calculate_compress called with an unassociated EOS_type EOS.")
1107 is = start ; ie = is + npts - 1
1108 do i=is,ie ; pressure(i) = eos%RL2_T2_to_Pa * press(i) ;
enddo
1110 select case (eos%form_of_EOS)
1112 call calculate_compress_linear(t, s, pressure, rho, drho_dp, start, npts, &
1113 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS)
1115 call calculate_compress_unesco(t, s, pressure, rho, drho_dp, start, npts)
1117 call calculate_compress_wright(t, s, pressure, rho, drho_dp, start, npts)
1119 call calculate_compress_teos10(t, s, pressure, rho, drho_dp, start, npts)
1121 call calculate_compress_nemo(t, s, pressure, rho, drho_dp, start, npts)
1123 call mom_error(fatal,
"calculate_compress: EOS%form_of_EOS is not valid.")
1126 if (eos%kg_m3_to_R /= 1.0)
then ;
do i=is,ie
1127 rho(i) = eos%kg_m3_to_R * rho(i)
1129 if (eos%L_T_to_m_s /= 1.0)
then ;
do i=is,ie
1130 drho_dp(i) = eos%L_T_to_m_s**2 * drho_dp(i)
1133 end subroutine calculate_compress_array
1138 subroutine calculate_compress_scalar(T, S, pressure, rho, drho_dp, EOS)
1139 real,
intent(in) :: T
1140 real,
intent(in) :: S
1141 real,
intent(in) :: pressure
1142 real,
intent(out) :: rho
1143 real,
intent(out) :: drho_dp
1148 real,
dimension(1) :: Ta, Sa, pa, rhoa, drho_dpa
1150 if (.not.
associated(eos))
call mom_error(fatal, &
1151 "calculate_compress called with an unassociated EOS_type EOS.")
1152 ta(1) = t ; sa(1) = s; pa(1) = pressure
1154 call calculate_compress_array(ta, sa, pa, rhoa, drho_dpa, 1, 1, eos)
1155 rho = rhoa(1) ; drho_dp = drho_dpa(1)
1157 end subroutine calculate_compress_scalar
1162 function eos_domain(HI, halo)
result(EOSdom)
1164 integer,
optional,
intent(in) :: halo
1165 integer,
dimension(2) :: eosdom
1171 halo_sz = 0 ;
if (
present(halo)) halo_sz = halo
1173 eosdom(1) = hi%isc - (hi%isd-1) - halo_sz
1174 eosdom(2) = hi%iec - (hi%isd-1) + halo_sz
1176 end function eos_domain
1185 subroutine analytic_int_specific_vol_dp(T, S, p_t, p_b, alpha_ref, HI, EOS, &
1186 dza, intp_dza, intx_dza, inty_dza, halo_size, &
1187 bathyP, dP_tiny, useMassWghtInterp)
1189 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1191 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1193 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1195 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1197 real,
intent(in) :: alpha_ref
1202 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1203 intent(inout) :: dza
1205 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1206 optional,
intent(inout) :: intp_dza
1209 real,
dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), &
1210 optional,
intent(inout) :: intx_dza
1213 real,
dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), &
1214 optional,
intent(inout) :: inty_dza
1217 integer,
optional,
intent(in) :: halo_size
1218 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1219 optional,
intent(in) :: bathyp
1220 real,
optional,
intent(in) :: dp_tiny
1222 logical,
optional,
intent(in) :: usemasswghtinterp
1229 if (.not.
associated(eos))
call mom_error(fatal, &
1230 "int_specific_vol_dp called with an unassociated EOS_type EOS.")
1234 if (eos%EOS_quadrature)
call mom_error(fatal,
"EOS_quadrature is set!")
1236 select case (eos%form_of_EOS)
1238 call int_spec_vol_dp_linear(t, s, p_t, p_b, alpha_ref, hi, eos%kg_m3_to_R*eos%Rho_T0_S0, &
1239 eos%kg_m3_to_R*eos%dRho_dT, eos%kg_m3_to_R*eos%dRho_dS, dza, &
1240 intp_dza, intx_dza, inty_dza, halo_size, &
1241 bathyp, dp_tiny, usemasswghtinterp)
1243 call int_spec_vol_dp_wright(t, s, p_t, p_b, alpha_ref, hi, dza, intp_dza, intx_dza, &
1244 inty_dza, halo_size, bathyp, dp_tiny, usemasswghtinterp, &
1245 sv_scale=eos%R_to_kg_m3, pres_scale=eos%RL2_T2_to_Pa)
1247 call mom_error(fatal,
"No analytic integration option is available with this EOS!")
1250 end subroutine analytic_int_specific_vol_dp
1255 subroutine analytic_int_density_dz(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, EOS, dpa, &
1256 intz_dpa, intx_dpa, inty_dpa, bathyT, dz_neglect, useMassWghtInterp)
1258 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1260 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1262 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1264 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1266 real,
intent(in) :: rho_ref
1269 real,
intent(in) :: rho_0
1272 real,
intent(in) :: g_e
1275 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1276 intent(inout) :: dpa
1278 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1279 optional,
intent(inout) :: intz_dpa
1282 real,
dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), &
1283 optional,
intent(inout) :: intx_dpa
1286 real,
dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), &
1287 optional,
intent(inout) :: inty_dpa
1290 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1291 optional,
intent(in) :: bathyt
1292 real,
optional,
intent(in) :: dz_neglect
1293 logical,
optional,
intent(in) :: usemasswghtinterp
1300 if (.not.
associated(eos))
call mom_error(fatal, &
1301 "int_density_dz called with an unassociated EOS_type EOS.")
1305 if (eos%EOS_quadrature)
call mom_error(fatal,
"EOS_quadrature is set!")
1307 select case (eos%form_of_EOS)
1309 rho_scale = eos%kg_m3_to_R
1310 if (rho_scale /= 1.0)
then
1311 call int_density_dz_linear(t, s, z_t, z_b, rho_ref, rho_0, g_e, hi, &
1312 rho_scale*eos%Rho_T0_S0, rho_scale*eos%dRho_dT, rho_scale*eos%dRho_dS, &
1313 dpa, intz_dpa, intx_dpa, inty_dpa, bathyt, dz_neglect, usemasswghtinterp)
1315 call int_density_dz_linear(t, s, z_t, z_b, rho_ref, rho_0, g_e, hi, &
1316 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS, &
1317 dpa, intz_dpa, intx_dpa, inty_dpa, bathyt, dz_neglect, usemasswghtinterp)
1320 rho_scale = eos%kg_m3_to_R
1321 pres_scale = eos%RL2_T2_to_Pa
1322 if ((rho_scale /= 1.0) .or. (pres_scale /= 1.0))
then
1323 call int_density_dz_wright(t, s, z_t, z_b, rho_ref, rho_0, g_e, hi, &
1324 dpa, intz_dpa, intx_dpa, inty_dpa, bathyt, &
1325 dz_neglect, usemasswghtinterp, rho_scale, pres_scale)
1327 call int_density_dz_wright(t, s, z_t, z_b, rho_ref, rho_0, g_e, hi, &
1328 dpa, intz_dpa, intx_dpa, inty_dpa, bathyt, &
1329 dz_neglect, usemasswghtinterp)
1332 call mom_error(fatal,
"No analytic integration option is available with this EOS!")
1335 end subroutine analytic_int_density_dz
1338 logical function query_compressible(EOS)
1341 if (.not.
associated(eos))
call mom_error(fatal, &
1342 "query_compressible called with an unassociated EOS_type EOS.")
1344 query_compressible = eos%compressible
1345 end function query_compressible
1348 subroutine eos_init(param_file, EOS, US)
1354 #include "version_variable.h"
1355 character(len=40) :: mdl =
"MOM_EOS"
1356 character(len=40) :: tmpstr
1358 if (.not.
associated(eos))
call eos_allocate(eos)
1363 call get_param(param_file, mdl,
"EQN_OF_STATE", tmpstr, &
1364 "EQN_OF_STATE determines which ocean equation of state "//&
1365 "should be used. Currently, the valid choices are "//&
1366 '"LINEAR", "UNESCO", "WRIGHT", "NEMO" and "TEOS10". '//&
1367 "This is only used if USE_EOS is true.", default=eos_default)
1368 select case (uppercase(tmpstr))
1369 case (eos_linear_string)
1370 eos%form_of_EOS = eos_linear
1371 case (eos_unesco_string)
1372 eos%form_of_EOS = eos_unesco
1373 case (eos_wright_string)
1374 eos%form_of_EOS = eos_wright
1375 case (eos_teos10_string)
1376 eos%form_of_EOS = eos_teos10
1377 case (eos_nemo_string)
1378 eos%form_of_EOS = eos_nemo
1380 call mom_error(fatal,
"interpret_eos_selection: EQN_OF_STATE "//&
1381 trim(tmpstr) //
"in input file is invalid.")
1383 call mom_mesg(
'interpret_eos_selection: equation of state set to "' // &
1384 trim(tmpstr)//
'"', 5)
1386 if (eos%form_of_EOS == eos_linear)
then
1387 eos%Compressible = .false.
1388 call get_param(param_file, mdl,
"RHO_T0_S0", eos%Rho_T0_S0, &
1389 "When EQN_OF_STATE="//trim(eos_linear_string)//
", "//&
1390 "this is the density at T=0, S=0.", units=
"kg m-3", &
1392 call get_param(param_file, mdl,
"DRHO_DT", eos%dRho_dT, &
1393 "When EQN_OF_STATE="//trim(eos_linear_string)//
", "//&
1394 "this is the partial derivative of density with "//&
1395 "temperature.", units=
"kg m-3 K-1", default=-0.2)
1396 call get_param(param_file, mdl,
"DRHO_DS", eos%dRho_dS, &
1397 "When EQN_OF_STATE="//trim(eos_linear_string)//
", "//&
1398 "this is the partial derivative of density with "//&
1399 "salinity.", units=
"kg m-3 PSU-1", default=0.8)
1402 call get_param(param_file, mdl,
"EOS_QUADRATURE", eos%EOS_quadrature, &
1403 "If true, always use the generic (quadrature) code "//&
1404 "code for the integrals of density.", default=.false.)
1406 call get_param(param_file, mdl,
"TFREEZE_FORM", tmpstr, &
1407 "TFREEZE_FORM determines which expression should be "//&
1408 "used for the freezing point. Currently, the valid "//&
1409 'choices are "LINEAR", "MILLERO_78", "TEOS10"', &
1410 default=tfreeze_default)
1411 select case (uppercase(tmpstr))
1412 case (tfreeze_linear_string)
1413 eos%form_of_TFreeze = tfreeze_linear
1414 case (tfreeze_millero_string)
1415 eos%form_of_TFreeze = tfreeze_millero
1416 case (tfreeze_teos10_string)
1417 eos%form_of_TFreeze = tfreeze_teos10
1419 call mom_error(fatal,
"interpret_eos_selection: TFREEZE_FORM "//&
1420 trim(tmpstr) //
"in input file is invalid.")
1423 if (eos%form_of_TFreeze == tfreeze_linear)
then
1424 call get_param(param_file, mdl,
"TFREEZE_S0_P0",eos%TFr_S0_P0, &
1425 "When TFREEZE_FORM="//trim(tfreeze_linear_string)//
", "//&
1426 "this is the freezing potential temperature at "//&
1427 "S=0, P=0.", units=
"deg C", default=0.0)
1428 call get_param(param_file, mdl,
"DTFREEZE_DS",eos%dTFr_dS, &
1429 "When TFREEZE_FORM="//trim(tfreeze_linear_string)//
", "//&
1430 "this is the derivative of the freezing potential "//&
1431 "temperature with salinity.", &
1432 units=
"deg C PSU-1", default=-0.054)
1433 call get_param(param_file, mdl,
"DTFREEZE_DP",eos%dTFr_dP, &
1434 "When TFREEZE_FORM="//trim(tfreeze_linear_string)//
", "//&
1435 "this is the derivative of the freezing potential "//&
1436 "temperature with pressure.", &
1437 units=
"deg C Pa-1", default=0.0)
1440 if ((eos%form_of_EOS == eos_teos10 .OR. eos%form_of_EOS == eos_nemo) .AND. &
1441 eos%form_of_TFreeze /= tfreeze_teos10)
then
1442 call mom_error(fatal,
"interpret_eos_selection: EOS_TEOS10 or EOS_NEMO \n" //&
1443 "should only be used along with TFREEZE_FORM = TFREEZE_TEOS10 .")
1447 eos%m_to_Z = 1. ;
if (
present(us)) eos%m_to_Z = us%m_to_Z
1448 eos%kg_m3_to_R = 1. ;
if (
present(us)) eos%kg_m3_to_R = us%kg_m3_to_R
1449 eos%R_to_kg_m3 = 1. ;
if (
present(us)) eos%R_to_kg_m3 = us%R_to_kg_m3
1450 eos%RL2_T2_to_Pa = 1. ;
if (
present(us)) eos%RL2_T2_to_Pa = us%RL2_T2_to_Pa
1451 eos%L_T_to_m_s = 1. ;
if (
present(us)) eos%L_T_to_m_s = us%L_T_to_m_s
1453 end subroutine eos_init
1456 subroutine eos_manual_init(EOS, form_of_EOS, form_of_TFreeze, EOS_quadrature, Compressible, &
1457 Rho_T0_S0, drho_dT, dRho_dS, TFr_S0_P0, dTFr_dS, dTFr_dp)
1459 integer,
optional,
intent(in) :: form_of_eos
1460 integer,
optional,
intent(in) :: form_of_tfreeze
1462 logical,
optional,
intent(in) :: eos_quadrature
1464 logical,
optional,
intent(in) :: compressible
1465 real ,
optional,
intent(in) :: rho_t0_s0
1466 real ,
optional,
intent(in) :: drho_dt
1468 real ,
optional,
intent(in) :: drho_ds
1470 real ,
optional,
intent(in) :: tfr_s0_p0
1471 real ,
optional,
intent(in) :: dtfr_ds
1473 real ,
optional,
intent(in) :: dtfr_dp
1476 if (
present(form_of_eos )) eos%form_of_EOS = form_of_eos
1477 if (
present(form_of_tfreeze)) eos%form_of_TFreeze = form_of_tfreeze
1478 if (
present(eos_quadrature )) eos%EOS_quadrature = eos_quadrature
1479 if (
present(compressible )) eos%Compressible = compressible
1480 if (
present(rho_t0_s0 )) eos%Rho_T0_S0 = rho_t0_s0
1481 if (
present(drho_dt )) eos%drho_dT = drho_dt
1482 if (
present(drho_ds )) eos%dRho_dS = drho_ds
1483 if (
present(tfr_s0_p0 )) eos%TFr_S0_P0 = tfr_s0_p0
1484 if (
present(dtfr_ds )) eos%dTFr_dS = dtfr_ds
1485 if (
present(dtfr_dp )) eos%dTFr_dp = dtfr_dp
1487 end subroutine eos_manual_init
1490 subroutine eos_allocate(EOS)
1493 if (.not.
associated(eos))
allocate(eos)
1494 end subroutine eos_allocate
1497 subroutine eos_end(EOS)
1500 if (
associated(eos))
deallocate(eos)
1501 end subroutine eos_end
1508 subroutine eos_use_linear(Rho_T0_S0, dRho_dT, dRho_dS, EOS, use_quadrature)
1509 real,
intent(in) :: rho_t0_s0
1510 real,
intent(in) :: drho_dt
1511 real,
intent(in) :: drho_ds
1512 logical,
optional,
intent(in) :: use_quadrature
1516 if (.not.
associated(eos))
call mom_error(fatal, &
1517 "MOM_EOS.F90: EOS_use_linear() called with an unassociated EOS_type EOS.")
1519 eos%form_of_EOS = eos_linear
1520 eos%Compressible = .false.
1521 eos%Rho_T0_S0 = rho_t0_s0
1522 eos%dRho_dT = drho_dt
1523 eos%dRho_dS = drho_ds
1524 eos%EOS_quadrature = .false.
1525 if (
present(use_quadrature)) eos%EOS_quadrature = use_quadrature
1527 end subroutine eos_use_linear
1531 subroutine convert_temp_salt_for_teos10(T, S, HI, kd, mask_z, EOS)
1532 integer,
intent(in) :: kd
1534 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed,kd), &
1536 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed,kd), &
1538 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed,kd), &
1539 intent(in) :: mask_z
1543 real :: gsw_sr_from_sp, gsw_ct_from_pt, gsw_sa_from_sp
1546 if (.not.
associated(eos))
call mom_error(fatal, &
1547 "convert_temp_salt_to_TEOS10 called with an unassociated EOS_type EOS.")
1549 if ((eos%form_of_EOS /= eos_teos10) .and. (eos%form_of_EOS /= eos_nemo))
return
1551 do k=1,kd ;
do j=hi%jsc,hi%jec ;
do i=hi%isc,hi%iec
1552 if (mask_z(i,j,k) >= 1.0)
then
1553 s(i,j,k) = gsw_sr_from_sp(s(i,j,k))
1558 t(i,j,k) = gsw_ct_from_pt(s(i,j,k), t(i,j,k))
1560 enddo ;
enddo ;
enddo
1561 end subroutine convert_temp_salt_for_teos10
1564 logical function eos_quadrature(EOS)
1567 eos_quadrature = eos%EOS_quadrature
1569 end function eos_quadrature
1572 subroutine extract_member_eos(EOS, form_of_EOS, form_of_TFreeze, EOS_quadrature, Compressible, &
1573 Rho_T0_S0, drho_dT, dRho_dS, TFr_S0_P0, dTFr_dS, dTFr_dp)
1575 integer,
optional,
intent(out) :: form_of_eos
1576 integer,
optional,
intent(out) :: form_of_tfreeze
1578 logical,
optional,
intent(out) :: eos_quadrature
1580 logical,
optional,
intent(out) :: compressible
1581 real ,
optional,
intent(out) :: rho_t0_s0
1582 real ,
optional,
intent(out) :: drho_dt
1584 real ,
optional,
intent(out) :: drho_ds
1586 real ,
optional,
intent(out) :: tfr_s0_p0
1587 real ,
optional,
intent(out) :: dtfr_ds
1589 real ,
optional,
intent(out) :: dtfr_dp
1592 if (
present(form_of_eos )) form_of_eos = eos%form_of_EOS
1593 if (
present(form_of_tfreeze)) form_of_tfreeze = eos%form_of_TFreeze
1594 if (
present(eos_quadrature )) eos_quadrature = eos%EOS_quadrature
1595 if (
present(compressible )) compressible = eos%Compressible
1596 if (
present(rho_t0_s0 )) rho_t0_s0 = eos%Rho_T0_S0
1597 if (
present(drho_dt )) drho_dt = eos%drho_dT
1598 if (
present(drho_ds )) drho_ds = eos%dRho_dS
1599 if (
present(tfr_s0_p0 )) tfr_s0_p0 = eos%TFr_S0_P0
1600 if (
present(dtfr_ds )) dtfr_ds = eos%dTFr_dS
1601 if (
present(dtfr_dp )) dtfr_dp = eos%dTFr_dp
1603 end subroutine extract_member_eos