Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
output.f90
Go to the documentation of this file.
1! This tutorial demonstrates how to output simulation data to .fld and .csv
2! files in Neko. It covers:
3!
4! - Writing single fields and lists of fields to .fld files using `fld_file_t`.
5! - Controlling output precision for .fld files.
6! - Writing data to .csv files using `csv_file_t` and `vector_t`.
7! - Managing output across simulation steps and cleaning up resources.
8module user
9 use neko
10 implicit none
11
12 ! Custom fields we will output. We add the target attribute to make sure we
13 ! can point to them.
14 type(field_t), target :: my_field1
15 type(field_t), target :: my_field2
16
17 ! A custom vector for CSV output
18 type(vector_t) :: vec
19
20contains
21
22 ! Register user-defined functions (see user_intf.f90)
23 subroutine user_setup(user)
24 type(user_t), intent(inout) :: user
25
26 user%startup => startup
27 user%initialize => initialize
28 user%finalize => finalize
29
30 end subroutine user_setup
31
32 ! We will use the startup routine to manipulate the end time.
33 subroutine startup(params)
34 type(json_file), intent(inout) :: params
35
36 call params%add("case.end_time", 0.0_rp)
37 end subroutine startup
38
39 subroutine initialize(time)
40 type(time_state_t), intent(in) :: time
41
42 ! A writer for .fld files
43 type(fld_file_t) :: fld_writer
44 ! Container for a list of fields, two in our case
45 type(field_list_t) :: field_pair
46 ! A writer for CSV files
47 type(csv_file_t) :: csv_writer
48
49 !
50 ! WRITING FLD FILES
51 !
52
53 ! Initialize the fields and set the values to 1.0 and 2.0
54 call my_field1%init(neko_user_access%case%fluid%dm_Xh, "my_field1")
55 call my_field2%init(neko_user_access%case%fluid%dm_Xh, "my_field2")
56 call field_cfill(my_field1, 1.0_rp)
57 call field_cfill(my_field2, 2.0_rp)
58
59 ! Initialize the writer using the filename
60 call fld_writer%init("my_output.fld")
61
62 ! Here is how we can output a single field to the fld file.
63 ! The field is written as the pressure field.
64 call fld_writer%write(my_field1)
65
66 ! We can also pack more fields inside a single file. To that end we need to
67 ! pass a field_list_t object to the writer. The field_list_t is a list of
68 ! field pointers. As such, it does not own the fields, it just point to
69 ! them. Therefore, this type is convenient for packing fields for output,
70 ! or other similar situations. For this reason, field_list_t is used as
71 ! as dummy argument type for many user interface routines.
72
73 ! Initialize the field_list_t object with the number of fields we want to
74 ! pack.
75 call field_pair%init(2)
76
77 ! Assign the fields to the list, the first parameter is the index of the
78 ! field in the list, the second is the field itself.
79 call field_pair%assign_to_field(1, my_field1)
80 call field_pair%assign_to_field(2, my_field2)
81
82
83 ! Write the list of fields to a different file, they will be put in the
84 ! pressure and temperature inside the fld.
85 call fld_writer%init("my_output2.fld")
86 call fld_writer%write(field_pair)
87
88 ! If one has 3 fields in the list, they will instead be written as velocity
89 ! components. Further adding 1 will populate the pressure with the first
90 ! field and then the next 3 will be the velocity components. Adding a fifth
91 ! field will put it into temperature, and all consecutive fields will be
92 ! scalars.
93
94 ! Finally, note that you can set the precision of the output by calling
95 call fld_writer%set_precision(dp) ! <- sets double precision output
96 call fld_writer%set_precision(sp) ! <- sets single precision output
97
98 !
99 ! WRITING CSV FILES
100 !
101
102 ! A vector_t can be used to pass values to a CSV file writer. Let us init
103 ! one to have 5 elements and set them to 3.0.
104 call vec%init(5)
105 vec = 3.0_rp
106
107 ! We initialize the CSV writer just like the fld writer.
108 call csv_writer%init("my_output.csv")
109 ! The writer can optionally add a header string to the file.
110 call csv_writer%set_header("# p1, p2, p3, p4, p5")
111
112 ! This will write one line to the CSV.
113 call csv_writer%write(vec)
114
115 ! Let us add another line. A common scenario is that you will update a
116 ! vector at each time step, e.f. in user_check and then append the result
117 ! to the CSV file.
118 vec = 4.0_rp
119 call csv_writer%write(vec)
120
121 ! Note that the CSV writer will append to file, if it exists, so you have
122 ! to take care of that manually. Finally, note that one can also use
123 ! matrix_t objects to write to CSV files, in case you have 2D data.
124
125 end subroutine initialize
126
127 subroutine finalize(time)
128 type(time_state_t), intent(in) :: time
129
130 ! Don't forget to free the objects you initialized
131 call my_field1%free()
132 call my_field2%free()
133 call vec%free()
134 end subroutine finalize
135
136end module user
Master module.
Definition neko.f90:34
type(field_t), target my_field1
Definition output.f90:14
type(vector_t) vec
subroutine initialize(time)
subroutine user_setup(user)
subroutine startup(params)
type(field_t), target my_field2
Definition output.f90:15
subroutine finalize(time)