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.
embedded_volume_tool.h
Go to the documentation of this file.
1 #ifndef EMBEDDED_VOLUME_TOOL_H
2 #define EMBEDDED_VOLUME_TOOL_H
3 //
4 // Project Name: Kratos
5 // Last Modified by: $Author: Guillermo Casas $
6 // Date: $Date: 2012-03-08 08:56:42 $
7 //
8 //
9 
10 // /* External includes */
11 
12 // System includes
13 #include <string>
14 #include <iostream>
15 #include <cstdlib>
16 
17 // Project includes
18 #include "includes/model_part.h"
19 
20 namespace Kratos
21 {
22 
25 
29 
33 
37 
41 
44 
47 //class EmbeddedVolumeTool
48 template<std::size_t TDim >
50 {
51 public:
54  typedef ModelPart::NodesContainerType::iterator NodeIteratorType;
55  typedef ModelPart::ElementsContainerType::iterator ElementIteratorType;
56  typedef std::size_t ListIndexType;
57 
60 
64 
67 
69  virtual ~EmbeddedVolumeTool() {}
70 
71 
75 
76  double CalculateNegativeDistanceVolume(ModelPart& rfluid_model_part)
77  {
78 
79  const int n_dem_elements = rfluid_model_part.Elements().size();
80  double total_volume = 0.0;
81 
82  for (int i = 0; i < n_dem_elements; i++){
83  ElementIteratorType ielem = rfluid_model_part.ElementsBegin() + i;
84  Geometry< Node >& geom = ielem->GetGeometry();
85 
86  array_1d<double, 4> distances;
87  unsigned int n_negatives = 0;
88 
89  for (unsigned int j = 0; j != 4; ++j){
90  double distance = geom[j].FastGetSolutionStepValue(DISTANCE);
91  distances[j] = distance;
92 
93  if (distance < 0.0){
94  ++n_negatives;
95  }
96 
97  }
98 
99  if (n_negatives == 1){
100 
101  for (unsigned int j = 0; j != 4; ++j){
102 
103  if (distances[j] < 0.0){
104  total_volume += CalculatePyramidVolume(j, geom, distances);
105  break;
106  }
107  }
108 
109  }
110 
111  else if (n_negatives == 2){
112 
113  for (unsigned int j = 0; j != 3; ++j){
114 
115  if (distances[j] < 0.0){
116 
117  for (unsigned int k = j + 1; j != 4; ++k){
118 
119  if (distances[k] < 0.0){
120  total_volume += CalculateHexahedronVolume(j, k, geom, distances);
121  break;
122 
123  }
124 
125  }
126 
127  break;
128 
129  }
130 
131  }
132 
133  }
134 
135  else if (n_negatives == 3){
136 
137  for (unsigned int j = 0; j != 4; ++j){
138 
139  if (distances[j] >= 0.0){
140  total_volume += fabs(CalculateVol(geom)) - CalculatePyramidVolume(j, geom, distances);
141  break;
142  }
143 
144  }
145 
146  }
147 
148  else if (n_negatives == 4){
149  total_volume += fabs(CalculateVol(geom));
150  }
151  }
152 
153  return total_volume;
154  }
155 
159 
160 
164 
165 
169 
170 
174 
176  virtual std::string Info() const
177  {
178  return "";
179  }
180 
182  virtual void PrintInfo(std::ostream& rOStream) const {}
183 
185  virtual void PrintData(std::ostream& rOStream) const {}
186 
187 
191 
193 
194 protected:
197 
198 
202 
203 
207 
208 
212 
213 
217 
218 
222 
223 
227 
228 
230 
231 private:
234 
235 
239 
240  //***************************************************************************************************************
241  //***************************************************************************************************************
242 
243  inline double CalculateVol(Geometry<Node >&geom)
244  {
245  return CalculateVol(geom[0].X(), geom[0].Y(), geom[0].Z(),
246  geom[1].X(), geom[1].Y(), geom[1].Z(),
247  geom[2].X(), geom[2].Y(), geom[2].Z(),
248  geom[3].X(), geom[3].Y(), geom[3].Z());
249  }
250 
251  //***************************************************************************************************************
252  //***************************************************************************************************************
253 
254  inline double CalculateVol(const double x0, const double y0,
255  const double x1, const double y1,
256  const double x2, const double y2)
257  {
258  return 0.5 * ((x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0));
259  }
260 
261  //***************************************************************************************************************
262  //***************************************************************************************************************
263 
264  inline double CalculateVol(const double x0, const double y0, const double z0,
265  const double x1, const double y1, const double z1,
266  const double x2, const double y2, const double z2,
267  const double x3, const double y3, const double z3)
268  {
269  double x10 = x1 - x0;
270  double y10 = y1 - y0;
271  double z10 = z1 - z0;
272 
273  double x20 = x2 - x0;
274  double y20 = y2 - y0;
275  double z20 = z2 - z0;
276 
277  double x30 = x3 - x0;
278  double y30 = y3 - y0;
279  double z30 = z3 - z0;
280 
281  double detJ = x10 * y20 * z30 - x10 * y30 * z20 +
282  y10 * z20 * x30 - y10 * x20 * z30 +
283  z10 * x20 * y30 - z10 * y20 * x30;
284 
285  return detJ * 0.1666666666666666666667;
286  }
287 
288  //***************************************************************************************************************
289  //***************************************************************************************************************
290 
291  inline double CalculatePyramidVolume(const unsigned int j, // tip of the pyramid
292  const Geometry<Node >&geom,
293  const array_1d<double, 4>& signed_dist) // nodal signed distances
294  {
295  array_1d<array_1d<double, 3>, 4 > coor; // coordinates of the pyramid vertices
296  array_1d<double, 4> dist;
297 
298  for (unsigned int i = 0; i != 4; ++i){
299  dist[i] = fabs(signed_dist[i]);
300  }
301 
302  for (unsigned int i = 0; i != 4; ++i){
303 
304  if (i == j){
305  coor[i][0] = geom[j].X();
306  coor[i][1] = geom[j].Y();
307  coor[i][2] = geom[j].Z();
308  }
309 
310  else { // for each edge, the weight of one end's coordinates is proportional to the absolut value of the signed distance of the other
311  double sum_d_inv = 1 / (dist[i] + dist[j]);
312  coor[i][0] = (geom[i].X() * dist[j] + geom[j].X() * dist[i]) * sum_d_inv;
313  coor[i][1] = (geom[i].Y() * dist[j] + geom[j].Y() * dist[i]) * sum_d_inv;
314  coor[i][2] = (geom[i].Z() * dist[j] + geom[j].Z() * dist[i]) * sum_d_inv;
315  }
316 
317  }
318 
319  return fabs(CalculateVol(coor[0][0], coor[0][1], coor[0][2],
320  coor[1][0], coor[1][1], coor[1][2],
321  coor[2][0], coor[2][1], coor[2][2],
322  coor[3][0], coor[3][1], coor[3][2]));
323  }
324 
325  //***************************************************************************************************************
326  //***************************************************************************************************************
327 
328  inline double CalculateHexahedronVolume(const unsigned int j, // first node included in the volume
329  const unsigned int k, // second node included in the volume
330  const Geometry<Node >&geom,
331  const array_1d<double, 4>& signed_dist) // nodal signed distances
332  {
333  array_1d<array_1d<double, 3>, 4 > coor; // coordinates of the intersections
334  array_1d<double, 4> dist;
335 
336  for (unsigned int i = 0; i != 4; ++i){
337  dist[i] = fabs(signed_dist[i]);
338  }
339 
340  double sub_volume = 0.0;
341  unsigned int d = 0;
342 
343  for (unsigned int i = 0; i != 4; ++i){
344 
345  if (i != j && i != k){
346  double sum_d_j_inv = 1 / (dist[i] + dist[j]);
347  double sum_d_k_inv = 1 / (dist[i] + dist[k]);
348  coor[d][0] = (geom[i].X() * dist[j] + geom[j].X() * dist[i]) * sum_d_j_inv;
349  coor[d][1] = (geom[i].Y() * dist[j] + geom[j].Y() * dist[i]) * sum_d_j_inv;
350  coor[d][2] = (geom[i].Z() * dist[j] + geom[j].Z() * dist[i]) * sum_d_j_inv;
351  coor[d + 1][0] = (geom[i].X() * dist[k] + geom[k].X() * dist[i]) * sum_d_k_inv;
352  coor[d + 1][1] = (geom[i].Y() * dist[k] + geom[k].Y() * dist[i]) * sum_d_k_inv;
353  coor[d + 1][2] = (geom[i].Z() * dist[k] + geom[k].Z() * dist[i]) * sum_d_k_inv;
354  d += 2;
355  }
356 
357  }
358 
359  sub_volume += fabs(CalculateVol(geom[j].X(), geom[j].Y(), geom[j].Z(),
360  coor[1][0], coor[1][1], coor[1][2],
361  coor[2][0], coor[2][1], coor[2][2],
362  coor[3][0], coor[3][1], coor[3][2]));
363 
364  sub_volume += fabs(CalculateVol(geom[j].X(), geom[j].Y(), geom[j].Z(),
365  coor[0][0], coor[0][1], coor[0][2],
366  coor[1][0], coor[1][1], coor[1][2],
367  coor[3][0], coor[3][1], coor[3][2]));
368 
369  sub_volume += fabs(CalculateVol(geom[k].X(), geom[k].Y(), geom[k].Z(),
370  coor[0][0], coor[0][1], coor[0][2],
371  coor[1][0], coor[1][1], coor[1][2],
372  geom[j].X(), geom[j].Y(), geom[j].Z()));
373 
374  sub_volume += fabs(CalculateVol(geom[k].X(), geom[k].Y(), geom[k].Z(),
375  coor[0][0], coor[0][1], coor[0][2],
376  geom[j].X(), geom[j].Y(), geom[j].Z(),
377  coor[3][0], coor[3][1], coor[3][2]));
378 
379  return sub_volume;
380  }
381 
382  //***************************************************************************************************************
383  //***************************************************************************************************************
384 
388 
392 
393 
397 
398 
402 
403 
407 
409  EmbeddedVolumeTool& operator=(EmbeddedVolumeTool const& rOther);
410 
412 
413 }; // Class EmbeddedVolumeTool
414 
416 
419 
420 
424 
425 
426 
427 
429 template<std::size_t TDim>
430 inline std::ostream& operator << (std::ostream& rOStream,
431  const EmbeddedVolumeTool<TDim>& rThis)
432 {
433  rThis.PrintInfo(rOStream);
434  rOStream << std::endl;
435  rThis.PrintData(rOStream);
436 
437  return rOStream;
438 }
440 
441 
442 } // namespace Kratos.
443 
444 #endif // EMBEDDED_VOLUME_TOOL_H
Definition: embedded_volume_tool.h:50
ModelPart::NodesContainerType::iterator NodeIteratorType
Definition: embedded_volume_tool.h:54
ModelPart::ElementsContainerType::iterator ElementIteratorType
Definition: embedded_volume_tool.h:55
double CalculateNegativeDistanceVolume(ModelPart &rfluid_model_part)
Definition: embedded_volume_tool.h:76
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: embedded_volume_tool.h:185
virtual ~EmbeddedVolumeTool()
Destructor.
Definition: embedded_volume_tool.h:69
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: embedded_volume_tool.h:182
virtual std::string Info() const
Turn back information as a stemplate<class T, std::size_t dim> tring.
Definition: embedded_volume_tool.h:176
EmbeddedVolumeTool()
Default constructor.
Definition: embedded_volume_tool.h:66
std::size_t ListIndexType
Definition: embedded_volume_tool.h:56
KRATOS_CLASS_POINTER_DEFINITION(EmbeddedVolumeTool< TDim >)
Pointer definition of EmbeddedVolumeTool.
Geometry base class.
Definition: geometry.h:71
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
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
float dist
Definition: edgebased_PureConvection.py:89
x2
Definition: generate_frictional_mortar_condition.py:122
x1
Definition: generate_frictional_mortar_condition.py:121
int d
Definition: ode_solve.py:397
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17