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.
local_refine_prism_mesh.hpp
Go to the documentation of this file.
1 // KRATOS __ __ _____ ____ _ _ ___ _ _ ____
2 // | \/ | ____/ ___|| | | |_ _| \ | |/ ___|
3 // | |\/| | _| \___ \| |_| || || \| | | _
4 // | | | | |___ ___) | _ || || |\ | |_| |
5 // |_| |_|_____|____/|_| |_|___|_| \_|\____| APPLICATION
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Vicente Mataix Ferrandiz
11 //
12 
13 #if !defined(KRATOS_LOCAL_REFINE_PRISM_MESH)
14 #define KRATOS_LOCAL_REFINE_PRISM_MESH
15 
16 #ifdef _OPENMP
17 #include <omp.h>
18 #endif
19 
20 // NOTE: Before compute the remeshing it is necessary to compute the neighbours
21 
22 // System includes
23 
24 /* Project includes */
25 #include "geometries/line_3d_2.h"
26 #include "geometries/prism_3d_6.h"
29 
30 namespace Kratos
31 {
47 {
48 public:
49 
55 
58  {
59 
60  }
61 
64  = default;
65 
69 
73 
81  {
82  // Lower face
83  array_1d<double, 3 > Coord_Node_1;
84  array_1d<double, 3 > Coord_Node_2;
85  array_1d<double, 3 > Coord_Node_3;
86 
87  // Upper face
88  array_1d<double, 3 > Coord_Node_4;
89  array_1d<double, 3 > Coord_Node_5;
90  array_1d<double, 3 > Coord_Node_6;
91 
92  // Center
93  array_1d<double, 3 > Coordinate_center_node;
94 
95  std::vector<int> node_center;
96  NodesArrayType& pNodes = this_model_part.Nodes();
97  int Id_Center = pNodes.size() + 1;
98  ElementsArrayType& rElements = this_model_part.Elements();
99  ElementsArrayType::iterator it_begin = rElements.ptr_begin();
100  ElementsArrayType::iterator it_end = rElements.ptr_end();
101  for (ElementsArrayType::iterator it = it_begin; it != it_end; ++it)
102  {
103  Element::GeometryType& geom = it->GetGeometry();
104  noalias(Coord_Node_1) = geom[0].Coordinates();
105  noalias(Coord_Node_2) = geom[1].Coordinates();
106  noalias(Coord_Node_3) = geom[2].Coordinates();
107  noalias(Coord_Node_4) = geom[3].Coordinates();
108  noalias(Coord_Node_5) = geom[4].Coordinates();
109  noalias(Coord_Node_6) = geom[5].Coordinates();
110 
111  unsigned int step_data_size = this_model_part.GetNodalSolutionStepDataSize();
112  Node ::DofsContainerType& reference_dofs = (this_model_part.NodesBegin())->GetDofs();
113  noalias(Coordinate_center_node) = 0.16666666666666666 * (Coord_Node_1 + Coord_Node_2 + Coord_Node_3 +
114  Coord_Node_4 + Coord_Node_5 + Coord_Node_6);
115 
116  /* Inserting the new node in the model part */
117  Node ::Pointer pnode = this_model_part.CreateNewNode(Id_Center, Coordinate_center_node[0], Coordinate_center_node[1], Coordinate_center_node[2]);
118  pnode->SetBufferSize(this_model_part.NodesBegin()->GetBufferSize());
119 
120  pnode->X0() = 0.16666666666666666 * (geom[0].X0() + geom[1].X0() + geom[2].X0() + geom[3].X0() + geom[4].X0() + geom[5].X0());
121  pnode->Y0() = 0.16666666666666666 * (geom[0].Y0() + geom[1].Y0() + geom[2].Y0() + geom[3].Y0() + geom[4].Y0() + geom[5].Y0());
122  pnode->Z0() = 0.16666666666666666 * (geom[0].Z0() + geom[1].Z0() + geom[2].Z0() + geom[3].Z0() + geom[4].Z0() + geom[5].Z0());
123 
124  for (Node ::DofsContainerType::iterator iii = reference_dofs.begin(); iii != reference_dofs.end(); iii++)
125  {
126  Node ::DofType& rDof = **iii;
127  Node ::DofType::Pointer p_new_dof = pnode->pAddDof(rDof);
128  if (geom[0].IsFixed(rDof.GetVariable()) && geom[1].IsFixed(rDof.GetVariable()) && geom[2].IsFixed(rDof.GetVariable()) && geom[3].IsFixed(rDof.GetVariable())
129  && geom[4].IsFixed(rDof.GetVariable()) && geom[5].IsFixed(rDof.GetVariable()))
130  {
131  (p_new_dof)->FixDof();
132  }
133  else
134  {
135  (p_new_dof)->FreeDof();
136  }
137  }
138 
139  /* Intepolating the data */
140  unsigned int buffer_size = pnode->GetBufferSize();
141  for (unsigned int step = 0; step < buffer_size; step++)
142  {
143  double* new_step_data = pnode->SolutionStepData().Data(step);
144 
145  // Lower face
146  double* step_data1 = geom[0].SolutionStepData().Data(step);
147  double* step_data2 = geom[1].SolutionStepData().Data(step);
148  double* step_data3 = geom[2].SolutionStepData().Data(step);
149 
150  // Upper face
151  double* step_data4 = geom[3].SolutionStepData().Data(step);
152  double* step_data5 = geom[4].SolutionStepData().Data(step);
153  double* step_data6 = geom[5].SolutionStepData().Data(step);
154 
155  // Copying this data in the position of the vector we are interested in
156  for (unsigned int j = 0; j < step_data_size; j++)
157  {
158  new_step_data[j] = 0.16666666666666666 * (step_data1[j] + step_data2[j] + step_data3[j] +
159  step_data4[j] + step_data5[j] + step_data6[j]);
160  }
161  }
162  node_center.push_back(Id_Center);
163  Id_Center++;
164  }
165  }
166 
167  /***********************************************************************************/
168  /***********************************************************************************/
169 
179  ModelPart& this_model_part,
180  const compressed_matrix<int>& Coord,
181  PointerVector< Element >& New_Elements,
182  bool interpolate_internal_variables
183  ) override
184  {
185  ElementsArrayType& rElements = this_model_part.Elements();
186  ElementsArrayType::iterator it_begin = rElements.ptr_begin();
187  ElementsArrayType::iterator it_end = rElements.ptr_end();
188  unsigned int to_be_deleted = 0;
189  unsigned int large_id = (rElements.end() - 1)->Id() * 10;
190  bool create_element = false;
191  int edge_ids[6];
192  int t[24];
193  int number_elem = 0;
194  int splitted_edges = 0;
195  int nint = 0;
196  std::vector<int> aux;
197 
198  const ProcessInfo& rCurrentProcessInfo = this_model_part.GetProcessInfo();
199 
200  std::cout << "****************** REFINING MESH ******************" << std::endl;
201  std::cout << "OLD NUMBER ELEMENTS: " << rElements.size() << std::endl;
202 
203  unsigned int current_id = (rElements.end() - 1)->Id() + 1;
204  for (ElementsArrayType::iterator it = it_begin; it != it_end; ++it)
205  {
206  for (int & i : t)
207  {
208  i = -1;
209  }
210 
211  Element::GeometryType& geom = it->GetGeometry();
212  CalculateEdges(geom, Coord, edge_ids, aux);
213 
214  // It creates the new conectivities
215  create_element = Split_Prism(edge_ids, t, &number_elem, &splitted_edges, &nint);
216 
217  // It creates the new elements
218  if (create_element == true)
219  {
220  to_be_deleted++;
221  for (int i = 0; i < number_elem; i++)
222  {
223  unsigned int base = i * 6;
224  unsigned int i0 = aux[t[base]];
225  unsigned int i1 = aux[t[base + 1]];
226  unsigned int i2 = aux[t[base + 2]];
227  unsigned int i3 = aux[t[base + 3]];
228  unsigned int i4 = aux[t[base + 4]];
229  unsigned int i5 = aux[t[base + 5]];
230 
231  Prism3D6<Node > geom(
232  this_model_part.Nodes()(i0),
233  this_model_part.Nodes()(i1),
234  this_model_part.Nodes()(i2),
235  this_model_part.Nodes()(i3),
236  this_model_part.Nodes()(i4),
237  this_model_part.Nodes()(i5)
238  );
239 
240  Element::Pointer p_element;
241  p_element = it->Create(current_id, geom, it->pGetProperties());
242  p_element->Initialize(rCurrentProcessInfo);
243  p_element->InitializeSolutionStep(rCurrentProcessInfo);
244  p_element->FinalizeSolutionStep(rCurrentProcessInfo);
245 
246  // Setting the internal variables in the child elem
247  if (interpolate_internal_variables == true)
248  {
249  InterpolateInteralVariables(number_elem, *it.base(), p_element, rCurrentProcessInfo);
250  }
251 
252  // Transfer elemental variables
253  p_element->GetData() = it->GetData();
254  p_element->GetValue(SPLIT_ELEMENT) = false;
255  New_Elements.push_back(p_element);
256 
257  current_id++;
258  }
259  it->SetId(large_id);
260  large_id++;
261  }
262  }
263 
264  /* Adding news elements to the model part */
265  for (PointerVector< Element >::iterator it_new = New_Elements.begin(); it_new != New_Elements.end(); it_new++)
266  {
267  rElements.push_back(*(it_new.base()));
268  }
269 
270  /* All of the elements to be erased are at the end */
271  rElements.Sort();
272 
273  /* Now remove all of the "old" elements */
274  rElements.erase(this_model_part.Elements().end() - to_be_deleted, this_model_part.Elements().end());
275 
276  std::cout << "NEW NUMBER ELEMENTS: " << rElements.size() << std::endl;
277  }
278 
279  /***********************************************************************************/
280  /***********************************************************************************/
281 
289  ModelPart& this_model_part,
290  const compressed_matrix<int>& Coord
291  ) override
292  {
293  KRATOS_TRY;
294 
295  PointerVector< Condition > New_Conditions;
296 
297  ConditionsArrayType& rConditions = this_model_part.Conditions();
298 
299  if (rConditions.size() > 0)
300  {
301  ConditionsArrayType::iterator it_begin = rConditions.ptr_begin();
302  ConditionsArrayType::iterator it_end = rConditions.ptr_end();
303  unsigned int to_be_deleted = 0;
304  unsigned int large_id = (rConditions.end() - 1)->Id() * 7;
305 
306  const ProcessInfo& rCurrentProcessInfo = this_model_part.GetProcessInfo();
307 
308  unsigned int current_id = (rConditions.end() - 1)->Id() + 1;
309 
310  for (ConditionsArrayType::iterator it = it_begin; it != it_end; ++it)
311  {
312  Condition::GeometryType& geom = it->GetGeometry();
313 
314  if (geom.size() == 2)
315  {
316  int index_0 = geom[0].Id() - 1;
317  int index_1 = geom[1].Id() - 1;
318  int new_id;
319 
320  if (index_0 > index_1)
321  {
322  new_id = Coord(index_1, index_0);
323  }
324  else
325  {
326  new_id = Coord(index_0, index_1);
327  }
328 
329  if (new_id > 0) // We need to create a new condition
330  {
331  to_be_deleted++;
332 
333  Line3D2<Node > newgeom1(
334  this_model_part.Nodes()(geom[0].Id()),
335  this_model_part.Nodes()(new_id)
336  );
337 
338  Line3D2<Node > newgeom2(
339  this_model_part.Nodes()(new_id),
340  this_model_part.Nodes()(geom[1].Id())
341  );
342 
343  Condition::Pointer pcond1 = it->Create(current_id++, newgeom1, it->pGetProperties());
344  Condition::Pointer pcond2 = it->Create(current_id++, newgeom2, it->pGetProperties());
345 
346  pcond1->GetData() = it->GetData();
347  pcond2->GetData() = it->GetData();
348 
349  New_Conditions.push_back(pcond1);
350  New_Conditions.push_back(pcond2);
351 
352  it->SetId(large_id);
353  large_id++;
354  }
355  }
356  }
357 
358  /* All of the elements to be erased are at the end */
359  this_model_part.Conditions().Sort();
360 
361  /* Remove all of the "old" elements */
362  this_model_part.Conditions().erase(this_model_part.Conditions().end() - to_be_deleted, this_model_part.Conditions().end());
363 
364  unsigned int total_size = this_model_part.Conditions().size() + New_Conditions.size();
365  this_model_part.Conditions().reserve(total_size);
366 
367  /* Adding news elements to the model part */
368  for (PointerVector< Condition >::iterator it_new = New_Conditions.begin(); it_new != New_Conditions.end(); it_new++)
369  {
370  it_new->Initialize(rCurrentProcessInfo);
371  it_new->InitializeSolutionStep(rCurrentProcessInfo);
372  it_new->FinalizeSolutionStep(rCurrentProcessInfo);
373  this_model_part.Conditions().push_back(*(it_new.base()));
374  }
375 
376  /* Renumber */
377  unsigned int my_index = 1;
378  for (ModelPart::ConditionsContainerType::iterator it = this_model_part.ConditionsBegin(); it != this_model_part.ConditionsEnd(); it++)
379  {
380  it->SetId(my_index++);
381  }
382 
383  }
384 
385  KRATOS_CATCH("");
386  }
387 
388  /***********************************************************************************/
389  /***********************************************************************************/
390 
401  Element::GeometryType& geom,
402  const compressed_matrix<int>& Coord,
403  int* edge_ids,
404  std::vector<int> & aux
405  ) override
406  {
407  aux.resize(12, false);
408 
409  // Lower face
410  int index_0 = mMapNodeIdToPos[geom[0].Id()];
411  int index_1 = mMapNodeIdToPos[geom[1].Id()];
412  int index_2 = mMapNodeIdToPos[geom[2].Id()];
413 
414  aux[0] = geom[0].Id();
415  aux[1] = geom[1].Id();
416  aux[2] = geom[2].Id();
417 
418  // Upper face
419  int index_3 = mMapNodeIdToPos[geom[3].Id()];
420  int index_4 = mMapNodeIdToPos[geom[4].Id()];
421  int index_5 = mMapNodeIdToPos[geom[5].Id()];
422 
423  aux[3] = geom[3].Id();
424  aux[4] = geom[4].Id();
425  aux[5] = geom[5].Id();
426 
427  //-------------------------------------------------------------------------
428 
429  // First node of the triangle face
430  if (index_0 > index_1)
431  {
432  aux[6] = Coord(index_1, index_0);
433  aux[9] = Coord(index_4, index_3);
434  }
435  else
436  {
437  aux[6] = Coord(index_0, index_1);
438  aux[9] = Coord(index_3, index_4);
439  }
440 
441  // Second node of the triangle face
442  if (index_1 > index_2)
443  {
444  aux[7] = Coord(index_2, index_1);
445  aux[10] = Coord(index_5, index_4);
446  }
447  else
448  {
449  aux[7] = Coord(index_1, index_2);
450  aux[10] = Coord(index_4, index_5);
451  }
452 
453  // Third node of the triangle face
454  if (index_2 > index_0)
455  {
456  aux[8] = Coord(index_0, index_2);
457  aux[11] = Coord(index_3, index_5);
458  }
459  else
460  {
461  aux[8] = Coord(index_2, index_0);
462  aux[11] = Coord(index_5, index_3);
463  }
464 
465  //-------------------------------------------------------------------------
466 
467  // Edge 01
468  if (aux[6] < 0)
469  {
470  if (index_0 > index_1)
471  {
472  edge_ids[0] = 0;
473  edge_ids[3] = 6;
474  }
475  else
476  {
477  edge_ids[0] = 1;
478  edge_ids[3] = 7;
479  }
480  }
481  else
482  {
483  edge_ids[0] = 3;
484  edge_ids[3] = 9;
485  }
486 
487  // Edge 12
488  if (aux[7] < 0)
489  {
490  if (index_1 > index_2)
491  {
492  edge_ids[1] = 1;
493  edge_ids[4] = 7;
494  }
495  else
496  {
497  edge_ids[1] = 2;
498  edge_ids[4] = 8;
499  }
500  }
501  else
502  {
503  edge_ids[1] = 4;
504  edge_ids[4] = 10;
505  }
506 
507  // Edge 20
508  if (aux[8] < 0)
509  {
510  if (index_2 > index_0)
511  {
512  edge_ids[2] = 2;
513  edge_ids[5] = 8;
514  }
515  else
516  {
517  edge_ids[2] = 0;
518  edge_ids[5] = 6;
519  }
520  }
521  else
522  {
523  edge_ids[2] = 5;
524  edge_ids[5] = 11;
525  }
526  }
527 
528 protected:
531 
535 
539 
543 
547 
551 
556 
557 private:
560 
564 
568 
572 
576 
580 
585 
586 };
587 
588 } // namespace Kratos.
589 
590 #endif // KRATOS_LOCAL_REFINE_PRISM_MESH defined
Geometry base class.
Definition: geometry.h:71
void push_back(PointPointerType x)
Definition: geometry.h:548
SizeType size() const
Definition: geometry.h:518
IndexType const & Id() const
Id of this Geometry.
Definition: geometry.h:964
An two node 3D line geometry with linear shape functions.
Definition: line_3d_2.h:64
Definition: local_refine_geometry_mesh.hpp:49
ModelPart::NodesContainerType NodesArrayType
Definition: local_refine_geometry_mesh.hpp:54
std::unordered_map< std::size_t, unsigned int > mMapNodeIdToPos
The current refinement level.
Definition: local_refine_geometry_mesh.hpp:240
void InterpolateInteralVariables(const int &number_elem, const TGeometricalObjectPointerType father_elem, TGeometricalObjectPointerType child_elem, const ProcessInfo &rCurrentProcessInfo)
Definition: local_refine_geometry_mesh.hpp:213
ModelPart::ElementsContainerType ElementsArrayType
Definition: local_refine_geometry_mesh.hpp:55
ModelPart::ConditionsContainerType ConditionsArrayType
Definition: local_refine_geometry_mesh.hpp:56
Definition: local_refine_prism_mesh.hpp:47
LocalRefinePrismMesh(ModelPart &model_part)
Default constructors.
Definition: local_refine_prism_mesh.hpp:57
void CalculateEdges(Element::GeometryType &geom, const compressed_matrix< int > &Coord, int *edge_ids, std::vector< int > &aux) override
Definition: local_refine_prism_mesh.hpp:400
void CalculateCoordinateCenterNodeAndInsertNewNodes(ModelPart &this_model_part)
Definition: local_refine_prism_mesh.hpp:80
void EraseOldConditionsAndCreateNew(ModelPart &this_model_part, const compressed_matrix< int > &Coord) override
Definition: local_refine_prism_mesh.hpp:288
void EraseOldElementAndCreateNewElement(ModelPart &this_model_part, const compressed_matrix< int > &Coord, PointerVector< Element > &New_Elements, bool interpolate_internal_variables) override
Definition: local_refine_prism_mesh.hpp:178
~LocalRefinePrismMesh() override=default
Destructor.
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
NodeType::Pointer CreateNewNode(int Id, double x, double y, double z, VariablesList::Pointer pNewVariablesList, IndexType ThisIndex=0)
Definition: model_part.cpp:270
ConditionIterator ConditionsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1361
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
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
ConditionIterator ConditionsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1371
Dof< double > DofType
Dof type.
Definition: node.h:83
std::vector< std::unique_ptr< Dof< double > >> DofsContainerType
The DoF container type definition.
Definition: node.h:92
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
size_type size() const
Definition: pointer_vector.h:255
iterator end()
Definition: pointer_vector.h:177
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector.h:89
iterator begin()
Definition: pointer_vector.h:169
void push_back(const TPointerType &x)
Definition: pointer_vector.h:270
A six node prism geometry with linear shape functions.
Definition: prism_3d_6.h:60
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
int step
Definition: face_heat.py:88
model_part
Definition: face_heat.py:14
int t
Definition: ode_solve.py:392
int j
Definition: quadrature.py:648
int current_id
Output settings end ####.
Definition: script.py:194
integer i
Definition: TensorModule.f:17
The class contains three helper functions to ease the splitting: PrismSplitMode, Split_Prism,...
int Split_Prism(const int edges[6], int t[24], int *number_elem, int *splitted_edges, int *nint)
Definition: split_prism.hpp:182