Neko 1.99.9
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-2026, 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
51 implicit none
52 private
53
56 type, public, extends(simulation_component_t) :: user_stats_t
57
59 real(kind=dp) :: start_time
61 real(kind=dp) :: time
63 type(mean_field_t), allocatable :: mean_fields(:)
65 integer :: n_avg_fields = 0
67 character(len=NEKO_VARNAME_LEN), allocatable :: field_names(:)
69 type(mean_field_output_t), private :: output
71 character(len=:), allocatable :: base_filename
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, &
115 0.0_dp)
116 call json_get_or_default(json, 'avg_direction', avg_dir, 'none')
117
118 if (json%valid_path('output_filename')) then
119 call json_get(json, 'output_filename', filename)
120 call user_stats_init_common(this, name, this%start_time, &
121 case%fluid%c_Xh, avg_dir, filename = filename)
122 else
123 call user_stats_init_common(this, name, this%start_time, &
124 case%fluid%c_Xh, avg_dir)
125 end if
126
127 end subroutine user_stats_init_from_json
128
129 subroutine user_stats_restart(this, time)
130 class(user_stats_t), intent(inout) :: this
131 type(time_state_t), intent(in) :: time
132 character(len=NEKO_FNAME_LEN) :: fname
133 character(len=5) :: prefix, suffix
134 real(kind=rp) :: t
135
136 t = time%t
137 if (t .gt. this%time) this%time = t
138
139 fname = this%output%file_%get_base_fname()
140 write (prefix, '(I0)') &
141 this%output%file_%file_type%get_start_counter()
142 call filename_suffix(fname, suffix)
143 fname = trim(this%case%output_directory) // &
144 trim(this%base_filename) // trim(prefix) // "." // trim(suffix)
145 call this%output%init_base(fname)
146
147 end subroutine user_stats_restart
148
162 subroutine user_stats_init_from_controllers(this, name, case, order, &
163 preprocess_controller, compute_controller, output_controller, &
164 start_time, coef, avg_dir, filename, precision)
165 class(user_stats_t), intent(inout) :: this
166 character(len=*), intent(in) :: name
167 class(case_t), intent(inout), target :: case
168 integer :: order
169 type(time_based_controller_t), intent(in) :: preprocess_controller
170 type(time_based_controller_t), intent(in) :: compute_controller
171 type(time_based_controller_t), intent(in) :: output_controller
172 real(kind=dp), intent(in) :: start_time
173 character(len=*), intent(in) :: avg_dir
174 type(coef_t), intent(inout) :: coef
175 character(len=*), intent(in), optional :: filename
176 integer, intent(in), optional :: precision
177
178 call this%init_base_from_components(case, order, preprocess_controller, &
179 compute_controller, output_controller)
180 call this%init_common(name, start_time, coef, avg_dir, filename, precision)
181
183
203 case, order, preprocess_control, preprocess_value, compute_control, &
204 compute_value, output_control, output_value, start_time, coef, avg_dir, &
205 filename, precision)
206 class(user_stats_t), intent(inout) :: this
207 character(len=*), intent(in) :: name
208 class(case_t), intent(inout), target :: case
209 integer :: order
210 character(len=*), intent(in) :: preprocess_control
211 real(kind=dp), intent(in) :: preprocess_value
212 character(len=*), intent(in) :: compute_control
213 real(kind=dp), intent(in) :: compute_value
214 character(len=*), intent(in) :: output_control
215 real(kind=dp), intent(in) :: output_value
216 real(kind=dp), intent(in) :: start_time
217 character(len=*), intent(in) :: avg_dir
218 type(coef_t), intent(inout) :: coef
219 character(len=*), intent(in), optional :: filename
220 integer, intent(in), optional :: precision
221
222 call this%init_base_from_components(case, order, preprocess_control, &
223 preprocess_value, compute_control, compute_value, output_control, &
224 output_value)
225 call this%init_common(name, start_time, coef, avg_dir, filename, precision)
226
228
229
235 subroutine user_stats_init_common(this, name, start_time, coef, avg_dir, &
236 filename, precision)
237 class(user_stats_t), intent(inout) :: this
238 character(len=*), intent(in) :: name
239 character(len=*), intent(in), optional :: filename
240 integer, intent(in), optional :: precision
241 real(kind=dp), intent(in) :: start_time
242 character(len=*), intent(in) :: avg_dir
243 type(coef_t), intent(inout) :: coef
244 integer :: i
245 type(field_t), pointer :: field_to_avg
246 character(len=NEKO_FNAME_LEN) :: stats_fname
247 character(len=1024) :: unique_name
248
249 unique_name = name // "/"
250
251 this%name = name
252 this%start_time = start_time
253 this%time = start_time
254
255 if (present(filename)) then
256 this%base_filename = filename
257 else
258 this%base_filename = "user_stats"
259 end if
260 stats_fname = trim(this%base_filename) // "0"
261
263 allocate(this%mean_fields(this%n_avg_fields))
264 do i = 1, this%n_avg_fields
265 field_to_avg => neko_registry%get_field(trim(this%field_names(i)))
266 call this%mean_fields(i)%init(field_to_avg, trim(unique_name) // &
267 "mean_" // trim(this%field_names(i)))
268 end do
269
270 call this%output%init(this%mean_fields, this%n_avg_fields, &
271 this%start_time, coef, avg_dir, name = stats_fname, &
272 path = this%case%output_directory)
273 ! Statistics are averaged over the interval between two writes, so
274 ! writing at the very start of the averaging would only produce an
275 ! empty file. The schedule is anchored to the start of the averaging.
276 call this%case%output_controller%add(this%output, &
277 this%output_controller%control_value, &
278 this%output_controller%control_mode, &
279 start_time = max(this%start_time, this%case%time%start_time), &
280 write_at_start = .false.)
281
282 nullify(field_to_avg)
283
284 end subroutine user_stats_init_common
285
287 subroutine user_stats_free(this)
288 class(user_stats_t), intent(inout) :: this
289 integer :: i
290
291 call this%free_base()
292
293 if (allocated(this%mean_fields)) then
294 do i = 1, this%n_avg_fields
295 call this%mean_fields(i)%free()
296 end do
297 deallocate(this%mean_fields)
298 end if
299
300 if (allocated(this%field_names)) then
301 deallocate(this%field_names)
302 end if
303
304 end subroutine user_stats_free
305
308 subroutine user_stats_compute(this, time)
309 class(user_stats_t), intent(inout) :: this
310 type(time_state_t), intent(in) :: time
311 integer :: i
312
314 if (time%t .ge. this%start_time) then
315 do i = 1, this%n_avg_fields
316 call this%mean_fields(i)%update( real(time%t - this%time, kind=rp) )
317 end do
318 this%time = time%t
319 end if
320
321 end subroutine user_stats_compute
322
323end module user_stats
double real
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:10
integer, parameter, public sp
Definition num_types.f90:8
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
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:158
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:161
integer, parameter, public neko_varname_len
Definition utils.f90:43
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:135
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.
#define max(a, b)
Definition tensor.cu:40