6 use num_types,
only: rp
7 use utils,
only: neko_error
8 use json_module,
only: json_file
9 use json_utils,
only: json_get_or_default, json_extract_object
12 use field,
only: field_t
13 use field_registry,
only: neko_field_registry
15 use vector,
only: vector_t
16 use matrix,
only: matrix_t
19 use comm,
only: neko_comm, pe_rank
20 use mpi_f08,
only: mpi_integer, mpi_sum, mpi_allreduce
22 use neko_config,
only: neko_bcknd_device
24 use,
intrinsic :: iso_fortran_env, only: stderr => error_unit
26 use math,
only: copy, cmult
27 use device_math,
only: device_copy
28 use field_math,
only: field_rzero
31 use device,
only: device_memcpy, host_to_device, device_to_host
33 use device_math,
only: device_copy
49 real(kind=rp) :: scale
55 generic :: init => init_from_json, init_from_components
56 procedure, pass(this) :: init_from_json => mma_optimizer_init_from_json
57 procedure, pass(this) :: init_from_components => &
58 mma_optimizer_init_from_components
60 procedure :: run => mma_optimizer_run
61 procedure :: free => mma_optimizer_free
68 subroutine mma_optimizer_init_from_json(this, parameters, problem, design, &
69 max_iterations, tolerance, simulation)
71 type(json_file),
intent(inout) :: parameters
74 integer,
intent(in) :: max_iterations
75 real(kind=rp),
intent(in) :: tolerance
78 character(len=1024) :: optimization_header
79 character(len=1024) :: problem_header
82 type(json_file) :: solver_parameters
85 call this%logger%init(
'optimization_data.csv')
88 problem_header =
problem%get_log_header()
89 optimization_header =
'iter, ' // trim(problem_header) // &
90 ', KKTmax, KKTnorm2, scaling factor'
91 call this%logger%set_header(trim(optimization_header))
95 if (pe_rank .eq. 0)
then
96 print *,
"Initializing mma_optimizer with steady_state_problem_t."
99 call json_extract_object(parameters,
"optimization.solver", &
101 call this%mma%init(x%x,
design%size(),
problem%get_n_constraints(), &
102 solver_parameters, this%scale, this%auto_scale)
105 max_iterations, tolerance, simulation)
108 end subroutine mma_optimizer_init_from_json
111 subroutine mma_optimizer_init_from_components(this, problem, design, &
112 max_iterations, tolerance, simulation)
116 integer,
intent(in) :: max_iterations
117 real(kind=rp),
intent(in) :: tolerance
120 call this%init_base(max_iterations, tolerance)
122 end subroutine mma_optimizer_init_from_components
125 subroutine mma_optimizer_run(this, problem, design, simulation)
129 type(
simulation_t),
optional,
intent(inout) :: simulation
133 integer :: iter, ierr, nglobal, n
134 real(kind=rp) :: scaling_factor
136 real(kind=rp) :: objective_value
137 type(vector_t) :: all_objectives
138 type(vector_t) :: constraint_value
139 type(vector_t) :: objective_sensitivities
140 type(matrix_t) :: constraint_sensitivities
142 type(vector_t) :: log_data
145 call mpi_allreduce(n, nglobal, 1, mpi_integer, mpi_sum, neko_comm, ierr)
148 scaling_factor = 1.0_rp
149 if (pe_rank .eq. 0)
then
150 print *,
"max_iterations for the optimization loop = ", &
154 if (
present(simulation))
call simulation%run_forward()
158 if (
present(simulation))
call simulation%run_backward()
161 call problem%get_objective_value(objective_value)
162 call problem%get_constraint_values(constraint_value)
163 call problem%get_objective_sensitivities(objective_sensitivities)
164 call problem%get_constraint_sensitivities(constraint_sensitivities)
165 call problem%get_all_objective_values(all_objectives)
168 call mma_logger_assemble_data(log_data, 0, objective_value, &
169 all_objectives, constraint_value, 0.0_rp, 0.0_rp, scaling_factor, &
171 call this%logger%write(log_data)
173 if (
present(simulation))
call simulation%write(0)
177 do iter = 1, this%max_iterations
178 if (this%mma%get_residumax() .lt. this%tolerance)
exit
181 if (this%auto_scale .eqv. .true.)
then
182 scaling_factor = abs(this%scale/constraint_value%x(1))
184 scaling_factor = abs(this%scale)
189 constraint_value = scaling_factor * constraint_value
190 constraint_sensitivities = scaling_factor * constraint_sensitivities
193 call this%mma%update(iter, x, objective_sensitivities, &
194 constraint_value, constraint_sensitivities)
196 call design%update_design(x)
198 if (
present(simulation))
call simulation%run_forward()
201 if (
present(simulation))
call simulation%run_backward()
204 call problem%get_objective_value(objective_value)
205 call problem%get_constraint_values(constraint_value)
206 call problem%get_objective_sensitivities(objective_sensitivities)
207 call problem%get_constraint_sensitivities(constraint_sensitivities)
208 call problem%get_all_objective_values(all_objectives)
210 call this%mma%KKT(x, objective_sensitivities, &
211 constraint_value, constraint_sensitivities)
214 call mma_logger_assemble_data(log_data, iter, objective_value, &
215 all_objectives, constraint_value, this%mma%get_residumax(), &
216 this%mma%get_residunorm(), scaling_factor, &
218 call this%logger%write(log_data)
220 if (
present(simulation))
call simulation%write(iter)
222 if (
present(simulation))
call simulation%reset()
226 if (pe_rank .eq. 0)
then
227 print *,
"MMA Optimization completed after", iter-1,
"iterations."
230 call constraint_value%free()
231 call objective_sensitivities%free()
232 call constraint_sensitivities%free()
234 end subroutine mma_optimizer_run
237 subroutine mma_optimizer_free(this)
242 end subroutine mma_optimizer_free
245 subroutine mma_logger_assemble_data(log_data, iter, objective_value, &
246 all_objectives, constraint_value, residumax, residunorm, &
247 scaling_factor, n, m)
248 type(vector_t),
intent(out) :: log_data
249 integer,
intent(in) :: iter
250 real(kind=rp),
intent(in) ::objective_value
251 type(vector_t),
intent(in) :: all_objectives
252 type(vector_t),
intent(in) :: constraint_value
253 real(kind=rp),
intent(in) :: residumax, residunorm, scaling_factor
254 integer,
intent(in) :: n, m
255 integer :: i_tmp1, i_tmp2
259 call log_data%init(5 + n + m)
262 log_data%x(1) = real(iter, kind=rp)
265 log_data%x(2) = objective_value
269 i_tmp2 = i_tmp1 + n - 1
270 log_data%x(i_tmp1 : i_tmp2) = all_objectives%x
274 i_tmp2 = i_tmp1 + m - 1
275 log_data%x(i_tmp1 : i_tmp2) = constraint_value%x
278 log_data%x(i_tmp2 + 1) = residumax
279 log_data%x(i_tmp2 + 2) = residunorm
280 log_data%x(i_tmp2 + 3) = scaling_factor
282 end subroutine mma_logger_assemble_data
283end module mma_optimizer
Some common Masking operations we may need.
Contains extensions to the neko library required to run the topology optimization code.
subroutine, public reset(neko_case)
Reset the case data structure.
Module for handling the optimization problem.
Implements the steady_problem_t type.
Abstract optimizer class.
The abstract problem type.