KratosDemStructuresCouplingApplication 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 (27) hide show
  1. KratosMultiphysics/.libs/KratosDemStructuresCouplingApplication.so +0 -0
  2. KratosMultiphysics/.libs/libKratosDemStructuresCouplingCore.dylib +0 -0
  3. KratosMultiphysics/DemStructuresCouplingApplication/__init__.py +7 -0
  4. KratosMultiphysics/DemStructuresCouplingApplication/control_module_fem_dem_utility.py +109 -0
  5. KratosMultiphysics/DemStructuresCouplingApplication/control_module_process.py +29 -0
  6. KratosMultiphysics/DemStructuresCouplingApplication/dem_fem_coupling_algorithm.py +251 -0
  7. KratosMultiphysics/DemStructuresCouplingApplication/dem_fem_launcher.py +10 -0
  8. KratosMultiphysics/DemStructuresCouplingApplication/dem_main_script_ready_for_coupling_with_fem.py +29 -0
  9. KratosMultiphysics/DemStructuresCouplingApplication/dem_poromechanics_coupling_analysis_stage.py +424 -0
  10. KratosMultiphysics/DemStructuresCouplingApplication/dem_structures_coupling_gid_output.py +201 -0
  11. KratosMultiphysics/DemStructuresCouplingApplication/multiaxial_control_module_fem_dem_generalized_2d_utility.py +141 -0
  12. KratosMultiphysics/DemStructuresCouplingApplication/sand_production_post_process_tool.py +135 -0
  13. KratosMultiphysics/DemStructuresCouplingApplication/sp_dem_fem_coupling_algorithm.py +303 -0
  14. KratosMultiphysics/DemStructuresCouplingApplication/sp_dem_fem_launcher.py +10 -0
  15. KratosMultiphysics/DemStructuresCouplingApplication/sp_statistics.py +143 -0
  16. KratosMultiphysics/DemStructuresCouplingApplication/sp_statistics_2.py +139 -0
  17. KratosMultiphysics/DemStructuresCouplingApplication/stress_failure_check_utility.py +36 -0
  18. kratosdemstructurescouplingapplication-10.4.4.dist-info/METADATA +17 -0
  19. kratosdemstructurescouplingapplication-10.4.4.dist-info/RECORD +27 -0
  20. kratosdemstructurescouplingapplication-10.4.4.dist-info/WHEEL +6 -0
  21. kratosdemstructurescouplingapplication.dylibs/libKratosCore.dylib +4 -0
  22. kratosdemstructurescouplingapplication.dylibs/libKratosDEMCore.dylib +0 -0
  23. kratosdemstructurescouplingapplication.dylibs/libKratosPoromechanicsCore.dylib +0 -0
  24. kratosdemstructurescouplingapplication.dylibs/libKratosStructuralMechanicsCore.dylib +0 -0
  25. kratosdemstructurescouplingapplication.dylibs/libgcc_s.1.1.dylib +0 -0
  26. kratosdemstructurescouplingapplication.dylibs/libgomp.1.dylib +0 -0
  27. kratosdemstructurescouplingapplication.dylibs/libstdc++.6.dylib +0 -0
