Neko 1.99.1
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
neko_api_user.f90
Go to the documentation of this file.
1! Copyright (c) 2025, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34submodule(neko_api) neko_api_user
35 implicit none
36
38 abstract interface
39 subroutine api_ic_callback(scheme_name, scheme_name_len) bind(c)
40 use, intrinsic :: iso_c_binding
41 implicit none
42 character(kind=c_char), dimension(*) :: scheme_name
43 integer(c_int), value :: scheme_name_len
44 end subroutine api_ic_callback
45 end interface
46
48 abstract interface
49 subroutine api_bc_callback(msk, msk_size, t, tstep) bind(c)
50 use, intrinsic :: iso_c_binding
51 import c_rp
52 implicit none
53 type(c_ptr), value :: msk
54 integer(c_int), value :: msk_size
55 real(kind=c_rp), value :: t
56 integer(c_int), value :: tstep
57 end subroutine api_bc_callback
58 end interface
59
62 abstract interface
63 subroutine api_ft_callback(scheme_name, scheme_name_len, t, tstep) bind(c)
64 use, intrinsic :: iso_c_binding
65 import c_rp
66 implicit none
67 character(kind=c_char), dimension(*) :: scheme_name
68 integer(c_int), value :: scheme_name_len
69 real(kind=c_rp), value :: t
70 integer(c_int), value :: tstep
71 end subroutine api_ft_callback
72 end interface
73
76 abstract interface
77 subroutine api_gn_callback(t, tstep) bind(c)
78 use, intrinsic :: iso_c_binding
79 import c_rp
80 implicit none
81 real(kind=c_rp), value :: t
82 integer(c_int), value :: tstep
83 end subroutine api_gn_callback
84 end interface
85
87 type api_user_cb
88 procedure(api_ic_callback), nopass, pointer :: initial
89 procedure(api_gn_callback), nopass, pointer :: preprocess
90 procedure(api_gn_callback), nopass, pointer :: compute
91 procedure(api_bc_callback), nopass, pointer :: dirichlet
92 procedure(api_ft_callback), nopass, pointer :: material
93 procedure(api_ft_callback), nopass, pointer :: source
94 end type api_user_cb
95
97 type(api_user_cb), allocatable :: neko_api_user_cb
98
100 type(field_list_t), pointer :: neko_api_cb_field_list => null()
101
102contains
103
112 module subroutine neko_api_user_cb_register(user, initial_cb, preprocess_cb, &
113 compute_cb, dirichlet_cb, material_cb, source_cb)
114 type(user_t), intent(inout) :: user
115 type(c_funptr), value :: initial_cb, preprocess_cb, compute_cb
116 type(c_funptr), value :: dirichlet_cb, material_cb, source_cb
117
118 ! Keeping neko_api_user_cb as an alloctable is a work around for
119 ! NAG which throws an incompatbile function pointer warning for
120 ! single precision
121 if (.not. allocated(neko_api_user_cb)) then
122 allocate(neko_api_user_cb)
123 neko_api_user_cb%initial => null()
124 neko_api_user_cb%preprocess => null()
125 neko_api_user_cb%compute => null()
126 neko_api_user_cb%dirichlet => null()
127 neko_api_user_cb%material => null()
128 neko_api_user_cb%source => null()
129 end if
130
131 ! We need the block construct in the following if statements to
132 ! adhere strictly with the f2008 standard, and support compilers
133 ! not implementing TS29133 (mainly GNU Fortran with -std=f2008)
134 if (c_associated(initial_cb)) then
135 user%initial_conditions => neko_api_user_initial_condition
136 block
137 procedure(api_ic_callback), pointer :: tmp
138 call c_f_procpointer(initial_cb, tmp)
139 neko_api_user_cb%initial => tmp
140 end block
141 end if
142
143 if (c_associated(preprocess_cb)) then
144 user%preprocess => neko_api_user_preprocess
145 block
146 procedure(api_gn_callback), pointer :: tmp
147 call c_f_procpointer(preprocess_cb, tmp)
148 neko_api_user_cb%preprocess => tmp
149 end block
150 end if
151
152 if (c_associated(compute_cb)) then
153 user%compute => neko_api_user_compute
154 block
155 procedure(api_gn_callback), pointer :: tmp
156 call c_f_procpointer(compute_cb, tmp)
157 neko_api_user_cb%compute => tmp
158 end block
159 end if
160
161 if (c_associated(dirichlet_cb)) then
162 user%dirichlet_conditions => neko_api_user_dirichlet_condition
163 block
164 procedure(api_bc_callback), pointer :: tmp
165 call c_f_procpointer(dirichlet_cb, tmp)
166 neko_api_user_cb%dirichlet => tmp
167 end block
168 end if
169
170 if (c_associated(material_cb)) then
171 user%material_properties => neko_api_user_material_properties
172 block
173 procedure(api_ft_callback), pointer :: tmp
174 call c_f_procpointer(material_cb, tmp)
175 neko_api_user_cb%material => tmp
176 end block
177 end if
178
179 if (c_associated(source_cb)) then
180 user%source_term => neko_api_user_source_term
181 block
182 procedure(api_ft_callback), pointer :: tmp
183 call c_f_procpointer(source_cb, tmp)
184 neko_api_user_cb%source => tmp
185 end block
186 end if
187
188 end subroutine neko_api_user_cb_register
189
191 subroutine neko_api_user_initial_condition(scheme_name, fields)
192 character(len=*), intent(in) :: scheme_name
193 type(field_list_t), intent(inout) :: fields
194
195 if (associated(neko_api_user_cb%initial)) then
196 call neko_api_user_cb%initial(trim(scheme_name), len_trim(scheme_name))
197 else
198 call neko_error("Initial condition callback not defined")
199 end if
200
201 end subroutine neko_api_user_initial_condition
202
204 subroutine neko_api_user_preprocess(time)
205 type(time_state_t), intent(in) :: time
206
207 if (associated(neko_api_user_cb%preprocess)) then
208 call neko_api_user_cb%preprocess(time%t, time%tstep)
209 else
210 call neko_error("Preprocessing callback not defined")
211 end if
212
213 end subroutine neko_api_user_preprocess
214
216 subroutine neko_api_user_compute(time)
217 type(time_state_t), intent(in) :: time
218
219 if (associated(neko_api_user_cb%compute)) then
220 call neko_api_user_cb%compute(time%t, time%tstep)
221 else
222 call neko_error("Compute callback not defined")
223 end if
224
225 end subroutine neko_api_user_compute
226
228 subroutine neko_api_user_dirichlet_condition(fields, bc, time)
229 type(field_list_t), intent(inout) :: fields
230 type(field_dirichlet_t), intent(in) :: bc
231 type(time_state_t), intent(in) :: time
232 type(c_ptr) :: bc_msk
233
234 call neko_api_set_cb_field_list(fields)
235
236 bc_msk = neko_api_user_bc_msk_ptr(bc)
237
238 if (associated(neko_api_user_cb%dirichlet)) then
239 call neko_api_user_cb%dirichlet(bc_msk, bc%msk(0), time%t, time%tstep)
240 else
241 call neko_error("Dirichlet condition callback not defined")
242 end if
243 nullify(neko_api_cb_field_list)
244
245 contains
246
248 function neko_api_user_bc_msk_ptr(bc) result(bc_ptr)
249 type(field_dirichlet_t), intent(in), target :: bc
250 type(c_ptr) :: bc_ptr
251 bc_ptr = c_loc(bc%msk(1))
252 end function neko_api_user_bc_msk_ptr
253
254 end subroutine neko_api_user_dirichlet_condition
255
257 subroutine neko_api_user_material_properties(scheme_name, properties, time)
258 character(len=*), intent(in) :: scheme_name
259 type(field_list_t), intent(inout) :: properties
260 type(time_state_t), intent(in) :: time
261
262 call neko_api_set_cb_field_list(properties)
263
264 if (associated(neko_api_user_cb%material)) then
265 call neko_api_user_cb%material(trim(scheme_name), &
266 len_trim(scheme_name),time%t, time%tstep)
267 else
268 call neko_error("Material properties callback not defined")
269 end if
270
271 nullify(neko_api_cb_field_list)
272 end subroutine neko_api_user_material_properties
273
275 subroutine neko_api_user_source_term(scheme_name, rhs, time)
276 character(len=*), intent(in) :: scheme_name
277 type(field_list_t), intent(inout) :: rhs
278 type(time_state_t), intent(in) :: time
279
280 call neko_api_set_cb_field_list(rhs)
281
282 if (associated(neko_api_user_cb%source)) then
283 call neko_api_user_cb%source(trim(scheme_name), &
284 len_trim(scheme_name),time%t, time%tstep)
285 else
286 call neko_error("Source term callback not defined")
287 end if
288
289 nullify(neko_api_cb_field_list)
290 end subroutine neko_api_user_source_term
291
293 subroutine neko_api_set_cb_field_list(fields)
294 type(field_list_t), target, intent(inout) :: fields
295
296 if (associated(neko_api_cb_field_list)) then
297 call neko_error("Callback field list already defined")
298 end if
299 neko_api_cb_field_list => fields
300 end subroutine neko_api_set_cb_field_list
301
304 module function neko_api_user_cb_get_field_by_name(field_name) result(f)
305 character(len=*), intent(in) :: field_name
306 type(field_t), pointer :: f
307
308 if (.not. associated(neko_api_cb_field_list)) then
309 call neko_error("Callback field list not defined")
310 end if
311
312 f => neko_api_cb_field_list%get(trim(field_name))
313
314 end function neko_api_user_cb_get_field_by_name
315
318 module function neko_api_user_cb_get_field_by_index(field_idx) result(f)
319 integer, intent(in) :: field_idx
320 type(field_t), pointer :: f
321
322 if (.not. associated(neko_api_cb_field_list)) then
323 call neko_error("Callback field list not defined")
324 end if
325
326 f => neko_api_cb_field_list%get(field_idx)
327
328 end function neko_api_user_cb_get_field_by_index
329
330end submodule neko_api_user
Defines a boundary condition.
Definition bc.f90:34
Neko C API.
Definition neko_api.f90:34