Neko 1.99.2
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-2026, 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!
35 use neko
36 use, intrinsic :: iso_c_binding
37 implicit none
38 private
39
41 abstract interface
42 subroutine api_ic_callback(scheme_name, scheme_name_len) bind(c)
43 use, intrinsic :: iso_c_binding
44 implicit none
45 character(kind=c_char), dimension(*) :: scheme_name
46 integer(c_int), value :: scheme_name_len
47 end subroutine api_ic_callback
48 end interface
49
51 abstract interface
52 subroutine api_bc_callback(msk, msk_size, t, tstep) bind(c)
53 use, intrinsic :: iso_c_binding
54 import c_rp
55 implicit none
56 type(c_ptr), value :: msk
57 integer(c_int), value :: msk_size
58 real(kind=c_rp), value :: t
59 integer(c_int), value :: tstep
60 end subroutine api_bc_callback
61 end interface
62
65 abstract interface
66 subroutine api_ft_callback(scheme_name, scheme_name_len, t, tstep) bind(c)
67 use, intrinsic :: iso_c_binding
68 import c_rp
69 implicit none
70 character(kind=c_char), dimension(*) :: scheme_name
71 integer(c_int), value :: scheme_name_len
72 real(kind=c_rp), value :: t
73 integer(c_int), value :: tstep
74 end subroutine api_ft_callback
75 end interface
76
79 abstract interface
80 subroutine api_gn_callback(t, tstep) bind(c)
81 use, intrinsic :: iso_c_binding
82 import c_rp
83 implicit none
84 real(kind=c_rp), value :: t
85 integer(c_int), value :: tstep
86 end subroutine api_gn_callback
87 end interface
88
91 procedure(api_ic_callback), nopass, pointer :: initial
92 procedure(api_gn_callback), nopass, pointer :: preprocess
93 procedure(api_gn_callback), nopass, pointer :: compute
94 procedure(api_bc_callback), nopass, pointer :: dirichlet
95 procedure(api_ft_callback), nopass, pointer :: material
96 procedure(api_ft_callback), nopass, pointer :: source
97 end type api_user_cb
98
102 end interface neko_api_user_cb_get_field
103
105 type(api_user_cb), allocatable :: neko_api_user_cb
106
108 type(field_list_t), pointer :: neko_api_cb_field_list => null()
109
110
112
113contains
114
123 subroutine neko_api_user_cb_register(user, initial_cb, preprocess_cb, &
124 compute_cb, dirichlet_cb, material_cb, source_cb)
125 type(user_t), intent(inout) :: user
126 type(c_funptr), value :: initial_cb, preprocess_cb, compute_cb
127 type(c_funptr), value :: dirichlet_cb, material_cb, source_cb
128
129 ! Keeping neko_api_user_cb as an alloctable is a work around for
130 ! NAG which throws an incompatbile function pointer warning for
131 ! single precision
132 if (.not. allocated(neko_api_user_cb)) then
133 allocate(neko_api_user_cb)
134 neko_api_user_cb%initial => null()
135 neko_api_user_cb%preprocess => null()
136 neko_api_user_cb%compute => null()
137 neko_api_user_cb%dirichlet => null()
138 neko_api_user_cb%material => null()
139 neko_api_user_cb%source => null()
140 end if
141
142 ! We need the block construct in the following if statements to
143 ! adhere strictly with the f2008 standard, and support compilers
144 ! not implementing TS29133 (mainly GNU Fortran with -std=f2008)
145 if (c_associated(initial_cb)) then
146 user%initial_conditions => neko_api_user_initial_condition
147 block
148 procedure(api_ic_callback), pointer :: tmp
149 call c_f_procpointer(initial_cb, tmp)
150 neko_api_user_cb%initial => tmp
151 end block
152 end if
153
154 if (c_associated(preprocess_cb)) then
155 user%preprocess => neko_api_user_preprocess
156 block
157 procedure(api_gn_callback), pointer :: tmp
158 call c_f_procpointer(preprocess_cb, tmp)
159 neko_api_user_cb%preprocess => tmp
160 end block
161 end if
162
163 if (c_associated(compute_cb)) then
164 user%compute => neko_api_user_compute
165 block
166 procedure(api_gn_callback), pointer :: tmp
167 call c_f_procpointer(compute_cb, tmp)
168 neko_api_user_cb%compute => tmp
169 end block
170 end if
171
172 if (c_associated(dirichlet_cb)) then
173 user%dirichlet_conditions => neko_api_user_dirichlet_condition
174 block
175 procedure(api_bc_callback), pointer :: tmp
176 call c_f_procpointer(dirichlet_cb, tmp)
177 neko_api_user_cb%dirichlet => tmp
178 end block
179 end if
180
181 if (c_associated(material_cb)) then
182 user%material_properties => neko_api_user_material_properties
183 block
184 procedure(api_ft_callback), pointer :: tmp
185 call c_f_procpointer(material_cb, tmp)
186 neko_api_user_cb%material => tmp
187 end block
188 end if
189
190 if (c_associated(source_cb)) then
191 user%source_term => neko_api_user_source_term
192 block
193 procedure(api_ft_callback), pointer :: tmp
194 call c_f_procpointer(source_cb, tmp)
195 neko_api_user_cb%source => tmp
196 end block
197 end if
198
199 end subroutine neko_api_user_cb_register
200
202 subroutine neko_api_user_initial_condition(scheme_name, fields)
203 character(len=*), intent(in) :: scheme_name
204 type(field_list_t), intent(inout) :: fields
205
206 if (associated(neko_api_user_cb%initial)) then
207 call neko_api_user_cb%initial(trim(scheme_name), len_trim(scheme_name))
208 else
209 call neko_error("Initial condition callback not defined")
210 end if
211
213
216 type(time_state_t), intent(in) :: time
217
218 if (associated(neko_api_user_cb%preprocess)) then
219 call neko_api_user_cb%preprocess(time%t, time%tstep)
220 else
221 call neko_error("Preprocessing callback not defined")
222 end if
223
224 end subroutine neko_api_user_preprocess
225
227 subroutine neko_api_user_compute(time)
228 type(time_state_t), intent(in) :: time
229
230 if (associated(neko_api_user_cb%compute)) then
231 call neko_api_user_cb%compute(time%t, time%tstep)
232 else
233 call neko_error("Compute callback not defined")
234 end if
235
236 end subroutine neko_api_user_compute
237
239 subroutine neko_api_user_dirichlet_condition(fields, bc, time)
240 type(field_list_t), intent(inout) :: fields
241 type(field_dirichlet_t), intent(in) :: bc
242 type(time_state_t), intent(in) :: time
243 type(c_ptr) :: bc_msk
244
245 call neko_api_set_cb_field_list(fields)
246
248
249 if (associated(neko_api_user_cb%dirichlet)) then
250 call neko_api_user_cb%dirichlet(bc_msk, bc%msk(0), time%t, time%tstep)
251 else
252 call neko_error("Dirichlet condition callback not defined")
253 end if
255
256 contains
257
259 function neko_api_user_bc_msk_ptr(bc) result(bc_ptr)
260 type(field_dirichlet_t), intent(in), target :: bc
261 type(c_ptr) :: bc_ptr
262 bc_ptr = c_loc(bc%msk(1))
263 end function neko_api_user_bc_msk_ptr
264
266
268 subroutine neko_api_user_material_properties(scheme_name, properties, time)
269 character(len=*), intent(in) :: scheme_name
270 type(field_list_t), intent(inout) :: properties
271 type(time_state_t), intent(in) :: time
272
273 call neko_api_set_cb_field_list(properties)
274
275 if (associated(neko_api_user_cb%material)) then
276 call neko_api_user_cb%material(trim(scheme_name), &
277 len_trim(scheme_name),time%t, time%tstep)
278 else
279 call neko_error("Material properties callback not defined")
280 end if
281
284
286 subroutine neko_api_user_source_term(scheme_name, rhs, time)
287 character(len=*), intent(in) :: scheme_name
288 type(field_list_t), intent(inout) :: rhs
289 type(time_state_t), intent(in) :: time
290
292
293 if (associated(neko_api_user_cb%source)) then
294 call neko_api_user_cb%source(trim(scheme_name), &
295 len_trim(scheme_name),time%t, time%tstep)
296 else
297 call neko_error("Source term callback not defined")
298 end if
299
301 end subroutine neko_api_user_source_term
302
304 subroutine neko_api_set_cb_field_list(fields)
305 type(field_list_t), target, intent(inout) :: fields
306
307 if (associated(neko_api_cb_field_list)) then
308 call neko_error("Callback field list already defined")
309 end if
310 neko_api_cb_field_list => fields
311 end subroutine neko_api_set_cb_field_list
312
315 function neko_api_user_cb_get_field_by_name(field_name) result(f)
316 character(len=*), intent(in) :: field_name
317 type(field_t), pointer :: f
318
319 if (.not. associated(neko_api_cb_field_list)) then
320 call neko_error("Callback field list not defined")
321 end if
322
323 f => neko_api_cb_field_list%get(trim(field_name))
324
326
329 function neko_api_user_cb_get_field_by_index(field_idx) result(f)
330 integer, intent(in) :: field_idx
331 type(field_t), pointer :: f
332
333 if (.not. associated(neko_api_cb_field_list)) then
334 call neko_error("Callback field list not defined")
335 end if
336
337 f => neko_api_cb_field_list%get(field_idx)
338
340
341end module neko_api_user
Abstract interface for boundary condition callbacks.
Abstract interface for callbacks requiring a field list and time Used for material properties and sou...
Abstract interface for generic callbacks requiring only time Used for preprocess and compute callback...
Abstract interface for initial condition callbacks.
Defines a boundary condition.
Definition bc.f90:34
Defines a dirichlet boundary condition.
Definition dirichlet.f90:34
Neko API user callbacks.
subroutine, public neko_api_user_cb_register(user, initial_cb, preprocess_cb, compute_cb, dirichlet_cb, material_cb, source_cb)
Register callbacks.
type(field_t) function, pointer neko_api_user_cb_get_field_by_name(field_name)
Retrive a pointer to a field for the currently active callback.
subroutine neko_api_set_cb_field_list(fields)
Set the callbacks active field list.
type(field_t) function, pointer neko_api_user_cb_get_field_by_index(field_idx)
Retrive a pointer to a field for the currently active callback.
subroutine neko_api_user_preprocess(time)
API user preprocessing callback caller.
subroutine neko_api_user_dirichlet_condition(fields, bc, time)
API user dirichlet condition callback caller.
type(api_user_cb), allocatable neko_api_user_cb
Registered callbacks in the API.
subroutine neko_api_user_compute(time)
API user compute callback caller.
subroutine neko_api_user_material_properties(scheme_name, properties, time)
API user material properties callback caller.
subroutine neko_api_user_source_term(scheme_name, rhs, time)
API user source term callback caller.
subroutine neko_api_user_initial_condition(scheme_name, fields)
API user initial condition callback caller.
type(field_list_t), pointer neko_api_cb_field_list
Pointer to an active field_list_t in a callback.
Master module.
Definition neko.f90:34
type(c_ptr) function neko_api_user_bc_msk_ptr(bc)
Helper function to extract a pointer to the mask.
Type defining all supported callbacks via the API.