26 use coupler_types_mod,
only : coupler_type_set_data, ind_csurf
29 implicit none ;
private
31 #include <MOM_memory.h>
33 public register_pseudo_salt_tracer, initialize_pseudo_salt_tracer
34 public pseudo_salt_tracer_column_physics, pseudo_salt_tracer_surface_state
35 public pseudo_salt_stock, pseudo_salt_tracer_end
39 type(time_type),
pointer :: time => null()
41 real,
pointer :: ps(:,:,:) => null()
43 real,
pointer :: diff(:,:,:) => null()
45 logical :: pseudo_salt_may_reinit = .true.
47 integer :: id_psd = -1
59 function register_pseudo_salt_tracer(HI, GV, param_file, CS, tr_Reg, restart_CS)
73 character(len=40) :: mdl =
"pseudo_salt_tracer"
74 character(len=200) :: inputdir
75 character(len=48) :: var_name
76 character(len=3) :: name_tag
78 #include "version_variable.h"
79 real,
pointer :: tr_ptr(:,:,:) => null()
80 logical :: register_pseudo_salt_tracer
81 integer :: isd, ied, jsd, jed, nz, i, j
82 isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
84 if (
associated(cs))
then
85 call mom_error(warning,
"register_pseudo_salt_tracer called with an "// &
86 "associated control structure.")
94 allocate(cs%ps(isd:ied,jsd:jed,nz)) ; cs%ps(:,:,:) = 0.0
95 allocate(cs%diff(isd:ied,jsd:jed,nz)) ; cs%diff(:,:,:) = 0.0
97 cs%tr_desc = var_desc(trim(
"pseudo_salt"),
"psu", &
98 "Pseudo salt passive tracer", caller=mdl)
100 tr_ptr => cs%ps(:,:,:)
101 call query_vardesc(cs%tr_desc, name=var_name, caller=
"register_pseudo_salt_tracer")
103 call register_tracer(tr_ptr, tr_reg, param_file, hi, gv, name=
"pseudo_salt", &
104 longname=
"Pseudo salt passive tracer", units=
"psu", &
105 registry_diags=.true., restart_cs=restart_cs, &
106 mandatory=.not.cs%pseudo_salt_may_reinit)
109 cs%restart_CSp => restart_cs
110 register_pseudo_salt_tracer = .true.
112 end function register_pseudo_salt_tracer
115 subroutine initialize_pseudo_salt_tracer(restart, day, G, GV, h, diag, OBC, CS, &
117 logical,
intent(in) :: restart
119 type(time_type),
target,
intent(in) :: day
122 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
124 type(
diag_ctrl),
target,
intent(in) :: diag
136 character(len=16) :: name
137 character(len=72) :: longname
138 character(len=48) :: units
139 character(len=48) :: flux_units
142 integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
143 integer :: isdb, iedb, jsdb, jedb
145 if (.not.
associated(cs))
return
146 if (.not.
associated(cs%diff))
return
148 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
149 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
150 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
156 call query_vardesc(cs%tr_desc, name=name, caller=
"initialize_pseudo_salt_tracer")
157 if ((.not.restart) .or. (.not.
query_initialized(cs%ps, name, cs%restart_CSp)))
then
158 do k=1,nz ;
do j=jsd,jed ;
do i=isd,ied
159 cs%ps(i,j,k) = tv%S(i,j,k)
160 enddo ;
enddo ;
enddo
163 if (
associated(obc))
then
167 cs%id_psd = register_diag_field(
"ocean_model",
"pseudo_salt_diff", cs%diag%axesTL, &
168 day,
"Difference between pseudo salt passive tracer and salt tracer",
"psu")
170 end subroutine initialize_pseudo_salt_tracer
173 subroutine pseudo_salt_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS, tv, debug, &
174 evap_CFL_limit, minimum_forcing_depth)
177 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
179 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
181 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
185 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
189 type(
forcing),
intent(in) :: fluxes
191 real,
intent(in) :: dt
195 logical,
intent(in) :: debug
196 real,
optional,
intent(in) :: evap_cfl_limit
198 real,
optional,
intent(in) :: minimum_forcing_depth
208 real :: year, h_total, scale, htot, ih_limit
209 integer :: secs, days
210 integer :: i, j, k, is, ie, js, je, nz, k_max
211 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work
213 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
215 if (.not.
associated(cs))
return
216 if (.not.
associated(cs%diff))
return
219 call hchksum(tv%S,
"salt pre pseudo-salt vertdiff", g%HI)
220 call hchksum(cs%ps,
"pseudo_salt pre pseudo-salt vertdiff", g%HI)
224 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then
225 do k=1,nz ;
do j=js,je ;
do i=is,ie
226 h_work(i,j,k) = h_old(i,j,k)
227 enddo ;
enddo ;
enddo
228 call applytracerboundaryfluxesinout(g, gv, cs%ps, dt, fluxes, h_work, &
229 evap_cfl_limit, minimum_forcing_depth, out_flux_optional=fluxes%netSalt)
230 call tracer_vertdiff(h_work, ea, eb, dt, cs%ps, g, gv)
232 call tracer_vertdiff(h_old, ea, eb, dt, cs%ps, g, gv)
235 do k=1,nz ;
do j=js,je ;
do i=is,ie
236 cs%diff(i,j,k) = cs%ps(i,j,k)-tv%S(i,j,k)
237 enddo ;
enddo ;
enddo
240 call hchksum(tv%S,
"salt post pseudo-salt vertdiff", g%HI)
241 call hchksum(cs%ps,
"pseudo_salt post pseudo-salt vertdiff", g%HI)
244 if (cs%id_psd>0)
call post_data(cs%id_psd, cs%diff, cs%diag)
246 end subroutine pseudo_salt_tracer_column_physics
251 function pseudo_salt_stock(h, stocks, G, GV, CS, names, units, stock_index)
254 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
255 real,
dimension(:),
intent(out) :: stocks
259 character(len=*),
dimension(:),
intent(out) :: names
260 character(len=*),
dimension(:),
intent(out) :: units
261 integer,
optional,
intent(in) :: stock_index
263 integer :: pseudo_salt_stock
270 integer :: i, j, k, is, ie, js, je, nz
271 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
273 pseudo_salt_stock = 0
274 if (.not.
associated(cs))
return
275 if (.not.
associated(cs%diff))
return
277 if (
present(stock_index))
then ;
if (stock_index > 0)
then
284 call query_vardesc(cs%tr_desc, name=names(1), units=units(1), caller=
"pseudo_salt_stock")
285 units(1) = trim(units(1))//
" kg"
287 do k=1,nz ;
do j=js,je ;
do i=is,ie
288 stocks(1) = stocks(1) + cs%diff(i,j,k) * &
289 (g%mask2dT(i,j) * g%areaT(i,j) * h(i,j,k))
290 enddo ;
enddo ;
enddo
291 stocks(1) = gv%H_to_kg_m2 * stocks(1)
293 pseudo_salt_stock = 1
295 end function pseudo_salt_stock
300 subroutine pseudo_salt_tracer_surface_state(state, h, G, CS)
302 type(
surface),
intent(inout) :: state
304 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
312 integer :: m, is, ie, js, je, isd, ied, jsd, jed
313 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
314 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
316 if (.not.
associated(cs))
return
320 end subroutine pseudo_salt_tracer_surface_state
323 subroutine pseudo_salt_tracer_end(CS)
328 if (
associated(cs))
then
329 if (
associated(cs%ps))
deallocate(cs%ps)
330 if (
associated(cs%diff))
deallocate(cs%diff)
333 end subroutine pseudo_salt_tracer_end