42 use num_types,
only: rp, dp
47 use vector,
only: vector_t
48 use matrix,
only: matrix_t
49 use device,
only: host_to_device, device_to_host
50 use json_module,
only: json_file
51 use json_utils,
only: json_extract_item, json_get, json_get_or_default
53 use logger,
only: neko_log
55 use vector_math,
only: vector_add2, vector_cfill
56 use time_step_controller,
only: time_step_controller_t
59 use simulation,
only: simulation_init, simulation_step, simulation_finalize
60 use mpi_f08,
only: mpi_wtime
61 use profiler,
only: profiler_start_region, profiler_end_region
71 integer :: n_design = 0
73 integer :: n_objectives = 0
75 integer :: n_constraints = 0
90 procedure, pass(this),
public :: free => problem_free
95 procedure, pass(this),
public :: compute => problem_compute
100 procedure, pass(this),
public :: compute_sensitivity => &
101 problem_compute_sensitivity
104 procedure, pass(this),
public :: run_forward_unsteady => &
105 problem_run_forward_unsteady
108 procedure, pass(this),
public :: run_backward_unsteady => &
109 problem_run_backward_unsteady
114 procedure, pass(this),
public :: read_objectives => problem_read_objectives
116 procedure, pass(this),
public :: read_constraints => &
117 problem_read_constraints
123 procedure, pass(this),
public :: write => problem_write
126 procedure, pass(this),
public :: add_objective => problem_add_objective
128 procedure, pass(this),
public :: add_constraint => problem_add_constraint
134 procedure, pass(this) :: update_objectives => &
135 problem_update_objectives
137 procedure, pass(this) :: update_constraints => &
138 problem_update_constraints
140 procedure, pass(this) :: update_objective_sensitivities => &
141 problem_update_objective_sensitivities
143 procedure, pass(this) :: update_constraint_sensitivities => &
144 problem_update_constraint_sensitivities
147 procedure, pass(this) :: reset_objectives => &
148 problem_reset_objectives
150 procedure, pass(this) :: reset_constraints => &
151 problem_reset_constraints
153 procedure, pass(this) :: reset_objective_sensitivities => &
154 problem_reset_objective_sensitivities
156 procedure, pass(this) :: reset_constraint_sensitivities => &
157 problem_reset_constraint_sensitivities
160 procedure, pass(this) :: accumulate_objectives => &
161 problem_accumulate_objectives
163 procedure, pass(this) :: accumulate_constraints => &
164 problem_accumulate_constraints
166 procedure, pass(this) :: accumulate_objective_sensitivities => &
167 problem_accumulate_objective_sensitivities
169 procedure, pass(this) :: accumulate_constraint_sensitivities => &
170 problem_accumulate_constraint_sensitivities
176 procedure, pass(this),
public :: get_objective_value => &
177 problem_get_objective_value
179 procedure, pass(this),
public :: get_all_objective_values => &
180 problem_get_all_objective_values
182 procedure, pass(this),
public :: get_constraint_values => &
183 problem_get_constraint_values
185 procedure, pass(this),
public :: get_objective_sensitivities => &
186 problem_get_objective_sensitivities
188 procedure, pass(this),
public :: get_constraint_sensitivities => &
189 problem_get_constraint_sensitivities
192 procedure, pass(this) :: get_n_objectives => problem_get_num_objectives
194 procedure, pass(this) :: get_n_constraints => problem_get_num_constraints
197 procedure, pass(this) :: get_log_header => problem_get_log_header
209 type(json_file),
intent(inout) :: parameters
210 class(
design_t),
intent(in) :: design
211 type(
simulation_t),
optional,
intent(inout) :: simulation
215 this%n_design =
design%size()
218 call this%read_objectives(parameters,
design, simulation)
219 call this%read_constraints(parameters,
design, simulation)
224 subroutine problem_free(this)
229 this%n_objectives = 0
230 this%n_constraints = 0
233 if (
allocated(this%objective_list))
then
234 do i = 1,
size(this%objective_list)
235 call this%objective_list(i)%free()
237 deallocate(this%objective_list)
241 if (
allocated(this%constraint_list))
then
242 do i = 1,
size(this%constraint_list)
243 call this%constraint_list(i)%free()
245 deallocate(this%constraint_list)
247 end subroutine problem_free
250 subroutine problem_write(this, idx)
252 integer,
intent(in) :: idx
254 end subroutine problem_write
260 subroutine problem_read_objectives(this, parameters, design, simulation)
262 type(json_file),
intent(inout) :: parameters
263 class(
design_t),
intent(in) :: design
264 type(
simulation_t),
optional,
intent(inout) :: simulation
268 character(len=:),
allocatable :: path, type
269 type(json_file) :: objective_json
270 integer :: n_objectives, i
273 call neko_log%section(
"Reading objectives")
276 path =
"optimization.objectives"
277 if (parameters%valid_path(path))
then
278 call parameters%info(path, n_children = n_objectives)
281 do i = 1, n_objectives
282 call json_extract_item(parameters, path, i, objective_json)
283 call json_get(objective_json,
"type", type)
284 call neko_log%message(type)
291 if (
present(simulation))
then
296 call json_get_or_default(parameters, &
297 "adjoint_fluid.dealias_sensitivity", dealias, .true.)
298 call alo%init_from_attributes(
design, simulation, weight = 1.0_rp, &
299 name =
"Augmented Lagrangian", mask_name =
"", &
305 call neko_log%end_section()
307 end subroutine problem_read_objectives
310 subroutine problem_read_constraints(this, parameters, design, simulation)
312 type(json_file),
intent(inout) :: parameters
313 class(
design_t),
intent(in) :: design
315 type(
simulation_t),
optional,
intent(inout) :: simulation
318 character(len=:),
allocatable :: path, type
319 type(json_file) :: constraint_json
320 integer :: n_constraints, i
322 call neko_log%section(
"Reading constraints")
325 path =
"optimization.constraints"
327 if (parameters%valid_path(path))
then
328 call parameters%info(path, n_children = n_constraints)
331 do i = 1, n_constraints
332 call json_extract_item(parameters, path, i, constraint_json)
333 call json_get(constraint_json,
"type", type)
334 call neko_log%message(type)
341 call neko_log%end_section()
343 end subroutine problem_read_constraints
346 subroutine problem_add_objective(this, objective)
348 class(
objective_t),
allocatable,
intent(inout) :: objective
353 if (
allocated(this%objective_list))
then
354 n =
size(this%objective_list)
355 call move_alloc(this%objective_list, temp_list)
356 allocate(this%objective_list(n + 1))
357 if (
allocated(temp_list))
then
359 call move_alloc(temp_list(i)%objective, &
360 this%objective_list(i)%objective)
364 allocate(this%objective_list(1))
367 call move_alloc(
objective, this%objective_list(n + 1)%objective)
368 this%n_objectives = n + 1
369 end subroutine problem_add_objective
372 subroutine problem_add_constraint(this, constraint)
374 class(
constraint_t),
allocatable,
intent(inout) :: constraint
379 if (
allocated(this%constraint_list))
then
380 n =
size(this%constraint_list)
381 call move_alloc(this%constraint_list, temp_list)
382 allocate(this%constraint_list(n + 1))
383 if (
allocated(temp_list))
then
385 call move_alloc(temp_list(i)%constraint, &
386 this%constraint_list(i)%constraint)
390 allocate(this%constraint_list(1))
393 call move_alloc(
constraint, this%constraint_list(n + 1)%constraint)
394 this%n_constraints = n + 1
395 end subroutine problem_add_constraint
401 subroutine problem_compute(this, design, simulation)
403 class(
design_t),
intent(inout) :: design
404 class(
simulation_t),
optional,
intent(inout) :: simulation
406 if (
present(simulation))
then
407 call simulation%reset()
408 if (simulation%unsteady)
then
410 call this%run_forward_unsteady(simulation,
design)
412 call simulation%run_forward()
414 call this%update_objectives(
design)
417 call this%update_objectives(
design)
420 call this%update_constraints(
design)
422 end subroutine problem_compute
425 subroutine problem_compute_sensitivity(this, design, simulation)
427 class(
design_t),
intent(inout) :: design
428 class(
simulation_t),
optional,
intent(inout) :: simulation
430 type(vector_t) :: objective_sensitivity
432 if (
present(simulation))
then
433 if (simulation%unsteady)
then
435 call this%run_backward_unsteady(simulation,
design)
437 call simulation%run_backward()
439 call this%update_objective_sensitivities(
design)
442 call this%update_objective_sensitivities(
design)
445 call this%update_constraint_sensitivities(
design)
447 call objective_sensitivity%init(this%n_design)
448 call this%get_objective_sensitivities(objective_sensitivity)
450 call design%map_backward(objective_sensitivity)
452 call objective_sensitivity%free()
453 end subroutine problem_compute_sensitivity
456 subroutine problem_run_forward_unsteady(this, simulation, design)
459 class(
design_t),
intent(inout) :: design
460 type(time_step_controller_t) :: dt_controller
461 real(kind=dp) :: loop_start
463 call dt_controller%init(simulation%neko_case%params)
465 call simulation%reset()
466 call simulation_init(simulation%neko_case, dt_controller)
469 call this%reset_objectives()
471 call profiler_start_region(
"Forward simulation")
472 loop_start = mpi_wtime()
473 simulation%n_timesteps = 0
474 do while (simulation%neko_case%time%t .lt. simulation%neko_case%time%end_time)
475 simulation%n_timesteps = simulation%n_timesteps + 1
477 call simulation_step(simulation%neko_case, dt_controller, loop_start)
479 call this%accumulate_objectives(
design, simulation%adjoint_case%time%dt)
481 call simulation%checkpoint%save(simulation%neko_case)
483 call profiler_end_region(
"Forward simulation")
485 call simulation_finalize(simulation%neko_case)
487 end subroutine problem_run_forward_unsteady
490 subroutine problem_run_backward_unsteady(this, simulation, design)
493 class(
design_t),
intent(inout) :: design
494 type(time_step_controller_t) :: dt_controller
495 real(kind=dp) :: loop_start
497 real(kind=rp) :: total_time
500 call dt_controller%init(simulation%neko_case%params)
505 call this%reset_objective_sensitivities()
507 cfl = simulation%adjoint_case%fluid_adj%compute_cfl(simulation%adjoint_case%time%dt)
508 loop_start = mpi_wtime()
510 total_time = simulation%n_timesteps * simulation%adjoint_case%time%dt
512 call profiler_start_region(
"Adjoint simulation")
531 do i = simulation%n_timesteps, 1, -1
533 call simulation%checkpoint%restore(simulation%neko_case, i)
535 call this%accumulate_objective_sensitivities(
design, &
536 simulation%adjoint_case%time%dt)
539 cfl, loop_start, total_time)
542 call profiler_end_region(
"Forward simulation")
546 end subroutine problem_run_backward_unsteady
557 subroutine problem_update_objectives(this, design)
559 class(
design_t),
intent(in) :: design
562 do i = 1, this%n_objectives
563 call this%objective_list(i)%objective%update_value(
design)
565 end subroutine problem_update_objectives
573 subroutine problem_update_constraints(this, design)
575 class(
design_t),
intent(in) :: design
578 do i = 1, this%n_constraints
579 call this%constraint_list(i)%constraint%update_value(
design)
581 end subroutine problem_update_constraints
589 subroutine problem_update_objective_sensitivities(this, design)
591 class(
design_t),
intent(in) :: design
594 do i = 1, this%n_objectives
595 call this%objective_list(i)%objective%update_sensitivity(
design)
597 end subroutine problem_update_objective_sensitivities
605 subroutine problem_update_constraint_sensitivities(this, design)
607 class(
design_t),
intent(in) :: design
610 do i = 1, this%n_constraints
611 call this%constraint_list(i)%constraint%update_sensitivity(
design)
613 end subroutine problem_update_constraint_sensitivities
622 subroutine problem_reset_objectives(this)
626 do i = 1, this%n_objectives
627 call this%objective_list(i)%objective%reset_value()
629 end subroutine problem_reset_objectives
635 subroutine problem_reset_constraints(this)
639 do i = 1, this%n_constraints
640 call this%constraint_list(i)%constraint%reset_value()
642 end subroutine problem_reset_constraints
648 subroutine problem_reset_objective_sensitivities(this)
652 do i = 1, this%n_objectives
653 call this%objective_list(i)%objective%reset_sensitivity()
655 end subroutine problem_reset_objective_sensitivities
661 subroutine problem_reset_constraint_sensitivities(this)
665 do i = 1, this%n_constraints
666 call this%constraint_list(i)%constraint%reset_sensitivity()
668 end subroutine problem_reset_constraint_sensitivities
679 subroutine problem_accumulate_objectives(this, design, dt)
681 class(
design_t),
intent(in) :: design
682 real(kind=rp),
intent(in) :: dt
685 do i = 1, this%n_objectives
686 call this%objective_list(i)%objective%accumulate_value(
design, dt)
688 end subroutine problem_accumulate_objectives
696 subroutine problem_accumulate_constraints(this, design, dt)
698 class(
design_t),
intent(in) :: design
699 real(kind=rp),
intent(in) :: dt
702 do i = 1, this%n_constraints
703 call this%constraint_list(i)%constraint%accumulate_value(
design, dt)
705 end subroutine problem_accumulate_constraints
713 subroutine problem_accumulate_objective_sensitivities(this, design, dt)
715 class(
design_t),
intent(in) :: design
716 real(kind=rp),
intent(in) :: dt
719 do i = 1, this%n_objectives
720 call this%objective_list(i)%objective%accumulate_sensitivity(
design, dt)
722 end subroutine problem_accumulate_objective_sensitivities
730 subroutine problem_accumulate_constraint_sensitivities(this, design, dt)
732 class(
design_t),
intent(in) :: design
733 real(kind=rp),
intent(in) :: dt
736 do i = 1, this%n_constraints
737 call this%constraint_list(i)%constraint%accumulate_sensitivity(
design, dt)
739 end subroutine problem_accumulate_constraint_sensitivities
750 subroutine problem_get_objective_value(this, objective_value)
752 real(kind=rp),
intent(out) :: objective_value
755 objective_value = 0.0_rp
756 do i = 1, this%n_objectives
757 objective_value = objective_value + &
758 this%objective_list(i)%objective%get_weight() * &
759 this%objective_list(i)%objective%get_value()
762 end subroutine problem_get_objective_value
770 subroutine problem_get_all_objective_values(this, all_objective_values)
772 type(vector_t),
intent(inout) :: all_objective_values
775 do i = 1, this%n_objectives
776 all_objective_values%x(i) = this%objective_list(i)%objective%value
779 call all_objective_values%copy_from(host_to_device, sync = .true.)
781 end subroutine problem_get_all_objective_values
789 subroutine problem_get_constraint_values(this, constraint_value)
791 type(vector_t),
intent(inout) :: constraint_value
794 do i = 1, this%n_constraints
795 constraint_value%x(i) = this%constraint_list(i)%constraint%value
798 call constraint_value%copy_from(host_to_device, sync = .true.)
800 end subroutine problem_get_constraint_values
808 subroutine problem_get_objective_sensitivities(this, sensitivity)
810 type(vector_t),
intent(inout) :: sensitivity
813 call vector_cfill(sensitivity, 0.0_rp)
814 do i = 1, this%n_objectives
815 call vector_add2(sensitivity, &
816 this%objective_list(i)%objective%sensitivity)
819 end subroutine problem_get_objective_sensitivities
827 subroutine problem_get_constraint_sensitivities(this, sensitivity)
829 type(matrix_t),
target,
intent(inout) :: sensitivity
830 real(kind=rp),
pointer :: row(:)
834 do i = 1, this%n_constraints
835 call this%constraint_list(i)%constraint%sensitivity%copy_from( &
836 device_to_host, sync = i .eq. this%n_constraints)
839 do i = 1, this%n_constraints
840 row(1:this%n_design) => sensitivity%x(i, :)
842 call copy(row, this%constraint_list(i)%constraint%sensitivity%x, &
846 call sensitivity%copy_from(host_to_device, sync = .true.)
848 end subroutine problem_get_constraint_sensitivities
854 pure function problem_get_num_objectives(this)
result(n)
858 n = this%n_objectives
859 end function problem_get_num_objectives
862 pure function problem_get_num_constraints(this)
result(n)
866 n = this%n_constraints
867 end function problem_get_num_constraints
870 function problem_get_log_header(this)
result(buff)
872 character(len=1024) :: buff
873 character(len=50) :: mini_buff
888 buff =
"Total objective function"
889 do i = 1, this%get_n_objectives()
891 write(mini_buff,
'(", ", A)') this%objective_list(i)%objective%name
892 buff = trim(buff) // trim(mini_buff)
895 do i = 1, this%get_n_constraints()
897 write(mini_buff,
'(", ", A)') &
898 this%constraint_list(i)%constraint%name
899 buff = trim(buff) // trim(mini_buff)
902 end function problem_get_log_header
Factory function Allocates and initializes an constraint function object.
Factory function Allocates and initializes an objective function object.
Implements the augmented_lagrangian_objective_t type.
Implements the constraint_t type.
Implements the objective_t type.
Module for handling the optimization problem.
subroutine problem_init(this, parameters, design, simulation)
The constructor for the base problem.
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.
An objective function implementing our augmented lagrangian sensitivity contribution.
The abstract constraint type.
Wrapper for constraints for use in lists.
The abstract objective type.
Wrapper for objectives for use in lists.
The abstract problem type.