Neko-TOP
A portable framework for high-order spectral element flow toplogy optimization.
Loading...
Searching...
No Matches
simulation.f90
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!
34! Here, we simply march forward to steady state solutions
36 use case, only: case_t
37 use neko, only: neko_init, neko_finalize, neko_solve
38 use adjoint_case, only: adjoint_case_t, adjoint_init, adjoint_free
39 use fluid_scheme_incompressible, only: fluid_scheme_incompressible_t
40 use adjoint_fluid_scheme, only: adjoint_fluid_scheme_t
42 use scalar_pnpn, only: scalar_pnpn_t
45 use scalars, only: scalars_t
46 use scalar_scheme, only: scalar_scheme_t
47 use fluid_pnpn, only: fluid_pnpn_t
48 use time_step_controller, only: time_step_controller_t
49 use time_state, only: time_state_t
50 use fld_file_output, only: fld_file_output_t
51 use chkp_output, only: chkp_output_t
52 use simcomp_executor, only: neko_simcomps
53 use neko_ext, only: reset
54 use field, only: field_t
55 use field_registry, only: neko_field_registry
56 use field_math, only: field_rzero, field_copy
57 use checkpoint, only: chkp_t
58 use file, only: file_t
59 use utils, only: neko_warning, neko_error
60 use comm, only: pe_rank
61 use json_file_module, only: json_file
62 use json_utils, only: json_extract_item, json_get_or_default
63 use num_types, only: rp, sp, dp
64 use logger, only: log_size, neko_log
65 use mpi_f08, only: mpi_wtime
66 use jobctrl, only: jobctrl_time_limit
67 use profiler, only: profiler_start, profiler_stop
68 use simulation_adjoint, only: simulation_adjoint_init, &
69 simulation_adjoint_step, simulation_adjoint_finalize
70 use simulation, only: simulation_init, simulation_step, simulation_finalize, &
71 simulation_restart
72 use simulation_checkpoint, only: simulation_checkpoint_t
73 implicit none
74 private
75
77
79 type(case_t), public :: neko_case
81 type(adjoint_case_t), public :: adjoint_case
83 class(fluid_scheme_incompressible_t), public, pointer :: fluid => null()
85 type(scalars_t), public, pointer :: scalars => null()
87 class(adjoint_fluid_scheme_t), public, pointer :: adjoint_fluid => null()
89 type(adjoint_scalars_t), public, pointer :: adjoint_scalars => null()
92 type(fld_file_output_t), public :: output_forward
95 type(fld_file_output_t), public :: output_adjoint
96
97 logical :: have_scalar = .false.
98 integer :: n_timesteps = 0
99
100 ! ----------------------------------------------------------------------- !
101 ! Checkpoint system
102
104 logical :: checkpoint_enable = .false.
106 type(simulation_checkpoint_t) :: checkpoint
107
108 contains
110 procedure, pass(this) :: init => simulation_initialize
112 procedure, pass(this) :: free => simulation_free
114 procedure, pass(this) :: run_forward => simulation_run_forward
116 procedure, pass(this) :: run_backward => simulation_run_backward
118 procedure, pass(this) :: reset => simulation_reset
120 procedure, pass(this) :: write => simulation_write
121
122 end type simulation_t
123 public :: simulation_t
124contains
125
127 subroutine simulation_initialize(this, parameters)
128 class(simulation_t), intent(inout), target :: this
129 type(json_file), intent(inout) :: parameters
130 integer :: i, n_scalars
131
132 ! initialize the primal
133 call neko_init(this%neko_case)
134 ! initialize the adjoint
135 call adjoint_init(this%adjoint_case, this%neko_case)
136
137 select type (fluid => this%neko_case%fluid)
138 type is (fluid_pnpn_t)
139 this%fluid => fluid
140 end select
141
142 select type (adjoint_fluid => this%adjoint_case%fluid_adj)
143 type is (adjoint_fluid_pnpn_t)
144 this%adjoint_fluid => adjoint_fluid
145 end select
146
147 if (allocated(this%neko_case%scalars)) then
148 this%scalars => this%neko_case%scalars
149 end if
150
151 if (allocated(this%adjoint_case%adjoint_scalars)) then
152 this%adjoint_scalars => this%adjoint_case%adjoint_scalars
153 end if
154
155 ! init the sampler
156 !---------------------------------------------------------
157 ! Allocate the output type
158 n_scalars = 0
159 if (allocated(this%neko_case%scalars)) then
160 n_scalars = size(this%neko_case%scalars%scalar_fields)
161 end if
162 call this%output_forward%init(sp, 'forward_fields', 4 + n_scalars)
163
164 call this%output_forward%fields%assign(1, this%fluid%p)
165 call this%output_forward%fields%assign(2, this%fluid%u)
166 call this%output_forward%fields%assign(3, this%fluid%v)
167 call this%output_forward%fields%assign(4, this%fluid%w)
168
169 ! Assign all scalar fields
170 if (allocated(this%neko_case%scalars)) then
171 do i = 1, n_scalars
172 call this%output_forward%fields%assign(4 + i, &
173 this%scalars%scalar_fields(i)%s)
174 end do
175 end if
176
177 n_scalars = 0
178 if (allocated(this%adjoint_case%adjoint_scalars)) then
179 n_scalars = size(this%adjoint_case%adjoint_scalars%adjoint_scalar_fields)
180 end if
181 call this%output_adjoint%init(sp, 'adjoint_fields', 4 + n_scalars)
182 call this%output_adjoint%fields%assign(1, this%adjoint_fluid%p_adj)
183 call this%output_adjoint%fields%assign(2, this%adjoint_fluid%u_adj)
184 call this%output_adjoint%fields%assign(3, this%adjoint_fluid%v_adj)
185 call this%output_adjoint%fields%assign(4, this%adjoint_fluid%w_adj)
186
187 ! Assign all scalar fields
188 if (allocated(this%adjoint_case%adjoint_scalars)) then
189 do i = 1, n_scalars
190 call this%output_adjoint%fields%assign(4 + i, &
191 this%adjoint_scalars%adjoint_scalar_fields(i)%s_adj)
192 end do
193 end if
194
195 call json_get_or_default(parameters, "checkpoints.enable", &
196 this%checkpoint_enable, .false.)
197 if (this%checkpoint_enable) then
198 call this%checkpoint%init(this%neko_case, parameters)
199 end if
200
201 end subroutine simulation_initialize
202
204 subroutine simulation_free(this)
205 class(simulation_t), intent(inout) :: this
206
207 if (this%checkpoint_enable) then
208 call this%checkpoint%free()
209 end if
210 call adjoint_free(this%adjoint_case)
211 call neko_finalize(this%neko_case)
212
213 end subroutine simulation_free
214
216 subroutine simulation_run_forward(this)
217 class(simulation_t), intent(inout) :: this
218 type(time_step_controller_t) :: dt_controller
219 real(kind=dp) :: loop_start
220
221 call dt_controller%init(this%neko_case%params)
222
223 call simulation_init(this%neko_case, dt_controller)
224
225 call profiler_start
226 loop_start = mpi_wtime()
227 do while (this%neko_case%time%t .lt. this%neko_case%time%end_time)
228 this%n_timesteps = this%n_timesteps + 1
229
230 call simulation_step(this%neko_case, dt_controller, loop_start)
231
232 if (this%checkpoint_enable) then
233 call this%checkpoint%save(this%neko_case)
234 end if
235 end do
236 call profiler_stop
237
238 call simulation_finalize(this%neko_case)
239
240 end subroutine simulation_run_forward
241
243 subroutine simulation_run_backward(this)
244 class(simulation_t), intent(inout) :: this
245 type(time_step_controller_t) :: dt_controller
246 real(kind=dp) :: loop_start
247 real(kind=rp) :: cfl
248 integer :: i
249
250 call dt_controller%init(this%neko_case%params)
251
252 call simulation_adjoint_init(this%adjoint_case, dt_controller)
253
254 call profiler_start
255 cfl = this%adjoint_case%fluid_adj%compute_cfl(this%adjoint_case%time%dt)
256 loop_start = mpi_wtime()
257
258 do i = this%n_timesteps, 1, -1
259 if (this%checkpoint_enable) then
260 call this%checkpoint%restore(this%neko_case, i)
261 end if
262
263 call simulation_adjoint_step(this%adjoint_case, dt_controller, cfl, &
264 loop_start)
265 end do
266 call profiler_stop
267
268 call simulation_adjoint_finalize(this%adjoint_case)
269
270 end subroutine simulation_run_backward
271
273 subroutine simulation_reset(this)
274 class(simulation_t), intent(inout) :: this
275 integer :: i, n_scalars
276
277 call reset(this%neko_case)
278
279 ! TODO
280 ! reset for the adjoint
281 ! call reset(this%adjoint_case)
282 this%adjoint_case%time%t = 0.0_rp
283 this%adjoint_case%time%tstep = 0
284 this%n_timesteps = 0
285
286 call field_rzero(this%adjoint_case%fluid_adj%u_adj)
287 call field_rzero(this%adjoint_case%fluid_adj%v_adj)
288 call field_rzero(this%adjoint_case%fluid_adj%w_adj)
289 n_scalars = 0
290 if (allocated(this%adjoint_case%adjoint_scalars)) then
291 n_scalars = size(this%adjoint_case%adjoint_scalars%adjoint_scalar_fields)
292 do i = 1, n_scalars
293 call field_rzero(&
294 this%adjoint_case%adjoint_scalars%adjoint_scalar_fields(i)%s_adj)
295 end do
296 end if
297
298 if (this%checkpoint_enable) then
299 call this%checkpoint%reset()
300 end if
301 end subroutine simulation_reset
302
304 subroutine simulation_write(this, idx)
305 class(simulation_t), intent(inout) :: this
306 integer, intent(in) :: idx
307
308 call this%output_forward%sample(real(idx, kind=rp))
309 call this%output_adjoint%sample(real(idx, kind=rp))
310
311 end subroutine simulation_write
312
313end module simulation_m
Adjoint Pn/Pn formulation.
Contains the adjoint_scalar_pnpn_t type.
Contains the adjoint_scalars_t type that manages multiple scalar fields.
Contains extensions to the neko library required to run the topology optimization code.
Definition neko_ext.f90:9
subroutine, public reset(neko_case)
Reset the case data structure.
Definition neko_ext.f90:55
Adjoint simulation driver.
Implements the steady_problem_t type.
Adjoint case type. Todo: This should Ideally be a subclass of case_t, however, that is not yet suppor...
Type to manage multiple adjoint scalar transport equations.