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