Neko 1.99.1
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 end subroutine simulation_component_free_base
331
335 subroutine simulation_component_preprocess_wrapper(this, time)
336 class(simulation_component_t), intent(inout) :: this
337 type(time_state_t), intent(in) :: time
338
339 if (this%preprocess_controller%check(time)) then
340 call this%preprocess_(time)
341 call this%preprocess_controller%register_execution()
342 end if
343 end subroutine simulation_component_preprocess_wrapper
344
348 subroutine simulation_component_compute_wrapper(this, time)
349 class(simulation_component_t), intent(inout) :: this
350 type(time_state_t), intent(in) :: time
351
352 if (this%compute_controller%check(time)) then
353 call this%compute_(time)
354 call this%compute_controller%register_execution()
355 end if
356 end subroutine simulation_component_compute_wrapper
357
360 subroutine simulation_component_restart_wrapper(this, time)
361 class(simulation_component_t), intent(inout) :: this
362 type(time_state_t), intent(in) :: time
363
364 call this%compute_controller%set_counter(time)
365 call this%output_controller%set_counter(time)
366 call this%restart_(time)
367
368 end subroutine simulation_component_restart_wrapper
369
372 subroutine restart_(this, time)
373 class(simulation_component_t), intent(inout) :: this
374 type(time_state_t), intent(in) :: time
375
376 ! Do nothing
377 end subroutine restart_
378
381 subroutine preprocess_(this, time)
382 class(simulation_component_t), intent(inout) :: this
383 type(time_state_t), intent(in) :: time
384
385 ! Do nothing
386 end subroutine preprocess_
387
390 subroutine compute_(this, time)
391 class(simulation_component_t), intent(inout) :: this
392 type(time_state_t), intent(in) :: time
393
394 ! Do nothing
395 end subroutine compute_
396end 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.