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.
AuxiliaryFunctions.h
Go to the documentation of this file.
1 /*
2  * File: AuxiliaryFunctions.h
3  * Author: msantasusana
4  *
5  * Created on 21 de mayo de 2012, 19:40
6  */
7 
8 #ifndef _DEM_AUXILIARY_FUNCTIONS_H
9 #define _DEM_AUXILIARY_FUNCTIONS_H
10 
11 #include <cmath>
12 #include "containers/array_1d.h"
13 #include "includes/serializer.h"
14 #include "includes/model_part.h"
16 
17 namespace Kratos {
18 
19  namespace AuxiliaryFunctions {
20 
21  static inline void CalculateAlphaFactor3D(const int n_neighbours, const double external_sphere_area, const double total_equiv_area , double& alpha) {
22 
23  double external_polyhedron_area = 0.0;
24 
25  switch (n_neighbours) {
26 
27  case 4:
28  external_polyhedron_area = 3.30797*external_sphere_area;
29  break;
30 
31  case 5:
32  external_polyhedron_area = 2.60892*external_sphere_area;
33  break;
34 
35  case 6:
36  external_polyhedron_area = 1.90986*external_sphere_area;
37  break;
38 
39  case 7:
40  external_polyhedron_area = 1.78192*external_sphere_area;
41  break;
42 
43  case 8:
44  external_polyhedron_area = 1.65399*external_sphere_area;
45  break;
46 
47  case 9:
48  external_polyhedron_area = 1.57175*external_sphere_area;
49  break;
50 
51  case 10:
52  external_polyhedron_area = 1.48951*external_sphere_area;
53  break;
54 
55  case 11:
56  external_polyhedron_area = 1.40727*external_sphere_area;
57  break;
58 
59  case 12:
60  external_polyhedron_area = 1.32503*external_sphere_area;
61  break;
62 
63  case 13:
64  external_polyhedron_area = 1.31023*external_sphere_area;
65  break;
66 
67  case 14:
68  external_polyhedron_area = 1.29542*external_sphere_area;
69  break;
70 
71  case 15:
72  external_polyhedron_area = 1.28061*external_sphere_area;
73  break;
74 
75  case 16:
76  external_polyhedron_area = 1.26580*external_sphere_area;
77  break;
78 
79  case 17:
80  external_polyhedron_area = 1.25099*external_sphere_area;
81  break;
82 
83  case 18:
84  external_polyhedron_area = 1.23618*external_sphere_area;
85  break;
86 
87  case 19:
88  external_polyhedron_area = 1.22138*external_sphere_area;
89  break;
90 
91  case 20:
92  external_polyhedron_area = 1.20657*external_sphere_area;
93  break;
94 
95  default:
96  external_polyhedron_area = 1.15000*external_sphere_area;
97  break;
98 
99  }//switch (n_neighbours)
100 
101  alpha = external_polyhedron_area/total_equiv_area;
102 
103  }//CalculateAlphaFactor
104 
105  static inline void CalculateAlphaFactor2D(const int n_neighbours, const double external_circle_perimeter, const double total_equiv_perimeter , double& alpha) {
106 
107  double external_polygon_perimeter = 0.0;
108 
109  switch (n_neighbours) {
110 
111  case 3:
112  external_polygon_perimeter = 1.65399*external_circle_perimeter;
113  break;
114 
115  case 4:
116  external_polygon_perimeter = 1.27324*external_circle_perimeter;
117  break;
118 
119  case 5:
120  external_polygon_perimeter = 1.15633*external_circle_perimeter;
121  break;
122 
123  case 6:
124  external_polygon_perimeter = 1.10266*external_circle_perimeter;
125  break;
126 
127  case 7:
128  external_polygon_perimeter = 1.07303*external_circle_perimeter;
129  break;
130 
131  case 8:
132  external_polygon_perimeter = 1.05479*external_circle_perimeter;
133  break;
134 
135  case 9:
136  external_polygon_perimeter = 1.04270*external_circle_perimeter;
137  break;
138 
139  case 10:
140  external_polygon_perimeter = 1.03425*external_circle_perimeter;
141  break;
142 
143  case 11:
144  external_polygon_perimeter = 1.02811*external_circle_perimeter;
145  break;
146 
147  case 12:
148  external_polygon_perimeter = 1.02349*external_circle_perimeter;
149  break;
150 
151  case 13:
152  external_polygon_perimeter = 1.01993*external_circle_perimeter;
153  break;
154 
155  case 14:
156  external_polygon_perimeter = 1.01713*external_circle_perimeter;
157  break;
158 
159  default:
160  external_polygon_perimeter = 1.0*external_circle_perimeter;
161 
162  break;
163 
164  }//switch (n_neighbours)
165 
166  alpha = external_polygon_perimeter/total_equiv_perimeter;
167 
168  }//CalculateAlphaFactor
169 
170  static inline void SwitchCase(const int case_opt, bool& delta_OPTION, bool& continuum_simulation_OPTION) {
171 
172  switch (case_opt) {
173 
174  case 0:
175  delta_OPTION = false;
176  continuum_simulation_OPTION = false;
177  break;
178 
179  case 1:
180  delta_OPTION = true;
181  continuum_simulation_OPTION = false;
182  break;
183 
184  case 2:
185  delta_OPTION = true;
186  continuum_simulation_OPTION = true;
187  break;
188 
189  case 3:
190  delta_OPTION = false;
191  continuum_simulation_OPTION = true;
192  break;
193 
194  default:
195  delta_OPTION = false;
196  continuum_simulation_OPTION = false;
197  }
198  } //SwitchCase
199 
200  inline array_1d<double,3> LinearTimeIncreasingFunction(const array_1d<double,3>& external_total_applied_force, const double current_time, const double end_time)
201  {
202  array_1d<double,3> externally_applied_force_now = external_total_applied_force*current_time/end_time;
203  return externally_applied_force_now;
204 
205  }// LinearTimeIncreasingFunction
206 
207  static inline void ComputeReactionOnTopAndBottomSpheres(ModelPart& r_model_part) {
208 
210  ElementsArrayType& pElements = r_model_part.GetCommunicator().LocalMesh().Elements();
211 
212  //double Y_coord = 0.0;
213  double Z_coord = 0.0;
214  double RX_bottom = 0.0;
215  double RY_bottom = 0.0;
216  double RZ_bottom = 0.0;
217  double RX_top = 0.0;
218  double RY_top = 0.0;
219  double RZ_top = 0.0;
220  double RX_average = 0.0;
221  double RY_average = 0.0;
222  double RZ_average = 0.0;
223  double time = 0.0;
224 
225  ElementsArrayType::iterator elem_iterator_begin = pElements.ptr_begin();
226  ElementsArrayType::iterator elem_iterator_end = pElements.ptr_end();
227 
228  for (ElementsArrayType::iterator elem_iterator = elem_iterator_begin; elem_iterator != elem_iterator_end; ++elem_iterator) {
229  //Node& node = elem_iterator->GetGeometry()[0];
230  array_1d<double, 3>& reaction_force = elem_iterator->GetGeometry()[0].FastGetSolutionStepValue(FORCE_REACTION);
231  //Y_coord = elem_iterator->GetGeometry()[0].Coordinates()[1];
232  Z_coord = elem_iterator->GetGeometry()[0].Coordinates()[2];
233  //if (Y_coord < 0.15) { /////////////////////////////////// Take this correctly!!
234  //if ((Z_coord < 0.3) || (Y_coord > 0.3)) {
235  if (Z_coord < 0.25) {
236  RX_bottom += reaction_force[0];
237  RY_bottom += reaction_force[1];
238  RZ_bottom += reaction_force[2];
239  } else {
240  RX_top += reaction_force[0];
241  RY_top += reaction_force[1];
242  RZ_top += reaction_force[2];
243  }
244  } //loop over particles
245 
246  time = r_model_part.GetProcessInfo()[TIME];
247  RX_average = 0.5 * (RX_bottom - RX_top);
248  RY_average = 0.5 * (RY_bottom - RY_top);
249  RZ_average = 0.5 * (RZ_bottom - RZ_top);
250 
251  std::ofstream outputfileX("reaction_forces_X.txt", std::ios_base::out | std::ios_base::app);
252  std::ofstream outputfileZ("reaction_forces_Z.txt", std::ios_base::out | std::ios_base::app);
253  std::ofstream outputfileYZ("reaction_forces_YZ.txt", std::ios_base::out | std::ios_base::app);
254 
255  outputfileX << time << " " << RX_bottom << " " << RX_top << " " << RX_average << "\n";
256  outputfileZ << time << " " << RZ_bottom << " " << RZ_top << " " << RZ_average << "\n";
257  outputfileYZ << time << " " << RY_bottom << " " << RY_top << " " << RY_average << " " << RZ_bottom << " " << RZ_top << " " << RZ_average << "\n";
258 
259  outputfileX.close();
260  outputfileZ.close();
261  outputfileYZ.close();
262  }
263 
265  // Given a real symmetric 3x3 matrix A, compute the eigenvalues
266  const int dim= A.size1();
267  Vector Result=ZeroVector(dim);
268 
269  const double p1 = A(0,1)*A(0,1) + A(0,2)*A(0,2) + A(1,2)*A(1,2);
270  if (p1 == 0) {//A is diagonal.
271  Result[0] = A(0,0);
272  Result[1] = A(1,1);
273  Result[2] = A(2,2);
274  return Result;
275  }
276 
277  const double q = 0.333333333333333333333333 * (A(0,0) + A(1,1) + A(2,2));
278  const double p2 = (A(0,0) - q) * (A(0,0) - q) + (A(1,1) - q) * (A(1,1) - q) + (A(2,2) - q) * (A(2,2) - q) + 2.0 * p1;
279  const double p = sqrt(0.16666666666666666666666667 * p2);
280 
282  const double inv_p = 1.0/p;
283 
284  // B = (1 / p) * (A - q * I) where I is the identity matrix
285  B(0,0) = inv_p * (A(0,0) - q);
286  B(1,1) = inv_p * (A(1,1) - q);
287  B(2,2) = inv_p * (A(2,2) - q);
288  B(0,1) = inv_p * A(0,1);
289  B(1,0) = inv_p * A(1,0);
290  B(0,2) = inv_p * A(0,2);
291  B(2,0) = inv_p * A(2,0);
292  B(1,2) = inv_p * A(1,2);
293  B(2,1) = inv_p * A(2,1);
294 
295  //r = det(B) / 2
296  double r = 0.5 * ( B(0,0)*B(1,1)*B(2,2) + B(0,1)*B(1,2)*B(2,0) + B(1,0)*B(2,1)*B(0,2) - B(2,0)*B(1,1)*B(0,2) - B(1,0)*B(0,1)*B(2,2) - B(0,0)*B(2,1)*B(1,2) );
297 
298  // In exact arithmetic for a symmetric matrix -1 <= r <= 1
299  // but computation error can leave it slightly outside this range.
300  double phi = 0.0;
301  if (r <= -1) { phi = 0.333333333333333333333333 * Globals::Pi; }
302  else if (r >= 1) { phi = 0.0; }
303  else { phi = 0.333333333333333333333333 * acos(r);}
304 
305  // the eigenvalues satisfy eig3 <= eig2 <= eig1 MAC: WATCH OUT!! This is not true, apparently!
306  Result[0] = q + 2.0 * p * std::cos(phi);
307  Result[2] = q + 2.0 * p * std::cos(phi + (0.6666666666666666666666*Globals::Pi));
308  Result[1] = 3.0 * q - Result[0] - Result[2]; //% since trace(A) = eig1 + eig2 + eig3
309 
310  return Result;
311  }
312 
313  }//namespace AuxiliaryFunctions
314 
315  namespace DemDebugFunctions {
316  static inline void CheckIfNan(const array_1d<double,3>& vector, const std::string& sentence) {
317  #ifdef KRATOS_DEBUG
318  if(std::isnan(vector[0]) || std::isnan(vector[1]) || std::isnan(vector[2])){
319  KRATOS_ERROR<<sentence;
320  }
321  #endif
322  }
323 
324  static inline void CheckIfNan(const double vector[3], const std::string& sentence) {
325  #ifdef KRATOS_DEBUG
326  if(std::isnan(vector[0]) || std::isnan(vector[1]) || std::isnan(vector[2])){
327  KRATOS_ERROR<<sentence;
328  }
329  #endif
330  }
331 
332  static inline void CheckIfNan(const double& value, const std::string& sentence) {
333  #ifdef KRATOS_DEBUG
334  if(std::isnan(value)){
335  KRATOS_ERROR<<sentence;
336  }
337  #endif
338  }
339 
340  }
341 
342 }//namespace Kratos
343 
344 #endif /* _KRATOSAUXILIARYFUNCTIONS_H */
345 
MeshType & LocalMesh()
Returns the reference to the mesh storing all local entities.
Definition: communicator.cpp:245
ElementsContainerType & Elements()
Definition: mesh.h:568
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
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
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
#define KRATOS_ERROR
Definition: exception.h:161
end_time
Definition: DEM_benchmarks.py:174
static void CalculateAlphaFactor2D(const int n_neighbours, const double external_circle_perimeter, const double total_equiv_perimeter, double &alpha)
Definition: AuxiliaryFunctions.h:105
static Vector EigenValuesDirectMethod(const BoundedMatrix< double, 3, 3 > &A)
Definition: AuxiliaryFunctions.h:264
static void CalculateAlphaFactor3D(const int n_neighbours, const double external_sphere_area, const double total_equiv_area, double &alpha)
Definition: AuxiliaryFunctions.h:21
static void SwitchCase(const int case_opt, bool &delta_OPTION, bool &continuum_simulation_OPTION)
Definition: AuxiliaryFunctions.h:170
static void ComputeReactionOnTopAndBottomSpheres(ModelPart &r_model_part)
Definition: AuxiliaryFunctions.h:207
array_1d< double, 3 > LinearTimeIncreasingFunction(const array_1d< double, 3 > &external_total_applied_force, const double current_time, const double end_time)
Definition: AuxiliaryFunctions.h:200
static void CheckIfNan(const array_1d< double, 3 > &vector, const std::string &sentence)
Definition: AuxiliaryFunctions.h:316
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
ModelPart::ElementsContainerType ElementsArrayType
Definition: gid_gauss_point_container.h:41
time
Definition: face_heat.py:85
alpha
Definition: generate_convection_diffusion_explicit_element.py:113
q
Definition: generate_convection_diffusion_explicit_element.py:109
out
Definition: isotropic_damage_automatic_differentiation.py:200
phi
Definition: isotropic_damage_automatic_differentiation.py:168
A
Definition: sensitivityMatrix.py:70
p
Definition: sensitivityMatrix.py:52
int dim
Definition: sensitivityMatrix.py:25
B
Definition: sensitivityMatrix.py:76