60 logical :: tracer_z_init
62 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(out) :: tr
63 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
64 character(len=*),
intent(in) :: filename, tr_name
66 real,
optional,
intent(in) :: missing_val
67 real,
optional,
intent(in) :: land_val
79 integer,
save :: init_calls = 0
81 #include "version_variable.h" 82 character(len=40) :: mdl =
"MOM_tracer_Z_init" 83 character(len=256) :: mesg
85 real,
allocatable,
dimension(:,:,:) :: &
87 real,
allocatable,
dimension(:) :: &
101 real :: htot(szi_(g))
106 logical :: has_edges, use_missing, zero_surface
107 character(len=80) :: loc_msg
108 integer :: k_top, k_bot, k_bot_prev
109 integer :: i, j, k, kz, is, ie, js, je, nz, nz_in
110 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
112 landval = 0.0 ;
if (
present(land_val)) landval = land_val
114 zero_surface = .false.
116 use_missing = .false.
117 if (
present(missing_val))
then 118 use_missing = .true. ; missing = missing_val
123 call read_z_edges(filename, tr_name, z_edges, nz_in, has_edges, use_missing, missing)
125 tracer_z_init = .false.
129 allocate(tr_in(g%isd:g%ied,g%jsd:g%jed,nz_in)) ; tr_in(:,:,:) = 0.0
130 allocate(tr_1d(nz_in)) ; tr_1d(:) = 0.0
131 call read_data(filename, tr_name, tr_in(:,:,:), domain=g%Domain%mpp_domain)
135 if (
present(missing_val))
then 136 do j=js,je ;
do i=is,ie
137 if (g%mask2dT(i,j) == 0.0)
then 138 tr_in(i,j,1) = landval
139 elseif (abs(tr_in(i,j,1) - missing_val) <= 1e-6*abs(missing_val))
then 140 write(loc_msg,
'(f7.2," N ",f7.2," E")') g%geoLatT(i,j), g%geoLonT(i,j)
141 if (zero_surface)
then 142 call mom_error(warning,
"tracer_Z_init: Missing value of "// &
143 trim(tr_name)//
" found in an ocean point at "//trim(loc_msg)// &
144 " in "//trim(filename) )
147 call mom_error(fatal,
"tracer_Z_init: Missing value of "// &
148 trim(tr_name)//
" found in an ocean point at "//trim(loc_msg)// &
149 " in "//trim(filename) )
153 do k=2,nz_in ;
do j=js,je ;
do i=is,ie
154 if (abs(tr_in(i,j,k) - missing_val) <= 1e-6*abs(missing_val)) &
155 tr_in(i,j,k) = tr_in(i,j,k-1)
156 enddo ;
enddo ;
enddo 159 allocate(wt(nz_in+1)) ;
allocate(z1(nz_in+1)) ;
allocate(z2(nz_in+1))
165 do i=is,ie ; htot(i) = 0.0 ;
enddo 166 do k=1,nz ;
do i=is,ie ; htot(i) = htot(i) + h(i,j,k) ;
enddo ;
enddo 168 do i=is,ie ;
if (g%mask2dT(i,j)*htot(i) > 0.0)
then 170 dilate = (g%bathyT(i,j) - 0.0) / htot(i)
171 e(nz+1) = -g%bathyT(i,j)
172 do k=nz,1,-1 ; e(k) = e(k+1) + dilate * h(i,j,k) ;
enddo 175 do k=1,nz_in ; tr_1d(k) = tr_in(i,j,k) ;
enddo 176 k_bot = 1 ; k_bot_prev = -1
178 if (e(k+1) > z_edges(1))
then 180 elseif (e(k) < z_edges(nz_in+1))
then 181 tr(i,j,k) = tr_1d(nz_in)
183 call find_overlap(z_edges, e(k), e(k+1), nz_in, &
184 k_bot, k_top, k_bot, wt, z1, z2)
186 if (kz /= k_bot_prev)
then 189 if ((kz < nz_in) .and. (kz > 1))
call &
190 find_limited_slope(tr_1d, z_edges, sl_tr, kz)
193 tr(i,j,k) = wt(kz) * &
194 (tr_1d(kz) + 0.5*sl_tr*(z2(kz) + z1(kz)))
197 do kz=k_top+1,k_bot-1
198 tr(i,j,k) = tr(i,j,k) + wt(kz)*tr_1d(kz)
200 if (k_bot > k_top)
then 204 if ((kz < nz_in) .and. (kz > 1))
call &
205 find_limited_slope(tr_1d, z_edges, sl_tr, kz)
207 tr(i,j,k) = tr(i,j,k) + wt(kz) * &
208 (tr_1d(kz) + 0.5*sl_tr*(z2(kz) + z1(kz)))
217 if ((e(k) > z_edges(1)) .and. (z_edges(nz_in+1) > e(k+1)))
then 218 tr(i,j,k) = (((e(k) - z_edges(1)) * tr_1d(1) + &
219 (z_edges(1) - z_edges(nz_in)) * tr(i,j,k)) + &
220 (z_edges(nz_in+1) - e(k+1)) * tr_1d(nz_in)) / &
222 elseif (e(k) > z_edges(1))
then 223 tr(i,j,k) = ((e(k) - z_edges(1)) * tr_1d(1) + &
224 (z_edges(1) - e(k+1)) * tr(i,j,k)) / &
226 elseif (z_edges(nz_in) > e(k+1))
then 227 tr(i,j,k) = ((e(k) - z_edges(nz_in+1)) * tr(i,j,k) + &
228 (z_edges(nz_in+1) - e(k+1)) * tr_1d(nz_in)) / &
234 do k=1,nz ; tr(i,j,k) = landval ;
enddo 240 do i=is,ie ; htot(i) = 0.0 ;
enddo 241 do k=1,nz ;
do i=is,ie ; htot(i) = htot(i) + h(i,j,k) ;
enddo ;
enddo 243 do i=is,ie ;
if (g%mask2dT(i,j)*htot(i) > 0.0)
then 245 dilate = (g%bathyT(i,j) - 0.0) / htot(i)
246 e(nz+1) = -g%bathyT(i,j)
247 do k=nz,1,-1 ; e(k) = e(k+1) + dilate * h(i,j,k) ;
enddo 250 do k=1,nz_in ; tr_1d(k) = tr_in(i,j,k) ;
enddo 253 if (e(k+1) > z_edges(1))
then 255 elseif (z_edges(nz_in) > e(k))
then 256 tr(i,j,k) = tr_1d(nz_in)
258 call find_overlap(z_edges, e(k), e(k+1), nz_in-1, &
259 k_bot, k_top, k_bot, wt, z1, z2)
262 if (k_top < nz_in)
then 263 tr(i,j,k) = wt(kz)*0.5*((tr_1d(kz) + tr_1d(kz+1)) + &
264 (tr_1d(kz+1) - tr_1d(kz))*(z2(kz)+z1(kz)))
266 tr(i,j,k) = wt(kz)*tr_1d(nz_in)
268 do kz=k_top+1,k_bot-1
269 tr(i,j,k) = tr(i,j,k) + wt(kz)*0.5*(tr_1d(kz) + tr_1d(kz+1))
271 if (k_bot > k_top)
then 273 tr(i,j,k) = tr(i,j,k) + wt(kz)*0.5*((tr_1d(kz) + tr_1d(kz+1)) + &
274 (tr_1d(kz+1) - tr_1d(kz))*(z2(kz)+z1(kz)))
279 if ((e(k) > z_edges(1)) .and. (z_edges(nz_in) > e(k+1)))
then 280 tr(i,j,k) = (((e(k) - z_edges(1)) * tr_1d(1) + &
281 (z_edges(1) - z_edges(nz_in)) * tr(i,j,k)) + &
282 (z_edges(nz_in) - e(k+1)) * tr_1d(nz_in)) / &
284 elseif (e(k) > z_edges(1))
then 285 tr(i,j,k) = ((e(k) - z_edges(1)) * tr_1d(1) + &
286 (z_edges(1) - e(k+1)) * tr(i,j,k)) / &
288 elseif (z_edges(nz_in) > e(k+1))
then 289 tr(i,j,k) = ((e(k) - z_edges(nz_in)) * tr(i,j,k) + &
290 (z_edges(nz_in) - e(k+1)) * tr_1d(nz_in)) / &
296 do k=1,nz ; tr(i,j,k) = landval ;
enddo 301 deallocate(tr_in) ;
deallocate(tr_1d) ;
deallocate(z_edges)
302 deallocate(wt) ;
deallocate(z1) ;
deallocate(z2)
304 tracer_z_init = .true.
Ocean grid type. See mom_grid for details.