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.
recover_volume_losses_process.hpp
Go to the documentation of this file.
1 //
2 // Project Name: KratosPfemApplication $
3 // Created by: $Author: JMCarbonell $
4 // Last modified by: $Co-Author: $
5 // Date: $Date: August 2018 $
6 // Revision: $Revision: 0.0 $
7 //
8 //
9 
10 
11 #if !defined(KRATOS_RECOVER_VOLUME_LOSSES_PROCESS_H_INCLUDED )
12 #define KRATOS_RECOVER_VOLUME_LOSSES_PROCESS_H_INCLUDED
13 
14 // External includes
15 
16 // System includes
17 
18 // Project includes
19 #include "includes/model_part.h"
21 #include "processes/process.h"
22 
23 
24 namespace Kratos
25 {
26 
29 
31 
35 {
36  public:
39 
42 
47 
51 
54  int EchoLevel)
55  : Process(Flags()), mrModelPart(rModelPart), mEchoLevel(EchoLevel)
56  {
57  mTotalVolume = 0;
58  }
59 
60 
63 
64 
68 
70  void operator()()
71  {
72  Execute();
73  }
74 
78 
80  void Execute() override
81  {
82  }
83 
86  void ExecuteInitialize() override
87  {
88  }
89 
92  void ExecuteBeforeSolutionLoop() override
93  {
94  mTotalVolume = this->ComputeVolume(mrModelPart);
95  }
96 
97 
100  {
101  KRATOS_TRY
102 
103  //recover volume losses due meshing
104  mTotalVolume = this->RecoverVolume(mrModelPart);
105 
106  KRATOS_CATCH("")
107  }
108 
111  {
112 
113  //recover volume losses due computation
114  mTotalVolume = this->RecoverVolume(mrModelPart);
115 
116  }
117 
118 
120  void ExecuteBeforeOutputStep() override
121  {
122  }
123 
124 
126  void ExecuteAfterOutputStep() override
127  {
128  }
129 
130 
133  void ExecuteFinalize() override
134  {
135  }
136 
137 
147 
149  std::string Info() const override
150  {
151  return "RecoverVolumeLossesProcess";
152  }
153 
155  void PrintInfo(std::ostream& rOStream) const override
156  {
157  rOStream << "RecoverVolumeLossesProcess";
158  }
159 
161  void PrintData(std::ostream& rOStream) const override
162  {
163  }
164 
169 
170  protected:
171 
193 
194  private:
195 
201 
202  ModelPart& mrModelPart;
203 
204  double mTotalVolume;
205 
206  int mEchoLevel;
207 
214 
215  //*******************************************************************************************
216  //*******************************************************************************************
217 
218  double RecoverVolume(ModelPart& rModelPart)
219  {
220 
221  KRATOS_TRY
222 
223  double Tolerance = 1e-6;
224  unsigned int NumberOfIterations = 5;
225  unsigned int iteration = -1;
226 
227  double CurrentVolume = this->ComputeVolume(rModelPart);
228 
229  double Error = fabs(mTotalVolume-CurrentVolume);
230 
231  this->SetFreeSurfaceElements(rModelPart);
232  double FreeSurfaceVolume = this->ComputeFreeSurfaceVolume(rModelPart);
233  double FreeSurfaceArea = this->ComputeFreeSurfaceArea(rModelPart);
234 
235  double VolumeIncrement = mTotalVolume-CurrentVolume;
236  //initial prediction of the offset
237  double Offset = VolumeIncrement/FreeSurfaceArea;
238 
239  FreeSurfaceVolume += VolumeIncrement;
240 
241  double CurrentFreeSurfaceVolume = 0;
242 
243  while( ++iteration < NumberOfIterations && Error > Tolerance )
244  {
245 
246  this->MoveFreeSurface(rModelPart,Offset);
247 
248  CurrentFreeSurfaceVolume = this->ComputeFreeSurfaceVolume(rModelPart);
249 
250  VolumeIncrement = (FreeSurfaceVolume - CurrentFreeSurfaceVolume);
251 
252  Offset = (VolumeIncrement / FreeSurfaceArea );
253 
254  Error = fabs(VolumeIncrement);
255 
256  //std::cout<<" Iteration: "<<iteration<<" Error in Volume "<<Error<<std::endl;
257  }
258 
259 
260  this->ResetFreeSurfaceElements(rModelPart);
261 
262  CurrentVolume = this->ComputeVolume(rModelPart);
263 
264  //std::cout<<" Recover Volume Losses perfomed in "<<iteration<<" iterations : Error "<<Error<<" CurrentVolume "<<CurrentVolume<<std::endl;
265 
266  return CurrentVolume;
267 
268  KRATOS_CATCH("")
269  }
270 
271 
272  //*******************************************************************************************
273  //*******************************************************************************************
274 
275  void MoveFreeSurface(ModelPart& rModelPart, const double& rOffset)
276  {
277  KRATOS_TRY
278 
279  ModelPart::NodesContainerType::iterator it_begin = rModelPart.NodesBegin();
280  int NumberOfNodes = rModelPart.NumberOfNodes();
281 
282  #pragma omp parallel for
283  for (int i=0; i<NumberOfNodes; ++i)
284  {
285  ModelPart::NodesContainerType::iterator i_node = it_begin + i;
286  if(i_node->Is(FREE_SURFACE) && (i_node->IsNot(RIGID) && i_node->IsNot(SOLID)) ){
287  const array_1d<double,3>& rNormal = i_node->FastGetSolutionStepValue(NORMAL);
288  i_node->Coordinates() += rOffset * rNormal;
289  i_node->FastGetSolutionStepValue(DISPLACEMENT) += rOffset * rNormal;
290  i_node->FastGetSolutionStepValue(DISPLACEMENT,1) += rOffset * rNormal;
291  }
292  }
293 
294  KRATOS_CATCH("")
295  }
296 
297 
298  //*******************************************************************************************
299  //*******************************************************************************************
300 
301  void SetFreeSurfaceElements(ModelPart& rModelPart)
302  {
303  KRATOS_TRY
304 
305  for(ModelPart::ElementsContainerType::iterator i_elem = rModelPart.ElementsBegin() ; i_elem != rModelPart.ElementsEnd() ; ++i_elem)
306  {
307  for(unsigned int i=0; i<i_elem->GetGeometry().size(); ++i)
308  {
309  if(i_elem->GetGeometry()[i].Is(FREE_SURFACE)){
310  i_elem->Set(FREE_SURFACE,true);
311  break;
312  }
313  }
314  }
315 
316  KRATOS_CATCH("")
317  }
318 
319 
320  //*******************************************************************************************
321  //*******************************************************************************************
322 
323  void ResetFreeSurfaceElements(ModelPart& rModelPart)
324  {
325  KRATOS_TRY
326 
327  for(ModelPart::ElementsContainerType::iterator i_elem = rModelPart.ElementsBegin() ; i_elem != rModelPart.ElementsEnd() ; ++i_elem)
328  {
329  i_elem->Set(FREE_SURFACE,false);
330  }
331 
332  KRATOS_CATCH("")
333  }
334 
335  //*******************************************************************************************
336  //*******************************************************************************************
337 
338  double ComputeVolume(ModelPart& rModelPart)
339  {
340  KRATOS_TRY
341 
342  const unsigned int dimension = rModelPart.GetProcessInfo()[SPACE_DIMENSION];
343  double ModelPartVolume = 0;
344 
345  if( dimension == 2 ){
346 
347  ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
348  int NumberOfElements = rModelPart.NumberOfElements();
349 
350  #pragma omp parallel for reduction(+:ModelPartVolume)
351  for (int i=0; i<NumberOfElements; ++i)
352  {
353  ModelPart::ElementsContainerType::iterator i_elem = it_begin + i;
354  if( i_elem->GetGeometry().Dimension() == 2 && i_elem->Is(FLUID) )
355  ModelPartVolume += i_elem->GetGeometry().Area();
356  }
357  }
358  else{ //dimension == 3
359 
360  ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
361  int NumberOfElements = rModelPart.NumberOfElements();
362 
363  #pragma omp parallel for reduction(+:ModelPartVolume)
364  for (int i=0; i<NumberOfElements; ++i)
365  {
366  ModelPart::ElementsContainerType::iterator i_elem = it_begin + i;
367  if( i_elem->GetGeometry().Dimension() == 3 && i_elem->Is(FLUID) )
368  ModelPartVolume += i_elem->GetGeometry().Volume();
369  }
370  }
371 
372  return ModelPartVolume;
373 
374  KRATOS_CATCH("")
375 
376  }
377 
378  //*******************************************************************************************
379  //*******************************************************************************************
380 
381  double ComputeFreeSurfaceVolume(ModelPart& rModelPart)
382  {
383  KRATOS_TRY
384 
385  const unsigned int dimension = rModelPart.GetProcessInfo()[SPACE_DIMENSION];
386  double ModelPartVolume = 0;
387 
388  if( dimension == 2 ){
389 
390  ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
391  int NumberOfElements = rModelPart.NumberOfElements();
392 
393  #pragma omp parallel for reduction(+:ModelPartVolume)
394  for (int i=0; i<NumberOfElements; ++i)
395  {
396  ModelPart::ElementsContainerType::iterator i_elem = it_begin + i;
397  if( i_elem->GetGeometry().Dimension() == 2 && i_elem->Is(FREE_SURFACE) && i_elem->Is(FLUID) )
398  ModelPartVolume += i_elem->GetGeometry().Area();
399  }
400  }
401  else{ //dimension == 3
402 
403  ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
404  int NumberOfElements = rModelPart.NumberOfElements();
405 
406  #pragma omp parallel for reduction(+:ModelPartVolume)
407  for (int i=0; i<NumberOfElements; ++i)
408  {
409  ModelPart::ElementsContainerType::iterator i_elem = it_begin + i;
410  if( i_elem->GetGeometry().Dimension() == 3 && i_elem->Is(FREE_SURFACE) && i_elem->Is(FLUID) )
411  ModelPartVolume += i_elem->GetGeometry().Volume();
412  }
413  }
414 
415  return ModelPartVolume;
416 
417  KRATOS_CATCH("")
418 
419  }
420 
421 
422  //*******************************************************************************************
423  //*******************************************************************************************
424 
425  double ComputeFreeSurfaceArea(ModelPart& rModelPart)
426  {
427  KRATOS_TRY
428 
429  const unsigned int dimension = rModelPart.GetProcessInfo()[SPACE_DIMENSION];
430  double FreeSurfaceArea = 0;
431 
432  if( dimension == 2 ){
433 
434  ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
435  int NumberOfElements = rModelPart.NumberOfElements();
436 
437  #pragma omp parallel for reduction(+:FreeSurfaceArea)
438  for (int i=0; i<NumberOfElements; ++i)
439  {
440  ModelPart::ElementsContainerType::iterator i_elem = it_begin + i;
441  GeometryType& rGeometry = i_elem->GetGeometry();
442  if( rGeometry.Dimension() == 2 && i_elem->Is(FREE_SURFACE) && i_elem->Is(FLUID) ){
443  for(unsigned int j=0; j<rGeometry.size()-1; ++j)
444  {
445  if(rGeometry[j].Is(FREE_SURFACE)){
446  for(unsigned int k=j+1; k<rGeometry.size(); ++k)
447  {
448  if(rGeometry[k].Is(FREE_SURFACE)){
449  FreeSurfaceArea += norm_2( rGeometry[k].Coordinates() - rGeometry[j].Coordinates() );
450  }
451  }
452 
453  }
454  }
455  }
456  }
457  }
458  else{ //dimension == 3
459 
460  DenseMatrix<unsigned int> lpofa; //connectivities of points defining faces
461  DenseVector<unsigned int> lnofa; //number of points defining faces
462 
463  ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
464  int NumberOfElements = rModelPart.NumberOfElements();
465 
466  #pragma omp parallel for private(lpofa,lnofa) reduction(+:FreeSurfaceArea)
467  for (int i=0; i<NumberOfElements; ++i)
468  {
469  ModelPart::ElementsContainerType::iterator i_elem = it_begin + i;
470 
471  GeometryType& rGeometry = i_elem->GetGeometry();
472 
473  if( rGeometry.Dimension() == 3 && i_elem->Is(FREE_SURFACE) && i_elem->Is(FLUID) ){
474 
475  rGeometry.NodesInFaces(lpofa);
476  rGeometry.NumberNodesInFaces(lnofa);
477 
478  for(unsigned int iface=0; iface<rGeometry.FacesNumber(); ++iface)
479  {
480  unsigned int free_surface = 0;
481  for(unsigned int j=1; j<=lnofa[iface]; ++j)
482  if(rGeometry[j].Is(FREE_SURFACE))
483  ++free_surface;
484 
485  if(free_surface==lnofa[iface])
486  FreeSurfaceArea+=Compute3DArea(rGeometry[lpofa(1,iface)].Coordinates(),
487  rGeometry[lpofa(2,iface)].Coordinates(),
488  rGeometry[lpofa(3,iface)].Coordinates());
489  }
490  }
491  }
492  }
493 
494  return FreeSurfaceArea;
495 
496  KRATOS_CATCH("")
497 
498  }
499 
500  //*******************************************************************************************
501  //*******************************************************************************************
502 
503  double Compute3DArea(array_1d<double,3> PointA, array_1d<double,3> PointB, array_1d<double,3> PointC){
504  double a = MathUtils<double>::Norm3(PointA - PointB);
505  double b = MathUtils<double>::Norm3(PointB - PointC);
506  double c = MathUtils<double>::Norm3(PointC - PointA);
507  double s = (a+b+c) / 2.0;
508  double Area=std::sqrt(s*(s-a)*(s-b)*(s-c));
509  return Area;
510  }
511 
515 
516 
520 
521 
525 
526 
528  RecoverVolumeLossesProcess& operator=(RecoverVolumeLossesProcess const& rOther);
529 
530 
532 
533 
535  //Process(Process const& rOther);
536 
537 
539 
540 }; // Class Process
541 
543 
546 
547 
551 
552 
554 inline std::istream& operator >> (std::istream& rIStream,
556 
558 inline std::ostream& operator << (std::ostream& rOStream,
559  const RecoverVolumeLossesProcess& rThis)
560 {
561  rThis.PrintInfo(rOStream);
562  rOStream << std::endl;
563  rThis.PrintData(rOStream);
564 
565  return rOStream;
566 }
568 
569 
570 } // namespace Kratos.
571 
572 #endif // KRATOS_RECOVER_VOLUME_LOSSES_PROCESS_H_INCLUDED defined
Base class for all Conditions.
Definition: condition.h:59
Definition: flags.h:58
bool Is(Flags const &rOther) const
Definition: flags.h:274
Geometry base class.
Definition: geometry.h:71
virtual void NodesInFaces(DenseMatrix< unsigned int > &rNodesInFaces) const
Definition: geometry.h:2195
static double Norm3(const TVectorType &a)
Calculates the norm of vector "a" which is assumed to be of size 3.
Definition: math_utils.h:691
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
This class defines the node.
Definition: node.h:65
The base class for all processes in Kratos.
Definition: process.h:49
Properties encapsulates data shared by different Elements or Conditions. It can store any type of dat...
Definition: properties.h:69
Move free surface to restore volume losses.
Definition: recover_volume_losses_process.hpp:35
void ExecuteBeforeSolutionLoop() override
Definition: recover_volume_losses_process.hpp:92
ModelPart::NodeType NodeType
Definition: recover_volume_losses_process.hpp:43
void ExecuteAfterOutputStep() override
this function will be executed at every time step AFTER writing the output
Definition: recover_volume_losses_process.hpp:126
ConditionType::GeometryType GeometryType
Definition: recover_volume_losses_process.hpp:46
ModelPart::PropertiesType PropertiesType
Definition: recover_volume_losses_process.hpp:45
void Execute() override
Execute method is used to execute the AssignPropertiesToNodesProcess algorithms.
Definition: recover_volume_losses_process.hpp:80
RecoverVolumeLossesProcess(ModelPart &rModelPart, int EchoLevel)
Default constructor.
Definition: recover_volume_losses_process.hpp:53
void operator()()
This operator is provided to call the process as a function and simply calls the Execute method.
Definition: recover_volume_losses_process.hpp:70
void ExecuteFinalizeSolutionStep() override
this function will be executed at every time step AFTER performing the solve phase
Definition: recover_volume_losses_process.hpp:110
ModelPart::ConditionType ConditionType
Definition: recover_volume_losses_process.hpp:44
void ExecuteFinalize() override
Definition: recover_volume_losses_process.hpp:133
void ExecuteInitializeSolutionStep() override
this function will be executed at every time step BEFORE performing the solve phase
Definition: recover_volume_losses_process.hpp:99
void ExecuteInitialize() override
Definition: recover_volume_losses_process.hpp:86
std::string Info() const override
Turn back information as a string.
Definition: recover_volume_losses_process.hpp:149
KRATOS_CLASS_POINTER_DEFINITION(RecoverVolumeLossesProcess)
Pointer definition of Process.
void PrintData(std::ostream &rOStream) const override
Print object's data.s.
Definition: recover_volume_losses_process.hpp:161
void ExecuteBeforeOutputStep() override
this function will be executed at every time step BEFORE writing the output
Definition: recover_volume_losses_process.hpp:120
virtual ~RecoverVolumeLossesProcess()
Destructor.
Definition: recover_volume_losses_process.hpp:62
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: recover_volume_losses_process.hpp:155
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
iteration
Definition: DEM_benchmarks.py:172
static int EchoLevel
Definition: co_sim_EMPIRE_API.h:42
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
a
Definition: generate_stokes_twofluid_element.py:77
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
c
Definition: generate_weakly_compressible_navier_stokes_element.py:108
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31