Neko 1.1.0
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
user_stats.f90
Go to the documentation of this file.
1! Copyright (c) 2024-2025, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
33!
35
37 use num_types, only : rp, dp, sp
38 use json_module, only : json_file
40 use registry, only : neko_registry
41 use field, only : field_t
42 use case, only : case_t
46 use mean_field, only : mean_field_t
47 use coefs, only : coef_t
48 use time_state, only : time_state_t
52 implicit none
53 private
54
57 type, public, extends(simulation_component_t) :: user_stats_t
58
60 real(kind=rp) :: start_time
62 real(kind=rp) :: time
64 type(mean_field_t), allocatable :: mean_fields(:)
66 integer :: n_avg_fields = 0
68 character(len=NEKO_VARNAME_LEN), allocatable :: field_names(:)
70 type(mean_field_output_t), private :: output
71 logical :: default_fname = .true.
72
73 contains
75 procedure, pass(this) :: init => user_stats_init_from_json
77 generic :: init_from_components => &
78 init_from_controllers, init_from_controllers_properties
80 procedure, pass(this) :: init_from_controllers => &
84 procedure, pass(this) :: init_from_controllers_properties => &
87 procedure, private, pass(this) :: init_common => user_stats_init_common
89 procedure, pass(this) :: free => user_stats_free
91 procedure, pass(this) :: compute_ => user_stats_compute
92 procedure, pass(this) :: restart_ => user_stats_restart
93 end type user_stats_t
94
95contains
96
100 subroutine user_stats_init_from_json(this, json, case)
101 class(user_stats_t), intent(inout), target :: this
102 type(json_file), intent(inout) :: json
103 class(case_t), intent(inout), target :: case
104 character(len=:), allocatable :: filename
105 character(len=:), allocatable :: avg_dir
106 character(len=:), allocatable :: name
107
108 call json_get_or_default(json, "name", name, "user_stats")
109 call this%init_base(json, case)
110
112 call json%info('fields', n_children = this%n_avg_fields)
113 call json_get(json, 'fields', this%field_names)
114 call json_get_or_lookup_or_default(json, 'start_time', this%start_time, 0.0_rp)
115 call json_get_or_default(json, 'avg_direction', avg_dir, 'none')
116
117 if (json%valid_path('output_filename')) then
118 call json_get(json, 'output_filename', filename)
119 call user_stats_init_common(this, name, this%start_time, &
120 case%fluid%c_Xh, avg_dir, filename = filename)
121 else
122 call user_stats_init_common(this, name, this%start_time, &
123 case%fluid%c_Xh, avg_dir)
124 end if
125
126 end subroutine user_stats_init_from_json
127
128 subroutine user_stats_restart(this, time)
129 class(user_stats_t), intent(inout) :: this
130 type(time_state_t), intent(in) :: time
131 character(len=NEKO_FNAME_LEN) :: fname
132 character(len=5) :: prefix, suffix
133 integer :: last_slash_pos
134 real(kind=rp) :: t
135 t = time%t
136 if (t .gt. this%time) this%time = t
137 if (this%default_fname) then
138 fname = this%output%file_%get_base_fname()
139 write (prefix, '(I5)') &
140 this%output%file_%file_type%get_start_counter()
141 call filename_suffix(fname, suffix)
142 last_slash_pos = &
144 if (last_slash_pos .ne. 0) then
145 fname = &
146 trim(fname(1:last_slash_pos))// &
147 "user_stats"//trim(adjustl(prefix))//"."//suffix
148 else
149 fname = "user_stats"// &
150 trim(adjustl(prefix))//"."//suffix
151 end if
152 call this%output%init_base(fname)
153 end if
154 end subroutine user_stats_restart
155
169 subroutine user_stats_init_from_controllers(this, name, case, order, &
170 preprocess_controller, compute_controller, output_controller, &
171 start_time, coef, avg_dir, filename, precision)
172 class(user_stats_t), intent(inout) :: this
173 character(len=*), intent(in) :: name
174 class(case_t), intent(inout), target :: case
175 integer :: order
176 type(time_based_controller_t), intent(in) :: preprocess_controller
177 type(time_based_controller_t), intent(in) :: compute_controller
178 type(time_based_controller_t), intent(in) :: output_controller
179 real(kind=rp), intent(in) :: start_time
180 character(len=*), intent(in) :: avg_dir
181 type(coef_t), intent(inout) :: coef
182 character(len=*), intent(in), optional :: filename
183 integer, intent(in), optional :: precision
184
185 call this%init_base_from_components(case, order, preprocess_controller, &
186 compute_controller, output_controller)
187 call this%init_common(name, start_time, coef, avg_dir, filename, precision)
188
190
210 case, order, preprocess_control, preprocess_value, compute_control, &
211 compute_value, output_control, output_value, start_time, coef, avg_dir, &
212 filename, precision)
213 class(user_stats_t), intent(inout) :: this
214 character(len=*), intent(in) :: name
215 class(case_t), intent(inout), target :: case
216 integer :: order
217 character(len=*), intent(in) :: preprocess_control
218 real(kind=rp), intent(in) :: preprocess_value
219 character(len=*), intent(in) :: compute_control
220 real(kind=rp), intent(in) :: compute_value
221 character(len=*), intent(in) :: output_control
222 real(kind=rp), intent(in) :: output_value
223 real(kind=rp), intent(in) :: start_time
224 character(len=*), intent(in) :: avg_dir
225 type(coef_t), intent(inout) :: coef
226 character(len=*), intent(in), optional :: filename
227 integer, intent(in), optional :: precision
228
229 call this%init_base_from_components(case, order, preprocess_control, &
230 preprocess_value, compute_control, compute_value, output_control, &
231 output_value)
232 call this%init_common(name, start_time, coef, avg_dir, filename, precision)
233
235
236
242 subroutine user_stats_init_common(this, name, start_time, coef, avg_dir, &
243 filename, precision)
244 class(user_stats_t), intent(inout) :: this
245 character(len=*), intent(in) :: name
246 character(len=*), intent(in), optional :: filename
247 integer, intent(in), optional :: precision
248 real(kind=rp), intent(in) :: start_time
249 character(len=*), intent(in) :: avg_dir
250 type(coef_t), intent(inout) :: coef
251 integer :: i
252 type(field_t), pointer :: field_to_avg
253 character(len=NEKO_FNAME_LEN) :: stats_fname
254
255 character(len=1024) :: unique_name
256 unique_name = name // "/"
257
258 this%name = name
259 this%start_time = start_time
260 this%time = start_time
261
262 if (present(filename)) then
263 this%default_fname = .false.
264 stats_fname = filename
265 else
266 stats_fname = "user_stats0"
267 this%default_fname = .true.
268 end if
269
271 allocate(this%mean_fields(this%n_avg_fields))
272 do i = 1, this%n_avg_fields
273 field_to_avg => neko_registry%get_field(trim(this%field_names(i)))
274 call this%mean_fields(i)%init(field_to_avg, trim(unique_name) // &
275 "mean_" // trim(this%field_names(i)))
276 end do
277
278 call this%output%init(this%mean_fields, this%n_avg_fields, &
279 this%start_time, coef, avg_dir, name = filename)
280 call this%case%output_controller%add(this%output, &
281 this%output_controller%control_value, &
282 this%output_controller%control_mode)
283
284 nullify(field_to_avg)
285
286 end subroutine user_stats_init_common
287
289 subroutine user_stats_free(this)
290 class(user_stats_t), intent(inout) :: this
291 integer :: i
292
293 call this%free_base()
294
295 if (allocated(this%mean_fields)) then
296 do i = 1, this%n_avg_fields
297 call this%mean_fields(i)%free()
298 end do
299 deallocate(this%mean_fields)
300 end if
301
302 if (allocated(this%field_names)) then
303 deallocate(this%field_names)
304 end if
305
306 end subroutine user_stats_free
307
310 subroutine user_stats_compute(this, time)
311 class(user_stats_t), intent(inout) :: this
312 type(time_state_t), intent(in) :: time
313 integer :: i
314
316 if (time%t .ge. this%start_time) then
317 do i = 1, this%n_avg_fields
318 call this%mean_fields(i)%update(time%t - this%time)
319 end do
320 this%time = time%t
321 end if
322
323 end subroutine user_stats_compute
324
325end module user_stats
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.
Defines a simulation case.
Definition case.f90:34
Coefficients.
Definition coef.f90:34
Defines a field.
Definition field.f90:34
Utilities for retrieving parameters from the case files.
Defines an output for a list of mean fields.
Implements mean_field_t.
integer, parameter, public dp
Definition num_types.f90:9
integer, parameter, public sp
Definition num_types.f90:8
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Implements output_controller_t
Defines an output.
Definition output.f90:34
Defines a registry for storing solution fields.
Definition registry.f90:34
type(registry_t), target, public neko_registry
Global field registry.
Definition registry.f90:144
Simulation components are objects that encapsulate functionality that can be fit to a particular comp...
subroutine restart_(this, time)
Dummy restart function.
subroutine compute_(this, time)
Dummy compute function.
Contains the time_based_controller_t type.
Module with things related to the simulation time.
Implements the user_stats_t type.
subroutine user_stats_free(this)
Destructor.
subroutine user_stats_compute(this, time)
Update the running averages.
subroutine user_stats_restart(this, time)
subroutine user_stats_init_from_controllers_properties(this, name, case, order, preprocess_control, preprocess_value, compute_control, compute_value, output_control, output_value, start_time, coef, avg_dir, filename, precision)
Constructor from components, passing properties to the time_based_controller` components in the base ...
subroutine user_stats_init_from_json(this, json, case)
Constructor from json.
subroutine user_stats_init_common(this, name, start_time, coef, avg_dir, filename, precision)
Common part of constructors.
subroutine user_stats_init_from_controllers(this, name, case, order, preprocess_controller, compute_controller, output_controller, start_time, coef, avg_dir, filename, precision)
Constructor from components, passing controllers.
Utilities.
Definition utils.f90:35
integer, parameter, public neko_fname_len
Definition utils.f90:42
subroutine, public filename_suffix(fname, suffix)
Extract a filename's suffix.
Definition utils.f90:124
integer, parameter, public neko_varname_len
Definition utils.f90:43
pure integer function, public filename_tslash_pos(fname)
Find position (in the string) of a filename's trailing slash.
Definition utils.f90:81
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:63
Computes the temporal mean of a field.
Output for a list of mean fields.
Base abstract class for simulation components.
A utility type for determining whether an action should be executed based on the current time value....
A struct that contains all info about the time, expand as needed.
A simulation component that computes the averages of fields in the registry.