Loading [MathJax]/extensions/tex2jax.js
Neko 0.9.99
A portable framework for high-order spectral element flow simulations
All Classes Namespaces Files Functions Variables Typedefs Enumerator Macros Pages
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 procedure, pass(this) :: free_base => simulation_component_free_base
67 procedure, pass(this) :: restart => simulation_component_restart_wrapper
70 procedure, pass(this) :: preprocess => &
74 procedure, pass(this) :: compute => simulation_component_compute_wrapper
76 procedure(simulation_component_init), pass(this), deferred :: init
78 procedure(simulation_component_free), pass(this), deferred :: free
80 procedure, pass(this) :: preprocess_
82 procedure, pass(this) :: compute_
84 procedure, pass(this) :: restart_
86
89 class(simulation_component_t), allocatable :: simcomp
91
92
93 abstract interface
94
97 subroutine simulation_component_init(this, json, case)
98 import simulation_component_t, json_file, case_t
99 class(simulation_component_t), intent(inout) :: this
100 type(json_file), intent(inout) :: json
101 class(case_t), intent(inout), target :: case
102 end subroutine simulation_component_init
103 end interface
104
105 abstract interface
106
109 class(simulation_component_t), intent(inout) :: this
110 end subroutine simulation_component_free
111 end interface
112
113 interface
114
119 module subroutine simulation_component_factory(object, json, case)
120 class(simulation_component_t), allocatable, intent(inout) :: object
121 type(json_file), intent(inout) :: json
122 class(case_t), intent(inout), target :: case
123 end subroutine simulation_component_factory
124 end interface
125
126 interface
127
130 module subroutine simulation_component_allocator(object, type_name)
131 class(simulation_component_t), allocatable, intent(inout) :: object
132 character(len=*), intent(in):: type_name
133 end subroutine simulation_component_allocator
134 end interface
135
136 !
137 ! Machinery for injecting user-defined types
138 !
139
143 abstract interface
144 subroutine simulation_component_allocate(obj)
145 import simulation_component_t
146 class(simulation_component_t), allocatable, intent(inout) :: obj
147 end subroutine simulation_component_allocate
148 end interface
149
150 interface
151
152 module subroutine register_simulation_component(type_name, allocator)
153 character(len=*), intent(in) :: type_name
154 procedure(simulation_component_allocate), pointer, intent(in) :: &
155 allocator
156 end subroutine register_simulation_component
157 end interface
158
159 ! A name-allocator pair for user-defined types. A helper type to define a
160 ! registry of custom allocators.
161 type allocator_entry
162 character(len=20) :: type_name
163 procedure(simulation_component_allocate), pointer, nopass :: allocator
164 end type allocator_entry
165
167 type(allocator_entry), allocatable :: simcomp_registry(:)
168
170 integer :: simcomp_registry_size = 0
171
172 public :: simulation_component_factory, simulation_component_allocator, &
173 register_simulation_component, simulation_component_allocate
174
175
176contains
178 subroutine simulation_component_init_base(this, json, case)
179 class(simulation_component_t), intent(inout) :: this
180 type(json_file), intent(inout) :: json
181 class(case_t), intent(inout), target :: case
182 character(len=:), allocatable :: preprocess_control, compute_control, &
183 output_control
184 real(kind=rp) :: preprocess_value, compute_value, output_value
185 integer :: order
186
187 this%case => case
188
189 ! We default to preprocess every time-step
190 call json_get_or_default(json, "preprocess_control", preprocess_control, &
191 "tsteps")
192 call json_get_or_default(json, "preprocess_value", preprocess_value, 1.0_rp)
193
194 ! We default to compute every time-step
195 call json_get_or_default(json, "compute_control", compute_control, &
196 "tsteps")
197 call json_get_or_default(json, "compute_value", compute_value, 1.0_rp)
198
199 if (compute_control .eq. "fluid_output") then
200 call json_get(this%case%params, 'case.fluid.output_control', &
201 compute_control)
202 call json_get(this%case%params, 'case.fluid.output_value', &
203 compute_value)
204 end if
205
206 ! We default to output whenever we execute
207 call json_get_or_default(json, "output_control", output_control, &
208 compute_control)
209 call json_get_or_default(json, "output_value", output_value, &
210 compute_value)
211
212 if (output_control == "global") then
213 call json_get(this%case%params, 'case.fluid.output_control', &
214 output_control)
215 call json_get(this%case%params, 'case.fluid.output_value', &
216 output_value)
217 end if
218
219 call json_get_or_default(json, "order", order, -1)
220 this%order = order
221
222 call this%preprocess_controller%init(case%time%end_time, &
223 preprocess_control, preprocess_value)
224 call this%compute_controller%init(case%time%end_time, compute_control, &
225 compute_value)
226 call this%output_controller%init(case%time%end_time, output_control, &
227 output_value)
228
229 end subroutine simulation_component_init_base
230
232 subroutine simulation_component_free_base(this)
233 class(simulation_component_t), intent(inout) :: this
234
235 nullify(this%case)
236 end subroutine simulation_component_free_base
237
241 subroutine simulation_component_preprocess_wrapper(this, time)
242 class(simulation_component_t), intent(inout) :: this
243 type(time_state_t), intent(in) :: time
244
245 if (this%preprocess_controller%check(time)) then
246 call this%preprocess_(time)
247 call this%preprocess_controller%register_execution()
248 end if
249 end subroutine simulation_component_preprocess_wrapper
250
254 subroutine simulation_component_compute_wrapper(this, time)
255 class(simulation_component_t), intent(inout) :: this
256 type(time_state_t), intent(in) :: time
257
258 if (this%compute_controller%check(time)) then
259 call this%compute_(time)
260 call this%compute_controller%register_execution()
261 end if
262 end subroutine simulation_component_compute_wrapper
263
266 subroutine simulation_component_restart_wrapper(this, time)
267 class(simulation_component_t), intent(inout) :: this
268 type(time_state_t), intent(in) :: time
269
270 call this%compute_controller%set_counter(time)
271 call this%output_controller%set_counter(time)
272 call this%restart_(time)
273
274 end subroutine simulation_component_restart_wrapper
275
278 subroutine restart_(this, time)
279 class(simulation_component_t), intent(inout) :: this
280 type(time_state_t), intent(in) :: time
281
282 ! Do nothing
283 end subroutine restart_
284
287 subroutine preprocess_(this, time)
288 class(simulation_component_t), intent(inout) :: this
289 type(time_state_t), intent(in) :: time
290
291 ! Do nothing
292 end subroutine preprocess_
293
296 subroutine compute_(this, time)
297 class(simulation_component_t), intent(inout) :: this
298 type(time_state_t), intent(in) :: time
299
300 ! Do nothing
301 end subroutine compute_
302end 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 preprocess_(this, time)
Dummy preprocessing function.
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_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.