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_block_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: Riccardo Rossi
11 // Collaborators: Vicente Mataix
12 //
13 //
14 
15 #pragma once
16 
17 /* System includes */
18 #include <unordered_set>
19 
20 /* External includes */
21 #ifdef KRATOS_SMP_OPENMP
22 #include <omp.h>
23 #endif
24 
25 /* Project includes */
26 #include "includes/define.h"
28 #include "includes/model_part.h"
29 #include "includes/key_hash.h"
30 #include "utilities/timer.h"
32 #include "includes/kratos_flags.h"
33 #include "includes/lock_object.h"
37 #include "spaces/ublas_space.h"
38 
39 namespace Kratos
40 {
41 
44 
48 
52 
56 
60 
76 template<class TSparseSpace,
77  class TDenseSpace, //= DenseSpace<double>,
78  class TLinearSolver //= LinearSolver<TSparseSpace,TDenseSpace>
79  >
81  : public BuilderAndSolver< TSparseSpace, TDenseSpace, TLinearSolver >
82 {
83 public:
86 
88  KRATOS_DEFINE_LOCAL_FLAG( SILENT_WARNINGS );
89 
92 
95 
98 
99  // The size_t types
100  typedef std::size_t SizeType;
101  typedef std::size_t IndexType;
102 
105  typedef typename BaseType::TDataType TDataType;
116 
121  typedef boost::numeric::ublas::compressed_matrix<double> CompressedMatrixType;
122 
124  typedef Node NodeType;
125  typedef typename NodeType::DofType DofType;
127 
131 
136  {
137  }
138 
143  typename TLinearSolver::Pointer pNewLinearSystemSolver,
144  Parameters ThisParameters
145  ) : BaseType(pNewLinearSystemSolver)
146  {
147  // Validate and assign defaults
148  ThisParameters = this->ValidateAndAssignParameters(ThisParameters, this->GetDefaultParameters());
149  this->AssignSettings(ThisParameters);
150  }
151 
155  explicit ResidualBasedBlockBuilderAndSolver(typename TLinearSolver::Pointer pNewLinearSystemSolver)
156  : BaseType(pNewLinearSystemSolver)
157  {
158  }
159 
163  {
164  }
165 
171  typename BaseType::Pointer Create(
172  typename TLinearSolver::Pointer pNewLinearSystemSolver,
173  Parameters ThisParameters
174  ) const override
175  {
176  return Kratos::make_shared<ClassType>(pNewLinearSystemSolver,ThisParameters);
177  }
178 
182 
186 
195  void Build(
196  typename TSchemeType::Pointer pScheme,
197  ModelPart& rModelPart,
199  TSystemVectorType& b) override
200  {
201  KRATOS_TRY
202 
203  KRATOS_ERROR_IF(!pScheme) << "No scheme provided!" << std::endl;
204 
205  // Getting the elements from the model
206  const int nelements = static_cast<int>(rModelPart.Elements().size());
207 
208  // Getting the array of the conditions
209  const int nconditions = static_cast<int>(rModelPart.Conditions().size());
210 
211  const ProcessInfo& CurrentProcessInfo = rModelPart.GetProcessInfo();
214 
215  //contributions to the system
216  LocalSystemMatrixType LHS_Contribution = LocalSystemMatrixType(0, 0);
217  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
218 
219  //vector containing the localization in the system of the different
220  //terms
222 
223  // Assemble all elements
224  const auto timer = BuiltinTimer();
225 
226  #pragma omp parallel firstprivate(nelements,nconditions, LHS_Contribution, RHS_Contribution, EquationId )
227  {
228  # pragma omp for schedule(guided, 512) nowait
229  for (int k = 0; k < nelements; k++) {
230  auto it_elem = el_begin + k;
231 
232  if (it_elem->IsActive()) {
233  // Calculate elemental contribution
234  pScheme->CalculateSystemContributions(*it_elem, LHS_Contribution, RHS_Contribution, EquationId, CurrentProcessInfo);
235 
236  // Assemble the elemental contribution
237  Assemble(A, b, LHS_Contribution, RHS_Contribution, EquationId);
238  }
239 
240  }
241 
242  #pragma omp for schedule(guided, 512)
243  for (int k = 0; k < nconditions; k++) {
244  auto it_cond = cond_begin + k;
245 
246  if (it_cond->IsActive()) {
247  // Calculate elemental contribution
248  pScheme->CalculateSystemContributions(*it_cond, LHS_Contribution, RHS_Contribution, EquationId, CurrentProcessInfo);
249 
250  // Assemble the elemental contribution
251  Assemble(A, b, LHS_Contribution, RHS_Contribution, EquationId);
252  }
253  }
254  }
255 
256  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() >= 1) << "Build time: " << timer << std::endl;
257 
258  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() > 2) << "Finished parallel building" << std::endl;
259 
260  KRATOS_CATCH("")
261  }
262 
271  void BuildLHS(
272  typename TSchemeType::Pointer pScheme,
273  ModelPart& rModelPart,
275  ) override
276  {
277  KRATOS_TRY
278 
279  KRATOS_ERROR_IF(!pScheme) << "No scheme provided!" << std::endl;
280 
281  // Getting the elements from the model
282  const int nelements = static_cast<int>(rModelPart.Elements().size());
283 
284  // Getting the array of the conditions
285  const int nconditions = static_cast<int>(rModelPart.Conditions().size());
286 
287  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
288  const auto it_elem_begin = rModelPart.ElementsBegin();
289  const auto it_cond_begin = rModelPart.ConditionsBegin();
290 
291  // Contributions to the system
292  LocalSystemMatrixType lhs_contribution(0, 0);
293 
294  // Vector containing the localization in the system of the different terms
295  Element::EquationIdVectorType equation_id;
296 
297  // Assemble all elements
298  const auto timer = BuiltinTimer();
299 
300  #pragma omp parallel firstprivate(nelements, nconditions, lhs_contribution, equation_id )
301  {
302  # pragma omp for schedule(guided, 512) nowait
303  for (int k = 0; k < nelements; ++k) {
304  auto it_elem = it_elem_begin + k;
305 
306  // Detect if the element is active or not. If the user did not make any choice the element is active by default
307  if (it_elem->IsActive()) {
308  // Calculate elemental contribution
309  pScheme->CalculateLHSContribution(*it_elem, lhs_contribution, equation_id, r_current_process_info);
310 
311  // Assemble the elemental contribution
312  AssembleLHS(rA, lhs_contribution, equation_id);
313  }
314  }
315 
316  #pragma omp for schedule(guided, 512)
317  for (int k = 0; k < nconditions; ++k) {
318  auto it_cond = it_cond_begin + k;
319 
320  // Detect if the element is active or not. If the user did not make any choice the element is active by default
321  if (it_cond->IsActive()) {
322  // Calculate elemental contribution
323  pScheme->CalculateLHSContribution(*it_cond, lhs_contribution, equation_id, r_current_process_info);
324 
325  // Assemble the elemental contribution
326  AssembleLHS(rA, lhs_contribution, equation_id);
327  }
328  }
329  }
330 
331  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() >= 1) << "Build time LHS: " << timer << std::endl;
332 
333  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() > 2) << "Finished parallel building LHS" << std::endl;
334 
335  KRATOS_CATCH("")
336  }
337 
348  typename TSchemeType::Pointer pScheme,
349  ModelPart& rModelPart,
350  TSystemMatrixType& A) override
351  {
352  KRATOS_TRY
353 
354  TSystemVectorType tmp(A.size1(), 0.0);
355  this->Build(pScheme, rModelPart, A, tmp);
356 
357  KRATOS_CATCH("")
358  }
359 
367  TSystemMatrixType& rA,
368  TSystemVectorType& rDx,
370  ) override
371  {
372  KRATOS_TRY
373  double norm_b;
374  if (TSparseSpace::Size(rb) != 0) {
375  norm_b = TSparseSpace::TwoNorm(rb);
376  } else {
377  norm_b = 0.0;
378  }
379 
380  if (norm_b != 0.0) {
381  // Do solve
382  BaseType::mpLinearSystemSolver->Solve(rA, rDx, rb);
383  } else {
384  TSparseSpace::SetToZero(rDx);
385  }
386 
387  if(mT.size1() != 0) { // If there are master-slave constraints
388  // Recover solution of the original problem
389  TSystemVectorType Dxmodified = rDx;
390 
391  // Recover solution of the original problem
392  TSparseSpace::Mult(mT, Dxmodified, rDx);
393  }
394 
395  // Prints information about the current time
396  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() > 1) << *(BaseType::mpLinearSystemSolver) << std::endl;
397 
398  KRATOS_CATCH("")
399  }
400 
409  TSystemMatrixType& rA,
410  TSystemVectorType& rDx,
411  TSystemVectorType& rb,
412  ModelPart& rModelPart
413  )
414  {
415  if(rModelPart.MasterSlaveConstraints().size() != 0) {
416  TSystemVectorType Dxmodified(rb.size());
417 
418  // Initialize the vector
419  TSparseSpace::SetToZero(Dxmodified);
420 
421  InternalSystemSolveWithPhysics(rA, Dxmodified, rb, rModelPart);
422 
423  //recover solution of the original problem
424  TSparseSpace::Mult(mT, Dxmodified, rDx);
425  } else {
426  InternalSystemSolveWithPhysics(rA, rDx, rb, rModelPart);
427  }
428  }
429 
438  TSystemMatrixType& rA,
439  TSystemVectorType& rDx,
440  TSystemVectorType& rb,
441  ModelPart& rModelPart
442  )
443  {
444  KRATOS_TRY
445 
446  double norm_b;
447  if (TSparseSpace::Size(rb) != 0)
448  norm_b = TSparseSpace::TwoNorm(rb);
449  else
450  norm_b = 0.00;
451 
452  if (norm_b != 0.00) {
453  //provide physical data as needed
454  if(BaseType::mpLinearSystemSolver->AdditionalPhysicalDataIsNeeded() )
455  BaseType::mpLinearSystemSolver->ProvideAdditionalData(rA, rDx, rb, BaseType::mDofSet, rModelPart);
456 
457  //do solve
458  BaseType::mpLinearSystemSolver->Solve(rA, rDx, rb);
459  } else {
460  KRATOS_WARNING_IF("ResidualBasedBlockBuilderAndSolver", mOptions.IsNot(SILENT_WARNINGS)) << "ATTENTION! setting the RHS to zero!" << std::endl;
461  }
462 
463  // Prints information about the current time
464  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() > 1) << *(BaseType::mpLinearSystemSolver) << std::endl;
465 
466  KRATOS_CATCH("")
467  }
468 
480  typename TSchemeType::Pointer pScheme,
481  ModelPart& rModelPart,
483  TSystemVectorType& Dx,
484  TSystemVectorType& b) override
485  {
486  KRATOS_TRY
487 
488  Timer::Start("Build");
489 
490  Build(pScheme, rModelPart, A, b);
491 
492  Timer::Stop("Build");
493 
494  if(rModelPart.MasterSlaveConstraints().size() != 0) {
495  const auto timer_constraints = BuiltinTimer();
496  Timer::Start("ApplyConstraints");
497  ApplyConstraints(pScheme, rModelPart, A, b);
498  Timer::Stop("ApplyConstraints");
499  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() >=1) << "Constraints build time: " << timer_constraints << std::endl;
500  }
501 
502  ApplyDirichletConditions(pScheme, rModelPart, A, Dx, b);
503 
504  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() == 3)) << "Before the solution of the system" << "\nSystem Matrix = " << A << "\nUnknowns vector = " << Dx << "\nRHS vector = " << b << std::endl;
505 
506  const auto timer = BuiltinTimer();
507  Timer::Start("Solve");
508 
509  SystemSolveWithPhysics(A, Dx, b, rModelPart);
510 
511  Timer::Stop("Solve");
512  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() >=1) << "System solve time: " << timer << std::endl;
513 
514  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() == 3)) << "After the solution of the system" << "\nSystem Matrix = " << A << "\nUnknowns vector = " << Dx << "\nRHS vector = " << b << std::endl;
515 
516  KRATOS_CATCH("")
517  }
518 
530  typename TSchemeType::Pointer pScheme,
531  ModelPart& rModelPart,
532  TSystemMatrixType& rA,
533  TSystemVectorType& rDx,
534  TSystemVectorType& rb,
535  const bool MoveMesh
536  ) override
537  {
538  Timer::Start("Linearizing on Old iteration");
539 
540  KRATOS_INFO_IF("BlockBuilderAndSolver", this->GetEchoLevel() > 0) << "Linearizing on Old iteration" << std::endl;
541 
542  KRATOS_ERROR_IF(rModelPart.GetBufferSize() == 1) << "BlockBuilderAndSolver: \n"
543  << "The buffer size needs to be at least 2 in order to use \n"
544  << "BuildAndSolveLinearizedOnPreviousIteration \n"
545  << "current buffer size for modelpart: " << rModelPart.Name() << std::endl
546  << "is :" << rModelPart.GetBufferSize()
547  << " Please set IN THE STRATEGY SETTINGS "
548  << " UseOldStiffnessInFirstIteration=false " << std::endl;
549 
550  DofsArrayType fixed_dofs;
551  for(auto& r_dof : BaseType::mDofSet){
552  if(r_dof.IsFixed()){
553  fixed_dofs.push_back(&r_dof);
554  r_dof.FreeDof();
555  }
556  }
557 
558  //TODO: Here we need to take the vector from other ones because
559  // We cannot create a trilinos vector without a communicator. To be improved!
560  TSystemVectorType dx_prediction(rDx);
561  TSystemVectorType rhs_addition(rb); //we know it is zero here, so we do not need to set it
562 
563  // Here we bring back the database to before the prediction,
564  // but we store the prediction increment in dx_prediction.
565  // The goal is that the stiffness is computed with the
566  // converged configuration at the end of the previous step.
568  // NOTE: this is initialized to - the value of dx prediction
569  dx_prediction[rDof.EquationId()] = -(rDof.GetSolutionStepValue() - rDof.GetSolutionStepValue(1));
570 
571  });
572 
573  // Use UpdateDatabase to bring back the solution to how it was at the end of the previous step
574  pScheme->Update(rModelPart, BaseType::mDofSet, rA, dx_prediction, rb);
575  if (MoveMesh) {
576  VariableUtils().UpdateCurrentPosition(rModelPart.Nodes(),DISPLACEMENT,0);
577  }
578 
579  Timer::Stop("Linearizing on Old iteration");
580 
581  Timer::Start("Build");
582 
583  this->Build(pScheme, rModelPart, rA, rb);
584 
585  Timer::Stop("Build");
586 
587  // Put back the prediction into the database
588  TSparseSpace::InplaceMult(dx_prediction, -1.0); //change sign to dx_prediction
589  TSparseSpace::UnaliasedAdd(rDx, 1.0, dx_prediction);
590 
591  // Use UpdateDatabase to bring back the solution
592  // to where it was taking into account BCs
593  // it is done here so that constraints are correctly taken into account right after
594  pScheme->Update(rModelPart, BaseType::mDofSet, rA, dx_prediction, rb);
595  if (MoveMesh) {
596  VariableUtils().UpdateCurrentPosition(rModelPart.Nodes(),DISPLACEMENT,0);
597  }
598 
599  // Apply rb -= A*dx_prediction
600  TSparseSpace::Mult(rA, dx_prediction, rhs_addition);
601  TSparseSpace::UnaliasedAdd(rb, -1.0, rhs_addition);
602 
603  for(auto& dof : fixed_dofs)
604  dof.FixDof();
605 
606  if (!rModelPart.MasterSlaveConstraints().empty()) {
607  const auto timer_constraints = BuiltinTimer();
608  Timer::Start("ApplyConstraints");
609  this->ApplyConstraints(pScheme, rModelPart, rA, rb);
610  Timer::Stop("ApplyConstraints");
611  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() >=1) << "Constraints build time: " << timer_constraints << std::endl;
612  }
613  this->ApplyDirichletConditions(pScheme, rModelPart, rA, rDx, rb);
614 
615  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() == 3)) << "Before the solution of the system" << "\nSystem Matrix = " << rA << "\nUnknowns vector = " << rDx << "\nRHS vector = " << rb << std::endl;
616 
617  const auto timer = BuiltinTimer();
618 
619  Timer::Start("Solve");
620 
621  this->SystemSolveWithPhysics(rA, rDx, rb, rModelPart);
622 
623  Timer::Stop("Solve");
624  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() >=1) << "System solve time: " << timer << std::endl;
625 
626  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() == 3)) << "After the solution of the system" << "\nSystem Matrix = " << rA << "\nUnknowns vector = " << rDx << "\nRHS vector = " << rb << std::endl;
627  }
628 
638  typename TSchemeType::Pointer pScheme,
639  ModelPart& rModelPart,
640  TSystemMatrixType& rA,
641  TSystemVectorType& rDx,
643  ) override
644  {
645  KRATOS_TRY
646 
647  BuildRHS(pScheme, rModelPart, rb);
648 
649  if(rModelPart.MasterSlaveConstraints().size() != 0) {
650  Timer::Start("ApplyRHSConstraints");
651  ApplyRHSConstraints(pScheme, rModelPart, rb);
652  Timer::Stop("ApplyRHSConstraints");
653  }
654 
655  ApplyDirichletConditions(pScheme, rModelPart, rA, rDx, rb);
656 
657  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() == 3)) << "Before the solution of the system" << "\nSystem Matrix = " << rA << "\nUnknowns vector = " << rDx << "\nRHS vector = " << rb << std::endl;
658 
659  const auto timer = BuiltinTimer();
660  Timer::Start("Solve");
661 
662  SystemSolveWithPhysics(rA, rDx, rb, rModelPart);
663 
664  Timer::Stop("Solve");
665  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", this->GetEchoLevel() >=1) << "System solve time: " << timer << std::endl;
666 
667  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() == 3)) << "After the solution of the system" << "\nSystem Matrix = " << rA << "\nUnknowns vector = " << rDx << "\nRHS vector = " << rb << std::endl;
668 
669  KRATOS_CATCH("")
670  }
671 
678  void BuildRHS(
679  typename TSchemeType::Pointer pScheme,
680  ModelPart& rModelPart,
681  TSystemVectorType& b) override
682  {
683  KRATOS_TRY
684 
685  Timer::Start("BuildRHS");
686 
687  BuildRHSNoDirichlet(pScheme,rModelPart,b);
688 
689  //NOTE: dofs are assumed to be numbered consecutively in the BlockBuilderAndSolver
691  const std::size_t i = rDof.EquationId();
692 
693  if (rDof.IsFixed())
694  b[i] = 0.0;
695  });
696 
697  Timer::Stop("BuildRHS");
698 
699  KRATOS_CATCH("")
700  }
701 
711  typename TSchemeType::Pointer pScheme,
712  ModelPart& rModelPart
713  ) override
714  {
715  KRATOS_TRY;
716 
717  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() > 1 && rModelPart.GetCommunicator().MyPID() == 0)) << "Setting up the dofs" << std::endl;
718 
719  //Gets the array of elements from the modeler
720  ElementsArrayType& r_elements_array = rModelPart.Elements();
721  const int number_of_elements = static_cast<int>(r_elements_array.size());
722 
723  DofsVectorType dof_list, second_dof_list; // NOTE: The second dof list is only used on constraints to include master/slave relations
724 
725  unsigned int nthreads = ParallelUtilities::GetNumThreads();
726 
727  typedef std::unordered_set < NodeType::DofType::Pointer, DofPointerHasher> set_type;
728 
729  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() > 2)) << "Number of threads" << nthreads << "\n" << std::endl;
730 
731  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() > 2)) << "Initializing element loop" << std::endl;
732 
738  set_type dof_global_set;
739  dof_global_set.reserve(number_of_elements*20);
740 
741  #pragma omp parallel firstprivate(dof_list, second_dof_list)
742  {
743  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
744 
745  // We cleate the temporal set and we reserve some space on them
746  set_type dofs_tmp_set;
747  dofs_tmp_set.reserve(20000);
748 
749  // Gets the array of elements from the modeler
750  #pragma omp for schedule(guided, 512) nowait
751  for (int i = 0; i < number_of_elements; ++i) {
752  auto it_elem = r_elements_array.begin() + i;
753 
754  // Gets list of Dof involved on every element
755  pScheme->GetDofList(*it_elem, dof_list, r_current_process_info);
756  dofs_tmp_set.insert(dof_list.begin(), dof_list.end());
757  }
758 
759  // Gets the array of conditions from the modeler
760  ConditionsArrayType& r_conditions_array = rModelPart.Conditions();
761  const int number_of_conditions = static_cast<int>(r_conditions_array.size());
762  #pragma omp for schedule(guided, 512) nowait
763  for (int i = 0; i < number_of_conditions; ++i) {
764  auto it_cond = r_conditions_array.begin() + i;
765 
766  // Gets list of Dof involved on every element
767  pScheme->GetDofList(*it_cond, dof_list, r_current_process_info);
768  dofs_tmp_set.insert(dof_list.begin(), dof_list.end());
769  }
770 
771  // Gets the array of constraints from the modeler
772  auto& r_constraints_array = rModelPart.MasterSlaveConstraints();
773  const int number_of_constraints = static_cast<int>(r_constraints_array.size());
774  #pragma omp for schedule(guided, 512) nowait
775  for (int i = 0; i < number_of_constraints; ++i) {
776  auto it_const = r_constraints_array.begin() + i;
777 
778  // Gets list of Dof involved on every element
779  it_const->GetDofList(dof_list, second_dof_list, r_current_process_info);
780  dofs_tmp_set.insert(dof_list.begin(), dof_list.end());
781  dofs_tmp_set.insert(second_dof_list.begin(), second_dof_list.end());
782  }
783 
784  // We merge all the sets in one thread
785  #pragma omp critical
786  {
787  dof_global_set.insert(dofs_tmp_set.begin(), dofs_tmp_set.end());
788  }
789  }
790 
791  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() > 2)) << "Initializing ordered array filling\n" << std::endl;
792 
793  DofsArrayType Doftemp;
795 
796  Doftemp.reserve(dof_global_set.size());
797  for (auto it= dof_global_set.begin(); it!= dof_global_set.end(); it++)
798  {
799  Doftemp.push_back( *it );
800  }
801  Doftemp.Sort();
802 
803  BaseType::mDofSet = Doftemp;
804 
805  //Throws an exception if there are no Degrees Of Freedom involved in the analysis
806  KRATOS_ERROR_IF(BaseType::mDofSet.size() == 0) << "No degrees of freedom!" << std::endl;
807 
808  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() > 2)) << "Number of degrees of freedom:" << BaseType::mDofSet.size() << std::endl;
809 
811 
812  KRATOS_INFO_IF("ResidualBasedBlockBuilderAndSolver", ( this->GetEchoLevel() > 2 && rModelPart.GetCommunicator().MyPID() == 0)) << "Finished setting up the dofs" << std::endl;
813 
814 #ifdef KRATOS_DEBUG
815  // If reactions are to be calculated, we check if all the dofs have reactions defined
816  // This is tobe done only in debug mode
818  for (auto dof_iterator = BaseType::mDofSet.begin(); dof_iterator != BaseType::mDofSet.end(); ++dof_iterator) {
819  KRATOS_ERROR_IF_NOT(dof_iterator->HasReaction()) << "Reaction variable not set for the following : " <<std::endl
820  << "Node : "<<dof_iterator->Id()<< std::endl
821  << "Dof : "<<(*dof_iterator)<<std::endl<<"Not possible to calculate reactions."<<std::endl;
822  }
823  }
824 #endif
825 
826  KRATOS_CATCH("");
827  }
828 
834  ModelPart& rModelPart
835  ) override
836  {
837  //int free_id = 0;
839 
840  IndexPartition<std::size_t>(BaseType::mDofSet.size()).for_each([&, this](std::size_t Index){
841  typename DofsArrayType::iterator dof_iterator = this->mDofSet.begin() + Index;
842  dof_iterator->SetEquationId(Index);
843  });
844  }
845 
846  //**************************************************************************
847  //**************************************************************************
848 
850  typename TSchemeType::Pointer pScheme,
854  ModelPart& rModelPart
855  ) override
856  {
857  KRATOS_TRY
858  if (pA == NULL) //if the pointer is not initialized initialize it to an empty matrix
859  {
861  pA.swap(pNewA);
862  }
863  if (pDx == NULL) //if the pointer is not initialized initialize it to an empty matrix
864  {
866  pDx.swap(pNewDx);
867  }
868  if (pb == NULL) //if the pointer is not initialized initialize it to an empty matrix
869  {
871  pb.swap(pNewb);
872  }
873 
874  TSystemMatrixType& A = *pA;
875  TSystemVectorType& Dx = *pDx;
876  TSystemVectorType& b = *pb;
877 
878  //resizing the system vectors and matrix
879  if (A.size1() == 0 || BaseType::GetReshapeMatrixFlag() == true) //if the matrix is not initialized
880  {
882  ConstructMatrixStructure(pScheme, A, rModelPart);
883  }
884  else
885  {
886  if (A.size1() != BaseType::mEquationSystemSize || A.size2() != BaseType::mEquationSystemSize)
887  {
888  KRATOS_ERROR <<"The equation system size has changed during the simulation. This is not permitted."<<std::endl;
890  ConstructMatrixStructure(pScheme, A, rModelPart);
891  }
892  }
893  if (Dx.size() != BaseType::mEquationSystemSize)
894  Dx.resize(BaseType::mEquationSystemSize, false);
895  TSparseSpace::SetToZero(Dx);
896  if (b.size() != BaseType::mEquationSystemSize) {
897  b.resize(BaseType::mEquationSystemSize, false);
898  }
899  TSparseSpace::SetToZero(b);
900 
902 
903  KRATOS_CATCH("")
904  }
905 
906  //**************************************************************************
907  //**************************************************************************
908 
910  typename TSchemeType::Pointer pScheme,
911  ModelPart& rModelPart,
913  TSystemVectorType& Dx,
914  TSystemVectorType& b) override
915  {
916  TSparseSpace::SetToZero(b);
917 
918  //refresh RHS to have the correct reactions
919  BuildRHSNoDirichlet(pScheme, rModelPart, b);
920 
921  //NOTE: dofs are assumed to be numbered consecutively in the BlockBuilderAndSolver
923  const std::size_t i = rDof.EquationId();
924 
925  rDof.GetSolutionStepReactionValue() = -b[i];
926  });
927  }
928 
941  typename TSchemeType::Pointer pScheme,
942  ModelPart& rModelPart,
943  TSystemMatrixType& rA,
944  TSystemVectorType& rDx,
946  ) override
947  {
948  const std::size_t system_size = rA.size1();
949  Vector scaling_factors (system_size);
950 
951  const auto it_dof_iterator_begin = BaseType::mDofSet.begin();
952 
953  // NOTE: dofs are assumed to be numbered consecutively in the BlockBuilderAndSolver
955  auto it_dof_iterator = it_dof_iterator_begin + Index;
956  if (it_dof_iterator->IsFixed()) {
957  scaling_factors[Index] = 0.0;
958  } else {
959  scaling_factors[Index] = 1.0;
960  }
961  });
962 
963  // Detect if there is a line of all zeros and set the diagonal to a certain number (1 if not scale, some norms values otherwise) if this happens
964  mScaleFactor = TSparseSpace::CheckAndCorrectZeroDiagonalValues(rModelPart.GetProcessInfo(), rA, rb, mScalingDiagonal);
965 
966  double* Avalues = rA.value_data().begin();
967  std::size_t* Arow_indices = rA.index1_data().begin();
968  std::size_t* Acol_indices = rA.index2_data().begin();
969 
970  IndexPartition<std::size_t>(system_size).for_each([&](std::size_t Index){
971  const std::size_t col_begin = Arow_indices[Index];
972  const std::size_t col_end = Arow_indices[Index+1];
973  const double k_factor = scaling_factors[Index];
974  if (k_factor == 0.0) {
975  // Zero out the whole row, except the diagonal
976  for (std::size_t j = col_begin; j < col_end; ++j)
977  if (Acol_indices[j] != Index )
978  Avalues[j] = 0.0;
979 
980  // Zero out the RHS
981  rb[Index] = 0.0;
982  } else {
983  // Zero out the column which is associated with the zero'ed row
984  for (std::size_t j = col_begin; j < col_end; ++j)
985  if(scaling_factors[ Acol_indices[j] ] == 0 )
986  Avalues[j] = 0.0;
987  }
988  });
989  }
990 
998  typename TSchemeType::Pointer pScheme,
999  ModelPart& rModelPart,
1000  TSystemVectorType& rb
1001  ) override
1002  {
1003  KRATOS_TRY
1004 
1005  if (rModelPart.MasterSlaveConstraints().size() != 0) {
1006  BuildMasterSlaveConstraints(rModelPart);
1007 
1008  // We compute the transposed matrix of the global relation matrix
1009  TSystemMatrixType T_transpose_matrix(mT.size2(), mT.size1());
1010  SparseMatrixMultiplicationUtility::TransposeMatrix<TSystemMatrixType, TSystemMatrixType>(T_transpose_matrix, mT, 1.0);
1011 
1012  TSystemVectorType b_modified(rb.size());
1013  TSparseSpace::Mult(T_transpose_matrix, rb, b_modified);
1014  TSparseSpace::Copy(b_modified, rb);
1015 
1016  // Apply diagonal values on slaves
1017  IndexPartition<std::size_t>(mSlaveIds.size()).for_each([&](std::size_t Index){
1018  const IndexType slave_equation_id = mSlaveIds[Index];
1019  if (mInactiveSlaveDofs.find(slave_equation_id) == mInactiveSlaveDofs.end()) {
1020  rb[slave_equation_id] = 0.0;
1021  }
1022  });
1023  }
1024 
1025  KRATOS_CATCH("")
1026  }
1027 
1036  typename TSchemeType::Pointer pScheme,
1037  ModelPart& rModelPart,
1038  TSystemMatrixType& rA,
1039  TSystemVectorType& rb
1040  ) override
1041  {
1042  KRATOS_TRY
1043 
1044  if (rModelPart.MasterSlaveConstraints().size() != 0) {
1045  BuildMasterSlaveConstraints(rModelPart);
1046 
1047  // We compute the transposed matrix of the global relation matrix
1048  TSystemMatrixType T_transpose_matrix(mT.size2(), mT.size1());
1049  SparseMatrixMultiplicationUtility::TransposeMatrix<TSystemMatrixType, TSystemMatrixType>(T_transpose_matrix, mT, 1.0);
1050 
1051  TSystemVectorType b_modified(rb.size());
1052  TSparseSpace::Mult(T_transpose_matrix, rb, b_modified);
1053  TSparseSpace::Copy(b_modified, rb);
1054 
1055  TSystemMatrixType auxiliar_A_matrix(mT.size2(), rA.size2());
1056  SparseMatrixMultiplicationUtility::MatrixMultiplication(T_transpose_matrix, rA, auxiliar_A_matrix); //auxiliar = T_transpose * rA
1057  T_transpose_matrix.resize(0, 0, false); //free memory
1058 
1059  SparseMatrixMultiplicationUtility::MatrixMultiplication(auxiliar_A_matrix, mT, rA); //A = auxilar * T NOTE: here we are overwriting the old A matrix!
1060  auxiliar_A_matrix.resize(0, 0, false); //free memory
1061 
1062  // Compute the scale factor value
1063  mScaleFactor = TSparseSpace::GetScaleNorm(rModelPart.GetProcessInfo(), rA, mScalingDiagonal);
1064 
1065  // Apply diagonal values on slaves
1066  IndexPartition<std::size_t>(mSlaveIds.size()).for_each([&](std::size_t Index){
1067  const IndexType slave_equation_id = mSlaveIds[Index];
1068  if (mInactiveSlaveDofs.find(slave_equation_id) == mInactiveSlaveDofs.end()) {
1069  rA(slave_equation_id, slave_equation_id) = mScaleFactor;
1070  rb[slave_equation_id] = 0.0;
1071  }
1072  });
1073  }
1074 
1075  KRATOS_CATCH("")
1076  }
1077 
1081  void Clear() override
1082  {
1083  BaseType::Clear();
1084 
1085  mSlaveIds.clear();
1086  mMasterIds.clear();
1087  mInactiveSlaveDofs.clear();
1088  mT.resize(0,0,false);
1089  mConstantVector.resize(0,false);
1090  }
1091 
1099  int Check(ModelPart& rModelPart) override
1100  {
1101  KRATOS_TRY
1102 
1103  return 0;
1104  KRATOS_CATCH("");
1105  }
1106 
1112  {
1113  Parameters default_parameters = Parameters(R"(
1114  {
1115  "name" : "block_builder_and_solver",
1116  "block_builder" : true,
1117  "diagonal_values_for_dirichlet_dofs" : "use_max_diagonal",
1118  "silent_warnings" : false
1119  })");
1120 
1121  // Getting base class default parameters
1122  const Parameters base_default_parameters = BaseType::GetDefaultParameters();
1123  default_parameters.RecursivelyAddMissingParameters(base_default_parameters);
1124  return default_parameters;
1125  }
1126 
1131  static std::string Name()
1132  {
1133  return "block_builder_and_solver";
1134  }
1135 
1139 
1145  {
1146  return mT;
1147  }
1148 
1154  {
1155  return mConstantVector;
1156  }
1157 
1164  {
1165  return mScaleFactor;
1166  }
1167 
1173  void SetScaleFactor(const double ScaleFactor)
1174  {
1176  }
1177 
1181 
1185 
1187  std::string Info() const override
1188  {
1189  return "ResidualBasedBlockBuilderAndSolver";
1190  }
1191 
1193  void PrintInfo(std::ostream& rOStream) const override
1194  {
1195  rOStream << Info();
1196  }
1197 
1199  void PrintData(std::ostream& rOStream) const override
1200  {
1201  rOStream << Info();
1202  }
1203 
1207 
1209 
1210 protected:
1213 
1217 
1220  std::vector<IndexType> mSlaveIds;
1221  std::vector<IndexType> mMasterIds;
1222  std::unordered_set<IndexType> mInactiveSlaveDofs;
1223  double mScaleFactor = 1.0;
1224 
1227 
1231 
1235 
1237  typename TSchemeType::Pointer pScheme,
1238  ModelPart& rModelPart,
1240  {
1241  KRATOS_TRY
1242 
1243  //Getting the Elements
1244  ElementsArrayType& pElements = rModelPart.Elements();
1245 
1246  //getting the array of the conditions
1247  ConditionsArrayType& ConditionsArray = rModelPart.Conditions();
1248 
1249  const ProcessInfo& CurrentProcessInfo = rModelPart.GetProcessInfo();
1250 
1251  //contributions to the system
1252  LocalSystemMatrixType LHS_Contribution = LocalSystemMatrixType(0, 0);
1253  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
1254 
1255  //vector containing the localization in the system of the different
1256  //terms
1257  Element::EquationIdVectorType EquationId;
1258 
1259  // assemble all elements
1260  //for (typename ElementsArrayType::ptr_iterator it = pElements.ptr_begin(); it != pElements.ptr_end(); ++it)
1261 
1262  const int nelements = static_cast<int>(pElements.size());
1263  #pragma omp parallel firstprivate(nelements, RHS_Contribution, EquationId)
1264  {
1265  #pragma omp for schedule(guided, 512) nowait
1266  for (int i=0; i<nelements; i++) {
1267  typename ElementsArrayType::iterator it = pElements.begin() + i;
1268  // If the element is active
1269  if(it->IsActive()) {
1270  //calculate elemental Right Hand Side Contribution
1271  pScheme->CalculateRHSContribution(*it, RHS_Contribution, EquationId, CurrentProcessInfo);
1272 
1273  //assemble the elemental contribution
1274  AssembleRHS(b, RHS_Contribution, EquationId);
1275  }
1276  }
1277 
1278  LHS_Contribution.resize(0, 0, false);
1279  RHS_Contribution.resize(0, false);
1280 
1281  // assemble all conditions
1282  const int nconditions = static_cast<int>(ConditionsArray.size());
1283  #pragma omp for schedule(guided, 512)
1284  for (int i = 0; i<nconditions; i++) {
1285  auto it = ConditionsArray.begin() + i;
1286  // If the condition is active
1287  if(it->IsActive()) {
1288  //calculate elemental contribution
1289  pScheme->CalculateRHSContribution(*it, RHS_Contribution, EquationId, CurrentProcessInfo);
1290 
1291  //assemble the elemental contribution
1292  AssembleRHS(b, RHS_Contribution, EquationId);
1293  }
1294  }
1295  }
1296 
1297  KRATOS_CATCH("")
1298 
1299  }
1300 
1302  {
1303  if (rModelPart.MasterSlaveConstraints().size() > 0) {
1304  Timer::Start("ConstraintsRelationMatrixStructure");
1305  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
1306 
1307  // Constraint initial iterator
1308  const auto it_const_begin = rModelPart.MasterSlaveConstraints().begin();
1309  std::vector<std::unordered_set<IndexType>> indices(BaseType::mDofSet.size());
1310 
1311  std::vector<LockObject> lock_array(indices.size());
1312 
1313  #pragma omp parallel
1314  {
1315  Element::EquationIdVectorType slave_ids(3);
1316  Element::EquationIdVectorType master_ids(3);
1317  std::unordered_map<IndexType, std::unordered_set<IndexType>> temp_indices;
1318 
1319  #pragma omp for schedule(guided, 512) nowait
1320  for (int i_const = 0; i_const < static_cast<int>(rModelPart.MasterSlaveConstraints().size()); ++i_const) {
1321  auto it_const = it_const_begin + i_const;
1322  it_const->EquationIdVector(slave_ids, master_ids, r_current_process_info);
1323 
1324  // Slave DoFs
1325  for (auto &id_i : slave_ids) {
1326  temp_indices[id_i].insert(master_ids.begin(), master_ids.end());
1327  }
1328  }
1329 
1330  // Merging all the temporal indexes
1331  for (auto& pair_temp_indices : temp_indices) {
1332  lock_array[pair_temp_indices.first].lock();
1333  indices[pair_temp_indices.first].insert(pair_temp_indices.second.begin(), pair_temp_indices.second.end());
1334  lock_array[pair_temp_indices.first].unlock();
1335  }
1336  }
1337 
1338  mSlaveIds.clear();
1339  mMasterIds.clear();
1340  for (int i = 0; i < static_cast<int>(indices.size()); ++i) {
1341  if (indices[i].size() == 0) // Master dof!
1342  mMasterIds.push_back(i);
1343  else // Slave dof
1344  mSlaveIds.push_back(i);
1345  indices[i].insert(i); // Ensure that the diagonal is there in T
1346  }
1347 
1348  // Count the row sizes
1349  const std::size_t nnz = block_for_each<SumReduction<std::size_t>>(indices, [](auto& rIndices) {return rIndices.size();});
1350 
1351  mT = TSystemMatrixType(indices.size(), indices.size(), nnz);
1352  mConstantVector.resize(indices.size(), false);
1353 
1354  double *Tvalues = mT.value_data().begin();
1355  IndexType *Trow_indices = mT.index1_data().begin();
1356  IndexType *Tcol_indices = mT.index2_data().begin();
1357 
1358  // Filling the index1 vector - DO NOT MAKE PARALLEL THE FOLLOWING LOOP!
1359  Trow_indices[0] = 0;
1360  for (int i = 0; i < static_cast<int>(mT.size1()); i++)
1361  Trow_indices[i + 1] = Trow_indices[i] + indices[i].size();
1362 
1363  IndexPartition<std::size_t>(mT.size1()).for_each([&](std::size_t Index){
1364  const IndexType row_begin = Trow_indices[Index];
1365  const IndexType row_end = Trow_indices[Index + 1];
1366  IndexType k = row_begin;
1367  for (auto it = indices[Index].begin(); it != indices[Index].end(); ++it) {
1368  Tcol_indices[k] = *it;
1369  Tvalues[k] = 0.0;
1370  k++;
1371  }
1372 
1373  indices[Index].clear(); //deallocating the memory
1374 
1375  std::sort(&Tcol_indices[row_begin], &Tcol_indices[row_end]);
1376  });
1377 
1378  mT.set_filled(indices.size() + 1, nnz);
1379 
1380  Timer::Stop("ConstraintsRelationMatrixStructure");
1381  }
1382  }
1383 
1384  virtual void BuildMasterSlaveConstraints(ModelPart& rModelPart)
1385  {
1386  KRATOS_TRY
1387 
1388  TSparseSpace::SetToZero(mT);
1389  TSparseSpace::SetToZero(mConstantVector);
1390 
1391  // The current process info
1392  const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
1393 
1394  // Contributions to the system
1395  Matrix transformation_matrix = LocalSystemMatrixType(0, 0);
1396  Vector constant_vector = LocalSystemVectorType(0);
1397 
1398  // Vector containing the localization in the system of the different terms
1399  Element::EquationIdVectorType slave_equation_ids, master_equation_ids;
1400 
1401  const int number_of_constraints = static_cast<int>(rModelPart.MasterSlaveConstraints().size());
1402 
1403  // We clear the set
1404  mInactiveSlaveDofs.clear();
1405 
1406  #pragma omp parallel firstprivate(transformation_matrix, constant_vector, slave_equation_ids, master_equation_ids)
1407  {
1408  std::unordered_set<IndexType> auxiliar_inactive_slave_dofs;
1409 
1410  #pragma omp for schedule(guided, 512)
1411  for (int i_const = 0; i_const < number_of_constraints; ++i_const) {
1412  auto it_const = rModelPart.MasterSlaveConstraints().begin() + i_const;
1413  it_const->EquationIdVector(slave_equation_ids, master_equation_ids, r_current_process_info);
1414 
1415  // If the constraint is active
1416  if (it_const->IsActive()) {
1417  it_const->CalculateLocalSystem(transformation_matrix, constant_vector, r_current_process_info);
1418 
1419  for (IndexType i = 0; i < slave_equation_ids.size(); ++i) {
1420  const IndexType i_global = slave_equation_ids[i];
1421 
1422  // Assemble matrix row
1423  AssembleRowContribution(mT, transformation_matrix, i_global, i, master_equation_ids);
1424 
1425  // Assemble constant vector
1426  const double constant_value = constant_vector[i];
1427  double& r_value = mConstantVector[i_global];
1428  AtomicAdd(r_value, constant_value);
1429  }
1430  } else { // Taking into account inactive constraints
1431  auxiliar_inactive_slave_dofs.insert(slave_equation_ids.begin(), slave_equation_ids.end());
1432  }
1433  }
1434 
1435  // We merge all the sets in one thread
1436  #pragma omp critical
1437  {
1438  mInactiveSlaveDofs.insert(auxiliar_inactive_slave_dofs.begin(), auxiliar_inactive_slave_dofs.end());
1439  }
1440  }
1441 
1442  // Setting the master dofs into the T and C system
1443  for (auto eq_id : mMasterIds) {
1444  mConstantVector[eq_id] = 0.0;
1445  mT(eq_id, eq_id) = 1.0;
1446  }
1447 
1448  // Setting inactive slave dofs in the T and C system
1449  for (auto eq_id : mInactiveSlaveDofs) {
1450  mConstantVector[eq_id] = 0.0;
1451  mT(eq_id, eq_id) = 1.0;
1452  }
1453 
1454  KRATOS_CATCH("")
1455  }
1456 
1458  typename TSchemeType::Pointer pScheme,
1460  ModelPart& rModelPart)
1461  {
1462  //filling with zero the matrix (creating the structure)
1463  Timer::Start("MatrixStructure");
1464 
1465  const ProcessInfo& CurrentProcessInfo = rModelPart.GetProcessInfo();
1466 
1467  const std::size_t equation_size = BaseType::mEquationSystemSize;
1468 
1469  std::vector< LockObject > lock_array(equation_size);
1470 
1471  std::vector<std::unordered_set<std::size_t> > indices(equation_size);
1472 
1473  block_for_each(indices, [](std::unordered_set<std::size_t>& rIndices){
1474  rIndices.reserve(40);
1475  });
1476 
1478 
1479  block_for_each(rModelPart.Elements(), ids, [&](Element& rElem, Element::EquationIdVectorType& rIdsTLS){
1480  pScheme->EquationId(rElem, rIdsTLS, CurrentProcessInfo);
1481  for (std::size_t i = 0; i < rIdsTLS.size(); i++) {
1482  lock_array[rIdsTLS[i]].lock();
1483  auto& row_indices = indices[rIdsTLS[i]];
1484  row_indices.insert(rIdsTLS.begin(), rIdsTLS.end());
1485  lock_array[rIdsTLS[i]].unlock();
1486  }
1487  });
1488 
1489  block_for_each(rModelPart.Conditions(), ids, [&](Condition& rCond, Element::EquationIdVectorType& rIdsTLS){
1490  pScheme->EquationId(rCond, rIdsTLS, CurrentProcessInfo);
1491  for (std::size_t i = 0; i < rIdsTLS.size(); i++) {
1492  lock_array[rIdsTLS[i]].lock();
1493  auto& row_indices = indices[rIdsTLS[i]];
1494  row_indices.insert(rIdsTLS.begin(), rIdsTLS.end());
1495  lock_array[rIdsTLS[i]].unlock();
1496  }
1497  });
1498 
1499  if (rModelPart.MasterSlaveConstraints().size() != 0) {
1500  struct TLS
1501  {
1504  };
1505  TLS tls;
1506 
1507  block_for_each(rModelPart.MasterSlaveConstraints(), tls, [&](MasterSlaveConstraint& rConst, TLS& rTls){
1508  rConst.EquationIdVector(rTls.slave_ids, rTls.master_ids, CurrentProcessInfo);
1509 
1510  for (std::size_t i = 0; i < rTls.slave_ids.size(); i++) {
1511  lock_array[rTls.slave_ids[i]].lock();
1512  auto& row_indices = indices[rTls.slave_ids[i]];
1513  row_indices.insert(rTls.slave_ids[i]);
1514  lock_array[rTls.slave_ids[i]].unlock();
1515  }
1516 
1517  for (std::size_t i = 0; i < rTls.master_ids.size(); i++) {
1518  lock_array[rTls.master_ids[i]].lock();
1519  auto& row_indices = indices[rTls.master_ids[i]];
1520  row_indices.insert(rTls.master_ids[i]);
1521  lock_array[rTls.master_ids[i]].unlock();
1522  }
1523  });
1524 
1525  }
1526 
1527  // Destroy locks
1528  lock_array = std::vector< LockObject >();
1529 
1530  // Count the row sizes
1531  const std::size_t nnz = block_for_each<SumReduction<std::size_t>>(indices, [](auto& rIndices) {return rIndices.size();});
1532 
1533  A = CompressedMatrixType(indices.size(), indices.size(), nnz);
1534 
1535  double* Avalues = A.value_data().begin();
1536  std::size_t* Arow_indices = A.index1_data().begin();
1537  std::size_t* Acol_indices = A.index2_data().begin();
1538 
1539  //filling the index1 vector - DO NOT MAKE PARALLEL THE FOLLOWING LOOP!
1540  Arow_indices[0] = 0;
1541  for (int i = 0; i < static_cast<int>(A.size1()); i++) {
1542  Arow_indices[i+1] = Arow_indices[i] + indices[i].size();
1543  }
1544 
1545  IndexPartition<std::size_t>(A.size1()).for_each([&](std::size_t i){
1546  const unsigned int row_begin = Arow_indices[i];
1547  const unsigned int row_end = Arow_indices[i+1];
1548  unsigned int k = row_begin;
1549  for (auto it = indices[i].begin(); it != indices[i].end(); it++) {
1550  Acol_indices[k] = *it;
1551  Avalues[k] = 0.0;
1552  k++;
1553  }
1554 
1555  indices[i].clear(); //deallocating the memory
1556 
1557  std::sort(&Acol_indices[row_begin], &Acol_indices[row_end]);
1558 
1559  });
1560 
1561  A.set_filled(indices.size()+1, nnz);
1562 
1563  Timer::Stop("MatrixStructure");
1564  }
1565 
1566  void Assemble(
1569  const LocalSystemMatrixType& LHS_Contribution,
1570  const LocalSystemVectorType& RHS_Contribution,
1571  Element::EquationIdVectorType& EquationId
1572  )
1573  {
1574  unsigned int local_size = LHS_Contribution.size1();
1575 
1576  for (unsigned int i_local = 0; i_local < local_size; i_local++) {
1577  unsigned int i_global = EquationId[i_local];
1578 
1579  double& r_a = b[i_global];
1580  const double& v_a = RHS_Contribution(i_local);
1581  AtomicAdd(r_a, v_a);
1582 
1583  AssembleRowContribution(A, LHS_Contribution, i_global, i_local, EquationId);
1584  }
1585  }
1586 
1587  //**************************************************************************
1588 
1590  TSystemMatrixType& rA,
1591  const LocalSystemMatrixType& rLHSContribution,
1592  Element::EquationIdVectorType& rEquationId
1593  )
1594  {
1595  const SizeType local_size = rLHSContribution.size1();
1596 
1597  for (IndexType i_local = 0; i_local < local_size; i_local++) {
1598  const IndexType i_global = rEquationId[i_local];
1599  AssembleRowContribution(rA, rLHSContribution, i_global, i_local, rEquationId);
1600  }
1601  }
1602 
1603  //**************************************************************************
1604 
1607  LocalSystemVectorType& RHS_Contribution,
1608  Element::EquationIdVectorType& EquationId
1609  )
1610  {
1611  unsigned int local_size = RHS_Contribution.size();
1612 
1613  for (unsigned int i_local = 0; i_local < local_size; i_local++) {
1614  unsigned int i_global = EquationId[i_local];
1615 
1616  // ASSEMBLING THE SYSTEM VECTOR
1617  double& b_value = b[i_global];
1618  const double& rhs_value = RHS_Contribution[i_local];
1619 
1620  AtomicAdd(b_value, rhs_value);
1621  }
1622  }
1623 
1624  inline void AssembleRowContribution(TSystemMatrixType& A, const Matrix& Alocal, const unsigned int i, const unsigned int i_local, Element::EquationIdVectorType& EquationId)
1625  {
1626  double* values_vector = A.value_data().begin();
1627  std::size_t* index1_vector = A.index1_data().begin();
1628  std::size_t* index2_vector = A.index2_data().begin();
1629 
1630  size_t left_limit = index1_vector[i];
1631 // size_t right_limit = index1_vector[i+1];
1632 
1633  //find the first entry
1634  size_t last_pos = ForwardFind(EquationId[0],left_limit,index2_vector);
1635  size_t last_found = EquationId[0];
1636 
1637  double& r_a = values_vector[last_pos];
1638  const double& v_a = Alocal(i_local,0);
1639  AtomicAdd(r_a, v_a);
1640 
1641  //now find all of the other entries
1642  size_t pos = 0;
1643  for (unsigned int j=1; j<EquationId.size(); j++) {
1644  unsigned int id_to_find = EquationId[j];
1645  if(id_to_find > last_found) {
1646  pos = ForwardFind(id_to_find,last_pos+1,index2_vector);
1647  } else if(id_to_find < last_found) {
1648  pos = BackwardFind(id_to_find,last_pos-1,index2_vector);
1649  } else {
1650  pos = last_pos;
1651  }
1652 
1653  double& r = values_vector[pos];
1654  const double& v = Alocal(i_local,j);
1655  AtomicAdd(r, v);
1656 
1657  last_found = id_to_find;
1658  last_pos = pos;
1659  }
1660  }
1661 
1666  void AssignSettings(const Parameters ThisParameters) override
1667  {
1668  BaseType::AssignSettings(ThisParameters);
1669 
1670  // Setting flags<
1671  const std::string& r_diagonal_values_for_dirichlet_dofs = ThisParameters["diagonal_values_for_dirichlet_dofs"].GetString();
1672 
1673  std::set<std::string> available_options_for_diagonal = {"no_scaling","use_max_diagonal","use_diagonal_norm","defined_in_process_info"};
1674 
1675  if (available_options_for_diagonal.find(r_diagonal_values_for_dirichlet_dofs) == available_options_for_diagonal.end()) {
1676  std::stringstream msg;
1677  msg << "Currently prescribed diagonal values for dirichlet dofs : " << r_diagonal_values_for_dirichlet_dofs << "\n";
1678  msg << "Admissible values for the diagonal scaling are : no_scaling, use_max_diagonal, use_diagonal_norm, or defined_in_process_info" << "\n";
1679  KRATOS_ERROR << msg.str() << std::endl;
1680  }
1681 
1682  // The first option will not consider any scaling (the diagonal values will be replaced with 1)
1683  if (r_diagonal_values_for_dirichlet_dofs == "no_scaling") {
1684  mScalingDiagonal = SCALING_DIAGONAL::NO_SCALING;
1685  } else if (r_diagonal_values_for_dirichlet_dofs == "use_max_diagonal") {
1686  mScalingDiagonal = SCALING_DIAGONAL::CONSIDER_MAX_DIAGONAL;
1687  } else if (r_diagonal_values_for_dirichlet_dofs == "use_diagonal_norm") { // On this case the norm of the diagonal will be considered
1688  mScalingDiagonal = SCALING_DIAGONAL::CONSIDER_NORM_DIAGONAL;
1689  } else { // Otherwise we will assume we impose a numerical value
1690  mScalingDiagonal = SCALING_DIAGONAL::CONSIDER_PRESCRIBED_DIAGONAL;
1691  }
1692  mOptions.Set(SILENT_WARNINGS, ThisParameters["silent_warnings"].GetBool());
1693  }
1694 
1698 
1702 
1706 
1708 
1709 private:
1712 
1716 
1720 
1724 
1725  inline void AddUnique(std::vector<std::size_t>& v, const std::size_t& candidate)
1726  {
1727  std::vector<std::size_t>::iterator i = v.begin();
1728  std::vector<std::size_t>::iterator endit = v.end();
1729  while (i != endit && (*i) != candidate) {
1730  i++;
1731  }
1732  if (i == endit) {
1733  v.push_back(candidate);
1734  }
1735  }
1736 
1737  //******************************************************************************************
1738  //******************************************************************************************
1739 
1740  inline void CreatePartition(unsigned int number_of_threads, const int number_of_rows, DenseVector<unsigned int>& partitions)
1741  {
1742  partitions.resize(number_of_threads + 1);
1743  int partition_size = number_of_rows / number_of_threads;
1744  partitions[0] = 0;
1745  partitions[number_of_threads] = number_of_rows;
1746  for (unsigned int i = 1; i < number_of_threads; i++) {
1747  partitions[i] = partitions[i - 1] + partition_size;
1748  }
1749  }
1750 
1751  inline unsigned int ForwardFind(const unsigned int id_to_find,
1752  const unsigned int start,
1753  const size_t* index_vector)
1754  {
1755  unsigned int pos = start;
1756  while(id_to_find != index_vector[pos]) pos++;
1757  return pos;
1758  }
1759 
1760  inline unsigned int BackwardFind(const unsigned int id_to_find,
1761  const unsigned int start,
1762  const size_t* index_vector)
1763  {
1764  unsigned int pos = start;
1765  while(id_to_find != index_vector[pos]) pos--;
1766  return pos;
1767  }
1768 
1772 
1776 
1780 
1784 
1786 
1787 }; /* Class ResidualBasedBlockBuilderAndSolver */
1788 
1790 
1793 
1794 // Here one should use the KRATOS_CREATE_LOCAL_FLAG, but it does not play nice with template parameters
1795 template<class TSparseSpace, class TDenseSpace, class TLinearSolver>
1796 const Kratos::Flags ResidualBasedBlockBuilderAndSolver<TSparseSpace, TDenseSpace, TLinearSolver>::SILENT_WARNINGS(Kratos::Flags::Create(0));
1797 
1799 
1800 } /* 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
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
virtual Parameters ValidateAndAssignParameters(Parameters ThisParameters, const Parameters DefaultParameters) const
This method validate and assign default parameters.
Definition: builder_and_solver.h:767
virtual void Clear()
This function is intended to be called at the end of the solution step to clean up memory storage not...
Definition: builder_and_solver.h:600
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
int GetEchoLevel() const
It returns the echo level.
Definition: builder_and_solver.h:674
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
Definition: builtin_timer.h:26
virtual int MyPID() const
Definition: communicator.cpp:91
Base class for all Conditions.
Definition: condition.h:59
Dof represents a degree of freedom (DoF).
Definition: dof.h:86
bool IsFixed() const
Definition: dof.h:376
EquationIdType EquationId() const
Definition: dof.h:324
TDataType & GetSolutionStepValue(IndexType SolutionStepIndex=0)
Definition: dof.h:256
TDataType & GetSolutionStepReactionValue(IndexType SolutionStepIndex=0)
Definition: dof.h:278
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: flags.h:58
void Set(const Flags ThisFlag)
Definition: flags.cpp:33
static Flags Create(IndexType ThisPosition, bool Value=true)
Definition: flags.h:138
bool IsNot(Flags const &rOther) const
Definition: flags.h:291
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
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
std::string & Name()
Definition: model_part.h:1811
IndexType GetBufferSize() const
This method gets the suffer size of the model part database.
Definition: model_part.h:1876
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
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class defines the node.
Definition: node.h:65
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
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
std::string GetString() const
This method returns the string contained in the current Parameter.
Definition: kratos_parameters.cpp:684
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
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector_set.h:95
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
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 builder and solving operations.
Definition: residualbased_block_builder_and_solver.h:82
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_block_builder_and_solver.h:1081
ResidualBasedBlockBuilderAndSolver()
Default constructor.
Definition: residualbased_block_builder_and_solver.h:135
BaseType::TDataType TDataType
Definition: residualbased_block_builder_and_solver.h:105
TSparseSpace::MatrixType & GetConstraintRelationMatrix() override
This method returns constraint relation (T) matrix.
Definition: residualbased_block_builder_and_solver.h:1144
KRATOS_DEFINE_LOCAL_FLAG(SILENT_WARNINGS)
Definition of the flags.
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_block_builder_and_solver.h:479
PointerVectorSet< Element, IndexedObject > ElementsContainerType
Additional definitions.
Definition: residualbased_block_builder_and_solver.h:118
double mScaleFactor
The set containing the inactive slave dofs.
Definition: residualbased_block_builder_and_solver.h:1223
void SetScaleFactor(const double ScaleFactor)
Sets the scale factor. This function sets a new value for the scale factor.
Definition: residualbased_block_builder_and_solver.h:1173
BaseType::TSystemVectorType TSystemVectorType
Definition: residualbased_block_builder_and_solver.h:108
void BuildLHS_CompleteOnFreeRows(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &A) override
Build a rectangular matrix of size n*N where "n" is the number of unrestrained degrees of freedom and...
Definition: residualbased_block_builder_and_solver.h:347
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: residualbased_block_builder_and_solver.h:1193
BaseType::TSystemMatrixPointerType TSystemMatrixPointerType
Definition: residualbased_block_builder_and_solver.h:111
BuilderAndSolver< TSparseSpace, TDenseSpace, TLinearSolver > BaseType
Definition of the base class.
Definition: residualbased_block_builder_and_solver.h:94
TSparseSpace::VectorType & GetConstraintConstantVector() override
This method returns constraint constant vector.
Definition: residualbased_block_builder_and_solver.h:1153
double GetScaleFactor()
Retrieves the current scale factor. This function returns the current scale factor value.
Definition: residualbased_block_builder_and_solver.h:1163
KRATOS_CLASS_POINTER_DEFINITION(ResidualBasedBlockBuilderAndSolver)
Definition of the pointer.
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_block_builder_and_solver.h:940
std::size_t IndexType
Definition: residualbased_block_builder_and_solver.h:101
std::vector< IndexType > mSlaveIds
This is vector containing the rigid movement of the constraint.
Definition: residualbased_block_builder_and_solver.h:1220
std::unordered_set< IndexType > mInactiveSlaveDofs
The equation ids of the master.
Definition: residualbased_block_builder_and_solver.h:1222
void AssembleRowContribution(TSystemMatrixType &A, const Matrix &Alocal, const unsigned int i, const unsigned int i_local, Element::EquationIdVectorType &EquationId)
Definition: residualbased_block_builder_and_solver.h:1624
ResidualBasedBlockBuilderAndSolver(typename TLinearSolver::Pointer pNewLinearSystemSolver, Parameters ThisParameters)
Default constructor. (with parameters)
Definition: residualbased_block_builder_and_solver.h:142
std::string Info() const override
Turn back information as a string.
Definition: residualbased_block_builder_and_solver.h:1187
BaseType::TSystemVectorPointerType TSystemVectorPointerType
Definition: residualbased_block_builder_and_solver.h:112
virtual void BuildMasterSlaveConstraints(ModelPart &rModelPart)
Definition: residualbased_block_builder_and_solver.h:1384
BaseType::ElementsArrayType ElementsArrayType
Definition: residualbased_block_builder_and_solver.h:114
void BuildRHSNoDirichlet(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemVectorType &b)
Definition: residualbased_block_builder_and_solver.h:1236
void AssembleRHS(TSystemVectorType &b, LocalSystemVectorType &RHS_Contribution, Element::EquationIdVectorType &EquationId)
Definition: residualbased_block_builder_and_solver.h:1605
SCALING_DIAGONAL mScalingDiagonal
The manually set scale factor.
Definition: residualbased_block_builder_and_solver.h:1225
virtual 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_block_builder_and_solver.h:408
~ResidualBasedBlockBuilderAndSolver() override
Definition: residualbased_block_builder_and_solver.h:162
BaseType::Pointer Create(typename TLinearSolver::Pointer pNewLinearSystemSolver, Parameters ThisParameters) const override
Create method.
Definition: residualbased_block_builder_and_solver.h:171
void AssignSettings(const Parameters ThisParameters) override
This method assigns settings to member variables.
Definition: residualbased_block_builder_and_solver.h:1666
static std::string Name()
Returns the name of the class as used in the settings (snake_case format)
Definition: residualbased_block_builder_and_solver.h:1131
DofType::Pointer DofPointerType
Definition: residualbased_block_builder_and_solver.h:126
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_block_builder_and_solver.h:710
Element::EquationIdVectorType EquationIdVectorType
Definition: residualbased_block_builder_and_solver.h:119
TSystemMatrixType mT
Definition: residualbased_block_builder_and_solver.h:1218
virtual void ConstructMasterSlaveConstraintsStructure(ModelPart &rModelPart)
Definition: residualbased_block_builder_and_solver.h:1301
BaseType::TSystemMatrixType TSystemMatrixType
Definition: residualbased_block_builder_and_solver.h:107
void InternalSystemSolveWithPhysics(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_block_builder_and_solver.h:437
void SetUpSystem(ModelPart &rModelPart) override
Organises the dofset in order to speed up the building phase.
Definition: residualbased_block_builder_and_solver.h:833
ResidualBasedBlockBuilderAndSolver< TSparseSpace, TDenseSpace, TLinearSolver > ClassType
The definition of the current class.
Definition: residualbased_block_builder_and_solver.h:97
void AssembleLHS(TSystemMatrixType &rA, const LocalSystemMatrixType &rLHSContribution, Element::EquationIdVectorType &rEquationId)
Definition: residualbased_block_builder_and_solver.h:1589
virtual void ConstructMatrixStructure(typename TSchemeType::Pointer pScheme, TSystemMatrixType &A, ModelPart &rModelPart)
Definition: residualbased_block_builder_and_solver.h:1457
BaseType::ConditionsArrayType ConditionsArrayType
Definition: residualbased_block_builder_and_solver.h:115
Element::DofsVectorType DofsVectorType
Definition: residualbased_block_builder_and_solver.h:120
void BuildLHS(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA) override
Function to perform the building of the LHS.
Definition: residualbased_block_builder_and_solver.h:271
TSystemVectorType mConstantVector
This is matrix containing the global relation for the constraints.
Definition: residualbased_block_builder_and_solver.h:1219
Node NodeType
DoF types definition.
Definition: residualbased_block_builder_and_solver.h:124
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: residualbased_block_builder_and_solver.h:1199
BaseType::LocalSystemVectorType LocalSystemVectorType
Definition: residualbased_block_builder_and_solver.h:109
void BuildRHSAndSolve(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb) override
Corresponds to the previews, but the System's matrix is considered already built and only the RHS is ...
Definition: residualbased_block_builder_and_solver.h:637
void SystemSolve(TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb) override
This is a call to the linear system solver.
Definition: residualbased_block_builder_and_solver.h:366
BaseType::DofsArrayType DofsArrayType
Definition: residualbased_block_builder_and_solver.h:106
void Build(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &b) override
Function to perform the build of the RHS. The vector could be sized as the total number of dofs or as...
Definition: residualbased_block_builder_and_solver.h:195
NodeType::DofType DofType
Definition: residualbased_block_builder_and_solver.h:125
ResidualBasedBlockBuilderAndSolver(typename TLinearSolver::Pointer pNewLinearSystemSolver)
Default constructor.
Definition: residualbased_block_builder_and_solver.h:155
boost::numeric::ublas::compressed_matrix< double > CompressedMatrixType
Definition: residualbased_block_builder_and_solver.h:121
Parameters GetDefaultParameters() const override
This method provides the defaults parameters to avoid conflicts between the different constructors.
Definition: residualbased_block_builder_and_solver.h:1111
void ApplyConstraints(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rb) override
Applies the constraints with master-slave relation matrix.
Definition: residualbased_block_builder_and_solver.h:1035
void Assemble(TSystemMatrixType &A, TSystemVectorType &b, const LocalSystemMatrixType &LHS_Contribution, const LocalSystemVectorType &RHS_Contribution, Element::EquationIdVectorType &EquationId)
Definition: residualbased_block_builder_and_solver.h:1566
int Check(ModelPart &rModelPart) override
This function is designed to be called once to perform all the checks needed on the input provided....
Definition: residualbased_block_builder_and_solver.h:1099
BaseType::NodesArrayType NodesArrayType
Definition: residualbased_block_builder_and_solver.h:113
std::size_t SizeType
Definition: residualbased_block_builder_and_solver.h:100
BaseType::LocalSystemMatrixType LocalSystemMatrixType
Definition: residualbased_block_builder_and_solver.h:110
void BuildAndSolveLinearizedOnPreviousIteration(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb, const bool MoveMesh) override
Function to perform the building and solving phase at the same time Linearizing with the database at ...
Definition: residualbased_block_builder_and_solver.h:529
void ApplyRHSConstraints(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemVectorType &rb) override
Applies the constraints with master-slave relation matrix (RHS only)
Definition: residualbased_block_builder_and_solver.h:997
BaseType::TSchemeType TSchemeType
Definition of the classes from the base class.
Definition: residualbased_block_builder_and_solver.h:104
void CalculateReactions(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b) override
It computes the reactions of the system.
Definition: residualbased_block_builder_and_solver.h:909
Flags mOptions
We identify the scaling considered for the dirichlet dofs.
Definition: residualbased_block_builder_and_solver.h:1226
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: residualbased_block_builder_and_solver.h:849
std::vector< IndexType > mMasterIds
The equation ids of the slaves.
Definition: residualbased_block_builder_and_solver.h:1221
void BuildRHS(typename TSchemeType::Pointer pScheme, ModelPart &rModelPart, TSystemVectorType &b) override
Function to perform the build of the RHS.
Definition: residualbased_block_builder_and_solver.h:678
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
This class implements a set of auxiliar, already parallelized, methods to perform some common tasks r...
Definition: variable_utils.h:63
void UpdateCurrentPosition(const ModelPart::NodesContainerType &rNodes, const ArrayVarType &rUpdateVariable=DISPLACEMENT, const IndexType BufferPosition=0)
This method updates the current coordinates For each node, this method takes the value of the provide...
Definition: variable_utils.cpp:273
#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
#define KRATOS_WARNING_IF(label, conditional)
Definition: logger.h:266
start
Definition: DEM_benchmarks.py:17
Vector VectorType
Definition: geometrical_transformation_utilities.h:56
Matrix MatrixType
Definition: geometrical_transformation_utilities.h:55
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 MoveMesh(Scheme< SparseSpaceType, LocalSpaceType > &dummy, ModelPart::NodesContainerType &rNodes)
Definition: add_strategies_to_python.cpp:175
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
SCALING_DIAGONAL
Definition: ublas_space.h:98
v
Definition: generate_convection_diffusion_explicit_element.py:114
ScaleFactor
Definition: generate_frictional_mortar_condition.py:131
int local_size
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:17
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
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
A
Definition: sensitivityMatrix.py:70
integer i
Definition: TensorModule.f:17
Definition: timer.py:1