Neko  0.8.1
A portable framework for high-order spectral element flow simulations
simcomp_executor.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 !
36  use num_types, only : rp
39  use json_module, only : json_file, json_core, json_value
41  use case, only : case_t
42  implicit none
43  private
44 
51  type, public :: simcomp_executor_t
53  class(simulation_component_wrapper_t), allocatable :: simcomps(:)
56  integer, allocatable :: order(:)
57  contains
59  procedure, pass(this) :: init => simcomp_executor_init
61  procedure, pass(this) :: free => simcomp_executor_free
63  procedure, pass(this) :: compute => simcomp_executor_compute
65  procedure, pass(this) :: restart=> simcomp_executor_restart
66 
67  end type simcomp_executor_t
68 
71 
72 contains
73 
75  subroutine simcomp_executor_init(this, case)
76  class(simcomp_executor_t), intent(inout) :: this
77  type(case_t), target, intent(inout) :: case
78  integer :: n_simcomps, i
79  type(json_core) :: core
80  type(json_value), pointer :: simcomp_object
81  type(json_file) :: comp_subdict
82  logical :: found
83  ! Help array for finding minimal values
84  logical, allocatable :: mask(:)
85  ! The order value for each simcomp in order of appearance in the case file.
86  integer, allocatable :: read_order(:)
87  ! Location of the min value
88  integer :: loc(1)
89 
90  call this%free()
91 
92  if (case%params%valid_path('case.simulation_components')) then
93 
94  call case%params%info('case.simulation_components', n_children=n_simcomps)
95  allocate(this%simcomps(n_simcomps))
96  allocate(this%order(n_simcomps))
97  allocate(read_order(n_simcomps))
98  allocate(mask(n_simcomps))
99  mask = .true.
100 
101  call case%params%get_core(core)
102  call case%params%get('case.simulation_components', simcomp_object, found)
103 
104  ! We need a separate loop to figure out the order, so that we can
105  ! apply the order to the initialization as well.
106  do i=1, n_simcomps
107  ! Create a new json containing just the subdict for this simcomp
108  call json_extract_item(core, simcomp_object, i, comp_subdict)
109  call json_get_or_default(comp_subdict, "order", read_order(i), i)
110  end do
111 
112  ! Figure out the execution order using a poor man's argsort.
113  ! Searches for the location of the min value, each time masking out the
114  ! found location prior to the next search.
115  do i= 1, n_simcomps
116  loc = minloc(read_order, mask=mask)
117  this%order(i) = loc(1)
118  mask(loc) = .false.
119  end do
120 
121  ! Init in the determined order.
122  do i=1, n_simcomps
123  call json_extract_item(core, simcomp_object, this%order(i),&
124  comp_subdict)
125  ! Have to add, the simcomp constructor expects it.
126  if (.not. comp_subdict%valid_path("order")) then
127  call comp_subdict%add("order", this%order(i))
128  end if
129  call simulation_component_factory(this%simcomps(i)%simcomp, &
130  comp_subdict, case)
131  end do
132  end if
133  end subroutine simcomp_executor_init
134 
136  subroutine simcomp_executor_free(this)
137  class(simcomp_executor_t), intent(inout) :: this
138  integer :: i
139 
140  if (allocated(this%order)) deallocate(this%order)
141 
142  if (allocated(this%simcomps)) then
143  do i=1, size(this%simcomps)
144  call this%simcomps(i)%simcomp%free
145  end do
146  deallocate(this%simcomps)
147  end if
148  end subroutine simcomp_executor_free
149 
153  subroutine simcomp_executor_compute(this, t, tstep)
154  class(simcomp_executor_t), intent(inout) :: this
155  real(kind=rp), intent(in) :: t
156  integer, intent(in) :: tstep
157  integer :: i
158 
159  if (allocated(this%simcomps)) then
160  do i=1, size(this%simcomps)
161  call this%simcomps(this%order(i))%simcomp%compute(t, tstep)
162  end do
163  end if
164 
165  end subroutine simcomp_executor_compute
166 
169  subroutine simcomp_executor_restart(this, t)
170  class(simcomp_executor_t), intent(inout) :: this
171  real(kind=rp), intent(in) :: t
172  integer :: i
173 
174  if (allocated(this%simcomps)) then
175  do i=1, size(this%simcomps)
176  call this%simcomps(this%order(i))%simcomp%restart(t)
177  end do
178  end if
179 
180  end subroutine simcomp_executor_restart
181 
182 end module simcomp_executor
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Definition: json_utils.f90:53
Retrieves a parameter by name or throws an error.
Definition: json_utils.f90:44
Defines a simulation case.
Definition: case.f90:34
Utilities for retrieving parameters from the case files.
Definition: json_utils.f90:34
subroutine, public json_extract_item(core, array, i, item)
Extract ith item from a JSON array as a separate JSON object.
Definition: json_utils.f90:364
integer, parameter, public rp
Global precision used in computations.
Definition: num_types.f90:12
Contains the simcomp_executor_t type.
type(simcomp_executor_t), public neko_simcomps
Global variable for the simulation component driver.
subroutine simcomp_executor_restart(this, t)
Execute restart for all simcomps.
subroutine simcomp_executor_compute(this, t, tstep)
Execute compute_ for all simcomps.
subroutine simcomp_executor_free(this)
Destructor.
subroutine simcomp_executor_init(this, case)
Constructor.
Defines a factory subroutine for simulation components.
subroutine, public simulation_component_factory(simcomp, json, case)
Simulation component factory. Both constructs and initializes the object.
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...
A helper type that is needed to have an array of polymorphic objects.