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.
tetgen_pfem_contact.h
Go to the documentation of this file.
1 //
2 // Project Name: Kratos
3 // Last Modified by: $Author: kazem $
4 // Date: $Date: 2009-01-15 14:50:34 $
5 // Revision: $Revision: 1.8 $
6 //
7 
8 
9 
10 
11 #if !defined(KRATOS_TETGEN_PFEM_CONTACT_H_INCLUDED )
12 #define KRATOS_TETGEN_PFEM_CONTACT_H_INCLUDED
13 
14 
15 
16 // System includes
17 #include <string>
18 #include <iostream>
19 #include <cstdlib>
20 #include <boost/timer.hpp>
21 
22 
23 
24 #include "tetgen.h" // Defined tetgenio, tetrahedralize().
25 
26 // Project includes
27 #include "includes/define.h"
28 #include "utilities/geometry_utilities.h"
29 #include "includes/model_part.h"
33 
35 //#include "containers/bucket.h"
36 //#include "containers/kd_tree.h"
37 //#include "external_includes/trigen_refine.h"
38 namespace Kratos
39 {
40 
41 
44 
48 
52 
56 
60 
62 
65 {
66 public:
69 
72 
76 
78  TetGenPfemContact() = default;
79 
81  virtual ~TetGenPfemContact() = default;
82 
83 
87 
88 
92 
93 
94  //*******************************************************************************************
95  //*******************************************************************************************
97  ModelPart& ThisModelPart ,
98  Element const& rReferenceElement,
99  Condition const& rReferenceBoundaryCondition
100  )
101  {
102 
103  KRATOS_TRY
104  KRATOS_WATCH(">>>>>>> INSIDE MESHER <<<<<<<<<");
105  std::vector <int> shell_list;
106  shell_list.clear();
107  int shell_num = 0;
108  ModelPart::NodesContainerType shell_nodes;
109 
110  for(ModelPart::ElementsContainerType::iterator elem = ThisModelPart.ElementsBegin();
111  elem!=ThisModelPart.ElementsEnd(); elem++)
112  {
113  Geometry< Node >& geom = elem->GetGeometry();
114 //KRATOS_WATCH(geom);
115 
116  shell_nodes.push_back(geom(0));
117  shell_nodes.push_back(geom(1));
118  shell_nodes.push_back(geom(2));
119 
120  }
121 
122  shell_nodes.Unique();
123 
124  ModelPart::NodesContainerType::iterator nodes_begin = shell_nodes.begin();
125  for(unsigned int ii=0; ii < shell_nodes.size(); ii++)
126  ( nodes_begin + ii ) ->SetId( ii + 1 );
127 
128  for(ModelPart::ElementsContainerType::iterator elem = ThisModelPart.ElementsBegin();
129  elem!=ThisModelPart.ElementsEnd(); elem++)
130  {
131  ++shell_num;
132  Geometry< Node >& geom = elem->GetGeometry();
133  shell_list.push_back(geom[0].Id());
134  shell_list.push_back(geom[1].Id());
135  shell_list.push_back(geom[2].Id());
136  }
137 
138  //mesh generation
139  tetgenio in_shell, out_shell;
140 
141  in_shell.firstnumber = 1;
142  in_shell.numberofpoints = shell_nodes.size();
143  in_shell.pointlist = new REAL[in_shell.numberofpoints * 3];
144 
145 
146  tetgenio::facet *f;
147  tetgenio::polygon *p;
148  //give the corrdinates to the mesher
149  for(unsigned int i = 0; i<shell_nodes.size(); i++)
150  {
151  int base = i*3;
152  in_shell.pointlist[base] = (nodes_begin + i)->X();
153  in_shell.pointlist[base+1] = (nodes_begin + i)->Y();
154  in_shell.pointlist[base+2] = (nodes_begin + i)->Z();
155  }
156 
157 
158  if(shell_num != 0)
159  {
160  int cnt = 0;
161  in_shell.numberoffacets = shell_num;
162  in_shell.facetmarkerlist = new int[in_shell.numberoffacets];
163  in_shell.facetlist = new tetgenio::facet[in_shell.numberoffacets];
164  for(int ii=0; ii<shell_num; ++ii)
165  {
166  f = &in_shell.facetlist[ii];
167  f->numberofpolygons = 1;
168  f->polygonlist = new tetgenio::polygon[f->numberofpolygons];
169  f->numberofholes = 0;
170  f->holelist = nullptr;
171 
172 
173  p = &f->polygonlist[0];
174  p->numberofvertices = 3;
175  p->vertexlist = new int[p->numberofvertices];
176  p->vertexlist[0] = shell_list[cnt];
177  p->vertexlist[1] = shell_list[cnt + 1];
178  p->vertexlist[2] = shell_list[cnt + 2];
179  cnt +=3;
180 
181  in_shell.facetmarkerlist[ii] = 5;
182  }
183 
184  //holes
185  in_shell.numberofholes = 0;
186  in_shell.holelist = nullptr;
187 
188  }
189 //KRATOS_WATCH("@@@@@@@@@@@@@ before meshing @@@@@@@@@@@@@@@@");
190  // in_shell.save_nodes("shell_mesh_in");
191  // in_shell.save_poly("shell_mesh_in");
192  //char tetgen_options[] = "VMYYJ";pA
193  char tetgen_options[] = "pYYJnQ";
194 
195  //KRATOS_WATCH(in_shell.numberofpoints);
196 
197  tetrahedralize(tetgen_options, &in_shell, &out_shell); //with option to remove slivers
198 
199  // out_shell.save_nodes("shell_mesh_out");
200  // out_shell.save_elements("shell_mesh_out");
201  //out_shell.save_faces("shell_mesh_out");
202  // out_shell.save_neighbors("shell_mesh_out");
203 
204  //deinitialize
205  in_shell.deinitialize();
206  in_shell.initialize();
207 
208  //clear elements
209  ThisModelPart.Elements().clear();
210  //ThisModelPart.Conditions().clear();
211 
212 
213  //add contact elements
214  boost::timer adding_elems;
215  Properties::Pointer properties = ThisModelPart.GetMesh().pGetProperties(1);
216  (ThisModelPart.Elements()).reserve(out_shell.numberoftetrahedra);
217  KRATOS_WATCH(out_shell.numberoftetrahedra);
218  for(int iii = 0; iii< out_shell.numberoftetrahedra; iii++)
219  {
220  int id = iii + 1;
221  int base = iii * 4;
222  //KRATOS_WATCH("inside 1");
224  *( (nodes_begin + out_shell.tetrahedronlist[base]-1).base() ),
225  *( (nodes_begin + out_shell.tetrahedronlist[base+1]-1).base() ),
226  *( (nodes_begin + out_shell.tetrahedronlist[base+2]-1).base() ),
227  *( (nodes_begin + out_shell.tetrahedronlist[base+3]-1).base() )
228  );
229 //KRATOS_WATCH(geom);
230 //KRATOS_WATCH("AFTER GEOM");
231  Element::Pointer p_element = rReferenceElement.Create(id, geom, properties);
232  p_element->GetValue(IS_FLUID) = 10; //before IS_CONTACT_MASTER
233  p_element->GetValue(IS_WATER_ELEMENT) = -10.0;
234  //KRATOS_WATCH("inside 12");
235 
236  (ThisModelPart.Elements()).push_back(p_element);
237 //KRATOS_WATCH(p_element->GetGeometry());
238 //KRATOS_WATCH("After get geometry");
239 
240  }
241  KRATOS_WATCH("After adding elements");
242  ThisModelPart.Elements().Sort();
243 
244  boost::timer adding_neighb;
245 // //filling the neighbour list
246  ModelPart::ElementsContainerType::const_iterator el_begin = ThisModelPart.ElementsBegin();
247  for(ModelPart::ElementsContainerType::const_iterator iii = ThisModelPart.ElementsBegin();
248  iii != ThisModelPart.ElementsEnd(); iii++)
249  {
250  //Geometry< Node >& geom = iii->GetGeometry();
251  int base = ( iii->Id() - 1 )*4;
252 
253  (iii->GetValue(NEIGHBOUR_ELEMENTS)).resize(4);
254  GlobalPointersVector< Element >& neighb = iii->GetValue(NEIGHBOUR_ELEMENTS);
255 
256  for(int i = 0; i<4; i++)
257  {
258  int index = out_shell.neighborlist[base+i];
259  if(index > 0)
260  neighb(i) = GlobalPointer<Element>(&*(el_begin + index-1)); //*((el_begin + index-1).base());
261  else
262  neighb(i) = Element::WeakPointer();//*(iii.base());
263  }
264  }
265  std::cout << "time for adding neigbours" << adding_neighb.elapsed() << std::endl;;
266 
267  //***********************************************************************************
268  //***********************************************************************************
269  //mark boundary nodes
270  //reset the boundary flag
271  /*
272  for(ModelPart::NodesContainerType::const_iterator in = ThisModelPart.NodesBegin(); in!=ThisModelPart.NodesEnd(); in++)
273  {
274  in->FastGetSolutionStepValue(IS_BOUNDARY) = 0;
275  }
276  */
277 
278  //***********************************************************************************
279  //***********************************************************************************
280  /* boost::timer adding_faces;
281  KRATOS_WATCH(out_shell.numberoftrifaces);
282  (ThisModelPart.Conditions()).reserve(out_shell.numberoftrifaces );
283 
284  //creating the faces
285  for(ModelPart::ElementsContainerType::const_iterator iii = ThisModelPart.ElementsBegin();
286  iii != ThisModelPart.ElementsEnd(); iii++)
287  {
288 
289  int base = ( iii->Id() - 1 )*4;
290 
291  //create boundary faces and mark the boundary nodes
292  //each face is opposite to the corresponding node number so
293  // 0 ----- 1 2 3
294  // 1 ----- 0 3 2
295  // 2 ----- 0 1 3
296  // 3 ----- 0 2 1
297 
298  //node 1
299  KRATOS_WATCH(rReferenceBoundaryCondition);
300  KRATOS_WATCH(properties);
301  //if( neighb(0).expired() );
302  if( out_shell.neighborlist[base] == -1)
303  {
304  CreateBoundaryFace(1, 2, 3, ThisModelPart, 0, *(iii.base()), properties,rReferenceBoundaryCondition );
305  }
306  //if(neighb(1).expired() );
307  if( out_shell.neighborlist[base+1] == -1)
308  {
309  CreateBoundaryFace(0,3,2, ThisModelPart, 1, *(iii.base()), properties, rReferenceBoundaryCondition );
310  }
311  if( out_shell.neighborlist[base+2] == -1)
312  //if(neighb(2).expired() );
313  {
314  CreateBoundaryFace(0,1,3, ThisModelPart, 2, *(iii.base()), properties, rReferenceBoundaryCondition );
315  }
316  if( out_shell.neighborlist[base+3] == -1)
317  //if(neighb(3).expired() );
318  {
319  CreateBoundaryFace(0,2,1, ThisModelPart, 3, *(iii.base()), properties, rReferenceBoundaryCondition );
320  }
321 
322  }
323 
324  std::cout << "time for adding faces" << adding_faces.elapsed() << std::endl;;
325  */
326  out_shell.deinitialize();
327  out_shell.initialize();
328 
329  shell_nodes.clear();
330  shell_list.clear();
331 
332  KRATOS_WATCH(">>>>>>>>>>>>>>>>>>>>< BYE BYE MESHER <<<<<<<<<<<<<<<<<<<<<<<<");
333  KRATOS_CATCH("")
334  }
335 
339 
340 
344 
345 
349 
351  virtual std::string Info() const
352  {
353  return "";
354  }
355 
357  virtual void PrintInfo(std::ostream& rOStream) const {}
358 
360  virtual void PrintData(std::ostream& rOStream) const {}
361 
362 
366 
367 
369 
370 protected:
373 
374 
378 
379 
383 
384 
388 
389 
393 
394 
398 
399 
403 
404 
406 
407 private:
410  /*
411  void CreateBoundaryFace(const int& i1, const int& i2, const int& i3, ModelPart& ThisModelPart, const int& outer_node_id, Element::Pointer origin_element, Properties::Pointer properties,Condition const& rReferenceBoundaryCondition)
412  {
413  KRATOS_TRY
414  KRATOS_WATCH("inside create boundary");
415  Geometry<Node >& geom = origin_element->GetGeometry();
416  //mark the nodes as free surface
417  geom[i1].FastGetSolutionStepValue(IS_BOUNDARY) = 1;
418  geom[i2].FastGetSolutionStepValue(IS_BOUNDARY) = 1;
419  geom[i3].FastGetSolutionStepValue(IS_BOUNDARY) = 1;
420 
421  //generate a face condition
422  Condition::NodesArrayType temp;
423  temp.reserve(3);
424  temp.push_back(geom(i1));
425  temp.push_back(geom(i2));
426  temp.push_back(geom(i3));
427  KRATOS_WATCH("face is created 1");
428  KRATOS_WATCH(geom);
429  KRATOS_WATCH(properties);
430  KRATOS_WATCH(rReferenceBoundaryCondition);
431  Geometry< Node >::Pointer cond = Geometry< Node >::Pointer(new Triangle3D3< Node >(temp) );
432  //Geometry< Node >::Pointer cond = Geometry< Node >::Pointer(new Triangle3D< Node >(temp) );
433  int id = (origin_element->Id()-1)*4;
434  //Condition::Pointer p_cond = Condition::Pointer(new Condition(id, cond, properties) );
435  //Condition::Pointer p_cond = rReferenceBoundaryCondition::Pointer(new Condition(id, cond, properties) );
436  Condition::Pointer p_cond = rReferenceBoundaryCondition.Create(id, temp, properties);
437  //assigning the neighbour node
438  KRATOS_WATCH("face is created 2");
439  (p_cond->GetValue(NEIGHBOUR_NODES)).clear();
440  (p_cond->GetValue(NEIGHBOUR_NODES)).push_back( Node::WeakPointer( geom(outer_node_id) ) );
441  (p_cond->GetValue(NEIGHBOUR_ELEMENTS)).clear();
442  (p_cond->GetValue(NEIGHBOUR_ELEMENTS)).push_back( Element::WeakPointer( origin_element ) );
443  ThisModelPart.Conditions().push_back(p_cond);
444  KRATOS_CATCH("")
445  KRATOS_WATCH("face is created");
446  }
447  */
448 
450 
454 
455 
459 
463 
464 
465 
466 
467  //**********************************************************************************************
468  //**********************************************************************************************
469 
473 
474 
478 
479 
483 
485  TetGenPfemContact& operator=(TetGenPfemContact const& rOther);
486 
487 
489 
490 }; // Class TetGenPfemModeler
491 
493 
496 
497 
501 
502 
504 inline std::istream& operator >> (std::istream& rIStream,
505  TetGenPfemContact& rThis);
506 
508 inline std::ostream& operator << (std::ostream& rOStream,
509  const TetGenPfemContact& rThis)
510 {
511  rThis.PrintInfo(rOStream);
512  rOStream << std::endl;
513  rThis.PrintData(rOStream);
514 
515  return rOStream;
516 }
518 
519 
520 } // namespace Kratos.
521 
522 #endif // KRATOS_TETGEN_PFEM_CONTACT_H_INCLUDED
523 
524 
Base class for all Conditions.
Definition: condition.h:59
Base class for all Elements.
Definition: element.h:60
virtual Pointer Create(IndexType NewId, NodesArrayType const &ThisNodes, PropertiesType::Pointer pProperties) const
It creates a new element pointer.
Definition: element.h:202
Geometry base class.
Definition: geometry.h:71
void push_back(PointPointerType x)
Definition: geometry.h:548
This class is a wrapper for a pointer to a data that is located in a different rank.
Definition: global_pointer.h:44
PropertiesType::Pointer pGetProperties(IndexType PropertiesId)
Definition: mesh.h:394
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ElementIterator ElementsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1169
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: model_part.h:128
ElementIterator ElementsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1179
MeshType & GetMesh(IndexType ThisIndex=0)
Definition: model_part.h:1791
Short class definition.
Definition: tetgen_pfem_contact.h:65
void ReGenerateMesh(ModelPart &ThisModelPart, Element const &rReferenceElement, Condition const &rReferenceBoundaryCondition)
Definition: tetgen_pfem_contact.h:96
virtual std::string Info() const
Turn back information as a string.
Definition: tetgen_pfem_contact.h:351
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: tetgen_pfem_contact.h:357
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: tetgen_pfem_contact.h:360
virtual ~TetGenPfemContact()=default
Destructor.
TetGenPfemContact()=default
Default constructor.
KRATOS_CLASS_POINTER_DEFINITION(TetGenPfemContact)
Pointer definition of TetGenPfemRefineFace.
A four node tetrahedra geometry with linear shape functions.
Definition: tetrahedra_3d_4.h:59
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_WATCH(variable)
Definition: define.h:806
#define KRATOS_TRY
Definition: define.h:109
#define REAL
Definition: delaunator_utilities.cpp:16
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
f
Definition: generate_convection_diffusion_explicit_element.py:112
p
Definition: sensitivityMatrix.py:52
integer i
Definition: TensorModule.f:17