KratosOptimizationApplication 10.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. KratosMultiphysics/.libs/KratosOptimizationApplication.so +0 -0
  2. KratosMultiphysics/.libs/libKratosOptimizationCore.dylib +0 -0
  3. KratosMultiphysics/OptimizationApplication/__init__.py +19 -0
  4. KratosMultiphysics/OptimizationApplication/algorithms/NLOPT_algorithms.py +255 -0
  5. KratosMultiphysics/OptimizationApplication/algorithms/SciPy_algorithms.py +154 -0
  6. KratosMultiphysics/OptimizationApplication/algorithms/__init__.py +0 -0
  7. KratosMultiphysics/OptimizationApplication/algorithms/algorithm.py +78 -0
  8. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_adam.py +68 -0
  9. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_base.py +393 -0
  10. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_gradient_projection.py +355 -0
  11. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_momentum_relaxed_gradient_projection.py +70 -0
  12. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_nesterov_accelarated_gradient.py +60 -0
  13. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_relaxed_gradient_projection.py +263 -0
  14. KratosMultiphysics/OptimizationApplication/algorithms/algorithm_steepest_descent.py +205 -0
  15. KratosMultiphysics/OptimizationApplication/algorithms/standardized_NLOPT_constraint.py +194 -0
  16. KratosMultiphysics/OptimizationApplication/algorithms/standardized_NLOPT_objective.py +191 -0
  17. KratosMultiphysics/OptimizationApplication/algorithms/standardized_SciPy_constraint.py +123 -0
  18. KratosMultiphysics/OptimizationApplication/algorithms/standardized_SciPy_objective.py +148 -0
  19. KratosMultiphysics/OptimizationApplication/algorithms/standardized_constraint.py +180 -0
  20. KratosMultiphysics/OptimizationApplication/algorithms/standardized_objective.py +133 -0
  21. KratosMultiphysics/OptimizationApplication/algorithms/standardized_rgp_constraint.py +268 -0
  22. KratosMultiphysics/OptimizationApplication/analyses_controller.py +75 -0
  23. KratosMultiphysics/OptimizationApplication/controls/control.py +123 -0
  24. KratosMultiphysics/OptimizationApplication/controls/external_response_function_control.py +149 -0
  25. KratosMultiphysics/OptimizationApplication/controls/master_control.py +198 -0
  26. KratosMultiphysics/OptimizationApplication/controls/material/material_properties_control.py +115 -0
  27. KratosMultiphysics/OptimizationApplication/controls/material/simp_control.py +229 -0
  28. KratosMultiphysics/OptimizationApplication/controls/shape/vertex_morphing_shape_control.py +289 -0
  29. KratosMultiphysics/OptimizationApplication/controls/thickness/shell_thickness_control.py +180 -0
  30. KratosMultiphysics/OptimizationApplication/controls_controller.py +205 -0
  31. KratosMultiphysics/OptimizationApplication/convergence_criteria/avg_abs_improvement_conv_criterion.py +98 -0
  32. KratosMultiphysics/OptimizationApplication/convergence_criteria/combined_conv_criterion.py +87 -0
  33. KratosMultiphysics/OptimizationApplication/convergence_criteria/constraint_conv_criterion.py +68 -0
  34. KratosMultiphysics/OptimizationApplication/convergence_criteria/convergence_criterion.py +26 -0
  35. KratosMultiphysics/OptimizationApplication/convergence_criteria/l2_conv_criterion.py +77 -0
  36. KratosMultiphysics/OptimizationApplication/convergence_criteria/magnitude_reduction_conv_criterion.py +85 -0
  37. KratosMultiphysics/OptimizationApplication/convergence_criteria/max_iter_conv_criterion.py +48 -0
  38. KratosMultiphysics/OptimizationApplication/convergence_criteria/patience_conv_criterion.py +116 -0
  39. KratosMultiphysics/OptimizationApplication/convergence_criteria/target_value_conv_criterion.py +64 -0
  40. KratosMultiphysics/OptimizationApplication/execution_policies/execution_policy.py +46 -0
  41. KratosMultiphysics/OptimizationApplication/execution_policies/execution_policy_decorator.py +67 -0
  42. KratosMultiphysics/OptimizationApplication/execution_policies/independent_analysis_execution_policy.py +78 -0
  43. KratosMultiphysics/OptimizationApplication/execution_policies/kratos_analysis_execution_policy.py +137 -0
  44. KratosMultiphysics/OptimizationApplication/execution_policies/stepping_analysis_execution_policy.py +88 -0
  45. KratosMultiphysics/OptimizationApplication/filtering/explicit_filter.py +124 -0
  46. KratosMultiphysics/OptimizationApplication/filtering/filter.py +188 -0
  47. KratosMultiphysics/OptimizationApplication/filtering/filter_utils.py +55 -0
  48. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_analysis.py +139 -0
  49. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_scalar_solver.py +39 -0
  50. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_shape_solver.py +67 -0
  51. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_solver_base.py +275 -0
  52. KratosMultiphysics/OptimizationApplication/filtering/helmholtz_vector_solver.py +39 -0
  53. KratosMultiphysics/OptimizationApplication/filtering/implicit_filter.py +192 -0
  54. KratosMultiphysics/OptimizationApplication/filtering/python_solvers_wrapper_implicit_filters.py +56 -0
  55. KratosMultiphysics/OptimizationApplication/model_part_controllers/connectivity_preserving_model_part_controller.py +72 -0
  56. KratosMultiphysics/OptimizationApplication/model_part_controllers/external_response_function_model_part_controller.py +110 -0
  57. KratosMultiphysics/OptimizationApplication/model_part_controllers/mdpa_model_part_controller.py +44 -0
  58. KratosMultiphysics/OptimizationApplication/model_part_controllers/model_part_controller.py +19 -0
  59. KratosMultiphysics/OptimizationApplication/model_parts_controller.py +92 -0
  60. KratosMultiphysics/OptimizationApplication/optimization_analysis.py +146 -0
  61. KratosMultiphysics/OptimizationApplication/optimizations_controller.py +223 -0
  62. KratosMultiphysics/OptimizationApplication/optimizer.py +61 -0
  63. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_ascii_output_process.py +212 -0
  64. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_field_output_process.py +122 -0
  65. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_graph_output_process.py +184 -0
  66. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_hdf5_output_process.py +84 -0
  67. KratosMultiphysics/OptimizationApplication/processes/optimization_problem_vtu_output_process.py +94 -0
  68. KratosMultiphysics/OptimizationApplication/processes/spatial_statistics_computation_process.py +81 -0
  69. KratosMultiphysics/OptimizationApplication/responses/__init__.py +0 -0
  70. KratosMultiphysics/OptimizationApplication/responses/additive_manufacturing_responses.py +410 -0
  71. KratosMultiphysics/OptimizationApplication/responses/analysis_based_response_function_factory.py +14 -0
  72. KratosMultiphysics/OptimizationApplication/responses/analysis_free_response_function_factory.py +14 -0
  73. KratosMultiphysics/OptimizationApplication/responses/base_response.py +66 -0
  74. KratosMultiphysics/OptimizationApplication/responses/binary_operator_response_function.py +103 -0
  75. KratosMultiphysics/OptimizationApplication/responses/combined_response_function.py +127 -0
  76. KratosMultiphysics/OptimizationApplication/responses/discrete_value_residual_response_function.py +131 -0
  77. KratosMultiphysics/OptimizationApplication/responses/evaluation_response_function.py +68 -0
  78. KratosMultiphysics/OptimizationApplication/responses/external_response_function.py +87 -0
  79. KratosMultiphysics/OptimizationApplication/responses/geometric_centroid_deviation_response_function.py +97 -0
  80. KratosMultiphysics/OptimizationApplication/responses/linear_strain_energy_response_function.py +72 -0
  81. KratosMultiphysics/OptimizationApplication/responses/literal_value_response_function.py +33 -0
  82. KratosMultiphysics/OptimizationApplication/responses/log_response_function.py +47 -0
  83. KratosMultiphysics/OptimizationApplication/responses/mass_response_function.py +71 -0
  84. KratosMultiphysics/OptimizationApplication/responses/response_function.py +126 -0
  85. KratosMultiphysics/OptimizationApplication/responses/response_routine.py +158 -0
  86. KratosMultiphysics/OptimizationApplication/responses/structural_responses.py +335 -0
  87. KratosMultiphysics/OptimizationApplication/responses_controller.py +390 -0
  88. KratosMultiphysics/OptimizationApplication/utilities/buffered_dict.py +399 -0
  89. KratosMultiphysics/OptimizationApplication/utilities/component_data_view.py +74 -0
  90. KratosMultiphysics/OptimizationApplication/utilities/helper_utilities.py +40 -0
  91. KratosMultiphysics/OptimizationApplication/utilities/logger_utilities.py +222 -0
  92. KratosMultiphysics/OptimizationApplication/utilities/model_part_utilities.py +117 -0
  93. KratosMultiphysics/OptimizationApplication/utilities/opt_line_search.py +173 -0
  94. KratosMultiphysics/OptimizationApplication/utilities/opt_projection.py +191 -0
  95. KratosMultiphysics/OptimizationApplication/utilities/optimization_problem.py +237 -0
  96. KratosMultiphysics/OptimizationApplication/utilities/optimization_problem_utilities.py +237 -0
  97. KratosMultiphysics/OptimizationApplication/utilities/response_utilities.py +249 -0
  98. KratosMultiphysics/OptimizationApplication/utilities/timer.py +45 -0
  99. KratosMultiphysics/OptimizationApplication/utilities/union_utilities.py +6 -0
  100. kratosoptimizationapplication-10.4.4.dist-info/METADATA +25 -0
  101. kratosoptimizationapplication-10.4.4.dist-info/RECORD +106 -0
  102. kratosoptimizationapplication-10.4.4.dist-info/WHEEL +6 -0
  103. kratosoptimizationapplication.dylibs/libKratosCore.dylib +4 -0
  104. kratosoptimizationapplication.dylibs/libgcc_s.1.1.dylib +0 -0
  105. kratosoptimizationapplication.dylibs/libgomp.1.dylib +0 -0
  106. kratosoptimizationapplication.dylibs/libstdc++.6.dylib +0 -0
