KratosContactStructuralMechanicsApplication 10.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- KratosMultiphysics/.libs/KratosContactStructuralMechanicsApplication.so +0 -0
- KratosMultiphysics/.libs/libKratosContactStructuralMechanicsCore.dylib +4 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/__init__.py +8 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/adaptive_remeshing/adaptative_remeshing_contact_structural_mechanics_analysis.py +291 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/adaptive_remeshing/adaptative_remeshing_contact_structural_mechanics_implicit_dynamic_solver.py +78 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/adaptive_remeshing/adaptative_remeshing_contact_structural_mechanics_static_solver.py +78 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/adaptive_remeshing/adaptative_remeshing_contact_structural_mechanics_utilities.py +67 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/alm_contact_process.py +498 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/auxiliary_methods_solvers.py +358 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/basic_mapping_process.py +103 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/contact_convergence_criteria_factory.py +210 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/contact_remesh_mmg_process.py +418 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/contact_structural_mechanics_explicit_dynamic_solver.py +103 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/contact_structural_mechanics_implicit_dynamic_solver.py +199 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/contact_structural_mechanics_static_solver.py +198 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/custom_sympy_fe_utilities.py +827 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/explicit_penalty_contact_process.py +282 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/mesh_tying_process.py +231 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/mpc_contact_process.py +418 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/mpc_contact_structural_mechanics_implicit_dynamic_solver.py +101 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/mpc_contact_structural_mechanics_static_solver.py +101 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/penalty_contact_process.py +254 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/python_solvers_wrapper_adaptative_remeshing_contact_structural.py +33 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/replace_properties_process.py +86 -0
- KratosMultiphysics/ContactStructuralMechanicsApplication/search_base_process.py +748 -0
- kratoscontactstructuralmechanicsapplication-10.4.4.dist-info/METADATA +74 -0
- kratoscontactstructuralmechanicsapplication-10.4.4.dist-info/RECORD +33 -0
- kratoscontactstructuralmechanicsapplication-10.4.4.dist-info/WHEEL +6 -0
- kratoscontactstructuralmechanicsapplication.dylibs/libKratosCore.dylib +4 -0
- kratoscontactstructuralmechanicsapplication.dylibs/libKratosStructuralMechanicsCore.dylib +0 -0
- kratoscontactstructuralmechanicsapplication.dylibs/libgcc_s.1.1.dylib +0 -0
- kratoscontactstructuralmechanicsapplication.dylibs/libgomp.1.dylib +0 -0
- kratoscontactstructuralmechanicsapplication.dylibs/libstdc++.6.dylib +0 -0
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Application dependent names and paths
|
|
2
|
+
from KratosMultiphysics import _ImportApplication
|
|
3
|
+
import KratosMultiphysics.StructuralMechanicsApplication
|
|
4
|
+
from KratosContactStructuralMechanicsApplication import *
|
|
5
|
+
application = KratosContactStructuralMechanicsApplication()
|
|
6
|
+
application_name = "KratosContactStructuralMechanicsApplication"
|
|
7
|
+
|
|
8
|
+
_ImportApplication(application, application_name)
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Importing Kratos
|
|
2
|
+
import KratosMultiphysics as KM
|
|
3
|
+
import KratosMultiphysics.StructuralMechanicsApplication as SMA
|
|
4
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication as CSMA
|
|
5
|
+
|
|
6
|
+
# Import the base structural analysis
|
|
7
|
+
from KratosMultiphysics.StructuralMechanicsApplication.structural_mechanics_analysis import StructuralMechanicsAnalysis as BaseClass
|
|
8
|
+
|
|
9
|
+
# NOTE: This analysis may fail because certain changes that are not part of the master branch are not here. This requires extra work in order to work.
|
|
10
|
+
|
|
11
|
+
class AdaptativeRemeshingContactStructuralMechanicsAnalysis(BaseClass):
|
|
12
|
+
"""
|
|
13
|
+
This class is the main-script of the ContactStructuralMechanicsApplication when using adaptative remeshing put in a class
|
|
14
|
+
|
|
15
|
+
It can be imported and used as "black-box"
|
|
16
|
+
"""
|
|
17
|
+
def __init__(self, model, project_parameters):
|
|
18
|
+
|
|
19
|
+
# Construct the base analysis.
|
|
20
|
+
default_params = KM.Parameters("""
|
|
21
|
+
{
|
|
22
|
+
"max_iteration" : 1,
|
|
23
|
+
"analysis_type" : "linear",
|
|
24
|
+
"contact_settings" :
|
|
25
|
+
{
|
|
26
|
+
"fancy_convergence_criterion" : false
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
""")
|
|
30
|
+
if project_parameters["solver_settings"].Has("max_iteration"):
|
|
31
|
+
self.non_linear_iterations = project_parameters["solver_settings"]["max_iteration"].GetInt()
|
|
32
|
+
else:
|
|
33
|
+
self.non_linear_iterations = 10
|
|
34
|
+
project_parameters["solver_settings"].AddValue("max_iteration", default_params["max_iteration"])
|
|
35
|
+
if project_parameters["solver_settings"].Has("analysis_type"):
|
|
36
|
+
project_parameters["solver_settings"]["analysis_type"].SetString("linear")
|
|
37
|
+
else:
|
|
38
|
+
project_parameters["solver_settings"].AddValue("analysis_type", default_params["analysis_type"])
|
|
39
|
+
if project_parameters["solver_settings"].Has("contact_settings"):
|
|
40
|
+
if project_parameters["solver_settings"]["contact_settings"].Has("fancy_convergence_criterion"):
|
|
41
|
+
project_parameters["solver_settings"]["contact_settings"]["fancy_convergence_criterion"].SetBool(False)
|
|
42
|
+
else:
|
|
43
|
+
project_parameters["solver_settings"]["contact_settings"].AddValue("fancy_convergence_criterion", default_params["contact_settings"]["fancy_convergence_criterion"])
|
|
44
|
+
else:
|
|
45
|
+
project_parameters["solver_settings"].AddValue("contact_settings", default_params["contact_settings"])
|
|
46
|
+
self.process_remesh = False
|
|
47
|
+
if project_parameters.Has("mesh_adaptivity_processes"):
|
|
48
|
+
self.process_remesh = True
|
|
49
|
+
if project_parameters.Has("processes"):
|
|
50
|
+
if project_parameters["processes"].Has("mesh_adaptivity_processes"):
|
|
51
|
+
self.process_remesh = True
|
|
52
|
+
if not self.process_remesh:
|
|
53
|
+
project_parameters["solver_settings"]["analysis_type"].SetString("linear")
|
|
54
|
+
super().__init__(model, project_parameters)
|
|
55
|
+
|
|
56
|
+
def Initialize(self):
|
|
57
|
+
""" Initializing the Analysis """
|
|
58
|
+
super().Initialize()
|
|
59
|
+
computing_model_part = self._GetSolver().GetComputingModelPart()
|
|
60
|
+
if not self.process_remesh:
|
|
61
|
+
convergence_criteria = self._GetSolver()._GetConvergenceCriterion()
|
|
62
|
+
convergence_criteria.Initialize(computing_model_part)
|
|
63
|
+
|
|
64
|
+
# Ensuring to have conditions on the BC before remesh
|
|
65
|
+
is_surface = False
|
|
66
|
+
for elem in computing_model_part.Elements:
|
|
67
|
+
geom = elem.GetGeometry()
|
|
68
|
+
if geom.WorkingSpaceDimension() != geom.LocalSpaceDimension():
|
|
69
|
+
is_surface = True
|
|
70
|
+
break
|
|
71
|
+
|
|
72
|
+
if not is_surface:
|
|
73
|
+
list_model_parts = []
|
|
74
|
+
# We need to detect the conditions in the boundary conditions
|
|
75
|
+
if self.project_parameters.Has("constraints_process_list"):
|
|
76
|
+
constraints_process_list = self.project_parameters["constraints_process_list"]
|
|
77
|
+
for i in range(0,constraints_process_list.size()):
|
|
78
|
+
item = constraints_process_list[i]
|
|
79
|
+
list_model_parts.append(item["Parameters"]["model_part_name"].GetString())
|
|
80
|
+
skin_detection_parameters = KM.Parameters("""
|
|
81
|
+
{
|
|
82
|
+
"list_model_parts_to_assign_conditions" : []
|
|
83
|
+
}
|
|
84
|
+
""")
|
|
85
|
+
for name_mp in list_model_parts:
|
|
86
|
+
skin_detection_parameters["list_model_parts_to_assign_conditions"].Append(name_mp)
|
|
87
|
+
|
|
88
|
+
if computing_model_part.ProcessInfo[KM.DOMAIN_SIZE] == 2:
|
|
89
|
+
detect_skin = KM.SkinDetectionProcess2D(computing_model_part, skin_detection_parameters)
|
|
90
|
+
else:
|
|
91
|
+
detect_skin = KM.SkinDetectionProcess3D(computing_model_part, skin_detection_parameters)
|
|
92
|
+
detect_skin.Execute()
|
|
93
|
+
self._GetSolver().SetEchoLevel(self.echo_level)
|
|
94
|
+
|
|
95
|
+
def RunSolutionLoop(self):
|
|
96
|
+
"""This function executes the solution loop of the AnalysisStage
|
|
97
|
+
It can be overridden by derived classes
|
|
98
|
+
"""
|
|
99
|
+
# If we remesh using a process
|
|
100
|
+
computing_model_part = self._GetSolver().GetComputingModelPart()
|
|
101
|
+
root_model_part = computing_model_part.GetRootModelPart()
|
|
102
|
+
if self.process_remesh:
|
|
103
|
+
while self.time < self.end_time:
|
|
104
|
+
self.time = self._GetSolver().AdvanceInTime(self.time)
|
|
105
|
+
# We reinitialize if remeshed previously
|
|
106
|
+
if root_model_part.Is(KM.MODIFIED):
|
|
107
|
+
self._ReInitializeSolver()
|
|
108
|
+
self.InitializeSolutionStep()
|
|
109
|
+
# We reinitialize if remeshed on the InitializeSolutionStep
|
|
110
|
+
if root_model_part.Is(KM.MODIFIED):
|
|
111
|
+
self._ReInitializeSolver()
|
|
112
|
+
self.InitializeSolutionStep()
|
|
113
|
+
# self._GetSolver().Predict() # NOTE: Legacy Predict, now is part of the InitializeSolutionStep
|
|
114
|
+
self._GetSolver().SolveSolutionStep()
|
|
115
|
+
self._transfer_slave_to_master()
|
|
116
|
+
self.FinalizeSolutionStep()
|
|
117
|
+
self.OutputSolutionStep()
|
|
118
|
+
else: # Remeshing adaptively
|
|
119
|
+
metric_process = self._GetSolver().get_metric_process()
|
|
120
|
+
remeshing_process = self._GetSolver().get_remeshing_process()
|
|
121
|
+
convergence_criteria = self._GetSolver()._GetConvergenceCriterion()
|
|
122
|
+
builder_and_solver = self._GetSolver()._GetBuilderAndSolver()
|
|
123
|
+
mechanical_solution_strategy = self._GetSolver()._GetSolutionStrategy()
|
|
124
|
+
|
|
125
|
+
while self.time < self.end_time:
|
|
126
|
+
self.time = self._GetSolver().AdvanceInTime(self.time)
|
|
127
|
+
non_linear_iteration = 1
|
|
128
|
+
while non_linear_iteration <= self.non_linear_iterations:
|
|
129
|
+
if computing_model_part.Is(KM.MODIFIED):
|
|
130
|
+
self._GetSolver().Clear()
|
|
131
|
+
# WE RECOMPUTE THE PROCESSES AGAIN
|
|
132
|
+
# Processes initialization
|
|
133
|
+
for process in self._GetListOfProcesses():
|
|
134
|
+
process.ExecuteInitialize()
|
|
135
|
+
## Processes before the loop
|
|
136
|
+
for process in self._GetListOfProcesses():
|
|
137
|
+
process.ExecuteBeforeSolutionLoop()
|
|
138
|
+
## Processes of initialize the solution step
|
|
139
|
+
for process in self._GetListOfProcesses():
|
|
140
|
+
process.ExecuteInitializeSolutionStep()
|
|
141
|
+
if non_linear_iteration == 1 or computing_model_part.Is(KM.MODIFIED):
|
|
142
|
+
self.InitializeSolutionStep()
|
|
143
|
+
# self._GetSolver().Predict() # NOTE: Legacy Predict, now is part of the InitializeSolutionStep
|
|
144
|
+
computing_model_part.Set(KM.MODIFIED, False)
|
|
145
|
+
computing_model_part.ProcessInfo.SetValue(KM.NL_ITERATION_NUMBER, non_linear_iteration)
|
|
146
|
+
reform_dofs = mechanical_solution_strategy.GetReformDofSetAtEachStepFlag()
|
|
147
|
+
mechanical_solution_strategy.SetReformDofSetAtEachStepFlag(True)
|
|
148
|
+
is_converged = convergence_criteria.PreCriteria(computing_model_part, builder_and_solver.GetDofSet(), mechanical_solution_strategy.GetSystemMatrix(), mechanical_solution_strategy.GetSolutionVector(), mechanical_solution_strategy.GetSystemVector())
|
|
149
|
+
self._GetSolver().SolveSolutionStep()
|
|
150
|
+
is_converged = convergence_criteria.PostCriteria(computing_model_part, builder_and_solver.GetDofSet(), mechanical_solution_strategy.GetSystemMatrix(), mechanical_solution_strategy.GetSolutionVector(), mechanical_solution_strategy.GetSystemVector())
|
|
151
|
+
self._transfer_slave_to_master()
|
|
152
|
+
self.FinalizeSolutionStep()
|
|
153
|
+
mechanical_solution_strategy.SetReformDofSetAtEachStepFlag(reform_dofs)
|
|
154
|
+
if is_converged:
|
|
155
|
+
KM.Logger.PrintInfo(self._GetSimulationName(), "Adaptative strategy converged in ", non_linear_iteration, "iterations" )
|
|
156
|
+
break
|
|
157
|
+
elif non_linear_iteration == self.non_linear_iterations:
|
|
158
|
+
KM.Logger.PrintInfo(self._GetSimulationName(), "Adaptative strategy not converged after ", non_linear_iteration, "iterations" )
|
|
159
|
+
break
|
|
160
|
+
else:
|
|
161
|
+
# Before remesh we set the flag INTERFACE to the conditions (we need edges to preserve submodelparts)
|
|
162
|
+
KM.VariableUtils().SetFlag(KM.INTERFACE, True, computing_model_part.GetSubModelPart("Contact").Conditions)
|
|
163
|
+
# We remove the contact model part to avoid problems (it will be recomputed later)
|
|
164
|
+
contact_model_part = computing_model_part.GetSubModelPart("Contact")
|
|
165
|
+
for model_part in contact_model_part.SubModelParts:
|
|
166
|
+
contact_model_part.RemoveSubModelPart(model_part.Name)
|
|
167
|
+
computing_model_part.RemoveSubModelPart("ComputingContact")
|
|
168
|
+
# Now we can remesh
|
|
169
|
+
metric_process.Execute()
|
|
170
|
+
remeshing_process.Execute()
|
|
171
|
+
# We remove the contact model part to avoid problems (it will be recomputed later)
|
|
172
|
+
computing_model_part.RemoveSubModelPart("Contact")
|
|
173
|
+
# Now we set as modified
|
|
174
|
+
computing_model_part.Set(KM.MODIFIED, True)
|
|
175
|
+
non_linear_iteration += 1
|
|
176
|
+
self.OutputSolutionStep()
|
|
177
|
+
|
|
178
|
+
#### Internal functions ####
|
|
179
|
+
def _CreateSolver(self):
|
|
180
|
+
""" Create the Solver (and create and import the ModelPart if it is not already in the model) """
|
|
181
|
+
|
|
182
|
+
# To avoid many prints
|
|
183
|
+
if self.echo_level == 0:
|
|
184
|
+
KM.Logger.GetDefaultOutput().SetSeverity(KM.Logger.Severity.WARNING)
|
|
185
|
+
|
|
186
|
+
## Solver construction
|
|
187
|
+
import python_solvers_wrapper_adaptative_remeshing_contact_structural
|
|
188
|
+
return python_solvers_wrapper_adaptative_remeshing_contact_structural.CreateSolver(self.model, self.project_parameters)
|
|
189
|
+
|
|
190
|
+
def _CreateProcesses(self, parameter_name, initialization_order):
|
|
191
|
+
"""Create a list of Processes
|
|
192
|
+
This method is TEMPORARY to not break existing code
|
|
193
|
+
It will be removed in the future
|
|
194
|
+
"""
|
|
195
|
+
list_of_processes = super()._CreateProcesses(parameter_name, initialization_order)
|
|
196
|
+
|
|
197
|
+
if parameter_name == "processes":
|
|
198
|
+
processes_block_names = ["mesh_adaptivity_processes"]
|
|
199
|
+
if len(list_of_processes) == 0: # Processes are given in the old format
|
|
200
|
+
KM.Logger.PrintWarning("AdaptativeRemeshingContactStructuralMechanicsAnalysis", "Using the old way to create the processes, this will be removed!")
|
|
201
|
+
from process_factory import KratosProcessFactory
|
|
202
|
+
factory = KratosProcessFactory(self.model)
|
|
203
|
+
for process_name in processes_block_names:
|
|
204
|
+
if (self.project_parameters.Has(process_name) is True):
|
|
205
|
+
list_of_processes += factory.ConstructListOfProcesses(self.project_parameters[process_name])
|
|
206
|
+
else: # Processes are given in the new format
|
|
207
|
+
for process_name in processes_block_names:
|
|
208
|
+
if (self.project_parameters.Has(process_name) is True):
|
|
209
|
+
raise Exception("Mixing of process initialization is not allowed!")
|
|
210
|
+
elif parameter_name == "output_processes":
|
|
211
|
+
pass # Already added
|
|
212
|
+
else:
|
|
213
|
+
raise NameError("wrong parameter name")
|
|
214
|
+
|
|
215
|
+
return list_of_processes
|
|
216
|
+
|
|
217
|
+
def _transfer_slave_to_master(self):
|
|
218
|
+
""" This method to transfer information from the slave side to the master side
|
|
219
|
+
|
|
220
|
+
Keyword arguments:
|
|
221
|
+
self -- It signifies an instance of a class.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
computing_model_part = self._GetSolver().GetComputingModelPart()
|
|
225
|
+
map_parameters = KM.Parameters("""
|
|
226
|
+
{
|
|
227
|
+
"echo_level" : 0,
|
|
228
|
+
"destination_variable_historical" : false,
|
|
229
|
+
"absolute_convergence_tolerance" : 1.0e-9,
|
|
230
|
+
"relative_convergence_tolerance" : 1.0e-4,
|
|
231
|
+
"max_number_iterations" : 10,
|
|
232
|
+
"origin_variable" : "AUGMENTED_NORMAL_CONTACT_PRESSURE",
|
|
233
|
+
"destination_variable" : "CONTACT_PRESSURE",
|
|
234
|
+
"integration_order" : 2
|
|
235
|
+
}
|
|
236
|
+
""")
|
|
237
|
+
|
|
238
|
+
interface_model_part = computing_model_part.GetSubModelPart("Contact")
|
|
239
|
+
main_model_part = computing_model_part.GetRootModelPart()
|
|
240
|
+
main_model_part.RemoveSubModelPart("ComputingContact")
|
|
241
|
+
|
|
242
|
+
if interface_model_part.HasSubModelPart("SlaveSubModelPart"):
|
|
243
|
+
slave_interface_model_part = interface_model_part.GetSubModelPart("SlaveSubModelPart")
|
|
244
|
+
else:
|
|
245
|
+
slave_interface_model_part = interface_model_part.CreateSubModelPart("SlaveSubModelPart")
|
|
246
|
+
KM.FastTransferBetweenModelPartsProcess(slave_interface_model_part, interface_model_part, KM.FastTransferBetweenModelPartsProcess.EntityTransfered.NODES, KM.SLAVE).Execute()
|
|
247
|
+
KM.FastTransferBetweenModelPartsProcess(slave_interface_model_part, interface_model_part, KM.FastTransferBetweenModelPartsProcess.EntityTransfered.CONDITIONS, KM.SLAVE).Execute()
|
|
248
|
+
if interface_model_part.HasSubModelPart("MasterSubModelPart"):
|
|
249
|
+
master_interface_model_part = interface_model_part.GetSubModelPart("MasterSubModelPart")
|
|
250
|
+
else:
|
|
251
|
+
master_interface_model_part = interface_model_part.CreateSubModelPart("MasterSubModelPart")
|
|
252
|
+
KM.FastTransferBetweenModelPartsProcess(master_interface_model_part, interface_model_part, KM.FastTransferBetweenModelPartsProcess.EntityTransfered.NODES, KM.MASTER).Execute()
|
|
253
|
+
KM.FastTransferBetweenModelPartsProcess(master_interface_model_part, interface_model_part, KM.FastTransferBetweenModelPartsProcess.EntityTransfered.CONDITIONS, KM.MASTER).Execute()
|
|
254
|
+
|
|
255
|
+
mortar_mapping = KM.SimpleMortarMapperProcess(slave_interface_model_part, master_interface_model_part, map_parameters)
|
|
256
|
+
mortar_mapping.Execute()
|
|
257
|
+
|
|
258
|
+
def _ReInitializeSolver(self):
|
|
259
|
+
""" This reinitializes after remesh """
|
|
260
|
+
self._GetSolver().Clear()
|
|
261
|
+
# WE INITIALIZE THE SOLVER
|
|
262
|
+
self._GetSolver().Initialize()
|
|
263
|
+
# WE RECOMPUTE THE PROCESSES AGAIN
|
|
264
|
+
## Processes initialization
|
|
265
|
+
for process in self._GetListOfProcesses():
|
|
266
|
+
process.ExecuteInitialize()
|
|
267
|
+
## Processes before the loop
|
|
268
|
+
for process in self._GetListOfProcesses():
|
|
269
|
+
process.ExecuteBeforeSolutionLoop()
|
|
270
|
+
## Processes of initialize the solution step
|
|
271
|
+
for process in self._GetListOfProcesses():
|
|
272
|
+
process.ExecuteInitializeSolutionStep()
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
from sys import argv
|
|
276
|
+
|
|
277
|
+
if len(argv) > 2:
|
|
278
|
+
err_msg = 'Too many input arguments!\n'
|
|
279
|
+
err_msg += 'Use this script in the following way:\n'
|
|
280
|
+
err_msg += '- With default ProjectParameters (read from "ProjectParameters.json"):\n'
|
|
281
|
+
err_msg += ' "python3 adaptative_contact_structural_mechanics_analysis.py"\n'
|
|
282
|
+
err_msg += '- With custom ProjectParameters:\n'
|
|
283
|
+
err_msg += ' "python3 adaptative_contact_structural_mechanics_analysis.py CustomProjectParameters.json"\n'
|
|
284
|
+
raise Exception(err_msg)
|
|
285
|
+
|
|
286
|
+
if len(argv) == 2: # ProjectParameters is being passed from outside
|
|
287
|
+
project_parameters_file_name = argv[1]
|
|
288
|
+
else: # using default name
|
|
289
|
+
project_parameters_file_name = "ProjectParameters.json"
|
|
290
|
+
|
|
291
|
+
AdaptativeRemeshingContactStructuralMechanicsAnalysis(project_parameters_file_name).Run()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics as KM
|
|
3
|
+
|
|
4
|
+
# Import applications
|
|
5
|
+
import KratosMultiphysics.StructuralMechanicsApplication as SMA
|
|
6
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication as CSMA
|
|
7
|
+
|
|
8
|
+
import KratosMultiphysics.kratos_utilities as kratos_utilities
|
|
9
|
+
if kratos_utilities.CheckIfApplicationsAvailable("MeshingApplication"):
|
|
10
|
+
has_meshing_application = True
|
|
11
|
+
else:
|
|
12
|
+
has_meshing_application = False
|
|
13
|
+
|
|
14
|
+
# Import adaptive remeshing utilities
|
|
15
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication.adaptative_remeshing_contact_structural_mechanics_utilities as adaptative_remeshing_contact_structural_mechanics_utilities
|
|
16
|
+
|
|
17
|
+
# Import base class file
|
|
18
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication.contact_structural_mechanics_implicit_dynamic_solver as contact_structural_mechanics_implicit_dynamic_solver
|
|
19
|
+
|
|
20
|
+
def CreateSolver(model, custom_settings):
|
|
21
|
+
return AdaptativeRemeshingContactImplicitMechanicalSolver(model, custom_settings)
|
|
22
|
+
|
|
23
|
+
class AdaptativeRemeshingContactImplicitMechanicalSolver(contact_structural_mechanics_implicit_dynamic_solver.ContactImplicitMechanicalSolver):
|
|
24
|
+
"""The contact structural mechanics implicit dynamic solver. (For adaptative remeshing)
|
|
25
|
+
See contact_structural_mechanics_implicit_dynamic_solver.py for more information.
|
|
26
|
+
"""
|
|
27
|
+
def __init__(self, model, custom_settings):
|
|
28
|
+
# Set defaults and validate custom settings.
|
|
29
|
+
self.adaptative_remeshing_utilities = adaptative_remeshing_contact_structural_mechanics_utilities.AdaptativeRemeshingContactMechanicalUtilities()
|
|
30
|
+
|
|
31
|
+
# Construct the base solver.
|
|
32
|
+
super(AdaptativeRemeshingContactImplicitMechanicalSolver, self).__init__(model, custom_settings)
|
|
33
|
+
KM.Logger.PrintInfo("::[AdaptativeRemeshingContactImplicitMechanicalSolver]:: ", "Construction finished")
|
|
34
|
+
|
|
35
|
+
#### Private functions ####
|
|
36
|
+
|
|
37
|
+
def AddVariables(self):
|
|
38
|
+
super(AdaptativeRemeshingContactImplicitMechanicalSolver, self).AddVariables()
|
|
39
|
+
if has_meshing_application:
|
|
40
|
+
self.main_model_part.AddNodalSolutionStepVariable(KM.NODAL_H)
|
|
41
|
+
KM.Logger.PrintInfo("::[AdaptativeRemeshingContactImplicitMechanicalSolver]:: ", "Variables ADDED")
|
|
42
|
+
|
|
43
|
+
def get_remeshing_process(self):
|
|
44
|
+
if not hasattr(self, '_remeshing_process'):
|
|
45
|
+
self._remeshing_process = self._create_remeshing_process()
|
|
46
|
+
return self._remeshing_process
|
|
47
|
+
|
|
48
|
+
def _create_remeshing_process(self):
|
|
49
|
+
if self.main_model_part.ProcessInfo[KM.DOMAIN_SIZE] == 2:
|
|
50
|
+
remeshing_process = MA.MmgProcess2D(self.main_model_part, self.settings["remeshing_parameters"])
|
|
51
|
+
else:
|
|
52
|
+
remeshing_process = MA.MmgProcess3D(self.main_model_part, self.settings["remeshing_parameters"])
|
|
53
|
+
|
|
54
|
+
return remeshing_process
|
|
55
|
+
|
|
56
|
+
def get_metric_process(self):
|
|
57
|
+
if not hasattr(self, '_metric_process'):
|
|
58
|
+
self._metric_process = self._create_metric_process()
|
|
59
|
+
return self._metric_process
|
|
60
|
+
|
|
61
|
+
def _create_metric_process(self):
|
|
62
|
+
if self.main_model_part.ProcessInfo[KM.DOMAIN_SIZE] == 2:
|
|
63
|
+
metric_process = MA.MetricErrorProcess2D(self.main_model_part, self.settings["metric_error_parameters"])
|
|
64
|
+
else:
|
|
65
|
+
metric_process = MA.MetricErrorProcess3D(self.main_model_part, self.settings["metric_error_parameters"])
|
|
66
|
+
|
|
67
|
+
return metric_process
|
|
68
|
+
|
|
69
|
+
def _CreateConvergenceCriterion(self):
|
|
70
|
+
error_criteria = self.settings["convergence_criterion"].GetString()
|
|
71
|
+
conv_settings = self._get_convergence_criterion_settings()
|
|
72
|
+
return self.adaptative_remeshing_utilities.GetConvergenceCriteria(error_criteria, conv_settings)
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def GetDefaultParameters(cls):
|
|
76
|
+
this_defaults = adaptative_remeshing_contact_structural_mechanics_utilities.AdaptativeRemeshingContactMechanicalUtilities().GetDefaultParameters()
|
|
77
|
+
this_defaults.AddMissingParameters(super().GetDefaultParameters())
|
|
78
|
+
return this_defaults
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics as KM
|
|
3
|
+
|
|
4
|
+
# Import applications
|
|
5
|
+
import KratosMultiphysics.StructuralMechanicsApplication as SMA
|
|
6
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication as CSMA
|
|
7
|
+
|
|
8
|
+
import KratosMultiphysics.kratos_utilities as kratos_utilities
|
|
9
|
+
if kratos_utilities.CheckIfApplicationsAvailable("MeshingApplication"):
|
|
10
|
+
has_meshing_application = True
|
|
11
|
+
else:
|
|
12
|
+
has_meshing_application = False
|
|
13
|
+
|
|
14
|
+
# Import adaptive remeshing utilities
|
|
15
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication.adaptative_remeshing_contact_structural_mechanics_utilities as adaptative_remeshing_contact_structural_mechanics_utilities
|
|
16
|
+
|
|
17
|
+
# Import base class file
|
|
18
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication.contact_structural_mechanics_static_solver as contact_structural_mechanics_static_solver
|
|
19
|
+
|
|
20
|
+
def CreateSolver(model, custom_settings):
|
|
21
|
+
return AdaptativeRemeshingContactStaticMechanicalSolver(model, custom_settings)
|
|
22
|
+
|
|
23
|
+
class AdaptativeRemeshingContactStaticMechanicalSolver(contact_structural_mechanics_static_solver.ContactStaticMechanicalSolver):
|
|
24
|
+
"""The structural mechanics static solver. (For adaptative remeshing)
|
|
25
|
+
See contact_structural_mechanics_static_solver.py for more information.
|
|
26
|
+
"""
|
|
27
|
+
def __init__(self, model, custom_settings):
|
|
28
|
+
# Set defaults and validate custom settings.
|
|
29
|
+
self.adaptative_remeshing_utilities = adaptative_remeshing_contact_structural_mechanics_utilities.AdaptativeRemeshingContactMechanicalUtilities()
|
|
30
|
+
|
|
31
|
+
# Construct the base solver.
|
|
32
|
+
super(AdaptativeRemeshingContactStaticMechanicalSolver, self).__init__(model, custom_settings)
|
|
33
|
+
KM.Logger.PrintInfo("::[AdaptativeRemeshingContactStaticMechanicalSolver]:: ", "Construction finished")
|
|
34
|
+
|
|
35
|
+
#### Private functions ####
|
|
36
|
+
|
|
37
|
+
def AddVariables(self):
|
|
38
|
+
super(AdaptativeRemeshingContactStaticMechanicalSolver, self).AddVariables()
|
|
39
|
+
if has_meshing_application:
|
|
40
|
+
self.main_model_part.AddNodalSolutionStepVariable(KM.NODAL_H)
|
|
41
|
+
KM.Logger.PrintInfo("::[AdaptativeRemeshingContactStaticMechanicalSolver]:: ", "Variables ADDED")
|
|
42
|
+
|
|
43
|
+
def get_remeshing_process(self):
|
|
44
|
+
if not hasattr(self, '_remeshing_process'):
|
|
45
|
+
self._remeshing_process = self._create_remeshing_process()
|
|
46
|
+
return self._remeshing_process
|
|
47
|
+
|
|
48
|
+
def _create_remeshing_process(self):
|
|
49
|
+
if self.main_model_part.ProcessInfo[KM.DOMAIN_SIZE] == 2:
|
|
50
|
+
remeshing_process = MA.MmgProcess2D(self.main_model_part, self.settings["remeshing_parameters"])
|
|
51
|
+
else:
|
|
52
|
+
remeshing_process = MA.MmgProcess3D(self.main_model_part, self.settings["remeshing_parameters"])
|
|
53
|
+
|
|
54
|
+
return remeshing_process
|
|
55
|
+
|
|
56
|
+
def get_metric_process(self):
|
|
57
|
+
if not hasattr(self, '_metric_process'):
|
|
58
|
+
self._metric_process = self._create_metric_process()
|
|
59
|
+
return self._metric_process
|
|
60
|
+
|
|
61
|
+
def _create_metric_process(self):
|
|
62
|
+
if self.main_model_part.ProcessInfo[KM.DOMAIN_SIZE] == 2:
|
|
63
|
+
metric_process = MA.MetricErrorProcess2D(self.main_model_part, self.settings["metric_error_parameters"])
|
|
64
|
+
else:
|
|
65
|
+
metric_process = MA.MetricErrorProcess3D(self.main_model_part, self.settings["metric_error_parameters"])
|
|
66
|
+
|
|
67
|
+
return metric_process
|
|
68
|
+
|
|
69
|
+
def _CreateConvergenceCriterion(self):
|
|
70
|
+
error_criteria = self.settings["convergence_criterion"].GetString()
|
|
71
|
+
conv_settings = self._get_convergence_criterion_settings()
|
|
72
|
+
return self.adaptative_remeshing_utilities.GetConvergenceCriteria(error_criteria, conv_settings)
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def GetDefaultParameters(cls):
|
|
76
|
+
this_defaults = adaptative_remeshing_contact_structural_mechanics_utilities.AdaptativeRemeshingContactMechanicalUtilities().GetDefaultParameters()
|
|
77
|
+
this_defaults.AddMissingParameters(super().GetDefaultParameters())
|
|
78
|
+
return this_defaults
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics as KM
|
|
3
|
+
|
|
4
|
+
# Import applications
|
|
5
|
+
import KratosMultiphysics.StructuralMechanicsApplication as SMA
|
|
6
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication as CSMA
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import KratosMultiphysics.MeshingApplication as MeshingApplication
|
|
10
|
+
missing_meshing_dependencies = False
|
|
11
|
+
missing_application = ''
|
|
12
|
+
except ImportError as e:
|
|
13
|
+
missing_meshing_dependencies = True
|
|
14
|
+
# extract name of the missing application from the error message
|
|
15
|
+
import re
|
|
16
|
+
missing_application = re.search(r'''.*'KratosMultiphysics\.(.*)'.*''','{0}'.format(e)).group(1)
|
|
17
|
+
|
|
18
|
+
# Import base class
|
|
19
|
+
import KratosMultiphysics.ContactStructuralMechanicsApplication.adaptative_remeshing_structural_mechanics_utilities as adaptative_remeshing_structural_mechanics_utilities
|
|
20
|
+
|
|
21
|
+
class AdaptativeRemeshingContactMechanicalUtilities(adaptative_remeshing_structural_mechanics_utilities.AdaptativeRemeshingMechanicalUtilities):
|
|
22
|
+
"""These are common utilities for adaptative remeshing (for contact)
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self):
|
|
26
|
+
new_parameters = KM.Parameters("""
|
|
27
|
+
{
|
|
28
|
+
"penalty_normal" : 1.0e4,
|
|
29
|
+
"penalty_tangential" : 1.0e4
|
|
30
|
+
}
|
|
31
|
+
""")
|
|
32
|
+
super(AdaptativeRemeshingContactMechanicalUtilities, self).__init__()
|
|
33
|
+
self.adaptative_remesh_parameters["compute_error_settings"]["compute_error_extra_parameters"].AddValue("penalty_normal", new_parameters["penalty_normal"])
|
|
34
|
+
self.adaptative_remesh_parameters["compute_error_settings"]["compute_error_extra_parameters"].AddValue("penalty_tangential", new_parameters["penalty_tangential"])
|
|
35
|
+
|
|
36
|
+
def GetDefaultParameters(self):
|
|
37
|
+
return self.adaptative_remesh_parameters
|
|
38
|
+
|
|
39
|
+
def SetDefaultParameters(self, settings):
|
|
40
|
+
self.adaptative_remesh_parameters = settings
|
|
41
|
+
|
|
42
|
+
def GetConvergenceCriteria(self, error_criteria, conv_settings):
|
|
43
|
+
if "_with_adaptative_remesh" in error_criteria:
|
|
44
|
+
conv_settings["convergence_criterion"].SetString(error_criteria.replace("_with_adaptative_remesh", ""))
|
|
45
|
+
import contact_convergence_criteria_factory
|
|
46
|
+
convergence_criterion = contact_convergence_criteria_factory.convergence_criterion(conv_settings)
|
|
47
|
+
|
|
48
|
+
# If we just use the adaptative convergence criteria
|
|
49
|
+
if missing_meshing_dependencies:
|
|
50
|
+
if "adaptative_remesh" in error_criteria:
|
|
51
|
+
raise NameError('The AdaptativeErrorCriteria can not be used without compiling the MeshingApplication')
|
|
52
|
+
else:
|
|
53
|
+
if error_criteria == "adaptative_remesh_criteria":
|
|
54
|
+
adaptative_error_criteria = CSMA.ContactErrorMeshCriteria(self.adaptative_remesh_parameters["compute_error_settings"])
|
|
55
|
+
convergence_criterion.mechanical_convergence_criterion = KM.AndCriteria(convergence_criterion.GetMortarCriteria(False), adaptative_error_criteria)
|
|
56
|
+
elif "with_adaptative_remesh" in error_criteria: # If we combine the regular convergence criteria with adaptative
|
|
57
|
+
adaptative_error_criteria = CSMA.ContactErrorMeshCriteria(self.adaptative_remesh_parameters["compute_error_settings"])
|
|
58
|
+
convergence_criterion.mechanical_convergence_criterion = KM.AndCriteria(convergence_criterion.mechanical_convergence_criterion, adaptative_error_criteria)
|
|
59
|
+
|
|
60
|
+
return convergence_criterion.mechanical_convergence_criterion
|
|
61
|
+
|
|
62
|
+
# If we combine the regular convergence criteria with adaptative
|
|
63
|
+
if not missing_meshing_dependencies:
|
|
64
|
+
if "with_adaptative_remesh" in error_criteria:
|
|
65
|
+
adaptative_error_criteria = CSMA.ContactErrorMeshCriteria(self.adaptative_remesh_parameters["compute_error_settings"])
|
|
66
|
+
convergence_criterion.mechanical_convergence_criterion = KM.AndCriteria(convergence_criterion.mechanical_convergence_criterion, adaptative_error_criteria)
|
|
67
|
+
return convergence_criterion.mechanical_convergence_criterion
|