This directory contains tutorial files that demonstrate various aspects of programming with Neko. Each file provides examples and explanations for specific features, concepts, or workflows in Neko, helping users to customize and extend their simulations effectively.
The files don't necessarily need to be run, but executing prepare.sh
will copy over a mesh and case file from the cylinder example, so you can use makeneko
on a .f90
and run it.
<tt>user_file_template.f90</tt>
A user file template with stubs for every possible user subroutine.
implicit none
contains
type(user_t), intent(inout) :: user
type(json_file), intent(inout) :: params
type(time_state_t), intent(in) :: time
character(len=*), intent(in) :: scheme_name
type(field_list_t), intent(inout) :: fields
type(mesh_t), intent(inout) :: msh
type(time_state_t), intent(in) :: time
type(time_state_t), intent(in) :: time
type(time_state_t), intent(in) :: time
character(len=*), intent(in) :: scheme_name
type(field_list_t), intent(inout) :: rhs
type(time_state_t), intent(in) :: time
type(field_list_t), intent(inout) :: fields
type(field_dirichlet_t), intent(in) :: bc
type(time_state_t), intent(in) :: time
character(len=*), intent(in) :: scheme_name
type(field_list_t), intent(inout) :: properties
type(time_state_t), intent(in) :: time
Implements the source_term_t type and a wrapper source_term_wrapper_t.
subroutine mesh_setup(msh, time)
subroutine initialize(time)
subroutine user_setup(user)
subroutine initial_conditions(scheme_name, fields)
subroutine material_properties(scheme_name, properties, time)
subroutine dirichlet_conditions(fields, bc, time)
subroutine startup(params)
subroutine finalize(time)
<tt>startup_and_json.f90</tt>
Demonstrates how to define user-specific routines and interact with the JSON parameter dictionary used for simulation configuration.
implicit none
type(json_file) :: case_params
contains
type(user_t), intent(inout) :: user
type(json_file), intent(inout) :: params
real(kind=rp) :: some_real
character(len=:), allocatable :: some_string
real(kind=rp), allocatable :: some_real_array(:)
type(json_file) :: some_json_object
call json_get(params, "case.fluid.scheme", some_string)
call json_get_or_default(params, "case.fluid.Re", some_real, 100.0_rp)
call json_extract_object(params, "case.fluid.initial_condition", &
some_json_object)
call some_json_object%print()
call params%add("case.fluid.initial_condition.my_param", 3.0_rp)
some_real_array = [1.0_rp, 2.0_rp, 3.0_rp]
call params%add("case.fluid.initial_condition.value", some_real_array)
call params%add("case.end_time", 0.0_rp)
call json_extract_object(params, "case.fluid.initial_condition", &
some_json_object)
call some_json_object%print()
case_params = params
real(kind=rp) some_variable
<tt>fields_vectors_math.f90</tt>
Explains how to work with the field_t
and vector_t
types in Neko, including mathematical operations and lifecycle management.
implicit none
type(field_t) :: my_field
type(vector_t) :: vec
contains
type(user_t), intent(inout) :: user
type(json_file), intent(inout) :: params
call params%add("case.end_time", 0.0_rp)
type(time_state_t), intent(in) :: time
call my_field%init(neko_user_access%case%fluid%dm_Xh, "my_field")
my_field = 1.0_rp
call vec%init(50)
vec = 1.0_rp
type(time_state_t), intent(in) :: time
integer :: i
do i = 1, my_field%size()
my_field%x(i,1,1,1) = my_field%x(i,1,1,1) * 2.0_rp
end do
if (neko_bcknd_device .eq. 1) then
call device_cmult(my_field%x_d, 2.0_rp, my_field%size())
else
call cmult(my_field%x, 2.0_rp, my_field%size())
end if
call field_cmult(my_field, 2.0_rp)
type(time_state_t), intent(in) :: time
call my_field%free()
<tt>registries.f90</tt>
Shows how to use registries in Neko to manage fields and temporary data efficiently.
implicit none
contains
type(user_t), intent(inout) :: user
type(json_file), intent(inout) :: params
call params%add("case.end_time", 0.0_rp)
type(time_state_t), intent(in) :: time
type(field_t), pointer :: my_field_ptr
my_field_ptr => neko_field_registry%get_field("u")
call neko_field_registry%add_field(my_field_ptr%dof, "my_field")
type(time_state_t), intent(in) :: time
integer :: temp_index
type(field_t), pointer :: temp_field_ptr
type(field_t), pointer :: u, v
call neko_scratch_registry%request_field(temp_field_ptr, temp_index)
u => neko_field_registry%get_field("u")
v => neko_field_registry%get_field("v")
call field_cfill(temp_field_ptr, 1.0_rp)
call field_add2(temp_field_ptr, u)
v = temp_field_ptr
call neko_scratch_registry%relinquish_field(temp_index)
<tt>output.f90</tt>
Shows how to output simulation data to .fld and .csv files.
implicit none
type(field_t), target :: my_field1
type(field_t), target :: my_field2
type(vector_t) :: vec
contains
type(user_t), intent(inout) :: user
type(json_file), intent(inout) :: params
call params%add("case.end_time", 0.0_rp)
type(time_state_t), intent(in) :: time
type(fld_file_t) :: fld_writer
type(field_list_t) :: field_pair
type(csv_file_t) :: csv_writer
call my_field1%init(neko_user_access%case%fluid%dm_Xh, "my_field1")
call my_field2%init(neko_user_access%case%fluid%dm_Xh, "my_field2")
call field_cfill(my_field1, 1.0_rp)
call field_cfill(my_field2, 2.0_rp)
call fld_writer%init("my_output.fld")
call fld_writer%write(my_field1)
call field_pair%init(2)
call field_pair%assign_to_field(1, my_field1)
call field_pair%assign_to_field(2, my_field2)
call fld_writer%init("my_output2.fld")
call fld_writer%write(field_pair)
call fld_writer%set_precision(dp)
call fld_writer%set_precision(sp)
call vec%init(5)
vec = 3.0_rp
call csv_writer%init("my_output.csv")
call csv_writer%set_header("# p1, p2, p3, p4, p5")
call csv_writer%write(vec)
vec = 4.0_rp
call csv_writer%write(vec)
type(time_state_t), intent(in) :: time
call my_field1%free()
call my_field2%free()
call vec%free()
<tt>custom_types.f90</tt>
Shows how to add a new run-time-selectable type to Neko, using a source term as an example.
use json_module, only : json_file
implicit none
private
character(len=:), allocatable :: greeting
contains
contains
variable_name)
class(my_source_term_t), intent(inout) :: this
type(json_file), intent(inout) :: json
type(field_list_t), intent(in), target :: fields
type(coef_t), intent(in), target :: coef
character(len=*), intent(in) :: variable_name
real(kind=
rp) :: start_time, end_time
call this%free()
call this%init_base(fields, coef, start_time, end_time)
call json_get(json,
"greeting", this%greeting)
class(my_source_term_t), intent(inout) :: this
if (allocated(this%greeting)) then
deallocate(this%greeting)
end if
call this%free_base()
class(my_source_term_t), intent(inout) :: this
type(time_state_t), intent(in) :: time
write(*,*) this%greeting
procedure(source_term_allocate), pointer :: allocator
call register_source_term("my_source_term", allocator)
class(source_term_t), allocatable, intent(inout) :: obj
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Retrieves a parameter by name or throws an error.
Source term factory. Both constructs and initializes the object.
In this module we implement a custom source term, my_source_term and prep it for being recognized by ...
subroutine my_source_term_compute(this, time)
Will just bring our greeting to the console.
subroutine my_source_term_allocate(obj)
subroutine, public custom_types_register_types()
subroutine my_source_term_free(this)
Destructor.
subroutine my_source_term_init_from_json(this, json, fields, coef, variable_name)
The common constructor using a JSON object.
Utilities for retrieving parameters from the case files.
integer, parameter, public rp
Global precision used in computations.
Module with things related to the simulation time.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
field_list_t, To be able to group fields together
Base abstract type for source terms.
A struct that contains all info about the time, expand as needed.