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,47 @@
1
+ from math import log
2
+ import KratosMultiphysics as Kratos
3
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
4
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import SupportedSensitivityFieldVariableTypes
5
+ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
6
+ from KratosMultiphysics.OptimizationApplication.utilities.response_utilities import EvaluateValue
7
+ from KratosMultiphysics.OptimizationApplication.utilities.response_utilities import EvaluateGradient
8
+
9
+ class LogResponseFunction(ResponseFunction):
10
+ def __init__(self, response_function: ResponseFunction, optimization_problem: OptimizationProblem):
11
+ super().__init__(f"log({response_function.GetName()})")
12
+ self.response_function = response_function
13
+ self.optimization_problem = optimization_problem
14
+
15
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
16
+ return self.response_function.GetImplementedPhysicalKratosVariables()
17
+
18
+ def Initialize(self) -> None:
19
+ self.response_function.Initialize()
20
+
21
+ def Check(self) -> None:
22
+ self.response_function.Check()
23
+
24
+ def Finalize(self) -> None:
25
+ self.response_function.Finalize()
26
+
27
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
28
+ return self.response_function.GetInfluencingModelPart()
29
+
30
+ def CalculateValue(self) -> float:
31
+ return log(EvaluateValue(self.response_function, self.optimization_problem))
32
+
33
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
34
+ v = EvaluateValue(self.response_function, self.optimization_problem)
35
+
36
+ resp_gradients = {var: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(cta) for var, cta in physical_variable_gradient_map.items()}
37
+ EvaluateGradient(self.response_function, resp_gradients, self.optimization_problem)
38
+
39
+ for variable, cta in physical_variable_gradient_map.items():
40
+ cta.data = resp_gradients[variable].data / v
41
+ Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor(cta, perform_collect_data_recursively=False, perform_store_data_recursively=False, copy=False).StoreData()
42
+
43
+ def GetChildResponses(self) -> 'list[ResponseFunction]':
44
+ return [self.response_function]
45
+
46
+ def __str__(self) -> str:
47
+ return f"Response [type = {self.__class__.__name__}, name = {self.GetName()}]"
@@ -0,0 +1,71 @@
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.responses.response_function import SupportedSensitivityFieldVariableTypes
7
+ from KratosMultiphysics.OptimizationApplication.utilities.model_part_utilities import ModelPartOperation
8
+
9
+ def Factory(model: Kratos.Model, parameters: Kratos.Parameters, _) -> ResponseFunction:
10
+ if not parameters.Has("name"):
11
+ raise RuntimeError(f"MassResponseFunction instantiation requires a \"name\" in parameters [ parameters = {parameters}].")
12
+ if not parameters.Has("settings"):
13
+ raise RuntimeError(f"MassResponseFunction instantiation requires a \"settings\" in parameters [ parameters = {parameters}].")
14
+
15
+ return MassResponseFunction(parameters["name"].GetString(), model, parameters["settings"])
16
+
17
+ class MassResponseFunction(ResponseFunction):
18
+ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters):
19
+ super().__init__(name)
20
+
21
+ default_settings = Kratos.Parameters("""{
22
+ "evaluated_model_part_names" : [
23
+ "PLEASE_PROVIDE_A_MODEL_PART_NAME"
24
+ ],
25
+ "perturbation_size": 1e-6
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 MassResponseFunction. [ 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
+ self.perturbation_size = parameters["perturbation_size"].GetDouble()
38
+
39
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
40
+ return [KratosOA.SHAPE, Kratos.DENSITY, Kratos.THICKNESS, KratosOA.CROSS_AREA]
41
+
42
+ def Initialize(self) -> None:
43
+ self.model_part = self.model_part_operation.GetModelPart()
44
+
45
+ def Check(self) -> None:
46
+ if self.model_part is None:
47
+ raise RuntimeError("Please call MassResponseFunction::Initialize first.")
48
+ KratosOA.ResponseUtils.MassResponseUtils.Check(self.model_part)
49
+
50
+ def Finalize(self) -> None:
51
+ pass
52
+
53
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
54
+ if self.model_part is None:
55
+ raise RuntimeError("Please call MassResponseFunction::Initialize first.")
56
+ return self.model_part
57
+
58
+ def CalculateValue(self) -> float:
59
+ return KratosOA.ResponseUtils.MassResponseUtils.CalculateValue(self.model_part)
60
+
61
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
62
+ # calculate the gradients
63
+ for physical_variable, cta in physical_variable_gradient_map.items():
64
+ KratosOA.ResponseUtils.MassResponseUtils.CalculateGradient(
65
+ physical_variable,
66
+ self.model_part,
67
+ cta,
68
+ self.perturbation_size)
69
+
70
+ def __str__(self) -> str:
71
+ return f"Response [type = {self.__class__.__name__}, name = {self.GetName()}, model part name = {self.model_part.FullName()}]"
@@ -0,0 +1,126 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Union
3
+ import KratosMultiphysics as Kratos
4
+ import KratosMultiphysics.OptimizationApplication as KratosOA
5
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
6
+
7
+ class ResponseFunction(ABC):
8
+ """Base response function.
9
+
10
+ This response function is the base response function. This is assumed to have following responsibilities.
11
+ 1. CalculateValue for a new design. (@see CalculateValue)
12
+ 2. CalculateSensitivity for a new design (@see CalculateSensitivity)
13
+
14
+ This response should only work on one model part. Hence, if multiple model parts required then,
15
+ a single model part should be created using Kratos.ModelPartOperationUtilities.
16
+ """
17
+ def __init__(self, response_name: str) -> None:
18
+ self.__name = response_name
19
+
20
+ def GetName(self) -> str:
21
+ return self.__name
22
+
23
+ @abstractmethod
24
+ def Initialize(self) -> None:
25
+ """Initializes the response.
26
+
27
+ This method initializes the response. This is only called once in the whole optimization process.
28
+
29
+ """
30
+ pass
31
+
32
+ @abstractmethod
33
+ def Check(self) -> None:
34
+ """Checks the response.
35
+
36
+ This method checks the response. This is only called once in the whole optimization process.
37
+
38
+ """
39
+ pass
40
+
41
+ @abstractmethod
42
+ def Finalize(self) -> None:
43
+ """Finalizes the response.
44
+
45
+ This method finalizes the response. This is only called once in the whole optimization process.
46
+
47
+ """
48
+ pass
49
+
50
+ @abstractmethod
51
+ def GetImplementedPhysicalKratosVariables(self) -> 'list[SupportedSensitivityFieldVariableTypes]':
52
+ """Returns all the dependent physical kratos variables of the response.
53
+
54
+ This method should return all the dependent physical variables of the response to make sure
55
+ that sensitivities w.r.t. those variables are requested from the response. If sensitivities
56
+ w.r.t. other variables are required from this response, they are ASSUMED TO BE ZERO.
57
+
58
+ Please return all the dependent physical variables, even though the gradient computation is not yet
59
+ implemented for some to avoid future bugs.
60
+
61
+ Returns:
62
+ list[SupportedSensitivityFieldVariableTypes]: All dependent physical variables of the response.
63
+ """
64
+ pass
65
+
66
+ @abstractmethod
67
+ def CalculateValue(self) -> float:
68
+ """Calculates the response value.
69
+
70
+ This method should always calculate the response value assuming the domain has changed.
71
+
72
+ Returns:
73
+ float: Calculated response value.
74
+ """
75
+ pass
76
+
77
+ @abstractmethod
78
+ def CalculateGradient(self, physical_variable_gradient_map: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]') -> None:
79
+ """Calculate gradient w.r.t. given physical variables.
80
+
81
+ This method should always calculate the sensitivities w.r.t. requested physical variables on the given @ref Kratos::TensorAdaptor
82
+ in the @ref Kratos::CombinedTensorAdaptor. An error should be thrown if sensitivitiy computation w.r.t. one or more given physical variables
83
+ are not implemented.
84
+
85
+ This method should always calculate the sensitivities assuming the domain has changed.
86
+
87
+ physical_variable_gradient_map is a map of physical variables, and their domains. The domains are represented by a @ref Kratos::CombinedTensorAdaptor
88
+ which contains list of empty @ref Kratos::TensorAdaptor. Each empty Kratos::TensorAdaptor contains details of the model part's nodes/conditions/element/properties
89
+ container for which the sensitivities w.r.t. physical variable requested.
90
+
91
+ Args:
92
+ physical_variable_gradient_map (dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]): Output containing calculated sensitivities w.r.t. requested physical variables.
93
+ """
94
+ pass
95
+
96
+ @abstractmethod
97
+ def GetInfluencingModelPart(self) -> Kratos.ModelPart:
98
+ """Returns the model part which influences the computation of the response value.
99
+
100
+ Following two cases are considered:
101
+ 1. Responses without adjoint system solve: The value of the response can only be influenced by
102
+ changing the quantities in the evaluated model part (evaluated model part is the one which the
103
+ response value is computed.) Therefore, in this case, this method should return the
104
+ evaluated model part.
105
+ 2. Responses with adjoint system solve: The value of the response can be influenced by
106
+ changing quantities in the adjoint/primal model part (Evaluated model part needs to have
107
+ intersection with the adjoint/primal model part). Therefore, in this case, this method should return the
108
+ adjoint analysis model part.
109
+
110
+ Returns:
111
+ Kratos.ModelPart: Response function model part which influences the response value.
112
+ """
113
+ pass
114
+
115
+ def GetChildResponses(self) -> 'list[ResponseFunction]':
116
+ """Returns the list of child responses.
117
+
118
+ This method returns list of child responses. If the current response is a leaf response,
119
+ then it will return empty list.
120
+
121
+ Needs to be implemented in non-leaf response functions.
122
+
123
+ Returns:
124
+ list[ResponseFunction]: List of child responses.
125
+ """
126
+ return []
@@ -0,0 +1,158 @@
1
+ import KratosMultiphysics as Kratos
2
+ import KratosMultiphysics.OptimizationApplication as KratosOA
3
+ from KratosMultiphysics.OptimizationApplication.controls.control import Control
4
+ from KratosMultiphysics.OptimizationApplication.responses.response_function import ResponseFunction
5
+ from KratosMultiphysics.OptimizationApplication.controls.master_control import MasterControl
6
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
7
+ import math, numpy
8
+
9
+ class ResponseRoutine:
10
+ """A class which adds optimization-specific utilities to simplify routines
11
+ and synchronization between the control field from algorithms and analysis models.
12
+ """
13
+ def __init__(self, master_control: MasterControl, response: ResponseFunction) -> None:
14
+ # set the master control
15
+ self.__master_control = master_control
16
+
17
+ # set the response
18
+ self.__response = response
19
+ self.__response_value = None
20
+ self.__contributing_controls_list: 'list[Control]' = []
21
+ self.__required_physical_gradients: 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]' = {}
22
+
23
+ def GetMasterControl(self) -> MasterControl:
24
+ return self.__master_control
25
+
26
+ def Initialize(self):
27
+ """Initializes the response routine.
28
+
29
+ Raises:
30
+ RuntimeError: If control domain and response domain does not have any intersection.
31
+ """
32
+ # create the required physical control fields to compute gradients
33
+ self.__response.Initialize()
34
+ self.__required_physical_gradients = self.__master_control.GetPhysicalKratosVariableMap()
35
+
36
+ # now check which are the dependent physical space variables for the response, if not then remove
37
+ # that variable
38
+ list_of_independent_variables = []
39
+ for required_physical_variable in self.__required_physical_gradients.keys():
40
+ if required_physical_variable not in self.__response.GetImplementedPhysicalKratosVariables():
41
+ list_of_independent_variables.append(required_physical_variable)
42
+
43
+ # now remove this independent combined tensor adaptor from the require combined tensor adaptors map.
44
+ for independent_variable in list_of_independent_variables:
45
+ del self.__required_physical_gradients[independent_variable]
46
+
47
+ for control in self.__master_control.GetListOfControls():
48
+ # check whether control has keys given by required gradients
49
+ if set(control.GetPhysicalKratosVariables()).intersection(self.__required_physical_gradients.keys()):
50
+ self.__contributing_controls_list.append(control)
51
+
52
+ if not self.__contributing_controls_list:
53
+ raise RuntimeError(f"The controls does not have any influence over the response {self.GetResponseName()}.")
54
+
55
+ self.my_current_control_field = self.__master_control.GetEmptyField()
56
+
57
+ def Check(self):
58
+ self.__response.Check()
59
+
60
+ def Finalize(self):
61
+ self.__response.Finalize()
62
+
63
+ def GetResponseName(self):
64
+ return self.__response.GetName()
65
+
66
+ def GetReponse(self) -> ResponseFunction:
67
+ return self.__response
68
+
69
+ def CalculateValue(self, control_field: Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor) -> float:
70
+ """Calculates the value of the response.
71
+
72
+ This method updates the design with the provided control field. If a control field is updated
73
+ which affects the this response value, then a new value is computed. Otherwise, the previous
74
+ value is returned.
75
+
76
+ Args:
77
+ control_field (Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor): Control field of the new design.
78
+
79
+ Returns:
80
+ float: Response value.
81
+ """
82
+ # update using the master control and get updated states.
83
+ self.__master_control.Update(control_field)
84
+ compute_response_value_flag = False
85
+
86
+ if self.__response_value is None:
87
+ self.my_current_control_field = Kratos.TensorAdaptors.DoubleTensorAdaptor(control_field)
88
+
89
+ if not math.isclose(numpy.linalg.norm(self.my_current_control_field.data, ord=numpy.inf), 0.0, abs_tol=1e-16):
90
+ rel_diff = (self.my_current_control_field.data - control_field.data) / numpy.linalg.norm(self.my_current_control_field.data, ord=numpy.inf)
91
+ else:
92
+ rel_diff = (self.my_current_control_field.data - control_field.data)
93
+
94
+ norm = numpy.linalg.norm(rel_diff, ord=numpy.inf)
95
+
96
+ if not math.isclose(norm, 0.0, abs_tol=1e-16):
97
+ compute_response_value_flag = True
98
+
99
+ compute_response_value_flag = compute_response_value_flag or self.__response_value is None
100
+ # TODO: In the case of having two analysis with the same mesh (model parts) for two different
101
+ # responses, we need to flag all the anayses which are affected by the control update_state
102
+ # from the first call, otherwise the second call will not update anything, hence no execution
103
+ # policies will be executed.
104
+
105
+ # Example: Drag 1 with 10m/s, Drag 2 with 20 m/s using the same mesh and model parts with two
106
+ # different analyses.
107
+ # now set the response value in response data container
108
+ # if len(modified_model_parts) > 0:
109
+ # # if there are any modified model parts, then this changes state of is_executed to false
110
+ # # in the execution policies which has some intersection with the modified model parts.
111
+ # ChangeExecutionPolicyStates(modified_model_parts, False, self.__optimization_problem)
112
+
113
+ if compute_response_value_flag:
114
+ self.__response_value = self.__response.CalculateValue()
115
+ Kratos.Logger.PrintInfo(f"Response value is calculated for {self.GetResponseName()}.")
116
+ else:
117
+ Kratos.Logger.PrintInfo(f"The control field is not updated, hence the response value is not computed for {self.GetResponseName()}.")
118
+
119
+ # Update current control field state
120
+ self.my_current_control_field.data[:] = control_field.data
121
+
122
+ return self.__response_value
123
+
124
+ def CalculateGradient(self) -> Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor:
125
+ """Returns CombinedTensorAdaptor containing all the control space gradients for all control variable types (fields).
126
+
127
+ Notes:
128
+ 1. It expects that the CalculateValue is called.
129
+ 2. The gradients are computed with respect to updates from master control.
130
+
131
+ Returns:
132
+ Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor: Returns mapped gradients combined tensor adaptor.
133
+ """
134
+ # fills the proper physical gradients from the response
135
+ self.__response.CalculateGradient(self.__required_physical_gradients)
136
+
137
+ # calculate and return the control space gradients from respective controls
138
+ self.__mapped_gradients = self.__master_control.MapGradient(self.__required_physical_gradients)
139
+ return self.__mapped_gradients
140
+
141
+ def GetMappedGradients(self):
142
+ return self.__mapped_gradients
143
+
144
+ def GetRequiredPhysicalGradients(self) -> 'dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]':
145
+ """Returns required physical gradients by this response
146
+
147
+ This method returns required physical gradients. The tensor adaptors may or not be empty field
148
+ depending on CalculateGradient is called or not.
149
+
150
+ Returns:
151
+ dict[SupportedSensitivityFieldVariableTypes, Kratos.TensorAdaptors.DoubleCombinedTensorAdaptor]: Required physical gradients.
152
+ """
153
+ return self.__required_physical_gradients
154
+
155
+ def GetName(self):
156
+ return self.GetReponse().GetName()
157
+
158
+