38 use json_module,
only : json_file, json_core, json_value
87 type(
case_t),
target,
intent(inout) :: case
88 character(len=*),
optional,
intent(in) :: simcomp_root
89 integer :: n_simcomps, i
90 type(json_core) :: core
91 type(json_value),
pointer :: simcomp_object
92 type(json_file) :: comp_subdict
93 logical :: found, is_user, has_user
95 logical,
allocatable :: mask(:)
97 integer,
allocatable :: read_order(:), order(:)
101 character(len=:),
allocatable :: root_name, comp_type
107 if (
present(simcomp_root))
then
108 root_name = simcomp_root
110 root_name =
'case.simulation_components'
114 call case%params%get_core(core)
115 call case%params%get(root_name, simcomp_object, found)
116 if (.not. found)
return
117 call neko_log%section(
'Initialize simcomp')
120 call case%params%info(root_name, n_children = n_simcomps)
121 this%n_simcomps = n_simcomps
122 allocate(this%simcomps(n_simcomps))
123 allocate(order(n_simcomps))
124 allocate(read_order(n_simcomps))
125 allocate(mask(n_simcomps), source = .true.)
136 has_user = has_user .or. is_user
139 if (read_order(i) .gt. max_order)
then
140 max_order = read_order(i)
147 if (read_order(i) == -1)
then
148 max_order = max_order + 1
149 read_order(i) = max_order
157 loc = minloc(read_order, mask = mask)
167 call json_get(comp_subdict,
"type", comp_type)
169 if (.not. is_user)
call neko_log%message(
'- ' // trim(comp_type))
171 call simulation_component_factory(this%simcomps(i)%simcomp, &
176 call neko_log%message(
'Initialize user simcomp')
178 comp_subdict = json_file(simcomp_object)
179 call case%usr%init_user_simcomp(comp_subdict)
185 deallocate(read_order)
196 if (
allocated(this%simcomps))
then
197 do i = 1, this%n_simcomps
198 call this%simcomps(i)%simcomp%free
200 deallocate(this%simcomps)
210 type(json_file),
intent(inout) :: settings
213 integer :: i, position
217 do i = 1, this%n_simcomps
218 if (.not.
allocated(this%simcomps(i)%simcomp))
then
225 if (position == 0)
then
226 call move_alloc(this%simcomps, tmp_simcomps)
227 allocate(this%simcomps(this%n_simcomps + 1))
229 if (
allocated(tmp_simcomps))
then
230 do i = 1, this%n_simcomps
231 call move_alloc(tmp_simcomps(i)%simcomp, this%simcomps(i)%simcomp)
233 deallocate(tmp_simcomps)
236 this%n_simcomps = this%n_simcomps + 1
237 position = this%n_simcomps
240 this%simcomps(position)%simcomp = object
241 call this%simcomps(position)%simcomp%init(settings, this%case)
243 if (
allocated(tmp_simcomps))
then
244 deallocate(tmp_simcomps)
255 integer :: i, order, max_order
256 logical :: order_found, previous_found
259 integer,
allocatable :: order_list(:)
262 do i = 1, this%n_simcomps
263 if (.not.
allocated(this%simcomps(i)%simcomp))
then
264 call neko_error(
"Simulation component not initialized.")
269 previous_found = .true.
270 do order = 1, this%n_simcomps
271 order_found = .false.
272 do i = 1, this%n_simcomps
273 if (this%simcomps(i)%simcomp%order == order .and. order_found)
then
274 call neko_error(
"Simulation component order must be unique.")
275 else if (this%simcomps(i)%simcomp%order == order)
then
279 if (order_found .and. .not. previous_found)
then
280 call neko_error(
"Simulation component order must be contiguous &
283 previous_found = order_found
286 allocate(order_list(this%n_simcomps))
289 do i = 1, this%n_simcomps
290 order_list(i) = this%simcomps(i)%simcomp%order
291 if (order_list(i) .gt. max_order)
then
292 max_order = order_list(i)
296 do i = 1, this%n_simcomps
297 if (order_list(i) .eq. -1)
then
298 order_list(i) = max_order + 1
299 max_order = max_order + 1
304 do i = 1, this%n_simcomps
305 if (order_list(i) .gt. this%n_simcomps)
then
306 deallocate(order_list)
307 call neko_error(
"Simulation component order is out of bounds.")
312 call move_alloc(this%simcomps, tmp_simcomps)
313 allocate(this%simcomps(this%n_simcomps))
314 do i = 1, this%n_simcomps
315 order = order_list(i)
316 call move_alloc(tmp_simcomps(i)%simcomp, this%simcomps(order)%simcomp)
319 if (
allocated(tmp_simcomps))
then
320 deallocate(tmp_simcomps)
322 if (
allocated(order_list))
then
323 deallocate(order_list)
332 real(kind=
rp),
intent(in) :: t
333 integer,
intent(in) :: tstep
336 if (
allocated(this%simcomps))
then
337 do i = 1,
size(this%simcomps)
338 call this%simcomps(i)%simcomp%preprocess(t, tstep)
349 real(kind=
rp),
intent(in) :: t
350 integer,
intent(in) :: tstep
353 if (
allocated(this%simcomps))
then
354 do i = 1, this%n_simcomps
355 call this%simcomps(i)%simcomp%compute(t, tstep)
365 real(kind=
rp),
intent(in) :: t
368 if (
allocated(this%simcomps))
then
369 do i = 1, this%n_simcomps
370 call this%simcomps(i)%simcomp%restart(t)
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.
integer, parameter, public rp
Global precision used in computations.
Contains the simcomp_executor_t type.
subroutine simcomp_executor_add(this, object, settings)
Appending a new simcomp to the executor.
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_restart(this, t)
Execute restart for all simcomps.
subroutine simcomp_executor_init(this, case, simcomp_root)
Constructor.
subroutine simcomp_executor_compute(this, t, tstep)
Execute compute_ for all simcomps.
subroutine simcomp_executor_free(this)
Destructor.
subroutine simcomp_executor_preprocess(this, t, tstep)
Execute preprocess_ for all simcomps.
Simulation components are objects that encapsulate functionality that can be fit to a particular comp...
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.