@@ -0,0 +1,141 @@
1
+ import KratosMultiphysics
2
+ import KratosMultiphysics.DEMApplication as Dem
3
+ import KratosMultiphysics.DemStructuresCouplingApplication as DemFem
4
+ from KratosMultiphysics.DEMApplication.multiaxial_control_module_generalized_2d_utility import MultiaxialControlModuleGeneralized2DUtility
5
+
6
+ class MultiaxialControlModuleFEMDEMGeneralized2DUtility(MultiaxialControlModuleGeneralized2DUtility):
7
+ def __init__(self, Model, settings):
8
+
9
+ #NOTE: Negative target_stress means compression
10
+
11
+ self.spheres_model_part = Model["SpheresPart"]
12
+ self.fem_model_part = Model["Structure"]
13
+
14
+ self.parameters = settings["multiaxial_control_module_fem_dem_generalized_2d_utility"]
15
+
16
+ self.cm_step = 0
17
+ self.output_interval = self.parameters["Parameters"]["output_interval"].GetInt()
18
+
19
+ self.cm_utility = DemFem.MultiaxialControlModuleFEMDEMGeneralized2DUtilities(self.spheres_model_part,
20
+ self.fem_model_part,
21
+ self.parameters)
22
+
23
+ def ExecuteFinalizeSolutionStep(self):
24
+ self.cm_utility.ExecuteFinalizeSolutionStep()
25
+
26
+ if self.output_interval == 0:
27
+ return
28
+ self.FillPrintVariables()
29
+
30
+ self.PrintResults()
31
+
32
+ def FillPrintVariables(self):
33
+ time = self.fem_model_part.ProcessInfo[KratosMultiphysics.TIME]
34
+ self.times.append(time)
35
+
36
+ # Pa to psi
37
+ unit_trans = 0.000145038
38
+
39
+ for name in self.actuator_names:
40
+ if name == 'Z':
41
+ for node in self.fem_submodelparts[name][0].Nodes:
42
+ self.reactions[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.REACTION_STRESS_Z))*unit_trans)
43
+ self.target_reactions[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.TARGET_STRESS_Z))*unit_trans)
44
+ self.velocities[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.LOADING_VELOCITY_Z))*unit_trans)
45
+ break
46
+ elif name == 'X':
47
+ for node in self.fem_submodelparts[name][0].Nodes:
48
+ self.reactions[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.REACTION_STRESS_X))*unit_trans)
49
+ self.target_reactions[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.TARGET_STRESS_X))*unit_trans)
50
+ self.velocities[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.LOADING_VELOCITY_X))*unit_trans)
51
+ break
52
+ elif name == 'Y':
53
+ for node in self.fem_submodelparts[name][0].Nodes:
54
+ self.reactions[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.REACTION_STRESS_Y))*unit_trans)
55
+ self.target_reactions[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.TARGET_STRESS_Y))*unit_trans)
56
+ self.velocities[name].append(abs(node.GetValue(KratosMultiphysics.DEMApplication.LOADING_VELOCITY_Y))*unit_trans)
57
+ break
58
+ elif name == 'Radial':
59
+ for node in self.fem_submodelparts[name][0].Nodes:
60
+ value_x = abs(node.GetValue(KratosMultiphysics.DEMApplication.REACTION_STRESS_X))*unit_trans
61
+ value_y = abs(node.GetValue(KratosMultiphysics.DEMApplication.REACTION_STRESS_Y))*unit_trans
62
+ norm = (value_x**2 + value_y**2)**0.5
63
+ self.reactions[name].append(norm)
64
+ value_x = abs(node.GetValue(KratosMultiphysics.DEMApplication.TARGET_STRESS_X))*unit_trans
65
+ value_y = abs(node.GetValue(KratosMultiphysics.DEMApplication.TARGET_STRESS_Y))*unit_trans
66
+ norm = (value_x**2 + value_y**2)**0.5
67
+ self.target_reactions[name].append(norm)
68
+ value_x = abs(node.GetValue(KratosMultiphysics.DEMApplication.LOADING_VELOCITY_X))*unit_trans
69
+ value_y = abs(node.GetValue(KratosMultiphysics.DEMApplication.LOADING_VELOCITY_Y))*unit_trans
70
+ norm = (value_x**2 + value_y**2)**0.5
71
+ self.velocities[name].append(norm)
72
+ break
73
+
74
+ def PrintResults(self):
75
+ self.cm_step += 1
76
+
77
+ if self.output_interval == 0:
78
+ return
79
+ if self.cm_step % self.output_interval != 0:
80
+ return
81
+
82
+ import matplotlib
83
+ matplotlib.use('agg')
84
+ import matplotlib.pyplot as plt
85
+
86
+ f = plt.figure()
87
+
88
+ for name in self.actuator_names:
89
+ plt.plot(self.times,
90
+ self.reactions[name],
91
+ color=self.colors[name],
92
+ linestyle=self.reactions['linestyle'],
93
+ linewidth=self.reactions['linewidth'],
94
+ label='reaction_' + name)
95
+ plt.plot(self.times,
96
+ self.target_reactions[name],
97
+ color=self.colors[name],
98
+ linestyle=self.target_reactions['linestyle'],
99
+ linewidth=self.target_reactions['linewidth'],
100
+ label='target_reaction_' + name)
101
+
102
+ # plt.legend(bbox_to_anchor=(1.05, 1.0), loc='upper left')
103
+ plt.legend()
104
+ max_stress = 0
105
+ for name in self.actuator_names:
106
+ max_stress = max(max(abs(min(self.target_reactions[name])),max(self.target_reactions[name])), max_stress)
107
+ plt.ylim(-0.1*max_stress,1.1*max_stress)
108
+
109
+ plt.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
110
+
111
+ # naming the x axis
112
+ plt.xlabel('Time (s)')
113
+ # naming the y axis
114
+ plt.ylabel('Stress (Psi)')
115
+ # giving a title to my graph
116
+ plt.title('Reaction vs target stresses')
117
+
118
+ f.savefig("reactions.pdf", bbox_inches='tight')
119
+ plt.close()
120
+
121
+ f = plt.figure()
122
+
123
+ for name in self.actuator_names:
124
+ plt.plot(self.times,
125
+ self.velocities[name],
126
+ color=self.colors[name],
127
+ label='velocity_' + name)
128
+
129
+ plt.legend()
130
+
131
+ plt.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
132
+
133
+ # naming the x axis
134
+ plt.xlabel('Time (s)')
135
+ # naming the y axis
136
+ plt.ylabel('velocity (m/s)')
137
+ # giving a title to my graph
138
+ plt.title('Loading velocity')
139
+
140
+ f.savefig("velocities.pdf", bbox_inches='tight')
141
+ plt.close()
@@ -0,0 +1,135 @@
1
+ # Import system python
2
+ import os
3
+
4
+ import numpy as np
5
+ import h5py
6
+ import KratosMultiphysics as Kratos
7
+ import KratosMultiphysics.DEMApplication as Dem
8
+ import KratosMultiphysics.DemStructuresCouplingApplication as DemFem
9
+
10
+ def Norm(vector):
11
+ return np.sqrt(sum(v**2 for v in vector))
12
+
13
+ class SandProductionPostProcessTool():
14
+ def __init__(self, fem_model_part, dem_model_part, test_number):
15
+
16
+ if not test_number:
17
+ return
18
+
19
+ self.parameters = Kratos.Parameters( """
20
+ {
21
+ "file_name": "sp_data.hdf5",
22
+ "target_porosity" : 0.3,
23
+ "probe_height" : 0.2032
24
+ } """ )
25
+
26
+ if test_number == 1: # CTW16
27
+ test_id = "CTW16"
28
+ elif test_number == 2: # CTW10
29
+ test_id = "CTW10"
30
+ else: # Blind test
31
+ test_id = "BlindTest"
32
+
33
+ self.parameters.AddEmptyValue("test_id")
34
+ self.parameters["test_id"].SetString(test_id)
35
+
36
+ self.dem_model_part = dem_model_part
37
+ self.fem_model_part = fem_model_part
38
+
39
+ self.post_process_utility = DemFem.PostProcessUtilities(self.dem_model_part)
40
+
41
+ self.internal_radius, self.external_radius, self.interface_radius, self.thickness, self.volume, self.average_radius = self.GetProbeDimensions()
42
+ for elem in self.dem_model_part.Elements:
43
+ self.density = elem.Properties[Dem.PARTICLE_DENSITY]
44
+ break
45
+ self.porosity = self.CalculatePorosity()
46
+ self.problem_path = os.getcwd()
47
+ self.file_path = os.path.join(str(self.problem_path),self.parameters["file_name"].GetString())
48
+ self.target_porosity = self.parameters["target_porosity"].GetDouble()
49
+ self.real_probe_height = self.parameters["probe_height"].GetDouble()
50
+
51
+ self.dtype = np.float64
52
+ self.compression_type = 'gzip'
53
+ self.number_of_readings = 0
54
+ self.last_time = - float('inf')
55
+
56
+ # This assumes annulus centered at the origin
57
+ with h5py.File(self.file_path, 'w') as f:
58
+ f.attrs['test_id'] = self.parameters["test_id"].GetString()
59
+ f.attrs['internal_radius'] = self.internal_radius
60
+ f.attrs['external_radius'] = self.external_radius
61
+ f.attrs['interface_radius'] = self.interface_radius
62
+ f.attrs['thickness'] = self.thickness
63
+ f.attrs['volume'] = self.volume
64
+ f.attrs['real_probe_height'] = self.real_probe_height
65
+ f.attrs['target_porosity'] = self.target_porosity
66
+ f.attrs['porosity'] = self.porosity
67
+ f.attrs['density'] = self.density
68
+
69
+ def CalculateAverageRadius(self):
70
+ radii_array = np.array([node.GetSolutionStepValue(Kratos.RADIUS) for node in self.dem_model_part.Nodes])
71
+ return sum(radii_array)/len(radii_array)
72
+
73
+ def GetProbeDimensions(self):
74
+ average_radius = self.CalculateAverageRadius()
75
+ internal_radius = min(Norm([node.X, node.Y]) for node in self.dem_model_part.Nodes) - average_radius
76
+ external_radius = max(Norm([node.X, node.Y]) for node in self.fem_model_part.Nodes)
77
+ interface_radius = max(Norm([node.X, node.Y]) for node in self.dem_model_part.Nodes) + average_radius
78
+ min_z = min(node.Z for node in self.fem_model_part.Nodes)
79
+ max_z = max(node.Z for node in self.fem_model_part.Nodes)
80
+ thickness = max_z - min_z
81
+ area = np.pi * (external_radius**2 - internal_radius**2)
82
+ volume = thickness * area
83
+ return internal_radius, external_radius, interface_radius, thickness, volume, average_radius
84
+
85
+ def CalculatePorosity(self):
86
+ volume = 0.
87
+ for node in self.dem_model_part.Nodes:
88
+ volume += 4/3 * np.pi * node.GetSolutionStepValue(Kratos.RADIUS) ** 3
89
+ volume_dem_part = np.pi * self.thickness * (self.interface_radius**2 - self.internal_radius**2)
90
+ porosity = volume / volume_dem_part
91
+ return porosity
92
+
93
+ def WriteData(self):
94
+ time = self.dem_model_part.ProcessInfo[Kratos.TIME]
95
+ name = str(self.number_of_readings)
96
+ with h5py.File(self.file_path, 'r+') as f:
97
+ f.create_group(name = name)
98
+ f[name].attrs['time'] = time
99
+ column_shape = (len(self.dem_model_part.Nodes), )
100
+ self.ids_array = np.array([node.Id for node in self.dem_model_part.Nodes])
101
+ self.radii_array = np.array([node.GetSolutionStepValue(Kratos.RADIUS) for node in self.dem_model_part.Nodes])
102
+ self.x_array = np.array([node.X for node in self.dem_model_part.Nodes])
103
+ self.y_array = np.array([node.Y for node in self.dem_model_part.Nodes])
104
+ self.z_array = np.array([node.Z for node in self.dem_model_part.Nodes])
105
+ is_sticky_list = []
106
+ self.post_process_utility.GetStickyStatus(is_sticky_list)
107
+ self.is_sticky_array = np.array(is_sticky_list)
108
+ initial_continuum_bonds_list = []
109
+ self.post_process_utility.GetInitialContinuumBonds(initial_continuum_bonds_list)
110
+ self.initial_continuum_bonds_array = np.array(initial_continuum_bonds_list)
111
+ current_continuum_bonds_list = []
112
+ self.post_process_utility.GetCurrentContinuumBonds(current_continuum_bonds_list)
113
+ self.current_continuum_bonds_array = np.array(current_continuum_bonds_list)
114
+
115
+ if not self.last_time == time:
116
+ with h5py.File(self.file_path, 'r+') as f:
117
+ f.create_dataset(name + '/id', compression = self.compression_type, shape = column_shape, dtype = self.dtype) # TODO: change type as int
118
+ f[name + '/id'][:] = self.ids_array[:]
119
+ f.create_dataset(name + '/radius', compression = self.compression_type, shape = column_shape, dtype = self.dtype)
120
+ f[name + '/radius'][:] = self.radii_array[:]
121
+ f.create_dataset(name + '/x', compression = self.compression_type, shape = column_shape, dtype = self.dtype)
122
+ f[name + '/x'][:] = self.x_array[:]
123
+ f.create_dataset(name + '/y', compression = self.compression_type, shape = column_shape, dtype = self.dtype)
124
+ f[name + '/y'][:] = self.y_array[:]
125
+ f.create_dataset(name + '/z', compression = self.compression_type, shape = column_shape, dtype = self.dtype)
126
+ f[name + '/z'][:] = self.z_array[:]
127
+ f.create_dataset(name + '/is_sticky', compression = self.compression_type, shape = column_shape, dtype = self.dtype)
128
+ f[name + '/is_sticky'][:] = self.is_sticky_array[:]
129
+ f.create_dataset(name + '/initial_continuum_bonds', compression = self.compression_type, shape = column_shape, dtype = self.dtype)
130
+ f[name + '/initial_continuum_bonds'][:] = self.initial_continuum_bonds_array[:]
131
+ f.create_dataset(name + '/current_continuum_bonds', compression = self.compression_type, shape = column_shape, dtype = self.dtype)
132
+ f[name + '/current_continuum_bonds'][:] = self.current_continuum_bonds_array[:]
133
+
134
+ self.last_time = time
135
+ self.number_of_readings += 1
@@ -0,0 +1,303 @@
1
+ import time as timer
2
+ import os
3
+ import KratosMultiphysics as Kratos
4
+ from Kratos import Logger
5
+ from KratosMultiphysics.deprecation_management import DeprecationManager
6
+
7
+ import KratosMultiphysics.DEMApplication as Dem
8
+ Logger.Print("Running under OpenMP........", label="DEM")
9
+ import KratosMultiphysics.StructuralMechanicsApplication as Structural
10
+ import KratosMultiphysics.DemStructuresCouplingApplication as DemFem
11
+ from KratosMultiphysics.DemStructuresCouplingApplication.dem_fem_coupling_algorithm import Algorithm
12
+
13
+ class SPAlgorithm(Algorithm):
14
+
15
+ def __init__(self):
16
+ super(SPAlgorithm,self).__init__()
17
+
18
+ sp_parameters_file_name = "SPParameters.json"
19
+
20
+ with open(sp_parameters_file_name,'r') as parameter_file:
21
+ self.sp_parameters = Kratos.Parameters(parameter_file.read())
22
+
23
+ self.ValidateSettings()
24
+
25
+ self.test_number = self.sp_parameters["problem_data"]["test_number"].GetInt()
26
+ # Test types (4 different options):
27
+ # Test number 0: no test simulation
28
+ # Test number 1: CTW16 specimen
29
+ # Test number 2: CTW10 specimen
30
+ # Test number 3: Blind test specimen
31
+
32
+ self.post_process_step_count = 0
33
+ self.post_process_frequency = self.sp_parameters["post_process_tool"]["output_interval"].GetInt()
34
+ self.use_post_process_tool = self.sp_parameters["post_process_tool"]["use_post_process_tool"].GetBool()
35
+ if not self.use_post_process_tool:
36
+ self.post_process_frequency = 0
37
+ self.post_process_write_count = self.post_process_frequency
38
+
39
+ @classmethod
40
+ def GetDefaultParameters(cls):
41
+ """This function returns the default-settings used by this class
42
+ """
43
+ return Kratos.Parameters("""{
44
+ "problem_data" : {
45
+ "test_number" : 1,
46
+ "center" : [0.0,0.0,0.0],
47
+ "axis" : [0.0,0.0,1.0],
48
+ "sp_radius": 0.042
49
+ },
50
+ "post_process_tool":{
51
+ "use_post_process_tool": false,
52
+ "output_interval": 0
53
+ },
54
+ "multiaxial_control_module_fem_dem_generalized_2d_utility" : {
55
+ "Parameters" : {
56
+ "control_module_delta_time": 2.0e-6,
57
+ "perturbation_tolerance": 1.0e-3,
58
+ "perturbation_period": 10,
59
+ "max_reaction_rate_factor": 10.0,
60
+ "stiffness_averaging_time_interval": 2.0e-6,
61
+ "velocity_averaging_time_interval": 2.0e-6,
62
+ "reaction_averaging_time_interval": 2.0e-8,
63
+ "output_interval": 0
64
+ },
65
+ "list_of_actuators" : []
66
+ }
67
+ }""")
68
+
69
+ # This function can be extended with new deprecated variables as they are generated
70
+ def TranslateLegacyVariablesAccordingToCurrentStandard(self, settings):
71
+ # Defining a string to help the user understand where the warnings come from (in case any is thrown)
72
+ context_string = type(self).__name__
73
+
74
+ if settings.Has('post_process_tool'):
75
+ sub_settings_where_var_is = settings['post_process_tool']
76
+ old_name = 'output_frequency'
77
+ new_name = 'output_interval'
78
+
79
+ if DeprecationManager.HasDeprecatedVariable(context_string, sub_settings_where_var_is, old_name, new_name):
80
+ DeprecationManager.ReplaceDeprecatedVariableName(sub_settings_where_var_is, old_name, new_name)
81
+
82
+
83
+ def ValidateSettings(self):
84
+ """This function validates the settings of the solver
85
+ """
86
+ default_settings = self.GetDefaultParameters()
87
+ self.TranslateLegacyVariablesAccordingToCurrentStandard(self.sp_parameters)
88
+ self.sp_parameters.ValidateAndAssignDefaults(default_settings)
89
+
90
+ def Initialize(self):
91
+ super(SPAlgorithm,self).Initialize()
92
+
93
+ self.InitializeAdditionalProcessInfoVars()
94
+
95
+ from KratosMultiphysics.DemStructuresCouplingApplication.multiaxial_control_module_fem_dem_generalized_2d_utility import MultiaxialControlModuleFEMDEMGeneralized2DUtility
96
+ self.multiaxial_control_module = MultiaxialControlModuleFEMDEMGeneralized2DUtility(self.model, self.sp_parameters)
97
+ self.multiaxial_control_module.ExecuteInitialize()
98
+ # if self.test_number:
99
+ # from KratosMultiphysics.DemStructuresCouplingApplication.control_module_fem_dem_utility import ControlModuleFemDemUtility
100
+ # self.control_module_fem_dem_utility = ControlModuleFemDemUtility(self.model, self.dem_solution.spheres_model_part, self.test_number)
101
+ # self.control_module_fem_dem_utility.ExecuteInitialize()
102
+
103
+ self.CreateSPMeasuringRingSubmodelpart()
104
+
105
+ # Create Postprocess tool for SP
106
+ if self.use_post_process_tool:
107
+ from KratosMultiphysics.DemStructuresCouplingApplication.sand_production_post_process_tool import SandProductionPostProcessTool
108
+ self.sp_post_process_tool = SandProductionPostProcessTool(self.structural_solution._GetSolver().GetComputingModelPart(),
109
+ self.dem_solution.spheres_model_part,
110
+ self.test_number)
111
+
112
+ from KratosMultiphysics.DemStructuresCouplingApplication import stress_failure_check_utility
113
+ self.stress_failure_check_utility = stress_failure_check_utility.StressFailureCheckUtility(self.dem_solution.spheres_model_part, self.test_number)
114
+
115
+ def CreateSPMeasuringRingSubmodelpart(self):
116
+
117
+ if not self.dem_solution.spheres_model_part.HasSubModelPart("RingSubmodelPart"):
118
+ self.dem_solution.spheres_model_part.CreateSubModelPart('RingSubmodelPart')
119
+ self.ring_submodelpart = self.dem_solution.spheres_model_part.GetSubModelPart('RingSubmodelPart')
120
+
121
+ zone_radius_to_measure_2d_sp = self.sp_parameters["problem_data"]["sp_radius"].GetDouble()
122
+ nodes_in_zone_radius_list = []
123
+ elements_in_zone_radius_list = []
124
+
125
+ for element in self.dem_solution.spheres_model_part.Elements:
126
+ node = element.GetNode(0)
127
+ x = node.X
128
+ y = node.Y
129
+
130
+ if (x * x + y * y) < zone_radius_to_measure_2d_sp * zone_radius_to_measure_2d_sp:
131
+ nodes_in_zone_radius_list.append(node.Id)
132
+ elements_in_zone_radius_list.append(element.Id)
133
+
134
+ self.ring_submodelpart.AddNodes(nodes_in_zone_radius_list)
135
+ self.ring_submodelpart.AddElements(elements_in_zone_radius_list)
136
+
137
+ def InitializeAdditionalProcessInfoVars(self):
138
+ self.dem_solution.spheres_model_part.ProcessInfo.SetValue(Dem.SIGMA_3_AVERAGE, 0.0)
139
+
140
+ def _TransferStructuresSkinToDem(self):
141
+ self.structural_mp = self.structural_solution._GetSolver().GetComputingModelPart()
142
+ self.skin_mp = self.structural_mp.GetSubModelPart("DetectedByProcessSkinModelPart")
143
+ # dem_walls_mp = self.dem_solution.rigid_face_model_part.CreateSubModelPart("SkinTransferredFromStructure")
144
+ dem_walls_mp = self.dem_solution.rigid_face_model_part
145
+ max_prop_id = 0
146
+ for prop in dem_walls_mp.Properties:
147
+ if prop.Id > max_prop_id:
148
+ max_prop_id = prop.Id
149
+ props = Kratos.Properties(max_prop_id + 1)
150
+ # NOTE: this should be more general
151
+ props[Dem.STATIC_FRICTION] = 0.2
152
+ props[Dem.DYNAMIC_FRICTION] = 0.2
153
+ props[Dem.WALL_COHESION] = 0.0
154
+ props[Dem.COMPUTE_WEAR] = False
155
+ props[Dem.SEVERITY_OF_WEAR] = 0.001
156
+ props[Dem.IMPACT_WEAR_SEVERITY] = 0.001
157
+ props[Dem.BRINELL_HARDNESS] = 200.0
158
+ props[Kratos.YOUNG_MODULUS] = 7e9
159
+ props[Kratos.POISSON_RATIO] = 0.16
160
+ dem_walls_mp.AddProperties(props)
161
+ DemFem.DemStructuresCouplingUtilities().TransferStructuresSkinToDem(self.skin_mp, dem_walls_mp, props)
162
+
163
+ def RunSolutionLoop(self):
164
+
165
+ self.dem_solution.step = 0
166
+ self.dem_solution.time = 0.0
167
+ self.dem_solution.time_old_print = 0.0
168
+ self.time_dem = 0.0
169
+ self.Dt_structural = self.structural_solution._GetSolver().settings["time_stepping"]["time_step"].GetDouble()
170
+
171
+ while self.structural_solution.time < self.structural_solution.end_time:
172
+
173
+ portion_of_the_force_which_is_new = 0.1
174
+ DemFem.DemStructuresCouplingUtilities().SmoothLoadTrasferredToFem(self.dem_solution.rigid_face_model_part, portion_of_the_force_which_is_new)
175
+
176
+ self.structural_solution.time = self.structural_solution._GetSolver().AdvanceInTime(self.structural_solution.time)
177
+
178
+ # if self.test_number:
179
+ # self.control_module_fem_dem_utility.ExecuteInitializeSolutionStep()
180
+ self.multiaxial_control_module.ExecuteInitializeSolutionStep()
181
+ self.structural_solution.InitializeSolutionStep()
182
+ self.structural_solution._GetSolver().Predict()
183
+ self.structural_solution._GetSolver().SolveSolutionStep()
184
+
185
+ time_final_DEM_substepping = self.structural_solution.time
186
+
187
+ self.Dt_DEM = self.dem_solution.spheres_model_part.ProcessInfo.GetValue(Kratos.DELTA_TIME)
188
+
189
+ DemFem.InterpolateStructuralSolutionForDEM().SaveStructuralSolution(self.structural_mp)
190
+
191
+ DemFem.ComputeDEMFaceLoadUtility().ClearDEMFaceLoads(self.skin_mp)
192
+
193
+ for self.dem_solution.time_dem in self.yield_DEM_time(self.dem_solution.time, time_final_DEM_substepping, self.Dt_DEM):
194
+ self.dem_solution.time = self.dem_solution.time + self.dem_solution._GetSolver().dt
195
+
196
+ self.dem_solution.step += 1
197
+
198
+ self.dem_solution.DEMFEMProcedures.UpdateTimeInModelParts(self.dem_solution.all_model_parts, self.dem_solution.time, self.dem_solution._GetSolver().dt, self.dem_solution.step)
199
+
200
+ self.dem_solution.InitializeSolutionStep()
201
+
202
+ self.dem_solution._GetSolver().Predict()
203
+
204
+ DemFem.InterpolateStructuralSolutionForDEM().InterpolateStructuralSolution(self.structural_mp, self.Dt_structural, self.structural_solution.time, self.dem_solution._GetSolver().dt, self.dem_solution.time)
205
+
206
+ self.dem_solution.SolverSolve()
207
+
208
+ self.dem_solution.FinalizeSolutionStep()
209
+
210
+ DemFem.ComputeDEMFaceLoadUtility().CalculateDEMFaceLoads(self.skin_mp, self.dem_solution._GetSolver().dt, self.Dt_structural)
211
+
212
+ #### PRINTING GRAPHS ####
213
+ os.chdir(self.dem_solution.graphs_path)
214
+ self.dem_solution.post_utils.ComputeMeanVelocitiesInTrap("Average_Velocity.txt", self.dem_solution.time, self.dem_solution.graphs_path)
215
+
216
+ #old function, we can not use them now #TODO:update it
217
+ #self.dem_solution.materialTest.MeasureForcesAndPressure()
218
+ #self.dem_solution.materialTest.PrintGraph(self.dem_solution.time)
219
+
220
+ self.dem_solution.DEMFEMProcedures.PrintGraph(self.dem_solution.time)
221
+ self.dem_solution.DEMFEMProcedures.PrintBallsGraph(self.dem_solution.time)
222
+
223
+ self.dem_solution.DEMEnergyCalculator.CalculateEnergyAndPlot(self.dem_solution.time)
224
+
225
+ self.dem_solution.BeforePrintingOperations(self.dem_solution.time)
226
+
227
+ #### GiD IO ##########################################
228
+ if self.dem_solution.IsTimeToPrintPostProcess():
229
+ self.dem_solution._GetSolver().PrepareElementsForPrinting()
230
+ if self.dem_solution.DEM_parameters["ContactMeshOption"].GetBool():
231
+ self.dem_solution._GetSolver().PrepareContactElementsForPrinting()
232
+ self.dem_solution.PrintResultsForGid(self.dem_solution.time)
233
+ self.SPPostProcessResults(self.dem_solution.time)
234
+ self.dem_solution.demio.PrintMultifileLists(self.dem_solution.time, self.dem_solution.post_path)
235
+ self.dem_solution.time_old_print = self.dem_solution.time
236
+
237
+ if self.test_number:
238
+ self.stress_failure_check_utility.ExecuteFinalizeSolutionStep()
239
+
240
+ DemFem.InterpolateStructuralSolutionForDEM().RestoreStructuralSolution(self.structural_mp)
241
+
242
+ # if self.test_number:
243
+ # self.control_module_fem_dem_utility.ExecuteFinalizeSolutionStep()
244
+ self.multiaxial_control_module.ExecuteFinalizeSolutionStep()
245
+ self.structural_solution.FinalizeSolutionStep()
246
+ self.structural_solution.OutputSolutionStep()
247
+
248
+ # Write SP data
249
+ if self.IsPostProcessWriteStep():
250
+ self.sp_post_process_tool.WriteData()
251
+
252
+ def IsPostProcessWriteStep(self):
253
+ self.post_process_step_count += 1
254
+ if self.post_process_step_count == self.post_process_write_count:
255
+ self.post_process_write_count += self.post_process_frequency
256
+ return True
257
+ else:
258
+ return False
259
+
260
+ def SPPostProcessResults(self,time):
261
+ DemFem.DemStructuresCouplingUtilities().MarkBrokenSpheres(self.ring_submodelpart)
262
+
263
+ center = Kratos.Array3()
264
+ center[0] = self.sp_parameters["problem_data"]["center"][0].GetDouble()
265
+ center[1] = self.sp_parameters["problem_data"]["center"][1].GetDouble()
266
+ center[2] = self.sp_parameters["problem_data"]["center"][2].GetDouble()
267
+ axis = Kratos.Array3()
268
+ axis[0] = self.sp_parameters["problem_data"]["axis"][0].GetDouble()
269
+ axis[1] = self.sp_parameters["problem_data"]["axis"][1].GetDouble()
270
+ axis[2] = self.sp_parameters["problem_data"]["axis"][2].GetDouble()
271
+
272
+ radius = 0
273
+ if self.test_number == 1:
274
+ radius = 0.0036195; #95% of the real hole. CTW16 specimen
275
+ elif self.test_number == 2:
276
+ radius = 0.012065; #95% of the real hole. CTW10 specimen
277
+ elif self.test_number == 3:
278
+ radius = 0.036195; #95% of the real hole. Blind Test
279
+
280
+ self.dem_solution.creator_destructor.MarkParticlesForErasingGivenCylinder(self.ring_submodelpart, center, axis, radius)
281
+
282
+ if self.test_number == 1 or self.test_number == 2:
283
+ if self.structural_solution._GetSolver().main_model_part.ProcessInfo[Kratos.DOMAIN_SIZE] == 2:
284
+ self.outer_walls_model_part = self.model["Structure.LinePressure2D_Outer_line"]
285
+ else:
286
+ self.outer_walls_model_part = self.model["Structure.SurfacePressure3D_lateral_pressure"]
287
+ DemFem.DemStructuresCouplingUtilities().ComputeSandProductionWithDepthFirstSearchNonRecursiveImplementation(self.ring_submodelpart, self.outer_walls_model_part, time)
288
+ DemFem.DemStructuresCouplingUtilities().ComputeSandProduction(self.ring_submodelpart, self.outer_walls_model_part, time)
289
+ elif self.test_number == 3:
290
+ if self.structural_solution._GetSolver().main_model_part.ProcessInfo[Kratos.DOMAIN_SIZE] == 2:
291
+ self.outer_walls_model_part_1 = self.model["Structure.LinePressure2D_Left_line"]
292
+ # self.outer_walls_model_part_2 = self.model["Structure.LinePressure2D_Bot_line"]
293
+ else:
294
+ self.outer_walls_model_part_1 = self.model["Structure.SurfacePressure3D_sigmaXpos"]
295
+ # self.outer_walls_model_part_2 = self.model["Structure.SurfacePressure3D_sigmaYpos"]
296
+ # NOTE: The stress printed in this case will also be the SigmaZ, but probably SigmaX is more appropriate
297
+ DemFem.DemStructuresCouplingUtilities().ComputeSandProductionWithDepthFirstSearchNonRecursiveImplementation(self.ring_submodelpart, self.outer_walls_model_part_1, time)
298
+ DemFem.DemStructuresCouplingUtilities().ComputeSandProduction(self.ring_submodelpart, self.outer_walls_model_part_1, time)
299
+ # DemFem.DemStructuresCouplingUtilities().ComputeTriaxialSandProduction(self.ring_submodelpart, self.outer_walls_model_part_1, self.outer_walls_model_part_2, time)
300
+
301
+
302
+ if __name__ == "__main__":
303
+ SPAlgorithm().Run()
@@ -0,0 +1,10 @@
1
+ import sys
2
+ import KratosMultiphysics as Kratos
3
+ from Kratos import Logger
4
+ import KratosMultiphysics.DEMApplication as Dem
5
+ import KratosMultiphysics.StructuralMechanicsApplication as Structural
6
+ import KratosMultiphysics.DemStructuresCouplingApplication as DemFem
7
+
8
+ from KratosMultiphysics.DemStructuresCouplingApplication.sp_dem_fem_coupling_algorithm import SPAlgorithm
9
+
10
+ SPAlgorithm().Run()