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.
mpi_discrete_particle_configure.h
Go to the documentation of this file.
1 // Project Name: Kratos
2 // Last Modified by: $Author: Nelson Lafontaine $
3 // Date: $Date: 2012-05-24 $
4 // Revision: $Revision: 1.0 $
5 //
6 
7 
8 #if !defined(KRATOS_MPI_DISCRETE_PARTICLE__CONFIGURE_INCLUDED)
9 #define KRATOS_MPI_DISCRETE_PARTICLE__CONFIGURE_INCLUDED
10 
11 
12 
13 // System includes
14 #include <string>
15 #include <iostream>
16 #include <cmath>
19 #include "mpi.h"
20 
21 namespace Kratos
22 {
23 
26 
30 
34 
38 
42 
43 
44 template <std::size_t TDimension>
46 public:
47 
48  enum { Dimension = TDimension,
49  DIMENSION = TDimension,
50  MAX_LEVEL = 16,
51  MIN_LEVEL = 2
52  };
53 
54  typedef Point PointType;
55  typedef std::vector<double>::iterator DistanceIteratorType;
56  typedef std::vector<typename Element::Pointer> ContainerType; // ModelPart::ElementsContainerType::ContainerType ContainerType;
57  typedef ContainerType::value_type PointerType;
58  typedef ContainerType::iterator IteratorType;
59  typedef ModelPart::ElementsContainerType ElementsContainerType; // pointer vector set de elements.
60  typedef ElementsContainerType::ContainerType ResultContainerType; // std vector de punters a elements
61  typedef ResultContainerType::value_type ResultPointerType;
62  typedef ResultContainerType::iterator ResultIteratorType;
63 
64 
65  typedef std::vector<PointerType>::iterator PointerTypeIterator;
66 
69 
73 
76 
80 
81 
85 
86 
87  //******************************************************************************************************************
88 
89  static inline void CalculateBoundingBox(const PointerType& rObject, PointType& rLowPoint, PointType& rHighPoint){
90 
91  rHighPoint = rLowPoint = rObject->GetGeometry().GetPoint(0);
92  double radius = rObject->GetGeometry()[0].GetSolutionStepValue(RADIUS);
93 
94  for(std::size_t i = 0; i < 3; i++){
95  rLowPoint[i] += -radius;
96  rHighPoint[i] += radius;
97  }
98  }
99 
100  static inline void CalculateBoundingBox(const PointerType& rObject, PointType& rLowPoint, PointType& rHighPoint, const double& Radius){
101 
102  rHighPoint = rLowPoint = rObject->GetGeometry().GetPoint(0);
103 
104  for(std::size_t i = 0; i < 3; i++){
105  rLowPoint[i] += -Radius;
106  rHighPoint[i] += Radius;
107  }
108 
109  }
110 
111  static inline void CalculateCenter(const PointerType& rObject, PointType& rCenter){
112 
113  rCenter = rObject->GetGeometry().GetPoint(0);
114  }
115 
116  //******************************************************************************************************************
117 
118  static inline bool Intersection(const PointerType& rObj_1, const PointerType& rObj_2){
119  array_1d<double, 3> rObj_2_to_rObj_1 = rObj_1->GetGeometry().GetPoint(0) - rObj_2->GetGeometry().GetPoint(0);
120  double distance_2 = inner_prod(rObj_2_to_rObj_1, rObj_2_to_rObj_1);
121  //distance_2 is the inter-center distance squared (from the definition of distance in search-structure.h, with operator (,))
122  const double& radius_1 = rObj_1->GetGeometry()[0].GetSolutionStepValue(RADIUS);
123  const double& radius_2 = rObj_2->GetGeometry()[0].GetSolutionStepValue(RADIUS);
124  double radius_sum = radius_1 + radius_2;
125  bool intersect = (distance_2 - radius_sum * radius_sum) <= 0;
126  return intersect;
127  }
128 
129 
130  static inline bool Intersection(const PointerType& rObj_1, const PointerType& rObj_2, const double& Radius){
131  array_1d<double, 3> rObj_2_to_rObj_1 = rObj_1->GetGeometry().GetPoint(0) - rObj_2->GetGeometry().GetPoint(0);
132  double distance_2 = inner_prod(rObj_2_to_rObj_1, rObj_2_to_rObj_1);
133  //distance_2 is the inter-center distance squared (from the definition of distance in search-structure.h, with operator (,))
134 // double radius_1 = Radius;//Cambien el radi del objecte de cerca per el gran, aixi no tindria que petar res
135 // double radius_1 = Radius;
136  const double& radius_1 = Radius;
137  const double& radius_2 = rObj_2->GetGeometry()[0].GetSolutionStepValue(RADIUS);
138  double radius_sum = radius_1 + radius_2;
139  bool intersect = (distance_2 - radius_sum * radius_sum) <= 0;
140  return intersect;
141  }
142 
143 
144 
145  //******************************************************************************************************************
146 
147  static inline bool IntersectionBox(const PointerType& rObject, const PointType& rLowPoint, const PointType& rHighPoint)
148  {
149 
150 // double separation_from_particle_radius_ratio = 0.1;
151 
152  array_1d<double, 3> center_of_particle = rObject->GetGeometry().GetPoint(0);
153 
154  const double& radius = rObject->GetGeometry()[0].GetSolutionStepValue(RADIUS);
155 
156  bool intersect = (rLowPoint[0] - radius <= center_of_particle[0] && rLowPoint[1] - radius <= center_of_particle[1] && rLowPoint[2] - radius <= center_of_particle[2] &&
157  rHighPoint[0] + radius >= center_of_particle[0] && rHighPoint[1] + radius >= center_of_particle[1] && rHighPoint[2] + radius >= center_of_particle[2]);
158 
159  return intersect;
160 
161  }
162 
163  static inline bool IntersectionBox(const PointerType& rObject, const PointType& rLowPoint, const PointType& rHighPoint, const double& Radius)
164  {
165 // double separation_from_particle_radius_ratio = 0.1;
166  array_1d<double, 3> center_of_particle = rObject->GetGeometry().GetPoint(0);
167 
168  double radius = Radius;//Cambien el radi del objecte de cerca per el gran, aixi no tindria que petar res
169  bool intersect = (rLowPoint[0] - radius <= center_of_particle[0] && rLowPoint[1] - radius <= center_of_particle[1] && rLowPoint[2] - radius <= center_of_particle[2] &&
170 
171  rHighPoint[0] + radius >= center_of_particle[0] && rHighPoint[1] + radius >= center_of_particle[1] && rHighPoint[2] + radius >= center_of_particle[2]);
172  return intersect;
173  }
174 
175  static inline void Distance(const PointerType& rObj_1, const PointerType& rObj_2, double& distance)
176  {
177  array_1d<double, 3> center_of_particle1 = rObj_1->GetGeometry().GetPoint(0);
178  array_1d<double, 3> center_of_particle2 = rObj_2->GetGeometry().GetPoint(0);
179 
180  distance = sqrt((center_of_particle1[0] - center_of_particle2[0]) * (center_of_particle1[0] - center_of_particle2[0]) +
181  (center_of_particle1[1] - center_of_particle2[1]) * (center_of_particle1[1] - center_of_particle2[1]) +
182  (center_of_particle1[2] - center_of_particle2[2]) * (center_of_particle1[2] - center_of_particle2[2]) );
183  }
184 
185 
186  static inline void ReduceIds(int& total_elements, int& first_element)
187  {
188  int mpi_rank;
189  int mpi_size;
190 
191  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
192  MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
193 
194  std::vector<int> reduceArray(mpi_size+1);
195 
196  MPI_Allgather(&total_elements,1,MPI_INT,&reduceArray[1],1,MPI_INT,MPI_COMM_WORLD);
197 
198  reduceArray[0] = 1;
199  for(int i = 1; i <= mpi_size; i++)
200  reduceArray[i] += reduceArray[i-1];
201 
202  first_element = reduceArray[mpi_rank];
203  }
204 
205  template<class TObjectType>
206  static inline void AsyncSendAndReceive(Communicator::Pointer Communicator,
207  std::vector<TObjectType>& SendObjects,
208  std::vector<TObjectType>& RecvObjects,
209  int * msgSendSize,
210  int * msgRecvSize)
211  {
212  Timer::Start("ASYNC2");
213  Communicator->AsyncSendAndReceiveNodes(SendObjects,RecvObjects,msgSendSize,msgRecvSize);
214  Timer::Stop("ASYNC2");
215  }
216 
217  template<class TObjectType>
218  static inline void AsyncSendAndReceive(std::vector<TObjectType>& SendObjects,
219  std::vector<TObjectType>& RecvObjects,
220  int * msgSendSize,
221  int * msgRecvSize)
222  {
223  Timer::Start("ASYNC1");
224 
225  int mpi_rank;
226  int mpi_size;
227 
228  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
229  MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
230 
231  std::stringstream * serializer_buffer;
232  std::vector<std::string> buffer(mpi_size);
233 // std::string buffer[mpi_size];
234 
235  for(int i = 0; i < mpi_size; i++)
236  {
237  if(mpi_rank != i)
238  {
239  Kratos::Serializer particleSerializer;
240  particleSerializer.save("nodes",SendObjects[i]);
241 
242  serializer_buffer = (std::stringstream *)particleSerializer.pGetBuffer();
243  buffer[i] = std::string(serializer_buffer->str());
244  msgSendSize[i] = buffer[i].size();
245  }
246  }
247 
248  MPI_Alltoall(msgSendSize,1,MPI_INT,msgRecvSize,1,MPI_INT,MPI_COMM_WORLD);
249 
250  int NumberOfCommunicationEvents = 0;
251  int NumberOfCommunicationEventsIndex = 0;
252 
253  char * message[mpi_size];
254  char * mpi_send_buffer[mpi_size];
255 
256  for(int j = 0; j < mpi_size; j++)
257  {
258  if(j != mpi_rank && msgRecvSize[j]) NumberOfCommunicationEvents++;
259  if(j != mpi_rank && msgSendSize[j]) NumberOfCommunicationEvents++;
260  }
261 
262  MPI_Request reqs[NumberOfCommunicationEvents];
263  MPI_Status stats[NumberOfCommunicationEvents];
264 
265  //Set up all receive and send events
266  for(int i = 0; i < mpi_size; i++)
267  {
268  if(i != mpi_rank && msgRecvSize[i])
269  {
270  message[i] = (char *)malloc(sizeof(char) * msgRecvSize[i]);
271 
272  MPI_Irecv(message[i],msgRecvSize[i],MPI_CHAR,i,0,MPI_COMM_WORLD,&reqs[NumberOfCommunicationEventsIndex++]);
273  }
274 
275  if(i != mpi_rank && msgSendSize[i])
276  {
277  mpi_send_buffer[i] = (char *)malloc(sizeof(char) * msgSendSize[i]);
278  memcpy(mpi_send_buffer[i],buffer[i].c_str(),msgSendSize[i]);
279  MPI_Isend(mpi_send_buffer[i],msgSendSize[i],MPI_CHAR,i,0,MPI_COMM_WORLD,&reqs[NumberOfCommunicationEventsIndex++]);
280  }
281  }
282  //wait untill all communications finish
283  MPI_Waitall(NumberOfCommunicationEvents, reqs, stats);
284 
285  MPI_Barrier(MPI_COMM_WORLD);
286 
287  for(int i = 0; i < mpi_size; i++)
288  {
289  if (i != mpi_rank && msgRecvSize[i])
290  {
291  Kratos::Serializer particleSerializer;
292  std::stringstream * serializer_buffer;
293  serializer_buffer = (std::stringstream *)particleSerializer.pGetBuffer();
294  serializer_buffer->write(message[i], msgRecvSize[i]);
295  particleSerializer.load("nodes",RecvObjects[i]);
296  }
297 
298  MPI_Barrier(MPI_COMM_WORLD);
299  }
300 
301  // Free buffers
302  for(int i = 0; i < mpi_size; i++)
303  {
304  if(mpi_rank != i && msgRecvSize[i])
305  free(message[i]);
306 
307  if(i != mpi_rank && msgSendSize[i])
308  free(mpi_send_buffer[i]);
309  }
310  Timer::Stop("ASYNC1");
311  }
312 
313  //******************************************************************************************************************
314 
318 
319 
323 
324 
328 
330  virtual std::string Info() const {return " Spatial Containers Configure for Particles"; }
331 
333  virtual void PrintInfo(std::ostream& rOStream) const {}
334 
336  virtual void PrintData(std::ostream& rOStream) const {}
337 
341 
342 
344 
345 protected:
348 
352 
356 
360 
364 
368 
372 
374 
375 private:
378 
382 
386 
390 
394 
398 
402 
405 
408 
410 
411  }; // Class ParticleConfigure
412 
414 
417 
421 
423  template <std::size_t TDimension>
424  inline std::istream& operator >> (std::istream& rIStream, MpiDiscreteParticleConfigure<TDimension> & rThis){
425  return rIStream;
426  }
427 
429  template <std::size_t TDimension>
430  inline std::ostream& operator << (std::ostream& rOStream, const MpiDiscreteParticleConfigure<TDimension>& rThis){
431  rThis.PrintInfo(rOStream);
432  rOStream << std::endl;
433  rThis.PrintData(rOStream);
434 
435  return rOStream;
436  }
437 
439 
440 } // namespace Kratos.
441 #endif /* MPI_DISCRETE_PARTICLE_CONFIGURE_H */
The Commmunicator class manages communication for distributed ModelPart instances.
Definition: communicator.h:67
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: model_part.h:168
Definition: mpi_discrete_particle_configure.h:45
ElementsContainerType::ContainerType ResultContainerType
Definition: mpi_discrete_particle_configure.h:60
virtual std::string Info() const
Turn back information as a string.
Definition: mpi_discrete_particle_configure.h:330
static void CalculateBoundingBox(const PointerType &rObject, PointType &rLowPoint, PointType &rHighPoint)
Definition: mpi_discrete_particle_configure.h:89
ContainerType::value_type PointerType
Definition: mpi_discrete_particle_configure.h:57
static bool IntersectionBox(const PointerType &rObject, const PointType &rLowPoint, const PointType &rHighPoint)
Definition: mpi_discrete_particle_configure.h:147
MpiDiscreteParticleConfigure()
Definition: mpi_discrete_particle_configure.h:74
KRATOS_CLASS_POINTER_DEFINITION(MpiDiscreteParticleConfigure)
Pointer definition of SpatialContainersConfigure.
std::vector< typename Element::Pointer > ContainerType
Definition: mpi_discrete_particle_configure.h:56
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: mpi_discrete_particle_configure.h:336
ContainerType::iterator IteratorType
Definition: mpi_discrete_particle_configure.h:58
std::vector< double >::iterator DistanceIteratorType
Definition: mpi_discrete_particle_configure.h:55
static void AsyncSendAndReceive(std::vector< TObjectType > &SendObjects, std::vector< TObjectType > &RecvObjects, int *msgSendSize, int *msgRecvSize)
Definition: mpi_discrete_particle_configure.h:218
ResultContainerType::iterator ResultIteratorType
Definition: mpi_discrete_particle_configure.h:62
virtual ~MpiDiscreteParticleConfigure()
Definition: mpi_discrete_particle_configure.h:75
static void CalculateCenter(const PointerType &rObject, PointType &rCenter)
Definition: mpi_discrete_particle_configure.h:111
@ DIMENSION
Definition: mpi_discrete_particle_configure.h:49
@ MIN_LEVEL
Definition: mpi_discrete_particle_configure.h:51
@ MAX_LEVEL
Definition: mpi_discrete_particle_configure.h:50
@ Dimension
Definition: mpi_discrete_particle_configure.h:48
static bool Intersection(const PointerType &rObj_1, const PointerType &rObj_2, const double &Radius)
Definition: mpi_discrete_particle_configure.h:130
std::vector< PointerType >::iterator PointerTypeIterator
Definition: mpi_discrete_particle_configure.h:65
static void CalculateBoundingBox(const PointerType &rObject, PointType &rLowPoint, PointType &rHighPoint, const double &Radius)
Definition: mpi_discrete_particle_configure.h:100
static void AsyncSendAndReceive(Communicator::Pointer Communicator, std::vector< TObjectType > &SendObjects, std::vector< TObjectType > &RecvObjects, int *msgSendSize, int *msgRecvSize)
Definition: mpi_discrete_particle_configure.h:206
static bool Intersection(const PointerType &rObj_1, const PointerType &rObj_2)
Definition: mpi_discrete_particle_configure.h:118
Point PointType
Definition: mpi_discrete_particle_configure.h:54
ModelPart::ElementsContainerType ElementsContainerType
Definition: mpi_discrete_particle_configure.h:59
ResultContainerType::value_type ResultPointerType
Definition: mpi_discrete_particle_configure.h:61
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: mpi_discrete_particle_configure.h:333
static void Distance(const PointerType &rObj_1, const PointerType &rObj_2, double &distance)
Definition: mpi_discrete_particle_configure.h:175
static bool IntersectionBox(const PointerType &rObject, const PointType &rLowPoint, const PointType &rHighPoint, const double &Radius)
Definition: mpi_discrete_particle_configure.h:163
static void ReduceIds(int &total_elements, int &first_element)
Definition: mpi_discrete_particle_configure.h:186
Point class.
Definition: point.h:59
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
void load(std::string const &rTag, TDataType &rObject)
Definition: serializer.h:207
void save(std::string const &rTag, std::array< TDataType, TDataSize > const &rObject)
Definition: serializer.h:545
BufferType * pGetBuffer()
Definition: serializer.h:903
static void Start(std::string const &rIntervalName)
This method starts the timer meassures.
Definition: timer.cpp:109
static void Stop(std::string const &rIntervalName)
This method stops the timer meassures.
Definition: timer.cpp:125
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
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
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
float radius
Definition: mesh_to_mdpa_converter.py:18
int j
Definition: quadrature.py:648
distance_2
Definition: sp_statistics.py:71
integer i
Definition: TensorModule.f:17
Configure::ContainerType ContainerType
Definition: transfer_utility.h:247