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')
265 bind(c, name="neko_case_is_done")
266 integer(c_intptr_t),
intent(inout) :: case_iptr
267 type(case_t),
pointer :: c
269 integer(c_int) :: is_done
271 cptr = transfer(case_iptr, c_null_ptr)
272 if (c_associated(cptr))
then
273 call c_f_pointer(cptr, c)
274 is_done = merge(1_c_int, 0_c_int, c%time%is_done())
276 call neko_error(
'Invalid Neko case')
284 integer(c_intptr_t),
intent(inout) :: case_iptr
285 type(case_t),
pointer :: C
288 cp = transfer(case_iptr, c_null_ptr)
289 if (c_associated(cp))
then
290 call c_f_pointer(cp, c)
293 call neko_error(
'Invalid Neko case')
301 bind(c, name="neko_step")
303 integer(c_intptr_t),
intent(inout) :: case_iptr
304 type(case_t),
pointer :: C
306 type(json_file) :: dt_params
308 real(kind=dp),
save :: step_loop_start = 0.0_dp
310 cptr = transfer(case_iptr, c_null_ptr)
311 if (c_associated(cptr))
then
312 call c_f_pointer(cptr, c)
315 if (c%time%is_done())
return
317 if (.not.
allocated(dt_controller))
then
318 allocate(dt_controller)
319 call json_get(c%params,
'case.time', dt_params)
320 call dt_controller%init(dt_params)
323 if (c%time%tstep .eq. 0)
then
324 call simulation_init(c, dt_controller)
326 step_loop_start = mpi_wtime()
329 if (.not. c%time%is_done())
then
330 call simulation_step(c, dt_controller, step_loop_start)
333 if (c%time%is_done())
then
334 call simulation_finalize(c)
335 if (
allocated(dt_controller))
then
336 deallocate(dt_controller)
341 call neko_error(
'Invalid Neko case')
351 bind(c, name="neko_output_ctrl_execute")
352 integer(c_intptr_t),
intent(inout) :: case_iptr
353 logical(kind=c_bool),
value :: force_output
354 logical :: f_force_output
355 type(case_t),
pointer :: C
357 type(time_state_t) :: f_time
359 cp = transfer(case_iptr, c_null_ptr)
360 if (c_associated(cp))
then
361 call c_f_pointer(cp, c)
363 call neko_error(
'Invalid Neko case')
366 f_force_output = transfer(force_output, f_force_output)
367 call c%output_controller%execute(c%time, f_force_output)
374 bind(c, name=
'neko_field')
375 character(kind=c_char),
dimension(*),
intent(in) :: field_name
376 character(len=8192) :: name
377 type(field_t),
pointer ::
field
378 type(c_ptr) :: field_ptr
383 if (field_name(len+1) .eq. c_null_char)
exit
385 name(len:len) = field_name(len)
388 field => neko_registry%get_field(trim(name(1:len)))
390 field_ptr = c_loc(
field%x)
397 bind(c, name=
'neko_field_order')
398 character(kind=c_char),
dimension(*),
intent(in) :: field_name
399 character(len=8192) :: name
400 type(field_t),
pointer ::
field
401 integer(c_int) :: field_lx
406 if (field_name(len+1) .eq. c_null_char)
exit
408 name(len:len) = field_name(len)
411 field => neko_registry%get_field(trim(name(1:len)))
413 field_lx =
field%Xh%lx
420 bind(c, name=
'neko_field_nelements')
421 character(kind=c_char),
dimension(*),
intent(in) :: field_name
422 character(len=8192) :: name
423 type(field_t),
pointer ::
field
424 integer(c_int) :: field_nelv
429 if (field_name(len+1) .eq. c_null_char)
exit
431 name(len:len) = field_name(len)
434 field => neko_registry%get_field(trim(name(1:len)))
436 field_nelv =
field%msh%nelv
443 bind(c, name=
'neko_field_size')
444 character(kind=c_char),
dimension(*),
intent(in) :: field_name
445 character(len=8192) :: name
446 type(field_t),
pointer ::
field
447 integer(c_int) :: field_size
452 if (field_name(len+1) .eq. c_null_char)
exit
454 name(len:len) = field_name(len)
457 field => neko_registry%get_field(trim(name(1:len)))
459 field_size =
field%dof%size()
470 bind(c, name=
'neko_field_dofmap')
471 character(kind=c_char),
dimension(*),
intent(in) :: field_name
472 type(c_ptr),
intent(inout) :: dof_ptr, x_ptr, y_ptr, z_ptr
473 character(len=8192) :: name
474 type(field_t),
pointer :: field
479 if (field_name(len+1) .eq. c_null_char)
exit
481 name(len:len) = field_name(len)
484 field => neko_registry%get_field(trim(name(1:len)))
497 x_ptr, y_ptr, z_ptr, size) bind(c, name='neko_case_fluid_dofmap')
498 integer(c_intptr_t),
intent(inout) :: case_iptr
499 type(case_t),
pointer :: C
501 type(c_ptr),
intent(inout) :: dof_ptr, x_ptr, y_ptr, z_ptr
502 integer,
intent(inout) :: size
504 cptr = transfer(case_iptr, c_null_ptr)
505 if (c_associated(cptr))
then
506 call c_f_pointer(cptr, c)
508 size = c%fluid%dm_Xh%size()
510 call neko_error(
'Invalid Neko case')
517 type(dofmap_t),
target,
intent(in) :: dm
518 type(c_ptr),
intent(inout) :: dof_ptr, x_ptr, y_ptr, z_ptr
520 dof_ptr = c_loc(dm%dof)
541 dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz) &
542 bind(c, name=
'neko_field_space')
543 character(kind=c_char),
dimension(*),
intent(in) :: field_name
544 integer,
intent(inout) :: lx
545 type(c_ptr),
intent(inout) :: zg, dr_inv, ds_inv, dt_inv
546 type(c_ptr),
intent(inout) :: wx, wy, wz, dx, dy, dz
547 character(len=8192) :: name
548 type(field_t),
pointer :: field
553 if (field_name(len+1) .eq. c_null_char)
exit
555 name(len:len) = field_name(len)
558 field => neko_registry%get_field(trim(name(1:len)))
560 wx, wy, wz, dx, dy, dz)
578 dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz) &
579 bind(c, name=
'neko_case_fluid_space')
580 integer(c_intptr_t),
intent(inout) :: case_iptr
581 type(case_t),
pointer :: C
583 integer,
intent(inout) :: lx
584 type(c_ptr),
intent(inout) :: zg, dr_inv, ds_inv, dt_inv
585 type(c_ptr),
intent(inout) :: wx, wy, wz, dx, dy, dz
588 cptr = transfer(case_iptr, c_null_ptr)
589 if (c_associated(cptr))
then
590 call c_f_pointer(cptr, c)
592 wx, wy, wz, dx, dy, dz)
594 call neko_error(
'Invalid Neko case')
601 wx, wy, wz, dx, dy, dz)
602 type(space_t),
target,
intent(in) :: Xh
603 integer,
intent(inout) :: lx
604 type(c_ptr),
intent(inout) :: zg, dr_inv, ds_inv, dt_inv
605 type(c_ptr),
intent(inout) :: wx, wy, wz, dx, dy, dz
609 dr_inv = c_loc(xh%dr_inv)
610 ds_inv = c_loc(xh%ds_inv)
611 dt_inv = c_loc(xh%dt_inv)
624 mult, dxdr, dydr, dzdr, dxds, dyds, dzds, dxdt, dydt, dzdt, &
625 drdx, drdy, drdz, dsdx, dsdy, dsdz, dtdx, dtdy, dtdz, &
626 jac, B, area, nx, ny, nz) bind(c, name='neko_case_fluid_coef')
627 integer(c_intptr_t),
intent(inout) :: case_iptr
628 type(case_t),
pointer :: C
630 type(c_ptr),
intent(inout) :: G11, G22, G33, G12, G13, G23
631 type(c_ptr),
intent(inout) :: mult
632 type(c_ptr),
intent(inout) :: dxdr, dydr, dzdr
633 type(c_ptr),
intent(inout) :: dxds, dyds, dzds
634 type(c_ptr),
intent(inout) :: dxdt, dydt, dzdt
635 type(c_ptr),
intent(inout) :: drdx, drdy, drdz
636 type(c_ptr),
intent(inout) :: dsdx, dsdy, dsdz
637 type(c_ptr),
intent(inout) :: dtdx, dtdy, dtdz
638 type(c_ptr),
intent(inout) :: jac, B, area, nx, ny, nz
641 cptr = transfer(case_iptr, c_null_ptr)
642 if (c_associated(cptr))
then
643 call c_f_pointer(cptr, c)
644 g11 = c_loc(c%fluid%c_Xh%G11)
645 g22 = c_loc(c%fluid%c_Xh%G22)
646 g33 = c_loc(c%fluid%c_Xh%G33)
647 g12 = c_loc(c%fluid%c_Xh%G12)
648 g13 = c_loc(c%fluid%c_Xh%G13)
649 g23 = c_loc(c%fluid%c_Xh%G23)
650 mult = c_loc(c%fluid%c_Xh%mult)
651 dxdr = c_loc(c%fluid%c_Xh%dxdr)
652 dydr = c_loc(c%fluid%c_Xh%dydr)
653 dzdr = c_loc(c%fluid%c_Xh%dzdr)
654 dxds = c_loc(c%fluid%c_Xh%dxds)
655 dyds = c_loc(c%fluid%c_Xh%dyds)
656 dzds = c_loc(c%fluid%c_Xh%dzds)
657 dxdt = c_loc(c%fluid%c_Xh%dxdt)
658 dydt = c_loc(c%fluid%c_Xh%dydt)
659 dzdt = c_loc(c%fluid%c_Xh%dzdt)
660 drdx = c_loc(c%fluid%c_Xh%drdx)
661 drdy = c_loc(c%fluid%c_Xh%drdy)
662 drdz = c_loc(c%fluid%c_Xh%drdz)
663 dsdx = c_loc(c%fluid%c_Xh%dsdx)
664 dsdy = c_loc(c%fluid%c_Xh%dsdy)
665 dsdz = c_loc(c%fluid%c_Xh%dsdz)
666 dtdx = c_loc(c%fluid%c_Xh%dtdx)
667 dtdy = c_loc(c%fluid%c_Xh%dtdy)
668 dtdz = c_loc(c%fluid%c_Xh%dtdz)
669 jac = c_loc(c%fluid%c_Xh%jac)
670 b = c_loc(c%fluid%c_Xh%B)
671 area = c_loc(c%fluid%c_Xh%area)
672 nx = c_loc(c%fluid%c_Xh%nx)
673 ny = c_loc(c%fluid%c_Xh%ny)
674 nz = c_loc(c%fluid%c_Xh%nz)
676 call neko_error(
'Invalid Neko case')
690 compute_cb, dirichlet_cb, material_cb, source_cb) &
691 bind(c, name=
'neko_user_setup')
692 integer(c_intptr_t),
intent(inout) :: case_iptr
693 type(c_funptr),
value :: initial_cb, preprocess_cb, compute_cb
694 type(c_funptr),
value :: dirichlet_cb, material_cb, source_cb
695 type(case_t),
pointer :: C
698 cptr = transfer(case_iptr, c_null_ptr)
699 if (c_associated(cptr))
then
700 call c_f_pointer(cptr, c)
701 call neko_api_user_cb_register(c%user, initial_cb, preprocess_cb, &
702 compute_cb, dirichlet_cb, material_cb, source_cb)
704 call neko_error(
'Invalid Neko case')
712 bind(c, name=
'neko_cb_field_by_name')
713 character(kind=c_char),
dimension(*),
intent(in) :: field_name
714 character(len=8192) :: name
715 type(field_t),
pointer ::
field
716 type(c_ptr) :: field_ptr
721 if (field_name(len+1) .eq. c_null_char)
exit
723 name(len:len) = field_name(len)
726 field => neko_api_user_cb_get_field(trim(name(1:len)))
728 field_ptr = c_loc(
field%x)
735 result(field_ptr) bind(c, name=
'neko_cb_field_by_index')
736 integer,
intent(in) :: field_idx
737 type(field_t),
pointer ::
field
738 type(c_ptr) :: field_ptr
740 field => neko_api_user_cb_get_field(field_idx)
742 field_ptr = c_loc(
field%x)
750 result(same_name) bind(c, name=
'neko_cb_field_name_at_index')
751 integer,
intent(in) :: field_idx
752 character(kind=c_char),
dimension(*),
intent(in) :: field_name
753 character(len=8192) :: name
754 type(field_t),
pointer :: f1, f2
755 type(c_ptr) :: field_ptr
757 logical(c_bool) :: same_name
761 if (field_name(len+1) .eq. c_null_char)
exit
763 name(len:len) = field_name(len)
766 f1 => neko_api_user_cb_get_field(field_idx)
767 f2 => neko_api_user_cb_get_field(trim(name(1:len)))
769 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.
integer(c_int) function neko_api_case_is_done(case_iptr)
Check if a case has reached its end time.
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.