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.
mpm_boundary_rotation_utility.h
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: Bodhinanda Chandra
11 //
12 
13 
14 #ifndef KRATOS_MPM_BOUNDARY_ROTATION_UTILITY
15 #define KRATOS_MPM_BOUNDARY_ROTATION_UTILITY
16 
17 // system includes
18 
19 // external includes
20 
21 // kratos includes
22 #include "includes/define.h"
23 #include "includes/node.h"
24 #include "containers/variable.h"
25 #include "geometries/geometry.h"
27 
28 namespace Kratos {
29 
32 
35 
39 
43 
47 
51 
52 /* A utility to rotate the local contributions of certain nodes to the system matrix,
53 which is required to apply slip conditions (roller-type support) in arbitrary directions to the boundary nodes.*/
54 template<class TLocalMatrixType, class TLocalVectorType>
55 class MPMBoundaryRotationUtility: public CoordinateTransformationUtils<TLocalMatrixType,TLocalVectorType,double> {
56 public:
59 
62 
64 
65  typedef Node NodeType;
66 
68 
72 
74 
79  const unsigned int DomainSize,
80  const unsigned int BlockSize,
81  const Variable<double>& rVariable):
82  CoordinateTransformationUtils<TLocalMatrixType,TLocalVectorType,double>(DomainSize,BlockSize,SLIP), mrFlagVariable(rVariable)
83  {}
84 
87 
90 
94 
98 
100 
105  void Rotate(
106  TLocalMatrixType& rLocalMatrix,
107  TLocalVectorType& rLocalVector,
108  GeometryType& rGeometry) const override
109  {
110  if (this->GetBlockSize() == this->GetDomainSize()) // irreducible case
111  {
112  if (this->GetDomainSize() == 2) this->template RotateAuxPure<2>(rLocalMatrix,rLocalVector,rGeometry);
113  else if (this->GetDomainSize() == 3) this->template RotateAuxPure<3>(rLocalMatrix,rLocalVector,rGeometry);
114  }
115  else // mixed formulation case
116  {
117  if (this->GetDomainSize() == 2) this->template RotateAux<2,3>(rLocalMatrix,rLocalVector,rGeometry);
118  else if (this->GetDomainSize() == 3) this->template RotateAux<3,4>(rLocalMatrix,rLocalVector,rGeometry);
119  }
120 
121  }
122 
124  void RotateRHS(
125  TLocalVectorType& rLocalVector,
126  GeometryType& rGeometry) const
127  {
128  this->Rotate(rLocalVector,rGeometry);
129  }
130 
132 
137  void ApplySlipCondition(TLocalMatrixType& rLocalMatrix,
138  TLocalVectorType& rLocalVector,
139  GeometryType& rGeometry) const override
140  {
141  const unsigned int LocalSize = rLocalVector.size();
142 
143  if (LocalSize > 0)
144  {
145  for(unsigned int itNode = 0; itNode < rGeometry.PointsNumber(); ++itNode)
146  {
147  if(this->IsSlip(rGeometry[itNode]) )
148  {
149  // We fix the first displacement dof (normal component) for each rotated block
150  unsigned int j = itNode * this->GetBlockSize();
151 
152  // Get the displacement of the boundary mesh, this does not assume that the mesh is moving.
153  // If the mesh is moving, need to consider the displacement of the moving mesh into account.
154  const array_1d<double,3> & displacement = rGeometry[itNode].FastGetSolutionStepValue(DISPLACEMENT);
155 
156  // Get Normal Vector of the boundary
157  array_1d<double,3> rN = rGeometry[itNode].FastGetSolutionStepValue(NORMAL);
158  this->Normalize(rN);
159 
160  // Zero out row/column corresponding to normal displacement DoF except diagonal term (set to 1)
161  // Applied IFF the local matrix passed is not empty [otherwise does nothing -- RHS only case]
162  if (rLocalMatrix.size1() != 0) {
163  for( unsigned int i = 0; i < LocalSize; ++i)
164  {
165  rLocalMatrix(i,j) = 0.0;
166  rLocalMatrix(j,i) = 0.0;
167  }
168  rLocalMatrix(j, j) = 1.0; // set diagonal term to 1.0
169  }
170 
171  // Set value of normal displacement at node directly to the normal displacement of the boundary mesh
172  rLocalVector[j] = inner_prod(rN,displacement);
173  }
174  }
175  }
176  }
177 
179  void ApplySlipCondition(TLocalVectorType& rLocalVector,
180  GeometryType& rGeometry) const override
181  {
182  // creates an empty dummy matrix to pass into the 'full' ApplySlipCondition -- this dummy matrix is
183  // ignored, effectively only updating the RHS
184  TLocalMatrixType dummyMatrix;
185  this->ApplySlipCondition(dummyMatrix, rLocalVector, rGeometry);
186  }
187 
188  // An extra function to distinguish the application of slip in element considering penalty imposition
189  void ElementApplySlipCondition(TLocalMatrixType& rLocalMatrix,
190  TLocalVectorType& rLocalVector,
191  GeometryType& rGeometry) const
192  {
193  // If it is not a penalty element, do as standard
194  // Otherwise, if it is a penalty element, don't do anything
195  if (!this->IsPenalty(rGeometry))
196  {
197  this->ApplySlipCondition(rLocalMatrix, rLocalVector, rGeometry);
198  }
199  }
200 
201  // An extra function to distinguish the application of slip in element considering penalty imposition (RHS Version)
202  void ElementApplySlipCondition(TLocalVectorType& rLocalVector,
203  GeometryType& rGeometry) const
204  {
205  // If it is not a penalty element, do as standard
206  // Otherwise, if it is a penalty element, don't do anything
207  if (!this->IsPenalty(rGeometry))
208  {
209  this->ApplySlipCondition(rLocalVector, rGeometry);
210  }
211  }
212 
213  // An extra function to distinguish the application of slip in condition considering penalty imposition
214  void ConditionApplySlipCondition(TLocalMatrixType& rLocalMatrix,
215  TLocalVectorType& rLocalVector,
216  GeometryType& rGeometry) const
217  {
218  // If it is not a penalty condition, do as standard
219  if (!this->IsPenalty(rGeometry))
220  {
221  this->ApplySlipCondition(rLocalMatrix, rLocalVector, rGeometry);
222  }
223  // Otherwise, do the following modification
224  else
225  {
226  const unsigned int LocalSize = rLocalVector.size();
227 
228  if (LocalSize > 0)
229  {
230  const unsigned int block_size = this->GetBlockSize();
231  TLocalMatrixType temp_matrix = ZeroMatrix(rLocalMatrix.size1(),rLocalMatrix.size2());
232  for(unsigned int itNode = 0; itNode < rGeometry.PointsNumber(); ++itNode)
233  {
234  if(this->IsSlip(rGeometry[itNode]) )
235  {
236  // We fix the first displacement dof (normal component) for each rotated block
237  unsigned int j = itNode * block_size;
238 
239  // Copy all normal value in LHS to the temp_matrix
240  // [ does nothing for dummy rLocalMatrix (size1() == 0) -- RHS only case ]
241  for (unsigned int i = j; i < rLocalMatrix.size1(); i+= block_size)
242  {
243  temp_matrix(i,j) = rLocalMatrix(i,j);
244  temp_matrix(j,i) = rLocalMatrix(j,i);
245  }
246 
247  // Remove all other value in RHS than the normal component
248  for(unsigned int i = j; i < (j + block_size); ++i)
249  {
250  if (i!=j) rLocalVector[i] = 0.0;
251  }
252  }
253  }
254  // All entries in penalty matrix zeroed out except for normal component
255  // [ no effect in case of empty dummy rLocalMatrix ]
256  rLocalMatrix = temp_matrix;
257  }
258  }
259  }
260 
261  // An extra function to distinguish the application of slip in condition considering penalty imposition (RHS Version)
262  void ConditionApplySlipCondition(TLocalVectorType& rLocalVector,
263  GeometryType& rGeometry) const
264  {
265  // creates an empty dummy matrix to pass into the 'full' ConditionApplySlipCondition -- this dummy matrix is
266  // ignored, effectively only updating the RHS
267  TLocalMatrixType dummyMatrix;
268  this->ConditionApplySlipCondition(dummyMatrix, rLocalVector, rGeometry);
269  }
270 
271  // Checking whether it is normal element or penalty element
272  bool IsPenalty(GeometryType& rGeometry) const
273  {
274  bool is_penalty = false;
275  for(unsigned int itNode = 0; itNode < rGeometry.PointsNumber(); ++itNode)
276  {
277  if(this->IsSlip(rGeometry[itNode]) )
278  {
279  const double identifier = rGeometry[itNode].FastGetSolutionStepValue(mrFlagVariable);
280  const double tolerance = 1.e-6;
281  if (identifier > 1.00 + tolerance)
282  {
283  is_penalty = true;
284  break;
285  }
286  }
287  }
288 
289  return is_penalty;
290  }
291 
293  virtual void RotateDisplacements(ModelPart& rModelPart) const
294  {
295  this->RotateVelocities(rModelPart);
296  }
297 
300  void RotateVelocities(ModelPart& rModelPart) const override
301  {
302  TLocalVectorType displacement(this->GetDomainSize());
303  TLocalVectorType Tmp(this->GetDomainSize());
304 
305  ModelPart::NodeIterator it_begin = rModelPart.NodesBegin();
306  #pragma omp parallel for firstprivate(displacement,Tmp)
307  for(int iii=0; iii<static_cast<int>(rModelPart.Nodes().size()); iii++)
308  {
309  ModelPart::NodeIterator itNode = it_begin+iii;
310  if( this->IsSlip(*itNode) )
311  {
312  //this->RotationOperator<TLocalMatrixType>(Rotation,);
313  if(this->GetDomainSize() == 3)
314  {
316  this->LocalRotationOperatorPure(rRot,*itNode);
317 
318  array_1d<double,3>& rDisplacement = itNode->FastGetSolutionStepValue(DISPLACEMENT);
319  for(unsigned int i = 0; i < 3; i++) displacement[i] = rDisplacement[i];
320  noalias(Tmp) = prod(rRot,displacement);
321  for(unsigned int i = 0; i < 3; i++) rDisplacement[i] = Tmp[i];
322  }
323  else
324  {
326  this->LocalRotationOperatorPure(rRot,*itNode);
327 
328  array_1d<double,3>& rDisplacement = itNode->FastGetSolutionStepValue(DISPLACEMENT);
329  for(unsigned int i = 0; i < 2; i++) displacement[i] = rDisplacement[i];
330  noalias(Tmp) = prod(rRot,displacement);
331  for(unsigned int i = 0; i < 2; i++) rDisplacement[i] = Tmp[i];
332  }
333  }
334  }
335  }
336 
338  virtual void RecoverDisplacements(ModelPart& rModelPart) const
339  {
340  this->RecoverVelocities(rModelPart);
341  }
342 
345  void RecoverVelocities(ModelPart& rModelPart) const override
346  {
347  TLocalVectorType displacement(this->GetDomainSize());
348  TLocalVectorType Tmp(this->GetDomainSize());
349 
350  ModelPart::NodeIterator it_begin = rModelPart.NodesBegin();
351  #pragma omp parallel for firstprivate(displacement,Tmp)
352  for(int iii=0; iii<static_cast<int>(rModelPart.Nodes().size()); iii++)
353  {
354  ModelPart::NodeIterator itNode = it_begin+iii;
355  if( this->IsSlip(*itNode) )
356  {
357  if(this->GetDomainSize() == 3)
358  {
360  this->LocalRotationOperatorPure(rRot,*itNode);
361 
362  array_1d<double,3>& rDisplacement = itNode->FastGetSolutionStepValue(DISPLACEMENT);
363  for(unsigned int i = 0; i < 3; i++) displacement[i] = rDisplacement[i];
364  noalias(Tmp) = prod(trans(rRot),displacement);
365  for(unsigned int i = 0; i < 3; i++) rDisplacement[i] = Tmp[i];
366  }
367  else
368  {
370  this->LocalRotationOperatorPure(rRot,*itNode);
371 
372  array_1d<double,3>& rDisplacement = itNode->FastGetSolutionStepValue(DISPLACEMENT);
373  for(unsigned int i = 0; i < 2; i++) displacement[i] = rDisplacement[i];
374  noalias(Tmp) = prod(trans(rRot),displacement);
375  for(unsigned int i = 0; i < 2; i++) rDisplacement[i] = Tmp[i];
376  }
377  }
378  }
379  }
380 
382  {
383  TLocalVectorType global_reaction(this->GetDomainSize());
384  TLocalVectorType local_reaction(this->GetDomainSize());
385  TLocalVectorType reaction(this->GetDomainSize());
386 
387  ModelPart::NodeIterator it_begin = rModelPart.NodesBegin();
388  #pragma omp parallel for firstprivate(reaction,local_reaction,global_reaction)
389  for(int iii=0; iii<static_cast<int>(rModelPart.Nodes().size()); iii++)
390  {
391  ModelPart::NodeIterator itNode = it_begin+iii;
392  const double nodal_mass = itNode->FastGetSolutionStepValue(NODAL_MASS, 0);
393 
394  if( this->IsSlip(*itNode) && nodal_mass > std::numeric_limits<double>::epsilon())
395  {
396  if(this->GetDomainSize() == 3)
397  {
399  this->LocalRotationOperatorPure(rRot,*itNode);
400 
401  array_1d<double,3>& rReaction = itNode->FastGetSolutionStepValue(REACTION);
402  // rotate reaction to local frame
403  for(unsigned int i = 0; i < 3; i++) reaction[i] = rReaction[i];
404  noalias(local_reaction) = prod(rRot,reaction);
405 
406  // remove tangential directions
407  local_reaction[1]=0.0;
408  local_reaction[2]=0.0;
409  // rotate reaction to global frame
410  noalias(global_reaction) = prod(trans(rRot),local_reaction);
411  // save values
412  for(unsigned int i = 0; i < 3; i++) rReaction[i] = global_reaction[i];
413  }
414  else
415  {
417  this->LocalRotationOperatorPure(rRot,*itNode);
418 
419  array_1d<double,3>& rReaction = itNode->FastGetSolutionStepValue(REACTION);
420  // rotate reaction to local frame
421  for(unsigned int i = 0; i < 2; i++) reaction[i] = rReaction[i];
422  noalias(local_reaction) = prod(rRot,reaction);
423 
424  // remove tangential direction
425  local_reaction[1]=0.0;
426  // rotate reaction to global frame
427  noalias(global_reaction) = prod(trans(rRot),local_reaction);
428  // save values
429  for(unsigned int i = 0; i < 2; i++) rReaction[i] = global_reaction[i];
430  }
431  }
432  }
433  }
437 
441 
445 
447  std::string Info() const override
448  {
449  std::stringstream buffer;
450  buffer << "MPMBoundaryRotationUtility";
451  return buffer.str();
452  }
453 
455  void PrintInfo(std::ostream& rOStream) const override
456  {
457  rOStream << "MPMBoundaryRotationUtility";
458  }
459 
461  void PrintData(std::ostream& rOStream) const override {}
462 
466 
468 
469 protected:
472 
476 
480 
484 
488 
492 
496 
498 
499 private:
502 
503  const Variable<double>& mrFlagVariable;
504 
508 
512 
516 
520 
524 
528 
530 };
531 
533 
536 
540 
542 template<class TLocalMatrixType, class TLocalVectorType>
543 inline std::istream& operator >>(std::istream& rIStream,
545  return rIStream;
546 }
547 
549 template<class TLocalMatrixType, class TLocalVectorType>
550 inline std::ostream& operator <<(std::ostream& rOStream,
552  rThis.PrintInfo(rOStream);
553  rOStream << std::endl;
554  rThis.PrintData(rOStream);
555 
556  return rOStream;
557 }
558 
560 
562 
563 }
564 
565 #endif // KRATOS_MPM_BOUNDARY_ROTATION_UTILITY
Definition: coordinate_transformation_utilities.h:57
double Normalize(TVectorType &rThis) const
Normalize a vector.
Definition: coordinate_transformation_utilities.h:994
bool IsSlip(const Node &rNode) const
Definition: coordinate_transformation_utilities.h:983
unsigned int GetBlockSize() const
Definition: coordinate_transformation_utilities.h:1014
void LocalRotationOperatorPure(BoundedMatrix< double, 3, 3 > &rRot, const GeometryType::PointType &rThisPoint) const
Definition: coordinate_transformation_utilities.h:138
unsigned int GetDomainSize() const
Definition: coordinate_transformation_utilities.h:1009
Geometry base class.
Definition: geometry.h:71
SizeType PointsNumber() const
Definition: geometry.h:528
Definition: amatrix_interface.h:41
Definition: mpm_boundary_rotation_utility.h:55
void Rotate(TLocalMatrixType &rLocalMatrix, TLocalVectorType &rLocalVector, GeometryType &rGeometry) const override
Rotate the local system contributions so that they are oriented with each node's normal.
Definition: mpm_boundary_rotation_utility.h:105
void ApplySlipCondition(TLocalMatrixType &rLocalMatrix, TLocalVectorType &rLocalVector, GeometryType &rGeometry) const override
Apply roler type boundary conditions to the rotated local contributions.
Definition: mpm_boundary_rotation_utility.h:137
void ConditionApplySlipCondition(TLocalVectorType &rLocalVector, GeometryType &rGeometry) const
Definition: mpm_boundary_rotation_utility.h:262
virtual void RotateDisplacements(ModelPart &rModelPart) const
Same functionalities as RotateVelocities, just to have a clear function naming.
Definition: mpm_boundary_rotation_utility.h:293
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: mpm_boundary_rotation_utility.h:461
MPMBoundaryRotationUtility & operator=(MPMBoundaryRotationUtility const &rOther)
Assignment operator.
Definition: mpm_boundary_rotation_utility.h:89
void ElementApplySlipCondition(TLocalMatrixType &rLocalMatrix, TLocalVectorType &rLocalVector, GeometryType &rGeometry) const
Definition: mpm_boundary_rotation_utility.h:189
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: mpm_boundary_rotation_utility.h:455
Node NodeType
Definition: mpm_boundary_rotation_utility.h:65
KRATOS_CLASS_POINTER_DEFINITION(MPMBoundaryRotationUtility)
Pointer definition of MPMBoundaryRotationUtility.
void CalculateReactionForces(ModelPart &rModelPart)
Definition: mpm_boundary_rotation_utility.h:381
std::string Info() const override
Turn back information as a string.
Definition: mpm_boundary_rotation_utility.h:447
void RotateVelocities(ModelPart &rModelPart) const override
Definition: mpm_boundary_rotation_utility.h:300
bool IsPenalty(GeometryType &rGeometry) const
Definition: mpm_boundary_rotation_utility.h:272
void ApplySlipCondition(TLocalVectorType &rLocalVector, GeometryType &rGeometry) const override
RHS only version of ApplySlipCondition.
Definition: mpm_boundary_rotation_utility.h:179
void RotateRHS(TLocalVectorType &rLocalVector, GeometryType &rGeometry) const
RHS only version of Rotate.
Definition: mpm_boundary_rotation_utility.h:124
MPMBoundaryRotationUtility(const unsigned int DomainSize, const unsigned int BlockSize, const Variable< double > &rVariable)
Constructor.
Definition: mpm_boundary_rotation_utility.h:78
void ConditionApplySlipCondition(TLocalMatrixType &rLocalMatrix, TLocalVectorType &rLocalVector, GeometryType &rGeometry) const
Definition: mpm_boundary_rotation_utility.h:214
virtual void RecoverDisplacements(ModelPart &rModelPart) const
Same functionalities as RecoverVelocities, just to have a clear function naming.
Definition: mpm_boundary_rotation_utility.h:338
void RecoverVelocities(ModelPart &rModelPart) const override
Definition: mpm_boundary_rotation_utility.h:345
Geometry< Node > GeometryType
Definition: mpm_boundary_rotation_utility.h:67
void ElementApplySlipCondition(TLocalVectorType &rLocalVector, GeometryType &rGeometry) const
Definition: mpm_boundary_rotation_utility.h:202
~MPMBoundaryRotationUtility() override
Destructor.
Definition: mpm_boundary_rotation_utility.h:86
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
MeshType::NodeIterator NodeIterator
Definition: model_part.h:134
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class defines the node.
Definition: node.h:65
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
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
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
int block_size
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:16
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17