KratosShapeOptimizationApplication 10.4.2__2-cp38-cp38-win_amd64.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 (66) hide show
  1. KratosMultiphysics/.libs/KratosShapeOptimizationApplication.pyd +0 -0
  2. KratosMultiphysics/.libs/KratosShapeOptimizationCore.dll +0 -0
  3. KratosMultiphysics/.libs/KratosShapeOptimizationCore.lib +0 -0
  4. KratosMultiphysics/ShapeOptimizationApplication/TemplateMainKratosShapeOptimization.py +31 -0
  5. KratosMultiphysics/ShapeOptimizationApplication/__init__.py +19 -0
  6. KratosMultiphysics/ShapeOptimizationApplication/algorithms/__init__.py +0 -0
  7. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_base.py +31 -0
  8. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_bead_optimization.py +412 -0
  9. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_factory.py +62 -0
  10. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_gradient_projection.py +317 -0
  11. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_penalized_projection.py +225 -0
  12. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_relaxed_gradient_projection.py +580 -0
  13. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_shape_fraction_optimization.py +622 -0
  14. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_steepest_descent.py +255 -0
  15. KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_trust_region.py +657 -0
  16. KratosMultiphysics/ShapeOptimizationApplication/analyzers/__init__.py +0 -0
  17. KratosMultiphysics/ShapeOptimizationApplication/analyzers/analyzer_base.py +30 -0
  18. KratosMultiphysics/ShapeOptimizationApplication/analyzers/analyzer_empty.py +21 -0
  19. KratosMultiphysics/ShapeOptimizationApplication/analyzers/analyzer_factory.py +310 -0
  20. KratosMultiphysics/ShapeOptimizationApplication/analyzers/analyzer_internal.py +155 -0
  21. KratosMultiphysics/ShapeOptimizationApplication/communicator_factory.py +259 -0
  22. KratosMultiphysics/ShapeOptimizationApplication/custom_ios/__init__.py +0 -0
  23. KratosMultiphysics/ShapeOptimizationApplication/custom_ios/wrl_io.py +82 -0
  24. KratosMultiphysics/ShapeOptimizationApplication/custom_ios/wrl_reader.py +119 -0
  25. KratosMultiphysics/ShapeOptimizationApplication/loggers/__init__.py +0 -0
  26. KratosMultiphysics/ShapeOptimizationApplication/loggers/data_logger_factory.py +199 -0
  27. KratosMultiphysics/ShapeOptimizationApplication/loggers/design_logger_base.py +28 -0
  28. KratosMultiphysics/ShapeOptimizationApplication/loggers/design_logger_gid.py +112 -0
  29. KratosMultiphysics/ShapeOptimizationApplication/loggers/design_logger_unv.py +73 -0
  30. KratosMultiphysics/ShapeOptimizationApplication/loggers/design_logger_vtk.py +96 -0
  31. KratosMultiphysics/ShapeOptimizationApplication/loggers/sensitivity_heatmap_logger.py +91 -0
  32. KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_base.py +128 -0
  33. KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_bead_optimization.py +79 -0
  34. KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_gradient_projection.py +80 -0
  35. KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_penalized_projection.py +79 -0
  36. KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_relaxed_gradient_projection.py +108 -0
  37. KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_shape_fraction_optimization.py +92 -0
  38. KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_steepest_descent.py +64 -0
  39. KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_trust_region.py +100 -0
  40. KratosMultiphysics/ShapeOptimizationApplication/mapper_factory.py +100 -0
  41. KratosMultiphysics/ShapeOptimizationApplication/mapping/__init__.py +0 -0
  42. KratosMultiphysics/ShapeOptimizationApplication/mapping/in_plane_vertex_morphing_mapper.py +140 -0
  43. KratosMultiphysics/ShapeOptimizationApplication/mapping/sliding_vertex_morphing_mapper.py +378 -0
  44. KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/__init__.py +0 -0
  45. KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/mesh_controller_base.py +22 -0
  46. KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/mesh_controller_basic_updating.py +35 -0
  47. KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/mesh_controller_with_solver.py +237 -0
  48. KratosMultiphysics/ShapeOptimizationApplication/model_part_controller_factory.py +197 -0
  49. KratosMultiphysics/ShapeOptimizationApplication/optimizer_factory.py +235 -0
  50. KratosMultiphysics/ShapeOptimizationApplication/response_functions/__init__.py +0 -0
  51. KratosMultiphysics/ShapeOptimizationApplication/response_functions/airfoil_2d_responses.py +189 -0
  52. KratosMultiphysics/ShapeOptimizationApplication/response_functions/face_angle.py +140 -0
  53. KratosMultiphysics/ShapeOptimizationApplication/response_functions/mesh_based_packaging.py +70 -0
  54. KratosMultiphysics/ShapeOptimizationApplication/response_functions/packaging_response_base.py +156 -0
  55. KratosMultiphysics/ShapeOptimizationApplication/response_functions/plane_based_packaging.py +61 -0
  56. KratosMultiphysics/ShapeOptimizationApplication/response_functions/response_function_factory.py +40 -0
  57. KratosMultiphysics/ShapeOptimizationApplication/response_functions/surface_normal_shape_change.py +125 -0
  58. KratosMultiphysics/ShapeOptimizationApplication/response_functions/total_volume.py +56 -0
  59. KratosMultiphysics/ShapeOptimizationApplication/utilities/__init__.py +0 -0
  60. KratosMultiphysics/ShapeOptimizationApplication/utilities/custom_math.py +443 -0
  61. KratosMultiphysics/ShapeOptimizationApplication/utilities/custom_sensitivity_heatmap.py +235 -0
  62. KratosMultiphysics/ShapeOptimizationApplication/utilities/custom_timer.py +47 -0
  63. KratosMultiphysics/ShapeOptimizationApplication/utilities/custom_variable_utilities.py +54 -0
  64. kratosshapeoptimizationapplication-10.4.2.dist-info/METADATA +31 -0
  65. kratosshapeoptimizationapplication-10.4.2.dist-info/RECORD +66 -0
  66. kratosshapeoptimizationapplication-10.4.2.dist-info/WHEEL +5 -0
