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.
iso_printer.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Pablo Becker
11 //
12 //
13 
14 #if !defined(KRATOS_ISO_PRINTING_APP)
15 #define KRATOS_ISO_PRINTING_APP
16 
17 
18 #ifdef _OPENMP
19 #include <omp.h>
20 #endif
21 
22 
23 
24 
25 // System includes
26 #include <string>
27 #include <iostream>
28 #include <cstdlib>
29 #include <cmath>
30 #include <algorithm>
31 
32 
33 /* Project includes */
34 #include "includes/define.h"
35 #include "includes/model_part.h"
36 #include "includes/node.h"
37 #include "includes/dof.h"
38 #include "includes/variables.h"
40 #include "geometries/geometry.h"
42 
43 
44 // #include "containers/array_1d.h"
45 // #include "processes/find_nodal_neighbours_process.h"
47 #include "includes/mesh.h"
48 #include "utilities/math_utils.h"
49 //#include "utilities/split_triangle.h"
52 //#include "geometries/triangle_2d_3.h"
55 #include "utilities/geometry_utilities.h"
56 // #include "spatial_containers/spatial_containers.h"
57 
58 
59 
60 
61 namespace Kratos
62 {
65 //HOW TO USE IT from python.
66 /*
67  #constructor:
68  Iso_App = IsosurfacePrinterApplication(model_part)
69 
70  #and then, in each time step in which results must be printed:
71  Iso_App.ClearData()
72  variable1 = PRESSURE
73  variable2 = DISTANCE
74  isovalue1 = 0.001
75  isovalue2 = 5.0
76  tolerance = 0.00000000001
77  Iso_App.AddScalarVarIsosurface(variable1, isovalue1, tolerance)
78  Iso_App.AddScalarVarIsosurface(variable2, isovalue2, tolerance)
79  #conditions can be also added
80 
81  used_nodes_array=Iso_App.CreateNodesArray() #after all the isosurfaces needed, the array must be created
82  size=used_nodes_array.Size()
83 
84  if size!=0: #results must be printed only when the array is not empty, otherwise it will segfault
85  gid_io.WriteNodalResults(PRESSURE,used_nodes_array,time,0)
86  gid_io.WriteNodalResults(VELOCITY,used_nodes_array,time,0)
87 
88 
89 
90 */
91 
92 
94 {
95 public:
96 
103  typedef Node PointType;
104  typedef Node ::Pointer PointPointerType;
105  typedef std::vector<PointType::Pointer> PointVector;
106  typedef PointVector::iterator PointIterator;
107 
113  {
114  int nnodes = mr_model_part.Nodes().size(); //both local nodes and the ones belonging to other CPU
115  m_used_nodes.resize(nnodes);
116  for (int index = 0; index!=nnodes; ++index) m_used_nodes[index]=false; //starting as zero (no needed nodes)
117  //smallest_edge=1.0;
118  } //
119 
121  {
122  }
123 
124 
125 
127 
133 
135  {
136  ModelPart& this_model_part = mr_model_part;
137 
138  KRATOS_TRY
139 
140  NodesArrayType& rNodes_old = this_model_part.Nodes(); //needed to find the position of the node in the node array
141  NodesArrayType::iterator it_begin_node_old = rNodes_old.ptr_begin();
142 
143  //int nlocal_nodes = this_model_part.GetCommunicator().LocalMesh().Nodes().size(); //only local nodes
144  //int nnodes = this_model_part.Nodes().size(); //both local nodes and the ones belonging to other CPU
145 
146  //the id of our processor:
147  //double this_partition_index = double(mrComm.MyPID());
148 
149 
150  //now we have to search for the conditions. they can only be triangles, otherwise -> not stored
151  int number_of_local_conditions=0;
152  for (ModelPart::ConditionsContainerType::iterator it = this_model_part.ConditionsBegin(); it != this_model_part.ConditionsEnd(); it++)
153  {
154  Geometry<Node >& geom = it->GetGeometry();
155  if (geom.size()==3)
156  {
157  ++number_of_local_conditions; //conditions are always owned
158  for (unsigned int i = 0; i < geom.size(); i++)
159  {
160  int node_position = this_model_part.Nodes().find(geom[i].Id()) - it_begin_node_old; //probably there-s a better way to do this, i only need the position in the array, (not the ID)
161  m_used_nodes[node_position]=true; //we will have to clone this node into the new model part, no matter if owned or not.
162  }
163  }
164  }
165 
166  //cout << "added conditions nodes to the list of nodes to be printed "<< endl;
167  KRATOS_CATCH("")
168  }
169 
170 
172 
173  //this is the function to create isosurfaces from a scalar variable. the other (a component from a vectorial variable) will be added later
174  void AddScalarVarIsosurface( Variable<double>& variable, double isovalue)
175  {
176  KRATOS_TRY
177 
178  /*
179  cout <<"Printing Isosurface Nodes with the following data:"<<endl;
180  KRATOS_WATCH(variable);
181  KRATOS_WATCH(isovalue);
182  */
183 
184  ModelPart& this_model_part = mr_model_part;
185  //ModelPart& new_model_part = mr_new_model_part;
186 
187  ElementsArrayType& rElements = this_model_part.Elements();
188 
189  //first of all create a matrix with no overlap
190  ElementsArrayType::iterator it_begin = rElements.ptr_begin(); //+element_partition[k];
191  ElementsArrayType::iterator it_end = rElements.ptr_end(); //+element_partition[k+1];
192 
193  NodesArrayType& rNodes_old = this_model_part.Nodes(); //needed to find the position of the node in the node array
194  NodesArrayType::iterator it_begin_node_old = rNodes_old.ptr_begin();
195 
196  double node_value; // node to closest point in the plane
197  double neigh_value; //other node of the edge (neighbour) to closest point in the plane
198  double diff_node_value; // difference between the imposed value of the variable and its value in the node
199  double diff_neigh_value; //distance between the two nodes of the edge
200  //double diff_node_neigh;
201  array_1d<unsigned int, 4 > list_matching_nodes; // used to save the new nodes that match exactly old nodes (very unlikely, but might be 4 for very plane elements)
202  unsigned int exact_nodes = 0;
203  unsigned int outside_nodes = 0;
204  int current_element=0;
205  int number_of_cuts=0;
206 
207  for (ElementsArrayType::iterator it = it_begin; it != it_end; ++it)
208  {
209  bool print_element=false;
210  ++current_element;
211  number_of_cuts = 0;
212  exact_nodes = 0;
213  outside_nodes = 0;
214  Geometry<Node >&geom = it->GetGeometry(); //geometry of the element
215  for (unsigned int i = 0; i < it->GetGeometry().size(); i++) //size = 4 ; nodes per element. NOTICE WE'LL BE LOOPING THE EDGES TWICE. THIS IS A WASTE OF TIME BUT MAKES IT EASIER TO IDENTITY ELEMENTS. LOOK BELOW.
216  //when we have a triangle inside a thetraedra, its edges (or nodes) must be cut 3 times by the plane. if we loop all 2 times we can have a counter. when it's = 6 then we have a triangle. when tetraedras are cutted 8 times then we have 2 triangles (or a cuatrilateral, the same)
217  {
218  node_value= geom[i].FastGetSolutionStepValue(variable);
219  diff_node_value = isovalue - node_value; // dist = (xnode-xp)*versor closest point-plane distance
220  for (unsigned int j = 0; j < it->GetGeometry().size(); j++) // looping on the neighbours
221  {
222  //unsigned int this_node_cutted_edges=0;
223  if (i != j) //(cant link node with itself)
224  {
225  neigh_value= geom[j].FastGetSolutionStepValue(variable);
226  diff_neigh_value = isovalue - neigh_value;
227  //diff_node_neigh = node_value - neigh_value;
228  //now that we have the two points of the edge defined we can check whether it is cut by the plane or not
229 
230  if ((diff_node_value * diff_neigh_value) < 0.0 ) // this means one is on top of the plane and the other on the bottom, no need to do more checks, it's in between!
231  {
232  ++number_of_cuts;
233  }
234  } //closing the i!=j if
235  } //closing the neighbour (j) loop
236  } //closing the nodes (i) loop
237 
238 
239  //now we have to save the data. we should get a list with the elements that will genereate triangles and the total number of triangles
240  if (exact_nodes < 4 || outside_nodes<2 ) //this means at least one new node has to be generated
241  {
242  if (number_of_cuts == 6 || number_of_cuts == 6) //it can be 8, in that case we have 2 triangles (the cut generates a square)
243  print_element=true;
244 
245  }
246  if (print_element==true)
247  {
248  for (unsigned int i = 0; i < it->GetGeometry().size(); i++) //size = 4 ; nodes per element. NOTICE WE'LL BE LOOPING THE EDGES TWICE. THIS IS A WASTE OF TIME BUT MAKES IT EASIER TO IDENTITY ELEMENTS. LOOK BELOW.
249  //when we have a triangle inside a thetraedra, its edges (or nodes) must be cut 3 times by the plane. if we loop all 2 times we can have a counter. when it's = 6 then we have a triangle. when tetraedras are cutted 8 times then we have 2 triangles (or a cuatrilateral, the same)
250  {
251  int node_position = this_model_part.Nodes().find(geom[i].Id()) - it_begin_node_old;
252  m_used_nodes[node_position]=true;
253  }
254  }
255  } //closing the elem loop
256 
257  //cout << "Added nodes that are part of the isosurface to the priting list" << endl;
258 
259  KRATOS_CATCH("")
260  }
261 
262 
263  //**********************************************************************************************************************
264 
265 
266  //this is the function to create isosurfaces from a scalar variable. the other (a component from a vectorial variable) will be added later
267  void AddScalarVarIsosurfaceAndLower( Variable<double>& variable, double isovalue)
268  {
269  KRATOS_TRY
270 
271  /*
272  cout <<"Printing Isosurface Nodes with the following data:"<<endl;
273  KRATOS_WATCH(variable);
274  KRATOS_WATCH(isovalue);
275  */
276 
277  ModelPart& this_model_part = mr_model_part;
278  //ModelPart& new_model_part = mr_new_model_part;
279 
280  ElementsArrayType& rElements = this_model_part.Elements();
281 
282  //first of all create a matrix with no overlap
283  ElementsArrayType::iterator it_begin = rElements.ptr_begin(); //+element_partition[k];
284  ElementsArrayType::iterator it_end = rElements.ptr_end(); //+element_partition[k+1];
285 
286  NodesArrayType& rNodes_old = this_model_part.Nodes(); //needed to find the position of the node in the node array
287  NodesArrayType::iterator it_begin_node_old = rNodes_old.ptr_begin();
288 
289  double node_value; // node to closest point in the plane
290  double neigh_value; //other node of the edge (neighbour) to closest point in the plane
291  double diff_node_value; // difference between the imposed value of the variable and its value in the node
292  double diff_neigh_value; //distance between the two nodes of the edge
293  //double diff_node_neigh;
294  array_1d<unsigned int, 4 > list_matching_nodes; // used to save the new nodes that match exactly old nodes (very unlikely, but might be 4 for very plane elements)
295  unsigned int exact_nodes = 0;
296  unsigned int outside_nodes = 0;
297  int current_element=0;
298  int number_of_cuts=0;
299 
300  for (ElementsArrayType::iterator it = it_begin; it != it_end; ++it)
301  {
302  bool print_element=false;
303  ++current_element;
304  number_of_cuts = 0;
305  exact_nodes = 0;
306  outside_nodes = 0;
307  Geometry<Node >&geom = it->GetGeometry(); //geometry of the element
308  for (unsigned int i = 0; i < it->GetGeometry().size(); i++) //size = 4 ; nodes per element. NOTICE WE'LL BE LOOPING THE EDGES TWICE. THIS IS A WASTE OF TIME BUT MAKES IT EASIER TO IDENTITY ELEMENTS. LOOK BELOW.
309  //when we have a triangle inside a thetraedra, its edges (or nodes) must be cut 3 times by the plane. if we loop all 2 times we can have a counter. when it's = 6 then we have a triangle. when tetraedras are cutted 8 times then we have 2 triangles (or a cuatrilateral, the same)
310  {
311  node_value= geom[i].FastGetSolutionStepValue(variable);
312  diff_node_value = isovalue - node_value; // dist = (xnode-xp)*versor closest point-plane distance
313  for (unsigned int j = 0; j < it->GetGeometry().size(); j++) // looping on the neighbours
314  {
315  //unsigned int this_node_cutted_edges=0;
316  if (i != j) //(cant link node with itself)
317  {
318  neigh_value= geom[j].FastGetSolutionStepValue(variable);
319  diff_neigh_value = isovalue - neigh_value;
320  //diff_node_neigh = node_value - neigh_value;
321  //now that we have the two points of the edge defined we can check whether it is cut by the plane or not
322 
323  if ((diff_node_value * diff_neigh_value) < 0.0 ) // this means one is on top of the plane and the other on the bottom, no need to do more checks, it's in between!
324  {
325  ++number_of_cuts;
326  }
327  } //closing the i!=j if
328  } //closing the neighbour (j) loop
329  } //closing the nodes (i) loop
330 
331 
332  //now we have to save the data. we should get a list with the elements that will genereate triangles and the total number of triangles
333  if (exact_nodes < 4 || outside_nodes<2 ) //this means at least one new node has to be generated
334  {
335  if (number_of_cuts == 6 || number_of_cuts == 6) //it can be 8, in that case we have 2 triangles (the cut generates a square)
336  print_element=true;
337 
338  }
339  if (print_element==true)
340  {
341  for (unsigned int i = 0; i < it->GetGeometry().size(); i++) //size = 4 ; nodes per element. NOTICE WE'LL BE LOOPING THE EDGES TWICE. THIS IS A WASTE OF TIME BUT MAKES IT EASIER TO IDENTITY ELEMENTS. LOOK BELOW.
342  //when we have a triangle inside a thetraedra, its edges (or nodes) must be cut 3 times by the plane. if we loop all 2 times we can have a counter. when it's = 6 then we have a triangle. when tetraedras are cutted 8 times then we have 2 triangles (or a cuatrilateral, the same)
343  {
344  int node_position = this_model_part.Nodes().find(geom[i].Id()) - it_begin_node_old;
345  m_used_nodes[node_position]=true;
346  }
347  }
348  } //closing the elem loop
349 
350  //looping the nodes, =true if below isovalue
352  {
353  //if (m_used_nodes[i]==true)
354  node_value= it->FastGetSolutionStepValue(variable);
355  if (node_value<isovalue)
356  {
357  int node_position = it- mr_model_part.NodesBegin();
358  m_used_nodes[node_position]=true;
359  }
360  //*++i;
361  }//closing node loop
362 
363  //cout << "Added nodes that are part of the isosurface to the priting list" << endl;
364 
365  KRATOS_CATCH("")
366  }
367 
368 
369 
371  //this is the function to create isosurfaces from a scalar variable. the other (a component from a vectorial variable) will be added later
372  void AddScalarVarIsosurfaceAndHigher( Variable<double>& variable, double isovalue)
373  {
374  KRATOS_TRY
375 
376  /*
377  cout <<"Printing Isosurface Nodes with the following data:"<<endl;
378  KRATOS_WATCH(variable);
379  KRATOS_WATCH(isovalue);
380  */
381 
382  ModelPart& this_model_part = mr_model_part;
383  //ModelPart& new_model_part = mr_new_model_part;
384 
385  ElementsArrayType& rElements = this_model_part.Elements();
386 
387  //first of all create a matrix with no overlap
388  ElementsArrayType::iterator it_begin = rElements.ptr_begin(); //+element_partition[k];
389  ElementsArrayType::iterator it_end = rElements.ptr_end(); //+element_partition[k+1];
390 
391  NodesArrayType& rNodes_old = this_model_part.Nodes(); //needed to find the position of the node in the node array
392  NodesArrayType::iterator it_begin_node_old = rNodes_old.ptr_begin();
393 
394  double node_value; // node to closest point in the plane
395  double neigh_value; //other node of the edge (neighbour) to closest point in the plane
396  double diff_node_value; // difference between the imposed value of the variable and its value in the node
397  double diff_neigh_value;; //distance between the two nodes of the edge
398  //double diff_node_neigh;
399  array_1d<unsigned int, 4 > list_matching_nodes; // used to save the new nodes that match exactly old nodes (very unlikely, but might be 4 for very plane elements)
400  unsigned int exact_nodes = 0;
401  unsigned int outside_nodes = 0;
402  int current_element=0;
403  int number_of_cuts=0;
404 
405  for (ElementsArrayType::iterator it = it_begin; it != it_end; ++it)
406  {
407  bool print_element=false;
408  ++current_element;
409  number_of_cuts = 0;
410  exact_nodes = 0;
411  outside_nodes = 0;
412  Geometry<Node >&geom = it->GetGeometry(); //geometry of the element
413  for (unsigned int i = 0; i < it->GetGeometry().size(); i++) //size = 4 ; nodes per element. NOTICE WE'LL BE LOOPING THE EDGES TWICE. THIS IS A WASTE OF TIME BUT MAKES IT EASIER TO IDENTITY ELEMENTS. LOOK BELOW.
414  //when we have a triangle inside a thetraedra, its edges (or nodes) must be cut 3 times by the plane. if we loop all 2 times we can have a counter. when it's = 6 then we have a triangle. when tetraedras are cutted 8 times then we have 2 triangles (or a cuatrilateral, the same)
415  {
416  node_value= geom[i].FastGetSolutionStepValue(variable);
417  diff_node_value = isovalue - node_value; // dist = (xnode-xp)*versor closest point-plane distance
418  for (unsigned int j = 0; j < it->GetGeometry().size(); j++) // looping on the neighbours
419  {
420  //unsigned int this_node_cutted_edges=0;
421  if (i != j) //(cant link node with itself)
422  {
423  neigh_value= geom[j].FastGetSolutionStepValue(variable);
424  diff_neigh_value = isovalue - neigh_value;
425  //diff_node_neigh = node_value - neigh_value;
426  //now that we have the two points of the edge defined we can check whether it is cut by the plane or not
427 
428  if ((diff_node_value * diff_neigh_value) < 0.0 ) // this means one is on top of the plane and the other on the bottom, no need to do more checks, it's in between!
429  {
430  ++number_of_cuts;
431  }
432  } //closing the i!=j if
433  } //closing the neighbour (j) loop
434  } //closing the nodes (i) loop
435 
436 
437  //now we have to save the data. we should get a list with the elements that will genereate triangles and the total number of triangles
438  if (exact_nodes < 4 || outside_nodes<2 ) //this means at least one new node has to be generated
439  {
440  if (number_of_cuts == 6 || number_of_cuts == 6) //it can be 8, in that case we have 2 triangles (the cut generates a square)
441  print_element=true;
442 
443  }
444  if (print_element==true)
445  {
446  for (unsigned int i = 0; i < it->GetGeometry().size(); i++) //size = 4 ; nodes per element. NOTICE WE'LL BE LOOPING THE EDGES TWICE. THIS IS A WASTE OF TIME BUT MAKES IT EASIER TO IDENTITY ELEMENTS. LOOK BELOW.
447  //when we have a triangle inside a thetraedra, its edges (or nodes) must be cut 3 times by the plane. if we loop all 2 times we can have a counter. when it's = 6 then we have a triangle. when tetraedras are cutted 8 times then we have 2 triangles (or a cuatrilateral, the same)
448  {
449  int node_position = this_model_part.Nodes().find(geom[i].Id()) - it_begin_node_old;
450  m_used_nodes[node_position]=true;
451  }
452  }
453  } //closing the elem loop
454 
455  //looping the nodes, =true if below isovalue
457  {
458  //if (m_used_nodes[i]==true)
459  node_value= it->FastGetSolutionStepValue(variable);
460  if (node_value>isovalue)
461  {
462  int node_position = it- mr_model_part.NodesBegin();
463  m_used_nodes[node_position]=true;
464  }
465  //*++i;
466  }//closing node loop
467 
468  //cout << "Added nodes that are part of the isosurface to the priting list" << endl;
469 
470  KRATOS_CATCH("")
471  }
472 
473 
475 
477 
479  {
480  NodesArrayType IsosurfaceNodes;
481  IsosurfaceNodes.clear();
482  //cout <<"Creating Nodes Array"<<endl;
483  int i=0;
484  //looping the nodes
486  {
487  if (m_used_nodes[i]==true)
488  {
489  IsosurfaceNodes.push_back(*it.base());
490 // IsosurfaceNodes.push_back(*it);
491  }
492  ++i;
493  }//closing node loop
494  //cout <<"my ID is" << mrComm.MyPID() <<"and i have"<< total_number_of_printed_nodes <<"nodes"<<endl;
495  return IsosurfaceNodes;
496  }//closing subroutine
497 
498 
500 
501  void ClearData()
502  {
503  int nnodes = mr_model_part.Nodes().size(); //both local nodes and the ones belonging to other CPU
504  //m_used_nodes.resize(nnodes);
505  for (int index = 0; index!=nnodes; ++index) m_used_nodes[index]=false; //starting as zero (no needed nodes)
506  }
507 
508 
509 
510 
511 
512 protected:
515 
516 
517 };
518 
519 
520 
521 
522 
523 } // namespace Kratos.
524 
525 #endif // KRATOS_ISO_PRINTING_APP defined
526 
527 
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
Definition: amatrix_interface.h:41
Definition: iso_printer.h:94
Node ::Pointer PointPointerType
Definition: iso_printer.h:104
void AddScalarVarIsosurfaceAndLower(Variable< double > &variable, double isovalue)
Definition: iso_printer.h:267
void AddSkinConditions()
ADDSKINCONDITIONS: THIS FUNCTION ADDS TO THE NEW MODEL PART THE DATA OF THE CONDITIONS BELONGING TO T...
Definition: iso_printer.h:134
DenseVector< Vector_Order_Tensor > Node_Vector_Order_Tensor
Definition: iso_printer.h:102
void AddScalarVarIsosurfaceAndHigher(Variable< double > &variable, double isovalue)
Definition: iso_printer.h:372
ModelPart::ConditionsContainerType ConditionsArrayType
Definition: iso_printer.h:99
PointVector::iterator PointIterator
Definition: iso_printer.h:106
~IsosurfacePrinterApplication()
Definition: iso_printer.h:120
void ClearData()
Definition: iso_printer.h:501
void AddScalarVarIsosurface(Variable< double > &variable, double isovalue)
Definition: iso_printer.h:174
ModelPart & mr_model_part
Definition: iso_printer.h:514
ModelPart::NodesContainerType NodesArrayType
Definition: iso_printer.h:97
std::vector< PointType::Pointer > PointVector
Definition: iso_printer.h:105
DenseVector< Matrix > Matrix_Order_Tensor
Definition: iso_printer.h:100
ModelPart::ElementsContainerType ElementsArrayType
Definition: iso_printer.h:98
IsosurfacePrinterApplication(ModelPart &model_part)
Definition: iso_printer.h:112
DenseVector< bool > m_used_nodes
Definition: iso_printer.h:513
DenseVector< Vector > Vector_Order_Tensor
Definition: iso_printer.h:101
NodesArrayType CreateNodesArray()
Definition: iso_printer.h:478
Node PointType
Definition: iso_printer.h:103
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ConditionIterator ConditionsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1361
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
ConditionIterator ConditionsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1371
This class defines the node.
Definition: node.h:65
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
ptr_iterator ptr_end()
Returns an iterator pointing to the end of the underlying data container.
Definition: pointer_vector_set.h:404
void clear()
Clear the set, removing all elements.
Definition: pointer_vector_set.h:663
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector_set.h:95
ptr_iterator ptr_begin()
Returns an iterator pointing to the beginning of the underlying data container.
Definition: pointer_vector_set.h:386
void push_back(TPointerType x)
Adds a pointer to the end of the set.
Definition: pointer_vector_set.h:544
Short class definition.
Definition: array_1d.h:61
#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
model_part
Definition: face_heat.py:14
int j
Definition: quadrature.py:648
int nnodes
Definition: sensitivityMatrix.py:24
integer i
Definition: TensorModule.f:17