28 implicit none ;
private 30 #include <MOM_memory.h> 42 public gsw_sp_from_sr, gsw_pt_from_ct
56 integer :: form_of_eos = 0
57 integer :: form_of_tfreeze = 0
59 logical :: eos_quadrature
61 logical :: compressible = .true.
100 real,
intent(in) :: T
101 real,
intent(in) :: S
102 real,
intent(in) :: pressure
103 real,
intent(out) :: rho
106 if (.not.
associated(eos))
call mom_error(fatal, &
107 "calculate_density_scalar called with an unassociated EOS_type EOS.")
109 select case (eos%form_of_EOS)
111 call calculate_density_scalar_linear(t, s, pressure, rho, &
112 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS)
114 call calculate_density_scalar_unesco(t, s, pressure, rho)
116 call calculate_density_scalar_wright(t, s, pressure, rho)
118 call calculate_density_scalar_teos10(t, s, pressure, rho)
120 call calculate_density_scalar_nemo(t, s, pressure, rho)
123 "calculate_density_scalar: EOS is not valid.")
130 real,
dimension(:),
intent(in) :: T
131 real,
dimension(:),
intent(in) :: S
132 real,
dimension(:),
intent(in) :: pressure
133 real,
dimension(:),
intent(out) :: rho
134 integer,
intent(in) :: start
135 integer,
intent(in) :: npts
138 if (.not.
associated(eos))
call mom_error(fatal, &
139 "calculate_density_array called with an unassociated EOS_type EOS.")
141 select case (eos%form_of_EOS)
143 call calculate_density_array_linear(t, s, pressure, rho, start, npts, &
144 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS)
146 call calculate_density_array_unesco(t, s, pressure, rho, start, npts)
148 call calculate_density_array_wright(t, s, pressure, rho, start, npts)
150 call calculate_density_array_teos10(t, s, pressure, rho, start, npts)
152 call calculate_density_array_nemo (t, s, pressure, rho, start, npts)
155 "calculate_density_array: EOS%form_of_EOS is not valid.")
162 real,
intent(in) :: S
163 real,
intent(in) :: pressure
164 real,
intent(out) :: T_fr
167 if (.not.
associated(eos))
call mom_error(fatal, &
168 "calculate_TFreeze_scalar called with an unassociated EOS_type EOS.")
170 select case (eos%form_of_TFreeze)
173 eos%dTFr_dS, eos%dTFr_dp)
180 "calculate_TFreeze_scalar: form_of_TFreeze is not valid.")
187 real,
dimension(:),
intent(in) :: S
188 real,
dimension(:),
intent(in) :: pressure
189 real,
dimension(:),
intent(out) :: T_fr
190 integer,
intent(in) :: start
191 integer,
intent(in) :: npts
194 if (.not.
associated(eos))
call mom_error(fatal, &
195 "calculate_TFreeze_scalar called with an unassociated EOS_type EOS.")
197 select case (eos%form_of_TFreeze)
200 eos%TFr_S0_P0, eos%dTFr_dS, eos%dTFr_dp)
207 "calculate_TFreeze_scalar: form_of_TFreeze is not valid.")
214 real,
dimension(:),
intent(in) :: T
215 real,
dimension(:),
intent(in) :: S
216 real,
dimension(:),
intent(in) :: pressure
217 real,
dimension(:),
intent(out) :: drho_dT
218 real,
dimension(:),
intent(out) :: drho_dS
219 integer,
intent(in) :: start
220 integer,
intent(in) :: npts
223 if (.not.
associated(eos))
call mom_error(fatal, &
224 "calculate_density_derivs called with an unassociated EOS_type EOS.")
226 select case (eos%form_of_EOS)
228 call calculate_density_derivs_linear(t, s, pressure, drho_dt, drho_ds, start, &
229 npts, eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS)
231 call calculate_density_derivs_unesco(t, s, pressure, drho_dt, drho_ds, start, npts)
233 call calculate_density_derivs_wright(t, s, pressure, drho_dt, drho_ds, start, npts)
235 call calculate_density_derivs_teos10(t, s, pressure, drho_dt, drho_ds, start, npts)
237 call calculate_density_derivs_nemo(t, s, pressure, drho_dt, drho_ds, start, npts)
240 "calculate_density_derivs: EOS%form_of_EOS is not valid.")
247 real,
dimension(:),
intent(in) :: T
248 real,
dimension(:),
intent(in) :: S
249 real,
dimension(:),
intent(in) :: pressure
250 real,
dimension(:),
intent(out) :: dSV_dT
251 real,
dimension(:),
intent(out) :: dSV_dS
252 integer,
intent(in) :: start
253 integer,
intent(in) :: npts
256 real,
dimension(size(T)) :: dRho_dT, dRho_dS, rho
259 if (.not.
associated(eos))
call mom_error(fatal, &
260 "calculate_density_derivs called with an unassociated EOS_type EOS.")
262 select case (eos%form_of_EOS)
264 call calculate_specvol_derivs_linear(t, s, pressure, dsv_dt, dsv_ds, start, &
265 npts, eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS)
268 call calculate_density_derivs_unesco(t, s, pressure, drho_dt, drho_ds, start, npts)
269 do j=start,start+npts-1
270 dsv_dt(j) = -drho_dt(j)/(rho(j)**2)
271 dsv_ds(j) = -drho_ds(j)/(rho(j)**2)
274 call calculate_specvol_derivs_wright(t, s, pressure, dsv_dt, dsv_ds, start, npts)
276 call calculate_specvol_derivs_teos10(t, s, pressure, dsv_dt, dsv_ds, start, npts)
279 call calculate_density_derivs_nemo(t, s, pressure, drho_dt, drho_ds, start, npts)
280 do j=start,start+npts-1
281 dsv_dt(j) = -drho_dt(j)/(rho(j)**2)
282 dsv_ds(j) = -drho_ds(j)/(rho(j)**2)
286 "calculate_density_derivs: EOS%form_of_EOS is not valid.")
293 real,
dimension(:),
intent(in) :: T
294 real,
dimension(:),
intent(in) :: S
295 real,
dimension(:),
intent(in) :: pressure
296 real,
dimension(:),
intent(out) :: rho
297 real,
dimension(:),
intent(out) :: drho_dp
299 integer,
intent(in) :: start
300 integer,
intent(in) :: npts
303 if (.not.
associated(eos))
call mom_error(fatal, &
304 "calculate_compress called with an unassociated EOS_type EOS.")
306 select case (eos%form_of_EOS)
309 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS)
315 call calculate_compress_teos10(t, s, pressure, rho, drho_dp, start, npts)
320 "calculate_compress: EOS%form_of_EOS is not valid.")
332 dza, intp_dza, intx_dza, inty_dza, halo_size)
336 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed),
intent(in) :: T
338 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed),
intent(in) :: S
340 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed),
intent(in) :: p_t
342 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed),
intent(in) :: p_b
346 real,
intent(in) :: alpha_ref
350 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed),
intent(out) :: dza
353 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed),
optional,
intent(out) :: intp_dza
356 real,
dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed),
optional,
intent(out) :: intx_dza
359 real,
dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB),
optional,
intent(out) :: inty_dza
361 integer,
optional,
intent(in) :: halo_size
363 if (.not.
associated(eos))
call mom_error(fatal, &
364 "int_specific_vol_dp called with an unassociated EOS_type EOS.")
366 if (eos%EOS_quadrature)
then 368 dza, intp_dza, intx_dza, inty_dza, halo_size)
369 else ;
select case (eos%form_of_EOS)
372 eos%dRho_dT, eos%dRho_dS, dza, intp_dza, &
373 intx_dza, inty_dza, halo_size)
376 intp_dza, intx_dza, inty_dza, halo_size)
379 dza, intp_dza, intx_dza, inty_dza, halo_size)
390 subroutine int_density_dz(T, S, z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, EOS, &
391 dpa, intz_dpa, intx_dpa, inty_dpa)
397 real,
dimension(HII%isd:HII%ied,HII%jsd:HII%jed),
intent(in) :: T
399 real,
dimension(HII%isd:HII%ied,HII%jsd:HII%jed),
intent(in) :: S
401 real,
dimension(HII%isd:HII%ied,HII%jsd:HII%jed),
intent(in) :: z_t
403 real,
dimension(HII%isd:HII%ied,HII%jsd:HII%jed),
intent(in) :: z_b
406 real,
intent(in) :: rho_ref
409 real,
intent(in) :: rho_0
411 real,
intent(in) :: G_e
415 real,
dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed),
intent(out) :: dpa
418 real,
dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed),
optional,
intent(out) :: intz_dpa
421 real,
dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed),
optional,
intent(out) :: intx_dpa
424 real,
dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB),
optional,
intent(out) :: inty_dpa
426 if (.not.
associated(eos))
call mom_error(fatal, &
427 "int_density_dz called with an unassociated EOS_type EOS.")
429 if (eos%EOS_quadrature)
then 431 eos, dpa, intz_dpa, intx_dpa, inty_dpa)
432 else ;
select case (eos%form_of_EOS)
434 call int_density_dz_linear(t, s, z_t, z_b, rho_ref, rho_0, g_e, hii, hio, &
435 eos%Rho_T0_S0, eos%dRho_dT, eos%dRho_dS, &
436 dpa, intz_dpa, intx_dpa, inty_dpa)
438 call int_density_dz_wright(t, s, z_t, z_b, rho_ref, rho_0, g_e, hii, hio, &
439 dpa, intz_dpa, intx_dpa, inty_dpa)
442 eos, dpa, intz_dpa, intx_dpa, inty_dpa)
451 if (.not.
associated(eos))
call mom_error(fatal, &
452 "query_compressible called with an unassociated EOS_type EOS.")
458 subroutine eos_init(param_file, EOS)
462 #include "version_variable.h" 463 character(len=40) :: mdl =
"MOM_EOS" 464 character(len=40) :: tmpstr
471 call get_param(param_file, mdl,
"EQN_OF_STATE", tmpstr, &
472 "EQN_OF_STATE determines which ocean equation of state \n"//&
473 "should be used. Currently, the valid choices are \n"//&
474 '"LINEAR", "UNESCO", "WRIGHT", "NEMO" and "TEOS10". \n'//&
475 "This is only used if USE_EOS is true.", default=
eos_default)
488 call mom_error(fatal,
"interpret_eos_selection: EQN_OF_STATE "//&
489 trim(tmpstr) //
"in input file is invalid.")
491 call mom_mesg(
'interpret_eos_selection: equation of state set to "' // &
492 trim(tmpstr)//
'"', 5)
495 eos%Compressible = .false.
496 call get_param(param_file, mdl,
"RHO_T0_S0", eos%Rho_T0_S0, &
498 "this is the density at T=0, S=0.", units=
"kg m-3", &
500 call get_param(param_file, mdl,
"DRHO_DT", eos%dRho_dT, &
502 "this is the partial derivative of density with \n"//&
503 "temperature.", units=
"kg m-3 K-1", default=-0.2)
504 call get_param(param_file, mdl,
"DRHO_DS", eos%dRho_dS, &
506 "this is the partial derivative of density with \n"//&
507 "salinity.", units=
"kg m-3 PSU-1", default=0.8)
510 call get_param(param_file, mdl,
"EOS_QUADRATURE", eos%EOS_quadrature, &
511 "If true, always use the generic (quadrature) code \n"//&
512 "code for the integrals of density.", default=.false.)
514 call get_param(param_file, mdl,
"TFREEZE_FORM", tmpstr, &
515 "TFREEZE_FORM determines which expression should be \n"//&
516 "used for the freezing point. Currently, the valid \n"//&
517 'choices are "LINEAR", "MILLERO_78", "TEOS10"', &
527 call mom_error(fatal,
"interpret_eos_selection: TFREEZE_FORM "//&
528 trim(tmpstr) //
"in input file is invalid.")
532 call get_param(param_file, mdl,
"TFREEZE_S0_P0",eos%TFr_S0_P0, &
534 "this is the freezing potential temperature at \n"//&
535 "S=0, P=0.", units=
"deg C", default=0.0)
536 call get_param(param_file, mdl,
"DTFREEZE_DS",eos%dTFr_dS, &
538 "this is the derivative of the freezing potential \n"//&
539 "temperature with salinity.", &
540 units=
"deg C PSU-1", default=-0.054)
541 call get_param(param_file, mdl,
"DTFREEZE_DP",eos%dTFr_dP, &
543 "this is the derivative of the freezing potential \n"//&
544 "temperature with pressure.", &
545 units=
"deg C Pa-1", default=0.0)
549 call mom_error(fatal,
"interpret_eos_selection: EOS_TEOS10 or EOS_NEMO \n" //&
550 "should only be used along with TFREEZE_FORM = TFREEZE_TEOS10 .")
560 if (.not.
associated(eos))
allocate(eos)
567 if (
associated(eos))
deallocate(eos)
575 subroutine eos_use_linear(Rho_T0_S0, dRho_dT, dRho_dS, EOS, use_quadrature)
576 real,
intent(in) :: Rho_T0_S0
577 real,
intent(in) :: dRho_dT
578 real,
intent(in) :: dRho_dS
579 logical,
optional,
intent(in) :: use_quadrature
582 if (.not.
associated(eos))
call mom_error(fatal, &
583 "MOM_EOS.F90: EOS_use_linear() called with an unassociated EOS_type EOS.")
586 eos%Compressible = .false.
587 eos%Rho_T0_S0 = rho_t0_s0
588 eos%dRho_dT = drho_dt
589 eos%dRho_dS = drho_ds
590 eos%EOS_quadrature = .false.
591 if (
present(use_quadrature)) eos%EOS_quadrature = use_quadrature
596 EOS, dpa, intz_dpa, intx_dpa, inty_dpa)
598 real,
dimension(HII%isd:HII%ied,HII%jsd:HII%jed), &
599 intent(in) :: T, S, z_t, z_b
600 real,
intent(in) :: rho_ref, rho_0, G_e
602 real,
dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), &
604 real,
dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), &
605 optional,
intent(out) :: intz_dpa
606 real,
dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed), &
607 optional,
intent(out) :: intx_dpa
608 real,
dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), &
609 optional,
intent(out) :: inty_dpa
641 real :: T5(5), S5(5), p5(5), r5(5)
643 real :: w_left, w_right, intz(5)
644 real,
parameter :: C1_90 = 1.0/90.0
647 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, i, j, m, n, ioff, joff
649 ioff = hio%idg_offset - hii%idg_offset
650 joff = hio%jdg_offset - hii%jdg_offset
654 isq = hio%IscB + ioff ; ieq = hio%IecB + ioff
655 jsq = hio%JscB + joff ; jeq = hio%JecB + joff
656 is = hio%isc + ioff ; ie = hio%iec + ioff
657 js = hio%jsc + joff ; je = hio%jec + joff
662 do j=jsq,jeq+1 ;
do i=isq,ieq+1
663 dz = z_t(i,j) - z_b(i,j)
665 t5(n) = t(i,j) ; s5(n) = s(i,j)
666 p5(n) = -gxrho*(z_t(i,j) - 0.25*
real(n-1)*dz)
671 rho_anom = c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + 12.0*r5(3)) - &
673 dpa(i-ioff,j-joff) = g_e*dz*rho_anom
676 if (
present(intz_dpa)) intz_dpa(i-ioff,j-joff) = 0.5*g_e*dz**2 * &
677 (rho_anom - c1_90*(16.0*(r5(4)-r5(2)) + 7.0*(r5(5)-r5(1))) )
680 if (
present(intx_dpa))
then ;
do j=js,je ;
do i=isq,ieq
681 intz(1) = dpa(i-ioff,j-joff) ; intz(5) = dpa(i+1-ioff,j-joff)
683 w_left = 0.25*
real(5-m) ; w_right = 1.0-w_left
684 dz = w_left*(z_t(i,j) - z_b(i,j)) + w_right*(z_t(i+1,j) - z_b(i+1,j))
685 t5(1) = w_left*t(i,j) + w_right*t(i+1,j)
686 s5(1) = w_left*s(i,j) + w_right*s(i+1,j)
687 p5(1) = -gxrho*(w_left*z_t(i,j) + w_right*z_t(i+1,j))
689 t5(n) = t5(1) ; s5(n) = s5(1)
690 p5(n) = p5(n-1) + gxrho*0.25*dz
695 intz(m) = g_e*dz*( c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + &
696 12.0*r5(3)) - rho_ref)
699 intx_dpa(i-ioff,j-joff) = c1_90*(7.0*(intz(1)+intz(5)) + 32.0*(intz(2)+intz(4)) + &
701 enddo ;
enddo ;
endif 703 if (
present(inty_dpa))
then ;
do j=jsq,jeq ;
do i=is,ie
704 intz(1) = dpa(i-ioff,j-joff) ; intz(5) = dpa(i-ioff,j-joff+1)
706 w_left = 0.25*
real(5-m) ; w_right = 1.0-w_left
707 dz = w_left*(z_t(i,j) - z_b(i,j)) + w_right*(z_t(i,j+1) - z_b(i,j+1))
708 t5(1) = w_left*t(i,j) + w_right*t(i,j+1)
709 s5(1) = w_left*s(i,j) + w_right*s(i,j+1)
710 p5(1) = -gxrho*(w_left*z_t(i,j) + w_right*z_t(i,j+1))
712 t5(n) = t5(1) ; s5(n) = s5(1)
713 p5(n) = p5(n-1) + gxrho*0.25*dz
718 intz(m) = g_e*dz*( c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + &
719 12.0*r5(3)) - rho_ref)
722 inty_dpa(i-ioff,j-joff) = c1_90*(7.0*(intz(1)+intz(5)) + 32.0*(intz(2)+intz(4)) + &
724 enddo ;
enddo ;
endif 730 z_t_arg, z_b_arg, depth, rho_ref, &
731 rho_0, G_e, EOS, dpa, &
732 intz_dpa, intx_dpa, inty_dpa)
735 real,
dimension(2),
intent(in) :: T_t_arg, T_b_arg, S_t_arg, S_b_arg
736 real,
dimension(2),
intent(inout) :: z_t_arg, z_b_arg
737 real,
dimension(2),
intent(in) :: depth
738 real,
intent(in) :: rho_ref, rho_0, G_e
740 real,
dimension(2),
intent(out) :: dpa
741 real,
dimension(2),
intent(out) :: intz_dpa
742 real,
intent(out) :: intx_dpa
743 real,
intent(out) :: inty_dpa
746 real :: T_t(2), T_b(2)
747 real :: S_t(2), S_b(2)
748 real :: z_t(2), z_b(2)
750 real :: T5(5), S5(5), p5(5), r5(5)
753 real :: w_left, w_right, intz(5)
756 real :: weight_t, weight_b
759 real,
parameter :: C1_90 = 1.0/90.0
766 dmin = min( depth(1), depth(2) )
768 z_b(1) = max( z_b_arg(1), -dmin )
769 z_b(2) = max( z_b_arg(2), -dmin )
771 if ( z_b(1) .GT. z_t_arg(1) ) z_b(1) = z_t_arg(1)
772 if ( z_b(2) .GT. z_t_arg(2) ) z_b(2) = z_t_arg(2)
781 s_b(1) = s_t_arg(1) + (s_b_arg(1)-s_t_arg(1)) * (h1 / (z_t_arg(1)-z_b_arg(1)))
782 s_b(2) = s_t_arg(2) + (s_b_arg(2)-s_t_arg(2)) * (h2 / (z_t_arg(2)-z_b_arg(2)))
784 t_b(1) = t_t_arg(1) + (t_b_arg(1)-t_t_arg(1)) * (h1 / (z_t_arg(1)-z_b_arg(1)))
785 t_b(2) = t_t_arg(2) + (t_b_arg(2)-t_t_arg(2)) * (h2 / (z_t_arg(2)-z_b_arg(2)))
799 weight_t = 0.25 *
real(5-n)
800 weight_b = 1.0 - weight_t
801 s5(n) = weight_t * s_t(1) + weight_b * s_b(1)
802 t5(n) = weight_t * t_t(1) + weight_b * t_b(1)
803 p5(n) = -gxrho*(z_t(1) - 0.25*
real(n-1)*dz)
809 rho_anom = c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + 12.0*r5(3)) - rho_ref
810 dpa(1) = g_e*dz*rho_anom
815 intz_dpa(1) = 0.5*g_e*dz**2 * &
816 (rho_anom - c1_90*(16.0*(r5(4)-r5(2)) + 7.0*(r5(5)-r5(1))) )
824 weight_t = 0.25 *
real(5-n)
825 weight_b = 1.0 - weight_t
826 s5(n) = weight_t * s_t(2) + weight_b * s_b(2)
827 t5(n) = weight_t * t_t(2) + weight_b * t_b(2)
828 p5(n) = -gxrho*(z_t(2) - 0.25*
real(n-1)*dz)
834 rho_anom = c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + 12.0*r5(3)) - rho_ref
835 dpa(2) = g_e*dz*rho_anom
840 intz_dpa(2) = 0.5*g_e*dz**2 * &
841 (rho_anom - c1_90*(16.0*(r5(4)-r5(2)) + 7.0*(r5(5)-r5(1))) )
852 w_left = 0.25*
real(5-m)
855 dz = w_left*(z_t(1) - z_b(1)) + w_right*(z_t(2) - z_b(2))
857 t5(1) = w_left*t_t(1) + w_right*t_t(2)
858 t5(5) = w_left*t_b(1) + w_right*t_b(2)
860 s5(1) = w_left*s_t(1) + w_right*s_t(2)
861 s5(5) = w_left*s_b(1) + w_right*s_b(2)
863 p5(1) = -gxrho*(w_left*z_t(1) + w_right*z_t(2))
865 p5(n) = p5(n-1) + gxrho*0.25*dz
869 weight_t = 0.25 *
real(5-n)
870 weight_b = 1.0 - weight_t
871 s5(n) = weight_t * s5(1) + weight_b * s5(5)
877 intz(m) = g_e*dz*( c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + &
878 12.0*r5(3)) - rho_ref)
882 intx_dpa = c1_90*(7.0*(intz(1)+intz(5)) + 32.0*(intz(2)+intz(4)) + &
895 w_left = 0.25*
real(5-m)
898 dz = w_left*(z_t(1) - z_b(2)) + w_right*(z_t(1) - z_b(2))
900 s5(1) = w_left*s_t(1) + w_right*s_t(2)
901 s5(5) = w_left*s_b(1) + w_right*s_b(2)
902 s5(1) = w_left*s_t(1) + w_right*s_t(2)
903 s5(5) = w_left*s_b(1) + w_right*s_b(2)
904 p5(1) = -gxrho*(w_left*z_t(1) + w_right*z_t(2))
906 p5(n) = p5(n-1) + gxrho*0.25*dz
909 weight_t = 0.25 *
real(5-n)
910 weight_b = 1.0 - weight_t
911 s5(n) = weight_t * s5(1) + weight_b * s5(5)
916 intz(m) = g_e*dz*( c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + &
917 12.0*r5(3)) - rho_ref)
921 inty_dpa = c1_90*(7.0*(intz(1)+intz(5)) + 32.0*(intz(2)+intz(4)) + &
935 rho_0, G_e, H_subroundoff, bathyT, HII, HIO, EOS, dpa, &
936 intz_dpa, intx_dpa, inty_dpa, &
939 real,
dimension(HII%isd:HII%ied,HII%jsd:HII%jed), &
940 intent(in) :: T_t, T_b, S_t, S_b, z_t, z_b
941 real,
intent(in) :: rho_ref, rho_0, G_e, H_subroundoff
942 real,
dimension(HII%isd:HII%ied,HII%jsd:HII%jed),
intent(in) :: bathyT
944 real,
dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), &
946 real,
dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), &
947 optional,
intent(out) :: intz_dpa
948 real,
dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed), &
949 optional,
intent(out) :: intx_dpa
950 real,
dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), &
951 optional,
intent(out) :: inty_dpa
952 logical,
optional,
intent(in) :: useMassWghtInterp
994 real :: T5((5*hio%iscb+1):(5*(hio%iecb+2)))
995 real :: S5((5*hio%iscb+1):(5*(hio%iecb+2)))
996 real :: p5((5*hio%iscb+1):(5*(hio%iecb+2)))
997 real :: r5((5*hio%iscb+1):(5*(hio%iecb+2)))
998 real :: u5((5*hio%iscb+1):(5*(hio%iecb+2)))
999 real :: T15((15*hio%iscb+1):(15*(hio%iecb+1)))
1000 real :: S15((15*hio%iscb+1):(15*(hio%iecb+1)))
1001 real :: p15((15*hio%iscb+1):(15*(hio%iecb+1)))
1002 real :: r15((15*hio%iscb+1):(15*(hio%iecb+1)))
1003 real :: wt_t(5), wt_b(5)
1005 real :: w_left, w_right, intz(5)
1006 real,
parameter :: C1_90 = 1.0/90.0
1007 real :: GxRho, I_Rho
1008 real :: dz(hio%iscb:hio%iecb+1), dz_x(5,hio%iscb:hio%iecb), dz_y(5,hio%isc:hio%iec)
1009 real :: weight_t, weight_b, hWght, massWeightingToggle
1010 real :: Ttl, Tbl, Ttr, Tbr, Stl, Sbl, Str, Sbr, hL, hR, iDenom
1011 integer :: Isq, Ieq, Jsq, Jeq, i, j, m, n
1012 integer :: iin, jin, ioff, joff
1015 ioff = hio%idg_offset - hii%idg_offset
1016 joff = hio%jdg_offset - hii%jdg_offset
1018 isq = hio%IscB ; ieq = hio%IecB ; jsq = hio%JscB ; jeq = hio%JecB
1022 massweightingtoggle = 0.
1023 if (
present(usemasswghtinterp))
then 1024 if (usemasswghtinterp) massweightingtoggle = 1.
1028 wt_t(n) = 0.25 *
real(5-n)
1029 wt_b(n) = 1.0 - wt_t(n)
1037 do i = isq,ieq+1 ; iin = i+ioff
1038 dz(i) = z_t(iin,jin) - z_b(iin,jin)
1040 p5(i*5+n) = -gxrho*(z_t(iin,jin) - 0.25*
real(n-1)*dz(i))
1042 s5(i*5+n) = wt_t(n) * s_t(iin,jin) + wt_b(n) * s_b(iin,jin)
1043 t5(i*5+n) = wt_t(n) * t_t(iin,jin) + wt_b(n) * t_b(iin,jin)
1049 do i=isq,ieq+1 ; iin = i+ioff
1051 rho_anom = c1_90*(7.0*(r5(i*5+1)+r5(i*5+5)) + 32.0*(r5(i*5+2)+r5(i*5+4)) + 12.0*r5(i*5+3)) - &
1053 dpa(i,j) = g_e*dz(i)*rho_anom
1054 if (
present(intz_dpa))
then 1057 intz_dpa(i,j) = 0.5*g_e*dz(i)**2 * &
1058 (rho_anom - c1_90*(16.0*(u5(i*5+4)-u5(i*5+2)) + 7.0*(u5(i*5+5)-u5(i*5+1))) )
1067 if (
present(intx_dpa))
then ;
do j=hio%jsc,hio%jec ; jin = j+joff
1068 do i=isq,ieq ; iin = i+ioff
1077 hwght = massweightingtoggle * &
1078 max(0., -bathyt(iin,jin)-z_t(iin+1,jin), -bathyt(iin+1,jin)-z_t(iin,jin))
1079 if (hwght > 0.)
then 1080 hl = (z_t(iin,jin) - z_b(iin,jin)) + h_subroundoff
1081 hr = (z_t(iin+1,jin) - z_b(iin+1,jin)) + h_subroundoff
1082 hwght = hwght * ( (hl-hr)/(hl+hr) )**2
1083 idenom = 1./( hwght*(hr + hl) + hl*hr )
1084 ttl = ( (hwght*hr)*t_t(iin+1,jin) + (hwght*hl + hr*hl)*t_t(iin,jin) ) * idenom
1085 ttr = ( (hwght*hl)*t_t(iin,jin) + (hwght*hr + hr*hl)*t_t(iin+1,jin) ) * idenom
1086 tbl = ( (hwght*hr)*t_b(iin+1,jin) + (hwght*hl + hr*hl)*t_b(iin,jin) ) * idenom
1087 tbr = ( (hwght*hl)*t_b(iin,jin) + (hwght*hr + hr*hl)*t_b(iin+1,jin) ) * idenom
1088 stl = ( (hwght*hr)*s_t(iin+1,jin) + (hwght*hl + hr*hl)*s_t(iin,jin) ) * idenom
1089 str = ( (hwght*hl)*s_t(iin,jin) + (hwght*hr + hr*hl)*s_t(iin+1,jin) ) * idenom
1090 sbl = ( (hwght*hr)*s_b(iin+1,jin) + (hwght*hl + hr*hl)*s_b(iin,jin) ) * idenom
1091 sbr = ( (hwght*hl)*s_b(iin,jin) + (hwght*hr + hr*hl)*s_b(iin+1,jin) ) * idenom
1093 ttl = t_t(iin,jin); tbl = t_b(iin,jin); ttr = t_t(iin+1,jin); tbr = t_b(iin+1,jin)
1094 stl = s_t(iin,jin); sbl = s_b(iin,jin); str = s_t(iin+1,jin); sbr = s_b(iin+1,jin)
1098 w_left = 0.25*
real(5-m) ; w_right = 1.0-w_left
1099 dz_x(m,i) = w_left*(z_t(iin,jin) - z_b(iin,jin)) + w_right*(z_t(iin+1,jin) - z_b(iin+1,jin))
1106 t15(pos+1) = w_left*ttl + w_right*ttr
1107 t15(pos+5) = w_left*tbl + w_right*tbr
1109 s15(pos+1) = w_left*stl + w_right*str
1110 s15(pos+5) = w_left*sbl + w_right*sbr
1112 p15(pos+1) = -gxrho*(w_left*z_t(iin,jin) + w_right*z_t(iin+1,jin))
1116 p15(pos+n) = p15(pos+n-1) + gxrho*0.25*dz_x(m,i)
1121 weight_t = 0.25 *
real(5-n)
1122 weight_b = 1.0 - weight_t
1123 s15(pos+n) = weight_t * s15(pos+1) + weight_b * s15(pos+5)
1124 t15(pos+n) = weight_t * t15(pos+1) + weight_b * t15(pos+5)
1131 do i=isq,ieq ; iin = i+ioff
1132 intz(1) = dpa(i,j) ; intz(5) = dpa(i+1,j)
1137 intz(m) = g_e*dz_x(m,i)*( c1_90*(7.0*(r15(pos+1)+r15(pos+5)) + 32.0*(r15(pos+2)+r15(pos+4)) + &
1138 12.0*r15(pos+3)) - rho_ref)
1141 intx_dpa(i,j) = c1_90*(7.0*(intz(1)+intz(5)) + 32.0*(intz(2)+intz(4)) + &
1149 if (
present(inty_dpa))
then ;
do j=jsq,jeq ; jin = j+joff
1150 do i=hio%isc,hio%iec ; iin = i+ioff
1158 hwght = massweightingtoggle * &
1159 max(0., -bathyt(i,j)-z_t(iin,jin+1), -bathyt(i,j+1)-z_t(iin,jin))
1160 if (hwght > 0.)
then 1161 hl = (z_t(iin,jin) - z_b(iin,jin)) + h_subroundoff
1162 hr = (z_t(iin,jin+1) - z_b(iin,jin+1)) + h_subroundoff
1163 hwght = hwght * ( (hl-hr)/(hl+hr) )**2
1164 idenom = 1./( hwght*(hr + hl) + hl*hr )
1165 ttl = ( (hwght*hr)*t_t(iin,jin+1) + (hwght*hl + hr*hl)*t_t(iin,jin) ) * idenom
1166 ttr = ( (hwght*hl)*t_t(iin,jin) + (hwght*hr + hr*hl)*t_t(iin,jin+1) ) * idenom
1167 tbl = ( (hwght*hr)*t_b(iin,jin+1) + (hwght*hl + hr*hl)*t_b(iin,jin) ) * idenom
1168 tbr = ( (hwght*hl)*t_b(iin,jin) + (hwght*hr + hr*hl)*t_b(iin,jin+1) ) * idenom
1169 stl = ( (hwght*hr)*s_t(iin,jin+1) + (hwght*hl + hr*hl)*s_t(iin,jin) ) * idenom
1170 str = ( (hwght*hl)*s_t(iin,jin) + (hwght*hr + hr*hl)*s_t(iin,jin+1) ) * idenom
1171 sbl = ( (hwght*hr)*s_b(iin,jin+1) + (hwght*hl + hr*hl)*s_b(iin,jin) ) * idenom
1172 sbr = ( (hwght*hl)*s_b(iin,jin) + (hwght*hr + hr*hl)*s_b(iin,jin+1) ) * idenom
1174 ttl = t_t(iin,jin); tbl = t_b(iin,jin); ttr = t_t(iin,jin+1); tbr = t_b(iin,jin+1)
1175 stl = s_t(iin,jin); sbl = s_b(iin,jin); str = s_t(iin,jin+1); sbr = s_b(iin,jin+1)
1179 w_left = 0.25*
real(5-m) ; w_right = 1.0-w_left
1180 dz_y(m,i) = w_left*(z_t(iin,jin) - z_b(iin,jin)) + w_right*(z_t(iin,jin+1) - z_b(iin,jin+1))
1187 t15(pos+1) = w_left*ttl + w_right*ttr
1188 t15(pos+5) = w_left*tbl + w_right*tbr
1190 s15(pos+1) = w_left*stl + w_right*str
1191 s15(pos+5) = w_left*sbl + w_right*sbr
1193 p15(pos+1) = -gxrho*(w_left*z_t(iin,jin) + w_right*z_t(iin,jin+1))
1196 do n=2,5 ; p15(pos+n) = p15(pos+n-1) + gxrho*0.25*dz_y(m,i) ;
enddo 1200 weight_t = 0.25 *
real(5-n)
1201 weight_b = 1.0 - weight_t
1202 s15(pos+n) = weight_t * s15(pos+1) + weight_b * s15(pos+5)
1203 t15(pos+n) = weight_t * t15(pos+1) + weight_b * t15(pos+5)
1209 r15(15*hio%isc+1:), 1, 15*(hio%iec-hio%isc+1), eos)
1210 do i=hio%isc,hio%iec ; iin = i+ioff
1211 intz(1) = dpa(i,j) ; intz(5) = dpa(i,j+1)
1216 intz(m) = g_e*dz_y(m,i)*( c1_90*(7.0*(r15(pos+1)+r15(pos+5)) + &
1217 32.0*(r15(pos+2)+r15(pos+4)) + &
1218 12.0*r15(pos+3)) - rho_ref)
1221 inty_dpa(i,j) = c1_90*(7.0*(intz(1)+intz(5)) + 32.0*(intz(2)+intz(4)) + &
1234 rho_ref, G_e, EOS, P_b, z_out)
1235 real,
intent(in) :: T_t
1236 real,
intent(in) :: T_b
1237 real,
intent(in) :: S_t
1238 real,
intent(in) :: S_b
1239 real,
intent(in) :: z_t
1240 real,
intent(in) :: z_b
1241 real,
intent(in) :: P_t
1242 real,
intent(in) :: P_tgt
1243 real,
intent(in) :: rho_ref
1244 real,
intent(in) :: G_e
1246 real,
intent(out) :: P_b
1247 real,
intent(out) :: z_out
1249 real :: top_weight, bottom_weight, rho_anom, w_left, w_right, GxRho, dz, dp, F_guess, F_l, F_r
1250 real :: Pa, Pa_left, Pa_right, Pa_tol
1252 gxrho = g_e * rho_ref
1255 dp =
frac_dp_at_pos(t_t, t_b, s_t, s_b, z_t, z_b, rho_ref, g_e, 1.0, eos)
1259 if (p_tgt < p_t )
then 1264 if (p_tgt > p_b)
then 1270 pa_left = p_t - p_tgt
1272 pa_right = p_b - p_tgt
1273 pa_tol = gxrho * 1.e-5
1274 f_guess = f_l - pa_left / ( pa_right -pa_left ) * ( f_r - f_l )
1275 pa = pa_right - pa_left
1276 do while ( abs(pa) > pa_tol )
1278 z_out = z_t + ( z_b - z_t ) * f_guess
1279 pa =
frac_dp_at_pos(t_t, t_b, s_t, s_b, z_t, z_b, rho_ref, g_e, f_guess, eos) - ( p_tgt - p_t )
1281 if (pa<pa_left)
then 1282 write(0,*) pa_left,pa,pa_right,p_t-p_tgt,p_b-p_tgt
1283 stop
'Blurgh! Too negative' 1287 elseif (pa>pa_right)
then 1288 write(0,*) pa_left,pa,pa_right,p_t-p_tgt,p_b-p_tgt
1289 stop
'Blurgh! Too positive' 1296 f_guess = f_l - pa_left / ( pa_right -pa_left ) * ( f_r - f_l )
1303 real function frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, pos, EOS)
1304 real,
intent(in) :: T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, pos
1307 real,
parameter :: C1_90 = 1.0/90.0
1308 real :: dz, top_weight, bottom_weight, rho_ave
1309 real,
dimension(5) :: T5, S5, p5, rho5
1314 bottom_weight = 0.25*
real(n-1) * pos
1315 top_weight = 1.0 - bottom_weight
1317 s5(n) = top_weight * s_t + bottom_weight * s_b
1318 t5(n) = top_weight * t_t + bottom_weight * t_b
1319 p5(n) = ( top_weight * z_t + bottom_weight * z_b ) * ( g_e * rho_ref )
1325 rho_ave = c1_90*(7.0*(rho5(1)+rho5(5)) + 32.0*(rho5(2)+rho5(4)) + 12.0*rho5(3))
1327 dz = ( z_t - z_b ) * pos
1337 z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, &
1338 EOS, dpa, intz_dpa, intx_dpa, inty_dpa)
1341 real,
dimension(HII%isd:HII%ied,HII%jsd:HII%jed), &
1342 intent(in) :: T, T_t, T_b, S, S_t, S_b, z_t, z_b
1343 real,
intent(in) :: rho_ref, rho_0, G_e
1345 real,
dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), &
1347 real,
dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), &
1348 optional,
intent(out) :: intz_dpa
1349 real,
dimension(HIO%IsdB:HIO%IedB,HIO%JsdB:HIO%JedB), &
1350 optional,
intent(out) :: intx_dpa
1351 real,
dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), &
1352 optional,
intent(out) :: inty_dpa
1392 real :: T5(5), S5(5), p5(5), r5(5)
1394 real :: w_left, w_right, intz(5)
1395 real,
parameter :: C1_90 = 1.0/90.0
1396 real :: GxRho, I_Rho
1398 real :: weight_t, weight_b
1402 real :: T_top, T_mid, T_bot
1403 real :: S_top, S_mid, S_bot
1404 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, i, j, m, n, ioff, joff
1405 real,
dimension(4) :: x, y
1406 real,
dimension(9) :: S_node, T_node, p_node, r_node
1410 "int_density_dz_generic_ppm: the implementation is not done yet, contact developer")
1412 ioff = hio%idg_offset - hii%idg_offset
1413 joff = hio%jdg_offset - hii%jdg_offset
1417 isq = hio%IscB + ioff ; ieq = hio%IecB + ioff
1418 jsq = hio%JscB + joff ; jeq = hio%JecB + joff
1419 is = hio%isc + ioff ; ie = hio%iec + ioff
1420 js = hio%jsc + joff ; je = hio%jec + joff
1428 do j=jsq,jeq+1 ;
do i=isq,ieq+1
1429 dz = z_t(i,j) - z_b(i,j)
1433 s1 = 6.0 * s(i,j) - 4.0 * s_t(i,j) - 2.0 * s_b(i,j)
1434 s2 = 3.0 * ( s_t(i,j) + s_b(i,j) - 2.0*s(i,j) )
1438 t1 = 6.0 * t(i,j) - 4.0 * t_t(i,j) - 2.0 * t_b(i,j)
1439 t2 = 3.0 * ( t_t(i,j) + t_b(i,j) - 2.0*t(i,j) )
1442 p5(n) = -gxrho*(z_t(i,j) - 0.25*
real(n-1)*dz)
1445 xi = 0.25 * ( n - 1 )
1446 s5(n) = s0 + s1 * xi + s2 * xi**2
1447 t5(n) = t0 + t1 * xi + t2 * xi**2
1456 rho_anom = 1000.0 + s(i,j) - rho_ref;
1457 dpa(i-ioff,j-joff) = g_e*dz*rho_anom
1465 intz_dpa(i-ioff,j-joff) = 0.5 * g_e * dz**2 * ( 1000.0 - rho_ref + s0 + s1/3.0 + &
1472 if (
present(intx_dpa))
then ;
do j=js,je ;
do i=isq,ieq
1473 intz(1) = dpa(i-ioff,j-joff) ; intz(5) = dpa(i+1-ioff,j-joff)
1475 w_left = 0.25*
real(5-m) ; w_right = 1.0-w_left
1476 dz = w_left*(z_t(i,j) - z_b(i,j)) + w_right*(z_t(i+1,j) - z_b(i+1,j))
1482 t_top = w_left*t_t(i,j) + w_right*t_t(i+1,j)
1483 t_mid = w_left*t(i,j) + w_right*t(i+1,j)
1484 t_bot = w_left*t_b(i,j) + w_right*t_b(i+1,j)
1486 s_top = w_left*s_t(i,j) + w_right*s_t(i+1,j)
1487 s_mid = w_left*s(i,j) + w_right*s(i+1,j)
1488 s_bot = w_left*s_b(i,j) + w_right*s_b(i+1,j)
1490 p5(1) = -gxrho*(w_left*z_t(i,j) + w_right*z_t(i+1,j))
1494 p5(n) = p5(n-1) + gxrho*0.25*dz
1499 s1 = 6.0 * s_mid - 4.0 * s_top - 2.0 * s_bot
1500 s2 = 3.0 * ( s_top + s_bot - 2.0*s_mid )
1504 t1 = 6.0 * t_mid - 4.0 * t_top - 2.0 * t_bot
1505 t2 = 3.0 * ( t_top + t_bot - 2.0*t_mid )
1509 xi = 0.25 * ( n - 1 )
1510 s5(n) = s0 + s1 * xi + s2 * xi**2
1511 t5(n) = t0 + t1 * xi + t2 * xi**2
1517 intz(m) = g_e*dz*( c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + &
1518 12.0*r5(3)) - rho_ref)
1520 intx_dpa(i-ioff,j-joff) = c1_90*(7.0*(intz(1)+intz(5)) + 32.0*(intz(2)+intz(4)) + &
1543 s1 = 6.0 * s(i,j) - 4.0 * s_t(i,j) - 2.0 * s_b(i,j)
1544 s2 = 3.0 * ( s_t(i,j) + s_b(i,j) - 2.0 * s(i,j) )
1546 s_node(6) = s0 + 0.5 * s1 + 0.25 * s2
1547 s_node(3) = s0 + s1 + s2
1551 s1 = 6.0 * s(i+1,j) - 4.0 * s_t(i+1,j) - 2.0 * s_b(i+1,j)
1552 s2 = 3.0 * ( s_t(i+1,j) + s_b(i+1,j) - 2.0 * s(i+1,j) )
1554 s_node(8) = s0 + 0.5 * s1 + 0.25 * s2
1555 s_node(4) = s0 + s1 + s2
1557 s_node(5) = 0.5 * ( s_node(2) + s_node(1) )
1558 s_node(9) = 0.5 * ( s_node(6) + s_node(8) )
1559 s_node(7) = 0.5 * ( s_node(3) + s_node(4) )
1562 r_node = r_node - rho_ref
1566 intx_dpa(i-ioff,j-joff) = intx_dpa(i-ioff,j-joff) * g_e
1568 enddo ;
enddo ;
endif 1573 if (
present(inty_dpa))
then 1574 call mom_error(warning,
"int_density_dz_generic_ppm still needs to be written for inty_dpa!")
1575 do j=jsq,jeq ;
do i=is,ie
1577 inty_dpa(i-ioff,j-joff) = 0.0
1590 z_b, rho_ref, rho_0, G_e, HI, EOS, dpa, intz_dpa, intx_dpa, inty_dpa)
1593 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1594 intent(in) :: T_t, T_b, S_t, S_b, z_t, z_b
1595 real,
intent(in) :: rho_ref, rho_0, G_e
1597 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1599 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1600 optional,
intent(out) :: intz_dpa
1601 real,
dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), &
1602 optional,
intent(out) :: intx_dpa
1603 real,
dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), &
1604 optional,
intent(out) :: inty_dpa
1644 real :: T5(5), S5(5), p5(5), r5(5)
1646 real :: w_left, w_right, intz(5)
1647 real,
parameter :: C1_90 = 1.0/90.0
1648 real :: GxRho, I_Rho
1650 real :: weight_t, weight_b
1651 integer :: Isq, Ieq, Jsq, Jeq, i, j, m, n
1653 real,
dimension(4) :: x, y, f
1655 isq = hi%IscB ; ieq = hi%IecB ; jsq = hi%JscB ; jeq = hi%JecB
1663 do j=jsq,jeq+1 ;
do i=isq,ieq+1
1664 dz = z_t(i,j) - z_b(i,j)
1665 ds = s_t(i,j) - s_b(i,j)
1667 weight_t = 0.25 *
real(5-n)
1668 weight_b = 1.0 - weight_t
1670 p5(n) = -gxrho*(z_t(i,j) - 0.25*
real(n-1)*dz)
1673 s5(n) = weight_t * s_t(i,j) + weight_b * s_b(i,j)
1674 t5(n) = weight_t * t_t(i,j) + weight_b * t_b(i,j)
1680 rho_anom = c1_90*(7.0*(r5(1)+r5(5)) + 32.0*(r5(2)+r5(4)) + 12.0*r5(3)) - &
1682 dpa(i,j) = g_e*dz*rho_anom
1685 rho_anom = 1000.0 + s_b(i,j) + 0.5 * ds - rho_ref
1686 dpa(i,j) = g_e * dz * rho_anom
1691 if (
present(intz_dpa)) intz_dpa(i,j) = 0.5*g_e*dz**2 * &
1692 (rho_anom - c1_90*(16.0*(r5(4)-r5(2)) + 7.0*(r5(5)-r5(1))) )
1694 intz_dpa(i,j) = ( 0.5 * (s_b(i,j)+1000.0-rho_ref) + &
1695 (1.0/3.0) * ds ) * g_e * dz**2
1702 if (
present(intx_dpa))
then ;
do j=hi%jsc,hi%jec ;
do i=isq,ieq
1713 f(1) = 1000.0 + s_t(i+1,j) - rho_ref
1714 f(2) = 1000.0 + s_t(i,j) - rho_ref
1715 f(3) = 1000.0 + s_b(i,j) - rho_ref
1716 f(4) = 1000.0 + s_b(i+1,j) - rho_ref
1720 intx_dpa(i,j) = intx_dpa(i,j) * g_e
1722 enddo ;
enddo ;
endif 1727 if (
present(inty_dpa))
then ;
do j=jsq,jeq ;
do i=hi%isc,hi%iec
1738 f(1) = 1000.0 + s_t(i,j+1) - rho_ref
1739 f(2) = 1000.0 + s_t(i,j) - rho_ref
1740 f(3) = 1000.0 + s_b(i,j) - rho_ref
1741 f(4) = 1000.0 + s_b(i,j+1) - rho_ref
1745 inty_dpa(i,j) = inty_dpa(i,j) * g_e
1747 enddo ;
enddo ;
endif 1758 real,
intent(in),
dimension(4) :: x, y, f
1759 real,
intent(out) :: integral
1763 real,
dimension(4) :: weight, xi, eta
1765 real :: dxdxi, dxdeta
1766 real :: dydxi, dydeta
1767 real,
dimension(4) :: phi, dphidxi, dphideta
1772 xi(1) = - sqrt(3.0) / 3.0
1773 xi(2) = sqrt(3.0) / 3.0
1774 xi(3) = sqrt(3.0) / 3.0
1775 xi(4) = - sqrt(3.0) / 3.0
1776 eta(1) = - sqrt(3.0) / 3.0
1777 eta(2) = - sqrt(3.0) / 3.0
1778 eta(3) = sqrt(3.0) / 3.0
1779 eta(4) = sqrt(3.0) / 3.0
1796 dxdxi = dxdxi + x(i) * dphidxi(i)
1797 dxdeta = dxdeta + x(i) * dphideta(i)
1798 dydxi = dydxi + y(i) * dphidxi(i)
1799 dydeta = dydeta + y(i) * dphideta(i)
1803 jacobian_k = dxdxi*dydeta - dydxi*dxdeta
1808 f_k = f_k + f(i) * phi(i)
1811 integral = integral + weight(k) * f_k * jacobian_k
1824 real,
intent(in),
dimension(4) :: x, y
1825 real,
intent(in),
dimension(9) :: f
1826 real,
intent(out) :: integral
1830 real,
dimension(9) :: weight, xi, eta
1832 real :: dxdxi, dxdeta
1833 real :: dydxi, dydeta
1834 real,
dimension(4) :: phiiso, dphiisodxi, dphiisodeta
1835 real,
dimension(9) :: phi, dphidxi, dphideta
1852 weight(1) = 25.0/81.0 ; xi(1) = -t ; eta(1) = t
1853 weight(2) = 40.0/81.0 ; xi(2) = .0 ; eta(2) = t
1854 weight(3) = 25.0/81.0 ; xi(3) = t ; eta(3) = t
1855 weight(4) = 40.0/81.0 ; xi(4) = -t ; eta(4) = .0
1856 weight(5) = 64.0/81.0 ; xi(5) = .0 ; eta(5) = .0
1857 weight(6) = 40.0/81.0 ; xi(6) = t ; eta(6) = .0
1858 weight(7) = 25.0/81.0 ; xi(7) = -t ; eta(7) = -t
1859 weight(8) = 40.0/81.0 ; xi(8) = .0 ; eta(8) = -t
1860 weight(9) = 25.0/81.0 ; xi(9) = t ; eta(9) = -t
1869 dphiisodxi, dphiisodeta )
1878 dxdxi = dxdxi + x(i) * dphiisodxi(i)
1879 dxdeta = dxdeta + x(i) * dphiisodeta(i)
1880 dydxi = dydxi + y(i) * dphiisodxi(i)
1881 dydeta = dydeta + y(i) * dphiisodeta(i)
1885 jacobian_k = dxdxi*dydeta - dydxi*dxdeta
1893 f_k = f_k + f(i) * phi(i)
1896 integral = integral + weight(k) * f_k * jacobian_k
1909 real,
intent(in) :: xi, eta
1910 real,
dimension(4),
intent(out) :: phi, dphidxi, dphideta
1923 phi(1) = 0.25 * ( 1 + xi ) * ( 1 + eta )
1924 phi(2) = 0.25 * ( 1 - xi ) * ( 1 + eta )
1925 phi(3) = 0.25 * ( 1 - xi ) * ( 1 - eta )
1926 phi(4) = 0.25 * ( 1 + xi ) * ( 1 - eta )
1928 dphidxi(1) = 0.25 * ( 1 + eta )
1929 dphidxi(2) = - 0.25 * ( 1 + eta )
1930 dphidxi(3) = - 0.25 * ( 1 - eta )
1931 dphidxi(4) = 0.25 * ( 1 - eta )
1933 dphideta(1) = 0.25 * ( 1 + xi )
1934 dphideta(2) = 0.25 * ( 1 - xi )
1935 dphideta(3) = - 0.25 * ( 1 - xi )
1936 dphideta(4) = - 0.25 * ( 1 + xi )
1947 real,
intent(in) :: xi, eta
1948 real,
dimension(9),
intent(out) :: phi, dphidxi, dphideta
1968 phi(1) = 0.25 * xi * ( 1 + xi ) * eta * ( 1 + eta )
1969 phi(2) = - 0.25 * xi * ( 1 - xi ) * eta * ( 1 + eta )
1970 phi(3) = 0.25 * xi * ( 1 - xi ) * eta * ( 1 - eta )
1971 phi(4) = - 0.25 * xi * ( 1 + xi ) * eta * ( 1 - eta )
1972 phi(5) = 0.5 * ( 1 + xi ) * ( 1 - xi ) * eta * ( 1 + eta )
1973 phi(6) = - 0.5 * xi * ( 1 - xi ) * ( 1 - eta ) * ( 1 + eta )
1974 phi(7) = - 0.5 * ( 1 - xi ) * ( 1 + xi ) * eta * ( 1 - eta )
1975 phi(8) = 0.5 * xi * ( 1 + xi ) * ( 1 - eta ) * ( 1 + eta )
1976 phi(9) = ( 1 - xi ) * ( 1 + xi ) * ( 1 - eta ) * ( 1 + eta )
2002 dza, intp_dza, intx_dza, inty_dza, halo_size)
2004 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
2005 intent(in) :: T, S, p_t, p_b
2006 real,
intent(in) :: alpha_ref
2008 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
2010 real,
dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
2011 optional,
intent(out) :: intp_dza
2012 real,
dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), &
2013 optional,
intent(out) :: intx_dza
2014 real,
dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), &
2015 optional,
intent(out) :: inty_dza
2016 integer,
optional,
intent(in) :: halo_size
2047 real :: T5(5), S5(5), p5(5), r5(5), a5(5)
2049 real :: w_left, w_right, intp(5)
2050 real,
parameter :: C1_90 = 1.0/90.0
2052 integer :: Isq, Ieq, Jsq, Jeq, ish, ieh, jsh, jeh, i, j, m, n, halo
2054 isq = hi%IscB ; ieq = hi%IecB ; jsq = hi%JscB ; jeq = hi%JecB
2055 halo = 0 ;
if (
present(halo_size)) halo = max(halo_size,0)
2056 ish = hi%isc-halo ; ieh = hi%iec+halo ; jsh = hi%jsc-halo ; jeh = hi%jec+halo
2057 if (
present(intx_dza))
then ; ish = min(isq,ish) ; ieh = max(ieq+1,ieh);
endif 2058 if (
present(inty_dza))
then ; jsh = min(jsq,jsh) ; jeh = max(jeq+1,jeh);
endif 2060 do j=jsh,jeh ;
do i=ish,ieh
2061 dp = p_b(i,j) - p_t(i,j)
2063 t5(n) = t(i,j) ; s5(n) = s(i,j)
2064 p5(n) = p_b(i,j) - 0.25*
real(n-1)*dp
2067 do n=1,5 ; a5(n) = 1.0 / r5(n) ;
enddo 2070 alpha_anom = c1_90*(7.0*(a5(1)+a5(5)) + 32.0*(a5(2)+a5(4)) + 12.0*a5(3)) - &
2072 dza(i,j) = dp*alpha_anom
2075 if (
present(intp_dza)) intp_dza(i,j) = 0.5*dp**2 * &
2076 (alpha_anom - c1_90*(16.0*(a5(4)-a5(2)) + 7.0*(a5(5)-a5(1))) )
2079 if (
present(intx_dza))
then ;
do j=hi%jsc,hi%jec ;
do i=isq,ieq
2080 intp(1) = dza(i,j) ; intp(5) = dza(i+1,j)
2082 w_left = 0.25*
real(5-m) ; w_right = 1.0-w_left
2083 dp = w_left*(p_b(i,j) - p_t(i,j)) + w_right*(p_b(i+1,j) - p_t(i+1,j))
2084 t5(1) = w_left*t(i,j) + w_right*t(i+1,j)
2085 s5(1) = w_left*s(i,j) + w_right*s(i+1,j)
2086 p5(1) = w_left*p_b(i,j) + w_right*p_b(i+1,j)
2088 t5(n) = t5(1) ; s5(n) = s5(1) ; p5(n) = p5(n-1) - 0.25*dp
2091 do n=1,5 ; a5(n) = 1.0 / r5(n) ;
enddo 2094 intp(m) = dp*( c1_90*(7.0*(a5(1)+a5(5)) + 32.0*(a5(2)+a5(4)) + &
2095 12.0*a5(3)) - alpha_ref)
2098 intx_dza(i,j) = c1_90*(7.0*(intp(1)+intp(5)) + 32.0*(intp(2)+intp(4)) + &
2100 enddo ;
enddo ;
endif 2102 if (
present(inty_dza))
then ;
do j=jsq,jeq ;
do i=hi%isc,hi%iec
2103 intp(1) = dza(i,j) ; intp(5) = dza(i,j+1)
2105 w_left = 0.25*
real(5-m) ; w_right = 1.0-w_left
2106 dp = w_left*(p_b(i,j) - p_t(i,j)) + w_right*(p_b(i,j+1) - p_t(i,j+1))
2107 t5(1) = w_left*t(i,j) + w_right*t(i,j+1)
2108 s5(1) = w_left*s(i,j) + w_right*s(i,j+1)
2109 p5(1) = w_left*p_b(i,j) + w_right*p_b(i,j+1)
2111 t5(n) = t5(1) ; s5(n) = s5(1) ; p5(n) = p5(n-1) - 0.25*dp
2114 do n=1,5 ; a5(n) = 1.0 / r5(n) ;
enddo 2117 intp(m) = dp*( c1_90*(7.0*(a5(1)+a5(5)) + 32.0*(a5(2)+a5(4)) + &
2118 12.0*a5(3)) - alpha_ref)
2121 inty_dza(i,j) = c1_90*(7.0*(intp(1)+intp(5)) + 32.0*(intp(2)+intp(4)) + &
2123 enddo ;
enddo ;
endif 2134 real,
dimension(SZI_(G),SZJ_(G), SZK_(G)),
intent(inout) :: T
2136 real,
dimension(SZI_(G),SZJ_(G), SZK_(G)),
intent(inout) :: S
2138 real,
dimension(:),
intent(in) :: press
2142 real,
dimension(SZI_(G),SZJ_(G), SZK_(G)),
intent(in) :: mask_z
2143 integer,
intent(in) :: kd
2146 real :: gsw_sr_from_sp, gsw_ct_from_pt, gsw_sa_from_sp
2149 if (.not.
associated(eos))
call mom_error(fatal, &
2150 "convert_temp_salt_to_TEOS10 called with an unassociated EOS_type EOS.")
2154 do k=1,kd ;
do j=g%jsc,g%jec ;
do i=g%isc,g%iec
2155 if (mask_z(i,j,k) .ge. 1.0)
then 2156 s(i,j,k) = gsw_sr_from_sp(s(i,j,k))
2159 t(i,j,k) = gsw_ct_from_pt(s(i,j,k),t(i,j,k))
subroutine, public int_spec_vol_dp_linear(T, S, p_t, p_b, alpha_ref, HI, Rho_T0_S0, dRho_dT, dRho_dS, dza, intp_dza, intx_dza, inty_dza, halo_size)
This subroutine calculates analytical and nearly-analytical integrals in pressure across layers of ge...
subroutine, public calculate_compress_teos10(T, S, pressure, rho, drho_dp, start, npts)
This subroutine computes the in situ density of sea water (rho in * units of kg/m^3) and the compress...
subroutine, public calculate_density_scalar_linear(T, S, pressure, rho, Rho_T0_S0, dRho_dT, dRho_dS)
This subroutine computes the density of sea water with a trivial linear equation of state (in kg/m^3)...
subroutine, public calculate_compress_unesco(T, S, pressure, rho, drho_dp, start, npts)
This subroutine computes the in situ density of sea water (rho) and the compressibility (drho/dp == C...
subroutine calculate_density_scalar(T, S, pressure, rho, EOS)
Calls the appropriate subroutine to calculate density of sea water for scalar inputs.
subroutine, public calculate_density_array_unesco(T, S, pressure, rho, start, npts)
This subroutine computes the in situ density of sea water (rho in units of kg/m^3) from salinity (S i...
logical function, public query_compressible(EOS)
Returns true if the equation of state is compressible (i.e. has pressure dependence) ...
subroutine, public int_specific_vol_dp(T, S, p_t, p_b, alpha_ref, HI, EOS, dza, intp_dza, intx_dza, inty_dza, halo_size)
Calls the appropriate subroutine to alculate analytical and nearly-analytical integrals in pressure a...
Ocean grid type. See mom_grid for details.
subroutine calculate_tfreeze_array(S, pressure, T_fr, start, npts, EOS)
Calls the appropriate subroutine to calculate the freezing point for a 1-D array. ...
subroutine, public eos_allocate(EOS)
Allocates EOS_type.
Calculates density of sea water from T, S and P.
Calculates the freezing point of sea water from T, S and P.
subroutine, public eos_end(EOS)
Deallocates EOS_type.
subroutine compute_integral_bilinear(x, y, f, integral)
subroutine, public calculate_density_derivs_wright(T, S, pressure, drho_dT, drho_dS, start, npts)
integer, parameter eos_wright
Provides the ocean grid type.
real function frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, pos, EOS)
Returns change in anomalous pressure change from top to non-dimensional position pos between z_t and ...
character *(10), parameter eos_unesco_string
subroutine, public calculate_specific_vol_derivs(T, S, pressure, dSV_dT, dSV_dS, start, npts, EOS)
Calls the appropriate subroutine to calculate specific volume derivatives for an array.
subroutine, public calculate_density_scalar_wright(T, S, pressure, rho)
This subroutine computes the in situ density of sea water (rho in units of kg/m^3) from salinity (S i...
subroutine, public eos_init(param_file, EOS)
Initializes EOS_type by allocating and reading parameters.
subroutine, public calculate_density_array_nemo(T, S, pressure, rho, start, npts)
This subroutine computes the in situ density of sea water (rho in units of kg/m^3) from absolute sali...
integer, parameter eos_linear
Defines the horizontal index type (hor_index_type) used for providing index ranges.
subroutine, public find_depth_of_pressure_in_cell(T_t, T_b, S_t, S_b, z_t, z_b, P_t, P_tgt, rho_ref, G_e, EOS, P_b, z_out)
Find the depth at which the reconstructed pressure matches P_tgt.
subroutine, public calculate_density_array_linear(T, S, pressure, rho, start, npts, Rho_T0_S0, dRho_dT, dRho_dS)
This subroutine computes the density of sea water with a trivial linear equation of state (in kg/m^3)...
subroutine, public int_density_dz_generic_ppm(T, T_t, T_b, S, S_t, S_b, z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, EOS, dpa, intz_dpa, intx_dpa, inty_dpa)
subroutine evaluate_shape_bilinear(xi, eta, phi, dphidxi, dphideta)
subroutine int_spec_vol_dp_generic(T, S, p_t, p_b, alpha_ref, HI, EOS, dza, intp_dza, intx_dza, inty_dza, halo_size)
Container for horizontal index ranges for data, computational and global domains. ...
subroutine, public calculate_density_derivs_nemo(T, S, pressure, drho_dT, drho_dS, start, npts)
character *(10), parameter eos_wright_string
integer, parameter tfreeze_teos10
subroutine, public calculate_compress(T, S, pressure, rho, drho_dp, start, npts, EOS)
Calls the appropriate subroutine to calculate the density and compressibility for 1-D array inputs...
character *(10), parameter eos_linear_string
subroutine, public convert_temp_salt_for_teos10(T, S, press, G, kd, mask_z, EOS)
Convert T&S to Absolute Salinity and Conservative Temperature if using TEOS10.
subroutine, public calculate_compress_linear(T, S, pressure, rho, drho_dp, start, npts, Rho_T0_S0, dRho_dT, dRho_dS)
This subroutine computes the in situ density of sea water (rho) and the compressibility (drho/dp == C...
subroutine, public calculate_density_derivs(T, S, pressure, drho_dT, drho_dS, start, npts, EOS)
Calls the appropriate subroutine to calculate density derivatives for 1-D array inputs.
integer, parameter tfreeze_linear
character(len=len(input_string)) function, public uppercase(input_string)
integer, parameter tfreeze_millero
character *(10), parameter tfreeze_teos10_string
subroutine, public calculate_specvol_derivs_teos10(T, S, pressure, dSV_dT, dSV_dS, start, npts)
subroutine, public calculate_compress_nemo(T, S, pressure, rho, drho_dp, start, npts)
integer, parameter eos_nemo
subroutine, public calculate_density_scalar_nemo(T, S, pressure, rho)
subroutine, public int_density_dz_linear(T, S, z_t, z_b, rho_ref, rho_0_pres, G_e, HII, HIO, Rho_T0_S0, dRho_dT, dRho_dS, dpa, intz_dpa, intx_dpa, inty_dpa)
This subroutine calculates analytical and nearly-analytical integrals of pressure anomalies across la...
subroutine, public int_density_dz_generic_plm_analytic(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, rho_0, G_e, HI, EOS, dpa, intz_dpa, intx_dpa, inty_dpa)
subroutine, public calculate_density_scalar_unesco(T, S, pressure, rho)
This subroutine computes the in situ density of sea water (rho in units of kg/m^3) from salinity (S i...
subroutine, public calculate_density_derivs_teos10(T, S, pressure, drho_dT, drho_dS, start, npts)
subroutine, public mom_mesg(message, verb, all_print)
Provides subroutines for quantities specific to the equation of state.
subroutine int_density_dz_generic_cell(T_t_arg, T_b_arg, S_t_arg, S_b_arg, z_t_arg, z_b_arg, depth, rho_ref, rho_0, G_e, EOS, dpa, intz_dpa, intx_dpa, inty_dpa)
subroutine, public calculate_specvol_derivs_wright(T, S, pressure, dSV_dT, dSV_dS, start, npts)
subroutine, public calculate_compress_wright(T, S, pressure, rho, drho_dp, start, npts)
This subroutine computes the in situ density of sea water (rho in units of kg/m^3) and the compressib...
subroutine, public int_spec_vol_dp_wright(T, S, p_t, p_b, alpha_ref, HI, dza, intp_dza, intx_dza, inty_dza, halo_size)
This subroutine calculates analytical and nearly-analytical integrals in pressure across layers of ge...
subroutine int_density_dz_generic(T, S, z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, EOS, dpa, intz_dpa, intx_dpa, inty_dpa)
subroutine calculate_tfreeze_scalar(S, pressure, T_fr, EOS)
Calls the appropriate subroutine to calculate the freezing point for scalar inputs.
subroutine, public calculate_specvol_derivs_linear(T, S, pressure, dSV_dT, dSV_dS, start, npts, Rho_T0_S0, dRho_dT, dRho_dS)
character *(10), parameter tfreeze_millero_string
subroutine, public calculate_density_derivs_unesco(T, S, pressure, drho_dT, drho_dS, start, npts)
This subroutine calculates the partial derivatives of density with potential temperature and salinity...
subroutine, public int_density_dz_generic_plm(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, rho_0, G_e, H_subroundoff, bathyT, HII, HIO, EOS, dpa, intz_dpa, intx_dpa, inty_dpa, useMassWghtInterp)
character *(10), parameter tfreeze_default
subroutine, public calculate_density_array_wright(T, S, pressure, rho, start, npts)
This subroutine computes the in situ density of sea water (rho in units of kg/m^3) from salinity (S i...
integer, parameter eos_unesco
subroutine, public calculate_density_scalar_teos10(T, S, pressure, rho)
This subroutine computes the in situ density of sea water (rho in units of kg/m^3) from salinity (S i...
subroutine, public eos_use_linear(Rho_T0_S0, dRho_dT, dRho_dS, EOS, use_quadrature)
Set equation of state structure (EOS) to linear with given coefficients.
subroutine, public calculate_density_derivs_linear(T, S, pressure, drho_dT_out, drho_dS_out, start, npts, Rho_T0_S0, dRho_dT, dRho_dS)
This subroutine calculates the partial derivatives of density * with potential temperature and salini...
character *(10), parameter eos_nemo_string
character *(10), parameter tfreeze_linear_string
subroutine evaluate_shape_quadratic(xi, eta, phi, dphidxi, dphideta)
subroutine, public calculate_density_array_teos10(T, S, pressure, rho, start, npts)
subroutine, public mom_error(level, message, all_print)
subroutine compute_integral_quadratic(x, y, f, integral)
character *(10), parameter eos_teos10_string
subroutine, public int_density_dz(T, S, z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, EOS, dpa, intz_dpa, intx_dpa, inty_dpa)
This subroutine calculates analytical and nearly-analytical integrals of pressure anomalies across la...
subroutine, public int_density_dz_wright(T, S, z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, dpa, intz_dpa, intx_dpa, inty_dpa)
This subroutine calculates analytical and nearly-analytical integrals of pressure anomalies across la...
character *(10), parameter eos_default
integer, parameter eos_teos10
A control structure for the equation of state.
subroutine calculate_density_array(T, S, pressure, rho, start, npts, EOS)
Calls the appropriate subroutine to calculate the density of sea water for 1-D array inputs...