12 use fckit_configuration_module,
only: fckit_configuration
19 use femps_operators_mod
20 use femps_testgrid_mod
46 type(fempsgrid) :: grid
47 type(fempsoprs) :: oprs
49 integer,
allocatable :: lev_start(:), lev_final(:)
63 type(fckit_configuration),
intent(in) :: conf
65 integer :: ngrids, niter, lprocs, lstart
66 logical :: check_convergence
67 character(len=:),
allocatable :: str
68 character(len=2055) :: path2fv3gridfiles
70 integer :: n, levs_per_proc
76 call conf%get_or_die(
"femps_iterations",niter)
77 call conf%get_or_die(
"femps_ngrids",ngrids)
78 call conf%get_or_die(
"femps_path2fv3gridfiles",str); path2fv3gridfiles = str
79 if( .not. conf%get(
'femps_levelprocs',lprocs) )
then
82 if( .not. conf%get(
'femps_checkconvergence',check_convergence) )
then
83 check_convergence = .false.
88 lprocs = min(lprocs,geom%f_comm%size())
89 lprocs = min(lprocs,geom%npz)
91 if (lprocs == -1)
then
92 self%lprocs = min(geom%npz,geom%f_comm%size())
97 if (geom%f_comm%rank() == 0 ) print*,
"Running femps with ", self%lprocs,
" processors."
99 allocate(self%lev_start(self%lprocs))
100 allocate(self%lev_final(self%lprocs))
102 if (self%lprocs == geom%npz)
then
104 self%lev_start(n) = n
105 self%lev_final(n) = n
111 self%lev_start(n) = lstart+1
112 self%lev_final(n) = self%lev_start(n) + levs_per_proc - 1
113 if (n .le. mod(geom%npz, self%lprocs)) self%lev_final(n) = self%lev_final(n) + 1
114 lstart = self%lev_final(n)
118 if (self%lev_final(self%lprocs) .ne. geom%npz) &
119 call abor1_ftn(
"fv3jedi_varcha_c2a_mod.create: last level not equal to number of levels.")
122 if (geom%f_comm%rank() < self%lprocs )
then
124 if (geom%f_comm%rank() == 0 ) print*,
'Creating FEMPS grid object'
125 call self%grid%setup(
'cs',ngrids=ngrids,cube=geom%npx-1,niter=niter,&
126 comm = geom%f_comm%communicator(), &
127 rank = geom%f_comm%rank(), &
128 csize = geom%f_comm%size(), &
129 check_convergence = check_convergence )
131 if (geom%f_comm%rank() == 0 ) print*,
'Creating FEMPS grid hierarchy from files'
132 call fv3grid_to_ugrid(self%grid,path2fv3gridfiles)
135 if (geom%f_comm%rank() == 0 ) print*,
'Creating FEMPS cubed-sphere connectivity'
136 call self%grid%build_cs(1,1)
139 if (geom%f_comm%rank() == 0 ) print*,
'Creating FEMPS static operators'
140 call preliminary(self%grid,self%oprs)
143 if (geom%f_comm%rank() == 0 ) print*,
'FEMPS partial deallocate'
144 call self%oprs%pdelete()
157 call self%oprs%delete()
158 call self%grid%delete()
160 deallocate(self%lev_start,self%lev_final)
175 character(len=field_clen),
allocatable :: fields_to_do(:)
176 real(kind=
kind_real),
pointer :: field_ptr(:,:,:)
179 logical :: have_udvd, have_vodi
180 real(kind=
kind_real),
pointer :: psi(:,:,:)
181 real(kind=
kind_real),
pointer :: chi(:,:,:)
182 real(kind=
kind_real),
allocatable :: ud(:,:,:)
183 real(kind=
kind_real),
allocatable :: vd(:,:,:)
184 real(kind=
kind_real),
allocatable :: vort(:,:,:)
185 real(kind=
kind_real),
allocatable :: divg(:,:,:)
189 real(kind=
kind_real),
pointer :: ps(:,:,:)
190 real(kind=
kind_real),
allocatable :: delp(:,:,:)
191 real(kind=
kind_real),
allocatable :: pe(:,:,:)
192 real(kind=
kind_real),
allocatable :: p(:,:,:)
193 real(kind=
kind_real),
allocatable :: pkz(:,:,:)
196 logical :: have_t, have_pt
197 real(kind=
kind_real),
pointer :: t(:,:,:)
198 real(kind=
kind_real),
allocatable :: pt(:,:,:)
202 real(kind=
kind_real),
pointer :: qi(:,:,:)
203 real(kind=
kind_real),
pointer :: ql(:,:,:)
204 real(kind=
kind_real),
pointer :: qilsf(:,:,:)
205 real(kind=
kind_real),
pointer :: qicnf(:,:,:)
206 real(kind=
kind_real),
allocatable :: qils(:,:,:)
207 real(kind=
kind_real),
allocatable :: qicn(:,:,:)
208 real(kind=
kind_real),
allocatable :: qlls(:,:,:)
209 real(kind=
kind_real),
allocatable :: qlcn(:,:,:)
213 call copy_subset(xctl%fields, xana%fields, fields_to_do)
217 if (.not.
allocated(fields_to_do))
return
223 if (xctl%has_field(
'psi') .and. xctl%has_field(
'chi'))
then
224 call xctl%get_field(
'psi', psi)
225 call xctl%get_field(
'chi', chi)
226 allocate(ud(geom%isc:geom%iec ,geom%jsc:geom%jec+1,1:geom%npz))
227 allocate(vd(geom%isc:geom%iec+1,geom%jsc:geom%jec ,1:geom%npz))
230 allocate(vort(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
231 allocate(divg(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
232 call psichi_to_vortdivg(geom, self%grid, self%oprs, psi, chi, self%lprocs, self%lev_start, &
233 self%lev_final, vort, divg)
240 if (xctl%has_field(
'ps'))
then
241 call xctl%get_field(
'ps', ps)
242 allocate(delp(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
243 allocate( pe(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz+1))
244 allocate( p(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
245 allocate( pkz(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
256 if (xctl%has_field(
't'))
then
257 call xctl%get_field(
't', t)
260 allocate(pt(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
269 if ( xctl%has_field(
'ice_wat') .and. xctl%has_field(
'liq_wat') .and. &
270 xctl%has_field(
'qilsf') .and. xctl%has_field(
'qicnf'))
then
271 call xctl%get_field(
'ice_wat', qi)
272 call xctl%get_field(
'liq_wat', ql)
273 call xctl%get_field(
'qilsf', qilsf)
274 call xctl%get_field(
'qicnf', qicnf)
275 allocate(qils(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
276 allocate(qicn(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
277 allocate(qlls(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
278 allocate(qlcn(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
279 call q2_to_q4(geom, qi, ql, qilsf, qicnf, qils, qicn, qlls, qlcn)
285 do f = 1,
size(fields_to_do)
287 call xana%get_field(trim(fields_to_do(f)), field_ptr)
289 select case (trim(fields_to_do(f)))
293 if (.not. have_udvd)
call field_fail(fields_to_do(f))
298 if (.not. have_udvd)
call field_fail(fields_to_do(f))
303 if (.not. have_vodi)
call field_fail(fields_to_do(f))
308 if (.not. have_vodi)
call field_fail(fields_to_do(f))
313 if (.not. have_pres)
call field_fail(fields_to_do(f))
318 if (.not. have_pres)
call field_fail(fields_to_do(f))
323 if (.not. have_pres)
call field_fail(fields_to_do(f))
328 if (.not. have_pres)
call field_fail(fields_to_do(f))
333 if (.not. have_pres)
call field_fail(fields_to_do(f))
338 if (.not. have_pres)
call field_fail(fields_to_do(f))
343 if (.not. have_pres)
call field_fail(fields_to_do(f))
351 xana%calendar_type = xctl%calendar_type
352 xana%date_init = xctl%date_init
367 character(len=field_clen),
allocatable :: fields_to_do(:)
368 real(kind=
kind_real),
pointer :: field_ptr(:,:,:)
372 real(kind=
kind_real),
pointer :: ud(:,:,:)
373 real(kind=
kind_real),
pointer :: vd(:,:,:)
374 real(kind=
kind_real),
allocatable :: psi(:,:,:)
375 real(kind=
kind_real),
allocatable :: chi(:,:,:)
376 real(kind=
kind_real),
allocatable :: vort(:,:,:)
377 real(kind=
kind_real),
allocatable :: divg(:,:,:)
381 real(kind=
kind_real),
allocatable :: delp(:,:,:)
382 real(kind=
kind_real),
pointer :: ps(:,:,:)
383 real(kind=
kind_real),
pointer :: pe(:,:,:)
384 real(kind=
kind_real),
allocatable :: p(:,:,:)
388 real(kind=
kind_real),
pointer :: pt(:,:,:)
389 real(kind=
kind_real),
allocatable :: pkz(:,:,:)
390 real(kind=
kind_real),
allocatable :: t(:,:,:)
394 real(kind=
kind_real),
pointer :: q(:,:,:)
395 real(kind=
kind_real),
allocatable :: qsat(:,:,:)
396 real(kind=
kind_real),
allocatable :: rh(:,:,:)
399 logical :: have_qiql, have_cfrc
400 real(kind=
kind_real),
allocatable :: qi(:,:,:)
401 real(kind=
kind_real),
allocatable :: ql(:,:,:)
402 real(kind=
kind_real),
pointer :: qils(:,:,:)
403 real(kind=
kind_real),
pointer :: qicn(:,:,:)
404 real(kind=
kind_real),
pointer :: qlls(:,:,:)
405 real(kind=
kind_real),
pointer :: qlcn(:,:,:)
406 real(kind=
kind_real),
allocatable :: qilsf(:,:,:)
407 real(kind=
kind_real),
allocatable :: qicnf(:,:,:)
411 real(kind=
kind_real),
allocatable :: tv(:,:,:)
415 call copy_subset(xana%fields, xctl%fields, fields_to_do)
419 if (.not.
allocated(fields_to_do))
return
424 if (xana%has_field(
'ud') .and. xana%has_field(
'vd'))
then
425 call xana%get_field(
'ud', ud)
426 call xana%get_field(
'vd', vd)
427 allocate( psi(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
428 allocate( chi(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
429 allocate(vort(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
430 allocate(divg(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
431 call udvd_to_psichi(geom, self%grid, self%oprs, ud, vd, psi, chi, &
432 self%lprocs, self%lev_start, self%lev_final, vort, divg)
439 if (xana%has_field(
'delp'))
then
440 call xana%get_field(
'delp', delp)
441 allocate(ps(geom%isc:geom%iec,geom%jsc:geom%jec,1))
442 ps(:,:,1) = sum(delp,3)
444 elseif (xana%has_field(
'pe'))
then
445 call xana%get_field(
'pe', pe )
446 allocate( ps(geom%isc:geom%iec,geom%jsc:geom%jec,1))
447 allocate(delp(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
449 ps(:,:,1) = pe(:,:,geom%npz+1)
456 if (xana%has_field(
't'))
then
457 call xana%get_field(
't', t)
459 elseif (xana%has_field(
'pt'))
then
460 allocate(t(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
461 call xana%get_field(
'pt', pt)
462 if (xana%has_field(
'pkz'))
then
463 call xana%get_field(
'pkz', pkz)
465 elseif (have_pres)
then
466 allocate( pkz(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
470 if (have_temp)
call pt_to_t(geom, pkz, pt, t)
476 if (xana%has_field(
'sphum') .and. have_temp .and. have_pres)
then
477 allocate(qsat(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
478 allocate( rh(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
479 call xana%get_field(
'sphum', q)
480 call get_qsat(geom, delp, t, q, qsat)
481 call q_to_rh(geom, qsat, q, rh)
489 if (xana%has_field(
'ice_wat') .and. xana%has_field(
'liq_wat'))
then
490 call xana%get_field(
'ice_wat', qi)
491 call xana%get_field(
'liq_wat', ql)
493 elseif (xana%has_field(
'qils') .and. xana%has_field(
'qicn') .and. &
494 xana%has_field(
'qlls') .and. xana%has_field(
'qlcn'))
then
495 call xana%get_field(
'qils', qils)
496 call xana%get_field(
'qicn', qicn)
497 call xana%get_field(
'qlls', qlls)
498 call xana%get_field(
'qlcn', qlcn)
499 allocate(qi(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
500 allocate(ql(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
501 allocate(qilsf(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
502 allocate(qicnf(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
503 call q4_to_q2(geom, qils, qicn, qlls, qlcn, qi, ql, qilsf, qicnf)
511 if (have_temp .and. xana%has_field(
'sphum'))
then
512 allocate(tv(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
513 call xana%get_field(
'sphum', q)
520 do f = 1,
size(fields_to_do)
522 call xctl%get_field(trim(fields_to_do(f)), field_ptr)
524 select case (trim(fields_to_do(f)))
528 if (.not. have_pcvd)
call field_fail(fields_to_do(f))
533 if (.not. have_pcvd)
call field_fail(fields_to_do(f))
538 if (.not. have_pcvd)
call field_fail(fields_to_do(f))
543 if (.not. have_pcvd)
call field_fail(fields_to_do(f))
548 if (.not. have_pres)
call field_fail(fields_to_do(f))
553 if (.not. have_pres)
call field_fail(fields_to_do(f))
558 if (.not. have_temp)
call field_fail(fields_to_do(f))
563 if (.not. have_virt)
call field_fail(fields_to_do(f))
568 if (.not. have_rhum)
call field_fail(fields_to_do(f))
573 if (.not. have_qiql)
call field_fail(fields_to_do(f))
578 if (.not. have_qiql)
call field_fail(fields_to_do(f))
583 if (.not. have_cfrc)
call field_fail(fields_to_do(f))
588 if (.not. have_cfrc)
call field_fail(fields_to_do(f))
596 xctl%calendar_type = xana%calendar_type
597 xctl%date_init = xana%date_init