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.
nodal_neighbours_search_process.hpp
Go to the documentation of this file.
1 //
2 // Project Name: KratosDelaunayMeshingApplication $
3 // Created by: $Author: JMCarbonell $
4 // Last modified by: $Co-Author: $
5 // Date: $Date: April 2018 $
6 // Revision: $Revision: 0.0 $
7 //
8 //
9 
10 #if !defined(KRATOS_NODAL_NEIGHBOURS_SEARCH_PROCESS_H_INCLUDED )
11 #define KRATOS_NODAL_NEIGHBOURS_SEARCH_PROCESS_H_INCLUDED
12 
13 // System includes
14 #include <string>
15 #include <iostream>
16 
17 // External includes
18 
19 // Project includes
20 #include "includes/define.h"
21 #include "processes/process.h"
22 #include "includes/node.h"
23 #include "includes/element.h"
24 #include "includes/model_part.h"
25 #include "utilities/openmp_utils.h"
27 
28 namespace Kratos
29 {
44 
46 
49  : public MesherProcess
50 {
51  public:
56 
59 
66 
72  int EchoLevel = 0,
73  int AverageElements = 10,
74  int AverageNodes = 10)
75  : mrModelPart(rModelPart)
76  {
77  mAverageElements = AverageNodes;
78  mAverageNodes = AverageElements;
79  mEchoLevel = EchoLevel;
80  }
81 
84  {
85  }
86 
90 
91  void operator()()
92  {
93  Execute();
94  }
95 
96 
100 
101  void Execute() override
102  {
103  bool success=false;
104 
105  int method = 0; //Kratos or Lohner method
106 
107  // double begin_time = OpenMPUtils::GetCurrentTime();
108 
109  if(method==0)
110  {
111  success=KratosSearch();
112  }
113  else
114  {
115  success=LohnerSearch(); //seems to be worse (needs to be optimized)
116  }
117 
118 
119  if(!success)
120  {
121  std::cout<<" ERROR: Nodal Neighbours Search FAILED !!! "<<std::endl;
122  }
123  // else
124  // {
125  // //print out the mesh generation time
126  // if( mEchoLevel > 1 ){
127  // double end_time = OpenMPUtils::GetCurrentTime();
128  // std::cout<<" Neighbour Nodes Search time = "<<end_time-begin_time<<std::endl;
129  // }
130  // //PrintNodeNeighbours();
131  // }
132 
133  };
134 
136  {
137  for(auto& i_node : mrModelPart.Nodes())
138  {
139  i_node.GetValue(NEIGHBOUR_ELEMENTS).clear();
140  i_node.GetValue(NEIGHBOUR_NODES).clear();
141  }
142  }
143 
147 
148 
152 
153 
157 
159  std::string Info() const override
160  {
161  return "NodalNeighboursSearchProcess";
162  }
163 
165  void PrintInfo(std::ostream& rOStream) const override
166  {
167  rOStream << "NodalNeighboursSearchProcess";
168  }
169 
171  void PrintData(std::ostream& rOStream) const override
172  {
173  }
174 
175 
179 
180 
182 
183  protected:
186 
187 
191 
192 
196 
197 
201 
202 
206 
207 
211 
212 
216 
217 
219 
220  private:
226  ModelPart& mrModelPart;
227  int mAverageElements;
228  int mAverageNodes;
229  int mEchoLevel;
230 
234  template<class TDataType> void AddUniquePointer
235  (GlobalPointersVector<TDataType>& v, const typename TDataType::WeakPointer candidate)
236  {
238  typename GlobalPointersVector< TDataType >::iterator endit = v.end();
239  while ( i != endit && (i)->Id() != (candidate)->Id())
240  {
241  i++;
242  }
243  if( i == endit )
244  {
245  v.push_back(candidate);
246  }
247 
248  }
249 
250  void CleanNodeNeighbours()
251  {
252  //************* Erase old node neighbours *************//
253  for(auto& i_node : mrModelPart.Nodes())
254  {
255  NodeWeakPtrVectorType& nNodes = i_node.GetValue(NEIGHBOUR_NODES);
256  nNodes.clear();
257  nNodes.reserve(mAverageNodes);
258 
259  ElementWeakPtrVectorType& nElements = i_node.GetValue(NEIGHBOUR_ELEMENTS);
260  nElements.clear();
261  nElements.reserve(mAverageElements);
262 
263  //set fixed nodes as Nodes<3>::STRUCTURE to not be removed in the meshing
264  for(const auto& i_dof : i_node.GetDofs())
265  {
266  if(i_dof->IsFixed())
267  {
268  i_node.Set(STRUCTURE);
269  break;
270  }
271  }
272 
273  }
274  //std::cout<<" [ Node Neighbours CLEAN ] "<<std::endl;
275  }
276 
277 
278  void PrintNodeNeighbours()
279  {
280  NodesContainerType& rNodes = mrModelPart.Nodes();
281  std::cout<<" NODES: neighbour elems: "<<std::endl;
282  for(auto& i_node : mrModelPart.Nodes())
283  {
284  std::cout<<"["<<i_node.Id()<<"]:"<<std::endl;
285  std::cout<<"( ";
286  ElementWeakPtrVectorType& nElements = i_node.GetValue(NEIGHBOUR_ELEMENTS);
287  for(auto& i_nelem : nElements)
288  {
289  std::cout<< i_nelem.Id()<<", ";
290  }
291  std::cout<<" )"<<std::endl;
292  }
293 
294  std::cout<<std::endl;
295 
296  std::cout<<" NODES: neighbour nodes: "<<std::endl;
297 
298  for(auto& i_node : rNodes)
299  {
300  std::cout<<"["<<i_node.Id()<<"]:"<<std::endl;
301  std::cout<<"( ";
302  NodeWeakPtrVectorType& nNodes = i_node.GetValue(NEIGHBOUR_NODES);
303  for(auto& i_nnode : nNodes)
304  {
305  std::cout<< i_nnode.Id()<<", ";
306  }
307  std::cout<<" )"<<std::endl;
308  }
309 
310  std::cout<<std::endl;
311  }
312 
316 
317  bool KratosSearch()
318  {
319  NodesContainerType& rNodes = mrModelPart.Nodes();
320  ElementsContainerType& rElements = mrModelPart.Elements();
321 
322  //************* Erase old node neighbours *************//
323  CleanNodeNeighbours();
324 
325  //************* Neighbours of nodes ************//
326 
327  //add the neighbour elements to all the nodes in the mesh
328  for(auto i_elem(rElements.begin()); i_elem != rElements.end(); ++i_elem)
329  {
330  Element::GeometryType& rGeometry = i_elem->GetGeometry();
331  for(unsigned int i = 0; i < rGeometry.size(); ++i)
332  {
333  rGeometry[i].GetValue(NEIGHBOUR_ELEMENTS).push_back(*i_elem.base());
334  }
335  }
336 
337  //adding the neighbouring nodes to all nodes in the mesh
338  for(auto& i_node : rNodes)
339  {
340  ElementWeakPtrVectorType& nElements = i_node.GetValue(NEIGHBOUR_ELEMENTS);
341  for(auto& i_nelem : nElements)
342  {
343  Element::GeometryType& rGeometry = i_nelem.GetGeometry();
344  for(unsigned int i = 0; i < rGeometry.size(); ++i)
345  {
346  if( rGeometry[i].Id() != i_node.Id() )
347  {
348  NodeWeakPtrVectorType& nNodes = i_node.GetValue(NEIGHBOUR_NODES);
349  AddUniquePointer<Node >(nNodes, rGeometry(i));
350  }
351  }
352  }
353  }
354 
355  return true;
356  }
357 
358 
359  bool LohnerSearch()
360  {
361  NodesContainerType& rNodes = mrModelPart.Nodes();
362  ElementsContainerType& rElements = mrModelPart.Elements();
363 
364  //************* Erase old node neighbours *************//
365  CleanNodeNeighbours();
366 
367  //************* Neighbours of nodes ************//
368  unsigned int Ne=rElements.size();
369  unsigned int Np=rNodes.size();
370 
371  if(Ne==1) return false; //there are no elements
372 
373  //Elements Position vs Nodes
374  std::vector<unsigned int> PSharedE (Np+1); //vector counting shared Elements
375  PSharedE.clear();
376  //Particles Position vs Particles
377  std::vector<unsigned int> PSharedN (Np+1); //vector counting shared Particles
378  PSharedN.clear();
379 
380  std::vector<std::vector<unsigned int> > PSurroundN (Np+1); //General matrix to account Neighbour Particles
381 
382  //ELEMENTS SURROUNDING A POINT
383  //1.- Count the number of elements connected to each point
384  int ipoi1=0;
385  PSharedE[0]=1;
386  PSharedN[0]=1;
387 
388  for(auto& i_elem : rElements)
389  {
390  Element::GeometryType& rGeometry = i_elem.GetGeometry();
391  for(unsigned int i = 0; i < rGeometry.size(); ++i)
392  {
393  ipoi1=rGeometry[i].Id(); //counter
394  PSharedE[ipoi1]+=1; //auxiliar counter: esup2
395  }
396  }
397 
398  Element::GeometryType& rGeometry = rElements.begin()->GetGeometry(); // the first element is taken as reference
399  unsigned int Nn= rGeometry.size();
400 
401  //2.- Reshuffling pass (1)
402  unsigned int pn;
403  for(auto& i_node : rNodes)
404  {
405  pn=i_node.Id();
406  int size= PSharedE[pn]*(Nn-1)+Nn; //it is an estimation of the size like mAverageNodes
407  if(mAverageNodes>size)
408  size=mAverageNodes;
409 
410  i_node.GetValue(NEIGHBOUR_ELEMENTS).resize(PSharedE[pn]);
411  PSurroundN[pn].resize(size);
412  }
413 
414  //3.- Store the elements in PSurroundE
415  for(auto i_elem(rElements.begin()); i_elem != rElements.end(); ++i_elem)
416  {
417  Element::GeometryType& rGeometry = i_elem->GetGeometry();
418  for(unsigned int i = 0; i < rGeometry.size(); ++i)
419  {
420  ipoi1=rGeometry[i].Id(); //counter
421  PSharedE[ipoi1]-=1;
422  //std::cout<<" NODE "<<ie->Id()<<" "<<PSharedE[ipoi1]<<std::endl;
423  ElementWeakPtrVectorType& nElements= rNodes[ipoi1].GetValue(NEIGHBOUR_ELEMENTS);
424  nElements(PSharedE[ipoi1])= *i_elem.base();
425  }
426  }
427 
428  //POINTS SURROUNDING A POINT
429  unsigned int nodeID=0;
430  unsigned int ipn=0;
431  unsigned int rpn=0;
432 
433  PSharedN.clear();
434 
435  for(auto& i_node : rNodes)
436  {
437  ElementWeakPtrVectorType& nElements = i_node.GetValue(NEIGHBOUR_ELEMENTS);
438 
439  rpn = i_node.Id();
440 
441  for(auto& i_nelem : nElements)
442  {
443 
444  Element::GeometryType& rGeometry = i_nelem.GetGeometry();
445 
446  for (unsigned int nd=0; nd<rGeometry.size(); ++nd)
447  {
448  ipn = rGeometry[nd].Id();
449 
450  if(ipn != rpn ) // Process to find the neighbour points of a point
451  {
452  nodeID=1;
453 
454  if (PSharedN[rpn]!=0)
455  {
456  for(unsigned int spn=0; spn<=PSharedN[rpn]; ++spn)
457  {
458  if (PSurroundN[rpn][spn]!=ipn)
459  {
460  nodeID=1;
461  }
462  else
463  {
464  nodeID=0;
465  break;
466  }
467  }
468  }
469 
470  if (nodeID)
471  {
472  PSurroundN[rpn][PSharedN[rpn] ]=ipn;
473  PSharedN[rpn]+=1;
474  }
475  }
476  }
477  }
478 
479  //Set everything on particles
480  NodeWeakPtrVectorType& nNodes = i_node.GetValue(NEIGHBOUR_NODES);
481 
482  for(unsigned int spn=0; spn<PSharedN[rpn]; ++spn)
483  {
484  //std::cout<<" ShNodes "<<PSurroundN[rpn][spn]<<std::endl;
485  AddUniquePointer<Node >(nNodes, rNodes(PSurroundN[rpn][spn]));
486  }
487  }
488 
489  return true;
490  }
491 
501 
504 
506  //NodalNeighboursSearchProcess(NodalNeighboursSearchProcess const& rOther);
507 
509 
510 }; // Class NodalNeighboursSearchProcess
511 
518 
520 inline std::istream& operator >> (std::istream& rIStream,
523 inline std::ostream& operator << (std::ostream& rOStream,
524  const NodalNeighboursSearchProcess& rThis)
525 {
526  rThis.PrintInfo(rOStream);
527  rOStream << std::endl;
528  rThis.PrintData(rOStream);
529 
530  return rOStream;
531 }
533 
534 
535 } // namespace Kratos.
536 
537 #endif // KRATOS_NODAL_NEIGHBOURS_SEARCH_PROCESS_H_INCLUDED defined
Geometry< NodeType > GeometryType
definition of the geometry type with given NodeType
Definition: element.h:83
This class is a vector which stores global pointers.
Definition: global_pointers_vector.h:61
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: global_pointers_vector.h:79
void clear()
Definition: global_pointers_vector.h:361
The base class for processes passed to the solution scheme.
Definition: mesher_process.hpp:37
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
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: model_part.h:128
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
Short class definition.
Definition: nodal_neighbours_search_process.hpp:50
ModelPart::ElementsContainerType ElementsContainerType
Definition: nodal_neighbours_search_process.hpp:58
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: nodal_neighbours_search_process.hpp:165
void ClearNeighbours()
Definition: nodal_neighbours_search_process.hpp:135
GlobalPointersVector< Element > ElementWeakPtrVectorType
Definition: nodal_neighbours_search_process.hpp:61
NodalNeighboursSearchProcess(ModelPart &rModelPart, int EchoLevel=0, int AverageElements=10, int AverageNodes=10)
Definition: nodal_neighbours_search_process.hpp:71
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: nodal_neighbours_search_process.hpp:171
KRATOS_CLASS_POINTER_DEFINITION(NodalNeighboursSearchProcess)
virtual ~NodalNeighboursSearchProcess()
Destructor.
Definition: nodal_neighbours_search_process.hpp:83
ModelPart::NodesContainerType NodesContainerType
Definition: nodal_neighbours_search_process.hpp:57
GlobalPointersVector< Node > NodeWeakPtrVectorType
Definition: nodal_neighbours_search_process.hpp:60
void operator()()
Definition: nodal_neighbours_search_process.hpp:91
GlobalPointersVector< Condition > ConditionWeakPtrVectorType
Definition: nodal_neighbours_search_process.hpp:62
std::string Info() const override
Turn back information as a string.
Definition: nodal_neighbours_search_process.hpp:159
void Execute() override
Execute method is used to execute the MesherProcess algorithms.
Definition: nodal_neighbours_search_process.hpp:101
static int EchoLevel
Definition: co_sim_EMPIRE_API.h:42
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
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
v
Definition: generate_convection_diffusion_explicit_element.py:114
pn
Definition: generate_droplet_dynamics.py:65
integer i
Definition: TensorModule.f:17