38 use case,
only: case_t
39 use neko,
only: neko_solve
40 use user_access_singleton,
only: neko_user_access
42 use fluid_scheme_incompressible,
only: fluid_scheme_incompressible_t
45 use scalar_pnpn,
only: scalar_pnpn_t
48 use scalars,
only: scalars_t
49 use scalar_scheme,
only: scalar_scheme_t
50 use fluid_pnpn,
only: fluid_pnpn_t
51 use time_step_controller,
only: time_step_controller_t
52 use time_state,
only: time_state_t
53 use field_output,
only: field_output_t
54 use chkp_output,
only: chkp_output_t
55 use simcomp_executor,
only: neko_simcomps
57 use field,
only: field_t
58 use registry,
only: neko_registry
59 use field_math,
only: field_rzero, field_copy
60 use checkpoint,
only: chkp_t
61 use file,
only: file_t
62 use utils,
only: neko_warning, neko_error
63 use comm,
only: pe_rank
64 use json_file_module,
only: json_file
65 use json_utils,
only: json_get, json_get_or_default
66 use num_types,
only: rp, sp, dp
67 use logger,
only: log_size, neko_log
68 use mpi_f08,
only: mpi_wtime
69 use jobctrl,
only: jobctrl_time_limit
70 use profiler,
only: profiler_start, profiler_stop, &
71 profiler_start_region, profiler_end_region
74 use simulation,
only: simulation_init, simulation_step, simulation_finalize, &
77 use runtime_stats,
only: neko_rt_stats
78 use scratch_registry,
only: neko_scratch_registry
79 use registry,
only: neko_registry
86 type(case_t),
public :: neko_case
90 class(fluid_scheme_incompressible_t),
public,
pointer :: fluid => null()
92 type(scalars_t),
public,
pointer :: scalars => null()
99 type(field_output_t),
public :: output_forward
102 type(field_output_t),
public :: output_adjoint
106 character(len=:),
allocatable :: forward_field_base_fname
110 character(len=:),
allocatable :: adjoint_field_base_fname
114 integer :: current_design_iteration = 0
116 logical :: unsteady = .false.
118 logical :: have_scalar = .false.
119 integer :: n_timesteps = 0
131 procedure, pass(this) :: free => simulation_free
133 procedure, pass(this) :: run_forward => simulation_run_forward
135 procedure, pass(this) :: run_backward => simulation_run_backward
137 procedure, pass(this) ::
reset => simulation_reset
139 procedure, pass(this) :: set_output_counter => &
140 simulation_set_output_counter
142 procedure, pass(this) :: set_design_iteration => &
143 simulation_set_design_iteration
145 procedure, pass(this) :: write => simulation_write
147 procedure, pass(this) :: write_forward => simulation_write_forward
149 procedure, pass(this) :: write_adjoint => simulation_write_adjoint
158 type(json_file),
intent(inout) :: parameters
159 type(json_file) :: checkpoint_params
160 integer :: i, n_scalars, unsteady_support
161 character(len=:),
allocatable :: output_directory, precision_s, file_format
163 logical :: unsteady, subdivide
166 call this%neko_case%init(parameters)
167 call neko_user_access%init(this%neko_case)
169 call neko_rt_stats%init(parameters)
170 call neko_simcomps%init(this%neko_case)
173 call this%adjoint_case%init(this%neko_case)
177 this%forward_field_base_fname = &
178 trim(this%neko_case%f_out%file_%get_base_fname())
179 this%adjoint_field_base_fname = &
180 trim(this%adjoint_case%f_out%file_%get_base_fname())
185 select type (fluid => this%neko_case%fluid)
186 type is (fluid_pnpn_t)
190 select type (adjoint_fluid => this%adjoint_case%fluid_adj)
192 this%adjoint_fluid => adjoint_fluid
195 if (
allocated(this%neko_case%scalars))
then
196 this%scalars => this%neko_case%scalars
199 if (
allocated(this%adjoint_case%adjoint_scalars))
then
200 this%adjoint_scalars => this%adjoint_case%adjoint_scalars
207 call json_get_or_default(parameters,
'case.output_directory', &
208 output_directory,
'')
209 call json_get_or_default(parameters,
'case.output_precision', precision_s, &
211 call json_get_or_default(parameters,
'case.fluid.output_format', &
213 call json_get_or_default(parameters,
'case.fluid.output_subdivide', &
216 if (trim(precision_s) .eq.
'double')
then
224 if (
allocated(this%neko_case%scalars))
then
225 n_scalars =
size(this%neko_case%scalars%scalar_fields)
227 call this%output_forward%init(
'forward_fields', 4 + n_scalars, &
228 precision = precision, &
229 path = trim(output_directory), &
230 format = trim(file_format))
231 call this%output_forward%file_%set_subdivide(subdivide)
233 call this%output_forward%fields%assign(1, this%fluid%p)
234 call this%output_forward%fields%assign(2, this%fluid%u)
235 call this%output_forward%fields%assign(3, this%fluid%v)
236 call this%output_forward%fields%assign(4, this%fluid%w)
239 if (
allocated(this%neko_case%scalars))
then
241 call this%output_forward%fields%assign(4 + i, &
242 this%scalars%scalar_fields(i)%scalar%s)
247 call json_get_or_default(parameters, &
248 'case.adjoint_fluid.output_format', file_format,
'fld')
249 call json_get_or_default(parameters, &
250 'case.adjoint_fluid.output_subdivide', subdivide, .false.)
253 if (
allocated(this%adjoint_case%adjoint_scalars))
then
254 n_scalars =
size(this%adjoint_case%adjoint_scalars%adjoint_scalar_fields)
256 call this%output_adjoint%init(
'adjoint_fields', 4 + n_scalars, &
257 precision = precision, &
258 path = trim(output_directory), &
259 format = trim(file_format))
260 call this%output_adjoint%file_%set_subdivide(subdivide)
262 call this%output_adjoint%fields%assign(1, this%adjoint_fluid%p_adj)
263 call this%output_adjoint%fields%assign(2, this%adjoint_fluid%u_adj)
264 call this%output_adjoint%fields%assign(3, this%adjoint_fluid%v_adj)
265 call this%output_adjoint%fields%assign(4, this%adjoint_fluid%w_adj)
268 if (
allocated(this%adjoint_case%adjoint_scalars))
then
270 call this%output_adjoint%fields%assign(4 + i, &
271 this%adjoint_scalars%adjoint_scalar_fields(i)%s_adj)
276 call json_get_or_default(parameters,
"unsteady", unsteady, .false.)
277 this%unsteady = unsteady
280 if (this%unsteady)
then
282 if (
"checkpoints" .in. parameters)
then
283 unsteady_support = unsteady_support + 1
286 if (unsteady_support .eq. 0)
then
287 call neko_error(
"No support for unsteady simulation provided, \\ &
288 & \\ current options include enabling checkpoints.")
291 if (unsteady_support .gt. 1)
then
292 call neko_error(
"Too many supports for unsteady simulation \\ &
293 & \\ provided, please select one.")
297 if (
"checkpoints" .in. parameters)
then
298 call json_get(parameters,
'checkpoints', checkpoint_params)
299 call this%checkpoint%init(this%neko_case, checkpoint_params)
305 subroutine simulation_free(this)
312 call this%neko_case%free()
313 call this%adjoint_case%free()
314 call this%output_forward%free()
315 call this%output_adjoint%free()
316 call this%checkpoint%free()
320 nullify(this%scalars)
321 nullify(this%adjoint_fluid)
322 nullify(this%adjoint_scalars)
325 this%unsteady = .false.
326 this%have_scalar = .false.
328 this%current_design_iteration = 0
329 if (
allocated(this%forward_field_base_fname))
then
330 deallocate(this%forward_field_base_fname)
332 if (
allocated(this%adjoint_field_base_fname))
then
333 deallocate(this%adjoint_field_base_fname)
337 call neko_simcomps%free()
339 end subroutine simulation_free
342 subroutine simulation_run_forward(this)
344 type(time_step_controller_t) :: dt_controller
345 real(kind=dp) :: loop_start
347 call dt_controller%init(this%neko_case%params)
349 call this%neko_case%time%reset()
350 call simulation_init(this%neko_case, dt_controller)
352 call profiler_start_region(
"Forward simulation")
353 loop_start = mpi_wtime()
355 do while (.not. this%neko_case%time%is_done())
356 this%n_timesteps = this%n_timesteps + 1
358 call simulation_step(this%neko_case, dt_controller, loop_start)
360 call this%checkpoint%save(this%neko_case)
362 call profiler_end_region(
"Forward simulation")
364 call simulation_finalize(this%neko_case)
366 end subroutine simulation_run_forward
369 subroutine simulation_run_backward(this)
371 type(time_step_controller_t) :: dt_controller
372 real(kind=dp) :: loop_start
376 call dt_controller%init(this%neko_case%params)
380 call profiler_start_region(
"Adjoint simulation")
381 cfl = this%adjoint_case%fluid_adj%compute_cfl(this%adjoint_case%time%dt)
382 loop_start = mpi_wtime()
383 do i = this%n_timesteps, 1, -1
384 call this%checkpoint%restore(this%neko_case, i)
389 call profiler_end_region(
"Adjoint simulation")
393 end subroutine simulation_run_backward
396 subroutine simulation_reset(this)
399 call reset(this%neko_case, this%current_design_iteration, &
400 this%forward_field_base_fname)
402 this%current_design_iteration, this%adjoint_field_base_fname)
403 call this%checkpoint%reset()
405 end subroutine simulation_reset
412 subroutine simulation_set_design_iteration(this, iteration)
414 integer,
intent(in) :: iteration
416 this%current_design_iteration = iteration
418 end subroutine simulation_set_design_iteration
420 subroutine simulation_set_output_counter(this, idx)
422 integer,
intent(in) :: idx
424 call this%output_forward%set_counter(idx)
425 call this%output_adjoint%set_counter(idx)
427 end subroutine simulation_set_output_counter
430 subroutine simulation_write(this, idx)
432 integer,
intent(in) :: idx
434 call this%output_forward%sample(real(idx, kind=rp))
435 call this%output_adjoint%sample(real(idx, kind=rp))
437 end subroutine simulation_write
440 subroutine simulation_write_forward(this, idx)
442 integer,
intent(in) :: idx
444 call this%output_forward%sample(real(idx, kind=rp))
446 end subroutine simulation_write_forward
449 subroutine simulation_write_adjoint(this, idx)
451 integer,
intent(in) :: idx
453 call this%output_adjoint%sample(real(idx, kind=rp))
455 end subroutine simulation_write_adjoint
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.
subroutine, public reset(neko_case, design_iteration, output_base_fname)
Reset the case data structure.
subroutine, public reset_adjoint(adjoint_case, neko_case, design_iteration, output_base_fname)
Reset the adjoint case data structure.
Adjoint simulation driver.
subroutine, public simulation_adjoint_init(c, dt_controller)
Initialise a simulation_adjoint of a case.
subroutine, public simulation_adjoint_step(c, dt_controller, cfl, tstep_loop_start_time, final_time)
Compute a single time-step of an adjoint case.
subroutine, public simulation_adjoint_finalize(c)
Finalize a simulation of a case.
Implements the steady_problem_t type.
subroutine simulation_initialize(this, parameters)
Initialize the simulation.
Adjoint case type. Todo: This should Ideally be a subclass of case_t, however, that is not yet suppor...
Base type of all fluid formulations.
Type to manage multiple adjoint scalar transport equations.