36 use num_types,
only: rp
37 use fld_file_output,
only: fld_file_output_t
41 use vector,
only: vector_t
42 use matrix,
only: matrix_t
43 use device,
only: device_memcpy, host_to_device, device_to_host
44 use neko_config,
only: neko_bcknd_device
45 use json_module,
only: json_file
46 use json_utils,
only: json_extract_item, json_get
48 use logger,
only: neko_log
49 use device_math,
only: device_copy
50 use vector,
only: vector_t
67 integer :: n_objectives
69 integer :: n_constraints
84 procedure, pass(this),
public :: free => problem_free
89 procedure, pass(this),
public :: compute => problem_compute
94 procedure, pass(this),
public :: compute_sensitivity => &
95 problem_compute_sensitivity
101 procedure, pass(this),
public :: read_objectives => problem_read_objectives
103 procedure, pass(this),
public :: read_constraints => &
104 problem_read_constraints
110 procedure, pass(this),
public :: write => problem_write
113 procedure, pass(this),
public :: add_objective => problem_add_objective
115 procedure, pass(this),
public :: add_constraint => problem_add_constraint
121 procedure, pass(this) :: update_objectives => &
122 problem_update_objectives
124 procedure, pass(this) :: update_constraints => &
125 problem_update_constraints
127 procedure, pass(this) :: update_objective_sensitivities => &
128 problem_update_objective_sensitivities
130 procedure, pass(this) :: update_constraint_sensitivities => &
131 problem_update_constraint_sensitivities
137 procedure, pass(this),
public :: get_objective_value => &
138 problem_get_objective_value
140 procedure, pass(this),
public :: get_all_objective_values => &
141 problem_get_all_objective_values
143 procedure, pass(this),
public :: get_constraint_values => &
144 problem_get_constraint_values
146 procedure, pass(this),
public :: get_objective_sensitivities => &
147 problem_get_objective_sensitivities
149 procedure, pass(this),
public :: get_constraint_sensitivities => &
150 problem_get_constraint_sensitivities
153 procedure, pass(this) :: get_n_objectives => problem_get_num_objectives
155 procedure, pass(this) :: get_n_constraints => problem_get_num_constraints
158 procedure, pass(this) :: get_log_header => problem_get_log_header
170 type(json_file),
intent(inout) :: parameters
171 class(
design_t),
intent(in) :: design
172 type(
simulation_t),
optional,
intent(inout) :: simulation
174 this%n_design =
design%size()
175 this%n_objectives = 0
176 this%n_constraints = 0
179 call this%read_objectives(parameters,
design, simulation)
182 call this%read_constraints(parameters,
design, simulation)
187 subroutine problem_free(this)
192 if (
allocated(this%objective_list))
then
193 do i = 1,
size(this%objective_list)
194 call this%objective_list(i)%free()
196 deallocate(this%objective_list)
200 if (
allocated(this%constraint_list))
then
201 do i = 1,
size(this%constraint_list)
202 call this%constraint_list(i)%free()
204 deallocate(this%constraint_list)
206 end subroutine problem_free
209 subroutine problem_write(this, idx)
211 integer,
intent(in) :: idx
213 end subroutine problem_write
219 subroutine problem_read_objectives(this, parameters, design, simulation)
221 type(json_file),
intent(inout) :: parameters
222 class(
design_t),
intent(in) :: design
224 type(
simulation_t),
optional,
intent(inout) :: simulation
227 character(len=:),
allocatable :: path, type
228 type(json_file) :: objective_json
229 integer :: n_objectives, i
231 call neko_log%section(
"Reading objectives")
234 path =
"optimization.objectives"
235 if (parameters%valid_path(path))
then
236 call parameters%info(path, n_children = n_objectives)
239 do i = 1, n_objectives
240 call json_extract_item(parameters, path, i, objective_json)
241 call json_get(objective_json,
"type", type)
242 call neko_log%message(type)
249 call neko_log%end_section()
251 end subroutine problem_read_objectives
254 subroutine problem_read_constraints(this, parameters, design, simulation)
256 type(json_file),
intent(inout) :: parameters
257 class(
design_t),
intent(in) :: design
259 type(
simulation_t),
optional,
intent(inout) :: simulation
262 character(len=:),
allocatable :: path, type
263 type(json_file) :: constraint_json
264 integer :: n_constraints, i
266 call neko_log%section(
"Reading constraints")
269 path =
"optimization.constraints"
271 if (parameters%valid_path(path))
then
272 call parameters%info(path, n_children = n_constraints)
275 do i = 1, n_constraints
276 call json_extract_item(parameters, path, i, constraint_json)
277 call json_get(constraint_json,
"type", type)
278 call neko_log%message(type)
285 call neko_log%end_section()
287 end subroutine problem_read_constraints
290 subroutine problem_add_objective(this, objective)
292 class(
objective_t),
allocatable,
intent(inout) :: objective
297 if (
allocated(this%objective_list))
then
298 n =
size(this%objective_list)
299 call move_alloc(this%objective_list, temp_list)
300 allocate(this%objective_list(n + 1))
301 if (
allocated(temp_list))
then
303 call move_alloc(temp_list(i)%objective, &
304 this%objective_list(i)%objective)
308 allocate(this%objective_list(1))
311 call move_alloc(
objective, this%objective_list(n + 1)%objective)
312 this%n_objectives = n + 1
313 end subroutine problem_add_objective
316 subroutine problem_add_constraint(this, constraint)
318 class(
constraint_t),
allocatable,
intent(inout) :: constraint
323 if (
allocated(this%constraint_list))
then
324 n =
size(this%constraint_list)
325 call move_alloc(this%constraint_list, temp_list)
326 allocate(this%constraint_list(n + 1))
327 if (
allocated(temp_list))
then
329 call move_alloc(temp_list(i)%constraint, &
330 this%constraint_list(i)%constraint)
334 allocate(this%constraint_list(1))
337 call move_alloc(
constraint, this%constraint_list(n + 1)%constraint)
338 this%n_constraints = n + 1
339 end subroutine problem_add_constraint
345 subroutine problem_compute(this, design)
347 class(
design_t),
intent(inout) :: design
349 call this%update_objectives(
design)
350 call this%update_constraints(
design)
352 end subroutine problem_compute
355 subroutine problem_compute_sensitivity(this, design)
357 class(
design_t),
intent(inout) :: design
359 type(vector_t) :: objective_sensitivity
361 call this%update_objective_sensitivities(
design)
362 call this%update_constraint_sensitivities(
design)
364 call this%get_objective_sensitivities(objective_sensitivity)
366 call design%map_backward(objective_sensitivity)
368 end subroutine problem_compute_sensitivity
379 subroutine problem_update_objectives(this, design)
381 class(
design_t),
intent(in) :: design
384 do i = 1, this%n_objectives
385 call this%objective_list(i)%objective%update_value(
design)
387 end subroutine problem_update_objectives
395 subroutine problem_update_constraints(this, design)
397 class(
design_t),
intent(in) :: design
400 do i = 1, this%n_constraints
401 call this%constraint_list(i)%constraint%update_value(
design)
403 end subroutine problem_update_constraints
411 subroutine problem_update_objective_sensitivities(this, design)
413 class(
design_t),
intent(in) :: design
416 do i = 1, this%n_objectives
417 call this%objective_list(i)%objective%update_sensitivity(
design)
419 end subroutine problem_update_objective_sensitivities
427 subroutine problem_update_constraint_sensitivities(this, design)
429 class(
design_t),
intent(in) :: design
432 do i = 1, this%n_constraints
433 call this%constraint_list(i)%constraint%update_sensitivity(
design)
435 end subroutine problem_update_constraint_sensitivities
446 subroutine problem_get_objective_value(this, objective_value)
448 real(kind=rp),
intent(out) :: objective_value
451 objective_value = 0.0_rp
452 do i = 1, this%n_objectives
453 objective_value = objective_value + &
454 this%objective_list(i)%objective%weight * &
455 this%objective_list(i)%objective%value
458 end subroutine problem_get_objective_value
466 subroutine problem_get_all_objective_values(this, all_objective_values)
468 type(vector_t),
intent(out) :: all_objective_values
471 call all_objective_values%init(this%n_objectives)
473 do i = 1, this%n_objectives
474 all_objective_values%x(i) = this%objective_list(i)%objective%value
477 if (neko_bcknd_device .eq. 1)
then
478 call device_memcpy(all_objective_values%x, all_objective_values%x_d, &
479 this%n_objectives, host_to_device, sync = .true.)
482 end subroutine problem_get_all_objective_values
490 subroutine problem_get_constraint_values(this, constraint_value)
492 type(vector_t),
intent(out) :: constraint_value
495 call constraint_value%init(this%n_constraints)
497 do i = 1, this%n_constraints
498 constraint_value%x(i) = this%constraint_list(i)%constraint%value
501 if (neko_bcknd_device .eq. 1)
then
502 call device_memcpy(constraint_value%x, constraint_value%x_d, &
503 this%n_constraints, host_to_device, sync = .true.)
506 end subroutine problem_get_constraint_values
514 subroutine problem_get_objective_sensitivities(this, sensitivity)
516 type(vector_t),
intent(out) :: sensitivity
519 call sensitivity%init(this%n_design)
521 do i = 1, this%n_objectives
522 sensitivity = sensitivity + this%objective_list(i)%objective%sensitivity
525 end subroutine problem_get_objective_sensitivities
533 subroutine problem_get_constraint_sensitivities(this, sensitivity)
535 type(matrix_t),
intent(out) :: sensitivity
538 call sensitivity%init(this%n_constraints, this%n_design)
540 do i = 1, this%n_constraints
541 if (neko_bcknd_device .eq. 1)
then
542 call device_memcpy( &
543 this%constraint_list(i)%constraint%sensitivity%x, &
544 this%constraint_list(i)%constraint%sensitivity%x_d, &
545 this%n_design, device_to_host, sync = .true.)
547 do j = 1, this%n_design
548 sensitivity%x(i, j) = &
549 this%constraint_list(i)%constraint%sensitivity%x(j)
553 if (neko_bcknd_device .eq. 1)
then
554 call device_memcpy(sensitivity%x, sensitivity%x_d, &
555 this%n_design * this%n_constraints, host_to_device, sync = .true.)
558 end subroutine problem_get_constraint_sensitivities
564 pure function problem_get_num_objectives(this)
result(n)
568 n = this%n_objectives
569 end function problem_get_num_objectives
572 pure function problem_get_num_constraints(this)
result(n)
576 n = this%n_constraints
577 end function problem_get_num_constraints
580 function problem_get_log_header(this)
result(buff)
582 character(len=1024) :: buff
583 character(len=50) :: mini_buff
598 buff =
"Total objective function"
599 do i = 1, this%get_n_objectives()
601 write(mini_buff,
'(", ", A)') this%objective_list(i)%objective%name
602 buff = trim(buff)//trim(mini_buff)
605 do i = 1, this%get_n_constraints()
607 write(mini_buff,
'(", ", A)') &
608 this%constraint_list(i)%constraint%name
609 buff = trim(buff)//trim(mini_buff)
612 end function problem_get_log_header
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.
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.