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.
global_rom_builder_and_solver.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: Sebastian Ares de Parga
11 //
12 //
13 
14 #pragma once
15 
16 // System includes
17 
18 // External includes
19 #include "concurrentqueue/concurrentqueue.h"
20 #include <Eigen/Core>
21 #include <Eigen/Dense>
22 #include <Eigen/Sparse>
23 
24 // Project includes
25 #include "includes/define.h"
26 #include "includes/model_part.h"
33 
34 /* Application includes */
37 
38 namespace Kratos
39 {
42 
46 
50 
54 
58 
62 template <class TSparseSpace, class TDenseSpace, class TLinearSolver>
63 class GlobalROMBuilderAndSolver : public ResidualBasedBlockBuilderAndSolver<TSparseSpace, TDenseSpace, TLinearSolver>
64 {
65 public:
66 
67  //TODO: UPDATE THIS
76 
79  // Class pointer definition
81 
82  // The size_t types
83  using SizeType = std::size_t;
84  using IndexType = std::size_t;
85 
88 
102 
107  using CompressedMatrixType = boost::numeric::ublas::compressed_matrix<double>;
110  using EigenDynamicMatrix = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
111  using EigenDynamicVector = Eigen::Matrix<double, Eigen::Dynamic, 1>;
112  using EigenSparseMatrix = Eigen::SparseMatrix<double, Eigen::RowMajor, int>;
113 
115  using DofType = typename Node::DofType;
117  using DofQueue = moodycamel::ConcurrentQueue<DofType::Pointer>;
118 
122 
124  typename TLinearSolver::Pointer pNewLinearSystemSolver,
125  Parameters ThisParameters): BaseType(pNewLinearSystemSolver)
126  {
127  // Validate and assign defaults
128  Parameters this_parameters_copy = ThisParameters.Clone();
129  this_parameters_copy = this->ValidateAndAssignParameters(this_parameters_copy, this->GetDefaultParameters());
130  this->AssignSettings(this_parameters_copy);
131  }
132 
134  typename TLinearSolver::Pointer pNewLinearSystemSolver)
135  : ResidualBasedBlockBuilderAndSolver<TSparseSpace, TDenseSpace, TLinearSolver>(pNewLinearSystemSolver)
136  {
137  }
138 
140 
144 
148 
149  typename BaseBuilderAndSolverType::Pointer Create(
150  typename TLinearSolver::Pointer pNewLinearSystemSolver,
151  Parameters ThisParameters) const override
152  {
153  return Kratos::make_shared<ClassType>(pNewLinearSystemSolver,ThisParameters);
154  }
155 
157  typename TSchemeType::Pointer pScheme,
158  ModelPart &rModelPart) override
159  {
160  KRATOS_TRY;
161 
162  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 1)) << "Setting up the dofs" << std::endl;
163  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 2)) << "Number of threads" << ParallelUtilities::GetNumThreads() << "\n" << std::endl;
164  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 2)) << "Initializing element loop" << std::endl;
165 
166  // Get model part data
167  if (mHromWeightsInitialized == false) {
168  InitializeHROMWeights(rModelPart);
169  }
170 
171  auto dof_queue = ExtractDofSet(pScheme, rModelPart);
172 
173  // Fill a sorted auxiliary array of with the DOFs set
174  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 2)) << "Initializing ordered array filling\n" << std::endl;
175  auto dof_array = SortAndRemoveDuplicateDofs(dof_queue);
176 
177  // Update base builder and solver DOFs array and set corresponding flag
180 
181  // Throw an exception if there are no DOFs involved in the analysis
182  KRATOS_ERROR_IF(BaseBuilderAndSolverType::GetDofSet().size() == 0) << "No degrees of freedom!" << std::endl;
183  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 2)) << "Number of degrees of freedom:" << BaseBuilderAndSolverType::GetDofSet().size() << std::endl;
184  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 2)) << "Finished setting up the dofs" << std::endl;
185 
186 #ifdef KRATOS_DEBUG
187  // If reactions are to be calculated, we check if all the dofs have reactions defined
189  {
190  for (const auto& r_dof: BaseBuilderAndSolverType::GetDofSet())
191  {
192  KRATOS_ERROR_IF_NOT(r_dof.HasReaction())
193  << "Reaction variable not set for the following :\n"
194  << "Node : " << r_dof.Id() << '\n'
195  << "Dof : " << r_dof << '\n'
196  << "Not possible to calculate reactions." << std::endl;
197  }
198  }
199 #endif
200  KRATOS_CATCH("");
201  }
202 
203  void SetUpSystem(ModelPart &rModelPart) override
204  {
205  auto& r_dof_set = BaseBuilderAndSolverType::GetDofSet();
207  IndexPartition<IndexType>(r_dof_set.size()).for_each([&](IndexType Index)
208  {
209  auto dof_iterator = r_dof_set.begin() + Index;
210  dof_iterator->SetEquationId(Index);
211  });
212  }
213 
214  // Vector ProjectToReducedBasis(
215  // const TSystemVectorType& rX,
216  // ModelPart::NodesContainerType& rNodes
217  // )
218  // {
219  // Vector rom_unknowns = ZeroVector(GetNumberOfROMModes());
220  // for(const auto& node : rNodes)
221  // {
222  // unsigned int node_aux_id = node.GetValue(AUX_ID);
223  // const auto& nodal_rom_basis = node.GetValue(ROM_BASIS);
224  // for (int i = 0; i < GetNumberOfROMModes(); ++i) {
225  // for (int j = 0; j < mNodalDofs; ++j) {
226  // rom_unknowns[i] += nodal_rom_basis(j, i)*rX(node_aux_id*mNodalDofs + j);
227  // }
228  // }
229  // }
230  // return rom_unknowns;
231  // }
232 
234  {
235  return mNumberOfRomModes;
236  }
237 
239  {
240  return mMonotonicityPreservingFlag;
241  }
242 
244  const TSystemVectorType& rRomUnkowns,
245  const ModelPart& rModelPart,
246  TSystemVectorType& rDx) const
247  {
248  const auto& r_dof_set = BaseBuilderAndSolverType::GetDofSet();
249  block_for_each(r_dof_set, [&](const DofType& r_dof)
250  {
251  const auto& r_node = rModelPart.GetNode(r_dof.Id());
252  const Matrix& r_rom_nodal_basis = r_node.GetValue(ROM_BASIS);
253  const Matrix::size_type row_id = mMapPhi.at(r_dof.GetVariable().Key());
254  rDx[r_dof.EquationId()] = inner_prod(row(r_rom_nodal_basis, row_id), rRomUnkowns);
255  });
256  }
257 
259  const ModelPart& rModelPart,
260  Matrix& rPhiGlobal)
261  {
262  const auto& r_dof_set = BaseBuilderAndSolverType::GetDofSet();
263  block_for_each(r_dof_set, [&](const DofType& r_dof)
264  {
265  const auto& r_node = rModelPart.GetNode(r_dof.Id());
266  const Matrix& r_rom_nodal_basis = r_node.GetValue(ROM_BASIS);
267  const Matrix::size_type row_id = mMapPhi.at(r_dof.GetVariable().Key());
268  if (r_dof.IsFixed())
269  {
270  noalias(row(rPhiGlobal, r_dof.EquationId())) = ZeroVector(r_rom_nodal_basis.size2());
271  }
272  else{
273  noalias(row(rPhiGlobal, r_dof.EquationId())) = row(r_rom_nodal_basis, row_id);
274  }
275  });
276  }
277 
279  TSystemMatrixType& rA,
281  )
282  {
283  const auto& r_dof_set = BaseType::GetDofSet();
284  Vector dofs_values = ZeroVector(r_dof_set.size());
285 
286  block_for_each(r_dof_set, [&](Dof<double>& rDof){
287  const std::size_t id = rDof.EquationId();
288  dofs_values[id] = rDof.GetSolutionStepValue();
289  });
290  double *values_vector = rA.value_data().begin();
291  std::size_t *index1_vector = rA.index1_data().begin();
292  std::size_t *index2_vector = rA.index2_data().begin();
293 
295  [&](std::size_t i)
296  {
297  for (std::size_t k = index1_vector[i]; k < index1_vector[i + 1]; k++) {
298  const double value = values_vector[k];
299  if (value > 0.0) {
300  const auto j = index2_vector[k];
301  if (j > i) {
302  // TODO: Partition in blocks to gain efficiency by avoiding thread locks.
303  // Values conflicting with other threads
304  auto& r_aij = rA(i,j).ref();
305  AtomicAdd(r_aij, -value);
306  auto& r_aji = rA(j,i).ref();
307  AtomicAdd(r_aji, -value);
308  auto& r_aii = rA(i,i).ref();
309  AtomicAdd(r_aii, value);
310  auto& r_ajj = rA(j,j).ref();
311  AtomicAdd(r_ajj, value);
312  auto& r_bi = rB[i];
313  AtomicAdd(r_bi, value*dofs_values[j] - value*dofs_values[i]);
314  auto& r_bj = rB[j];
315  AtomicAdd(r_bj, value*dofs_values[i] - value*dofs_values[j]);
316  }
317  }
318  }
319  }
320  );
321  }
322 
324  ModelPart& rModelPart,
325  TSystemMatrixType& rA,
326  TSystemVectorType& rDx,
327  TSystemVectorType& rb) override
328  {
329  // Call the base B&S InitializeSolutionStep
330  BaseBuilderAndSolverType::InitializeSolutionStep(rModelPart, rA, rDx, rb);
331 
332  // Reset the ROM solution increment in the root modelpart database
333  auto& r_root_mp = rModelPart.GetRootModelPart();
334  r_root_mp.GetValue(ROM_SOLUTION_INCREMENT) = ZeroVector(GetNumberOfROMModes());
335  }
336 
337 
339  typename TSchemeType::Pointer pScheme,
340  ModelPart &rModelPart,
342  TSystemVectorType &Dx,
343  TSystemVectorType &b) override
344  {
345  KRATOS_TRY
346 
347  BuildAndProjectROM(pScheme, rModelPart, A, b, Dx);
348 
349  SolveROM(rModelPart, mEigenRomA, mEigenRomB, Dx);
350 
351  KRATOS_CATCH("")
352  }
353 
355  typename TSchemeType::Pointer pScheme,
359  ModelPart &rModelPart) override
360  {
361  KRATOS_TRY
362 
363  // If not initialized, initalize the system arrays to an empty vector/matrix
364  if (!pA) {
365  TSystemMatrixPointerType p_new_A = Kratos::make_shared<TSystemMatrixType>(0, 0);
366  pA.swap(p_new_A);
367  }
368  if (!pDx) {
369  TSystemVectorPointerType p_new_Dx = Kratos::make_shared<TSystemVectorType>(0);
370  pDx.swap(p_new_Dx);
371  }
372  if (!pb) {
373  TSystemVectorPointerType p_new_b = Kratos::make_shared<TSystemVectorType>(0);
374  pb.swap(p_new_b);
375  }
376 
377  TSystemVectorType& r_Dx = *pDx;
380  }
381 
382  TSystemVectorType& r_b = *pb;
385  }
386 
387  KRATOS_CATCH("")
388  }
389 
391  {
392  Parameters default_parameters = Parameters(R"(
393  {
394  "name" : "global_rom_builder_and_solver",
395  "nodal_unknowns" : [],
396  "number_of_rom_dofs" : 10,
397  "rom_bns_settings" : {
398  "monotonicity_preserving": false
399  }
400  })");
402 
403  return default_parameters;
404  }
405 
406  static std::string Name()
407  {
408  return "global_rom_builder_and_solver";
409  }
410 
414 
418 
422 
424  virtual std::string Info() const override
425  {
426  return "GlobalROMBuilderAndSolver";
427  }
428 
430  virtual void PrintInfo(std::ostream &rOStream) const override
431  {
432  rOStream << Info();
433  }
434 
436  virtual void PrintData(std::ostream &rOStream) const override
437  {
438  rOStream << Info();
439  }
440 
444 
446 protected:
450 
454 
456  std::unordered_map<Kratos::VariableData::KeyType, Matrix::size_type> mMapPhi;
459  bool mHromSimulation = false;
462 
466 
470 
471  void AssignSettings(const Parameters ThisParameters) override
472  {
474 
475  // Set member variables
476  mNodalDofs = ThisParameters["nodal_unknowns"].size();
477  mNumberOfRomModes = ThisParameters["number_of_rom_dofs"].GetInt();
478  mMonotonicityPreservingFlag = ThisParameters["rom_bns_settings"]["monotonicity_preserving"].GetBool();
479 
480  // Set up a map with key the variable key and value the correct row in ROM basis
481  IndexType k = 0;
482  for (const auto& r_var_name : ThisParameters["nodal_unknowns"].GetStringArray()) {
483  if(KratosComponents<Variable<double>>::Has(r_var_name)) {
484  const auto& var = KratosComponents<Variable<double>>::Get(r_var_name);
485  mMapPhi[var.Key()] = k++;
486  } else {
487  KRATOS_ERROR << "Variable \""<< r_var_name << "\" not valid" << std::endl;
488  }
489  }
490  }
491 
492 
494  {
495  KRATOS_TRY
496 
497  using ElementQueue = moodycamel::ConcurrentQueue<Element::Pointer>;
498  using ConditionQueue = moodycamel::ConcurrentQueue<Condition::Pointer>;
499 
500  // Inspecting elements
501  ElementQueue element_queue;
502  block_for_each(rModelPart.Elements().GetContainer(),
503  [&](Element::Pointer p_element)
504  {
505  if (p_element->Has(HROM_WEIGHT)) {
506  element_queue.enqueue(std::move(p_element));
507  } else {
508  p_element->SetValue(HROM_WEIGHT, 1.0);
509  }
510  });
511 
512  // Inspecting conditions
513  ConditionQueue condition_queue;
514  block_for_each(rModelPart.Conditions().GetContainer(),
515  [&](Condition::Pointer p_condition)
516  {
517  if (p_condition->Has(HROM_WEIGHT)) {
518  condition_queue.enqueue(std::move(p_condition));
519  } else {
520  p_condition->SetValue(HROM_WEIGHT, 1.0);
521  }
522  });
523 
524  // Dequeueing elements
525  std::size_t err_id;
526  mSelectedElements.reserve(element_queue.size_approx());
527  Element::Pointer p_element;
528  while ( (err_id = element_queue.try_dequeue(p_element)) != 0) {
529  mSelectedElements.push_back(std::move(p_element));
530  }
531 
532  // Dequeueing conditions
533  mSelectedConditions.reserve(condition_queue.size_approx());
534  Condition::Pointer p_condition;
535  while ( (err_id = condition_queue.try_dequeue(p_condition)) != 0) {
536  mSelectedConditions.push_back(std::move(p_condition));
537  }
538 
539  // Wrap-up
540  mHromSimulation = !(mSelectedElements.empty() && mSelectedConditions.empty());
541  mHromWeightsInitialized = true;
542 
543  KRATOS_CATCH("")
544  }
545 
547  typename TSchemeType::Pointer pScheme,
548  ModelPart& rModelPart)
549  {
550  KRATOS_TRY
551 
552  DofQueue dof_queue;
553 
554  // Emulates ConcurrentQueue::enqueue_bulk adding move semantics to avoid atomic ops
555  const auto enqueue_bulk_move = [](DofQueue& r_queue, DofsVectorType& r_dof_list) {
556  for(auto& p_dof: r_dof_list) {
557  r_queue.enqueue(std::move(p_dof));
558  }
559  r_dof_list.clear();
560  };
561 
562  // Inspecting elements
563  DofsVectorType tls_dof_list; // Preallocation
564  block_for_each(rModelPart.Elements(), tls_dof_list,
565  [&](const Element& r_element, DofsVectorType& r_dof_list)
566  {
567  pScheme->GetDofList(r_element, r_dof_list, rModelPart.GetProcessInfo());
568  enqueue_bulk_move(dof_queue, r_dof_list);
569  });
570 
571  // Inspecting conditions
572  block_for_each(rModelPart.Conditions(), tls_dof_list,
573  [&](const Condition& r_condition, DofsVectorType& r_dof_list)
574  {
575  pScheme->GetDofList(r_condition, r_dof_list, rModelPart.GetProcessInfo());
576  enqueue_bulk_move(dof_queue, r_dof_list);
577  });
578 
579  // Inspecting master-slave constraints
580  std::pair<DofsVectorType, DofsVectorType> tls_ms_dof_lists; // Preallocation
581  block_for_each(rModelPart.MasterSlaveConstraints(), tls_ms_dof_lists,
582  [&](const MasterSlaveConstraint& r_constraint, std::pair<DofsVectorType, DofsVectorType>& r_dof_lists)
583  {
584  r_constraint.GetDofList(r_dof_lists.first, r_dof_lists.second, rModelPart.GetProcessInfo());
585 
586  enqueue_bulk_move(dof_queue, r_dof_lists.first);
587  enqueue_bulk_move(dof_queue, r_dof_lists.second);
588  });
589 
590  return dof_queue;
591 
592  KRATOS_CATCH("")
593  }
594 
596  {
597  KRATOS_TRY
598 
599  DofsArrayType dof_array;
600  dof_array.reserve(rDofQueue.size_approx());
601  DofType::Pointer p_dof;
602  std::size_t err_id;
603  while ( (err_id = rDofQueue.try_dequeue(p_dof)) != 0) {
604  dof_array.push_back(std::move(p_dof));
605  }
606 
607  dof_array.Unique(); // Sorts internally
608 
609  return dof_array;
610 
611  KRATOS_CATCH("")
612  }
613 
617  template<typename TMatrix>
618  static void ResizeIfNeeded(TMatrix& mat, const SizeType rows, const SizeType cols)
619  {
620  if(mat.size1() != rows || mat.size2() != cols) {
621  mat.resize(rows, cols, false);
622  }
623  }
624 
628  virtual void BuildAndProjectROM(
629  typename TSchemeType::Pointer pScheme,
630  ModelPart &rModelPart,
631  TSystemMatrixType &rA,
632  TSystemVectorType &rb,
633  TSystemVectorType &rDx)
634  {
635  KRATOS_TRY
636 
637  KRATOS_ERROR_IF(!pScheme) << "No scheme provided!" << std::endl;
638 
639  const auto assembling_timer = BuiltinTimer();
640 
641  if (rA.size1() != BaseType::mEquationSystemSize || rA.size2() != BaseType::mEquationSystemSize) {
642  rA.resize(BaseType::mEquationSystemSize, BaseType::mEquationSystemSize, false);
643  BaseType::ConstructMatrixStructure(pScheme, rA, rModelPart);
644  }
645 
646  Build(pScheme, rModelPart, rA, rb);
647 
648  if (mMonotonicityPreservingFlag) {
649  BaseType::ApplyDirichletConditions(pScheme, rModelPart, rA, rDx, rb);
650  MonotonicityPreserving(rA, rb);
651  }
652 
653  ProjectROM(rModelPart, rA, rb);
654 
655  double time = assembling_timer.ElapsedSeconds();
656  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 0)) << "Build and project time: " << time << std::endl;
657 
658  KRATOS_CATCH("")
659  }
660 
668  void Build(
669  typename TSchemeType::Pointer pScheme,
670  ModelPart& rModelPart,
672  TSystemVectorType& b) override
673  {
674  KRATOS_TRY
675 
676  KRATOS_ERROR_IF(!pScheme) << "No scheme provided!" << std::endl;
677 
678  // // Getting the elements from the model
679  const int nelements = mHromSimulation ? mSelectedElements.size() : rModelPart.Elements().size();
680 
681  // // Getting the array of the conditions
682  const int nconditions = mHromSimulation ? mSelectedConditions.size() : rModelPart.Conditions().size();
683 
684  const ProcessInfo& CurrentProcessInfo = rModelPart.GetProcessInfo();
685  ModelPart::ElementsContainerType::iterator el_begin = mHromSimulation ? mSelectedElements.begin() : rModelPart.Elements().begin();
686  ModelPart::ConditionsContainerType::iterator cond_begin = mHromSimulation ? mSelectedConditions.begin() : rModelPart.Conditions().begin();
687 
688  //contributions to the system
689  LocalSystemMatrixType LHS_Contribution = LocalSystemMatrixType(0, 0);
690  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
691 
692  //vector containing the localization in the system of the different
693  //terms
695 
696  // Assemble all elements
697  const auto timer = BuiltinTimer();
698 
699  #pragma omp parallel firstprivate(nelements,nconditions, LHS_Contribution, RHS_Contribution, EquationId )
700  {
701  # pragma omp for schedule(guided, 512) nowait
702  for (int k = 0; k < nelements; k++) {
703  auto it_elem = el_begin + k;
704 
705  if (it_elem->IsActive()) {
706  // Calculate elemental contribution
707  pScheme->CalculateSystemContributions(*it_elem, LHS_Contribution, RHS_Contribution, EquationId, CurrentProcessInfo);
708 
709  //Get HROM weight and multiply it by its contribution
710  const double h_rom_weight = mHromSimulation ? it_elem->GetValue(HROM_WEIGHT) : 1.0;
711  LHS_Contribution *= h_rom_weight;
712  RHS_Contribution *= h_rom_weight;
713 
714  // Assemble the elemental contribution
715  BaseType::Assemble(A, b, LHS_Contribution, RHS_Contribution, EquationId);
716  }
717 
718  }
719 
720  #pragma omp for schedule(guided, 512)
721  for (int k = 0; k < nconditions; k++) {
722  auto it_cond = cond_begin + k;
723 
724  if (it_cond->IsActive()) {
725  // Calculate elemental contribution
726  pScheme->CalculateSystemContributions(*it_cond, LHS_Contribution, RHS_Contribution, EquationId, CurrentProcessInfo);
727 
728  //Get HROM weight and multiply it by its contribution
729  const double h_rom_weight = mHromSimulation ? it_cond->GetValue(HROM_WEIGHT) : 1.0;
730  LHS_Contribution *= h_rom_weight;
731  RHS_Contribution *= h_rom_weight;
732 
733  // Assemble the elemental contribution
734  BaseType::Assemble(A, b, LHS_Contribution, RHS_Contribution, EquationId);
735  }
736  }
737  }
738 
739  KRATOS_INFO_IF("GlobalROMResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() >= 1) << "Build time: " << timer.ElapsedSeconds() << std::endl;
740 
741  KRATOS_INFO_IF("GlobalROMResidualBasedBlockBuilderAndSolver", (this->GetEchoLevel() > 2 && rModelPart.GetCommunicator().MyPID() == 0)) << "Finished parallel building" << std::endl;
742 
743  KRATOS_CATCH("")
744  }
745 
749  virtual void ProjectROM(
750  ModelPart &rModelPart,
751  TSystemMatrixType &rA,
752  TSystemVectorType &rb)
753  {
754  KRATOS_TRY
755 
756  if (mRightRomBasisInitialized==false){
757  mPhiGlobal = ZeroMatrix(BaseBuilderAndSolverType::GetEquationSystemSize(), GetNumberOfROMModes());
758  mRightRomBasisInitialized = true;
759  }
760 
761  BuildRightROMBasis(rModelPart, mPhiGlobal);
762 
763  auto a_wrapper = UblasWrapper<double>(rA);
764  const auto& eigen_rA = a_wrapper.matrix();
765  Eigen::Map<EigenDynamicVector> eigen_rb(rb.data().begin(), rb.size());
766  Eigen::Map<EigenDynamicMatrix> eigen_mPhiGlobal(mPhiGlobal.data().begin(), mPhiGlobal.size1(), mPhiGlobal.size2());
767 
768  EigenDynamicMatrix eigen_rA_times_mPhiGlobal = eigen_rA * eigen_mPhiGlobal; //TODO: Make it in parallel.
769 
770  // Compute the matrix multiplication
771  mEigenRomA = eigen_mPhiGlobal.transpose() * eigen_rA_times_mPhiGlobal; //TODO: Make it in parallel.
772  mEigenRomB = eigen_mPhiGlobal.transpose() * eigen_rb; //TODO: Make it in parallel.
773 
774  KRATOS_CATCH("")
775  }
776 
780  virtual void SolveROM(
781  ModelPart &rModelPart,
782  EigenDynamicMatrix &rEigenRomA,
783  EigenDynamicVector &rEigenRomB,
784  TSystemVectorType &rDx)
785  {
786  KRATOS_TRY
787 
788  RomSystemVectorType dxrom(GetNumberOfROMModes());
789 
790  const auto solving_timer = BuiltinTimer();
791 
792  using EigenDynamicVector = Eigen::Matrix<double, Eigen::Dynamic, 1>;
793  Eigen::Map<EigenDynamicVector> dxrom_eigen(dxrom.data().begin(), dxrom.size());
794  dxrom_eigen = rEigenRomA.colPivHouseholderQr().solve(rEigenRomB);
795 
796  double time = solving_timer.ElapsedSeconds();
797  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 0)) << "Solve reduced system time: " << time << std::endl;
798 
799  // Save the ROM solution increment in the root modelpart database
800  auto& r_root_mp = rModelPart.GetRootModelPart();
801  noalias(r_root_mp.GetValue(ROM_SOLUTION_INCREMENT)) += dxrom;
802 
803  // project reduced solution back to full order model
804  const auto backward_projection_timer = BuiltinTimer();
805  ProjectToFineBasis(dxrom, rModelPart, rDx);
806  KRATOS_INFO_IF("GlobalROMBuilderAndSolver", (this->GetEchoLevel() > 0)) << "Project to fine basis time: " << backward_projection_timer.ElapsedSeconds() << std::endl;
807 
808  KRATOS_CATCH("")
809  }
810 
814 
818 
822 private:
825 
826  SizeType mNumberOfRomModes;
827  EigenDynamicMatrix mEigenRomA;
828  EigenDynamicVector mEigenRomB;
829  Matrix mPhiGlobal;
830  bool mMonotonicityPreservingFlag;
831 
835 
837 }; /* Class GlobalROMBuilderAndSolver */
838 
842 
843 
845 
846 } /* namespace Kratos.*/
Current class provides an implementation for the base builder and solving operations.
Definition: builder_and_solver.h:64
std::size_t IndexType
Definition of the index type.
Definition: builder_and_solver.h:76
TSparseSpace::VectorType TSystemVectorType
Definition of the vector size.
Definition: builder_and_solver.h:85
virtual void InitializeSolutionStep(ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb)
It applies certain operations at the system of equations at the beginning of the solution step.
Definition: builder_and_solver.h:553
bool GetCalculateReactionsFlag() const
This method returns the flag mCalculateReactionsFlag.
Definition: builder_and_solver.h:184
TSparseSpace::MatrixType TSystemMatrixType
Definition of the sparse matrix.
Definition: builder_and_solver.h:82
ModelPart::ConditionsContainerType ConditionsArrayType
Definition: builder_and_solver.h:111
virtual void AssignSettings(const Parameters ThisParameters)
This method assigns settings to member variables.
Definition: builder_and_solver.h:780
Scheme< TSparseSpace, TDenseSpace > TSchemeType
Definition of the scheme type.
Definition: builder_and_solver.h:100
virtual Parameters ValidateAndAssignParameters(Parameters ThisParameters, const Parameters DefaultParameters) const
This method validate and assign default parameters.
Definition: builder_and_solver.h:767
ModelPart::DofsArrayType DofsArrayType
Definition of the DoF array type.
Definition: builder_and_solver.h:106
TDenseSpace::MatrixType LocalSystemMatrixType
The local matrix definition.
Definition: builder_and_solver.h:94
TSparseSpace::VectorPointerType TSystemVectorPointerType
Definition of the pointer to the vector.
Definition: builder_and_solver.h:91
void SetDofSetIsInitializedFlag(bool DofSetIsInitialized)
This method sets the flag mDofSetIsInitialized.
Definition: builder_and_solver.h:211
TDenseSpace::VectorType LocalSystemVectorType
The local vector definition.
Definition: builder_and_solver.h:97
unsigned int GetEquationSystemSize() const
This method returns the value mEquationSystemSize.
Definition: builder_and_solver.h:238
TSparseSpace::MatrixPointerType TSystemMatrixPointerType
Definition of the pointer to the sparse matrix.
Definition: builder_and_solver.h:88
std::size_t SizeType
Definition of the size type.
Definition: builder_and_solver.h:73
int GetEchoLevel() const
It returns the echo level.
Definition: builder_and_solver.h:674
virtual DofsArrayType & GetDofSet()
It allows to get the list of Dofs from the element.
Definition: builder_and_solver.h:507
virtual Parameters GetDefaultParameters() const
This method provides the defaults parameters to avoid conflicts between the different constructors.
Definition: builder_and_solver.h:628
unsigned int mEquationSystemSize
Flag taking in account if it is needed or not to calculate the reactions.
Definition: builder_and_solver.h:747
ModelPart::ElementsContainerType ElementsArrayType
Definition: builder_and_solver.h:110
Definition: builtin_timer.h:26
virtual int MyPID() const
Definition: communicator.cpp:91
Base class for all Conditions.
Definition: condition.h:59
TDataType & GetValue(const Variable< TDataType > &rThisVariable)
Gets the value associated with a given variable.
Definition: data_value_container.h:268
iterator begin()
Iterator pointing to the beginning of the container.
Definition: data_value_container.h:209
Dof represents a degree of freedom (DoF).
Definition: dof.h:86
const VariableData & GetVariable() const
Definition: dof.h:303
IndexType Id() const
Definition: dof.h:292
bool IsFixed() const
Definition: dof.h:376
EquationIdType EquationId() const
Definition: dof.h:324
TDataType & GetSolutionStepValue(IndexType SolutionStepIndex=0)
Definition: dof.h:256
Base class for all Elements.
Definition: element.h:60
std::vector< DofType::Pointer > DofsVectorType
Definition: element.h:100
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
Definition: global_rom_builder_and_solver.h:64
void SetUpSystem(ModelPart &rModelPart) override
Organises the dofset in order to speed up the building phase.
Definition: global_rom_builder_and_solver.h:203
bool GetMonotonicityPreservingFlag() const noexcept
Definition: global_rom_builder_and_solver.h:238
Eigen::SparseMatrix< double, Eigen::RowMajor, int > EigenSparseMatrix
Definition: global_rom_builder_and_solver.h:112
virtual std::string Info() const override
Turn back information as a string.
Definition: global_rom_builder_and_solver.h:424
bool mRightRomBasisInitialized
Definition: global_rom_builder_and_solver.h:461
virtual void ProjectROM(ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rb)
Definition: global_rom_builder_and_solver.h:749
Eigen::Matrix< double, Eigen::Dynamic, 1 > EigenDynamicVector
Definition: global_rom_builder_and_solver.h:111
virtual void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: global_rom_builder_and_solver.h:430
SizeType mNodalDofs
Definition: global_rom_builder_and_solver.h:455
LocalSystemMatrixType RomSystemMatrixType
Definition: global_rom_builder_and_solver.h:108
GlobalROMBuilderAndSolver(typename TLinearSolver::Pointer pNewLinearSystemSolver)
Definition: global_rom_builder_and_solver.h:133
bool mHromSimulation
Definition: global_rom_builder_and_solver.h:459
std::unordered_map< Kratos::VariableData::KeyType, Matrix::size_type > mMapPhi
Definition: global_rom_builder_and_solver.h:456
void ProjectToFineBasis(const TSystemVectorType &rRomUnkowns, const ModelPart &rModelPart, TSystemVectorType &rDx) const
Definition: global_rom_builder_and_solver.h:243
void BuildRightROMBasis(const ModelPart &rModelPart, Matrix &rPhiGlobal)
Definition: global_rom_builder_and_solver.h:258
virtual void SolveROM(ModelPart &rModelPart, EigenDynamicMatrix &rEigenRomA, EigenDynamicVector &rEigenRomB, TSystemVectorType &rDx)
Definition: global_rom_builder_and_solver.h:780
static DofsArrayType SortAndRemoveDuplicateDofs(DofQueue &rDofQueue)
Definition: global_rom_builder_and_solver.h:595
void Build(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &b) override
Function to perform the build of the LHS and RHS multiplied by its corresponding hrom weight.
Definition: global_rom_builder_and_solver.h:668
static void ResizeIfNeeded(TMatrix &mat, const SizeType rows, const SizeType cols)
Definition: global_rom_builder_and_solver.h:618
typename BaseBuilderAndSolverType::LocalSystemMatrixType LocalSystemMatrixType
Definition: global_rom_builder_and_solver.h:97
SizeType GetNumberOfROMModes() const noexcept
Definition: global_rom_builder_and_solver.h:233
virtual void BuildAndProjectROM(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rb, TSystemVectorType &rDx)
Definition: global_rom_builder_and_solver.h:628
ElementsArrayType mSelectedElements
Definition: global_rom_builder_and_solver.h:457
Parameters GetDefaultParameters() const override
This method provides the defaults parameters to avoid conflicts between the different constructors.
Definition: global_rom_builder_and_solver.h:390
void AssignSettings(const Parameters ThisParameters) override
This method assigns settings to member variables.
Definition: global_rom_builder_and_solver.h:471
void SetUpDofSet(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart) override
Builds the list of the DofSets involved in the problem by "asking" to each element and condition its ...
Definition: global_rom_builder_and_solver.h:156
virtual void InitializeSolutionStep(ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb) override
It applies certain operations at the system of equations at the beginning of the solution step.
Definition: global_rom_builder_and_solver.h:323
static DofQueue ExtractDofSet(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart)
Definition: global_rom_builder_and_solver.h:546
void MonotonicityPreserving(TSystemMatrixType &rA, TSystemVectorType &rB)
Definition: global_rom_builder_and_solver.h:278
typename BaseBuilderAndSolverType::LocalSystemVectorType LocalSystemVectorType
Definition: global_rom_builder_and_solver.h:96
KRATOS_CLASS_POINTER_DEFINITION(GlobalROMBuilderAndSolver)
void BuildAndSolve(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b) override
Function to perform the building and solving phase at the same time.
Definition: global_rom_builder_and_solver.h:338
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > EigenDynamicMatrix
Definition: global_rom_builder_and_solver.h:110
GlobalROMBuilderAndSolver(typename TLinearSolver::Pointer pNewLinearSystemSolver, Parameters ThisParameters)
Definition: global_rom_builder_and_solver.h:123
bool mHromWeightsInitialized
Definition: global_rom_builder_and_solver.h:460
void ResizeAndInitializeVectors(typename TSchemeType::Pointer pScheme, TSystemMatrixPointerType &pA, TSystemVectorPointerType &pDx, TSystemVectorPointerType &pb, ModelPart &rModelPart) override
This method initializes and resizes the system of equations.
Definition: global_rom_builder_and_solver.h:354
virtual void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: global_rom_builder_and_solver.h:436
BaseBuilderAndSolverType::Pointer Create(typename TLinearSolver::Pointer pNewLinearSystemSolver, Parameters ThisParameters) const override
Create method.
Definition: global_rom_builder_and_solver.h:149
moodycamel::ConcurrentQueue< DofType::Pointer > DofQueue
Definition: global_rom_builder_and_solver.h:117
typename ModelPart::MasterSlaveConstraintContainerType MasterSlaveConstraintContainerType
Additional definitions.
Definition: global_rom_builder_and_solver.h:104
void InitializeHROMWeights(ModelPart &rModelPart)
Definition: global_rom_builder_and_solver.h:493
LocalSystemVectorType RomSystemVectorType
Definition: global_rom_builder_and_solver.h:109
ConditionsArrayType mSelectedConditions
Definition: global_rom_builder_and_solver.h:458
static std::string Name()
Definition: global_rom_builder_and_solver.h:406
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
std::size_t size_type
Definition: amatrix_interface.h:57
KratosComponents class encapsulates a lookup table for a family of classes in a generic way.
Definition: kratos_components.h:49
A class that implements the interface for different master-slave constraints to be applied on a syste...
Definition: master_slave_constraint.h:76
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
MasterSlaveConstraintContainerType & MasterSlaveConstraints(IndexType ThisIndex=0)
Definition: model_part.h:654
Communicator & GetCommunicator()
Definition: model_part.h:1821
ConditionsContainerType & Conditions(IndexType ThisIndex=0)
Definition: model_part.h:1381
MeshType::MasterSlaveConstraintContainerType MasterSlaveConstraintContainerType
Definition: model_part.h:219
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ModelPart & GetRootModelPart()
Definition: model_part.cpp:510
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
NodeType & GetNode(IndexType NodeId, IndexType ThisIndex=0)
Definition: model_part.h:433
Dof< double > DofType
Dof type.
Definition: node.h:83
static int GetNumThreads()
Returns the current number of threads.
Definition: parallel_utilities.cpp:34
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
Parameters Clone() const
Generates a clone of the current document.
Definition: kratos_parameters.cpp:397
SizeType size() const
This method returns the total size of the current array parameter.
Definition: kratos_parameters.cpp:993
bool GetBool() const
This method returns the boolean contained in the current Parameter.
Definition: kratos_parameters.cpp:675
void AddMissingParameters(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing contain at least all parameters...
Definition: kratos_parameters.cpp:1369
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
size_type size() const
Returns the number of elements in the container.
Definition: pointer_vector_set.h:502
void swap(PointerVectorSet &rOther)
Swaps the contents of this PointerVectorSet with another.
Definition: pointer_vector_set.h:532
TContainerType & GetContainer()
Definition: pointer_vector_set.h:778
void reserve(int reservedsize)
Reserves memory for a specified number of elements.
Definition: pointer_vector_set.h:733
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Current class provides an implementation for standard builder and solving operations.
Definition: residualbased_block_builder_and_solver.h:82
Element::EquationIdVectorType EquationIdVectorType
Definition: residualbased_block_builder_and_solver.h:119
Element::DofsVectorType DofsVectorType
Definition: residualbased_block_builder_and_solver.h:120
boost::numeric::ublas::compressed_matrix< double > CompressedMatrixType
Definition: residualbased_block_builder_and_solver.h:121
This class provides the implementation of the basic tasks that are needed by the solution strategy.
Definition: scheme.h:56
Definition: ublas_wrapper.h:32
KeyType Key() const
Definition: variable_data.h:187
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_INFO_IF(label, conditional)
Definition: logger.h:251
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
void AtomicAdd(TDataType &target, const TDataType &value)
Definition: atomic_utilities.h:55
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > EigenDynamicMatrix
Definition: linear_solvers_define.h:32
void block_for_each(TIterator itBegin, TIterator itEnd, TFunction &&rFunction)
Execute a functor on all items of a range in parallel.
Definition: parallel_utilities.h:299
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
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
Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > EigenDynamicVector
Definition: linear_solvers_define.h:33
time
Definition: face_heat.py:85
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
def Index()
Definition: hdf5_io_tools.py:38
tuple const
Definition: ode_solve.py:403
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
mat
Definition: script_ELASTIC.py:155
A
Definition: sensitivityMatrix.py:70
integer i
Definition: TensorModule.f:17
Definition: timer.py:1