KratosOptimizationApplication 10.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- KratosMultiphysics/.libs/KratosOptimizationApplication.so +0 -0
- KratosMultiphysics/.libs/libKratosOptimizationCore.dylib +0 -0
- KratosMultiphysics/OptimizationApplication/__init__.py +19 -0
- KratosMultiphysics/OptimizationApplication/algorithms/NLOPT_algorithms.py +255 -0
- KratosMultiphysics/OptimizationApplication/algorithms/SciPy_algorithms.py +154 -0
- KratosMultiphysics/OptimizationApplication/algorithms/__init__.py +0 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm.py +78 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_adam.py +68 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_base.py +393 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_gradient_projection.py +355 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_momentum_relaxed_gradient_projection.py +70 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_nesterov_accelarated_gradient.py +60 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_relaxed_gradient_projection.py +263 -0
- KratosMultiphysics/OptimizationApplication/algorithms/algorithm_steepest_descent.py +205 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_NLOPT_constraint.py +194 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_NLOPT_objective.py +191 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_SciPy_constraint.py +123 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_SciPy_objective.py +148 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_constraint.py +180 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_objective.py +133 -0
- KratosMultiphysics/OptimizationApplication/algorithms/standardized_rgp_constraint.py +268 -0
- KratosMultiphysics/OptimizationApplication/analyses_controller.py +75 -0
- KratosMultiphysics/OptimizationApplication/controls/control.py +123 -0
- KratosMultiphysics/OptimizationApplication/controls/external_response_function_control.py +149 -0
- KratosMultiphysics/OptimizationApplication/controls/master_control.py +198 -0
- KratosMultiphysics/OptimizationApplication/controls/material/material_properties_control.py +115 -0
- KratosMultiphysics/OptimizationApplication/controls/material/simp_control.py +229 -0
- KratosMultiphysics/OptimizationApplication/controls/shape/vertex_morphing_shape_control.py +289 -0
- KratosMultiphysics/OptimizationApplication/controls/thickness/shell_thickness_control.py +180 -0
- KratosMultiphysics/OptimizationApplication/controls_controller.py +205 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/avg_abs_improvement_conv_criterion.py +98 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/combined_conv_criterion.py +87 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/constraint_conv_criterion.py +68 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/convergence_criterion.py +26 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/l2_conv_criterion.py +77 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/magnitude_reduction_conv_criterion.py +85 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/max_iter_conv_criterion.py +48 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/patience_conv_criterion.py +116 -0
- KratosMultiphysics/OptimizationApplication/convergence_criteria/target_value_conv_criterion.py +64 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/execution_policy.py +46 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/execution_policy_decorator.py +67 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/independent_analysis_execution_policy.py +78 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/kratos_analysis_execution_policy.py +137 -0
- KratosMultiphysics/OptimizationApplication/execution_policies/stepping_analysis_execution_policy.py +88 -0
- KratosMultiphysics/OptimizationApplication/filtering/explicit_filter.py +124 -0
- KratosMultiphysics/OptimizationApplication/filtering/filter.py +188 -0
- KratosMultiphysics/OptimizationApplication/filtering/filter_utils.py +55 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_analysis.py +139 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_scalar_solver.py +39 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_shape_solver.py +67 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_solver_base.py +275 -0
- KratosMultiphysics/OptimizationApplication/filtering/helmholtz_vector_solver.py +39 -0
- KratosMultiphysics/OptimizationApplication/filtering/implicit_filter.py +192 -0
- KratosMultiphysics/OptimizationApplication/filtering/python_solvers_wrapper_implicit_filters.py +56 -0
- KratosMultiphysics/OptimizationApplication/model_part_controllers/connectivity_preserving_model_part_controller.py +72 -0
- KratosMultiphysics/OptimizationApplication/model_part_controllers/external_response_function_model_part_controller.py +110 -0
- KratosMultiphysics/OptimizationApplication/model_part_controllers/mdpa_model_part_controller.py +44 -0
- KratosMultiphysics/OptimizationApplication/model_part_controllers/model_part_controller.py +19 -0
- KratosMultiphysics/OptimizationApplication/model_parts_controller.py +92 -0
- KratosMultiphysics/OptimizationApplication/optimization_analysis.py +146 -0
- KratosMultiphysics/OptimizationApplication/optimizations_controller.py +223 -0
- KratosMultiphysics/OptimizationApplication/optimizer.py +61 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_ascii_output_process.py +212 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_field_output_process.py +122 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_graph_output_process.py +184 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_hdf5_output_process.py +84 -0
- KratosMultiphysics/OptimizationApplication/processes/optimization_problem_vtu_output_process.py +94 -0
- KratosMultiphysics/OptimizationApplication/processes/spatial_statistics_computation_process.py +81 -0
- KratosMultiphysics/OptimizationApplication/responses/__init__.py +0 -0
- KratosMultiphysics/OptimizationApplication/responses/additive_manufacturing_responses.py +410 -0
- KratosMultiphysics/OptimizationApplication/responses/analysis_based_response_function_factory.py +14 -0
- KratosMultiphysics/OptimizationApplication/responses/analysis_free_response_function_factory.py +14 -0
- KratosMultiphysics/OptimizationApplication/responses/base_response.py +66 -0
- KratosMultiphysics/OptimizationApplication/responses/binary_operator_response_function.py +103 -0
- KratosMultiphysics/OptimizationApplication/responses/combined_response_function.py +127 -0
- KratosMultiphysics/OptimizationApplication/responses/discrete_value_residual_response_function.py +131 -0
- KratosMultiphysics/OptimizationApplication/responses/evaluation_response_function.py +68 -0
- KratosMultiphysics/OptimizationApplication/responses/external_response_function.py +87 -0
- KratosMultiphysics/OptimizationApplication/responses/geometric_centroid_deviation_response_function.py +97 -0
- KratosMultiphysics/OptimizationApplication/responses/linear_strain_energy_response_function.py +72 -0
- KratosMultiphysics/OptimizationApplication/responses/literal_value_response_function.py +33 -0
- KratosMultiphysics/OptimizationApplication/responses/log_response_function.py +47 -0
- KratosMultiphysics/OptimizationApplication/responses/mass_response_function.py +71 -0
- KratosMultiphysics/OptimizationApplication/responses/response_function.py +126 -0
- KratosMultiphysics/OptimizationApplication/responses/response_routine.py +158 -0
- KratosMultiphysics/OptimizationApplication/responses/structural_responses.py +335 -0
- KratosMultiphysics/OptimizationApplication/responses_controller.py +390 -0
- KratosMultiphysics/OptimizationApplication/utilities/buffered_dict.py +399 -0
- KratosMultiphysics/OptimizationApplication/utilities/component_data_view.py +74 -0
- KratosMultiphysics/OptimizationApplication/utilities/helper_utilities.py +40 -0
- KratosMultiphysics/OptimizationApplication/utilities/logger_utilities.py +222 -0
- KratosMultiphysics/OptimizationApplication/utilities/model_part_utilities.py +117 -0
- KratosMultiphysics/OptimizationApplication/utilities/opt_line_search.py +173 -0
- KratosMultiphysics/OptimizationApplication/utilities/opt_projection.py +191 -0
- KratosMultiphysics/OptimizationApplication/utilities/optimization_problem.py +237 -0
- KratosMultiphysics/OptimizationApplication/utilities/optimization_problem_utilities.py +237 -0
- KratosMultiphysics/OptimizationApplication/utilities/response_utilities.py +249 -0
- KratosMultiphysics/OptimizationApplication/utilities/timer.py +45 -0
- KratosMultiphysics/OptimizationApplication/utilities/union_utilities.py +6 -0
- kratosoptimizationapplication-10.4.4.dist-info/METADATA +25 -0
- kratosoptimizationapplication-10.4.4.dist-info/RECORD +106 -0
- kratosoptimizationapplication-10.4.4.dist-info/WHEEL +6 -0
- kratosoptimizationapplication.dylibs/libKratosCore.dylib +4 -0
- kratosoptimizationapplication.dylibs/libgcc_s.1.1.dylib +0 -0
- kratosoptimizationapplication.dylibs/libgomp.1.dylib +0 -0
- kratosoptimizationapplication.dylibs/libstdc++.6.dylib +0 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import KratosMultiphysics as KM
|
|
2
|
+
from KratosMultiphysics import Parameters, Logger
|
|
3
|
+
import KratosMultiphysics.OptimizationApplication as KOA
|
|
4
|
+
from KratosMultiphysics.OptimizationApplication.responses.base_response import BaseResponseFunction
|
|
5
|
+
|
|
6
|
+
import time as timer
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
class InterfaceResponseFunction(BaseResponseFunction):
|
|
10
|
+
|
|
11
|
+
def __init__(self,response_name, response_settings,model):
|
|
12
|
+
|
|
13
|
+
self.type = "interface"
|
|
14
|
+
self.variable = "INTERFACE"
|
|
15
|
+
super().__init__(response_name, response_settings, model)
|
|
16
|
+
|
|
17
|
+
self.supported_control_types = ["material"]
|
|
18
|
+
self.gradients_variables = {"material":"D_INTERFACE_D_FD"}
|
|
19
|
+
|
|
20
|
+
if len(self.evaluated_model_parts) != 1:
|
|
21
|
+
raise RuntimeError("InterfaceResponseFunction: 'evaluated_objects' of response '{}' must have only one entry !".format(self.name))
|
|
22
|
+
|
|
23
|
+
for control_type in self.control_types:
|
|
24
|
+
if not control_type in self.supported_control_types:
|
|
25
|
+
raise RuntimeError("InterfaceResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
root_model_part_name = self.evaluated_model_parts[0].split(".")[0]
|
|
29
|
+
for evaluated_model_part in self.evaluated_model_parts:
|
|
30
|
+
if evaluated_model_part.split(".")[0] != root_model_part_name:
|
|
31
|
+
raise RuntimeError("InterfaceResponseFunction: evaluated_model_parts of mass response must have the same root model part !")
|
|
32
|
+
|
|
33
|
+
self.root_model_part = self.model.GetModelPart(root_model_part_name)
|
|
34
|
+
|
|
35
|
+
# add vars and response
|
|
36
|
+
self.response_function = KOA.InterfaceOptResponse(response_name,model,self.response_settings)
|
|
37
|
+
for control_type in self.control_types:
|
|
38
|
+
self.root_model_part.AddNodalSolutionStepVariable(KM.KratosGlobals.GetVariable(self.gradients_variables[control_type]))
|
|
39
|
+
|
|
40
|
+
def GetVariableName(self):
|
|
41
|
+
return self.variable
|
|
42
|
+
|
|
43
|
+
def GetGradientsVariablesName(self):
|
|
44
|
+
return self.gradients_variables
|
|
45
|
+
|
|
46
|
+
def GetGradientVariableNameForType(self,control_type, raise_error=True):
|
|
47
|
+
if raise_error:
|
|
48
|
+
if not control_type in self.supported_control_types:
|
|
49
|
+
raise RuntimeError("InterfaceResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
50
|
+
|
|
51
|
+
return self.gradients_variables[control_type]
|
|
52
|
+
|
|
53
|
+
def Initialize(self):
|
|
54
|
+
super().Initialize()
|
|
55
|
+
self.response_function.Initialize()
|
|
56
|
+
|
|
57
|
+
def CalculateValue(self):
|
|
58
|
+
Logger.PrintInfo("InterfaceResponseFunction:CalculateValue: Starting value calculation for response ", self.name)
|
|
59
|
+
startTime = timer.time()
|
|
60
|
+
self.value = self.response_function.CalculateValue()
|
|
61
|
+
Logger.PrintInfo("InterfaceResponseFunction:CalculateValue: Time needed for calculating value ",round(timer.time() - startTime,2),"s")
|
|
62
|
+
return self.value
|
|
63
|
+
|
|
64
|
+
def CalculateGradientsForTypesAndObjects(self,control_types,controlled_objects,raise_error=True):
|
|
65
|
+
|
|
66
|
+
if raise_error:
|
|
67
|
+
for itr in range(len(controlled_objects)):
|
|
68
|
+
controlled_object = controlled_objects[itr]
|
|
69
|
+
control_type = control_types[itr]
|
|
70
|
+
found = False
|
|
71
|
+
for itr_2 in range(len(self.controlled_model_parts)):
|
|
72
|
+
controlled_model_part = self.controlled_model_parts[itr_2]
|
|
73
|
+
controlled_type = self.control_types[itr_2]
|
|
74
|
+
if controlled_type==control_type and controlled_model_part==controlled_object:
|
|
75
|
+
found = True
|
|
76
|
+
break
|
|
77
|
+
if not found:
|
|
78
|
+
raise RuntimeError("InterfaceResponseFunction:CalculateGradientsForTypesAndObjects: control type {} of control object {} is not in the control_types of response {}".format(control_types[itr],controlled_object,self.name))
|
|
79
|
+
|
|
80
|
+
Logger.PrintInfo("InterfaceResponseFunction", "Starting ", control_types," gradients calculation of response ", self.name," for ",controlled_objects)
|
|
81
|
+
startTime = timer.time()
|
|
82
|
+
self.response_function.CalculateGradient()
|
|
83
|
+
Logger.PrintInfo("InterfaceResponseFunction", "Time needed for calculating gradients ",round(timer.time() - startTime,2),"s")
|
|
84
|
+
|
|
85
|
+
class PartitionMassResponseFunction(BaseResponseFunction):
|
|
86
|
+
|
|
87
|
+
def __init__(self,response_name, response_settings,model):
|
|
88
|
+
|
|
89
|
+
self.type = "partition_mass"
|
|
90
|
+
self.variable = "PARTITION_MASS"
|
|
91
|
+
super().__init__(response_name, response_settings, model)
|
|
92
|
+
|
|
93
|
+
self.supported_control_types = ["material"]
|
|
94
|
+
self.gradients_variables = {"material":"D_PARTITION_MASS_D_FD"}
|
|
95
|
+
|
|
96
|
+
if len(self.evaluated_model_parts) != 1:
|
|
97
|
+
raise RuntimeError("PartitionMassResponseFunction: 'evaluated_objects' of response '{}' must have only one entry !".format(self.name))
|
|
98
|
+
|
|
99
|
+
for control_type in self.control_types:
|
|
100
|
+
if not control_type in self.supported_control_types:
|
|
101
|
+
raise RuntimeError("PartitionMassResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
root_model_part_name = self.evaluated_model_parts[0].split(".")[0]
|
|
105
|
+
for evaluated_model_part in self.evaluated_model_parts:
|
|
106
|
+
if evaluated_model_part.split(".")[0] != root_model_part_name:
|
|
107
|
+
raise RuntimeError("PartitionMassResponseFunction: evaluated_model_parts of mass response must have the same root model part !")
|
|
108
|
+
|
|
109
|
+
self.root_model_part = self.model.GetModelPart(root_model_part_name)
|
|
110
|
+
|
|
111
|
+
# add vars and response
|
|
112
|
+
self.response_function = KOA.PartitionMassOptResponse(response_name,model,self.response_settings)
|
|
113
|
+
for control_type in self.control_types:
|
|
114
|
+
self.root_model_part.AddNodalSolutionStepVariable(KM.KratosGlobals.GetVariable(self.gradients_variables[control_type]))
|
|
115
|
+
|
|
116
|
+
def GetVariableName(self):
|
|
117
|
+
return self.variable
|
|
118
|
+
|
|
119
|
+
def GetGradientsVariablesName(self):
|
|
120
|
+
return self.gradients_variables
|
|
121
|
+
|
|
122
|
+
def GetGradientVariableNameForType(self,control_type, raise_error=True):
|
|
123
|
+
if raise_error:
|
|
124
|
+
if not control_type in self.supported_control_types:
|
|
125
|
+
raise RuntimeError("PartitionMassResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
126
|
+
|
|
127
|
+
return self.gradients_variables[control_type]
|
|
128
|
+
|
|
129
|
+
def Initialize(self):
|
|
130
|
+
super().Initialize()
|
|
131
|
+
self.response_function.Initialize()
|
|
132
|
+
|
|
133
|
+
def CalculateValue(self):
|
|
134
|
+
Logger.PrintInfo("PartitionMassResponseFunction:CalculateValue: Starting value calculation for response ", self.name)
|
|
135
|
+
startTime = timer.time()
|
|
136
|
+
self.value = self.response_function.CalculateValue()
|
|
137
|
+
Logger.PrintInfo("PartitionMassResponseFunction:CalculateValue: Time needed for calculating value ",round(timer.time() - startTime,2),"s")
|
|
138
|
+
return self.value
|
|
139
|
+
|
|
140
|
+
def CalculateGradientsForTypesAndObjects(self,control_types,controlled_objects,raise_error=True):
|
|
141
|
+
|
|
142
|
+
if raise_error:
|
|
143
|
+
for itr in range(len(controlled_objects)):
|
|
144
|
+
controlled_object = controlled_objects[itr]
|
|
145
|
+
control_type = control_types[itr]
|
|
146
|
+
found = False
|
|
147
|
+
for itr_2 in range(len(self.controlled_model_parts)):
|
|
148
|
+
controlled_model_part = self.controlled_model_parts[itr_2]
|
|
149
|
+
controlled_type = self.control_types[itr_2]
|
|
150
|
+
if controlled_type==control_type and controlled_model_part==controlled_object:
|
|
151
|
+
found = True
|
|
152
|
+
break
|
|
153
|
+
if not found:
|
|
154
|
+
raise RuntimeError("PartitionMassResponseFunction:CalculateGradientsForTypesAndObjects: control type {} of control object {} is not in the control_types of response {}".format(control_types[itr],controlled_object,self.name))
|
|
155
|
+
|
|
156
|
+
Logger.PrintInfo("PartitionMassResponseFunction", "Starting ", control_types," gradients calculation of response ", self.name," for ",controlled_objects)
|
|
157
|
+
startTime = timer.time()
|
|
158
|
+
self.response_function.CalculateGradient()
|
|
159
|
+
Logger.PrintInfo("PartitionMassResponseFunction", "Time needed for calculating gradients ",round(timer.time() - startTime,2),"s")
|
|
160
|
+
|
|
161
|
+
class PartitionMassResponseFunction(BaseResponseFunction):
|
|
162
|
+
|
|
163
|
+
def __init__(self,response_name, response_settings,model):
|
|
164
|
+
|
|
165
|
+
self.type = "partition_mass"
|
|
166
|
+
self.variable = "PARTITION_MASS"
|
|
167
|
+
super().__init__(response_name, response_settings, model)
|
|
168
|
+
|
|
169
|
+
self.supported_control_types = ["material"]
|
|
170
|
+
self.gradients_variables = {"material":"D_PARTITION_MASS_D_FD"}
|
|
171
|
+
|
|
172
|
+
if len(self.evaluated_model_parts) != 1:
|
|
173
|
+
raise RuntimeError("PartitionMassResponseFunction: 'evaluated_objects' of response '{}' must have only one entry !".format(self.name))
|
|
174
|
+
|
|
175
|
+
for control_type in self.control_types:
|
|
176
|
+
if not control_type in self.supported_control_types:
|
|
177
|
+
raise RuntimeError("PartitionMassResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
root_model_part_name = self.evaluated_model_parts[0].split(".")[0]
|
|
181
|
+
for evaluated_model_part in self.evaluated_model_parts:
|
|
182
|
+
if evaluated_model_part.split(".")[0] != root_model_part_name:
|
|
183
|
+
raise RuntimeError("PartitionMassResponseFunction: evaluated_model_parts of mass response must have the same root model part !")
|
|
184
|
+
|
|
185
|
+
self.root_model_part = self.model.GetModelPart(root_model_part_name)
|
|
186
|
+
|
|
187
|
+
# add vars and response
|
|
188
|
+
self.response_function = KOA.PartitionMassOptResponse(response_name,model,self.response_settings)
|
|
189
|
+
for control_type in self.control_types:
|
|
190
|
+
self.root_model_part.AddNodalSolutionStepVariable(KM.KratosGlobals.GetVariable(self.gradients_variables[control_type]))
|
|
191
|
+
|
|
192
|
+
def GetVariableName(self):
|
|
193
|
+
return self.variable
|
|
194
|
+
|
|
195
|
+
def GetGradientsVariablesName(self):
|
|
196
|
+
return self.gradients_variables
|
|
197
|
+
|
|
198
|
+
def GetGradientVariableNameForType(self,control_type, raise_error=True):
|
|
199
|
+
if raise_error:
|
|
200
|
+
if not control_type in self.supported_control_types:
|
|
201
|
+
raise RuntimeError("PartitionMassResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
202
|
+
|
|
203
|
+
return self.gradients_variables[control_type]
|
|
204
|
+
|
|
205
|
+
def Initialize(self):
|
|
206
|
+
super().Initialize()
|
|
207
|
+
self.response_function.Initialize()
|
|
208
|
+
|
|
209
|
+
def CalculateValue(self):
|
|
210
|
+
Logger.PrintInfo("PartitionMassResponseFunction:CalculateValue: Starting value calculation for response ", self.name)
|
|
211
|
+
startTime = timer.time()
|
|
212
|
+
self.value = self.response_function.CalculateValue()
|
|
213
|
+
Logger.PrintInfo("PartitionMassResponseFunction:CalculateValue: Time needed for calculating value ",round(timer.time() - startTime,2),"s")
|
|
214
|
+
return self.value
|
|
215
|
+
|
|
216
|
+
def CalculateGradientsForTypesAndObjects(self,control_types,controlled_objects,raise_error=True):
|
|
217
|
+
|
|
218
|
+
if raise_error:
|
|
219
|
+
for itr in range(len(controlled_objects)):
|
|
220
|
+
controlled_object = controlled_objects[itr]
|
|
221
|
+
control_type = control_types[itr]
|
|
222
|
+
found = False
|
|
223
|
+
for itr_2 in range(len(self.controlled_model_parts)):
|
|
224
|
+
controlled_model_part = self.controlled_model_parts[itr_2]
|
|
225
|
+
controlled_type = self.control_types[itr_2]
|
|
226
|
+
if controlled_type==control_type and controlled_model_part==controlled_object:
|
|
227
|
+
found = True
|
|
228
|
+
break
|
|
229
|
+
if not found:
|
|
230
|
+
raise RuntimeError("PartitionMassResponseFunction:CalculateGradientsForTypesAndObjects: control type {} of control object {} is not in the control_types of response {}".format(control_types[itr],controlled_object,self.name))
|
|
231
|
+
|
|
232
|
+
Logger.PrintInfo("PartitionMassResponseFunction", "Starting ", control_types," gradients calculation of response ", self.name," for ",controlled_objects)
|
|
233
|
+
startTime = timer.time()
|
|
234
|
+
self.response_function.CalculateGradient()
|
|
235
|
+
Logger.PrintInfo("PartitionMassResponseFunction", "Time needed for calculating gradients ",round(timer.time() - startTime,2),"s")
|
|
236
|
+
|
|
237
|
+
class PartitionInterfaceStressResponseFunction(BaseResponseFunction):
|
|
238
|
+
|
|
239
|
+
def __init__(self,response_name, response_settings,model):
|
|
240
|
+
|
|
241
|
+
self.type = "partition_interface_stress"
|
|
242
|
+
self.variable = "STRESS"
|
|
243
|
+
super().__init__(response_name, response_settings, model)
|
|
244
|
+
|
|
245
|
+
self.supported_control_types = ["material"]
|
|
246
|
+
self.gradients_variables = {"material":"D_STRESS_D_FD"}
|
|
247
|
+
|
|
248
|
+
if len(self.evaluated_model_parts) != 1:
|
|
249
|
+
raise RuntimeError("PartitionInterfaceStressResponseFunction: 'evaluated_objects' of response '{}' must have only one entry !".format(self.name))
|
|
250
|
+
|
|
251
|
+
for control_type in self.control_types:
|
|
252
|
+
if not control_type in self.supported_control_types:
|
|
253
|
+
raise RuntimeError("PartitionInterfaceStressResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
root_model_part_name = self.evaluated_model_parts[0].split(".")[0]
|
|
257
|
+
for evaluated_model_part in self.evaluated_model_parts:
|
|
258
|
+
if evaluated_model_part.split(".")[0] != root_model_part_name:
|
|
259
|
+
raise RuntimeError("PartitionInterfaceStressResponseFunction: evaluated_model_parts of mass response must have the same root model part !")
|
|
260
|
+
|
|
261
|
+
self.root_model_part = self.model.GetModelPart(root_model_part_name)
|
|
262
|
+
|
|
263
|
+
# add vars and response
|
|
264
|
+
self.response_function = KOA.PartitionInterfaceStressOptResponse(response_name,model,self.response_settings)
|
|
265
|
+
for control_type in self.control_types:
|
|
266
|
+
self.root_model_part.AddNodalSolutionStepVariable(KM.KratosGlobals.GetVariable(self.gradients_variables[control_type]))
|
|
267
|
+
|
|
268
|
+
def GetVariableName(self):
|
|
269
|
+
return self.variable
|
|
270
|
+
|
|
271
|
+
def GetGradientsVariablesName(self):
|
|
272
|
+
return self.gradients_variables
|
|
273
|
+
|
|
274
|
+
def GetGradientVariableNameForType(self,control_type, raise_error=True):
|
|
275
|
+
if raise_error:
|
|
276
|
+
if not control_type in self.supported_control_types:
|
|
277
|
+
raise RuntimeError("PartitionInterfaceStressResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
278
|
+
|
|
279
|
+
return self.gradients_variables[control_type]
|
|
280
|
+
|
|
281
|
+
def Initialize(self):
|
|
282
|
+
super().Initialize()
|
|
283
|
+
self.response_function.Initialize()
|
|
284
|
+
|
|
285
|
+
def CalculateValue(self):
|
|
286
|
+
Logger.PrintInfo("PartitionInterfaceStressResponseFunction:CalculateValue: Starting value calculation for response ", self.name)
|
|
287
|
+
startTime = timer.time()
|
|
288
|
+
self.value = self.response_function.CalculateValue()
|
|
289
|
+
Logger.PrintInfo("PartitionInterfaceStressResponseFunction:CalculateValue: Time needed for calculating value ",round(timer.time() - startTime,2),"s")
|
|
290
|
+
return self.value
|
|
291
|
+
|
|
292
|
+
def CalculateGradientsForTypesAndObjects(self,control_types,controlled_objects,raise_error=True):
|
|
293
|
+
|
|
294
|
+
if raise_error:
|
|
295
|
+
for itr in range(len(controlled_objects)):
|
|
296
|
+
controlled_object = controlled_objects[itr]
|
|
297
|
+
control_type = control_types[itr]
|
|
298
|
+
found = False
|
|
299
|
+
for itr_2 in range(len(self.controlled_model_parts)):
|
|
300
|
+
controlled_model_part = self.controlled_model_parts[itr_2]
|
|
301
|
+
controlled_type = self.control_types[itr_2]
|
|
302
|
+
if controlled_type==control_type and controlled_model_part==controlled_object:
|
|
303
|
+
found = True
|
|
304
|
+
break
|
|
305
|
+
if not found:
|
|
306
|
+
raise RuntimeError("PartitionInterfaceStressResponseFunction:CalculateGradientsForTypesAndObjects: control type {} of control object {} is not in the control_types of response {}".format(control_types[itr],controlled_object,self.name))
|
|
307
|
+
|
|
308
|
+
Logger.PrintInfo("PartitionInterfaceStressResponseFunction", "Starting ", control_types," gradients calculation of response ", self.name," for ",controlled_objects)
|
|
309
|
+
startTime = timer.time()
|
|
310
|
+
self.response_function.CalculateGradient()
|
|
311
|
+
Logger.PrintInfo("PartitionInterfaceStressResponseFunction", "Time needed for calculating gradients ",round(timer.time() - startTime,2),"s")
|
|
312
|
+
|
|
313
|
+
class MaxOverhangAngleResponseFunction(BaseResponseFunction):
|
|
314
|
+
|
|
315
|
+
def __init__(self,response_name, response_settings,model):
|
|
316
|
+
|
|
317
|
+
self.default_response_settings = KM.Parameters("""{
|
|
318
|
+
"evaluated_objects": [],
|
|
319
|
+
"control_types": [],
|
|
320
|
+
"controlled_objects": [],
|
|
321
|
+
"print_direction": [],
|
|
322
|
+
"max_angle": -30.0,
|
|
323
|
+
"heaviside_beta": 25.0,
|
|
324
|
+
"penalty_factor": 2.0,
|
|
325
|
+
"gradient_settings":{
|
|
326
|
+
"step_size" : 1e-6,
|
|
327
|
+
"gradient_mode": "finite_differencing"
|
|
328
|
+
}
|
|
329
|
+
}""")
|
|
330
|
+
|
|
331
|
+
response_settings.RecursivelyValidateAndAssignDefaults(self.default_response_settings)
|
|
332
|
+
|
|
333
|
+
self.type = "max_overhang_angle"
|
|
334
|
+
self.variable = "MAX_OVERHANG_ANGLE"
|
|
335
|
+
super().__init__(response_name, response_settings, model)
|
|
336
|
+
|
|
337
|
+
self.supported_control_types = ["shape"]
|
|
338
|
+
self.gradients_variables = {"shape":"D_MAX_OVERHANG_ANGLE_D_X"}
|
|
339
|
+
|
|
340
|
+
if len(self.evaluated_model_parts) != 1:
|
|
341
|
+
raise RuntimeError("MaxOverhangAngleResponseFunction: 'evaluated_objects' of response '{}' must have only one entry !".format(self.name))
|
|
342
|
+
|
|
343
|
+
for control_type in self.control_types:
|
|
344
|
+
if not control_type in self.supported_control_types:
|
|
345
|
+
raise RuntimeError("MaxOverhangAngleResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
346
|
+
|
|
347
|
+
root_model_part_name = self.evaluated_model_parts[0].split(".")[0]
|
|
348
|
+
for evaluated_model_part in self.evaluated_model_parts:
|
|
349
|
+
if evaluated_model_part.split(".")[0] != root_model_part_name:
|
|
350
|
+
raise RuntimeError("MaxOverhangAngleResponseFunction: evaluated_model_parts of max_overhang_angle response must have the same root model part !")
|
|
351
|
+
|
|
352
|
+
self.root_model_part = self.model.GetModelPart(root_model_part_name)
|
|
353
|
+
|
|
354
|
+
# add vars and response
|
|
355
|
+
for control_type in self.control_types:
|
|
356
|
+
self.root_model_part.AddNodalSolutionStepVariable(KM.KratosGlobals.GetVariable(self.gradients_variables[control_type]))
|
|
357
|
+
self.root_model_part.AddNodalSolutionStepVariable(KM.KratosGlobals.GetVariable(self.gradients_variables[control_type]))
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def GetVariableName(self):
|
|
361
|
+
return self.variable
|
|
362
|
+
|
|
363
|
+
def GetGradientsVariablesName(self):
|
|
364
|
+
return self.gradients_variables
|
|
365
|
+
|
|
366
|
+
def GetGradientVariableNameForType(self,control_type, raise_error=True):
|
|
367
|
+
if raise_error:
|
|
368
|
+
if not control_type in self.supported_control_types:
|
|
369
|
+
raise RuntimeError("MaxOverhangAngleResponseFunction: type {} in 'control_types' of response '{}' is not supported, supported types are {} !".format(control_type,self.name,self.supported_control_types))
|
|
370
|
+
|
|
371
|
+
return self.gradients_variables[control_type]
|
|
372
|
+
|
|
373
|
+
def Initialize(self):
|
|
374
|
+
super().Initialize()
|
|
375
|
+
|
|
376
|
+
def CalculateValue(self):
|
|
377
|
+
Logger.PrintInfo("MaxOverhangAngleResponseFunction:CalculateValue: Starting value calculation for response ", self.name)
|
|
378
|
+
startTime = timer.time()
|
|
379
|
+
|
|
380
|
+
r_evaluated_model_parts: 'list[KM.ModelPart]' = []
|
|
381
|
+
for model_part_name in self.evaluated_model_parts:
|
|
382
|
+
r_evaluated_model_parts.append(self.model[model_part_name])
|
|
383
|
+
|
|
384
|
+
self.value = KOA.ResponseUtils.MaxOverhangAngleResponseUtils.CalculateValue(r_evaluated_model_parts,self.response_settings)
|
|
385
|
+
|
|
386
|
+
Logger.PrintInfo("MaxOverhangAngleResponseFunction:CalculateValue: Time needed for calculating value ",round(timer.time() - startTime,2),"s")
|
|
387
|
+
return self.value
|
|
388
|
+
|
|
389
|
+
def CalculateGradientsForTypesAndObjects(self,control_types,controlled_objects,raise_error=True):
|
|
390
|
+
|
|
391
|
+
r_evaluated_model_parts: 'list[KM.ModelPart]' = []
|
|
392
|
+
for model_part_name in self.evaluated_model_parts:
|
|
393
|
+
r_evaluated_model_parts.append(self.model[model_part_name])
|
|
394
|
+
|
|
395
|
+
r_controlled_model_parts: 'list[KM.ModelPart]' = []
|
|
396
|
+
for model_part_name in controlled_objects:
|
|
397
|
+
r_controlled_model_parts.append(self.model[model_part_name])
|
|
398
|
+
|
|
399
|
+
Logger.PrintInfo("MaxOverhangAngleResponseFunction", "Starting ", control_types," gradients calculation of response ", self.name," for ",controlled_objects)
|
|
400
|
+
startTime = timer.time()
|
|
401
|
+
KOA.ResponseUtils.MaxOverhangAngleResponseUtils.CalculateSensitivity(r_evaluated_model_parts,{KM.SHAPE_SENSITIVITY: r_controlled_model_parts},self.response_settings)
|
|
402
|
+
|
|
403
|
+
#TODO: After restructuring this copying data should be removed
|
|
404
|
+
for model_part in r_controlled_model_parts:
|
|
405
|
+
for node in model_part.Nodes:
|
|
406
|
+
shape_sens = node.GetValue(KM.SHAPE_SENSITIVITY)
|
|
407
|
+
node.SetSolutionStepValue(KM.KratosGlobals.GetVariable("D_MAX_OVERHANG_ANGLE_D_X"), shape_sens)
|
|
408
|
+
|
|
409
|
+
Logger.PrintInfo("MaxOverhangAngleResponseFunction", "Time needed for calculating gradients ",round(timer.time() - startTime,2),"s")
|
|
410
|
+
|
KratosMultiphysics/OptimizationApplication/responses/analysis_based_response_function_factory.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# importing the Kratos Library
|
|
2
|
+
from . import structural_responses
|
|
3
|
+
from . import additive_manufacturing_responses
|
|
4
|
+
|
|
5
|
+
def CreateResponseFunction(response_name,response_type,response_settings, response_analysis,model):
|
|
6
|
+
|
|
7
|
+
if response_type == "strain_energy":
|
|
8
|
+
return structural_responses.StrainEnergyResponseFunction(response_name,response_settings,response_analysis,model)
|
|
9
|
+
|
|
10
|
+
elif response_type == "stress":
|
|
11
|
+
return structural_responses.StressResponseFunction(response_name,response_settings,response_analysis,model)
|
|
12
|
+
|
|
13
|
+
elif response_type == "partition_interface_stress":
|
|
14
|
+
return additive_manufacturing_responses.PartitionInterfaceStressResponseFunction(response_name,response_settings,model)
|
KratosMultiphysics/OptimizationApplication/responses/analysis_free_response_function_factory.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# importing the Kratos Library
|
|
2
|
+
from . import structural_responses
|
|
3
|
+
from . import additive_manufacturing_responses
|
|
4
|
+
|
|
5
|
+
def CreateResponseFunction(response_name,response_type,response_settings,model):
|
|
6
|
+
|
|
7
|
+
if response_type == "mass":
|
|
8
|
+
return structural_responses.MassResponseFunction(response_name,response_settings,model)
|
|
9
|
+
elif response_type == "interface":
|
|
10
|
+
return additive_manufacturing_responses.InterfaceResponseFunction(response_name,response_settings,model)
|
|
11
|
+
elif response_type == "partition_mass":
|
|
12
|
+
return additive_manufacturing_responses.PartitionMassResponseFunction(response_name,response_settings,model)
|
|
13
|
+
elif response_type == "am_max_overhang_angle":
|
|
14
|
+
return additive_manufacturing_responses.MaxOverhangAngleResponseFunction(response_name,response_settings,model)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# importing the Kratos Library
|
|
2
|
+
from numpy import gradient
|
|
3
|
+
import KratosMultiphysics as KM
|
|
4
|
+
from KratosMultiphysics import Parameters, Logger
|
|
5
|
+
import KratosMultiphysics.OptimizationApplication as KOA
|
|
6
|
+
|
|
7
|
+
import time as timer
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
# ==============================================================================
|
|
11
|
+
class BaseResponseFunction:
|
|
12
|
+
|
|
13
|
+
def __init__(self,response_name, response_settings, model, response_analysis=None):
|
|
14
|
+
|
|
15
|
+
self.name = response_name
|
|
16
|
+
self.response_settings = response_settings
|
|
17
|
+
self.model = model
|
|
18
|
+
self.analysis = response_analysis
|
|
19
|
+
self.analysis_model_part = None
|
|
20
|
+
if not response_analysis == None:
|
|
21
|
+
self.analysis_model_part = self.analysis._GetSolver().GetComputingModelPart()
|
|
22
|
+
|
|
23
|
+
self.evaluated_model_parts = response_settings["evaluated_objects"].GetStringArray()
|
|
24
|
+
self.controlled_model_parts = response_settings["controlled_objects"].GetStringArray()
|
|
25
|
+
self.control_types = response_settings["control_types"].GetStringArray()
|
|
26
|
+
|
|
27
|
+
def Initialize(self):
|
|
28
|
+
|
|
29
|
+
for evaluated_model_part in self.evaluated_model_parts:
|
|
30
|
+
if not self.analysis == None:
|
|
31
|
+
evaluated_model_part_splitted = evaluated_model_part.split(".")
|
|
32
|
+
if not evaluated_model_part_splitted[0] == self.analysis_model_part.Name:
|
|
33
|
+
raise RuntimeError("BaseResponseFunction:Initialize: root evaluated_model_part {} of response '{}' is not the analysis model!".format(evaluated_model_part_splitted[0],self.name))
|
|
34
|
+
if not self.model.HasModelPart(evaluated_model_part):
|
|
35
|
+
raise RuntimeError("BaseResponseFunction:Initialize: evaluated_model_part {} of response '{}' does not exist!".format(evaluated_model_part,self.name))
|
|
36
|
+
|
|
37
|
+
for controlled_model_part in self.controlled_model_parts:
|
|
38
|
+
if not self.model.HasModelPart(controlled_model_part):
|
|
39
|
+
raise RuntimeError("BaseResponseFunction:Initialize: controlled_model_part {} of response '{}' does not exist!".format(controlled_model_part,self.name))
|
|
40
|
+
|
|
41
|
+
def CalculateValue(self):
|
|
42
|
+
raise RuntimeError("BaseResponseFunction:CalculateValue: Not implemented ! ")
|
|
43
|
+
|
|
44
|
+
def GetValue(self):
|
|
45
|
+
raise RuntimeError("BaseResponseFunction:GetValue: Not implemented ! ")
|
|
46
|
+
|
|
47
|
+
def CalculateGradients(self):
|
|
48
|
+
raise RuntimeError("BaseResponseFunction:CalculateGradients: Not implemented ! ")
|
|
49
|
+
|
|
50
|
+
def CalculateGradientsForTypeAndObjects(self,control_type,controlled_objects,raise_error=True):
|
|
51
|
+
raise RuntimeError("BaseResponseFunction:CalculateGradientsForTypeAndObjects: Not implemented ! ")
|
|
52
|
+
|
|
53
|
+
def GetGradients(self):
|
|
54
|
+
raise RuntimeError("BaseResponseFunction:GetGradients: Not implemented ! ")
|
|
55
|
+
|
|
56
|
+
def GetType(self):
|
|
57
|
+
raise RuntimeError("BaseResponseFunction:GetValue: Not implemented ! ")
|
|
58
|
+
|
|
59
|
+
def GetVariableName(self):
|
|
60
|
+
raise RuntimeError("BaseResponseFunction:GetVariableName: Not implemented ! ")
|
|
61
|
+
|
|
62
|
+
def GetGradientsVariablesName(self):
|
|
63
|
+
raise RuntimeError("BaseResponseFunction:GetGradientsVariablesName: Not implemented ! ")
|
|
64
|
+
|
|
65
|
+
def GetGradientVariableNameForType(self,control_type):
|
|
66
|
+
raise RuntimeError("BaseResponseFunction:GetGradientVariableNameForType: Not implemented ! ")
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from math import log
|
|
3
|
+
|
|
4
|
+
import KratosMultiphysics as Kratos
|
|
5
|
+
from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
|
|
6
|
+
from KratosMultiphysics.OptimizationApplication.responses.response_function import SupportedSensitivityFieldVariableTypes
|
|
7
|
+
from KratosMultiphysics.OptimizationApplication.utilities.model_part_utilities import ModelPartOperation
|
|
8
|
+
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
|
|
9
|
+
from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView
|
|
10
|
+
from KratosMultiphysics.OptimizationApplication.utilities.response_utilities import EvaluateValue
|
|
11
|
+
from KratosMultiphysics.OptimizationApplication.utilities.response_utilities import EvaluateGradient
|
|
12
|
+
from KratosMultiphysics.OptimizationApplication.utilities.response_utilities import BinaryOperator
|
|
13
|
+
|
|
14
|
+
class BinaryOperatorResponseFunction(ResponseFunction):
|
|
15
|
+
def __init__(self, response_function_1: ResponseFunction, response_function_2: ResponseFunction, binary_operator: BinaryOperator, optimization_problem: OptimizationProblem):
|
|
16
|
+
if binary_operator == BinaryOperator.DIVIDE:
|
|
17
|
+
# this is because, the optimization_problem data container uses "/" as a path separator.
|
|
18
|
+
super().__init__(f"({response_function_1.GetName()}÷{response_function_2.GetName()})")
|
|
19
|
+
else:
|
|
20
|
+
super().__init__(f"({response_function_1.GetName()}{binary_operator.value}{response_function_2.GetName()})")
|
|
21
|
+
|
|
22
|
+
self.optimization_problem = optimization_problem
|
|
23
|
+
self.response_function_1 = response_function_1
|
|
24
|
+
self.response_function_2 = response_function_2
|
|
25
|
+
self.binary_operator = binary_operator
|
|
26
|
+
self.model_part: Optional[Kratos.ModelPart] = None
|
|
27
|
+
|
|
28
|
+
def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
|
|
29
|
+
vars_list = self.response_function_1.GetImplementedPhysicalKratosVariables()
|
|
30
|
+
vars_list.extend(self.response_function_2.GetImplementedPhysicalKratosVariables())
|
|
31
|
+
return vars_list
|
|
32
|
+
|
|
33
|
+
def Initialize(self) -> None:
|
|
34
|
+
self.response_function_1.Initialize()
|
|
35
|
+
self.response_function_2.Initialize()
|
|
36
|
+
|
|
37
|
+
if len(self.response_function_1.GetImplementedPhysicalKratosVariables()) != 0 and len(self.response_function_2.GetImplementedPhysicalKratosVariables()) != 0:
|
|
38
|
+
self.model_part = ModelPartOperation(self.response_function_1.GetInfluencingModelPart().GetModel(), ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", [self.response_function_1.GetInfluencingModelPart().FullName(), self.response_function_2.GetInfluencingModelPart().FullName()], False).GetModelPart()
|
|
39
|
+
elif len(self.response_function_1.GetImplementedPhysicalKratosVariables()) != 0:
|
|
40
|
+
self.model_part = self.response_function_1.GetInfluencingModelPart()
|
|
41
|
+
elif len(self.response_function_2.GetImplementedPhysicalKratosVariables()) != 0:
|
|
42
|
+
self.model_part = self.response_function_2.GetInfluencingModelPart()
|
|
43
|
+
|
|
44
|
+
def Check(self) -> None:
|
|
45
|
+
self.response_function_1.Check()
|
|
46
|
+
self.response_function_2.Check()
|
|
47
|
+
|
|
48
|
+
def Finalize(self) -> None:
|
|
49
|
+
self.response_function_1.Finalize()
|
|
50
|
+
self.response_function_2.Finalize()
|
|
51
|
+
|
|
52
|
+
def GetInfluencingModelPart(self) -> Kratos.ModelPart:
|
|
53
|
+
return self.model_part
|
|
54
|
+
|
|
55
|
+
def CalculateValue(self) -> float:
|
|
56
|
+
v1 = EvaluateValue(self.response_function_1, self.optimization_problem)
|
|
57
|
+
v2 = EvaluateValue(self.response_function_2, self.optimization_problem)
|
|
58
|
+
|
|
59
|
+
# now do the binary arithmetics.
|
|
60
|
+
if self.binary_operator == BinaryOperator.ADD:
|
|
61
|
+
return v1 + v2
|
|
62
|
+
elif self.binary_operator == BinaryOperator.SUBTRACT:
|
|
63
|
+
return v1 - v2
|
|
64
|
+
elif self.binary_operator == BinaryOperator.MULTIPLY:
|
|
65
|
+
return v1 * v2
|
|
66
|
+
elif self.binary_operator == BinaryOperator.DIVIDE:
|
|
67
|
+
return v1 / v2
|
|
68
|
+
elif self.binary_operator == BinaryOperator.POWER:
|
|
69
|
+
return v1 ** v2
|
|
70
|
+
|
|
71
|
+
def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
|
|
72
|
+
v1 = EvaluateValue(self.response_function_1, self.optimization_problem)
|
|
73
|
+
v2 = EvaluateValue(self.response_function_2, self.optimization_problem)
|
|
74
|
+
|
|
75
|
+
resp_1_gradients = {variable: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(cta) for variable, cta in physical_variable_gradient_map.items()}
|
|
76
|
+
EvaluateGradient(self.response_function_1, resp_1_gradients, self.optimization_problem)
|
|
77
|
+
|
|
78
|
+
resp_2_gradients = {variable: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(cta) for variable, cta in physical_variable_gradient_map.items()}
|
|
79
|
+
EvaluateGradient(self.response_function_2, resp_2_gradients, self.optimization_problem)
|
|
80
|
+
|
|
81
|
+
for variable, result_cta in physical_variable_gradient_map.items():
|
|
82
|
+
g1_cta = resp_1_gradients[variable]
|
|
83
|
+
g2_cta = resp_2_gradients[variable]
|
|
84
|
+
if self.binary_operator == BinaryOperator.ADD:
|
|
85
|
+
result_cta.data = g1_cta.data + g2_cta.data
|
|
86
|
+
elif self.binary_operator == BinaryOperator.SUBTRACT:
|
|
87
|
+
result_cta.data = g1_cta.data - g2_cta.data
|
|
88
|
+
elif self.binary_operator == BinaryOperator.MULTIPLY:
|
|
89
|
+
result_cta.data = g1_cta.data * v2 + g2_cta.data * v1
|
|
90
|
+
elif self.binary_operator == BinaryOperator.DIVIDE:
|
|
91
|
+
result_cta.data = g1_cta.data / v2 - g2_cta.data * (v1 / v2 ** 2)
|
|
92
|
+
elif self.binary_operator == BinaryOperator.POWER:
|
|
93
|
+
result_cta.data = (g1_cta.data * (v2 / v1) + g2_cta.data * log(v1)) * (v1 ** v2)
|
|
94
|
+
Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(result_cta, perform_store_data_recursively=False, copy=False).StoreData()
|
|
95
|
+
|
|
96
|
+
def GetChildResponses(self) -> 'list[ResponseFunction]':
|
|
97
|
+
return [self.response_function_1, self.response_function_2]
|
|
98
|
+
|
|
99
|
+
def __str__(self) -> str:
|
|
100
|
+
if self.model_part is not None:
|
|
101
|
+
return f"Response [type = {self.__class__.__name__}, name = {self.GetName()}, model part name = {self.model_part.FullName()}]"
|
|
102
|
+
else:
|
|
103
|
+
return f"Response [type = {self.__class__.__name__}, name = {self.GetName()}, model part name = n/a ]"
|