36 use num_types,
only: rp
37 use fld_file_output,
only: fld_file_output_t
42 use vector,
only: vector_t
43 use matrix,
only: matrix_t
44 use device,
only: device_memcpy, host_to_device, device_to_host
45 use neko_config,
only: neko_bcknd_device
46 use json_module,
only: json_file
47 use json_utils,
only: json_extract_item, json_get, json_get_or_default
49 use logger,
only: neko_log
50 use device_math,
only: device_copy
51 use vector_math,
only: vector_add2
68 integer :: n_objectives
70 integer :: n_constraints
85 procedure, pass(this),
public :: free => problem_free
90 procedure, pass(this),
public :: compute => problem_compute
95 procedure, pass(this),
public :: compute_sensitivity => &
96 problem_compute_sensitivity
102 procedure, pass(this),
public :: read_objectives => problem_read_objectives
104 procedure, pass(this),
public :: read_constraints => &
105 problem_read_constraints
111 procedure, pass(this),
public :: write => problem_write
114 procedure, pass(this),
public :: add_objective => problem_add_objective
116 procedure, pass(this),
public :: add_constraint => problem_add_constraint
122 procedure, pass(this) :: update_objectives => &
123 problem_update_objectives
125 procedure, pass(this) :: update_constraints => &
126 problem_update_constraints
128 procedure, pass(this) :: update_objective_sensitivities => &
129 problem_update_objective_sensitivities
131 procedure, pass(this) :: update_constraint_sensitivities => &
132 problem_update_constraint_sensitivities
138 procedure, pass(this),
public :: get_objective_value => &
139 problem_get_objective_value
141 procedure, pass(this),
public :: get_all_objective_values => &
142 problem_get_all_objective_values
144 procedure, pass(this),
public :: get_constraint_values => &
145 problem_get_constraint_values
147 procedure, pass(this),
public :: get_objective_sensitivities => &
148 problem_get_objective_sensitivities
150 procedure, pass(this),
public :: get_constraint_sensitivities => &
151 problem_get_constraint_sensitivities
154 procedure, pass(this) :: get_n_objectives => problem_get_num_objectives
156 procedure, pass(this) :: get_n_constraints => problem_get_num_constraints
159 procedure, pass(this) :: get_log_header => problem_get_log_header
171 type(json_file),
intent(inout) :: parameters
172 class(
design_t),
intent(in) :: design
173 type(
simulation_t),
optional,
intent(inout) :: simulation
175 this%n_design =
design%size()
176 this%n_objectives = 0
177 this%n_constraints = 0
180 call this%read_objectives(parameters,
design, simulation)
183 call this%read_constraints(parameters,
design, simulation)
188 subroutine problem_free(this)
193 if (
allocated(this%objective_list))
then
194 do i = 1,
size(this%objective_list)
195 call this%objective_list(i)%free()
197 deallocate(this%objective_list)
201 if (
allocated(this%constraint_list))
then
202 do i = 1,
size(this%constraint_list)
203 call this%constraint_list(i)%free()
205 deallocate(this%constraint_list)
207 end subroutine problem_free
210 subroutine problem_write(this, idx)
212 integer,
intent(in) :: idx
214 end subroutine problem_write
220 subroutine problem_read_objectives(this, parameters, design, simulation)
222 type(json_file),
intent(inout) :: parameters
223 class(
design_t),
intent(in) :: design
225 type(
simulation_t),
optional,
intent(inout) :: simulation
228 character(len=:),
allocatable :: path, type
229 type(json_file) :: objective_json
230 integer :: n_objectives, i
233 call neko_log%section(
"Reading objectives")
236 path =
"optimization.objectives"
237 if (parameters%valid_path(path))
then
238 call parameters%info(path, n_children = n_objectives)
241 do i = 1, n_objectives
242 call json_extract_item(parameters, path, i, objective_json)
243 call json_get(objective_json,
"type", type)
244 call neko_log%message(type)
251 if (
present(simulation))
then
256 call json_get_or_default(parameters, &
257 "adjoint_fluid.dealias_sensitivity", dealias, .true.)
258 call alo%init_from_attributes(
design, simulation, weight = 1.0_rp, &
259 name =
"Augmented Lagrangian", mask_name =
"", &
265 call neko_log%end_section()
267 end subroutine problem_read_objectives
270 subroutine problem_read_constraints(this, parameters, design, simulation)
272 type(json_file),
intent(inout) :: parameters
273 class(
design_t),
intent(in) :: design
275 type(
simulation_t),
optional,
intent(inout) :: simulation
278 character(len=:),
allocatable :: path, type
279 type(json_file) :: constraint_json
280 integer :: n_constraints, i
282 call neko_log%section(
"Reading constraints")
285 path =
"optimization.constraints"
287 if (parameters%valid_path(path))
then
288 call parameters%info(path, n_children = n_constraints)
291 do i = 1, n_constraints
292 call json_extract_item(parameters, path, i, constraint_json)
293 call json_get(constraint_json,
"type", type)
294 call neko_log%message(type)
301 call neko_log%end_section()
303 end subroutine problem_read_constraints
306 subroutine problem_add_objective(this, objective)
308 class(
objective_t),
allocatable,
intent(inout) :: objective
313 if (
allocated(this%objective_list))
then
314 n =
size(this%objective_list)
315 call move_alloc(this%objective_list, temp_list)
316 allocate(this%objective_list(n + 1))
317 if (
allocated(temp_list))
then
319 call move_alloc(temp_list(i)%objective, &
320 this%objective_list(i)%objective)
324 allocate(this%objective_list(1))
327 call move_alloc(
objective, this%objective_list(n + 1)%objective)
328 this%n_objectives = n + 1
329 end subroutine problem_add_objective
332 subroutine problem_add_constraint(this, constraint)
334 class(
constraint_t),
allocatable,
intent(inout) :: constraint
339 if (
allocated(this%constraint_list))
then
340 n =
size(this%constraint_list)
341 call move_alloc(this%constraint_list, temp_list)
342 allocate(this%constraint_list(n + 1))
343 if (
allocated(temp_list))
then
345 call move_alloc(temp_list(i)%constraint, &
346 this%constraint_list(i)%constraint)
350 allocate(this%constraint_list(1))
353 call move_alloc(
constraint, this%constraint_list(n + 1)%constraint)
354 this%n_constraints = n + 1
355 end subroutine problem_add_constraint
361 subroutine problem_compute(this, design, simulation)
363 class(
design_t),
intent(inout) :: design
364 class(
simulation_t),
optional,
intent(inout) :: simulation
366 if (
present(simulation))
then
367 call simulation%reset()
368 call simulation%run_forward()
371 call this%update_objectives(
design)
372 call this%update_constraints(
design)
374 end subroutine problem_compute
377 subroutine problem_compute_sensitivity(this, design, simulation)
379 class(
design_t),
intent(inout) :: design
380 class(
simulation_t),
optional,
intent(inout) :: simulation
382 type(vector_t) :: objective_sensitivity
384 if (
present(simulation))
call simulation%run_backward()
386 call this%update_objective_sensitivities(
design)
387 call this%update_constraint_sensitivities(
design)
389 call objective_sensitivity%init(this%n_design)
390 call this%get_objective_sensitivities(objective_sensitivity)
392 call design%map_backward(objective_sensitivity)
394 call objective_sensitivity%free()
395 end subroutine problem_compute_sensitivity
406 subroutine problem_update_objectives(this, design)
408 class(
design_t),
intent(in) :: design
411 do i = 1, this%n_objectives
412 call this%objective_list(i)%objective%update_value(
design)
414 end subroutine problem_update_objectives
422 subroutine problem_update_constraints(this, design)
424 class(
design_t),
intent(in) :: design
427 do i = 1, this%n_constraints
428 call this%constraint_list(i)%constraint%update_value(
design)
430 end subroutine problem_update_constraints
438 subroutine problem_update_objective_sensitivities(this, design)
440 class(
design_t),
intent(in) :: design
443 do i = 1, this%n_objectives
444 call this%objective_list(i)%objective%update_sensitivity(
design)
446 end subroutine problem_update_objective_sensitivities
454 subroutine problem_update_constraint_sensitivities(this, design)
456 class(
design_t),
intent(in) :: design
459 do i = 1, this%n_constraints
460 call this%constraint_list(i)%constraint%update_sensitivity(
design)
462 end subroutine problem_update_constraint_sensitivities
473 subroutine problem_get_objective_value(this, objective_value)
475 real(kind=rp),
intent(out) :: objective_value
478 objective_value = 0.0_rp
479 do i = 1, this%n_objectives
480 objective_value = objective_value + &
481 this%objective_list(i)%objective%get_weight() * &
482 this%objective_list(i)%objective%get_value()
485 end subroutine problem_get_objective_value
493 subroutine problem_get_all_objective_values(this, all_objective_values)
495 type(vector_t),
intent(inout) :: all_objective_values
498 call all_objective_values%init(this%n_objectives)
499 do i = 1, this%n_objectives
500 all_objective_values%x(i) = this%objective_list(i)%objective%value
503 if (neko_bcknd_device .eq. 1)
then
504 call device_memcpy(all_objective_values%x, all_objective_values%x_d, &
505 this%n_objectives, host_to_device, sync = .true.)
508 end subroutine problem_get_all_objective_values
516 subroutine problem_get_constraint_values(this, constraint_value)
518 type(vector_t),
intent(inout) :: constraint_value
521 call constraint_value%init(this%n_constraints)
522 do i = 1, this%n_constraints
523 constraint_value%x(i) = this%constraint_list(i)%constraint%value
526 if (neko_bcknd_device .eq. 1)
then
527 call device_memcpy(constraint_value%x, constraint_value%x_d, &
528 this%n_constraints, host_to_device, sync = .true.)
531 end subroutine problem_get_constraint_values
539 subroutine problem_get_objective_sensitivities(this, sensitivity)
541 type(vector_t),
intent(inout) :: sensitivity
544 call sensitivity%init(this%n_design)
545 do i = 1, this%n_objectives
546 call vector_add2(sensitivity, &
547 this%objective_list(i)%objective%sensitivity)
550 end subroutine problem_get_objective_sensitivities
558 subroutine problem_get_constraint_sensitivities(this, sensitivity)
560 type(matrix_t),
intent(inout) :: sensitivity
561 type(vector_t) :: tmp
564 n = this%n_constraints * this%n_design
565 call sensitivity%init(this%n_constraints, this%n_design)
566 if (neko_bcknd_device .eq. 1)
then
567 call tmp%init(this%n_design)
570 do i = 1, this%n_constraints
571 if (neko_bcknd_device .eq. 1)
then
572 tmp = this%constraint_list(i)%constraint%sensitivity
573 call device_memcpy(tmp%x, tmp%x_d, &
574 this%n_design, device_to_host, sync = .true.)
575 do j = 1, this%n_design
576 sensitivity%x(i, j) = tmp%x(j)
579 do j = 1, this%n_design
580 sensitivity%x(i, j) = &
581 this%constraint_list(i)%constraint%sensitivity%x(j)
586 if (neko_bcknd_device .eq. 1)
then
587 call device_memcpy(sensitivity%x, sensitivity%x_d, n, &
588 host_to_device, sync = .true.)
592 if (neko_bcknd_device .eq. 1)
then
596 end subroutine problem_get_constraint_sensitivities
602 pure function problem_get_num_objectives(this)
result(n)
606 n = this%n_objectives
607 end function problem_get_num_objectives
610 pure function problem_get_num_constraints(this)
result(n)
614 n = this%n_constraints
615 end function problem_get_num_constraints
618 function problem_get_log_header(this)
result(buff)
620 character(len=1024) :: buff
621 character(len=50) :: mini_buff
636 buff =
"Total objective function"
637 do i = 1, this%get_n_objectives()
639 write(mini_buff,
'(", ", A)') this%objective_list(i)%objective%name
640 buff = trim(buff)//trim(mini_buff)
643 do i = 1, this%get_n_constraints()
645 write(mini_buff,
'(", ", A)') &
646 this%constraint_list(i)%constraint%name
647 buff = trim(buff)//trim(mini_buff)
650 end function problem_get_log_header
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.
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.