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_refine.h
Go to the documentation of this file.
1 //
2 // Project Name: Kratos
3 // Last Modified by: $Author: anonymous $
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_MODELER_H_INCLUDED )
12 #define KRATOS_TETGEN_PFEM_MODELER_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"
37 //#include "containers/bucket.h"
38 //#include "containers/kd_tree.h"
39 //#include "external_includes/trigen_refine.h"
40 namespace Kratos
41 {
42 
43 
46 
50 
54 
58 
62 
64 
67  {
68  public:
71 
74 
78 
81  mJ(ZeroMatrix(3,3)), //local jacobian
82  mJinv(ZeroMatrix(3,3)), //inverse jacobian
83  mc(ZeroVector(3)), //dimension = number of nodes
84  mRhs(ZeroVector(3)){} //dimension = number of nodes
85 
87  virtual ~TetGenPfemModeler()= default;
88 
89 
93 
94 
98 
99 
100  //*******************************************************************************************
101  //*******************************************************************************************
103  ModelPart& ThisModelPart ,
104  Element const& rReferenceElement,
105  Condition const& rReferenceBoundaryCondition,
106  EntitiesEraseProcess<Node>& node_erase, bool rem_nodes = true, bool add_nodes=true,
107  double alpha_param = 1.4, double h_factor=0.5)
108  {
109 
110  KRATOS_TRY
111  if (ThisModelPart.NodesBegin()->SolutionStepsDataHas(IS_FREE_SURFACE)==false )
112  KRATOS_THROW_ERROR(std::logic_error,"Add ----IS_FREE_SURFACE---- variable!!!!!! ERROR","");
113  if (ThisModelPart.NodesBegin()->SolutionStepsDataHas(IS_STRUCTURE)==false )
114  KRATOS_THROW_ERROR(std::logic_error,"Add ----IS_STRUCTURE---- variable!!!!!! ERROR","");
115  if (ThisModelPart.NodesBegin()->SolutionStepsDataHas(IS_BOUNDARY)==false )
116  KRATOS_THROW_ERROR(std::logic_error,"Add ----IS_BOUNDARY---- variable!!!!!! ERROR","");
117  if (ThisModelPart.NodesBegin()->SolutionStepsDataHas(IS_FLUID)==false )
118  KRATOS_THROW_ERROR(std::logic_error,"Add ----IS_FLUID---- variable!!!!!! ERROR","");
119 
120  KRATOS_WATCH(" ENTERED TETGENMESHSUITE PFEM of Meshing Application")
121 
122  //clearing elements
123 
124  ThisModelPart.Elements().clear();
125  ThisModelPart.Conditions().clear();
126 
127  boost::timer auxiliary;
129  typedef Node PointType;
130  typedef Node::Pointer PointPointerType;
131  //typedef PointerVector<PointType> PointVector;
132  typedef std::vector<PointType::Pointer> PointVector;
133  typedef PointVector::iterator PointIterator;
134  typedef std::vector<double> DistanceVector;
135  typedef std::vector<double>::iterator DistanceIterator;
136 
137  int step_data_size = ThisModelPart.GetNodalSolutionStepDataSize();
138 
139  // bucket types
140  //typedef Bucket<3, PointType, ModelPart::NodesContainerType, PointPointerType, PointIterator, DistanceIterator > BucketType;
141  //typedef Bins< 3, PointType, PointVector, PointPointerType, PointIterator, DistanceIterator > StaticBins;
142  // bucket types
144 
145 
146  //*************
147  // DynamicBins;
148  typedef Tree< KDTreePartition<BucketType> > kd_tree; //Kdtree;
149  //typedef Tree< StaticBins > Bin; //Binstree;
150  unsigned int bucket_size = 20;
151 
152  //performing the interpolation - all of the nodes in this list will be preserved
153  unsigned int max_results = 50;
154  //PointerVector<PointType> res(max_results);
155  //NodeIterator res(max_results);
156  PointVector res(max_results);
157  DistanceVector res_distances(max_results);
158  Node work_point(0,0.0,0.0,0.0);
159  KRATOS_WATCH(h_factor)
160  //if the remove_node switch is activated, we check if the nodes got too close
161  if (rem_nodes==true)
162  {
163 
164  PointVector list_of_nodes;
165  list_of_nodes.reserve(ThisModelPart.Nodes().size());
166  for(ModelPart::NodesContainerType::iterator i_node = ThisModelPart.NodesBegin() ; i_node != ThisModelPart.NodesEnd() ; i_node++)
167  {
168  (list_of_nodes).push_back(*(i_node.base()));
169  //(list_of_nodes).push_back(i_node.base());
170  }
171 
172  kd_tree nodes_tree1(list_of_nodes.begin(),list_of_nodes.end(), bucket_size);
173  //std::cout<<nodes_tree2<<std::endl;
174 
175  unsigned int n_points_in_radius;
176  //radius means the distance, closer than which no node shall be allowd. if closer -> mark for erasing
177  double radius;
178 
179  for(ModelPart::NodesContainerType::const_iterator in = ThisModelPart.NodesBegin();
180  in != ThisModelPart.NodesEnd(); in++)
181  {
182  radius=h_factor*in->FastGetSolutionStepValue(NODAL_H);
183 
184  work_point[0]=in->X();
185  work_point[1]=in->Y();
186  work_point[2]=in->Z();
187 
188  n_points_in_radius = nodes_tree1.SearchInRadius(work_point, radius, res.begin(),res_distances.begin(), max_results);
189  if (n_points_in_radius>1)
190  {
191  if (in->FastGetSolutionStepValue(IS_BOUNDARY)==0.0 && in->FastGetSolutionStepValue(IS_STRUCTURE)==0.0 && in->FastGetSolutionStepValue(IS_LAGRANGIAN_INLET)==0.0)
192  {
193  in->Set(TO_ERASE,true);
194  //below is just for the bladder example
195 
196  }
197  }
198 
199  }
200 
201  node_erase.Execute();
202  }
206 
207 
208  tetgenio in, out, in2, outnew;
209 
210  // All indices start from 1.
211  in.firstnumber = 1;
212 
213  in.numberofpoints = ThisModelPart.Nodes().size();
214  in.pointlist = new REAL[in.numberofpoints * 3];
215 
216  //writing the point coordinates in a vector
217  ModelPart::NodesContainerType::iterator nodes_begin = ThisModelPart.NodesBegin();
218 
219  //reorder node Ids
220  for(unsigned int i = 0; i<ThisModelPart.Nodes().size(); i++)
221  {
222  (nodes_begin + i)->SetId(i+1);
223 // (nodes_begin + i)->Id() = i+1;
224  }
225 
226  //give the corrdinates to the mesher
227  for(unsigned int i = 0; i<ThisModelPart.Nodes().size(); i++)
228  {
229  int base = i*3;
230  in.pointlist[base] = (nodes_begin + i)->X();
231  in.pointlist[base+1] = (nodes_begin + i)->Y();
232  in.pointlist[base+2] = (nodes_begin + i)->Z();
233  }
234  char tetgen_options[] = "SQJ";
235 
236 
237  tetrahedralize(tetgen_options, &in, &out); //with option to remove slivers
238 
239 
240  double first_part_time = auxiliary.elapsed();
241  std::cout << "mesh generation time = " << first_part_time << std::endl;
242 
243  //generate Kratos Tetrahedra3D4
244  int el_number = out.numberoftetrahedra;
245 
246  boost::timer alpha_shape_time;
247  //calculate r , center for all of the elements
248  std::vector<int> preserved_list(el_number);
249  array_1d<double,3> x1,x2,x3,x4, xc;
250  int point_base;
251  int number_of_preserved_elems = 0;
252  for(int el = 0; el< el_number; el++)
253  {
254  int base = el * 4;
255 
256  //coordinates
257  point_base = (out.tetrahedronlist[base] - 1)*3;
258  x1[0] = out.pointlist[point_base];
259  x1[1] = out.pointlist[point_base+1];
260  x1[2] = out.pointlist[point_base+2];
261 
262  point_base = (out.tetrahedronlist[base+1] - 1)*3;
263  x2[0] = out.pointlist[point_base];
264  x2[1] = out.pointlist[point_base+1];
265  x2[2] = out.pointlist[point_base+2];
266 
267  point_base = (out.tetrahedronlist[base+2] - 1)*3;
268  x3[0] = out.pointlist[point_base];
269  x3[1] = out.pointlist[point_base+1];
270  x3[2] = out.pointlist[point_base+2];
271 
272  point_base = (out.tetrahedronlist[base+3] - 1)*3;
273  x4[0] = out.pointlist[point_base];
274  x4[1] = out.pointlist[point_base+1];
275  x4[2] = out.pointlist[point_base+2];
276 
277  //calculate the geometrical data
278  //degenerate elements are given a very high radius
279  double geometrical_hmin, geometrical_hmax;
280  double radius;
281  double vol;
282  CalculateElementData(x1,x2,x3,x4,vol,xc,radius,geometrical_hmin,geometrical_hmax);
283 
284  //calculate the prescribed h
285  double prescribed_h = (nodes_begin + out.tetrahedronlist[base]-1)->FastGetSolutionStepValue(NODAL_H);
286  prescribed_h += (nodes_begin + out.tetrahedronlist[base+1]-1)->FastGetSolutionStepValue(NODAL_H);
287  prescribed_h += (nodes_begin + out.tetrahedronlist[base+2]-1)->FastGetSolutionStepValue(NODAL_H);
288  prescribed_h += (nodes_begin + out.tetrahedronlist[base+3]-1)->FastGetSolutionStepValue(NODAL_H);
289  prescribed_h *= 0.25;
290 
291  //check the number of nodes on the wall
292  int nb = int( (nodes_begin + out.tetrahedronlist[base]-1)->FastGetSolutionStepValue(IS_STRUCTURE) );
293  nb += int( (nodes_begin + out.tetrahedronlist[base+1]-1)->FastGetSolutionStepValue(IS_STRUCTURE) );
294  nb += int( (nodes_begin + out.tetrahedronlist[base+2]-1)->FastGetSolutionStepValue(IS_STRUCTURE) );
295  nb += int((nodes_begin + out.tetrahedronlist[base+3]-1)->FastGetSolutionStepValue(IS_STRUCTURE) );
296 
297  //check the number of nodes of bo node_erase.Execute();undary
298  int nfs = int( (nodes_begin + out.tetrahedronlist[base]-1)->FastGetSolutionStepValue(IS_FREE_SURFACE) );
299  nfs += int( (nodes_begin + out.tetrahedronlist[base+1]-1)->FastGetSolutionStepValue(IS_FREE_SURFACE) );
300  nfs += int( (nodes_begin + out.tetrahedronlist[base+2]-1)->FastGetSolutionStepValue(IS_FREE_SURFACE) );
301  nfs += int((nodes_begin + out.tetrahedronlist[base+3]-1)->FastGetSolutionStepValue(IS_FREE_SURFACE) );
302 
303  //check the number of nodes of boundary
304  int nfluid = int( (nodes_begin + out.tetrahedronlist[base]-1)->FastGetSolutionStepValue(IS_FLUID) );
305  nfluid += int( (nodes_begin + out.tetrahedronlist[base+1]-1)->FastGetSolutionStepValue(IS_FLUID) );
306  nfluid += int( (nodes_begin + out.tetrahedronlist[base+2]-1)->FastGetSolutionStepValue(IS_FLUID) );
307  nfluid += int((nodes_begin + out.tetrahedronlist[base+3]-1)->FastGetSolutionStepValue(IS_FLUID) );
308 
309  int n_lag = int( (nodes_begin + out.tetrahedronlist[base]-1)->FastGetSolutionStepValue(IS_LAGRANGIAN_INLET) );
310  n_lag += int( (nodes_begin + out.tetrahedronlist[base+1]-1)->FastGetSolutionStepValue(IS_LAGRANGIAN_INLET) );
311  n_lag += int( (nodes_begin + out.tetrahedronlist[base+2]-1)->FastGetSolutionStepValue(IS_LAGRANGIAN_INLET) );
312  n_lag += int((nodes_begin + out.tetrahedronlist[base+3]-1)->FastGetSolutionStepValue(IS_LAGRANGIAN_INLET) );
313 
314 
315  //cases:
316  //4 nodes on the wall - elminate
317  // at least one node of boundary OR at least one node NOT of fluid --> pass alpha shape
318  /*
319  if(nb == 4) // 4 nodes on the wall
320  preserved_list[el] = false;
321  else if (nboundary != 0 || nfluid != 4) //close to the free surface or external
322  {
323  if( radius < prescribed_h * alpha_param && //alpha shape says to preserve
324  nb!=4) //the nodes are not all on the boundary
325  {
326  preserved_list[el] = true; //preserve!!
327  number_of_preserved_elems += 1;
328  }
329  }
330  else
331  {
332  preserved_list[el] = true;
333  number_of_preserved_elems += 1;
334  }
335  */
336  if(nb == 4) // 4 nodes on the wall
337  {
338  preserved_list[el] = false;
339 
340  }
341  else
342  {
343  //if (nfs != 0 || nfluid != 4) //close to the free surface or external
344  if (n_lag >= 2 && nb==3 ) //close to the free surface or external
345  {
346  if( radius < prescribed_h * 1.5*alpha_param ) //alpha shape says to preserve
347  //the nodes are not all on the boundary
348  {
349  preserved_list[el] = true; //preserve!!
350  number_of_preserved_elems += 1;
351  }
352  else
353  {
354  preserved_list[el] = false;
355 
356  }
357  }
358  else if (nfs != 0 ) //close to the free surface or external
359  {
360  if( radius < prescribed_h * alpha_param ) //alpha shape says to preserve
361  //the nodes are not all on the boundary
362  {
363  preserved_list[el] = true; //preserve!!
364  number_of_preserved_elems += 1;
365  }
366  else
367  {
368  preserved_list[el] = false;
369 
370  }
371  }
372 
373 
374  else if (nfluid < 3.9) //close to the free surface or external
375  {
376  if( radius < prescribed_h * alpha_param ) //alpha shape says to preserve
377  //the nodes are not all on the boundary
378  {
379  preserved_list[el] = true; //preserve!!
380  number_of_preserved_elems += 1;
381  }
382  else
383  {
384  preserved_list[el] = false;
385 
386  }
387  }
388 
389  else //internal elements should be preserved as much as possible not to create holes
390  {
391  if( radius < prescribed_h * alpha_param * 5.0 )
392  {
393 //std::cout << "element not deleted" <<std::endl;
394  preserved_list[el] = true; //preserve!!
395  number_of_preserved_elems += 1;
396  }
397  else
398  {
399 //std::cout << "sliver removed" << std::endl;
400  preserved_list[el] = false;
401 
402  }
403 // preserved_list[el] = true;
404 // number_of_preserved_elems += 1;
405  }
406  }
407 
408  }
409  std::cout << "time for passing alpha shape" << alpha_shape_time.elapsed() << std::endl;
410 
411  //freeing unnecessary memory
412  in.deinitialize();
413  in.initialize();
414 
415  //setting the new new ids in a aux vector
416 // tetgenio in2;
417 
418  in2.firstnumber = 1;
419  in2.numberofpoints = ThisModelPart.Nodes().size();
420  in2.pointlist = new REAL[in2.numberofpoints * 3];
421 
422  for(unsigned int i = 0; i<ThisModelPart.Nodes().size(); i++)
423  {
424  int base = i*3;
425  in2.pointlist[base] = (nodes_begin + i)->X();
426  in2.pointlist[base+1] = (nodes_begin + i)->Y();
427  in2.pointlist[base+2] = (nodes_begin + i)->Z();
428  }
429  std::cout << "qui" << std::endl;
430  in2.numberoftetrahedra = number_of_preserved_elems;
431  in2.tetrahedronlist = new int[in2.numberoftetrahedra * 4];
432  in2.tetrahedronvolumelist = new double[in2.numberoftetrahedra];
433 
434  int counter = 0;
435  for(int el = 0; el< el_number; el++)
436  {
437  if( preserved_list[el] )
438  {
439  //saving the compact element list
440  int new_base = counter*4;
441  int old_base = el*4;
442  in2.tetrahedronlist[new_base] = out.tetrahedronlist[old_base];
443  in2.tetrahedronlist[new_base+1] = out.tetrahedronlist[old_base+1];
444  in2.tetrahedronlist[new_base+2] = out.tetrahedronlist[old_base+2];
445  in2.tetrahedronlist[new_base+3] = out.tetrahedronlist[old_base+3];
446 
447  //calculate the prescribed h
448  double prescribed_h = (nodes_begin + out.tetrahedronlist[old_base]-1)->FastGetSolutionStepValue(NODAL_H);
449  prescribed_h += (nodes_begin + out.tetrahedronlist[old_base+1]-1)->FastGetSolutionStepValue(NODAL_H);
450  prescribed_h += (nodes_begin + out.tetrahedronlist[old_base+2]-1)->FastGetSolutionStepValue(NODAL_H);
451  prescribed_h += (nodes_begin + out.tetrahedronlist[old_base+3]-1)->FastGetSolutionStepValue(NODAL_H);
452  prescribed_h *= 0.25;
453  //if h is the height of a perfect tetrahedra, the edge size is edge = sqrt(3/2) h
454  //filling in the list of "IDEAL" tetrahedron volumes=1/12 * (edge)^3 * sqrt(2)~0.11785* h^3=
455  //0.2165063509*h^3
456 
457 
458  //chapuza to be checked - I just didnt want so much of refinement,,,,
459  in2.tetrahedronvolumelist[counter] = 2000.0*0.217*prescribed_h*prescribed_h*prescribed_h;
460 
461 
462  //in2.tetrahedronvolumelist[counter] = 0.217*prescribed_h*prescribed_h*prescribed_h;
463  //in2.tetrahedronvolumelist[counter] = 0.0004;
464  //KRATOS_WATCH(in2.tetrahedronvolumelist[counter])
465  counter += 1;
466  }
467 
468  }
469 
470  //NOW WE SHALL IDENTIFY FLYING NODES
471  /*
472  std::vector<double> aux_before_ref(ThisModelPart.Nodes().size());
473 
474  for (unsigned int i=0; i<aux_before_ref.size();i++)
475  {
476  aux_before_ref[i]=0.0;
477  }
478 
479  for(int el = 0; el< el_number; el++)
480  {
481  int old_base=el*4;
482  if (preserved_list[el]==true)
483  {
484 
485  //we add a non-zero value for the node of the element that has a non-zero value
486  aux_before_ref[out.tetrahedronlist[old_base]-1]+=1;
487  aux_before_ref[out.tetrahedronlist[old_base+1]-1]+=1;
488  aux_before_ref[out.tetrahedronlist[old_base+2]-1]+=1;
489  aux_before_ref[out.tetrahedronlist[old_base+3]-1]+=1;
490  }
491  }
492  */
493  //creating a new mesh
494  boost::timer mesh_recreation_time;
495 
496  //freeing unnecessary memory
497  out.deinitialize();
498  out.initialize();
499 
500 
501  //HERE WE ADD THE VOLUME CONSTRAINT -the desired volume of the equidistant tertrahedra
502  //based upon average nodal_h (that is the "a" switch
503  //char regeneration_options[] = "rQJYq1.8anS";
504  if (add_nodes==true)
505  {
506  char mesh_regen_opts[] = "rQJYYqnS";
507  tetrahedralize(mesh_regen_opts, &in2, &outnew);
508  KRATOS_WATCH("Adaptive remeshing executed")
509  }
510  else
511  {
512  char mesh_regen_opts[] = "rQJYnS";
513  tetrahedralize(mesh_regen_opts, &in2, &outnew);
514  KRATOS_WATCH("Non-Adaptive remeshing executed")
515  }
516 
517  //q - creates quality mesh, with the default radius-edge ratio set to 2.0
518 
519  std::cout << "mesh recreation time" << mesh_recreation_time.elapsed() << std::endl;
520 
521 
522  //PAVEL
523 
524  //putting the new nodes in a spatial container
525  //PointerVector< Element >& neighb
526 
527  /*
528  typedef Node PointType;
529  typedef Node::Pointer PointPointerType;
530  typedef std::vector<PointType::Pointer> PointVector;
531  typedef PointVector::iterator PointIterator;
532  typedef std::vector<double> DistanceVector;
533  typedef std::vector<double>::iterator DistanceIterator;
534 
535  int step_data_size = ThisModelPart.GetNodalSolutionStepDataSize();
536 
537  // bucket types
538  typedef Bucket<3, PointType, PointVector, PointPointerType, PointIterator, DistanceIterator > BucketType;
539  typedef Bins< 3, PointType, PointVector, PointPointerType, PointIterator, DistanceIterator > StaticBins;
540 
541  // DynamicBins;
542  typedef Tree< KDTreePartition<BucketType> > kd_tree; //Kdtree;
543  //typedef Tree< StaticBins > Bin; //Binstree;
544  */
545  PointVector list_of_new_nodes;
546 
547  Node::DofsContainerType& reference_dofs = (ThisModelPart.NodesBegin())->GetDofs();
548 
549  int n_points_before_refinement = in2.numberofpoints;
550  //if the refinement was performed, we need to add it to the model part.
551  if (outnew.numberofpoints>n_points_before_refinement)
552  {
553  for(int i = n_points_before_refinement; i<outnew.numberofpoints;i++)
554  {
555  int id=i+1;
556  int base = i*3;
557  double& x= outnew.pointlist[base];
558  double& y= outnew.pointlist[base+1];
559  double& z= outnew.pointlist[base+2];
560 
561  Node::Pointer pnode = ThisModelPart.CreateNewNode(id,x,y,z);
562 
563  //putting the new node also in an auxiliary list
564  //KRATOS_WATCH("adding nodes to list")
565  list_of_new_nodes.push_back( pnode );
566 
567  //std::cout << "new node id = " << pnode->Id() << std::endl;
568  //generating the dofs
569  for(Node::DofsContainerType::iterator iii = reference_dofs.begin(); iii != reference_dofs.end(); iii++)
570  {
571  Node::DofType &rDof = **iii;
572  Node::DofType::Pointer p_new_dof = pnode->pAddDof( rDof );
573 
574  (p_new_dof)->FreeDof();
575  }
576 
577  }
578  }
579 
580  std::cout << "During refinement we added " << outnew.numberofpoints-n_points_before_refinement<< "nodes " <<std::endl;
581 
582 
583  bucket_size = 50;
584 
585  //performing the interpolation - all of the nodes in this list will be preserved
586  max_results = 800;
587  PointVector results(max_results);
588  DistanceVector results_distances(max_results);
590  //int data_size = ThisModelPart.GetNodalSolutionStepTotalDataSize();
591 
592 
593  //double* work_array;
594  //Node work_point(0,0.0,0.0,0.0);
595 
596 
597 
598  //NOW WE SHALL IDENTIFY LONELY BUT NOT FLYING NODES (compare with the flying nodes identification above (after first remeshing step))
599  /*
600  std::vector<double> aux_after_ref(outnew.numberofpoints);
601 
602  for (unsigned int i=0; i<aux_after_ref.size();i++)
603  {
604  aux_after_ref[i]=0.0;
605  }
606  int el_number_ref= outnew.numberoftetrahedra;
607 
608  for(int el = 0; el< el_number_ref; el++)
609  {
610  int base=el*4;
611 
612 
613  //we add a non-zero value for the node of the element that has a non-zero value
614  aux_after_ref[outnew.tetrahedronlist[base]-1]+=1;
615  aux_after_ref[outnew.tetrahedronlist[base+1]-1]+=1;
616  aux_after_ref[outnew.tetrahedronlist[base+2]-1]+=1;
617  aux_after_ref[outnew.tetrahedronlist[base+3]-1]+=1;
618 
619  }
620  */
621 
622  if(outnew.numberofpoints-n_points_before_refinement > 0) //if we added points
623  {
624  kd_tree nodes_tree2(list_of_new_nodes.begin(),list_of_new_nodes.end(),bucket_size);
625  //std::cout<<nodes_tree2<<std::endl;
626  nodes_begin = ThisModelPart.NodesBegin();
627 
628  for(int el = 0; el< in2.numberoftetrahedra; el++)
629  //for(unsigned int el = 0; el< outnew.numberoftetrahedra; el++)
630  {
631 
632  int base = el * 4;
633  //coordinates
634 
635  point_base = (in2.tetrahedronlist[base] - 1)*3;
636  x1[0] = in2.pointlist[point_base];
637  x1[1] = in2.pointlist[point_base+1];
638  x1[2] = in2.pointlist[point_base+2];
639 
640  point_base = (in2.tetrahedronlist[base+1] - 1)*3;
641  x2[0] = in2.pointlist[point_base];
642  x2[1] = in2.pointlist[point_base+1];
643  x2[2] = in2.pointlist[point_base+2];
644 
645  point_base = (in2.tetrahedronlist[base+2] - 1)*3;
646  x3[0] = in2.pointlist[point_base];
647  x3[1] = in2.pointlist[point_base+1];
648  x3[2] = in2.pointlist[point_base+2];
649 
650  point_base = (in2.tetrahedronlist[base+3] - 1)*3;
651  x4[0] = in2.pointlist[point_base];
652  x4[1] = in2.pointlist[point_base+1];
653  x4[2] = in2.pointlist[point_base+2];
654 
655  //calculate the geometrical data
656  //degenerate elements are given a very high radius
657  double geometrical_hmin, geometrical_hmax;
658  double radius;
659  double vol;
660 
662 
663  //it calculates the data necessary to perfom the search, like the element center etc., search radius
664  //and writes it to radius, xc etc etc
665 
666  CalculateElementData(x1,x2,x3,x4,vol,xc,radius,geometrical_hmin,geometrical_hmax);
667 
668  //find all of the nodes in a radius centered in xc
669 
670  std::size_t number_of_points_in_radius;
671  work_point.X() = xc[0]; work_point.Y() = xc[1]; work_point.Z() = xc[2];
672 
673  number_of_points_in_radius = nodes_tree2.SearchInRadius(work_point, radius, results.begin(),results_distances.begin(), max_results);
674 
675 
676  //for each of the nodes in radius find if it is inside the element or not
677  //if inside interpolate
678 
679 
681  *( (nodes_begin + in2.tetrahedronlist[base]-1).base() ),
682  *( (nodes_begin + in2.tetrahedronlist[base+1]-1).base() ),
683  *( (nodes_begin + in2.tetrahedronlist[base+2]-1).base() ),
684  *( (nodes_begin + in2.tetrahedronlist[base+3]-1).base() )
685  );
686 
687 
688  //KRATOS_WATCH(results.size())
689  for(auto it=results.begin(); it!=results.begin() + number_of_points_in_radius; it++)
690  {
691  bool is_inside=false;
692 
693  is_inside = CalculatePosition(x1[0],x1[1],x1[2],
694  x2[0],x2[1],x2[2],
695  x3[0],x3[1],x3[2],
696  x4[0],x4[1],x4[2],
697  (*it)->X(),(*it)->Y(), (*it)->Z(),N);
698 
699  if(is_inside == true)
700  {
701 
702  Interpolate( geom, N, step_data_size, *(it) );
703 
704  }
705 
706  }
707  }
708  }
709 
710  ThisModelPart.Elements().clear();
711  ThisModelPart.Conditions().clear();
712 
713  //set the coordinates to the original value
714  for(auto & list_of_new_node : list_of_new_nodes)
715  {
716  const array_1d<double,3>& disp = list_of_new_node->FastGetSolutionStepValue(DISPLACEMENT);
717  list_of_new_node->X0() = list_of_new_node->X() - disp[0];
718  list_of_new_node->Y0() = list_of_new_node->Y() - disp[1];
719  list_of_new_node->Z0() = list_of_new_node->Z() - disp[2];
720  }
721  //cleaning unnecessary data
722  in2.deinitialize();
723  in2.initialize();
724 
725  //***********************************************************************************
726  //***********************************************************************************
727  boost::timer adding_elems;
728  //add preserved elements to the kratos
729  Properties::Pointer properties = ThisModelPart.GetMesh().pGetProperties(1);
730  nodes_begin = ThisModelPart.NodesBegin();
731  (ThisModelPart.Elements()).reserve(outnew.numberoftetrahedra);
732 
733  for(int iii = 0; iii< outnew.numberoftetrahedra; iii++)
734  {
735  int id = iii + 1;
736  int base = iii * 4;
738  *( (nodes_begin + outnew.tetrahedronlist[base]-1).base() ),
739  *( (nodes_begin + outnew.tetrahedronlist[base+1]-1).base() ),
740  *( (nodes_begin + outnew.tetrahedronlist[base+2]-1).base() ),
741  *( (nodes_begin + outnew.tetrahedronlist[base+3]-1).base() )
742  );
743 
744 
745 #ifdef _DEBUG
746 ModelPart::NodesContainerType& ModelNodes = ThisModelPart.Nodes();
747  if( *(ModelNodes).find( outnew.tetrahedronlist[base]).base() == *(ThisModelPart.Nodes().end()).base() )
748  KRATOS_THROW_ERROR(std::logic_error,"trying to use an inexisting node","");
749  if( *(ModelNodes).find( outnew.tetrahedronlist[base+1]).base() == *(ThisModelPart.Nodes().end()).base() )
750  KRATOS_THROW_ERROR(std::logic_error,"trying to use an inexisting node","");
751  if( *(ModelNodes).find( outnew.tetrahedronlist[base+2]).base() == *(ThisModelPart.Nodes().end()).base() )
752  KRATOS_THROW_ERROR(std::logic_error,"trying to use an inexisting node","");
753  if( *(ModelNodes).find( outnew.tetrahedronlist[base+3]).base() == *(ThisModelPart.Nodes().end()).base() )
754  KRATOS_THROW_ERROR(std::logic_error,"trying to use an inexisting node","");
755 #endif
756 
757  Element::Pointer p_element = rReferenceElement.Create(id, geom, properties);
758  (ThisModelPart.Elements()).push_back(p_element);
759 
760  }
761  std::cout << "time for adding elems" << adding_elems.elapsed() << std::endl;;
762  ThisModelPart.Elements().Sort();
763 
764  boost::timer adding_neighb;
765 // //filling the neighbour list
766  ModelPart::ElementsContainerType::const_iterator el_begin = ThisModelPart.ElementsBegin();
767  for(ModelPart::ElementsContainerType::const_iterator iii = ThisModelPart.ElementsBegin();
768  iii != ThisModelPart.ElementsEnd(); iii++)
769  {
770  //Geometry< Node >& geom = iii->GetGeometry();
771  int base = ( iii->Id() - 1 )*4;
772 
773  (iii->GetValue(NEIGHBOUR_ELEMENTS)).resize(4);
774  GlobalPointersVector< Element >& neighb = iii->GetValue(NEIGHBOUR_ELEMENTS);
775 
776  for(int i = 0; i<4; i++)
777  {
778  int index = outnew.neighborlist[base+i];
779  if(index > 0)
780  neighb(i) = GlobalPointer<Element>(&*(el_begin + index-1)); //*((el_begin + index-1).base());
781  else
782  neighb(i) = Element::WeakPointer();
783  }
784  }
785  std::cout << "time for adding neigbours" << adding_neighb.elapsed() << std::endl;;
786 
787 
788 
789 
790 
791  //***********************************************************************************
792  //***********************************************************************************
793  //mark boundary nodes
794  //reset the boundary flag
795  for(ModelPart::NodesContainerType::const_iterator in = ThisModelPart.NodesBegin(); in!=ThisModelPart.NodesEnd(); in++)
796  {
797  in->FastGetSolutionStepValue(IS_BOUNDARY) = 0;
798  }
799 
800  std::cout << "reset the boundary flag" << adding_neighb.elapsed() << std::endl;;
801  //***********************************************************************************
802  //***********************************************************************************
803  boost::timer adding_faces;
804 
805  (ThisModelPart.Conditions()).reserve(outnew.numberoftrifaces );
806 
807  //creating the faces
808  for(ModelPart::ElementsContainerType::const_iterator iii = ThisModelPart.ElementsBegin();
809  iii != ThisModelPart.ElementsEnd(); iii++)
810  {
811 
812  int base = ( iii->Id() - 1 )*4;
813 
814  //create boundary faces and mark the boundary nodes
815  //each face is opposite to the corresponding node number so
816  // 0 ----- 1 2 3
817  // 1 ----- 0 3 2
818  // 2 ----- 0 1 3
819  // 3 ----- 0 2 1
820 
821  //node 1
822 
823  //if( neighb(0).expired() );
824  if( outnew.neighborlist[base] == -1)
825  {
826  CreateBoundaryFace(1, 2, 3, ThisModelPart, 0, *(iii.base()), rReferenceBoundaryCondition, properties );
827  }
828  //if(neighb(1).expired() );
829  if( outnew.neighborlist[base+1] == -1)
830  {
831  CreateBoundaryFace(0,3,2, ThisModelPart, 1, *(iii.base()), rReferenceBoundaryCondition, properties );
832  }
833  if( outnew.neighborlist[base+2] == -1)
834  //if(neighb(2).expired() );
835  {
836  CreateBoundaryFace(0,1,3, ThisModelPart, 2, *(iii.base()), rReferenceBoundaryCondition, properties );
837  }
838  if( outnew.neighborlist[base+3] == -1)
839  //if(neighb(3).expired() );
840  {
841  CreateBoundaryFace(0,2,1, ThisModelPart, 3, *(iii.base()), rReferenceBoundaryCondition, properties );
842  }
843 
844  }
845  outnew.deinitialize();
846  outnew.initialize();
847  std::cout << "time for adding faces" << adding_faces.elapsed() << std::endl;;
848 
849 
850 
851  //here we remove lonely nodes that are not teh flying nodes, but are the lonely nodes inside water vol
852  /*
853  for(ModelPart::NodesContainerType::const_iterator in = ThisModelPart.NodesBegin(); in!=ThisModelPart.NodesEnd(); in++)
854  {
855  //if this is a node added during refinement, but isnt contained in any element
856  if (aux_after_ref[in->GetId()]==0 && in->GetId()>aux_before_ref.size() && in->GetId()<aux_after_ref.size())
857  {
858  in->Set(TO_ERASE,true);
859  KRATOS_WATCH("This is that ugly ugly lonely interior node a666a. IT SHALL BE TERRRRMINATED!!!!!!")
860  KRATOS_WATCH(in->GetId())
861  }
862  //if this was an interior node after first step and became single due to derefinement - erase it
863  if (aux_after_ref[in->GetId()]==0 && in->GetId()<aux_before_ref.size() && aux_before_ref[in->GetId()]!=0)
864  {
865  in->Set(TO_ERASE,true);
866  KRATOS_WATCH("This is that ugly ugly lonely interior node. IT SHALL BE TERRRRMINATED!!!!!!")
867  }
868  }
869  */
870 
871 
872  double second_part_time = auxiliary.elapsed();
873  std::cout << "second part time = " << second_part_time - first_part_time << std::endl;
874 
875 
876  KRATOS_CATCH("")
877  }
878 
882 
883 
887 
888 
892 
894  virtual std::string Info() const{return "";}
895 
897  virtual void PrintInfo(std::ostream& rOStream) const{}
898 
900  virtual void PrintData(std::ostream& rOStream) const{}
901 
902 
906 
907 
909 
910  protected:
913 
914 
918 
919 
923 
924 
928 
929 
933 
934 
938 
939 
943 
944 
946 
947  private:
950 
951 
955  boost::numeric::ublas::bounded_matrix<double,3,3> mJ; //local jacobian
956  boost::numeric::ublas::bounded_matrix<double,3,3> mJinv; //inverse jacobian
957  array_1d<double,3> mc; //center pos
958  array_1d<double,3> mRhs; //center pos
959 
960 
961  void CreateBoundaryFace(const int& i1, const int& i2, const int& i3, ModelPart& ThisModelPart, const int& outer_node_id, Element::Pointer origin_element, Condition const& rReferenceBoundaryCondition, Properties::Pointer properties)
962  {
963  KRATOS_TRY
964 
965  Geometry<Node >& geom = origin_element->GetGeometry();
966  //mark the nodes as free surface
967  geom[i1].FastGetSolutionStepValue(IS_BOUNDARY) = 1;
968  geom[i2].FastGetSolutionStepValue(IS_BOUNDARY) = 1;
969  geom[i3].FastGetSolutionStepValue(IS_BOUNDARY) = 1;
970 
971  //generate a face condition
973  temp.reserve(3);
974  temp.push_back(geom(i1));
975  temp.push_back(geom(i2));
976  temp.push_back(geom(i3));
978  //Geometry< Node >::Pointer cond = Geometry< Node >::Pointer(new Triangle3D< Node >(temp) );
979  int id = (origin_element->Id()-1)*4;
980  Condition::Pointer p_cond = rReferenceBoundaryCondition.Create(id, temp, properties);
981 
982  //assigning the neighbour node
983  (p_cond->GetValue(NEIGHBOUR_NODES)).clear();
984  (p_cond->GetValue(NEIGHBOUR_NODES)).push_back( Node::WeakPointer( geom(outer_node_id) ) );
985  (p_cond->GetValue(NEIGHBOUR_ELEMENTS)).clear();
986  (p_cond->GetValue(NEIGHBOUR_ELEMENTS)).push_back( Element::WeakPointer( origin_element ) );
987  ThisModelPart.Conditions().push_back(p_cond);
988  KRATOS_CATCH("")
989 
990  }
991 
994  void Interpolate( Tetrahedra3D4<Node >& geom, const array_1d<double,4>& N,
995  unsigned int step_data_size,
996  Node::Pointer pnode)
997  {
998  unsigned int buffer_size = pnode->GetBufferSize();
999 
1000 
1001  for(unsigned int step = 0; step<buffer_size; step++)
1002  {
1003 
1004  //getting the data of the solution step
1005  double* step_data = (pnode)->SolutionStepData().Data(step);
1006 
1007 
1008  double* node0_data = geom[0].SolutionStepData().Data(step);
1009  double* node1_data = geom[1].SolutionStepData().Data(step);
1010  double* node2_data = geom[2].SolutionStepData().Data(step);
1011  double* node3_data = geom[3].SolutionStepData().Data(step);
1012 
1013  //copying this data in the position of the vector we are interested in
1014  for(unsigned int j= 0; j<step_data_size; j++)
1015  {
1016 
1017  step_data[j] = N[0]*node0_data[j] + N[1]*node1_data[j] + N[2]*node2_data[j] + N[3]*node3_data[j];
1018 
1019 
1020  }
1021  }
1022  //now we assure that the flag variables are set coorect!! since we add nodes inside of the fluid volume only
1023  //we manually reset the IS_BOUNDARY, IS_FLUID, IS_STRUCTURE, IS_FREE_SURFACE values in a right way
1024  //not to have values, like 0.33 0.66 resulting if we would have been interpolating them in the same way
1025  //as the normal variables, like Velocity etc
1026 
1027  pnode->FastGetSolutionStepValue(IS_BOUNDARY)=0.0;
1028  pnode->FastGetSolutionStepValue(IS_STRUCTURE)=0.0;
1029  pnode->FastGetSolutionStepValue(IS_LAGRANGIAN_INLET)=0.0;
1030  pnode->FastGetSolutionStepValue(IS_FREE_SURFACE)=0.0;
1031  pnode->FastGetSolutionStepValue(IS_FLUID)=1.0;
1032  }
1033 
1034  inline double CalculateVol( const double x0, const double y0, const double z0,
1035  const double x1, const double y1, const double z1,
1036  const double x2, const double y2, const double z2,
1037  const double x3, const double y3, const double z3
1038  )
1039  {
1040  double x10 = x1 - x0;
1041  double y10 = y1 - y0;
1042  double z10 = z1 - z0;
1043 
1044  double x20 = x2 - x0;
1045  double y20 = y2 - y0;
1046  double z20 = z2 - z0;
1047 
1048  double x30 = x3 - x0;
1049  double y30 = y3 - y0;
1050  double z30 = z3 - z0;
1051 
1052  double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
1053  return detJ*0.1666666666666666666667;
1054 
1055  //return 0.5*( (x1-x0)*(y2-y0)- (y1-y0)*(x2-x0) );
1056  }
1057 
1058  inline bool CalculatePosition( const double x0, const double y0, const double z0,
1059  const double x1, const double y1, const double z1,
1060  const double x2, const double y2, const double z2,
1061  const double x3, const double y3, const double z3,
1062  const double xc, const double yc, const double zc,
1063  array_1d<double,4>& N
1064  )
1065  {
1066 
1067 
1068  double vol = CalculateVol(x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3);
1069 
1070  double inv_vol = 0.0;
1071  if(vol < 1e-26)
1072  {
1073  //KRATOS_THROW_ERROR(std::logic_error,"element with zero vol found","");
1074  KRATOS_WATCH("WARNING!!!!!!!!!! YOU HAVE A SLIVER HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
1075  return false;
1076  }
1077  else
1078  {
1079  inv_vol = 1.0 / vol;
1080  N[0] = CalculateVol(x1,y1,z1,x3,y3,z3,x2,y2,z2,xc,yc,zc) * inv_vol;
1081  N[1] = CalculateVol(x3,y3,z3,x0,y0,z0,x2,y2,z2,xc,yc,zc) * inv_vol;
1082  N[2] = CalculateVol(x3,y3,z3,x1,y1,z1,x0,y0,z0,xc,yc,zc) * inv_vol;
1083  N[3] = CalculateVol(x0,y0,z0,x1,y1,z1,x2,y2,z2,xc,yc,zc) * inv_vol;
1084 
1085 
1086  if(N[0] >= 0.0 && N[1] >= 0.0 && N[2] >= 0.0 && N[3] >=0.0 && N[0] <= 1.0 && N[1] <= 1.0 && N[2] <= 1.0 && N[3] <=1.0)
1087  {
1088  //if the xc yc zc is inside the tetrahedron return true
1089  return true;
1090  }
1091  else
1092  return false;
1093  }
1094 
1095 
1096  }
1097  //***************************************
1098  //***************************************
1099  inline void CalculateCenterAndSearchRadius(const double x0, const double y0, const double z0,
1100  const double x1, const double y1, const double z1,
1101  const double x2, const double y2, const double z2,
1102  const double x3, const double y3, const double z3,
1103  double& xc, double& yc, double& zc, double& R
1104  )
1105  {
1106  xc = 0.25*(x0+x1+x2+x3);
1107  yc = 0.25*(y0+y1+y2+y3);
1108  zc = 0.25*(z0+z1+z2+z3);
1109 
1110  double R1 = (xc-x0)*(xc-x0) + (yc-y0)*(yc-y0) + (zc-z0)*(zc-z0);
1111  double R2 = (xc-x1)*(xc-x1) + (yc-y1)*(yc-y1) + (zc-z1)*(zc-z1);
1112  double R3 = (xc-x2)*(xc-x2) + (yc-y2)*(yc-y2) + (zc-z2)*(zc-z2);
1113  double R4 = (xc-x3)*(xc-x3) + (yc-y3)*(yc-y3) + (zc-z3)*(zc-z3);
1114 
1115  R = R1;
1116  if(R2 > R) R = R2;
1117  if(R3 > R) R = R3;
1118  if(R4 > R) R = R4;
1119 
1120  R = sqrt(R);
1121  }
1122  //*****************************************************************************************
1123  //*****************************************************************************************
1124  void CalculateElementData(const array_1d<double,3>& c1,
1125  const array_1d<double,3>& c2,
1126  const array_1d<double,3>& c3,
1127  const array_1d<double,3>& c4,
1128  double& volume,
1129  array_1d<double,3>& xc,
1130  double& radius,
1131  double& hmin,
1132  double& hmax
1133  )
1134  {
1135  KRATOS_TRY
1136  const double x0 = c1[0]; const double y0 = c1[1]; const double z0 = c1[2];
1137  const double x1 = c2[0]; const double y1 = c2[1]; const double z1 = c2[2];
1138  const double x2 = c3[0]; const double y2 = c3[1]; const double z2 = c3[2];
1139  const double x3 = c4[0]; const double y3 = c4[1]; const double z3 = c4[2];
1140 
1141 // KRATOS_WATCH("111111111111111111111");
1142  //calculate min side lenght
1143  //(use xc as a auxiliary vector) !!!!!!!!!!!!
1144  double aux;
1145  noalias(xc) = c4; noalias(xc)-=c1; aux = inner_prod(xc,xc); hmin = aux; hmax = aux;
1146  noalias(xc) = c3; noalias(xc)-=c1; aux = inner_prod(xc,xc); if(aux<hmin) hmin = aux; else if(aux>hmax) hmax = aux;
1147  noalias(xc) = c2; noalias(xc)-=c1; aux = inner_prod(xc,xc); if(aux<hmin) hmin = aux; else if(aux>hmax) hmax = aux;
1148  noalias(xc) = c4; noalias(xc)-=c2; aux = inner_prod(xc,xc); if(aux<hmin) hmin = aux; else if(aux>hmax) hmax = aux;
1149  noalias(xc) = c3; noalias(xc)-=c2; aux = inner_prod(xc,xc); if(aux<hmin) hmin = aux; else if(aux>hmax) hmax = aux;
1150  noalias(xc) = c4; noalias(xc)-=c3; aux = inner_prod(xc,xc); if(aux<hmin) hmin = aux; else if(aux>hmax) hmax = aux;
1151  hmin = sqrt(hmin);
1152  hmax = sqrt(hmax);
1153 
1154  //calculation of the jacobian
1155  mJ(0,0) = x1-x0; mJ(0,1) = y1-y0; mJ(0,2) = z1-z0;
1156  mJ(1,0) = x2-x0; mJ(1,1) = y2-y0; mJ(1,2) = z2-z0;
1157  mJ(2,0) = x3-x0; mJ(2,1) = y3-y0; mJ(2,2) = z3-z0;
1158 // KRATOS_WATCH("33333333333333333333333");
1159 
1160  //inverse of the jacobian
1161  //first column
1162  mJinv(0,0) = mJ(1,1)*mJ(2,2) - mJ(1,2)*mJ(2,1);
1163  mJinv(1,0) = -mJ(1,0)*mJ(2,2) + mJ(1,2)*mJ(2,0);
1164  mJinv(2,0) = mJ(1,0)*mJ(2,1) - mJ(1,1)*mJ(2,0);
1165  //second column
1166  mJinv(0,1) = -mJ(0,1)*mJ(2,2) + mJ(0,2)*mJ(2,1);
1167  mJinv(1,1) = mJ(0,0)*mJ(2,2) - mJ(0,2)*mJ(2,0);
1168  mJinv(2,1) = -mJ(0,0)*mJ(2,1) + mJ(0,1)*mJ(2,0);
1169  //third column
1170  mJinv(0,2) = mJ(0,1)*mJ(1,2) - mJ(0,2)*mJ(1,1);
1171  mJinv(1,2) = -mJ(0,0)*mJ(1,2) + mJ(0,2)*mJ(1,0);
1172  mJinv(2,2) = mJ(0,0)*mJ(1,1) - mJ(0,1)*mJ(1,0);
1173  //calculation of determinant (of the input matrix)
1174 
1175 // KRATOS_WATCH("44444444444444444444444444");
1176  double detJ = mJ(0,0)*mJinv(0,0)
1177  + mJ(0,1)*mJinv(1,0)
1178  + mJ(0,2)*mJinv(2,0);
1179 
1180  volume = detJ * 0.16666666667;
1181 // KRATOS_WATCH("55555555555555555555555");
1182 
1183  if(volume < 1e-3 * hmax*hmax*hmax) //this is a sliver and we will remove it
1184  {
1185  //KRATOS_WATCH("666666666666666666666666666");
1186  //very bad element // ser a very high center for it to be eliminated
1187  xc[0]=0.0; xc[1]=0.0; xc[2]=0.0;
1188  radius = 10000000;
1189 // KRATOS_WATCH("777777777777777777777777");
1190  }
1191  else
1192  {
1193 
1194 // KRATOS_WATCH("888888888888888888888888");
1195  double x0_2 = x0*x0 + y0*y0 + z0*z0;
1196  double x1_2 = x1*x1 + y1*y1 + z1*z1;
1197  double x2_2 = x2*x2 + y2*y2 + z2*z2;
1198  double x3_2 = x3*x3 + y3*y3 + z3*z3;
1199 
1200  //finalizing the calculation of the inverted matrix
1201  mJinv /= detJ;
1202 
1203  //calculating the RHS
1204  //calculating the RHS
1205  mRhs[0] = 0.5*(x1_2 - x0_2);
1206  mRhs[1] = 0.5*(x2_2 - x0_2);
1207  mRhs[2] = 0.5*(x3_2 - x0_2);
1208 
1209  //calculate position of the center
1210  noalias(xc) = prod(mJinv,mRhs);
1211 
1212  //calculate radius
1213  radius = pow(xc[0] - x0,2);
1214  radius += pow(xc[1] - y0,2);
1215  radius += pow(xc[2] - z0,2);
1216  radius = sqrt(radius);
1217 // KRATOS_WATCH("999999999999999999999999999");
1218  }
1219  KRATOS_CATCH("")
1220  }
1221 
1222  template< class T, std::size_t dim >
1223  class PointDistance{
1224  public:
1225  double operator()( T const& p1, T const& p2 ){
1226  double dist = 0.0;
1227  for( std::size_t i = 0 ; i < dim ; i++){
1228  double tmp = p1[i] - p2[i];
1229  dist += tmp*tmp;
1230  }
1231  return sqrt(dist);
1232  }
1233  };
1234 
1235  template< class T, std::size_t dim >
1236  class DistanceCalculator{
1237  public:
1238  double operator()( T const& p1, T const& p2 ){
1239  double dist = 0.0;
1240  for( std::size_t i = 0 ; i < dim ; i++){
1241  double tmp = p1[i] - p2[i];
1242  dist += tmp*tmp;
1243  }
1244  return dist;
1245  }
1246  };
1247 
1251 
1255 
1256 
1260 
1261 
1265 
1266 
1270 
1272  TetGenPfemModeler& operator=(TetGenPfemModeler const& rOther);
1273 
1274 
1276 
1277  }; // Class TetGenPfemModeler
1278 
1280 
1283 
1284 
1288 
1289 
1291  inline std::istream& operator >> (std::istream& rIStream,
1292  TetGenPfemModeler& rThis);
1293 
1295  inline std::ostream& operator << (std::ostream& rOStream,
1296  const TetGenPfemModeler& rThis)
1297  {
1298  rThis.PrintInfo(rOStream);
1299  rOStream << std::endl;
1300  rThis.PrintData(rOStream);
1301 
1302  return rOStream;
1303  }
1305 
1306 
1307 } // namespace Kratos.
1308 
1309 #endif // KRATOS_TETGEN_PFEM_MODELER_H_INCLUDED defined
1310 
1311 
Short class definition.
Definition: bucket.h:57
Base class for all Conditions.
Definition: condition.h:59
virtual Pointer Create(IndexType NewId, NodesArrayType const &ThisNodes, PropertiesType::Pointer pProperties) const
It creates a new condition pointer.
Definition: condition.h:205
Dof represents a degree of freedom (DoF).
Definition: dof.h:86
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
This process removes the entities from a model part with the flag TO_ERASE.
Definition: entity_erase_process.h:70
void Execute() override
Execute method is used to execute the Process algorithms.
Geometry base class.
Definition: geometry.h:71
This class is a wrapper for a pointer to a data that is located in a different rank.
Definition: global_pointer.h:44
Definition: amatrix_interface.h:497
Definition: amatrix_interface.h:530
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
NodeType::Pointer CreateNewNode(int Id, double x, double y, double z, VariablesList::Pointer pNewVariablesList, IndexType ThisIndex=0)
Definition: model_part.cpp:270
SizeType GetNodalSolutionStepDataSize()
Definition: model_part.h:571
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ConditionsContainerType & Conditions(IndexType ThisIndex=0)
Definition: model_part.h:1381
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
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
MeshType & GetMesh(IndexType ThisIndex=0)
Definition: model_part.h:1791
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class defines the node.
Definition: node.h:65
std::vector< std::unique_ptr< Dof< double > >> DofsContainerType
The DoF container type definition.
Definition: node.h:92
double Y() const
Definition: point.h:187
double Z() const
Definition: point.h:193
double X() const
Definition: point.h:181
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
Short class definition.
Definition: tetgen_pfem_refine.h:67
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: tetgen_pfem_refine.h:897
virtual ~TetGenPfemModeler()=default
Destructor.
TetGenPfemModeler()
Default constructor.
Definition: tetgen_pfem_refine.h:80
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: tetgen_pfem_refine.h:900
void ReGenerateMesh(ModelPart &ThisModelPart, Element const &rReferenceElement, Condition const &rReferenceBoundaryCondition, EntitiesEraseProcess< Node > &node_erase, bool rem_nodes=true, bool add_nodes=true, double alpha_param=1.4, double h_factor=0.5)
Definition: tetgen_pfem_refine.h:102
virtual std::string Info() const
Turn back information as a string.
Definition: tetgen_pfem_refine.h:894
KRATOS_CLASS_POINTER_DEFINITION(TetGenPfemModeler)
Pointer definition of TetGenPfemModeler.
A four node tetrahedra geometry with linear shape functions.
Definition: tetrahedra_3d_4.h:59
A generic tree data structure for spatial partitioning.
Definition: tree.h:190
A three node 3D triangle geometry with linear shape functions.
Definition: triangle_3d_3.h:77
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#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
z
Definition: GenerateWind.py:163
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
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
DistanceVector::iterator DistanceIterator
Definition: internal_variables_interpolation_process.h:56
std::vector< PointTypePointer > PointVector
Definition: internal_variables_interpolation_process.h:53
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
PointVector::iterator PointIterator
Definition: internal_variables_interpolation_process.h:54
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
std::vector< double > DistanceVector
Definition: internal_variables_interpolation_process.h:55
Point PointType
Geometric definitions.
Definition: mortar_classes.h:36
float dist
Definition: edgebased_PureConvection.py:89
int step
Definition: face_heat.py:88
y
Other simbols definition.
Definition: generate_axisymmetric_navier_stokes_element.py:54
res
Definition: generate_convection_diffusion_explicit_element.py:211
x2
Definition: generate_frictional_mortar_condition.py:122
x1
Definition: generate_frictional_mortar_condition.py:121
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
out
Definition: isotropic_damage_automatic_differentiation.py:200
R
Definition: isotropic_damage_automatic_differentiation.py:172
float radius
Definition: mesh_to_mdpa_converter.py:18
int j
Definition: quadrature.py:648
el
Definition: read_stl.py:25
float temp
Definition: rotating_cone.py:85
float xc
Definition: rotating_cone.py:77
float yc
Definition: rotating_cone.py:78
int counter
Definition: script_THERMAL_CORRECT.py:218
add_nodes
Definition: script.py:96
N
Definition: sensitivityMatrix.py:29
x
Definition: sensitivityMatrix.py:49
int dim
Definition: sensitivityMatrix.py:25
volume
Definition: sp_statistics.py:15
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31