forked from HYCOM/HYCOM-src
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hycom_cice.F90
403 lines (390 loc) · 16.1 KB
/
hycom_cice.F90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
program hycom_cice
!
! --- ESMF driver for HYCOM ocean model and CICE sea-ice model
!
use ESMF_Mod
use mod_hycom, only : &
OCN_put_export => put_export, &
OCN_get_import => get_import, &
OCN_end_of_run => end_of_run, &
OCN_nts_day => nts_day, &
OCN_nts_cpl => nts_ice, &
OCN_SetServices => HYCOM_SetServices
use ice_kinds_mod
use CICE_ComponentMod, only : &
ICE_SetServices => CICE_SetServices
use CICE_InitMod, only : &
ICE_nts_day => nts_day
use CICE_RunMod, only : &
ICE_put_export => put_export, &
ICE_get_import => get_import, &
ICE_end_of_run => end_of_run
use mod_OICPL, only : &
CPL_i2o => ice2ocn_phase, &
CPL_o2i => ocn2ice_phase, &
CPL_SetServices => OICPL_SetServices
!
implicit none
!
! --- Local variables
!
! --- Gridded Components
type(ESMF_GridComp) :: ocnGridComp, & !HYCOM as an ESMF component
iceGridComp ! CICE as an ESMF component
!
! --- Coupler Components
type(ESMF_CplComp) :: o2iCplComp
!
! --- States, Virtual Machines, and Layouts
type(ESMF_State) :: ocnImpState, & ! HYCOM import state
ocnExpState, & ! HYCOM export state
iceImpState, & ! CICE import state
iceExpState, & ! CICE export state
cplImpState, & ! OICPL import state
cplExpState ! OICPL export state
!
type(ESMF_VM) :: worldVM
integer :: petCount, localPet, split
!
! --- Calendars and clocks
type(ESMF_Clock) :: worldClock
type(ESMF_Clock) :: ocnClock
type(ESMF_Clock) :: iceClock
!
! --- Return codes for error checks
integer :: rc,rc2
!
! --- ICE coupling frequency
integer :: ice_nts_cpl,ocn_cpl_day
!
! --- Miscellaneous
integer :: i,its,its_ocn,its_ice,icpl,iday
!
!-------------------------------------------------------------------------------
! Initialize the ESMF Framework
!-------------------------------------------------------------------------------
!
! --- Set default calendar and log type; get world VM
rc = ESMF_Success
call ESMF_Initialize(defaultCalendar=ESMF_CAL_GREGORIAN, &
defaultLogType=ESMF_LOG_MULTI, &
vm=worldVM, &
rc=rc)
if (rc .ne. ESMF_SUCCESS) stop 99
!
! --- Get VM info
call ESMF_VMGet(worldVM, petCount=petCount, localPET=localPet, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"ESMF_VMGet failed", rcToReturn=rc2)) &
goto 10
!
!-------------------------------------------------------------------------------
! --- Create section
!-------------------------------------------------------------------------------
!
! --- Create the OCEAN gridded component
ocnGridComp = ESMF_GridCompCreate( &
name="OCEAN Gridded Component", &
gridCompType=ESMF_OCEAN, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OCEAN GridCompCreate failed", rcToReturn=rc2)) &
goto 10
!
! --- Create empty OCEAN import/export states
ocnImpState = ESMF_StateCreate(stateName="OCEAN Import", &
stateType=ESMF_STATE_IMPORT, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OCEAN ImpState Create failed", rcToReturn=rc2)) &
goto 10
ocnExpState = ESMF_StateCreate(stateName="OCEAN Export", &
stateType=ESMF_STATE_EXPORT, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OCEAN ExpState Create failed", rcToReturn=rc2)) &
goto 10
!
! --- Create the SEAICE gridded component
iceGridComp = ESMF_GridCompCreate( &
name='SEAICE Component', &
gridcomptype=ESMF_SEAICE, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"SEAICE GridCompCreate failed", rcToReturn=rc2)) &
goto 10
!
! --- Create empty SEAICE import/export states
iceImpState = ESMF_StateCreate(stateName="SEAICE Import", &
stateType=ESMF_STATE_IMPORT, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"SEAICE ImpState Create failed", rcToReturn=rc2)) &
goto 10
iceExpState = ESMF_StateCreate(stateName="SEAICE Export", &
stateType=ESMF_STATE_EXPORT, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"SEAICE ExpState Create failed", rcToReturn=rc2)) &
goto 10
!
! --- Create the OICPL coupler component
o2iCplComp = ESMF_CplCompCreate( &
name="OICPL Coupler Component", &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPLE CplCompCreate failed", rcToReturn=rc2)) &
goto 10
!
! --- Create empty OICPL import/export states
cplImpState = ESMF_StateCreate(stateName="OICPL Import", &
stateType=ESMF_STATE_IMPORT, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL ImpState Create failed", rcToReturn=rc2)) &
goto 10
cplExpState = ESMF_StateCreate(stateName="OICPL Export", &
stateType=ESMF_STATE_EXPORT, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL ExpState Create failed", rcToReturn=rc2)) &
goto 10
!
! --- Add OCEAN and SEAICE states to OICPL states
CALL ESMF_StateAdd(cplImpState, ocnImpState, rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL: Add OCEAN impState failed", rcToReturn=rc2)) &
goto 10
CALL ESMF_StateAdd(cplImpState, iceImpState, rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL: Add SEAICE impState failed", rcToReturn=rc2)) &
goto 10
CALL ESMF_StateAdd(cplExpState, ocnExpState, rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL: Add OCEAN expState failed", rcToReturn=rc2)) &
goto 10
CALL ESMF_StateAdd(cplExpState, iceExpState, rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL: Add SEAICE impState failed", rcToReturn=rc2)) &
goto 10
!
!-------------------------------------------------------------------------------
! --- Register section
!-------------------------------------------------------------------------------
!
! --- Register the OCEAN gridded component
call ESMF_GridCompSetServices(ocnGridComp, &
OCN_SetServices, rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OCEAN Registration failed", rcToReturn=rc2)) &
goto 10
!
! --- Register the SEAICE gridded component
call ESMF_GridCompSetServices(iceGridComp, &
ICE_SetServices, rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"SEAICE Registration failed", rcToReturn=rc2)) &
goto 10
!
! --- Register the OICPL coupler component
call ESMF_CplCompSetServices(o2iCplComp, &
CPL_SetServices,rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL Registration failed", rcToReturn=rc2)) &
goto 10
!
!-------------------------------------------------------------------------------
! --- Initalize Section
!-------------------------------------------------------------------------------
!
! --- Initialize OCEAN gridded component
call ESMF_GridCompInitialize( gridComp=ocnGridComp, &
importState=ocnImpState, &
exportState=ocnExpState, &
phase=ESMF_SINGLEPHASE, &
blockingflag=ESMF_NONBLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OCEAN Initialize failed", rcToReturn=rc2)) &
goto 10
!
! --- Initialize SEAICE gridded component
call ESMF_GridCompInitialize( gridComp=iceGridComp, &
importState=iceImpState, &
exportState=iceExpState, &
phase=ESMF_SINGLEPHASE, &
blockingflag=ESMF_NONBLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"SEAICE Initialize failed", rcToReturn=rc2)) &
goto 10
!
ocn_cpl_day = OCN_nts_day/OCN_nts_cpl
ice_nts_cpl = ICE_nts_day/ocn_cpl_day
if (localPet.eq.0) then !master
write(6,'(a,i5)') 'OCN_nts_day = ',OCN_nts_day
write(6,'(a,i5)') 'ICE_nts_day = ',ICE_nts_day
write(6,'(a,i5)') 'OCN_nts_cpl = ',OCN_nts_cpl
write(6,'(a,i5)') 'ice_nts_cpl = ',ice_nts_cpl
endif
if (OCN_nts_day.ne.ocn_cpl_day*OCN_nts_cpl) then
if (localPet.eq.0) then !master
write(6,*) 'ERROR OCN_nts_cpl not a divisor of OCN_nts_day'
endif
goto 10
endif
if (ICE_nts_day.ne.ocn_cpl_day*ice_nts_cpl) then
if (localPet.eq.0) then !master
write(6,*) 'ERROR ice_nts_cpl not a divisor of ICE_nts_day'
endif
goto 10
endif
!
! --- Initialize OICPL coupler component
call ESMF_CplCompInitialize( cplComp=o2iCplComp, &
importState=cplImpState, &
exportState=cplExpState, &
phase=ESMF_SINGLEPHASE, &
blockingflag=ESMF_BLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL Initialize failed", rcToReturn=rc2)) &
goto 10
!
! --- Couple SEAICE to OCEAN
call ESMF_CplCompRun( cplComp=o2iCplComp, &
importState=cplImpState, &
exportState=cplExpState, &
phase=CPL_i2o, &
blockingflag=ESMF_BLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL I2O Run failed", rcToReturn=rc2)) &
goto 10
!
! --- Couple OCEAN to SEAICE
call ESMF_CplCompRun( cplComp=o2iCplComp, &
importState=cplImpState, &
exportState=cplExpState, &
phase=CPL_o2i, &
blockingflag=ESMF_BLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL I2O Run failed", rcToReturn=rc2)) &
goto 10
!
!-------------------------------------------------------------------------------
! --- Run Section
!-------------------------------------------------------------------------------
!
! --- Run Ocean and SeaIce in lockstep, both looking backwards for imports
do icpl=1,huge(iday)/2 !until end of run
! --- OCEAN
do its= 1,OCN_nts_cpl !couple period, OCEAN
if (mod(its,OCN_nts_cpl).le.1 .and. &
localPet.eq.0) then !master
write(6,'(a,i4,i4)') ' OCEAN run - icpl,its = ',icpl,its
endif
OCN_get_import = its.eq.1 !import at start of period
OCN_put_export = its.eq.OCN_nts_cpl !export at end of period
call ESMF_GridCompRun( gridComp=ocnGridComp, &
importState=ocnImpState, &
exportState=ocnExpState, &
phase=ESMF_SINGLEPHASE, &
blockingflag=ESMF_NONBLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OCEAN Run failed", rcToReturn=rc2)) &
goto 10
enddo !its; OCEAN
! --- SEAICE
do its= 1,ice_nts_cpl !couple period, SEAICE
if (mod(its,ice_nts_cpl).le.1 .and. &
localPet.eq.0) then !master
write(6,'(a,i4,i4)') 'SEAICE run - icpl,its = ',icpl,its
endif
ICE_get_import = its.eq.1 !import at start of period
ICE_put_export = its.eq.ice_nts_cpl !export at end of period
! ICE_put_export = .false. !don't export at end of period
call ESMF_GridCompRun( gridComp=iceGridComp, &
importState=iceImpState, &
exportState=iceExpState, &
phase=ESMF_SINGLEPHASE, &
blockingflag=ESMF_NONBLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"SEAICE Run failed (last half day)", rcToReturn=rc2)) &
goto 10
enddo !its; SEAICE
! --- use end_of_run, rather than a ESMF Clock
if (OCN_end_of_run) then
exit !icpl
endif !end_of_run
! --- Couple SEAICE to OCEAN
call ESMF_CplCompRun( cplComp=o2iCplComp, &
importState=cplImpState, &
exportState=cplExpState, &
phase=CPL_i2o, &
blockingflag=ESMF_BLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL I2O Run failed", rcToReturn=rc2)) &
goto 10
! --- Couple OCEAN to SEAICE
call ESMF_CplCompRun( cplComp=o2iCplComp, &
importState=cplImpState, &
exportState=cplExpState, &
phase=CPL_o2i, &
blockingflag=ESMF_BLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL I2O Run failed", rcToReturn=rc2)) &
goto 10
enddo !icpl
!
call ESMF_VMBarrier(worldVM)
!
!-------------------------------------------------------------------------------
! Finalize Section
!-------------------------------------------------------------------------------
!
! --- Finalize OCEAN gridded component
call ESMF_GridCompFinalize( gridComp=ocnGridComp, &
importState=ocnImpState, &
exportState=ocnExpState, &
phase=ESMF_SINGLEPHASE, &
blockingflag=ESMF_NONBLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OCEAN Finalize failed", rcToReturn=rc2)) &
goto 10
!
! --- Finalize SEAICE gridded component
call ESMF_GridCompFinalize( gridComp=iceGridComp, &
importState=iceImpState, &
exportState=iceExpState, &
phase=ESMF_SINGLEPHASE, &
blockingflag=ESMF_NONBLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"SEAICE Finalize failed", rcToReturn=rc2)) &
goto 10
!
! --- Finalize OACPL coupler component
call ESMF_CplCompFinalize( cplComp=o2iCplComp, &
importState=cplImpState, &
exportState=cplExpState, &
phase=ESMF_SINGLEPHASE, &
blockingflag=ESMF_BLOCKING, &
rc=rc)
if (ESMF_LogMsgFoundError(rc, &
"OICPL Finalize failed", rcToReturn=rc2)) &
goto 10
!
10 continue
call ESMF_VMBarrier(worldVM)
call ESMF_Finalize(rc=rc)
!
stop
end program hycom_cice