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
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import numpy
|
|
2
|
+
import KratosMultiphysics as Kratos
|
|
3
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
|
|
4
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.standardized_objective import StandardizedObjective
|
|
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.opt_line_search import CreateLineSearch
|
|
9
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.standardized_constraint import StandardizedConstraint
|
|
10
|
+
from KratosMultiphysics.LinearSolversApplication.dense_linear_solver_factory import ConstructSolver
|
|
11
|
+
from KratosMultiphysics.OptimizationApplication.utilities.helper_utilities import CallOnAll
|
|
12
|
+
from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import time_decorator
|
|
13
|
+
from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import OptimizationAlgorithmTimeLogger
|
|
14
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem_utilities import OutputGradientFields
|
|
15
|
+
from KratosMultiphysics.OptimizationApplication.convergence_criteria.convergence_criterion import ConvergenceCriterion
|
|
16
|
+
from KratosMultiphysics.OptimizationApplication.convergence_criteria.constraint_conv_criterion import ConstraintConvCriterion
|
|
17
|
+
from KratosMultiphysics.OptimizationApplication.convergence_criteria.combined_conv_criterion import CombinedConvCriterion
|
|
18
|
+
from KratosMultiphysics.OptimizationApplication.convergence_criteria.max_iter_conv_criterion import MaxIterConvCriterion
|
|
19
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem_utilities import OptimizationComponentFactory
|
|
20
|
+
from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import ListLogger
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
24
|
+
return AlgorithmGradientProjection(model, parameters, optimization_problem)
|
|
25
|
+
|
|
26
|
+
class AlgorithmGradientProjection(Algorithm):
|
|
27
|
+
"""
|
|
28
|
+
A classical steepest descent algorithm to solve unconstrained optimization problems.
|
|
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
|
+
"settings" : {
|
|
41
|
+
"echo_level" : 0,
|
|
42
|
+
"line_search" : {},
|
|
43
|
+
"conv_settings" : {},
|
|
44
|
+
"linear_solver_settings" : {},
|
|
45
|
+
"correction_size" : 0.0
|
|
46
|
+
}
|
|
47
|
+
}""")
|
|
48
|
+
|
|
49
|
+
def __init__(self, model:Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
50
|
+
self.model = model
|
|
51
|
+
self.parameters = parameters
|
|
52
|
+
self._optimization_problem = optimization_problem
|
|
53
|
+
parameters.ValidateAndAssignDefaults(self.GetDefaultParameters())
|
|
54
|
+
|
|
55
|
+
self.master_control = MasterControl() # Need to fill it with controls
|
|
56
|
+
self._optimization_problem.AddComponent(self.master_control)
|
|
57
|
+
|
|
58
|
+
for control_name in parameters["controls"].GetStringArray():
|
|
59
|
+
control = optimization_problem.GetControl(control_name)
|
|
60
|
+
self.master_control.AddControl(control)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
settings = parameters["settings"]
|
|
64
|
+
settings.ValidateAndAssignDefaults(self.GetDefaultParameters()["settings"])
|
|
65
|
+
|
|
66
|
+
self.echo_level = settings["echo_level"].GetInt()
|
|
67
|
+
|
|
68
|
+
ComponentDataView("algorithm", self._optimization_problem).SetDataBuffer(self.GetMinimumBufferSize())
|
|
69
|
+
|
|
70
|
+
self.__line_search_method = CreateLineSearch(settings["line_search"], self._optimization_problem)
|
|
71
|
+
|
|
72
|
+
self._objective = StandardizedObjective(parameters["objective"], self.master_control, self._optimization_problem)
|
|
73
|
+
self._optimization_problem.AddComponent(self._objective)
|
|
74
|
+
self._constraints_list: 'list[StandardizedConstraint]' = []
|
|
75
|
+
for constraint_param in parameters["constraints"].values():
|
|
76
|
+
constraint = StandardizedConstraint(constraint_param, self.master_control, self._optimization_problem)
|
|
77
|
+
self._optimization_problem.AddComponent(constraint)
|
|
78
|
+
self._constraints_list.append(constraint)
|
|
79
|
+
self._control_field = None
|
|
80
|
+
self._obj_val = None
|
|
81
|
+
|
|
82
|
+
self._convergence_criteria = self._CreateConvergenceCriteria(settings["conv_settings"])
|
|
83
|
+
|
|
84
|
+
default_linear_solver_settings = Kratos.Parameters("""{
|
|
85
|
+
"solver_type": "LinearSolversApplication.dense_col_piv_householder_qr"
|
|
86
|
+
}""")
|
|
87
|
+
settings["linear_solver_settings"].ValidateAndAssignDefaults(default_linear_solver_settings)
|
|
88
|
+
self.linear_solver = ConstructSolver(settings["linear_solver_settings"])
|
|
89
|
+
self.correction_size = settings["correction_size"].GetDouble()
|
|
90
|
+
|
|
91
|
+
def GetMinimumBufferSize(self) -> int:
|
|
92
|
+
return 2
|
|
93
|
+
|
|
94
|
+
def Check(self):
|
|
95
|
+
self.master_control.Check()
|
|
96
|
+
self._objective.Check()
|
|
97
|
+
CallOnAll(self._constraints_list, StandardizedConstraint.Check)
|
|
98
|
+
|
|
99
|
+
@time_decorator()
|
|
100
|
+
def Initialize(self):
|
|
101
|
+
self.converged = False
|
|
102
|
+
self._obj_val = None
|
|
103
|
+
self.master_control.Initialize()
|
|
104
|
+
self._objective.Initialize()
|
|
105
|
+
CallOnAll(self._constraints_list, StandardizedConstraint.Initialize)
|
|
106
|
+
self._control_field = self.master_control.GetControlField()
|
|
107
|
+
self.algorithm_data = ComponentDataView("algorithm", self._optimization_problem)
|
|
108
|
+
|
|
109
|
+
self._convergence_criteria.Initialize()
|
|
110
|
+
|
|
111
|
+
@time_decorator()
|
|
112
|
+
def Finalize(self):
|
|
113
|
+
self.master_control.Finalize()
|
|
114
|
+
self._objective.Finalize()
|
|
115
|
+
CallOnAll(self._constraints_list, StandardizedConstraint.Finalize)
|
|
116
|
+
|
|
117
|
+
self._convergence_criteria.Finalize()
|
|
118
|
+
|
|
119
|
+
@time_decorator()
|
|
120
|
+
def ComputeSearchDirection(self, obj_grad: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor, constr_grad: 'list[Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
|
|
121
|
+
active_constraints_list = [self._constraints_list[i] for i in range(len(self._constraints_list)) if self.__constr_value[i] >= 0.0]
|
|
122
|
+
number_of_active_constraints = len(active_constraints_list)
|
|
123
|
+
|
|
124
|
+
search_direction = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(obj_grad, perform_collect_data_recursively=False, perform_store_data_recursively=False)
|
|
125
|
+
correction = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(obj_grad, perform_collect_data_recursively=False, perform_store_data_recursively=False)
|
|
126
|
+
|
|
127
|
+
if not number_of_active_constraints:
|
|
128
|
+
search_direction.data[:] *= -1.0
|
|
129
|
+
correction.data[:] = 0.0
|
|
130
|
+
else:
|
|
131
|
+
constraint_violations = Kratos.Vector(number_of_active_constraints)
|
|
132
|
+
for i, active_constraint in enumerate(active_constraints_list):
|
|
133
|
+
constraint_violations[i] = active_constraint.GetScaledViolationValue()
|
|
134
|
+
|
|
135
|
+
# compute the projected search direction and correction
|
|
136
|
+
ntn = Kratos.Matrix(number_of_active_constraints, number_of_active_constraints)
|
|
137
|
+
for i in range(number_of_active_constraints):
|
|
138
|
+
for j in range(i, number_of_active_constraints):
|
|
139
|
+
ntn[i, j] = numpy.dot(constr_grad[i].data.ravel(), constr_grad[j].data.ravel())
|
|
140
|
+
ntn[j, i] = ntn[i, j]
|
|
141
|
+
|
|
142
|
+
# get the inverse of ntn
|
|
143
|
+
ntn_inverse = Kratos.Matrix(number_of_active_constraints, number_of_active_constraints)
|
|
144
|
+
|
|
145
|
+
# create the identity matrix
|
|
146
|
+
identity_matrix = Kratos.Matrix(number_of_active_constraints, number_of_active_constraints, 0.0)
|
|
147
|
+
for i in range(number_of_active_constraints):
|
|
148
|
+
identity_matrix[i, i] = 1.0
|
|
149
|
+
|
|
150
|
+
# solve for inverse of ntn
|
|
151
|
+
self.linear_solver.Solve(ntn, ntn_inverse, identity_matrix)
|
|
152
|
+
|
|
153
|
+
search_direction.data[:] = - (obj_grad.data[:] - self._CollectiveListVectorProduct(constr_grad, ntn_inverse * self._CollectiveListCollectiveProduct(constr_grad, obj_grad)).data)
|
|
154
|
+
correction.data[:] = - self._CollectiveListVectorProduct(constr_grad, ntn_inverse * constraint_violations).data
|
|
155
|
+
|
|
156
|
+
correction_norm = numpy.linalg.norm(correction.data.ravel())
|
|
157
|
+
if correction_norm > self.correction_size:
|
|
158
|
+
correction.data[:] *= self.correction_size / correction_norm
|
|
159
|
+
|
|
160
|
+
search_direction.StoreData()
|
|
161
|
+
correction.StoreData()
|
|
162
|
+
|
|
163
|
+
self.algorithm_data.GetBufferedData()["search_direction"] = search_direction
|
|
164
|
+
self.algorithm_data.GetBufferedData()["correction"] = correction
|
|
165
|
+
|
|
166
|
+
@time_decorator()
|
|
167
|
+
def ComputeControlUpdate(self, alpha: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor) -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
|
|
168
|
+
search_direction: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor = self.algorithm_data.GetBufferedData()["search_direction"]
|
|
169
|
+
update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(search_direction, perform_collect_data_recursively=False, perform_store_data_recursively=False)
|
|
170
|
+
update.data[:] = search_direction.data * alpha.data + self.algorithm_data.GetBufferedData()["correction"].data
|
|
171
|
+
Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(update, perform_store_data_recursively=False, copy=False).StoreData()
|
|
172
|
+
self.algorithm_data.GetBufferedData()["control_field_update"] = update
|
|
173
|
+
return update
|
|
174
|
+
|
|
175
|
+
@time_decorator()
|
|
176
|
+
def UpdateControl(self) -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
|
|
177
|
+
update: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor = self.algorithm_data.GetBufferedData()["control_field_update"]
|
|
178
|
+
self._control_field.data[:] += update.data
|
|
179
|
+
Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(self._control_field, perform_store_data_recursively=False, copy=False).StoreData()
|
|
180
|
+
|
|
181
|
+
@time_decorator()
|
|
182
|
+
def GetCurrentObjValue(self) -> float:
|
|
183
|
+
return self._obj_val
|
|
184
|
+
|
|
185
|
+
@time_decorator()
|
|
186
|
+
def GetCurrentControlField(self):
|
|
187
|
+
return self._control_field
|
|
188
|
+
|
|
189
|
+
@time_decorator()
|
|
190
|
+
def Output(self) -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
|
|
191
|
+
self.algorithm_data.GetBufferedData()["control_field"] = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(self._control_field)
|
|
192
|
+
OutputGradientFields(self._objective, self._optimization_problem, True)
|
|
193
|
+
for constraint in self._constraints_list:
|
|
194
|
+
OutputGradientFields(constraint, self._optimization_problem, constraint.IsActive())
|
|
195
|
+
for process in self._optimization_problem.GetListOfProcesses("output_processes"):
|
|
196
|
+
if process.IsOutputStep():
|
|
197
|
+
process.PrintOutput()
|
|
198
|
+
|
|
199
|
+
@time_decorator()
|
|
200
|
+
def Solve(self):
|
|
201
|
+
while not self.converged:
|
|
202
|
+
with OptimizationAlgorithmTimeLogger("Gradient Projection",self._optimization_problem.GetStep()):
|
|
203
|
+
self._InitializeIteration()
|
|
204
|
+
|
|
205
|
+
self._obj_val = self._objective.CalculateStandardizedValue(self._control_field)
|
|
206
|
+
obj_info = self._objective.GetInfo()
|
|
207
|
+
self.algorithm_data.GetBufferedData()["std_obj_value"] = obj_info["std_value"]
|
|
208
|
+
self.algorithm_data.GetBufferedData()["rel_change[%]"] = obj_info["rel_change [%]"]
|
|
209
|
+
if "abs_change [%]" in obj_info:
|
|
210
|
+
self.algorithm_data.GetBufferedData()["abs_change[%]"] = obj_info["abs_change [%]"]
|
|
211
|
+
|
|
212
|
+
obj_grad = self._objective.CalculateStandardizedGradient()
|
|
213
|
+
|
|
214
|
+
self.__constr_value = []
|
|
215
|
+
active_constr_grad = []
|
|
216
|
+
for constraint in self._constraints_list:
|
|
217
|
+
value = constraint.CalculateStandardizedValue(self._control_field)
|
|
218
|
+
self.__constr_value.append(value)
|
|
219
|
+
constr_name = constraint.GetResponseName()
|
|
220
|
+
self.algorithm_data.GetBufferedData()[f"std_constr_{constr_name}_value"] = value
|
|
221
|
+
if value >= 0.0:
|
|
222
|
+
active_constr_grad.append(constraint.CalculateStandardizedGradient())
|
|
223
|
+
|
|
224
|
+
self.ComputeSearchDirection(obj_grad, active_constr_grad)
|
|
225
|
+
|
|
226
|
+
alpha = self.__line_search_method.ComputeStep()
|
|
227
|
+
|
|
228
|
+
self.ComputeControlUpdate(alpha)
|
|
229
|
+
|
|
230
|
+
self._FinalizeIteration()
|
|
231
|
+
|
|
232
|
+
self.converged = self._convergence_criteria.IsConverged()
|
|
233
|
+
|
|
234
|
+
self.Output()
|
|
235
|
+
|
|
236
|
+
self.UpdateControl()
|
|
237
|
+
|
|
238
|
+
ListLogger("Convergence info", self._convergence_criteria.GetInfo())
|
|
239
|
+
|
|
240
|
+
if not self.converged:
|
|
241
|
+
self._optimization_problem.AdvanceStep()
|
|
242
|
+
|
|
243
|
+
return self.converged
|
|
244
|
+
|
|
245
|
+
def GetOptimizedObjectiveValue(self) -> float:
|
|
246
|
+
if self.converged:
|
|
247
|
+
return self._obj_val
|
|
248
|
+
else:
|
|
249
|
+
raise RuntimeError("Optimization problem hasn't been solved.")
|
|
250
|
+
|
|
251
|
+
def _CreateConvergenceCriteria(self, settings: Kratos.Parameters) -> ConvergenceCriterion:
|
|
252
|
+
"""
|
|
253
|
+
Here we create default constraint convergence criteria, if nothing
|
|
254
|
+
is defined in the "constraint_conv_settings".
|
|
255
|
+
|
|
256
|
+
"""
|
|
257
|
+
default_settings = Kratos.Parameters("""{
|
|
258
|
+
"max_iter" : 0,
|
|
259
|
+
"objective_conv_settings" : {},
|
|
260
|
+
"constraint_conv_settings": {}
|
|
261
|
+
}""")
|
|
262
|
+
|
|
263
|
+
if settings.Has("constraint_conv_settings") and settings["constraint_conv_settings"].IsString():
|
|
264
|
+
default_settings["constraint_conv_settings"].SetString("")
|
|
265
|
+
|
|
266
|
+
settings.ValidateAndAssignDefaults(default_settings)
|
|
267
|
+
|
|
268
|
+
default_additional_conv_params = Kratos.Parameters("""{
|
|
269
|
+
"type" : "",
|
|
270
|
+
"module" : "KratosMultiphysics.OptimizationApplication.convergence_criteria",
|
|
271
|
+
"settings": {}
|
|
272
|
+
}""")
|
|
273
|
+
|
|
274
|
+
max_iter_params = Kratos.Parameters("""{
|
|
275
|
+
"max_iter": """ + str(settings["max_iter"].GetInt()) + """
|
|
276
|
+
}""")
|
|
277
|
+
max_iter_conv_criterion = MaxIterConvCriterion(max_iter_params, self._optimization_problem)
|
|
278
|
+
|
|
279
|
+
and_conv_criteria: 'list[ConvergenceCriterion]' = []
|
|
280
|
+
if not settings["objective_conv_settings"].IsEquivalentTo(Kratos.Parameters("""{}""")):
|
|
281
|
+
# objective convergence criteria is given.
|
|
282
|
+
current_settings = settings["objective_conv_settings"]
|
|
283
|
+
current_settings.AddMissingParameters(default_additional_conv_params)
|
|
284
|
+
and_conv_criteria.append(OptimizationComponentFactory(self.model, current_settings, self._optimization_problem))
|
|
285
|
+
|
|
286
|
+
if settings["constraint_conv_settings"].IsSubParameter() and not settings["constraint_conv_settings"].IsEquivalentTo(Kratos.Parameters("""{}""")):
|
|
287
|
+
# constraint convergence criteria is given
|
|
288
|
+
current_settings = settings["constraint_conv_settings"]
|
|
289
|
+
current_settings.AddMissingParameters(default_additional_conv_params)
|
|
290
|
+
and_conv_criteria.append(OptimizationComponentFactory(self.model, current_settings, self._optimization_problem))
|
|
291
|
+
else:
|
|
292
|
+
if settings["constraint_conv_settings"].IsString():
|
|
293
|
+
if settings["constraint_conv_settings"].GetString() != "none":
|
|
294
|
+
raise RuntimeError("constraint_conv_settings can only be either \"none\" or sub-paramter.")
|
|
295
|
+
elif settings["constraint_conv_settings"].IsSubParameter():
|
|
296
|
+
# constraint convergence criteria is not given, so creating them here.
|
|
297
|
+
constraint_settings = Kratos.Parameters("""{
|
|
298
|
+
"component_name": ""
|
|
299
|
+
}""")
|
|
300
|
+
for constraint in self._constraints_list:
|
|
301
|
+
current_settings = constraint_settings.Clone()
|
|
302
|
+
current_settings["component_name"].SetString(f"response_function.{constraint.GetName()}")
|
|
303
|
+
and_conv_criteria.append(ConstraintConvCriterion(current_settings, self._optimization_problem))
|
|
304
|
+
|
|
305
|
+
if len(and_conv_criteria) == 0:
|
|
306
|
+
return max_iter_conv_criterion
|
|
307
|
+
elif len(and_conv_criteria) == 1:
|
|
308
|
+
# now create the combined one and return the combined one
|
|
309
|
+
combined_params = Kratos.Parameters("""{
|
|
310
|
+
"operator": "or"
|
|
311
|
+
}""")
|
|
312
|
+
combined_conv_criteria = CombinedConvCriterion(self.model, combined_params, self._optimization_problem)
|
|
313
|
+
combined_conv_criteria.Add(max_iter_conv_criterion)
|
|
314
|
+
combined_conv_criteria.Add(and_conv_criteria[0])
|
|
315
|
+
return combined_conv_criteria
|
|
316
|
+
else:
|
|
317
|
+
# create the "and" combined conv criterion first
|
|
318
|
+
combined_params = Kratos.Parameters("""{
|
|
319
|
+
"operator": "and"
|
|
320
|
+
}""")
|
|
321
|
+
and_combined_conv_criteria = CombinedConvCriterion(self.model, combined_params, self._optimization_problem)
|
|
322
|
+
for and_conv in and_conv_criteria:
|
|
323
|
+
and_combined_conv_criteria.Add(and_conv)
|
|
324
|
+
|
|
325
|
+
# now create the "or" combined conv criterion with the max_iter and the previous one
|
|
326
|
+
combined_params = Kratos.Parameters("""{
|
|
327
|
+
"operator": "or"
|
|
328
|
+
}""")
|
|
329
|
+
or_combined_conv_criteria = CombinedConvCriterion(self.model, combined_params, self._optimization_problem)
|
|
330
|
+
or_combined_conv_criteria.Add(max_iter_conv_criterion)
|
|
331
|
+
or_combined_conv_criteria.Add(and_combined_conv_criteria)
|
|
332
|
+
return or_combined_conv_criteria
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
@staticmethod
|
|
336
|
+
def _CollectiveListCollectiveProduct(collective_list: 'list[Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]', other_collective: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor) -> Kratos.Vector:
|
|
337
|
+
result = Kratos.Vector(len(collective_list))
|
|
338
|
+
for i, collective_list_item in enumerate(collective_list):
|
|
339
|
+
result[i] = numpy.dot(collective_list_item.data.ravel(), other_collective.data.ravel())
|
|
340
|
+
return result
|
|
341
|
+
|
|
342
|
+
@staticmethod
|
|
343
|
+
def _CollectiveListVectorProduct(collective_list: 'list[Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]', vector: Kratos.Vector) -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
|
|
344
|
+
if len(collective_list) != vector.Size():
|
|
345
|
+
raise RuntimeError(f"Collective list size and vector size mismatch. [ Collective list size = {len(collective_list)}, vector size = {vector.Size()}]")
|
|
346
|
+
if len(collective_list) == 0:
|
|
347
|
+
raise RuntimeError("Collective lists cannot be empty.")
|
|
348
|
+
|
|
349
|
+
result = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(collective_list[0], perform_collect_data_recursively=False, perform_store_data_recursively=False)
|
|
350
|
+
result.data[:] = 0.0
|
|
351
|
+
for i, collective_list_item in enumerate(collective_list):
|
|
352
|
+
result.data[:] += collective_list_item.data * vector[i]
|
|
353
|
+
|
|
354
|
+
result.StoreData()
|
|
355
|
+
return result
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import KratosMultiphysics as Kratos
|
|
2
|
+
import KratosMultiphysics.OptimizationApplication as KratosOA
|
|
3
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
|
|
4
|
+
from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import time_decorator
|
|
5
|
+
from KratosMultiphysics.OptimizationApplication.algorithms.algorithm_relaxed_gradient_projection import AlgorithmRelaxedGradientProjection
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
9
|
+
return AlgorithmMomentumRelaxedGradientProjection(model, parameters, optimization_problem)
|
|
10
|
+
|
|
11
|
+
class AlgorithmMomentumRelaxedGradientProjection(AlgorithmRelaxedGradientProjection):
|
|
12
|
+
"""
|
|
13
|
+
Nesterov Accelerated Gradient method to solve unconstrained optimization problems.
|
|
14
|
+
The implementation is based on https://paperswithcode.com/method/nesterov-accelerated-gradient
|
|
15
|
+
In current version to save one response evaluation, the f(x) is only calculated on the momentum points.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
@classmethod
|
|
19
|
+
def GetDefaultParameters(cls):
|
|
20
|
+
return Kratos.Parameters("""{
|
|
21
|
+
"module" : "KratosMultiphysics.OptimizationApplication.algorithms",
|
|
22
|
+
"type" : "PLEASE_PROVIDE_AN_ALGORITHM_CLASS_NAME",
|
|
23
|
+
"objective" : {},
|
|
24
|
+
"constraints" : [],
|
|
25
|
+
"controls" : [],
|
|
26
|
+
"echo_level" : 0,
|
|
27
|
+
"settings" : {
|
|
28
|
+
"echo_level" : 0,
|
|
29
|
+
"line_search" : {},
|
|
30
|
+
"conv_settings" : {},
|
|
31
|
+
"linear_solver_settings" : {},
|
|
32
|
+
"history_size" : 20,
|
|
33
|
+
"max_inner_iter" : 20,
|
|
34
|
+
"buffer_coeff_update_factor" : 0.1,
|
|
35
|
+
"eta" : 0.9
|
|
36
|
+
}
|
|
37
|
+
}""")
|
|
38
|
+
|
|
39
|
+
def __init__(self, model:Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
40
|
+
super().__init__(model, parameters, optimization_problem)
|
|
41
|
+
self.prev_update = None
|
|
42
|
+
self.eta = self.parameters["settings"]["eta"].GetDouble()
|
|
43
|
+
|
|
44
|
+
@time_decorator()
|
|
45
|
+
def ComputeControlUpdate(self, alpha: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor):
|
|
46
|
+
# compute the correction part from momentum point
|
|
47
|
+
search_direction: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor = self.algorithm_data.GetBufferedData()["search_direction"]
|
|
48
|
+
update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(search_direction, perform_store_data_recursively=False)
|
|
49
|
+
update.data[:] *= alpha.data
|
|
50
|
+
update.StoreData()
|
|
51
|
+
# add momentum to the correction update to compute new momentum point.
|
|
52
|
+
if self.prev_update:
|
|
53
|
+
mom_update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(update, perform_store_data_recursively=False)
|
|
54
|
+
mom_update.data[:] += self.prev_update.data * self.eta
|
|
55
|
+
mom_update.StoreData()
|
|
56
|
+
|
|
57
|
+
full_update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(update, perform_store_data_recursively=False)
|
|
58
|
+
full_update.data[:] += mom_update.data * self.eta
|
|
59
|
+
full_update.StoreData()
|
|
60
|
+
self.prev_update = mom_update
|
|
61
|
+
else:
|
|
62
|
+
full_update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(update, perform_store_data_recursively=False)
|
|
63
|
+
full_update.data[:] *= (1 + self.eta)
|
|
64
|
+
full_update.StoreData()
|
|
65
|
+
self.prev_update = update
|
|
66
|
+
|
|
67
|
+
self.algorithm_data.GetBufferedData().SetValue("control_field_update", full_update, overwrite=True)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
return full_update
|
KratosMultiphysics/OptimizationApplication/algorithms/algorithm_nesterov_accelarated_gradient.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
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 AlgorithmNesterovAcceleratedGradient(model, parameters, optimization_problem)
|
|
9
|
+
|
|
10
|
+
class AlgorithmNesterovAcceleratedGradient(AlgorithmSteepestDescent):
|
|
11
|
+
"""
|
|
12
|
+
Nesterov Accelerated Gradient method to solve unconstrained optimization problems.
|
|
13
|
+
The implementation is based on https://paperswithcode.com/method/nesterov-accelerated-gradient
|
|
14
|
+
In current version to save one response evaluation, the f(x) is only calculated on the momentum points.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def GetDefaultParameters(cls):
|
|
19
|
+
return Kratos.Parameters("""{
|
|
20
|
+
"module" : "KratosMultiphysics.OptimizationApplication.algorithms",
|
|
21
|
+
"type" : "PLEASE_PROVIDE_AN_ALGORITHM_CLASS_NAME",
|
|
22
|
+
"objective" : {},
|
|
23
|
+
"controls" : [],
|
|
24
|
+
"echo_level" : 0,
|
|
25
|
+
"settings" : {
|
|
26
|
+
"eta" : 0.9,
|
|
27
|
+
"echo_level" : 0,
|
|
28
|
+
"line_search" : {},
|
|
29
|
+
"conv_settings" : {}
|
|
30
|
+
}
|
|
31
|
+
}""")
|
|
32
|
+
|
|
33
|
+
def __init__(self, model:Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
|
|
34
|
+
super().__init__(model, parameters, optimization_problem)
|
|
35
|
+
self.prev_update = None
|
|
36
|
+
self.eta = self.parameters["settings"]["eta"].GetDouble()
|
|
37
|
+
|
|
38
|
+
@time_decorator()
|
|
39
|
+
def ComputeControlUpdate(self, alpha: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor):
|
|
40
|
+
# compute the correction part from momentum point
|
|
41
|
+
search_direction: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor = self.algorithm_data.GetBufferedData()["search_direction"]
|
|
42
|
+
update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(search_direction, perform_collect_data_recursively=False, perform_store_data_recursively=False)
|
|
43
|
+
update.data[:] *= alpha.data[:]
|
|
44
|
+
update.StoreData()
|
|
45
|
+
# add momentum to the correction update to compute new momentum point.
|
|
46
|
+
if self.prev_update:
|
|
47
|
+
mom_update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(update, perform_store_data_recursively=False)
|
|
48
|
+
mom_update.data[:] += self.prev_update.data * self.eta
|
|
49
|
+
mom_update.StoreData()
|
|
50
|
+
control_field_update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(mom_update, perform_store_data_recursively=False)
|
|
51
|
+
control_field_update.data[:] = update.data + mom_update.data * self.eta
|
|
52
|
+
control_field_update.StoreData()
|
|
53
|
+
self.algorithm_data.GetBufferedData()["control_field_update"] = control_field_update
|
|
54
|
+
self.prev_update = mom_update
|
|
55
|
+
else:
|
|
56
|
+
control_field_update = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(update, perform_store_data_recursively=False)
|
|
57
|
+
control_field_update.data[:] = update.data * (1 + self.eta)
|
|
58
|
+
control_field_update.StoreData()
|
|
59
|
+
self.algorithm_data.GetBufferedData()["control_field_update"] = control_field_update
|
|
60
|
+
self.prev_update = update
|