ROMS
Loading...
Searching...
No Matches
mod_coupler.F
Go to the documentation of this file.
1#include "cppdefs.h"
3
4#if defined MODEL_COUPLING && defined MCT_LIB
5!
6!git $Id$
7!================================================== Hernan G. Arango ===
8! Copyright (c) 2002-2025 The ROMS Group !
9! Licensed under a MIT/X style license !
10! See License_ROMS.md !
11!=======================================================================
12!
13 USE mod_param
14!
15 implicit none
16!
17!-----------------------------------------------------------------------
18! Set several model coupling structures.
19!-----------------------------------------------------------------------
20!
21! Integer vector structure.
22!
24 integer, pointer :: val(:)
25 END TYPE
26!
27! String vector structure.
28!
30 character (len=10), pointer :: code(:)
31 END TYPE
32!
33! Coupling field attributes structure.
34!
36 integer :: fieldid ! field ID
37 integer :: gridid ! associated grid ID
38 integer :: maskid ! associated land/sea mask ID
39 integer :: gridtype ! grid type (RHO-, U-, V-points)
40 real(r8) :: addoffset ! number added to data
41 real(r8) :: scale ! scaling factor
42 real(r8) :: expmin ! exported minimum value
43 real(r8) :: expmax ! exported maximum value
44 real(r8) :: impmin ! imported minimum value
45 real(r8) :: impmax ! imported maximum value
46 character (len=40) :: code ! field code
47 character (len=40) :: variable ! associated model variable
48 character (len=80) :: name ! long descriptive field name
49 character (len=80) :: units ! field units
50 END TYPE t_field
51!
52! Coupling model exchange mesh attributes structure.
53!
54 TYPE t_mesh
55 integer :: gridid ! grid ID
56 integer :: gridtype ! grid type (RHO-, U-, V-points)
57 character (len=40) :: code ! grid code
58 character (len=40) :: variable ! associated model variable
59 character (len=80) :: name ! long descriptive grid name
60 character (len=80) :: units ! grid units
61 END TYPE t_mesh
62!
63! Time clock.
64!
66 integer :: year ! year
67 integer :: month ! month
68 integer :: day ! day
69 integer :: hour ! hour
70 integer :: minute ! minute
71 integer :: second ! second
72 integer :: yearday ! day of the year
73 integer :: timezone ! time zone, hours offset
74 character (len=30) :: string ! time string
75 END TYPE t_clock
76!
77!-----------------------------------------------------------------------
78! Set various variables used to couple ROMS to other modeling
79! systems.
80!-----------------------------------------------------------------------
81!
82! Number of models to couple.
83!
84 integer :: nmodels
85!
86! Coupled model components IDs.
87!
88 integer :: atmid = 3
89 integer :: wavid = 2
90 integer :: ocnid = 1
91!
92! Logical switch to report verbose import/export field ranges.
93!
94 logical :: lreport = .false.
95!
96! Input coupled model order labels used to determine the values of
97! each model index in information variable.
98!
99 character (len=20), allocatable :: orderlabel(:)
100!
101! Coupled model indices. Values are initilized here to zero and
102! assigned in "inp_par" using order labels codes.
103!
104 integer :: iatmos = 0 ! atmospheric model
105 integer :: iocean = 0 ! ocean model
106 integer :: iwaves = 0 ! wave model
107!
108! Standard input file name for each coupled model.
109!
110 character (len=256), allocatable :: inpname(:)
111!
112! Export/Import fields information file name.
113!
114 character (len=256) :: cplname
115!
116! Number of parallel nodes assigned to each model in the coupled model.
117! Their sum must be equal to the total number of processors.
118!
119 integer, allocatable :: nthreads(:)
120!
121! Assigned Pertsistent Execution Threads (PETs) for each coupled
122! model.
123!
124 TYPE (t_integer), allocatable :: pets(:)
125!
126! Time interval (seconds) between coupling of models. This is a symmetric
127! matrix. For example, the time interval coupling between ocean and
128! atmosphere models is:
129!
130! TimeInterval(Iocean,Iatmos) = TimeInterval(Iocean,Iatmos)
131!
132 real(r8), allocatable :: timeinterval(:,:)
133!
134! Number of time-steps for how often to couple ROMS to other models.
135!
136! CoupleSteps(:,ng) = MAX(1,INT(TimeInterval(Iocean,:)/dt(ng)))
137!
138 integer, allocatable :: couplesteps(:,:)
139!
140! Export/Import fields information structure. This information is read
141! from input CPLname file.
142!
143 integer, parameter :: maxnumberfields = 50
144
146!
147! Number export and import fields for each coupled model.
148!
149 integer, allocatable :: nexport(:)
150 integer, allocatable :: nimport(:)
151!
152! Export/import fields IDs for each coupled model.
153!
154 TYPE (t_integer), allocatable :: exportid(:)
155 TYPE (t_integer), allocatable :: importid(:)
156!
157! Export/import fields codes for each coupled model.
158!
159 TYPE (t_string), allocatable :: export(:)
160 TYPE (t_string), allocatable :: import(:)
161!
162! Export fields attribute string.
163!
164 character (len=240), allocatable :: exportlist(:)
165
166 CONTAINS
167
168 SUBROUTINE allocate_coupler (Nnodes)
169!
170!=======================================================================
171! !
172! This routine allocates all variables in the module for all coupled !
173! models. It also initialize variable when appropriate. !
174! !
175!=======================================================================
176!
177 USE mod_parallel
178 USE mod_iounits
179 USE mod_ncparam
180 USE mod_scalars
181!
182! Imported variable declarations.
183!
184 integer, intent(in) :: Nnodes
185!
186! Local variable declarations.
187!
188 logical :: load
189!
190 integer, parameter :: inp = 20
191!
192 integer :: Nfields
193 integer :: gtype, i, id, ifield, inode, lvar, model, ng, varid
194 integer :: io_err
195!
196 real(r8) :: add_offset, scale
197!
198 character (len=40 ) :: code
199 character (len=80 ) :: string
200 character (len=256) :: io_errmsg
201 character (len=MaxLen), dimension(5) :: Vinfo
202!
203!-----------------------------------------------------------------------
204! Read in coupling export/import variable information.
205!-----------------------------------------------------------------------
206!
207! Open input coupling variable information file.
208!
209 OPEN (inp, file=trim(cplname), form='formatted', status='old', &
210 & iostat=io_err, iomsg=io_errmsg)
211 IF (io_err.ne.0) THEN
212 IF (myrank.eq.0) WRITE(stdout,50) trim(cplname), trim(io_errmsg)
213 exit_flag=5
214 RETURN
215 END IF
216!
217! Read in variable information. Ignore blank and comment [char(33)=!]
218! input lines.
219!
220 varid=0
221 DO WHILE (.true.)
222 READ (inp,*,err=30,END=40) Vinfo(1)
223 lvar=len_trim(vinfo(1))
224!
225! Read in other variable information.
226!
227 IF ((lvar.gt.0).and.(vinfo(1)(1:1).ne.char(33))) THEN
228 READ (inp,*,err=30) vinfo(2)
229 READ (inp,*,err=30) vinfo(3)
230 READ (inp,*,err=30) vinfo(4)
231 READ (inp,*,err=30) vinfo(5)
232 READ (inp,*,err=30) add_offset
233 READ (inp,*,err=30) scale
234!
235! Determine staggered C-grid variable.
236!
237 SELECT CASE (trim(adjustl(vinfo(5))))
238 CASE ('p2dvar')
239 gtype=p2dvar
240 CASE ('r2dvar')
241 gtype=r2dvar
242 CASE ('u2dvar')
243 gtype=u2dvar
244 CASE ('v2dvar')
245 gtype=v2dvar
246 CASE ('p3dvar')
247 gtype=p3dvar
248 CASE ('r3dvar')
249 gtype=r3dvar
250 CASE ('u3dvar')
251 gtype=u3dvar
252 CASE ('v3dvar')
253 gtype=v3dvar
254 CASE ('w3dvar')
255 gtype=w3dvar
256 CASE ('b3dvar')
257 gtype=b3dvar
258 CASE DEFAULT
259 gtype=0
260 END SELECT
261!
262! Load variable data into information arrays.
263!
264 varid=varid+1
265 IF (varid.gt.maxnumberfields) THEN
266 WRITE (stdout,60) maxnumberfields, varid
267 stop
268 END IF
269 fields(varid) % code = trim(adjustl(vinfo(1)))
270 fields(varid) % variable = trim(adjustl(vinfo(2)))
271 fields(varid) % name = trim(adjustl(vinfo(3)))
272 fields(varid) % units = trim(adjustl(vinfo(4)))
273 fields(varid) % FieldID = varid
274 fields(varid) % GridType = gtype
275 fields(varid) % AddOffset = add_offset
276 fields(varid) % scale = scale
277 END IF
278 END DO
279 30 WRITE (stdout,80) trim(adjustl(vinfo(1)))
280 stop
281 40 CLOSE (inp)
282 nfields=varid
283!
284!-----------------------------------------------------------------------
285! Determine identification index for export and import fields.
286!-----------------------------------------------------------------------
287!
288! Allocate IDs structures.
289!
290 IF (.not.allocated(exportid)) THEN
291 allocate ( exportid(nmodels) )
292 DO model=1,nmodels
293 allocate ( exportid(model)%val(nexport(model)) )
294 exportid(model)%val=0
295 END DO
296 END IF
297 IF (.not.allocated(importid)) THEN
298 allocate ( importid(nmodels) )
299 DO model=1,nmodels
300 allocate ( importid(model)%val(nimport(model)) )
301 importid(model)%val=0
302 END DO
303 END IF
304 IF (.not.allocated(exportlist)) THEN
305 allocate ( exportlist(nmodels) )
306 END IF
307!
308! Look fields information and extract Export/Import fields IDs for
309! each coupled model.
310!
311 DO model=1,nmodels
312 DO ifield=1,nexport(model)
313 DO i=1,nfields
314 IF (trim(adjustl(fields(i)%code)).eq. &
315 & trim(adjustl(export(model)%code(ifield)))) THEN
316 exportid(model)%val(ifield)=fields(i)%FieldID
317 END IF
318 END DO
319 END DO
320 DO ifield=1,nimport(model)
321 DO i=1,nfields
322 IF (trim(adjustl(fields(i)%code)).eq. &
323 & trim(adjustl(import(model)%code(ifield)))) THEN
324 importid(model)%val(ifield)=fields(i)%FieldID
325 END IF
326 END DO
327 END DO
328 END DO
329 DO model=1,nmodels
330 exportlist(model)=' '
331 DO ifield=1,nexport(model)
332 id=exportid(model)%val(ifield)
333 IF (id.gt.0) THEN
334 code=adjustl(fields(id)%code)
335 IF (ifield.eq.1) THEN
336 exportlist(model)=trim(exportlist(model))//trim(code)
337 ELSE
338 exportlist(model)=trim(exportlist(model))//':'//trim(code)
339 END IF
340 ELSE
341 WRITE (stdout,70) model, trim(exportlist(model)), &
342 & trim(cplname)
343 stop
344 END IF
345 END DO
346 END DO
347!
348!-----------------------------------------------------------------------
349! Assign processors to coupled models.
350!-----------------------------------------------------------------------
351!
352! Allocate structure.
353!
354 IF (.not.allocated(pets)) THEN
355 allocate ( pets(nmodels) )
356 DO model=1,nmodels
357 allocate ( pets(model)%val(nthreads(model)) )
358 END DO
359 END IF
360!
361! Assign parallel threads for each coupled model. Start counting from
362! zero. That is, they are [0:Nnodes-1] available.
363!
364 inode=-1
365 DO model=1,nmodels
366 DO i=1,nthreads(model)
367 inode=inode+1
368 pets(model)%val(i)=inode
369 END DO
370 END DO
371!
372! Report.
373!
374 IF ((inode+1).ne.nnodes) THEN
375 IF (myrank.eq.0) THEN
376 WRITE (stdout,80) inode, nnodes
377 END IF
378 stop
379 ELSE
380 IF (myrank.eq.0) THEN
381 WRITE (stdout,90)
382 DO model=1,nmodels
383 IF (model.eq.iocean) THEN
384 string='Ocean Model MPI nodes:'
385 ELSE IF (model.eq.iwaves) THEN
386 string='Waves Model MPI nodes:'
387 ELSE IF (model.eq.iatmos) THEN
388 string='Atmos Model MPI nodes:'
389 END IF
390 WRITE (stdout,100) trim(string), &
391 & pets(model)%val(1), &
392 & pets(model)%val(nthreads(model))
393 END DO
394 END IF
395 WRITE (stdout,'(/)')
396 END IF
397 IF (myrank.eq.0) THEN
398 DO model=1,nmodels
399 IF (model.eq.iocean) THEN
400 string='Ocean Export:'
401 ELSE IF (model.eq.iwaves) THEN
402 string='Waves Export:'
403 ELSE IF (model.eq.iatmos) THEN
404 string='Atmos Export:'
405 END IF
406 WRITE (stdout,110) trim(string), trim(exportlist(model))
407 END DO
408 WRITE (stdout,'(/)')
409 END IF
410
411!
412 50 FORMAT (/,' MOD_COUPLER - Unable to open variable information', &
413 & ' file: ',/,15x,a,/,15x,'ERROR: ',a, &
414 /,15x,'Default file is located in source directory.')
415 60 FORMAT (/,' MOD_COUPLER - too small dimension ', &
416 & 'parameter, MV = ',2i5,/,15x, &
417 & 'change file mod_ncparam.F and recompile.')
418 70 FORMAT (/,' MOD_COUPLER - Unregistered export field for ', &
419 & ' model = ',i1,/,15x,'ExportList = ',a,/,15x, &
420 & ' check file = ',a)
421 80 FORMAT (/,' MOD_COUPLER - Number assigned processors: ', &
422 & i3.3,/,15x,'not equal to spawned MPI nodes: ',i3.3)
423 90 FORMAT (/,' Model Coupling Parallel Threads:',/)
424100 FORMAT (3x,a,3x,i3.3,' - ',i3.3)
425110 FORMAT (3x,a,1x,a)
426
427 END SUBROUTINE allocate_coupler
428!
429#endif
430 END MODULE mod_coupler
character(len=20), dimension(:), allocatable orderlabel
Definition mod_coupler.F:99
character(len=256) cplname
integer iocean
integer wavid
Definition mod_coupler.F:89
integer, dimension(:,:), allocatable couplesteps
integer iatmos
type(t_integer), dimension(:), allocatable exportid
logical lreport
Definition mod_coupler.F:94
integer, dimension(:), allocatable nexport
type(t_string), dimension(:), allocatable export
type(t_field), dimension(maxnumberfields) fields
integer atmid
Definition mod_coupler.F:88
character(len=240), dimension(:), allocatable exportlist
type(t_integer), dimension(:), allocatable pets
integer, dimension(:), allocatable nthreads
type(t_string), dimension(:), allocatable import
integer, parameter maxnumberfields
integer ocnid
Definition mod_coupler.F:90
integer, dimension(:), allocatable nimport
character(len=256), dimension(:), allocatable inpname
subroutine allocate_coupler(nnodes)
integer nmodels
Definition mod_coupler.F:84
type(t_integer), dimension(:), allocatable importid
integer iwaves
real(r8), dimension(:,:), allocatable timeinterval
type(t_io), dimension(:), allocatable err
integer stdout
integer, parameter b3dvar
Definition mod_param.F:725
integer, parameter r3dvar
Definition mod_param.F:721
integer, parameter u3dvar
Definition mod_param.F:722
integer, parameter u2dvar
Definition mod_param.F:718
integer, parameter w3dvar
Definition mod_param.F:724
integer, parameter p2dvar
Definition mod_param.F:716
integer, parameter r2dvar
Definition mod_param.F:717
integer, parameter v2dvar
Definition mod_param.F:719
integer, parameter p3dvar
Definition mod_param.F:720
integer, parameter v3dvar
Definition mod_param.F:723
integer exit_flag