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.
normal_calculation_utils.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: Pooyan Dadvand
11 // Riccardo Rossi
12 // Vicente Mataix Ferrandiz
13 // Ruben Zorrilla
14 //
15 
16 #if !defined(KRATOS_NORMAL_CALCULATION_UTILS )
17 #define KRATOS_NORMAL_CALCULATION_UTILS
18 
19 // System includes
20 
21 // External includes
22 
23 // Project includes
24 #include "includes/model_part.h"
25 #include "utilities/math_utils.h"
28 
29 namespace Kratos
30 {
31 
34 
38 
42 
46 
50 
59 class KRATOS_API(KRATOS_CORE) NormalCalculationUtils
60 {
61 public:
64 
66  typedef std::size_t IndexType;
67 
69  typedef std::size_t SizeType;
70 
71  // Node definitions
72  typedef Node NodeType;
73 
76 
79 
82 
85 
89 
93 
97 
103  template<class TContainerType>
105  ModelPart& rModelPart,
106  const NormalVariableType& rNormalVariable = NORMAL
107  );
108 
118  template<class TContainerType, bool TIsHistorical = true>
120  ModelPart& rModelPart,
121  const bool EnforceGenericGeometryAlgorithm = false,
122  const bool ConsiderUnitNormal = false,
123  const NormalVariableType& rNormalVariable = NORMAL
124  );
125 
134  template<class TContainerType, bool TIsHistorical = true>
136  ModelPart& rModelPart,
137  const bool EnforceGenericGeometryAlgorithm = false,
138  const NormalVariableType& rNormalVariable = NORMAL
139  );
140 
150  ConditionsArrayType& rConditions,
151  const std::size_t Dimension,
152  const NormalVariableType& rNormalVariable = NORMAL
153  );
154 
164  ConditionsArrayType& rConditions,
165  const std::size_t Dimension,
166  const NormalVariableType& rNormalVariable = NORMAL
167  );
168 
175  void CalculateNormalShapeDerivativesOnSimplex(
176  ConditionsArrayType& rConditions,
177  const std::size_t Dimension
178  );
179 
189  ModelPart& rModelPart,
190  const std::size_t Dimension,
191  const NormalVariableType& rNormalVariable = NORMAL
192  );
193 
203  ModelPart& rModelPart,
204  const std::size_t Dimension,
205  const NormalVariableType& rNormalVariable = NORMAL
206  );
207 
216  ModelPart& rModelPart,
217  const NormalVariableType& rNormalVariable = NORMAL
218  );
219 
228  ModelPart& rModelPart,
229  const NormalVariableType& rNormalVariable = NORMAL
230  );
231 
237  void SwapNormals(ModelPart& rModelPart);
238 
248  template<class TValueType>
250  ModelPart& rModelPart,
251  const std::size_t Dimension,
252  const Variable<TValueType>& rVariable,
253  const TValueType Zero,
254  const NormalVariableType& rNormalVariable = NORMAL
255  )
256  {
257  KRATOS_TRY;
258 
259  // Reset normals
260  //TODO: This can be parallel
261  const array_1d<double,3> ZeroNormal(3,0.0);
262  for(ModelPart::NodesContainerType::iterator it = rModelPart.NodesBegin(); it !=rModelPart.NodesEnd(); it++) {
263  noalias(it->FastGetSolutionStepValue(rNormalVariable)) = ZeroNormal;
264  }
265 
266  // Calculate new condition normals, using only conditions with rVariable == rValue
267  array_1d<double,3> An(3,0.0);
268 
269  if ( Dimension == 2 ) {
270  for ( ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); ++itCond ) {
271  if ( itCond->GetValue(rVariable) != Zero )
272  CalculateNormal2D(*itCond,An,rNormalVariable);
273  }
274  } else if ( Dimension == 3 ) {
275  array_1d<double,3> v1(3,0.0);
276  array_1d<double,3> v2(3,0.0);
277 
278  for ( ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); ++itCond ) {
279  if ( itCond->GetValue(rVariable) != Zero )
280  CalculateNormal3D(*itCond,An,v1,v2,rNormalVariable);
281  }
282  }
283 
284  // Transfer normals to nodes
285  for ( ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); ++itCond ) {
286  Condition::GeometryType& rGeom = itCond->GetGeometry();
287  const double Coef = 1.0 / rGeom.PointsNumber();
288  const auto& r_normal = itCond->GetValue(rNormalVariable);
289  for ( Condition::GeometryType::iterator itNode = rGeom.begin(); itNode != rGeom.end(); ++itNode)
290  noalias(itNode->FastGetSolutionStepValue(rNormalVariable)) += r_normal * Coef;
291  }
292 
293  // For MPI: correct values on partition boundaries
294  rModelPart.GetCommunicator().AssembleCurrentData(rNormalVariable);
295 
296  KRATOS_CATCH("");
297  }
298 
300 
307  template<class TValueType>
309  ModelPart& rModelPart,
310  const std::size_t Dimension,
311  const Variable<TValueType>& rVariable
312  )
313  {
314  CalculateOnSimplex(rModelPart,Dimension,rVariable,TValueType(),NORMAL);
315  }
316 
326  template<class TValueType>
328  ModelPart& rModelPart,
329  const std::size_t Dimension,
330  const Variable<TValueType>& rVariable,
331  const TValueType Zero,
332  const double rAlpha,
333  const NormalVariableType& rNormalVariable = NORMAL
334  )
335  {
336  KRATOS_TRY;
337 
338  // Reset normals
339  //TODO: This can be parallel
340  const array_1d<double,3> ZeroNormal(3,0.0);
341  for(ModelPart::NodesContainerType::iterator it = rModelPart.NodesBegin(); it !=rModelPart.NodesEnd(); it++) {
342  noalias(it->FastGetSolutionStepValue(NORMAL)) = ZeroNormal;
343  it->FastGetSolutionStepValue(NODAL_PAUX) = 0.0;
344  }
345 
346  // Calculate new condition normals, using only conditions with rVariable == rValue
347  array_1d<double,3> An(3,0.0);
348 
349  if ( Dimension == 2 ) {
350  for ( ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); ++itCond ) {
351  if ( itCond->GetValue(rVariable) != Zero )
352  CalculateNormal2D(*itCond,An,rNormalVariable);
353  }
354  } else if ( Dimension == 3 ) {
355  array_1d<double,3> v1(3,0.0);
356  array_1d<double,3> v2(3,0.0);
357 
358  for ( ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); ++itCond ) {
359  if ( itCond->GetValue(rVariable) != Zero )
360  CalculateNormal3D(*itCond,An,v1,v2,rNormalVariable);
361  }
362  }
363 
364  // Loop over nodes to set normals
365  for(ModelPart::NodesContainerType::iterator it = rModelPart.NodesBegin(); it !=rModelPart.NodesEnd(); it++) {
366  std::vector< array_1d<double,3> > N_Mat;
367  N_Mat.reserve(10);
368  double nodal_area = 0.0;
369 
370  GlobalPointersVector<Condition >& ng_cond = it->GetValue(NEIGHBOUR_CONDITIONS);
371 
372  if(ng_cond.size() != 0) {
373  for(GlobalPointersVector<Condition >::iterator ic = ng_cond.begin(); ic!=ng_cond.end(); ic++) {
374  Condition::GeometryType& pGeom = ic->GetGeometry();
375  const auto& rNormal = ic->GetValue(rNormalVariable);
376  const double Coef = 1.0 / pGeom.PointsNumber();
377  double norm_normal = norm_2( rNormal );
378 
379  if(norm_normal != 0.0) {
380  nodal_area += Coef * norm_normal;
381 
382  if(N_Mat.size() == 0.0) {
383  N_Mat.push_back( rNormal * Coef );
384  } else {
385  int added = 0;
386  for(unsigned int ii=0; ii<N_Mat.size();++ii) {
387  const array_1d<double,3>& temp_normal = N_Mat[ii];
388  double norm_temp = norm_2( temp_normal );
389 
390  double cos_alpha=temp_normal[0]*rNormal[0] + temp_normal[1]*rNormal[1] +temp_normal[2]*rNormal[2];
391  cos_alpha /= (norm_temp*norm_normal);
392 
393  if( cos_alpha > std::cos(0.017453293*rAlpha)) {
394  N_Mat[ii] += rNormal * Coef;
395  added = 1;
396  }
397  }
398 
399  if(!added)
400  N_Mat.push_back( rNormal*Coef );
401  }
402  }
403  }
404  }
405 
406  // Compute NORMAL and mark
407  array_1d<double,3> sum_Normal(3,0.0);
408 
409  for(unsigned int ii=0; ii<N_Mat.size(); ++ii) {
410  sum_Normal += N_Mat[ii];
411  }
412 
413  noalias( it->FastGetSolutionStepValue(rNormalVariable) ) = sum_Normal;
414  it->FastGetSolutionStepValue(NODAL_PAUX) = nodal_area;
415  //assign IS_SLIP = 0 for vertices
416  if(N_Mat.size() == 2) {
417 // it->SetValue(IS_SLIP,0);
418  it->FastGetSolutionStepValue(IS_SLIP)=20.0;
419  } else if(N_Mat.size() == 3) {
420  it->FastGetSolutionStepValue(IS_SLIP)=30.0;
421  } else if(N_Mat.size() == 1) {
422  it->FastGetSolutionStepValue(IS_SLIP)=10.0;
423  }
424  }
425 
426  // For MPI: correct values on partition boundaries
427  rModelPart.GetCommunicator().AssembleCurrentData(rNormalVariable);
428  rModelPart.GetCommunicator().AssembleCurrentData(NODAL_PAUX);
429 
430  KRATOS_CATCH("");
431  }
432 
442  template< class TValueType >
444  ModelPart& rModelPart,
445  int Dimension,
446  const Variable<TValueType>& rVariable,
447  const TValueType Zero,const double rAlpha,
448  const NormalVariableType& rNormalVariable = NORMAL
449  )
450  {
451  KRATOS_TRY;
452 
453  // Reset normals
454  //TODO: This can be parallel
455  const array_1d<double,3> ZeroNormal(3,0.0);
456  for(ModelPart::NodesContainerType::iterator it = rModelPart.NodesBegin(); it !=rModelPart.NodesEnd(); it++) {
457  noalias(it->GetValue(rNormalVariable)) = ZeroNormal;
458  it->GetValue(NODAL_PAUX) = 0.0;
459  }
460 
461  // Calculate new condition normals, using only conditions with rVariable == rValue
462  array_1d<double,3> An(3,0.0);
463 
464  if ( Dimension == 2 ) {
465  for ( ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); ++itCond ) {
466  if ( itCond->GetValue(rVariable) != Zero )
467  CalculateNormal2D(*itCond,An,rNormalVariable);
468  }
469  } else if ( Dimension == 3 ) {
470  array_1d<double,3> v1(3,0.0);
471  array_1d<double,3> v2(3,0.0);
472 
473  for ( ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); ++itCond ) {
474  if ( itCond->GetValue(rVariable) != Zero )
475  CalculateNormal3D(*itCond,An,v1,v2,rNormalVariable);
476  }
477  }
478 
479  // Loop over nodes to set normals
480  for(ModelPart::NodesContainerType::iterator it = rModelPart.NodesBegin(); it !=rModelPart.NodesEnd(); it++) {
481  std::vector< array_1d<double,3> > N_Mat;
482  N_Mat.reserve(10);
483  double nodal_area = 0.0;
484 
485  GlobalPointersVector<Condition >& ng_cond = it->GetValue(NEIGHBOUR_CONDITIONS);
486 
487  if(ng_cond.size() != 0){
488  for(GlobalPointersVector<Condition >::iterator ic = ng_cond.begin(); ic!=ng_cond.end(); ic++) {
489  Condition::GeometryType& pGeom = ic->GetGeometry();
490  const auto& rNormal = ic->GetValue(rNormalVariable);
491  const double Coef = 1.0 / pGeom.PointsNumber();
492  double norm_normal = norm_2( rNormal );
493 
494  if(norm_normal != 0.0) {
495  nodal_area += Coef * norm_normal;
496 
497  if(N_Mat.size() == 0.0) {
498  N_Mat.push_back( rNormal * Coef );
499  } else{
500  int added = 0;
501  for(unsigned int ii=0; ii<N_Mat.size();++ii) {
502  const array_1d<double,3>& temp_normal = N_Mat[ii];
503  double norm_temp = norm_2( temp_normal );
504 
505  double cos_alpha=temp_normal[0]*rNormal[0] + temp_normal[1]*rNormal[1] +temp_normal[2]*rNormal[2];
506  cos_alpha /= (norm_temp*norm_normal);
507 
508  if( cos_alpha > cos(0.017453293*rAlpha) ){
509  N_Mat[ii] += rNormal * Coef;
510  added = 1;}
511  }
512  if(!added)
513  N_Mat.push_back( rNormal*Coef );
514 
515  }
516  }
517  }
518  }
519 
520  // Compute NORMAL and mark
521  array_1d<double,3> sum_Normal(3,0.0);
522 
523  for(unsigned int ii=0; ii<N_Mat.size(); ++ii){
524  sum_Normal += N_Mat[ii];
525  }
526 
527  noalias( it->FastGetSolutionStepValue(rNormalVariable) ) = sum_Normal;
528  it->FastGetSolutionStepValue(NODAL_PAUX) = nodal_area;
529  //assign IS_SLIP = 0 for vertices
530  if(N_Mat.size() == 2){
531 // it->SetValue(IS_SLIP,0);
532  it->FastGetSolutionStepValue(IS_SLIP)=20.0;
533  } else if(N_Mat.size() == 3) {
534  it->FastGetSolutionStepValue(IS_SLIP)=30.0;
535  } else if(N_Mat.size() == 1) {
536  it->FastGetSolutionStepValue(IS_SLIP)=10.0;
537 
538  }
539  }
540 
541  // For MPI: correct values on partition boundaries
542  rModelPart.GetCommunicator().AssembleCurrentData(rNormalVariable);
543  rModelPart.GetCommunicator().AssembleCurrentData(NODAL_PAUX);
544 
545  KRATOS_CATCH("");
546  }
547 
548 private:
551 
555 
559 
563 
571  template<class TContainerType, bool TIsHistorical>
572  void InitializeNormals(
573  ModelPart& rModelPart,
574  const NormalVariableType& rNormalVariable
575  );
576 
584  template<class TContainerType, bool TIsHistorical>
585  void ComputeUnitNormalsFromAreaNormals(
586  ModelPart& rModelPart,
587  const NormalVariableType& rNormalVariable
588  );
589 
596  static void CalculateNormal2D(
597  Condition& rCondition,
598  array_1d<double,3>& rAn,
599  const NormalVariableType& rNormalVariable
600  );
601 
606  static void CalculateNormalShapeDerivative2D(
607  ConditionType& rCondition
608  );
609 
617  static void CalculateNormal3D(
618  Condition& rCondition,
619  array_1d<double,3>& rAn,
620  array_1d<double,3>& rv1,
621  array_1d<double,3>& rv2,
622  const NormalVariableType& rNormalVariable
623  );
624 
629  static void CalculateNormalShapeDerivative3D(
630  ConditionType& rCondition
631  );
632 
639  template<class TContainerType>
640  TContainerType& GetContainer(ModelPart& rModelPart);
641 
650  template<class TContainerType, bool TIsHistorical>
651  void CalculateNormalsUsingGenericAlgorithm(
652  ModelPart& rModelPart,
653  const bool ConsiderUnitNormal,
654  const NormalVariableType& rNormalVariable
655  );
656 
665  template<bool TIsHistorical>
666  array_1d<double,3>& GetNormalValue(
667  NodeType& rNode,
668  const NormalVariableType& rNormalVariable
669  );
670 
679  template<bool TIsHistorical>
680  void SetNormalValue(
681  NodeType& rNode,
682  const NormalVariableType& rNormalVariable,
683  const array_1d<double,3>& rNormalValue
684  );
685 
694  bool CheckUseSimplex(
695  const ModelPart& rModelPart,
696  const bool EnforceGenericGeometryAlgorithm
697  );
698 
707  template<bool TIsHistorical>
708  void AuxiliaryCalculateOnSimplex(
709  ConditionsArrayType& rConditions,
710  const std::size_t Dimension,
711  const NormalVariableType& rNormalVariable
712  );
713 
718 
722 
726 
730 
731 }; // Class NormalCalculationUtils
732 
733 } // namespace Kratos
734 
735 #endif /* KRATOS_NORMAL_CALCULATION_UTILS defined */
virtual bool AssembleCurrentData(Variable< int > const &ThisVariable)
Definition: communicator.cpp:502
Base class for all Conditions.
Definition: condition.h:59
Geometry base class.
Definition: geometry.h:71
SizeType PointsNumber() const
Definition: geometry.h:528
PointsArrayType::iterator iterator
PointsArrayType typedefs.
Definition: geometry.h:213
iterator begin()
Definition: geometry.h:465
iterator end()
Definition: geometry.h:473
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometry.h:627
This class is a vector which stores global pointers.
Definition: global_pointers_vector.h:61
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: global_pointers_vector.h:79
iterator begin()
Definition: global_pointers_vector.h:221
size_type size() const
Definition: global_pointers_vector.h:307
iterator end()
Definition: global_pointers_vector.h:229
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
Communicator & GetCommunicator()
Definition: model_part.h:1821
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
MeshType::ConditionIterator ConditionIterator
Definition: model_part.h:189
ConditionIterator ConditionsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1371
This class defines the node.
Definition: node.h:65
void CalculateNormals(ModelPart &rModelPart, const bool EnforceGenericGeometryAlgorithm=false, const bool ConsiderUnitNormal=false, const NormalVariableType &rNormalVariable=NORMAL)
It computes the mean of the normal in the entities and in all the nodes.
Geometry< NodeType > GeometryType
Definition of geometries.
Definition: normal_calculation_utils.h:75
ModelPart::ConditionType ConditionType
Condition type definition.
Definition: normal_calculation_utils.h:78
void CalculateOnSimplex(ModelPart &rModelPart, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the area normal (vector oriented as the normal with a dimension proportional to the area).
void CalculateOnSimplexLowMemory(ModelPart &rModelPart, int Dimension, const Variable< TValueType > &rVariable, const TValueType Zero, const double rAlpha, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the area normal (vector oriented as the normal with a dimension proportional to the area) ...
Definition: normal_calculation_utils.h:443
std::size_t SizeType
The size type definition.
Definition: normal_calculation_utils.h:69
void CalculateUnitNormals(ModelPart &rModelPart, const bool EnforceGenericGeometryAlgorithm=false, const NormalVariableType &rNormalVariable=NORMAL)
It computes the mean of the normal in the entities and in all the nodes (unit normal version)
void CalculateOnSimplexNonHistorical(ModelPart &rModelPart, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the area normal in the non-historical database (vector oriented as the normal with a dimen...
Node NodeType
Definition: normal_calculation_utils.h:72
std::size_t IndexType
The index type definition.
Definition: normal_calculation_utils.h:66
void CalculateOnSimplex(ModelPart &rModelPart, const std::size_t Dimension, const Variable< TValueType > &rVariable, const TValueType Zero, const double rAlpha, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the area normal (vector oriented as the normal with a dimension proportional to the area) ...
Definition: normal_calculation_utils.h:327
void CalculateNormalsInContainer(ModelPart &rModelPart, const NormalVariableType &rNormalVariable=NORMAL)
It computes the normal in the conditions.
void CalculateOnSimplexNonHistorical(ModelPart &rModelPart, const std::size_t Dimension, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the area normal in the non-historical database (vector oriented as the normal with a dimen...
void CalculateOnSimplex(ConditionsArrayType &rConditions, const std::size_t Dimension, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the "area normal" (vector oriented as the normal with a dimension proportional to the area...
void CalculateOnSimplex(ModelPart &rModelPart, const std::size_t Dimension, const Variable< TValueType > &rVariable, const TValueType Zero, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the area normal (vector oriented as the normal with a dimension proportional to the area) ...
Definition: normal_calculation_utils.h:249
ModelPart::ConditionsContainerType ConditionsArrayType
Conditions array definition.
Definition: normal_calculation_utils.h:81
void CalculateOnSimplex(ModelPart &rModelPart, const std::size_t Dimension, const Variable< TValueType > &rVariable)
Calculates the area normal (vector oriented as the normal with a dimension proportional to the area) ...
Definition: normal_calculation_utils.h:308
void CalculateOnSimplex(ModelPart &rModelPart, const std::size_t Dimension, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the area normal (vector oriented as the normal with a dimension proportional to the area).
void CalculateOnSimplexNonHistorical(ConditionsArrayType &rConditions, const std::size_t Dimension, const NormalVariableType &rNormalVariable=NORMAL)
Calculates the "area normal" in the non-historical database (vector oriented as the normal with a dim...
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
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector_set.h:95
Variable class contains all information needed to store and retrive data from a data container.
Definition: variable.h:63
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
TContainerType & GetContainer(ModelPart::MeshType &rMesh)
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
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
Tool to evaluate the normals on nodes based on the normals of a set of surface conditions.