KratosMultiphysics
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.
control_module_fem_dem_2d_utilities.hpp
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Ignasi de Pouplana
11 //
12 
13 
14 #ifndef KRATOS_CONTROL_MODULE_FEM_DEM_2D_UTILITIES
15 #define KRATOS_CONTROL_MODULE_FEM_DEM_2D_UTILITIES
16 
17 // /* External includes */
18 
19 // System includes
20 
21 // Project includes
22 #include "includes/variables.h"
23 
24 /* System includes */
25 #include <limits>
26 #include <iostream>
27 #include <iomanip>
28 
29 /* External includes */
30 #ifdef _OPENMP
31 #include <omp.h>
32 #endif
33 
34 /* Project includes */
35 #include "geometries/geometry.h"
36 #include "includes/define.h"
37 #include "includes/model_part.h"
38 
39 #include "includes/table.h"
41 
42 // Application includes
44 
46 
47 
48 namespace Kratos
49 {
51 {
52 public:
53 
55 
58 
60 
62  ModelPart& rDemModelPart,
63  Parameters& rParameters
64  ) :
65  mrFemModelPart(rFemModelPart),
66  mrDemModelPart(rDemModelPart)
67 {
69 
70  Parameters default_parameters( R"(
71  {
72  "alternate_axis_loading": false,
73  "target_stress_table_id" : 0,
74  "initial_velocity" : 0.0,
75  "limit_velocity" : 1.0,
76  "velocity_factor" : 1.0,
77  "compression_length" : 1.0,
78  "young_modulus" : 1.0e7,
79  "stress_increment_tolerance": 100.0,
80  "update_stiffness": true,
81  "start_time" : 0.0,
82  "stress_averaging_time": 1.0e-5
83  } )" );
84 
85  // Now validate agains defaults -- this also ensures no type mismatch
86  rParameters.ValidateAndAssignDefaults(default_parameters);
87 
88  // Note: this utility is design to be used in the Z direction of a 2D case
89  mTargetStressTableId = rParameters["target_stress_table_id"].GetInt();
90  mVelocity = rParameters["initial_velocity"].GetDouble();
91  mLimitVelocity = rParameters["limit_velocity"].GetDouble();
92  mVelocityFactor = rParameters["velocity_factor"].GetDouble();
93  mCompressionLength = rParameters["compression_length"].GetDouble();
94  mStartTime = rParameters["start_time"].GetDouble();
95  mStressIncrementTolerance = rParameters["stress_increment_tolerance"].GetDouble();
96  mUpdateStiffness = rParameters["update_stiffness"].GetBool();
97  mReactionStressOld = 0.0;
98  mStiffness = rParameters["young_modulus"].GetDouble()/mCompressionLength; // mStiffness is actually a stiffness over an area
99  mStressAveragingTime = rParameters["stress_averaging_time"].GetDouble();
100  mVectorOfLastStresses.resize(0);
101 
102  mAlternateAxisLoading = rParameters["alternate_axis_loading"].GetBool();
103  mZCounter = 3;
104 
105  // Initialize Variables
106  mrDemModelPart.GetProcessInfo().SetValue(TARGET_STRESS_Z,0.0);
107  int NNodes = static_cast<int>(mrFemModelPart.Nodes().size());
108  ModelPart::NodesContainerType::iterator it_begin = mrFemModelPart.NodesBegin();
109  array_1d<double,3> zero_vector = ZeroVector(3);
110  #pragma omp parallel for
111  for(int i = 0; i<NNodes; i++) {
112  ModelPart::NodesContainerType::iterator it = it_begin + i;
113  it->SetValue(TARGET_STRESS,zero_vector);
114  it->SetValue(REACTION_STRESS,zero_vector);
115  it->SetValue(LOADING_VELOCITY,zero_vector);
116  }
117  NNodes = static_cast<int>(mrDemModelPart.Nodes().size());
118  it_begin = mrDemModelPart.NodesBegin();
119  #pragma omp parallel for
120  for(int i = 0; i<NNodes; i++) {
121  ModelPart::NodesContainerType::iterator it = it_begin + i;
122  it->SetValue(TARGET_STRESS,zero_vector);
123  it->SetValue(REACTION_STRESS,zero_vector);
124  it->SetValue(LOADING_VELOCITY,zero_vector);
125  }
126 
127  mApplyCM = false;
128 
129  KRATOS_CATCH("");
130 }
131 
133 
135 
136 //***************************************************************************************************************
137 //***************************************************************************************************************
138 
139 // Before FEM and DEM solution
141 {
142  KRATOS_TRY;
143 
144  mrDemModelPart.GetProcessInfo()[IMPOSED_Z_STRAIN_VALUE] = 0.0;
145 
146  // Fem elements have IMPOSED_Z_STRAIN_VALUE already initialized as 0.0
147 
148  KRATOS_CATCH("");
149 }
150 
151 // Before FEM and DEM solution
153 {
154  KRATOS_TRY;
155 
156  const double CurrentTime = mrFemModelPart.GetProcessInfo()[TIME];
157  const double delta_time = mrFemModelPart.GetProcessInfo()[DELTA_TIME];
158  const ProcessInfo& CurrentProcessInfo = mrFemModelPart.GetProcessInfo();
159  int NElems = static_cast<int>(mrFemModelPart.Elements().size());
160  ModelPart::ElementsContainerType::iterator elem_begin = mrFemModelPart.ElementsBegin();
161  const int NNodes = static_cast<int>(mrFemModelPart.Nodes().size());
162  ModelPart::NodesContainerType::iterator it_begin = mrFemModelPart.NodesBegin();
163  TableType::Pointer pTargetStressTable = mrFemModelPart.pGetTable(mTargetStressTableId);
164 
165  double reaction_stress = CalculateReactionStress();
166  reaction_stress = UpdateVectorOfHistoricalStressesAndComputeNewAverage(reaction_stress);
167 
168  // Check whether this is a loading step for the current axis
169  IsTimeToApplyCM();
170 
171  if (mApplyCM == true) {
172 
173  // Update K if required
174  if (mAlternateAxisLoading == false) {
175  if(mUpdateStiffness == true) {
176  mStiffness = EstimateStiffness(reaction_stress,delta_time);
177  }
178  }
179  mReactionStressOld = reaction_stress;
180 
181  // Update velocity
182  const double NextTargetStress = pTargetStressTable->GetValue(CurrentTime+delta_time);
183  const double df_target = NextTargetStress - reaction_stress;
184  double delta_velocity = df_target/(mStiffness * delta_time) - mVelocity;
185 
186  if(std::abs(df_target) < mStressIncrementTolerance) { delta_velocity = -mVelocity; }
187 
188  mVelocity += mVelocityFactor * delta_velocity;
189 
190  if(std::abs(mVelocity) > std::abs(mLimitVelocity)) {
191  if(mVelocity >= 0.0) { mVelocity = std::abs(mLimitVelocity); }
192  else { mVelocity = - std::abs(mLimitVelocity); }
193  }
194 
195  // Update IMPOSED_Z_STRAIN_VALUE
196  // DEM modelpart
198  // FEM modelpart
199  const double imposed_z_strain = mrDemModelPart.GetProcessInfo()[IMPOSED_Z_STRAIN_VALUE];
200  #pragma omp parallel for
201  for(int i = 0; i < NElems; i++)
202  {
203  ModelPart::ElementsContainerType::iterator itElem = elem_begin + i;
204  Element::GeometryType& rGeom = itElem->GetGeometry();
205  GeometryData::IntegrationMethod MyIntegrationMethod = itElem->GetIntegrationMethod();
206  const Element::GeometryType::IntegrationPointsArrayType& IntegrationPoints = rGeom.IntegrationPoints(MyIntegrationMethod);
207  unsigned int NumGPoints = IntegrationPoints.size();
208  std::vector<double> imposed_z_strain_vector(NumGPoints);
209  // Loop through GaussPoints
210  for ( unsigned int GPoint = 0; GPoint < NumGPoints; GPoint++ )
211  {
212  imposed_z_strain_vector[GPoint] = imposed_z_strain;
213  }
214  itElem->SetValuesOnIntegrationPoints( IMPOSED_Z_STRAIN_VALUE, imposed_z_strain_vector, CurrentProcessInfo );
215  }
216  // Save calculated velocity and reaction for print (only at FEM nodes)
217  #pragma omp parallel for
218  for(int i = 0; i<NNodes; i++) {
219  ModelPart::NodesContainerType::iterator it = it_begin + i;
220  it->GetValue(TARGET_STRESS_Z) = pTargetStressTable->GetValue(CurrentTime);
221  it->GetValue(REACTION_STRESS_Z) = reaction_stress;
222  it->GetValue(LOADING_VELOCITY_Z) = mVelocity;
223  }
224  } else {
225  // Save calculated velocity and reaction for print (only at FEM nodes)
226  #pragma omp parallel for
227  for(int i = 0; i<NNodes; i++) {
228  ModelPart::NodesContainerType::iterator it = it_begin + i;
229  it->GetValue(TARGET_STRESS_Z) = pTargetStressTable->GetValue(CurrentTime);
230  it->GetValue(REACTION_STRESS_Z) = reaction_stress;
231  it->GetValue(LOADING_VELOCITY_Z) = 0.0;
232  }
233  }
234 
235  mrDemModelPart.GetProcessInfo()[TARGET_STRESS_Z] = pTargetStressTable->GetValue(CurrentTime);
236 
237  KRATOS_CATCH("");
238 }
239 
240 // After FEM and DEM solution
242 {
243  // Update K with latest ReactionStress after the axis has been loaded
244  if (mApplyCM == true) {
245  if (mAlternateAxisLoading == true) {
246  const double delta_time = mrFemModelPart.GetProcessInfo()[DELTA_TIME];
247  double ReactionStress = CalculateReactionStress();
248  if(mUpdateStiffness == true) {
249  mStiffness = EstimateStiffness(ReactionStress,delta_time);
250  }
251  }
252  }
253 }
254 
255 //***************************************************************************************************************
256 //***************************************************************************************************************
257 
261 
262 
266 
268 
269 virtual std::string Info() const
270 {
271  return "";
272 }
273 
275 
276 virtual void PrintInfo(std::ostream& rOStream) const
277 {
278 }
279 
281 
282 virtual void PrintData(std::ostream& rOStream) const
283 {
284 }
285 
286 
290 
292 
293 protected:
296 
299  unsigned int mTargetStressTableId;
300  double mVelocity;
304  double mStartTime;
307  double mStiffness;
309  std::vector<double> mVectorOfLastStresses;
312  unsigned int mZCounter;
313  bool mApplyCM;
314 
318 
319 
323 
324 
328 
329 
333 
337 
338 
342 
343 
345 
346 private:
347 
350 
351 
358 
362 
363 double UpdateVectorOfHistoricalStressesAndComputeNewAverage(const double& last_reaction) {
364  KRATOS_TRY;
365  int length_of_vector = mVectorOfLastStresses.size();
366  if (length_of_vector == 0) { //only the first time
367  int number_of_steps_for_stress_averaging = (int) (mStressAveragingTime / mrFemModelPart.GetProcessInfo()[DELTA_TIME]);
368  if(number_of_steps_for_stress_averaging < 1) number_of_steps_for_stress_averaging = 1;
369  mVectorOfLastStresses.resize(number_of_steps_for_stress_averaging);
370  KRATOS_INFO("DEM") << " 'number_of_steps_for_stress_averaging' is "<< number_of_steps_for_stress_averaging << std::endl;
371  }
372 
373  length_of_vector = mVectorOfLastStresses.size();
374 
375  if(length_of_vector > 1) {
376  for(int i=1; i<length_of_vector; i++) {
378  }
379  }
380  mVectorOfLastStresses[length_of_vector-1] = last_reaction;
381 
382  double average = 0.0;
383  for(int i=0; i<length_of_vector; i++) {
384  average += mVectorOfLastStresses[i];
385  }
386  average /= (double) length_of_vector;
387  return average;
388 
389  KRATOS_CATCH("");
390 }
391 
392 void IsTimeToApplyCM(){
393  const double current_time = mrFemModelPart.GetProcessInfo()[TIME];
394  mApplyCM = false;
395 
396  if(current_time >= mStartTime) {
397  if (mAlternateAxisLoading == true) {
398  const unsigned int step = mrFemModelPart.GetProcessInfo()[STEP];
399  if(step == mZCounter){
400  mApplyCM = true;
401  mZCounter += 3;
402  }
403  } else {
404  mApplyCM = true;
405  }
406  }
407 }
408 
409 double CalculateReactionStress() {
410  // DEM variables
412  // FEM variables
413  const ProcessInfo& CurrentProcessInfo = mrFemModelPart.GetProcessInfo();
414  int NElems = static_cast<int>(mrFemModelPart.Elements().size());
415  ModelPart::ElementsContainerType::iterator elem_begin = mrFemModelPart.ElementsBegin();
416 
417  // Calculate face_area
418  double face_area = 0.0;
419  // DEM modelpart
420  #pragma omp parallel for reduction(+:face_area)
421  for (int i = 0; i < (int)rElements.size(); i++) {
422  ModelPart::ElementsContainerType::ptr_iterator ptr_itElem = rElements.ptr_begin() + i;
423  Element* p_element = ptr_itElem->get();
424  SphericContinuumParticle* pDemElem = dynamic_cast<SphericContinuumParticle*>(p_element);
425  const double radius = pDemElem->GetRadius();
426  face_area += Globals::Pi*radius*radius;
427  }
428  // FEM modelpart
429  #pragma omp parallel for reduction(+:face_area)
430  for(int i = 0; i < NElems; i++) {
431  ModelPart::ElementsContainerType::iterator itElem = elem_begin + i;
432  face_area += itElem->GetGeometry().Area();
433  }
434 
435  // Calculate ReactionStress
436  double face_reaction = 0.0;
437  // DEM modelpart
438  #pragma omp parallel for reduction(+:face_reaction)
439  for (int i = 0; i < (int)rElements.size(); i++) {
440  ModelPart::ElementsContainerType::ptr_iterator ptr_itElem = rElements.ptr_begin() + i;
441  Element* p_element = ptr_itElem->get();
442  SphericContinuumParticle* pDemElem = dynamic_cast<SphericContinuumParticle*>(p_element);
443  BoundedMatrix<double, 3, 3> stress_tensor = ZeroMatrix(3,3);
444  noalias(stress_tensor) = (*(pDemElem->mSymmStressTensor));
445  const double radius = pDemElem->GetRadius();
446  face_reaction += stress_tensor(2,2) * Globals::Pi*radius*radius;
447  }
448  // FEM modelpart
449  #pragma omp parallel for reduction(+:face_reaction)
450  for(int i = 0; i < NElems; i++)
451  {
452  ModelPart::ElementsContainerType::iterator itElem = elem_begin + i;
453  Element::GeometryType& rGeom = itElem->GetGeometry();
454  GeometryData::IntegrationMethod MyIntegrationMethod = itElem->GetIntegrationMethod();
455  const Element::GeometryType::IntegrationPointsArrayType& IntegrationPoints = rGeom.IntegrationPoints(MyIntegrationMethod);
456  unsigned int NumGPoints = IntegrationPoints.size();
457  std::vector<Vector> stress_vector(NumGPoints);
458  itElem->CalculateOnIntegrationPoints( CAUCHY_STRESS_VECTOR, stress_vector, CurrentProcessInfo );
459  const double area_over_gp = rGeom.Area()/NumGPoints;
460  // Loop through GaussPoints
461  for ( unsigned int GPoint = 0; GPoint < NumGPoints; GPoint++ )
462  {
463  face_reaction += stress_vector[GPoint][2] * area_over_gp;
464  }
465  }
466 
467  double reaction_stress;
468  if (std::abs(face_area) > 1.0e-12) {
469  reaction_stress = face_reaction / face_area;
470  } else {
471  reaction_stress = 0.0;
472  }
473 
474  return reaction_stress;
475 }
476 
477 double EstimateStiffness(const double& rReactionStress, const double& rDeltaTime) {
478  double K_estimated = mStiffness;
479  if(std::abs(mVelocity) > 1.0e-12 && std::abs(rReactionStress-mReactionStressOld) > mStressIncrementTolerance) {
480  K_estimated = std::abs((rReactionStress-mReactionStressOld)/(mVelocity * rDeltaTime));
481  }
482  return K_estimated;
483 }
484 
488 
489 
493 
494 
498 
501 
502 
504 
505 }; // Class ControlModuleFemDem2DUtilities
506 
507 } // namespace Python.
508 
509 #endif // KRATOS_CONTROL_MODULE_FEM_DEM_2D_UTILITIES
MeshType & LocalMesh()
Returns the reference to the mesh storing all local entities.
Definition: communicator.cpp:245
Definition: control_module_fem_dem_2d_utilities.hpp:51
double mStiffness
Definition: control_module_fem_dem_2d_utilities.hpp:307
bool mApplyCM
Definition: control_module_fem_dem_2d_utilities.hpp:313
KRATOS_CLASS_POINTER_DEFINITION(ControlModuleFemDem2DUtilities)
double mStressAveragingTime
Definition: control_module_fem_dem_2d_utilities.hpp:310
virtual std::string Info() const
Turn back information as a stemplate<class T, std::size_t dim> tring.
Definition: control_module_fem_dem_2d_utilities.hpp:269
unsigned int mZCounter
Definition: control_module_fem_dem_2d_utilities.hpp:312
unsigned int mTargetStressTableId
Definition: control_module_fem_dem_2d_utilities.hpp:299
double mVelocityFactor
Definition: control_module_fem_dem_2d_utilities.hpp:302
ControlModuleFemDem2DUtilities(ModelPart &rFemModelPart, ModelPart &rDemModelPart, Parameters &rParameters)
Default constructor.
Definition: control_module_fem_dem_2d_utilities.hpp:61
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: control_module_fem_dem_2d_utilities.hpp:282
std::vector< double > mVectorOfLastStresses
Definition: control_module_fem_dem_2d_utilities.hpp:309
ModelPart & mrFemModelPart
Definition: control_module_fem_dem_2d_utilities.hpp:297
double mReactionStressOld
Definition: control_module_fem_dem_2d_utilities.hpp:305
double mStressIncrementTolerance
Definition: control_module_fem_dem_2d_utilities.hpp:306
double mStartTime
Definition: control_module_fem_dem_2d_utilities.hpp:304
void ExecuteFinalizeSolutionStep()
Definition: control_module_fem_dem_2d_utilities.hpp:241
void ExecuteInitialize()
Definition: control_module_fem_dem_2d_utilities.hpp:140
double mCompressionLength
Definition: control_module_fem_dem_2d_utilities.hpp:303
virtual ~ControlModuleFemDem2DUtilities()
Destructor.
Definition: control_module_fem_dem_2d_utilities.hpp:134
void ExecuteInitializeSolutionStep()
Definition: control_module_fem_dem_2d_utilities.hpp:152
Table< double, double > TableType
Defining a table with double argument and result type as table type.
Definition: control_module_fem_dem_2d_utilities.hpp:57
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: control_module_fem_dem_2d_utilities.hpp:276
ModelPart & mrDemModelPart
Definition: control_module_fem_dem_2d_utilities.hpp:298
double mLimitVelocity
Definition: control_module_fem_dem_2d_utilities.hpp:301
bool mAlternateAxisLoading
Definition: control_module_fem_dem_2d_utilities.hpp:311
double mVelocity
Definition: control_module_fem_dem_2d_utilities.hpp:300
bool mUpdateStiffness
Definition: control_module_fem_dem_2d_utilities.hpp:308
void SetValue(const Variable< TDataType > &rThisVariable, TDataType const &rValue)
Sets the value for a given variable.
Definition: data_value_container.h:320
TDataType & GetValue(const Variable< TDataType > &rThisVariable)
Gets the value associated with a given variable.
Definition: data_value_container.h:268
Geometry< NodeType > GeometryType
definition of the geometry type with given NodeType
Definition: element.h:83
IntegrationMethod
Definition: geometry_data.h:76
Geometry base class.
Definition: geometry.h:71
std::vector< IntegrationPointType > IntegrationPointsArrayType
Definition: geometry.h:161
const IntegrationPointsArrayType & IntegrationPoints() const
Definition: geometry.h:2284
ElementsContainerType & Elements()
Definition: mesh.h:568
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ElementIterator ElementsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1169
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: model_part.h:168
Communicator & GetCommunicator()
Definition: model_part.h:1821
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
TableType::Pointer pGetTable(IndexType TableId)
Definition: model_part.h:595
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
double GetDouble() const
This method returns the double contained in the current Parameter.
Definition: kratos_parameters.cpp:657
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
void ValidateAndAssignDefaults(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing match the form prescribed by th...
Definition: kratos_parameters.cpp:1306
bool GetBool() const
This method returns the boolean contained in the current Parameter.
Definition: kratos_parameters.cpp:675
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Definition: table.h:435
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_INFO(label)
Definition: logger.h:250
constexpr double Pi
Definition: global_variables.h:25
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
TABLE_NUMBER_ANGULAR_VELOCITY TABLE_NUMBER_MOMENT I33 BEAM_INERTIA_ROT_UNIT_LENGHT_Y KRATOS_DEFINE_APPLICATION_VARIABLE(DEM_APPLICATION, double, BEAM_INERTIA_ROT_UNIT_LENGHT_Z) typedef std double
Definition: DEM_application_variables.h:182
ProcessInfo
Definition: edgebased_PureConvection.py:116
int step
Definition: face_heat.py:88
delta_time
Definition: generate_frictional_mortar_condition.py:130
float radius
Definition: mesh_to_mdpa_converter.py:18
integer i
Definition: TensorModule.f:17