7 #include "MAPL_Generic.h"
8 #include "unused_dummy.H"
17 use fckit_configuration_module,
only: fckit_configuration
24 use fckit_mpi_module,
only: fckit_mpi_comm
28 use mapl_capmod,
only: mapl_cap
29 use mapl_applicationsupport
32 use mapl_profiler,
only: get_global_time_profiler, baseprofiler, timeprofiler
33 use geos_gcmgridcompmod,
only: geos_gcm => setservices
50 integer :: geossubsteps
51 type(fckit_mpi_comm) :: f_comm
52 integer :: isc, iec, jsc, jec, npz
53 type(esmf_time) :: start_time
54 logical :: saved_state
61 type(esmf_field) :: field(1)
62 character(len=ESMF_MAXSTR) :: short_name, long_name, units
74 type(fckit_configuration),
intent(in) :: conf
77 type(mapl_capoptions) :: cap_options
78 type(mapl_communicators) :: mapl_comm
80 integer :: rc, subcommunicator
82 type(duration) :: dtstep
83 integer :: geos_dt, jedi_dt
84 character(len=20) :: ststep
85 character(len=:),
allocatable :: str
86 logical :: esmf_logging
87 type(esmf_logkind_flag) :: esmf_logkind
96 self%f_comm = geom%f_comm
100 cap_options = mapl_capoptions(cap_rc_file=
'CAP.rc')
101 cap_options%use_comm_world = .false.
102 cap_options%comm = geom%f_comm%communicator()
103 cap_options%npes_model = geom%f_comm%size()
107 self%Cap = mapl_cap( name=
'GCM', set_services=geos_gcm, cap_options = cap_options)
111 call self%cap%initialize_mpi()
115 mapl_comm%mapl%comm = geom%f_comm%communicator()
116 mapl_comm%global%comm = geom%f_comm%communicator()
117 mapl_comm%esmf%comm = geom%f_comm%communicator()
118 mapl_comm%io%comm = mpi_comm_null
127 subcommunicator = self%cap%create_member_subcommunicator(self%cap%get_comm_world(), rc=rc)
128 call self%cap%initialize_io_clients_servers(subcommunicator, rc = rc)
130 if (conf%has(
'ESMF_Logging'))
call conf%get_or_die(
'ESMF_Logging',esmf_logging)
133 if (esmf_logging)
then
134 esmf_logkind = esmf_logkind_multi
136 esmf_logkind = esmf_logkind_none
138 call esmf_initialize (vm=vm, logkindflag=esmf_logkind, mpicommunicator=mapl_comm%esmf%comm, rc=rc)
142 call self%cap%initialize_cap_gc(mapl_comm)
146 call self%cap%cap_gc%set_services(rc = rc);
147 if (rc.ne.0)
call abor1_ftn(
"geos_mod: set_services failed")
151 call self%cap%cap_gc%initialize(rc = rc);
152 if (rc.ne.0)
call abor1_ftn(
"geos_mod: initialize failed")
160 call conf%get_or_die(
"tstep",str)
163 dtstep = trim(ststep)
164 jedi_dt = int(duration_seconds(dtstep))
166 geos_dt = self%cap%cap_gc%get_heartbeat_dt(rc = rc)
167 if (rc.ne.0)
call abor1_ftn(
"geos_mod: error retrieving heartbeat")
169 if (jedi_dt < geos_dt)
then
170 call abor1_ftn(
"geos_mod: JEDI model time step should not be less than GEOS time step")
171 elseif (mod(jedi_dt,geos_dt) .ne. 0)
then
172 call abor1_ftn(
"geos_mod: JEDI time step needs to be divisible by GEOS time step")
175 self%GEOSsubsteps = jedi_dt/geos_dt
177 if (geom%f_comm%rank() == 0)
then
178 print*,
"There are ", int(self%GEOSsubsteps,2),
" time steps of GEOS for each time step of JEDI"
181 self%start_time = self%cap%cap_gc%get_current_time(rc=rc)
182 self%saved_state = .false.
183 if (conf%has(
'reforecast'))
call conf%get_or_die(
'reforecast',self%reforecast)
198 call self%cap%cap_gc%destroy_state(rc = rc)
199 call self%cap%cap_gc%finalize(rc = rc);
200 if (rc.ne.0)
call abor1_ftn(
"geos_mod: finalize failed")
201 call self%cap%finalize_io_clients_servers()
202 call mapl_finalize(comm=self%f_comm%communicator())
206 call esmf_finalize(endflag=esmf_end_keepmpi,rc=rc)
220 if (self%saved_state)
then
221 call self%cap%rewind_model(self%start_time,rc=rc)
222 call self%cap%cap_gc%refresh_state(rc=rc)
225 if (self%reforecast .and. (.not.self%saved_state) )
then
226 call self%cap%cap_gc%record_state(rc=rc)
227 self%saved_state = .true.
241 type(datetime),
intent(in) :: vdate
249 do n = 1,self%GEOSsubsteps
251 call self%cap%step_model(rc = rc)
252 if (rc.ne.0)
call abor1_ftn(
"geos_mod: step_model failed")
296 integer :: num_items, i, rc, rank, lb(3), ub(3), fnpz
297 type(esmf_field) :: field
298 character(len=ESMF_MAXSTR),
allocatable :: item_names(:)
299 real(kind=esmf_kind_r4),
pointer :: farrayptr2(:,:)
300 real(kind=esmf_kind_r4),
pointer :: farrayptr3(:,:,:)
301 character(len=field_clen) :: fv3jedi_name
303 real(kind=
kind_real),
allocatable,
dimension(:,:,:) :: field_geos
308 allocate(field_geos(self%isc:self%iec, self%jsc:self%jec, self%npz+1))
313 call esmf_stateget(self%cap%cap_gc%export_state, itemcount = num_items, rc = rc)
314 if (rc.ne.0)
call abor1_ftn(
"geos_to_state: ESMF_StateGet itemcount failed")
319 allocate(item_names(num_items))
320 call esmf_stateget(self%cap%cap_gc%export_state, itemnamelist = item_names, rc = rc)
321 if (rc.ne.0)
call abor1_ftn(
"geos_to_state: ESMF_StateGet itemnamelist failed")
330 select case (trim(item_names(i)))
350 fv3jedi_name =
'delp'
356 fv3jedi_name =
'delz'
362 fv3jedi_name =
'phis'
364 fv3jedi_name =
'ice_wat'
366 fv3jedi_name =
'liq_wat'
368 fv3jedi_name =
'varflt'
372 fv3jedi_name =
'sphum'
374 fv3jedi_name =
"qicn"
376 fv3jedi_name =
"qlcn"
378 fv3jedi_name =
"qils"
380 fv3jedi_name =
"qlls"
390 fv3jedi_name =
'cfcn'
392 fv3jedi_name =
'kcbl'
402 fv3jedi_name =
'o3ppmv'
406 fv3jedi_name =
'frland'
408 fv3jedi_name =
'frlandice'
410 fv3jedi_name =
'frlake'
412 fv3jedi_name =
'frocean'
414 fv3jedi_name =
'frseaice'
416 fv3jedi_name =
'ustar'
418 fv3jedi_name =
'bstar'
426 fv3jedi_name =
'u_srf'
428 fv3jedi_name =
'v_srf'
430 fv3jedi_name =
'sheleg'
432 fv3jedi_name =
'soilt'
434 fv3jedi_name =
'soilm'
438 fv3jedi_name =
'zpbl'
442 call abor1_ftn(
"geos_to_state no map between GEOS name and JEDI name "//trim(item_names(i)))
449 if (state%has_field(trim(fv3jedi_name)))
then
452 call esmf_stateget(self%cap%cap_gc%export_state, item_names(i), field, rc = rc)
453 if (rc.ne.0)
call abor1_ftn(
"geos_to_state: ESMF_StateGet field failed")
456 call esmf_fieldvalidate(field, rc = rc)
457 if (rc.ne.0)
call abor1_ftn(
"geos_to_state: ESMF_FieldValidate failed")
460 call esmf_fieldget(field, rank = rank, rc = rc)
461 if (rc.ne.0)
call abor1_ftn(
"geos_to_state: ESMF_FieldGet rank failed")
464 field_geos = 0.0_kind_real
467 call esmf_fieldget( field, 0, farrayptr = farrayptr2, totallbound = lb(1:2), totalubound = ub(1:2), rc = rc )
468 if (rc.ne.0)
call abor1_ftn(
"geos_to_state: ESMF_FieldGet 2D failed")
471 field_geos(self%isc:self%iec,self%jsc:self%jec,1) = farrayptr2(lb(1):ub(1),lb(2):ub(2))
474 elseif (rank == 3)
then
476 call esmf_fieldget( field, 0, farrayptr = farrayptr3, totallbound = lb, totalubound = ub, rc = rc )
477 if (rc.ne.0)
call abor1_ftn(
"geos_to_state: ESMF_FieldGet 3D failed")
480 field_geos(self%isc:self%iec,self%jsc:self%jec,1:fnpz) = farrayptr3(lb(1):ub(1),lb(2):ub(2),lb(3):ub(3))
485 call abor1_ftn(
"geos_mod: can only handle rank 2 or rank 3 fields from GEOS")
490 if ((ub(1)-lb(1)+1 .ne. self%iec-self%isc+1) .or. (ub(2)-lb(2)+1 .ne. self%jec-self%jsc+1) )
then
491 call abor1_ftn(
"geos_to_state: dimension mismatch between JEDI and GEOS horizontal grid")
495 call state%get_field(trim(fv3jedi_name), field_ptr)
497 if (field_ptr%npz .ne. fnpz) &
498 call abor1_ftn(
"geos_to_state: dimension mismatch between JEDI and GEOS vertical grid")
501 field_ptr%array(:,:,1:fnpz) = field_geos(:,:,1:fnpz)
506 deallocate(item_names)
517 integer :: num_items, i, rc
518 type(esmf_field) :: field
519 character(len=ESMF_MAXSTR),
allocatable :: item_names(:)
528 call esmf_stateget(self%cap%cap_gc%export_state, itemcount = num_items, rc = rc)
529 if (rc.ne.0)
call abor1_ftn(
"allocate_exports: ESMF_StateGet itemcount failed")
534 allocate(item_names(num_items))
535 call esmf_stateget(self%cap%cap_gc%export_state, itemnamelist = item_names, rc = rc)
536 if (rc.ne.0)
call abor1_ftn(
"allocate_exports: ESMF_StateGet items failed")
544 call esmf_stateget(self%cap%cap_gc%export_state, item_names(i), field, rc = rc)
545 if (rc.ne.0)
call abor1_ftn(
"allocate_exports: ESMF_StateGet field failed")
548 call esmf_fieldvalidate(field, rc = rc)
549 if (rc.ne.0)
call abor1_ftn(
"allocate_exports: ESMF_FieldValidate failed")
551 call mapl_allocatecoupling(field, rc)
552 if (rc.ne.0)
call abor1_ftn(
"allocate_exports: MAPL_AllocateCoupling failed")
556 deallocate(item_names)
564 type (MAPL_Communicator),
intent(inout) :: mcomm
570 if (comm == mpi_comm_null)
then
572 mcomm%rank = mpi_undefined
573 mcomm%root = mpi_undefined
575 call mpi_comm_size(comm, mcomm%size,status)
577 call mpi_comm_rank(comm, mcomm%rank,status)