38 use,
intrinsic :: iso_c_binding
74 logical :: initialized
76 call mpi_initialized(initialized)
78 if (.not.initialized)
then
79 call neko_warning(
'Neko has not been initialised')
82 call neko_log%newline()
90 call neko_registry%init()
91 call neko_const_registry%init()
98 call neko_registry%free()
104 bind(c, name="neko_scratch_registry_init")
106 call neko_scratch_registry%init()
112 bind(c, name="neko_scratch_registry_free")
114 call neko_scratch_registry%free()
121 bind(c, name="neko_case_allocate")
122 integer(c_intptr_t),
intent(inout) :: case_iptr
123 type(case_t),
pointer :: C
128 case_iptr = transfer(cp, 0_c_intptr_t)
136 bind(c, name="neko_case_init")
137 type(c_ptr),
intent(in) :: case_json
138 integer(c_int),
value :: case_len
139 integer(c_intptr_t),
intent(inout) :: case_iptr
140 type(json_file) :: json_case
141 type(case_t),
pointer :: C
146 cp = transfer(case_iptr, c_null_ptr)
147 if (c_associated(cp))
then
148 call c_f_pointer(cp, c)
152 case_iptr = transfer(cp, 0_c_intptr_t)
157 if (c_associated(case_json))
then
159 character(kind=c_char,len=case_len+1),
pointer :: s
160 character(len=:),
allocatable :: fcase_json
161 call c_f_pointer(case_json, s)
162 fcase_json = s(1:case_len)
163 call json_case%load_from_string(fcase_json)
164 deallocate(fcase_json)
172 call c%init(json_case)
177 call neko_simcomps%init(c)
185 integer(c_intptr_t),
intent(inout) :: case_iptr
186 type(case_t),
pointer :: C
189 cp = transfer(case_iptr, c_null_ptr)
190 if (c_associated(cp))
then
191 call c_f_pointer(cp, c)
194 call neko_error(
'Invalid Neko case')
203 bind(c, name="neko_case_time")
204 integer(c_intptr_t),
intent(inout) :: case_iptr
205 real(kind=c_rp) :: time
206 type(case_t),
pointer :: c
209 cptr = transfer(case_iptr, c_null_ptr)
210 if (c_associated(cptr))
then
211 call c_f_pointer(cptr, c)
214 call neko_error(
'Invalid Neko case')
223 bind(c, name="neko_case_end_time")
224 integer(c_intptr_t),
intent(inout) :: case_iptr
225 real(kind=c_rp) :: end_time
226 type(case_t),
pointer :: c
229 cptr = transfer(case_iptr, c_null_ptr)
230 if (c_associated(cptr))
then
231 call c_f_pointer(cptr, c)
232 end_time = c%time%end_time
234 call neko_error(
'Invalid Neko case')
243 bind(c, name="neko_case_tstep")
244 integer(c_intptr_t),
intent(inout) :: case_iptr
245 type(case_t),
pointer :: c
247 integer(c_int) :: tstep
249 cptr = transfer(case_iptr, c_null_ptr)
250 if (c_associated(cptr))
then
251 call c_f_pointer(cptr, c)
254 call neko_error(
'Invalid Neko case')
262 integer(c_intptr_t),
intent(inout) :: case_iptr
263 type(case_t),
pointer :: C
266 cp = transfer(case_iptr, c_null_ptr)
267 if (c_associated(cp))
then
268 call c_f_pointer(cp, c)
271 call neko_error(
'Invalid Neko case')
279 bind(c, name="neko_step")
281 integer(c_intptr_t),
intent(inout) :: case_iptr
282 type(case_t),
pointer :: C
284 type(json_file) :: dt_params
286 real(kind=dp),
save :: step_loop_start = 0.0_dp
288 cptr = transfer(case_iptr, c_null_ptr)
289 if (c_associated(cptr))
then
290 call c_f_pointer(cptr, c)
292 if (.not.
allocated(dt_controller))
then
293 allocate(dt_controller)
294 call json_get(c%params,
'case.time', dt_params)
295 call dt_controller%init(dt_params)
298 if (c%time%tstep .eq. 0)
then
299 call simulation_init(c, dt_controller)
301 step_loop_start = mpi_wtime()
304 if (.not. c%time%is_done())
then
305 call simulation_step(c, dt_controller, step_loop_start)
308 if (c%time%is_done())
then
309 call simulation_finalize(c)
310 if (
allocated(dt_controller))
then
311 deallocate(dt_controller)
316 call neko_error(
'Invalid Neko case')
326 bind(c, name="neko_output_ctrl_execute")
327 integer(c_intptr_t),
intent(inout) :: case_iptr
328 logical(kind=c_bool),
value :: force_output
329 logical :: f_force_output
330 type(case_t),
pointer :: C
332 type(time_state_t) :: f_time
334 cp = transfer(case_iptr, c_null_ptr)
335 if (c_associated(cp))
then
336 call c_f_pointer(cp, c)
338 call neko_error(
'Invalid Neko case')
341 f_force_output = transfer(force_output, f_force_output)
342 call c%output_controller%execute(c%time, f_force_output)
349 bind(c, name=
'neko_field')
350 character(kind=c_char),
dimension(*),
intent(in) :: field_name
351 character(len=8192) :: name
352 type(field_t),
pointer ::
field
353 type(c_ptr) :: field_ptr
358 if (field_name(len+1) .eq. c_null_char)
exit
360 name(len:len) = field_name(len)
363 field => neko_registry%get_field(trim(name(1:len)))
365 field_ptr = c_loc(
field%x)
372 bind(c, name=
'neko_field_order')
373 character(kind=c_char),
dimension(*),
intent(in) :: field_name
374 character(len=8192) :: name
375 type(field_t),
pointer ::
field
376 integer(c_int) :: field_lx
381 if (field_name(len+1) .eq. c_null_char)
exit
383 name(len:len) = field_name(len)
386 field => neko_registry%get_field(trim(name(1:len)))
388 field_lx =
field%Xh%lx
395 bind(c, name=
'neko_field_nelements')
396 character(kind=c_char),
dimension(*),
intent(in) :: field_name
397 character(len=8192) :: name
398 type(field_t),
pointer ::
field
399 integer(c_int) :: field_nelv
404 if (field_name(len+1) .eq. c_null_char)
exit
406 name(len:len) = field_name(len)
409 field => neko_registry%get_field(trim(name(1:len)))
411 field_nelv =
field%msh%nelv
418 bind(c, name=
'neko_field_size')
419 character(kind=c_char),
dimension(*),
intent(in) :: field_name
420 character(len=8192) :: name
421 type(field_t),
pointer ::
field
422 integer(c_int) :: field_size
427 if (field_name(len+1) .eq. c_null_char)
exit
429 name(len:len) = field_name(len)
432 field => neko_registry%get_field(trim(name(1:len)))
434 field_size =
field%dof%size()
445 bind(c, name=
'neko_field_dofmap')
446 character(kind=c_char),
dimension(*),
intent(in) :: field_name
447 type(c_ptr),
intent(inout) :: dof_ptr, x_ptr, y_ptr, z_ptr
448 character(len=8192) :: name
449 type(field_t),
pointer :: field
454 if (field_name(len+1) .eq. c_null_char)
exit
456 name(len:len) = field_name(len)
459 field => neko_registry%get_field(trim(name(1:len)))
472 x_ptr, y_ptr, z_ptr, size) bind(c, name='neko_case_fluid_dofmap')
473 integer(c_intptr_t),
intent(inout) :: case_iptr
474 type(case_t),
pointer :: C
476 type(c_ptr),
intent(inout) :: dof_ptr, x_ptr, y_ptr, z_ptr
477 integer,
intent(inout) :: size
479 cptr = transfer(case_iptr, c_null_ptr)
480 if (c_associated(cptr))
then
481 call c_f_pointer(cptr, c)
483 size = c%fluid%dm_Xh%size()
485 call neko_error(
'Invalid Neko case')
492 type(dofmap_t),
target,
intent(in) :: dm
493 type(c_ptr),
intent(inout) :: dof_ptr, x_ptr, y_ptr, z_ptr
495 dof_ptr = c_loc(dm%dof)
516 dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz) &
517 bind(c, name=
'neko_field_space')
518 character(kind=c_char),
dimension(*),
intent(in) :: field_name
519 integer,
intent(inout) :: lx
520 type(c_ptr),
intent(inout) :: zg, dr_inv, ds_inv, dt_inv
521 type(c_ptr),
intent(inout) :: wx, wy, wz, dx, dy, dz
522 character(len=8192) :: name
523 type(field_t),
pointer :: field
528 if (field_name(len+1) .eq. c_null_char)
exit
530 name(len:len) = field_name(len)
533 field => neko_registry%get_field(trim(name(1:len)))
535 wx, wy, wz, dx, dy, dz)
553 dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz) &
554 bind(c, name=
'neko_case_fluid_space')
555 integer(c_intptr_t),
intent(inout) :: case_iptr
556 type(case_t),
pointer :: C
558 integer,
intent(inout) :: lx
559 type(c_ptr),
intent(inout) :: zg, dr_inv, ds_inv, dt_inv
560 type(c_ptr),
intent(inout) :: wx, wy, wz, dx, dy, dz
563 cptr = transfer(case_iptr, c_null_ptr)
564 if (c_associated(cptr))
then
565 call c_f_pointer(cptr, c)
567 wx, wy, wz, dx, dy, dz)
569 call neko_error(
'Invalid Neko case')
576 wx, wy, wz, dx, dy, dz)
577 type(space_t),
target,
intent(in) :: Xh
578 integer,
intent(inout) :: lx
579 type(c_ptr),
intent(inout) :: zg, dr_inv, ds_inv, dt_inv
580 type(c_ptr),
intent(inout) :: wx, wy, wz, dx, dy, dz
584 dr_inv = c_loc(xh%dr_inv)
585 ds_inv = c_loc(xh%ds_inv)
586 dt_inv = c_loc(xh%dt_inv)
599 mult, dxdr, dydr, dzdr, dxds, dyds, dzds, dxdt, dydt, dzdt, &
600 drdx, drdy, drdz, dsdx, dsdy, dsdz, dtdx, dtdy, dtdz, &
601 jac, B, area, nx, ny, nz) bind(c, name='neko_case_fluid_coef')
602 integer(c_intptr_t),
intent(inout) :: case_iptr
603 type(case_t),
pointer :: C
605 type(c_ptr),
intent(inout) :: G11, G22, G33, G12, G13, G23
606 type(c_ptr),
intent(inout) :: mult
607 type(c_ptr),
intent(inout) :: dxdr, dydr, dzdr
608 type(c_ptr),
intent(inout) :: dxds, dyds, dzds
609 type(c_ptr),
intent(inout) :: dxdt, dydt, dzdt
610 type(c_ptr),
intent(inout) :: drdx, drdy, drdz
611 type(c_ptr),
intent(inout) :: dsdx, dsdy, dsdz
612 type(c_ptr),
intent(inout) :: dtdx, dtdy, dtdz
613 type(c_ptr),
intent(inout) :: jac, B, area, nx, ny, nz
616 cptr = transfer(case_iptr, c_null_ptr)
617 if (c_associated(cptr))
then
618 call c_f_pointer(cptr, c)
619 g11 = c_loc(c%fluid%c_Xh%G11)
620 g22 = c_loc(c%fluid%c_Xh%G22)
621 g33 = c_loc(c%fluid%c_Xh%G33)
622 g12 = c_loc(c%fluid%c_Xh%G12)
623 g13 = c_loc(c%fluid%c_Xh%G13)
624 g23 = c_loc(c%fluid%c_Xh%G23)
625 mult = c_loc(c%fluid%c_Xh%mult)
626 dxdr = c_loc(c%fluid%c_Xh%dxdr)
627 dydr = c_loc(c%fluid%c_Xh%dydr)
628 dzdr = c_loc(c%fluid%c_Xh%dzdr)
629 dxds = c_loc(c%fluid%c_Xh%dxds)
630 dyds = c_loc(c%fluid%c_Xh%dyds)
631 dzds = c_loc(c%fluid%c_Xh%dzds)
632 dxdt = c_loc(c%fluid%c_Xh%dxdt)
633 dydt = c_loc(c%fluid%c_Xh%dydt)
634 dzdt = c_loc(c%fluid%c_Xh%dzdt)
635 drdx = c_loc(c%fluid%c_Xh%drdx)
636 drdy = c_loc(c%fluid%c_Xh%drdy)
637 drdz = c_loc(c%fluid%c_Xh%drdz)
638 dsdx = c_loc(c%fluid%c_Xh%dsdx)
639 dsdy = c_loc(c%fluid%c_Xh%dsdy)
640 dsdz = c_loc(c%fluid%c_Xh%dsdz)
641 dtdx = c_loc(c%fluid%c_Xh%dtdx)
642 dtdy = c_loc(c%fluid%c_Xh%dtdy)
643 dtdz = c_loc(c%fluid%c_Xh%dtdz)
644 jac = c_loc(c%fluid%c_Xh%jac)
645 b = c_loc(c%fluid%c_Xh%B)
646 area = c_loc(c%fluid%c_Xh%area)
647 nx = c_loc(c%fluid%c_Xh%nx)
648 ny = c_loc(c%fluid%c_Xh%ny)
649 nz = c_loc(c%fluid%c_Xh%nz)
651 call neko_error(
'Invalid Neko case')
665 compute_cb, dirichlet_cb, material_cb, source_cb) &
666 bind(c, name=
'neko_user_setup')
667 integer(c_intptr_t),
intent(inout) :: case_iptr
668 type(c_funptr),
value :: initial_cb, preprocess_cb, compute_cb
669 type(c_funptr),
value :: dirichlet_cb, material_cb, source_cb
670 type(case_t),
pointer :: C
673 cptr = transfer(case_iptr, c_null_ptr)
674 if (c_associated(cptr))
then
675 call c_f_pointer(cptr, c)
676 call neko_api_user_cb_register(c%user, initial_cb, preprocess_cb, &
677 compute_cb, dirichlet_cb, material_cb, source_cb)
679 call neko_error(
'Invalid Neko case')
687 bind(c, name=
'neko_cb_field_by_name')
688 character(kind=c_char),
dimension(*),
intent(in) :: field_name
689 character(len=8192) :: name
690 type(field_t),
pointer ::
field
691 type(c_ptr) :: field_ptr
696 if (field_name(len+1) .eq. c_null_char)
exit
698 name(len:len) = field_name(len)
701 field => neko_api_user_cb_get_field(trim(name(1:len)))
703 field_ptr = c_loc(
field%x)
710 result(field_ptr) bind(c, name=
'neko_cb_field_by_index')
711 integer,
intent(in) :: field_idx
712 type(field_t),
pointer ::
field
713 type(c_ptr) :: field_ptr
715 field => neko_api_user_cb_get_field(field_idx)
717 field_ptr = c_loc(
field%x)
725 result(same_name) bind(c, name=
'neko_cb_field_name_at_index')
726 integer,
intent(in) :: field_idx
727 character(kind=c_char),
dimension(*),
intent(in) :: field_name
728 character(len=8192) :: name
729 type(field_t),
pointer :: f1, f2
730 type(c_ptr) :: field_ptr
732 logical(c_bool) :: same_name
736 if (field_name(len+1) .eq. c_null_char)
exit
738 name(len:len) = field_name(len)
741 f1 => neko_api_user_cb_get_field(field_idx)
742 f2 => neko_api_user_cb_get_field(trim(name(1:len)))
744 same_name = trim(f1%name) .eq. trim(f2%name)
subroutine, public neko_api_user_cb_register(user, initial_cb, preprocess_cb, compute_cb, dirichlet_cb, material_cb, source_cb)
Register callbacks.
subroutine neko_api_wrap_dofmap(dm, dof_ptr, x_ptr, y_ptr, z_ptr)
Helper function to assign pointers to a dofmap's data.
subroutine neko_api_finalize()
Finalize Neko.
subroutine neko_api_wrap_space(xh, lx, zg, dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz)
Helper function to assign pointers to a space's data.
subroutine neko_api_user_setup(case_iptr, initial_cb, preprocess_cb, compute_cb, dirichlet_cb, material_cb, source_cb)
Setup user-provided callbacks.
subroutine neko_api_step(case_iptr)
Compute a time-step for a neko case.
integer(c_int) function neko_api_field_nelements(field_name)
Retrive the number of elements in a field.
subroutine neko_api_device_finalize()
Finalize Neko device layer.
subroutine neko_api_job_info()
Display job information.
subroutine neko_api_registry_init()
Initialise a Neko field registry.
subroutine neko_api_field_space(field_name, lx, zg, dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz)
Retrive the space associated with a field.
subroutine neko_api_case_free(case_iptr)
Destroy a Neko case.
subroutine neko_api_case_allocate(case_iptr)
Allocate memory for a Neko case.
subroutine neko_api_output_ctrl_execute(case_iptr, force_output)
Execute the Case's output controller.
subroutine neko_api_case_init(case_json, case_len, case_iptr)
Initalise a Neko case.
subroutine neko_api_field_dofmap(field_name, dof_ptr, x_ptr, y_ptr, z_ptr)
Retrive the dofmap associated with a field.
subroutine neko_api_case_fluid_space(case_iptr, lx, zg, dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz)
Retrive the space associated with a case's fluid solver.
real(kind=c_rp) function neko_api_case_end_time(case_iptr)
Retrive the end time of a case.
type(c_ptr) function neko_api_user_cb_field_by_index(field_idx)
Retrive a pointer to a user callback field.
logical(c_bool) function neko_api_user_cb_field_name_at_index(field_idx, field_name)
Check if the user callback field at a given index has a given name.
subroutine neko_api_scratch_registry_init()
Initialise a Neko scratch registry.
type(c_ptr) function neko_api_field(field_name)
Retrive a pointer to a flow field.
integer(c_int) function neko_api_field_size(field_name)
Retrive the total number of degrees of freedom of a field.
subroutine neko_api_scratch_registry_free()
Destroy a Neko scratch registry.
subroutine neko_api_solve(case_iptr)
Solve a neko case.
subroutine neko_api_case_fluid_coef(case_iptr, g11, g22, g33, g12, g13, g23, mult, dxdr, dydr, dzdr, dxds, dyds, dzds, dxdt, dydt, dzdt, drdx, drdy, drdz, dsdx, dsdy, dsdz, dtdx, dtdy, dtdz, jac, b, area, nx, ny, nz)
Retrive the coefficient associated with a case's fluid solver.
subroutine neko_api_registry_free()
Destroy a Neko field registry.
type(c_ptr) function neko_api_user_cb_field_by_name(field_name)
Retrive a pointer to a user callback field.
subroutine neko_api_case_fluid_dofmap(case_iptr, dof_ptr, x_ptr, y_ptr, z_ptr, size)
Retrive the dofmap associated with a case's fluid solver.
integer(c_int) function neko_api_field_order(field_name)
Retrive the order of a field.
subroutine neko_api_device_init()
Initialise Neko device layer.
real(kind=c_rp) function neko_api_case_time(case_iptr)
Retrive the current time of a case.
integer(c_int) function neko_api_case_tstep(case_iptr)
Retrive the time-step of a case.
subroutine neko_api_init()
Initialise Neko.
Implements type time_step_controller.
void neko_solve(int **case_iptr)
Provides a tool to set time step dt.