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.
Files changed (106) hide show
  1. KratosMultiphysics/.libs/KratosOptimizationApplication.so +0 -0
  2. KratosMultiphysics/.libs/libKratosOptimizationCore.dylib +0 -0
  3. KratosMultiphysics/OptimizationApplication/__init__.py +19 -0
  4. KratosMultiphysics/OptimizationApplication/algorithms/NLOPT_algorithms.py +255 -0
  5. KratosMultiphysics/OptimizationApplication/algorithms/SciPy_algorithms.py +154 -0
  6. KratosMultiphysics/OptimizationApplication/algorithms/__init__.py +0 -0
  7. KratosMultiphysics/OptimizationApplication/algorithms/algorithm.py +78 -0
  8. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_adam.py +68 -0
  9. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_base.py +393 -0
  10. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_gradient_projection.py +355 -0
  11. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_momentum_relaxed_gradient_projection.py +70 -0
  12. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_nesterov_accelarated_gradient.py +60 -0
  13. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_relaxed_gradient_projection.py +263 -0
  14. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_steepest_descent.py +205 -0
  15. KratosMultiphysics/OptimizationApplication/algorithms/standardized_NLOPT_constraint.py +194 -0
  16. KratosMultiphysics/OptimizationApplication/algorithms/standardized_NLOPT_objective.py +191 -0
  17. KratosMultiphysics/OptimizationApplication/algorithms/standardized_SciPy_constraint.py +123 -0
  18. KratosMultiphysics/OptimizationApplication/algorithms/standardized_SciPy_objective.py +148 -0
  19. KratosMultiphysics/OptimizationApplication/algorithms/standardized_constraint.py +180 -0
  20. KratosMultiphysics/OptimizationApplication/algorithms/standardized_objective.py +133 -0
  21. KratosMultiphysics/OptimizationApplication/algorithms/standardized_rgp_constraint.py +268 -0
  22. KratosMultiphysics/OptimizationApplication/analyses_controller.py +75 -0
  23. KratosMultiphysics/OptimizationApplication/controls/control.py +123 -0
  24. KratosMultiphysics/OptimizationApplication/controls/external_response_function_control.py +149 -0
  25. KratosMultiphysics/OptimizationApplication/controls/master_control.py +198 -0
  26. KratosMultiphysics/OptimizationApplication/controls/material/material_properties_control.py +115 -0
  27. KratosMultiphysics/OptimizationApplication/controls/material/simp_control.py +229 -0
  28. KratosMultiphysics/OptimizationApplication/controls/shape/vertex_morphing_shape_control.py +289 -0
  29. KratosMultiphysics/OptimizationApplication/controls/thickness/shell_thickness_control.py +180 -0
  30. KratosMultiphysics/OptimizationApplication/controls_controller.py +205 -0
  31. KratosMultiphysics/OptimizationApplication/convergence_criteria/avg_abs_improvement_conv_criterion.py +98 -0
  32. KratosMultiphysics/OptimizationApplication/convergence_criteria/combined_conv_criterion.py +87 -0
  33. KratosMultiphysics/OptimizationApplication/convergence_criteria/constraint_conv_criterion.py +68 -0
  34. KratosMultiphysics/OptimizationApplication/convergence_criteria/convergence_criterion.py +26 -0
  35. KratosMultiphysics/OptimizationApplication/convergence_criteria/l2_conv_criterion.py +77 -0
  36. KratosMultiphysics/OptimizationApplication/convergence_criteria/magnitude_reduction_conv_criterion.py +85 -0
  37. KratosMultiphysics/OptimizationApplication/convergence_criteria/max_iter_conv_criterion.py +48 -0
  38. KratosMultiphysics/OptimizationApplication/convergence_criteria/patience_conv_criterion.py +116 -0
  39. KratosMultiphysics/OptimizationApplication/convergence_criteria/target_value_conv_criterion.py +64 -0
  40. KratosMultiphysics/OptimizationApplication/execution_policies/execution_policy.py +46 -0
  41. KratosMultiphysics/OptimizationApplication/execution_policies/execution_policy_decorator.py +67 -0
  42. KratosMultiphysics/OptimizationApplication/execution_policies/independent_analysis_execution_policy.py +78 -0
  43. KratosMultiphysics/OptimizationApplication/execution_policies/kratos_analysis_execution_policy.py +137 -0
  44. KratosMultiphysics/OptimizationApplication/execution_policies/stepping_analysis_execution_policy.py +88 -0
  45. KratosMultiphysics/OptimizationApplication/filtering/explicit_filter.py +124 -0
  46. KratosMultiphysics/OptimizationApplication/filtering/filter.py +188 -0
  47. KratosMultiphysics/OptimizationApplication/filtering/filter_utils.py +55 -0
  48. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_analysis.py +139 -0
  49. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_scalar_solver.py +39 -0
  50. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_shape_solver.py +67 -0
  51. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_solver_base.py +275 -0
  52. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_vector_solver.py +39 -0
  53. KratosMultiphysics/OptimizationApplication/filtering/implicit_filter.py +192 -0
  54. KratosMultiphysics/OptimizationApplication/filtering/python_solvers_wrapper_implicit_filters.py +56 -0
  55. KratosMultiphysics/OptimizationApplication/model_part_controllers/connectivity_preserving_model_part_controller.py +72 -0
  56. KratosMultiphysics/OptimizationApplication/model_part_controllers/external_response_function_model_part_controller.py +110 -0
  57. KratosMultiphysics/OptimizationApplication/model_part_controllers/mdpa_model_part_controller.py +44 -0
  58. KratosMultiphysics/OptimizationApplication/model_part_controllers/model_part_controller.py +19 -0
  59. KratosMultiphysics/OptimizationApplication/model_parts_controller.py +92 -0
  60. KratosMultiphysics/OptimizationApplication/optimization_analysis.py +146 -0
  61. KratosMultiphysics/OptimizationApplication/optimizations_controller.py +223 -0
  62. KratosMultiphysics/OptimizationApplication/optimizer.py +61 -0
  63. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_ascii_output_process.py +212 -0
  64. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_field_output_process.py +122 -0
  65. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_graph_output_process.py +184 -0
  66. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_hdf5_output_process.py +84 -0
  67. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_vtu_output_process.py +94 -0
  68. KratosMultiphysics/OptimizationApplication/processes/spatial_statistics_computation_process.py +81 -0
  69. KratosMultiphysics/OptimizationApplication/responses/__init__.py +0 -0
  70. KratosMultiphysics/OptimizationApplication/responses/additive_manufacturing_responses.py +410 -0
  71. KratosMultiphysics/OptimizationApplication/responses/analysis_based_response_function_factory.py +14 -0
  72. KratosMultiphysics/OptimizationApplication/responses/analysis_free_response_function_factory.py +14 -0
  73. KratosMultiphysics/OptimizationApplication/responses/base_response.py +66 -0
  74. KratosMultiphysics/OptimizationApplication/responses/binary_operator_response_function.py +103 -0
  75. KratosMultiphysics/OptimizationApplication/responses/combined_response_function.py +127 -0
  76. KratosMultiphysics/OptimizationApplication/responses/discrete_value_residual_response_function.py +131 -0
  77. KratosMultiphysics/OptimizationApplication/responses/evaluation_response_function.py +68 -0
  78. KratosMultiphysics/OptimizationApplication/responses/external_response_function.py +87 -0
  79. KratosMultiphysics/OptimizationApplication/responses/geometric_centroid_deviation_response_function.py +97 -0
  80. KratosMultiphysics/OptimizationApplication/responses/linear_strain_energy_response_function.py +72 -0
  81. KratosMultiphysics/OptimizationApplication/responses/literal_value_response_function.py +33 -0
  82. KratosMultiphysics/OptimizationApplication/responses/log_response_function.py +47 -0
  83. KratosMultiphysics/OptimizationApplication/responses/mass_response_function.py +71 -0
  84. KratosMultiphysics/OptimizationApplication/responses/response_function.py +126 -0
  85. KratosMultiphysics/OptimizationApplication/responses/response_routine.py +158 -0
  86. KratosMultiphysics/OptimizationApplication/responses/structural_responses.py +335 -0
  87. KratosMultiphysics/OptimizationApplication/responses_controller.py +390 -0
  88. KratosMultiphysics/OptimizationApplication/utilities/buffered_dict.py +399 -0
  89. KratosMultiphysics/OptimizationApplication/utilities/component_data_view.py +74 -0
  90. KratosMultiphysics/OptimizationApplication/utilities/helper_utilities.py +40 -0
  91. KratosMultiphysics/OptimizationApplication/utilities/logger_utilities.py +222 -0
  92. KratosMultiphysics/OptimizationApplication/utilities/model_part_utilities.py +117 -0
  93. KratosMultiphysics/OptimizationApplication/utilities/opt_line_search.py +173 -0
  94. KratosMultiphysics/OptimizationApplication/utilities/opt_projection.py +191 -0
  95. KratosMultiphysics/OptimizationApplication/utilities/optimization_problem.py +237 -0
  96. KratosMultiphysics/OptimizationApplication/utilities/optimization_problem_utilities.py +237 -0
  97. KratosMultiphysics/OptimizationApplication/utilities/response_utilities.py +249 -0
  98. KratosMultiphysics/OptimizationApplication/utilities/timer.py +45 -0
  99. KratosMultiphysics/OptimizationApplication/utilities/union_utilities.py +6 -0
  100. kratosoptimizationapplication-10.4.4.dist-info/METADATA +25 -0
  101. kratosoptimizationapplication-10.4.4.dist-info/RECORD +106 -0
  102. kratosoptimizationapplication-10.4.4.dist-info/WHEEL +6 -0
  103. kratosoptimizationapplication.dylibs/libKratosCore.dylib +4 -0
  104. kratosoptimizationapplication.dylibs/libgcc_s.1.1.dylib +0 -0
  105. kratosoptimizationapplication.dylibs/libgomp.1.dylib +0 -0
  106. kratosoptimizationapplication.dylibs/libstdc++.6.dylib +0 -0
@@ -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
@@ -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