Neko 1.99.2
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
simulation_component.f90
Go to the documentation of this file.
1! Copyright (c) 2023, 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!
39 use num_types, only : rp
40 use json_module, only : json_file
41 use case, only : case_t
44 use time_state, only : time_state_t
45 implicit none
46 private
47
49 type, abstract, public :: simulation_component_t
51 type(case_t), pointer :: case
53 type(time_based_controller_t) :: preprocess_controller
55 type(time_based_controller_t) :: compute_controller
59 integer :: order
60 contains
62 procedure, pass(this) :: init_base => simulation_component_init_base
64 generic :: init_base_from_components => &
65 init_base_from_controllers_properties, &
66 init_base_from_controllers
70 procedure, pass(this) :: init_base_from_controllers => &
75 procedure, pass(this) :: init_base_from_controllers_properties => &
78 procedure, pass(this) :: free_base => simulation_component_free_base
81 procedure, pass(this) :: restart => simulation_component_restart_wrapper
84 procedure, pass(this) :: preprocess => &
88 procedure, pass(this) :: compute => simulation_component_compute_wrapper
90 procedure(simulation_component_init), pass(this), deferred :: init
92 procedure(simulation_component_free), pass(this), deferred :: free
94 procedure, pass(this) :: preprocess_
96 procedure, pass(this) :: compute_
98 procedure, pass(this) :: restart_
100 procedure, pass(this) :: parse_json => simulation_component_parse_json
102
105 class(simulation_component_t), allocatable :: simcomp
107
108
109 abstract interface
110
113 subroutine simulation_component_init(this, json, case)
114 import simulation_component_t, json_file, case_t
115 class(simulation_component_t), intent(inout), target :: this
116 type(json_file), intent(inout) :: json
117 class(case_t), intent(inout), target :: case
118 end subroutine simulation_component_init
119 end interface
120
121 abstract interface
122
125 class(simulation_component_t), intent(inout) :: this
126 end subroutine simulation_component_free
127 end interface
128
129 interface
130
135 module subroutine simulation_component_factory(object, json, case)
136 class(simulation_component_t), allocatable, intent(inout) :: object
137 type(json_file), intent(inout) :: json
138 class(case_t), intent(inout), target :: case
139 end subroutine simulation_component_factory
140 end interface
141
142 interface
143
146 module subroutine simulation_component_allocator(object, type_name)
147 class(simulation_component_t), allocatable, intent(inout) :: object
148 character(len=*), intent(in):: type_name
149 end subroutine simulation_component_allocator
150 end interface
151
152 !
153 ! Machinery for injecting user-defined types
154 !
155
159 abstract interface
160 subroutine simulation_component_allocate(obj)
161 import simulation_component_t
162 class(simulation_component_t), allocatable, intent(inout) :: obj
163 end subroutine simulation_component_allocate
164 end interface
165
166 interface
167
168 module subroutine register_simulation_component(type_name, allocator)
169 character(len=*), intent(in) :: type_name
170 procedure(simulation_component_allocate), pointer, intent(in) :: &
171 allocator
172 end subroutine register_simulation_component
173 end interface
174
175 ! A name-allocator pair for user-defined types. A helper type to define a
176 ! registry of custom allocators.
177 type allocator_entry
178 character(len=20) :: type_name
179 procedure(simulation_component_allocate), pointer, nopass :: allocator
180 end type allocator_entry
181
183 type(allocator_entry), allocatable :: simcomp_registry(:)
184
186 integer :: simcomp_registry_size = 0
187
188 public :: simulation_component_factory, simulation_component_allocator, &
189 register_simulation_component, simulation_component_allocate
190
191
192contains
194 subroutine simulation_component_init_base(this, json, case)
195 class(simulation_component_t), intent(inout) :: this
196 type(json_file), intent(inout) :: json
197 class(case_t), intent(inout), target :: case
198 character(len=:), allocatable :: preprocess_control, compute_control, &
199 output_control
200 real(kind=rp) :: preprocess_value, compute_value, output_value
201 integer :: order
202
203 call this%parse_json(json, case%params, preprocess_control, &
204 preprocess_value, compute_control, compute_value, output_control, &
205 output_value)
206
207 call json_get_or_default(json, "order", order, -1)
208
209 call this%init_base_from_components(case, order, &
210 preprocess_control, preprocess_value, compute_control, compute_value, &
211 output_control, output_value)
212
213 end subroutine simulation_component_init_base
214
225 subroutine simulation_component_init_base_from_controllers_properties(this, &
226 case, order, preprocess_control, preprocess_value, compute_control, &
227 compute_value, output_control, output_value)
228 class(simulation_component_t), intent(inout) :: this
229 class(case_t), intent(inout), target :: case
230 integer :: order
231 character(len=*), intent(in) :: preprocess_control
232 real(kind=rp), intent(in) :: preprocess_value
233 character(len=*), intent(in) :: compute_control
234 real(kind=rp), intent(in) :: compute_value
235 character(len=*), intent(in) :: output_control
236 real(kind=rp), intent(in) :: output_value
237
238 this%case => case
239 this%order = order
240
241 call this%preprocess_controller%init(case%time%start_time, &
242 case%time%end_time, preprocess_control, preprocess_value)
243 call this%compute_controller%init(case%time%start_time, case%time%end_time,&
244 compute_control, compute_value)
245 call this%output_controller%init(case%time%start_time, case%time%end_time, &
246 output_control, output_value)
247
248 end subroutine simulation_component_init_base_from_controllers_properties
249
256 subroutine simulation_component_init_base_from_controllers(this, case, order,&
257 preprocess_controller, compute_controller, output_controller)
258 class(simulation_component_t), intent(inout) :: this
259 class(case_t), intent(inout), target :: case
260 integer :: order
261 type(time_based_controller_t), intent(in) :: preprocess_controller
262 type(time_based_controller_t), intent(in) :: compute_controller
263 type(time_based_controller_t), intent(in) :: output_controller
264
265 this%case => case
266 this%order = order
267 this%preprocess_controller = preprocess_controller
268 this%compute_controller = compute_controller
269 this%output_controller = output_controller
270 end subroutine simulation_component_init_base_from_controllers
271
281 subroutine simulation_component_parse_json(this, json, case_params, &
282 preprocess_control, preprocess_value, compute_control, compute_value, &
283 output_control, output_value)
284 class(simulation_component_t), intent(inout) :: this
285 type(json_file), intent(inout) :: json
286 type(json_file), intent(inout) :: case_params
287 character(len=:), allocatable, intent(inout) :: preprocess_control
288 real(kind=rp), intent(out) :: preprocess_value
289 character(len=:), allocatable, intent(inout) :: compute_control
290 real(kind=rp), intent(out) :: compute_value
291 character(len=:), allocatable, intent(inout) :: output_control
292 real(kind=rp), intent(out) :: output_value
293
294 ! We default to preprocess every time-step
295 call json_get_or_default(json, "preprocess_control", preprocess_control, &
296 "tsteps")
297 call json_get_or_default(json, "preprocess_value", preprocess_value, 1.0_rp)
298
299 ! We default to compute every time-step
300 call json_get_or_default(json, "compute_control", compute_control, &
301 "tsteps")
302 call json_get_or_default(json, "compute_value", compute_value, 1.0_rp)
303
304 if (compute_control .eq. "fluid_output") then
305 call json_get(case_params, 'case.fluid.output_control', &
306 compute_control)
307 call json_get(case_params, 'case.fluid.output_value', &
308 compute_value)
309 end if
310
311 ! We default to output whenever we execute
312 call json_get_or_default(json, "output_control", output_control, &
313 compute_control)
314 call json_get_or_default(json, "output_value", output_value, &
315 compute_value)
316
317 if (output_control == "global") then
318 call json_get(case_params, 'case.fluid.output_control', &
319 output_control)
320 call json_get(case_params, 'case.fluid.output_value', &
321 output_value)
322 end if
323 end subroutine simulation_component_parse_json
324
326 subroutine simulation_component_free_base(this)
327 class(simulation_component_t), intent(inout) :: this
328
329 nullify(this%case)
330
331 call this%preprocess_controller%free()
332 call this%compute_controller%free()
333 call this%output_controller%free()
334 end subroutine simulation_component_free_base
335
339 subroutine simulation_component_preprocess_wrapper(this, time)
340 class(simulation_component_t), intent(inout) :: this
341 type(time_state_t), intent(in) :: time
342
343 if (this%preprocess_controller%check(time)) then
344 call this%preprocess_(time)
345 call this%preprocess_controller%register_execution()
346 end if
347 end subroutine simulation_component_preprocess_wrapper
348
352 subroutine simulation_component_compute_wrapper(this, time)
353 class(simulation_component_t), intent(inout) :: this
354 type(time_state_t), intent(in) :: time
355
356 if (this%compute_controller%check(time)) then
357 call this%compute_(time)
358 call this%compute_controller%register_execution()
359 end if
360 end subroutine simulation_component_compute_wrapper
361
364 subroutine simulation_component_restart_wrapper(this, time)
365 class(simulation_component_t), intent(inout) :: this
366 type(time_state_t), intent(in) :: time
367
368 call this%compute_controller%set_counter(time)
369 call this%output_controller%set_counter(time)
370 call this%restart_(time)
371
372 end subroutine simulation_component_restart_wrapper
373
376 subroutine restart_(this, time)
377 class(simulation_component_t), intent(inout) :: this
378 type(time_state_t), intent(in) :: time
379
380 ! Do nothing
381 end subroutine restart_
382
385 subroutine preprocess_(this, time)
386 class(simulation_component_t), intent(inout) :: this
387 type(time_state_t), intent(in) :: time
388
389 ! Do nothing
390 end subroutine preprocess_
391
394 subroutine compute_(this, time)
395 class(simulation_component_t), intent(inout) :: this
396 type(time_state_t), intent(in) :: time
397
398 ! Do nothing
399 end subroutine compute_
400end module simulation_component
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.
The common constructor using a JSON dictionary.
Defines a simulation case.
Definition case.f90:34
Utilities for retrieving parameters from the case files.
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Implements output_controller_t
Simulation components are objects that encapsulate functionality that can be fit to a particular comp...
subroutine simulation_component_free_base(this)
Destructor for the simulation_component_t (base) class.
subroutine restart_(this, time)
Dummy restart function.
subroutine simulation_component_restart_wrapper(this, time)
Wrapper for calling set_counter_ based for the controllers.
subroutine simulation_component_init_base_from_controllers(this, case, order, preprocess_controller, compute_controller, output_controller)
Constructor for the simulation_component_t (base) class from components.
subroutine preprocess_(this, time)
Dummy preprocessing function.
subroutine simulation_component_init_base_from_controllers_properties(this, case, order, preprocess_control, preprocess_value, compute_control, compute_value, output_control, output_value)
Constructor for the simulation_component_t (base) class via the properties of the time_based_controll...
subroutine simulation_component_init_base(this, json, case)
Constructor for the simulation_component_t (base) class.
subroutine compute_(this, time)
Dummy compute function.
subroutine simulation_component_preprocess_wrapper(this, time)
Wrapper for calling preprocess_ based on the preprocess_controller. Serves as the public interface.
subroutine simulation_component_parse_json(this, json, case_params, preprocess_control, preprocess_value, compute_control, compute_value, output_control, output_value)
Parse JSON to determine the properties of the time_based_controllers.
subroutine simulation_component_compute_wrapper(this, time)
Wrapper for calling compute_ based on the compute_controller. Serves as the public interface.
Contains the time_based_controller_t type.
Module with things related to the simulation time.
Base abstract class for simulation components.
A helper type that is needed to have an array of polymorphic objects.
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.