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.
pre_utilities.h
Go to the documentation of this file.
1 #ifndef PRE_UTILITES_H
2 #define PRE_UTILITES_H
3 
4 /* System includes */
5 #include <limits>
6 #include <iostream>
7 #include <iomanip>
8 #include <fstream>
9 #include <vector>
10 #include <cstdlib>
11 #include <time.h>
12 #include <string>
13 
14 /* External includes */
15 #ifdef _OPENMP
16 #include <omp.h>
17 #endif
18 
19 /* Project includes */
20 #include "includes/define.h"
21 #include "utilities/timer.h"
22 #include "includes/variables.h"
23 #include "utilities/openmp_utils.h"
24 #include "cluster_information.h"
26 
27 namespace Kratos
28 {
29 
31  {
32  public:
33 
38 
40 
43 
44  PreUtilities(ModelPart& rModelPart)
45  {
46  //mInitialCenterOfMassAndMass = CalculateCenterOfMass(rModelPart);
47  //mInitialMass = CalculateTotalMass(rModelPart);
48  }
49 
51  virtual ~PreUtilities() {}
52 
53  void SetClusterInformationInProperties(std::string const& name,
54  pybind11::list& list_of_coordinates,
55  pybind11::list& list_of_radii,
56  double size,
57  double volume,
58  pybind11::list& inertias,
59  Properties::Pointer& p_properties) {
60  ClusterInformation cl_info;
61 
62  cl_info.mName = name;
63 
64  array_1d<double,3> coords(3,0.0);
65 
66  for (int i = 0; i < (int)pybind11::len(list_of_coordinates); i++) {
67  pybind11::list list(list_of_coordinates[i]);
68  coords[0] = pybind11::cast<double>(list[0]);
69  coords[1] = pybind11::cast<double>(list[1]);
70  coords[2] = pybind11::cast<double>(list[2]);
71  cl_info.mListOfCoordinates.push_back(coords);
72  }
73  for (int i = 0; i < (int)pybind11::len(list_of_radii); i++) {
74  cl_info.mListOfRadii.push_back(pybind11::cast<double>(list_of_radii[i]));
75  }
76  //TODO: check the sizes (should be the same)
77  cl_info.mSize = size;
78  cl_info.mVolume = volume;
79  cl_info.mInertias[0] = pybind11::cast<double>(inertias[0]);
80  cl_info.mInertias[1] = pybind11::cast<double>(inertias[1]);
81  cl_info.mInertias[2] = pybind11::cast<double>(inertias[2]);
82 
83  p_properties->SetValue(CLUSTER_INFORMATION, cl_info);
84  }
85 
86  void PrintNumberOfNeighboursHistogram(const ModelPart& rSpheresModelPart, std::string const& filename) {
87  std::vector<int> number_of_spheres_with_i_neighbours;
88  number_of_spheres_with_i_neighbours.resize(20);
89  for(int i=0; i<(int)number_of_spheres_with_i_neighbours.size(); i++) {number_of_spheres_with_i_neighbours[i] = 0;}
90 
91  const ElementsArrayType& pElements = rSpheresModelPart.GetCommunicator().LocalMesh().Elements();
92  ElementsArrayType::ptr_const_iterator begin = pElements.ptr_begin();
93 
94  for(int i=0; i<(int)pElements.size(); i++) {
95  ElementsArrayType::ptr_const_iterator it = begin + i;
96  const Element& el = **it;
97  const SphericContinuumParticle* p_cont_sphere = dynamic_cast<const SphericContinuumParticle*>(&el);
98  if(p_cont_sphere) {
99  unsigned int size = p_cont_sphere->mContinuumInitialNeighborsSize;
100  if(size > number_of_spheres_with_i_neighbours.size() - 1) size = number_of_spheres_with_i_neighbours.size() - 1;
101  number_of_spheres_with_i_neighbours[size] += 1;
102  } else {
103  const SphericParticle* p_sphere = dynamic_cast<const SphericParticle*>(&el);
104  unsigned int size = p_sphere->mNeighbourElements.size();
105  if(size > number_of_spheres_with_i_neighbours.size() - 1) size = number_of_spheres_with_i_neighbours.size() - 1;
106  number_of_spheres_with_i_neighbours[size] += 1;
107  }
108  }
109  std::ofstream outputfile(filename, std::ios_base::out | std::ios_base::app);
110  outputfile << "number_of_neighbours percentage_of_spheres_with_that_number_of_neighbours number_of_spheres_with_that_number_of_neighbours\n";
111  for(int i=0; i<(int)number_of_spheres_with_i_neighbours.size(); i++) {
112  const double percentage = (double)(number_of_spheres_with_i_neighbours[i]) / (double)(rSpheresModelPart.NumberOfElements(0)) * 100.0;
113  outputfile <<i<<" "<<percentage<<" "<<number_of_spheres_with_i_neighbours[i]<<"\n";
114  }
115 
116  }
117 
118 
119  void FillAnalyticSubModelPartUtility(ModelPart& rSpheresModelPart, ModelPart& rAnalyticSpheresModelPart){
120  ElementsArrayType& pElements = rSpheresModelPart.GetCommunicator().LocalMesh().Elements();
121  std::vector<std::vector<std::size_t> > thread_vectors_of_elem_ids;
122  std::vector<std::vector<std::size_t> > thread_vectors_of_node_ids;
123  int mNumberOfThreads = ParallelUtilities::GetNumThreads();
124  thread_vectors_of_elem_ids.resize(mNumberOfThreads);
125  thread_vectors_of_node_ids.resize(mNumberOfThreads);
126 
127  #pragma omp parallel for
128  for (int k = 0; k < (int)pElements.size(); k++) {
129  ElementsArrayType::iterator it = pElements.ptr_begin() + k;
130  int analytic_particle_id = it->Id();
131  thread_vectors_of_elem_ids[OpenMPUtils::ThisThread()].push_back(analytic_particle_id);
132  thread_vectors_of_node_ids[OpenMPUtils::ThisThread()].push_back(it->GetGeometry()[0].Id());
133  }
134  std::vector<std::size_t> vector_of_elem_ids;
135  std::vector<std::size_t> vector_of_node_ids;
136  for (int i = 0; i < mNumberOfThreads; i++) {
137  vector_of_elem_ids.insert(vector_of_elem_ids.end(), thread_vectors_of_elem_ids[i].begin(), thread_vectors_of_elem_ids[i].end());
138  vector_of_node_ids.insert(vector_of_node_ids.end(), thread_vectors_of_node_ids[i].begin(), thread_vectors_of_node_ids[i].end());
139  }
140  rAnalyticSpheresModelPart.AddElements(vector_of_elem_ids);
141  rAnalyticSpheresModelPart.AddNodes(vector_of_node_ids);
142  }
143 
144 // non-OMP version
145 // void FillAnalyticSubModelPartUtility(ModelPart& rSpheresModelPart, ModelPart& rAnalyticSpheresModelPart){
146 // ElementsArrayType& pElements = rSpheresModelPart.GetCommunicator().LocalMesh().Elements();
147 // std::vector<long unsigned int> vector_of_ids;
148 // for (int k = 0; k < (int)pElements.size(); k++) {
149 // ElementsArrayType::iterator it = pElements.ptr_begin() + k;
150 // int analytic_particle_id = it->Id();
151 // vector_of_ids.push_back(analytic_particle_id);
152 // }
153 // rAnalyticSpheresModelPart.AddElements(vector_of_ids);
154 // }
155 
156  void ResetSkinParticles(ModelPart& r_model_part) {
157  auto& pNodes = r_model_part.GetCommunicator().LocalMesh().Nodes();
158  #pragma omp parallel for
159  for (int k = 0; k < (int)pNodes.size(); k++) {
160  auto it = pNodes.begin() + k;
161  it->FastGetSolutionStepValue(SKIN_SPHERE) = 0.0;
162  }
163  }
164 
165  void SetSkinParticlesInnerCircularBoundary(ModelPart& r_model_part, const double inner_radius, const double detection_radius) {
166  auto& pNodes = r_model_part.GetCommunicator().LocalMesh().Nodes();
167 
168  #pragma omp parallel for
169  for (int k = 0; k < (int)pNodes.size(); k++) {
170  auto it = pNodes.begin() + k;
171  const array_1d<double, 3>& coords = it->Coordinates();
172  array_1d<double, 3> vector_distance_to_center;
173  noalias(vector_distance_to_center) = coords;
174  const double distance_to_center = MathUtils<double>::Norm3(vector_distance_to_center);
175  if(distance_to_center < inner_radius + detection_radius) {
176  it->FastGetSolutionStepValue(SKIN_SPHERE) = 1.0;
177  }
178  }
179  }
180 
181  void SetSkinParticlesOuterCircularBoundary(ModelPart& r_model_part, const double outer_radius, const double detection_radius) {
182  auto& pNodes = r_model_part.GetCommunicator().LocalMesh().Nodes();
183 
184  #pragma omp parallel for
185  for (int k = 0; k < (int)pNodes.size(); k++) {
186  auto it = pNodes.begin() + k;
187  const array_1d<double, 3>& coords = it->Coordinates();
188  array_1d<double, 3> vector_distance_to_center;
189  noalias(vector_distance_to_center) = coords;
190  const double distance_to_center = MathUtils<double>::Norm3(vector_distance_to_center);
191  const double radius = it->FastGetSolutionStepValue(RADIUS);
192  if (distance_to_center + radius > outer_radius - detection_radius) {
193  it->FastGetSolutionStepValue(SKIN_SPHERE) = 1.0;
194  }
195  }
196  }
197 
198  void SetSkinParticlesOuterSquaredBoundary(ModelPart& r_model_part, const double outer_radius, const array_1d<double, 3>& center, const double detection_radius) {
199 
200  auto& pNodes = r_model_part.GetCommunicator().LocalMesh().Nodes();
201 
202  #pragma omp parallel for
203  for (int k = 0; k < (int)pNodes.size(); k++) {
204  auto it = pNodes.begin() + k;
205  const array_1d<double, 3>& coords = it->Coordinates();
206  array_1d<double, 3> vector_distance_to_center;
207  noalias(vector_distance_to_center) = coords - center;
208  const double total_x_distance = fabs(vector_distance_to_center[0]);
209  const double total_y_distance = fabs(vector_distance_to_center[1]);
210  const double radius = it->FastGetSolutionStepValue(RADIUS);
211 
212  if ((total_x_distance + radius > outer_radius - detection_radius) || (total_y_distance + radius > outer_radius - detection_radius)) {
213  it->FastGetSolutionStepValue(SKIN_SPHERE) = 1.0;
214  }
215  }
216  }
217 
218  void BreakBondUtility(ModelPart& rSpheresModelPart) {
219 
220  ElementsArrayType& pElements = rSpheresModelPart.GetCommunicator().LocalMesh().Elements();
221  #pragma omp parallel for
222  for (int k = 0; k < (int)pElements.size(); k++) {
223 
224  ElementsArrayType::iterator it = pElements.ptr_begin() + k;
225  Element* p_element = &(*it);
226  SphericContinuumParticle* p_sphere = dynamic_cast<SphericContinuumParticle*>(p_element);
227 
228  if (p_sphere->mNeighbourElements[k] == NULL) continue;
229 
230  double x_node = p_sphere->GetGeometry()[0].Coordinates()[0];
231  double y_node = p_sphere->GetGeometry()[0].Coordinates()[1];
232  double z_node = p_sphere->GetGeometry()[0].Coordinates()[2];
233  double radius = 0.0225; // radi
234 
235  if ((x_node*x_node + z_node*z_node >= radius*radius && y_node < 0.01) || (x_node*x_node + z_node*z_node >= radius*radius && y_node > 0.07)) { // 1- geometry condition
236  unsigned int number_of_neighbors = p_sphere->mContinuumInitialNeighborsSize;
237  for (unsigned int i = 0; i < number_of_neighbors; i++)
238  {
239  SphericContinuumParticle* neighbour_iterator = dynamic_cast<SphericContinuumParticle*>(p_sphere->mNeighbourElements[i]);
240  double x_node_it = neighbour_iterator->GetGeometry()[0].Coordinates()[0];
241  double z_node_it = neighbour_iterator->GetGeometry()[0].Coordinates()[2];
242  double radius_it = 0.0225; // radi de la entalla en el shear test.
243  if (x_node_it*x_node_it + z_node_it*z_node_it < radius_it*radius_it) { // 2- geometry condition
244 
245  //int& failure_type = p_sphere->mIniNeighbourFailureId[i];
246  //failure_type = 1;
247  p_sphere->Set(TO_ERASE, true);
248  neighbour_iterator->Set(TO_ERASE, true);
249 
250  //noalias(other_to_me_vector) = p_sphere->GetGeometry()[0].Coordinates() - p_sphere->mNeighbourElements[i]->GetGeometry()[0].Coordinates();
251  //noalias(initial_other_to_me_vector) = p_sphere->GetGeometry()[0].GetInitialPosition() - p_sphere->mNeighbourElements[i]->GetGeometry()[0].GetInitialPosition();
252  }
253  }
254  } else if ((x_node*x_node + z_node*z_node < radius*radius && y_node < 0.01) || (x_node*x_node + z_node*z_node < radius*radius && y_node > 0.07)) {
255  unsigned int number_of_neighbors = p_sphere->mContinuumInitialNeighborsSize;
256  for (unsigned int i = 0; i < number_of_neighbors; i++)
257  {
258  SphericContinuumParticle* neighbour_iterator = dynamic_cast<SphericContinuumParticle*>(p_sphere->mNeighbourElements[i]);
259  double x_node_it = neighbour_iterator->GetGeometry()[0].Coordinates()[0];
260  double z_node_it = neighbour_iterator->GetGeometry()[0].Coordinates()[2];
261  double radius_it = 0.0225; // radi de la entalla en el shear test.
262  if (x_node_it*x_node_it + z_node_it*z_node_it > radius_it*radius_it) { // 2- geometry condition
263 
264  //int& failure_type = p_sphere->mIniNeighbourFailureId[i];
265  //failure_type = 1;
266  p_sphere->Set(TO_ERASE, true);
267  neighbour_iterator->Set(TO_ERASE, true);
268  }
269  }
270  }
271  }
272  }
273 
275 
276  // We have a prismatic specimen of dimensions 1m x 1m x 2m
277  const double side = 0.15;
278  int divisions;
279  KRATOS_WARNING("DEM") << "\nEnter the number of divisions: ";
280  std::cin >> divisions;
281  if (!divisions) {
282  KRATOS_WARNING("DEM") << "\nCannot divide by zero. Program stopped.\n\n";
283  exit(EXIT_FAILURE);
284  }
285  const double radius = 0.5 * side / divisions;
286  int node_counter = 0;
287  std::vector<int> skin_nodes;
288  std::vector<int> top_nodes;
289  std::vector<int> bottom_nodes;
290  filename += "DEM.mdpa";
291 
292  //
293 
294  std::ifstream infile(filename);
295  if(infile.good()) {
296  while(1){
297  KRATOS_WARNING("DEM") << "\nThe file already exists. Do you want to overwrite it? (y/n) ";
298  char yn;
299  std::cin >> yn;
300  if(yn == 'n') {
301  KRATOS_WARNING("DEM") << "\nStopped.\n\n";
302  exit(EXIT_FAILURE);
303  }
304  if(yn=='y') break;
305  }
306  }
307 
308  KRATOS_INFO("DEM") << "\nGenerating mesh...\n\n";
309 
310  clock_t initial_time, end_time;
311  initial_time = clock();
312  std::ofstream outputfile(filename, std::ios_base::out);
313  outputfile << "Begin ModelPartData\nEnd ModelPartData\n\n";
314  outputfile << "Begin Properties 1\n";
315  outputfile << "PARTICLE_DENSITY 2550.0\n";
316  outputfile << "YOUNG_MODULUS 35e9\n";
317  outputfile << "POISSON_RATIO 0.20\n";
318  outputfile << "STATIC_FRICTION 0.5773502691896257\n";
319  outputfile << "DYNAMIC_FRICTION 0.5773502691896257\n";
320  outputfile << "FRICTION_DECAY 500.0\n";
321  outputfile << "PARTICLE_COHESION 0.0\n";
322  outputfile << "COEFFICIENT_OF_RESTITUTION 0.2\n";
323  outputfile << "PARTICLE_MATERIAL 1\n";
324  outputfile << "ROLLING_FRICTION 0.01\n";
325  outputfile << "ROLLING_FRICTION_WITH_WALLS 0.01\n";
326  outputfile << "DEM_CONTINUUM_CONSTITUTIVE_LAW_NAME DEM_Dempack\n";
327  outputfile << "DEM_DISCONTINUUM_CONSTITUTIVE_LAW_NAME DEM_D_Linear_viscous_Coulomb\n";
328  outputfile << "SLOPE_LIMIT_COEFF_C1 24\n";
329  outputfile << "SLOPE_LIMIT_COEFF_C2 28\n";
330  outputfile << "SLOPE_LIMIT_COEFF_C3 1\n";
331  outputfile << "SLOPE_FRACTION_N1 1\n";
332  outputfile << "SLOPE_FRACTION_N2 1\n";
333  outputfile << "SLOPE_FRACTION_N3 35e9\n";
334  outputfile << "YOUNG_MODULUS_PLASTIC 1000\n";
335  outputfile << "PLASTIC_YIELD_STRESS 0.2\n";
336  outputfile << "DAMAGE_FACTOR 1\n";
337  outputfile << "SHEAR_ENERGY_COEF 1\n";
338  outputfile << "CONTACT_TAU_ZERO 5\n";
339  outputfile << "CONTACT_SIGMA_MIN 1\n";
340  outputfile << "CONTACT_INTERNAL_FRICC 20\n";
341  outputfile << "End Properties\n";
342 
343  outputfile << "\nBegin Nodes\n";
344 
345  // Relative sizes according to axes:
346  int ai=1;
347  int aj=2;
348  int ak=1;
349 
350  //Generation of the samble
351  for (int k = 0; k < ai*divisions; k++) {
352  for (int j = 0; j < aj* divisions; j++) {
353  for (int i = 0; i < ak*divisions; i++) {
354  outputfile << ++node_counter << " " << (1 + 2 * i) * radius - 0.5*side << " " << (1 + 2 * j) * radius << " " << (1 + 2 * k) * radius - 0.5*side << '\n';
355  if ((i == 0) || (j == 0) || (k == 0) || (i == ai* divisions - 1) || (j == aj*divisions - 1) || (k == ak*divisions - 1)) skin_nodes.push_back(node_counter);
356  if (k == 0) bottom_nodes.push_back(node_counter);
357  if (k == 2 * divisions - 1) top_nodes.push_back(node_counter);
358  }
359  }
360  }
361  //
362  outputfile << "End Nodes\n";
363  outputfile << "\nBegin Elements SphericContinuumParticle3D\n";
364  for (int i = 1; i <= node_counter; i++) outputfile << i << " 1 " << i << '\n';
365  outputfile << "End Elements\n";
366  outputfile << "\nBegin NodalData RADIUS\n";
367  for (int i = 1; i <= node_counter; i++) outputfile << i << " 0 " << radius << '\n';
368  outputfile << "End NodalData\n";
369  outputfile << "\nBegin NodalData COHESIVE_GROUP // whole specimen\n";
370  for (int i = 1; i <= node_counter; i++) outputfile << i << " 0 1\n";
371  outputfile << "End NodalData\n";
372  //outputfile << "\nBegin NodalData COHESIVE_GROUP // bottom nodes\n";
373  //for (std::vector<int>::iterator it_bottom = bottom_nodes.begin(); it_bottom != bottom_nodes.end(); it_bottom++) outputfile << *it_bottom << " 0 1\n";
374  //outputfile << "End NodalData\n\nBegin NodalData COHESIVE_GROUP // top nodes\n";
375  //for (std::vector<int>::iterator it_top = top_nodes.begin(); it_top != top_nodes.end(); it_top++) outputfile << *it_top << " 0 1\n";
376  //outputfile << "End NodalData\n";
377  outputfile << "\nBegin NodalData SKIN_SPHERE\n";
378  for (std::vector<int>::iterator it_skin = skin_nodes.begin(); it_skin != skin_nodes.end(); it_skin++) outputfile << *it_skin << " 0 1\n";
379  outputfile << "End NodalData\n\n";
380  /*outputfile << "Begin Mesh 1 // bottom nodes\n Begin MeshData\n VELOCITY_START_TIME 0.0\n";
381  outputfile << " FORCE_INTEGRATION_GROUP 0\n VELOCITY_STOP_TIME 100.0\n TOP 0\n";
382  outputfile << " IMPOSED_VELOCITY_Z_VALUE 0.0005\n BOTTOM 0\n End MeshData\n Begin MeshNodes\n";
383  for (std::vector<int>::iterator it_bottom = bottom_nodes.begin(); it_bottom != bottom_nodes.end(); it_bottom++) outputfile << " " << *it_bottom << '\n';
384  outputfile << " End MeshNodes\nEnd Mesh\n\n";
385  outputfile << "Begin Mesh 2 // top nodes\n Begin MeshData\n VELOCITY_START_TIME 0.0\n";
386  outputfile << " FORCE_INTEGRATION_GROUP 0\n VELOCITY_STOP_TIME 100.0\n TOP 0\n";
387  outputfile << " IMPOSED_VELOCITY_Z_VALUE -0.0005\n BOTTOM 0\n End MeshData\n Begin MeshNodes\n";
388  for (std::vector<int>::iterator it_top = top_nodes.begin(); it_top != top_nodes.end(); it_top++) outputfile << " " << *it_top << '\n';
389  outputfile << " End MeshNodes\nEnd Mesh\n";*/
390  outputfile.close();
391  end_time = clock();
392  double elapsed_time = (double(end_time) - double(initial_time)) / CLOCKS_PER_SEC;
393  KRATOS_INFO("DEM") << "\nfinished!\n\n";
394  KRATOS_INFO("DEM") << "\nTotal number of elements: " << node_counter << '\n';
395  KRATOS_INFO("DEM") << "\nTime required to create the mdpa file: " << elapsed_time << " seconds\n\n";
396  }
397 
398  void MeasureTopHeight(ModelPart& rModelPart, double& subtotal, double& weight)
399  {
400  /*
401  ElementsArrayType& pElements = rModelPart.Elements();
402 
403  for (ElementsArrayType::iterator it= pElements.begin(); it!=pElements.end(); ++it)
404  {
405 
406  if( it->GetGeometry()[0].FastGetSolutionStepValue(GROUP_ID) == 1 )
407  {
408  ParticleWeakVectorType& mrNeighbours = it->GetValue(NEIGHBOUR_ELEMENTS);
409 
410  for(ParticleWeakIteratorType ineighbour = mrNeighbours.begin();
411  ineighbour != mrNeighbours.end(); ineighbour++)
412  {
413  if( ineighbour->GetGeometry()[0].FastGetSolutionStepValue(GROUP_ID) != 1 )
414  {
415  subtotal += it->GetGeometry()[0].Coordinates()[1]*it->GetGeometry()[0].FastGetSolutionStepValue(RADIUS);
416  weight += it->GetGeometry()[0].FastGetSolutionStepValue(RADIUS);
417 
418  break;
419  }
420  }
421  }
422  }
423  */
424  }
425 
426  void MeasureBotHeight(ModelPart& rModelPart, double& subtotal, double& weight)
427  {
428  /*
429  ElementsArrayType& pElements = rModelPart.Elements();
430 
431  for (ElementsArrayType::iterator it= pElements.begin(); it!=pElements.end(); ++it)
432  {
433  if( it->GetGeometry()[0].FastGetSolutionStepValue(GROUP_ID) == 2 )
434  {
435  ParticleWeakVectorType& mrNeighbours = it->GetValue(NEIGHBOUR_ELEMENTS);
436 
437  for(ParticleWeakIteratorType ineighbour = mrNeighbours.begin();
438  ineighbour != mrNeighbours.end(); ineighbour++)
439  {
440  if( ineighbour->GetGeometry()[0].FastGetSolutionStepValue(GROUP_ID) != 2 )
441  {
442  subtotal += it->GetGeometry()[0].Coordinates()[1]*it->GetGeometry()[0].FastGetSolutionStepValue(RADIUS);
443  weight += it->GetGeometry()[0].FastGetSolutionStepValue(RADIUS);
444 
445  break;
446  }
447  }
448  }
449  }
450  */
451  }
452 
453  void MarkToEraseParticlesOutsideRadius(ModelPart& r_model_part, const double max_radius, const array_1d<double, 3>& center, const double tolerance_for_erasing) {
454  auto& pNodes = r_model_part.GetCommunicator().LocalMesh().Nodes();
455 
456  #pragma omp parallel for
457  for (int k = 0; k < (int)pNodes.size(); k++) {
458  auto it = pNodes.begin() + k;
459  const array_1d<double, 3>& coords = it->Coordinates();
460  array_1d<double, 3> vector_distance_to_center;
461  noalias(vector_distance_to_center) = coords - center;
462  const double distance_to_center = MathUtils<double>::Norm3(vector_distance_to_center);
463  const double radius = it->FastGetSolutionStepValue(RADIUS);
464  if(distance_to_center + radius > max_radius + tolerance_for_erasing) {
465  it->Set(TO_ERASE, true);
466  }
467  }
468  }
469 
470  void MarkToEraseParticlesOutsideRadiusForGettingCylinder(ModelPart& r_model_part, const double max_radius, const array_1d<double, 3>& center, const double tolerance_for_erasing) {
471  auto& pNodes = r_model_part.GetCommunicator().LocalMesh().Nodes();
472 
473  #pragma omp parallel for
474  for (int k = 0; k < (int)pNodes.size(); k++) {
475  auto it = pNodes.begin() + k;
476  const array_1d<double, 3>& coords = it->Coordinates();
477  const double distance_to_center = std::sqrt((coords[0] - center[0]) * (coords[0] - center[0]) + (coords[2] - center[2]) * (coords[2] - center[2]));
478  const double radius = it->FastGetSolutionStepValue(RADIUS);
479  if(distance_to_center + radius > max_radius + tolerance_for_erasing) {
480  it->Set(TO_ERASE, true);
481  }
482  }
483  }
484 
485  void MarkToEraseParticlesOutsideBoundary(ModelPart& r_model_part, const double min_x, const double max_x, const double min_y, const double max_y, const double min_z, const double max_z, const double tolerance_for_erasing) {
486  auto& pNodes = r_model_part.GetCommunicator().LocalMesh().Nodes();
487 
488  #pragma omp parallel for
489  for (int k = 0; k < (int)pNodes.size(); k++) {
490  auto it = pNodes.begin() + k;
491  const array_1d<double, 3>& coords = it->Coordinates();
492  const double radius = it->FastGetSolutionStepValue(RADIUS);
493  if(coords[0] + radius > max_x + tolerance_for_erasing || coords[0] - radius < min_x - tolerance_for_erasing) {
494  it->Set(TO_ERASE, true);
495  }
496  else if(coords[1] + radius > max_y + tolerance_for_erasing || coords[1] - radius < min_y - tolerance_for_erasing) {
497  it->Set(TO_ERASE, true);
498  }
499  else if(coords[2] + radius > max_z + tolerance_for_erasing || coords[2] - radius < min_z - tolerance_for_erasing) {
500  it->Set(TO_ERASE, true);
501  }
502  }
503  }
504 
505  void ApplyConcentricForceOnParticles(ModelPart& r_model_part, const array_1d<double, 3>& center, const double density_for_artificial_gravity) {
506  auto& pElements = r_model_part.GetCommunicator().LocalMesh().Elements();
507 
508  #pragma omp parallel for
509  for (int k = 0; k < (int)pElements.size(); k++) {
510  auto it = pElements.begin() + k;
511  auto& node = it->GetGeometry()[0];
512  const array_1d<double, 3>& coords = node.Coordinates();
513  array_1d<double, 3> vector_particle_to_center;
514  noalias(vector_particle_to_center) = center - coords;
515  const double distance_to_center = MathUtils<double>::Norm3(vector_particle_to_center);
516  const double inv_dist = 1.0 / distance_to_center;
517  array_1d<double, 3> force;
518  SphericParticle* spheric_p_particle = dynamic_cast<SphericParticle*> (&*it);
519  const double volume = spheric_p_particle->CalculateVolume();
520  noalias(force) = inv_dist * vector_particle_to_center * volume * density_for_artificial_gravity;
521  node.FastGetSolutionStepValue(EXTERNAL_APPLIED_FORCE) = force;
522  }
523  }
524 
526  {
527  return mInitialCenterOfMassAndMass;
528  }
529 
531 
532  virtual std::string Info() const
533  {
534  return "";
535  }
536 
538 
539  virtual void PrintInfo(std::ostream& rOStream) const
540  {
541  }
542 
544 
545  virtual void PrintData(std::ostream& rOStream) const
546  {
547  }
548 
549  private:
550 
551  array_1d<double, 3> mInitialCenterOfMassAndMass;
552  double mInitialMass;
553 
555  PreUtilities & operator=(PreUtilities const& rOther);
556 
557  }; // Class PreUtilities
558 
560  // template<std::size_t TDim>
561  // inline std::ostream& operator << (std::ostream& rOStream)
562  // {
563  // rThis.PrintInfo(rOStream);
564  // rOStream << std::endl;
565  // rThis.PrintData(rOStream);
566  //
567  // return rOStream;
568  // }
569 
570 } // namespace Kratos
571 
572 #endif // PRE_UTILITES_H
Definition: cluster_information.h:14
double mVolume
Definition: cluster_information.h:20
double mSize
Definition: cluster_information.h:19
std::vector< double > mListOfRadii
Definition: cluster_information.h:21
array_1d< double, 3 > mInertias
Definition: cluster_information.h:23
std::string mName
Definition: cluster_information.h:17
std::vector< array_1d< double, 3 > > mListOfCoordinates
Definition: cluster_information.h:22
MeshType & LocalMesh()
Returns the reference to the mesh storing all local entities.
Definition: communicator.cpp:245
Base class for all Elements.
Definition: element.h:60
void Set(const Flags ThisFlag)
Definition: flags.cpp:33
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
static double Norm3(const TVectorType &a)
Calculates the norm of vector "a" which is assumed to be of size 3.
Definition: math_utils.h:691
NodesContainerType & Nodes()
Definition: mesh.h:346
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
SizeType NumberOfElements(IndexType ThisIndex=0) const
Definition: model_part.h:1027
void AddElements(std::vector< IndexType > const &ElementIds, IndexType ThisIndex=0)
Definition: model_part.cpp:941
void AddNodes(std::vector< IndexType > const &NodeIds, IndexType ThisIndex=0)
Definition: model_part.cpp:235
static int ThisThread()
Wrapper for omp_get_thread_num().
Definition: openmp_utils.h:108
static int GetNumThreads()
Returns the current number of threads.
Definition: parallel_utilities.cpp:34
ptr_iterator ptr_begin()
Returns an iterator pointing to the beginning of the underlying data container.
Definition: pointer_vector_set.h:386
iterator begin()
Returns an iterator pointing to the beginning of the container.
Definition: pointer_vector_set.h:278
Definition: pre_utilities.h:31
void CreateCartesianSpecimenMdpa(std::string filename)
Definition: pre_utilities.h:274
void SetSkinParticlesInnerCircularBoundary(ModelPart &r_model_part, const double inner_radius, const double detection_radius)
Definition: pre_utilities.h:165
PreUtilities(ModelPart &rModelPart)
Definition: pre_utilities.h:44
KRATOS_CLASS_POINTER_DEFINITION(PreUtilities)
void MarkToEraseParticlesOutsideBoundary(ModelPart &r_model_part, const double min_x, const double max_x, const double min_y, const double max_y, const double min_z, const double max_z, const double tolerance_for_erasing)
Definition: pre_utilities.h:485
ModelPart::NodesContainerType::ContainerType NodesContainerType
Definition: pre_utilities.h:35
virtual std::string Info() const
Turn back information as a stemplate<class T, std::size_t dim> tring.
Definition: pre_utilities.h:532
void MarkToEraseParticlesOutsideRadiusForGettingCylinder(ModelPart &r_model_part, const double max_radius, const array_1d< double, 3 > &center, const double tolerance_for_erasing)
Definition: pre_utilities.h:470
ModelPart::ElementsContainerType ElementsArrayType
Definition: pre_utilities.h:34
virtual ~PreUtilities()
Destructor.
Definition: pre_utilities.h:51
void BreakBondUtility(ModelPart &rSpheresModelPart)
Definition: pre_utilities.h:218
void FillAnalyticSubModelPartUtility(ModelPart &rSpheresModelPart, ModelPart &rAnalyticSpheresModelPart)
Definition: pre_utilities.h:119
array_1d< double, 3 > GetInitialCenterOfMass()
Definition: pre_utilities.h:525
void PrintNumberOfNeighboursHistogram(const ModelPart &rSpheresModelPart, std::string const &filename)
Definition: pre_utilities.h:86
GlobalPointersVector< Element >::iterator ParticleWeakIteratorType
Definition: pre_utilities.h:37
void ApplyConcentricForceOnParticles(ModelPart &r_model_part, const array_1d< double, 3 > &center, const double density_for_artificial_gravity)
Definition: pre_utilities.h:505
void SetClusterInformationInProperties(std::string const &name, pybind11::list &list_of_coordinates, pybind11::list &list_of_radii, double size, double volume, pybind11::list &inertias, Properties::Pointer &p_properties)
Definition: pre_utilities.h:53
void SetSkinParticlesOuterCircularBoundary(ModelPart &r_model_part, const double outer_radius, const double detection_radius)
Definition: pre_utilities.h:181
void MeasureBotHeight(ModelPart &rModelPart, double &subtotal, double &weight)
Definition: pre_utilities.h:426
void ResetSkinParticles(ModelPart &r_model_part)
Definition: pre_utilities.h:156
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: pre_utilities.h:539
void MarkToEraseParticlesOutsideRadius(ModelPart &r_model_part, const double max_radius, const array_1d< double, 3 > &center, const double tolerance_for_erasing)
Definition: pre_utilities.h:453
void SetSkinParticlesOuterSquaredBoundary(ModelPart &r_model_part, const double outer_radius, const array_1d< double, 3 > &center, const double detection_radius)
Definition: pre_utilities.h:198
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: pre_utilities.h:545
GlobalPointersVector< Element > ParticleWeakVectorType
Definition: pre_utilities.h:36
PreUtilities()
Default constructor.
Definition: pre_utilities.h:42
void MeasureTopHeight(ModelPart &rModelPart, double &subtotal, double &weight)
Definition: pre_utilities.h:398
Definition: spheric_continuum_particle.h:26
unsigned int mContinuumInitialNeighborsSize
Definition: spheric_continuum_particle.h:133
Definition: spheric_particle.h:31
virtual double CalculateVolume()
Definition: spheric_particle.cpp:2196
std::vector< SphericParticle * > mNeighbourElements
Definition: spheric_particle.h:248
#define KRATOS_INFO(label)
Definition: logger.h:250
#define KRATOS_WARNING(label)
Definition: logger.h:265
end_time
Definition: DEM_benchmarks.py:174
elapsed_time
Definition: DEM_benchmarks.py:181
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
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
string percentage
Definition: all_t_win_vs_m_fixed_error.py:236
string filename
Definition: cube_mesher.py:766
initial_time
Definition: dam_analysis.py:4
out
Definition: isotropic_damage_automatic_differentiation.py:200
float radius
Definition: mesh_to_mdpa_converter.py:18
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
el
Definition: read_stl.py:25
volume
Definition: sp_statistics.py:15
integer i
Definition: TensorModule.f:17
Definition: mesh_converter.cpp:38
Configure::ContainerType ContainerType
Definition: transfer_utility.h:247