KratosOptimizationApplication 10.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- KratosMultiphysics/.libs/KratosOptimizationApplication.so +0 -0
- KratosMultiphysics/.libs/libKratosOptimizationCore.dylib +0 -0
- KratosMultiphysics/OptimizationApplication/__init__.py +19 -0
- KratosMultiphysics/OptimizationApplication/algorithms/NLOPT_algorithms.py +255 -0
- KratosMultiphysics/OptimizationApplication/algorithms/SciPy_algorithms.py +154 -0
- KratosMultiphysics/OptimizationApplication/algorithms/__init__.py +0 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm.py +78 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_adam.py +68 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_base.py +393 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_gradient_projection.py +355 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_momentum_relaxed_gradient_projection.py +70 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_nesterov_accelarated_gradient.py +60 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_relaxed_gradient_projection.py +263 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_steepest_descent.py +205 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_NLOPT_constraint.py +194 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_NLOPT_objective.py +191 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_SciPy_constraint.py +123 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_SciPy_objective.py +148 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_constraint.py +180 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_objective.py +133 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_rgp_constraint.py +268 -0
- KratosMultiphysics/OptimizationApplication/analyses_controller.py +75 -0
- KratosMultiphysics/OptimizationApplication/controls/control.py +123 -0
- KratosMultiphysics/OptimizationApplication/controls/external_response_function_control.py +149 -0
- KratosMultiphysics/OptimizationApplication/controls/master_control.py +198 -0
- KratosMultiphysics/OptimizationApplication/controls/material/material_properties_control.py +115 -0
- KratosMultiphysics/OptimizationApplication/controls/material/simp_control.py +229 -0
- KratosMultiphysics/OptimizationApplication/controls/shape/vertex_morphing_shape_control.py +289 -0
- KratosMultiphysics/OptimizationApplication/controls/thickness/shell_thickness_control.py +180 -0
- KratosMultiphysics/OptimizationApplication/controls_controller.py +205 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/avg_abs_improvement_conv_criterion.py +98 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/combined_conv_criterion.py +87 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/constraint_conv_criterion.py +68 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/convergence_criterion.py +26 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/l2_conv_criterion.py +77 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/magnitude_reduction_conv_criterion.py +85 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/max_iter_conv_criterion.py +48 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/patience_conv_criterion.py +116 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/target_value_conv_criterion.py +64 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/execution_policy.py +46 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/execution_policy_decorator.py +67 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/independent_analysis_execution_policy.py +78 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/kratos_analysis_execution_policy.py +137 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/stepping_analysis_execution_policy.py +88 -0
- KratosMultiphysics/OptimizationApplication/filtering/explicit_filter.py +124 -0
- KratosMultiphysics/OptimizationApplication/filtering/filter.py +188 -0
- KratosMultiphysics/OptimizationApplication/filtering/filter_utils.py +55 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_analysis.py +139 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_scalar_solver.py +39 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_shape_solver.py +67 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_solver_base.py +275 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_vector_solver.py +39 -0
- KratosMultiphysics/OptimizationApplication/filtering/implicit_filter.py +192 -0
- KratosMultiphysics/OptimizationApplication/filtering/python_solvers_wrapper_implicit_filters.py +56 -0
- KratosMultiphysics/OptimizationApplication/model_part_controllers/connectivity_preserving_model_part_controller.py +72 -0
- KratosMultiphysics/OptimizationApplication/model_part_controllers/external_response_function_model_part_controller.py +110 -0
- KratosMultiphysics/OptimizationApplication/model_part_controllers/mdpa_model_part_controller.py +44 -0
- KratosMultiphysics/OptimizationApplication/model_part_controllers/model_part_controller.py +19 -0
- KratosMultiphysics/OptimizationApplication/model_parts_controller.py +92 -0
- KratosMultiphysics/OptimizationApplication/optimization_analysis.py +146 -0
- KratosMultiphysics/OptimizationApplication/optimizations_controller.py +223 -0
- KratosMultiphysics/OptimizationApplication/optimizer.py +61 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_ascii_output_process.py +212 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_field_output_process.py +122 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_graph_output_process.py +184 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_hdf5_output_process.py +84 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_vtu_output_process.py +94 -0
- KratosMultiphysics/OptimizationApplication/processes/spatial_statistics_computation_process.py +81 -0
- KratosMultiphysics/OptimizationApplication/responses/__init__.py +0 -0
- KratosMultiphysics/OptimizationApplication/responses/additive_manufacturing_responses.py +410 -0
- KratosMultiphysics/OptimizationApplication/responses/analysis_based_response_function_factory.py +14 -0
- KratosMultiphysics/OptimizationApplication/responses/analysis_free_response_function_factory.py +14 -0
- KratosMultiphysics/OptimizationApplication/responses/base_response.py +66 -0
- KratosMultiphysics/OptimizationApplication/responses/binary_operator_response_function.py +103 -0
- KratosMultiphysics/OptimizationApplication/responses/combined_response_function.py +127 -0
- KratosMultiphysics/OptimizationApplication/responses/discrete_value_residual_response_function.py +131 -0
- KratosMultiphysics/OptimizationApplication/responses/evaluation_response_function.py +68 -0
- KratosMultiphysics/OptimizationApplication/responses/external_response_function.py +87 -0
- KratosMultiphysics/OptimizationApplication/responses/geometric_centroid_deviation_response_function.py +97 -0
- KratosMultiphysics/OptimizationApplication/responses/linear_strain_energy_response_function.py +72 -0
- KratosMultiphysics/OptimizationApplication/responses/literal_value_response_function.py +33 -0
- KratosMultiphysics/OptimizationApplication/responses/log_response_function.py +47 -0
- KratosMultiphysics/OptimizationApplication/responses/mass_response_function.py +71 -0
- KratosMultiphysics/OptimizationApplication/responses/response_function.py +126 -0
- KratosMultiphysics/OptimizationApplication/responses/response_routine.py +158 -0
- KratosMultiphysics/OptimizationApplication/responses/structural_responses.py +335 -0
- KratosMultiphysics/OptimizationApplication/responses_controller.py +390 -0
- KratosMultiphysics/OptimizationApplication/utilities/buffered_dict.py +399 -0
- KratosMultiphysics/OptimizationApplication/utilities/component_data_view.py +74 -0
- KratosMultiphysics/OptimizationApplication/utilities/helper_utilities.py +40 -0
- KratosMultiphysics/OptimizationApplication/utilities/logger_utilities.py +222 -0
- KratosMultiphysics/OptimizationApplication/utilities/model_part_utilities.py +117 -0
- KratosMultiphysics/OptimizationApplication/utilities/opt_line_search.py +173 -0
- KratosMultiphysics/OptimizationApplication/utilities/opt_projection.py +191 -0
- KratosMultiphysics/OptimizationApplication/utilities/optimization_problem.py +237 -0
- KratosMultiphysics/OptimizationApplication/utilities/optimization_problem_utilities.py +237 -0
- KratosMultiphysics/OptimizationApplication/utilities/response_utilities.py +249 -0
- KratosMultiphysics/OptimizationApplication/utilities/timer.py +45 -0
- KratosMultiphysics/OptimizationApplication/utilities/union_utilities.py +6 -0
- kratosoptimizationapplication-10.4.4.dist-info/METADATA +25 -0
- kratosoptimizationapplication-10.4.4.dist-info/RECORD +106 -0
- kratosoptimizationapplication-10.4.4.dist-info/WHEEL +6 -0
- kratosoptimizationapplication.dylibs/libKratosCore.dylib +4 -0
- kratosoptimizationapplication.dylibs/libgcc_s.1.1.dylib +0 -0
- kratosoptimizationapplication.dylibs/libgomp.1.dylib +0 -0
- kratosoptimizationapplication.dylibs/libstdc++.6.dylib +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# KratosOptimizationApplication
|
|
3
|
+
#
|
|
4
|
+
# License: BSD License
|
|
5
|
+
# license: OptimizationApplication/license.txt
|
|
6
|
+
#
|
|
7
|
+
# Main authors: Reza Najian Asl, https://github.com/RezaNajian
|
|
8
|
+
#
|
|
9
|
+
# ==============================================================================
|
|
10
|
+
|
|
11
|
+
# ------------------------------------------------------------------------------
|
|
12
|
+
# Imports
|
|
13
|
+
# ------------------------------------------------------------------------------
|
|
14
|
+
from KratosMultiphysics import _ImportApplication
|
|
15
|
+
from KratosOptimizationApplication import *
|
|
16
|
+
application = KratosOptimizationApplication()
|
|
17
|
+
application_name = "KratosOptimizationApplication"
|
|
18
|
+
|
|
19
|
+
_ImportApplication(application, application_name)
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
try:
|
|
2
|
+
import nlopt
|
|
3
|
+
except ImportError:
|
|
4
|
+
raise Exception("NLOPT python library is not available")
|
|
5
|
+
|
|
6
|
+
import KratosMultiphysics as Kratos
|
|
7
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
|
|
8
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.standardized_NLOPT_objective import StandardizedNLOPTObjective
|
|
9
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.standardized_NLOPT_constraint import StandardizedNLOPTConstraint
|
|
10
|
+
from KratosMultiphysics.OptimizationApplication.controls.master_control import MasterControl
|
|
11
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.algorithm import Algorithm
|
|
12
|
+
from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView
|
|
13
|
+
from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import DictLogger
|
|
14
|
+
from KratosMultiphysics.OptimizationApplication.utilities.helper_utilities import CallOnAll
|
|
15
|
+
from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import time_decorator
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
20
|
+
return NLOPTAlgorithms(model, parameters, optimization_problem)
|
|
21
|
+
|
|
22
|
+
class NLOPTAlgorithms(Algorithm):
|
|
23
|
+
"""
|
|
24
|
+
A classical steepest descent algorithm to solve unconstrained optimization problems.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def GetDefaultParameters(cls):
|
|
29
|
+
return Kratos.Parameters("""{
|
|
30
|
+
"module" : "KratosMultiphysics.OptimizationApplication.algorithms",
|
|
31
|
+
"type" : "PLEASE_PROVIDE_AN_ALGORITHM_CLASS_NAME",
|
|
32
|
+
"objective" : {},
|
|
33
|
+
"constraints" : [],
|
|
34
|
+
"controls" : [],
|
|
35
|
+
"echo_level" : 0,
|
|
36
|
+
"NLOPT_settings" : {
|
|
37
|
+
"algorithm_name" : "mma",
|
|
38
|
+
"subsidiary_algorithm_name" : "",
|
|
39
|
+
"verbosity" : 0,
|
|
40
|
+
"controls_lower_bound": "",
|
|
41
|
+
"controls_upper_bound": "",
|
|
42
|
+
"stopping_criteria" : {
|
|
43
|
+
"rel_obj_tol": 1e-3,
|
|
44
|
+
"abs_obj_tol": 1e-3,
|
|
45
|
+
"rel_contr_tol": 1e-3,
|
|
46
|
+
"abs_contr_tol": 1e-3,
|
|
47
|
+
"maximum_function_evalualtion": 10
|
|
48
|
+
},
|
|
49
|
+
"algorithm_specific_settings" : {}
|
|
50
|
+
}
|
|
51
|
+
}""")
|
|
52
|
+
|
|
53
|
+
def __init__(self, model:Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
54
|
+
self.model = model
|
|
55
|
+
self.parameters = parameters
|
|
56
|
+
self._optimization_problem = optimization_problem
|
|
57
|
+
|
|
58
|
+
parameters.ValidateAndAssignDefaults(self.GetDefaultParameters())
|
|
59
|
+
|
|
60
|
+
# controls
|
|
61
|
+
self.master_control = MasterControl()
|
|
62
|
+
self._optimization_problem.AddComponent(self.master_control)
|
|
63
|
+
for control_name in parameters["controls"].GetStringArray():
|
|
64
|
+
control = optimization_problem.GetControl(control_name)
|
|
65
|
+
self.master_control.AddControl(control)
|
|
66
|
+
self.__control_field = None
|
|
67
|
+
|
|
68
|
+
# objective & constraints
|
|
69
|
+
self.__objective = StandardizedNLOPTObjective(parameters["objective"], self.master_control, self._optimization_problem)
|
|
70
|
+
self._optimization_problem.AddComponent(self.__objective)
|
|
71
|
+
self.__constraints = []
|
|
72
|
+
for constraint_settings in parameters["constraints"].values():
|
|
73
|
+
constraint = StandardizedNLOPTConstraint(constraint_settings, self.master_control, self._optimization_problem)
|
|
74
|
+
self._optimization_problem.AddComponent(constraint)
|
|
75
|
+
self.__constraints.append(constraint)
|
|
76
|
+
|
|
77
|
+
# nlopt settings
|
|
78
|
+
NLOPT_settings = parameters["NLOPT_settings"]
|
|
79
|
+
NLOPT_settings.ValidateAndAssignDefaults(self.GetDefaultParameters()["NLOPT_settings"])
|
|
80
|
+
|
|
81
|
+
# nlopt verbosity
|
|
82
|
+
self.nlopt_verbosity = NLOPT_settings["verbosity"].GetInt()
|
|
83
|
+
|
|
84
|
+
# upper and lower bounds
|
|
85
|
+
self.nlopt_controls_lower_bound = NLOPT_settings["controls_lower_bound"].GetString()
|
|
86
|
+
self.nlopt_controls_upper_bound = NLOPT_settings["controls_upper_bound"].GetString()
|
|
87
|
+
|
|
88
|
+
# nlopt algorithm
|
|
89
|
+
self.algorithm_name = NLOPT_settings["algorithm_name"].GetString()
|
|
90
|
+
if len(self.__constraints)==0:
|
|
91
|
+
self.CheckOptimizerSupport(self.algorithm_name,None)
|
|
92
|
+
else:
|
|
93
|
+
for constraint in self.__constraints:
|
|
94
|
+
if constraint.IsEqualityType():
|
|
95
|
+
self.CheckOptimizerSupport(self.algorithm_name,"equality")
|
|
96
|
+
else:
|
|
97
|
+
self.CheckOptimizerSupport(self.algorithm_name,"inequality")
|
|
98
|
+
|
|
99
|
+
# nlopt subsidiary algorithm
|
|
100
|
+
self.subsidiary_algorithm_name = NLOPT_settings["subsidiary_algorithm_name"].GetString()
|
|
101
|
+
if self.algorithm_name == "augmented_lagrangian":
|
|
102
|
+
if self.subsidiary_algorithm_name == "":
|
|
103
|
+
raise ValueError(f"The algorithm {self.algorithm_name} requires a subsidiary optimizer to be provided.")
|
|
104
|
+
else:
|
|
105
|
+
self.CheckOptimizerSupport(self.subsidiary_algorithm_name,None)
|
|
106
|
+
|
|
107
|
+
# stopping
|
|
108
|
+
self.stopping_criteria = NLOPT_settings["stopping_criteria"]
|
|
109
|
+
self.stopping_criteria.ValidateAndAssignDefaults(self.GetDefaultParameters()["NLOPT_settings"]["stopping_criteria"])
|
|
110
|
+
|
|
111
|
+
# alg specific settings
|
|
112
|
+
self.opt_algorithm_specific_settings = NLOPT_settings["algorithm_specific_settings"]
|
|
113
|
+
|
|
114
|
+
def GetMinimumBufferSize(self) -> int:
|
|
115
|
+
return 2
|
|
116
|
+
|
|
117
|
+
def Check(self):
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
@time_decorator()
|
|
121
|
+
def Initialize(self):
|
|
122
|
+
self.converged = False
|
|
123
|
+
self.master_control.Initialize()
|
|
124
|
+
self.__objective.Initialize()
|
|
125
|
+
self.__objective.Check()
|
|
126
|
+
CallOnAll(self.__constraints, StandardizedNLOPTConstraint.Initialize)
|
|
127
|
+
self.__control_field = self.master_control.GetControlField()
|
|
128
|
+
self.algorithm_data = ComponentDataView("algorithm", self._optimization_problem)
|
|
129
|
+
|
|
130
|
+
# create nlopt optimizer
|
|
131
|
+
self.x0 = self.__control_field.data.reshape(-1)
|
|
132
|
+
self.nlopt_optimizer = nlopt.opt(self.GetOptimizer(self.algorithm_name), self.x0.size)
|
|
133
|
+
|
|
134
|
+
# add subsidiary optimization algorithm
|
|
135
|
+
if self.subsidiary_algorithm_name != "":
|
|
136
|
+
self.nlopt_subsidiary_optimizer = nlopt.opt(self.GetOptimizer(self.subsidiary_algorithm_name), self.x0.size)
|
|
137
|
+
self.nlopt_optimizer.set_local_optimizer(self.nlopt_subsidiary_optimizer)
|
|
138
|
+
else:
|
|
139
|
+
self.nlopt_subsidiary_optimizer = None
|
|
140
|
+
|
|
141
|
+
# set nlopt verbosity
|
|
142
|
+
self.nlopt_optimizer.set_param("verbosity",self.nlopt_verbosity)
|
|
143
|
+
|
|
144
|
+
# assign objectives and constraints
|
|
145
|
+
self.nlopt_optimizer.set_min_objective(self.__objective.CalculateStandardizedValueAndGradients)
|
|
146
|
+
for constraint in self.__constraints:
|
|
147
|
+
if constraint.IsEqualityType():
|
|
148
|
+
self.nlopt_optimizer.add_equality_constraint(constraint.CalculateStandardizedValueAndGradients,1e-8)
|
|
149
|
+
else:
|
|
150
|
+
self.nlopt_optimizer.add_inequality_constraint(constraint.CalculateStandardizedValueAndGradients,1e-8)
|
|
151
|
+
|
|
152
|
+
# now set stopping criteria
|
|
153
|
+
self.SetOptimizerStoppingCriteria(self.nlopt_optimizer)
|
|
154
|
+
if self.nlopt_subsidiary_optimizer is not None:
|
|
155
|
+
self.SetOptimizerStoppingCriteria(self.nlopt_subsidiary_optimizer)
|
|
156
|
+
|
|
157
|
+
# set bounds if exist
|
|
158
|
+
if self.nlopt_controls_lower_bound != "":
|
|
159
|
+
self.nlopt_optimizer.set_lower_bounds(float(self.nlopt_controls_lower_bound))
|
|
160
|
+
if self.nlopt_controls_upper_bound != "":
|
|
161
|
+
self.nlopt_optimizer.set_upper_bounds(float(self.nlopt_controls_upper_bound))
|
|
162
|
+
|
|
163
|
+
# now add algorithm specific settings
|
|
164
|
+
self.SetOptimizerSepcificSettings(self.nlopt_optimizer)
|
|
165
|
+
if self.nlopt_subsidiary_optimizer is not None:
|
|
166
|
+
self.SetOptimizerSepcificSettings(self.nlopt_subsidiary_optimizer)
|
|
167
|
+
|
|
168
|
+
@time_decorator()
|
|
169
|
+
def Finalize(self):
|
|
170
|
+
self.__objective.Finalize()
|
|
171
|
+
for constraint in self.__constraints:
|
|
172
|
+
constraint.Finalize()
|
|
173
|
+
self.master_control.Finalize()
|
|
174
|
+
|
|
175
|
+
@time_decorator()
|
|
176
|
+
def Solve(self):
|
|
177
|
+
self.nlopt_optimizer.optimize(self.x0)
|
|
178
|
+
CallOnAll(self._optimization_problem.GetListOfProcesses("output_processes"), Kratos.OutputProcess.PrintOutput)
|
|
179
|
+
self.LogTermination()
|
|
180
|
+
|
|
181
|
+
def LogTermination(self):
|
|
182
|
+
stopval = self.nlopt_optimizer.get_stopval()
|
|
183
|
+
maxtime = self.nlopt_optimizer.get_maxtime()
|
|
184
|
+
nlopt_result_map = {
|
|
185
|
+
nlopt.SUCCESS: 'Generic success return value.',
|
|
186
|
+
nlopt.STOPVAL_REACHED: f'Optimization stopped because stopval ({stopval}) was reached.',
|
|
187
|
+
nlopt.FTOL_REACHED: f'Optimization stopped because ftol_rel ({self.stopping_criteria["rel_obj_tol"].GetDouble()}) or ftol_abs ({self.stopping_criteria["abs_obj_tol"].GetDouble()}) was reached.',
|
|
188
|
+
nlopt.XTOL_REACHED: f'Optimization stopped because xtol_rel ({self.stopping_criteria["rel_contr_tol"].GetDouble()}) or xtol_abs ({self.stopping_criteria["abs_contr_tol"].GetDouble()}) was reached.',
|
|
189
|
+
nlopt.MAXEVAL_REACHED: f'Optimization stopped because maxeval ({self.stopping_criteria["maximum_function_evalualtion"].GetInt()}) was reached.',
|
|
190
|
+
nlopt.MAXTIME_REACHED: f'Optimization stopped because maxtime ({maxtime}) was reached.',
|
|
191
|
+
nlopt.FAILURE: 'Generic failure return value.',
|
|
192
|
+
nlopt.INVALID_ARGS: 'Invalid arguments (e.g. lower bounds are bigger than upper bounds, an unknown algorithm was specified, etcetera).',
|
|
193
|
+
nlopt.OUT_OF_MEMORY: 'Ran out of memory.',
|
|
194
|
+
nlopt.ROUNDOFF_LIMITED: 'Halted because roundoff errors limited progress. (In this case, the optimization still typically returns a useful result.)',
|
|
195
|
+
nlopt.FORCED_STOP: 'Halted because of a forced termination: the user called nlopt_force_stop(opt) on the optimization’s nlopt_opt object opt from the user’s objective function or constraints.'
|
|
196
|
+
}
|
|
197
|
+
info = {"Termination":nlopt_result_map[self.nlopt_optimizer.last_optimize_result()]}
|
|
198
|
+
DictLogger(f"NLOPT-{self.algorithm_name}",info)
|
|
199
|
+
|
|
200
|
+
def CheckOptimizerSupport(self, algorithm_name, constraint_type):
|
|
201
|
+
# Unconstrained gradient-based optimizers
|
|
202
|
+
unconstrained_optimizers = {"lbfgs","mma","ccsaq","tnewton_precond_restart",
|
|
203
|
+
"tnewton_precond","tnewton_restart","augmented_lagrangian",
|
|
204
|
+
"neldermead","evolutionary"}
|
|
205
|
+
|
|
206
|
+
# Constrained gradient-based optimizers with equality constraints
|
|
207
|
+
equality_constrained_optimizers = {"slsqp","augmented_lagrangian"}
|
|
208
|
+
|
|
209
|
+
# Constrained gradient-based optimizers with inequality constraints
|
|
210
|
+
inequality_constrained_optimizers = {"mma","slsqp","ccsaq","augmented_lagrangian"}
|
|
211
|
+
|
|
212
|
+
if constraint_type == "equality":
|
|
213
|
+
if algorithm_name not in equality_constrained_optimizers:
|
|
214
|
+
raise ValueError(f"The algorithm {algorithm_name} does not support equality constraints, support {equality_constrained_optimizers}.")
|
|
215
|
+
elif constraint_type == "inequality":
|
|
216
|
+
if algorithm_name not in inequality_constrained_optimizers:
|
|
217
|
+
raise ValueError(f"The algorithm {algorithm_name} does not support inequality constraints, support {inequality_constrained_optimizers}.")
|
|
218
|
+
else:
|
|
219
|
+
if algorithm_name not in unconstrained_optimizers:
|
|
220
|
+
raise ValueError(f"The algorithm {algorithm_name} does not support unconstrained optimization, support {unconstrained_optimizers}.")
|
|
221
|
+
return True
|
|
222
|
+
|
|
223
|
+
def GetOptimizer(self,name):
|
|
224
|
+
nlopt_algorithm_dict = {
|
|
225
|
+
"mma": nlopt.LD_MMA,
|
|
226
|
+
"slsqp": nlopt.LD_SLSQP,
|
|
227
|
+
"lbfgs": nlopt.LD_LBFGS,
|
|
228
|
+
"ccsaq": nlopt.LD_CCSAQ,
|
|
229
|
+
"tnewton_precond_restart": nlopt.LD_TNEWTON_PRECOND_RESTART,
|
|
230
|
+
"tnewton_precond": nlopt.LD_TNEWTON_PRECOND,
|
|
231
|
+
"tnewton_restart": nlopt.LD_TNEWTON_RESTART,
|
|
232
|
+
"augmented_lagrangian": nlopt.AUGLAG,
|
|
233
|
+
"neldermead": nlopt.LN_NELDERMEAD,
|
|
234
|
+
"evolutionary": nlopt.GN_ESCH
|
|
235
|
+
}
|
|
236
|
+
return nlopt_algorithm_dict[name]
|
|
237
|
+
|
|
238
|
+
def SetOptimizerStoppingCriteria(self,nlopt_optimizer):
|
|
239
|
+
nlopt_optimizer.set_ftol_rel(self.stopping_criteria["rel_obj_tol"].GetDouble())
|
|
240
|
+
nlopt_optimizer.set_ftol_abs(self.stopping_criteria["abs_obj_tol"].GetDouble())
|
|
241
|
+
nlopt_optimizer.set_xtol_rel(self.stopping_criteria["rel_contr_tol"].GetDouble())
|
|
242
|
+
nlopt_optimizer.set_xtol_abs(self.stopping_criteria["abs_contr_tol"].GetDouble())
|
|
243
|
+
nlopt_optimizer.set_maxeval(self.stopping_criteria["maximum_function_evalualtion"].GetInt())
|
|
244
|
+
|
|
245
|
+
def SetOptimizerSepcificSettings(self,nlopt_optimizer):
|
|
246
|
+
if self.opt_algorithm_specific_settings.Has("inner_maxeval"):
|
|
247
|
+
nlopt_optimizer.set_param("inner_maxeval",self.opt_algorithm_specific_settings["inner_maxeval"].GetInt())
|
|
248
|
+
if self.opt_algorithm_specific_settings.Has("dual_ftol_rel"):
|
|
249
|
+
nlopt_optimizer.set_param("dual_ftol_rel",self.opt_algorithm_specific_settings["dual_ftol_rel"].GetDouble())
|
|
250
|
+
if self.opt_algorithm_specific_settings.Has("initial_step"):
|
|
251
|
+
nlopt_optimizer.set_initial_step(self.opt_algorithm_specific_settings["initial_step"].GetDouble())
|
|
252
|
+
if self.opt_algorithm_specific_settings.Has("population"):
|
|
253
|
+
nlopt_optimizer.set_population(self.opt_algorithm_specific_settings["population"].GetInt())
|
|
254
|
+
if self.opt_algorithm_specific_settings.Has("number_of_stored_vectors"):
|
|
255
|
+
nlopt_optimizer.set_vector_storage(self.opt_algorithm_specific_settings["number_of_stored_vectors"].GetInt())
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import KratosMultiphysics as Kratos
|
|
2
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
|
|
3
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.standardized_SciPy_objective import StandardizedSciPyObjective
|
|
4
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.standardized_SciPy_constraint import StandardizedSciPyConstraint
|
|
5
|
+
from KratosMultiphysics.OptimizationApplication.controls.master_control import MasterControl
|
|
6
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.algorithm import Algorithm
|
|
7
|
+
from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView
|
|
8
|
+
from KratosMultiphysics.OptimizationApplication.utilities.helper_utilities import CallOnAll
|
|
9
|
+
from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import time_decorator
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem_utilities import OutputGradientFields
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
import scipy
|
|
17
|
+
except ImportError:
|
|
18
|
+
raise Exception("SciPy python library is not available")
|
|
19
|
+
|
|
20
|
+
import scipy.optimize
|
|
21
|
+
from scipy.optimize import NonlinearConstraint
|
|
22
|
+
|
|
23
|
+
def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
24
|
+
return SciPyAlgorithms(model, parameters, optimization_problem)
|
|
25
|
+
|
|
26
|
+
class SciPyAlgorithms(Algorithm):
|
|
27
|
+
"""
|
|
28
|
+
A SciPy wrapper to use algorithms from Library. Provide Method and it settings in the options dict.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def GetDefaultParameters(cls):
|
|
33
|
+
return Kratos.Parameters("""{
|
|
34
|
+
"module" : "KratosMultiphysics.OptimizationApplication.algorithms",
|
|
35
|
+
"type" : "PLEASE_PROVIDE_AN_ALGORITHM_CLASS_NAME",
|
|
36
|
+
"objective" : {},
|
|
37
|
+
"constraints" : [],
|
|
38
|
+
"controls" : [],
|
|
39
|
+
"echo_level" : 0,
|
|
40
|
+
"SciPy_settings" : {
|
|
41
|
+
"method" : "",
|
|
42
|
+
"lower_bound" : -1e16,
|
|
43
|
+
"upper_bound" : 1e16,
|
|
44
|
+
"options" : {}
|
|
45
|
+
}
|
|
46
|
+
}""")
|
|
47
|
+
|
|
48
|
+
def __init__(self, model:Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
49
|
+
self.model = model
|
|
50
|
+
self.parameters = parameters
|
|
51
|
+
self.parameters.ValidateAndAssignDefaults(self.GetDefaultParameters())
|
|
52
|
+
self._optimization_problem = optimization_problem
|
|
53
|
+
|
|
54
|
+
# scipy settings
|
|
55
|
+
self.SciPy_settings = self.parameters["SciPy_settings"]
|
|
56
|
+
self.SciPy_settings.ValidateAndAssignDefaults(self.GetDefaultParameters()["SciPy_settings"])
|
|
57
|
+
|
|
58
|
+
# controls
|
|
59
|
+
self.master_control = MasterControl()
|
|
60
|
+
self._optimization_problem.AddComponent(self.master_control)
|
|
61
|
+
for control_name in parameters["controls"].GetStringArray():
|
|
62
|
+
control = optimization_problem.GetControl(control_name)
|
|
63
|
+
self.master_control.AddControl(control)
|
|
64
|
+
self.__control_field = None
|
|
65
|
+
|
|
66
|
+
# objective & constraints
|
|
67
|
+
self.__objective = StandardizedSciPyObjective(parameters["objective"], self.master_control, self._optimization_problem)
|
|
68
|
+
self._optimization_problem.AddComponent(self.__objective)
|
|
69
|
+
self.bounds = scipy.optimize.Bounds(lb=self.SciPy_settings["lower_bound"].GetDouble(), ub=self.SciPy_settings["upper_bound"].GetDouble())
|
|
70
|
+
self.__kratos_constraints = []
|
|
71
|
+
self.__scipy_constraints = []
|
|
72
|
+
for constraint_settings in parameters["constraints"].values():
|
|
73
|
+
constraint = StandardizedSciPyConstraint(constraint_settings, self.master_control, self._optimization_problem)
|
|
74
|
+
self.__kratos_constraints.append(constraint)
|
|
75
|
+
self._optimization_problem.AddComponent(constraint)
|
|
76
|
+
|
|
77
|
+
# create SciPy specific constraints
|
|
78
|
+
scipy_constraint = NonlinearConstraint(constraint.CalculateStandardizedValue, constraint.GetLowerBound(), constraint.GetUpperBound(), constraint.CalculateStandardizedGradient)
|
|
79
|
+
self.__scipy_constraints.append(scipy_constraint)
|
|
80
|
+
|
|
81
|
+
def GetMinimumBufferSize(self) -> int:
|
|
82
|
+
return 2
|
|
83
|
+
|
|
84
|
+
def Check(self):
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
@time_decorator()
|
|
88
|
+
def Initialize(self):
|
|
89
|
+
self.converged = False
|
|
90
|
+
self.master_control.Initialize()
|
|
91
|
+
self.__objective.Initialize()
|
|
92
|
+
self.__objective.Check()
|
|
93
|
+
CallOnAll(self.__kratos_constraints, StandardizedSciPyConstraint.Initialize)
|
|
94
|
+
self.__control_field = self.master_control.GetControlField()
|
|
95
|
+
self.algorithm_data = ComponentDataView("algorithm", self._optimization_problem)
|
|
96
|
+
self.algorithm_data.SetDataBuffer(self.GetMinimumBufferSize())
|
|
97
|
+
|
|
98
|
+
# create nlopt optimizer
|
|
99
|
+
self.x0 = self.__control_field.data.reshape(-1)
|
|
100
|
+
|
|
101
|
+
@time_decorator()
|
|
102
|
+
def Finalize(self):
|
|
103
|
+
self.__objective.Finalize()
|
|
104
|
+
for constraint in self.__kratos_constraints:
|
|
105
|
+
constraint.Finalize()
|
|
106
|
+
self.master_control.Finalize()
|
|
107
|
+
|
|
108
|
+
@time_decorator()
|
|
109
|
+
def Solve(self):
|
|
110
|
+
if not self.__scipy_constraints:
|
|
111
|
+
res = scipy.optimize.minimize(self.__objective.CalculateStandardizedValue, self.x0, method=self.SciPy_settings["method"].GetString(), jac=self.__objective.CalculateStandardizedGradient, options=self.__GetOptions(), callback=self.Output, bounds=self.bounds)
|
|
112
|
+
elif self.__scipy_constraints:
|
|
113
|
+
res = scipy.optimize.minimize(self.__objective.CalculateStandardizedValue, self.x0, method=self.SciPy_settings["method"].GetString(), jac=self.__objective.CalculateStandardizedGradient, constraints=self.__scipy_constraints, options=self.__GetOptions(), callback=self.Output, bounds=self.bounds)
|
|
114
|
+
Kratos.Logger.PrintInfo(self.__class__.__name__, f"res::success: {res.success}")
|
|
115
|
+
Kratos.Logger.PrintInfo(self.__class__.__name__, f"res::status: {res.status}")
|
|
116
|
+
Kratos.Logger.PrintInfo(self.__class__.__name__, f"res::message: {res.message}")
|
|
117
|
+
|
|
118
|
+
@time_decorator()
|
|
119
|
+
def Output(self, *args) -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
|
|
120
|
+
# SciPy calls it at the end of each optimization iterations. Sometime it doesn't call f(x) during iteration, hence to avoid lack of data in the buffer we have a flag "computed" here.
|
|
121
|
+
if self.__objective.computed:
|
|
122
|
+
|
|
123
|
+
Kratos.Logger.PrintInfo(self.__class__.__name__, f"Output iteration {self._optimization_problem.GetStep()}")
|
|
124
|
+
|
|
125
|
+
self.__control_field.data[:] = args[0]
|
|
126
|
+
Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(self.__control_field, perform_store_data_recursively=False, copy=False).StoreData()
|
|
127
|
+
|
|
128
|
+
self.algorithm_data.GetBufferedData().SetValue("control_field", self.__control_field.Clone(), overwrite=True)
|
|
129
|
+
OutputGradientFields(self.__objective, self._optimization_problem, True)
|
|
130
|
+
for constraint in self.__kratos_constraints:
|
|
131
|
+
OutputGradientFields(constraint, self._optimization_problem, True)
|
|
132
|
+
for process in self._optimization_problem.GetListOfProcesses("output_processes"):
|
|
133
|
+
if process.IsOutputStep():
|
|
134
|
+
process.PrintOutput()
|
|
135
|
+
|
|
136
|
+
# Advance in Optimization Iteration
|
|
137
|
+
self._optimization_problem.AdvanceStep()
|
|
138
|
+
self.__objective.computed = False
|
|
139
|
+
|
|
140
|
+
def __GetOptions(self):
|
|
141
|
+
options = self.SciPy_settings["options"]
|
|
142
|
+
dict_options = dict()
|
|
143
|
+
for key in options.keys():
|
|
144
|
+
if options[key].IsBool():
|
|
145
|
+
dict_options[key] = options[key].GetBool()
|
|
146
|
+
elif options[key].IsDouble():
|
|
147
|
+
dict_options[key] = options[key].GetDouble()
|
|
148
|
+
elif options[key].IsInt():
|
|
149
|
+
dict_options[key] = options[key].GetInt()
|
|
150
|
+
elif options[key].IsString():
|
|
151
|
+
dict_options[key] = options[key].GetString()
|
|
152
|
+
else:
|
|
153
|
+
raise RuntimeError(f"Unsupported data type with key = \"{key}\" [ value = {options[key]} ].")
|
|
154
|
+
return dict_options
|
|
File without changes
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
import KratosMultiphysics as Kratos
|
|
4
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
|
|
5
|
+
from KratosMultiphysics.OptimizationApplication.utilities.helper_utilities import CallOnAll
|
|
6
|
+
|
|
7
|
+
class Algorithm(ABC):
|
|
8
|
+
"""Base class for algorithm.
|
|
9
|
+
|
|
10
|
+
Algorithm works purely in the control space. Hence, the ResponseRoutine which
|
|
11
|
+
the algorithm is associated with should convert all physical space gradients to
|
|
12
|
+
control space and control space designs to physical space designs.
|
|
13
|
+
|
|
14
|
+
The purpose of the algorithm is to solve a minimization problem. Hence, the used
|
|
15
|
+
ResponseRoutine should standardize the values and gradients it computes accordingly.
|
|
16
|
+
|
|
17
|
+
Algorithm should create one MasterControl from all the require controls, and share
|
|
18
|
+
it among all the ResponseRoutines.
|
|
19
|
+
|
|
20
|
+
Once it received the objective/constraint values and their gradients, the algorithm
|
|
21
|
+
will compute the new design and request new objective/constraints values and their
|
|
22
|
+
gradients until the specified convergence criteria is met.
|
|
23
|
+
"""
|
|
24
|
+
def __init__(self, optimization_problem: OptimizationProblem) -> None:
|
|
25
|
+
self._optimization_problem = optimization_problem
|
|
26
|
+
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def Initialize(self) -> None:
|
|
29
|
+
"""Initializes the algorithm, ResponseRoutines and MasterControl.
|
|
30
|
+
"""
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
@abstractmethod
|
|
34
|
+
def Check(self) -> None:
|
|
35
|
+
"""Checks algorithm, ResponseRoutines and MasterControl.
|
|
36
|
+
"""
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def Finalize(self) -> None:
|
|
41
|
+
"""Finalizes algorithm ResponseRoutines and MasterControl.
|
|
42
|
+
"""
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
@abstractmethod
|
|
46
|
+
def Solve(self) -> bool:
|
|
47
|
+
"""Solves the optimization problem.
|
|
48
|
+
|
|
49
|
+
This method will have a loop which iterates until the specified
|
|
50
|
+
convergence for the given optimization problem.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
bool: Convergence status. True for converged, False for non-converged.
|
|
54
|
+
"""
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
def GetProcessesOrder(self) -> 'list[str]':
|
|
58
|
+
"""The order of execution of the process categories.
|
|
59
|
+
|
|
60
|
+
This defines the order of execution of the processes defined under "processes"
|
|
61
|
+
in either "kratos_process" or "optimization_data_processes".
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
list[str]: List of strings for process categories.
|
|
65
|
+
"""
|
|
66
|
+
return ["auxiliary_processes", "output_processes"]
|
|
67
|
+
|
|
68
|
+
def CallOnAllProcesses(self, process_types: 'list[str]', *args, **kwargs):
|
|
69
|
+
for process_type in process_types:
|
|
70
|
+
CallOnAll(self._optimization_problem.GetListOfProcesses(process_type), *args, **kwargs)
|
|
71
|
+
|
|
72
|
+
def _InitializeIteration(self) -> None:
|
|
73
|
+
for process_type in self._optimization_problem.GetAvailableProcessTypes():
|
|
74
|
+
list(map(lambda x: x.ExecuteInitializeSolutionStep(), self._optimization_problem.GetListOfProcesses(process_type)))
|
|
75
|
+
|
|
76
|
+
def _FinalizeIteration(self) -> None:
|
|
77
|
+
for process_type in self._optimization_problem.GetAvailableProcessTypes():
|
|
78
|
+
list(map(lambda x: x.ExecuteFinalizeSolutionStep(), self._optimization_problem.GetListOfProcesses(process_type)))
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import KratosMultiphysics as Kratos
|
|
2
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
|
|
3
|
+
from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import time_decorator
|
|
4
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.algorithm_steepest_descent import AlgorithmSteepestDescent
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
8
|
+
return AlgorithmAdam(model, parameters, optimization_problem)
|
|
9
|
+
|
|
10
|
+
class AlgorithmAdam(AlgorithmSteepestDescent):
|
|
11
|
+
"""
|
|
12
|
+
Adam (Adaptive Moment Estimation) method to solve unconstrained optimization problems.
|
|
13
|
+
The implementation is based on https://arxiv.org/pdf/1412.6980
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def GetDefaultParameters(cls):
|
|
18
|
+
return Kratos.Parameters("""{
|
|
19
|
+
"module" : "KratosMultiphysics.OptimizationApplication.algorithms",
|
|
20
|
+
"type" : "PLEASE_PROVIDE_AN_ALGORITHM_CLASS_NAME",
|
|
21
|
+
"objective" : {},
|
|
22
|
+
"controls" : [],
|
|
23
|
+
"echo_level" : 0,
|
|
24
|
+
"settings" : {
|
|
25
|
+
"beta_1" : 0.9,
|
|
26
|
+
"beta_2" : 0.999,
|
|
27
|
+
"epsilon" : 1e-8,
|
|
28
|
+
"echo_level" : 0,
|
|
29
|
+
"line_search" : {},
|
|
30
|
+
"conv_settings" : {}
|
|
31
|
+
}
|
|
32
|
+
}""")
|
|
33
|
+
|
|
34
|
+
def __init__(self, model:Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
35
|
+
super().__init__(model, parameters, optimization_problem)
|
|
36
|
+
self.beta_1 = self.parameters["settings"]["beta_1"].GetDouble()
|
|
37
|
+
self.beta_2 = self.parameters["settings"]["beta_2"].GetDouble()
|
|
38
|
+
self.epsilon = self.parameters["settings"]["epsilon"].GetDouble()
|
|
39
|
+
self.prev_moment_1 = None
|
|
40
|
+
self.prev_moment_2 = None
|
|
41
|
+
|
|
42
|
+
@time_decorator()
|
|
43
|
+
def ComputeControlUpdate(self, alpha: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor):
|
|
44
|
+
search_direction: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor = self.algorithm_data.GetBufferedData()["search_direction"]
|
|
45
|
+
time_step = self._optimization_problem.GetStep() + 1
|
|
46
|
+
|
|
47
|
+
# update the biased first and second raw moment estimates
|
|
48
|
+
moment_1 = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(search_direction, perform_collect_data_recursively=False, perform_store_data_recursively=False)
|
|
49
|
+
moment_2 = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(search_direction, perform_collect_data_recursively=False, perform_store_data_recursively=False)
|
|
50
|
+
if self.prev_moment_1 and self.prev_moment_2:
|
|
51
|
+
moment_1.data[:] = self.prev_moment_1.data * self.beta_1 + search_direction.data * (1.0 - self.beta_1)
|
|
52
|
+
moment_2.data[:] = self.prev_moment_2.data * self.beta_2 + search_direction.data ** 2 * (1.0 - self.beta_2)
|
|
53
|
+
else:
|
|
54
|
+
moment_1.data[:] = search_direction.data * (1.0 - self.beta_1)
|
|
55
|
+
moment_2.data[:] = search_direction.data ** 2 * (1.0 - self.beta_2)
|
|
56
|
+
moment_1.StoreData()
|
|
57
|
+
moment_2.StoreData()
|
|
58
|
+
self.prev_moment_1 = moment_1
|
|
59
|
+
self.prev_moment_2 = moment_2
|
|
60
|
+
|
|
61
|
+
# bias correct the moment estimates and compute the control field update
|
|
62
|
+
moment_1_hat = moment_1.data / (1.0 - self.beta_1 ** time_step)
|
|
63
|
+
moment_2_hat = moment_2.data / (1.0 - self.beta_2 ** time_step)
|
|
64
|
+
|
|
65
|
+
control_field_update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(moment_2, perform_store_data_recursively=False)
|
|
66
|
+
control_field_update.data[:] = alpha.data * moment_1_hat / (moment_2_hat ** 0.5 + self.epsilon)
|
|
67
|
+
control_field_update.StoreData()
|
|
68
|
+
self.algorithm_data.GetBufferedData()["control_field_update"] = control_field_update
|