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,139 @@
1
+ from typing import Any, Optional
2
+
3
+ # Importing Kratos
4
+ import KratosMultiphysics as KM
5
+ import KratosMultiphysics.OptimizationApplication as KOA
6
+ import KratosMultiphysics.OptimizationApplication.filtering.python_solvers_wrapper_implicit_filters as implicit_filter_solvers
7
+
8
+ # Importing the base class
9
+ from KratosMultiphysics.analysis_stage import AnalysisStage
10
+
11
+ class HelmholtzAnalysis(AnalysisStage):
12
+ """
13
+ This class is the main-script of the implicit filtering analysis
14
+ It can be imported and used as "black-box"
15
+ """
16
+ def __init__(self, model: KM.Model, project_parameters: KM.Parameters):
17
+ super().__init__(model, project_parameters)
18
+ self.__source_data: 'Optional[KM.TensorAdaptors.DoubleTensorAdaptor]' = None
19
+ self.__neighbour_entities: 'dict[Any, KM.TensorAdaptors.IntTensorAdaptor]' = {}
20
+
21
+ #### Internal functions ####
22
+ def _CreateSolver(self):
23
+ """ Create the Solver (and create and import the ModelPart if it is not already in the model) """
24
+ return implicit_filter_solvers.CreateSolver(self.model, self.project_parameters)
25
+
26
+ def _GetSimulationName(self):
27
+ return "::[Helmholtz/Sobolev Analysis]:: "
28
+
29
+ def _GetComputingModelPart(self):
30
+ return self._GetSolver().GetComputingModelPart()
31
+
32
+ def _SetSolverMode(self, invers_mode:bool = False):
33
+ self._GetComputingModelPart().ProcessInfo.SetValue(KOA.COMPUTE_HELMHOLTZ_INVERSE, invers_mode)
34
+
35
+ def _SetHelmHoltzSourceMode(self, integrated_field=False):
36
+ self._GetComputingModelPart().ProcessInfo.SetValue(KOA.HELMHOLTZ_INTEGRATED_FIELD, integrated_field)
37
+
38
+ #### Public user interface functions ####
39
+ def Initialize(self):
40
+ super().Initialize()
41
+ self.InitializeFilterModelPart()
42
+
43
+ def InitializeFilterModelPart(self):
44
+ self._SetSolverMode()
45
+ self._GetSolver().SetFilterRadius(self._GetSolver().GetFilterRadius())
46
+ self._SetHelmHoltzSourceMode()
47
+
48
+ def RunSolver(self):
49
+ self.InitializeSolutionStep()
50
+ self._GetSolver().Predict()
51
+ self._GetSolver().SolveSolutionStep()
52
+ self.FinalizeSolutionStep()
53
+
54
+ def FilterField(self, unfiltered_field: KM.TensorAdaptors.DoubleTensorAdaptor) -> KM.TensorAdaptors.DoubleTensorAdaptor:
55
+
56
+ self.__AssignTensorDataToNodalSource(unfiltered_field)
57
+ self._SetSolverMode(False)
58
+ self._SetHelmHoltzSourceMode(False)
59
+ self.RunSolver()
60
+ return self.__AssignNodalSolutionToTensorData()
61
+
62
+ def FilterIntegratedField(self, unfiltered_field: KM.TensorAdaptors.DoubleTensorAdaptor) -> KM.TensorAdaptors.DoubleTensorAdaptor:
63
+
64
+ self.__AssignTensorDataToNodalSource(unfiltered_field)
65
+ self._SetSolverMode(False)
66
+ self._SetHelmHoltzSourceMode(True)
67
+ self.RunSolver()
68
+ return self.__AssignNodalSolutionToTensorData()
69
+
70
+ def UnFilterField(self, filtered_field: KM.TensorAdaptors.DoubleTensorAdaptor) -> KM.TensorAdaptors.DoubleTensorAdaptor:
71
+
72
+ self.__AssignTensorDataToNodalSource(filtered_field)
73
+ self._SetSolverMode(True)
74
+ self._SetHelmHoltzSourceMode(False)
75
+ self.RunSolver()
76
+ return self.__AssignNodalSolutionToTensorData()
77
+
78
+ def AssignTensorDataToNodalSolution(self, data_exp: KM.TensorAdaptors.DoubleTensorAdaptor) -> None:
79
+ ta = KM.TensorAdaptors.DoubleTensorAdaptor(data_exp, copy=False)
80
+ if not isinstance(ta.GetContainer(), KM.NodesArray):
81
+ neighbours = self.__GetNeighbourEntities(data_exp)
82
+ ta = KOA.OptimizationUtils.MapContainerDataToNodalData(data_exp, neighbours.GetContainer())
83
+ KM.TensorAdaptors.HistoricalVariableTensorAdaptor(ta, self._GetSolver().GetSolvingVariable(), copy=False).StoreData()
84
+
85
+ def __AssignTensorDataToNodalSource(self, data_exp: KM.TensorAdaptors.DoubleTensorAdaptor):
86
+ self.__source_data = KM.TensorAdaptors.DoubleTensorAdaptor(data_exp)
87
+
88
+ # it is better to work on the model part of the data_exp rather than the internal
89
+ # model part created with ConnectivityPreserveModelPart because, then all the outputs will
90
+ # be written to one vtu file automatically, otherwise, there will be outputs distributed among
91
+ # the helmholtz model part and the original model part. This is safer because the helmholtz modelpart
92
+ # is created using the ConnectivityPreserveModeller which preserves the same nodes and condition/element
93
+ # data containers.
94
+
95
+ ta = KM.TensorAdaptors.DoubleTensorAdaptor(data_exp, copy=False)
96
+ if not isinstance(ta.GetContainer(), KM.NodesArray):
97
+ neighbours = self.__GetNeighbourEntities(data_exp)
98
+ ta = KOA.OptimizationUtils.MapContainerDataToNodalData(data_exp, neighbours.GetContainer())
99
+ KM.TensorAdaptors.VariableTensorAdaptor(ta, self._GetSolver().GetSourceVariable(), copy=False).StoreData()
100
+
101
+ def __AssignNodalSolutionToTensorData(self) -> KM.TensorAdaptors.DoubleTensorAdaptor:
102
+ if self.__source_data is None:
103
+ raise RuntimeError("The __AssignTensorDataToNodalSource should be called first.")
104
+
105
+ # it is better to work on the model part of the data_exp rather than the internal
106
+ # model part created with ConnectivityPreserveModelPart because, then all the outputs will
107
+ # be written to one vtu file automatically, otherwise, there will be outputs distributed among
108
+ # the helmholtz model part and the original model part. This is safer because the helmholtz modelpart
109
+ # is created using the ConnectivityPreserveModeller which preserves the same nodes and condition/element
110
+ # data containers.
111
+ neighbours = self.__GetNeighbourEntities(self.__source_data)
112
+ solution = KM.TensorAdaptors.HistoricalVariableTensorAdaptor(neighbours.GetContainer(), self._GetSolver().GetSolvingVariable())
113
+ solution.CollectData()
114
+
115
+ if isinstance(self.__source_data.GetContainer(), KM.NodesArray):
116
+ return KM.TensorAdaptors.DoubleTensorAdaptor(solution, copy=False)
117
+ else:
118
+ return KOA.OptimizationUtils.MapNodalDataToContainerData(solution, self.__source_data.GetContainer(), neighbours)
119
+
120
+ def __GetNeighbourEntities(self, data_exp: KM.TensorAdaptors.DoubleTensorAdaptor) -> KM.TensorAdaptors.IntTensorAdaptor:
121
+ # following makes the number of neighbours computation to be executed once
122
+ # per given container, hence if the mesh element/connectivity changes
123
+ # this computation needs to be redone. Especially in the case if MMG is
124
+ # used for re-meshing.
125
+ key = data_exp.GetContainer()
126
+ if key not in self.__neighbour_entities.keys():
127
+ if not isinstance(key, KM.NodesArray):
128
+ if isinstance(data_exp.GetContainer(), KM.ConditionsArray):
129
+ self.__neighbour_entities[key] = KM.TensorAdaptors.Utils.CreateNodalConditionNeighboursCountTensorAdaptor(self._GetSolver().GetComputingModelPart())
130
+ elif isinstance(data_exp.GetContainer(), KM.ElementsArray):
131
+ self.__neighbour_entities[key] = KM.TensorAdaptors.Utils.CreateNodalElementNeighboursCountTensorAdaptor(self._GetSolver().GetComputingModelPart())
132
+ else:
133
+ raise RuntimeError(f"Unsupported tensor adaptor container. Only supports neighbour computation for condition or element containers [ tensor adaptor = {data_exp} ]." )
134
+ else:
135
+ ta = KM.TensorAdaptors.IntTensorAdaptor(key, KM.IntNDData([len(key)]), copy=False)
136
+ ta.data[:] = 1
137
+ self.__neighbour_entities[key] = ta
138
+
139
+ return self.__neighbour_entities[key]
@@ -0,0 +1,39 @@
1
+ # Importing the Kratos Library
2
+ import KratosMultiphysics as KM
3
+
4
+ # Import applications
5
+ import KratosMultiphysics.OptimizationApplication as KOA
6
+
7
+ # Import baseclass
8
+ from KratosMultiphysics.OptimizationApplication.filtering.helmholtz_solver_base import HelmholtzSolverBase
9
+
10
+ def CreateSolver(model: KM.Model, custom_settings: KM.Parameters):
11
+ return HelmholtzScalarSolver(model, custom_settings)
12
+
13
+ class HelmholtzScalarSolver(HelmholtzSolverBase):
14
+ def GetSolvingVariable(self) -> KM.DoubleVariable:
15
+ return KOA.HELMHOLTZ_SCALAR
16
+
17
+ def _GetComputingModelPartName(self) -> str:
18
+ return self.GetOriginModelPart().FullName().replace(".", "_") + "_helmholtz_scalar"
19
+
20
+ def SetFilterRadius(self, filter_radius: float) -> None:
21
+ self.GetComputingModelPart().ProcessInfo.SetValue(KOA.HELMHOLTZ_RADIUS, filter_radius)
22
+
23
+ def _FillComputingModelPart(self) -> None:
24
+ if self.GetOriginModelPart().NumberOfElements() > 0:
25
+ # here we have to replace the elements, while keeping the
26
+ # geometries the same. Hence using the ConnectivityPreserveModeller
27
+ container = self.GetOriginModelPart().Elements
28
+ num_nodes = self._GetContainerTypeNumNodes(container)
29
+ if self._IsSurfaceContainer(container):
30
+ KM.ConnectivityPreserveModeler().GenerateModelPart(self.GetOriginModelPart(), self.GetComputingModelPart(), f"HelmholtzSurfaceElement3D{num_nodes}N")
31
+ else:
32
+ KM.ConnectivityPreserveModeler().GenerateModelPart(self.GetOriginModelPart(), self.GetComputingModelPart(), f"HelmholtzSolidElement3D{num_nodes}N")
33
+ elif self.GetOriginModelPart().NumberOfConditions() > 0:
34
+ # here we have conditions in the origin model part. Now we have to create elements using
35
+ # the geometries of the conditions. There cannot be volume conditions in Kratos, therefore,
36
+ # there can be only surface conditions, hence only required to create surface elements.
37
+ KOA.OptAppModelPartUtils.GenerateModelPart(self.GetOriginModelPart().Conditions, self.GetComputingModelPart(), f"HelmholtzSurfaceElement3D{self._GetContainerTypeNumNodes(self.GetOriginModelPart().Conditions)}N")
38
+ else:
39
+ raise RuntimeError(f"No elements or conditions found in {self.GetOriginModelPart()}.")
@@ -0,0 +1,67 @@
1
+ # Importing the Kratos Library
2
+ import KratosMultiphysics as KM
3
+ import KratosMultiphysics.OptimizationApplication as KOA
4
+
5
+ # Import baseclass
6
+ from KratosMultiphysics.OptimizationApplication.filtering.helmholtz_solver_base import HelmholtzSolverBase
7
+
8
+ def CreateSolver(model: KM.Model, custom_settings: KM.Parameters):
9
+ return HelmholtzShapeSolver(model, custom_settings)
10
+
11
+ class HelmholtzShapeSolver(HelmholtzSolverBase):
12
+ def GetSolvingVariable(self) -> KM.Array1DVariable3:
13
+ return KOA.HELMHOLTZ_VECTOR
14
+
15
+ def _GetComputingModelPartName(self) -> str:
16
+ return self.GetOriginModelPart().FullName().replace(".", "_") + "_helmholtz_shape"
17
+
18
+ def SetFilterRadius(self, filter_radius: float) -> None:
19
+ self.GetComputingModelPart().ProcessInfo.SetValue(KOA.HELMHOLTZ_RADIUS, filter_radius)
20
+ KOA.ImplicitFilterUtils.SetBulkRadiusForShapeFiltering(self.GetComputingModelPart())
21
+
22
+ def _FillComputingModelPart(self) -> None:
23
+ if self.GetOriginModelPart().NumberOfElements() > 0:
24
+ # here we have to replace the elements, while keeping the
25
+ # geometries the same. Hence using the ConnectivityPreserveModeller
26
+ container = self.GetOriginModelPart().Elements
27
+ num_nodes = self._GetContainerTypeNumNodes(container)
28
+ if self._IsSurfaceContainer(container):
29
+ KM.ConnectivityPreserveModeler().GenerateModelPart(self.GetOriginModelPart(), self.GetComputingModelPart(), f"HelmholtzVectorSurfaceElement3D{num_nodes}N")
30
+ else:
31
+ raise RuntimeError(f"Helmholtz shape solver found volume elements in {self.GetOriginModelPart().FullName()}. It can work with only either surface elements or surface conditions.")
32
+ elif self.GetOriginModelPart().NumberOfConditions() > 0:
33
+ # we have only conditions in the origin model part. Since this solver is used to
34
+ # do the mesh motion as well, then we need to work on the origin model part's root model part.
35
+ # here also we can use the connectivity preserve modeller.
36
+ element_num_nodes = self._GetContainerTypeNumNodes(self.GetOriginRootModelPart().Elements)
37
+ KM.ConnectivityPreserveModeler().GenerateModelPart(self.GetOriginRootModelPart(), self.GetComputingModelPart(), f"HelmholtzSolidShapeElement3D{element_num_nodes}N", f"HelmholtzSurfaceShapeCondition3D{self._GetContainerTypeNumNodes(self.GetOriginRootModelPart().Conditions)}N")
38
+
39
+ # now we have to add the material properties
40
+ properties = KM.Parameters("""{
41
+ "properties" : [
42
+ {
43
+ "model_part_name": \"""" + self.GetComputingModelPart().FullName() + """\",
44
+ "properties_id" : """ + str(self.GetComputingModelPart().NumberOfProperties() + 1) + """,
45
+ "Material": {
46
+ "constitutive_law": {
47
+ "name": "HelmholtzJacobianStiffened3D"
48
+ },
49
+ "Variables": {
50
+ "POISSON_RATIO": 0.3
51
+ }
52
+ }
53
+ }
54
+ ]
55
+ }""")
56
+ KM.ReadMaterialsUtility(self.model).ReadMaterials(properties)
57
+
58
+ # now we do the tetrahedral mesh orientation check and parent element
59
+ # assignment.
60
+ if element_num_nodes == 4:
61
+ tmoc = KM.TetrahedralMeshOrientationCheck
62
+ flags = (tmoc.COMPUTE_NODAL_NORMALS).AsFalse() | (tmoc.COMPUTE_CONDITION_NORMALS).AsFalse() | tmoc.ASSIGN_NEIGHBOUR_ELEMENTS_TO_CONDITIONS
63
+ KM.TetrahedralMeshOrientationCheck(self.GetComputingModelPart(), False, flags).Execute()
64
+ else:
65
+ raise RuntimeError("Helmholtz shape solver only supports tetrahedral elements.")
66
+ else:
67
+ raise RuntimeError(f"No elements or conditions found in {self.GetOriginModelPart()}.")
@@ -0,0 +1,275 @@
1
+ import abc
2
+ import typing
3
+ import numpy
4
+
5
+ # Importing the Kratos Library
6
+ import KratosMultiphysics
7
+ import KratosMultiphysics.OptimizationApplication as KOA
8
+ from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import SupportedSensitivityFieldVariableTypes
9
+
10
+ # Other imports
11
+ from KratosMultiphysics.python_solver import PythonSolver
12
+ from KratosMultiphysics.python_linear_solver_factory import ConstructSolver
13
+
14
+ class HelmholtzSolverBase(PythonSolver):
15
+ """The base class for Helmholtz-based solvers.
16
+
17
+ This class defines the user interface to Helmholtz solvers.
18
+
19
+ """
20
+ def __init__(self, model: KratosMultiphysics.Model, custom_settings: KratosMultiphysics.Parameters):
21
+ self._validate_settings_in_baseclass=True # To be removed eventually
22
+ super().__init__(model, custom_settings)
23
+
24
+ # Either retrieve the model part from the model or create a new one
25
+ self.filtering_model_part_name = self.settings["model_part_name"].GetString()
26
+
27
+ if self.filtering_model_part_name == "":
28
+ raise Exception('Please provide the model part name as the "model_part_name" (string) parameter!')
29
+
30
+ # the filtering_model_part_name can be a sub model part. Hence we need the main model part
31
+ # for variable and dof addition.
32
+ root_model_part_name = self.filtering_model_part_name.split(".")[0]
33
+ if self.model.HasModelPart(root_model_part_name):
34
+ self.origin_root_model_part = self.model.GetModelPart(root_model_part_name)
35
+ else:
36
+ self.origin_root_model_part = model.CreateModelPart(root_model_part_name)
37
+
38
+ domain_size = self.settings["domain_size"].GetInt()
39
+ if domain_size == -1:
40
+ raise Exception('Please provide the domain size as the "domain_size" (int) parameter!')
41
+ self.origin_root_model_part.ProcessInfo.SetValue(KratosMultiphysics.DOMAIN_SIZE, domain_size)
42
+
43
+ # we don't create the helmholtz model part here, because
44
+ # we need to have unique model parts for different filtering variable types
45
+ # hence, it cannot be determined at this point.
46
+ self.helmholtz_model_part: 'typing.Optional[KratosMultiphysics.ModelPart]' = None
47
+
48
+ # Get the filter radius
49
+ self.filter_radius = self.settings["filter_radius"].GetDouble()
50
+
51
+ KratosMultiphysics.Logger.PrintInfo("::[HelmholtzSolverBase]:: Construction finished")
52
+
53
+ @classmethod
54
+ def GetDefaultParameters(cls) -> KratosMultiphysics.Parameters:
55
+ this_defaults = KratosMultiphysics.Parameters("""{
56
+ "solver_type" : "helmholtz_solver_base",
57
+ "domain_size" : -1,
58
+ "filter_type" : "",
59
+ "filter_radius" : 0.0,
60
+ "model_part_name" : "",
61
+ "time_stepping" : {
62
+ "time_step" : 1.0
63
+ },
64
+ "model_import_settings" : {
65
+ "input_type" : "mdpa",
66
+ "input_filename" : "unknown_name"
67
+ },
68
+ "linear_solver_settings" : {
69
+ "solver_type" : "amgcl",
70
+ "smoother_type":"ilu0",
71
+ "krylov_type": "gmres",
72
+ "coarsening_type": "aggregation",
73
+ "max_iteration": 200,
74
+ "provide_coordinates": false,
75
+ "gmres_krylov_space_dimension": 100,
76
+ "verbosity" : 0,
77
+ "tolerance": 1e-7,
78
+ "scaling": false,
79
+ "block_size": 1,
80
+ "use_block_matrices_if_possible" : true,
81
+ "coarse_enough" : 5000
82
+ },
83
+ "material_properties": {}
84
+ }""")
85
+ this_defaults.AddMissingParameters(super().GetDefaultParameters())
86
+ return this_defaults
87
+
88
+ #### Public user interface functions ####
89
+
90
+ @abc.abstractmethod
91
+ def _GetComputingModelPartName(self) -> str:
92
+ pass
93
+
94
+ @abc.abstractmethod
95
+ def _FillComputingModelPart(self) -> None:
96
+ pass
97
+
98
+ @abc.abstractmethod
99
+ def GetSolvingVariable(self) -> SupportedSensitivityFieldVariableTypes:
100
+ pass
101
+
102
+ @abc.abstractmethod
103
+ def SetFilterRadius(self, filter_radius: float) -> None:
104
+ pass
105
+
106
+ def AddVariables(self) -> None:
107
+ self.GetOriginRootModelPart().AddNodalSolutionStepVariable(self.GetSolvingVariable())
108
+ KratosMultiphysics.Logger.PrintInfo("::[HelmholtzSolverBase]:: Variables ADDED.")
109
+
110
+ def AddDofs(self) -> None:
111
+ if isinstance(self.GetSolvingVariable(), KratosMultiphysics.DoubleVariable):
112
+ KratosMultiphysics.VariableUtils().AddDof(self.GetSolvingVariable(), self.GetOriginRootModelPart())
113
+ elif isinstance(self.GetSolvingVariable(), KratosMultiphysics.Array1DVariable3):
114
+ KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.KratosGlobals.GetVariable(f"{self.GetSolvingVariable().Name()}_X"), self.GetOriginRootModelPart())
115
+ KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.KratosGlobals.GetVariable(f"{self.GetSolvingVariable().Name()}_Y"), self.GetOriginRootModelPart())
116
+ KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.KratosGlobals.GetVariable(f"{self.GetSolvingVariable().Name()}_Z"), self.GetOriginRootModelPart())
117
+ else:
118
+ raise RuntimeError("Unsupported solving variable type.")
119
+ KratosMultiphysics.Logger.PrintInfo("::[HelmholtzSolverBase]:: DOFs ADDED.")
120
+
121
+ def AdvanceInTime(self, current_time: float) -> float:
122
+ dt = self.settings["time_stepping"]["time_step"].GetDouble()
123
+ new_time = current_time + dt
124
+ self.helmholtz_model_part.ProcessInfo[KratosMultiphysics.STEP] += 1
125
+ self.helmholtz_model_part.CloneTimeStep(new_time)
126
+
127
+ return new_time
128
+
129
+ def Initialize(self) -> None:
130
+ self._GetSolutionStrategy().Initialize()
131
+ neighbours_ta_int = KratosMultiphysics.TensorAdaptors.Utils.CreateNodalElementNeighboursCountTensorAdaptor(self.helmholtz_model_part)
132
+
133
+ writing_ta = KratosMultiphysics.TensorAdaptors.VariableTensorAdaptor(neighbours_ta_int.GetContainer(), KratosMultiphysics.NUMBER_OF_NEIGHBOUR_ELEMENTS)
134
+ writing_ta.SetData(neighbours_ta_int.data)
135
+ writing_ta.StoreData()
136
+ KratosMultiphysics.Logger.PrintInfo("::[HelmholtzSolverBase]:: Finished initialization.")
137
+
138
+ def InitializeSolutionStep(self) -> None:
139
+ self._GetSolutionStrategy().InitializeSolutionStep()
140
+
141
+ def FinalizeSolutionStep(self) -> None:
142
+ self._GetSolutionStrategy().FinalizeSolutionStep()
143
+
144
+ def Predict(self) -> None:
145
+ self._GetSolutionStrategy().Predict()
146
+
147
+ def SolveSolutionStep(self) -> None:
148
+ is_converged = bool(self._GetSolutionStrategy().Solve())
149
+ return is_converged
150
+
151
+ def SetEchoLevel(self, level: int) -> None:
152
+ self._GetSolutionStrategy().SetEchoLevel(level)
153
+
154
+ def GetEchoLevel(self) -> int:
155
+ self._GetSolutionStrategy().GetEchoLevel()
156
+
157
+ def Clear(self) -> None:
158
+ self._GetSolutionStrategy().Clear()
159
+
160
+ def ImportModelPart(self) -> None:
161
+ self._ImportModelPart(self.origin_root_model_part, self.settings["model_import_settings"])
162
+
163
+ def GetComputingModelPart(self) -> KratosMultiphysics.ModelPart:
164
+ return self.helmholtz_model_part
165
+
166
+ def GetOriginRootModelPart(self) -> KratosMultiphysics.ModelPart:
167
+ return self.origin_root_model_part
168
+
169
+ def GetOriginModelPart(self) -> KratosMultiphysics.ModelPart:
170
+ return self.model[self.filtering_model_part_name]
171
+
172
+ def GetFilterRadius(self) -> str:
173
+ return self.filter_radius
174
+
175
+ #### Protected functions ####
176
+
177
+ #### Specific internal functions ####
178
+
179
+ def _GetScheme(self):
180
+ if not hasattr(self, '_solution_scheme'):
181
+ self._solution_scheme = self._CreateScheme()
182
+ return self._solution_scheme
183
+
184
+ def _GetLinearSolver(self):
185
+ if not hasattr(self, '_linear_solver'):
186
+ self._linear_solver = self._CreateLinearSolver()
187
+ return self._linear_solver
188
+
189
+ def _GetBuilderAndSolver(self):
190
+ if not hasattr(self, '_builder_and_solver'):
191
+ self._builder_and_solver = self._CreateBuilderAndSolver()
192
+ return self._builder_and_solver
193
+
194
+ def _GetSolutionStrategy(self):
195
+ if not hasattr(self, '_solution_strategy'):
196
+ self._solution_strategy = self._CreateSolutionStrategy()
197
+ return self._solution_strategy
198
+
199
+ def _CreateBuilderAndSolver(self):
200
+ linear_solver = self._GetLinearSolver()
201
+ return KratosMultiphysics.ResidualBasedBlockBuilderAndSolver(linear_solver)
202
+
203
+ def _CreateLinearSolver(self):
204
+ return ConstructSolver(self.settings["linear_solver_settings"])
205
+
206
+ def _CreateScheme(self):
207
+ return KratosMultiphysics.ResidualBasedIncrementalUpdateStaticScheme()
208
+
209
+ def _CreateSolutionStrategy(self):
210
+ computing_model_part = self.GetComputingModelPart()
211
+ scheme = self._GetScheme()
212
+ builder_and_solver = self._GetBuilderAndSolver()
213
+ return KratosMultiphysics.ResidualBasedLinearStrategy(computing_model_part,
214
+ scheme,
215
+ builder_and_solver,
216
+ False,
217
+ False,
218
+ False,
219
+ False)
220
+
221
+ def _GetContainerTypeNumNodes(self, container: 'typing.Union[KratosMultiphysics.ConditionsArray, KratosMultiphysics.ElementsArray]') -> int:
222
+ num_nodes = None
223
+ for cont_type in container:
224
+ return len(cont_type.GetNodes())
225
+ return num_nodes
226
+
227
+ def _IsSurfaceContainer(self, container: 'typing.Union[KratosMultiphysics.ConditionsArray, KratosMultiphysics.ElementsArray]') -> bool:
228
+ return any(map(lambda x: x.GetGeometry().WorkingSpaceDimension() != x.GetGeometry().LocalSpaceDimension(), container))
229
+
230
+ def GetSourceVariable(self) -> SupportedSensitivityFieldVariableTypes:
231
+ if isinstance(self.GetSolvingVariable(), KratosMultiphysics.DoubleVariable):
232
+ return KOA.HELMHOLTZ_SCALAR_SOURCE
233
+ elif isinstance(self.GetSolvingVariable(), KratosMultiphysics.Array1DVariable3):
234
+ return KOA.HELMHOLTZ_VECTOR_SOURCE
235
+ else:
236
+ raise RuntimeError("Unsupported solving variable.")
237
+
238
+ def PrepareModelPart(self) -> str:
239
+ computing_model_part_name = self._GetComputingModelPartName()
240
+
241
+ if self.model.HasModelPart(computing_model_part_name):
242
+ # a same model part with same entities were already created by some other filter
243
+ # hence reusing it
244
+ self.helmholtz_model_part = self.model[computing_model_part_name]
245
+ else:
246
+ # the model part needs to be created.
247
+ self.helmholtz_model_part = self.model.CreateModelPart(computing_model_part_name)
248
+ KOA.OptimizationUtils.SetSolutionStepVariablesList(self.helmholtz_model_part, self.GetOriginRootModelPart())
249
+
250
+ # now fill with the appropriate elements and conditions
251
+ self._FillComputingModelPart()
252
+
253
+ self.__IncrementModelPartUsageCounter()
254
+
255
+ def __IncrementModelPartUsageCounter(self) -> None:
256
+ # we increase the usage number of filters using the model part.
257
+ # this is required to know whether we need to apply boundary conditions
258
+ # every time filter is used so that we don't mix-up different BCs from
259
+ # different filters and mesh motion solvers
260
+
261
+ # in here, the origin model part and its parents are updated. This is because,
262
+ # the computing model part shares nodes with the origin model part.
263
+ def increase_counter(model_part: KratosMultiphysics.ModelPart) -> None:
264
+ if not model_part.Has(KOA.NUMBER_OF_SOLVERS_USING_NODES):
265
+ model_part[KOA.NUMBER_OF_SOLVERS_USING_NODES] = 0
266
+ model_part[KOA.NUMBER_OF_SOLVERS_USING_NODES] += 1
267
+
268
+ current_model_part = self.GetOriginModelPart()
269
+ increase_counter(current_model_part)
270
+
271
+ # now increase the usage counter in all parent model parts.
272
+ while current_model_part != current_model_part.GetParentModelPart():
273
+ current_model_part = current_model_part.GetParentModelPart()
274
+ increase_counter(current_model_part)
275
+
@@ -0,0 +1,39 @@
1
+ # Importing the Kratos Library
2
+ import KratosMultiphysics as KM
3
+
4
+ # Import applications
5
+ import KratosMultiphysics.OptimizationApplication as KOA
6
+
7
+ # Import baseclass
8
+ from KratosMultiphysics.OptimizationApplication.filtering.helmholtz_solver_base import HelmholtzSolverBase
9
+
10
+ def CreateSolver(model: KM.Model, custom_settings: KM.Parameters):
11
+ return HelmholtzVectorSolver(model, custom_settings)
12
+
13
+ class HelmholtzVectorSolver(HelmholtzSolverBase):
14
+ def GetSolvingVariable(self) -> KM.Array1DVariable3:
15
+ return KOA.HELMHOLTZ_VECTOR
16
+
17
+ def _GetComputingModelPartName(self) -> str:
18
+ return self.GetOriginModelPart().FullName().replace(".", "_") + "_helmholtz_vector"
19
+
20
+ def SetFilterRadius(self, filter_radius: float) -> None:
21
+ self.GetComputingModelPart().ProcessInfo.SetValue(KOA.HELMHOLTZ_RADIUS, filter_radius)
22
+
23
+ def _FillComputingModelPart(self) -> None:
24
+ if self.GetOriginModelPart().NumberOfElements() > 0:
25
+ # here we have to replace the elements, while keeping the
26
+ # geometries the same. Hence using the ConnectivityPreserveModeller
27
+ container = self.GetOriginModelPart().Elements
28
+ num_nodes = self._GetContainerTypeNumNodes(container)
29
+ if self._IsSurfaceContainer(container):
30
+ KM.ConnectivityPreserveModeler().GenerateModelPart(self.GetOriginModelPart(), self.GetComputingModelPart(), f"HelmholtzVectorSurfaceElement3D{num_nodes}N")
31
+ else:
32
+ KM.ConnectivityPreserveModeler().GenerateModelPart(self.GetOriginModelPart(), self.GetComputingModelPart(), f"HelmholtzVectorSolidElement3D{num_nodes}N")
33
+ elif self.GetOriginModelPart().NumberOfConditions() > 0:
34
+ # here we have conditions in the origin model part. Now we have to create elements using
35
+ # the geometries of the conditions. There cannot be volume conditions in Kratos, therefore,
36
+ # there can be only surface conditions, hence only required to create surface elements.
37
+ KOA.OptAppModelPartUtils.GenerateModelPart(self.GetOriginModelPart().Conditions, self.GetComputingModelPart(), f"HelmholtzVectorSurfaceElement3D{self._GetContainerTypeNumNodes(self.GetOriginModelPart().Conditions)}N")
38
+ else:
39
+ raise RuntimeError(f"No elements or conditions found in {self.GetOriginModelPart()}.")