Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
registries.f90
Go to the documentation of this file.
1! This tutorial demonstrates how to use registries in Neko to manage fields and
2! temporary data. It covers the following key points:
3!
4! - Accessing and managing fields using the `neko_registry`:
5! - Retrieving existing fields registered by solvers (e.g., velocity fields).
6! - Registering new fields for use across modules or for output purposes.
7! - Registering and accessing other types of data (e.g., scalars) in the
8! registry.
9! - Using the `neko_scratch_registry` to manage temporary fields:
10! - Requesting temporary fields for intermediate calculations.
11! - Reliquishing temporary fields to free resources.
12!
13module user
14 use neko
15 implicit none
16
17contains
18
19
20 ! Register user-defined functions (see user_intf.f90)
21 subroutine user_setup(user)
22 type(user_t), intent(inout) :: user
23
24 user%startup => startup
25 user%initialize => initialize
26 user%compute => compute
27
28 end subroutine user_setup
29
30 ! We will use the startup routine to manipulate the end time.
31 subroutine startup(params)
32 type(json_file), intent(inout) :: params
33
34 call params%add("case.end_time", 0.0_rp)
35 end subroutine startup
36
37 subroutine initialize(time)
38 type(time_state_t), intent(in) :: time
39
40 type(field_t), pointer :: my_field_ptr
41
42 ! Sometimes we need fields to be accessible across different modules. This
43 ! can include fields that we create in the user module. To that end, Neko
44 ! provides a special singleton object of type `registry_t`. The name
45 ! of the singleton is `neko_registry`. Solvers register their solution
46 ! fields there, for example.
47
48 ! Here we can grab the x-velocity from the fluid_scheme_t, which is
49 ! registered as "u" in the registry.
50 my_field_ptr => neko_registry%get_field("u")
51
52 ! We can also register new fields. For that we need a dofmap_t object, just
53 ! like when we initialize a field. Once in the registry, the field is
54 ! available for access and manipulation in other modules.
55 ! Practical example: you may want to run some calculations on this field and
56 ! then use the field_writer simcomp to output it to disk during the
57 ! simulation. The field_writer looks for fields in the registry, given their
58 ! names.
59 call neko_registry%add_field(my_field_ptr%dof, "my_field")
60
61 ! The registry supports working with more types than fields. You can also
62 ! register `vector_t`, `matrix_t`, as well as real and integer scalars.
63 ! For example:
64 call neko_registry%add_integer_scalar(42, "meaning_of_life")
65
66 end subroutine initialize
67
68 subroutine compute(time)
69 type(time_state_t), intent(in) :: time
70
71 integer :: tmp_index
72 type(field_t), pointer :: temp_field_ptr
73 type(field_t), pointer :: u, v
74
75 ! Sometimes we need some temporary fields to perform certain calculations.
76 ! Instead of declaring them inside a subroutine, Neko provides yet another
77 ! singleton: `neko_scratch_registry`, of type `scratch_registry_t`. The
78 ! advantage of using it is saving memory and time to allocate things.
79
80 ! We get a temporary by using a field_t pointer and an index.
81 call neko_scratch_registry%request_field(temp_field_ptr, tmp_index, .false.)
82
83 u => neko_registry%get_field("u")
84 v => neko_registry%get_field("v")
85
86 ! Perform some operations and use the temporary for something
87 call field_cfill(temp_field_ptr, 1.0_rp)
88 call field_add2(temp_field_ptr, u)
89 v = temp_field_ptr
90
91 ! At the end of the subroutine, the temporary field needs to be reliquished.
92 ! This is where the integer index comes in.
93 call neko_scratch_registry%relinquish_field(tmp_index)
94
95 end subroutine compute
96
97end module user
Master module.
Definition neko.f90:34
subroutine initialize(time)
subroutine user_setup(user)
subroutine compute(time)
subroutine startup(params)