34 implicit none ;
private
36 #include <MOM_memory.h>
39 public register_rgc_tracer, initialize_rgc_tracer
40 public rgc_tracer_column_physics, rgc_tracer_end
42 integer,
parameter :: ntr = 1
46 logical :: coupled_tracers = .false.
47 character(len = 200) :: tracer_ic_file
48 type(time_type),
pointer :: time
50 real,
pointer :: tr(:,:,:,:) => null()
51 real,
pointer :: tr_aux(:,:,:,:) => null()
52 real :: land_val(ntr) = -1.0
57 logical :: mask_tracers
67 function register_rgc_tracer(HI, GV, param_file, CS, tr_Reg, restart_CS)
77 character(len=80) :: name, longname
79 #include "version_variable.h"
80 character(len=40) :: mdl =
"RGC_tracer"
81 character(len=200) :: inputdir
82 real,
pointer :: tr_ptr(:,:,:) => null()
83 logical :: register_rgc_tracer
84 integer :: isd, ied, jsd, jed, nz, m
85 isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
87 if (
associated(cs))
then
88 call mom_error(warning,
"RGC_register_tracer called with an "// &
89 "associated control structure.")
96 call get_param(param_file, mdl,
"RGC_TRACER_IC_FILE", cs%tracer_IC_file, &
97 "The name of a file from which to read the initial \n"//&
98 "conditions for the RGC tracers, or blank to initialize \n"//&
99 "them internally.", default=
" ")
100 if (len_trim(cs%tracer_IC_file) >= 1)
then
101 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
102 inputdir = slasher(inputdir)
103 cs%tracer_IC_file = trim(inputdir)//trim(cs%tracer_IC_file)
104 call log_param(param_file, mdl,
"INPUTDIR/RGC_TRACER_IC_FILE", &
107 call get_param(param_file, mdl,
"SPONGE", cs%use_sponge, &
108 "If true, sponges may be applied anywhere in the domain. \n"//&
109 "The exact location and properties of those sponges are \n"//&
110 "specified from MOM_initialization.F90.", default=.false.)
112 call get_param(param_file, mdl,
"LENLAT", cs%lenlat, &
113 "The latitudinal or y-direction length of the domain", &
114 fail_if_missing=.true., do_not_log=.true.)
116 call get_param(param_file, mdl,
"LENLON", cs%lenlon, &
117 "The longitudinal or x-direction length of the domain", &
118 fail_if_missing=.true., do_not_log=.true.)
120 call get_param(param_file, mdl,
"CONT_SHELF_LENGTH", cs%CSL, &
121 "The length of the continental shelf (x dir, km).", &
124 call get_param(param_file, mdl,
"LENSPONGE", cs%lensponge, &
125 "The length of the sponge layer (km).", &
128 allocate(cs%tr(isd:ied,jsd:jed,nz,ntr)) ; cs%tr(:,:,:,:) = 0.0
129 if (cs%mask_tracers)
then
130 allocate(cs%tr_aux(isd:ied,jsd:jed,nz,ntr)) ; cs%tr_aux(:,:,:,:) = 0.0
134 if (m < 10)
then ;
write(name,
'("tr_RGC",I1.1)') m
135 else ;
write(name,
'("tr_RGC",I2.2)') m ;
endif
136 write(longname,
'("Concentration of RGC Tracer ",I2.2)') m
137 cs%tr_desc(m) = var_desc(name, units=
"kg kg-1", longname=longname, caller=mdl)
140 tr_ptr => cs%tr(:,:,:,m)
142 call register_tracer(tr_ptr, tr_reg, param_file, hi, gv, &
143 name=name, longname=longname, units=
"kg kg-1", &
144 registry_diags=.true., flux_units=
"kg/s", &
145 restart_cs=restart_cs)
149 register_rgc_tracer = .true.
150 end function register_rgc_tracer
154 subroutine initialize_rgc_tracer(restart, day, G, GV, h, diag, OBC, CS, &
155 layer_CSp, sponge_CSp)
159 logical,
intent(in) :: restart
161 type(time_type),
target,
intent(in) :: day
162 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
164 type(
diag_ctrl),
target,
intent(in) :: diag
174 real,
allocatable :: temp(:,:,:)
175 real,
pointer,
dimension(:,:,:) :: &
176 obc_tr1_u => null(), &
180 character(len=16) :: name
181 character(len=72) :: longname
182 character(len=48) :: units
183 character(len=48) :: flux_units
185 real,
pointer :: tr_ptr(:,:,:) => null()
188 real :: e(szk_(g)+1), e_top, e_bot, d_tr
189 integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m
190 integer :: isdb, iedb, jsdb, jedb
193 if (.not.
associated(cs))
return
194 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
195 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
196 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
197 h_neglect = gv%H_subroundoff
202 if (.not.restart)
then
203 if (len_trim(cs%tracer_IC_file) >= 1)
then
205 if (.not.
file_exists(cs%tracer_IC_file, g%Domain)) &
206 call mom_error(fatal,
"RGC_initialize_tracer: Unable to open "// &
209 call query_vardesc(cs%tr_desc(m), name, caller=
"initialize_RGC_tracer")
210 call mom_read_data(cs%tracer_IC_file, trim(name), cs%tr(:,:,:,m), g%Domain)
214 do k=1,nz ;
do j=js,je ;
do i=is,ie
216 enddo ;
enddo ;
enddo
219 do j=js,je ;
do i=is,ie
221 if (g%geoLonT(i,j) <= (cs%CSL))
then
229 if ( cs%use_sponge )
then
233 if (
associated(sponge_csp))
then
234 nzdata = get_ale_sponge_nz_data(sponge_csp)
236 allocate(temp(g%isd:g%ied,g%jsd:g%jed,nzdata))
237 do k=1,nzdata ;
do j=js,je ;
do i=is,ie
238 if (g%geoLonT(i,j) >= (cs%lenlon - cs%lensponge) .AND. g%geoLonT(i,j) <= cs%lenlon)
then
244 tr_ptr => cs%tr(:,:,:,m)
250 elseif (
associated(layer_csp))
then
252 allocate(temp(g%isd:g%ied,g%jsd:g%jed,nz))
253 do k=1,nz ;
do j=js,je ;
do i=is,ie
254 if (g%geoLonT(i,j) >= (cs%lenlon - cs%lensponge) .AND. g%geoLonT(i,j) <= cs%lenlon)
then
259 tr_ptr => cs%tr(:,:,:,m)
260 call set_up_sponge_field(temp, tr_ptr, g, nz, layer_csp)
265 call mom_error(fatal,
"RGC_initialize_tracer: "// &
266 "The pointer to sponge_CSp must be associated if SPONGE is defined.")
270 end subroutine initialize_rgc_tracer
275 subroutine rgc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, US, CS, &
276 evap_CFL_limit, minimum_forcing_depth)
279 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
281 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
283 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
287 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
291 type(
forcing),
intent(in) :: fluxes
293 real,
intent(in) :: dt
296 real,
optional,
intent(in) :: evap_cfl_limit
298 real,
optional,
intent(in) :: minimum_forcing_depth
305 real :: c1(szi_(g),szk_(g))
306 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work
307 real :: in_flux(szi_(g),szj_(g),2)
309 integer :: i, j, k, is, ie, js, je, nz, m
310 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
312 if (.not.
associated(cs))
return
316 do j=js,je ;
do i=is,ie
318 if (g%geoLonT(i,j) <= (cs%CSL))
then
323 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then
325 do k=1,nz ;
do j=js,je ;
do i=is,ie
326 h_work(i,j,k) = h_old(i,j,k)
327 enddo ;
enddo ; enddo;
328 call applytracerboundaryfluxesinout(g, gv, cs%tr(:,:,:,m) , dt, fluxes, h_work, &
329 evap_cfl_limit, minimum_forcing_depth, in_flux(:,:,m))
331 call tracer_vertdiff(h_work, ea, eb, dt, cs%tr(:,:,:,m), g, gv)
335 call tracer_vertdiff(h_old, ea, eb, dt, cs%tr(:,:,:,m), g, gv)
339 end subroutine rgc_tracer_column_physics
341 subroutine rgc_tracer_end(CS)
345 if (
associated(cs))
then
346 if (
associated(cs%tr))
deallocate(cs%tr)
349 end subroutine rgc_tracer_end