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.
distance_calculation_element_simplex.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: Riccardo Rossi
11 //
12 //
13 
14 #if !defined(KRATOS_DISTANCE_CALCULATION_ELEMENT_H_INCLUDED )
15 #define KRATOS_DISTANCE_CALCULATION_ELEMENT_H_INCLUDED
16 
17 // System includes
18 #include <string>
19 #include <iostream>
20 
21 
22 // External includes
23 
24 
25 // Project includes
26 #include "containers/array_1d.h"
27 #include "includes/define.h"
28 #include "includes/element.h"
29 #include "includes/serializer.h"
30 #include "geometries/geometry.h"
31 #include "utilities/math_utils.h"
32 #include "utilities/geometry_utilities.h"
33 
34 // Application includes
35 #include "includes/variables.h"
36 #include "includes/kratos_flags.h"
37 
38 namespace Kratos
39 {
40 
43 
46 
50 
54 
58 
62 
64 
66 template< unsigned int TDim >
68 {
69 public:
72 
75 
77  typedef Node NodeType;
78 
81 
84 
86  typedef Vector VectorType;
87 
89  typedef Matrix MatrixType;
90 
91  typedef std::size_t IndexType;
92 
93  typedef std::size_t SizeType;
94 
96 
97  typedef std::vector<std::size_t> EquationIdVectorType;
98 
99  typedef std::vector<DofType::Pointer> DofsVectorType;
100 
102 
105 
108 
111 
115 
116  //Constructors.
117 
119 
123  Element(NewId)
124  {}
125 
127 
132  Element(NewId, ThisNodes)
133  {}
134 
136 
140  DistanceCalculationElementSimplex(IndexType NewId, GeometryType::Pointer pGeometry) :
141  Element(NewId, pGeometry)
142  {}
143 
145 
150  DistanceCalculationElementSimplex(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties) :
151  Element(NewId, pGeometry, pProperties)
152  {}
153 
156  {}
157 
158 
162 
163 
167 
169 
176  Element::Pointer Create(IndexType NewId, NodesArrayType const& ThisNodes,
177  PropertiesType::Pointer pProperties) const override
178  {
179  return Element::Pointer(new DistanceCalculationElementSimplex(NewId, GetGeometry().Create(ThisNodes), pProperties));
180  }
181 
183 
190  Element::Pointer Create(IndexType NewId,
191  GeometryType::Pointer pGeom,
192  PropertiesType::Pointer pProperties) const override
193  {
194  return Element::Pointer(new DistanceCalculationElementSimplex(NewId, pGeom, pProperties));
195  }
196 
198  void CalculateLocalSystem(MatrixType& rLeftHandSideMatrix,
199  VectorType& rRightHandSideVector,
200  const ProcessInfo& rCurrentProcessInfo) override
201  {
202  const unsigned int number_of_points = TDim+1;
203 
206 
207  if (rLeftHandSideMatrix.size1() != number_of_points)
208  rLeftHandSideMatrix.resize(number_of_points, number_of_points, false);
209 
210  if (rRightHandSideVector.size() != number_of_points)
211  rRightHandSideVector.resize(number_of_points, false);
212 
213  //getting data for the given geometry
214  double Area;
216 
217  //get distances at the nodes
218  array_1d<double, TDim+1 > distances;
219  for(unsigned int i=0; i<number_of_points; i++)
220  {
221  distances[i] = GetGeometry()[i].FastGetSolutionStepValue(DISTANCE);
222 // if (distances[i] >= 0.0 && distances[i] < 1e-30) distances[i] = 1e-30;
223  }
224 
225  const double dgauss = inner_prod(N,distances);
226 
227  const double coeff1 = rCurrentProcessInfo.Has(VARIATIONAL_REDISTANCE_COEFFICIENT_FIRST) ? rCurrentProcessInfo[VARIATIONAL_REDISTANCE_COEFFICIENT_FIRST] : 0.01;
228  const double coeff2 = rCurrentProcessInfo.Has(VARIATIONAL_REDISTANCE_COEFFICIENT_SECOND) ? rCurrentProcessInfo[VARIATIONAL_REDISTANCE_COEFFICIENT_SECOND] : 0.1;
229  const unsigned int step = rCurrentProcessInfo[FRACTIONAL_STEP];
230 
231  if(step == 1) //solve a poisson problem with a positive/negative heat source depending on the sign of the existing distance function
232  {
233  //compute distance on gauss point
234 
235  this->SetValue(DISTANCE,dgauss); //saving the distance, to see if it changed sign between iterations
236  //compute LHS
237  noalias(rLeftHandSideMatrix) = Area*prod(DN_DX,trans(DN_DX));
238 
239  //compute RHS
240  double source = 1.0;
241  if(dgauss < 0.0) source=-1.0;
242  noalias(rRightHandSideVector) = source*Area*N;
243 
244  noalias(rRightHandSideVector) -= prod(rLeftHandSideMatrix,distances);
245 
246 
247  //impose that the normal gradient is 1 on outer faces
248  unsigned int nboundary = 0;
249  for(unsigned int i=0; i<TDim+1; i++)
250  if(GetGeometry()[i].Is(BOUNDARY)) nboundary +=1;
251 
252  if(nboundary == TDim)
253  {
254  array_1d<double,TDim> DN_out(TDim, 0.0);
255  for(unsigned int i=0; i<TDim+1; i++)
256  if(GetGeometry()[i].IsNot(BOUNDARY))
257  {
258  noalias(DN_out) = row(DN_DX,i);
259  break;
260  }
261 
262  double normDn = norm_2(DN_out);
263  for(unsigned int i=0; i<TDim+1; i++)
264  if(GetGeometry()[i].Is(BOUNDARY))
265  {
266  rRightHandSideVector[i] += coeff1*source*normDn*Area*(TDim-1); //TODO: check this! it should be TDim*(TDim-1)*N[i] with N[i] on the face and then equal to 1/TDim
267  // using the area as weighting factor is excessive. Reduced it to get a closer to constant gradient between the regions close and far away from the interface
268  }
269 
270  }
271 
272 
273  }
274  else //solve an optimization problem with the goal of achievieng a gradient of one for the distance function
275  {
276  //for debuggin purposes:
277  if( dgauss * (this->GetValue(DISTANCE)) < 0.0 )
278  std::cout << "Element " << this->Id() << " changed sign while redistancing!!" << std::endl;
279 
280  //compute the gradient of the distance
281  const array_1d<double,TDim> grad = prod(trans(DN_DX),distances);
282  double grad_norm = norm_2(grad);
283 
284  //compute RHS ad grad N_i \cdot ( 1/norm_grad * grad - grad)
285  //and multiply everything by grad_norm
286  noalias(rRightHandSideVector) = Area*(1.0 - grad_norm)* prod(DN_DX,grad);
287 
288 
289  //compute the LHS as an approximation of the tangent.
290  //such approximation is taken as a laplacian, which comes from the assumption that the
291  //direction of n does not change when d changes
292  //
293  //
294  //note that the exact tangent could be computed as "P1+P2" with
295  //n = grad/grad_norm
296  //P1 = (1.0 - 1.0 / (grad_norm + eps) ) * DN_DX * DN_DX.transpose()
297  //P2 = 1.0/(grad_norm + eps) * dot(DN_DX * outer(n,n) * DN_DX.transpose() )
298  //unfortunately the numerical experiments tell that this in too unstable to be used unless a very
299  //good initial approximation is used
300 // noalias(rLeftHandSideMatrix) = (Area*(grad_norm - 1.0))*rod(DN_DX,trans(DN_DX) ); //RISKY!!
301  noalias(rLeftHandSideMatrix) = Area*std::max(grad_norm,coeff2)*prod( DN_DX,trans(DN_DX) );
302  }
303  }
304 
305 
307 
314  const ProcessInfo& rCurrentProcessInfo) const override
315  {
316 
317  unsigned int number_of_nodes = TDim+1;
318  if (rResult.size() != number_of_nodes)
319  rResult.resize(number_of_nodes, false);
320 
321  for (unsigned int i = 0; i < number_of_nodes; i++)
322  rResult[i] = GetGeometry()[i].GetDof(DISTANCE).EquationId();
323  }
324 
326 
330  void GetDofList(DofsVectorType& rElementalDofList,
331  const ProcessInfo& rCurrentProcessInfo) const override
332  {
333  unsigned int number_of_nodes = TDim+1;
334 
335  if (rElementalDofList.size() != number_of_nodes)
336  rElementalDofList.resize(number_of_nodes);
337 
338  for (unsigned int i = 0; i < number_of_nodes; i++)
339  rElementalDofList[i] = GetGeometry()[i].pGetDof(DISTANCE);
340 
341  }
342 
343 
347 
351 
353 
361  int Check(const ProcessInfo& rCurrentProcessInfo) const override
362 {
363  KRATOS_TRY
364 
365  // Perform basic element checks
366  int ErrorCode = Kratos::Element::Check(rCurrentProcessInfo);
367  if(ErrorCode != 0) return ErrorCode;
368 
369  if(this->GetGeometry().size() != TDim+1)
370  KRATOS_THROW_ERROR(std::invalid_argument,"wrong number of nodes for element",this->Id());
371 
372  // Checks on nodes
373 
374  // Check that the element's nodes contain all required SolutionStepData and Degrees of freedom
375  for(unsigned int i=0; i<this->GetGeometry().size(); ++i)
376  {
377  if(this->GetGeometry()[i].SolutionStepsDataHas(DISTANCE) == false)
378  KRATOS_THROW_ERROR(std::invalid_argument,"missing DISTANCE variable on solution step data for node ",this->GetGeometry()[i].Id());
379  }
380 
381 
382 
383  return 0;
384 
385  KRATOS_CATCH("");
386  }
387 
388  void CalculateRightHandSide(VectorType& rRightHandSideVector,
389  const ProcessInfo& rCurrentProcessInfo) override
390  {
391  KRATOS_ERROR << "should not enter here" << std::endl;
392  if (rRightHandSideVector.size() != 0)
393  rRightHandSideVector.resize(0, false);
394  }
398 
399 
403 
404  const Parameters GetSpecifications() const override
405  {
406  const Parameters specifications = Parameters(R"({
407  "time_integration" : ["static"],
408  "framework" : "eulerian",
409  "symmetric_lhs" : true,
410  "positive_definite_lhs" : true,
411  "output" : {
412  "gauss_point" : [],
413  "nodal_historical" : ["DISTANCE"],
414  "nodal_non_historical" : [],
415  "entity" : []
416  },
417  "required_variables" : ["DISTANCE"],
418  "required_dofs" : ["DISTANCE"],
419  "flags_used" : ["BOUNDARY"],
420  "compatible_geometries" : ["Triangle2D3","Tetrahedra3D4"],
421  "element_integrates_in_time" : false,
422  "compatible_constitutive_laws": {
423  "type" : [],
424  "dimension" : [],
425  "strain_size" : []
426  },
427  "required_polynomial_degree_of_geometry" : 1,
428  "documentation" :
429  "This element is intended to be used in combination with the VariationalDistanceCalculationProcess. It implements a two-step resolution of an Eikonal equation in order to obtain a distance field with unit gradient norm."
430  })");
431  return specifications;
432  }
433 
435  std::string Info() const override
436  {
437  std::stringstream buffer;
438  buffer << "DistanceCalculationElementSimplex #" << Id();
439  return buffer.str();
440  }
441 
443  void PrintInfo(std::ostream& rOStream) const override
444  {
445  rOStream << "DistanceCalculationElementSimplex" << TDim << "D";
446  }
447 
448 // /// Print object's data.
449 // virtual void PrintData(std::ostream& rOStream) const;
450 
454 
455 
457 
458 protected:
461 
462 
466 
467 
471 
475 
476 
480 
481 
485 
486 
490 
491 
493 
494 private:
497 
501 
505 
506  friend class Serializer;
507 
508  void save(Serializer& rSerializer) const override
509  {
511  }
512 
513  void load(Serializer& rSerializer) override
514  {
516  }
517 
521 
522 
526 
527 
531 
532 
536 
537 
541 
544 
547 
549 
550 }; // Class DistanceCalculationElementSimplex
551 
553 
556 
557 
561 
562 
564 template< unsigned int TDim >
565 inline std::istream& operator >>(std::istream& rIStream,
567 {
568  return rIStream;
569 }
570 
572 template< unsigned int TDim >
573 inline std::ostream& operator <<(std::ostream& rOStream,
575 {
576  rThis.PrintInfo(rOStream);
577  rOStream << std::endl;
578  rThis.PrintData(rOStream);
579 
580  return rOStream;
581 }
583 
585 
586 } // namespace Kratos.
587 
588 #endif // KRATOS_DISTANCE_CALCULATION_ELEMENT_H_INCLUDED defined
PeriodicInterfaceProcess & operator=(const PeriodicInterfaceProcess &)=delete
bool Has(const Variable< TDataType > &rThisVariable) const
Checks if the data container has a value associated with a given variable.
Definition: data_value_container.h:382
A stabilized element for the incompressible Navier-Stokes equations.
Definition: distance_calculation_element_simplex.h:68
Geometry< NodeType > GeometryType
Geometry type (using with given NodeType)
Definition: distance_calculation_element_simplex.h:80
Matrix MatrixType
Matrix type for local contributions to the linear system.
Definition: distance_calculation_element_simplex.h:89
const Parameters GetSpecifications() const override
This method provides the specifications/requirements of the element.
Definition: distance_calculation_element_simplex.h:404
~DistanceCalculationElementSimplex() override
Destructor.
Definition: distance_calculation_element_simplex.h:155
DistanceCalculationElementSimplex(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
Constuctor using geometry and properties.
Definition: distance_calculation_element_simplex.h:150
Element::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override
Create a new element of this type.
Definition: distance_calculation_element_simplex.h:190
Element::Pointer Create(IndexType NewId, NodesArrayType const &ThisNodes, PropertiesType::Pointer pProperties) const override
Create a new element of this type.
Definition: distance_calculation_element_simplex.h:176
void GetDofList(DofsVectorType &rElementalDofList, const ProcessInfo &rCurrentProcessInfo) const override
Returns a list of the element's Dofs.
Definition: distance_calculation_element_simplex.h:330
DistanceCalculationElementSimplex(IndexType NewId=0)
Default constuctor.
Definition: distance_calculation_element_simplex.h:122
Kratos::Matrix ShapeFunctionDerivativesType
Type for a matrix containing the shape function gradients.
Definition: distance_calculation_element_simplex.h:107
PointerVectorSet< DofType > DofsArrayType
Definition: distance_calculation_element_simplex.h:101
DistanceCalculationElementSimplex(IndexType NewId, const NodesArrayType &ThisNodes)
Constructor using an array of nodes.
Definition: distance_calculation_element_simplex.h:131
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: distance_calculation_element_simplex.h:443
Kratos::Vector ShapeFunctionsType
Type for shape function values container.
Definition: distance_calculation_element_simplex.h:104
GeometryType::ShapeFunctionsGradientsType ShapeFunctionDerivativesArrayType
Type for an array of shape function gradient matrices.
Definition: distance_calculation_element_simplex.h:110
void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Calculate the element's local contribution to the system for the current step.
Definition: distance_calculation_element_simplex.h:198
std::size_t SizeType
Definition: distance_calculation_element_simplex.h:93
DistanceCalculationElementSimplex(IndexType NewId, GeometryType::Pointer pGeometry)
Constructor using a geometry object.
Definition: distance_calculation_element_simplex.h:140
Node NodeType
Node type (default is: Node)
Definition: distance_calculation_element_simplex.h:77
std::vector< std::size_t > EquationIdVectorType
Definition: distance_calculation_element_simplex.h:97
int Check(const ProcessInfo &rCurrentProcessInfo) const override
Checks the input and that all required Kratos variables have been registered.
Definition: distance_calculation_element_simplex.h:361
void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const override
Provides the global indices for each one of this element's local rows.
Definition: distance_calculation_element_simplex.h:313
Dof< double > DofType
Definition: distance_calculation_element_simplex.h:95
void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: distance_calculation_element_simplex.h:388
std::string Info() const override
Turn back information as a string.
Definition: distance_calculation_element_simplex.h:435
Vector VectorType
Vector type for local contributions to the linear system.
Definition: distance_calculation_element_simplex.h:86
std::vector< DofType::Pointer > DofsVectorType
Definition: distance_calculation_element_simplex.h:99
std::size_t IndexType
Definition: distance_calculation_element_simplex.h:91
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(DistanceCalculationElementSimplex)
Pointer definition of DistanceCalculationElementSimplex.
Geometry< NodeType >::PointsArrayType NodesArrayType
Definition of nodes container type, redefined from GeometryType.
Definition: distance_calculation_element_simplex.h:83
Dof represents a degree of freedom (DoF).
Definition: dof.h:86
Base class for all Elements.
Definition: element.h:60
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: element.h:1135
virtual int Check(const ProcessInfo &rCurrentProcessInfo) const
Definition: element.h:904
std::size_t IndexType
Definition: flags.h:74
bool Is(Flags const &rOther) const
Definition: flags.h:274
bool IsNot(Flags const &rOther) const
Definition: flags.h:291
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometrical_object.h:248
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
void SetValue(const TVariableType &rThisVariable, typename TVariableType::Type const &rValue)
Definition: geometrical_object.h:238
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
IndexType const & Id() const
Id of this Geometry.
Definition: geometry.h:964
static void CalculateGeometryData(const GeometryType &rGeometry, BoundedMatrix< double, 4, 3 > &rDN_DX, array_1d< double, 4 > &rN, double &rVolume)
This function is designed to compute the shape function derivatives, shape functions and volume in 3D...
Definition: geometry_utilities.h:176
IndexType Id() const
Definition: indexed_object.h:107
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
This class defines the node.
Definition: node.h:65
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
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
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_SERIALIZE_SAVE_BASE_CLASS(Serializer, BaseType)
Definition: define.h:812
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_SERIALIZE_LOAD_BASE_CLASS(Serializer, BaseType)
Definition: define.h:815
#define KRATOS_ERROR
Definition: exception.h:161
static double max(double a, double b)
Definition: GeometryFunctions.h:79
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
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
int step
Definition: face_heat.py:88
grad
Definition: hinsberg_optimization.py:148
def load(f)
Definition: ode_solve.py:307
N
Definition: sensitivityMatrix.py:29
integer i
Definition: TensorModule.f:17