9 use fckit_configuration_module,
only: fckit_configuration
12 use constants_mod,
only: grav
13 use field_manager_mod,
only: model_atmos
14 use mpp_domains_mod,
only: mpp_update_domains
15 use tracer_manager_mod,
only: get_number_tracers, get_tracer_names, get_tracer_index, no_tracer, &
19 use external_ic_mod,
only: remap_scalar, remap_dwinds, source
20 use fv_arrays_mod,
only: fv_atmos_type, deallocate_fv_atmos_type, r_grid
21 use fv_grid_utils_mod,
only: mid_pt_sphere, get_unit_vect2, get_latlon_vector, inner_prod
22 use test_cases_mod,
only: checker_tracers
38 type(fv_atmos_type),
allocatable ::
atm(:)
39 logical,
allocatable :: grids_on_this_pe(:)
40 logical :: from_cold_start, checker_tr
58 type(fckit_configuration),
intent(in) :: conf
60 integer :: gtile, p_split = 1, n
61 logical :: checks_passed
62 character(len=:),
allocatable :: str
65 call fv_init(self%Atm, 300.0_kind_real, self%grids_on_this_pe, p_split, gtile)
68 if( .not. conf%get(
'input is cold starts', self%from_cold_start) ) self%from_cold_start = .true.
71 if( .not. conf%get(
'check tracers', self%checker_tr) ) self%checker_tr = .false.
72 if( .not. conf%get(
'check tracers nt', self%nt_checker) ) self%nt_checker = 0
75 if (.not. conf%get(
"source of inputs", str))
then
76 str =
'FV3GFS GAUSSIAN NETCDF FILE'
81 self%Atm(1)%flagstruct%nggps_ic = .true.
84 self%Atm(1)%ak = real(geom%ak,
kind_fv3)
85 self%Atm(1)%bk = real(geom%bk,
kind_fv3)
86 self%Atm%ptop = real(geom%ak(1),
kind_fv3)
89 checks_passed = .true.
90 if (checks_passed) checks_passed = geom%npx == self%Atm(1)%npx
91 if (checks_passed) checks_passed = geom%npy == self%Atm(1)%npy
92 if (checks_passed) checks_passed = geom%npz == self%Atm(1)%npz
93 if (checks_passed) checks_passed = geom%isd == self%Atm(1)%bd%isd
94 if (checks_passed) checks_passed = geom%ied == self%Atm(1)%bd%ied
95 if (checks_passed) checks_passed = geom%jsd == self%Atm(1)%bd%jsd
96 if (checks_passed) checks_passed = geom%jed == self%Atm(1)%bd%jed
97 if (.not.checks_passed)
call abor1_ftn(
"fv3jedi_vc_vertremap_mod.field_fail: Geometry generated"// &
98 " here does not match fv3-jedi geometry.")
100 if (.not.
size(self%Atm)==1)
call abor1_ftn(
"fv3jedi_vc_vertremap_mod.field_fail: Atm strucutre"// &
101 " with size > 1 not supported.")
113 do n = 1,
size(self%Atm)
114 call deallocate_fv_atmos_type(self%Atm(n))
117 deallocate(self%grids_on_this_pe)
131 character(len=field_clen),
allocatable :: fields_to_do(:)
135 real(kind=
kind_real),
allocatable :: orog_filt(:,:,:)
136 real(kind=
kind_real),
allocatable :: ps_cold(:,:,:)
137 real(kind=
kind_real),
allocatable :: zh_cold(:,:,:)
138 real(kind=
kind_real),
allocatable :: w_cold(:,:,:)
139 real(kind=
kind_real),
allocatable :: t_cold(:,:,:)
140 real(kind=
kind_real),
allocatable :: q_tmp(:,:,:)
141 real(kind=
kind_real),
allocatable :: ud_cold(:,:,:)
142 real(kind=
kind_real),
allocatable :: vd_cold(:,:,:)
144 logical :: have_remapped
145 type(fv_atmos_type),
pointer :: Atm
146 integer:: i, j, k, nt, ntracers, ntprog, itoa, levp, isc, iec, jsc, jec, npz, nts
147 integer:: liq_wat, ice_wat, rainwat, snowwat, graupel, ntclamt
148 character(len=64) :: tracer_name
149 real(kind=
kind_fv3),
allocatable :: ak(:), bk(:)
150 real(kind=
kind_fv3),
allocatable :: q_cold(:,:,:,:)
151 real(kind=
kind_fv3) :: wt, qt, m_fac
154 character(len=field_clen) :: ps_fname
155 character(len=field_clen) :: zh_fname
156 character(len=field_clen) :: w_fname
157 character(len=field_clen) :: t_fname
158 character(len=field_clen) :: ud_fname
159 character(len=field_clen) :: vd_fname
164 call copy_subset(xin%fields, xout%fields, fields_to_do)
169 if (.not.
allocated(fields_to_do))
return
180 if (self%from_cold_start)
then
181 ps_fname = trim(ps_fname)//
'_cold'
182 zh_fname = trim(zh_fname)//
'_cold'
183 w_fname = trim(w_fname)//
'_cold'
184 t_fname = trim(t_fname)//
'_cold'
185 ud_fname = trim(ud_fname)//
'_cold'
186 vd_fname = trim(vd_fname)//
'_cold'
192 have_remapped = .false.
193 if ( xin%has_field(ps_fname) .and. xin%has_field(zh_fname) .and. &
194 xin%has_field(w_fname) .and. &
195 xin%has_field(
'orog_filt') .and. &
196 xin%has_field(ud_fname) .and. xin%has_field(vd_fname) )
then
207 call xin%get_field(
'orog_filt', orog_filt)
208 atm%phis(isc:iec,jsc:jec) = real(orog_filt(isc:iec,jsc:jec,1),
kind_fv3)*grav
211 call xin%get_field(ps_fname, ps_cold)
212 call xin%get_field(zh_fname, zh_cold)
213 call xin%get_field( w_fname, w_cold)
216 levp =
size(w_cold,3)
217 itoa = levp - npz + 1
223 ak(itoa:levp+1) =
atm%ak(1:npz+1)
224 bk(itoa:levp+1) =
atm%bk(1:npz+1)
225 ak(1) = max(1.e-9_kind_fv3, ak(1))
230 call get_number_tracers(model_atmos, num_tracers=ntracers, num_prog=ntprog)
231 call get_number_tracers(model_atmos, num_tracers=ntracers, num_prog=ntprog)
235 call get_tracer_names(model_atmos, nt, tracer_name)
237 call set_tracer_profile (model_atmos, nt,
atm%q(:,:,:,nt) )
239 do nt = ntprog+1, ntracers
240 call get_tracer_names(model_atmos, nt, tracer_name)
242 call set_tracer_profile (model_atmos, nt,
atm%qdiag(:,:,:,nt) )
246 allocate (q_cold(isc:iec, jsc:jec, levp, ntracers))
247 q_cold = 0.0_kind_fv3
249 call get_tracer_names(model_atmos, nt, tracer_name)
250 if (self%from_cold_start) tracer_name = trim(tracer_name)//
"_cold"
251 if (xin%has_field(trim(tracer_name)))
then
252 call xin%get_field(trim(tracer_name), q_tmp)
253 q_cold(:,:,:,nt) = real(q_tmp,
kind_fv3)
259 if (xin%has_field(t_fname))
then
260 call xin%get_field( t_fname, t_cold)
261 call remap_scalar(
atm, levp, npz, ntracers, ak, bk, real(ps_cold(:,:,1),
kind_fv3), q_cold, &
262 real(zh_cold,kind_fv3),
real(w_cold,kind_fv3),
real(t_cold,kind_fv3))
264 call remap_scalar(
atm, levp, npz, ntracers, ak, bk, real(ps_cold(:,:,1),kind_fv3), q_cold, &
265 real(zh_cold,kind_fv3),
real(w_cold,kind_fv3))
270 call xin%get_field(ud_fname, ud_cold)
271 call xin%get_field(vd_fname, vd_cold)
273 call remap_dwinds(levp, npz, ak, bk, real(ps_cold(:,:,1),kind_fv3), real(ud_cold,kind_fv3), &
274 real(vd_cold,kind_fv3), Atm)
278 liq_wat = get_tracer_index(model_atmos,
'liq_wat')
279 ice_wat = get_tracer_index(model_atmos,
'ice_wat')
280 rainwat = get_tracer_index(model_atmos,
'rainwat')
281 snowwat = get_tracer_index(model_atmos,
'snowwat')
282 graupel = get_tracer_index(model_atmos,
'graupel')
283 ntclamt = get_tracer_index(model_atmos,
'cld_amt')
285 if (self%from_cold_start)
then
290 if (
atm%flagstruct%nwat == 6 )
then
291 qt = wt*(1.0_kind_fv3 +
atm%q(i,j,k,liq_wat) +
atm%q(i,j,k,ice_wat) + &
292 atm%q(i,j,k,rainwat) +
atm%q(i,j,k,snowwat) + &
293 atm%q(i,j,k,graupel))
295 qt = wt*(1.0_kind_fv3 + sum(
atm%q(i,j,k,2:
atm%flagstruct%nwat)))
298 if (ntclamt > 0)
atm%q(i,j,k,ntclamt) = 0.0
308 if (
atm%flagstruct%nwat == 6 )
then
309 qt = wt*(1.0_kind_fv3 +
atm%q(i,j,k,liq_wat) +
atm%q(i,j,k,ice_wat) + &
310 atm%q(i,j,k,rainwat) +
atm%q(i,j,k,snowwat) + &
311 atm%q(i,j,k,graupel))
313 qt = wt*(1.0_kind_fv3 + sum(
atm%q(i,j,k,2:
atm%flagstruct%nwat)))
317 atm%q(i,j,k,nt) = m_fac *
atm%q(i,j,k,nt)
320 if (ntclamt > 0)
atm%q(i,j,k,ntclamt) = 0.0
326 if (self%checker_tr)
then
327 nts = ntracers - self%nt_checker+1
328 call checker_tracers(isc, iec, jsc, jec,
atm%bd%isd,
atm%bd%ied,
atm%bd%jsd,
atm%bd%jed, &
329 self%nt_checker, npz,
atm%q(:,:,:,nts:ntracers), &
330 atm%gridstruct%agrid_64(isc:iec,jsc:jec,1), &
331 atm%gridstruct%agrid_64(isc:iec,jsc:jec,2), &
332 real(9.0_kind_real,kind_fv3),
real(9.0_kind_real,kind_fv3))
335 have_remapped = .true.
342 do f = 1,
size(fields_to_do)
345 if (.not. have_remapped)
call field_fail(fields_to_do(f))
347 call xout%get_field(trim(fields_to_do(f)), field_ptr)
349 select case (trim(fields_to_do(f)))
353 field_ptr%array(isc:iec,jsc:jec+1,:) =
atm%u(isc:iec,jsc:jec+1,:)
357 field_ptr%array(isc:iec+1,jsc:jec,:) =
atm%v(isc:iec+1,jsc:jec,:)
361 field_ptr%array(isc:iec,jsc:jec,:) =
atm%pt(isc:iec,jsc:jec,:)
365 field_ptr%array(isc:iec,jsc:jec,:) =
atm%delp(isc:iec,jsc:jec,:)
369 field_ptr%array(isc:iec,jsc:jec,1) =
atm%ps(isc:iec,jsc:jec)
373 field_ptr%array(isc:iec,jsc:jec,:) =
atm%delz(isc:iec,jsc:jec,:)
377 field_ptr%array(isc:iec,jsc:jec,:) =
atm%w(isc:iec,jsc:jec,:)
381 field_ptr%array(isc:iec,jsc:jec,1) =
atm%phis(isc:iec,jsc:jec)
383 case (
'sphum',
'liq_wat',
'ice_wat',
'o3mr',
'graupel',
'snowwat',
'rainwat')
385 nt = get_tracer_index(model_atmos, trim(fields_to_do(f)))
386 if (nt == no_tracer)
call field_fail(fields_to_do(f))
387 field_ptr%array(isc:iec,jsc:jec,:) =
atm%q(isc:iec,jsc:jec,:,nt)
389 case (
'sgs_tke',
'cld_amt')
391 field_ptr%array = 0.0_kind_real
395 call abor1_ftn(
"fv3jedi_vc_coldstartwinds_mod.changevar unknown field: "//trim(fields_to_do(f))&
396 //
". Not in input field and no transform case specified.")
405 xout%calendar_type = xin%calendar_type
406 xout%date_init = xin%date_init