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.
residualbased_elimination_builder_and_solver_with_constraints.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: Vicente Mataix Ferrandiz
11 //
12 //
13 #if !defined(KRATOS_RESIDUAL_BASED_ELIMINATION_BUILDER_AND_SOLVER_WITH_CONSTRAINTS)
14 #define KRATOS_RESIDUAL_BASED_ELIMINATION_BUILDER_AND_SOLVER_WITH_CONSTRAINTS
15 
16 /* System includes */
17 #include <unordered_set>
18 #include <unordered_map>
19 
20 /* External includes */
21 
22 /* Project includes */
26 #include "input_output/logger.h"
29 
30 namespace Kratos
31 {
32 
35 
39 
43 
47 
51 
87 template <class TSparseSpace,
88  class TDenseSpace,
89  class TLinearSolver
90  >
92  : public ResidualBasedEliminationBuilderAndSolver<TSparseSpace, TDenseSpace, TLinearSolver>
93 {
94  public:
97 
100 
103 
106 
109 
110  // The size_t types
111  typedef std::size_t SizeType;
112  typedef std::size_t IndexType;
113 
116  typedef typename BaseType::TDataType TDataType;
124  typedef typename BaseType::NodeType NodeType;
128 
133  typedef boost::numeric::ublas::compressed_matrix<double> CompressedMatrixType;
134 
136  typedef typename NodeType::DofType DofType;
138 
140  typedef std::unordered_set<IndexType> IndexSetType;
141 
143  typedef std::unordered_map<IndexType, IndexType> IndexMapType;
144 
147  typedef typename MasterSlaveConstraint::Pointer MasterSlaveConstraintPointerType;
148  typedef std::vector<IndexType> VectorIndexType;
150 
154 
158 
163  {
164  }
165 
170  typename TLinearSolver::Pointer pNewLinearSystemSolver,
171  Parameters ThisParameters
172  ) : BaseType(pNewLinearSystemSolver)
173  {
174  // Validate and assign defaults
175  ThisParameters = this->ValidateAndAssignParameters(ThisParameters, this->GetDefaultParameters());
176  this->AssignSettings(ThisParameters);
177  }
178 
183  typename TLinearSolver::Pointer pNewLinearSystemSolver,
184  const bool CheckConstraintRelation = true,
185  const bool ResetRelationMatrixEachIteration = false
186  )
187  : BaseType(pNewLinearSystemSolver),
188  mCheckConstraintRelation(CheckConstraintRelation),
189  mResetRelationMatrixEachIteration(ResetRelationMatrixEachIteration)
190  {
191  }
192 
196  {
197  }
198 
204  typename BuilderAndSolverBaseType::Pointer Create(
205  typename TLinearSolver::Pointer pNewLinearSystemSolver,
206  Parameters ThisParameters
207  ) const override
208  {
209  return Kratos::make_shared<ClassType>(pNewLinearSystemSolver,ThisParameters);
210  }
211 
215 
219 
220  void SetUpSystem(ModelPart& rModelPart) override
221  {
222  if(rModelPart.MasterSlaveConstraints().size() > 0)
223  SetUpSystemWithConstraints(rModelPart);
224  else
225  BaseType::SetUpSystem(rModelPart);
226  }
227 
236  void Build(
237  typename TSchemeType::Pointer pScheme,
238  ModelPart& rModelPart,
239  TSystemMatrixType& rA,
241  ) override
242  {
243  if(rModelPart.MasterSlaveConstraints().size() > 0)
244  BuildWithConstraints(pScheme, rModelPart, rA, rb);
245  else
246  BaseType::Build(pScheme, rModelPart, rA, rb);
247  }
248 
260  typename TSchemeType::Pointer pScheme,
261  ModelPart& rModelPart,
263  TSystemVectorType& Dx,
264  TSystemVectorType& b) override
265  {
266  if(rModelPart.MasterSlaveConstraints().size() > 0)
267  BuildAndSolveWithConstraints(pScheme, rModelPart, A, Dx, b);
268  else
269  BaseType::BuildAndSolve(pScheme, rModelPart, A, Dx, b);
270  }
271 
278  void BuildRHS(
279  typename TSchemeType::Pointer pScheme,
280  ModelPart& rModelPart,
281  TSystemVectorType& b) override
282  {
283  KRATOS_TRY
284 
285  if(rModelPart.MasterSlaveConstraints().size() > 0)
286  BuildRHSWithConstraints(pScheme, rModelPart, b);
287  else
288  BaseType::BuildRHS(pScheme, rModelPart, b);
289 
290  KRATOS_CATCH("")
291 
292  }
293 
303  typename TSchemeType::Pointer pScheme,
304  ModelPart& rModelPart
305  ) override
306  {
307  if(rModelPart.MasterSlaveConstraints().size() > 0)
308  SetUpDofSetWithConstraints(pScheme, rModelPart);
309  else
310  BaseType::SetUpDofSet(pScheme, rModelPart);
311  }
312 
318  {
319  Parameters default_parameters = Parameters(R"(
320  {
321  "name" : "elimination_builder_and_solver_with_constraints",
322  "check_constraint_relation" : true,
323  "reset_relation_matrix_each_iteration" : true
324  })");
325 
326  // Getting base class default parameters
327  const Parameters base_default_parameters = BaseType::GetDefaultParameters();
328  default_parameters.RecursivelyAddMissingParameters(base_default_parameters);
329  return default_parameters;
330  }
331 
336  static std::string Name()
337  {
338  return "elimination_builder_and_solver_with_constraints";
339  }
340 
344 
348 
352 
354  std::string Info() const override
355  {
356  return "ResidualBasedEliminationBuilderAndSolverWithConstraints";
357  }
358 
360  void PrintInfo(std::ostream& rOStream) const override
361  {
362  rOStream << Info();
363  }
364 
366  void PrintData(std::ostream& rOStream) const override
367  {
368  rOStream << Info();
369  }
370 
374 
376 protected:
379 
383 
392 
395 
397  bool mCleared = true;
398 
402 
406 
415  TSystemMatrixType& rT,
416  const LocalSystemMatrixType& rTransformationMatrix,
417  const EquationIdVectorType& rSlaveEquationId,
418  const EquationIdVectorType& rMasterEquationId
419  )
420  {
421  const SizeType local_size_1 = rTransformationMatrix.size1();
422 
423  for (IndexType i_local = 0; i_local < local_size_1; ++i_local) {
424  IndexType i_global = rSlaveEquationId[i_local];
425 
426  if (i_global < BaseType::mEquationSystemSize) {
427  BaseType::AssembleRowContributionFreeDofs(rT, rTransformationMatrix, i_global, i_local, rMasterEquationId);
428  }
429  }
430  }
431 
439  typename TSchemeType::Pointer pScheme,
440  TSystemMatrixType& rA,
441  ModelPart& rModelPart
442  ) override
443  {
444  if(rModelPart.MasterSlaveConstraints().size() > 0)
445  ConstructMatrixStructureWithConstraints(pScheme, rA, rModelPart);
446  else
447  BaseType::ConstructMatrixStructure(pScheme, rA, rModelPart);
448  }
449 
459  typename TSchemeType::Pointer pScheme,
460  ModelPart& rModelPart,
461  TSystemMatrixType& rA,
462  TSystemVectorType& rDx,
464  )
465  {
466  KRATOS_TRY
467 
468  Timer::Start("Build");
469 
470  // We apply the master/slave relationship before build
471  ApplyMasterSlaveRelation(pScheme, rModelPart, rA, rDx, rb);
472 
473  // We compute the effective constant vector
475  TSparseSpace::SetToZero(dummy_Dx);
476  ComputeEffectiveConstant(pScheme, rModelPart, dummy_Dx);
477 
478  // We do the build (after that we resize the solution vector to avoid problems)
479  BuildWithConstraints(pScheme, rModelPart, rA, rb);
480 
481  Timer::Stop("Build");
482 
483  // Now we apply the BC
484  rDx.resize(mDoFToSolveSystemSize, false);
485  ApplyDirichletConditions(pScheme, rModelPart, rA, rDx, rb);
486 
487  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", (this->GetEchoLevel() == 3)) <<
488  "Before the solution of the system" << "\nSystem Matrix = " << rA << "\nUnknowns vector = " << rDx << "\nRHS vector = " << rb << std::endl;
489 
490  // We solve the system of equations
491  const auto timer = BuiltinTimer();
492  const double start_solve = timer.ElapsedSeconds();
493  Timer::Start("Solve");
494  SystemSolveWithPhysics(rA, rDx, rb, rModelPart);
495 
496  Timer::Stop("Solve");
497  const double stop_solve = timer.ElapsedSeconds();
498 
499  // We compute the effective constant vector
500  ComputeEffectiveConstant(pScheme, rModelPart, rDx);
501 
502  // We reconstruct the Unknowns vector and the residual
503  const double start_reconstruct_slaves = timer.ElapsedSeconds();
504  ReconstructSlaveSolutionAfterSolve(pScheme, rModelPart, rA, rDx, rb);
505 
506  const double stop_reconstruct_slaves = timer.ElapsedSeconds();
507  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", (this->GetEchoLevel() >= 1 && rModelPart.GetCommunicator().MyPID() == 0)) << "Reconstruct slaves time: " << stop_reconstruct_slaves - start_reconstruct_slaves << std::endl;
508 
509  // Some verbosity
510  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", (this->GetEchoLevel() >= 1 && rModelPart.GetCommunicator().MyPID() == 0)) << "System solve time: " << stop_solve - start_solve << std::endl;
511 
512  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", (this->GetEchoLevel() == 3)) <<
513  "After the solution of the system" << "\nSystem Matrix = " << rA << "\nUnknowns vector = " << rDx << "\nRHS vector = " << rb << std::endl;
514 
515  KRATOS_CATCH("")
516  }
517 
525  typename TSchemeType::Pointer pScheme,
526  ModelPart& rModelPart,
528  )
529  {
530  Timer::Start("Build RHS");
531 
532  // Resetting to zero the vector of reactions
534  TSparseSpace::SetToZero(*(BaseType::mpReactionsVector));
535  }
536 
537  // Builing without BC
538  BuildRHSNoDirichlet(pScheme,rModelPart,rb);
539 
540  Timer::Stop("Build RHS");
541 
542  ApplyDirichletConditionsRHS(pScheme, rModelPart, rb);
543 
544  // We get the global T matrix
545  const TSystemMatrixType& rTMatrix = *mpTMatrix;
546 
547  // Reconstruct the RHS
548  TSystemVectorType rb_copy = rb;
549  rb.resize(BaseType::mEquationSystemSize, false);
550  TSparseSpace::Mult(rTMatrix, rb_copy, rb);
551 
552  // Adding contribution to reactions
553  TSystemVectorType& r_reactions_vector = *BaseType::mpReactionsVector;
554 
556  for (auto& r_dof : BaseType::mDofSet) {
557  const bool is_master_fixed = mDoFMasterFixedSet.find(r_dof) == mDoFMasterFixedSet.end() ? false : true;
558  const bool is_slave = mDoFSlaveSet.find(r_dof) == mDoFSlaveSet.end() ? false : true;
559  if (is_master_fixed || is_slave) { // Fixed or MPC dof
560  const IndexType equation_id = r_dof.EquationId();
561  r_reactions_vector[mReactionEquationIdMap[equation_id]] += rb[equation_id];
562  }
563  }
564  }
565 
566  // Some verbosity
567  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", (this->GetEchoLevel() == 3)) <<
568  "After the solution of the system" << "\nRHS vector = " << rb << std::endl;
569  }
570 
578  typename TSchemeType::Pointer pScheme,
579  ModelPart& rModelPart
580  )
581  {
582  KRATOS_TRY;
583 
584  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", ( this->GetEchoLevel() > 1 && rModelPart.GetCommunicator().MyPID() == 0)) << "Setting up the dofs" << std::endl;
585 
586  DofsVectorType dof_list, second_dof_list; // NOTE: The second dof list is only used on constraints to include master/slave relations
587 
588  typedef std::unordered_set < DofPointerType, DofPointerHasher> set_type;
589 
590  // Declaring temporal variables
591  DofsArrayType dof_temp_all, dof_temp_solvable, dof_temp_slave;
592 
593  // We assign an empty dof array to our dof sets
596 
602  set_type dof_global_set, dof_global_slave_set;
603 
604  #pragma omp parallel firstprivate(dof_list, second_dof_list)
605  {
606  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
607 
608  // We cleate the temporal set and we reserve some space on them
609  set_type dofs_tmp_set, dof_temp_slave_set;
610  dofs_tmp_set.reserve(20000);
611  dof_temp_slave_set.reserve(200);
612 
613  // Gets the array of elements from the modeler
614  ElementsArrayType& r_elements_array = rModelPart.Elements();
615  const int number_of_elements = static_cast<int>(r_elements_array.size());
616  #pragma omp for schedule(guided, 512) nowait
617  for (int i = 0; i < number_of_elements; ++i) {
618  auto it_elem = r_elements_array.begin() + i;
619 
620  // Gets list of Dof involved on every element
621  pScheme->GetDofList(*it_elem, dof_list, r_current_process_info);
622  dofs_tmp_set.insert(dof_list.begin(), dof_list.end());
623  }
624 
625  // Gets the array of conditions from the modeler
626  ConditionsArrayType& r_conditions_array = rModelPart.Conditions();
627  const int number_of_conditions = static_cast<int>(r_conditions_array.size());
628  #pragma omp for schedule(guided, 512) nowait
629  for (int i = 0; i < number_of_conditions; ++i) {
630  auto it_cond = r_conditions_array.begin() + i;
631 
632  // Gets list of Dof involved on every element
633  pScheme->GetDofList(*it_cond, dof_list, r_current_process_info);
634  dofs_tmp_set.insert(dof_list.begin(), dof_list.end());
635  }
636 
637  // Gets the array of constraints from the modeler
638  auto& r_constraints_array = rModelPart.MasterSlaveConstraints();
639  const int number_of_constraints = static_cast<int>(r_constraints_array.size());
640  #pragma omp for schedule(guided, 512) nowait
641  for (int i = 0; i < number_of_constraints; ++i) {
642  auto it_const = r_constraints_array.begin() + i;
643 
644  // Gets list of Dof involved on every element
645  it_const->GetDofList(dof_list, second_dof_list, r_current_process_info);
646  dofs_tmp_set.insert(dof_list.begin(), dof_list.end());
647  dofs_tmp_set.insert(second_dof_list.begin(), second_dof_list.end());
648  dof_temp_slave_set.insert(dof_list.begin(), dof_list.end());
649  }
650 
651  // We merge all the sets in one thread
652  #pragma omp critical
653  {
654  dof_global_set.insert(dofs_tmp_set.begin(), dofs_tmp_set.end());
655  dof_global_slave_set.insert(dof_temp_slave_set.begin(), dof_temp_slave_set.end());
656  }
657  }
658 
659  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", ( this->GetEchoLevel() > 2)) << "Initializing ordered array filling\n" << std::endl;
660 
662  dof_temp_all.reserve(dof_global_set.size());
663  for (auto p_dof : dof_global_set) {
664  dof_temp_all.push_back( p_dof );
665  }
666  dof_temp_all.Sort();
667  BaseType::mDofSet = dof_temp_all;
668 
669  dof_temp_slave.reserve(dof_global_slave_set.size());
670  for (auto p_dof : dof_global_slave_set) {
671  dof_temp_slave.push_back( p_dof );
672  }
673  dof_temp_slave.Sort();
674  mDoFSlaveSet = dof_temp_slave;
675 
676  // Throws an exception if there are no Degrees Of Freedom involved in the analysis
677  KRATOS_ERROR_IF(BaseType::mDofSet.size() == 0) << "No degrees of freedom!" << std::endl;
678  KRATOS_WARNING_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", mDoFSlaveSet.size() == 0) << "No slave degrees of freedom to solve!" << std::endl;
679 
680  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", ( this->GetEchoLevel() > 2)) << "Number of degrees of freedom:" << BaseType::mDofSet.size() << std::endl;
681 
683 
684  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", ( this->GetEchoLevel() > 2 && rModelPart.GetCommunicator().MyPID() == 0)) << "Finished setting up the dofs" << std::endl;
685 
686 #ifdef USE_LOCKS_IN_ASSEMBLY
687  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", ( this->GetEchoLevel() > 2)) << "Initializing lock array" << std::endl;
688 
689  if (BaseType::mLockArray.size() != 0) {
690  for (int i = 0; i < static_cast<int>(BaseType::mLockArray.size()); ++i) {
691  omp_destroy_lock(&BaseType::mLockArray[i]);
692  }
693  }
694  BaseType::mLockArray.resize(BaseType::mDofSet.size());
695 
696  for (int i = 0; i < static_cast<int>(BaseType::mLockArray.size()); ++i) {
697  omp_init_lock(&BaseType::mLockArray[i]);
698  }
699 
700  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", ( this->GetEchoLevel() > 2)) << "End of setup dof set\n" << std::endl;
701 #endif
702 
703  // If reactions are to be calculated, we check if all the dofs have reactions defined
704  // This is tobe done only in debug mode
705  #ifdef KRATOS_DEBUG
707  for(auto dof_iterator = BaseType::mDofSet.begin(); dof_iterator != BaseType::mDofSet.end(); ++dof_iterator) {
708  KRATOS_ERROR_IF_NOT(dof_iterator->HasReaction()) << "Reaction variable not set for the following : " << std::endl
709  << "Node : " << dof_iterator->Id() << std::endl
710  << "Dof : " << (*dof_iterator) << std::endl << "Not possible to calculate reactions." << std::endl;
711  }
712  }
713  #endif
714 
715  KRATOS_CATCH("");
716  }
717 
726  TSystemMatrixType& rA,
727  TSystemVectorType& rDx,
728  TSystemVectorType& rb,
729  ModelPart& rModelPart
730  )
731  {
732  KRATOS_TRY
733 
734  double norm_b = 0.0;
735  if (TSparseSpace::Size(rb) > 0)
736  norm_b = TSparseSpace::TwoNorm(rb);
737 
738  if (norm_b > 0.0) {
739  // Create the auxiliar dof set
740  DofsArrayType aux_dof_set;
741  aux_dof_set.reserve(mDoFToSolveSystemSize);
742  for (auto& r_dof : BaseType::mDofSet) {
743  if (r_dof.EquationId() < BaseType::mEquationSystemSize) {
744  auto it = mDoFSlaveSet.find(r_dof);
745  if (it == mDoFSlaveSet.end())
746  aux_dof_set.push_back( &r_dof );
747  }
748  }
749  aux_dof_set.Sort();
750 
751  KRATOS_ERROR_IF_NOT(aux_dof_set.size() == mDoFToSolveSystemSize) << "Inconsistency (I) in system size: " << mDoFToSolveSystemSize << " vs " << aux_dof_set.size() << "\n Size dof set " << BaseType::mDofSet.size() << " vs Size slave dof set " << mDoFSlaveSet.size() << std::endl;
752  KRATOS_ERROR_IF_NOT(aux_dof_set.size() == rA.size1()) << "Inconsistency (II) in system size: " << rA.size1() << " vs " << aux_dof_set.size() << "\n Size dof set " << BaseType::mDofSet.size() << " vs Size slave dof set " << mDoFSlaveSet.size() << std::endl;
753 
754  // Provide physical data as needed
755  if(BaseType::mpLinearSystemSolver->AdditionalPhysicalDataIsNeeded())
756  BaseType::mpLinearSystemSolver->ProvideAdditionalData(rA, rDx, rb, aux_dof_set, rModelPart);
757 
758  // Do solve
759  BaseType::mpLinearSystemSolver->Solve(rA, rDx, rb);
760  } else {
761  TSparseSpace::SetToZero(rDx);
762  KRATOS_WARNING_IF("ResidualBasedEliminationBuilderAndSolver", rModelPart.GetCommunicator().MyPID() == 0) << "ATTENTION! setting the RHS to zero!" << std::endl;
763  }
764 
765  // Prints information about the current time
766  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolver", this->GetEchoLevel() > 1 && rModelPart.GetCommunicator().MyPID() == 0) << *(BaseType::mpLinearSystemSolver) << std::endl;
767 
768  KRATOS_CATCH("")
769 
770  }
771 
778  typename TSchemeType::Pointer pScheme,
779  TSystemMatrixType& rA,
780  ModelPart& rModelPart
781  )
782  {
783  // Filling with zero the matrix (creating the structure)
784  Timer::Start("MatrixStructure");
785 
786  // The total number of dof of the system
787  const SizeType equation_size = BaseType::mEquationSystemSize;
788 
789  // This vector contains the indexes sets for all rows
790  std::vector<IndexSetType> indices(equation_size);
791 
792  // We reserve some indexes on each row
793  block_for_each(indices, [](IndexSetType& rIndices){
794  rIndices.reserve(40);
795  });
796 
798  EquationIdVectorType ids(3, 0);
799  EquationIdVectorType second_ids(3, 0); // NOTE: Used only on the constraints to take into account the master dofs
800 
801  #pragma omp parallel firstprivate(ids, second_ids)
802  {
803  // The process info
804  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
805 
806  // We repeat the same declaration for each thead
807  std::vector<IndexSetType> temp_indexes(equation_size);
808 
809  #pragma omp for
810  for (int index = 0; index < static_cast<int>(equation_size); ++index)
811  temp_indexes[index].reserve(30);
812 
813  // Getting the size of the array of elements from the model
814  const int number_of_elements = static_cast<int>(rModelPart.Elements().size());
815 
816  // Element initial iterator
817  const auto el_begin = rModelPart.ElementsBegin();
818 
819  // We iterate over the elements
820  #pragma omp for schedule(guided, 512) nowait
821  for (int i_elem = 0; i_elem<number_of_elements; ++i_elem) {
822  auto it_elem = el_begin + i_elem;
823  pScheme->EquationId(*it_elem, ids, r_current_process_info);
824 
825  for (auto& id_i : ids) {
826  if (id_i < BaseType::mEquationSystemSize) {
827  auto& row_indices = temp_indexes[id_i];
828  for (auto& id_j : ids) {
829  if (id_j < BaseType::mEquationSystemSize) {
830  row_indices.insert(id_j);
831  }
832  }
833  }
834  }
835  }
836 
837  // Getting the size of the array of the conditions
838  const int number_of_conditions = static_cast<int>(rModelPart.Conditions().size());
839 
840  // Condition initial iterator
841  const auto cond_begin = rModelPart.ConditionsBegin();
842 
843  // We iterate over the conditions
844  #pragma omp for schedule(guided, 512) nowait
845  for (int i_cond = 0; i_cond<number_of_conditions; ++i_cond) {
846  auto it_cond = cond_begin + i_cond;
847  pScheme->EquationId(*it_cond, ids, r_current_process_info);
848  for (auto& id_i : ids) {
849  if (id_i < BaseType::mEquationSystemSize) {
850  auto& row_indices = temp_indexes[id_i];
851  for (auto& id_j : ids) {
852  if (id_j < BaseType::mEquationSystemSize) {
853  row_indices.insert(id_j);
854  }
855  }
856  }
857  }
858  }
859 
860  // Getting the size of the array of the constraints
861  const int number_of_constraints = static_cast<int>(rModelPart.MasterSlaveConstraints().size());
862 
863  // Constraint initial iterator
864  const auto const_begin = rModelPart.MasterSlaveConstraints().begin();
865 
866  // We iterate over the constraints
867  #pragma omp for schedule(guided, 512) nowait
868  for (int i_const = 0; i_const < number_of_constraints; ++i_const) {
869  auto it_const = const_begin + i_const;
870 
871  // If the constraint is active
872  if(it_const->IsActive()) {
873  it_const->EquationIdVector(ids, second_ids, r_current_process_info);
874  // Slave DoFs
875  for (auto& id_i : ids) {
876  if (id_i < BaseType::mEquationSystemSize) {
877  auto& row_indices = temp_indexes[id_i];
878  for (auto& id_j : ids) {
879  if (id_j < BaseType::mEquationSystemSize) {
880  row_indices.insert(id_j);
881  }
882  }
883  }
884  }
885  // Master DoFs
886  for (auto& id_i : second_ids) {
887  if (id_i < BaseType::mEquationSystemSize) {
888  auto& row_indices = temp_indexes[id_i];
889  for (auto& id_j : second_ids) {
890  if (id_j < BaseType::mEquationSystemSize) {
891  row_indices.insert(id_j);
892  }
893  }
894  }
895  }
896  }
897  }
898 
899  // Merging all the temporal indexes
900  #pragma omp critical
901  {
902  for (int i = 0; i < static_cast<int>(temp_indexes.size()); ++i) {
903  indices[i].insert(temp_indexes[i].begin(), temp_indexes[i].end());
904  }
905  }
906  }
907 
908  // Count the row sizes
909  SizeType nnz = 0;
910  for (IndexType i = 0; i < indices.size(); ++i)
911  nnz += indices[i].size();
912 
913  rA = CompressedMatrixType(indices.size(), indices.size(), nnz);
914 
915  double *Avalues = rA.value_data().begin();
916  IndexType *Arow_indices = rA.index1_data().begin();
917  IndexType *Acol_indices = rA.index2_data().begin();
918 
919  // Filling the index1 vector - DO NOT MAKE PARALLEL THE FOLLOWING LOOP!
920  Arow_indices[0] = 0;
921  for (int i = 0; i < static_cast<int>(rA.size1()); i++)
922  Arow_indices[i + 1] = Arow_indices[i] + indices[i].size();
923 
924  IndexPartition<std::size_t>(rA.size1()).for_each([&](std::size_t Index){
925  const IndexType row_begin = Arow_indices[Index];
926  const IndexType row_end = Arow_indices[Index + 1];
927  IndexType k = row_begin;
928  for (auto it = indices[Index].begin(); it != indices[Index].end(); ++it) {
929  Acol_indices[k] = *it;
930  Avalues[k] = 0.0;
931  k++;
932  }
933 
934  indices[Index].clear(); //deallocating the memory
935 
936  std::sort(&Acol_indices[row_begin], &Acol_indices[row_end]);
937  });
938 
939  rA.set_filled(indices.size() + 1, nnz);
940 
941  Timer::Stop("MatrixStructure");
942  }
943 
951  typename TSchemeType::Pointer pScheme,
952  TSystemMatrixType& rT,
953  ModelPart& rModelPart
954  )
955  {
956  // Filling with zero the matrix (creating the structure)
957  Timer::Start("RelationMatrixStructure");
958 
959  IndexMapType solvable_dof_reorder;
960  std::unordered_map<IndexType, IndexSetType> master_indices;
961 
962  // Filling with "ones"
963  typedef std::pair<IndexType, IndexType> IndexIndexPairType;
964  typedef std::pair<IndexType, IndexSetType> IndexIndexSetPairType;
965  IndexType counter = 0;
966  for (auto& dof : BaseType::mDofSet) {
967  if (dof.EquationId() < BaseType::mEquationSystemSize) {
968  const IndexType equation_id = dof.EquationId();
969  auto it = mDoFSlaveSet.find(dof);
970  if (it == mDoFSlaveSet.end()) {
971  solvable_dof_reorder.insert(IndexIndexPairType(equation_id, counter));
972  master_indices.insert(IndexIndexSetPairType(equation_id, IndexSetType({counter})));
973  ++counter;
974  } else {
975  master_indices.insert(IndexIndexSetPairType(equation_id, IndexSetType({})));
976  }
977  }
978  }
979 
980  // The process info
981  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
982 
984  EquationIdVectorType ids(3, 0);
985  EquationIdVectorType second_ids(3, 0); // NOTE: Used only on the constraints to take into account the master dofs
986 
987  const int number_of_constraints = static_cast<int>(rModelPart.MasterSlaveConstraints().size());
988  const auto it_const_begin = rModelPart.MasterSlaveConstraints().begin();
989  // TODO: OMP
990  for (int i_const = 0; i_const < number_of_constraints; ++i_const) {
991  auto it_const = it_const_begin + i_const;
992 
993  // If the constraint is active
994  if(it_const->IsActive()) {
995  it_const->EquationIdVector(ids, second_ids, r_current_process_info);
996  for (auto& slave_id : ids) {
997  if (slave_id < BaseType::mEquationSystemSize) {
998  auto it_slave = solvable_dof_reorder.find(slave_id);
999  if (it_slave == solvable_dof_reorder.end()) {
1000  for (auto& master_id : second_ids) {
1001  if (master_id < BaseType::mEquationSystemSize) {
1002  auto& master_row_indices = master_indices[slave_id];
1003  master_row_indices.insert(solvable_dof_reorder[master_id]);
1004  }
1005  }
1006  }
1007  }
1008  }
1009  }
1010  }
1011 
1012  KRATOS_DEBUG_ERROR_IF_NOT(BaseType::mEquationSystemSize == master_indices.size()) << "Inconsistency in the dofs size: " << BaseType::mEquationSystemSize << "\t vs \t" << master_indices.size() << std::endl;
1013 
1014  // Count the row sizes
1015  SizeType nnz = 0;
1016  for (IndexType i = 0; i < BaseType::mEquationSystemSize; ++i) {
1017  nnz += master_indices[i].size();
1018  }
1019 
1021 
1022  double *Tvalues = rT.value_data().begin();
1023  IndexType *Trow_indices = rT.index1_data().begin();
1024  IndexType *Tcol_indices = rT.index2_data().begin();
1025 
1026  // Filling the index1 vector - DO NOT MAKE PARALLEL THE FOLLOWING LOOP!
1027  Trow_indices[0] = 0;
1028  for (IndexType i = 0; i < BaseType::mEquationSystemSize; ++i)
1029  Trow_indices[i + 1] = Trow_indices[i] + master_indices[i].size();
1030 
1031  KRATOS_DEBUG_ERROR_IF_NOT(Trow_indices[BaseType::mEquationSystemSize] == nnz) << "Nonzero values does not coincide with the row index definition: " << Trow_indices[BaseType::mEquationSystemSize] << " vs " << nnz << std::endl;
1032 
1033  IndexPartition<std::size_t>(rT.size1()).for_each([&](std::size_t Index){
1034  const IndexType row_begin = Trow_indices[Index];
1035  const IndexType row_end = Trow_indices[Index + 1];
1036  IndexType k = row_begin;
1037  for (auto it = master_indices[Index].begin(); it != master_indices[Index].end(); ++it) {
1038  Tcol_indices[k] = *it;
1039  Tvalues[k] = 0.0;
1040  k++;
1041  }
1042 
1043  master_indices[Index].clear(); //deallocating the memory
1044 
1045  std::sort(&Tcol_indices[row_begin], &Tcol_indices[row_end]);
1046  });
1047  rT.set_filled(BaseType::mEquationSystemSize + 1, nnz);
1048 
1049  // Setting ones
1050  for (auto& solv_dof : solvable_dof_reorder) {
1051  rT(solv_dof.first, solv_dof.second) = 1.0;
1052  }
1053 
1054  Timer::Stop("RelationMatrixStructure");
1055  }
1056 
1067  typename TSchemeType::Pointer pScheme,
1068  ModelPart& rModelPart,
1069  TSystemMatrixType& rA,
1070  TSystemVectorType& rb,
1071  const bool UseBaseBuild = true
1072  )
1073  {
1074  KRATOS_TRY
1075 
1076  // We build the original system
1077  if (UseBaseBuild)
1078  BaseType::Build(pScheme, rModelPart, rA, rb);
1079  else
1080  BuildWithoutConstraints(pScheme, rModelPart, rA, rb);
1081 
1082  // Assemble the constraints
1083  const auto timer = BuiltinTimer();
1084 
1085  // We get the global T matrix
1086  const TSystemMatrixType& rTMatrix = *mpTMatrix;
1087 
1088  // We compute only once (or if cleared)
1089  if (mCleared) {
1090  mCleared = false;
1091  ComputeConstraintContribution(pScheme, rModelPart, true, mComputeConstantContribution);
1092  } else if (mResetRelationMatrixEachIteration) {
1093  ResetConstraintSystem();
1094  ComputeConstraintContribution(pScheme, rModelPart, mResetRelationMatrixEachIteration, mComputeConstantContribution);
1095  }
1096 
1097  // We compute the transposed matrix of the global relation matrix
1099  SparseMatrixMultiplicationUtility::TransposeMatrix<TSystemMatrixType, TSystemMatrixType>(T_transpose_matrix, rTMatrix, 1.0);
1100 
1101  // The proper way to include the constants is in the RHS as T^t(f - A * g)
1102  TSystemVectorType rb_copy = rb;
1104  // We get the g constant vector
1105  TSystemVectorType& rDeltaConstantVector = *mpDeltaConstantVector;
1106  TSystemVectorType aux_constant_vector(rDeltaConstantVector);
1107  TSparseSpace::Mult(rA, rDeltaConstantVector, aux_constant_vector);
1108  TSparseSpace::UnaliasedAdd(rb_copy, -1.0, aux_constant_vector);
1109  }
1110 
1111  // The auxiliar matrix to store the intermediate matrix multiplication
1113  SparseMatrixMultiplicationUtility::MatrixMultiplication(T_transpose_matrix, rA, auxiliar_A_matrix);
1114 
1115  // We do a backup of the matrix before apply the constraints
1116  if (mpOldAMatrix == NULL) { // If the pointer is not initialized initialize it to an empty matrix
1118  mpOldAMatrix.swap(pNewOldAMatrix);
1119  }
1120  (*mpOldAMatrix).swap(rA);
1121  // We resize of system of equations
1122  rA.resize(mDoFToSolveSystemSize, mDoFToSolveSystemSize, false);
1123  rb.resize(mDoFToSolveSystemSize, false);
1124 
1125  // Final multiplication
1126  SparseMatrixMultiplicationUtility::MatrixMultiplication(auxiliar_A_matrix, rTMatrix, rA);
1127  TSparseSpace::Mult(T_transpose_matrix, rb_copy, rb);
1128 
1129  // Cleaning up memory
1130  auxiliar_A_matrix.resize(0, 0, false);
1131  T_transpose_matrix.resize(0, 0, false);
1132 
1133  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", this->GetEchoLevel() >= 1) << "Constraint relation build time and multiplication: " << timer.ElapsedSeconds() << std::endl;
1134 
1135  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", this->GetEchoLevel() > 2) << "Finished parallel building with constraints" << std::endl;
1136 
1137  KRATOS_CATCH("")
1138  }
1139 
1148  typename TSchemeType::Pointer pScheme,
1149  ModelPart& rModelPart,
1150  TSystemVectorType& rb
1151  )
1152  {
1153  KRATOS_TRY
1154 
1155  // Assemble the constraints
1156  const auto timer = BuiltinTimer();
1157 
1158  // We get the global T matrix
1159  const TSystemMatrixType& rTMatrix = *mpTMatrix;
1160 
1161  // We compute only once (or if cleared)
1162  if (mCleared) {
1163  mCleared = false;
1164  ComputeConstraintContribution(pScheme, rModelPart, true, mComputeConstantContribution);
1165  } else if (mResetRelationMatrixEachIteration) {
1166  ResetConstraintSystem();
1167  ComputeConstraintContribution(pScheme, rModelPart, mResetRelationMatrixEachIteration, mComputeConstantContribution);
1168  }
1169 
1170  // We compute the transposed matrix of the global relation matrix
1172  SparseMatrixMultiplicationUtility::TransposeMatrix<TSystemMatrixType, TSystemMatrixType>(T_transpose_matrix, rTMatrix, 1.0);
1173 
1174  // We build the original system
1175  TSystemMatrixType A; // Dummy auxiliar matrix we ned to build anyway because are needed to impose the rigid displacements
1178  ConstructMatrixStructure(pScheme, A, rModelPart);
1179  BuildWithoutConstraints(pScheme, rModelPart, A, rb);
1180  } else {
1181  BuildRHSNoDirichletWithoutConstraints(pScheme, rModelPart, rb);
1182  }
1183 
1184  // The proper way to include the constants is in the RHS as T^t(f - A * g)
1185  TSystemVectorType rb_copy = rb;
1187  // We get the g constant vector
1188  TSystemVectorType& rDeltaConstantVector = *mpDeltaConstantVector;
1189  TSystemVectorType aux_constant_vector(rDeltaConstantVector);
1190  TSparseSpace::Mult(A, rDeltaConstantVector, aux_constant_vector);
1191  TSparseSpace::UnaliasedAdd(rb_copy, -1.0, aux_constant_vector);
1192  }
1193 
1194  rb.resize(mDoFToSolveSystemSize, false);
1195 
1196  // Final multiplication
1197  TSparseSpace::Mult(T_transpose_matrix, rb_copy, rb);
1198 
1199  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", this->GetEchoLevel() >= 1) << "Constraint relation build time and multiplication: " << timer.ElapsedSeconds() << std::endl;
1200 
1201  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", this->GetEchoLevel() > 2) << "Finished parallel building with constraints" << std::endl;
1202 
1203  KRATOS_CATCH("")
1204  }
1205 
1215  typename TSchemeType::Pointer pScheme,
1219  ModelPart& rModelPart
1220  ) override
1221  {
1222  // We resize the basic system
1223  BaseType::ResizeAndInitializeVectors(pScheme, pA, pDx, pb, rModelPart);
1224 
1225  // If needed resize the vector for the calculation of reactions
1227  const SizeType reactions_vector_size = BaseType::mDofSet.size() - mDoFToSolveSystemSize + mDoFMasterFixedSet.size();
1228  TSystemVectorType& rReactionsVector = *(BaseType::mpReactionsVector);
1229  if (rReactionsVector.size() != reactions_vector_size)
1230  rReactionsVector.resize(reactions_vector_size, false);
1231  }
1232 
1233  // Now we resize the relation matrix used on the MPC solution
1234  if(rModelPart.MasterSlaveConstraints().size() > 0) {
1235  if (mpTMatrix == NULL) { // If the pointer is not initialized initialize it to an empty matrix
1237  mpTMatrix.swap(pNewT);
1238  }
1239 
1240  // The rigid movement
1241  if (mpConstantVector == NULL) { // If the pointer is not initialized initialize it to an empty vector
1243  mpConstantVector.swap(pNewConstantVector);
1244  }
1245 
1246  // The effective rigid movement
1247  if (mpDeltaConstantVector == NULL) { // If the pointer is not initialized initialize it to an empty vector
1249  mpDeltaConstantVector.swap(pNewConstantVector);
1250  }
1251 
1252  // System matrices/vectors
1253  TSystemMatrixType& rTMatrix = *mpTMatrix;
1254  TSystemVectorType& rConstantVector = *mpConstantVector;
1255  TSystemVectorType& rDeltaConstantVector = *mpDeltaConstantVector;
1256 
1257  // Resizing the system matrix
1258  if (rTMatrix.size1() == 0 || BaseType::GetReshapeMatrixFlag() || mCleared) { // If the matrix is not initialized
1259  rTMatrix.resize(BaseType::mEquationSystemSize, mDoFToSolveSystemSize, false);
1260  ConstructRelationMatrixStructure(pScheme, rTMatrix, rModelPart);
1261  } else {
1262  if (rTMatrix.size1() != BaseType::mEquationSystemSize || rTMatrix.size2() != mDoFToSolveSystemSize) {
1263  KRATOS_ERROR <<"The equation system size has changed during the simulation. This is not permitted."<<std::endl;
1264  rTMatrix.resize(BaseType::mEquationSystemSize, mDoFToSolveSystemSize, false);
1265  ConstructRelationMatrixStructure(pScheme, rTMatrix, rModelPart);
1266  }
1267  }
1268 
1269  // Resizing the system vector
1270  // The rigid movement
1271  if (rConstantVector.size() != BaseType::mEquationSystemSize || BaseType::GetReshapeMatrixFlag() || mCleared) {
1272  rConstantVector.resize(BaseType::mEquationSystemSize, false);
1273  mComputeConstantContribution = ComputeConstraintContribution(pScheme, rModelPart);
1274  } else {
1275  if (rConstantVector.size() != BaseType::mEquationSystemSize) {
1276  KRATOS_ERROR <<"The equation system size has changed during the simulation. This is not permitted."<<std::endl;
1277  rConstantVector.resize(BaseType::mEquationSystemSize, false);
1278  mComputeConstantContribution = ComputeConstraintContribution(pScheme, rModelPart);
1279  }
1280  }
1281  // The effective rigid movement
1283  if (rDeltaConstantVector.size() != BaseType::mEquationSystemSize || BaseType::GetReshapeMatrixFlag() || mCleared) {
1284  rDeltaConstantVector.resize(BaseType::mEquationSystemSize, false);
1285  } else {
1286  if (rDeltaConstantVector.size() != BaseType::mEquationSystemSize) {
1287  KRATOS_ERROR <<"The equation system size has changed during the simulation. This is not permitted."<<std::endl;
1288  rDeltaConstantVector.resize(BaseType::mEquationSystemSize, false);
1289  }
1290  }
1291  }
1292  }
1293  }
1294 
1304  typename TSchemeType::Pointer pScheme,
1305  ModelPart& rModelPart,
1306  TSystemMatrixType& rA,
1307  TSystemVectorType& rDx,
1308  TSystemVectorType& rb
1309  ) override
1310  {
1311  KRATOS_TRY
1312 
1313  // Refresh RHS to have the correct reactions
1314  BuildRHS(pScheme, rModelPart, rb);
1315 
1316  // Adding contribution to reactions
1317  TSystemVectorType& r_reactions_vector = *BaseType::mpReactionsVector;
1318 
1319  // Updating variables
1320  for (auto& r_dof : BaseType::mDofSet) {
1321  if ((r_dof.IsFixed()) || mDoFSlaveSet.find(r_dof) != mDoFSlaveSet.end()) {
1322  r_dof.GetSolutionStepReactionValue() = -r_reactions_vector[mReactionEquationIdMap[r_dof.EquationId()]];
1323  }
1324  }
1325 
1326  KRATOS_CATCH("ResidualBasedEliminationBuilderAndSolverWithConstraints::CalculateReactions failed ..");
1327  }
1328 
1339  typename TSchemeType::Pointer pScheme,
1340  ModelPart& rModelPart,
1341  TSystemMatrixType& rA,
1342  TSystemVectorType& rDx,
1343  TSystemVectorType& rb
1344  ) override
1345  {
1346  KRATOS_TRY;
1347 
1348  if (mDoFMasterFixedSet.size() > 0) {
1349  // We apply the same method as in the block builder and solver but instead of fixing the fixed Dofs, we just fix the master fixed Dofs
1350  std::vector<double> scaling_factors (mDoFToSolveSystemSize, 0.0);
1351 
1352  // NOTE: Dofs are assumed to be numbered consecutively
1353  const auto it_dof_begin = BaseType::mDofSet.begin();
1354  IndexType counter = 0;
1355  for (IndexType i = 0; i < BaseType::mDofSet.size(); ++i) {
1356  auto it_dof = it_dof_begin + i;
1357  const IndexType equation_id = it_dof->EquationId();
1358  if (equation_id < BaseType::mEquationSystemSize ) {
1359  auto it_first_check = mDoFSlaveSet.find(*it_dof);
1360  if (it_first_check == mDoFSlaveSet.end()) {
1361  auto it_second_check = mDoFSlaveSet.find(*it_dof);
1362  if (it_second_check == mDoFSlaveSet.end()) {
1363  if(mDoFMasterFixedSet.find(*it_dof) == mDoFMasterFixedSet.end()) {
1364  scaling_factors[counter] = 1.0;
1365  }
1366  }
1367  counter += 1;
1368  }
1369  }
1370  }
1371 
1372  double* Avalues = rA.value_data().begin();
1373  IndexType* Arow_indices = rA.index1_data().begin();
1374  IndexType* Acol_indices = rA.index2_data().begin();
1375 
1376  // Define zero value tolerance
1377  const double zero_tolerance = std::numeric_limits<double>::epsilon();
1378 
1379  // Detect if there is a line of all zeros and set the diagonal to a 1 if this happens
1380  #pragma omp parallel for
1381  for(int k = 0; k < static_cast<int>(mDoFToSolveSystemSize); ++k) {
1382  const IndexType col_begin = Arow_indices[k];
1383  const IndexType col_end = Arow_indices[k+1];
1384  bool empty = true;
1385  for (IndexType j = col_begin; j < col_end; ++j) {
1386  if(std::abs(Avalues[j]) > zero_tolerance) {
1387  empty = false;
1388  break;
1389  }
1390  }
1391 
1392  if(empty) {
1393  rA(k,k) = 1.0;
1394  rb[k] = 0.0;
1395  }
1396  }
1397 
1399  const IndexType col_begin = Arow_indices[Index];
1400  const IndexType col_end = Arow_indices[Index+1];
1401  const double k_factor = scaling_factors[Index];
1402  if (k_factor == 0) {
1403  // Zero out the whole row, except the diagonal
1404  for (IndexType j = col_begin; j < col_end; ++j)
1405  if (Acol_indices[j] != Index )
1406  Avalues[j] = 0.0;
1407 
1408  // Zero out the RHS
1409  rb[Index] = 0.0;
1410  } else {
1411  // Zero out the column which is associated with the zero'ed row
1412  for (IndexType j = col_begin; j < col_end; ++j) {
1413  if(scaling_factors[ Acol_indices[j] ] == 0 ) {
1414  Avalues[j] = 0.0;
1415  }
1416  }
1417  }
1418  });
1419  }
1420 
1421  KRATOS_CATCH("");
1422  }
1423 
1427  void Clear() override
1428  {
1429  BaseType::Clear();
1430 
1431  // Resetting auxiliar set of dofs
1434 
1435  // Clearing the relation map
1436  mReactionEquationIdMap.clear();
1437 
1438  // Clear constraint system
1439  if (mpTMatrix != nullptr)
1440  TSparseSpace::Clear(mpTMatrix);
1441  if (mpConstantVector != nullptr)
1442  TSparseSpace::Clear(mpConstantVector);
1443  if (mpDeltaConstantVector != nullptr)
1444  TSparseSpace::Clear(mpDeltaConstantVector);
1445 
1446  // Set the flag
1447  mCleared = true;
1448 
1449  KRATOS_INFO_IF("ResidualBasedEliminationBuilderAndSolverWithConstraints", this->GetEchoLevel() > 1) << "Clear Function called" << std::endl;
1450  }
1451 
1456  void AssignSettings(const Parameters ThisParameters) override
1457  {
1458  BaseType::AssignSettings(ThisParameters);
1459  mCheckConstraintRelation = ThisParameters["check_constraint_relation"].GetBool();
1460  mResetRelationMatrixEachIteration = ThisParameters["reset_relation_matrix_each_iteration"].GetBool();
1461  }
1462 
1466 
1470 
1474 
1476 
1477 private:
1480 
1484 
1488 
1492 
1497  void SetUpSystemWithConstraints(ModelPart& rModelPart)
1498  {
1499  KRATOS_TRY
1500 
1501  // First we set up the system of equations without constraints
1502  // Set equation id for degrees of freedom the free degrees of freedom are positioned at the beginning of the system, while the fixed one are at the end (in opposite order).
1503  //
1504  // That means that if the EquationId is greater than "mEquationSystemSize" the pointed degree of freedom is restrained
1505  // This is almost the same SetUpSystem from ResidualBasedEliminationBuilderAndSolver, but we don't discard from the system the fixed dofs that are part of a constraint at the same time
1506 
1508 
1509  // The current process info
1510  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
1511 
1512  // Vector containing the localization in the system of the different terms
1513  DofsVectorType slave_dof_list, master_dof_list;
1514 
1515  // Declaring temporal variables
1516  DofsArrayType dof_temp_fixed_master;
1517 
1518  typedef std::unordered_set < DofPointerType, DofPointerHasher> set_type;
1519  set_type dof_global_fixed_master_set;
1520 
1521  // Iterate over constraints
1522  const int number_of_constraints = static_cast<int>(rModelPart.MasterSlaveConstraints().size());
1523  const auto it_const_begin = rModelPart.MasterSlaveConstraints().begin();
1524  #pragma omp parallel firstprivate(slave_dof_list, master_dof_list)
1525  {
1526  // We cleate the temporal set and we reserve some space on them
1527  set_type dof_temp_fixed_master_set;
1528  dof_temp_fixed_master_set.reserve(2000);
1529 
1530  #pragma omp for schedule(guided, 512) nowait
1531  for (int i_const = 0; i_const < number_of_constraints; ++i_const) {
1532  auto it_const = it_const_begin + i_const;
1533 
1534  // If the constraint is active
1535  if (it_const->IsActive()) {
1536  it_const->GetDofList(slave_dof_list, master_dof_list, r_current_process_info);
1537 
1538  // Filling the set of dofs master and fixed at the same time
1539  for (auto& master_dof : master_dof_list) {
1540  if (master_dof->IsFixed()) {
1541  dof_temp_fixed_master_set.insert(master_dof);
1542  }
1543  }
1544  }
1545  }
1546 
1547  // We merge all the sets in one thread
1548  #pragma omp critical
1549  {
1550  dof_global_fixed_master_set.insert(dof_temp_fixed_master_set.begin(), dof_temp_fixed_master_set.end());
1551  }
1552  }
1553 
1554  dof_temp_fixed_master.reserve(dof_global_fixed_master_set.size());
1555  for (auto p_dof : dof_global_fixed_master_set) {
1556  dof_temp_fixed_master.push_back( p_dof );
1557  }
1558  dof_temp_fixed_master.Sort();
1559  mDoFMasterFixedSet = dof_temp_fixed_master;
1560 
1562  int free_id = 0;
1563  int fix_id = BaseType::mDofSet.size();
1564 
1565  for (auto& dof : BaseType::mDofSet) {
1566  if (dof.IsFixed()) {
1567  auto it = mDoFMasterFixedSet.find(dof);
1568  if (it == mDoFMasterFixedSet.end()) {
1569  dof.SetEquationId(--fix_id);
1570  } else {
1571  dof.SetEquationId(free_id++);
1572  }
1573  } else {
1574  dof.SetEquationId(free_id++);
1575  }
1576  }
1577 
1579 
1580  // Add the computation of the global ids of the solvable dofs
1581  IndexType counter = 0;
1582  for (auto& dof : BaseType::mDofSet) {
1583  if (dof.EquationId() < BaseType::mEquationSystemSize) {
1584  auto it = mDoFSlaveSet.find(dof);
1585  if (it == mDoFSlaveSet.end()) {
1586  ++counter;
1587  }
1588  }
1589  }
1590 
1591  // The total system of equations to be solved
1593 
1594  // Finally we build the relation between the EquationID and the component of the reaction
1595  counter = 0;
1596  for (auto& r_dof : BaseType::mDofSet) {
1597  const bool is_master_fixed = mDoFMasterFixedSet.find(r_dof) == mDoFMasterFixedSet.end() ? false : true;
1598  const bool is_slave = mDoFSlaveSet.find(r_dof) == mDoFSlaveSet.end() ? false : true;
1599  if (is_master_fixed || is_slave) { // Fixed or MPC dof
1600  mReactionEquationIdMap.insert({r_dof.EquationId(), counter});
1601  ++counter;
1602  }
1603  }
1604 
1605  KRATOS_CATCH("ResidualBasedEliminationBuilderAndSolverWithConstraints::SetUpSystemWithConstraints failed ..");
1606  }
1607 
1616  void ApplyMasterSlaveRelation(
1617  typename TSchemeType::Pointer pScheme,
1618  ModelPart& rModelPart,
1619  TSystemMatrixType& rA,
1620  TSystemVectorType& rDx,
1621  TSystemVectorType& rb
1622  )
1623  {
1624  KRATOS_TRY
1625 
1626  // First we reset the slave dofs
1628 
1629  // Now we apply the constraints
1631 
1632  KRATOS_CATCH("");
1633  }
1634 
1642  bool CheckMasterSlaveRelation(
1643  typename TSchemeType::Pointer pScheme,
1644  ModelPart& rModelPart,
1645  TSystemVectorType& rDx,
1646  TSystemVectorType& rDxSolved
1647  )
1648  {
1649  KRATOS_TRY
1650 
1651  // Auxiliar values
1652  const auto it_dof_begin = BaseType::mDofSet.begin();
1653  TSystemVectorType current_solution(mDoFToSolveSystemSize);
1656 
1657  // Get current values
1658  IndexType counter = 0;
1659  for (IndexType i = 0; i < BaseType::mDofSet.size(); ++i) {
1660  auto it_dof = it_dof_begin + i;
1661  const IndexType equation_id = it_dof->EquationId();
1662  if (equation_id < BaseType::mEquationSystemSize ) {
1663  auto it = mDoFSlaveSet.find(*it_dof);
1664  if (it == mDoFSlaveSet.end()) {
1665  current_solution[counter] = it_dof->GetSolutionStepValue() + rDxSolved[counter];
1666  counter += 1;
1667  }
1668  }
1669  }
1670 
1671  block_for_each(BaseType::mDofSet, [&, this](Dof<double>& rDof){
1672  const IndexType equation_id = rDof.EquationId();
1673  if (equation_id < this->mEquationSystemSize ) {
1674  residual_solution[equation_id] = rDof.GetSolutionStepValue() + rDx[equation_id];
1675  }
1676  });
1677 
1678  // Apply master slave constraints
1679  const TSystemMatrixType& rTMatrix = *mpTMatrix;
1680  TSparseSpace::Mult(rTMatrix, current_solution, updated_solution);
1681 
1683  ComputeConstraintContribution(pScheme, rModelPart, false, true);
1684  const TSystemVectorType& rConstantVector = *mpConstantVector;
1685  TSparseSpace::UnaliasedAdd(updated_solution, 1.0, rConstantVector);
1686  }
1687 
1688  TSparseSpace::UnaliasedAdd(residual_solution, -1.0, updated_solution);
1689 
1690  // Check database
1691  for(int k = 0; k < static_cast<int>(BaseType::mEquationSystemSize); ++k) {
1692  if (std::abs(residual_solution[k]) > std::numeric_limits<double>::epsilon()) return false;
1693  }
1694 
1695  return true;
1696 
1697  KRATOS_CATCH("");
1698  }
1699 
1708  void ReconstructSlaveSolutionAfterSolve(
1709  typename TSchemeType::Pointer pScheme,
1710  ModelPart& rModelPart,
1711  TSystemMatrixType& rA,
1712  TSystemVectorType& rDx,
1713  TSystemVectorType& rb
1714  )
1715  {
1716  KRATOS_TRY
1717 
1718  // We get the global T matrix and the constant vector
1719  const TSystemMatrixType& rTMatrix = *mpTMatrix;
1720 
1721  // We reconstruct the complete vector of Unknowns
1722  TSystemVectorType Dx_copy = rDx;
1723  rDx.resize(BaseType::mEquationSystemSize);
1724  TSparseSpace::Mult(rTMatrix, Dx_copy, rDx);
1725 
1726  // Add the constant vector
1728  const TSystemVectorType& rDeltaConstantVector = *mpDeltaConstantVector;
1729  TSparseSpace::UnaliasedAdd(rDx, 1.0, rDeltaConstantVector);
1730  }
1731 
1732  // We check the solution
1734  KRATOS_ERROR_IF_NOT(CheckMasterSlaveRelation(pScheme, rModelPart, rDx, Dx_copy)) << "The relation between master/slave dofs is not respected" << std::endl;
1735  }
1736 
1737  // Simply restore old LHS
1738  (rA).swap(*mpOldAMatrix);
1739  mpOldAMatrix = NULL;
1740 
1741  // Reconstruct the RHS
1742  TSystemVectorType rb_copy = rb;
1743  rb.resize(BaseType::mEquationSystemSize, false);
1744  TSparseSpace::Mult(rTMatrix, rb_copy, rb);
1745 
1746  KRATOS_CATCH("ResidualBasedEliminationBuilderAndSolverWithConstraints::ReconstructSlaveSolutionAfterSolve failed ..");
1747  }
1748 
1756  void BuildWithoutConstraints(
1757  typename TSchemeType::Pointer pScheme,
1758  ModelPart& rModelPart,
1759  TSystemMatrixType& rA,
1760  TSystemVectorType& rb
1761  )
1762  {
1763  // The current process info
1764  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
1765 
1766  // Getting the array of elements
1767  ElementsArrayType& r_elements_array = rModelPart.Elements();
1768 
1769  // Getting the array of the conditions
1770  ConditionsArrayType& r_conditons_array = rModelPart.Conditions();
1771 
1772  // Contributions to the system
1773  LocalSystemMatrixType lhs_contribution = LocalSystemMatrixType(0, 0);
1774  LocalSystemVectorType rhs_contribution = LocalSystemVectorType(0);
1775 
1776  // Vector containing the localization in the system of the different terms
1777  Element::EquationIdVectorType equation_id;
1778 
1779  // Assemble all elements and conditions
1780  #pragma omp parallel firstprivate( lhs_contribution, rhs_contribution, equation_id)
1781  {
1782  // Elements
1783  const auto it_elem_begin = r_elements_array.begin();
1784  const int nelements = static_cast<int>(r_elements_array.size());
1785  #pragma omp for schedule(guided, 512) nowait
1786  for (int i = 0; i<nelements; ++i) {
1787  auto it_elem = it_elem_begin + i;
1788  // If the element is active
1789  if (it_elem->IsActive()) {
1790  // Calculate elemental contribution
1791  pScheme->CalculateSystemContributions(*it_elem, lhs_contribution, rhs_contribution, equation_id, r_current_process_info);
1792 
1793  // Assemble the elemental contribution
1794  AssembleWithoutConstraints(rA, rb, lhs_contribution, rhs_contribution, equation_id);
1795  }
1796  }
1797 
1798  // Conditions
1799  const auto it_cond_begin = r_conditons_array.begin();
1800  const int nconditions = static_cast<int>(r_conditons_array.size());
1801  #pragma omp for schedule(guided, 512)
1802  for (int i = 0; i<nconditions; ++i) {
1803  auto it_cond = it_cond_begin + i;
1804  // If the condition is active
1805  if (it_cond->IsActive()) {
1806  // Calculate elemental contribution
1807  pScheme->CalculateSystemContributions(*it_cond, lhs_contribution, rhs_contribution, equation_id, r_current_process_info);
1808 
1809  // Assemble the elemental contribution
1810  AssembleWithoutConstraints(rA, rb, lhs_contribution, rhs_contribution, equation_id);
1811  }
1812  }
1813  }
1814  }
1815 
1823  void BuildRHSNoDirichletWithoutConstraints(
1824  typename TSchemeType::Pointer pScheme,
1825  ModelPart& rModelPart,
1826  TSystemVectorType& rb
1827  )
1828  {
1829  // The current process info
1830  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
1831 
1832  // Getting the array of elements
1833  ElementsArrayType& r_elements_array = rModelPart.Elements();
1834 
1835  // Getting the array of the conditions
1836  ConditionsArrayType& r_conditons_array = rModelPart.Conditions();
1837 
1838  // Contributions to the system
1839  LocalSystemVectorType rhs_contribution = LocalSystemVectorType(0);
1840 
1841  // Vector containing the localization in the system of the different terms
1842  Element::EquationIdVectorType equation_id;
1843 
1844  // Assemble all elements and conditions
1845  #pragma omp parallel firstprivate( rhs_contribution, equation_id)
1846  {
1847  // Elements
1848  const auto it_elem_begin = r_elements_array.begin();
1849  const int nelements = static_cast<int>(r_elements_array.size());
1850  #pragma omp for schedule(guided, 512) nowait
1851  for (int i = 0; i<nelements; ++i) {
1852  auto it_elem = it_elem_begin + i;
1853  // If the element is active
1854  if (it_elem->IsActive()) {
1855  // Calculate elemental Right Hand Side Contribution
1856  pScheme->CalculateRHSContribution(*it_elem, rhs_contribution, equation_id, r_current_process_info);
1857 
1858  // Assemble the elemental contribution
1859  AssembleRHSWithoutConstraints(rb, rhs_contribution, equation_id);
1860  }
1861  }
1862 
1863  // Conditions
1864  const auto it_cond_begin = r_conditons_array.begin();
1865  const int nconditions = static_cast<int>(r_conditons_array.size());
1866  #pragma omp for schedule(guided, 512)
1867  for (int i = 0; i<nconditions; ++i) {
1868  auto it_cond = it_cond_begin + i;
1869  // If the condition is active
1870  if (it_cond->IsActive()) {
1871  // Calculate elemental contribution
1872  pScheme->CalculateRHSContribution(*it_cond, rhs_contribution, equation_id, r_current_process_info);
1873 
1874  // Assemble the elemental contribution
1875  AssembleRHSWithoutConstraints(rb, rhs_contribution, equation_id);
1876  }
1877  }
1878  }
1879  }
1880 
1885  void AssembleWithoutConstraints(
1886  TSystemMatrixType& rA,
1887  TSystemVectorType& rb,
1888  const LocalSystemMatrixType& rLHSContribution,
1889  const LocalSystemVectorType& rRHSContribution,
1890  const Element::EquationIdVectorType& rEquationId
1891  )
1892  {
1893  const SizeType local_size = rLHSContribution.size1();
1894 
1895  // Assemble RHS
1896  AssembleRHSWithoutConstraints(rb, rRHSContribution, rEquationId);
1897 
1898  // Assemble LHS
1899  for (IndexType i_local = 0; i_local < local_size; ++i_local) {
1900  const IndexType i_global = rEquationId[i_local];
1901 
1902  if (i_global < BaseType::mEquationSystemSize) {
1903  BaseType::AssembleRowContributionFreeDofs(rA, rLHSContribution, i_global, i_local, rEquationId);
1904  }
1905  }
1906  }
1907 
1908 
1913  void AssembleRHSWithoutConstraints(
1914  TSystemVectorType& rb,
1915  const LocalSystemVectorType& rRHSContribution,
1916  const Element::EquationIdVectorType& rEquationId
1917  )
1918  {
1919  const SizeType local_size = rRHSContribution.size();
1920 
1922  for (IndexType i_local = 0; i_local < local_size; ++i_local) {
1923  const IndexType i_global = rEquationId[i_local];
1924 
1925  if (i_global < BaseType::mEquationSystemSize) { // free dof
1926  // ASSEMBLING THE SYSTEM VECTOR
1927  double& r_b_value = rb[i_global];
1928  const double rhs_value = rRHSContribution[i_local];
1929 
1930  AtomicAdd(r_b_value, rhs_value);
1931  }
1932  }
1933  } else {
1934  TSystemVectorType& r_reactions_vector = *BaseType::mpReactionsVector;
1935  for (IndexType i_local = 0; i_local < local_size; ++i_local) {
1936  const IndexType i_global = rEquationId[i_local];
1937  auto it_dof = BaseType::mDofSet.begin() + i_global;
1938 
1939  const bool is_master_fixed = mDoFMasterFixedSet.find(*it_dof) == mDoFMasterFixedSet.end() ? false : true;
1940  const bool is_slave = mDoFSlaveSet.find(*it_dof) == mDoFSlaveSet.end() ? false : true;
1941  if (is_master_fixed || is_slave) { // Fixed or MPC dof
1942  double& r_b_value = r_reactions_vector[mReactionEquationIdMap[i_global]];
1943  const double rhs_value = rRHSContribution[i_local];
1944 
1945  AtomicAdd(r_b_value, rhs_value);
1946  } else if (it_dof->IsFree()) { // Free dof not in the MPC
1947  // ASSEMBLING THE SYSTEM VECTOR
1948  double& r_b_value = rb[i_global];
1949  const double& rhs_value = rRHSContribution[i_local];
1950 
1951  AtomicAdd(r_b_value, rhs_value);
1952  }
1953  }
1954  }
1955  }
1956 
1960  void ResetConstraintSystem()
1961  {
1962  TSystemMatrixType& rTMatrix = *mpTMatrix;
1963  double *Tvalues = rTMatrix.value_data().begin();
1964 
1965  IndexPartition<std::size_t>(rTMatrix.nnz()).for_each([&Tvalues](std::size_t Index){
1966  Tvalues[Index] = 0.0;
1967  });
1968 
1969  IndexMapType solvable_dof_reorder;
1970 
1971  // Filling with "ones"
1972  typedef std::pair<IndexType, IndexType> IndexIndexPairType;
1973  IndexType counter = 0;
1974  for (auto& dof : BaseType::mDofSet) {
1975  if (dof.EquationId() < BaseType::mEquationSystemSize) {
1976  const IndexType equation_id = dof.EquationId();
1977  auto it = mDoFSlaveSet.find(dof);
1978  if (it == mDoFSlaveSet.end()) {
1979  solvable_dof_reorder.insert(IndexIndexPairType(equation_id, counter));
1980  ++counter;
1981  }
1982  }
1983  }
1984 
1985  // Setting ones
1986  for (auto& solv_dof : solvable_dof_reorder) {
1987  rTMatrix(solv_dof.first, solv_dof.second) = 1.0;
1988  }
1989 
1991  TSystemVectorType& rConstantVector = *mpConstantVector;
1992  TSparseSpace::SetToZero(rConstantVector);
1993  }
1994  }
1995 
2002  void ApplyDirichletConditionsRHS(
2003  typename TSchemeType::Pointer pScheme,
2004  ModelPart& rModelPart,
2005  TSystemVectorType& rb
2006  )
2007  {
2008  KRATOS_TRY;
2009 
2010  if (mDoFMasterFixedSet.size() > 0) {
2011  // NOTE: dofs are assumed to be numbered consecutively
2012  const auto it_dof_begin = BaseType::mDofSet.begin();
2013 
2014  IndexPartition<std::size_t>(mDoFToSolveSystemSize).for_each([&, this](std::size_t Index){
2015  auto it_dof = it_dof_begin + Index;
2016  if (Index < this->mEquationSystemSize) {
2017  auto it = mDoFSlaveSet.find(*it_dof);
2018  if (it == mDoFSlaveSet.end()) {
2019  if(mDoFMasterFixedSet.find(*it_dof) != mDoFMasterFixedSet.end()) {
2020  rb[Index] = 0.0;
2021  }
2022  }
2023  }
2024  });
2025  }
2026 
2027  KRATOS_CATCH("");
2028  }
2029 
2038  bool ComputeConstraintContribution(
2039  typename TSchemeType::Pointer pScheme,
2040  ModelPart& rModelPart,
2041  const bool ComputeTranslationMatrix = false,
2042  const bool ComputeConstantVector = false
2043  )
2044  {
2045  KRATOS_TRY;
2046 
2047  // We build the global T matrix and the g constant vector
2048  TSystemMatrixType& rTMatrix = *mpTMatrix;
2049  TSystemVectorType& rConstantVector = *mpConstantVector;
2050 
2051  // Filling constant vector
2052  if (ComputeConstantVector) {
2053  IndexPartition<std::size_t>(this->mEquationSystemSize).for_each([&rConstantVector](std::size_t Index){
2054  rConstantVector[Index] = 0.0;
2055  });
2056  }
2057 
2058  // Auxiliar set to reorder master DoFs
2059  IndexMapType solvable_dof_reorder;
2060 
2061  // Filling with "ones"
2062  typedef std::pair<IndexType, IndexType> IndexIndexPairType;
2063  IndexType counter = 0;
2064  for (auto& dof : BaseType::mDofSet) {
2065  if (dof.EquationId() < BaseType::mEquationSystemSize) {
2066  const IndexType equation_id = dof.EquationId();
2067  auto it = mDoFSlaveSet.find(dof);
2068  if (it == mDoFSlaveSet.end()) {
2069  solvable_dof_reorder.insert(IndexIndexPairType(equation_id, counter));
2070  ++counter;
2071  }
2072  }
2073  }
2074 
2075  // The current process info
2076  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
2077 
2078  // Initialize the constant vector
2079  double aux_constant_value = 0.0;
2080 
2081  // Contributions to the system
2082  LocalSystemMatrixType transformation_matrix = LocalSystemMatrixType(0, 0);
2083  LocalSystemVectorType constant_vector = LocalSystemVectorType(0);
2084 
2085  // Vector containing the localization in the system of the different terms
2086  EquationIdVectorType slave_equation_id, master_equation_id;
2087 
2088  const int number_of_constraints = static_cast<int>(rModelPart.MasterSlaveConstraints().size());
2089 
2090  std::unordered_set<IndexType> auxiliar_constant_equations_ids;
2091 
2092  #pragma omp parallel firstprivate(transformation_matrix, constant_vector, slave_equation_id, master_equation_id)
2093  {
2094  std::unordered_set<IndexType> auxiliar_temp_constant_equations_ids;
2095  auxiliar_temp_constant_equations_ids.reserve(2000);
2096 
2097  #pragma omp for schedule(guided, 512)
2098  for (int i_const = 0; i_const < number_of_constraints; ++i_const) {
2099  auto it_const = rModelPart.MasterSlaveConstraints().begin() + i_const;
2100 
2101  // If the constraint is active
2102  if (it_const->IsActive()) {
2103  it_const->CalculateLocalSystem(transformation_matrix, constant_vector, r_current_process_info);
2104  it_const->EquationIdVector(slave_equation_id, master_equation_id, r_current_process_info);
2105 
2106  // Reassign reordered dofs to the master side
2107  for (auto& id : master_equation_id) {
2108  id = solvable_dof_reorder[id];
2109  }
2110 
2111  if (ComputeConstantVector) {
2112  for (IndexType i = 0; i < slave_equation_id.size(); ++i) {
2113  const IndexType i_global = slave_equation_id[i];
2114  if (i_global < BaseType::mEquationSystemSize) {
2115  const double constant_value = constant_vector[i];
2116  if (std::abs(constant_value) > 0.0) {
2117  auxiliar_temp_constant_equations_ids.insert(i_global);
2118  double& r_value = rConstantVector[i_global];
2119  AtomicAdd(r_value, constant_value);
2120  }
2121  }
2122  }
2123  } else {
2124  for (IndexType i = 0; i < slave_equation_id.size(); ++i) {
2125  const IndexType i_global = slave_equation_id[i];
2126  if (i_global < BaseType::mEquationSystemSize) {
2127  const double constant_value = constant_vector[i];
2128  AtomicAdd(aux_constant_value, std::abs(constant_value));
2129  }
2130  }
2131  }
2132 
2133  if (ComputeTranslationMatrix) {
2134  // Assemble the constraint contribution
2135  AssembleRelationMatrix(rTMatrix, transformation_matrix, slave_equation_id, master_equation_id);
2136  }
2137  }
2138  }
2139 
2140  // We merge all the sets in one thread
2141  #pragma omp critical
2142  {
2143  auxiliar_constant_equations_ids.insert(auxiliar_temp_constant_equations_ids.begin(), auxiliar_temp_constant_equations_ids.end());
2144  }
2145  }
2146 
2147  return aux_constant_value > std::numeric_limits<double>::epsilon() ? true : false;
2148 
2149  KRATOS_CATCH("");
2150  }
2151 
2158  void ComputeEffectiveConstant(
2159  typename TSchemeType::Pointer pScheme,
2160  ModelPart& rModelPart,
2161  TSystemVectorType& rDxSolved
2162  )
2163  {
2164  if (mComputeConstantContribution) {
2165  // We get
2166  const TSystemMatrixType& rTMatrix = *mpTMatrix;
2167  TSystemVectorType& rConstantVector = *mpConstantVector;
2168  TSystemVectorType& rDeltaConstantVector = *mpDeltaConstantVector;
2169  TSparseSpace::Copy(rConstantVector, rDeltaConstantVector);
2170 
2171  // We reconstruct the complete vector of Unknowns
2172  TSystemVectorType Dx(BaseType::mEquationSystemSize);
2173  TSparseSpace::Mult(rTMatrix, rDxSolved, Dx);
2174 
2175  // Compute the effective constant vector
2176  // Auxiliar initial dof iterator
2177  const auto it_dof_begin = BaseType::mDofSet.begin();
2178 
2179  TSystemVectorType u(BaseType::mEquationSystemSize);
2180 
2181  block_for_each(BaseType::mDofSet, [&, this](Dof<double>& rDof){
2182  const IndexType equation_id = rDof.EquationId();
2183  if (equation_id < this->mEquationSystemSize ) {
2184  u[equation_id] = rDof.GetSolutionStepValue() + Dx[equation_id];
2185  }
2186  });
2187 
2188  TSystemVectorType u_bar(mDoFToSolveSystemSize);
2189  IndexType counter = 0;
2190  for (IndexType i = 0; i < BaseType::mDofSet.size(); ++i) {
2191  auto it_dof = it_dof_begin + i;
2192  const IndexType equation_id = it_dof->EquationId();
2193  if (equation_id < BaseType::mEquationSystemSize ) {
2194 
2195  auto it = mDoFSlaveSet.find(*it_dof);
2196  if (it == mDoFSlaveSet.end()) {
2197  u_bar[counter] = it_dof->GetSolutionStepValue() + rDxSolved[counter];
2198  counter += 1;
2199  }
2200  }
2201  }
2202  TSystemVectorType u_bar_complete(BaseType::mEquationSystemSize);
2203  TSparseSpace::Mult(rTMatrix, u_bar, u_bar_complete);
2204 
2205  TSparseSpace::UnaliasedAdd(rDeltaConstantVector, 1.0, u_bar_complete);
2206  TSparseSpace::UnaliasedAdd(rDeltaConstantVector, -1.0, u);
2207  }
2208  }
2209 
2216 
2220 
2222 
2223 }; /* Class ResidualBasedEliminationBuilderAndSolverWithConstraints */
2224 
2226 
2229 
2231 
2232 } /* namespace Kratos.*/
2233 
2234 #endif /* KRATOS_RESIDUAL_BASED_BLOCK_BUILDER_AND_SOLVER defined */
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
bool mDofSetIsInitialized
If the matrix is reshaped each step.
Definition: builder_and_solver.h:743
TSparseSpace::VectorType TSystemVectorType
Definition of the vector size.
Definition: builder_and_solver.h:85
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
TSystemVectorPointerType mpReactionsVector
Definition: builder_and_solver.h:751
virtual Parameters ValidateAndAssignParameters(Parameters ThisParameters, const Parameters DefaultParameters) const
This method validate and assign default parameters.
Definition: builder_and_solver.h:767
bool GetReshapeMatrixFlag() const
This method returns the flag mReshapeMatrixFlag.
Definition: builder_and_solver.h:220
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
TSparseSpace::DataType TDataType
Definition of the data type.
Definition: builder_and_solver.h:79
TLinearSolver::Pointer mpLinearSystemSolver
Definition: builder_and_solver.h:737
DofsArrayType mDofSet
Pointer to the linear solver.
Definition: builder_and_solver.h:739
TDenseSpace::VectorType LocalSystemVectorType
The local vector definition.
Definition: builder_and_solver.h:97
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
bool mCalculateReactionsFlag
Flag taking care if the dof set was initialized ot not.
Definition: builder_and_solver.h:745
int GetEchoLevel() const
It returns the echo level.
Definition: builder_and_solver.h:674
unsigned int mEquationSystemSize
Flag taking in account if it is needed or not to calculate the reactions.
Definition: builder_and_solver.h:747
Definition: builtin_timer.h:26
virtual int MyPID() const
Definition: communicator.cpp:91
Dof represents a degree of freedom (DoF).
Definition: dof.h:86
std::vector< DofType::Pointer > DofsVectorType
Definition: element.h:100
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
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
ElementIterator ElementsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1169
MasterSlaveConstraintContainerType & MasterSlaveConstraints(IndexType ThisIndex=0)
Definition: model_part.h:654
ConditionIterator ConditionsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1361
Communicator & GetCommunicator()
Definition: model_part.h:1821
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
void RecursivelyAddMissingParameters(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing contain at least all parameters...
Definition: kratos_parameters.cpp:1457
bool GetBool() const
This method returns the boolean contained in the current Parameter.
Definition: kratos_parameters.cpp:675
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 Sort()
Sort the elements in the set.
Definition: pointer_vector_set.h:753
void push_back(TPointerType x)
Adds a pointer to the end of the set.
Definition: pointer_vector_set.h:544
iterator begin()
Returns an iterator pointing to the beginning of the container.
Definition: pointer_vector_set.h:278
iterator find(const key_type &Key)
Find an element with the specified key.
Definition: pointer_vector_set.h:678
void reserve(int reservedsize)
Reserves memory for a specified number of elements.
Definition: pointer_vector_set.h:733
iterator end()
Returns an iterator pointing to the end of the container.
Definition: pointer_vector_set.h:314
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Current class provides an implementation for standard elimination builder and solving operations.
Definition: residualbased_elimination_builder_and_solver.h:76
Element::DofsVectorType DofsVectorType
Definition: residualbased_elimination_builder_and_solver.h:105
void BuildRHS(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemVectorType &rb) override
Function to perform the build of the RHS.
Definition: residualbased_elimination_builder_and_solver.h:572
void AssembleRowContributionFreeDofs(TSystemMatrixType &rA, const Matrix &rALocal, const IndexType i, const IndexType i_local, const Element::EquationIdVectorType &EquationId)
This function is equivalent to the AssembleRowContribution of the block builder and solver.
Definition: residualbased_elimination_builder_and_solver.h:1227
void BuildAndSolve(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb) override
Function to perform the building and solving phase at the same time.
Definition: residualbased_elimination_builder_and_solver.h:507
Element::EquationIdVectorType EquationIdVectorType
Definition of the equation id vector.
Definition: residualbased_elimination_builder_and_solver.h:104
void Build(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rb) override
Function to perform the build of the RHS. The vector could be sized as the total number of dofs or as...
Definition: residualbased_elimination_builder_and_solver.h:184
void ResizeAndInitializeVectors(typename TSchemeType::Pointer pScheme, TSystemMatrixPointerType &pA, TSystemVectorPointerType &pDx, TSystemVectorPointerType &pb, ModelPart &rModelPart) override
This method resize and initializes the system of euqations.
Definition: residualbased_elimination_builder_and_solver.h:788
Parameters GetDefaultParameters() const override
This method provides the defaults parameters to avoid conflicts between the different constructors.
Definition: residualbased_elimination_builder_and_solver.h:942
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: residualbased_elimination_builder_and_solver.h:646
void Clear() override
This function is intended to be called at the end of the solution step to clean up memory storage not...
Definition: residualbased_elimination_builder_and_solver.h:912
Node NodeType
Node definition.
Definition: residualbased_elimination_builder_and_solver.h:108
void AssignSettings(const Parameters ThisParameters) override
This method assigns settings to member variables.
Definition: residualbased_elimination_builder_and_solver.h:1314
virtual void ConstructMatrixStructure(typename TSchemeType::Pointer pScheme, TSystemMatrixType &rA, ModelPart &rModelPart)
This method constructs the relationship between the DoF.
Definition: residualbased_elimination_builder_and_solver.h:1078
void SetUpSystem(ModelPart &rModelPart) override
Organises the dofset in order to speed up the building phase.
Definition: residualbased_elimination_builder_and_solver.h:759
Current class provides an implementation for standard builder and solving operations.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:93
void BuildRHS(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemVectorType &b) override
Function to perform the build of the RHS.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:278
ResidualBasedEliminationBuilderAndSolverWithConstraints(typename TLinearSolver::Pointer pNewLinearSystemSolver, Parameters ThisParameters)
Default constructor. (with parameters)
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:169
void Build(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rb) override
Function to perform the build of the RHS. The vector could be sized as the total number of dofs or as...
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:236
PointerVectorSet< Element, IndexedObject > ElementsContainerType
Additional definitions.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:130
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: residualbased_elimination_builder_and_solver_with_constraints.h:259
MasterSlaveConstraint::Pointer MasterSlaveConstraintPointerType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:147
boost::numeric::ublas::compressed_matrix< double > CompressedMatrixType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:133
Vector VectorType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:149
Element::EquationIdVectorType EquationIdVectorType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:131
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: residualbased_elimination_builder_and_solver_with_constraints.h:302
bool mComputeConstantContribution
If we reset the relation matrix at each iteration.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:396
void BuildWithConstraints(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rb, const bool UseBaseBuild=true)
This function is exactly same as the Build() function in base class except that the function.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:1066
void ConstructMatrixStructure(typename TSchemeType::Pointer pScheme, TSystemMatrixType &rA, ModelPart &rModelPart) override
This method constructs the relationship between the DoF.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:438
BaseType::TSystemMatrixPointerType TSystemMatrixPointerType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:122
std::unordered_set< IndexType > IndexSetType
Set definition.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:140
bool mCheckConstraintRelation
In order to know the corresponding EquaionId for each component of the reaction vector.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:393
void BuildRHSNoDirichlet(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemVectorType &rb)
Function to perform the build of the RHS.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:1147
DofType::Pointer DofPointerType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:137
ResidualBasedEliminationBuilderAndSolverWithConstraints< TSparseSpace, TDenseSpace, TLinearSolver > ClassType
The definition of the current class.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:108
BaseType::TDataType TDataType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:116
MasterSlaveConstraint MasterSlaveConstraintType
MPC definitions.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:146
void ApplyDirichletConditions(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb) override
Applies the dirichlet conditions. This operation may be very heavy or completely unexpensive dependin...
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:1338
ResidualBasedEliminationBuilderAndSolverWithConstraints()
Default constructor.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:162
BaseType::NodesArrayType NodesArrayType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:125
bool mCleared
If we compute the constant contribution of the MPC.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:397
void SetUpSystem(ModelPart &rModelPart) override
Organises the dofset in order to speed up the building phase.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:220
BaseType::ConditionsArrayType ConditionsArrayType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:127
void Clear() override
This function is intended to be called at the end of the solution step to clean up memory storage not...
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:1427
BaseType::ElementsArrayType ElementsArrayType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:126
Element::DofsVectorType DofsVectorType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:132
BaseType::TSystemVectorType TSystemVectorType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:119
ResidualBasedEliminationBuilderAndSolverWithConstraints(typename TLinearSolver::Pointer pNewLinearSystemSolver, const bool CheckConstraintRelation=true, const bool ResetRelationMatrixEachIteration=false)
Default constructor.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:182
bool mResetRelationMatrixEachIteration
If we do a constraint check relation.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:394
TSystemMatrixPointerType mpOldAMatrix
This is matrix containing the global relation for the constraints.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:385
void ResizeAndInitializeVectors(typename TSchemeType::Pointer pScheme, TSystemMatrixPointerType &pA, TSystemVectorPointerType &pDx, TSystemVectorPointerType &pb, ModelPart &rModelPart) override
This method resize and initializes the system of euqations.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:1214
BaseType::LocalSystemMatrixType LocalSystemMatrixType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:121
void SystemSolveWithPhysics(TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb, ModelPart &rModelPart)
This is a call to the linear system solver (taking into account some physical particularities of the ...
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:725
KRATOS_CLASS_POINTER_DEFINITION(ResidualBasedEliminationBuilderAndSolverWithConstraints)
Pointer definition of ResidualBasedEliminationBuilderAndSolverWithConstraints.
ResidualBasedEliminationBuilderAndSolver< TSparseSpace, TDenseSpace, TLinearSolver > BaseType
Definition of the base class.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:105
std::unordered_map< IndexType, IndexType > IndexMapType
Map definition.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:143
DofsArrayType mDoFMasterFixedSet
This is vector contains the effective constant displacement.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:388
void CalculateReactions(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb) override
It computes the reactions of the system.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:1303
std::size_t IndexType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:112
BaseType::TSchemeType TSchemeType
Definition of the classes from the base class.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:115
TSystemVectorPointerType mpDeltaConstantVector
This is vector containing the rigid movement of the constraint.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:387
SizeType mDoFToSolveSystemSize
The set containing the slave DoF of the system.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:390
virtual void ConstructMatrixStructureWithConstraints(typename TSchemeType::Pointer pScheme, TSystemMatrixType &rA, ModelPart &rModelPart)
This function is exactly same as the ConstructMatrixStructure() function in base class except that th...
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:777
void AssembleRelationMatrix(TSystemMatrixType &rT, const LocalSystemMatrixType &rTransformationMatrix, const EquationIdVectorType &rSlaveEquationId, const EquationIdVectorType &rMasterEquationId)
This method assembles the global relation matrix (T matrix used to impose the MPC)
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:414
BuilderAndSolverBaseType::Pointer Create(typename TLinearSolver::Pointer pNewLinearSystemSolver, Parameters ThisParameters) const override
Create method.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:204
BuilderAndSolver< TSparseSpace, TDenseSpace, TLinearSolver > BuilderAndSolverBaseType
Definition of the base class.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:102
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:360
TSystemMatrixPointerType mpTMatrix
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:384
DofsArrayType mDoFSlaveSet
The set containing the fixed master DoF of the system.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:389
TSystemVectorPointerType mpConstantVector
This is matrix containing the old LHS structure.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:386
BaseType::NodeType NodeType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:124
NodeType::DofType DofType
DoF types definition.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:136
Parameters GetDefaultParameters() const override
This method provides the defaults parameters to avoid conflicts between the different constructors.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:317
IndexMapType mReactionEquationIdMap
Number of degrees of freedom of the problem to actually be solved.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:391
virtual void ConstructRelationMatrixStructure(typename TSchemeType::Pointer pScheme, TSystemMatrixType &rT, ModelPart &rModelPart)
This function is exactly same as the ConstructMatrixStructure() function in base class except that th...
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:950
void AssignSettings(const Parameters ThisParameters) override
This method assigns settings to member variables.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:1456
BaseType::TSystemVectorPointerType TSystemVectorPointerType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:123
std::vector< IndexType > VectorIndexType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:148
void SetUpDofSetWithConstraints(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart)
Builds the list of the DofSets involved in the problem by "asking" to each element and condition its ...
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:577
std::string Info() const override
Turn back information as a string.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:354
BaseType::DofsArrayType DofsArrayType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:117
std::size_t SizeType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:111
void BuildAndSolveWithConstraints(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb)
The same methods as the base class but with constraints.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:458
void BuildRHSWithConstraints(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemVectorType &rb)
The same methods as the base class but with constraints.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:524
BaseType::LocalSystemVectorType LocalSystemVectorType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:120
~ResidualBasedEliminationBuilderAndSolverWithConstraints() override
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:195
static std::string Name()
Returns the name of the class as used in the settings (snake_case format)
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:336
BaseType::TSystemMatrixType TSystemMatrixType
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:118
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: residualbased_elimination_builder_and_solver_with_constraints.h:366
This class provides the implementation of the basic tasks that are needed by the solution strategy.
Definition: scheme.h:56
static void MatrixMultiplication(const AMatrix &rA, const BMatrix &rB, CMatrix &rC)
Matrix-matrix product C = A·B @detail This method uses a template for each matrix.
Definition: sparse_matrix_multiplication_utility.h:117
static void Start(std::string const &rIntervalName)
This method starts the timer meassures.
Definition: timer.cpp:109
static void Stop(std::string const &rIntervalName)
This method stops the timer meassures.
Definition: timer.cpp:125
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#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_DEBUG_ERROR_IF_NOT(conditional)
Definition: exception.h:172
#define KRATOS_INFO_IF(label, conditional)
Definition: logger.h:251
#define KRATOS_WARNING_IF(label, conditional)
Definition: logger.h:266
void ApplyConstraints(ModelPart &rModelPart)
This method resets the values of the slave dofs.
Definition: constraint_utilities.cpp:159
void ResetSlaveDofs(ModelPart &rModelPart)
This method resets the values of the slave dofs.
Definition: constraint_utilities.cpp:136
double TwoNorm(SparseSpaceType &dummy, SparseSpaceType::VectorType &x)
Definition: add_strategies_to_python.cpp:164
TSpaceType::IndexType Size(TSpaceType &dummy, typename TSpaceType::VectorType const &rV)
Definition: add_strategies_to_python.cpp:111
void Mult(TSpaceType &dummy, typename TSpaceType::MatrixType &rA, typename TSpaceType::VectorType &rX, typename TSpaceType::VectorType &rY)
Definition: add_strategies_to_python.cpp:98
void UnaliasedAdd(TSpaceType &dummy, typename TSpaceType::VectorType &x, const double A, const typename TSpaceType::VectorType &rY)
Definition: add_strategies_to_python.cpp:170
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
void AtomicAdd(TDataType &target, const TDataType &value)
Definition: atomic_utilities.h:55
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
ProcessInfo
Definition: edgebased_PureConvection.py:116
int local_size
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:17
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
u
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:30
def Index()
Definition: hdf5_io_tools.py:38
int dof
Definition: ode_solve.py:393
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
int counter
Definition: script_THERMAL_CORRECT.py:218
A
Definition: sensitivityMatrix.py:70
integer i
Definition: TensorModule.f:17
Definition: timer.py:1