38 use json_module,
only : json_file
58 integer,
private :: n_simcomps
62 logical,
private :: finalized = .false.
93 type(
case_t),
target,
intent(inout) :: case
94 character(len=*),
optional,
intent(in) :: simcomp_root
95 integer :: n_simcomps, i
96 type(json_file) :: comp_subdict
99 logical,
allocatable :: mask(:)
101 integer,
allocatable :: read_order(:), order(:)
105 character(len=:),
allocatable :: root_name, comp_type
111 if (
present(simcomp_root))
then
112 root_name = simcomp_root
114 root_name =
'case.simulation_components'
118 if (.not. (root_name .in.
case%params))
return
119 call neko_log%section(
'Initialize simcomp')
122 call case%params%info(root_name, n_children = n_simcomps)
123 this%n_simcomps = n_simcomps
124 allocate(this%simcomps(n_simcomps))
125 allocate(order(n_simcomps))
126 allocate(read_order(n_simcomps))
127 allocate(
mask(n_simcomps), source = .true.)
137 if (read_order(i) .gt. max_order)
then
138 max_order = read_order(i)
145 if (read_order(i) == -1)
then
146 max_order = max_order + 1
147 read_order(i) = max_order
155 loc = minloc(read_order,
mask =
mask)
165 call json_get(comp_subdict,
"type", comp_type)
166 call neko_log%message(
'- ' // trim(comp_type))
168 call this%simcomps(i)%init(comp_subdict,
case)
173 deallocate(read_order)
184 if (
allocated(this%simcomps))
then
185 do i = 1, this%n_simcomps
186 call this%simcomps(i)%free()
188 deallocate(this%simcomps)
192 this%finalized = .false.
201 integer :: i, j, order, max_order
202 logical :: order_found, previous_found
205 integer,
allocatable :: order_list(:)
208 do i = 1, this%n_simcomps
209 if (.not. this%simcomps(i)%is_allocated())
then
210 call neko_error(
"Simulation component not initialized.")
215 previous_found = .true.
216 do order = 1, this%n_simcomps
217 order_found = .false.
218 do i = 1, this%n_simcomps
219 if (this%simcomps(i)%simcomp%order == order .and. order_found)
then
220 call neko_error(
"Simulation component order must be unique.")
221 else if (this%simcomps(i)%simcomp%order == order)
then
225 if (order_found .and. .not. previous_found)
then
226 call neko_error(
"Simulation component order must be contiguous " // &
229 previous_found = order_found
232 allocate(order_list(this%n_simcomps))
235 do i = 1, this%n_simcomps
236 order_list(i) = this%simcomps(i)%simcomp%order
237 if (order_list(i) .gt. max_order)
then
238 max_order = order_list(i)
242 do i = 1, this%n_simcomps
243 if (order_list(i) .eq. -1)
then
244 order_list(i) = max_order + 1
245 max_order = max_order + 1
250 do i = 1, this%n_simcomps
251 if (order_list(i) .gt. this%n_simcomps)
then
252 deallocate(order_list)
253 call neko_error(
"Simulation component order is out of bounds.")
258 call move_alloc(this%simcomps, tmp_simcomps)
259 allocate(this%simcomps(this%n_simcomps))
260 do i = 1, this%n_simcomps
261 order = order_list(i)
262 call this%simcomps(order)%move_from(tmp_simcomps(i))
263 call tmp_simcomps(i)%free()
266 if (
allocated(tmp_simcomps))
then
267 deallocate(tmp_simcomps)
269 if (
allocated(order_list))
then
270 deallocate(order_list)
274 do i = 1, this%n_simcomps - 1
275 do j = i + 1, this%n_simcomps
276 associate(simcomp_i => this%simcomps(i)%simcomp, &
277 simcomp_j => this%simcomps(j)%simcomp)
278 if (simcomp_i%name .eq. simcomp_j%name)
then
279 call neko_error(
"Simulation component names must be unique. " &
280 //
"Duplicate name: " // trim(simcomp_i%name))
286 this%finalized = .true.
293 type(time_state_t),
intent(in) :: time
296 if (.not. this%finalized)
call this%finalize()
298 if (
allocated(this%simcomps))
then
299 do i = 1,
size(this%simcomps)
300 call this%simcomps(i)%simcomp%preprocess(time)
313 type(time_state_t),
intent(in) :: time
318 if (
allocated(this%simcomps))
then
319 do i = 1,
size(this%simcomps)
320 if (
allocated(this%simcomps(i)%simcomp))
then
321 t = min(t, this%simcomps(i)%simcomp%time_to_next(time))
332 type(time_state_t),
intent(in) :: time
335 if (.not. this%finalized)
call this%finalize()
337 if (
allocated(this%simcomps))
then
338 do i = 1, this%n_simcomps
339 call this%simcomps(i)%simcomp%compute(time)
349 type(time_state_t),
intent(in) :: time
352 if (
allocated(this%simcomps))
then
353 do i = 1, this%n_simcomps
354 call this%simcomps(i)%simcomp%restart(time)
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.
Utilities for retrieving parameters from the case files.
type(log_t), public neko_log
Global log stream.
Object for handling masks in Neko.
integer, parameter, public dp
integer, parameter, public rp
Global precision used in computations.
Contains the simcomp_executor_t type.
subroutine simcomp_executor_restart(this, time)
Execute restart for all simcomps.
subroutine simcomp_executor_compute(this, time)
Execute compute_ for all simcomps.
type(simcomp_executor_t), target, public neko_simcomps
Global variable for the simulation component driver.
subroutine simcomp_executor_finalize(this)
Finalize the initialization. Sorts the simcomps based on the order property. Additionally we check th...
subroutine simcomp_executor_init(this, case, simcomp_root)
Constructor.
real(kind=dp) function simcomp_executor_time_to_next(this, time)
The time until the next scheduled execution of preprocess, compute or the output of any simcomp,...
pure integer function simcomp_executor_get_n(this)
Get the number of simcomps.
subroutine simcomp_executor_preprocess(this, time)
Execute preprocess_ for all simcomps.
subroutine simcomp_executor_free(this)
Destructor.
Simulation components are objects that encapsulate functionality that can be fit to a particular comp...
Module with things related to the simulation time.
Singleton type that serves as a driver for the simulation components. Stores all the components in th...
Base abstract class for simulation components.
A helper type that is needed to have an array of polymorphic objects.
A struct that contains all info about the time, expand as needed.