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
|
@@ -0,0 +1,259 @@
|
|
|
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
|
+
def CreateCommunicator(optimization_settings):
|
|
14
|
+
return Communicator(optimization_settings)
|
|
15
|
+
|
|
16
|
+
# ==============================================================================
|
|
17
|
+
class Communicator:
|
|
18
|
+
|
|
19
|
+
# --------------------------------------------------------------------------
|
|
20
|
+
def __init__(self, optimization_settings):
|
|
21
|
+
self.optimization_settings = optimization_settings
|
|
22
|
+
self.supported_objective_types = ["minimization", "maximization"]
|
|
23
|
+
self.supported_constraint_types = ["=", "<", ">", "<=", ">="]
|
|
24
|
+
self.supported_constraint_references = ["initial_value", "specified_value"]
|
|
25
|
+
|
|
26
|
+
objective_settings = self.__ExtractResponseSettingsRecursively(optimization_settings["objectives"])
|
|
27
|
+
constraint_settings = self.__ExtractResponseSettingsRecursively(optimization_settings["constraints"])
|
|
28
|
+
all_response_settings = objective_settings + constraint_settings
|
|
29
|
+
|
|
30
|
+
self.list_of_requests = self.__initializeListOfRequests(all_response_settings)
|
|
31
|
+
self.list_of_responses = self.__initializeListOfObjectives(objective_settings)
|
|
32
|
+
self.list_of_responses.update(self.__initializeListOfConstraints(constraint_settings))
|
|
33
|
+
|
|
34
|
+
# --------------------------------------------------------------------------
|
|
35
|
+
def initializeCommunication(self):
|
|
36
|
+
self.__deleteAllRequests()
|
|
37
|
+
self.__deleteAllReportedValues()
|
|
38
|
+
|
|
39
|
+
# --------------------------------------------------------------------------
|
|
40
|
+
def updateRequest(self, response_id, **kwargs):
|
|
41
|
+
if "request_value" in kwargs.keys():
|
|
42
|
+
self.list_of_requests[response_id]["calculateValue"] = kwargs["request_value"]
|
|
43
|
+
if "request_gradient" in kwargs.keys():
|
|
44
|
+
self.list_of_requests[response_id]["calculateGradient"] = kwargs["request_gradient"]
|
|
45
|
+
|
|
46
|
+
# --------------------------------------------------------------------------
|
|
47
|
+
def requestValueOf(self, response_id):
|
|
48
|
+
self.list_of_requests[response_id]["calculateValue"] = True
|
|
49
|
+
|
|
50
|
+
# --------------------------------------------------------------------------
|
|
51
|
+
def requestGradientOf(self, response_id):
|
|
52
|
+
self.list_of_requests[response_id]["calculateGradient"] = True
|
|
53
|
+
|
|
54
|
+
# --------------------------------------------------------------------------
|
|
55
|
+
def isRequestingValueOf(self, response_id):
|
|
56
|
+
if response_id not in self.list_of_requests.keys():
|
|
57
|
+
return False
|
|
58
|
+
else:
|
|
59
|
+
return self.list_of_requests[response_id]["calculateValue"]
|
|
60
|
+
|
|
61
|
+
# --------------------------------------------------------------------------
|
|
62
|
+
def isRequestingGradientOf(self, response_id):
|
|
63
|
+
if response_id not in self.list_of_requests.keys():
|
|
64
|
+
return False
|
|
65
|
+
else:
|
|
66
|
+
return self.list_of_requests[response_id]["calculateGradient"]
|
|
67
|
+
|
|
68
|
+
# --------------------------------------------------------------------------
|
|
69
|
+
def reportValue(self, response_id, value):
|
|
70
|
+
self.__storeValue(response_id, value)
|
|
71
|
+
if self.__isResponseWaitingForInitialValueAsReference(response_id):
|
|
72
|
+
self.__setValueAsReference(response_id, value)
|
|
73
|
+
|
|
74
|
+
standardized_value = self.__translateValueToStandardForm(response_id, value)
|
|
75
|
+
self.__storeStandardizedValue(response_id, standardized_value)
|
|
76
|
+
|
|
77
|
+
# --------------------------------------------------------------------------
|
|
78
|
+
def reportGradient(self, response_id, gradient):
|
|
79
|
+
dimension = len(next(iter(gradient.values())))
|
|
80
|
+
if dimension == 1:
|
|
81
|
+
gradient = {key: [value[0], 0.0, 0.0] for key, value in gradient.items()}
|
|
82
|
+
elif dimension == 2:
|
|
83
|
+
gradient = {key: [value[0], value[1], 0.0] for key, value in gradient.items()}
|
|
84
|
+
|
|
85
|
+
standardized_gradient = self.__translateGradientToStandardForm(response_id, gradient)
|
|
86
|
+
self.__storeStandardizedGradient(response_id, standardized_gradient)
|
|
87
|
+
|
|
88
|
+
# --------------------------------------------------------------------------
|
|
89
|
+
def getValue(self, response_id):
|
|
90
|
+
if self.list_of_responses[response_id]["value"] is None:
|
|
91
|
+
raise RuntimeError("The requested value for ", response_id, " is None!")
|
|
92
|
+
return self.list_of_responses[response_id]["value"]
|
|
93
|
+
|
|
94
|
+
# --------------------------------------------------------------------------
|
|
95
|
+
def getReferenceValue(self, response_id):
|
|
96
|
+
if self.list_of_responses[response_id]["reference_value"] is None:
|
|
97
|
+
raise RuntimeError("The requested reference_value for ", response_id, " is None!")
|
|
98
|
+
return self.list_of_responses[response_id]["reference_value"]
|
|
99
|
+
|
|
100
|
+
# --------------------------------------------------------------------------
|
|
101
|
+
def getStandardizedValue(self, response_id):
|
|
102
|
+
if self.list_of_responses[response_id]["standardized_value"] is None:
|
|
103
|
+
raise RuntimeError("The requested standardized_value for ", response_id, " is None!")
|
|
104
|
+
return self.list_of_responses[response_id]["standardized_value"]
|
|
105
|
+
|
|
106
|
+
# --------------------------------------------------------------------------
|
|
107
|
+
def getStandardizedGradient(self, response_id):
|
|
108
|
+
if self.list_of_responses[response_id]["standardized_gradient"] is None:
|
|
109
|
+
raise RuntimeError("The requested standardized_gradient for ", response_id, " is None!")
|
|
110
|
+
return self.list_of_responses[response_id]["standardized_gradient"]
|
|
111
|
+
|
|
112
|
+
# --------------------------------------------------------------------------
|
|
113
|
+
@classmethod
|
|
114
|
+
def __ExtractResponseSettingsRecursively(cls, response_settings):
|
|
115
|
+
list_of_settings = []
|
|
116
|
+
|
|
117
|
+
for itr in range(response_settings.size()):
|
|
118
|
+
response_i = response_settings[itr]
|
|
119
|
+
if response_i.Has("is_combined"):
|
|
120
|
+
if response_i["is_combined"].GetBool():
|
|
121
|
+
list_of_settings += cls.__ExtractResponseSettingsRecursively(response_i["combined_responses"])
|
|
122
|
+
|
|
123
|
+
list_of_settings += [response_i]
|
|
124
|
+
|
|
125
|
+
return list_of_settings
|
|
126
|
+
|
|
127
|
+
# --------------------------------------------------------------------------
|
|
128
|
+
@classmethod
|
|
129
|
+
def __initializeListOfRequests(cls, response_settings):
|
|
130
|
+
list_of_requests = {}
|
|
131
|
+
|
|
132
|
+
for response in response_settings:
|
|
133
|
+
response_id = response["identifier"].GetString()
|
|
134
|
+
list_of_requests[response_id] = {"calculateValue": False, "calculateGradient": False}
|
|
135
|
+
|
|
136
|
+
return list_of_requests
|
|
137
|
+
|
|
138
|
+
# --------------------------------------------------------------------------
|
|
139
|
+
def __initializeListOfObjectives(self, objective_settings):
|
|
140
|
+
list_of_objectives = {}
|
|
141
|
+
|
|
142
|
+
for objective in objective_settings:
|
|
143
|
+
objective_id = objective["identifier"].GetString()
|
|
144
|
+
|
|
145
|
+
if objective["type"].GetString() not in self.supported_objective_types:
|
|
146
|
+
raise RuntimeError("Unsupported type defined for the following objective: " + objective_id)
|
|
147
|
+
|
|
148
|
+
list_of_objectives[objective_id] = { "type" : objective["type"].GetString(),
|
|
149
|
+
"value" : None,
|
|
150
|
+
"scaling_factor" : objective["scaling_factor"].GetDouble(),
|
|
151
|
+
"standardized_value" : None,
|
|
152
|
+
"standardized_gradient": None }
|
|
153
|
+
|
|
154
|
+
return list_of_objectives
|
|
155
|
+
|
|
156
|
+
# --------------------------------------------------------------------------
|
|
157
|
+
def __initializeListOfConstraints(self, constraint_settings):
|
|
158
|
+
list_of_constraints = {}
|
|
159
|
+
|
|
160
|
+
for constraint in constraint_settings:
|
|
161
|
+
constraint_id = constraint["identifier"].GetString()
|
|
162
|
+
|
|
163
|
+
if constraint["type"].GetString() not in self.supported_constraint_types:
|
|
164
|
+
raise RuntimeError("Unsupported type defined for the following constraint: " + constraint_id)
|
|
165
|
+
|
|
166
|
+
if constraint["reference"].GetString() not in self.supported_constraint_references:
|
|
167
|
+
raise RuntimeError("Unsupported reference defined for the following constraint: " + constraint_id)
|
|
168
|
+
|
|
169
|
+
if constraint["reference"].GetString() == "specified_value":
|
|
170
|
+
list_of_constraints[constraint_id] = { "type" : constraint["type"].GetString(),
|
|
171
|
+
"value" : None,
|
|
172
|
+
"scaling_factor" : constraint["scaling_factor"].GetDouble(),
|
|
173
|
+
"standardized_value" : None,
|
|
174
|
+
"standardized_gradient": None,
|
|
175
|
+
"reference_value" : constraint["reference_value"].GetDouble() }
|
|
176
|
+
elif constraint["reference"].GetString() == "initial_value":
|
|
177
|
+
list_of_constraints[constraint_id] = { "type" : constraint["type"].GetString(),
|
|
178
|
+
"value" : None,
|
|
179
|
+
"scaling_factor" : constraint["scaling_factor"].GetDouble(),
|
|
180
|
+
"standardized_value" : None,
|
|
181
|
+
"standardized_gradient": None,
|
|
182
|
+
"reference_value" : None }
|
|
183
|
+
else:
|
|
184
|
+
raise RuntimeError("Unsupported reference defined for the following constraint: " + constraint_id)
|
|
185
|
+
|
|
186
|
+
return list_of_constraints
|
|
187
|
+
|
|
188
|
+
# --------------------------------------------------------------------------
|
|
189
|
+
def __deleteAllRequests(self):
|
|
190
|
+
for response_id in self.list_of_requests:
|
|
191
|
+
self.list_of_requests[response_id]["calculateValue"] = False
|
|
192
|
+
self.list_of_requests[response_id]["calculateGradient"] = False
|
|
193
|
+
|
|
194
|
+
# --------------------------------------------------------------------------
|
|
195
|
+
def __deleteAllReportedValues(self):
|
|
196
|
+
for response_id in self.list_of_responses:
|
|
197
|
+
self.list_of_responses[response_id]["value"] = None
|
|
198
|
+
self.list_of_responses[response_id]["standardized_value"] = None
|
|
199
|
+
self.list_of_responses[response_id]["standardized_gradient"] = None
|
|
200
|
+
|
|
201
|
+
# --------------------------------------------------------------------------
|
|
202
|
+
def __isResponseWaitingForInitialValueAsReference(self, response_id):
|
|
203
|
+
response = self.list_of_responses[response_id]
|
|
204
|
+
if "reference_value" in response:
|
|
205
|
+
is_reference_value_missing = (response["reference_value"] is None)
|
|
206
|
+
if is_reference_value_missing:
|
|
207
|
+
return True
|
|
208
|
+
return False
|
|
209
|
+
|
|
210
|
+
# --------------------------------------------------------------------------
|
|
211
|
+
def __setValueAsReference(self, response_id, value):
|
|
212
|
+
self.list_of_responses[response_id]["reference_value"] = value
|
|
213
|
+
|
|
214
|
+
# --------------------------------------------------------------------------
|
|
215
|
+
def __translateValueToStandardForm(self, response_id, value):
|
|
216
|
+
response_type = self.list_of_responses[response_id]["type"]
|
|
217
|
+
scaling_factor = self.list_of_responses[response_id]["scaling_factor"]
|
|
218
|
+
|
|
219
|
+
if response_type in self.supported_objective_types:
|
|
220
|
+
if response_type == "maximization":
|
|
221
|
+
return -scaling_factor*value
|
|
222
|
+
else:
|
|
223
|
+
return scaling_factor*value
|
|
224
|
+
else:
|
|
225
|
+
reference_value = self.list_of_responses[response_id]["reference_value"]
|
|
226
|
+
|
|
227
|
+
if response_type == ">" or response_type == ">=":
|
|
228
|
+
return scaling_factor*(reference_value-value)
|
|
229
|
+
else:
|
|
230
|
+
return scaling_factor*(value-reference_value)
|
|
231
|
+
|
|
232
|
+
# --------------------------------------------------------------------------
|
|
233
|
+
def __translateGradientToStandardForm(self, response_id, gradient):
|
|
234
|
+
response_type = self.list_of_responses[response_id]["type"]
|
|
235
|
+
scaling_factor = self.list_of_responses[response_id]["scaling_factor"]
|
|
236
|
+
|
|
237
|
+
if response_type == "maximization" or response_type == ">" or response_type == ">=":
|
|
238
|
+
scaling_factor *= -1
|
|
239
|
+
|
|
240
|
+
for vector in gradient.values():
|
|
241
|
+
vector[0] *= scaling_factor
|
|
242
|
+
vector[1] *= scaling_factor
|
|
243
|
+
vector[2] *= scaling_factor
|
|
244
|
+
|
|
245
|
+
return gradient
|
|
246
|
+
|
|
247
|
+
# --------------------------------------------------------------------------
|
|
248
|
+
def __storeValue(self, response_id, value):
|
|
249
|
+
self.list_of_responses[response_id]["value"] = value
|
|
250
|
+
|
|
251
|
+
# --------------------------------------------------------------------------
|
|
252
|
+
def __storeStandardizedValue(self, response_id, value):
|
|
253
|
+
self.list_of_responses[response_id]["standardized_value"] = value
|
|
254
|
+
|
|
255
|
+
# --------------------------------------------------------------------------
|
|
256
|
+
def __storeStandardizedGradient(self, response_id, gradient):
|
|
257
|
+
self.list_of_responses[response_id]["standardized_gradient"] = gradient
|
|
258
|
+
|
|
259
|
+
# ==============================================================================
|
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# KratosShapeOptimizationApplication
|
|
3
|
+
#
|
|
4
|
+
# License: BSD License
|
|
5
|
+
# license: ShapeOptimizationApplication/license.txt
|
|
6
|
+
#
|
|
7
|
+
# Main authors: Geiser Armin, https://github.com/armingeiser
|
|
8
|
+
#
|
|
9
|
+
# ==============================================================================
|
|
10
|
+
|
|
11
|
+
import KratosMultiphysics as KM
|
|
12
|
+
from .wrl_reader import read_shapes, detect_file
|
|
13
|
+
|
|
14
|
+
def _rename_to_valid_name(model_part, shape):
|
|
15
|
+
name = shape.name
|
|
16
|
+
|
|
17
|
+
ref_name = name
|
|
18
|
+
i = 2
|
|
19
|
+
while model_part.HasSubModelPart(name):
|
|
20
|
+
name = ref_name +"_{}".format(i)
|
|
21
|
+
i += 1
|
|
22
|
+
|
|
23
|
+
if shape.name != name:
|
|
24
|
+
KM.Logger.PrintWarning("ShapeOpt", "WrlIO: Name of the sub model part has been changed from '{}' to '{}' in order "\
|
|
25
|
+
"to avoid name clashes!".format(shape.name, name))
|
|
26
|
+
shape.name = name
|
|
27
|
+
|
|
28
|
+
class WrlIO:
|
|
29
|
+
|
|
30
|
+
def __init__(self, file_name):
|
|
31
|
+
self.file_name = detect_file(file_name)
|
|
32
|
+
|
|
33
|
+
def ReadModelPart(self, model_part):
|
|
34
|
+
KM.Logger.PrintInfo("ShapeOpt", "Start reading model part from '{}'.".format(self.file_name))
|
|
35
|
+
|
|
36
|
+
if model_part.ProcessInfo.GetValue(KM.DOMAIN_SIZE) != 3:
|
|
37
|
+
raise Exception("WrlIO: Domain size has to be 3!")
|
|
38
|
+
|
|
39
|
+
shapes = read_shapes(self.file_name)
|
|
40
|
+
|
|
41
|
+
node_multiplicity = {}
|
|
42
|
+
|
|
43
|
+
nodes_shift = 0
|
|
44
|
+
faces_shift = 0
|
|
45
|
+
for i, shape in enumerate(shapes):
|
|
46
|
+
_rename_to_valid_name(model_part, shape)
|
|
47
|
+
sub_model_part = model_part.CreateSubModelPart(shape.name)
|
|
48
|
+
|
|
49
|
+
property_id = i+1
|
|
50
|
+
new_property = model_part.CreateNewProperties(property_id)
|
|
51
|
+
|
|
52
|
+
for i, node in enumerate(shape.nodes):
|
|
53
|
+
node_id = i + nodes_shift
|
|
54
|
+
new_node = model_part.CreateNewNode(node_id, *node)
|
|
55
|
+
sub_model_part.AddNode(new_node, 0)
|
|
56
|
+
node_multiplicity[node_id] = 0
|
|
57
|
+
|
|
58
|
+
for i, face in enumerate(shape.faces):
|
|
59
|
+
face_id = i + faces_shift
|
|
60
|
+
node_ids = [x + nodes_shift for x in face]
|
|
61
|
+
|
|
62
|
+
for node_id in node_ids:
|
|
63
|
+
node_multiplicity[node_id] += 1
|
|
64
|
+
|
|
65
|
+
condition_type = "SurfaceCondition3D{}N".format(len(node_ids))
|
|
66
|
+
new_condition = model_part.CreateNewCondition(condition_type, face_id, node_ids, new_property)
|
|
67
|
+
sub_model_part.AddCondition(new_condition)
|
|
68
|
+
|
|
69
|
+
nodes_shift += len(shape.nodes)
|
|
70
|
+
faces_shift += len(shape.faces)
|
|
71
|
+
|
|
72
|
+
# remove flying nodes
|
|
73
|
+
counter = 0
|
|
74
|
+
for node_id, count in node_multiplicity.items():
|
|
75
|
+
if count == 0:
|
|
76
|
+
model_part.RemoveNode(node_id)
|
|
77
|
+
counter += 1
|
|
78
|
+
|
|
79
|
+
if counter > 0:
|
|
80
|
+
KM.Logger.PrintWarning("WrlIO", "Deleted {} flying nodes from model part!".format(counter))
|
|
81
|
+
|
|
82
|
+
KM.Logger.PrintInfo("ShapeOpt", "Finished reading model part.")
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# KratosShapeOptimizationApplication
|
|
3
|
+
#
|
|
4
|
+
# License: BSD License
|
|
5
|
+
# license: ShapeOptimizationApplication/license.txt
|
|
6
|
+
#
|
|
7
|
+
# Main authors: Geiser Armin, https://github.com/armingeiser
|
|
8
|
+
#
|
|
9
|
+
# ==============================================================================
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
class Shape:
|
|
14
|
+
def __init__(self, name, nodes, faces):
|
|
15
|
+
self.name = name
|
|
16
|
+
self.nodes = nodes
|
|
17
|
+
self.faces = faces
|
|
18
|
+
|
|
19
|
+
def detect_file(file_name):
|
|
20
|
+
wrl_name = file_name + ".wrl"
|
|
21
|
+
vrml_name = file_name + ".vrml"
|
|
22
|
+
|
|
23
|
+
if os.path.isfile(wrl_name) and os.path.isfile(vrml_name):
|
|
24
|
+
raise Exception("Wrl reader: file {} found with '.wrl' and '.vrml' ending! Please remove one of them!".format(file_name))
|
|
25
|
+
elif os.path.isfile(wrl_name):
|
|
26
|
+
return wrl_name
|
|
27
|
+
elif os.path.isfile(vrml_name):
|
|
28
|
+
return vrml_name
|
|
29
|
+
else:
|
|
30
|
+
raise Exception("Wrl reader: file {} not found with '.wrl' or '.vrml' ending!".format(file_name))
|
|
31
|
+
|
|
32
|
+
def read_nodes(line, file):
|
|
33
|
+
nodes = []
|
|
34
|
+
while "[" not in line:
|
|
35
|
+
line = next(file)
|
|
36
|
+
|
|
37
|
+
line = next(file)
|
|
38
|
+
|
|
39
|
+
while "]" not in line:
|
|
40
|
+
if line == "\n":
|
|
41
|
+
line = next(file)
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
entries = line.split(",")[0].split()
|
|
45
|
+
if len(entries) != 3:
|
|
46
|
+
raise RuntimeError("wrl_reader: Did not find 3 coordinate components!", line)
|
|
47
|
+
nodes.append([float(x) for x in entries])
|
|
48
|
+
except IOError:
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
line = next(file)
|
|
52
|
+
|
|
53
|
+
return nodes
|
|
54
|
+
|
|
55
|
+
def read_faces(line, file):
|
|
56
|
+
faces = []
|
|
57
|
+
while "[" not in line:
|
|
58
|
+
line = next(file)
|
|
59
|
+
|
|
60
|
+
line = next(file)
|
|
61
|
+
|
|
62
|
+
while "]" not in line:
|
|
63
|
+
if line == "\n":
|
|
64
|
+
line = next(file)
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
entries = line.split(",")
|
|
68
|
+
entries = [x.strip() for x in entries]
|
|
69
|
+
if entries.count("-1") != 1:
|
|
70
|
+
raise RuntimeError("wrl_reader: Can only read one face per line!", line)
|
|
71
|
+
entries = entries[:entries.index("-1")]
|
|
72
|
+
if len(entries) < 2:
|
|
73
|
+
raise RuntimeError("wrl_reader: Can not read faces with less than 3 nodes!", line)
|
|
74
|
+
elif len(entries) > 4:
|
|
75
|
+
raise RuntimeError("wrl_reader: Can not read faces with more than 4 nodes!", line)
|
|
76
|
+
faces.append([int(x) for x in entries])
|
|
77
|
+
except IOError:
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
line = next(file)
|
|
81
|
+
|
|
82
|
+
return faces
|
|
83
|
+
|
|
84
|
+
def read_shape(line, file):
|
|
85
|
+
try:
|
|
86
|
+
name = line.split("#")[1].strip()
|
|
87
|
+
except IndexError:
|
|
88
|
+
name = "geometry"
|
|
89
|
+
nodes = []
|
|
90
|
+
faces = []
|
|
91
|
+
|
|
92
|
+
while "geometry" not in line:
|
|
93
|
+
line = next(file)
|
|
94
|
+
if "IndexedFaceSet" not in line:
|
|
95
|
+
raise RuntimeError("wrl_reader: Can not read '{}'".format(line))
|
|
96
|
+
|
|
97
|
+
while not nodes or not faces:
|
|
98
|
+
if line.strip().startswith("coord "):
|
|
99
|
+
nodes = read_nodes(line, file)
|
|
100
|
+
elif line.strip().startswith("coordIndex"):
|
|
101
|
+
faces = read_faces(line, file)
|
|
102
|
+
line = next(file)
|
|
103
|
+
|
|
104
|
+
return Shape(name, nodes, faces)
|
|
105
|
+
|
|
106
|
+
def read_shapes(file_name):
|
|
107
|
+
shapes = []
|
|
108
|
+
with open(file_name, "r") as file:
|
|
109
|
+
|
|
110
|
+
first_line = file.readline()
|
|
111
|
+
if not first_line.startswith("#VRML V2.0"):
|
|
112
|
+
raise RuntimeError("wrl_reader: Can not read '{}' format!"\
|
|
113
|
+
" Only '#VRML V2.0' is supported.".format(first_line.strip()))
|
|
114
|
+
|
|
115
|
+
for line in file:
|
|
116
|
+
if line.strip().startswith("Shape"):
|
|
117
|
+
shapes.append(read_shape(line, file))
|
|
118
|
+
line = next(file)
|
|
119
|
+
return shapes
|
|
File without changes
|
|
@@ -0,0 +1,199 @@
|
|
|
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 Kratos
|
|
15
|
+
|
|
16
|
+
# Additional imports
|
|
17
|
+
import shutil
|
|
18
|
+
import os
|
|
19
|
+
|
|
20
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.design_logger_gid import DesignLoggerGID
|
|
21
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.design_logger_unv import DesignLoggerUNV
|
|
22
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.design_logger_vtk import DesignLoggerVTK
|
|
23
|
+
|
|
24
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.value_logger_steepest_descent import ValueLoggerSteepestDescent
|
|
25
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.value_logger_penalized_projection import ValueLoggerPenalizedProjection
|
|
26
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.value_logger_trust_region import ValueLoggerTrustRegion
|
|
27
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.value_logger_bead_optimization import ValueLoggerBeadOptimization
|
|
28
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.value_logger_gradient_projection import ValueLoggerGradientProjection
|
|
29
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.value_logger_relaxed_gradient_projection import ValueLoggerRelaxedGradientProjection
|
|
30
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.value_logger_shape_fraction_optimization import ValueLoggerShapeFractionOptimization
|
|
31
|
+
from KratosMultiphysics.ShapeOptimizationApplication.loggers.sensitivity_heatmap_logger import (
|
|
32
|
+
SensitivityHeatmapLoggerSteepestDescent,
|
|
33
|
+
SensitivityHeatmapLoggerPenalizedProjection,
|
|
34
|
+
SensitivityHeatmapLoggerGradientProjection,
|
|
35
|
+
SensitivityHeatmapLoggerTrustRegion,
|
|
36
|
+
SensitivityHeatmapLoggerBeadOptimization)
|
|
37
|
+
|
|
38
|
+
# ==============================================================================
|
|
39
|
+
def CreateDataLogger( ModelPartController, Communicator, OptimizationSettings ):
|
|
40
|
+
return DataLogger( ModelPartController, Communicator, OptimizationSettings )
|
|
41
|
+
|
|
42
|
+
# ==============================================================================
|
|
43
|
+
class DataLogger():
|
|
44
|
+
# --------------------------------------------------------------------------
|
|
45
|
+
def __init__( self, ModelPartController, Communicator, OptimizationSettings ):
|
|
46
|
+
self.ModelPartController = ModelPartController
|
|
47
|
+
self.Communicator = Communicator
|
|
48
|
+
self.OptimizationSettings = OptimizationSettings
|
|
49
|
+
|
|
50
|
+
default_logger_settings = Kratos.Parameters("""
|
|
51
|
+
{
|
|
52
|
+
"output_directory" : "Optimization_Results",
|
|
53
|
+
"optimization_log_filename" : "optimization_log",
|
|
54
|
+
"design_output_mode" : "write_optimization_model_part",
|
|
55
|
+
"sensitivity_heatmap" : false,
|
|
56
|
+
"sensitivity_heatmap_settings": {},
|
|
57
|
+
"nodal_results" : [ "SHAPE_CHANGE" ],
|
|
58
|
+
"output_format" : { "name": "vtk" }
|
|
59
|
+
}""")
|
|
60
|
+
|
|
61
|
+
self.OptimizationSettings["output"].ValidateAndAssignDefaults(default_logger_settings)
|
|
62
|
+
|
|
63
|
+
self.ValueLogger = self.__CreateValueLogger()
|
|
64
|
+
self.DesignLogger = self.__CreateDesignLogger()
|
|
65
|
+
self.SensitivityHeatmapLogger = self.__CreateSensitivityHeatmapLogger()
|
|
66
|
+
|
|
67
|
+
self.__CreateFolderToStoreOptimizationResults()
|
|
68
|
+
self.__OutputInformationAboutResponseFunctions()
|
|
69
|
+
|
|
70
|
+
# -----------------------------------------------------------------------------
|
|
71
|
+
def __CreateValueLogger( self ):
|
|
72
|
+
AlgorithmName = self.OptimizationSettings["optimization_algorithm"]["name"].GetString()
|
|
73
|
+
if AlgorithmName == "steepest_descent":
|
|
74
|
+
return ValueLoggerSteepestDescent( self.Communicator, self.OptimizationSettings )
|
|
75
|
+
elif AlgorithmName == "penalized_projection":
|
|
76
|
+
return ValueLoggerPenalizedProjection( self.Communicator, self.OptimizationSettings )
|
|
77
|
+
elif AlgorithmName == "gradient_projection":
|
|
78
|
+
return ValueLoggerGradientProjection( self.Communicator, self.OptimizationSettings )
|
|
79
|
+
elif AlgorithmName == "trust_region":
|
|
80
|
+
return ValueLoggerTrustRegion( self.Communicator, self.OptimizationSettings )
|
|
81
|
+
elif AlgorithmName == "bead_optimization":
|
|
82
|
+
return ValueLoggerBeadOptimization( self.Communicator, self.OptimizationSettings )
|
|
83
|
+
elif AlgorithmName == "relaxed_gradient_projection":
|
|
84
|
+
return ValueLoggerRelaxedGradientProjection(self.Communicator, self.OptimizationSettings)
|
|
85
|
+
elif AlgorithmName == "shape_fraction_optimization":
|
|
86
|
+
return ValueLoggerShapeFractionOptimization( self.Communicator, self.OptimizationSettings )
|
|
87
|
+
else:
|
|
88
|
+
raise NameError("The following optimization algorithm not supported by the response logger (name may be misspelled): " + AlgorithmName)
|
|
89
|
+
|
|
90
|
+
# -----------------------------------------------------------------------------
|
|
91
|
+
def __CreateDesignLogger( self ):
|
|
92
|
+
valid_output_modes = ["write_design_surface", "write_optimization_model_part", "none"]
|
|
93
|
+
output_mode = self.OptimizationSettings["output"]["design_output_mode"].GetString()
|
|
94
|
+
|
|
95
|
+
# backward compatibility
|
|
96
|
+
if output_mode == "WriteDesignSurface":
|
|
97
|
+
Kratos.Logger.PrintWarning("ShapeOpt", "'design_output_mode': 'WriteDesignSurface' is deprecated and replaced with 'write_design_surface'.")
|
|
98
|
+
self.OptimizationSettings["output"]["design_output_mode"].SetString("write_design_surface")
|
|
99
|
+
output_mode = self.OptimizationSettings["output"]["design_output_mode"].GetString()
|
|
100
|
+
|
|
101
|
+
if output_mode == "WriteOptimizationModelPart":
|
|
102
|
+
Kratos.Logger.PrintWarning("ShapeOpt", "'design_output_mode': 'WriteOptimizationModelPart' is deprecated and replaced with 'write_optimization_model_part'.")
|
|
103
|
+
self.OptimizationSettings["output"]["design_output_mode"].SetString("write_optimization_model_part")
|
|
104
|
+
output_mode = self.OptimizationSettings["output"]["design_output_mode"].GetString()
|
|
105
|
+
|
|
106
|
+
if output_mode not in valid_output_modes:
|
|
107
|
+
raise RuntimeError("Invalid 'design_output_mode', available options are: {}".format(valid_output_modes))
|
|
108
|
+
|
|
109
|
+
if output_mode == "none":
|
|
110
|
+
Kratos.Logger.Print("")
|
|
111
|
+
Kratos.Logger.PrintInfo("ShapeOpt", "No design output will be created because 'design_output_mode' = 'None'.")
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
outputFormatName = self.OptimizationSettings["output"]["output_format"]["name"].GetString()
|
|
115
|
+
if outputFormatName == "gid":
|
|
116
|
+
return DesignLoggerGID( self.ModelPartController, self.OptimizationSettings )
|
|
117
|
+
if outputFormatName == "unv":
|
|
118
|
+
return DesignLoggerUNV( self.ModelPartController, self.OptimizationSettings )
|
|
119
|
+
if outputFormatName == "vtk":
|
|
120
|
+
return DesignLoggerVTK( self.ModelPartController, self.OptimizationSettings )
|
|
121
|
+
else:
|
|
122
|
+
raise NameError("The following output format is not supported by the design logger (name may be misspelled): " + outputFormatName)
|
|
123
|
+
|
|
124
|
+
# -----------------------------------------------------------------------------
|
|
125
|
+
def __CreateSensitivityHeatmapLogger( self ):
|
|
126
|
+
if not self.OptimizationSettings["output"]["sensitivity_heatmap"].GetBool():
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
AlgorithmName = self.OptimizationSettings["optimization_algorithm"]["name"].GetString()
|
|
130
|
+
if AlgorithmName == "steepest_descent":
|
|
131
|
+
return SensitivityHeatmapLoggerSteepestDescent( self.ModelPartController, self.OptimizationSettings )
|
|
132
|
+
elif AlgorithmName == "penalized_projection":
|
|
133
|
+
return SensitivityHeatmapLoggerPenalizedProjection( self.ModelPartController, self.OptimizationSettings )
|
|
134
|
+
elif AlgorithmName == "gradient_projection":
|
|
135
|
+
return SensitivityHeatmapLoggerGradientProjection( self.ModelPartController, self.OptimizationSettings )
|
|
136
|
+
elif AlgorithmName == "trust_region":
|
|
137
|
+
return SensitivityHeatmapLoggerTrustRegion( self.ModelPartController, self.OptimizationSettings )
|
|
138
|
+
elif AlgorithmName == "bead_optimization":
|
|
139
|
+
return SensitivityHeatmapLoggerBeadOptimization( self.ModelPartController, self.OptimizationSettings )
|
|
140
|
+
else:
|
|
141
|
+
raise NameError("The following optimization algorithm is not supported by the sensitivity heatmap logger (name may be misspelled): " + AlgorithmName)
|
|
142
|
+
|
|
143
|
+
# --------------------------------------------------------------------------
|
|
144
|
+
def __CreateFolderToStoreOptimizationResults ( self ):
|
|
145
|
+
resultsDirectory = self.OptimizationSettings["output"]["output_directory"].GetString()
|
|
146
|
+
if os.path.exists(resultsDirectory):
|
|
147
|
+
shutil.rmtree(resultsDirectory)
|
|
148
|
+
os.makedirs(resultsDirectory)
|
|
149
|
+
|
|
150
|
+
# --------------------------------------------------------------------------
|
|
151
|
+
def __OutputInformationAboutResponseFunctions( self ):
|
|
152
|
+
numberOfObjectives = self.OptimizationSettings["objectives"].size()
|
|
153
|
+
numberOfConstraints = self.OptimizationSettings["constraints"].size()
|
|
154
|
+
|
|
155
|
+
Kratos.Logger.Print("")
|
|
156
|
+
Kratos.Logger.PrintInfo("ShapeOpt", "The following objectives are defined:\n")
|
|
157
|
+
for objectiveNumber in range(numberOfObjectives):
|
|
158
|
+
Kratos.Logger.Print(self.OptimizationSettings["objectives"][objectiveNumber])
|
|
159
|
+
|
|
160
|
+
if numberOfConstraints != 0:
|
|
161
|
+
Kratos.Logger.PrintInfo("ShapeOpt", "The following constraints are defined:\n")
|
|
162
|
+
for constraintNumber in range(numberOfConstraints):
|
|
163
|
+
Kratos.Logger.Print(self.OptimizationSettings["constraints"][constraintNumber],"\n")
|
|
164
|
+
else:
|
|
165
|
+
Kratos.Logger.PrintInfo("ShapeOpt", "No constraints defined.\n")
|
|
166
|
+
|
|
167
|
+
# --------------------------------------------------------------------------
|
|
168
|
+
def InitializeDataLogging( self ):
|
|
169
|
+
if self.DesignLogger:
|
|
170
|
+
self.DesignLogger.InitializeLogging()
|
|
171
|
+
self.ValueLogger.InitializeLogging()
|
|
172
|
+
if self.SensitivityHeatmapLogger:
|
|
173
|
+
self.SensitivityHeatmapLogger.InitializeLogging()
|
|
174
|
+
|
|
175
|
+
# --------------------------------------------------------------------------
|
|
176
|
+
def LogCurrentDesign( self, current_iteration ):
|
|
177
|
+
if self.DesignLogger:
|
|
178
|
+
self.DesignLogger.LogCurrentDesign( current_iteration )
|
|
179
|
+
|
|
180
|
+
# --------------------------------------------------------------------------
|
|
181
|
+
def LogCurrentValues( self, current_iteration, additional_values ):
|
|
182
|
+
self.ValueLogger.LogCurrentValues( current_iteration, additional_values )
|
|
183
|
+
|
|
184
|
+
# --------------------------------------------------------------------------
|
|
185
|
+
def LogSensitivityHeatmap( self, current_iteration, mapper ):
|
|
186
|
+
if self.SensitivityHeatmapLogger:
|
|
187
|
+
self.SensitivityHeatmapLogger.LogSensitivityHeatmap( current_iteration, mapper )
|
|
188
|
+
|
|
189
|
+
# --------------------------------------------------------------------------
|
|
190
|
+
def FinalizeDataLogging( self ):
|
|
191
|
+
if self.DesignLogger:
|
|
192
|
+
self.DesignLogger.FinalizeLogging()
|
|
193
|
+
self.ValueLogger.FinalizeLogging()
|
|
194
|
+
|
|
195
|
+
# --------------------------------------------------------------------------
|
|
196
|
+
def GetValues( self, key ):
|
|
197
|
+
return self.ValueLogger.GetValues(key)
|
|
198
|
+
|
|
199
|
+
# ==============================================================================
|