17 use mom_eos, only : query_compressible
19 implicit none ;
private 21 #include <MOM_memory.h> 23 public pressureforce_mont_bouss, pressureforce_mont_nonbouss, set_pbce_bouss
24 public set_pbce_nonbouss, pressureforce_mont_init, pressureforce_mont_end
39 type(time_type),
pointer :: time => null()
42 real,
pointer :: pfu_bc(:,:,:) => null()
44 real,
pointer :: pfv_bc(:,:,:) => null()
47 integer :: id_pfu_bc = -1, id_pfv_bc = -1, id_e_tidal = -1
63 subroutine pressureforce_mont_nonbouss(h, tv, PFu, PFv, G, GV, US, CS, p_atm, pbce, eta)
67 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
69 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(out) :: PFu
71 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(out) :: PFv
74 real,
dimension(:,:),
optional,
pointer :: p_atm
76 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
77 optional,
intent(out) :: pbce
80 real,
dimension(SZI_(G),SZJ_(G)),
optional,
intent(out) :: eta
83 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
87 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: p
91 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
target :: &
97 real,
dimension(SZI_(G)) :: Rho_cv_BL
100 real,
dimension(SZI_(G),SZJ_(G)) :: &
109 real :: p_ref(szi_(g))
111 real :: rho_in_situ(szi_(g))
112 real :: PFu_bc, PFv_bc
125 real :: alpha_Lay(szk_(g))
126 real :: dalpha_int(szk_(g)+1)
128 integer,
dimension(2) :: EOSdom
129 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb
131 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
132 nkmb=gv%nk_rho_varies
133 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
134 eosdom(1) = isq - (g%isd-1) ; eosdom(2) = g%iec+1 - (g%isd-1)
137 if (
present(p_atm))
then ;
if (
associated(p_atm)) use_p_atm = .true. ;
endif 138 is_split = .false. ;
if (
present(pbce)) is_split = .true.
139 use_eos =
associated(tv%eqn_of_state)
141 if (.not.
associated(cs))
call mom_error(fatal, &
142 "MOM_PressureForce_Mont: Module must be initialized before it is used.")
144 if (query_compressible(tv%eqn_of_state))
call mom_error(fatal, &
145 "PressureForce_Mont_nonBouss: The Montgomery form of the pressure force "//&
146 "can no longer be used with a compressible EOS. Use #define ANALYTIC_FV_PGF.")
149 i_gearth = 1.0 / gv%g_Earth
150 dp_neglect = gv%g_Earth * gv%H_to_RZ * gv%H_subroundoff
151 do k=1,nz ; alpha_lay(k) = 1.0 / (gv%Rlay(k)) ;
enddo 152 do k=2,nz ; dalpha_int(k) = alpha_lay(k-1) - alpha_lay(k) ;
enddo 156 do j=jsq,jeq+1 ;
do i=isq,ieq+1 ; p(i,j,1) = p_atm(i,j) ;
enddo ;
enddo 159 do j=jsq,jeq+1 ;
do i=isq,ieq+1 ; p(i,j,1) = 0.0 ;
enddo ;
enddo 162 do j=jsq,jeq+1 ;
do k=1,nz ;
do i=isq,ieq+1
163 p(i,j,k+1) = p(i,j,k) + gv%g_Earth * gv%H_to_RZ * h(i,j,k)
164 enddo ;
enddo ;
enddo 166 if (
present(eta))
then 167 pa_to_h = 1.0 / (gv%g_Earth * gv%H_to_RZ)
170 do j=jsq,jeq+1 ;
do i=isq,ieq+1
171 eta(i,j) = (p(i,j,nz+1) - p_atm(i,j)) * pa_to_h
175 do j=jsq,jeq+1 ;
do i=isq,ieq+1
176 eta(i,j) = p(i,j,nz+1) * pa_to_h
185 do j=jsq,jeq+1 ;
do i=isq,ieq+1
186 ssh(i,j) = -g%bathyT(i,j)
191 call int_specific_vol_dp(tv%T(:,:,k), tv%S(:,:,k), p(:,:,k), p(:,:,k+1), &
192 0.0, g%HI, tv%eqn_of_state, us, dz_geo(:,:,k), halo_size=1)
195 do j=jsq,jeq+1 ;
do k=1,nz ;
do i=isq,ieq+1
196 ssh(i,j) = ssh(i,j) + i_gearth * dz_geo(i,j,k)
197 enddo ;
enddo ;
enddo 200 do j=jsq,jeq+1 ;
do k=1,nz ;
do i=isq,ieq+1
201 ssh(i,j) = ssh(i,j) + gv%H_to_RZ * h(i,j,k) * alpha_lay(k)
202 enddo ;
enddo ;
enddo 205 call calc_tidal_forcing(cs%Time, ssh, e_tidal, g, cs%tides_CSp, m_to_z=us%m_to_Z)
207 do j=jsq,jeq+1 ;
do i=isq,ieq+1
208 geopot_bot(i,j) = -gv%g_Earth*(e_tidal(i,j) + g%bathyT(i,j))
212 do j=jsq,jeq+1 ;
do i=isq,ieq+1
213 geopot_bot(i,j) = -gv%g_Earth*g%bathyT(i,j)
225 tv_tmp%T => t_tmp ; tv_tmp%S => s_tmp
226 tv_tmp%eqn_of_state => tv%eqn_of_state
227 do i=isq,ieq+1 ; p_ref(i) = tv%P_Ref ;
enddo 230 do k=1,nkmb ;
do i=isq,ieq+1
231 tv_tmp%T(i,j,k) = tv%T(i,j,k) ; tv_tmp%S(i,j,k) = tv%S(i,j,k)
234 tv%eqn_of_state, eosdom)
235 do k=nkmb+1,nz ;
do i=isq,ieq+1
236 if (gv%Rlay(k) < rho_cv_bl(i))
then 237 tv_tmp%T(i,j,k) = tv%T(i,j,nkmb) ; tv_tmp%S(i,j,k) = tv%S(i,j,nkmb)
239 tv_tmp%T(i,j,k) = tv%T(i,j,k) ; tv_tmp%S(i,j,k) = tv%S(i,j,k)
244 tv_tmp%T => tv%T ; tv_tmp%S => tv%S
245 tv_tmp%eqn_of_state => tv%eqn_of_state
246 do i=isq,ieq+1 ; p_ref(i) = 0 ;
enddo 249 do k=1,nz ;
do j=jsq,jeq+1
251 tv%eqn_of_state, eosdom)
252 do i=isq,ieq+1 ; alpha_star(i,j,k) = 1.0 / rho_in_situ(i) ;
enddo 260 m(i,j,nz) = geopot_bot(i,j) + p(i,j,nz+1) * alpha_star(i,j,nz)
262 do k=nz-1,1,-1 ;
do i=isq,ieq+1
263 m(i,j,k) = m(i,j,k+1) + p(i,j,k+1) * (alpha_star(i,j,k) - alpha_star(i,j,k+1))
270 m(i,j,nz) = geopot_bot(i,j) + p(i,j,nz+1) * alpha_lay(nz)
272 do k=nz-1,1,-1 ;
do i=isq,ieq+1
273 m(i,j,k) = m(i,j,k+1) + p(i,j,k+1) * dalpha_int(k+1)
278 if (cs%GFS_scale < 1.0)
then 281 do j=jsq,jeq+1 ;
do i=isq,ieq+1
282 dm(i,j) = (cs%GFS_scale - 1.0) * m(i,j,1)
285 do k=1,nz ;
do j=jsq,jeq+1 ;
do i=isq,ieq+1
286 m(i,j,k) = m(i,j,k) + dm(i,j)
287 enddo ;
enddo ;
enddo 307 if (
present(pbce))
then 308 call set_pbce_nonbouss(p, tv_tmp, g, gv, us, cs%GFS_scale, pbce, alpha_star)
316 do j=jsq,jeq+1 ;
do i=isq,ieq+1
317 dp_star(i,j) = (p(i,j,k+1) - p(i,j,k)) + dp_neglect
319 do j=js,je ;
do i=isq,ieq
321 pfu_bc = (alpha_star(i+1,j,k) - alpha_star(i,j,k)) * (g%IdxCu(i,j) * &
322 ((dp_star(i,j)*dp_star(i+1,j) + (p(i,j,k)*dp_star(i+1,j) + p(i+1,j,k)*dp_star(i,j))) / &
323 (dp_star(i,j) + dp_star(i+1,j))))
324 pfu(i,j,k) = -(m(i+1,j,k) - m(i,j,k)) * g%IdxCu(i,j) + pfu_bc
325 if (
associated(cs%PFu_bc)) cs%PFu_bc(i,j,k) = pfu_bc
327 do j=jsq,jeq ;
do i=is,ie
328 pfv_bc = (alpha_star(i,j+1,k) - alpha_star(i,j,k)) * (g%IdyCv(i,j) * &
329 ((dp_star(i,j)*dp_star(i,j+1) + (p(i,j,k)*dp_star(i,j+1) + p(i,j+1,k)*dp_star(i,j))) / &
330 (dp_star(i,j) + dp_star(i,j+1))))
331 pfv(i,j,k) = -(m(i,j+1,k) - m(i,j,k)) * g%IdyCv(i,j) + pfv_bc
332 if (
associated(cs%PFv_bc)) cs%PFv_bc(i,j,k) = pfv_bc
338 do j=js,je ;
do i=isq,ieq
339 pfu(i,j,k) = -(m(i+1,j,k) - m(i,j,k)) * g%IdxCu(i,j)
341 do j=jsq,jeq ;
do i=is,ie
342 pfv(i,j,k) = -(m(i,j+1,k) - m(i,j,k)) * g%IdyCv(i,j)
347 if (cs%id_PFu_bc>0)
call post_data(cs%id_PFu_bc, cs%PFu_bc, cs%diag)
348 if (cs%id_PFv_bc>0)
call post_data(cs%id_PFv_bc, cs%PFv_bc, cs%diag)
349 if (cs%id_e_tidal>0)
call post_data(cs%id_e_tidal, e_tidal, cs%diag)
351 end subroutine pressureforce_mont_nonbouss
360 subroutine pressureforce_mont_bouss(h, tv, PFu, PFv, G, GV, US, CS, p_atm, pbce, eta)
364 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
366 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(out) :: PFu
368 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(out) :: PFv
371 real,
dimension(:,:),
optional,
pointer :: p_atm
373 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
optional,
intent(out) :: pbce
376 real,
dimension(SZI_(G),SZJ_(G)),
optional,
intent(out) :: eta
378 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
382 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: e
386 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
target :: &
392 real :: Rho_cv_BL(szi_(g))
394 real :: h_star(szi_(g),szj_(g))
396 real :: e_tidal(szi_(g),szj_(g))
399 real :: p_ref(szi_(g))
403 real :: PFu_bc, PFv_bc
414 integer,
dimension(2) :: EOSdom
415 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb
418 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
419 nkmb=gv%nk_rho_varies
420 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
421 eosdom(1) = isq - (g%isd-1) ; eosdom(2) = g%iec+1 - (g%isd-1)
424 if (
present(p_atm))
then ;
if (
associated(p_atm)) use_p_atm = .true. ;
endif 425 is_split = .false. ;
if (
present(pbce)) is_split = .true.
426 use_eos =
associated(tv%eqn_of_state)
428 if (.not.
associated(cs))
call mom_error(fatal, &
429 "MOM_PressureForce_Mont: Module must be initialized before it is used.")
431 if (query_compressible(tv%eqn_of_state))
call mom_error(fatal, &
432 "PressureForce_Mont_Bouss: The Montgomery form of the pressure force "//&
433 "can no longer be used with a compressible EOS. Use #define ANALYTIC_FV_PGF.")
436 h_neglect = gv%H_subroundoff * gv%H_to_Z
438 g_rho0 = gv%g_Earth / gv%Rho0
447 do i=isq,ieq+1 ; e(i,j,1) = -g%bathyT(i,j) ;
enddo 448 do k=1,nz ;
do i=isq,ieq+1
449 e(i,j,1) = e(i,j,1) + h(i,j,k)*gv%H_to_Z
452 call calc_tidal_forcing(cs%Time, e(:,:,1), e_tidal, g, cs%tides_CSp, m_to_z=us%m_to_Z)
458 do j=jsq,jeq+1 ;
do i=isq,ieq+1
459 e(i,j,nz+1) = -(g%bathyT(i,j) + e_tidal(i,j))
463 do j=jsq,jeq+1 ;
do i=isq,ieq+1
464 e(i,j,nz+1) = -g%bathyT(i,j)
468 do j=jsq,jeq+1 ;
do k=nz,1,-1 ;
do i=isq,ieq+1
469 e(i,j,k) = e(i,j,k+1) + h(i,j,k)*gv%H_to_Z
470 enddo ;
enddo ;
enddo 481 tv_tmp%T => t_tmp ; tv_tmp%S => s_tmp
482 tv_tmp%eqn_of_state => tv%eqn_of_state
484 do i=isq,ieq+1 ; p_ref(i) = tv%P_Ref ;
enddo 487 do k=1,nkmb ;
do i=isq,ieq+1
488 tv_tmp%T(i,j,k) = tv%T(i,j,k) ; tv_tmp%S(i,j,k) = tv%S(i,j,k)
491 tv%eqn_of_state, eosdom)
493 do k=nkmb+1,nz ;
do i=isq,ieq+1
494 if (gv%Rlay(k) < rho_cv_bl(i))
then 495 tv_tmp%T(i,j,k) = tv%T(i,j,nkmb) ; tv_tmp%S(i,j,k) = tv%S(i,j,nkmb)
497 tv_tmp%T(i,j,k) = tv%T(i,j,k) ; tv_tmp%S(i,j,k) = tv%S(i,j,k)
502 tv_tmp%T => tv%T ; tv_tmp%S => tv%S
503 tv_tmp%eqn_of_state => tv%eqn_of_state
504 do i=isq,ieq+1 ; p_ref(i) = 0.0 ;
enddo 510 do k=1,nz ;
do j=jsq,jeq+1
511 call calculate_density(tv_tmp%T(:,j,k), tv_tmp%S(:,j,k), p_ref, rho_star(:,j,k), &
512 tv%eqn_of_state, eosdom)
513 do i=isq,ieq+1 ; rho_star(i,j,k) = g_rho0*rho_star(i,j,k) ;
enddo 522 m(i,j,1) = cs%GFS_scale * (rho_star(i,j,1) * e(i,j,1))
523 if (use_p_atm) m(i,j,1) = m(i,j,1) + p_atm(i,j) * i_rho0
525 do k=2,nz ;
do i=isq,ieq+1
526 m(i,j,k) = m(i,j,k-1) + (rho_star(i,j,k) - rho_star(i,j,k-1)) * e(i,j,k)
533 m(i,j,1) = gv%g_prime(1) * e(i,j,1)
534 if (use_p_atm) m(i,j,1) = m(i,j,1) + p_atm(i,j) * i_rho0
536 do k=2,nz ;
do i=isq,ieq+1
537 m(i,j,k) = m(i,j,k-1) + gv%g_prime(k) * e(i,j,k)
542 if (
present(pbce))
then 543 call set_pbce_bouss(e, tv_tmp, g, gv, us, cs%Rho0, cs%GFS_scale, pbce, rho_star)
551 do j=jsq,jeq+1 ;
do i=isq,ieq+1
552 h_star(i,j) = (e(i,j,k) - e(i,j,k+1)) + h_neglect
554 do j=js,je ;
do i=isq,ieq
555 pfu_bc = -1.0*(rho_star(i+1,j,k) - rho_star(i,j,k)) * (g%IdxCu(i,j) * &
556 ((h_star(i,j) * h_star(i+1,j) - (e(i,j,k) * h_star(i+1,j) + &
557 e(i+1,j,k) * h_star(i,j))) / (h_star(i,j) + h_star(i+1,j))))
558 pfu(i,j,k) = -(m(i+1,j,k) - m(i,j,k)) * g%IdxCu(i,j) + pfu_bc
559 if (
associated(cs%PFu_bc)) cs%PFu_bc(i,j,k) = pfu_bc
561 do j=jsq,jeq ;
do i=is,ie
562 pfv_bc = -1.0*(rho_star(i,j+1,k) - rho_star(i,j,k)) * (g%IdyCv(i,j) * &
563 ((h_star(i,j) * h_star(i,j+1) - (e(i,j,k) * h_star(i,j+1) + &
564 e(i,j+1,k) * h_star(i,j))) / (h_star(i,j) + h_star(i,j+1))))
565 pfv(i,j,k) = -(m(i,j+1,k) - m(i,j,k)) * g%IdyCv(i,j) + pfv_bc
566 if (
associated(cs%PFv_bc)) cs%PFv_bc(i,j,k) = pfv_bc
572 do j=js,je ;
do i=isq,ieq
573 pfu(i,j,k) = -(m(i+1,j,k) - m(i,j,k)) * g%IdxCu(i,j)
575 do j=jsq,jeq ;
do i=is,ie
576 pfv(i,j,k) = -(m(i,j+1,k) - m(i,j,k)) * g%IdyCv(i,j)
581 if (
present(eta))
then 587 do j=jsq,jeq+1 ;
do i=isq,ieq+1
588 eta(i,j) = e(i,j,1)*gv%Z_to_H + e_tidal(i,j)*gv%Z_to_H
592 do j=jsq,jeq+1 ;
do i=isq,ieq+1
593 eta(i,j) = e(i,j,1)*gv%Z_to_H
598 if (cs%id_PFu_bc>0)
call post_data(cs%id_PFu_bc, cs%PFu_bc, cs%diag)
599 if (cs%id_PFv_bc>0)
call post_data(cs%id_PFv_bc, cs%PFv_bc, cs%diag)
600 if (cs%id_e_tidal>0)
call post_data(cs%id_e_tidal, e_tidal, cs%diag)
602 end subroutine pressureforce_mont_bouss
606 subroutine set_pbce_bouss(e, tv, G, GV, US, Rho0, GFS_scale, pbce, rho_star)
609 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(in) :: e
612 real,
intent(in) :: Rho0
613 real,
intent(in) :: GFS_scale
616 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
620 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
621 optional,
intent(in) :: rho_star
625 real :: Ihtot(szi_(g))
626 real :: press(szi_(g))
627 real :: T_int(szi_(g))
628 real :: S_int(szi_(g))
629 real :: dR_dT(szi_(g))
630 real :: dR_dS(szi_(g))
631 real :: rho_in_situ(szi_(g))
638 integer,
dimension(2) :: EOSdom
639 integer :: Isq, Ieq, Jsq, Jeq, nz, i, j, k
641 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB ; nz = g%ke
642 eosdom(1) = isq - (g%isd-1) ; eosdom(2) = g%iec+1 - (g%isd-1)
644 rho0xg = rho0 * gv%g_Earth
645 g_rho0 = gv%g_Earth / gv%Rho0
646 use_eos =
associated(tv%eqn_of_state)
647 z_neglect = gv%H_subroundoff*gv%H_to_Z
650 if (
present(rho_star))
then 654 ihtot(i) = gv%H_to_Z / ((e(i,j,1)-e(i,j,nz+1)) + z_neglect)
655 pbce(i,j,1) = gfs_scale * rho_star(i,j,1) * gv%H_to_Z
657 do k=2,nz ;
do i=isq,ieq+1
658 pbce(i,j,k) = pbce(i,j,k-1) + (rho_star(i,j,k)-rho_star(i,j,k-1)) * &
659 ((e(i,j,k) - e(i,j,nz+1)) * ihtot(i))
666 ihtot(i) = gv%H_to_Z / ((e(i,j,1)-e(i,j,nz+1)) + z_neglect)
667 press(i) = -rho0xg*e(i,j,1)
670 tv%eqn_of_state, eosdom)
672 pbce(i,j,1) = g_rho0*(gfs_scale * rho_in_situ(i)) * gv%H_to_Z
676 press(i) = -rho0xg*e(i,j,k)
677 t_int(i) = 0.5*(tv%T(i,j,k-1)+tv%T(i,j,k))
678 s_int(i) = 0.5*(tv%S(i,j,k-1)+tv%S(i,j,k))
681 tv%eqn_of_state, eosdom)
683 pbce(i,j,k) = pbce(i,j,k-1) + g_rho0 * &
684 ((e(i,j,k) - e(i,j,nz+1)) * ihtot(i)) * &
685 (dr_dt(i)*(tv%T(i,j,k)-tv%T(i,j,k-1)) + &
686 dr_ds(i)*(tv%S(i,j,k)-tv%S(i,j,k-1)))
695 ihtot(i) = 1.0 / ((e(i,j,1)-e(i,j,nz+1)) + z_neglect)
696 pbce(i,j,1) = gv%g_prime(1) * gv%H_to_Z
698 do k=2,nz ;
do i=isq,ieq+1
699 pbce(i,j,k) = pbce(i,j,k-1) + &
700 (gv%g_prime(k)*gv%H_to_Z) * ((e(i,j,k) - e(i,j,nz+1)) * ihtot(i))
705 end subroutine set_pbce_bouss
709 subroutine set_pbce_nonbouss(p, tv, G, GV, US, GFS_scale, pbce, alpha_star)
712 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(in) :: p
715 real,
intent(in) :: GFS_scale
718 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(out) :: pbce
721 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
optional,
intent(in) :: alpha_star
724 real,
dimension(SZI_(G),SZJ_(G)) :: &
728 real :: T_int(szi_(g))
729 real :: S_int(szi_(g))
730 real :: dR_dT(szi_(g))
731 real :: dR_dS(szi_(g))
732 real :: rho_in_situ(szi_(g))
733 real :: alpha_Lay(szk_(g))
734 real :: dalpha_int(szk_(g)+1)
740 integer,
dimension(2) :: EOSdom
741 integer :: Isq, Ieq, Jsq, Jeq, nz, i, j, k
743 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB ; nz = g%ke
744 eosdom(1) = isq - (g%isd-1) ; eosdom(2) = g%iec+1 - (g%isd-1)
746 use_eos =
associated(tv%eqn_of_state)
748 dp_dh = gv%g_Earth * gv%H_to_RZ
749 dp_neglect = gv%g_Earth * gv%H_to_RZ * gv%H_subroundoff
752 if (
present(alpha_star))
then 756 c_htot(i,j) = dp_dh / ((p(i,j,nz+1)-p(i,j,1)) + dp_neglect)
757 pbce(i,j,nz) = dp_dh * alpha_star(i,j,nz)
759 do k=nz-1,1,-1 ;
do i=isq,ieq+1
760 pbce(i,j,k) = pbce(i,j,k+1) + ((p(i,j,k+1)-p(i,j,1)) * c_htot(i,j)) * &
761 (alpha_star(i,j,k) - alpha_star(i,j,k+1))
767 call calculate_density(tv%T(:,j,nz), tv%S(:,j,nz), p(:,j,nz+1), rho_in_situ, &
768 tv%eqn_of_state, eosdom)
770 c_htot(i,j) = dp_dh / ((p(i,j,nz+1)-p(i,j,1)) + dp_neglect)
771 pbce(i,j,nz) = dp_dh / (rho_in_situ(i))
775 t_int(i) = 0.5*(tv%T(i,j,k)+tv%T(i,j,k+1))
776 s_int(i) = 0.5*(tv%S(i,j,k)+tv%S(i,j,k+1))
778 call calculate_density(t_int, s_int, p(:,j,k+1), rho_in_situ, tv%eqn_of_state, eosdom)
780 tv%eqn_of_state, eosdom)
782 pbce(i,j,k) = pbce(i,j,k+1) + ((p(i,j,k+1)-p(i,j,1))*c_htot(i,j)) * &
783 ((dr_dt(i)*(tv%T(i,j,k+1)-tv%T(i,j,k)) + &
784 dr_ds(i)*(tv%S(i,j,k+1)-tv%S(i,j,k))) / (rho_in_situ(i)**2))
791 do k=1,nz ; alpha_lay(k) = 1.0 / (gv%Rlay(k)) ;
enddo 792 do k=2,nz ; dalpha_int(k) = alpha_lay(k-1) - alpha_lay(k) ;
enddo 797 c_htot(i,j) = dp_dh / ((p(i,j,nz+1)-p(i,j,1)) + dp_neglect)
798 pbce(i,j,nz) = dp_dh * alpha_lay(nz)
800 do k=nz-1,1,-1 ;
do i=isq,ieq+1
801 pbce(i,j,k) = pbce(i,j,k+1) + ((p(i,j,k+1)-p(i,j,1))*c_htot(i,j)) * dalpha_int(k+1)
806 if (gfs_scale < 1.0)
then 809 do j=jsq,jeq+1 ;
do i=isq,ieq+1
810 dpbce(i,j) = (gfs_scale - 1.0) * pbce(i,j,1)
813 do k=1,nz ;
do j=jsq,jeq+1 ;
do i=isq,ieq+1
814 pbce(i,j,k) = pbce(i,j,k) + dpbce(i,j)
815 enddo ;
enddo ;
enddo 818 end subroutine set_pbce_nonbouss
821 subroutine pressureforce_mont_init(Time, G, GV, US, param_file, diag, CS, tides_CSp)
822 type(time_type),
target,
intent(in) :: Time
827 type(
diag_ctrl),
target,
intent(inout) :: diag
832 logical :: use_temperature, use_EOS
834 # include "version_variable.h" 835 character(len=40) :: mdl
837 if (
associated(cs))
then 838 call mom_error(warning,
"PressureForce_init called with an associated "// &
839 "control structure.")
841 else ;
allocate(cs) ;
endif 843 cs%diag => diag ; cs%Time => time
844 if (
present(tides_csp))
then 845 if (
associated(tides_csp)) cs%tides_CSp => tides_csp
848 mdl =
"MOM_PressureForce_Mont" 850 call get_param(param_file, mdl,
"RHO_0", cs%Rho0, &
851 "The mean ocean density used with BOUSSINESQ true to "//&
852 "calculate accelerations and the mass for conservation "//&
853 "properties, or with BOUSSINSEQ false to convert some "//&
854 "parameters from vertical units of m to kg m-2.", &
855 units=
"kg m-3", default=1035.0, scale=us%R_to_kg_m3)
856 call get_param(param_file, mdl,
"TIDES", cs%tides, &
857 "If true, apply tidal momentum forcing.", default=.false.)
858 call get_param(param_file, mdl,
"USE_EOS", use_eos, default=.true., &
862 cs%id_PFu_bc = register_diag_field(
'ocean_model',
'PFu_bc', diag%axesCuL, time, &
863 'Density Gradient Zonal Pressure Force Accel.',
"meter second-2", conversion=us%L_T2_to_m_s2)
864 cs%id_PFv_bc = register_diag_field(
'ocean_model',
'PFv_bc', diag%axesCvL, time, &
865 'Density Gradient Meridional Pressure Force Accel.',
"meter second-2", conversion=us%L_T2_to_m_s2)
866 if (cs%id_PFu_bc > 0)
then 867 call safe_alloc_ptr(cs%PFu_bc,g%IsdB,g%IedB,g%jsd,g%jed,g%ke)
868 cs%PFu_bc(:,:,:) = 0.0
870 if (cs%id_PFv_bc > 0)
then 871 call safe_alloc_ptr(cs%PFv_bc,g%isd,g%ied,g%JsdB,g%JedB,g%ke)
872 cs%PFv_bc(:,:,:) = 0.0
877 cs%id_e_tidal = register_diag_field(
'ocean_model',
'e_tidal', diag%axesT1, &
878 time,
'Tidal Forcing Astronomical and SAL Height Anomaly',
'meter', conversion=us%Z_to_m)
882 if (gv%g_prime(1) /= gv%g_Earth) cs%GFS_scale = gv%g_prime(1) / gv%g_Earth
884 call log_param(param_file, mdl,
"GFS / G_EARTH", cs%GFS_scale)
886 end subroutine pressureforce_mont_init
889 subroutine pressureforce_mont_end(CS)
891 if (
associated(cs))
deallocate(cs)
892 end subroutine pressureforce_mont_end
Ocean grid type. See mom_grid for details.
Calculates density of sea water from T, S and P.
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
The MOM6 facility to parse input files for runtime parameters.
An overloaded interface to log the values of various types of parameters.
Make a diagnostic available for averaging or output.
Describes various unit conversion factors.
Provides the Montgomery potential form of pressure gradient.
Tidal contributions to geopotential.
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Routines for error handling and I/O management.
Calculate the derivatives of density with temperature and salinity from T, S, and P...
Provides subroutines for quantities specific to the equation of state.
An overloaded interface to log version information about modules.
Describes the vertical ocean grid, including unit conversion factors.
Provides integrals of density.
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
The control structure for the MOM_tidal_forcing module.
Provides a transparent vertical ocean grid type and supporting routines.
Provides transparent structures with groups of MOM6 variables and supporting routines.
Control structure for the Montgomery potential form of pressure gradient.
An overloaded interface to read and log the values of various types of parameters.