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.
scaling_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 //
12 
13 #if !defined(KRATOS_SCALING_SOLVER_H_INCLUDED )
14 #define KRATOS_SCALING_SOLVER_H_INCLUDED
15 
16 // System includes
17 #include <cmath>
18 #include <complex>
19 
20 // External includes
21 
22 // Project includes
23 #include "includes/define.h"
26 #include "utilities/openmp_utils.h"
27 
28 namespace Kratos
29 {
30 
33 
37 
41 
45 
49 
60 template<class TSparseSpaceType, class TDenseSpaceType,
61  class TReordererType = Reorderer<TSparseSpaceType, TDenseSpaceType> >
63  : public LinearSolver<TSparseSpaceType, TDenseSpaceType, TReordererType>
64 {
65 public:
68 
71 
74 
77 
80 
83 
86 
89 
93 
96  {
97  }
98 
105  typename BaseType::Pointer pLinearSolver,
106  const bool SymmetricScaling = true
107  ) : BaseType (),
108  mpLinearSolver(pLinearSolver),
109  mSymmetricScaling(SymmetricScaling)
110  {
111  }
112 
117  ScalingSolver(Parameters ThisParameters)
118  : BaseType ()
119  {
120  KRATOS_TRY
121 
122  KRATOS_ERROR_IF_NOT(ThisParameters.Has("solver_type")) << "Solver_type must be specified to construct the ScalingSolver" << std::endl;
123 
124  mpLinearSolver = LinearSolverFactoryType().Create(ThisParameters);
125 
126  mSymmetricScaling = ThisParameters.Has("symmetric_scaling") ? ThisParameters["symmetric_scaling"].GetBool() : true;
127 
128  KRATOS_CATCH("")
129  }
130 
132  ScalingSolver(const ScalingSolver& Other) : BaseType(Other) {}
133 
134 
136  ~ScalingSolver() override {}
137 
138 
142 
145  {
146  BaseType::operator=(Other);
147  return *this;
148  }
149 
153 
160  {
161  return mpLinearSolver->AdditionalPhysicalDataIsNeeded();
162  }
163 
171  SparseMatrixType& rA,
172  VectorType& rX,
173  VectorType& rB,
174  typename ModelPart::DofsArrayType& rdof_set,
175  ModelPart& r_model_part
176  ) override
177  {
178  mpLinearSolver->ProvideAdditionalData(rA,rX,rB,rdof_set,r_model_part);
179  }
180 
182  {
183  mpLinearSolver->InitializeSolutionStep(rA,rX,rB);
184  }
185 
193  {
194  mpLinearSolver->FinalizeSolutionStep(rA,rX,rB);
195  }
196 
201  void Clear() override
202  {
203  mpLinearSolver->Clear();
204  }
205 
214  bool Solve(SparseMatrixType& rA, VectorType& rX, VectorType& rB) override
215  {
216  if(this->IsNotConsistent(rA, rX, rB))
217  return false;
218 
219  VectorType scaling_vector(rX.size());
220 
221  //obtain the scaling matrix
222  GetScalingWeights(rA,scaling_vector);
223 
224  //scale system
225  if(mSymmetricScaling == false)
226  {
227  KRATOS_THROW_ERROR(std::logic_error,"not yet implemented","")
228  }
229  else
230  {
231  IndexPartition<std::size_t>(scaling_vector.size()).for_each([&](std::size_t Index){
232  scaling_vector[Index] = sqrt(std::abs(scaling_vector[Index]));
233  });
234 
235  SymmetricScaling(rA,scaling_vector);
236 
237 
238  }
239 
240  //scale RHS
241  IndexPartition<std::size_t>(scaling_vector.size()).for_each([&](std::size_t Index){
242  rB[Index] /= scaling_vector[Index];
243  });
244 
245 
246  //solve the problem
247  bool is_solved = mpLinearSolver->Solve(rA,rX,rB);
248 
249  //backscale the solution
250  if(mSymmetricScaling == true)
251  {
252  IndexPartition<std::size_t>(scaling_vector.size()).for_each([&](std::size_t Index){
253  rX[Index] /= scaling_vector[Index];
254  });
255  }
256 
257  return is_solved;
258  }
259 
260 
261 
265 
267  {
268  return mpLinearSolver->GetIterationsNumber();
269  }
270 
271 
275 
276 
280 
282  std::string Info() const override
283  {
284  std::stringstream buffer;
285  buffer << "Composite Linear Solver. Uses internally the following linear solver " << mpLinearSolver->Info();
286  return buffer.str();
287  }
288 
290  void PrintInfo(std::ostream& rOStream) const override
291  {
292  rOStream << Info();
293  }
294 
296  void PrintData(std::ostream& rOStream) const override
297  {
298  BaseType::PrintData(rOStream);
299  }
300 
301 
305 
306 
308 
309 protected:
312 
313 
317 
318 
322 
323 
327 
328 
332 
333 
337 
338 
342 
343 
345 
346 private:
349 
350 
355  bool mSymmetricScaling;
356 
360  static void SymmetricScaling( SparseMatrixType& A, const VectorType& aux)
361  {
362  //typedef unsigned int size_type;
363  //typedef double value_type;
364 
365  //create partition
367  int number_of_threads = ParallelUtilities::GetNumThreads();
368  OpenMPUtils::DivideInPartitions(A.size1(),number_of_threads, partition);
369  //parallel loop
370 
371  #pragma omp parallel
372  {
373  int thread_id = OpenMPUtils::ThisThread();
374  int number_of_rows = partition[thread_id+1] - partition[thread_id];
375  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::index_array_type::iterator row_iter_begin = A.index1_data().begin()+partition[thread_id];
376  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::index_array_type::iterator index_2_begin = A.index2_data().begin()+*row_iter_begin;
377  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::value_array_type::iterator value_begin = A.value_data().begin()+*row_iter_begin;
378 
379  perform_matrix_scaling( number_of_rows,
380  row_iter_begin,
381  index_2_begin,
382  value_begin,
383  partition[thread_id],
384  aux
385  );
386  }
387  }
388 
392  static void perform_matrix_scaling(
393  int number_of_rows,
394  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::index_array_type::iterator row_begin,
395  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::index_array_type::iterator index2_begin,
396  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::value_array_type::iterator value_begin,
397  unsigned int output_begin_index,
398  const VectorType& weights
399  )
400  {
401  int row_size;
402  typename SparseMatrixType::index_array_type::const_iterator row_it = row_begin;
403  int kkk = output_begin_index;
404  for(int k = 0; k < number_of_rows; k++)
405  {
406  row_size= *(row_it+1)-*row_it;
407  row_it++;
408  const typename TDenseSpaceType::DataType row_weight = weights[kkk++];
409 
410  for(int i = 0; i<row_size; i++)
411  {
412  const typename TDenseSpaceType::DataType col_weight = weights[*index2_begin];
413  typename TDenseSpaceType::DataType t = (*value_begin);
414  t /= (row_weight*col_weight);
415  (*value_begin) = t; //check if this is correcct!!
416  value_begin++;
417  index2_begin++;
418  }
419 
420  }
421  }
422 
423 
424  static void GetScalingWeights( const SparseMatrixType& A, VectorType& aux)
425  {
426  //typedef unsigned int size_type;
427  //typedef double value_type;
428 
429  //create partition
431  int number_of_threads = ParallelUtilities::GetNumThreads();
432  OpenMPUtils::DivideInPartitions(A.size1(),number_of_threads, partition);
433  //parallel loop
434 
435  #pragma omp parallel
436  {
437  int thread_id = OpenMPUtils::ThisThread();
438  int number_of_rows = partition[thread_id+1] - partition[thread_id];
439  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::index_array_type::const_iterator row_iter_begin = A.index1_data().begin()+partition[thread_id];
440  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::index_array_type::const_iterator index_2_begin = A.index2_data().begin()+*row_iter_begin;
441  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::value_array_type::const_iterator value_begin = A.value_data().begin()+*row_iter_begin;
442 
443  GS2weights( number_of_rows,
444  row_iter_begin,
445  index_2_begin,
446  value_begin,
447  partition[thread_id],
448  aux
449  );
450  }
451  }
452 
456  static void GS2weights(
457  int number_of_rows,
458  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::index_array_type::const_iterator row_begin,
459  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::index_array_type::const_iterator index2_begin,
460  typename boost::numeric::ublas::compressed_matrix<typename TDenseSpaceType::DataType>::value_array_type::const_iterator value_begin,
461  unsigned int output_begin_index,
462  VectorType& weights
463  )
464  {
465  int row_size;
466  typename SparseMatrixType::index_array_type::const_iterator row_it = row_begin;
467  int kkk = output_begin_index;
468  for(int k = 0; k < number_of_rows; k++)
469  {
470  row_size= *(row_it+1)-*row_it;
471  row_it++;
472  double t = 0.0;
473 
474  for(int i = 0; i<row_size; i++)
475  {
476  double tmp = std::abs(*value_begin);
477  t += tmp*tmp;
478  value_begin++;
479  }
480  t = sqrt(t);
481  weights[kkk++] = t;
482  }
483  }
484 
485 
489 
490 
494 
495 
499 
500 
504 
505 
507 
508 }; // Class ScalingSolver
509 
511 
514 
515 
519 
520 
522 template<class TSparseSpaceType, class TDenseSpaceType,
523  class TPreconditionerType,
524  class TReordererType>
525 inline std::istream& operator >> (std::istream& IStream,
526  ScalingSolver<TSparseSpaceType, TDenseSpaceType,
527  TReordererType>& rThis)
528 {
529  return IStream;
530 }
531 
533 template<class TSparseSpaceType, class TDenseSpaceType,
534  class TPreconditionerType,
535  class TReordererType>
536 inline std::ostream& operator << (std::ostream& OStream,
537  const ScalingSolver<TSparseSpaceType, TDenseSpaceType,
538  TReordererType>& rThis)
539 {
540  rThis.PrintInfo(OStream);
541  OStream << std::endl;
542  rThis.PrintData(OStream);
543 
544  return OStream;
545 }
547 
548 
549 } // namespace Kratos.
550 
551 #endif // KRATOS_SCALING_SOLVER_H_INCLUDED defined
552 
553 
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
Here we add the functions needed for the registration of linear solvers.
Definition: linear_solver_factory.h:62
Base class for all the linear solvers in Kratos.
Definition: linear_solver.h:65
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: linear_solver.h:388
LinearSolver & operator=(const LinearSolver &Other)
Assignment operator.
Definition: linear_solver.h:112
virtual bool IsNotConsistent(SparseMatrixType &rA, VectorType &rX, VectorType &rB)
This method checks if the dimensions of the system of equations are not consistent.
Definition: linear_solver.h:346
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
static void DivideInPartitions(const int NumTerms, const int NumThreads, PartitionVector &Partitions)
Divide an array of length NumTerms between NumThreads threads.
Definition: openmp_utils.h:158
static int ThisThread()
Wrapper for omp_get_thread_num().
Definition: openmp_utils.h:108
std::vector< int > PartitionVector
Vector type for the output of DivideInPartitions method.
Definition: openmp_utils.h:53
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
bool Has(const std::string &rEntry) const
This method checks if the Parameter contains a certain entry.
Definition: kratos_parameters.cpp:520
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
This solvers rescales in order to improve the conditioning of the system.
Definition: scaling_solver.h:64
TDenseSpaceType::MatrixType DenseMatrixType
The definition of the spaces (dense matrix)
Definition: scaling_solver.h:82
KRATOS_CLASS_POINTER_DEFINITION(ScalingSolver)
Pointer definition of ScalingSolver.
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: scaling_solver.h:290
TSparseSpaceType::IndexType IndexType
The index type definition to be consistent.
Definition: scaling_solver.h:88
void ProvideAdditionalData(SparseMatrixType &rA, VectorType &rX, VectorType &rB, typename ModelPart::DofsArrayType &rdof_set, ModelPart &r_model_part) override
Definition: scaling_solver.h:170
void Clear() override
Definition: scaling_solver.h:201
~ScalingSolver() override
Destructor.
Definition: scaling_solver.h:136
TSparseSpaceType::VectorType VectorType
The definition of the spaces (vector)
Definition: scaling_solver.h:79
std::string Info() const override
Turn back information as a string.
Definition: scaling_solver.h:282
void InitializeSolutionStep(SparseMatrixType &rA, VectorType &rX, VectorType &rB) override
Definition: scaling_solver.h:181
void FinalizeSolutionStep(SparseMatrixType &rA, VectorType &rX, VectorType &rB) override
Definition: scaling_solver.h:192
ScalingSolver()
Default constructor.
Definition: scaling_solver.h:95
IndexType GetIterationsNumber() override
Definition: scaling_solver.h:266
ScalingSolver(const ScalingSolver &Other)
Copy constructor.
Definition: scaling_solver.h:132
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: scaling_solver.h:296
bool AdditionalPhysicalDataIsNeeded() override
Definition: scaling_solver.h:159
ScalingSolver & operator=(const ScalingSolver &Other)
Assignment operator.
Definition: scaling_solver.h:144
TSparseSpaceType::MatrixType SparseMatrixType
The definition of the spaces (sparse matrix)
Definition: scaling_solver.h:76
LinearSolver< TSparseSpaceType, TDenseSpaceType, TReordererType > BaseType
Definition of the base type.
Definition: scaling_solver.h:73
bool Solve(SparseMatrixType &rA, VectorType &rX, VectorType &rB) override
Definition: scaling_solver.h:214
ScalingSolver(Parameters ThisParameters)
Constructor with parameters.
Definition: scaling_solver.h:117
LinearSolverFactory< TSparseSpaceType, TDenseSpaceType > LinearSolverFactoryType
The definition of the linear solver factory type.
Definition: scaling_solver.h:85
ScalingSolver(typename BaseType::Pointer pLinearSolver, const bool SymmetricScaling=true)
Constructor without parameters.
Definition: scaling_solver.h:104
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
std::size_t IndexType
Definition: binary_expression.cpp:25
Vector VectorType
Definition: geometrical_transformation_utilities.h:56
Matrix MatrixType
Definition: geometrical_transformation_utilities.h:55
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
def Index()
Definition: hdf5_io_tools.py:38
int t
Definition: ode_solve.py:392
int k
Definition: quadrature.py:595
A
Definition: sensitivityMatrix.py:70
integer i
Definition: TensorModule.f:17