ICON Community Interface 0.4.0
Loading...
Searching...
No Matches
yaxt_nest_fortran_plugin.F90
Go to the documentation of this file.
1! --------------------------------------------------------------------
3! using the YAXT library to set up child/parent communication and
4! get the owner PE of cells...
5!
6! @authors 07/2025 :: ICON Community Interface <comin@icon-model.org>
7!
8! --------------------------------------------------------------------
10
11 USE comin_plugin_interface, ONLY: comin_callback_register &
12 , comin_var_get &
13 , t_comin_var_descriptor &
14 , t_comin_var_handle &
15 , comin_descrdata_get_domain &
16 , t_comin_descrdata_domain &
17 , comin_descrdata_get_global &
18 , t_comin_descrdata_global &
19 , t_comin_setup_version_info &
20 , comin_setup_get_version &
21 , ep_secondary_constructor &
22 , ep_destructor &
23 , ep_atm_integrate_end &
24 , comin_flag_read &
25 , comin_flag_write &
26 , comin_zaxis_2d &
27 , comin_parallel_get_host_mpi_rank &
28 , comin_current_get_domain_id &
29 , comin_parallel_get_plugin_mpi_comm &
30 , comin_domain_outside_loop &
31 , t_comin_plugin_info &
32 , comin_current_get_plugin_info &
33 , comin_plugin_finish &
34 , comin_metadata_get &
35 , comin_metadata_set &
36 , comin_var_request_add &
37 , comin_error_check, comin_print_info &
38 , comin_print_debug
39 USE yaxt, ONLY: xt_redist
40
41 IMPLICIT NONE
42
43 CHARACTER(LEN=*), PARAMETER :: pluginname = "yaxt_nest_fortran_plugin"
44
46 INTEGER, PARAMETER :: wp = selected_real_kind(12, 307)
47 TYPE(t_comin_setup_version_info) :: version
48
49 TYPE(t_comin_var_handle), ALLOCATABLE :: temp(:) ! temperature
50 TYPE(t_comin_var_handle), ALLOCATABLE :: temp_diag(:) ! temperature
51 INTEGER :: rank
52 INTEGER :: n_dom, nproma
53
55 TYPE(t_comin_descrdata_global), POINTER :: p_global
57 TYPE(t_comin_descrdata_domain), POINTER :: ptr
58 END TYPE t_patch
59 TYPE(t_patch), ALLOCATABLE :: p_patch(:)
60
62 TYPE(xt_redist), ALLOCATABLE :: yaxt_redist(:)
63
64 CHARACTER(LEN=120) :: text
65
66CONTAINS
67
68 ! --------------------------------------------------------------------
69 ! ComIn primary constructor.
70 ! --------------------------------------------------------------------
71 SUBROUTINE comin_main() BIND(C)
72
73 USE yaxt, ONLY: xt_initialize, xt_idxlist, xt_idxlist_delete &
74 , xt_xmap, xt_xmap_delete, xt_idxstripes_new, xt_idxvec_new &
75 , xt_stripe, xt_idxempty_new, xt_xmap_dist_dir_new &
76 , xt_redist_p2p_new, xt_initialized, xi => xt_int_kind
77 USE mpi, ONLY: mpi_double_precision
78
79 CHARACTER(LEN=*), PARAMETER :: substr = 'comin_main (yaxt_nest_fortran_plugin)'
80 TYPE(t_comin_plugin_info) :: this_plugin
81 TYPE(t_comin_var_descriptor) :: temp_d
82 INTEGER :: p_all_comm ! communicator of all ICON tasks
83 TYPE(xt_idxlist) :: src_idxlist, tgt_idxlist
84 TYPE(xt_xmap) :: xmap
85 INTEGER :: ii, ic, cid
86 INTEGER, DIMENSION(:), ALLOCATABLE :: src_indices, parent_indices, tgt_indices
87
89 rank = comin_parallel_get_host_mpi_rank()
90 CALL comin_print_info("setup")
91
93 version = comin_setup_get_version()
94 IF (version%version_no_major > 1) THEN
95 CALL comin_plugin_finish(substr, "incompatible ComIn library version!")
96 END IF
97
99 CALL comin_current_get_plugin_info(this_plugin)
100 WRITE (text, '(a,a,a,i4)') " plugin " &
101 , trim(this_plugin%name), " has id: ", this_plugin%id
102 CALL comin_print_info(text)
103
105 ! not applicable for this example
106
108 CALL comin_callback_register(ep_secondary_constructor &
110 CALL comin_callback_register(ep_atm_integrate_end &
112 CALL comin_callback_register(ep_destructor &
114
116 p_global => comin_descrdata_get_global()
117 nproma = p_global%nproma
118 n_dom = p_global%n_dom
119 IF (n_dom == 1) THEN
120 CALL comin_plugin_finish(substr, "only applicable for nested domain setups")
121 END IF
122 ALLOCATE (p_patch(n_dom))
123 DO ii = 1, n_dom
124 p_patch(ii)%ptr => comin_descrdata_get_domain(ii)
125 END DO
126
128 p_all_comm = comin_parallel_get_plugin_mpi_comm()
129 IF (.NOT. xt_initialized()) THEN
130 CALL comin_print_info("Initialize yaxt...")
131 CALL xt_initialize(p_all_comm)
132 END IF
133
135 ALLOCATE (yaxt_redist(n_dom))
136 DO ii = 1, n_dom
137 DO ic = 1, p_patch(ii)%ptr%n_childdom
138 cid = p_patch(ii)%ptr%child_id(ic)
139 ALLOCATE (src_indices(count(p_patch(ii)%ptr%cells%decomp_domain == 0)))
140 ALLOCATE (parent_indices(SIZE(p_patch(cid)%ptr%cells%parent_glb_idx)))
141 ALLOCATE (tgt_indices(count(p_patch(cid)%ptr%cells%decomp_domain >= 0)))
142 ! assign values to source indices: if reshaped array of child_id for this
143 ! parent equals the current child id (cid): use global index, else: -1
144 src_indices = merge(p_patch(ii)%ptr%cells%glb_index, -1_xi &
145 & , reshape(p_patch(ii)%ptr%cells%child_id &
146 & , (/SIZE(p_patch(ii)%ptr%cells%child_id)/)) == cid)
147 ! compute 1D global parent index for each cell
148 parent_indices = idx_1d(reshape(p_patch(cid)%ptr%cells%parent_glb_idx &
149 & , (/SIZE(p_patch(cid)%ptr%cells%parent_glb_idx)/)) &
150 & , reshape(p_patch(cid)%ptr%cells%parent_glb_blk &
151 & , (/SIZE(p_patch(cid)%ptr%cells%parent_glb_blk)/)))
152 ! restrict target indices to the cells owned by the task
153 tgt_indices = pack(parent_indices &
154 & , reshape(p_patch(cid)%ptr%cells%decomp_domain &
155 & , (/SIZE(p_patch(cid)%ptr%cells%decomp_domain)/)) >= 0)
156
157 src_idxlist = xt_idxvec_new(src_indices, SIZE(src_indices, 1))
158 tgt_idxlist = xt_idxvec_new(tgt_indices, SIZE(tgt_indices, 1))
159
160 ! ... create exchange map ...
161 xmap = xt_xmap_dist_dir_new(src_idxlist, tgt_idxlist, p_all_comm)
162
163 ! ... create redistribution instance for DP ...
164 yaxt_redist(cid) = xt_redist_p2p_new(xmap, mpi_double_precision)
165
166 ! ... clean up
167 CALL xt_xmap_delete(xmap)
168 CALL xt_idxlist_delete(src_idxlist)
169 CALL xt_idxlist_delete(tgt_idxlist)
170 DEALLOCATE (src_indices, parent_indices, tgt_indices)
171 END DO
172
173 temp_d = t_comin_var_descriptor(id=ii, name="temp_yaxt_diag")
174 CALL comin_var_request_add(temp_d, .true.)
175 CALL comin_metadata_set(temp_d, "zaxis_id", comin_zaxis_2d)
176 CALL comin_metadata_set(temp_d, "tracer", .false.)
177 CALL comin_metadata_set(temp_d, "restart", .false.)
178 CALL comin_metadata_set(temp_d, "units", "K")
179 END DO
180
181 END SUBROUTINE comin_main
182
183 ! --------------------------------------------------------------------
184 ! ComIn secondary constructor.
185 ! --------------------------------------------------------------------
186 SUBROUTINE yaxt_nest_fortran_constructor() BIND(C)
187
188 USE yaxt, ONLY: xt_idxlist, xt_idxlist_delete &
189 , xt_xmap, xt_xmap_delete &
190 , xt_redist
191
192 INTEGER :: ii, pid
193
194 CALL comin_print_info("secondary constructor")
195
196 ALLOCATE (temp(n_dom), temp_diag(n_dom))
197 DO ii = 1, n_dom
198 CALL comin_print_info("request temperature")
199 CALL comin_var_get([ep_atm_integrate_end], &
200 & t_comin_var_descriptor(name='temp', id=ii), comin_flag_read, temp(ii))
201 CALL comin_print_info("request diagnostic temperature")
202 pid = p_patch(ii)%ptr%parent_id
203 IF (pid <= 0) cycle
204 CALL comin_var_get([ep_atm_integrate_end], &
205 & t_comin_var_descriptor(name='temp_yaxt_diag', id=ii), comin_flag_write, temp_diag(ii))
206 END DO
207 END SUBROUTINE yaxt_nest_fortran_constructor
208
209 ! --------------------------------------------------------------------
210 ! ComIn callback function.
211 ! --------------------------------------------------------------------
212 SUBROUTINE yaxt_nest_fortran_exchange() BIND(C)
213
214 USE yaxt, ONLY: xt_redist_s_exchange1
215 USE iso_c_binding, ONLY: c_loc
216
217 INTEGER :: domain_id, pid
218 REAL(kind=wp), DIMENSION(:,:), POINTER :: src
219 REAL(kind=wp), DIMENSION(:, :, :), POINTER :: temp3d, tgt
220
221 CALL comin_print_info("callback before output")
222
223 domain_id = comin_current_get_domain_id()
224 IF (domain_id == comin_domain_outside_loop) THEN
225 CALL comin_print_debug("currently not in domain loop")
226 RETURN
227 ELSE
228 WRITE (text, '(a,a,i0)') "currently on domain ", domain_id
229 CALL comin_print_debug(text)
230 END IF
231
232 pid = p_patch(domain_id)%ptr%parent_id
233 IF (pid <= 0) RETURN
234
235 CALL temp_diag(domain_id)%to_3d(tgt)
236 tgt = 0._wp
237
238 CALL temp(pid)%to_3d(temp3d)
239 ALLOCATE (src(p_global%nproma,p_patch(pid)%ptr%cells%nblks))
240 ! select the near surface temperature as source variable field
241 src(:,:) = temp3d(:,p_patch(pid)%ptr%nlev,:)
242
244 CALL xt_redist_s_exchange1(yaxt_redist(domain_id), c_loc(src), c_loc(tgt))
245 ! find the min/max temperatures, filter out 0 values
246 WRITE(text, '(a,2(1x,f7.3))') ': min/max temperature src' &
247 , minval(pack(src, src > 0._wp)), maxval(pack(src, src > 0._wp))
248 CALL comin_print_info(text)
249 WRITE(text, '(a,2(1x,f7.3))') ': min/max temperature tgt' &
250 , minval(pack(tgt, tgt > 0._wp)), maxval(pack(tgt, tgt > 0._wp))
251 CALL comin_print_info(text)
252 DEALLOCATE(src)
253
254 END SUBROUTINE yaxt_nest_fortran_exchange
255
256 ! --------------------------------------------------------------------
257 ! ComIn callback function.
258 ! --------------------------------------------------------------------
259 SUBROUTINE yaxt_nest_fortran_destructor() BIND(C)
260
261 USE yaxt, ONLY: xt_finalize, xt_redist_delete
262
263 INTEGER :: ii, pid
264
265 CALL comin_print_info("destructor")
266
268 DO ii = 1, n_dom
269 pid = p_patch(ii)%ptr%parent_id
270 IF (pid <= 0) cycle
271 CALL xt_redist_delete(yaxt_redist(ii))
272 END DO
273 DEALLOCATE (temp, temp_diag, p_patch)
274
276 CALL xt_finalize()
277
278 END SUBROUTINE yaxt_nest_fortran_destructor
279
280 ELEMENTAL INTEGER FUNCTION idx_1d(jl, jb)
281 INTEGER, INTENT(IN) :: jl, jb
282 IF (jb <= 0) THEN
283 idx_1d = 0 ! This covers the special case nproma==1,jb=0,jl=1
284 ! All other cases are invalid and get also a 0 returned
285 ELSE
286 idx_1d = sign((jb - 1)*nproma + abs(jl), jl)
287 END IF
288 END FUNCTION idx_1d
289
Example plugin for the ICON Community Interface (ComIn)
elemental integer function idx_1d(jl, jb)
character(len= *), parameter pluginname
integer, parameter wp
working precision (will be compared to ComIn's and ICON's)
type(t_comin_var_handle), dimension(:), allocatable temp
type(t_comin_setup_version_info) version
type(t_comin_var_handle), dimension(:), allocatable temp_diag
type(t_comin_descrdata_global), pointer p_global
access descriptive data structures
type(t_patch), dimension(:), allocatable p_patch
void comin_main()