YAC 3.14.0
Yet Another Coupler
Loading...
Searching...
No Matches
dummy_ocean.f90
Go to the documentation of this file.
1! Copyright (c) 2024 The YAC Authors
2!
3! SPDX-License-Identifier: BSD-3-Clause
4
7
9
10 USE mpi
11 USE yac
12
13 IMPLICIT NONE
14
15 INTEGER, PARAMETER :: pd = 12
16 INTEGER, PARAMETER :: rd = 307
17
18 INTEGER, PARAMETER :: dp = selected_real_kind(pd,rd)
19 INTEGER, PARAMETER :: wp = dp
20
21 INTEGER, PARAMETER :: no_of_fields = 14
22 INTEGER, PARAMETER :: max_char_length = 132
23
24 INTEGER, PARAMETER :: nbr_cells = 2
25 INTEGER, PARAMETER :: nbr_vertices = 4
26
27 REAL(wp), PARAMETER :: yac_rad = 0.017453292519943295769_wp ! M_PI / 180
28
29 CHARACTER(LEN=max_char_length) :: dummy_name
30 CHARACTER(LEN=max_char_length) :: field_name(no_of_fields)
31 INTEGER :: field_collection_size(no_of_fields)
32 CHARACTER(LEN=max_char_length) :: yaml_filename
33 CHARACTER(LEN=max_char_length) :: grid_name
34 CHARACTER(LEN=max_char_length) :: comp_name
35 CHARACTER(LEN=max_char_length) :: timestep_string
36
37 INTEGER :: role
38 INTEGER :: i, info, ierror
39 INTEGER :: comp_id
40 INTEGER :: cell_point_ids(1)
41 INTEGER :: grid_id
42
43 INTEGER :: glb_index(nbr_cells)
44 INTEGER :: cell_core_mask(nbr_cells)
45 INTEGER :: nbr_vertices_per_cell
46
47 REAL(wp), ALLOCATABLE :: buffer(:,:)
48 REAL(wp), ALLOCATABLE :: buffer_lon(:)
49 REAL(wp), ALLOCATABLE :: buffer_lat(:)
50 INTEGER, ALLOCATABLE :: cell_to_vertex(:,:)
51
52 INTEGER, ALLOCATABLE :: cell_mask(:)
53 INTEGER, ALLOCATABLE :: field_id(:)
54
55 INTEGER :: local_comm, npes, rank
56
57 CALL mpi_init (ierror)
58
59
60 ! Initialise the coupler
61 CALL yac_finit ( )
62 yaml_filename = "toy_dummy.yaml" ! default configuration file name
63 CALL parse_arguments(yaml_filename)
64 CALL yac_fread_config_yaml(yaml_filename)
65
66 ! Inform the coupler about what we are
67 comp_name = "dummy_ocean"
68 grid_name = "dummy_ocean_grid"
69 CALL yac_fdef_comp ( comp_name, comp_id )
70
71 print *, "YAC Version: ", trim(yac_fget_version())
72
73 CALL yac_fget_comp_comm ( comp_id, local_comm )
74 print *, 'Local Comm', local_comm
75
76 CALL mpi_comm_rank ( local_comm, rank, ierror )
77 CALL mpi_comm_size ( local_comm, npes, ierror )
78
79 WRITE ( 6 , * ) trim(comp_name), " rank ", rank, ": local size is ", npes
80
81 ALLOCATE(buffer_lon(nbr_vertices))
82 ALLOCATE(buffer_lat(nbr_vertices))
83 ALLOCATE(cell_to_vertex(3,nbr_cells))
84
85 nbr_vertices_per_cell = 3
86
87 ! Define vertices
88
89 ! 1
90 ! / \
91 ! / o \
92 ! / \
93 ! 2-------3 Eq.
94 ! \ /
95 ! \ o /
96 ! \ /
97 ! 4
98
99 buffer_lon(1) = 0.0 * yac_rad
100 buffer_lon(2) = -1.0 * yac_rad
101 buffer_lon(3) = 1.0 * yac_rad
102 buffer_lon(4) = 0.0 * yac_rad
103 buffer_lat(1) = 1.0 * yac_rad
104 buffer_lat(2) = 0.0 * yac_rad
105 buffer_lat(3) = 0.0 * yac_rad
106 buffer_lat(4) = -1.0 * yac_rad
107
108 ! Connectivity
109 cell_to_vertex(1,1) = 1
110 cell_to_vertex(2,1) = 2
111 cell_to_vertex(3,1) = 3 ! cell 1
112 cell_to_vertex(1,2) = 2
113 cell_to_vertex(2,2) = 4
114 cell_to_vertex(3,2) = 3 ! cell 2
115
116 ! Definition of an unstructured grid
117 CALL yac_fdef_grid ( &
118 & grid_name, &
119 & nbr_vertices, &
120 & nbr_cells, &
121 & nbr_vertices_per_cell, &
122 & buffer_lon, &
123 & buffer_lat, &
124 & cell_to_vertex, &
125 & grid_id )
126
127 ! Decomposition information
128
129 DO i = 1, nbr_cells
130 glb_index(i) = i
131 cell_core_mask(i) = 1
132 ENDDO
133
134 CALL yac_fset_global_index ( &
135 & glb_index, &
137 & grid_id )
138 CALL yac_fset_core_mask ( &
139 & cell_core_mask, &
141 & grid_id )
142
143 ! Center points in cells (needed e.g. for nearest neighbour)
144
145 buffer_lon(1) = 0.0 * yac_rad
146 buffer_lon(2) = 0.0 * yac_rad
147 buffer_lat(1) = 0.5 * yac_rad
148 buffer_lat(2) = -0.5 * yac_rad
149
150 CALL yac_fdef_points ( &
151 & grid_id, &
152 & nbr_cells, &
154 & buffer_lon, &
155 & buffer_lat, &
156 & cell_point_ids(1) )
157
158 DEALLOCATE (buffer_lon, buffer_lat, cell_to_vertex)
159
160 ! Mask generation
161 ALLOCATE(cell_mask(nbr_cells))
162 DO i = 1, nbr_cells
163 cell_mask(i) = 1
164 ENDDO
165
166 CALL yac_fset_mask ( &
167 & cell_mask, &
168 & cell_point_ids(1) )
169
170 DEALLOCATE (cell_mask)
171
172 field_name(1) = "surface_downward_eastward_stress" ! bundled field containing two components
173 field_name(2) = "surface_downward_northward_stress" ! bundled field containing two components
174 field_name(3) = "surface_fresh_water_flux" ! bundled field containing three components
175 field_name(4) = "surface_temperature"
176 field_name(5) = "total_heat_flux" ! bundled field containing four components
177 field_name(6) = "atmosphere_sea_ice_bundle" ! bundled field containing four components
178 field_name(7) = "sea_surface_temperature"
179 field_name(8) = "eastward_sea_water_velocity"
180 field_name(9) = "northward_sea_water_velocity"
181 field_name(10) = "ocean_sea_ice_bundle" ! bundled field containing four components
182 field_name(11) = "ocean_out1" ! output field
183 field_name(12) = "ocean_out2" ! output field
184 field_name(13) = "ocean_out3" ! output field
185 field_name(14) = "ocean_out4" ! output field
186
187 field_collection_size(1) = 2
188 field_collection_size(2) = 2
189 field_collection_size(3) = 3
190 field_collection_size(4) = 1
191 field_collection_size(5) = 4
192 field_collection_size(6) = 4
193 field_collection_size(7) = 1
194 field_collection_size(8) = 1
195 field_collection_size(9) = 1
196 field_collection_size(10) = 5
197 field_collection_size(11) = 1
198 field_collection_size(12) = 1
199 field_collection_size(13) = 1
200 field_collection_size(14) = 1
201
202 ALLOCATE(field_id(no_of_fields))
203
204 ! fields for coupling
205
206 DO i = 1, no_of_fields-4
207 CALL yac_fdef_field ( &
208 & field_name(i), &
209 & comp_id, &
210 & cell_point_ids, &
211 & 1, &
212 & field_collection_size(i), &
213 & "1", &
215 & field_id(i) )
216 ENDDO
217
218 ! fields for output server
219
220 DO i = no_of_fields-3, no_of_fields
221 CALL yac_fdef_field ( &
222 & field_name(i), &
223 & comp_id, &
224 & cell_point_ids, &
225 & 1, &
226 & field_collection_size(i), &
227 & "1", &
229 & field_id(i) )
230 ENDDO
231
232 CALL yac_fenddef ( )
233
234 ! Data exchange
235
236 ALLOCATE(buffer(nbr_cells,5))
237 buffer(:,:) = 0.0_wp
238
239 ! field_id(1) represents "TAUX" wind stress component
240 ! field_id(2) represents "TAUY" wind stress component
241 ! field_id(3) represents "SFWFLX" surface fresh water flux
242 ! field_id(4) represents "SFTEMP" surface temperature
243 ! field_id(5) represents "THFLX" total heat flux
244 ! field_id(6) represents "ICEATM" ice temperatures and melt potential
245 !
246 ! field_id(7) represents "SST" sea surface temperature
247 ! field_id(8) represents "OCEANU" u component of ocean surface current
248 ! field_id(9) represents "OCEANV" v component of ocean surface current
249 ! field_id(10)represents "ICEOCE" ice thickness, concentration and temperatures
250 !
251 ! field_id(11) - field_id(14) represent output fields
252 !
253 ! Get some info back from the coupling configuration
254 !
255 DO i = 1, no_of_fields
256 timestep_string = yac_fget_field_timestep( field_id(i) )
257 WRITE ( 6 , * ) "Field ID ", field_id(i), trim(timestep_string)
258 ENDDO
259
260 DO i = 1, no_of_fields
261 role = yac_fget_field_role( field_id(i) )
262 dummy_name = yac_fget_field_name_from_field_id( field_id(i) )
263 WRITE ( 6 , * ) "Requested role for ", trim(dummy_name) , " is ", role
264 ENDDO
265
266 !
267 ! Send fields from ocean to atmosphere
268 ! ------------------------------------
269 !
270 ! SST
271 buffer(:,1) = 110.0_wp
272 CALL yac_fput ( field_id(7), nbr_cells, 1, buffer(1:nbr_cells,1:1), info, ierror )
273 IF ( info > 0 ) &
274 WRITE ( 6 , * ) "ocean CPL SST", minval(buffer(1:nbr_cells,1:1)), maxval(buffer(1:nbr_cells,1:1))
275
276 ! zonal velocity
277 buffer(:,1) = 120.0_wp
278 CALL yac_fput ( field_id(8), nbr_cells, 1, buffer(1:nbr_cells,1:1), info, ierror )
279 IF ( info > 0 ) &
280 WRITE ( 6 , * ) "ocean CPL U", minval(buffer(1:nbr_cells,1:1)), maxval(buffer(1:nbr_cells,1:1))
281
282 ! meridional velocity
283 buffer(:,1) = 130.0_wp
284 CALL yac_fput ( field_id(9), nbr_cells, 1, buffer(1:nbr_cells,1:1), info, ierror )
285 IF ( info > 0 ) &
286 WRITE ( 6 , * ) "ocean CPL V", minval(buffer(1:nbr_cells,1:1)), maxval(buffer(1:nbr_cells,1:1))
287
288 ! Ice thickness, concentration, T1 and T2
289 buffer(:,1) = 140.1_wp
290 buffer(:,2) = 140.2_wp
291 buffer(:,3) = 140.3_wp
292 buffer(:,4) = 140.4_wp
293 buffer(:,5) = 140.5_wp
294
295 CALL yac_fput ( field_id(10), nbr_cells, 5, buffer(1:nbr_cells,1:5), info, ierror )
296 IF ( info > 0 ) THEN
297 WRITE ( 6 , * ) "ocean CPL ice 1", minval(buffer(1:nbr_cells,1:1)), maxval(buffer(1:nbr_cells,1:1))
298 WRITE ( 6 , * ) "ocean CPL ice 2", minval(buffer(1:nbr_cells,2:2)), maxval(buffer(1:nbr_cells,2:2))
299 WRITE ( 6 , * ) "ocean CPL ice 3", minval(buffer(1:nbr_cells,3:3)), maxval(buffer(1:nbr_cells,3:3))
300 WRITE ( 6 , * ) "ocean CPL ice 4", minval(buffer(1:nbr_cells,4:4)), maxval(buffer(1:nbr_cells,4:4))
301 WRITE ( 6 , * ) "ocean CPL ice 5", minval(buffer(1:nbr_cells,5:5)), maxval(buffer(1:nbr_cells,5:5))
302 ENDIF
303
304 !
305 ! Receive fields from atmosphere
306 ! ------------------------------
307
308 ! zonal wind stress
309
310 CALL yac_fget ( field_id(1), nbr_cells, 2, buffer, info, ierror )
311
312 ! meridional wind stress
313
314 CALL yac_fget ( field_id(2), nbr_cells, 2, buffer, info, ierror )
315
316 ! freshwater flux
317
318 CALL yac_fget ( field_id(3), nbr_cells, 3, buffer, info, ierror )
319
320 ! surface air temperature
321 CALL yac_fget ( field_id(4), nbr_cells, 1, buffer, info, ierror )
322
323 ! total heat flux - 4 parts - record 5
324
325 CALL yac_fget ( field_id(5), nbr_cells, 4, buffer, info, ierror )
326
327 ! ice parameter
328
329 CALL yac_fget ( field_id(6), nbr_cells, 4, buffer, info, ierror )
330
331 DEALLOCATE(buffer)
332 DEALLOCATE(field_id)
333
334 CALL yac_ffinalize
335
336 CALL mpi_finalize (ierror)
337
338CONTAINS
339
340 SUBROUTINE parse_arguments(configFilename)
341
342 CHARACTER(LEN=max_char_length) :: configFilename
343
344 CHARACTER(LEN=max_char_length) :: arg
345 INTEGER :: i
346 LOGICAL :: skip_arg = .false.
347
348 DO i = 1, command_argument_count()
349
350 IF (.NOT. skip_arg) THEN
351
352 CALL get_command_argument(i, arg)
353
354 SELECT CASE (arg)
355
356 CASE ('-c')
357 IF (i == command_argument_count()) THEN
358 print '(2a, /)', 'missing parameter for command-line option: ', arg
359 print '(a, /)', 'command-line options:'
360 print '(a)', ' -c configFilename'
361 stop
362 ELSE
363 CALL get_command_argument(i+1, configfilename)
364 skip_arg = .true.
365 END IF
366
367 CASE default
368 print '(2a, /)', 'unrecognised command-line option: ', arg
369 print '(a, /)', 'command-line options:'
370 print '(a)', ' -c configFilename'
371 stop
372 END SELECT
373 ELSE
374 skip_arg = .false.
375 END IF
376 END DO
377
378 END SUBROUTINE parse_arguments
379
380END PROGRAM dummy_ocean
program dummy_ocean
Fortran interface for the definition of coupling fields using default masks.
Fortran interface for the definition of grids.
Fortran interface for the definition of points.
Fortran interface for invoking the end of the definition phase.
Fortran interface for the coupler termination.
Fortran interface for getting back a local MPI communicator.
Fortran interface for getting the YAC version.
Fortran interface for receiving coupling fields.
Fortran interface for sending coupling fields.
Fortran interface for the reading of configuration files.
Fortran interface for the setting of a grid core masks.
Fortran interface for the setting of grid global ids.
Fortran interface for the setting of default pointset masks.
@ yac_location_cell
@ yac_time_unit_second
static void parse_arguments(int argc, char **argv, enum experiment_type *experiment)
Definition toy_scrip.c:490
character(len=:) function, allocatable yac_fget_field_name_from_field_id(field_id)