FV3-JEDI
fv3jedi_nuopc_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2017-2018 UCAR
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 
7 
8 use iso_c_binding
9 use fckit_configuration_module, only: fckit_configuration
10 use datetime_mod
11 use duration_mod
12 use netcdf
13 
18 
19 use fckit_mpi_module, only: fckit_mpi_comm, fckit_mpi_sum
20 
21 use esmf
22 use nuopc_comp, only: nuopc_compsetclock
23 use nuopc_driver, only: nuopc_drivergetcomp
24 use nuopc_model, only: nuopc_modelget
25 use esm, only: esmss => setservices
26 
27 implicit none
28 private
29 
30 public :: model_nuopc_type
31 public :: model_nuopc_create
32 public :: model_nuopc_delete
33 public :: model_nuopc_initialize
34 public :: model_nuopc_step
35 public :: model_nuopc_finalize
36 
37 ! ------------------------------------------------------------------------------
38 
39 !> Fortran derived type to hold model definition
41  integer :: urc
42  integer :: dt
43  type(esmf_gridcomp) :: esmcomp !NUOPC driver
44 end type model_nuopc_type
45 
46 ! ------------------------------------------------------------------------------
47 
48 contains
49 
50 ! ------------------------------------------------------------------------------
51 
52 subroutine model_nuopc_create(self, geom, c_conf)
53 
54 implicit none
55 type(c_ptr), intent(in) :: c_conf
56 type(model_nuopc_type), intent(inout) :: self
57 type(fv3jedi_geom), intent(in) :: geom
58 
59 integer :: rc
60 
61 character(len=20) :: ststep
62 type(duration) :: dtstep
63 character(len=20) :: cdate_start
64 character(len=20) :: cdate_final
65 
66 type(fckit_mpi_comm) :: f_comm
67 type(fckit_configuration) :: f_conf
68 character(len=:), allocatable :: str
69 
70 
71 ! Fortran configuration
72 ! ---------------------
73 f_conf = fckit_configuration(c_conf)
74 
75 ! FCKIT MPI from geometry
76 f_comm = geom%f_comm
77 
78 ! Initialize ESMF
79 call esmf_initialize(logkindflag=esmf_logkind_multi, &
80  defaultcalkind=esmf_calkind_gregorian, mpicommunicator=f_comm%communicator(), rc=rc)
81 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
82  line=__line__, &
83  file=__file__)) &
84  call esmf_finalize(endflag=esmf_end_abort)
85 
86 call esmf_logwrite("esm-JEDI STARTING", esmf_logmsg_info, rc=rc)
87 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
88  line=__line__, &
89  file=__file__)) &
90  call esmf_finalize(endflag=esmf_end_abort)
91 
92 ! Create the Earth system Component
93 self%esmComp = esmf_gridcompcreate(name="esm", rc=rc)
94 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
95  line=__line__, &
96  file=__file__)) &
97  call esmf_finalize(endflag=esmf_end_abort)
98 
99 ! SetServices for the Earth system Component
100 call esmf_gridcompsetservices(self%esmComp, esmss, userrc=self%urc, rc=rc)
101 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
102  line=__line__, &
103  file=__file__)) &
104  call esmf_finalize(endflag=esmf_end_abort)
105 if (esmf_logfounderror(rctocheck=self%urc, msg=esmf_logerr_passthru, &
106  line=__line__, &
107  file=__file__)) &
108  call esmf_finalize(endflag=esmf_end_abort)
109 
110 
111 ! Reset the clock based on what JEDI provides
112 ! -------------------------------------------
113 
114 call f_conf%get_or_die("tstep",str)
115 ststep = str
116 deallocate(str)
117 dtstep = trim(ststep)
118 self%dt = int(duration_seconds(dtstep))
119 
120 cdate_start = '2018-04-14T21:00:00Z'
121 cdate_final = '2018-04-15T03:00:00Z'
122 
123 call nuopc_reset_clock(self%esmComp, self%dt, cdate_start, cdate_final)
124 
125 
126 ! Call Initialize for the Earth system Component
127 call esmf_gridcompinitialize(self%esmComp, userrc=self%urc, rc=rc)
128 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
129  line=__line__, &
130  file=__file__)) &
131  call esmf_finalize(endflag=esmf_end_abort)
132 if (esmf_logfounderror(rctocheck=self%urc, msg=esmf_logerr_passthru, &
133  line=__line__, &
134  file=__file__)) &
135  call esmf_finalize(endflag=esmf_end_abort)
136 
137 end subroutine model_nuopc_create
138 
139 ! ------------------------------------------------------------------------------
140 
141 subroutine model_nuopc_delete(self)
142 
143 implicit none
144 type(model_nuopc_type), intent(inout) :: self
145 
146 integer :: rc
147 
148 ! Call Finalize for the Earth system Component
149 call esmf_gridcompfinalize(self%esmComp, userrc=self%urc, rc=rc)
150 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
151  line=__line__, &
152  file=__file__)) &
153  call esmf_finalize(endflag=esmf_end_abort)
154 if (esmf_logfounderror(rctocheck=self%urc, msg=esmf_logerr_passthru, &
155  line=__line__, &
156  file=__file__)) &
157  call esmf_finalize(endflag=esmf_end_abort)
158 
159 ! Destroy the Earth system Component
160 call esmf_gridcompdestroy(self%esmComp, rc=rc)
161 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
162  line=__line__, &
163  file=__file__)) &
164  call esmf_finalize(endflag=esmf_end_abort)
165 
166 call esmf_logwrite("esm-JEDI FINISHED", esmf_logmsg_info, rc=rc)
167 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
168  line=__line__, &
169  file=__file__)) &
170  call esmf_finalize(endflag=esmf_end_abort)
171 
172 ! Finalize ESMF
173 call esmf_finalize(endflag=esmf_end_keepmpi,rc=rc)
174 
175 end subroutine model_nuopc_delete
176 
177 ! ------------------------------------------------------------------------------
178 
179 subroutine model_nuopc_initialize(self, state, vdate)
180 
181 implicit none
182 type(model_nuopc_type), intent(inout) :: self
183 type(fv3jedi_state), intent(in) :: state
184 type(datetime), intent(in) :: vdate !< Valid datetime after step
185 
186 ! Note that calling ESMF initialize here is likely not safe since finalize
187 ! is not the mirror image of finalize. E.g. there is nothing in ESMF to prevent
188 ! a user for allocating a module level array in SetServices and deallocating it
189 ! in finalize.
190 
191 end subroutine model_nuopc_initialize
192 
193 ! ------------------------------------------------------------------------------
194 
195 subroutine model_nuopc_step(self, state, vdate1, vdate2)
196 
197 implicit none
198 type(model_nuopc_type), intent(inout) :: self
199 type(fv3jedi_state), intent(inout) :: state
200 type(datetime), intent(in) :: vdate1 !< Valid datetime before advance
201 type(datetime), intent(in) :: vdate2 !< Valid datetime after advance
202 
203 integer :: rc
204 character(len=20) :: vdatec1, vdatec2
205 
206 !Convert datetimes
207 call datetime_to_string(vdate1, vdatec1)
208 call datetime_to_string(vdate2, vdatec2)
209 
210 !Reset the GridComp clock for this advance step
211 call nuopc_reset_clock(self%esmComp, self%dt, vdatec1, vdatec2)
212 
213 ! JEDI state to NUOPC model state
214 call state_to_nuopc( state, self )
215 
216 ! Call Run for Earth the system Component
217 call esmf_gridcomprun(self%esmComp, userrc=self%urc, rc=rc)
218 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
219  line=__line__, &
220  file=__file__)) &
221  call esmf_finalize(endflag=esmf_end_abort)
222 if (esmf_logfounderror(rctocheck=self%urc, msg=esmf_logerr_passthru, &
223  line=__line__, &
224  file=__file__)) &
225  call esmf_finalize(endflag=esmf_end_abort)
226 
227 ! JEDI state to NUOPC model state to JEDI state
228 call nuopc_to_state( self, state )
229 
230 end subroutine model_nuopc_step
231 
232 ! ------------------------------------------------------------------------------
233 
234 subroutine model_nuopc_finalize(self, state, vdate)
235 
236 implicit none
237 type(model_nuopc_type), intent(inout) :: self
238 type(fv3jedi_state), intent(in) :: state
239 type(datetime), intent(in) :: vdate !< Valid datetime after step
240 
241 ! Note that calling ESMF initialize here is likely not safe since finalize
242 ! is not the mirror image of finalize. E.g. there is nothing in ESMF to prevent
243 ! a user for allocating a module level array in SetServices and deallocating it
244 ! in finalize.
245 
246 end subroutine model_nuopc_finalize
247 
248 ! ------------------------------------------------------------------------------
249 
250 subroutine state_to_nuopc( state, self )
251 
252 implicit none
253 type(fv3jedi_state), intent(in) :: state
254 type(model_nuopc_type), intent(inout) :: self
255 
256 type(esmf_gridcomp) :: atmComp
257 type(esmf_clock) :: clock
258 type(esmf_state) :: importState, exportState
259 integer :: rc
260 type (ESMF_FieldBundle) :: bundle
261 type (ESMF_Field) :: field
262 
263 real(kind_real), pointer :: sst(:,:), pmsl(:,:)
264 type(esmf_fieldstatus_flag) :: fieldStatus
265 
266 integer :: LB(2), UB(2)
267 
268 integer, save :: init = 0
269 
270 !Get the atmosphere child component
271 call nuopc_drivergetcomp(self%esmComp, "ATM", comp=atmcomp, rc=rc)
272 
273 !Get atmosphere import state
274 call nuopc_modelget(atmcomp, modelclock=clock, importstate=importstate, rc=rc)
275 
276 !Get field from import state
277 call esmf_stateget(importstate, "sst", field, rc=rc)
278 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
279  line=__line__, &
280  file=__file__)) &
281  call esmf_finalize(endflag=esmf_end_abort)
282 
283 !Get pointer to the air_pressure_at_sea_level field
284 call esmf_fieldget(field, status=fieldstatus, rc=rc)
285 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
286  line=__line__, &
287  file=__file__)) &
288  call esmf_finalize(endflag=esmf_end_abort)
289 
290 call esmf_fieldget(field, 0, sst, computationallbound=lb, computationalubound=ub, rc=rc)
291 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
292  line=__line__, &
293  file=__file__)) &
294  call esmf_finalize(endflag=esmf_end_abort)
295 
296 print*, "JED-DATA sst", sst(lb(1),lb(2))
297 
298 if (associated(sst)) nullify(sst)
299 if (associated(pmsl)) nullify(pmsl)
300 
301 
302 end subroutine state_to_nuopc
303 
304 ! ------------------------------------------------------------------------------
305 
306 subroutine nuopc_to_state( self, state )
307 
308 implicit none
309 type(model_nuopc_type), intent(in) :: self
310 type(fv3jedi_state), intent(inout) :: state
311 
312 type(esmf_gridcomp) :: atmComp
313 type(esmf_clock) :: clock
314 type(esmf_state) :: importState, exportState
315 integer :: rc
316 
317 !Get the atmosphere child component
318 call nuopc_drivergetcomp(self%esmComp, "ATM", comp=atmcomp, rc=rc)
319 
320 end subroutine nuopc_to_state
321 
322 ! ------------------------------------------------------------------------------
323 
324 subroutine nuopc_reset_clock( driver, dt, cdate_start, cdate_final)
325 
326 implicit none
327 type(esmf_gridcomp), intent(inout) :: driver
328 integer, intent(in) :: dt
329 character(len=20), intent(in) :: cdate_start
330 character(len=20), intent(in) :: cdate_final
331 
332 type(esmf_time) :: startTime
333 type(esmf_time) :: stopTime
334 type(esmf_timeinterval) :: timeStep
335 type(esmf_clock) :: externalClock
336 
337 integer :: rc
338 
339 integer yy1,mm1,dd1,hh1,mn1
340 integer yy2,mm2,dd2,hh2,mn2
341 
342 !Convert character dates to integers
343 read(cdate_start(1:4),'(i)') yy1
344 read(cdate_final(1:4),'(i)') yy2
345 read(cdate_start(6:7),'(i)') mm1
346 read(cdate_final(6:7),'(i)') mm2
347 read(cdate_start(9:10),'(i)') dd1
348 read(cdate_final(9:10),'(i)') dd2
349 read(cdate_start(12:13),'(i)') hh1
350 read(cdate_final(12:13),'(i)') hh2
351 read(cdate_start(15:16),'(i)') mn1
352 read(cdate_final(15:16),'(i)') mn2
353 
354 call esmf_timeintervalset(timestep, s=dt, rc=rc)
355 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
356  line=__line__, &
357  file=__file__)) &
358  call esmf_finalize(endflag=esmf_end_abort)
359 
360 call esmf_timeset(starttime, yy=yy1, mm=mm1, dd=dd1, h=hh1, m=mn1, rc=rc)
361 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
362  line=__line__, &
363  file=__file__)) &
364  call esmf_finalize(endflag=esmf_end_abort)
365 
366 call esmf_timeset(stoptime, yy=yy2, mm=mm2, dd=dd2, h=hh2, m=mn2, rc=rc)
367 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
368  line=__line__, &
369  file=__file__)) &
370  call esmf_finalize(endflag=esmf_end_abort)
371 
372 externalclock = esmf_clockcreate(name="Application Clock", &
373  timestep=timestep, starttime=starttime, stoptime=stoptime, rc=rc)
374 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
375  line=__line__, &
376  file=__file__)) &
377  call esmf_finalize(endflag=esmf_end_abort)
378 
379 call nuopc_compsetclock(driver, externalclock=externalclock, rc=rc)
380 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
381  line=__line__, &
382  file=__file__)) &
383  call esmf_finalize(endflag=esmf_end_abort)
384 
385 end subroutine nuopc_reset_clock
386 
387 ! ------------------------------------------------------------------------------
388 
389 end module fv3jedi_nuopc_mod
esm::setservices
subroutine, public setservices(driver, rc)
Definition: esm.F90:31
fv3jedi_state_mod::fv3jedi_state
Fortran derived type to hold FV3JEDI state.
Definition: fv3jedi_state_mod.F90:30
fv3jedi_nuopc_mod::model_nuopc_finalize
subroutine, public model_nuopc_finalize(self, state, vdate)
Definition: fv3jedi_nuopc_mod.F90:235
fv3jedi_nuopc_mod::model_nuopc_initialize
subroutine, public model_nuopc_initialize(self, state, vdate)
Definition: fv3jedi_nuopc_mod.F90:180
fv3jedi_nuopc_mod::model_nuopc_type
Fortran derived type to hold model definition.
Definition: fv3jedi_nuopc_mod.F90:40
fv3jedi_state_mod
Definition: fv3jedi_state_mod.F90:6
fv3jedi_nuopc_mod
Definition: fv3jedi_nuopc_mod.F90:6
fv3jedi_geom_mod
Fortran module handling geometry for the FV3 model.
Definition: fv3jedi_geom_mod.f90:8
fv3jedi_nuopc_mod::state_to_nuopc
subroutine state_to_nuopc(state, self)
Definition: fv3jedi_nuopc_mod.F90:251
fv3jedi_increment_mod
Definition: fv3jedi_increment_mod.F90:6
fv3jedi_geom_mod::fv3jedi_geom
Fortran derived type to hold geometry data for the FV3JEDI model.
Definition: fv3jedi_geom_mod.f90:46
fv3jedi_nuopc_mod::nuopc_reset_clock
subroutine nuopc_reset_clock(driver, dt, cdate_start, cdate_final)
Definition: fv3jedi_nuopc_mod.F90:325
esm
Definition: esm.F90:1
fv3jedi_nuopc_mod::nuopc_to_state
subroutine nuopc_to_state(self, state)
Definition: fv3jedi_nuopc_mod.F90:307
fv3jedi_nuopc_mod::model_nuopc_step
subroutine, public model_nuopc_step(self, state, vdate1, vdate2)
Definition: fv3jedi_nuopc_mod.F90:196
fv3jedi_nuopc_mod::model_nuopc_create
subroutine, public model_nuopc_create(self, geom, c_conf)
Definition: fv3jedi_nuopc_mod.F90:53
fv3jedi_nuopc_mod::model_nuopc_delete
subroutine, public model_nuopc_delete(self)
Definition: fv3jedi_nuopc_mod.F90:142
fv3jedi_kinds_mod
Definition: fv3jedi_kinds_mod.f90:6
fv3jedi_increment_mod::fv3jedi_increment
Definition: fv3jedi_increment_mod.F90:34