KratosMeshMovingApplication 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/KratosMeshMovingApplication.so +0 -0
- KratosMultiphysics/.libs/libKratosMeshMovingCore.dylib +0 -0
- KratosMultiphysics/MeshMovingApplication/__init__.py +6 -0
- KratosMultiphysics/MeshMovingApplication/ale_fluid_solver.py +226 -0
- KratosMultiphysics/MeshMovingApplication/impose_mesh_motion_process.py +139 -0
- KratosMultiphysics/MeshMovingApplication/mesh_moving_analysis.py +86 -0
- KratosMultiphysics/MeshMovingApplication/mesh_solver_base.py +264 -0
- KratosMultiphysics/MeshMovingApplication/mesh_solver_laplacian.py +42 -0
- KratosMultiphysics/MeshMovingApplication/mesh_solver_structural_similarity.py +34 -0
- KratosMultiphysics/MeshMovingApplication/python_solvers_wrapper_mesh_motion.py +62 -0
- KratosMultiphysics/MeshMovingApplication/trilinos_mesh_solver_base.py +78 -0
- KratosMultiphysics/MeshMovingApplication/trilinos_mesh_solver_laplacian.py +46 -0
- KratosMultiphysics/MeshMovingApplication/trilinos_mesh_solver_structural_similarity.py +36 -0
- kratosmeshmovingapplication-10.4.4.dist-info/METADATA +34 -0
- kratosmeshmovingapplication-10.4.4.dist-info/RECORD +20 -0
- kratosmeshmovingapplication-10.4.4.dist-info/WHEEL +6 -0
- kratosmeshmovingapplication.dylibs/libKratosCore.dylib +4 -0
- kratosmeshmovingapplication.dylibs/libgcc_s.1.1.dylib +0 -0
- kratosmeshmovingapplication.dylibs/libgomp.1.dylib +0 -0
- kratosmeshmovingapplication.dylibs/libstdc++.6.dylib +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics as KM
|
|
3
|
+
|
|
4
|
+
# Other imports
|
|
5
|
+
from KratosMultiphysics.python_solver import PythonSolver
|
|
6
|
+
import KratosMultiphysics.MeshMovingApplication.python_solvers_wrapper_mesh_motion as mesh_mothion_solvers_wrapper
|
|
7
|
+
|
|
8
|
+
class AleFluidSolver(PythonSolver):
|
|
9
|
+
def __init__(self, model, solver_settings, parallelism):
|
|
10
|
+
|
|
11
|
+
self._validate_settings_in_baseclass=True # To be removed eventually
|
|
12
|
+
super().__init__(model, solver_settings)
|
|
13
|
+
|
|
14
|
+
self.start_fluid_solution_time = self.settings["start_fluid_solution_time"].GetDouble()
|
|
15
|
+
|
|
16
|
+
self.parallelism = parallelism
|
|
17
|
+
|
|
18
|
+
fluid_solver_settings = self.settings["fluid_solver_settings"]
|
|
19
|
+
mesh_motion_solver_settings = self.settings["mesh_motion_solver_settings"]
|
|
20
|
+
|
|
21
|
+
fluid_model_part_name = fluid_solver_settings["model_part_name"].GetString()
|
|
22
|
+
if not self.model.HasModelPart(fluid_model_part_name):
|
|
23
|
+
model.CreateModelPart(fluid_model_part_name)
|
|
24
|
+
|
|
25
|
+
# Derived class decides if the reactions should be computed or not
|
|
26
|
+
self._ManipulateFluidSolverSettingsForReactionsComputation(fluid_solver_settings)
|
|
27
|
+
|
|
28
|
+
# Creating the fluid solver
|
|
29
|
+
self.fluid_solver = self._CreateFluidSolver(fluid_solver_settings, parallelism)
|
|
30
|
+
|
|
31
|
+
# Creating the mesh-motion solver
|
|
32
|
+
if not mesh_motion_solver_settings.Has("echo_level"):
|
|
33
|
+
mesh_motion_solver_settings.AddValue("echo_level", self.settings["echo_level"])
|
|
34
|
+
|
|
35
|
+
# Making sure the settings are consistent btw fluid and mesh-motion
|
|
36
|
+
if mesh_motion_solver_settings.Has("model_part_name"):
|
|
37
|
+
if not fluid_model_part_name == mesh_motion_solver_settings["model_part_name"].GetString():
|
|
38
|
+
err_msg = 'Fluid- and Mesh-Solver have to use the same MainModelPart ("model_part_name")!\n'
|
|
39
|
+
err_msg += 'Use "mesh_motion_parts" for specifying mesh-motion on sub-model-parts'
|
|
40
|
+
raise Exception(err_msg)
|
|
41
|
+
else:
|
|
42
|
+
mesh_motion_solver_settings.AddValue("model_part_name", fluid_solver_settings["model_part_name"])
|
|
43
|
+
|
|
44
|
+
domain_size = fluid_solver_settings["domain_size"].GetInt()
|
|
45
|
+
if mesh_motion_solver_settings.Has("domain_size"):
|
|
46
|
+
mesh_motion_domain_size = mesh_motion_solver_settings["domain_size"].GetInt()
|
|
47
|
+
if not domain_size == mesh_motion_domain_size:
|
|
48
|
+
raise Exception('Fluid- and Mesh-Solver have to use the same "domain_size"!')
|
|
49
|
+
else:
|
|
50
|
+
mesh_motion_solver_settings.AddValue("domain_size", fluid_solver_settings["domain_size"])
|
|
51
|
+
|
|
52
|
+
# Derived class decides if the mesh velocities should be computed or not
|
|
53
|
+
self._ManipulateMeshMotionSolverSettingsForMeshVelocityComputation(fluid_solver_settings, mesh_motion_solver_settings)
|
|
54
|
+
|
|
55
|
+
# Constructing the mesh-solver with the entire mesh
|
|
56
|
+
# if no submodelparts are specified then this is used for the computation of the mesh-motion
|
|
57
|
+
# otherwise it only adds the dofs and the variables (to the entire ModelPart!)
|
|
58
|
+
self.mesh_motion_solver_full_mesh = mesh_mothion_solvers_wrapper.CreateSolverByParameters(
|
|
59
|
+
model, mesh_motion_solver_settings, parallelism)
|
|
60
|
+
|
|
61
|
+
# Getting the min_buffer_size from both solvers
|
|
62
|
+
# and assigning it to the fluid_solver, bcs this one handles the model_part
|
|
63
|
+
self.fluid_solver.min_buffer_size = max(
|
|
64
|
+
self.fluid_solver.GetMinimumBufferSize(),
|
|
65
|
+
self.mesh_motion_solver_full_mesh.GetMinimumBufferSize())
|
|
66
|
+
|
|
67
|
+
KM.Logger.PrintInfo("::[AleFluidSolver]::", "Construction finished")
|
|
68
|
+
|
|
69
|
+
@classmethod
|
|
70
|
+
def GetDefaultParameters(cls):
|
|
71
|
+
this_defaults = KM.Parameters("""{
|
|
72
|
+
"solver_type" : "ale_fluid",
|
|
73
|
+
"start_fluid_solution_time" : 0.0,
|
|
74
|
+
"ale_boundary_parts" : [ ],
|
|
75
|
+
"mesh_motion_parts" : [ ],
|
|
76
|
+
"fluid_solver_settings" : { },
|
|
77
|
+
"mesh_motion_solver_settings" : { }
|
|
78
|
+
}""")
|
|
79
|
+
this_defaults.AddMissingParameters(super().GetDefaultParameters())
|
|
80
|
+
return this_defaults
|
|
81
|
+
|
|
82
|
+
def AddVariables(self):
|
|
83
|
+
self.mesh_motion_solver_full_mesh.AddVariables()
|
|
84
|
+
self.fluid_solver.AddVariables()
|
|
85
|
+
|
|
86
|
+
KM.Logger.PrintInfo("::[AleFluidSolver]::", "Variables Added")
|
|
87
|
+
|
|
88
|
+
def AddDofs(self):
|
|
89
|
+
self.mesh_motion_solver_full_mesh.AddDofs()
|
|
90
|
+
self.fluid_solver.AddDofs()
|
|
91
|
+
KM.Logger.PrintInfo("::[AleFluidSolver]::", "DOFs Added")
|
|
92
|
+
|
|
93
|
+
def Initialize(self):
|
|
94
|
+
# Saving the ALE-interface-parts for later
|
|
95
|
+
# this can only be done AFTER reading the ModelPart
|
|
96
|
+
main_model_part_name = self.settings["fluid_solver_settings"]["model_part_name"].GetString()
|
|
97
|
+
|
|
98
|
+
ale_boundary_parts_params = self.settings["ale_boundary_parts"]
|
|
99
|
+
self.ale_boundary_parts = []
|
|
100
|
+
for i_name in range(ale_boundary_parts_params.size()):
|
|
101
|
+
sub_model_part_name = ale_boundary_parts_params[i_name].GetString()
|
|
102
|
+
full_model_part_name = main_model_part_name + "." + sub_model_part_name
|
|
103
|
+
self.ale_boundary_parts.append(self.model[full_model_part_name])
|
|
104
|
+
|
|
105
|
+
mesh_motion_parts_params = self.settings["mesh_motion_parts"]
|
|
106
|
+
self.mesh_motion_solvers = []
|
|
107
|
+
if mesh_motion_parts_params.size() == 0:
|
|
108
|
+
# the entire Fluid-ModelPart is used in the Mesh-Solver
|
|
109
|
+
self.mesh_motion_solvers.append(self.mesh_motion_solver_full_mesh)
|
|
110
|
+
else:
|
|
111
|
+
# SubModelParts of the Fluid-ModelPart are used in the Mesh-Solver
|
|
112
|
+
# each SubModelPart has its own mesh-solver
|
|
113
|
+
# Note that these solvers do NOT need to call AddVariables and AddDofs
|
|
114
|
+
# since this is done already for the MainModelPart
|
|
115
|
+
for i_name in range(mesh_motion_parts_params.size()):
|
|
116
|
+
sub_model_part_name = mesh_motion_parts_params[i_name].GetString()
|
|
117
|
+
if sub_model_part_name == main_model_part_name:
|
|
118
|
+
err_msg = 'The MainModelPart cannot be used as one of the Sub-Mesh-Solvers!\n'
|
|
119
|
+
err_msg += 'Remove "mesh_motion_parts" for specifying mesh-motion on the MainModelPart'
|
|
120
|
+
raise Exception(err_msg)
|
|
121
|
+
full_model_part_name = main_model_part_name + "." + sub_model_part_name
|
|
122
|
+
sub_mesh_solver_settings = self.settings["mesh_motion_solver_settings"].Clone()
|
|
123
|
+
sub_mesh_solver_settings["model_part_name"].SetString(full_model_part_name)
|
|
124
|
+
|
|
125
|
+
self.mesh_motion_solvers.append(mesh_mothion_solvers_wrapper.CreateSolverByParameters(
|
|
126
|
+
self.model, sub_mesh_solver_settings, self.parallelism))
|
|
127
|
+
|
|
128
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
129
|
+
mesh_solver.Initialize()
|
|
130
|
+
self.fluid_solver.Initialize()
|
|
131
|
+
|
|
132
|
+
KM.Logger.PrintInfo("::[AleFluidSolver]::", "Finished initialization")
|
|
133
|
+
|
|
134
|
+
def ImportModelPart(self):
|
|
135
|
+
self.fluid_solver.ImportModelPart() # only ONE mesh_solver imports the ModelPart
|
|
136
|
+
|
|
137
|
+
def PrepareModelPart(self):
|
|
138
|
+
# Doing it ONLY for the fluid solver (since this contains filling the buffer)
|
|
139
|
+
self.fluid_solver.PrepareModelPart()
|
|
140
|
+
|
|
141
|
+
def AdvanceInTime(self, current_time):
|
|
142
|
+
# Doing it ONLY for the fluid solver
|
|
143
|
+
return self.fluid_solver.AdvanceInTime(current_time)
|
|
144
|
+
|
|
145
|
+
def Finalize(self):
|
|
146
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
147
|
+
mesh_solver.Finalize()
|
|
148
|
+
self.fluid_solver.Finalize()
|
|
149
|
+
|
|
150
|
+
def InitializeSolutionStep(self):
|
|
151
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
152
|
+
mesh_solver.InitializeSolutionStep()
|
|
153
|
+
self.fluid_solver.InitializeSolutionStep()
|
|
154
|
+
|
|
155
|
+
def Predict(self):
|
|
156
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
157
|
+
mesh_solver.Predict()
|
|
158
|
+
self.fluid_solver.Predict()
|
|
159
|
+
|
|
160
|
+
def FinalizeSolutionStep(self):
|
|
161
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
162
|
+
mesh_solver.FinalizeSolutionStep()
|
|
163
|
+
self.fluid_solver.FinalizeSolutionStep()
|
|
164
|
+
|
|
165
|
+
def SolveSolutionStep(self):
|
|
166
|
+
is_converged = True
|
|
167
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
168
|
+
is_converged &= mesh_solver.SolveSolutionStep()
|
|
169
|
+
|
|
170
|
+
if self.fluid_solver.GetComputingModelPart().ProcessInfo[KM.TIME] >= self.start_fluid_solution_time:
|
|
171
|
+
self.__ApplyALEBoundaryCondition()
|
|
172
|
+
is_converged &= self.fluid_solver.SolveSolutionStep()
|
|
173
|
+
|
|
174
|
+
return is_converged
|
|
175
|
+
|
|
176
|
+
def Check(self):
|
|
177
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
178
|
+
mesh_solver.Check()
|
|
179
|
+
self.fluid_solver.Check()
|
|
180
|
+
|
|
181
|
+
def Clear(self):
|
|
182
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
183
|
+
mesh_solver.Clear()
|
|
184
|
+
self.fluid_solver.Clear()
|
|
185
|
+
|
|
186
|
+
def GetComputingModelPart(self):
|
|
187
|
+
return self.fluid_solver.GetComputingModelPart() # this is the same as the one used in the MeshSolver
|
|
188
|
+
|
|
189
|
+
def GetFluidSolver(self):
|
|
190
|
+
return self.fluid_solver
|
|
191
|
+
|
|
192
|
+
def GetMeshMotionSolver(self):
|
|
193
|
+
if len(self.mesh_motion_solvers) > 1:
|
|
194
|
+
raise Exception('More than one mesh-motion-solver exists, please use "GetMeshMotionSolvers"')
|
|
195
|
+
return self.mesh_motion_solvers[0]
|
|
196
|
+
|
|
197
|
+
def GetMeshMotionSolvers(self):
|
|
198
|
+
return self.mesh_motion_solvers
|
|
199
|
+
|
|
200
|
+
def MoveMesh(self):
|
|
201
|
+
for mesh_solver in self.mesh_motion_solvers:
|
|
202
|
+
mesh_solver.MoveMesh()
|
|
203
|
+
|
|
204
|
+
def _CreateFluidSolver(self, solver_settings, parallelism):
|
|
205
|
+
'''This function creates the fluid solver.
|
|
206
|
+
It has to be overridden in derived classes
|
|
207
|
+
'''
|
|
208
|
+
raise NotImplementedError("Fluid solver creation must be implemented in the derived class.")
|
|
209
|
+
|
|
210
|
+
def __ApplyALEBoundaryCondition(self):
|
|
211
|
+
'''Copy the MESH_VELOCITY to the VELOCITY (ALE) on the ale-boundary
|
|
212
|
+
'''
|
|
213
|
+
for mp in self.ale_boundary_parts:
|
|
214
|
+
KM.VariableUtils().CopyVectorVar(
|
|
215
|
+
KM.MESH_VELOCITY,
|
|
216
|
+
KM.VELOCITY,
|
|
217
|
+
mp.GetCommunicator().LocalMesh().Nodes)
|
|
218
|
+
mp.GetCommunicator().SynchronizeVariable(KM.VELOCITY)
|
|
219
|
+
|
|
220
|
+
@classmethod
|
|
221
|
+
def _ManipulateFluidSolverSettingsForReactionsComputation(cls, fluid_solver_settings):
|
|
222
|
+
raise NotImplementedError('"_ManipulateFluidSolverSettingsForReactionsComputation" has to be implemented in the derived class!')
|
|
223
|
+
|
|
224
|
+
@classmethod
|
|
225
|
+
def _ManipulateMeshMotionSolverSettingsForMeshVelocityComputation(cls, fluid_solver_settings, mesh_motion_solver_settings):
|
|
226
|
+
raise NotImplementedError('"_ManipulateMeshMotionSolverSettingsForMeshVelocityComputation" has to be implemented in the derived class!')
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# --- Core Imports ---
|
|
2
|
+
import KratosMultiphysics
|
|
3
|
+
|
|
4
|
+
# --- MeshMoving Imports ---
|
|
5
|
+
import KratosMultiphysics.MeshMovingApplication as MeshMovingApplication
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def Factory(parameters, model):
|
|
9
|
+
if not isinstance(parameters, KratosMultiphysics.Parameters):
|
|
10
|
+
raise Exception(
|
|
11
|
+
'expected input shall be a Parameters object, encapsulating a json string')
|
|
12
|
+
return ImposeMeshMotionProcess(model, parameters["Parameters"])
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ImposeMeshMotionProcess(KratosMultiphysics.Process):
|
|
16
|
+
""" @brief Impose a rotation followed by translation on a ModelPart.
|
|
17
|
+
|
|
18
|
+
@details The transformation is equivalent to:
|
|
19
|
+
1) Translation to the reference frame (offset the origin)
|
|
20
|
+
2) Specified rotation
|
|
21
|
+
3) Reverse translation from the reference frame (undo origin offset)
|
|
22
|
+
4) Specified translation
|
|
23
|
+
Note: angles in radians
|
|
24
|
+
|
|
25
|
+
The rotation can be defined by either "euler_angles"
|
|
26
|
+
or a "rotation_axis" and "rotation_angle" pair. The following parameters can be
|
|
27
|
+
defined parametrically (see GenericFunctionUtility):
|
|
28
|
+
"euler_angles", "rotation_axis", "reference_point", "rotation_angle", "translation_vector"
|
|
29
|
+
|
|
30
|
+
Default parameters:
|
|
31
|
+
@code
|
|
32
|
+
{
|
|
33
|
+
"model_part_name" : "",
|
|
34
|
+
"interval" : [0.0, "End"],
|
|
35
|
+
"rotation_definition" : "rotation_axis",
|
|
36
|
+
"euler_angles" : [0.0, 0.0, 0.0],
|
|
37
|
+
"rotation_axis" : [0.0, 0.0, 1.0],
|
|
38
|
+
"reference_point" : [0.0, 0.0, 0.0]
|
|
39
|
+
"rotation_angle" : 0,
|
|
40
|
+
"translation_vector" : [0.0, 0.0, 0.0],
|
|
41
|
+
}
|
|
42
|
+
@endcode
|
|
43
|
+
|
|
44
|
+
@note the euler angles follow the convention specified by @ref{Quaternion} (Z, -X', Z")
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(self,
|
|
48
|
+
model: KratosMultiphysics.Model,
|
|
49
|
+
parameters: KratosMultiphysics.Parameters):
|
|
50
|
+
"""Impose a rotation followed by translation on a ModelPart."""
|
|
51
|
+
KratosMultiphysics.Process.__init__(self)
|
|
52
|
+
|
|
53
|
+
# 'rotation_angle' can either be a float or "End", but the validator can't handle both
|
|
54
|
+
# => convert 'rotation_angle' to the input type
|
|
55
|
+
default_parameters = self.GetDefaultParameters()
|
|
56
|
+
if parameters.Has("rotation_angle") and parameters["rotation_angle"].IsString():
|
|
57
|
+
default_parameters.RemoveValue("rotation_angle")
|
|
58
|
+
default_parameters.AddValue("rotation_angle", parameters["rotation_angle"])
|
|
59
|
+
|
|
60
|
+
parameters.ValidateAndAssignDefaults(default_parameters)
|
|
61
|
+
self.model_part = model[parameters["model_part_name"].GetString()]
|
|
62
|
+
|
|
63
|
+
# Parse interval
|
|
64
|
+
self.interval_utility = KratosMultiphysics.IntervalUtility(parameters)
|
|
65
|
+
|
|
66
|
+
# Determine whether a constant transform will suffice or a parametric one is needed
|
|
67
|
+
requires_parametric_transform = False
|
|
68
|
+
|
|
69
|
+
euler_angle_parameters = parameters["euler_angles"]
|
|
70
|
+
rotation_axis_parameters = parameters["rotation_axis"]
|
|
71
|
+
rotation_angle_parameters = parameters["rotation_angle"]
|
|
72
|
+
reference_point_parameters = parameters["reference_point"]
|
|
73
|
+
translation_vector_parameters = parameters["translation_vector"]
|
|
74
|
+
|
|
75
|
+
if rotation_angle_parameters.IsString():
|
|
76
|
+
requires_parametric_transform = True
|
|
77
|
+
else:
|
|
78
|
+
for i in range(3):
|
|
79
|
+
if euler_angle_parameters[i].IsString() or rotation_axis_parameters[i].IsString() or reference_point_parameters[i].IsString() or translation_vector_parameters[i].IsString():
|
|
80
|
+
requires_parametric_transform = True
|
|
81
|
+
break
|
|
82
|
+
|
|
83
|
+
rotation_definition = parameters["rotation_definition"].GetString()
|
|
84
|
+
|
|
85
|
+
if requires_parametric_transform:
|
|
86
|
+
if rotation_definition == "rotation_axis":
|
|
87
|
+
self.transform = MeshMovingApplication.ParametricAffineTransform(
|
|
88
|
+
rotation_axis_parameters,
|
|
89
|
+
rotation_angle_parameters,
|
|
90
|
+
reference_point_parameters,
|
|
91
|
+
translation_vector_parameters)
|
|
92
|
+
elif rotation_definition == "euler_angles":
|
|
93
|
+
self.transform = MeshMovingApplication.ParametricAffineTransform(
|
|
94
|
+
euler_angle_parameters,
|
|
95
|
+
reference_point_parameters,
|
|
96
|
+
translation_vector_parameters)
|
|
97
|
+
else:
|
|
98
|
+
raise ValueError("Invalid rotation definition '{}'".format(rotation_definition))
|
|
99
|
+
|
|
100
|
+
else:
|
|
101
|
+
reference_point = reference_point_parameters.GetVector()
|
|
102
|
+
translation_vector = translation_vector_parameters.GetVector()
|
|
103
|
+
if rotation_definition == "rotation_axis":
|
|
104
|
+
rotation_axis = rotation_axis_parameters.GetVector()
|
|
105
|
+
rotation_angle = rotation_angle_parameters.GetDouble()
|
|
106
|
+
self.transform = MeshMovingApplication.AffineTransform(
|
|
107
|
+
rotation_axis,
|
|
108
|
+
rotation_angle,
|
|
109
|
+
reference_point,
|
|
110
|
+
translation_vector)
|
|
111
|
+
elif rotation_definition == "euler_angles":
|
|
112
|
+
euler_angles = euler_angle_parameters.GetVector()
|
|
113
|
+
self.transform = MeshMovingApplication.AffineTransform(
|
|
114
|
+
euler_angles,
|
|
115
|
+
reference_point,
|
|
116
|
+
translation_vector)
|
|
117
|
+
else:
|
|
118
|
+
raise ValueError("Invalid rotation definition '{}'".format(rotation_definition))
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def ExecuteInitializeSolutionStep(self):
|
|
122
|
+
time = self.model_part.ProcessInfo[KratosMultiphysics.TIME]
|
|
123
|
+
|
|
124
|
+
if self.interval_utility.IsInInterval(time):
|
|
125
|
+
MeshMovingApplication.MoveModelPart(self.model_part, self.transform)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@staticmethod
|
|
129
|
+
def GetDefaultParameters():
|
|
130
|
+
return KratosMultiphysics.Parameters("""{
|
|
131
|
+
"model_part_name" : "",
|
|
132
|
+
"interval" : [0.0, "End"],
|
|
133
|
+
"rotation_definition" : "rotation_axis",
|
|
134
|
+
"euler_angles" : [0.0, 0.0, 0.0],
|
|
135
|
+
"rotation_axis" : [0.0, 0.0, 1.0],
|
|
136
|
+
"reference_point" : [0.0, 0.0, 0.0],
|
|
137
|
+
"rotation_angle" : 0,
|
|
138
|
+
"translation_vector" : [0.0, 0.0, 0.0]
|
|
139
|
+
}""")
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Importing Kratos
|
|
2
|
+
import KratosMultiphysics
|
|
3
|
+
import KratosMultiphysics.MeshMovingApplication.python_solvers_wrapper_mesh_motion as mesh_mothion_solvers
|
|
4
|
+
|
|
5
|
+
# Importing the base class
|
|
6
|
+
from KratosMultiphysics.analysis_stage import AnalysisStage
|
|
7
|
+
|
|
8
|
+
class MeshMovingAnalysis(AnalysisStage):
|
|
9
|
+
"""
|
|
10
|
+
This class is the main-script of the MeshMovingApplication put in a class
|
|
11
|
+
It can be imported and used as "black-box"
|
|
12
|
+
"""
|
|
13
|
+
def __init__(self, model, project_parameters):
|
|
14
|
+
# Making sure that older cases fail with a meaningful error message
|
|
15
|
+
solver_settings = project_parameters["solver_settings"]
|
|
16
|
+
if not solver_settings.Has("time_stepping"):
|
|
17
|
+
raise Exception("Using the old way to pass the time_step, this was removed!")
|
|
18
|
+
|
|
19
|
+
if not solver_settings.Has("domain_size"):
|
|
20
|
+
raise Exception("Using the old way to pass the domain_size, this was removed!")
|
|
21
|
+
|
|
22
|
+
if not solver_settings.Has("model_part_name"):
|
|
23
|
+
raise Exception("Using the old way to pass the model_part_name, this was removed!")
|
|
24
|
+
|
|
25
|
+
if not solver_settings.Has("echo_level"): # this is done to remain backwards-compatible
|
|
26
|
+
raise Exception('"solver_settings" does not have "echo_level", please add it!')
|
|
27
|
+
|
|
28
|
+
super().__init__(model, project_parameters)
|
|
29
|
+
|
|
30
|
+
#### Internal functions ####
|
|
31
|
+
def _CreateSolver(self):
|
|
32
|
+
""" Create the Solver (and create and import the ModelPart if it is not alread in the model) """
|
|
33
|
+
return mesh_mothion_solvers.CreateSolver(self.model, self.project_parameters)
|
|
34
|
+
|
|
35
|
+
def _CreateProcesses(self, parameter_name, initialization_order):
|
|
36
|
+
"""Create a list of Processes
|
|
37
|
+
This method is TEMPORARY to not break existing code
|
|
38
|
+
It was removed, now throwing errors to avoid silent failures
|
|
39
|
+
"""
|
|
40
|
+
list_of_processes = super()._CreateProcesses(parameter_name, initialization_order)
|
|
41
|
+
|
|
42
|
+
if parameter_name == "processes":
|
|
43
|
+
processes_block_names = ["boundary_conditions_process_list", "list_other_processes", "json_output_process",
|
|
44
|
+
"json_check_process", "check_analytic_results_process"]
|
|
45
|
+
if len(list_of_processes) == 0: # Processes are given in the old format (or no processes are specified)
|
|
46
|
+
for process_name in processes_block_names:
|
|
47
|
+
if self.project_parameters.Has(process_name):
|
|
48
|
+
raise Exception("Using the old way to create the processes, this was removed!")
|
|
49
|
+
else: # Processes are given in the new format
|
|
50
|
+
for process_name in processes_block_names:
|
|
51
|
+
if self.project_parameters.Has(process_name):
|
|
52
|
+
raise Exception("Mixing of process initialization is not alowed!")
|
|
53
|
+
elif parameter_name == "output_processes":
|
|
54
|
+
if self.project_parameters.Has("output_configuration"):
|
|
55
|
+
raise Exception("Using the old way to create the gid-output, this was removed!")
|
|
56
|
+
else:
|
|
57
|
+
raise NameError("wrong parameter name")
|
|
58
|
+
|
|
59
|
+
return list_of_processes
|
|
60
|
+
|
|
61
|
+
def _GetSimulationName(self):
|
|
62
|
+
return "::[Mesh Moving Simulation]:: "
|
|
63
|
+
|
|
64
|
+
if __name__ == "__main__":
|
|
65
|
+
from sys import argv
|
|
66
|
+
|
|
67
|
+
if len(argv) > 2:
|
|
68
|
+
err_msg = 'Too many input arguments!\n'
|
|
69
|
+
err_msg += 'Use this script in the following way:\n'
|
|
70
|
+
err_msg += '- With default ProjectParameters (read from "ProjectParameters.json"):\n'
|
|
71
|
+
err_msg += ' "python3 mesh_moving_analysis.py"\n'
|
|
72
|
+
err_msg += '- With custom ProjectParameters:\n'
|
|
73
|
+
err_msg += ' "python3 mesh_moving_analysis.py CustomProjectParameters.json"\n'
|
|
74
|
+
raise Exception(err_msg)
|
|
75
|
+
|
|
76
|
+
if len(argv) == 2: # ProjectParameters is being passed from outside
|
|
77
|
+
project_parameters_file_name = argv[1]
|
|
78
|
+
else: # using default name
|
|
79
|
+
project_parameters_file_name = "ProjectParameters.json"
|
|
80
|
+
|
|
81
|
+
with open(project_parameters_file_name,'r') as parameter_file:
|
|
82
|
+
parameters = KratosMultiphysics.Parameters(parameter_file.read())
|
|
83
|
+
|
|
84
|
+
model = KratosMultiphysics.Model()
|
|
85
|
+
simulation = MeshMovingAnalysis(model, parameters)
|
|
86
|
+
simulation.Run()
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics
|
|
3
|
+
import KratosMultiphysics.MeshMovingApplication as KMM
|
|
4
|
+
|
|
5
|
+
# Other imports
|
|
6
|
+
from KratosMultiphysics.python_solver import PythonSolver
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MeshSolverBase(PythonSolver):
|
|
10
|
+
"""The base class for mesh motion solvers.
|
|
11
|
+
|
|
12
|
+
This class defines the user interface to mesh motion solvers.
|
|
13
|
+
|
|
14
|
+
Derived classes must override the function _CreateSolutionStrategy()
|
|
15
|
+
to customize the mesh motion algorithm. The mesh motion solving strategy and linear
|
|
16
|
+
solver should always be retrieved using the getter functions. Only the
|
|
17
|
+
member variables listed below should be accessed directly.
|
|
18
|
+
|
|
19
|
+
Public member variables:
|
|
20
|
+
settings -- Kratos parameters for general mesh motion settings.
|
|
21
|
+
mesh_model_part -- the mesh motion model part.
|
|
22
|
+
"""
|
|
23
|
+
def __init__(self, model, custom_settings):
|
|
24
|
+
self._validate_settings_in_baseclass=True # To be removed eventually
|
|
25
|
+
super().__init__(model, custom_settings)
|
|
26
|
+
|
|
27
|
+
# Either retrieve the model part from the model or create a new one
|
|
28
|
+
model_part_name = self.settings["model_part_name"].GetString()
|
|
29
|
+
|
|
30
|
+
if model_part_name == "":
|
|
31
|
+
raise Exception('Please provide the model part name as the "model_part_name" (string) parameter!')
|
|
32
|
+
|
|
33
|
+
if self.model.HasModelPart(model_part_name):
|
|
34
|
+
self.mesh_model_part = self.model.GetModelPart(model_part_name)
|
|
35
|
+
else:
|
|
36
|
+
self.mesh_model_part = model.CreateModelPart(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
|
+
|
|
42
|
+
self.mesh_model_part.ProcessInfo.SetValue(KratosMultiphysics.DOMAIN_SIZE, domain_size)
|
|
43
|
+
|
|
44
|
+
# If required, create the time discretization helper
|
|
45
|
+
if self.settings["calculate_mesh_velocity"].GetBool():
|
|
46
|
+
# BDF2 was the default in the MeshSolver-Strategies
|
|
47
|
+
default_settings = KratosMultiphysics.Parameters("""{
|
|
48
|
+
"time_scheme" : "bdf2",
|
|
49
|
+
"alpha_m": 0.0,
|
|
50
|
+
"alpha_f": 0.0
|
|
51
|
+
}""")
|
|
52
|
+
|
|
53
|
+
self.settings["mesh_velocity_calculation"].ValidateAndAssignDefaults(default_settings)
|
|
54
|
+
self.__CreateTimeIntegratorHelper()
|
|
55
|
+
|
|
56
|
+
self.reinitialize_model_part_each_step = self.settings["reinitialize_model_part_each_step"].GetBool()
|
|
57
|
+
|
|
58
|
+
KratosMultiphysics.Logger.PrintInfo("::[MeshSolverBase]:: Construction finished")
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def GetDefaultParameters(cls):
|
|
62
|
+
this_defaults = KratosMultiphysics.Parameters("""{
|
|
63
|
+
"solver_type" : "mesh_solver_base",
|
|
64
|
+
"buffer_size" : 1,
|
|
65
|
+
"domain_size" : -1,
|
|
66
|
+
"model_part_name" : "",
|
|
67
|
+
"time_stepping" : { },
|
|
68
|
+
"model_import_settings" : {
|
|
69
|
+
"input_type" : "mdpa",
|
|
70
|
+
"input_filename" : "unknown_name"
|
|
71
|
+
},
|
|
72
|
+
"linear_solver_settings" : {
|
|
73
|
+
"solver_type" : "amgcl",
|
|
74
|
+
"smoother_type":"ilu0",
|
|
75
|
+
"krylov_type": "gmres",
|
|
76
|
+
"coarsening_type": "aggregation",
|
|
77
|
+
"max_iteration": 200,
|
|
78
|
+
"provide_coordinates": false,
|
|
79
|
+
"gmres_krylov_space_dimension": 100,
|
|
80
|
+
"verbosity" : 0,
|
|
81
|
+
"tolerance": 1e-7,
|
|
82
|
+
"scaling": false,
|
|
83
|
+
"block_size": 1,
|
|
84
|
+
"use_block_matrices_if_possible" : true,
|
|
85
|
+
"coarse_enough" : 5000
|
|
86
|
+
},
|
|
87
|
+
"reform_dofs_each_step" : false,
|
|
88
|
+
"compute_reactions" : false,
|
|
89
|
+
"poisson_ratio" : 0.3,
|
|
90
|
+
"calculate_mesh_velocity" : true,
|
|
91
|
+
"mesh_velocity_calculation" : { },
|
|
92
|
+
"superimpose_mesh_disp_with": [],
|
|
93
|
+
"superimpose_mesh_velocity_with": [],
|
|
94
|
+
"reinitialize_model_part_each_step": false
|
|
95
|
+
}""")
|
|
96
|
+
this_defaults.AddMissingParameters(super().GetDefaultParameters())
|
|
97
|
+
return this_defaults
|
|
98
|
+
|
|
99
|
+
#### Public user interface functions ####
|
|
100
|
+
|
|
101
|
+
def AddVariables(self):
|
|
102
|
+
# Add variables required for the mesh moving calculation
|
|
103
|
+
self.mesh_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.MESH_DISPLACEMENT)
|
|
104
|
+
self.mesh_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.MESH_REACTION)
|
|
105
|
+
|
|
106
|
+
# Adding Variables used for computation of Mesh-Velocity
|
|
107
|
+
if self.settings["calculate_mesh_velocity"].GetBool():
|
|
108
|
+
self.mesh_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.MESH_VELOCITY)
|
|
109
|
+
time_scheme = self.settings["mesh_velocity_calculation"]["time_scheme"].GetString()
|
|
110
|
+
if not time_scheme.startswith("bdf"): # bdfx does not need MESH_ACCELERATION
|
|
111
|
+
self.mesh_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.MESH_ACCELERATION)
|
|
112
|
+
|
|
113
|
+
KratosMultiphysics.Logger.PrintInfo("::[MeshSolverBase]:: Variables ADDED.")
|
|
114
|
+
|
|
115
|
+
def AddDofs(self):
|
|
116
|
+
KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.MESH_DISPLACEMENT_X, KratosMultiphysics.MESH_REACTION_X, self.mesh_model_part)
|
|
117
|
+
KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.MESH_DISPLACEMENT_Y, KratosMultiphysics.MESH_REACTION_Y, self.mesh_model_part)
|
|
118
|
+
KratosMultiphysics.VariableUtils().AddDof(KratosMultiphysics.MESH_DISPLACEMENT_Z, KratosMultiphysics.MESH_REACTION_Z, self.mesh_model_part)
|
|
119
|
+
KratosMultiphysics.Logger.PrintInfo("::[MeshSolverBase]:: DOFs ADDED.")
|
|
120
|
+
|
|
121
|
+
def AdvanceInTime(self, current_time):
|
|
122
|
+
dt = self.settings["time_stepping"]["time_step"].GetDouble()
|
|
123
|
+
new_time = current_time + dt
|
|
124
|
+
self.mesh_model_part.ProcessInfo[KratosMultiphysics.STEP] += 1
|
|
125
|
+
self.mesh_model_part.CloneTimeStep(new_time)
|
|
126
|
+
|
|
127
|
+
return new_time
|
|
128
|
+
|
|
129
|
+
def Initialize(self):
|
|
130
|
+
self._GetSolutionStrategy().Initialize()
|
|
131
|
+
#self.neighbour_search.Execute()
|
|
132
|
+
KratosMultiphysics.Logger.PrintInfo("::[MeshSolverBase]:: Finished initialization.")
|
|
133
|
+
|
|
134
|
+
def InitializeSolutionStep(self):
|
|
135
|
+
self._GetSolutionStrategy().InitializeSolutionStep()
|
|
136
|
+
|
|
137
|
+
def FinalizeSolutionStep(self):
|
|
138
|
+
self._GetSolutionStrategy().FinalizeSolutionStep()
|
|
139
|
+
|
|
140
|
+
def Predict(self):
|
|
141
|
+
self._GetSolutionStrategy().Predict()
|
|
142
|
+
|
|
143
|
+
def SolveSolutionStep(self):
|
|
144
|
+
# Calling Solve bcs this is what is currently implemented in the MeshSolverStrategies
|
|
145
|
+
# explicit bool conversion is only needed bcs "Solve" returns a double
|
|
146
|
+
is_converged = bool(self._GetSolutionStrategy().Solve())
|
|
147
|
+
self.MoveMesh()
|
|
148
|
+
|
|
149
|
+
# Superimpose the user-defined mesh displacement
|
|
150
|
+
for variable in KratosMultiphysics.kratos_utilities.GenerateVariableListFromInput(self.settings["superimpose_mesh_disp_with"]):
|
|
151
|
+
KMM.SuperImposeMeshDisplacement(variable)
|
|
152
|
+
|
|
153
|
+
# Superimpose the user-defined mesh velocity
|
|
154
|
+
for variable in KratosMultiphysics.kratos_utilities.GenerateVariableListFromInput(self.settings["superimpose_mesh_velocity_with"]):
|
|
155
|
+
KMM.SuperImposeMeshVelocity(variable)
|
|
156
|
+
|
|
157
|
+
return is_converged
|
|
158
|
+
|
|
159
|
+
def SetEchoLevel(self, level):
|
|
160
|
+
self._GetSolutionStrategy().SetEchoLevel(level)
|
|
161
|
+
|
|
162
|
+
def GetEchoLevel(self):
|
|
163
|
+
self._GetSolutionStrategy().GetEchoLevel()
|
|
164
|
+
|
|
165
|
+
def Clear(self):
|
|
166
|
+
self._GetSolutionStrategy().Clear()
|
|
167
|
+
|
|
168
|
+
def GetMinimumBufferSize(self):
|
|
169
|
+
buffer_size = max(self.settings["buffer_size"].GetInt(), self.mesh_model_part.GetBufferSize())
|
|
170
|
+
if self.settings["calculate_mesh_velocity"].GetBool():
|
|
171
|
+
buffer_size = max(buffer_size, KratosMultiphysics.TimeDiscretization.GetMinimumBufferSize(self.time_int_helper))
|
|
172
|
+
return buffer_size
|
|
173
|
+
|
|
174
|
+
def MoveMesh(self):
|
|
175
|
+
# move local and ghost nodes
|
|
176
|
+
self.mesh_model_part.GetCommunicator().SynchronizeVariable(KratosMultiphysics.MESH_DISPLACEMENT)
|
|
177
|
+
KMM.MoveMesh(self.mesh_model_part.Nodes)
|
|
178
|
+
|
|
179
|
+
# If required, calculate the MESH_VELOCITY.
|
|
180
|
+
if self.settings["calculate_mesh_velocity"].GetBool():
|
|
181
|
+
KMM.CalculateMeshVelocities(self.mesh_model_part, self.time_int_helper)
|
|
182
|
+
|
|
183
|
+
def ImportModelPart(self):
|
|
184
|
+
# we can use the default implementation in the base class
|
|
185
|
+
self._ImportModelPart(self.mesh_model_part,self.settings["model_import_settings"])
|
|
186
|
+
|
|
187
|
+
def PrepareModelPart(self):
|
|
188
|
+
if not self.mesh_model_part.ProcessInfo[KratosMultiphysics.IS_RESTARTED]:
|
|
189
|
+
self._set_and_fill_buffer()
|
|
190
|
+
|
|
191
|
+
def GetComputingModelPart(self):
|
|
192
|
+
return self.mesh_model_part
|
|
193
|
+
|
|
194
|
+
#### Specific internal functions ####
|
|
195
|
+
|
|
196
|
+
def _GetLinearSolver(self):
|
|
197
|
+
if not hasattr(self, '_linear_solver'):
|
|
198
|
+
self._linear_solver = self._CreateLinearSolver()
|
|
199
|
+
return self._linear_solver
|
|
200
|
+
|
|
201
|
+
def _GetSolutionStrategy(self):
|
|
202
|
+
if not hasattr(self, '_mesh_motion_solving_strategy'):
|
|
203
|
+
self._mesh_motion_solving_strategy = self._CreateSolutionStrategy()
|
|
204
|
+
return self._mesh_motion_solving_strategy
|
|
205
|
+
|
|
206
|
+
#### Private functions ####
|
|
207
|
+
|
|
208
|
+
def _CreateLinearSolver(self):
|
|
209
|
+
from KratosMultiphysics.python_linear_solver_factory import ConstructSolver
|
|
210
|
+
return ConstructSolver(self.settings["linear_solver_settings"])
|
|
211
|
+
|
|
212
|
+
def _CreateSolutionStrategy(self):
|
|
213
|
+
"""Create the mesh motion solving strategy.
|
|
214
|
+
|
|
215
|
+
The mesh motion solving strategy must provide the functions defined in SolutionStrategy.
|
|
216
|
+
"""
|
|
217
|
+
raise Exception("Mesh motion solving strategy must be created by the derived class.")
|
|
218
|
+
|
|
219
|
+
def _set_and_fill_buffer(self):
|
|
220
|
+
"""Prepare nodal solution step data containers and time step information. """
|
|
221
|
+
# Set the buffer size for the nodal solution steps data. Existing nodal
|
|
222
|
+
# solution step data may be lost.
|
|
223
|
+
buffer_size = self.GetMinimumBufferSize()
|
|
224
|
+
self.mesh_model_part.SetBufferSize(buffer_size)
|
|
225
|
+
# Cycle the buffer. This sets all historical nodal solution step data to
|
|
226
|
+
# the current value and initializes the time stepping in the process info.
|
|
227
|
+
delta_time = self.mesh_model_part.ProcessInfo[KratosMultiphysics.DELTA_TIME]
|
|
228
|
+
time = self.mesh_model_part.ProcessInfo[KratosMultiphysics.TIME]
|
|
229
|
+
step =-buffer_size
|
|
230
|
+
time = time - delta_time * buffer_size
|
|
231
|
+
self.mesh_model_part.ProcessInfo.SetValue(KratosMultiphysics.TIME, time)
|
|
232
|
+
for i in range(0, buffer_size):
|
|
233
|
+
step = step + 1
|
|
234
|
+
time = time + delta_time
|
|
235
|
+
self.mesh_model_part.ProcessInfo.SetValue(KratosMultiphysics.STEP, step)
|
|
236
|
+
self.mesh_model_part.CloneTimeStep(time)
|
|
237
|
+
self.mesh_model_part.ProcessInfo[KratosMultiphysics.IS_RESTARTED] = False
|
|
238
|
+
|
|
239
|
+
def __CreateTimeIntegratorHelper(self):
|
|
240
|
+
'''Initializing the helper-class for the time-integration
|
|
241
|
+
'''
|
|
242
|
+
mesh_vel_calc_setting = self.settings["mesh_velocity_calculation"]
|
|
243
|
+
time_scheme = mesh_vel_calc_setting["time_scheme"].GetString()
|
|
244
|
+
|
|
245
|
+
if time_scheme == "bdf1":
|
|
246
|
+
self.time_int_helper = KratosMultiphysics.TimeDiscretization.BDF1()
|
|
247
|
+
elif time_scheme == "bdf2":
|
|
248
|
+
self.time_int_helper = KratosMultiphysics.TimeDiscretization.BDF2()
|
|
249
|
+
elif time_scheme == "newmark":
|
|
250
|
+
self.time_int_helper = KratosMultiphysics.TimeDiscretization.Newmark()
|
|
251
|
+
elif time_scheme == "bossak":
|
|
252
|
+
if mesh_vel_calc_setting.Has("alpha_m"):
|
|
253
|
+
alpha_m = mesh_vel_calc_setting["alpha_m"].GetDouble()
|
|
254
|
+
self.time_int_helper = KratosMultiphysics.TimeDiscretization.Bossak(alpha_m)
|
|
255
|
+
else:
|
|
256
|
+
self.time_int_helper = KratosMultiphysics.TimeDiscretization.Bossak()
|
|
257
|
+
elif time_scheme == "generalized_alpha":
|
|
258
|
+
alpha_m = mesh_vel_calc_setting["alpha_m"].GetDouble()
|
|
259
|
+
alpha_f = mesh_vel_calc_setting["alpha_f"].GetDouble()
|
|
260
|
+
self.time_int_helper = KratosMultiphysics.TimeDiscretization.GeneralizedAlpha(alpha_m, alpha_f)
|
|
261
|
+
else:
|
|
262
|
+
err_msg = 'The requested time scheme "{}" is not available for the calculation of the mesh velocity!\n'.format(time_scheme)
|
|
263
|
+
err_msg += 'Available options are: "bdf1", "bdf2", "newmark", "bossak", "generalized_alpha"'
|
|
264
|
+
raise Exception(err_msg)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics as KM
|
|
3
|
+
|
|
4
|
+
# Import applications
|
|
5
|
+
import KratosMultiphysics.MeshMovingApplication as KratosMeshMoving
|
|
6
|
+
|
|
7
|
+
# Import baseclass
|
|
8
|
+
from KratosMultiphysics.MeshMovingApplication.mesh_solver_base import MeshSolverBase
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def CreateSolver(model, custom_settings):
|
|
12
|
+
return MeshSolverLaplacian(model, custom_settings)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MeshSolverLaplacian(MeshSolverBase):
|
|
16
|
+
def __init__(self, model, custom_settings):
|
|
17
|
+
super().__init__(model, custom_settings)
|
|
18
|
+
if custom_settings["buffer_size"].GetInt() < 2:
|
|
19
|
+
raise Exception("A buffer_size of at least 2 is required!")
|
|
20
|
+
KM.Logger.PrintInfo("::[MeshSolverLaplacian]:: Construction finished")
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def GetDefaultParameters(cls):
|
|
24
|
+
this_defaults = KM.Parameters("""{
|
|
25
|
+
"buffer_size" : 2
|
|
26
|
+
}""")
|
|
27
|
+
this_defaults.AddMissingParameters(super().GetDefaultParameters())
|
|
28
|
+
return this_defaults
|
|
29
|
+
|
|
30
|
+
def _CreateSolutionStrategy(self):
|
|
31
|
+
linear_solver = self._GetLinearSolver()
|
|
32
|
+
reform_dofs_each_step = self.settings["reform_dofs_each_step"].GetBool()
|
|
33
|
+
compute_reactions = self.settings["compute_reactions"].GetBool()
|
|
34
|
+
solving_strategy = KratosMeshMoving.LaplacianMeshMovingStrategy(self.mesh_model_part,
|
|
35
|
+
linear_solver,
|
|
36
|
+
0,
|
|
37
|
+
reform_dofs_each_step,
|
|
38
|
+
compute_reactions,
|
|
39
|
+
False,
|
|
40
|
+
self.echo_level,
|
|
41
|
+
self.reinitialize_model_part_each_step)
|
|
42
|
+
return solving_strategy
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics
|
|
3
|
+
|
|
4
|
+
# Import applications
|
|
5
|
+
import KratosMultiphysics.MeshMovingApplication as KratosMeshMoving
|
|
6
|
+
|
|
7
|
+
# Import baseclass
|
|
8
|
+
from KratosMultiphysics.MeshMovingApplication.mesh_solver_base import MeshSolverBase
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def CreateSolver(model, custom_settings):
|
|
12
|
+
return MeshSolverStructuralSimilarity(model, custom_settings)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MeshSolverStructuralSimilarity(MeshSolverBase):
|
|
16
|
+
def __init__(self, model, custom_settings):
|
|
17
|
+
super().__init__(model, custom_settings)
|
|
18
|
+
KratosMultiphysics.Logger.PrintInfo("::[MeshSolverStructuralSimilarity]:: Construction finished")
|
|
19
|
+
|
|
20
|
+
def _CreateSolutionStrategy(self):
|
|
21
|
+
linear_solver = self._GetLinearSolver()
|
|
22
|
+
reform_dofs_each_step = self.settings["reform_dofs_each_step"].GetBool()
|
|
23
|
+
compute_reactions = self.settings["compute_reactions"].GetBool()
|
|
24
|
+
poisson_ratio = self.settings["poisson_ratio"].GetDouble()
|
|
25
|
+
solving_strategy = KratosMeshMoving.StructuralMeshMovingStrategy(self.mesh_model_part,
|
|
26
|
+
linear_solver,
|
|
27
|
+
0,
|
|
28
|
+
reform_dofs_each_step,
|
|
29
|
+
compute_reactions,
|
|
30
|
+
False,
|
|
31
|
+
self.echo_level,
|
|
32
|
+
poisson_ratio,
|
|
33
|
+
self.reinitialize_model_part_each_step)
|
|
34
|
+
return solving_strategy
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import KratosMultiphysics
|
|
2
|
+
from importlib import import_module
|
|
3
|
+
|
|
4
|
+
def CreateSolverByParameters(model, solver_settings, parallelism):
|
|
5
|
+
|
|
6
|
+
solver_type = solver_settings["solver_type"].GetString()
|
|
7
|
+
if solver_type.startswith("mesh_solver_"):
|
|
8
|
+
solver_type = solver_type[12:] # remove preceding "mesh_solver_"
|
|
9
|
+
depr_msg = 'Using the old names to construct the MeshSolver\n'
|
|
10
|
+
depr_msg += 'Please remove the preceding "mesh_solver_" from "solver_type"'
|
|
11
|
+
KratosMultiphysics.Logger.PrintWarning("DEPRECATION", depr_msg)
|
|
12
|
+
|
|
13
|
+
# Solvers for OpenMP parallelism
|
|
14
|
+
if (parallelism == "OpenMP"):
|
|
15
|
+
|
|
16
|
+
if (solver_type == "laplacian"):
|
|
17
|
+
solver_module_name = "mesh_solver_laplacian"
|
|
18
|
+
|
|
19
|
+
elif (solver_type == "structural_similarity"):
|
|
20
|
+
solver_module_name = "mesh_solver_structural_similarity"
|
|
21
|
+
|
|
22
|
+
else:
|
|
23
|
+
err_msg = 'The requested solver type "' + solver_type + '" is not in the python solvers wrapper\n'
|
|
24
|
+
err_msg += 'Available options are: "laplacian", "structural_similarity"'
|
|
25
|
+
raise Exception(err_msg)
|
|
26
|
+
|
|
27
|
+
# Solvers for MPI parallelism
|
|
28
|
+
elif (parallelism == "MPI"):
|
|
29
|
+
|
|
30
|
+
if (solver_type == "laplacian"):
|
|
31
|
+
solver_module_name = "trilinos_mesh_solver_laplacian"
|
|
32
|
+
|
|
33
|
+
elif (solver_type == "structural_similarity"):
|
|
34
|
+
solver_module_name = "trilinos_mesh_solver_structural_similarity"
|
|
35
|
+
|
|
36
|
+
else:
|
|
37
|
+
err_msg = 'The requested solver type "' + solver_type + '" is not in the python solvers wrapper\n'
|
|
38
|
+
err_msg += 'Available options are: "laplacian", "structural_similarity"'
|
|
39
|
+
raise Exception(err_msg)
|
|
40
|
+
|
|
41
|
+
else:
|
|
42
|
+
err_msg = 'The requested parallel type "' + parallelism + '" is not available!\n'
|
|
43
|
+
err_msg += 'Available options are: "OpenMP", "MPI"'
|
|
44
|
+
raise Exception(err_msg)
|
|
45
|
+
|
|
46
|
+
module_full = 'KratosMultiphysics.MeshMovingApplication.' + solver_module_name
|
|
47
|
+
solver = import_module(module_full).CreateSolver(model, solver_settings)
|
|
48
|
+
|
|
49
|
+
return solver
|
|
50
|
+
|
|
51
|
+
def CreateSolver(model, custom_settings):
|
|
52
|
+
|
|
53
|
+
if (type(model) != KratosMultiphysics.Model):
|
|
54
|
+
raise Exception("input is expected to be provided as a Kratos Model object")#
|
|
55
|
+
|
|
56
|
+
if (type(custom_settings) != KratosMultiphysics.Parameters):
|
|
57
|
+
raise Exception("input is expected to be provided as a Kratos Parameters object")
|
|
58
|
+
|
|
59
|
+
solver_settings = custom_settings["solver_settings"]
|
|
60
|
+
parallelism = custom_settings["problem_data"]["parallel_type"].GetString()
|
|
61
|
+
|
|
62
|
+
return CreateSolverByParameters(model, solver_settings, parallelism)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics
|
|
3
|
+
|
|
4
|
+
# Import applications
|
|
5
|
+
import KratosMultiphysics.MeshMovingApplication as KratosMeshMoving
|
|
6
|
+
import KratosMultiphysics.TrilinosApplication as TrilinosApplication
|
|
7
|
+
from KratosMultiphysics.TrilinosApplication import trilinos_linear_solver_factory
|
|
8
|
+
|
|
9
|
+
# Import baseclass
|
|
10
|
+
from KratosMultiphysics.MeshMovingApplication.mesh_solver_base import MeshSolverBase
|
|
11
|
+
|
|
12
|
+
# Importing MPI extensions to Kratos
|
|
13
|
+
from KratosMultiphysics.mpi.distributed_import_model_part_utility import DistributedImportModelPartUtility
|
|
14
|
+
|
|
15
|
+
class TrilinosMeshSolverBase(MeshSolverBase):
|
|
16
|
+
def __init__(self, model, custom_settings):
|
|
17
|
+
super().__init__(model, custom_settings)
|
|
18
|
+
KratosMultiphysics.Logger.PrintInfo("::[TrilinosMeshSolverBase]:: Construction finished")
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def GetDefaultParameters(cls):
|
|
22
|
+
this_defaults = KratosMultiphysics.Parameters("""{
|
|
23
|
+
"linear_solver_settings" : {
|
|
24
|
+
"solver_type" : "amgcl",
|
|
25
|
+
"smoother_type":"ilu0",
|
|
26
|
+
"krylov_type": "gmres",
|
|
27
|
+
"coarsening_type": "aggregation",
|
|
28
|
+
"max_iteration": 200,
|
|
29
|
+
"provide_coordinates": false,
|
|
30
|
+
"gmres_krylov_space_dimension": 100,
|
|
31
|
+
"verbosity" : 0,
|
|
32
|
+
"tolerance": 1e-7,
|
|
33
|
+
"scaling": false,
|
|
34
|
+
"block_size": 1,
|
|
35
|
+
"use_block_matrices_if_possible" : true,
|
|
36
|
+
"coarse_enough" : 5000
|
|
37
|
+
}
|
|
38
|
+
}""")
|
|
39
|
+
this_defaults.AddMissingParameters(super().GetDefaultParameters())
|
|
40
|
+
return this_defaults
|
|
41
|
+
|
|
42
|
+
#### Public user interface functions ####
|
|
43
|
+
|
|
44
|
+
def AddVariables(self):
|
|
45
|
+
super().AddVariables()
|
|
46
|
+
self.mesh_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.PARTITION_INDEX)
|
|
47
|
+
KratosMultiphysics.Logger.PrintInfo("::[TrilinosMeshSolverBase]:: Variables ADDED.")
|
|
48
|
+
|
|
49
|
+
def ImportModelPart(self):
|
|
50
|
+
KratosMultiphysics.Logger.PrintInfo("::[TrilinosMeshSolverBase]:: ", "Importing model part.")
|
|
51
|
+
self.distributed_model_part_importer = DistributedImportModelPartUtility(self.mesh_model_part, self.settings)
|
|
52
|
+
self.distributed_model_part_importer.ImportModelPart()
|
|
53
|
+
KratosMultiphysics.Logger.PrintInfo("::[TrilinosMeshSolverBase]:: ", "Finished importing model part.")
|
|
54
|
+
|
|
55
|
+
def PrepareModelPart(self):
|
|
56
|
+
super().PrepareModelPart()
|
|
57
|
+
# Construct the mpi-communicator
|
|
58
|
+
self.distributed_model_part_importer.CreateCommunicators()
|
|
59
|
+
KratosMultiphysics.Logger.PrintInfo("::[TrilinosMeshSolverBase]::", "ModelPart prepared for Solver.")
|
|
60
|
+
|
|
61
|
+
def Finalize(self):
|
|
62
|
+
super().Finalize()
|
|
63
|
+
self._GetSolutionStrategy().Clear() # needed for proper finalization of MPI
|
|
64
|
+
|
|
65
|
+
#### Specific internal functions ####
|
|
66
|
+
|
|
67
|
+
def get_communicator(self):
|
|
68
|
+
if not hasattr(self, '_communicator'):
|
|
69
|
+
self._communicator = TrilinosApplication.CreateEpetraCommunicator(self.mesh_model_part.GetCommunicator().GetDataCommunicator())
|
|
70
|
+
return self._communicator
|
|
71
|
+
|
|
72
|
+
#### Private functions ####
|
|
73
|
+
|
|
74
|
+
def _CreateLinearSolver(self):
|
|
75
|
+
return trilinos_linear_solver_factory.ConstructSolver(self.settings["linear_solver_settings"])
|
|
76
|
+
|
|
77
|
+
def _CreateSolutionStrategy(self):
|
|
78
|
+
raise Exception("Mesh motion solver must be created by the derived class.")
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics
|
|
3
|
+
|
|
4
|
+
# Import applications
|
|
5
|
+
from KratosMultiphysics.MeshMovingApplication import TrilinosExtension as TrilinosMeshMoving
|
|
6
|
+
|
|
7
|
+
# Import baseclass
|
|
8
|
+
from KratosMultiphysics.MeshMovingApplication.trilinos_mesh_solver_base import TrilinosMeshSolverBase
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def CreateSolver(model, custom_settings):
|
|
12
|
+
return TrilinosMeshSolverLaplacian(model, custom_settings)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TrilinosMeshSolverLaplacian(TrilinosMeshSolverBase):
|
|
16
|
+
def __init__(self, model, custom_settings):
|
|
17
|
+
super().__init__(model, custom_settings)
|
|
18
|
+
if custom_settings["buffer_size"].GetInt() < 2:
|
|
19
|
+
raise Exception("A buffer_size of at least 2 is required!")
|
|
20
|
+
KratosMultiphysics.Logger.PrintInfo("::[TrilinosMeshSolverLaplacian]:: Construction finished")
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def GetDefaultParameters(cls):
|
|
24
|
+
this_defaults = KratosMultiphysics.Parameters("""{
|
|
25
|
+
"buffer_size" : 2
|
|
26
|
+
}""")
|
|
27
|
+
this_defaults.AddMissingParameters(super().GetDefaultParameters())
|
|
28
|
+
return this_defaults
|
|
29
|
+
|
|
30
|
+
#### Private functions ####
|
|
31
|
+
|
|
32
|
+
def _CreateSolutionStrategy(self):
|
|
33
|
+
linear_solver = self._GetLinearSolver()
|
|
34
|
+
reform_dofs_each_step = self.settings["reform_dofs_each_step"].GetBool()
|
|
35
|
+
compute_reactions = self.settings["compute_reactions"].GetBool()
|
|
36
|
+
communicator = self.get_communicator()
|
|
37
|
+
solving_strategy = TrilinosMeshMoving.TrilinosLaplacianMeshMovingStrategy(
|
|
38
|
+
communicator,
|
|
39
|
+
self.mesh_model_part,
|
|
40
|
+
linear_solver,
|
|
41
|
+
0,
|
|
42
|
+
reform_dofs_each_step,
|
|
43
|
+
compute_reactions,
|
|
44
|
+
False,
|
|
45
|
+
self.echo_level)
|
|
46
|
+
return solving_strategy
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Importing the Kratos Library
|
|
2
|
+
import KratosMultiphysics
|
|
3
|
+
|
|
4
|
+
# Import applications
|
|
5
|
+
from KratosMultiphysics.MeshMovingApplication import TrilinosExtension as TrilinosMeshMoving
|
|
6
|
+
|
|
7
|
+
# Import baseclass
|
|
8
|
+
from KratosMultiphysics.MeshMovingApplication.trilinos_mesh_solver_base import TrilinosMeshSolverBase
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def CreateSolver(model, custom_settings):
|
|
12
|
+
return TrilinosMeshSolverStructuralSimilarity(model, custom_settings)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TrilinosMeshSolverStructuralSimilarity(TrilinosMeshSolverBase):
|
|
16
|
+
def __init__(self, model, custom_settings):
|
|
17
|
+
super().__init__(model, custom_settings)
|
|
18
|
+
KratosMultiphysics.Logger.PrintInfo("::[TrilinosMeshSolverStructuralSimilarity]:: Construction finished")
|
|
19
|
+
|
|
20
|
+
#### Private functions ####
|
|
21
|
+
|
|
22
|
+
def _CreateSolutionStrategy(self):
|
|
23
|
+
linear_solver = self._GetLinearSolver()
|
|
24
|
+
communicator = self.get_communicator()
|
|
25
|
+
reform_dofs_each_step = self.settings["reform_dofs_each_step"].GetBool()
|
|
26
|
+
compute_reactions = self.settings["compute_reactions"].GetBool()
|
|
27
|
+
solving_strategy = TrilinosMeshMoving.TrilinosStructuralMeshMovingStrategy(
|
|
28
|
+
communicator,
|
|
29
|
+
self.mesh_model_part,
|
|
30
|
+
linear_solver,
|
|
31
|
+
0,
|
|
32
|
+
reform_dofs_each_step,
|
|
33
|
+
compute_reactions,
|
|
34
|
+
False,
|
|
35
|
+
self.echo_level)
|
|
36
|
+
return solving_strategy
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: KratosMeshMovingApplication
|
|
3
|
+
Version: 10.4.4
|
|
4
|
+
Summary: KRATOS Multiphysics ("Kratos") is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
|
|
5
|
+
Author-email: Kratos Team <kratos@listas.cimne.upc.edu>
|
|
6
|
+
License: BSD-4-Clause
|
|
7
|
+
Classifier: Programming Language :: C++
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Requires-Dist: kratosmultiphysics==10.4.4
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
## MeshMoving Application
|
|
15
|
+
|
|
16
|
+
The MeshMoving Application (formerly ALEapplication) contains different mesh-update techniques.
|
|
17
|
+
|
|
18
|
+
A typical application for the use of mesh-moving is in Fluid-Structure Interaction (FSI) when the fluid mesh is moved after the displacements of the structure are mapped on the interface
|
|
19
|
+
|
|
20
|
+
### Features:
|
|
21
|
+
|
|
22
|
+
- laplacian mesh motion solver
|
|
23
|
+
|
|
24
|
+
- structural similarity mesh motion solver
|
|
25
|
+
|
|
26
|
+
- computation of mesh velocities (ALE)
|
|
27
|
+
|
|
28
|
+
- ALE-fluid solver for the usage in FSI
|
|
29
|
+
|
|
30
|
+
- works both in OpenMP and MPI
|
|
31
|
+
|
|
32
|
+
### Usage
|
|
33
|
+
|
|
34
|
+
Check the tests for examples on how to use the solvers.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
KratosMultiphysics/MeshMovingApplication/trilinos_mesh_solver_laplacian.py,sha256=U1yz8l3NZAZDjVq6tFZO_21i168FU3565eoD1czS-wg,1714
|
|
2
|
+
KratosMultiphysics/MeshMovingApplication/python_solvers_wrapper_mesh_motion.py,sha256=u1ELsL6EC-K36u6MnWY8fHhKT8RVRvk-BgKJwoJBook,2566
|
|
3
|
+
KratosMultiphysics/MeshMovingApplication/ale_fluid_solver.py,sha256=ragG5SOS3EwCDWNfdit5dqM7CPkPsQBwa4QKxuZ9-Lk,10538
|
|
4
|
+
KratosMultiphysics/MeshMovingApplication/mesh_solver_laplacian.py,sha256=iZJEB1bweM_mZpeXkhaivRZrd4cdxACXvTOJKa45_hA,1873
|
|
5
|
+
KratosMultiphysics/MeshMovingApplication/__init__.py,sha256=qH-YUTfyUgx0keq8i3UZZ4XMQLTgnYNA6Swy--zfG4w,236
|
|
6
|
+
KratosMultiphysics/MeshMovingApplication/trilinos_mesh_solver_structural_similarity.py,sha256=0fb2S9OU4STfL4xE4zzs_v7INmLRt9zOwA-SMJ8iPkY,1349
|
|
7
|
+
KratosMultiphysics/MeshMovingApplication/mesh_moving_analysis.py,sha256=5WKqHFGR8QIHrbNKjOfoG29CkM4OJaV5VgPMleCT_bk,4135
|
|
8
|
+
KratosMultiphysics/MeshMovingApplication/mesh_solver_structural_similarity.py,sha256=CS9see7PzgOAlTXf5YXXxlmJ4aK5V3lvfxw7MaNtDvg,1685
|
|
9
|
+
KratosMultiphysics/MeshMovingApplication/trilinos_mesh_solver_base.py,sha256=cOGcdcb58ZO-I7RngK5hQMGat00FzlZQHnOF6NGLOzY,3349
|
|
10
|
+
KratosMultiphysics/MeshMovingApplication/impose_mesh_motion_process.py,sha256=h9mveA7LKFpvbjU4V5F8nWVyGEfd5tW5lQ-YCILzGqc,6397
|
|
11
|
+
KratosMultiphysics/MeshMovingApplication/mesh_solver_base.py,sha256=Fyz2cPTyYZZf-d-9VzkwyyxndCwWlGx4i0_1LrBlkpo,12270
|
|
12
|
+
KratosMultiphysics/.libs/KratosMeshMovingApplication.so,sha256=J0Oa2ZNrlEM8NG2TxO3pfyx49Xy0ZV6T2kp4I9NwnHc,2642336
|
|
13
|
+
KratosMultiphysics/.libs/libKratosMeshMovingCore.dylib,sha256=Z3WQAVPrbFH2WM9zl2qUaAWarA_HBaF8u5dfOJTSogI,4337856
|
|
14
|
+
kratosmeshmovingapplication.dylibs/libstdc++.6.dylib,sha256=sQ4u0s2Atn1FnSvvZUZO2QLkXwH_rTkkNkFvGq0odBY,3403264
|
|
15
|
+
kratosmeshmovingapplication.dylibs/libKratosCore.dylib,sha256=OoC_b2OBg955Xg9Cy296CGIoi5fs-H7Vt6xLvl3NrW0,63629792
|
|
16
|
+
kratosmeshmovingapplication.dylibs/libgcc_s.1.1.dylib,sha256=efJUcaA3mSImJI9pt7uV_DBg67lDGg7X_YOakSxYy3I,219232
|
|
17
|
+
kratosmeshmovingapplication.dylibs/libgomp.1.dylib,sha256=KoD8H23zFfDTnSQM_Ei1qnTJKpEgJRRVQ1BYSfqZ1iI,438880
|
|
18
|
+
kratosmeshmovingapplication-10.4.4.dist-info/RECORD,,
|
|
19
|
+
kratosmeshmovingapplication-10.4.4.dist-info/WHEEL,sha256=QX0UaoWXQIAv8vp5R3do793urekDoJdJRoGCk8nXIBY,115
|
|
20
|
+
kratosmeshmovingapplication-10.4.4.dist-info/METADATA,sha256=bOH3CiETRRaoiK8FDe-NjoNUIhganto4zGStNGXRolg,1258
|
|
Binary file
|
|
Binary file
|
|
Binary file
|