@@ -0,0 +1,31 @@
1
+ import KratosMultiphysics
2
+ from KratosMultiphysics.ShapeOptimizationApplication.optimizer_factory import Optimizer
3
+
4
+ import shutil
5
+ import os, time, datetime
6
+
7
+ if __name__ == "__main__":
8
+ from sys import argv
9
+
10
+ if len(argv) > 2:
11
+ err_msg = 'Too many input arguments!\n'
12
+ err_msg += 'Use this script in the following way:\n'
13
+ err_msg += '- With default ProjectParameters (read from "ProjectParameters.json"):\n'
14
+ err_msg += ' "python3 structural_mechanics_analysis.py"\n'
15
+ err_msg += '- With custom ProjectParameters:\n'
16
+ err_msg += ' "python3 structural_mechanics_analysis.py CustomProjectParameters.json"\n'
17
+ raise Exception(err_msg)
18
+
19
+ if len(argv) == 2: # ProjectParameters is being passed from outside
20
+ project_parameters_file_name = argv[1]
21
+ else: # using default name
22
+ project_parameters_file_name = "optimization_parameters.json"
23
+
24
+ with open(project_parameters_file_name,'r') as parameter_file:
25
+ parameters = KratosMultiphysics.Parameters(parameter_file.read())
26
+
27
+ model = KratosMultiphysics.Model()
28
+ # Create optimizer and perform optimization
29
+ optimizer = Optimizer(model, parameters["optimization_settings"])
30
+ optimizer.Optimize()
31
+ shutil.copyfile("optimization_parameters.json", "Optimization_Results/optimization_parameters.json")
@@ -0,0 +1,19 @@
1
+ # ==============================================================================
2
+ # KratosShapeOptimizationApplication
3
+ #
4
+ # License: BSD License
5
+ # license: ShapeOptimizationApplication/license.txt
6
+ #
7
+ # Main authors: Baumgaertner Daniel, https://github.com/dbaumgaertner
8
+ #
9
+ # ==============================================================================
10
+
11
+ # ------------------------------------------------------------------------------
12
+ # Imports
13
+ # ------------------------------------------------------------------------------
14
+ from KratosMultiphysics import _ImportApplication
15
+ from KratosShapeOptimizationApplication import *
16
+ application = KratosShapeOptimizationApplication()
17
+ application_name = "KratosShapeOptimizationApplication"
18
+
19
+ _ImportApplication(application, application_name)
@@ -0,0 +1,31 @@
1
+ # ==============================================================================
2
+ # KratosShapeOptimizationApplication
3
+ #
4
+ # License: BSD License
5
+ # license: ShapeOptimizationApplication/license.txt
6
+ #
7
+ # Main authors: Baumgaertner Daniel, https://github.com/dbaumgaertner
8
+ # Geiser Armin, https://github.com/armingeiser
9
+ #
10
+ # ==============================================================================
11
+
12
+
13
+ # ==============================================================================
14
+ class OptimizationAlgorithm:
15
+ # --------------------------------------------------------------------------
16
+ def CheckApplicability( self ):
17
+ raise RuntimeError("Algorithm base class is called. Please check your implementation of the function >> CheckApplicability << .")
18
+
19
+ # --------------------------------------------------------------------------
20
+ def InitializeOptimizationLoop( self ):
21
+ raise RuntimeError("Algorithm base class is called. Please check your implementation of the function >> InitializeOptimizationLoop << .")
22
+
23
+ # --------------------------------------------------------------------------
24
+ def RunOptimizationLoop( self ):
25
+ raise RuntimeError("Algorithm base class is called. Please check your implementation of the function >> RunOptimizationLoop << .")
26
+
27
+ # --------------------------------------------------------------------------
28
+ def FinalizeOptimizationLoop( self ):
29
+ raise RuntimeError("Algorithm base class is called. Please check your implementation of the function >> FinalizeOptimizationLoop << .")
30
+
31
+ # ==============================================================================
@@ -0,0 +1,412 @@
1
+ # ==============================================================================
2
+ # KratosShapeOptimizationApplication
3
+ #
4
+ # License: BSD License
5
+ # license: ShapeOptimizationApplication/license.txt
6
+ #
7
+ # Main authors: Baumgaertner Daniel, https://github.com/dbaumgaertner
8
+ # Geiser Armin, https://github.com/armingeiser
9
+ #
10
+ # ==============================================================================
11
+
12
+
13
+ # Kratos Core and Apps
14
+ import KratosMultiphysics as KM
15
+ import KratosMultiphysics.ShapeOptimizationApplication as KSO
16
+
17
+ # Additional imports
18
+ from KratosMultiphysics.ShapeOptimizationApplication.algorithms.algorithm_base import OptimizationAlgorithm
19
+ from KratosMultiphysics.ShapeOptimizationApplication import mapper_factory
20
+ from KratosMultiphysics.ShapeOptimizationApplication.loggers import data_logger_factory
21
+ from KratosMultiphysics.ShapeOptimizationApplication.utilities.custom_timer import Timer
22
+ from KratosMultiphysics.ShapeOptimizationApplication.utilities.custom_variable_utilities import WriteDictionaryDataOnNodalVariable
23
+ import math
24
+
25
+ # ==============================================================================
26
+ class AlgorithmBeadOptimization(OptimizationAlgorithm):
27
+ # --------------------------------------------------------------------------
28
+ def __init__(self, optimization_settings, analyzer, communicator, model_part_controller):
29
+ default_algorithm_settings = KM.Parameters("""
30
+ {
31
+ "name" : "bead_optimization",
32
+ "bead_height" : 1.0,
33
+ "bead_direction" : [],
34
+ "bead_side" : "both",
35
+ "fix_boundaries" : [],
36
+ "estimated_lagrange_multiplier" : 1.0,
37
+ "max_total_iterations" : 10000,
38
+ "max_outer_iterations" : 10000,
39
+ "max_inner_iterations" : 30,
40
+ "min_inner_iterations" : 3,
41
+ "inner_iteration_tolerance" : 1e-3,
42
+ "line_search" : {
43
+ "line_search_type" : "manual_stepping",
44
+ "normalize_search_direction" : true,
45
+ "step_size" : 1.0
46
+ },
47
+ "filter_penalty_term" : false,
48
+ "penalty_filter_radius" : -1.0
49
+ }""")
50
+ self.algorithm_settings = optimization_settings["optimization_algorithm"]
51
+ self.algorithm_settings.RecursivelyValidateAndAssignDefaults(default_algorithm_settings)
52
+
53
+ self.optimization_settings = optimization_settings
54
+ self.mapper_settings = optimization_settings["design_variables"]["filter"]
55
+
56
+ if self.algorithm_settings["filter_penalty_term"].GetBool():
57
+ if self.algorithm_settings["penalty_filter_radius"].GetDouble() == -1.0:
58
+ raise RuntimeError("The parameter `penalty_filter_radius` is missing in order to filter the penalty term!")
59
+
60
+ self.analyzer = analyzer
61
+ self.communicator = communicator
62
+ self.model_part_controller = model_part_controller
63
+
64
+ self.design_surface = None
65
+ self.mapper = None
66
+ self.penalty_filter = None
67
+ self.data_logger = None
68
+ self.optimization_utilities = None
69
+
70
+ self.objectives = optimization_settings["objectives"]
71
+ self.constraints = optimization_settings["constraints"]
72
+
73
+ self.bead_height = self.algorithm_settings["bead_height"].GetDouble()
74
+ self.bead_side = self.algorithm_settings["bead_side"].GetString()
75
+ self.filter_penalty_term = self.algorithm_settings["filter_penalty_term"].GetBool()
76
+ self.estimated_lagrange_multiplier = self.algorithm_settings["estimated_lagrange_multiplier"].GetDouble()
77
+ self.max_total_iterations = self.algorithm_settings["max_total_iterations"].GetInt()
78
+ self.max_outer_iterations = self.algorithm_settings["max_outer_iterations"].GetInt()
79
+ self.max_inner_iterations = self.algorithm_settings["max_inner_iterations"].GetInt()
80
+ self.min_inner_iterations = self.algorithm_settings["min_inner_iterations"].GetInt()
81
+ self.inner_iteration_tolerance = self.algorithm_settings["inner_iteration_tolerance"].GetDouble()
82
+ self.step_size = self.algorithm_settings["line_search"]["step_size"].GetDouble()
83
+
84
+ self.lower_bound = None
85
+ self.upper_bound = None
86
+
87
+ self.lambda0 = 0.0
88
+ self.penalty_scaling_0 = 1.0
89
+ self.penalty_factor_0 = 1.0
90
+
91
+ self.optimization_model_part = model_part_controller.GetOptimizationModelPart()
92
+ self.optimization_model_part.AddNodalSolutionStepVariable(KSO.ALPHA)
93
+ self.optimization_model_part.AddNodalSolutionStepVariable(KSO.ALPHA_MAPPED)
94
+ self.optimization_model_part.AddNodalSolutionStepVariable(KSO.DF1DALPHA)
95
+ self.optimization_model_part.AddNodalSolutionStepVariable(KSO.DF1DALPHA_MAPPED)
96
+ self.optimization_model_part.AddNodalSolutionStepVariable(KSO.DPDALPHA)
97
+ self.optimization_model_part.AddNodalSolutionStepVariable(KSO.DPDALPHA_MAPPED)
98
+ self.optimization_model_part.AddNodalSolutionStepVariable(KSO.DLDALPHA)
99
+
100
+ # --------------------------------------------------------------------------
101
+ def CheckApplicability(self):
102
+ if self.objectives.size() > 1:
103
+ raise RuntimeError("The augmented lagrange algorithm for bead optimization only supports one objective function!")
104
+ if self.constraints.size() > 0:
105
+ raise RuntimeError("The augmented lagrange algorithm for bead does not allow for any constraints!")
106
+
107
+ # --------------------------------------------------------------------------
108
+ def InitializeOptimizationLoop(self):
109
+ self.model_part_controller.Initialize()
110
+ self.model_part_controller.SetMinimalBufferSize(2)
111
+
112
+ self.analyzer.InitializeBeforeOptimizationLoop()
113
+
114
+ self.design_surface = self.model_part_controller.GetDesignSurface()
115
+
116
+ self.mapper = mapper_factory.CreateMapper(self.design_surface, self.design_surface, self.mapper_settings)
117
+ self.mapper.Initialize()
118
+ self.model_part_controller.InitializeDamping()
119
+
120
+ if self.filter_penalty_term:
121
+ penalty_filter_radius = self.algorithm_settings["penalty_filter_radius"].GetDouble()
122
+ filter_radius = self.mapper_settings["filter_radius"].GetDouble()
123
+ if abs(filter_radius - penalty_filter_radius) > 1e-9:
124
+ penalty_filter_settings = self.mapper_settings.Clone()
125
+ penalty_filter_settings["filter_radius"].SetDouble(self.algorithm_settings["penalty_filter_radius"].GetDouble())
126
+ self.penalty_filter = mapper_factory.CreateMapper(self.design_surface, self.design_surface, penalty_filter_settings)
127
+ self.penalty_filter.Initialize()
128
+ else:
129
+ self.penalty_filter = self.mapper
130
+
131
+ self.data_logger = data_logger_factory.CreateDataLogger(self.model_part_controller, self.communicator, self.optimization_settings)
132
+ self.data_logger.InitializeDataLogging()
133
+
134
+ self.optimization_utilities = KSO.OptimizationUtilities
135
+
136
+ # Identify fixed design areas
137
+ KM.VariableUtils().SetFlag(KM.BOUNDARY, False, self.optimization_model_part.Nodes)
138
+
139
+ radius = self.mapper_settings["filter_radius"].GetDouble()
140
+ search_based_functions = KSO.SearchBasedFunctions(self.design_surface)
141
+
142
+ for itr in range(self.algorithm_settings["fix_boundaries"].size()):
143
+ sub_model_part_name = self.algorithm_settings["fix_boundaries"][itr].GetString()
144
+ node_set = self.optimization_model_part.GetSubModelPart(sub_model_part_name).Nodes
145
+ search_based_functions.FlagNodesInRadius(node_set, KM.BOUNDARY, radius)
146
+
147
+ # Specify bounds and assign starting values for ALPHA
148
+ if self.bead_side == "positive":
149
+ KM.VariableUtils().SetScalarVar(KSO.ALPHA, 0.5, self.design_surface.Nodes, KM.BOUNDARY, False)
150
+ self.lower_bound = 0.0
151
+ self.upper_bound = 1.0
152
+ elif self.bead_side == "negative":
153
+ KM.VariableUtils().SetScalarVar(KSO.ALPHA, -0.5, self.design_surface.Nodes, KM.BOUNDARY, False)
154
+ self.lower_bound = -1.0
155
+ self.upper_bound = 0.0
156
+ elif self.bead_side == "both":
157
+ KM.VariableUtils().SetScalarVar(KSO.ALPHA, 0.0, self.design_surface.Nodes, KM.BOUNDARY, False)
158
+ self.lower_bound = -1.0
159
+ self.upper_bound = 1.0
160
+ else:
161
+ raise RuntimeError("Specified bead direction mode not supported!")
162
+
163
+ # Initialize ALPHA_MAPPED according to initial ALPHA values
164
+ self.mapper.Map(KSO.ALPHA, KSO.ALPHA_MAPPED)
165
+
166
+ # Specify bead direction
167
+ bead_direction = self.algorithm_settings["bead_direction"].GetVector()
168
+ if len(bead_direction) == 0:
169
+ self.model_part_controller.ComputeUnitSurfaceNormals()
170
+ for node in self.design_surface.Nodes:
171
+ normalized_normal = node.GetSolutionStepValue(KSO.NORMALIZED_SURFACE_NORMAL)
172
+ node.SetValue(KSO.BEAD_DIRECTION,normalized_normal)
173
+
174
+ elif len(bead_direction) == 3:
175
+ norm = math.sqrt(bead_direction[0]**2 + bead_direction[1]**2 + bead_direction[2]**2)
176
+ normalized_bead_direction = [value/norm for value in bead_direction]
177
+ KM.VariableUtils().SetNonHistoricalVectorVar(KSO.BEAD_DIRECTION, normalized_bead_direction, self.design_surface.Nodes)
178
+ else:
179
+ raise RuntimeError("Wrong definition of bead direction. Options are: 1) [] -> takes surface normal, 2) [x.x,x.x,x.x] -> takes specified vector.")
180
+
181
+ # --------------------------------------------------------------------------
182
+ def RunOptimizationLoop(self):
183
+ timer = Timer()
184
+ timer.StartTimer()
185
+
186
+ current_lambda = self.lambda0
187
+ penalty_scaling = self.penalty_scaling_0
188
+ penalty_factor = self.penalty_factor_0
189
+
190
+ total_iteration = 0
191
+ is_design_converged = False
192
+ is_max_total_iterations_reached = False
193
+ previos_L = None
194
+
195
+ for outer_iteration in range(1,self.max_outer_iterations+1):
196
+ for inner_iteration in range(1,self.max_inner_iterations+1):
197
+
198
+ total_iteration += 1
199
+ timer.StartNewLap()
200
+
201
+ KM.Logger.Print("=======================================================================================")
202
+ KM.Logger.PrintInfo("ShapeOpt", timer.GetTimeStamp(), ": Starting iteration ",outer_iteration,".",inner_iteration,".",total_iteration,"(outer . inner . total)")
203
+ KM.Logger.Print("=======================================================================================\n")
204
+
205
+ # Initialize new shape
206
+ self.model_part_controller.UpdateTimeStep(total_iteration)
207
+
208
+ for node in self.design_surface.Nodes:
209
+ new_shape_change = node.GetSolutionStepValue(KSO.ALPHA_MAPPED) * node.GetValue(KSO.BEAD_DIRECTION) * self.bead_height
210
+ node.SetSolutionStepValue(KSO.SHAPE_CHANGE, new_shape_change)
211
+
212
+ self.model_part_controller.DampNodalUpdateVariableIfSpecified(KSO.SHAPE_CHANGE)
213
+
214
+ for node in self.design_surface.Nodes:
215
+ shape_update = node.GetSolutionStepValue(KSO.SHAPE_CHANGE,0) - node.GetSolutionStepValue(KSO.SHAPE_CHANGE,1)
216
+ node.SetSolutionStepValue(KSO.SHAPE_UPDATE, shape_update)
217
+
218
+ self.model_part_controller.UpdateMeshAccordingInputVariable(KSO.SHAPE_UPDATE)
219
+ self.model_part_controller.SetReferenceMeshToMesh()
220
+
221
+ # Analyze shape
222
+ self.communicator.initializeCommunication()
223
+ self.communicator.requestValueOf(self.objectives[0]["identifier"].GetString())
224
+ self.communicator.requestGradientOf(self.objectives[0]["identifier"].GetString())
225
+
226
+ self.analyzer.AnalyzeDesignAndReportToCommunicator(self.optimization_model_part, total_iteration, self.communicator)
227
+
228
+ objective_value = self.communicator.getStandardizedValue(self.objectives[0]["identifier"].GetString())
229
+ objGradientDict = self.communicator.getStandardizedGradient(self.objectives[0]["identifier"].GetString())
230
+ WriteDictionaryDataOnNodalVariable(objGradientDict, self.optimization_model_part, KSO.DF1DX)
231
+
232
+ self.model_part_controller.DampNodalSensitivityVariableIfSpecified(KSO.DF1DX)
233
+
234
+ # Compute sensitivities w.r.t. scalar design variable alpha
235
+ for node in self.design_surface.Nodes:
236
+ raw_gradient = node.GetSolutionStepValue(KSO.DF1DX)
237
+ bead_dir = node.GetValue(KSO.BEAD_DIRECTION)
238
+
239
+ dF1dalpha_i = self.bead_height*(raw_gradient[0]*bead_dir[0] + raw_gradient[1]*bead_dir[1] + raw_gradient[2]*bead_dir[2])
240
+ node.SetSolutionStepValue(KSO.DF1DALPHA, dF1dalpha_i)
241
+
242
+ # Map gradient of objective
243
+ self.mapper.InverseMap(KSO.DF1DALPHA, KSO.DF1DALPHA_MAPPED)
244
+
245
+ # Compute scaling
246
+ max_norm_objective_gradient = self.optimization_utilities.ComputeMaxNormOfNodalVariable(self.design_surface, KSO.DF1DALPHA_MAPPED)
247
+
248
+ if outer_iteration == 1 and inner_iteration == min(3,self.max_inner_iterations):
249
+ if self.bead_side == "positive" or self.bead_side == "negative":
250
+ max_norm_penalty_gradient = 1.0
251
+ elif self.bead_side == "both":
252
+ max_norm_penalty_gradient = 2.0
253
+
254
+ penalty_scaling = max_norm_objective_gradient/max_norm_penalty_gradient
255
+
256
+ # Compute penalization term
257
+ penalty_value = 0.0
258
+ if self.bead_side == "positive":
259
+ for node in self.design_surface.Nodes:
260
+ if not node.Is(KM.BOUNDARY):
261
+ alpha_i = node.GetSolutionStepValue(KSO.ALPHA)
262
+ penalty_value += penalty_scaling*(alpha_i-alpha_i**2)
263
+
264
+ penalty_gradient_i = penalty_scaling*(1-2*alpha_i)
265
+ node.SetSolutionStepValue(KSO.DPDALPHA, penalty_gradient_i)
266
+
267
+ elif self.bead_side == "negative":
268
+ for node in self.design_surface.Nodes:
269
+ if not node.Is(KM.BOUNDARY):
270
+ alpha_i = node.GetSolutionStepValue(KSO.ALPHA)
271
+ penalty_value += penalty_scaling*(-alpha_i-alpha_i**2)
272
+
273
+ penalty_gradient_i = penalty_scaling*(-1-2*alpha_i)
274
+ node.SetSolutionStepValue(KSO.DPDALPHA, penalty_gradient_i)
275
+
276
+ elif self.bead_side == "both":
277
+ for node in self.design_surface.Nodes:
278
+ if not node.Is(KM.BOUNDARY):
279
+ alpha_i = node.GetSolutionStepValue(KSO.ALPHA)
280
+ penalty_value += penalty_scaling*(-alpha_i**2+1)
281
+
282
+ penalty_gradient_i = penalty_scaling*(-2*alpha_i)
283
+ node.SetSolutionStepValue(KSO.DPDALPHA, penalty_gradient_i)
284
+
285
+ # Filter penalty term if specified
286
+ if self.filter_penalty_term:
287
+ self.penalty_filter.InverseMap(KSO.DPDALPHA, KSO.DPDALPHA_MAPPED)
288
+
289
+ # Compute value of Lagrange function
290
+ L = objective_value + current_lambda*penalty_value + 0.5*penalty_factor*penalty_value**2
291
+ if inner_iteration == 1:
292
+ dL_relative = 0.0
293
+ else:
294
+ dL_relative = 100*(L/previos_L-1)
295
+
296
+ # Compute gradient of Lagrange function
297
+ if self.filter_penalty_term:
298
+ penalty_gradient_variable = KSO.DPDALPHA_MAPPED
299
+ else:
300
+ penalty_gradient_variable = KSO.DPDALPHA
301
+ for node in self.design_surface.Nodes:
302
+ dLdalpha_i = node.GetSolutionStepValue(KSO.DF1DALPHA_MAPPED) + current_lambda*node.GetSolutionStepValue(penalty_gradient_variable)
303
+ node.SetSolutionStepValue(KSO.DLDALPHA, dLdalpha_i)
304
+
305
+ # Normalization using infinity norm
306
+ dLdalpha_for_normalization = {}
307
+ for node in self.design_surface.Nodes:
308
+ nodal_alpha = node.GetSolutionStepValue(KSO.ALPHA)
309
+ if nodal_alpha==self.lower_bound or nodal_alpha==self.upper_bound or node.Is(KM.BOUNDARY):
310
+ dLdalpha_for_normalization[node.Id] = 0.0
311
+ else:
312
+ dLdalpha_for_normalization[node.Id] = node.GetSolutionStepValue(KSO.DLDALPHA)**2
313
+
314
+ max_value = math.sqrt(max(dLdalpha_for_normalization.values()))
315
+ if max_value == 0.0:
316
+ max_value = 1.0
317
+
318
+ # Compute updated design variable
319
+ for node in self.design_surface.Nodes:
320
+ dalpha = -self.step_size*node.GetSolutionStepValue(KSO.DLDALPHA)/max_value
321
+ alpha_new = node.GetSolutionStepValue(KSO.ALPHA) + dalpha
322
+
323
+ # Enforce bounds
324
+ alpha_new = max(alpha_new, self.lower_bound)
325
+ alpha_new = min(alpha_new, self.upper_bound)
326
+
327
+ # Enforce constraints
328
+ if node.Is(KM.BOUNDARY):
329
+ alpha_new = 0.0
330
+
331
+ node.SetSolutionStepValue(KSO.ALPHA,alpha_new)
332
+
333
+ alpha_new_vectorized = alpha_new * node.GetValue(KSO.BEAD_DIRECTION)
334
+ node.SetSolutionStepValue(KSO.CONTROL_POINT_CHANGE,alpha_new_vectorized)
335
+
336
+ # Map design variables
337
+ self.mapper.Map(KSO.ALPHA, KSO.ALPHA_MAPPED)
338
+
339
+ # Log current optimization step and store values for next iteration
340
+ additional_values_to_log = {}
341
+ additional_values_to_log["step_size"] = self.algorithm_settings["line_search"]["step_size"].GetDouble()
342
+ additional_values_to_log["outer_iteration"] = outer_iteration
343
+ additional_values_to_log["inner_iteration"] = inner_iteration
344
+ additional_values_to_log["lagrange_value"] = L
345
+ additional_values_to_log["lagrange_value_relative_change"] = dL_relative
346
+ additional_values_to_log["penalty_value"] = penalty_value
347
+ additional_values_to_log["penalty_lambda"] = current_lambda
348
+ additional_values_to_log["penalty_scaling"] = penalty_scaling
349
+ additional_values_to_log["penalty_factor"] = penalty_factor
350
+ additional_values_to_log["max_norm_objective_gradient"] = max_norm_objective_gradient
351
+
352
+ self.data_logger.LogSensitivityHeatmap(total_iteration, self.mapper)
353
+ self.data_logger.LogCurrentValues(total_iteration, additional_values_to_log)
354
+ self.data_logger.LogCurrentDesign(total_iteration)
355
+
356
+ previos_L = L
357
+
358
+ # Convergence check of inner loop
359
+ if total_iteration == self.max_total_iterations:
360
+ is_max_total_iterations_reached = True
361
+ break
362
+
363
+ if inner_iteration >= self.min_inner_iterations and inner_iteration >1:
364
+ # In the first outer iteration, the constraint is not yet active and properly scaled. Therefore, the objective is used to check the relative improvement
365
+ if outer_iteration == 1:
366
+ if abs(self.data_logger.GetValues("rel_change_objective")[total_iteration]) < self.inner_iteration_tolerance:
367
+ break
368
+ else:
369
+ if abs(dL_relative) < self.inner_iteration_tolerance:
370
+ break
371
+
372
+ if penalty_value == 0.0:
373
+ is_design_converged = True
374
+ break
375
+
376
+ KM.Logger.Print("")
377
+ KM.Logger.PrintInfo("ShapeOpt", "Time needed for current optimization step = ", timer.GetLapTime(), "s")
378
+ KM.Logger.PrintInfo("ShapeOpt", "Time needed for total optimization so far = ", timer.GetTotalTime(), "s")
379
+
380
+ # Compute penalty factor such that estimated Lagrange multiplier is obtained
381
+ if outer_iteration==1:
382
+ penalty_factor = self.estimated_lagrange_multiplier/penalty_value
383
+
384
+ # Update lambda
385
+ current_lambda = current_lambda + penalty_factor*penalty_value
386
+
387
+ KM.Logger.Print("")
388
+ KM.Logger.PrintInfo("ShapeOpt", "Time needed for current optimization step = ", timer.GetLapTime(), "s")
389
+ KM.Logger.PrintInfo("ShapeOpt", "Time needed for total optimization so far = ", timer.GetTotalTime(), "s")
390
+
391
+ # Check convergence of outer loop
392
+ if outer_iteration == self.max_outer_iterations:
393
+ KM.Logger.Print("")
394
+ KM.Logger.PrintInfo("ShapeOpt", "Maximal outer iterations of optimization problem reached!")
395
+ break
396
+
397
+ if is_max_total_iterations_reached:
398
+ KM.Logger.Print("")
399
+ KM.Logger.PrintInfo("ShapeOpt", "Maximal total iterations of optimization problem reached!")
400
+ break
401
+
402
+ if is_design_converged:
403
+ KM.Logger.Print("")
404
+ KM.Logger.PrintInfo("ShapeOpt", "Update of design variables is zero. Optimization converged!")
405
+ break
406
+
407
+ # --------------------------------------------------------------------------
408
+ def FinalizeOptimizationLoop(self):
409
+ self.data_logger.FinalizeDataLogging()
410
+ self.analyzer.FinalizeAfterOptimizationLoop()
411
+
412
+ # ==============================================================================
@@ -0,0 +1,62 @@
1
+ # ==============================================================================
2
+ # KratosShapeOptimizationApplication
3
+ #
4
+ # License: BSD License
5
+ # license: ShapeOptimizationApplication/license.txt
6
+ #
7
+ # Main authors: Baumgaertner Daniel, https://github.com/dbaumgaertner
8
+ #
9
+ # ==============================================================================
10
+
11
+
12
+
13
+ # ==============================================================================
14
+ def CreateOptimizationAlgorithm(optimization_settings, analyzer, communicator, model_part_controller):
15
+ algorithm_name = optimization_settings["optimization_algorithm"]["name"].GetString()
16
+
17
+ if algorithm_name == "steepest_descent":
18
+ from .algorithm_steepest_descent import AlgorithmSteepestDescent
19
+ return AlgorithmSteepestDescent(optimization_settings,
20
+ analyzer,
21
+ communicator,
22
+ model_part_controller)
23
+ elif algorithm_name == "gradient_projection":
24
+ from .algorithm_gradient_projection import AlgorithmGradientProjection
25
+ return AlgorithmGradientProjection(optimization_settings,
26
+ analyzer,
27
+ communicator,
28
+ model_part_controller)
29
+ elif algorithm_name == "penalized_projection":
30
+ from .algorithm_penalized_projection import AlgorithmPenalizedProjection
31
+ return AlgorithmPenalizedProjection(optimization_settings,
32
+ analyzer,
33
+ communicator,
34
+ model_part_controller)
35
+ elif algorithm_name == "trust_region":
36
+ from .algorithm_trust_region import AlgorithmTrustRegion
37
+ return AlgorithmTrustRegion(optimization_settings,
38
+ analyzer,
39
+ communicator,
40
+ model_part_controller)
41
+ elif algorithm_name == "bead_optimization":
42
+ from .algorithm_bead_optimization import AlgorithmBeadOptimization
43
+ return AlgorithmBeadOptimization(optimization_settings,
44
+ analyzer,
45
+ communicator,
46
+ model_part_controller)
47
+ elif algorithm_name == "relaxed_gradient_projection":
48
+ from .algorithm_relaxed_gradient_projection import AlgorithmRelaxedGradientProjection
49
+ return AlgorithmRelaxedGradientProjection(optimization_settings,
50
+ analyzer,
51
+ communicator,
52
+ model_part_controller)
53
+ elif algorithm_name == "shape_fraction_optimization":
54
+ from .algorithm_shape_fraction_optimization import AlgorithmShapeFractionOptimization
55
+ return AlgorithmShapeFractionOptimization(optimization_settings,
56
+ analyzer,
57
+ communicator,
58
+ model_part_controller)
59
+ else:
60
+ raise NameError("The following optimization algorithm is not supported by the algorithm factory: " + algorithm_name)
61
+
62
+ # ==============================================================================