KratosShapeOptimizationApplication 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/KratosShapeOptimizationApplication.so +0 -0
- KratosMultiphysics/.libs/libKratosShapeOptimizationCore.dylib +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/TemplateMainKratosShapeOptimization.py +31 -0
- KratosMultiphysics/ShapeOptimizationApplication/__init__.py +19 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/__init__.py +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_base.py +31 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_bead_optimization.py +412 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_factory.py +62 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_gradient_projection.py +317 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_penalized_projection.py +225 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_relaxed_gradient_projection.py +580 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_shape_fraction_optimization.py +622 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_steepest_descent.py +255 -0
- KratosMultiphysics/ShapeOptimizationApplication/algorithms/algorithm_trust_region.py +657 -0
- KratosMultiphysics/ShapeOptimizationApplication/analyzers/__init__.py +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/analyzers/analyzer_base.py +30 -0
- KratosMultiphysics/ShapeOptimizationApplication/analyzers/analyzer_empty.py +21 -0
- KratosMultiphysics/ShapeOptimizationApplication/analyzers/analyzer_factory.py +310 -0
- KratosMultiphysics/ShapeOptimizationApplication/analyzers/analyzer_internal.py +155 -0
- KratosMultiphysics/ShapeOptimizationApplication/communicator_factory.py +259 -0
- KratosMultiphysics/ShapeOptimizationApplication/custom_ios/__init__.py +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/custom_ios/wrl_io.py +82 -0
- KratosMultiphysics/ShapeOptimizationApplication/custom_ios/wrl_reader.py +119 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/__init__.py +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/data_logger_factory.py +199 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/design_logger_base.py +28 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/design_logger_gid.py +112 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/design_logger_unv.py +73 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/design_logger_vtk.py +96 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/sensitivity_heatmap_logger.py +91 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_base.py +128 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_bead_optimization.py +79 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_gradient_projection.py +80 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_penalized_projection.py +79 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_relaxed_gradient_projection.py +108 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_shape_fraction_optimization.py +92 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_steepest_descent.py +64 -0
- KratosMultiphysics/ShapeOptimizationApplication/loggers/value_logger_trust_region.py +100 -0
- KratosMultiphysics/ShapeOptimizationApplication/mapper_factory.py +100 -0
- KratosMultiphysics/ShapeOptimizationApplication/mapping/__init__.py +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/mapping/in_plane_vertex_morphing_mapper.py +140 -0
- KratosMultiphysics/ShapeOptimizationApplication/mapping/sliding_vertex_morphing_mapper.py +378 -0
- KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/__init__.py +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/mesh_controller_base.py +22 -0
- KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/mesh_controller_basic_updating.py +35 -0
- KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/mesh_controller_with_solver.py +237 -0
- KratosMultiphysics/ShapeOptimizationApplication/model_part_controller_factory.py +197 -0
- KratosMultiphysics/ShapeOptimizationApplication/optimizer_factory.py +235 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/__init__.py +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/airfoil_2d_responses.py +189 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/face_angle.py +140 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/mesh_based_packaging.py +70 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/packaging_response_base.py +156 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/plane_based_packaging.py +61 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/response_function_factory.py +40 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/surface_normal_shape_change.py +125 -0
- KratosMultiphysics/ShapeOptimizationApplication/response_functions/total_volume.py +56 -0
- KratosMultiphysics/ShapeOptimizationApplication/utilities/__init__.py +0 -0
- KratosMultiphysics/ShapeOptimizationApplication/utilities/custom_math.py +443 -0
- KratosMultiphysics/ShapeOptimizationApplication/utilities/custom_sensitivity_heatmap.py +235 -0
- KratosMultiphysics/ShapeOptimizationApplication/utilities/custom_timer.py +47 -0
- KratosMultiphysics/ShapeOptimizationApplication/utilities/custom_variable_utilities.py +54 -0
- kratosshapeoptimizationapplication-10.4.4.dist-info/METADATA +31 -0
- kratosshapeoptimizationapplication-10.4.4.dist-info/RECORD +69 -0
- kratosshapeoptimizationapplication-10.4.4.dist-info/WHEEL +6 -0
- kratosshapeoptimizationapplication.dylibs/libKratosCore.dylib +4 -0
- kratosshapeoptimizationapplication.dylibs/libgcc_s.1.1.dylib +0 -0
- kratosshapeoptimizationapplication.dylibs/libgomp.1.dylib +0 -0
- kratosshapeoptimizationapplication.dylibs/libstdc++.6.dylib +0 -0
KratosMultiphysics/ShapeOptimizationApplication/mesh_controllers/mesh_controller_with_solver.py
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
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
|
+
# Kratos Core and Apps
|
|
13
|
+
import KratosMultiphysics as KM
|
|
14
|
+
import KratosMultiphysics.ShapeOptimizationApplication as KSO
|
|
15
|
+
|
|
16
|
+
# Additional imports
|
|
17
|
+
import time as timer
|
|
18
|
+
from KratosMultiphysics.ShapeOptimizationApplication.mesh_controllers.mesh_controller_base import MeshController
|
|
19
|
+
from KratosMultiphysics.MeshMovingApplication.mesh_moving_analysis import MeshMovingAnalysis
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import KratosMultiphysics.MeshingApplication as KMA
|
|
23
|
+
from KratosMultiphysics.MeshingApplication.mmg_process import MmgProcess as automatic_remeshing_process
|
|
24
|
+
if not hasattr(KMA, "MmgProcess2D"):
|
|
25
|
+
automatic_remeshing_process = None
|
|
26
|
+
automatic_remeshing_error_msg = "MeshingApplication is not compiled with '-DINCLUDE_MMG=ON'"
|
|
27
|
+
except ImportError as err:
|
|
28
|
+
automatic_remeshing_process = None
|
|
29
|
+
automatic_remeshing_error_msg = str(err)
|
|
30
|
+
|
|
31
|
+
# # ==============================================================================
|
|
32
|
+
class MeshControllerWithSolver(MeshController) :
|
|
33
|
+
# --------------------------------------------------------------------------
|
|
34
|
+
def __init__(self, MeshSolverSettings, model):
|
|
35
|
+
default_settings = KM.Parameters("""
|
|
36
|
+
{
|
|
37
|
+
"apply_mesh_solver" : true,
|
|
38
|
+
"solver_settings" : {
|
|
39
|
+
"domain_size" : 3,
|
|
40
|
+
"echo_level" : 0,
|
|
41
|
+
"solver_type" : "structural_similarity",
|
|
42
|
+
"model_part_name" : "NONE",
|
|
43
|
+
"model_import_settings" : {
|
|
44
|
+
"input_type" : "use_input_model_part"
|
|
45
|
+
},
|
|
46
|
+
"time_stepping" : {
|
|
47
|
+
"time_step" : 1.0
|
|
48
|
+
},
|
|
49
|
+
"linear_solver_settings" : {
|
|
50
|
+
"solver_type" : "amgcl",
|
|
51
|
+
"smoother_type":"ilu0",
|
|
52
|
+
"krylov_type": "gmres",
|
|
53
|
+
"coarsening_type": "aggregation",
|
|
54
|
+
"max_iteration": 200,
|
|
55
|
+
"verbosity" : 0,
|
|
56
|
+
"tolerance": 1e-7
|
|
57
|
+
},
|
|
58
|
+
"compute_reactions" : false,
|
|
59
|
+
"calculate_mesh_velocity" : false
|
|
60
|
+
},
|
|
61
|
+
"processes" : {
|
|
62
|
+
"boundary_conditions_process_list" : []
|
|
63
|
+
},
|
|
64
|
+
"use_automatic_remeshing" : false,
|
|
65
|
+
"automatic_remeshing_settings": {
|
|
66
|
+
"strategy" : "optimization",
|
|
67
|
+
"step_frequency" : 1,
|
|
68
|
+
"automatic_remesh": true,
|
|
69
|
+
"automatic_remesh_parameters": {
|
|
70
|
+
"automatic_remesh_type": "Ratio",
|
|
71
|
+
"min_size_ratio": 1.0,
|
|
72
|
+
"max_size_ratio": 5.0,
|
|
73
|
+
"refer_type" : "Mean"
|
|
74
|
+
},
|
|
75
|
+
"echo_level": 0,
|
|
76
|
+
"force_min" : true,
|
|
77
|
+
"force_max" : true
|
|
78
|
+
}
|
|
79
|
+
}""")
|
|
80
|
+
self.MeshSolverSettings = MeshSolverSettings
|
|
81
|
+
self.MeshSolverSettings.ValidateAndAssignDefaults(default_settings)
|
|
82
|
+
self.MeshSolverSettings["solver_settings"].ValidateAndAssignDefaults(default_settings["solver_settings"])
|
|
83
|
+
self.MeshSolverSettings["processes"].ValidateAndAssignDefaults(default_settings["processes"])
|
|
84
|
+
|
|
85
|
+
if not self.MeshSolverSettings["solver_settings"].Has("linear_solver_settings"):
|
|
86
|
+
MeshSolverSettings.AddValue("linear_solver_settings", default_settings["solver_settings"]["linear_solver_settings"])
|
|
87
|
+
KM.Logger.PrintInfo("ShapeOpt", "::[MeshControllerWithSolver]:: using default linear solver for mesh motion.")
|
|
88
|
+
|
|
89
|
+
if not MeshSolverSettings.Has("problem_data"):
|
|
90
|
+
self.__AddDefaultProblemData(self.MeshSolverSettings)
|
|
91
|
+
else:
|
|
92
|
+
KM.Logger.PrintInfo("ShapeOpt", "::[MeshControllerWithSolver]:: using custom problem data for mesh motion.")
|
|
93
|
+
|
|
94
|
+
self.OptimizationModelPart = model[self.MeshSolverSettings["solver_settings"]["model_part_name"].GetString()]
|
|
95
|
+
|
|
96
|
+
if self.MeshSolverSettings["processes"]["boundary_conditions_process_list"].size() == 0:
|
|
97
|
+
self.__FixWholeSurface(self.OptimizationModelPart, self.MeshSolverSettings)
|
|
98
|
+
self.has_automatic_boundary_process = True
|
|
99
|
+
else:
|
|
100
|
+
self.has_automatic_boundary_process = False
|
|
101
|
+
|
|
102
|
+
self.is_remeshing_used = self.MeshSolverSettings["use_automatic_remeshing"].GetBool()
|
|
103
|
+
if (self.is_remeshing_used):
|
|
104
|
+
automatic_remeshing_process_settings = self.MeshSolverSettings["automatic_remeshing_settings"]
|
|
105
|
+
if (automatic_remeshing_process is None):
|
|
106
|
+
raise RuntimeError("Automatic remeshing requires to import MeshingApplication. Importing failed with following error msg.\n\t" + automatic_remeshing_error_msg)
|
|
107
|
+
|
|
108
|
+
self.__CheckAndSetAutomaticMeshRefinementSettings(automatic_remeshing_process_settings)
|
|
109
|
+
self.remeshing_process = automatic_remeshing_process(model, automatic_remeshing_process_settings)
|
|
110
|
+
|
|
111
|
+
# remeshing requires to reinitialize the model_part of the mesh solver
|
|
112
|
+
self.MeshSolverSettings["solver_settings"].AddBool("reinitialize_model_part_each_step", True)
|
|
113
|
+
|
|
114
|
+
KM.Logger.PrintInfo("ShapeOpt", "Initialized automatic automatic remeshing process")
|
|
115
|
+
|
|
116
|
+
self._mesh_moving_analysis = MeshMovingAnalysis(model, self.MeshSolverSettings)
|
|
117
|
+
|
|
118
|
+
# --------------------------------------------------------------------------
|
|
119
|
+
def Initialize(self):
|
|
120
|
+
if self.has_automatic_boundary_process:
|
|
121
|
+
KSO.GeometryUtilities(self.OptimizationModelPart).ExtractBoundaryNodes("auto_surface_nodes")
|
|
122
|
+
|
|
123
|
+
self._mesh_moving_analysis.Initialize()
|
|
124
|
+
if self.is_remeshing_used:
|
|
125
|
+
self.remeshing_process.ExecuteInitialize()
|
|
126
|
+
|
|
127
|
+
# --------------------------------------------------------------------------
|
|
128
|
+
def UpdateMeshAccordingInputVariable(self, variable):
|
|
129
|
+
KM.Logger.Print("")
|
|
130
|
+
KM.Logger.PrintInfo("ShapeOpt", "Starting to update the mesh...")
|
|
131
|
+
startTime = timer.time()
|
|
132
|
+
|
|
133
|
+
time_before_update = self.OptimizationModelPart.ProcessInfo.GetValue(KM.TIME)
|
|
134
|
+
step_before_update = self.OptimizationModelPart.ProcessInfo.GetValue(KM.STEP)
|
|
135
|
+
delta_time_before_update = self.OptimizationModelPart.ProcessInfo.GetValue(KM.DELTA_TIME)
|
|
136
|
+
|
|
137
|
+
# Reset step/time iterators such that they match the current iteration after calling RunSolutionLoop (which internally calls CloneTimeStep)
|
|
138
|
+
self.OptimizationModelPart.ProcessInfo.SetValue(KM.STEP, step_before_update-1)
|
|
139
|
+
self.OptimizationModelPart.ProcessInfo.SetValue(KM.TIME, time_before_update-1)
|
|
140
|
+
self.OptimizationModelPart.ProcessInfo.SetValue(KM.DELTA_TIME, 0)
|
|
141
|
+
|
|
142
|
+
KM.VariableUtils().CopyVectorVar(variable, KM.MESH_DISPLACEMENT, self.OptimizationModelPart.Nodes)
|
|
143
|
+
|
|
144
|
+
if self.has_automatic_boundary_process and self.is_remeshing_used:
|
|
145
|
+
self.OptimizationModelPart.GetSubModelPart("auto_surface_nodes").GetNodes().clear()
|
|
146
|
+
KSO.GeometryUtilities(self.OptimizationModelPart).ExtractBoundaryNodes("auto_surface_nodes")
|
|
147
|
+
|
|
148
|
+
if not self._mesh_moving_analysis.time < self._mesh_moving_analysis.end_time:
|
|
149
|
+
self._mesh_moving_analysis.end_time += 1
|
|
150
|
+
self._mesh_moving_analysis.RunSolutionLoop()
|
|
151
|
+
|
|
152
|
+
if self.is_remeshing_used:
|
|
153
|
+
self.OptimizationModelPart.Set(KM.MODIFIED, False)
|
|
154
|
+
self.remeshing_process.ExecuteInitializeSolutionStep()
|
|
155
|
+
self.remeshing_process.ExecuteFinalizeSolutionStep()
|
|
156
|
+
|
|
157
|
+
KSO.MeshControllerUtilities(self.OptimizationModelPart).LogMeshChangeAccordingInputVariable(KM.MESH_DISPLACEMENT)
|
|
158
|
+
|
|
159
|
+
self.OptimizationModelPart.ProcessInfo.SetValue(KM.STEP, step_before_update)
|
|
160
|
+
self.OptimizationModelPart.ProcessInfo.SetValue(KM.TIME, time_before_update)
|
|
161
|
+
self.OptimizationModelPart.ProcessInfo.SetValue(KM.DELTA_TIME, delta_time_before_update)
|
|
162
|
+
|
|
163
|
+
KM.Logger.PrintInfo("ShapeOpt", "Time needed for updating the mesh = ",round(timer.time() - startTime,2),"s")
|
|
164
|
+
|
|
165
|
+
# --------------------------------------------------------------------------
|
|
166
|
+
def Finalize(self):
|
|
167
|
+
self._mesh_moving_analysis.Finalize()
|
|
168
|
+
|
|
169
|
+
if self.is_remeshing_used:
|
|
170
|
+
self.remeshing_process.ExecuteFinalize()
|
|
171
|
+
|
|
172
|
+
# --------------------------------------------------------------------------
|
|
173
|
+
@staticmethod
|
|
174
|
+
def __AddDefaultProblemData(mesh_solver_settings):
|
|
175
|
+
problem_data = KM.Parameters("""{
|
|
176
|
+
"echo_level" : 0,
|
|
177
|
+
"start_time" : 0.0,
|
|
178
|
+
"end_time" : 1.0,
|
|
179
|
+
"parallel_type" : "OpenMP"
|
|
180
|
+
}""")
|
|
181
|
+
|
|
182
|
+
mesh_solver_settings.AddValue("problem_data", problem_data)
|
|
183
|
+
|
|
184
|
+
# --------------------------------------------------------------------------
|
|
185
|
+
@staticmethod
|
|
186
|
+
def __FixWholeSurface(optimization_model_part, mesh_solver_settings):
|
|
187
|
+
optimization_model_part.CreateSubModelPart("auto_surface_nodes")
|
|
188
|
+
|
|
189
|
+
auto_process_settings = KM.Parameters(
|
|
190
|
+
"""
|
|
191
|
+
{
|
|
192
|
+
"python_module" : "fix_vector_variable_process",
|
|
193
|
+
"kratos_module" : "KratosMultiphysics",
|
|
194
|
+
"help" : "This process fixes the selected components of a given vector variable without modifying the value of the variable.",
|
|
195
|
+
"process_name" : "FixVectorVariableProcess",
|
|
196
|
+
"Parameters" : {
|
|
197
|
+
"model_part_name" : \""""+str(optimization_model_part.Name)+""".auto_surface_nodes\",
|
|
198
|
+
"variable_name" : "MESH_DISPLACEMENT",
|
|
199
|
+
"constrained" : [true,true,true]
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
""")
|
|
203
|
+
|
|
204
|
+
KM.Logger.PrintInfo("ShapeOpt", "Add automatic process to fix the whole surface to mesh motion solver:")
|
|
205
|
+
mesh_solver_settings["processes"]["boundary_conditions_process_list"].Append(auto_process_settings)
|
|
206
|
+
|
|
207
|
+
# --------------------------------------------------------------------------
|
|
208
|
+
def __CheckAndSetAutomaticMeshRefinementSettings(self, parameters):
|
|
209
|
+
if (parameters.Has("interpolate_nodal_values")):
|
|
210
|
+
if (parameters["interpolate_nodal_values"].GetBool()):
|
|
211
|
+
KM.Logger.PrintWarning("ShapeOpt", "Historical value interpolation is not allowed in automatic remeshing. Turning it off.")
|
|
212
|
+
parameters["interpolate_nodal_values"].SetBool(False)
|
|
213
|
+
else:
|
|
214
|
+
parameters.AddBool("interpolate_nodal_values", False)
|
|
215
|
+
|
|
216
|
+
if (parameters.Has("interpolate_non_historical")):
|
|
217
|
+
if (parameters["interpolate_non_historical"].GetBool()):
|
|
218
|
+
KM.Logger.PrintWarning("ShapeOpt", "Non-historical value interpolation is not allowed in automatic remeshing. Turning it off.")
|
|
219
|
+
parameters["interpolate_non_historical"].SetBool(False)
|
|
220
|
+
else:
|
|
221
|
+
parameters.AddBool("interpolate_non_historical", False)
|
|
222
|
+
|
|
223
|
+
if (parameters.Has("extrapolate_contour_values")):
|
|
224
|
+
if (parameters["extrapolate_contour_values"].GetBool()):
|
|
225
|
+
KM.Logger.PrintWarning("ShapeOpt", "Value extrapolation is not allowed in automatic remeshing. Turning it off.")
|
|
226
|
+
parameters["extrapolate_contour_values"].SetBool(False)
|
|
227
|
+
else:
|
|
228
|
+
parameters.AddBool("extrapolate_contour_values", False)
|
|
229
|
+
|
|
230
|
+
if (parameters.Has("model_part_name")):
|
|
231
|
+
if (parameters["model_part_name"].GetString() != self.OptimizationModelPart.Name):
|
|
232
|
+
KM.Logger.PrintWarning("ShapeOpt", "Mismatching model part name provided for automatic remeshing [ " + parameters["model_part_name"].GetString() + " ]. Using the optimization model part [ " + self.OptimizationModelPart.Name + " ].")
|
|
233
|
+
parameters["model_part_name"].SetString(self.OptimizationModelPart.Name)
|
|
234
|
+
else:
|
|
235
|
+
parameters.AddString("model_part_name", self.OptimizationModelPart.Name)
|
|
236
|
+
|
|
237
|
+
# ==============================================================================
|
|
@@ -0,0 +1,197 @@
|
|
|
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
|
+
# importing the Kratos Library
|
|
13
|
+
import KratosMultiphysics as KM
|
|
14
|
+
import KratosMultiphysics.ShapeOptimizationApplication as KSO
|
|
15
|
+
|
|
16
|
+
# ==============================================================================
|
|
17
|
+
def CreateController(model_settings, model):
|
|
18
|
+
return ModelPartController(model_settings, model)
|
|
19
|
+
|
|
20
|
+
# ==============================================================================
|
|
21
|
+
class ModelPartController:
|
|
22
|
+
# --------------------------------------------------------------------------
|
|
23
|
+
def __init__(self, model_settings, model):
|
|
24
|
+
self.model_settings = model_settings
|
|
25
|
+
|
|
26
|
+
default_settings = KM.Parameters("""
|
|
27
|
+
{
|
|
28
|
+
"domain_size" : 3,
|
|
29
|
+
"model_part_name" : "OPTIMIZATION_MODEL_PART_NAME",
|
|
30
|
+
"model_import_settings" : {
|
|
31
|
+
"input_type" : "mdpa",
|
|
32
|
+
"input_filename" : "OPTIMIZATION_MODEL_PART_FILENAME"
|
|
33
|
+
},
|
|
34
|
+
"design_surface_sub_model_part_name" : "DESIGN_SURFACE_NAME",
|
|
35
|
+
"damping" : {
|
|
36
|
+
"apply_damping" : false,
|
|
37
|
+
"recalculate_damping": false,
|
|
38
|
+
"max_neighbor_nodes" : 10000,
|
|
39
|
+
"damping_regions" : []
|
|
40
|
+
},
|
|
41
|
+
"direction_damping" : {
|
|
42
|
+
"recalculate_damping": true,
|
|
43
|
+
"max_neighbor_nodes" : 10000,
|
|
44
|
+
"damping_regions" : []
|
|
45
|
+
},
|
|
46
|
+
"mesh_motion" : {
|
|
47
|
+
"apply_mesh_solver" : false
|
|
48
|
+
}
|
|
49
|
+
}""")
|
|
50
|
+
|
|
51
|
+
self.model_settings.ValidateAndAssignDefaults(default_settings)
|
|
52
|
+
self.model_settings["model_import_settings"].ValidateAndAssignDefaults(default_settings["model_import_settings"])
|
|
53
|
+
self.model_settings["damping"].ValidateAndAssignDefaults(default_settings["damping"])
|
|
54
|
+
self.model_settings["direction_damping"].ValidateAndAssignDefaults(default_settings["direction_damping"])
|
|
55
|
+
|
|
56
|
+
for direction_damping_settings in self.model_settings["direction_damping"]["damping_regions"].values():
|
|
57
|
+
if not direction_damping_settings.Has("max_neighbor_nodes"):
|
|
58
|
+
max_neighbors = self.model_settings["direction_damping"]["max_neighbor_nodes"].GetInt()
|
|
59
|
+
direction_damping_settings.AddEmptyValue("max_neighbor_nodes").SetInt(max_neighbors)
|
|
60
|
+
|
|
61
|
+
self.model = model
|
|
62
|
+
|
|
63
|
+
model_part_name = self.model_settings["model_part_name"].GetString()
|
|
64
|
+
self.optimization_model_part = model.CreateModelPart(model_part_name)
|
|
65
|
+
self.optimization_model_part.ProcessInfo.SetValue(KM.DOMAIN_SIZE, self.model_settings["domain_size"].GetInt())
|
|
66
|
+
|
|
67
|
+
if self.model_settings["mesh_motion"]["apply_mesh_solver"].GetBool():
|
|
68
|
+
from KratosMultiphysics.ShapeOptimizationApplication.mesh_controllers.mesh_controller_with_solver import MeshControllerWithSolver
|
|
69
|
+
self.mesh_controller = MeshControllerWithSolver(self.model_settings["mesh_motion"], self.model)
|
|
70
|
+
else:
|
|
71
|
+
from KratosMultiphysics.ShapeOptimizationApplication.mesh_controllers.mesh_controller_basic_updating import MeshControllerBasicUpdating
|
|
72
|
+
self.mesh_controller = MeshControllerBasicUpdating(self.optimization_model_part)
|
|
73
|
+
|
|
74
|
+
self.design_surface = None
|
|
75
|
+
self.damping_utility = None
|
|
76
|
+
self.direction_dampings = []
|
|
77
|
+
|
|
78
|
+
# --------------------------------------------------------------------------
|
|
79
|
+
def Initialize(self):
|
|
80
|
+
self.__ImportOptimizationModelPart()
|
|
81
|
+
self.__IdentifyDesignSurface()
|
|
82
|
+
|
|
83
|
+
self.mesh_controller.Initialize()
|
|
84
|
+
|
|
85
|
+
def InitializeDamping(self):
|
|
86
|
+
"""Initialize damping utilities, should be called after mapper is initialized"""
|
|
87
|
+
if self.model_settings["damping"]["apply_damping"].GetBool():
|
|
88
|
+
self.damping_utility = KSO.DampingUtilities(
|
|
89
|
+
self.design_surface, self.model_settings["damping"]
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
for direction_damping_settings in self.model_settings["direction_damping"]["damping_regions"].values():
|
|
93
|
+
self.direction_dampings.append(
|
|
94
|
+
KSO.DirectionDampingUtilities(
|
|
95
|
+
self.design_surface, direction_damping_settings
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# --------------------------------------------------------------------------
|
|
100
|
+
def SetMinimalBufferSize(self, buffer_size):
|
|
101
|
+
if self.optimization_model_part.GetBufferSize() < buffer_size:
|
|
102
|
+
self.optimization_model_part.SetBufferSize(buffer_size)
|
|
103
|
+
|
|
104
|
+
# --------------------------------------------------------------------------
|
|
105
|
+
def UpdateTimeStep(self, step):
|
|
106
|
+
self.optimization_model_part.CloneTimeStep(step)
|
|
107
|
+
self.optimization_model_part.ProcessInfo.SetValue(KM.STEP, step)
|
|
108
|
+
|
|
109
|
+
# --------------------------------------------------------------------------
|
|
110
|
+
def UpdateMeshAccordingInputVariable(self, InputVariable):
|
|
111
|
+
self.mesh_controller.UpdateMeshAccordingInputVariable(InputVariable)
|
|
112
|
+
|
|
113
|
+
if self.model_settings["damping"]["recalculate_damping"].GetBool():
|
|
114
|
+
self.damping_utility = KSO.DampingUtilities(
|
|
115
|
+
self.design_surface, self.model_settings["damping"]
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
if self.model_settings["direction_damping"]["recalculate_damping"].GetBool():
|
|
119
|
+
self.direction_dampings = []
|
|
120
|
+
for direction_damping_settings in self.model_settings["direction_damping"]["damping_regions"].values():
|
|
121
|
+
self.direction_dampings.append(
|
|
122
|
+
KSO.DirectionDampingUtilities(
|
|
123
|
+
self.design_surface, direction_damping_settings
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# --------------------------------------------------------------------------
|
|
128
|
+
def SetMeshToReferenceMesh(self):
|
|
129
|
+
KSO.MeshControllerUtilities(self.optimization_model_part).SetMeshToReferenceMesh()
|
|
130
|
+
|
|
131
|
+
# --------------------------------------------------------------------------
|
|
132
|
+
def SetReferenceMeshToMesh(self):
|
|
133
|
+
KSO.MeshControllerUtilities(self.optimization_model_part).SetReferenceMeshToMesh()
|
|
134
|
+
|
|
135
|
+
# --------------------------------------------------------------------------
|
|
136
|
+
def SetDeformationVariablesToZero(self):
|
|
137
|
+
KSO.MeshControllerUtilities(self.optimization_model_part).SetDeformationVariablesToZero()
|
|
138
|
+
|
|
139
|
+
# --------------------------------------------------------------------------
|
|
140
|
+
def GetOptimizationModelPart(self):
|
|
141
|
+
return self.optimization_model_part
|
|
142
|
+
|
|
143
|
+
# --------------------------------------------------------------------------
|
|
144
|
+
def GetModel(self):
|
|
145
|
+
return self.model
|
|
146
|
+
|
|
147
|
+
# --------------------------------------------------------------------------
|
|
148
|
+
def GetDesignSurface(self):
|
|
149
|
+
return self.design_surface
|
|
150
|
+
|
|
151
|
+
# --------------------------------------------------------------------------
|
|
152
|
+
def DampNodalSensitivityVariableIfSpecified(self, variable):
|
|
153
|
+
if self.model_settings["damping"]["apply_damping"].GetBool():
|
|
154
|
+
self.damping_utility.DampNodalVariable(variable)
|
|
155
|
+
|
|
156
|
+
for direction_damping in reversed(self.direction_dampings):
|
|
157
|
+
direction_damping.DampNodalVariable(variable)
|
|
158
|
+
|
|
159
|
+
# --------------------------------------------------------------------------
|
|
160
|
+
def DampNodalUpdateVariableIfSpecified(self, variable):
|
|
161
|
+
for direction_damping in self.direction_dampings:
|
|
162
|
+
direction_damping.DampNodalVariable(variable)
|
|
163
|
+
|
|
164
|
+
if self.model_settings["damping"]["apply_damping"].GetBool():
|
|
165
|
+
self.damping_utility.DampNodalVariable(variable)
|
|
166
|
+
|
|
167
|
+
# --------------------------------------------------------------------------
|
|
168
|
+
def ComputeUnitSurfaceNormals(self):
|
|
169
|
+
KSO.GeometryUtilities(self.GetDesignSurface()).ComputeUnitSurfaceNormals()
|
|
170
|
+
|
|
171
|
+
# --------------------------------------------------------------------------
|
|
172
|
+
def ProjectNodalVariableOnUnitSurfaceNormals(self, variable):
|
|
173
|
+
KSO.GeometryUtilities(self.GetDesignSurface()).ProjectNodalVariableOnUnitSurfaceNormals(variable)
|
|
174
|
+
|
|
175
|
+
# --------------------------------------------------------------------------
|
|
176
|
+
def __ImportOptimizationModelPart(self):
|
|
177
|
+
input_type = self.model_settings["model_import_settings"]["input_type"].GetString()
|
|
178
|
+
if input_type != "mdpa":
|
|
179
|
+
raise RuntimeError("The model part for the optimization has to be read from the mdpa file!")
|
|
180
|
+
input_filename = self.model_settings["model_import_settings"]["input_filename"].GetString()
|
|
181
|
+
|
|
182
|
+
model_part_io = KM.ModelPartIO(input_filename)
|
|
183
|
+
model_part_io.ReadModelPart(self.optimization_model_part)
|
|
184
|
+
|
|
185
|
+
self.SetMinimalBufferSize(1)
|
|
186
|
+
|
|
187
|
+
# --------------------------------------------------------------------------
|
|
188
|
+
def __IdentifyDesignSurface(self):
|
|
189
|
+
nameOfDesignSurface = self.model_settings["design_surface_sub_model_part_name"].GetString()
|
|
190
|
+
if self.optimization_model_part.HasSubModelPart(nameOfDesignSurface):
|
|
191
|
+
self.design_surface = self.optimization_model_part.GetSubModelPart(nameOfDesignSurface)
|
|
192
|
+
KM.Logger.Print("")
|
|
193
|
+
KM.Logger.PrintInfo("ShapeOpt", "The following design surface was defined:\n\n",self.design_surface)
|
|
194
|
+
else:
|
|
195
|
+
raise ValueError("The following sub-model part (design surface) specified for shape optimization does not exist: ",nameOfDesignSurface)
|
|
196
|
+
|
|
197
|
+
# ==============================================================================
|
|
@@ -0,0 +1,235 @@
|
|
|
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
|
+
# Kratos Core and Apps
|
|
13
|
+
import KratosMultiphysics as KM
|
|
14
|
+
import KratosMultiphysics.ShapeOptimizationApplication as KSO
|
|
15
|
+
|
|
16
|
+
# additional imports
|
|
17
|
+
from KratosMultiphysics.ShapeOptimizationApplication.utilities.custom_timer import Timer
|
|
18
|
+
from KratosMultiphysics.ShapeOptimizationApplication.analyzers.analyzer_empty import EmptyAnalyzer
|
|
19
|
+
from KratosMultiphysics.ShapeOptimizationApplication import model_part_controller_factory
|
|
20
|
+
from KratosMultiphysics.ShapeOptimizationApplication.analyzers import analyzer_factory
|
|
21
|
+
from KratosMultiphysics.ShapeOptimizationApplication import communicator_factory
|
|
22
|
+
from KratosMultiphysics.ShapeOptimizationApplication.algorithms import algorithm_factory
|
|
23
|
+
|
|
24
|
+
## Purely for backward compatibility, should be removed soon.
|
|
25
|
+
def CreateOptimizer(optimization_settings,model,external_analyzer=EmptyAnalyzer()):
|
|
26
|
+
return Optimizer(model, optimization_settings, external_analyzer)
|
|
27
|
+
|
|
28
|
+
def Create( model, optimization_settings, external_analyzer=EmptyAnalyzer()):
|
|
29
|
+
return Optimizer(model, optimization_settings, external_analyzer)
|
|
30
|
+
|
|
31
|
+
# ==============================================================================
|
|
32
|
+
class Optimizer:
|
|
33
|
+
# --------------------------------------------------------------------------
|
|
34
|
+
def __init__(self, model, optimization_settings, external_analyzer=EmptyAnalyzer()):
|
|
35
|
+
self._ValidateSettings(optimization_settings)
|
|
36
|
+
self.optimization_settings = optimization_settings
|
|
37
|
+
|
|
38
|
+
self.model_part_controller = model_part_controller_factory.CreateController(optimization_settings["model_settings"], model)
|
|
39
|
+
self.analyzer = analyzer_factory.CreateAnalyzer(optimization_settings, self.model_part_controller, external_analyzer)
|
|
40
|
+
self.communicator = communicator_factory.CreateCommunicator(optimization_settings)
|
|
41
|
+
|
|
42
|
+
if not optimization_settings["design_variables"]["type"].GetString() == "vertex_morphing":
|
|
43
|
+
raise NameError("The following type of design variables is not supported by the optimizer: " + variable_type)
|
|
44
|
+
|
|
45
|
+
self.__AddVariablesToBeUsedByAllAlgorithms()
|
|
46
|
+
self.__AddVariablesToBeUsedByDesignVariables()
|
|
47
|
+
|
|
48
|
+
# --------------------------------------------------------------------------
|
|
49
|
+
def __AddVariablesToBeUsedByAllAlgorithms(self):
|
|
50
|
+
model_part = self.model_part_controller.GetOptimizationModelPart()
|
|
51
|
+
number_of_objectives = self.optimization_settings["objectives"].size()
|
|
52
|
+
number_of_constraints = self.optimization_settings["constraints"].size()
|
|
53
|
+
|
|
54
|
+
nodal_variable = KM.KratosGlobals.GetVariable("DF1DX")
|
|
55
|
+
model_part.AddNodalSolutionStepVariable(nodal_variable)
|
|
56
|
+
nodal_variable = KM.KratosGlobals.GetVariable("DF1DX_MAPPED")
|
|
57
|
+
model_part.AddNodalSolutionStepVariable(nodal_variable)
|
|
58
|
+
|
|
59
|
+
for itr in range(1,number_of_constraints+1):
|
|
60
|
+
nodal_variable = KM.KratosGlobals.GetVariable(f"DC{(itr)}DX")
|
|
61
|
+
model_part.AddNodalSolutionStepVariable(nodal_variable)
|
|
62
|
+
nodal_variable = KM.KratosGlobals.GetVariable(f"DC{(itr)}DX_MAPPED")
|
|
63
|
+
model_part.AddNodalSolutionStepVariable(nodal_variable)
|
|
64
|
+
|
|
65
|
+
model_part.AddNodalSolutionStepVariable(KSO.CONTROL_POINT_UPDATE)
|
|
66
|
+
model_part.AddNodalSolutionStepVariable(KSO.CONTROL_POINT_CHANGE)
|
|
67
|
+
model_part.AddNodalSolutionStepVariable(KSO.SHAPE_UPDATE)
|
|
68
|
+
model_part.AddNodalSolutionStepVariable(KSO.SHAPE_CHANGE)
|
|
69
|
+
model_part.AddNodalSolutionStepVariable(KSO.MESH_CHANGE)
|
|
70
|
+
model_part.AddNodalSolutionStepVariable(KM.NORMAL)
|
|
71
|
+
model_part.AddNodalSolutionStepVariable(KSO.NORMALIZED_SURFACE_NORMAL)
|
|
72
|
+
|
|
73
|
+
# variables required for remeshing
|
|
74
|
+
model_part.AddNodalSolutionStepVariable(KM.DISTANCE)
|
|
75
|
+
model_part.AddNodalSolutionStepVariable(KM.DISTANCE_GRADIENT)
|
|
76
|
+
|
|
77
|
+
# sensitivity heatmap
|
|
78
|
+
if self.optimization_settings["output"].Has("sensitivity_heatmap") and \
|
|
79
|
+
self.optimization_settings["output"]["sensitivity_heatmap"].GetBool():
|
|
80
|
+
self.__AddVariablesToBeUsedBySensitivityHeatmap()
|
|
81
|
+
|
|
82
|
+
def __AddVariablesToBeUsedByDesignVariables(self):
|
|
83
|
+
if self.optimization_settings["design_variables"]["filter"].Has("in_plane_morphing") and \
|
|
84
|
+
self.optimization_settings["design_variables"]["filter"]["in_plane_morphing"].GetBool():
|
|
85
|
+
model_part = self.model_part_controller.GetOptimizationModelPart()
|
|
86
|
+
model_part.AddNodalSolutionStepVariable(KSO.BACKGROUND_COORDINATE)
|
|
87
|
+
model_part.AddNodalSolutionStepVariable(KSO.BACKGROUND_NORMAL)
|
|
88
|
+
model_part.AddNodalSolutionStepVariable(KSO.OUT_OF_PLANE_DELTA)
|
|
89
|
+
if self.optimization_settings["design_variables"]["filter"].Has("sliding_morphing") and \
|
|
90
|
+
self.optimization_settings["design_variables"]["filter"]["sliding_morphing"].GetBool():
|
|
91
|
+
model_part = self.model_part_controller.GetOptimizationModelPart()
|
|
92
|
+
model_part.AddNodalSolutionStepVariable(KSO.BACKGROUND_COORDINATE)
|
|
93
|
+
model_part.AddNodalSolutionStepVariable(KSO.BACKGROUND_NORMAL)
|
|
94
|
+
model_part.AddNodalSolutionStepVariable(KSO.OUT_OF_PLANE_DELTA)
|
|
95
|
+
|
|
96
|
+
if self.optimization_settings["design_variables"]["filter"]["filter_radius"].IsString() and \
|
|
97
|
+
self.optimization_settings["design_variables"]["filter"]["filter_radius"].GetString() == "adaptive":
|
|
98
|
+
# variables required for adaptive
|
|
99
|
+
model_part = self.model_part_controller.GetOptimizationModelPart()
|
|
100
|
+
model_part.AddNodalSolutionStepVariable(KSO.VERTEX_MORPHING_RADIUS)
|
|
101
|
+
model_part.AddNodalSolutionStepVariable(KSO.VERTEX_MORPHING_RADIUS_RAW)
|
|
102
|
+
model_part.AddNodalSolutionStepVariable(KSO.GAUSSIAN_CURVATURE)
|
|
103
|
+
model_part.AddNodalSolutionStepVariable(KSO.MAX_NEIGHBOUR_DISTANCE)
|
|
104
|
+
|
|
105
|
+
def __AddVariablesToBeUsedBySensitivityHeatmap(self):
|
|
106
|
+
model_part = self.model_part_controller.GetOptimizationModelPart()
|
|
107
|
+
|
|
108
|
+
model_part.AddNodalSolutionStepVariable(KM.NODAL_AREA)
|
|
109
|
+
|
|
110
|
+
sensitivity_heatmap_settings = None
|
|
111
|
+
if self.optimization_settings["output"].Has("sensitivity_heatmap_settings"):
|
|
112
|
+
sensitivity_heatmap_settings = self.optimization_settings["output"]["sensitivity_heatmap_settings"]
|
|
113
|
+
|
|
114
|
+
weigthing = True
|
|
115
|
+
mapping = True
|
|
116
|
+
if sensitivity_heatmap_settings:
|
|
117
|
+
if sensitivity_heatmap_settings.Has("sensitivity_weighting") and \
|
|
118
|
+
not sensitivity_heatmap_settings["sensitivity_weighting"].GetBool():
|
|
119
|
+
weigthing = False
|
|
120
|
+
if sensitivity_heatmap_settings.Has("mapping") and \
|
|
121
|
+
not sensitivity_heatmap_settings["mapping"].GetBool():
|
|
122
|
+
mapping = False
|
|
123
|
+
|
|
124
|
+
if self.optimization_settings["optimization_algorithm"]["name"].GetString() == "bead_optimization":
|
|
125
|
+
model_part.AddNodalSolutionStepVariable(KSO.HEATMAP_DF1DALPHA)
|
|
126
|
+
if weigthing:
|
|
127
|
+
model_part.AddNodalSolutionStepVariable(KSO.DF1DALPHA_WEIGHTED)
|
|
128
|
+
if mapping:
|
|
129
|
+
model_part.AddNodalSolutionStepVariable(KSO.DF1DALPHA_WEIGHTED_MAPPED)
|
|
130
|
+
else:
|
|
131
|
+
model_part.AddNodalSolutionStepVariable(KSO.HEATMAP_DF1DX)
|
|
132
|
+
if weigthing:
|
|
133
|
+
model_part.AddNodalSolutionStepVariable(KSO.DF1DX_WEIGHTED)
|
|
134
|
+
if mapping:
|
|
135
|
+
model_part.AddNodalSolutionStepVariable(KSO.DF1DX_WEIGHTED_MAPPED)
|
|
136
|
+
|
|
137
|
+
number_of_constraints = self.optimization_settings["constraints"].size()
|
|
138
|
+
if number_of_constraints != 0:
|
|
139
|
+
model_part.AddNodalSolutionStepVariable(KSO.HEATMAP_MAX)
|
|
140
|
+
model_part.AddNodalSolutionStepVariable(KSO.HEATMAP_L2)
|
|
141
|
+
for itr in range(1,number_of_constraints+1):
|
|
142
|
+
nodal_variable = KM.KratosGlobals.GetVariable(f"HEATMAP_DC{(itr)}DX")
|
|
143
|
+
model_part.AddNodalSolutionStepVariable(nodal_variable)
|
|
144
|
+
if weigthing:
|
|
145
|
+
nodal_variable = KM.KratosGlobals.GetVariable(f"DC{(itr)}DX_WEIGHTED")
|
|
146
|
+
model_part.AddNodalSolutionStepVariable(nodal_variable)
|
|
147
|
+
if mapping:
|
|
148
|
+
nodal_variable = KM.KratosGlobals.GetVariable(f"DC{(itr)}DX_WEIGHTED_MAPPED")
|
|
149
|
+
model_part.AddNodalSolutionStepVariable(nodal_variable)
|
|
150
|
+
|
|
151
|
+
# --------------------------------------------------------------------------
|
|
152
|
+
def Optimize(self):
|
|
153
|
+
algorithm_name = self.optimization_settings["optimization_algorithm"]["name"].GetString()
|
|
154
|
+
|
|
155
|
+
KM.Logger.Print("")
|
|
156
|
+
KM.Logger.Print("===============================================================================")
|
|
157
|
+
KM.Logger.PrintInfo("ShapeOpt", Timer().GetTimeStamp(), ": Starting optimization using the following algorithm: ", algorithm_name)
|
|
158
|
+
KM.Logger.Print("===============================================================================\n")
|
|
159
|
+
|
|
160
|
+
algorithm = algorithm_factory.CreateOptimizationAlgorithm(self.optimization_settings,
|
|
161
|
+
self.analyzer,
|
|
162
|
+
self.communicator,
|
|
163
|
+
self.model_part_controller)
|
|
164
|
+
algorithm.CheckApplicability()
|
|
165
|
+
algorithm.InitializeOptimizationLoop()
|
|
166
|
+
algorithm.RunOptimizationLoop()
|
|
167
|
+
algorithm.FinalizeOptimizationLoop()
|
|
168
|
+
|
|
169
|
+
KM.Logger.Print("")
|
|
170
|
+
KM.Logger.Print("===============================================================================")
|
|
171
|
+
KM.Logger.PrintInfo("ShapeOpt", "Finished optimization")
|
|
172
|
+
KM.Logger.Print("===============================================================================\n")
|
|
173
|
+
|
|
174
|
+
# ==============================================================================
|
|
175
|
+
# ------------------------------------------------------------------------------
|
|
176
|
+
# ==============================================================================
|
|
177
|
+
def _ValidateSettings(self, optimization_settings):
|
|
178
|
+
self._ValidateTopLevelSettings(optimization_settings)
|
|
179
|
+
self._ValidateObjectiveSettingsRecursively(optimization_settings["objectives"])
|
|
180
|
+
self._ValidateConstraintSettings(optimization_settings["constraints"])
|
|
181
|
+
|
|
182
|
+
# ------------------------------------------------------------------------------
|
|
183
|
+
def _ValidateTopLevelSettings(self, optimization_settings):
|
|
184
|
+
default_settings = KM.Parameters("""
|
|
185
|
+
{
|
|
186
|
+
"model_settings" : { },
|
|
187
|
+
"objectives" : [ ],
|
|
188
|
+
"constraints" : [ ],
|
|
189
|
+
"design_variables" : { },
|
|
190
|
+
"optimization_algorithm" : { },
|
|
191
|
+
"output" : { }
|
|
192
|
+
}""")
|
|
193
|
+
|
|
194
|
+
for key in default_settings.keys():
|
|
195
|
+
if not optimization_settings.Has(key):
|
|
196
|
+
raise RuntimeError("Optimizer: Required setting '{}' missing in 'optimization_settings'!".format(key))
|
|
197
|
+
|
|
198
|
+
optimization_settings.ValidateAndAssignDefaults(default_settings)
|
|
199
|
+
|
|
200
|
+
# ------------------------------------------------------------------------------
|
|
201
|
+
def _ValidateObjectiveSettingsRecursively(self, objective_settings):
|
|
202
|
+
default_settings = KM.Parameters("""
|
|
203
|
+
{
|
|
204
|
+
"identifier" : "NO_IDENTIFIER_SPECIFIED",
|
|
205
|
+
"type" : "minimization",
|
|
206
|
+
"scaling_factor" : 1.0,
|
|
207
|
+
"analyzer" : "external",
|
|
208
|
+
"response_settings" : {},
|
|
209
|
+
"is_combined" : false,
|
|
210
|
+
"combination_type" : "sum",
|
|
211
|
+
"combined_responses" : [],
|
|
212
|
+
"weight" : 1.0,
|
|
213
|
+
"project_gradient_on_surface_normals" : false
|
|
214
|
+
}""")
|
|
215
|
+
for itr in range(objective_settings.size()):
|
|
216
|
+
objective_settings[itr].ValidateAndAssignDefaults(default_settings)
|
|
217
|
+
|
|
218
|
+
if objective_settings[itr]["is_combined"].GetBool():
|
|
219
|
+
self._ValidateObjectiveSettingsRecursively(objective_settings[itr]["combined_responses"])
|
|
220
|
+
|
|
221
|
+
# ------------------------------------------------------------------------------
|
|
222
|
+
def _ValidateConstraintSettings(self, constraint_settings):
|
|
223
|
+
default_settings = KM.Parameters("""
|
|
224
|
+
{
|
|
225
|
+
"identifier" : "NO_IDENTIFIER_SPECIFIED",
|
|
226
|
+
"type" : "<",
|
|
227
|
+
"scaling_factor" : 1.0,
|
|
228
|
+
"reference" : "initial_value",
|
|
229
|
+
"reference_value" : 1.0,
|
|
230
|
+
"analyzer" : "external",
|
|
231
|
+
"response_settings" : {},
|
|
232
|
+
"project_gradient_on_surface_normals" : false
|
|
233
|
+
}""")
|
|
234
|
+
for itr in range(constraint_settings.size()):
|
|
235
|
+
constraint_settings[itr].ValidateAndAssignDefaults(default_settings)
|