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.
mesh_rotation_utility.h
Go to the documentation of this file.
1 #if !defined(KRATOS_MESH_ROTATION_UTILITY)
2 #define KRATOS_MESH_ROTATION_UTILITY
3 
4 // /* External includes */
5 #ifdef _OPENMP
6 #include <omp.h>
7 #endif
8 
9 // Project includes
10 #include "includes/model_part.h"
11 #include "utilities/openmp_utils.h"
13 
14 namespace Kratos
15 {
17 {
18 
19 public:
20 
22 
23 MeshRotationUtility(Parameters & r_parameters): mpStationaryModelPart(NULL)
24 {
25  mOmega = r_parameters["frame_of_reference"]["angular_velocity_magnitude"].GetDouble();
26  mAInit = r_parameters["frame_of_reference"]["frame_rotation_axis_initial_point"].GetVector();
27  mAFinal = r_parameters["frame_of_reference"]["frame_rotation_axis_final_point"].GetVector();
28  mAxisVersor = CalculateNormalized(mAFinal - mAInit);
29 
30  // Constructing auxiliary Rodrigues matrices
31  mI = identity_matrix<double>(3);
32 
33  for (int i = 0; i < 3; ++i){
34  for (int j = 0; j < 3; ++j){
35  mUU(i, j) = mAxisVersor[i] * mAxisVersor[j];
36  }
37  }
38 
39  mUx = ZeroMatrix(3, 3);
40  mUx(0, 1) = - mAxisVersor[2];
41  mUx(0, 2) = mAxisVersor[1];
42  mUx(1, 0) = mAxisVersor[2];
43  mUx(1, 2) = - mAxisVersor[0];
44  mUx(2, 0) = - mAxisVersor[1];
45  mUx(2, 1) = mAxisVersor[0];
46 }
47 
49 
50 void RotateMesh(ModelPart& r_model_part, double time)
51 {
52  CalculateRodriguesMatrices(time);
53 
54  const int nnodes = r_model_part.Nodes().size();
55 
56  if (nnodes > 0){
57  auto it_begin = r_model_part.NodesBegin();
60 
61  #pragma omp parallel for private(P0, P)
62  for (int i = 0; i < nnodes; ++i){
63  auto it = it_begin + i;
64  RotateNode(*(it.base()), P0, P);
65  array_1d<double, 3>& displacement = it->FastGetSolutionStepValue(DISPLACEMENT);
66  noalias(displacement) = P - P0;
67  array_1d<double, 3>& velocity = it->FastGetSolutionStepValue(MESH_VELOCITY);
68  noalias(velocity) = prod(mRp, P0 - mAInit);
69  }
70  }
71 }
72 
73 void RotateDEMMesh(ModelPart& r_model_part, double time)
74 {
75  CalculateRodriguesMatrices(time);
76  const int nnodes = r_model_part.Nodes().size();
77  if (nnodes > 0){
78  auto it_begin = r_model_part.NodesBegin();
81 
82  #pragma omp parallel for private(P0, P)
83  for (int i = 0; i < nnodes; ++i){
84  auto it = it_begin + i;
85  RotateNode(*(it.base()), P0, P);
86  array_1d<double, 3>& displacement = it->FastGetSolutionStepValue(DISPLACEMENT);
87  noalias(displacement) = P - P0;
88  it->Fix(DISPLACEMENT_X);
89  it->Fix(DISPLACEMENT_Y);
90  it->Fix(DISPLACEMENT_Z);
91  array_1d<double, 3>& velocity = it->FastGetSolutionStepValue(VELOCITY);
92  noalias(velocity) = prod(mRp, P0 - mAInit);
93  it->Fix(VELOCITY_X);
94  it->Fix(VELOCITY_Y);
95  it->Fix(VELOCITY_Z);
96  }
97  }
98 }
99 
100 void SetStationaryField(ModelPart& r_model_part, const double time)
101 {
102  mpStationaryModelPart = &r_model_part;
103  mStationaryTime = time;
104  const int nnodes = r_model_part.Nodes().size();
105  mStationaryVelocities.resize(nnodes);
106 
107  if (nnodes > 0){
108  auto it_begin = r_model_part.NodesBegin();
109 
110  #pragma omp parallel for
111  for (int i = 0; i < nnodes; ++i){
112  auto it = it_begin + i;
113  noalias(mStationaryVelocities[i]) = it->FastGetSolutionStepValue(VELOCITY);
114  }
115  }
116 }
117 
118 void RotateFluidVelocities(const double time)
119 {
120  CalculateRodriguesMatrices(time, mStationaryTime);
121 
122  const int nnodes = mpStationaryModelPart->Nodes().size();
123 
124  if (nnodes > 0){
125  auto it_begin = mpStationaryModelPart->NodesBegin();
126 
127  #pragma omp parallel for
128  for (int i = 0; i < nnodes; ++i){
129  auto it = it_begin + i;
130  array_1d<double, 3>& velocity = it->FastGetSolutionStepValue(VELOCITY);
131  RotateVector(mStationaryVelocities[i], velocity);
132  }
133  }
134 }
135 
136 private:
137 
138 void CalculateRodriguesMatrices(const double time, const double initial_time=0.0)
139 {
140  const double delta_time = time - initial_time;
141  double sin_theta = std::sin(delta_time * mOmega);
142  double cos_theta = std::cos(delta_time * mOmega);
143 
144  // Rotation matrix
145  noalias(mR) = cos_theta * mI + sin_theta * mUx + (1.0 - cos_theta) * mUU;
146 
147  // Rotation matrix derivative (derivative of R with respect to time)
148  noalias(mRp) = - mOmega * sin_theta * mI + mOmega * cos_theta * mUx + mOmega * sin_theta * mUU;
149 }
150 
151 void RotateNode(Kratos::Node::Pointer p_node, array_1d<double, 3>& P0, array_1d<double, 3>& P)
152 {
153  P0[0] = p_node->X0();
154  P0[1] = p_node->Y0();
155  P0[2] = p_node->Z0();
156  noalias(P) = mAInit + prod(mR, P0 - mAInit);
157  p_node->X() = P[0];
158  p_node->Y() = P[1];
159  p_node->Z() = P[2];
160 }
161 
162 void RotateVector(const array_1d<double, 3>& initial_vector, array_1d<double, 3>& vector)
163 {
164  noalias(vector) = mAInit + prod(mR, initial_vector - mAInit);
165 }
166 
167 array_1d<double, 3> CalculateNormalized(array_1d<double, 3>&& vector)
168 {
169  const double norm = norm_2(vector);
170 
171  if (norm > 0.0){
172  vector *= 1.0 / norm;
173  }
174 
175  return vector;
176 }
177 
178 double mOmega;
179 double mStationaryTime;
180 array_1d<double, 3> mAInit;
181 array_1d<double, 3> mAFinal;
182 array_1d<double, 3> mAxisVersor;
183 BoundedMatrix<double, 3, 3> mI;
184 BoundedMatrix<double, 3, 3> mUU;
185 BoundedMatrix<double, 3, 3> mUx;
186 BoundedMatrix<double, 3, 3> mR;
187 BoundedMatrix<double, 3, 3> mRp;
188 std::vector<array_1d<double, 3> > mStationaryVelocities;
189 ModelPart* mpStationaryModelPart;
190 
191 //**************************************************************************************************************************************************
192 //**************************************************************************************************************************************************
193 
194 }; // Class MeshRotationUtility
195 
196 } // namespace Kratos.
197 
198 #endif // KRATOS_MESH_ROTATION_UTILITY defined
199 
Definition: mesh_rotation_utility.h:17
void RotateMesh(ModelPart &r_model_part, double time)
Definition: mesh_rotation_utility.h:50
virtual ~MeshRotationUtility()
Definition: mesh_rotation_utility.h:48
MeshRotationUtility(Parameters &r_parameters)
Definition: mesh_rotation_utility.h:23
void SetStationaryField(ModelPart &r_model_part, const double time)
Definition: mesh_rotation_utility.h:100
KRATOS_CLASS_POINTER_DEFINITION(MeshRotationUtility)
void RotateFluidVelocities(const double time)
Definition: mesh_rotation_utility.h:118
void RotateDEMMesh(ModelPart &r_model_part, double time)
Definition: mesh_rotation_utility.h:73
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
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
Vector GetVector() const
This method returns the vector contained in the current Parameter.
Definition: kratos_parameters.cpp:707
Kratos::ModelPart ModelPart
Definition: kratos_wrapper.h:31
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
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
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
float velocity
Definition: PecletTest.py:54
initial_time
Definition: dam_analysis.py:4
time
Definition: face_heat.py:85
delta_time
Definition: generate_frictional_mortar_condition.py:130
int j
Definition: quadrature.py:648
int nnodes
Definition: sensitivityMatrix.py:24
integer i
Definition: TensorModule.f:17