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,133 @@
1
+ import KratosMultiphysics as Kratos
2
+ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
3
+ from KratosMultiphysics.OptimizationApplication.responses.response_routine import ResponseRoutine
4
+ from KratosMultiphysics.OptimizationApplication.controls.master_control import MasterControl
5
+ from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView
6
+ from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import DictLogger
7
+ from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import TimeLogger
8
+ from KratosMultiphysics.OptimizationApplication.utilities.response_utilities import EvaluateResponseExpression
9
+ from KratosMultiphysics.kratos_utilities import IssueDeprecationWarning
10
+
11
+ class StandardizedObjective(ResponseRoutine):
12
+ """Standardized objective response function
13
+
14
+ This class transformed a user-given optimization problem into the standard format.
15
+ Supported objective types:
16
+ "minimization",
17
+ "maximization"
18
+
19
+ """
20
+ def __init__(self, parameters: Kratos.Parameters, master_control: MasterControl, optimization_problem: OptimizationProblem, required_buffer_size: int = 2):
21
+ # backward compatibility
22
+ if parameters.Has("response_name"):
23
+ IssueDeprecationWarning(self.__class__.__name__, "\"response_name\" is deprecated. Please use \"response_expression\".")
24
+ parameters.AddString("response_expression", parameters["response_name"].GetString())
25
+ parameters.RemoveValue("response_name")
26
+
27
+ default_parameters = Kratos.Parameters("""{
28
+ "response_expression": "",
29
+ "type" : "",
30
+ "scaling" : 1.0
31
+ }""")
32
+ parameters.ValidateAndAssignDefaults(default_parameters)
33
+
34
+ response = EvaluateResponseExpression(parameters["response_expression"].GetString(), optimization_problem)
35
+
36
+ super().__init__(master_control, response)
37
+
38
+ if required_buffer_size < 2:
39
+ raise RuntimeError(f"Standardized objective requires 2 as minimum buffer size. [ response name = {self.GetResponseName()} ]")
40
+
41
+ component_data_view = ComponentDataView(response, optimization_problem)
42
+ component_data_view.SetDataBuffer(required_buffer_size)
43
+
44
+ self.__optimization_problem = optimization_problem
45
+ self.__buffered_data = component_data_view.GetBufferedData()
46
+ self.__unbuffered_data = component_data_view.GetUnBufferedData()
47
+
48
+ scaling = parameters["scaling"].GetDouble()
49
+ if scaling < 0.0:
50
+ raise RuntimeError(f"Scaling should be always positive [ given scale = {scaling}]")
51
+
52
+ self.__objective_type = parameters["type"].GetString()
53
+ if self.__objective_type == "minimization":
54
+ self.__scaling = scaling
55
+ elif self.__objective_type == "maximization":
56
+ self.__scaling = -scaling
57
+ else:
58
+ raise RuntimeError(f"Requesting unsupported type {self.__objective_type} for objective response function. Supported types are: \n\tminimization\n\tmaximization")
59
+
60
+ def GetInitialValue(self) -> float:
61
+ if self.__unbuffered_data.HasValue("initial_value"):
62
+ return self.__unbuffered_data["initial_value"] * self.__scaling
63
+ else:
64
+ raise RuntimeError(f"Response value for {self.GetResponseName()} is not calculated yet.")
65
+
66
+ def CalculateStandardizedValue(self, control_field: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor, save_value: bool = True) -> float:
67
+ with TimeLogger(f"StandardizedObjective::Calculate {self.GetResponseName()} value", None, "Finished"):
68
+ response_value = self.CalculateValue(control_field)
69
+ standardized_response_value = response_value * self.__scaling
70
+
71
+ if not self.__unbuffered_data.HasValue("initial_value"):
72
+ self.__unbuffered_data["initial_value"] = response_value
73
+
74
+ if save_value:
75
+ if self.__buffered_data.HasValue("value"): del self.__buffered_data["value"]
76
+ self.__buffered_data["value"] = response_value
77
+
78
+ DictLogger("Objective info",self.GetInfo())
79
+
80
+ return standardized_response_value
81
+
82
+ def GetValue(self, step_index: int = 0) -> float:
83
+ return self.__buffered_data.GetValue("value", step_index)
84
+
85
+ def GetStandardizedValue(self, step_index: int = 0) -> float:
86
+ return self.GetValue(step_index) * self.__scaling
87
+
88
+ def CalculateStandardizedGradient(self, save_field: bool = True) -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
89
+
90
+ with TimeLogger(f"StandardizedObjective::Calculate {self.GetResponseName()} gradients", None, "Finished"):
91
+ gradient_cta = self.CalculateGradient()
92
+ if save_field:
93
+ # save the physical gradients for post processing in unbuffered data container.
94
+ for physical_var, physical_gradient in self.GetRequiredPhysicalGradients().items():
95
+ variable_name = f"d{self.GetResponseName()}_d{physical_var.Name()}"
96
+ if self.__unbuffered_data.HasValue(variable_name): del self.__unbuffered_data[variable_name]
97
+ self.__unbuffered_data[variable_name] = Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(physical_gradient)
98
+
99
+ # save the filtered gradients for post processing in unbuffered data container.
100
+ for gradient_ta, control in zip(gradient_cta.GetTensorAdaptors(), self.GetMasterControl().GetListOfControls()):
101
+ variable_name = f"d{self.GetResponseName()}_d{control.GetName()}"
102
+ if self.__unbuffered_data.HasValue(variable_name): del self.__unbuffered_data[variable_name]
103
+ # cloning is a cheap operation, it only moves underlying pointers
104
+ # does not create additional memory.
105
+ self.__unbuffered_data[variable_name] = Kratos.TensorAdaptors.DoubleTensorAdaptor(gradient_ta)
106
+
107
+ gradient_cta.data[:] *= self.__scaling
108
+ Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(gradient_cta, perform_store_data_recursively=False, copy=False).StoreData()
109
+ return gradient_cta
110
+
111
+ def GetRelativeChange(self) -> float:
112
+ if self.__optimization_problem.GetStep() > 0:
113
+ return self.GetStandardizedValue() / self.GetStandardizedValue(1) - 1.0 if abs(self.GetStandardizedValue(1)) > 1e-12 else self.GetStandardizedValue()
114
+ else:
115
+ return 0.0
116
+
117
+ def GetAbsoluteChange(self) -> float:
118
+ return self.GetStandardizedValue() - self.GetInitialValue()
119
+
120
+ def GetInfo(self) -> dict:
121
+ info = {
122
+ "name": self.GetResponseName(),
123
+ "type": self.__objective_type,
124
+ "value": self.GetValue(),
125
+ "std_value": self.GetStandardizedValue(),
126
+ "abs_change": self.GetAbsoluteChange(),
127
+ "rel_change [%]": self.GetRelativeChange() * 100.0
128
+ }
129
+ init_value = self.GetInitialValue()
130
+ if init_value:
131
+ info["abs_change [%]"] = self.GetAbsoluteChange()/init_value * 100
132
+
133
+ return info
@@ -0,0 +1,268 @@
1
+ import KratosMultiphysics as Kratos
2
+ import KratosMultiphysics.OptimizationApplication as KratosOA
3
+ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
4
+ from KratosMultiphysics.OptimizationApplication.responses.response_routine import ResponseRoutine
5
+ from KratosMultiphysics.OptimizationApplication.controls.master_control import MasterControl
6
+ from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView
7
+ from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import DictLogger
8
+ from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import TimeLogger
9
+ from KratosMultiphysics.OptimizationApplication.utilities.response_utilities import EvaluateResponseExpression
10
+ from KratosMultiphysics.kratos_utilities import IssueDeprecationWarning
11
+ from enum import Enum
12
+
13
+
14
+ class ConstraintType(Enum):
15
+ EQUAL = "="
16
+ LOWER = "<"
17
+ LOWEREQ = "<="
18
+ GREATER = ">"
19
+ GREATEREQ = ">="
20
+
21
+ class StandardizedRGPConstraint(ResponseRoutine):
22
+ """Standardized RGP constraint response function
23
+
24
+ This class creates instances to standardize any response function for the specified type of the constraint.
25
+ Supported constraint types:
26
+ "=",
27
+ "<",
28
+ "<=,
29
+ ">",
30
+ ">="
31
+
32
+ The reference value for the constraint either can be the "initial_value" or a specified value.
33
+
34
+ It can be used only with relaxed_gradient_projection_algorithm. The class contains necessary functions to compute critical zones.
35
+
36
+ """
37
+ def __init__(self, parameters: Kratos.Parameters, master_control: MasterControl, optimization_problem: OptimizationProblem, required_buffer_size: int = 4):
38
+ # backward compatibility
39
+ if parameters.Has("response_name"):
40
+ IssueDeprecationWarning(self.__class__.__name__, "\"response_name\" is deprecated. Please use \"response_expression\".")
41
+ parameters.AddString("response_expression", parameters["response_name"].GetString())
42
+ parameters.RemoveValue("response_name")
43
+
44
+ default_parameters = Kratos.Parameters("""{
45
+ "response_expression" : "",
46
+ "type" : "",
47
+ "scaled_ref_value" : 0.0,
48
+ "buffer_factor" : 2.0,
49
+ "max_w_c" : 10.0,
50
+ "tolerance" : 1e-3
51
+ }""")
52
+
53
+ if parameters.Has("scaled_ref_value") and parameters["scaled_ref_value"].IsDouble():
54
+ default_parameters["scaled_ref_value"].SetDouble(0.0)
55
+ elif parameters.Has("scaled_ref_value") and parameters["scaled_ref_value"].GetString() == "initial_value":
56
+ default_parameters["scaled_ref_value"].SetString("initial_value")
57
+ else:
58
+ type = parameters["scaled_ref_value"].GetString()
59
+ raise RuntimeError(f"Provided \"scaled_ref_value\" = {type} is not supported for constraint response functions. Followings are supported options: \n\tinitial_value\n\tfloat value")
60
+
61
+ parameters.ValidateAndAssignDefaults(default_parameters)
62
+
63
+ response = EvaluateResponseExpression(parameters["response_expression"].GetString(), optimization_problem)
64
+
65
+ super().__init__(master_control, response)
66
+
67
+ if required_buffer_size < 4:
68
+ raise RuntimeError(f"Standardized RGP constraint requires 4 as minimum buffer size. [ response name = {self.GetResponseName()} ]")
69
+
70
+ component_data_view = ComponentDataView(response, optimization_problem)
71
+ component_data_view.SetDataBuffer(required_buffer_size)
72
+
73
+ self.__optimization_problem = optimization_problem
74
+ self.__buffered_data = component_data_view.GetBufferedData()
75
+ self.__unbuffered_data = component_data_view.GetUnBufferedData()
76
+
77
+ if parameters["scaled_ref_value"].IsDouble():
78
+ self.__reference_value = parameters["scaled_ref_value"].GetDouble()
79
+ elif parameters["scaled_ref_value"].IsString() and parameters["scaled_ref_value"].GetString() == "initial_value":
80
+ self.__reference_value = None
81
+
82
+
83
+ self.__constraint_type = ConstraintType(parameters["type"].GetString())
84
+ if self.__constraint_type in [ConstraintType.EQUAL, ConstraintType.LOWEREQ, ConstraintType.LOWER]:
85
+ self.__scaling = 1.0
86
+ elif self.__constraint_type in [ConstraintType.GREATEREQ, ConstraintType.GREATER]:
87
+ self.__scaling = -1.0
88
+ if not self.__reference_value is None: self.__reference_value *= -1
89
+ else:
90
+ raise RuntimeError(f"Provided \"type\" = {self.__constraint_type} is not supported in constraint response functions. Followings are supported options: \n\t=\n\t<=\n\t<\n\t>=\n\t>")
91
+
92
+ # buffer coefficients
93
+ self.BSF = parameters["buffer_factor"].GetDouble()
94
+ self.BSF_init = self.BSF
95
+ self.CBV = 0.0
96
+ self.BS = 1e-6
97
+ self.max_w_c = parameters["max_w_c"].GetDouble()
98
+ self.CF = 1.0
99
+
100
+ self.tolerance = parameters["tolerance"].GetDouble()
101
+
102
+ def IsEqualityType(self) -> str:
103
+ return self.__constraint_type == ConstraintType.EQUAL
104
+
105
+ def ComputeW(self) -> float:
106
+ if self.IsEqualityType():
107
+ return max(abs(self.GetStandardizedValue() - (self.CBV - self.BS)), 0.0) / self.BS
108
+ else:
109
+ return max(self.GetStandardizedValue() - (self.CBV - self.BS), 0.0) / self.BS
110
+
111
+ def PredictW(self, value):
112
+ if self.IsEqualityType():
113
+ return max(abs(value - (self.CBV - self.BS)), 0.0) / self.BS
114
+ else:
115
+ return max(value - (self.CBV - self.BS), 0.0) / self.BS
116
+
117
+ def Compute_W_relax(self, w:float) -> float:
118
+ if w <= 0.0:
119
+ return 0.0
120
+ elif w <= 1.0:
121
+ return w
122
+ else:
123
+ return 1.0
124
+
125
+ def Compute_W_correction(self, w:float) -> float:
126
+ if w <= 1.0:
127
+ return 0.0
128
+ elif w <= self.max_w_c:
129
+ return (w - 1.0) * self.BSF_init * self.CF
130
+ else:
131
+ return (self.max_w_c - 1) * self.BSF_init * self.CF
132
+
133
+ def UpdateBufferSize(self):
134
+ step = self.__optimization_problem.GetStep() + 1
135
+ if step == 1:
136
+ return
137
+
138
+ max_step = min(step, self.__buffered_data.GetBufferSize())
139
+ values = []
140
+ delta_values = []
141
+ abs_delta_values = []
142
+ for index in range(max_step):
143
+ values.append(self.GetStandardizedValue(index))
144
+ if index > 0:
145
+ delta_values.append(values[index - 1] - values[index])
146
+ abs_delta_values.append(abs(values[index - 1] - values[index]))
147
+
148
+ max_delta = max(abs_delta_values)
149
+
150
+ # # Update CBV if violating
151
+ if self.IsEqualityType():
152
+ if step > 1:
153
+ if values[0] > 0.0 and values[1] > 0.0 and delta_values[0] > 0.0:
154
+ self.CF += 0.5
155
+
156
+ if values[0] < 0.0 and values[1] < 0.0 and delta_values[0] < 0.0:
157
+ self.CF += 0.5
158
+ else:
159
+ if step > 1:
160
+ if values[0] > 0.0 and values[1] > 0.0 and delta_values[0] > 0.0:
161
+ self.CF += 0.5
162
+
163
+ if values[0] < 0.0 and values[1] < 0.0 and delta_values[0] < 0.0:
164
+ self.CF -= 0.5
165
+ self.CF = max (self.CF, 1.0)
166
+
167
+ self.BS = max(self.BSF * max_delta, 1e-6)
168
+ # Update BSF if zig zaging
169
+ if step > 3:
170
+ if delta_values[0] * delta_values[1] < 0.0 and delta_values[1] * delta_values[2] < 0.0:
171
+ self.BSF += 1
172
+
173
+ print(f"RGP Constraint {self.GetResponseName()}:: UpdateBufferSize")
174
+ print(f"RGP Constraint {self.GetResponseName()}:: CBV = {self.CBV}")
175
+ print(f"RGP Constraint {self.GetResponseName()}:: BSF = {self.BSF}")
176
+ print(f"RGP Constraint {self.GetResponseName()}:: BS = {self.BS}")
177
+ print(f"RGP Constraint {self.GetResponseName()}:: CF = {self.CF}")
178
+
179
+ def IsActive(self):
180
+ return self.ComputeW() > 0.0
181
+
182
+ def IsSatisfied(self, value=None):
183
+ if not value:
184
+ value = abs(self.GetStandardizedValue()) if self.IsEqualityType() else self.GetStandardizedValue()
185
+ if self.IsEqualityType():
186
+ if abs(value) <= self.tolerance: return True
187
+ else: return False
188
+ else:
189
+ if value <= self.tolerance: return True
190
+ else: return False
191
+
192
+ def GetReferenceValue(self) -> float:
193
+ if self.__reference_value is not None:
194
+ return self.__reference_value
195
+ else:
196
+ if self.__unbuffered_data.HasValue("initial_value"):
197
+ return self.__unbuffered_data["initial_value"] * self.__scaling
198
+ else:
199
+ raise RuntimeError(f"Response value for {self.GetResponseName()} is not calculated yet.")
200
+
201
+ def CalculateStandardizedValue(self, control_field: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor, save_value: bool = True) -> float:
202
+ with TimeLogger(f"StandardizedRGPConstraint::Calculate {self.GetResponseName()} value", None, "Finished"):
203
+ response_value = self.CalculateValue(control_field)
204
+ standardized_response_value = response_value * self.__scaling
205
+
206
+ if not self.__unbuffered_data.HasValue("initial_value"):
207
+ self.__unbuffered_data["initial_value"] = response_value
208
+
209
+ standardized_response_value -= self.GetReferenceValue()
210
+
211
+ if save_value:
212
+ if self.__buffered_data.HasValue("value"): del self.__buffered_data["value"]
213
+ if self.__buffered_data.HasValue("std_value"): del self.__buffered_data["std_value"]
214
+ self.__buffered_data["value"] = response_value
215
+ self.__buffered_data["std_value"] = standardized_response_value
216
+
217
+ DictLogger("Constraint info",self.GetInfo())
218
+
219
+ return standardized_response_value
220
+
221
+ def CalculateStandardizedGradient(self) -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
222
+ with TimeLogger(f"StandardizedRGPConstraint::Calculate {self.GetResponseName()} gradients", None, "Finished"):
223
+ gradient_cta = self.CalculateGradient()
224
+ if self.IsEqualityType():
225
+ factor = 1.0 if self.GetStandardizedValue() > 0.0 else -1.0
226
+ else:
227
+ factor = 1.0
228
+ gradient_cta.data[:] *= self.__scaling * factor
229
+ return gradient_cta
230
+
231
+ def GetValue(self, step_index: int = 0) -> float:
232
+ return self.__buffered_data.GetValue("value", step_index)
233
+
234
+ def GetStandardizedValue(self, step_index: int = 0) -> float:
235
+ return self.GetValue(step_index) * self.__scaling - self.GetReferenceValue()
236
+
237
+ def GetIfConstraintActive(self, step_index: int = 0) -> bool:
238
+ return True
239
+
240
+ def GetAbsoluteViolation(self, step_index: int = 0) -> float:
241
+ is_violated = self.IsEqualityType() or self.GetStandardizedValue(step_index) >= 0.0
242
+ return self.GetStandardizedValue(step_index) * is_violated
243
+
244
+ def GetRelativeViolation(self, step_index: int = 0) -> float:
245
+ return self.GetAbsoluteViolation(step_index) / self.GetReferenceValue() if abs(self.GetReferenceValue()) > 1e-12 else 0.0
246
+
247
+ def GetRelativeChange(self) -> float:
248
+ if self.__optimization_problem.GetStep() > 1:
249
+ return self.GetStandardizedValue() / self.GetStandardizedValue(1) - 1.0 if abs(self.GetStandardizedValue(1)) > 1e-12 else self.GetStandardizedValue()
250
+ else:
251
+ return 0.0
252
+
253
+ def GetAbsoluteChange(self) -> float:
254
+ return self.GetValue() - self.__unbuffered_data["initial_value"] if abs(self.GetReferenceValue()) > 1e-12 else self.GetStandardizedValue()
255
+
256
+ def GetInfo(self) -> dict:
257
+ info = {
258
+ "name": self.GetResponseName(),
259
+ "value": self.GetValue(),
260
+ "type": self.__constraint_type,
261
+ "ref_value": self.GetReferenceValue(),
262
+ "standartiezed_value": self.GetStandardizedValue(),
263
+ "abs_change": self.GetAbsoluteChange(),
264
+ "abs_violation": self.GetAbsoluteViolation(),
265
+ "rel_change [%]": self.GetRelativeChange() * 100.0,
266
+ "rel_violation [%]": self.GetRelativeViolation() * 100.0 if not self.GetReferenceValue() == 0.0 else str(None)
267
+ }
268
+ return info
@@ -0,0 +1,75 @@
1
+ # | / |
2
+ # ' / __| _` | __| _ \ __|
3
+ # . \ | ( | | ( |\__ `
4
+ # _|\_\_| \__,_|\__|\___/ ____/
5
+ # Multi-Physics
6
+ #
7
+ # License: BSD License
8
+ # license: OptimizationApplication/license.txt
9
+ #
10
+ # Main authors: Reza Najian Asl, https://github.com/RezaNajian
11
+ # Suneth Warnakulasuriya
12
+ #
13
+
14
+ # additional imports
15
+ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
16
+ from KratosMultiphysics.OptimizationApplication.execution_policies.execution_policy_decorator import ExecutionPolicyDecorator
17
+ from KratosMultiphysics.OptimizationApplication.utilities.logger_utilities import TimeLogger
18
+
19
+ # ==============================================================================
20
+ def CreateController(execution_policies_settings,model,model_parts_controller):
21
+ return AnalysesController(execution_policies_settings,model,model_parts_controller)
22
+
23
+ # ==============================================================================
24
+ class AnalysesController:
25
+ # --------------------------------------------------------------------------
26
+ def __init__(self, execution_policies_settings, model, model_parts_controller):
27
+ self.execution_policies_settings = execution_policies_settings
28
+ self.model_parts_controller = model_parts_controller
29
+ self.model = model
30
+
31
+ self.execution_policy_decorators = {}
32
+ for execution_policy_settings in self.execution_policies_settings:
33
+ execution_policy_wrapper = ExecutionPolicyDecorator(self.model, execution_policy_settings, OptimizationProblem())
34
+ if not execution_policy_wrapper.GetName() in self.execution_policy_decorators.keys():
35
+ self.execution_policy_decorators[execution_policy_wrapper.GetName()] = execution_policy_wrapper
36
+ else:
37
+ raise RuntimeError(f"Found already existing execution policy with the name \"{execution_policy_wrapper.GetExecutionPolicyName()}\". Please provide unique names.")
38
+
39
+ # --------------------------------------------------------------------------
40
+ def GetExecutionPolicyDecorator(self, execution_policy_name: str) -> ExecutionPolicyDecorator:
41
+ if not execution_policy_name in self.execution_policy_decorators.keys():
42
+ raise RuntimeError("AnalysesController: Try to get an execution policy {} which does not exist.".format(execution_policy_name))
43
+ else:
44
+ return self.execution_policy_decorators[execution_policy_name]
45
+
46
+ # --------------------------------------------------------------------------
47
+ def GetAnalysis(self, execution_policy_name: str):
48
+ return self.GetExecutionPolicyDecorator(execution_policy_name).GetExecutionPolicy().analysis
49
+
50
+ # --------------------------------------------------------------------------
51
+ def Initialize(self):
52
+ for execution_policy_wrapper in self.execution_policy_decorators.values():
53
+ execution_policy_name = execution_policy_wrapper.GetName()
54
+ with TimeLogger(self.__class__.__name__, f"Initializing {execution_policy_name}...", f"Finished initializing {execution_policy_name}"):
55
+ execution_policy_wrapper.Initialize()
56
+
57
+ # --------------------------------------------------------------------------
58
+ def RunAnalysis(self, execution_policy_name: str):
59
+ with TimeLogger(self.__class__.__name__, f"Starting {execution_policy_name}...", f"Finished execution of {execution_policy_name}."):
60
+ self.GetExecutionPolicyDecorator(execution_policy_name).Execute()
61
+
62
+ # --------------------------------------------------------------------------
63
+ def RunAll(self):
64
+ for name in self.analyses.keys():
65
+ self.RunAnalysis(name)
66
+
67
+ # --------------------------------------------------------------------------
68
+ def RunAnalyses(self, analyses_name):
69
+ if not isinstance(analyses_name, list):
70
+ raise RuntimeError("AnalysesController: RunAnalyses requires list of analysis names")
71
+ for analysis_name in analyses_name:
72
+ self.RunAnalysis(analysis_name)
73
+
74
+
75
+
@@ -0,0 +1,123 @@
1
+ from abc import ABC, abstractmethod
2
+ import KratosMultiphysics as Kratos
3
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
4
+
5
+ class Control(ABC):
6
+ """Base abstract control class.
7
+
8
+ The base abstract control class has the following responsibilities.
9
+ 1. Initializes and finalizes the control.
10
+ 2. Maps physical space gradients to control space gradients, if needed. Otherwise, it passes.
11
+ 2. Updating the controlled parts of the model part with new given design.
12
+ 3. Retrieve control field.
13
+ 4. Retrieve physical space kratos variables (If more than one physical space kratos variables are controlled by the given control field.)
14
+
15
+ This control should only work on one model part and one kratos control variable. Hence, if multiple model parts required then,
16
+ a single model part should be created using Kratos.ModelPartOperationUtilities.
17
+
18
+ """
19
+ def __init__(self, control_name: str) -> None:
20
+ self.__name = control_name
21
+
22
+ def GetName(self) -> str:
23
+ return self.__name
24
+
25
+ @abstractmethod
26
+ def Initialize(self) -> None:
27
+ """Initializes the control.
28
+
29
+ This method initializes the control. This is only called once in the whole optimization process.
30
+
31
+ """
32
+ pass
33
+
34
+ @abstractmethod
35
+ def Check(self) -> None:
36
+ """Checks the control.
37
+
38
+ This method checks the control. This is only called once in the whole optimization process.
39
+
40
+ """
41
+ pass
42
+
43
+ @abstractmethod
44
+ def Finalize(self) -> None:
45
+ """Finalizes the control.
46
+
47
+ This method finalizes the control. This is only called once in the whole optimization process.
48
+
49
+ """
50
+ pass
51
+
52
+ @abstractmethod
53
+ def GetPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
54
+ """Returns list of physical control variables controlled by this control.
55
+
56
+ This method returns list of physical variable which are controlled by the control. In most of the cases, there is only one
57
+ control variable per control. But in some rare cases, there may be the requirement to control two physical variables. Anyhow,
58
+ the control space should only have one variable per control in the control space, but they can have multiple physical variables
59
+ in their design space.
60
+
61
+ Returns:
62
+ list[SupportedSensitivityFieldVariableTypes]: List of physical control variables.
63
+ """
64
+ pass
65
+
66
+ @abstractmethod
67
+ def GetEmptyField(self) -> Kratos.TensorAdaptors.DoubleTensorAdaptor:
68
+ """Returns a new empty data field holder with correct dimensionality information.
69
+
70
+ This returns a new empty data field holder to give information about on which model part's container
71
+ this model part is acting on. It does not read any data from respective model part's container.
72
+
73
+ Returns:
74
+ Kratos.TensorAdaptors.DoubleTensorAdaptor: Returns a new empty @ref Kratos.TensorAdaptor corresponding to control's model part's respective container.
75
+ """
76
+ pass
77
+
78
+ @abstractmethod
79
+ def GetControlField(self) -> Kratos.TensorAdaptors.DoubleTensorAdaptor:
80
+ """Returns the current control field of the control.
81
+
82
+ This method returns the control field of the current design.
83
+
84
+ Returns:
85
+ Kratos.TensorAdaptors.DoubleTensorAdaptor: Current designs control field.
86
+ """
87
+ pass
88
+
89
+ @abstractmethod
90
+ def MapGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleTensorAdaptor]') -> Kratos.TensorAdaptors.DoubleTensorAdaptor:
91
+ """Maps physical space gradients to the control space.
92
+
93
+ This method is used to map the given physical space gradients to the control space. The input should be as in the following example:
94
+ physical_variable_gradient_map = {
95
+ Kratos.YOUNG_MODULUS: Kratos.DoubleTensorAdaptor,
96
+ Kratos.DENSITY : Kratos.DoubleTensorAdaptor,
97
+ Kratos.SHAPE : Kratos.DoubleTensorAdaptor
98
+ }
99
+
100
+ All the gradients w.r.t. @see GetPhysicalKratosVariables() variables will be given in @ref physical_variable_gradient_map.
101
+ If the response does not depend on some of them or all, then @ref Kratos.TensorAdaptor with correctly sized zero tensors will be passed.
102
+
103
+ Args:
104
+ physical_variable_gradient_map (dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleTensorAdaptor]): Map of physical space variable and @ref Kratos::TensorAdaptor with sensitivities.
105
+
106
+ Returns:
107
+ Kratos.TensorAdaptors.DoubleTensorAdaptor: Gradients mapped in to control space.
108
+ """
109
+ pass
110
+
111
+ @abstractmethod
112
+ def Update(self, control_field: Kratos.TensorAdaptors.DoubleTensorAdaptor) -> bool:
113
+ """Modifies the current control with the given control field.
114
+
115
+ Args:
116
+ control_field (Kratos.TensorAdaptors.DoubleTensorAdaptor): The control field in control space.
117
+
118
+ Returns:
119
+ bool: True if the control field was applied to obtain a new design, otherwise False
120
+ """
121
+ pass
122
+
123
+