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.
edge_based_data_structure.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: Ruben Zorrilla
11 //
12 
13 #pragma once
14 
15 
16 // System includes
17 
18 
19 // Project includes
21 #include "includes/define.h"
23 #include "includes/model_part.h"
24 #include "utilities/geometry_utilities.h"
25 
26 namespace Kratos
27 {
30 
33 
37 
41 
45 
49 
50 template<unsigned int TDim>
52 {
53 public:
56 
57  // Number of element nodes (note that simplicial elements are assumed)
58  static constexpr std::size_t NumNodes = TDim + 1;
59 
60  // Number of edges per element (note that simplicial elements are assumed)
61  static constexpr std::size_t NumEdges = TDim == 2 ? 3 : 6;
62 
63  // Number of edges per face (note that simplicial elements are assumed)
64  static constexpr std::size_t NumEdgesFace = TDim == 2 ? 1 : 3;
65 
66  // Number of edges per face (note that simplicial elements are assumed)
67  static constexpr std::size_t NumNodesFace = TDim == 2 ? 2 : 3;
68 
69  //TODO: Fake edge data structure to be defined later on
70  class EdgeData final
71  {
72  public:
73 
74  EdgeData() = default;
75 
76  EdgeData(const EdgeData& rOther) = delete;
77 
78  bool IsBoundary() const
79  {
80  return mIsBoundary;
81  }
82 
83  double GetLength() const
84  {
85  return mLength;
86  }
87 
89  {
90  return mMij;
91  }
92 
93  double GetOffDiagonalLaplacian() const
94  {
95  return mLij;
96  }
97 
99  {
100  return mAEC;
101  }
102 
104  {
105  return mNiDNj;
106  }
107 
109  {
110  return mDNiNj;
111  }
112 
114  {
115  return mNiNjNormal;
116  }
117 
118  void SetLength(const double Length)
119  {
120  mLength = Length;
121  }
122 
123  void SetAntidiffusiveEdgeContribution(const double AntidiffusiveEedgeContribution)
124  {
125  mAEC = AntidiffusiveEedgeContribution;
126  }
127 
129  const double Weight,
130  const double Ni,
131  const double Nj,
132  const array_1d<double, TDim> &rDNiDX,
133  const array_1d<double, TDim> &rDNjDX)
134  {
135  mMij += Weight * Ni * Nj;
136  for (std::size_t d = 0; d < TDim; ++d) {
137  mLij += Weight * rDNiDX[d] * rDNjDX[d];
138  mNiDNj[d] += Weight * Ni * rDNjDX[d];
139  mDNiNj[d] += Weight * rDNiDX[d] * Nj;
140  }
141  }
142 
144  const double Weight,
145  const double Ni,
146  const double Nj,
147  const array_1d<double,TDim>& rUnitNormal)
148  {
149  // Convective boundary term
150  for (std::size_t d = 0; d < TDim; ++d) {
151  mNiNjNormal[d] += Weight * Ni * Nj * rUnitNormal[d];
152  }
153 
154  // Set the boundary flag to true
155  mIsBoundary = true;
156  }
157 
158  private:
159 
160  bool mIsBoundary = false; // flag to indicate if current flag belongs to a boundary
161  double mLength = 0.0; // l_{ij}
162  double mMij = 0.0; // N_{i}*N_{j}
163  double mLij = 0.0; // grad(N_{i})^{T}*grad(N_{j})
164  double mAEC = 0.0; // f_{ij} (raw Antidiffusive Edge Contribution, AEC)
165  array_1d<double, TDim> mNiDNj = ZeroVector(TDim); // N_{i}*grad(N_{j})
166  array_1d<double, TDim> mDNiNj = ZeroVector(TDim); // grad(N_{i})*N_{j}
167  array_1d<double, TDim> mNiNjNormal = ZeroVector(TDim); // NiNjn
168  };
169 
171  using IndexType = std::size_t;
172 
174  using SizeType = std::size_t;
175 
177  using EdgeDataPointerType = std::unique_ptr<EdgeData>;
178 
181 
183  using IndicesVectorType = std::vector<IndexType>;
184 
186  using EdgeDataVectorType = std::vector<EdgeDataPointerType>;
187 
189  using MassMatrixVectorType = std::vector<double>;
190 
192  using BoundaryMassMatrixVectorType = std::vector<array_1d<double,TDim>>;
193 
196 
200 
203 
206 
209 
213 
214 
218 
219  void CalculateEdgeDataStructure(const ModelPart& rModelPart)
220  {
221  // Check that the mesh is of simplicial elements
222  CheckGeometryTypes(rModelPart);
223 
224  // Create the edges container sparse graph
225  // Note that this is used to create the CSR storage indices arrays
226  SparseGraphType edges_graph;
227  FillEdgesSparseGraph(rModelPart, edges_graph);
228  edges_graph.ExportCSRArrays(mRowIndices, mColIndices);
229 
230  // Create the edge data sparse container
231  CalculateEdgeDataValues(rModelPart, edges_graph);
232  }
233 
234  void Clear()
235  {
236  mNumEdges = 0;
237  mRowIndices.clear();
238  mColIndices.clear();
239  mEdgeData.clear();
240  mMassMatrixDiagonal.clear();
241  mLumpedMassMatrixDiagonal.clear();
242  }
243 
247 
249  {
250  return mNumEdges;
251  }
252 
254  {
255  return mRowIndices;
256  }
257 
259  {
260  return mColIndices;
261  }
262 
264  {
265  return mMassMatrixDiagonal;
266  }
267 
269  {
270  return mMassMatrixDiagonal[I-1];
271  }
272 
274  {
275  return mBoundaryMassMatrixDiagonal;
276  }
277 
279  {
280  return mBoundaryMassMatrixDiagonal[I-1];
281  }
282 
284  {
285  return mLumpedMassMatrixDiagonal;
286  }
287 
289  {
290  return mLumpedMassMatrixDiagonal[I-1];
291  }
292 
294  {
295  return mEdgeData;
296  }
297 
299  IndexType I,
300  IndexType J)
301  {
302  const IndexType ij_col_vect_index = GetColumVectorIndex(I,J);
303  return *(mEdgeData[ij_col_vect_index]);
304  }
305 
307  IndexType I,
308  IndexType J) const
309  {
310  const IndexType ij_col_vect_index = GetColumVectorIndex(I,J);
311  return *(mEdgeData[ij_col_vect_index]);
312  }
313 
317 
318 
322 
324  std::string Info() const
325  {
326  std::stringstream buffer;
327  buffer << "EdgeBasedDataStructure";
328  return buffer.str();
329  }
330 
332  void PrintInfo(std::ostream& rOStream) const
333  {
334  rOStream << "EdgeBasedDataStructure" << std::endl;
335  PrintData(rOStream);
336  }
337 
339  void PrintData(std::ostream& rOStream) const
340  {
341  }
342 
346 
347 
349 protected:
352 
353 
357 
358 
362 
363 
367 
368 
372 
373 
377 
378 
382 
383 
385 
386 private:
389 
390 
394 
395  SizeType mNumEdges;
396  IndicesVectorType mRowIndices;
397  IndicesVectorType mColIndices;
398  MassMatrixVectorType mMassMatrixDiagonal;
399  MassMatrixVectorType mLumpedMassMatrixDiagonal;
400  BoundaryMassMatrixVectorType mBoundaryMassMatrixDiagonal;
401  EdgeDataVectorType mEdgeData;
402 
406 
407 
411 
412  void CheckGeometryTypes(const ModelPart&)
413  {
414  //TODO: Implement this!
415  }
416 
417  void FillEdgesSparseGraph(
418  const ModelPart& rModelPart,
419  SparseGraphType& rEdgesSparseGraph)
420  {
421  // Get the edge connectivities from nodal neighbours and set the sparse graph with these
422  // Note that we define edge ij such as i is the lower id between i and j
423  mNumEdges = 0;
424  for (auto& r_node : rModelPart.Nodes()) {
425  // i-node values
426  const IndexType i_id = r_node.Id();
427  std::vector<IndexType> col_ids;
428 
429  // Loop nodal neighbours (j-node)
430  auto& r_node_neighs = r_node.GetValue(NEIGHBOUR_NODES);
431  for (auto& r_neigh : r_node_neighs) {
432  // Check ids for adding current edge
433  const IndexType j_id = r_neigh.Id();
434  if (i_id < j_id) {
435  col_ids.push_back(j_id);
436  mNumEdges++;
437  }
438  }
439  // Add edges from current node to graph
440  if (col_ids.size() != 0) {
441  rEdgesSparseGraph.AddEntries(i_id, col_ids);
442  }
443  }
444 
445  // Finalize edge graph
446  rEdgesSparseGraph.Finalize();
447  }
448 
449  void CalculateEdgeDataValues(
450  const ModelPart& rModelPart,
451  const SparseGraphType& rEdgesSparseGraph)
452  {
453  // Resize values vector to the number of edges
454  KRATOS_ERROR_IF(mNumEdges == 0) << "No edges in model part '" << rModelPart.FullName() << "'." << std::endl;
455  mEdgeData.resize(mNumEdges);
456  mMassMatrixDiagonal.resize(rModelPart.NumberOfNodes());
457  mLumpedMassMatrixDiagonal.resize(rModelPart.NumberOfNodes());
458  mBoundaryMassMatrixDiagonal.resize(rModelPart.NumberOfNodes());
459 
460  // Initialize mass matrices diagonal values
461  std::fill(mMassMatrixDiagonal.begin(), mMassMatrixDiagonal.end(), 0.0);
462  std::fill(mLumpedMassMatrixDiagonal.begin(), mLumpedMassMatrixDiagonal.end(), 0.0);
463  std::fill(mBoundaryMassMatrixDiagonal.begin(), mBoundaryMassMatrixDiagonal.end(), ZeroVector(TDim));
464 
465  // Allocate auxiliary arrays for the elementwise calculations
466  double domain_size;
467  array_1d<double, NumNodes> fake_N;
468  BoundedMatrix<double, NumNodes, TDim> DNDX;
469  BoundedMatrix<double, NumEdges, NumNodes> N;
470  BoundedMatrix<double, NumEdgesFace, NumNodesFace> N_face;
471 
472  // Loop elements to calculate their corresponding edge contributions
473  for (auto& r_element : rModelPart.Elements()) {
474  // Getting geometry data of the element
475  GetEdgeShapeFunctionsValues(N);
476  const auto& r_geom = r_element.GetGeometry();
477  GeometryUtils::CalculateGeometryData(r_geom, DNDX, fake_N, domain_size);
478 
479  // Loop integration points
480  // Note that these are placed at each edge midpoint
481  const double w_gauss = domain_size / NumEdges;
482  for (IndexType g = 0; g < NumEdges; ++g) {
483  // Get shape functions values at current Gauss pt
484  const auto& r_N = row(N, g);
485 
486  // Loop element edges to add the off-diagonal (IJ) contributions
487  for (IndexType i = 0; i < NumNodes-1; ++i) {
488  const IndexType i_id = r_geom[i].Id();
489  for (IndexType j = i+1; j < NumNodes; ++j) {
490  const IndexType j_id = r_geom[j].Id();
491 
492  // Get ij-edge auxiliary local ids
493  // Note that these are set according to the "i lowest id" storage criterion
494  IndexType aux_i;
495  IndexType aux_j;
496  if (i_id < j_id) {
497  aux_i = i;
498  aux_j = j;
499  } else {
500  aux_i = j;
501  aux_j = i;
502  }
503  const IndexType aux_i_id = r_geom[aux_i].Id();
504  const IndexType aux_j_id = r_geom[aux_j].Id();
505 
506  // If not created yet, create current edge data container
507  // Note that we also set the length which is the same for all neighbour elements
508  // auto& rp_edge_data = pGetEdgeData(i_id, j_id);
509  auto& rp_edge_data = pGetEdgeData(aux_i_id, aux_j_id);
510  if (rp_edge_data == nullptr) {
511  rp_edge_data = std::move(Kratos::make_unique<EdgeData>());
512  rp_edge_data->SetLength(norm_2(r_geom[aux_i].Coordinates()-r_geom[aux_j].Coordinates()));
513  }
514 
515  // Add current element off-diagonal (IJ) contributions
516  rp_edge_data->AddOffDiagonalValues(w_gauss, r_N[aux_i], r_N[aux_j], row(DNDX, aux_i), row(DNDX, aux_j));
517  }
518  }
519 
520  // Add the mass matrices diagonal (II) contributions
521  // Note that in here we take advantage of the fact that there is an integration point at the mid of each face
522  for (IndexType i = 0; i < NumNodes; ++i) {
523  const IndexType i_row = r_geom[i].Id() - 1;
524  const double aux_mass = w_gauss * r_N[i] * r_N[i];
525  mMassMatrixDiagonal[i_row] += aux_mass;
526  mLumpedMassMatrixDiagonal[i_row] += 2.0 * aux_mass;
527  }
528  }
529  }
530 
531  // Loop the conditions to calculate the normals in the boundary edges
532  // Note that in here we are assuming that current model part has conditions in the entire skin
533  KRATOS_ERROR_IF(rModelPart.GetCommunicator().GlobalNumberOfConditions() == 0) << "No conditions found in model part '" << rModelPart.FullName() << "'." << std::endl;
534  array_1d<double,TDim> unit_normal;
535  for (auto& r_condition : rModelPart.Conditions()) {
536  // Get condition data
537  const auto& r_geom = r_condition.GetGeometry();
538  GetEdgeFaceShapeFunctionsValues(N_face);
539  CalculateUnitNormal(r_geom, unit_normal);
540  const double domain_size = r_geom.DomainSize();
541 
542  // Loop integration points
543  // Note that these are placed at each edge midpoint
544  const double w_gauss = domain_size / NumEdgesFace;
545  for (IndexType g = 0; g < NumEdgesFace; ++g) {
546  // Get shape functions values at current Gauss pt
547  const auto& r_N_face = row(N_face, g);
548 
549  // Loop element edges to add the off-diagonal (IJ) contributions
550  for (IndexType i = 0; i < TDim - 1; ++i) {
551  const IndexType i_id = r_geom[i].Id();
552  for (IndexType j = i + 1; j < TDim; ++j) {
553  const IndexType j_id = r_geom[j].Id();
554 
555  // Get ij-edge auxiliary local ids
556  // Note that these are set according to the "i lowest id" storage criterion
557  IndexType aux_i;
558  IndexType aux_j;
559  if (i_id < j_id) {
560  aux_i = i;
561  aux_j = j;
562  } else {
563  aux_i = j;
564  aux_j = i;
565  }
566  const IndexType aux_i_id = r_geom[aux_i].Id();
567  const IndexType aux_j_id = r_geom[aux_j].Id();
568 
569  // Get current edge data container
570  auto& rp_edge_data = pGetEdgeData(aux_i_id, aux_j_id);
571  KRATOS_ERROR_IF(rp_edge_data == nullptr) << "Boundary edge " << aux_i_id << "-" << aux_j_id << " data structure is not present." << std::endl;
572  rp_edge_data->AddConvectiveBoundaryValue(w_gauss, r_N_face[aux_i], r_N_face[aux_j], unit_normal);
573  }
574  }
575 
576  // Add the boundary mass matrix diagonal (II) contribution
577  // Note that this already includes the unit normal contribution
578  // Note that in here we take advantage of the fact that there is an integration point at the mid of each face
579  for (IndexType i = 0; i < NumNodesFace; ++i) {
580  const IndexType i_row = r_geom[i].Id() - 1;
581  const double aux_mass = w_gauss * r_N_face[i] * r_N_face[i];
582  noalias(mBoundaryMassMatrixDiagonal[i_row]) += aux_mass * unit_normal;
583  }
584  }
585  }
586  }
587 
588  void CalculateUnitNormal(
589  const Geometry<Node>& rGeometry,
590  array_1d<double, TDim>& rUnitNormal) const
591  {
592  if constexpr (TDim == 2) {
593  rUnitNormal[0] = rGeometry[1].Y() - rGeometry[0].Y();
594  rUnitNormal[1] = -(rGeometry[1].X() - rGeometry[0].X());
595  } else {
596  array_1d<double, 3> v1, v2;
597  v1[0] = rGeometry[1].X() - rGeometry[0].X();
598  v1[1] = rGeometry[1].Y() - rGeometry[0].Y();
599  v1[2] = rGeometry[1].Z() - rGeometry[0].Z();
600 
601  v2[0] = rGeometry[2].X() - rGeometry[0].X();
602  v2[1] = rGeometry[2].Y() - rGeometry[0].Y();
603  v2[2] = rGeometry[2].Z() - rGeometry[0].Z();
604 
605  MathUtils<double>::CrossProduct(rUnitNormal, v1, v2);
606  rUnitNormal *= 0.5;
607  }
608 
609  const double n_norm = norm_2(rUnitNormal);
610  KRATOS_WARNING_IF("EdgeBasedDataStructure", n_norm < 1.0e-12) << "Normal is close to zero." << std::endl;
611  rUnitNormal /= n_norm;
612  }
613 
614  void GetEdgeShapeFunctionsValues(BoundedMatrix<double, NumEdges, NumNodes>& rN) const
615  {
616  if constexpr (TDim == 2) {
617  rN(0,0) = 0.5; rN(0,1) = 0.5; rN(0,2) = 0.0;
618  rN(1,0) = 0.0; rN(1,1) = 0.5; rN(1,2) = 0.5;
619  rN(2,0) = 0.5; rN(2,1) = 0.0; rN(2,2) = 0.5;
620  } else {
621  rN(0,0) = 0.5; rN(0,1) = 0.5; rN(0,2) = 0.0; rN(0,3) = 0.0;
622  rN(1,0) = 0.0; rN(1,1) = 0.5; rN(1,2) = 0.5; rN(1,3) = 0.0;
623  rN(2,0) = 0.0; rN(2,1) = 0.0; rN(2,2) = 0.5; rN(2,3) = 0.5;
624  rN(3,0) = 0.5; rN(3,1) = 0.0; rN(3,2) = 0.5; rN(3,3) = 0.0;
625  rN(4,0) = 0.5; rN(4,1) = 0.0; rN(4,2) = 0.0; rN(4,3) = 0.5;
626  rN(5,0) = 0.0; rN(5,1) = 0.5; rN(5,2) = 0.0; rN(5,3) = 0.5;
627  }
628  }
629 
630  void GetEdgeFaceShapeFunctionsValues(BoundedMatrix<double, NumEdgesFace, NumNodesFace>& rN) const
631  {
632  if constexpr (TDim == 2) {
633  rN(0,0) = 0.5; rN(0,1) = 0.5;
634  } else {
635  rN(0,0) = 0.5; rN(0,1) = 0.5; rN(0,2) = 0.0;
636  rN(1,0) = 0.0; rN(1,1) = 0.5; rN(1,2) = 0.5;
637  rN(2,0) = 0.5; rN(2,1) = 0.0; rN(2,2) = 0.5;
638  }
639  }
640 
641  friend class Serializer;
642 
643  void save(Serializer &rSerializer) const
644  {
645  }
646 
647  void load(Serializer &rSerializer)
648  {
649  }
650 
654 
655  IndexType GetColumVectorIndex(
656  const IndexType I,
657  const IndexType J) const
658  {
659  IndexType j_col_index = -1;
660  const IndexType i_row_index = mRowIndices[I];
661  for (auto it = mColIndices.begin() + i_row_index; it != mColIndices.end(); ++it) {
662  if (*it == J) {
663  j_col_index = std::distance(mColIndices.begin(), it);
664  break;
665  }
666  }
667  return j_col_index;
668  }
669 
670  EdgeDataPointerType& pGetEdgeData(
671  const IndexType GlobalIdI,
672  const IndexType GlobalIdJ)
673  {
674  // Get ij-edge auxiliary ids (edges are stored being i the lowest nodal i and j the largest)
675  const IndexType aux_i_id = std::min(GlobalIdI, GlobalIdJ);
676  const IndexType aux_j_id = std::max(GlobalIdI, GlobalIdJ);
677 
678  // Get position in the column indices vector as this is the same one to be used in the values vector
679  const IndexType ij_col_index = GetColumVectorIndex(aux_i_id, aux_j_id);
680  KRATOS_ERROR_IF(ij_col_index < 0) << "Column index cannot be found for ij-edge " << GlobalIdI << "-" << GlobalIdJ << "." << std::endl;
681 
682  return mEdgeData[ij_col_index];
683  }
684 
688 
689 
693 
694 
696 }; // Class CsrMatrix
697 
701 
702 
706 
708 template <unsigned int TDim>
709 inline std::istream &operator>>(
710  std::istream &rIStream,
712 {
713  return rIStream;
714 }
715 
717 template <unsigned int TDim>
718 inline std::ostream &operator<<(
719  std::ostream &rOStream,
720  const EdgeBasedDataStructure<TDim> &rThis)
721 {
722  rThis.PrintInfo(rOStream);
723  rOStream << std::endl;
724  rThis.PrintData(rOStream);
725 
726  return rOStream;
727 }
728 
731 
732 } // namespace Kratos.
733 
Definition: edge_based_data_structure.h:71
void AddOffDiagonalValues(const double Weight, const double Ni, const double Nj, const array_1d< double, TDim > &rDNiDX, const array_1d< double, TDim > &rDNjDX)
Definition: edge_based_data_structure.h:128
double GetLength() const
Definition: edge_based_data_structure.h:83
const array_1d< double, TDim > & GetOffDiagonalConvectiveBoundary() const
Definition: edge_based_data_structure.h:113
double GetOffDiagonalLaplacian() const
Definition: edge_based_data_structure.h:93
const array_1d< double, TDim > & GetOffDiagonalConvectiveTranspose() const
Definition: edge_based_data_structure.h:108
double GetOffDiagonalConsistentMass() const
Definition: edge_based_data_structure.h:88
void SetLength(const double Length)
Definition: edge_based_data_structure.h:118
const array_1d< double, TDim > & GetOffDiagonalConvective() const
Definition: edge_based_data_structure.h:103
bool IsBoundary() const
Definition: edge_based_data_structure.h:78
double GetAntidiffusiveEdgeContribution() const
Definition: edge_based_data_structure.h:98
EdgeData(const EdgeData &rOther)=delete
void AddConvectiveBoundaryValue(const double Weight, const double Ni, const double Nj, const array_1d< double, TDim > &rUnitNormal)
Definition: edge_based_data_structure.h:143
void SetAntidiffusiveEdgeContribution(const double AntidiffusiveEedgeContribution)
Definition: edge_based_data_structure.h:123
Definition: edge_based_data_structure.h:52
void CalculateEdgeDataStructure(const ModelPart &rModelPart)
Definition: edge_based_data_structure.h:219
static constexpr std::size_t NumEdges
Definition: edge_based_data_structure.h:61
std::string Info() const
Turn back information as a string.
Definition: edge_based_data_structure.h:324
std::size_t SizeType
Size type definition.
Definition: edge_based_data_structure.h:174
std::vector< double > MassMatrixVectorType
CSR storage mass matrices vector definition.
Definition: edge_based_data_structure.h:189
const IndicesVectorType & GetRowIndices() const
Definition: edge_based_data_structure.h:253
const MassMatrixVectorType & GetMassMatrixDiagonal() const
Definition: edge_based_data_structure.h:263
void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: edge_based_data_structure.h:339
void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: edge_based_data_structure.h:332
static constexpr std::size_t NumEdgesFace
Definition: edge_based_data_structure.h:64
std::size_t IndexType
Index type definition.
Definition: edge_based_data_structure.h:171
const IndicesVectorType & GetColIndices() const
Definition: edge_based_data_structure.h:258
static constexpr std::size_t NumNodesFace
Definition: edge_based_data_structure.h:67
std::vector< IndexType > IndicesVectorType
CSR storage indices vector definition.
Definition: edge_based_data_structure.h:183
std::vector< array_1d< double, TDim > > BoundaryMassMatrixVectorType
CSR storage boundary mass matrices vector definition.
Definition: edge_based_data_structure.h:192
SparseGraph< IndexType > SparseGraphType
Sparse graph definition.
Definition: edge_based_data_structure.h:180
const EdgeData & GetEdgeData(IndexType I, IndexType J) const
Definition: edge_based_data_structure.h:306
const BoundaryMassMatrixVectorType & GetBoundaryMassMatrixDiagonal() const
Definition: edge_based_data_structure.h:273
EdgeBasedDataStructure & operator=(const EdgeBasedDataStructure &rOther)=delete
Assignment operator.
SizeType NumberOfEdges() const
Definition: edge_based_data_structure.h:248
static constexpr std::size_t NumNodes
Definition: edge_based_data_structure.h:58
const MassMatrixVectorType & GetLumpedMassMatrixDiagonal() const
Definition: edge_based_data_structure.h:283
EdgeData & GetEdgeData(IndexType I, IndexType J)
Definition: edge_based_data_structure.h:298
~EdgeBasedDataStructure()=default
Destructor.
void Clear()
Definition: edge_based_data_structure.h:234
const EdgeDataVectorType & GetEdgeData() const
Definition: edge_based_data_structure.h:293
std::unique_ptr< EdgeData > EdgeDataPointerType
Edge data container pointer type.
Definition: edge_based_data_structure.h:177
std::vector< EdgeDataPointerType > EdgeDataVectorType
CSR storage off-diagonal values vector definition.
Definition: edge_based_data_structure.h:186
const array_1d< double, TDim > & GetBoundaryMassMatrixDiagonal(IndexType I) const
Definition: edge_based_data_structure.h:278
KRATOS_CLASS_POINTER_DEFINITION(EdgeBasedDataStructure)
Pointer definition of EdgeBasedDataStructure.
EdgeBasedDataStructure()=default
Constructor.
double GetMassMatrixDiagonal(IndexType I) const
Definition: edge_based_data_structure.h:268
double GetLumpedMassMatrixDiagonal(IndexType I) const
Definition: edge_based_data_structure.h:288
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
static T CrossProduct(const T &a, const T &b)
Performs the vector product of the two input vectors a,b.
Definition: math_utils.h:762
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
Short class definition.
Definition: sparse_graph.h:66
IndexType ExportCSRArrays(TVectorType &rRowIndices, TVectorType &rColIndices) const
Definition: sparse_graph.h:215
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_WARNING_IF(label, conditional)
Definition: logger.h:266
static double max(double a, double b)
Definition: GeometryFunctions.h:79
static double min(double a, double b)
Definition: GeometryFunctions.h:71
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
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
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
int domain_size
Definition: face_heat.py:4
w_gauss
Definition: generate_convection_diffusion_explicit_element.py:136
def load(f)
Definition: ode_solve.py:307
int d
Definition: ode_solve.py:397
int j
Definition: quadrature.py:648
J
Definition: sensitivityMatrix.py:58
N
Definition: sensitivityMatrix.py:29
integer i
Definition: TensorModule.f:17