@@ -0,0 +1,127 @@
1
+ from typing import Optional
2
+
3
+ import KratosMultiphysics as Kratos
4
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
5
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
6
+ from KratosMultiphysics.OptimizationApplication.utilities.model_part_utilities import ModelPartOperation
7
+ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
8
+ from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView
9
+
10
+ def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> ResponseFunction:
11
+ if not parameters.Has("name"):
12
+ raise RuntimeError(f"CombinedResponseFunction instantiation requires a \"name\" in parameters [ parameters = {parameters}].")
13
+ if not parameters.Has("settings"):
14
+ raise RuntimeError(f"CombinedResponseFunction instantiation requires a \"settings\" in parameters [ parameters = {parameters}].")
15
+
16
+ return CombinedResponseFunction(parameters["name"].GetString(), model, parameters["settings"], optimization_problem)
17
+
18
+ class CombinedResponseFunction(ResponseFunction):
19
+ """Response function to combine multiple response functions.
20
+
21
+ This response function can combine multiple response functions to a single response function.
22
+ Following methods are used to combine the response values:
23
+ 1. weighted sum - Weighted summation of responses list is used as the combined response function value.
24
+
25
+ """
26
+ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
27
+ super().__init__(name)
28
+
29
+ default_settings = Kratos.Parameters("""{
30
+ "combining_method" : "sum",
31
+ "combining_responses": [
32
+ {
33
+ "response_name" : "",
34
+ "response_weight": 0.0
35
+ }
36
+ ]
37
+ }""")
38
+ parameters.ValidateAndAssignDefaults(default_settings)
39
+ self.combining_method = parameters["combining_method"].GetString()
40
+
41
+ self.model = model
42
+ self.model_part: Optional[Kratos.ModelPart] = None
43
+ self.optimization_problem = optimization_problem
44
+
45
+ self.list_of_responses: 'list[tuple[ResponseFunction, float]]' = []
46
+ for response_params in parameters["combining_responses"].values():
47
+ response_params.ValidateAndAssignDefaults(default_settings["combining_responses"].values()[0])
48
+ response_name = response_params["response_name"].GetString()
49
+
50
+ if response_name not in [response.GetName() for response in optimization_problem.GetListOfResponses()]:
51
+ raise RuntimeError(f"\"{response_name}\" not found in the optimization problem. Please check whether this response is defined before the \"{self.GetName()}\".")
52
+
53
+ self.list_of_responses.append(
54
+ (
55
+ self.optimization_problem.GetResponse(response_name),
56
+ response_params["response_weight"].GetDouble()
57
+ ))
58
+
59
+ if len(self.list_of_responses) == 0:
60
+ raise RuntimeError(f"Combined response \"{self.GetName()}\" does not have any responses to combine.")
61
+
62
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
63
+ variables_list: 'list[SupportedSensitivityFieldVariableTypes]' = []
64
+ for response, _ in self.list_of_responses:
65
+ variables_list.extend(response.GetImplementedPhysicalKratosVariables())
66
+ return list(set(variables_list))
67
+
68
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
69
+ influencing_model_part_names = [response.GetInfluencingModelPart().FullName() for response, _ in self.list_of_responses]
70
+ model_part_operation = ModelPartOperation(self.model, ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", influencing_model_part_names, False)
71
+ self.model_part = model_part_operation.GetModelPart()
72
+ return self.model_part
73
+
74
+ def Initialize(self) -> None:
75
+ for response, _ in self.list_of_responses:
76
+ response.Initialize()
77
+
78
+ component_data_view = ComponentDataView(self, self.optimization_problem)
79
+ component_data_view.SetDataBuffer(1)
80
+ self.buffered_data = component_data_view.GetBufferedData()
81
+ self.unbuffered_data = component_data_view.GetUnBufferedData()
82
+
83
+ def Check(self) -> None:
84
+ for response, _ in self.list_of_responses:
85
+ response.Check()
86
+
87
+ def Finalize(self) -> None:
88
+ for response, _ in self.list_of_responses:
89
+ response.Finalize()
90
+
91
+ def CalculateValue(self) -> float:
92
+ if self.combining_method == "sum":
93
+ value = 0.0
94
+ for response, weight in self.list_of_responses:
95
+ response_value = response.CalculateValue()
96
+ value += response_value * weight
97
+ self.buffered_data.SetValue(f"{response.GetName()}", response_value, overwrite=True)
98
+ else:
99
+ raise RuntimeError(f"Unsupported combining_method = \"{self.combining_method}\". Followings are supported:\n\tsum")
100
+ return value
101
+
102
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
103
+ # make everything zeros
104
+ for _, combined_tensor_adaptor in physical_variable_gradient_map.items():
105
+ combined_tensor_adaptor.data[:] = 0.0
106
+ Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(combined_tensor_adaptor, perform_store_data_recursively=False, copy=False).StoreData()
107
+
108
+ for response_function, weight in self.list_of_responses:
109
+ # get the map for the response function
110
+ sub_physical_variable_combined_tensor_adaptor: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]' = {}
111
+ for physical_variable, combined_tensor_adaptor in physical_variable_gradient_map.items():
112
+ if physical_variable in response_function.GetImplementedPhysicalKratosVariables():
113
+ sub_physical_variable_combined_tensor_adaptor[physical_variable] = combined_tensor_adaptor.Clone()
114
+
115
+ # calculate the gradients
116
+ response_function.CalculateGradient(sub_physical_variable_combined_tensor_adaptor)
117
+
118
+ # now aggregate the gradients
119
+ for physical_variable, local_combined_tensor_adaptor in sub_physical_variable_combined_tensor_adaptor.items():
120
+ self.unbuffered_data.SetValue(f"d{response_function.GetName()}_d{physical_variable.Name()}", local_combined_tensor_adaptor.Clone(), overwrite=True)
121
+ if self.combining_method == "sum":
122
+ physical_variable_gradient_map[physical_variable].data[:] += local_combined_tensor_adaptor.data[:] * weight
123
+ else:
124
+ raise RuntimeError(f"Unsupported combining_method = \"{self.combining_method}\". Followings are supported:\n\tsum")
125
+
126
+ for _, combined_tensor_adaptor in physical_variable_gradient_map.items():
127
+ Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(combined_tensor_adaptor, perform_store_data_recursively=False, copy=False).StoreData()
@@ -0,0 +1,131 @@
1
+ import numpy
2
+ from typing import Optional
3
+
4
+ import KratosMultiphysics as Kratos
5
+ import KratosMultiphysics.OptimizationApplication as KratosOA
6
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
7
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
8
+ from KratosMultiphysics.OptimizationApplication.utilities.model_part_utilities import ModelPartOperation
9
+
10
+ def Factory(model: Kratos.Model, parameters: Kratos.Parameters, _) -> ResponseFunction:
11
+ if not parameters.Has("name"):
12
+ raise RuntimeError(f"DiscreteValueResidualResponseFunction instantiation requires a \"name\" in parameters [ parameters = {parameters}].")
13
+ if not parameters.Has("settings"):
14
+ raise RuntimeError(f"DiscreteValueResidualResponseFunction instantiation requires a \"settings\" in parameters [ parameters = {parameters}].")
15
+
16
+ return DiscreteValueResidualResponseFunction(parameters["name"].GetString(), model, parameters["settings"])
17
+
18
+ class DiscreteValueResidualResponseFunction(ResponseFunction):
19
+ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters):
20
+ super().__init__(name)
21
+
22
+ default_settings = Kratos.Parameters("""{
23
+ "evaluated_model_part_names" : [
24
+ "PLEASE_PROVIDE_A_MODEL_PART_NAME"
25
+ ],
26
+ "container_type" : "node_historical",
27
+ "variable_name" : "",
28
+ "residual_type" : "exact",
29
+ "list_of_discrete_values": [0.0]
30
+ }""")
31
+ parameters.ValidateAndAssignDefaults(default_settings)
32
+
33
+ self.model = model
34
+ self.variable: SupportedSensitivityFieldVariableTypes = Kratos.KratosGlobals.GetVariable(parameters["variable_name"].GetString())
35
+ if not isinstance(self.variable, Kratos.DoubleVariable):
36
+ raise RuntimeError(f"Only supports double variables. Provided variable is \"{self.variable.Name()}\".")
37
+
38
+ self.list_of_discrete_values = parameters["list_of_discrete_values"].GetVector()
39
+
40
+ self.residual_type = parameters["residual_type"].GetString()
41
+ if self.residual_type not in ["exact", "logarithm"]:
42
+ raise RuntimeError(f"Unsupported residual_type = \"{self.residual_type}\" requested. Followings are supported:\n\texact\n\tlogarithm")
43
+
44
+ container_type = parameters["container_type"].GetString()
45
+ if container_type == "node_historical":
46
+ self.ta_getter = lambda model_part: Kratos.TensorAdaptors.HistoricalVariableTensorAdaptor(model_part.Nodes, self.variable)
47
+ elif container_type == "node_non_historical":
48
+ self.ta_getter = lambda model_part : Kratos.TensorAdaptors.VariableTensorAdaptor(model_part.Nodes, self.variable)
49
+ elif container_type == "condition":
50
+ self.ta_getter = lambda model_part : Kratos.TensorAdaptors.VariableTensorAdaptor(model_part.Conditions, self.variable)
51
+ elif container_type == "condition_properties":
52
+ self.ta_getter = lambda model_part : KratosOA.TensorAdaptors.PropertiesVariableTensorAdaptor(model_part.Conditions, self.variable)
53
+ elif container_type == "element":
54
+ self.ta_getter = lambda model_part : Kratos.TensorAdaptors.VariableTensorAdaptor(model_part.Elements, self.variable)
55
+ elif container_type == "element_properties":
56
+ self.ta_getter = lambda model_part : KratosOA.TensorAdaptors.PropertiesVariableTensorAdaptor(model_part.Elements, self.variable)
57
+ else:
58
+ raise RuntimeError(f"Unsupported container_type = \"{container_type}\" requested. Followings are supported:\n\tnode_historical\n\tnode_non_historical\n\tcondition\n\tcondition_properties\n\telement\n\telement_properties")
59
+
60
+ evaluated_model_part_names = parameters["evaluated_model_part_names"].GetStringArray()
61
+ if len(evaluated_model_part_names) == 0:
62
+ raise RuntimeError(f"No model parts were provided for DiscreteValueResidualResponseFunction. [ response name = \"{self.GetName()}\"]")
63
+
64
+ self.model_part_operation = ModelPartOperation(self.model, ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", evaluated_model_part_names, False)
65
+ self.model_part: Optional[Kratos.ModelPart] = None
66
+
67
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
68
+ return [self.variable]
69
+
70
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
71
+ if self.model_part is None:
72
+ raise RuntimeError("Please call DiscreteValueResidualResponseFunction::Initialize first.")
73
+ return self.model_part
74
+
75
+ def Initialize(self) -> None:
76
+ self.model_part = self.model_part_operation.GetModelPart()
77
+
78
+ def Check(self) -> None:
79
+ pass
80
+
81
+ def Finalize(self) -> None:
82
+ pass
83
+
84
+ def CalculateValue(self) -> float:
85
+ ta = self.ta_getter(self.model_part)
86
+ ta.CollectData()
87
+
88
+ resultant = Kratos.TensorAdaptors.DoubleTensorAdaptor(ta)
89
+
90
+ if self.residual_type == "exact":
91
+ resultant.data[:] = 1.0
92
+ elif self.residual_type == "logarithm":
93
+ resultant.data[:] = 0.0
94
+
95
+ for value in self.list_of_discrete_values:
96
+ if self.residual_type == "exact":
97
+ resultant.data[:] *= (ta.data[:] - value) ** 2
98
+ elif self.residual_type == "logarithm":
99
+ resultant.data[:] += numpy.log((ta.data[:] - value) ** 2)
100
+
101
+ return numpy.sum(resultant.data)
102
+
103
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
104
+ values = self.ta_getter(self.model_part)
105
+ values.CollectData()
106
+
107
+ # calculate the gradients
108
+ for physical_variable, cta in physical_variable_gradient_map.items():
109
+ if physical_variable == self.variable:
110
+
111
+ # initialize the current tensor adaptor
112
+ for ta in cta.GetTensorAdaptors():
113
+ ta.data[:] = 0.0
114
+
115
+ for ta in cta.GetTensorAdaptors():
116
+ for i, value_i in enumerate(self.list_of_discrete_values):
117
+ if self.residual_type == "exact":
118
+ partial_gradient_ta = Kratos.TensorAdaptors.DoubleTensorAdaptor(ta)
119
+ partial_gradient_ta.data[:] = 1.0
120
+ for j, value_j in enumerate(self.list_of_discrete_values):
121
+ if i == j:
122
+ partial_gradient_ta.data *= (values.data[:] - value_j) * 2.0
123
+ else:
124
+ partial_gradient_ta.data *= (values.data[:] - value_j) ** 2
125
+ ta.data[:] += partial_gradient_ta.data
126
+ elif self.residual_type == "logarithm":
127
+ ta.data[:] += (((values.data - value_i) ** (-2)) * (values.data - value_i) * 2.0)
128
+
129
+ Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(cta, perform_collect_data_recursively=False, copy=False).CollectData()
130
+ else:
131
+ raise RuntimeError(f"Unsupported sensitivity w.r.t. {physical_variable.Name()} requested. Followings are supported sensitivity variables:\n\t{self.variable.Name()}")
@@ -0,0 +1,68 @@
1
+ import KratosMultiphysics as Kratos
2
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
3
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import SupportedSensitivityFieldVariableTypes
4
+ from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView
5
+ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
6
+ from KratosMultiphysics.OptimizationApplication.utilities.buffered_dict import BufferedDict
7
+
8
+ class EvaluationResponseFunction(ResponseFunction):
9
+ def __init__(self, response_function: ResponseFunction, optimization_problem: OptimizationProblem):
10
+ super().__init__(f"Eval_{response_function.GetName()}")
11
+ self.response_function = response_function
12
+ self.optimization_problem = optimization_problem
13
+
14
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
15
+ return self.response_function.GetImplementedPhysicalKratosVariables()
16
+
17
+ def Initialize(self) -> None:
18
+ self.response_function.Initialize()
19
+ if not ComponentDataView("evaluated_responses", self.optimization_problem).HasDataBuffer():
20
+ ComponentDataView("evaluated_responses", self.optimization_problem).SetDataBuffer(1)
21
+
22
+ def Check(self) -> None:
23
+ self.response_function.Check()
24
+
25
+ def Finalize(self) -> None:
26
+ self.response_function.Finalize()
27
+
28
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
29
+ return self.response_function.GetInfluencingModelPart()
30
+
31
+ def CalculateValue(self) -> float:
32
+ # this response is used at the top most level of the evaluated chained responses.
33
+ # so this creates a new data container under the optimization problem to avoid
34
+ # having to compute the same response value twice.
35
+
36
+ buffered_data = ComponentDataView("evaluated_responses", self.optimization_problem).GetBufferedData()
37
+
38
+ # reset data of the evaluation
39
+ self.__ResetEvaluationData(self, buffered_data, "values")
40
+
41
+ # now calculate
42
+ return self.response_function.CalculateValue()
43
+
44
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
45
+ # this response is used at the top most level of the evaluated chained responses.
46
+ # so this creates a new data container under the optimization problem to avoid
47
+ # having to compute the same response gradient twice.
48
+
49
+ unbuffered_data = ComponentDataView("evaluated_responses", self.optimization_problem).GetUnBufferedData()
50
+
51
+ # reset data of the evaluation
52
+ self.__ResetEvaluationData(self, unbuffered_data, "gradients")
53
+
54
+ return self.response_function.CalculateGradient(physical_variable_gradient_map)
55
+
56
+ def GetChildResponses(self) -> 'list[ResponseFunction]':
57
+ return [self.response_function]
58
+
59
+ def __str__(self) -> str:
60
+ return f"Response [type = {self.__class__.__name__}, name = {self.GetName()}]"
61
+
62
+ @staticmethod
63
+ def __ResetEvaluationData(response_function: ResponseFunction, data: BufferedDict, prefix: str) -> None:
64
+ if data.HasValue(f"{prefix}/{response_function.GetName()}"):
65
+ del data[f"{prefix}/{response_function.GetName()}"]
66
+ for child_response in response_function.GetChildResponses():
67
+ # now reset the children
68
+ EvaluationResponseFunction.__ResetEvaluationData(child_response, data, prefix)
@@ -0,0 +1,87 @@
1
+ import numpy
2
+ from typing import Optional
3
+ import KratosMultiphysics as Kratos
4
+ import KratosMultiphysics.OptimizationApplication as KratosOA
5
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
6
+ from KratosMultiphysics.OptimizationApplication.utilities.model_part_utilities import ModelPartOperation
7
+ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
8
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
9
+
10
+ def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> ResponseFunction:
11
+ if not parameters.Has("name"):
12
+ raise RuntimeError(f"ExternalResponseFunction instantiation requires a \"name\" in parameters [ parameters = {parameters}].")
13
+ if not parameters.Has("settings"):
14
+ raise RuntimeError(f"ExternalResponseFunction instantiation requires a \"settings\" in parameters [ parameters = {parameters}].")
15
+
16
+ return ExternalResponseFunction(parameters["name"].GetString(), model, parameters["settings"], optimization_problem)
17
+
18
+ class ExternalResponseFunction(ResponseFunction):
19
+ def __init__(self, response_name: str, model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> None:
20
+ super().__init__(response_name)
21
+
22
+ default_parameters = Kratos.Parameters("""{
23
+ "evaluated_model_part_names": []
24
+ }""")
25
+ parameters.ValidateAndAssignDefaults(default_parameters)
26
+
27
+ self.model = model
28
+ self.optimization_problem = optimization_problem
29
+
30
+ evaluated_model_part_names = parameters["evaluated_model_part_names"].GetStringArray()
31
+ if len(evaluated_model_part_names) == 0:
32
+ raise RuntimeError(f"No model parts were provided for MassResponseFunction. [ response name = \"{self.GetName()}\"]")
33
+ self.model_part_operation = ModelPartOperation(self.model, ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", evaluated_model_part_names, False)
34
+ self.model_part: Optional[Kratos.ModelPart] = None
35
+
36
+ def Initialize(self) -> None:
37
+ self.model_part = self.model_part_operation.GetModelPart()
38
+
39
+ def Check(self) -> None:
40
+ pass
41
+
42
+ def Finalize(self) -> None:
43
+ pass
44
+
45
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
46
+ return [KratosOA.CUSTOM_DESIGN_VARIABLE]
47
+
48
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
49
+ return self.model_part
50
+
51
+ def _GetDesignVariableValues(self) -> 'dict[str, numpy.ndarray]':
52
+ # get the values from the model part nodal non-historical container
53
+ result: 'dict[str, numpy.ndarray]' = {}
54
+ for mp_name in self.model_part_operation.list_of_operation_model_part_full_names:
55
+ ta = Kratos.TensorAdaptors.VariableTensorAdaptor(self.model[mp_name].Nodes, KratosOA.CUSTOM_DESIGN_VARIABLE)
56
+ ta.CollectData()
57
+ result[mp_name] = ta.data
58
+
59
+ return result
60
+
61
+ def _UpdateGradientsFromNumpy(self, numpy_values_map: 'dict[str, numpy.ndarray]', physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
62
+ for i, mp_name in enumerate(self.model_part_operation.list_of_operation_model_part_full_names):
63
+ # assign the sensitivities to the physical_variable_gradient_map
64
+ physical_variable_gradient_map[KratosOA.CUSTOM_DESIGN_VARIABLE].GetTensorAdaptors()[i].data[:] = numpy_values_map[mp_name]
65
+ Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(physical_variable_gradient_map[KratosOA.CUSTOM_DESIGN_VARIABLE], perform_collect_data_recursively=False, copy=False).CollectData()
66
+
67
+ def CalculateValue(self) -> float:
68
+ numpy_values = self._GetDesignVariableValues()[self.model_part_operation.list_of_operation_model_part_full_names[0]]
69
+
70
+ # do the update of the model here with the new values.
71
+ # there after compute the new response value.
72
+
73
+ return float((numpy_values[0]-2) ** 2 + (numpy_values[1]-3) ** 2 + (numpy_values[2]-4) ** 2 + (numpy_values[3]-5))**2
74
+
75
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
76
+ numpy_values = self._GetDesignVariableValues()[self.model_part_operation.list_of_operation_model_part_full_names[0]]
77
+
78
+ # compute the gradients
79
+ df_dx0 = 2 * (numpy_values[0]-2)
80
+ df_dx1 = 2 * (numpy_values[1]-3)
81
+ df_dx2 = 2 * (numpy_values[2]-4)
82
+ df_dx3 = 2 * (numpy_values[3]-5)
83
+
84
+ # create the numpy array of sensitivities
85
+ numpy_exp_map = {self.model_part_operation.list_of_operation_model_part_full_names[0]: numpy.array([df_dx0, df_dx1, df_dx2, df_dx3])}
86
+
87
+ self._UpdateGradientsFromNumpy(numpy_exp_map, physical_variable_gradient_map)
@@ -0,0 +1,97 @@
1
+ from typing import Optional
2
+
3
+ import KratosMultiphysics as Kratos
4
+ import KratosMultiphysics.OptimizationApplication as KratosOA
5
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
6
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
7
+ from KratosMultiphysics.OptimizationApplication.utilities.model_part_utilities import ModelPartOperation
8
+ from KratosMultiphysics.OptimizationApplication.utilities.model_part_utilities import ModelPartUtilities
9
+
10
+ def Factory(model: Kratos.Model, parameters: Kratos.Parameters, _) -> ResponseFunction:
11
+ if not parameters.Has("name"):
12
+ raise RuntimeError(f"GeometricCentroidDeviationResponseFunction instantiation requires a \"name\" in parameters [ parameters = {parameters}].")
13
+ if not parameters.Has("settings"):
14
+ raise RuntimeError(f"GeometricCentroidDeviationResponseFunction instantiation requires a \"settings\" in parameters [ parameters = {parameters}].")
15
+
16
+ return GeometricCentroidDeviationResponseFunction(parameters["name"].GetString(), model, parameters["settings"])
17
+
18
+ class GeometricCentroidDeviationResponseFunction(ResponseFunction):
19
+ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters):
20
+ super().__init__(name)
21
+
22
+ default_settings = Kratos.Parameters("""{
23
+ "evaluated_model_part_names" : [
24
+ "PLEASE_PROVIDE_A_MODEL_PART_NAME"
25
+ ]
26
+ }""")
27
+ parameters.ValidateAndAssignDefaults(default_settings)
28
+
29
+ self.model = model
30
+
31
+ evaluated_model_part_names = parameters["evaluated_model_part_names"].GetStringArray()
32
+ if len(evaluated_model_part_names) == 0:
33
+ raise RuntimeError(f"No model parts were provided for GeometricCentroidDeviationResponseFunction. [ response name = \"{self.GetName()}\"]")
34
+
35
+ self.model_part_operation = ModelPartOperation(self.model, ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", evaluated_model_part_names, False)
36
+ self.model_part: Optional[Kratos.ModelPart] = None
37
+
38
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
39
+ return [KratosOA.SHAPE]
40
+
41
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
42
+ if self.model_part is None:
43
+ raise RuntimeError("Please call GeometricCentroidDeviationResponseFunction::Initialize first.")
44
+ return self.model_part
45
+
46
+ def Initialize(self) -> None:
47
+ self.model_part = self.model_part_operation.GetModelPart()
48
+
49
+ self.model_part_center = Kratos.Array3(0.0)
50
+ number_of_nodes = self.model_part.GetCommunicator().GlobalNumberOfNodes()
51
+
52
+ if number_of_nodes == 0:
53
+ raise RuntimeError(f"The provided model part {self.model_part.FullName()} does not contain any nodes.")
54
+
55
+ for node in self.model_part.Nodes:
56
+ self.model_part_center[0] += node.X
57
+ self.model_part_center[1] += node.Y
58
+ self.model_part_center[2] += node.Z
59
+
60
+ self.model_part_center = self.model_part.GetCommunicator().GetDataCommunicator().SumAll(self.model_part_center)
61
+ self.model_part_center /= number_of_nodes
62
+
63
+ def Check(self) -> None:
64
+ pass
65
+
66
+ def Finalize(self) -> None:
67
+ pass
68
+
69
+ def CalculateValue(self) -> float:
70
+ average_location = Kratos.Array3(0.0)
71
+ for node in self.model_part.Nodes:
72
+ average_location[0] += node.X
73
+ average_location[1] += node.Y
74
+ average_location[2] += node.Z
75
+
76
+ average_location = self.model_part.GetCommunicator().GetDataCommunicator().SumAll(average_location)
77
+
78
+ number_of_nodes = self.model_part.GetCommunicator().GlobalNumberOfNodes()
79
+ self.value_array = (average_location / number_of_nodes - self.model_part_center)
80
+ return self.value_array[0] ** 2 + self.value_array[1] ** 2 + self.value_array[2] ** 2
81
+
82
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
83
+ number_of_nodes = self.model_part.GetCommunicator().GlobalNumberOfNodes()
84
+
85
+ # calculate the gradients
86
+ for physical_variable, sensitivity_ta in physical_variable_gradient_map.items():
87
+ if physical_variable == KratosOA.SHAPE:
88
+ Kratos.VariableUtils().SetNonHistoricalVariableToZero(Kratos.SHAPE_SENSITIVITY, self.model_part.Nodes)
89
+ Kratos.VariableUtils().SetNonHistoricalVariable(Kratos.SHAPE_SENSITIVITY, 2.0 * self.value_array / number_of_nodes, self.model_part.Nodes)
90
+ for sub_sensitivity_ta in sensitivity_ta.GetTensorAdaptors():
91
+ if isinstance(sub_sensitivity_ta.GetContainer(), Kratos.NodesArray):
92
+ Kratos.TensorAdaptors.VariableTensorAdaptor(sub_sensitivity_ta, Kratos.SHAPE_SENSITIVITY, copy=False).CollectData()
93
+ else:
94
+ raise RuntimeError(f"Requesting sensitivity w.r.t. SHAPE for a non nodal tensor adaptor. [ Requested container tensor adaptor = {sub_sensitivity_ta} ].")
95
+ sensitivity_ta.CollectData()
96
+ else:
97
+ raise RuntimeError(f"Unsupported sensitivity w.r.t. {physical_variable.Name()} requested. Followings are supported sensitivity variables:\n\tSHAPE")
@@ -0,0 +1,72 @@
1
+ from typing import Optional
2
+
3
+ import KratosMultiphysics as Kratos
4
+ import KratosMultiphysics.OptimizationApplication as KratosOA
5
+ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
6
+ from KratosMultiphysics.OptimizationApplication.execution_policies.execution_policy_decorator import ExecutionPolicyDecorator
7
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
8
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import SupportedSensitivityFieldVariableTypes
9
+ from KratosMultiphysics.OptimizationApplication.utilities.model_part_utilities import ModelPartOperation
10
+
11
+ def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> ResponseFunction:
12
+ if not parameters.Has("name"):
13
+ raise RuntimeError(f"LinearStrainEnergyResponseFunction instantiation requires a \"name\" in parameters [ parameters = {parameters}].")
14
+ if not parameters.Has("settings"):
15
+ raise RuntimeError(f"LinearStrainEnergyResponseFunction instantiation requires a \"settings\" in parameters [ parameters = {parameters}].")
16
+
17
+ return LinearStrainEnergyResponseFunction(parameters["name"].GetString(), model, parameters["settings"], optimization_problem)
18
+
19
+ class LinearStrainEnergyResponseFunction(ResponseFunction):
20
+ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem):
21
+ super().__init__(name)
22
+
23
+ default_settings = Kratos.Parameters("""{
24
+ "primal_analysis_name" : "",
25
+ "perturbation_size" : 1e-8,
26
+ "evaluated_model_part_names" : [
27
+ "PLEASE_PROVIDE_A_MODEL_PART_NAME"
28
+ ]
29
+ }""")
30
+ parameters.ValidateAndAssignDefaults(default_settings)
31
+
32
+ self.perturbation_size = parameters["perturbation_size"].GetDouble()
33
+ self.model = model
34
+ self.primal_analysis_execution_policy_decorator: ExecutionPolicyDecorator = optimization_problem.GetExecutionPolicy(parameters["primal_analysis_name"].GetString())
35
+
36
+ evaluated_model_part_names = parameters["evaluated_model_part_names"].GetStringArray()
37
+ if len(evaluated_model_part_names) == 0:
38
+ raise RuntimeError(f"No model parts were provided for LinearStrainEnergyResponseFunction. [ response name = \"{self.GetName()}\"]")
39
+
40
+ self.model_part_operation = ModelPartOperation(self.model, ModelPartOperation.OperationType.UNION, f"response_{self.GetName()}", evaluated_model_part_names, False)
41
+ self.model_part: Optional[Kratos.ModelPart] = None
42
+
43
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
44
+ return [KratosOA.SHAPE, Kratos.YOUNG_MODULUS, Kratos.THICKNESS, Kratos.POISSON_RATIO]
45
+
46
+ def Initialize(self) -> None:
47
+ self.model_part = self.model_part_operation.GetModelPart()
48
+
49
+ def Check(self) -> None:
50
+ pass
51
+
52
+ def Finalize(self) -> None:
53
+ pass
54
+
55
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
56
+ return self.primal_analysis_execution_policy_decorator.GetAnalysisModelPart()
57
+
58
+ def CalculateValue(self) -> float:
59
+ self.primal_analysis_execution_policy_decorator.Execute()
60
+ return KratosOA.ResponseUtils.LinearStrainEnergyResponseUtils.CalculateValue(self.model_part)
61
+
62
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
63
+ # calculate the gradients
64
+ for physical_variable, cta in physical_variable_gradient_map.items():
65
+ KratosOA.ResponseUtils.LinearStrainEnergyResponseUtils.CalculateGradient(
66
+ physical_variable,
67
+ self.GetInfluencingModelPart(),
68
+ cta,
69
+ self.perturbation_size)
70
+
71
+ def __str__(self) -> str:
72
+ return f"Response [type = {self.__class__.__name__}, name = {self.GetName()}, model part name = {self.model_part.FullName()}]"
@@ -0,0 +1,33 @@
1
+ import KratosMultiphysics as Kratos
2
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
3
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
4
+
5
+ class LiteralValueResponseFunction(ResponseFunction):
6
+ def __init__(self, value: float):
7
+ super().__init__(str(value))
8
+
9
+ self.value = value
10
+
11
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
12
+ return []
13
+
14
+ def Initialize(self) -> None:
15
+ pass
16
+
17
+ def Check(self) -> None:
18
+ pass
19
+
20
+ def Finalize(self) -> None:
21
+ pass
22
+
23
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
24
+ raise RuntimeError(f"The literal value response function does not have an influencing model part.")
25
+
26
+ def CalculateValue(self) -> float:
27
+ return self.value
28
+
29
+ def CalculateGradient(self, _: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
30
+ raise RuntimeError(f"The literal value response function does not depend on any variable, hence no gradients.")
31
+
32
+ def __str__(self) -> str:
33
+ return f"Response [type = {self.__class__.__name__}, name = {self.GetName()}]"