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.
rom_residuals_utility.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: RAUL BRAVO
11 //
12 
13 #if !defined( ROM_RESIDUALS_UTILITY_H_INCLUDED )
14 #define ROM_RESIDUALS_UTILITY_H_INCLUDED
15 
16 /* Project includes */
17 #include "includes/define.h"
18 #include "includes/model_part.h"
20 #include "spaces/ublas_space.h"
21 
22 /* Application includes */
25 
26 namespace Kratos
27 {
28  typedef UblasSpace<double, CompressedMatrix, boost::numeric::ublas::vector<double>> SparseSpaceType;
29  typedef UblasSpace<double, Matrix, Vector> LocalSpaceType;
31 
32  // This utility returns the converged residuals projected onto the ROM basis Phi.
34  {
35  public:
36 
38 
40  ModelPart& rModelPart,
41  Parameters ThisParameters,
42  BaseSchemeType::Pointer pScheme
43  ): mrModelPart(rModelPart), mpScheme(pScheme){
44  // Validate default parameters
45  Parameters default_parameters = Parameters(R"(
46  {
47  "nodal_unknowns" : [],
48  "number_of_rom_dofs" : 10,
49  "petrov_galerkin_number_of_rom_dofs" : 10
50  })" );
51 
52  ThisParameters.ValidateAndAssignDefaults(default_parameters);
53 
54  mNodalVariablesNames = ThisParameters["nodal_unknowns"].GetStringArray();
55 
57  mRomDofs = ThisParameters["number_of_rom_dofs"].GetInt();
58  mPetrovGalerkinRomDofs = ThisParameters["petrov_galerkin_number_of_rom_dofs"].GetInt();
59 
60  // Setting up mapping: VARIABLE_KEY --> CORRECT_ROW_IN_BASIS
61  for(int k=0; k<mNodalDofs; k++){
63  {
65  mMapPhi[var.Key()] = k;
66  }
67  else
68  KRATOS_ERROR << "variable \""<< mNodalVariablesNames[k] << "\" not valid" << std::endl;
69 
70  }
71  }
72 
74 
78  template<typename TMatrix>
79  static void ResizeIfNeeded(TMatrix& rMat, const std::size_t Rows, const std::size_t Cols)
80 
81  {
82  if(rMat.size1() != Rows || rMat.size2() != Cols) {
83  rMat.resize(Rows, Cols, false);
84  }
85  };
86 
88  {
89  // Getting the number of elements and conditions from the model
90  const int n_elements = static_cast<int>(mrModelPart.Elements().size());
91  const int n_conditions = static_cast<int>(mrModelPart.Conditions().size());
92 
93  const auto& r_current_process_info = mrModelPart.GetProcessInfo();
94  const auto el_begin = mrModelPart.ElementsBegin();
95  const auto cond_begin = mrModelPart.ConditionsBegin();
96 
97  //contributions to the system
98  Matrix lhs_contribution = ZeroMatrix(0, 0);
99  Vector rhs_contribution = ZeroVector(0);
100 
101  //vector containing the localization in the system of the different terms
102  Element::EquationIdVectorType equation_id;
103  Matrix matrix_residuals( (n_elements + n_conditions), mRomDofs); // Matrix of reduced residuals.
104  Matrix phi_elemental;
105 
106  //dofs container initialization
107  Element::DofsVectorType elem_dofs;
108  Condition::DofsVectorType cond_dofs;
109  #pragma omp parallel firstprivate(n_elements, n_conditions, lhs_contribution, rhs_contribution, equation_id, phi_elemental, el_begin, cond_begin, elem_dofs, cond_dofs)
110  {
111  #pragma omp for nowait
112  for (int k = 0; k < n_elements; k++){
113  const auto it_el = el_begin + k;
114  //detect if the element is active or not. If the user did not make any choice the element is active by default
115  bool element_is_active = true;
116  if ((it_el)->IsDefined(ACTIVE))
117  element_is_active = (it_el)->Is(ACTIVE);
118  if (element_is_active){
119  //calculate elemental contribution
120  mpScheme->CalculateSystemContributions(*it_el, lhs_contribution, rhs_contribution, equation_id, r_current_process_info);
121  it_el->GetDofList(elem_dofs, r_current_process_info);
122  //assemble the elemental contribution - here is where the ROM acts
123  //compute the elemental reduction matrix phi_elemental
124  const auto& r_geom = it_el->GetGeometry();
125  if(phi_elemental.size1() != elem_dofs.size() || phi_elemental.size2() != mRomDofs)
126  phi_elemental.resize(elem_dofs.size(), mRomDofs,false);
127  RomAuxiliaryUtilities::GetPhiElemental(phi_elemental, elem_dofs, r_geom, mMapPhi);
128  noalias(row(matrix_residuals, k)) = prod(trans(phi_elemental), rhs_contribution); // The size of the residual will vary only when using more ROM modes, one row per condition
129  }
130 
131  }
132 
133  #pragma omp for nowait
134  for (int k = 0; k < n_conditions; k++){
135  ModelPart::ConditionsContainerType::iterator it = cond_begin + k;
136  //detect if the condition is active or not. If the user did not make any choice the condition is active by default
137  bool condition_is_active = true;
138  if ((it)->IsDefined(ACTIVE))
139  condition_is_active = (it)->Is(ACTIVE);
140  if (condition_is_active){
141  it->GetDofList(cond_dofs, r_current_process_info);
142  //calculate elemental contribution
143  mpScheme->CalculateSystemContributions(*it, lhs_contribution, rhs_contribution, equation_id, r_current_process_info);
144  //assemble the elemental contribution - here is where the ROM acts
145  //compute the elemental reduction matrix phi_elemental
146  const auto& r_geom = it->GetGeometry();
147  if(phi_elemental.size1() != cond_dofs.size() || phi_elemental.size2() != mRomDofs)
148  phi_elemental.resize(cond_dofs.size(), mRomDofs,false);
149  RomAuxiliaryUtilities::GetPhiElemental(phi_elemental, cond_dofs, r_geom, mMapPhi);
150  noalias(row(matrix_residuals, k+n_elements)) = prod(trans(phi_elemental), rhs_contribution); // The size of the residual will vary only when using more ROM modes, one row per condition
151  }
152  }
153  }
154  return matrix_residuals;
155  }
156 
158  {
159  // Getting the number of elements and conditions from the model
160  const int n_elements = static_cast<int>(mrModelPart.Elements().size());
161  const int n_conditions = static_cast<int>(mrModelPart.Conditions().size());
162 
163  const auto& r_current_process_info = mrModelPart.GetProcessInfo();
164  const auto el_begin = mrModelPart.ElementsBegin();
165  const auto cond_begin = mrModelPart.ConditionsBegin();
166 
167  //contributions to the system
168  Matrix lhs_contribution;
169  Vector rhs_contribution;
170 
171  //vector containing the localization in the system of the different terms
172  Element::EquationIdVectorType equation_id;
173  Matrix matrix_residuals( (n_elements + n_conditions), mPetrovGalerkinRomDofs); // Matrix of reduced residuals.
174  Matrix psi_elemental;
175 
176  //dofs container initialization
177  Element::DofsVectorType elem_dofs;
178  Condition::DofsVectorType cond_dofs;
179  #pragma omp parallel firstprivate(n_elements, n_conditions, lhs_contribution, rhs_contribution, equation_id, psi_elemental, el_begin, cond_begin, elem_dofs, cond_dofs)
180  {
181  #pragma omp for nowait
182  for (int k = 0; k < n_elements; k++){
183  const auto it_el = el_begin + k;
184  //detect if the element is active or not. If the user did not make any choice the element is active by default
185  const bool element_is_active = it_el->IsDefined(ACTIVE) ? it_el->Is(ACTIVE) : true;
186  if (element_is_active){
187  //calculate elemental contribution
188  mpScheme->CalculateSystemContributions(*it_el, lhs_contribution, rhs_contribution, equation_id, r_current_process_info);
189  it_el->GetDofList(elem_dofs, r_current_process_info);
190  //assemble the elemental contribution - here is where the ROM acts
191  //compute the elemental reduction matrix phi_elemental
192  const auto& r_geom = it_el->GetGeometry();
193  if(psi_elemental.size1() != elem_dofs.size() || psi_elemental.size2() != mPetrovGalerkinRomDofs)
194  psi_elemental.resize(elem_dofs.size(), mPetrovGalerkinRomDofs,false);
195  RomAuxiliaryUtilities::GetPsiElemental(psi_elemental, elem_dofs, r_geom, mMapPhi);
196  noalias(row(matrix_residuals, k)) = prod(trans(psi_elemental), rhs_contribution); // The size of the residual will vary only when using more ROM modes, one row per condition
197  }
198 
199  }
200 
201  #pragma omp for nowait
202  for (int k = 0; k < n_conditions; k++){
203  const auto it = cond_begin + k;
204  //detect if the condition is active or not. If the user did not make any choice the condition is active by default
205  const bool condition_is_active = it->IsDefined(ACTIVE) ? it->Is(ACTIVE) : true;
206  if (condition_is_active){
207  it->GetDofList(cond_dofs, r_current_process_info);
208  //calculate elemental contribution
209  mpScheme->CalculateSystemContributions(*it, lhs_contribution, rhs_contribution, equation_id, r_current_process_info);
210  //assemble the elemental contribution - here is where the ROM acts
211  //compute the elemental reduction matrix phi_elemental
212  const auto& r_geom = it->GetGeometry();
213  if(psi_elemental.size1() != cond_dofs.size() || psi_elemental.size2() != mPetrovGalerkinRomDofs)
214  psi_elemental.resize(cond_dofs.size(), mPetrovGalerkinRomDofs,false);
215  RomAuxiliaryUtilities::GetPsiElemental(psi_elemental, cond_dofs, r_geom, mMapPhi);
216  noalias(row(matrix_residuals, k+n_elements)) = prod(trans(psi_elemental), rhs_contribution); // The size of the residual will vary only when using more ROM modes, one row per condition
217  }
218  }
219  }
220  return matrix_residuals;
221  }
222 
224  Matrix& rJPhi
225  )
226  {
227  const int n_elements = static_cast<int>(mrModelPart.Elements().size());
228  const int n_conditions = static_cast<int>(mrModelPart.Conditions().size());
229 
230  const auto& r_current_process_info = mrModelPart.GetProcessInfo();
231 
232  //contributions to the system
233  Vector rhs_contribution;
234 
235  //vector containing the localization in the system of the different terms
236  Element::EquationIdVectorType equation_id;
237  Matrix matrix_residuals( (n_elements + n_conditions), mRomDofs);
238  Matrix phi_j_elemental;
239 
240  const auto el_begin = mrModelPart.ElementsBegin();
241  const auto cond_begin = mrModelPart.ConditionsBegin();
242 
243  //dofs container initialization
244  Element::DofsVectorType elem_dofs;
245  Condition::DofsVectorType cond_dofs;
246  #pragma omp parallel firstprivate(n_elements, n_conditions, rhs_contribution, equation_id, phi_j_elemental, el_begin, cond_begin, elem_dofs, cond_dofs)
247  {
248  #pragma omp for
249  for (int k = 0; k < n_elements; k++){
250  auto r_element = el_begin + k;
251  if (r_element->IsDefined(ACTIVE) && r_element->IsNot(ACTIVE)) continue;
252 
253  mpScheme->CalculateRHSContribution(*r_element, rhs_contribution, equation_id, r_current_process_info);
254  r_element->GetDofList(elem_dofs, r_current_process_info);
255 
256  const std::size_t ndofs = elem_dofs.size();
257  ResizeIfNeeded(phi_j_elemental, ndofs, mRomDofs);
258  RomAuxiliaryUtilities::GetJPhiElemental(phi_j_elemental, elem_dofs, rJPhi);
259 
260  #pragma omp critical
261  {
262  noalias(row(matrix_residuals, k)) = prod(trans(phi_j_elemental), rhs_contribution);
263  }
264  }
265 
266  #pragma omp for
267  for (int k = 0; k < n_conditions; k++){
268  auto r_condition = cond_begin + k;
269  if (r_condition->IsDefined(ACTIVE) && r_condition->IsNot(ACTIVE)) continue;
270 
271  mpScheme->CalculateRHSContribution(*r_condition, rhs_contribution, equation_id, r_current_process_info);
272  r_condition->GetDofList(cond_dofs, r_current_process_info);
273 
274  const std::size_t ndofs = cond_dofs.size();
275  ResizeIfNeeded(phi_j_elemental, ndofs, mRomDofs);
276  RomAuxiliaryUtilities::GetJPhiElemental(phi_j_elemental, cond_dofs, rJPhi);
277 
278  #pragma omp critical
279  {
280  noalias(row(matrix_residuals, n_elements + k)) = prod(trans(phi_j_elemental), rhs_contribution);
281  }
282  }
283  }
284  return matrix_residuals;
285  }
286 
287  protected:
288  std::vector< std::string > mNodalVariablesNames;
290  unsigned int mRomDofs;
293  BaseSchemeType::Pointer mpScheme;
294  std::unordered_map<Kratos::VariableData::KeyType, Matrix::size_type> mMapPhi;
295  };
296 
297 
298 } // namespace Kratos
299 
300 
301 
302 #endif // ROM_RESIDUALS_UTILITY_H_INCLUDED defined
std::vector< DofType::Pointer > DofsVectorType
Definition: condition.h:100
std::vector< DofType::Pointer > DofsVectorType
Definition: element.h:100
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
KratosComponents class encapsulates a lookup table for a family of classes in a generic way.
Definition: kratos_components.h:49
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
ConditionIterator ConditionsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1361
ConditionsContainerType & Conditions(IndexType ThisIndex=0)
Definition: model_part.h:1381
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
std::vector< std::string > GetStringArray() const
This method returns the array of strings in the current Parameter.
Definition: kratos_parameters.cpp:693
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
void ValidateAndAssignDefaults(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing match the form prescribed by th...
Definition: kratos_parameters.cpp:1306
Definition: rom_residuals_utility.h:34
static void ResizeIfNeeded(TMatrix &rMat, const std::size_t Rows, const std::size_t Cols)
Definition: rom_residuals_utility.h:79
Matrix GetProjectedResidualsOntoJPhi(Matrix &rJPhi)
Definition: rom_residuals_utility.h:223
ModelPart & mrModelPart
Definition: rom_residuals_utility.h:292
unsigned int mPetrovGalerkinRomDofs
Definition: rom_residuals_utility.h:291
Matrix GetProjectedResidualsOntoPsi()
Definition: rom_residuals_utility.h:157
int mNodalDofs
Definition: rom_residuals_utility.h:289
Matrix GetProjectedResidualsOntoPhi()
Definition: rom_residuals_utility.h:87
RomResidualsUtility(ModelPart &rModelPart, Parameters ThisParameters, BaseSchemeType::Pointer pScheme)
Definition: rom_residuals_utility.h:39
KRATOS_CLASS_POINTER_DEFINITION(RomResidualsUtility)
std::unordered_map< Kratos::VariableData::KeyType, Matrix::size_type > mMapPhi
Definition: rom_residuals_utility.h:294
BaseSchemeType::Pointer mpScheme
Definition: rom_residuals_utility.h:293
unsigned int mRomDofs
Definition: rom_residuals_utility.h:290
std::vector< std::string > mNodalVariablesNames
Definition: rom_residuals_utility.h:288
This class provides the implementation of the basic tasks that are needed by the solution strategy.
Definition: scheme.h:56
static void GetPsiElemental(Matrix &rPsiElemental, const Element::DofsVectorType &rDofs, const Element::GeometryType &rGeom, const std::unordered_map< Kratos::VariableData::KeyType, Matrix::size_type > &rVarToRowMapping)
Obtain the left elemental basis (Psi) matrix for a particular element.
Definition: rom_auxiliary_utilities.cpp:750
static void GetPhiElemental(Matrix &rPhiElemental, const Element::DofsVectorType &rDofs, const Element::GeometryType &rGeom, const std::unordered_map< Kratos::VariableData::KeyType, Matrix::size_type > &rVarToRowMapping)
Obtain the elemental basis matrix for a particular element.
Definition: rom_auxiliary_utilities.cpp:718
static void GetJPhiElemental(Matrix &rJPhiElemental, const Element::DofsVectorType &rDofs, const Matrix &rJPhi)
Obtain the JPhi elemental matrix for a particular element. JPhi represents the projection of the Jaco...
Definition: rom_auxiliary_utilities.cpp:782
#define KRATOS_ERROR
Definition: exception.h:161
bool Has(const std::string &ModelerName)
Checks if the modeler is registered.
Definition: modeler_factory.cpp:24
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
Scheme< SparseSpaceType, LocalSpaceType > BaseSchemeType
Definition: rom_residuals_utility.h:30
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
TUblasSparseSpace< double > SparseSpaceType
Definition: linear_solver_factory.h:154
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
TUblasDenseSpace< double > LocalSpaceType
Definition: register_factories.h:33
int k
Definition: quadrature.py:595