ICON Community Interface 0.4.0
Loading...
Searching...
No Matches
simple_fortran_plugin.F90
Go to the documentation of this file.
1! --------------------------------------------------------------------
3! with basic (not MPI-parallel) callbacks and accessing variables and
4! descriptive data structures.
5!
6! Note that in order to demonstrate ComIn's language interoperability,
7! a similary plugin has been implemented in C, see the subdirectory
8! "simple_c".
9!
10!
11! @authors 01/2023 :: ICON Community INTERFACE <comin@icon-model.org>
12!
13! SPDX-License-Identifier: BSD-3-Clause
14!
15! Please see the file LICENSE in the root of the source tree for this code.
16! Where software is supplied by third parties, it is indicated in the
17! headers of the routines.
18! --------------------------------------------------------------------
20 USE mpi
21 USE iso_c_binding, ONLY : c_int, c_ptr, c_f_pointer, c_associated
22 USE comin_plugin_interface, ONLY : comin_callback_register, &
23 & comin_var_get, comin_parallel_get_host_mpi_comm, &
24 & t_comin_var_descriptor, t_comin_var_handle, &
25 & comin_var_request_add, &
26 & comin_descrdata_get_domain, t_comin_descrdata_domain, &
27 & comin_descrdata_get_global, t_comin_descrdata_global, &
28 & comin_descrdata_get_simulation_interval, &
29 & t_comin_descrdata_simulation_interval, &
30 & t_comin_setup_version_info, comin_setup_get_version, &
31 & ep_secondary_constructor, ep_destructor, &
32 & ep_atm_physics_before, ep_atm_write_output_before, &
33 & comin_flag_read, comin_flag_write, comin_zaxis_2d, &
34 & comin_parallel_get_host_mpi_rank, comin_current_get_domain_id, &
35 & comin_domain_outside_loop, comin_callback_get_ep_name, &
36 & t_comin_plugin_info, comin_current_get_plugin_info, &
37 & comin_plugin_finish, comin_metadata_set, &
38 & comin_metadata_get, &
39 & comin_descrdata_get_timesteplength, comin_hgrid_unstructured_edge,&
40 & comin_error_check, comin_var_get_descr_list_head, &
41 & comin_var_get_descr_list_next, comin_var_get_descr_list_var_desc, &
42 & comin_error_check, comin_print_info, &
43 & comin_dim_semantics_nproma, comin_dim_semantics_level, &
44 & comin_dim_semantics_block, comin_dim_semantics_unused, &
45 & comin_var_datatype_double
46
47 IMPLICIT NONE
48
49 CHARACTER(LEN=*), PARAMETER :: pluginname = "simple_fortran_plugin"
50
52 INTEGER, PARAMETER :: wp = selected_real_kind(12,307)
53 TYPE(t_comin_setup_version_info) :: version
54
55 TYPE(t_comin_var_handle) :: pres, vn, simple_fortran_var, simple_fortran_tracer
56 INTEGER :: rank
57
59 TYPE(t_comin_descrdata_domain), POINTER :: p_patch
60 TYPE(t_comin_descrdata_global), POINTER :: p_global
61 TYPE(t_comin_descrdata_simulation_interval), POINTER :: p_simulation_interval
62
63 TYPE(t_comin_var_handle), ALLOCATABLE :: qv(:)
64
65 CHARACTER(LEN=200) :: text
66
67CONTAINS
68
69 ! --------------------------------------------------------------------
70 ! ComIn primary constructor.
71 ! --------------------------------------------------------------------
72 SUBROUTINE comin_main() BIND(C)
73 !
74 TYPE(t_comin_plugin_info) :: this_plugin
75 TYPE(t_comin_var_descriptor) :: simple_fortran_d, simple_fortran_tracer_d
76 REAL(wp) :: dtime_1, dtime_2
77
78 rank = comin_parallel_get_host_mpi_rank()
79 CALL comin_print_info("setup")
80
81 version = comin_setup_get_version()
82 IF (version%version_no_major > 1) THEN
83 CALL comin_plugin_finish("comin_main (simple_fortran_plugin)", "incompatible version!")
84 END IF
85
87 CALL comin_current_get_plugin_info(this_plugin)
88 WRITE (text,'(a,i4)') " plugin id: ", this_plugin%id
89 CALL comin_print_info(text)
90
92
93 ! request host model to add variable simple_fortran_var
94 simple_fortran_d = t_comin_var_descriptor(id = 1, name = "simple_fortran_var")
95 CALL comin_var_request_add(simple_fortran_d, .false.)
96 CALL comin_metadata_set(simple_fortran_d, "tracer", .false.)
97 CALL comin_metadata_set(simple_fortran_d, "restart", .false.)
98
99 ! request host model to add tracer simple_fortran_tracer
100 simple_fortran_tracer_d = t_comin_var_descriptor( id = -1, name = "simple_fortran_tracer" )
101 CALL comin_var_request_add(simple_fortran_tracer_d, .false.)
102 CALL comin_metadata_set(simple_fortran_tracer_d, "tracer", .true.)
103 CALL comin_metadata_set(simple_fortran_tracer_d, "restart", .false.)
104
105 ! register callbacks
106 CALL comin_callback_register(ep_secondary_constructor, simple_fortran_constructor)
107 CALL comin_callback_register(ep_atm_write_output_before, simple_fortran_diagfct)
108 CALL comin_callback_register(ep_destructor, simple_fortran_destructor)
109
110 ! get descriptive data structures
111 p_patch => comin_descrdata_get_domain(1)
112 p_global => comin_descrdata_get_global()
113 p_simulation_interval => comin_descrdata_get_simulation_interval()
114
115 dtime_1 = comin_descrdata_get_timesteplength(1)
116 dtime_2 = comin_descrdata_get_timesteplength(2)
117 WRITE(text,"(A,F5.0,F5.0)") " timesteplength from comin_descrdata_get_timesteplength", dtime_1, dtime_2
118 CALL comin_print_info(text)
119 END SUBROUTINE comin_main
120
121 ! --------------------------------------------------------------------
122 ! ComIn secondary constructor.
123 ! --------------------------------------------------------------------
124 SUBROUTINE simple_fortran_constructor() BIND(C)
125 TYPE(t_comin_var_descriptor) :: var_desc
126 INTEGER :: jg, hgrid_id, datatype
127 LOGICAL :: tracer, multi_timelevel
128 REAL(WP), POINTER :: tracer_slice(:,:,:)
129 TYPE(c_ptr) :: it
130 TYPE(t_comin_var_descriptor) :: descriptor
131
132 CALL comin_print_info("third party callback: secondary constructor.")
133 CALL comin_print_info("third party callback: iterate over variable list:")
134
135 it = comin_var_get_descr_list_head()
136 DO WHILE (c_associated(it))
137 CALL comin_var_get_descr_list_var_desc(it, descriptor)
138 WRITE (text,*) "Variable found: ", trim(descriptor%name), &
139 "(", descriptor%id, ")"
140 CALL comin_print_info(text)
141 it = comin_var_get_descr_list_next(it)
142 END DO
143
144 WRITE (text,*) " ", pluginname, " - register some variables in some context"
145 CALL comin_print_info(text)
146 var_desc = t_comin_var_descriptor('pres', 1)
147 CALL comin_var_get([ep_atm_write_output_before], &
148 & var_desc, comin_flag_read, pres)
149 IF (.NOT. pres%valid()) &
150 & CALL comin_plugin_finish("simple_fortran_constructor", "Internal error!")
151
152 IF (any(pres%dim_semantics() /= [comin_dim_semantics_nproma, &
153 & comin_dim_semantics_level, &
154 & comin_dim_semantics_block, &
155 & comin_dim_semantics_unused, &
156 & comin_dim_semantics_unused ])) &
157 & CALL comin_plugin_finish("simple_fortran_constructor", "Dimension check failed!")
158
159 var_desc = t_comin_var_descriptor('vn', 1)
160 CALL comin_var_get([ep_atm_write_output_before], &
161 & var_desc, comin_flag_read, vn)
162 IF (.NOT. vn%valid()) &
163 & CALL comin_plugin_finish("simple_fortran_constructor vn", "Internal error!")
164
165 CALL comin_metadata_get(var_desc, "hgrid_id", hgrid_id)
166 IF (hgrid_id/=comin_hgrid_unstructured_edge) &
167 & CALL comin_plugin_finish("comin_var_get_metadata_hgrid", "Internal error!")
168 CALL comin_metadata_get(var_desc, "multi_timelevel", multi_timelevel)
169
170 ALLOCATE(qv(p_global%n_dom))
171 DO jg =1, p_global%n_dom
172 CALL comin_var_get([ep_atm_write_output_before], &
173 & t_comin_var_descriptor(name='qv', id=jg), &
174 & comin_flag_read, qv(jg))
175 CALL comin_metadata_get(t_comin_var_descriptor(name='qv', id=jg), &
176 & "datatype", datatype)
177 IF (datatype/=comin_var_datatype_double) &
178 & CALL comin_plugin_finish("simple_fortran_constructor", "Internal error!")
179 IF (.NOT. qv(jg)%valid()) &
180 & CALL comin_plugin_finish("simple_fortran_constructor", "Internal error!")
181
182 IF (any(qv(jg)%dim_semantics() /= [ comin_dim_semantics_nproma, &
183 & comin_dim_semantics_level, &
184 & comin_dim_semantics_block, &
185 & comin_dim_semantics_unused, &
186 & comin_dim_semantics_unused ] )) &
187 & CALL comin_plugin_finish("simple_fortran_constructor", "Dimension check failed!")
188 END DO
189
190 CALL comin_var_get([ep_atm_write_output_before], &
191 & t_comin_var_descriptor(name="simple_fortran_var", id=1), &
192 & comin_flag_write, simple_fortran_var)
193 IF (.NOT. simple_fortran_var%valid()) &
194 & CALL comin_plugin_finish("simple_fortran_constructor", "Internal error!")
195
196 CALL comin_metadata_get(t_comin_var_descriptor(name="simple_fortran_var", id=1), &
197 & "tracer", tracer)
198
199 CALL comin_var_get([ep_atm_write_output_before], &
200 & t_comin_var_descriptor(name="simple_fortran_tracer", id=1), &
201 & comin_flag_write, simple_fortran_tracer)
202 IF (.NOT. simple_fortran_tracer%valid()) &
203 & CALL comin_plugin_finish("simple_fortran_constructor", "Internal error!")
204
205 ! access the "simple_fortran_tracer" via a 3D array pointer:
206 CALL simple_fortran_tracer%to_3d(tracer_slice)
207 tracer_slice(1,9,1) = 1.0
208 END SUBROUTINE simple_fortran_constructor
209
210 ! --------------------------------------------------------------------
211 ! ComIn callback function.
212 ! --------------------------------------------------------------------
213 SUBROUTINE simple_fortran_diagfct() BIND(C)
214 INTEGER :: ierr, domain_id, jg, comm, root
215 REAL(wp) :: local_max, global_max
216 REAL(wp), POINTER, DIMENSION(:,:,:,:,:) :: simple_fortran_ptr, &
217 & pres_ptr, qv_ptr
218
219 CALL comin_print_info("third party callback: before output.")
220
221 domain_id = comin_current_get_domain_id()
222
223 IF (domain_id == comin_domain_outside_loop) THEN
224 CALL comin_print_info("currently not in domain loop")
225 ELSE
226 WRITE(text,'(a,i0)') " currently on domain ", domain_id
227 CALL comin_print_info(text)
228 END IF
229
230 CALL simple_fortran_var%get_ptr(simple_fortran_ptr)
231 CALL pres%get_ptr(pres_ptr)
232 simple_fortran_ptr = pres_ptr + 42
233
234 DO jg =1, p_global%n_dom
235 comm = comin_parallel_get_host_mpi_comm()
236 CALL qv(jg)%get_ptr(qv_ptr)
237 local_max = maxval(qv_ptr)
238 root = 0
239 CALL mpi_reduce(local_max, global_max, 1, mpi_double_precision, mpi_max, root, comm, ierr)
240 WRITE(text,"(A,I8,A,F8.6)") "domain ", jg, ": global max = ", global_max
241 CALL comin_print_info(text)
242 END DO
243 END SUBROUTINE simple_fortran_diagfct
244
245 ! --------------------------------------------------------------------
246 ! ComIn callback function.
247 ! --------------------------------------------------------------------
248 SUBROUTINE simple_fortran_destructor() BIND(C)
249 CALL comin_print_info("third party callback: destructor.")
250 END SUBROUTINE simple_fortran_destructor
251
252END MODULE simple_fortran_plugin
Example plugin for the ICON Community Interface (ComIn)
type(t_comin_descrdata_global), pointer p_global
type(t_comin_var_handle), dimension(:), allocatable qv
type(t_comin_var_handle) vn
type(t_comin_var_handle) simple_fortran_tracer
type(t_comin_descrdata_simulation_interval), pointer p_simulation_interval
type(t_comin_setup_version_info) version
character(len= *), parameter pluginname
integer, parameter wp
working precision (will be compared to ComIn's and ICON's)
type(t_comin_descrdata_domain), pointer p_patch
access descriptive data structures
type(t_comin_var_handle) simple_fortran_var
void comin_main()