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