ComIn 0.5.1
ICON Community Interface
Loading...
Searching...
No Matches
comin_variable_types.F90
Go to the documentation of this file.
1!> @file comin_variable_types.F90
2!! @brief Data types for variable definition
3!
4! @authors 08/2021 :: ICON Community Interface <comin@icon-model.org>
5!
6! SPDX-License-Identifier: BSD-3-Clause
7!
8! See LICENSES for license information.
9! Where software is supplied by third parties, it is indicated in the
10! headers of the routines.
11!
13
14 USE iso_c_binding, ONLY: c_int, c_int64_t, c_char, c_bool, c_ptr, c_null_ptr, c_f_pointer, c_loc
21
22 IMPLICIT NONE
23
24 PUBLIC
25
26#include "comin_global.inc"
27
28 ! ------------------------------------
29 ! data types for variable definition
30 ! ------------------------------------
31
32 !> Variable descriptor.
33 !! identifies (uniquely) a variable. Do not confuse with meta-data
34 !! @ingroup fortran_interface
36 CHARACTER(LEN=:), ALLOCATABLE :: name
37 ! domain id
38 INTEGER :: id
40
42 MODULE PROCEDURE create_comin_var_descriptor
44 END INTERFACE
45
46 TYPE, BIND(C) :: t_comin_var_descriptor_c
47 CHARACTER(KIND=c_char) :: name(comin_max_len_var_name+1)
48 ! domain id
49 INTEGER(kind=c_int) :: id
51
54 END INTERFACE
55
56 !> Variable pointer. Fortran interface for accessing variables
57 !! @ingroup fortran_interface
59 !> pointer to the internal data structure, private (not part of the Fortran interface)
60 TYPE(t_comin_var_item), PRIVATE, POINTER :: var_item
61
62 CONTAINS
63 generic, PUBLIC :: get_ptr => get_ptr_dp, get_ptr_sp, get_ptr_i
64 PROCEDURE, PRIVATE :: get_ptr_dp => comin_var_get_ptr_dp
65 PROCEDURE, PRIVATE :: get_ptr_sp => comin_var_get_ptr_sp
66 PROCEDURE, PRIVATE :: get_ptr_i => comin_var_get_ptr_i
67 PROCEDURE, PUBLIC :: array_shape => comin_var_get_array_shape
68 PROCEDURE, PUBLIC :: descriptor => comin_var_get_descriptor
69 PROCEDURE, PUBLIC :: lcontainer => comin_var_get_lcontainer
70 PROCEDURE, PUBLIC :: ncontained => comin_var_get_ncontained
71 PROCEDURE, PUBLIC :: dim_semantics => comin_var_get_dim_semantics
72 PROCEDURE, PUBLIC :: valid => comin_var_get_valid
73 generic, PUBLIC :: to_3d => to_3d_dp, to_3d_sp, to_3d_i
74 PROCEDURE, PRIVATE :: to_3d_dp => comin_var_to_3d_dp
75 PROCEDURE, PRIVATE :: to_3d_sp => comin_var_to_3d_sp
76 PROCEDURE, PRIVATE :: to_3d_i => comin_var_to_3d_i
77 END TYPE t_comin_var_handle
78
79 !> Variable item
80 TYPE, BIND(C) :: t_comin_var_item
81 !> the var_descriptor
82 TYPE(t_comin_var_descriptor_c) :: descriptor
83
84 !> the (current) pointer to the data
85 ! REAL(wp), POINTER :: ptr(:,:,:,:,:) => NULL()
86 TYPE(c_ptr) :: cptr = c_null_ptr
87
88 !> type id for the array cptr is pointing to
89 INTEGER(KIND=C_INT) :: type_id
90
91 !> shape for the array cptr is pointing to
92 INTEGER(KIND=C_INT) :: array_shape(5)
93
94 !> the (current) device ptr to the data (if any)
95 TYPE(c_ptr) :: device_ptr = c_null_ptr
96
97 ! index positions in the 5D array.
98 INTEGER(KIND=C_INT), DIMENSION(5) :: dim_semantics
99
100 !> if (tracer==.TRUE.) and (ncontained > 0), then the variable
101 ! pointer refers to an array slice pointer
102 ! ptr(:,:,:,:,ncontained)
103 INTEGER(KIND=C_INT) :: ncontained = 0
104 !> LOGICAL flag. TRUE, if this is a container (contains variables)
105 LOGICAL(kind=c_bool) :: lcontainer = .false.
106
107 !> metadata store, pointer to TYPE(t_comin_var_metadata)
108 TYPE(c_ptr) :: metadata
109 END TYPE t_comin_var_item
110
111 INTERFACE
112 SUBROUTINE comin_var_sync_device_mem_fct(ptr, device_ptr, datatype, array_shape, direction) BIND(C)
113 IMPORT c_ptr, c_int
114 TYPE(c_ptr), VALUE, INTENT(IN) :: ptr, device_ptr
115 INTEGER(C_INT), VALUE, INTENT(IN) :: datatype
116 INTEGER(C_INT), INTENT(IN) :: array_shape(5)
117 INTEGER(C_INT), VALUE, INTENT(IN) :: direction
118 END SUBROUTINE comin_var_sync_device_mem_fct
119 END INTERFACE
120 INTERFACE
121 SUBROUTINE comin_var_sync_halo_fct(jg, ptr, datatype, array_shape, dim_semantics) BIND(C)
122 IMPORT c_ptr, c_int
123 INTEGER(C_INT), VALUE, INTENT(IN) :: jg
124 TYPE(c_ptr), VALUE, INTENT(IN) :: ptr
125 INTEGER(C_INT), VALUE, INTENT(IN) :: datatype
126 INTEGER(C_INT), INTENT(IN) :: array_shape(5), dim_semantics(5)
127 END SUBROUTINE comin_var_sync_halo_fct
128 END INTERFACE
129
130CONTAINS
131
132 !> Create a variable descriptor from a variable name and id.
133 FUNCTION create_comin_var_descriptor(name, id) RESULT(desc)
134 CHARACTER(len=*), INTENT(IN) :: name
135 INTEGER, INTENT(IN) :: id
136
137 TYPE(t_comin_var_descriptor) :: desc
138
139 desc%name = trim(adjustl(name))
140 desc%id = id
141 END FUNCTION create_comin_var_descriptor
142
143 !> Create a variable descriptor from a C structure.
144 FUNCTION create_comin_var_descriptor_from_c(desc_c) RESULT(desc)
145 TYPE(t_comin_var_descriptor_c), INTENT(IN) :: desc_c
146 TYPE(t_comin_var_descriptor) :: desc
147
148 desc = create_comin_var_descriptor(convert_c_string(desc_c%name), desc_c%id)
150
151 !> Create a variable descriptor (C version) from a Fortran structure.
152 FUNCTION create_comin_var_descriptor_from_ftn(desc_ftn) RESULT(desc)
153 TYPE(t_comin_var_descriptor), INTENT(IN) :: desc_ftn
154 TYPE(t_comin_var_descriptor_c) :: desc
155
156 desc%id = desc_ftn%id
157 CALL convert_f_string(trim(desc_ftn%name), desc%name)
159
160 !> compare two variable descriptors.
161 FUNCTION comin_var_descr_match(var_descriptor1, var_descriptor2)
162 TYPE(t_comin_var_descriptor), INTENT(IN) :: var_descriptor1, var_descriptor2
163 LOGICAL :: comin_var_descr_match
164 ! local
165 LOGICAL :: l_name, l_domain
166
167 l_domain = (var_descriptor1%id == var_descriptor2%id)
168 comin_var_descr_match = l_domain
169 IF (.NOT. comin_var_descr_match) RETURN
170 l_name = (var_descriptor1%name == var_descriptor2%name)
171 comin_var_descr_match = l_name
172 END FUNCTION comin_var_descr_match
173
174 FUNCTION comin_var_ptr_init(var_item) &
175 result(var_ptr)
176 TYPE(t_comin_var_item), POINTER, INTENT(IN) :: var_item
177 TYPE(t_comin_var_handle) :: var_ptr
178 var_ptr = t_comin_var_handle(var_item = var_item)
179 END FUNCTION comin_var_ptr_init
180
181 SUBROUTINE comin_var_get_ptr_dp(this, ptr)
182 CLASS(t_comin_var_handle), INTENT(IN) :: this
183 REAL(dp), POINTER, INTENT(INOUT) :: ptr(:,:,:,:,:)
184
185 CALL c_f_pointer(this%var_item%cptr, ptr, this%var_item%array_shape)
186 END SUBROUTINE comin_var_get_ptr_dp
187
188 SUBROUTINE comin_var_get_ptr_sp(this, ptr)
189 CLASS(t_comin_var_handle), INTENT(IN) :: this
190 REAL(sp), POINTER, INTENT(INOUT) :: ptr(:,:,:,:,:)
191
192 CALL c_f_pointer(this%var_item%cptr, ptr, this%var_item%array_shape)
193 END SUBROUTINE comin_var_get_ptr_sp
194
195 SUBROUTINE comin_var_get_ptr_i(this, ptr)
196 CLASS(t_comin_var_handle), INTENT(IN) :: this
197 INTEGER(C_INT), POINTER, INTENT(INOUT) :: ptr(:,:,:,:,:)
198
199 CALL c_f_pointer(this%var_item%cptr, ptr, this%var_item%array_shape)
200 END SUBROUTINE comin_var_get_ptr_i
201
203 result(array_shape)
204 CLASS(t_comin_var_handle), INTENT(IN) :: this
205 INTEGER :: array_shape(5)
206 array_shape = this%var_item%array_shape
207 END FUNCTION comin_var_get_array_shape
208
210 result(descriptor)
211 CLASS(t_comin_var_handle), INTENT(IN) :: this
212 TYPE(t_comin_var_descriptor) :: descriptor
213 descriptor = t_comin_var_descriptor(this%var_item%descriptor)
214 END FUNCTION comin_var_get_descriptor
215
217 result(lcontainer)
218 CLASS(t_comin_var_handle), INTENT(IN) :: this
219 LOGICAL :: lcontainer
220 lcontainer = this%var_item%lcontainer
221 END FUNCTION comin_var_get_lcontainer
222
224 result(ncontained)
225 CLASS(t_comin_var_handle), INTENT(IN) :: this
226 INTEGER :: ncontained
227 ncontained = this%var_item%ncontained
228 END FUNCTION comin_var_get_ncontained
229
231 result(dim_semantics)
232 CLASS(t_comin_var_handle), INTENT(IN) :: this
233 INTEGER :: dim_semantics(5)
234 dim_semantics = this%var_item%dim_semantics
235 END FUNCTION comin_var_get_dim_semantics
236
237 FUNCTION comin_var_get_valid(this) &
238 result(valid)
239 CLASS(t_comin_var_handle), INTENT(IN) :: this
240 LOGICAL :: valid
241 valid = ASSOCIATED(this%var_item)
242 END FUNCTION comin_var_get_valid
243
244 !> Convenience operation for accessing 2D/3D fields.
245 !! @ingroup fortran_interface
246 !!
247 !! Assumes that the last dimension is not used!
248 SUBROUTINE comin_var_to_3d_dp(var, slice)
249 CLASS(t_comin_var_handle), INTENT(IN) :: var
250 REAL(dp), POINTER :: slice(:,:,:)
251 REAL(dp), POINTER :: tmp_ptr(:,:,:,:,:)
252 INTEGER :: pos_jn
253
254 ! this operation is invalid if the field is a container
255 IF (var%lcontainer()) THEN
256 CALL comin_plugin_finish("comin_var_to_3d", &
257 & " ERROR: Attempt to convert container variable into 3D field.")
258 END IF
259
260 CALL var%get_ptr(tmp_ptr)
261
262 pos_jn = findloc(var%dim_semantics(), comin_dim_semantics_container, dim=1)
263 SELECT CASE (pos_jn)
264 CASE(1)
265 slice => tmp_ptr(1, :, :, :, 1)
266 CASE(2)
267 slice => tmp_ptr(:, 1, :, :, 1)
268 CASE(3)
269 slice => tmp_ptr(:, :, 1, :, 1)
270 CASE DEFAULT
271 slice => tmp_ptr(:, :, :, 1, 1)
272 END SELECT
273 END SUBROUTINE comin_var_to_3d_dp
274
275 !> Convenience operation for accessing 2D/3D fields.
276 !! @ingroup fortran_interface
277 !!
278 !! Assumes that the last dimension is not used!
279 SUBROUTINE comin_var_to_3d_sp(var, slice)
280 CLASS(t_comin_var_handle), INTENT(IN) :: var
281 REAL(sp), POINTER :: slice(:,:,:)
282 REAL(sp), POINTER :: tmp_ptr(:,:,:,:,:)
283 INTEGER :: pos_jn
284
285 ! this operation is invalid if the field is a container
286 IF (var%lcontainer()) THEN
287 CALL comin_plugin_finish("comin_var_to_3d", &
288 & " ERROR: Attempt to convert container variable into 3D field.")
289 END IF
290
291 CALL var%get_ptr(tmp_ptr)
292
293 pos_jn = findloc(var%dim_semantics(), comin_dim_semantics_container, dim=1)
294 SELECT CASE (pos_jn)
295 CASE(1)
296 slice => tmp_ptr(1, :, :, :, 1)
297 CASE(2)
298 slice => tmp_ptr(:, 1, :, :, 1)
299 CASE(3)
300 slice => tmp_ptr(:, :, 1, :, 1)
301 CASE DEFAULT
302 slice => tmp_ptr(:, :, :, 1, 1)
303 END SELECT
304 END SUBROUTINE comin_var_to_3d_sp
305
306 !> Convenience operation for accessing 2D/3D fields.
307 !! @ingroup fortran_interface
308 !!
309 !! Assumes that the last dimension is not used!
310 SUBROUTINE comin_var_to_3d_i(var, slice)
311 CLASS(t_comin_var_handle), INTENT(IN) :: var
312 INTEGER(C_INT), POINTER :: slice(:,:,:)
313 INTEGER(C_INT), POINTER :: tmp_ptr(:,:,:,:,:)
314 INTEGER :: pos_jn
315
316 ! this operation is invalid if the field is a container
317 IF (var%lcontainer()) THEN
318 CALL comin_plugin_finish("comin_var_to_3d", &
319 & " ERROR: Attempt to convert container variable into 3D field.")
320 END IF
321
322 CALL var%get_ptr(tmp_ptr)
323
324 pos_jn = findloc(var%dim_semantics(), comin_dim_semantics_container, dim=1)
325 SELECT CASE (pos_jn)
326 CASE(1)
327 slice => tmp_ptr(1, :, :, :, 1)
328 CASE(2)
329 slice => tmp_ptr(:, 1, :, :, 1)
330 CASE(3)
331 slice => tmp_ptr(:, :, 1, :, 1)
332 CASE DEFAULT
333 slice => tmp_ptr(:, :, :, 1, 1)
334 END SELECT
335 END SUBROUTINE comin_var_to_3d_i
336
337 SUBROUTINE comin_var_handle_set_cptr(var, cptr)
338 TYPE(t_comin_var_handle), INTENT(INOUT) :: var
339 TYPE(c_ptr), INTENT(IN) :: cptr
340
341 var%var_item%cptr = cptr
342#if defined(OPENACC)
343 var%var_item%device_ptr = acc_deviceptr(cptr)
344#endif
345
346 END SUBROUTINE
347
348END MODULE comin_variable_types
void comin_plugin_finish(const char *routine, const char *text)
Variable pointer. Fortran interface for accessing variables.
subroutine comin_var_to_3d_sp(var, slice)
Convenience operation for accessing 2D/3D fields.
integer, parameter wp
working precision
subroutine comin_var_to_3d_i(var, slice)
Convenience operation for accessing 2D/3D fields.
subroutine, public comin_plugin_finish(routine, text)
Wrapper function for callback to ICON's "finish" routine.
subroutine comin_var_to_3d_dp(var, slice)
Convenience operation for accessing 2D/3D fields.
subroutine, public convert_f_string(string, arr)
Convert Fortran string into C-style character array.
integer function, dimension(5) comin_var_get_dim_semantics(this)
type(t_comin_var_handle) function comin_var_ptr_init(var_item)
integer function, dimension(5) comin_var_get_array_shape(this)
subroutine comin_var_get_ptr_dp(this, ptr)
type(t_comin_var_descriptor) function create_comin_var_descriptor_from_c(desc_c)
Create a variable descriptor from a C structure.
logical function comin_var_get_lcontainer(this)
integer function comin_var_get_ncontained(this)
type(t_comin_var_descriptor_c) function create_comin_var_descriptor_from_ftn(desc_ftn)
Create a variable descriptor (C version) from a Fortran structure.
logical function comin_var_descr_match(var_descriptor1, var_descriptor2)
compare two variable descriptors.
subroutine comin_var_handle_set_cptr(var, cptr)
type(t_comin_var_descriptor) function comin_var_get_descriptor(this)
subroutine comin_var_get_ptr_i(this, ptr)
type(t_comin_var_descriptor) function create_comin_var_descriptor(name, id)
Create a variable descriptor from a variable name and id.
subroutine comin_var_get_ptr_sp(this, ptr)
logical function comin_var_get_valid(this)