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.
rayleigh_quotient_iteration_eigenvalue_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: Pooyan Dadvand
11 // Collaborator: Vicente Mataix Ferrandiz
12 //
13 //
14 
15 #if !defined(KRATOS_RAYLEIGH_QUOTIENT_ITERATION_EIGENVALUE_SOLVER_H_INCLUDED )
16 #define KRATOS_RAYLEIGH_QUOTIENT_ITERATION_EIGENVALUE_SOLVER_H_INCLUDED
17 
18 // System includes
19 #include <string>
20 #include <iostream>
21 #include <numeric>
22 #include <vector>
23 
24 // External includes
25 
26 // Project includes
27 #include "includes/define.h"
31 
32 namespace Kratos
33 {
36 
40 
44 
48 
52 
61 template<class TSparseSpaceType, class TDenseSpaceType, class TLinearSolverType,
62  class TPreconditionerType = Preconditioner<TSparseSpaceType, TDenseSpaceType>,
63  class TReordererType = Reorderer<TSparseSpaceType, TDenseSpaceType> >
64 class RayleighQuotientIterationEigenvalueSolver : public IterativeSolver<TSparseSpaceType, TDenseSpaceType, TPreconditionerType, TReordererType>
65 {
66 public:
69 
72 
75 
78 
81 
84 
87 
89  typedef std::size_t SizeType;
90 
92  typedef std::size_t IndexType;
93 
97 
100  {
101 
102  }
103 
112  double NewMaxTolerance,
113  unsigned int NewMaxIterationsNumber,
114  unsigned int NewRequiredEigenvalueNumber,
115  typename TLinearSolverType::Pointer pLinearSolver,
116  double ShiftingConvergence = 0.25
117  ): BaseType(NewMaxTolerance, NewMaxIterationsNumber),
118  mRequiredEigenvalueNumber(NewRequiredEigenvalueNumber),
119  mpLinearSolver(pLinearSolver),
120  mShiftingConvergence(ShiftingConvergence)
121  {
122 
123  }
124 
131  Parameters ThisParameters,
132  typename TLinearSolverType::Pointer pLinearSolver
133  ): mpLinearSolver(pLinearSolver)
134  {
135  Parameters DefaultParameters = Parameters(R"(
136  {
137  "solver_type" : "rayleigh_quotient_iteration_eigenvalue_solver",
138  "max_iteration" : 500,
139  "tolerance" : 1e-9,
140  "required_eigen_number" : 1,
141  "shifting_convergence" : 0.25,
142  "verbosity" : 1,
143  "linear_solver_settings" : {}
144  })" );
145 
146  ThisParameters.ValidateAndAssignDefaults(DefaultParameters);
147 
148  mRequiredEigenvalueNumber = ThisParameters["required_eigen_number"].GetInt();
149  mShiftingConvergence = ThisParameters["shifting_convergence"].GetDouble();
150  mEchoLevel = ThisParameters["verbosity"].GetInt();
151  BaseType::SetTolerance( ThisParameters["tolerance"].GetDouble() );
152  BaseType::SetMaxIterationsNumber( ThisParameters["max_iteration"].GetInt() );
153  }
154 
158  BaseType(Other),
159  mRequiredEigenvalueNumber(Other.mRequiredEigenvalueNumber), mpLinearSolver(Other.mpLinearSolver),
160  mShiftingConvergence(Other.mShiftingConvergence)
161  {
162 
163  }
164 
167 
171 
174  {
175  BaseType::operator=(Other);
176  return *this;
177  }
178 
182 
189  static void InitializeSystem(
190  VectorType& rR,
191  const SparseMatrixType& rM
192  )
193  {
194  const SizeType size_m = rM.size1();
195 
196  // Resize in case of not same size
197  if (rR.size() != size_m)
198  rR.resize(size_m);
199 
200  IndexPartition<std::size_t>(size_m).for_each([&](std::size_t Index){
201  rR[Index] = rM(Index, Index);
202  });
203 
204  KRATOS_ERROR_IF(norm_2(rR) == 0.0) << "Invalid M matrix. The norm2 of its diagonal is Zero" << std::endl;
205 
206  rR /= norm_2(rR);
207  }
208 
214  {
215  // define an object to store skyline matrix and factorization
217 
218  // copy myMatrix into skyline format
219  myFactorization.copyFromCSRMatrix(ShiftedK);
220 
221  // factorize it
222  myFactorization.factorize();
223  SizeType counter = 0; // number of eigenvalues less than the shift
224  for(SizeType i = 0 ; i < ShiftedK.size1() ; i++){
225  if(myFactorization.entriesD[i] < 0.0) {
226  counter++;
227  }
228  }
229 
230  return counter;
231  }
232 
240  void Solve(
242  SparseMatrixType& M,
243  DenseVectorType& Eigenvalues,
244  DenseMatrixType& Eigenvectors
245  ) override
246  {
247  SizeType size = K.size1();
248  SizeType max_iteration = BaseType::GetMaxIterationsNumber();
249  double tolerance = BaseType::GetTolerance();
250 
251  VectorType x = boost::numeric::ublas::zero_vector<double>(size);
252  VectorType y = boost::numeric::ublas::zero_vector<double>(size);
253 
254  InitializeSystem(y,M);
255 
256  if(Eigenvalues.size() < 1) {
257  Eigenvalues.resize(1,0.0);
258  }
259 
260  const double epsilon = 1.0e-9;
261  // Starting with first step
262  double beta = 0.0;
263  double ro = 0.0;
264  double shift_value = 0.0;
265  double old_ro = 0.0;//Eigenvalues[0];
266 
267  KRATOS_INFO_IF("RayleighQuotientIterationEigenvalueSolver", mEchoLevel > 1) << "Iteration beta \t ro \t\t convergence norm \t min \t\t max" << std::endl;
268 
269  SparseMatrixType shifted_k(K);
270  // define an object to store skyline matrix and factorization
272 
273  // Copy myMatrix into skyline format
274  my_factorization.copyFromCSRMatrix(shifted_k);
275 
276  // Factorize it
277  my_factorization.factorize();
278 
279  double min_shift_value = 0.0;
280  double max_shift_value = 0.0;
281 
282  SizeType smaller_eigenvalue_numbers = 0;
283 
284  for(SizeType i = 0 ; i < max_iteration ; ++i) {
285  //K*x = y
286  //mpLinearSolver->Solve(shifted_k,x,y);
287  my_factorization.backForwardSolve(size, y, x);
288 
289  ro = inner_prod(y,x);
290 
291  //y = M*x
293 
294  beta = inner_prod(x, y);
295  KRATOS_ERROR_IF(beta == 0.0) << "Zero beta norm!" << std::endl;
296 
297  const double delta_ro = (ro / beta);
298 
299  ro = delta_ro + shift_value;
300 
301  KRATOS_ERROR_IF(ro == 0.0) << "Perpendicular eigenvector to M" << std::endl;
302 
303  double convergence_norm = std::abs((ro - old_ro) / ro);
304 
305  if(convergence_norm < mShiftingConvergence) { // Start shifting after certain convergence
306  // If there are no smaller eigenvalues yet we need to extend the range
307  if(smaller_eigenvalue_numbers == 0) {
308  max_shift_value = ro;
309  }
310 
311  if((ro > max_shift_value)||(ro < min_shift_value)) {
312  shift_value = (max_shift_value + min_shift_value) / 2.0;
313  } else {
314  shift_value = ro;
315  }
316 
317  SparseMatrixMultiplicationUtility::MatrixAdd<SparseMatrixType, SparseMatrixType>(shifted_k, M, - shift_value);
318 
319  // Copy myMatrix into skyline format
320  my_factorization.copyFromCSRMatrix(shifted_k);
321 
322  // Factorize it
323  my_factorization.factorize();
324 
325  SizeType new_smaller_eigenvalue_numbers = SturmSequenceCheck(shifted_k);
326 
327  if(new_smaller_eigenvalue_numbers == 0) {
328  min_shift_value = shift_value;
329  } else {
330  max_shift_value = shift_value;
331  smaller_eigenvalue_numbers = new_smaller_eigenvalue_numbers;
332  }
333 
334  unsigned int iteration_number = 0;
335  unsigned int max_shift_number = 4;
336 
337  while((smaller_eigenvalue_numbers > 1) && (max_shift_value-min_shift_value > epsilon) && (iteration_number++ < max_shift_number)) {
338  shift_value = (max_shift_value + min_shift_value) / 2.0;
339  shifted_k = K;
340  SparseMatrixMultiplicationUtility::MatrixAdd<SparseMatrixType, SparseMatrixType>(shifted_k, M, - shift_value);
341 
342  // Copy myMatrix into skyline format
343  my_factorization.copyFromCSRMatrix(shifted_k);
344 
345  // Factorize it
346  my_factorization.factorize();
347 
348  new_smaller_eigenvalue_numbers = SturmSequenceCheck(shifted_k);
349 
350  if(new_smaller_eigenvalue_numbers == 0) {
351  min_shift_value = shift_value;
352  KRATOS_INFO_IF("RayleighQuotientIterationEigenvalueSolver", mEchoLevel > 1) << " Finding " << smaller_eigenvalue_numbers << " eigenvalues in [" << min_shift_value << "," << max_shift_value << "]" << std::endl;
353  } else {
354  max_shift_value = shift_value;
355  smaller_eigenvalue_numbers = new_smaller_eigenvalue_numbers;
356  KRATOS_INFO_IF("RayleighQuotientIterationEigenvalueSolver", mEchoLevel > 1) << " Finding " << smaller_eigenvalue_numbers << " eigenvalues in [" << min_shift_value << "," << max_shift_value << "]" << std::endl;
357  }
358  }
359 
360  }
361 
362  if(beta < 0.0) {
363  beta = -std::sqrt(-beta);
364  } else {
365  beta = std::sqrt(beta);
366  }
367 
368  TSparseSpaceType::InplaceMult(y, 1.0/beta);
369 
370  KRATOS_INFO_IF("RayleighQuotientIterationEigenvalueSolver", mEchoLevel > 1) << i << " \t " << beta << " \t " << ro << " \t " << convergence_norm << " \t\t " << min_shift_value << " \t " << max_shift_value << std::endl;
371 
372  if(convergence_norm < tolerance) {
373  break;
374  }
375 
376  old_ro = ro;
377  }
378 
379  KRATOS_INFO_IF("RayleighQuotientIterationEigenvalueSolver", mEchoLevel > 0) << "ro:\n" << ro << std::endl << std::endl << "y:\n" << y << std::endl;
380 
381  Eigenvalues[0] = ro;
382 
383  if((Eigenvectors.size1() < 1) || (Eigenvectors.size2() < size)) {
384  Eigenvectors.resize(1,size);
385  }
386 
387  for(SizeType i = 0 ; i < size ; i++) {
388  Eigenvectors(0,i) = x[i] / beta;
389  }
390  }
391 
395 
396 
400 
401 
405 
407  std::string Info() const override
408  {
409  std::stringstream buffer;
410  buffer << "Power iteration eigenvalue solver with " << BaseType::GetPreconditioner()->Info();
411  return buffer.str();
412  }
413 
415  void PrintInfo(std::ostream& rOStream) const override
416  {
417  rOStream << Info();
418  }
419 
421  void PrintData(std::ostream& rOStream) const override
422  {
423  BaseType::PrintData(rOStream);
424  }
425 
429 
430 
432 
433 protected:
436 
437 
441 
442 
446 
447 
451 
452 
456 
457 
461 
462 
466 
467 
469 
470 private:
473 
474 
478 
479  unsigned int mRequiredEigenvalueNumber;
480 
481  unsigned int mEchoLevel;
482 
483  typename TLinearSolverType::Pointer mpLinearSolver;
484 
485  double mShiftingConvergence;
486 
487  std::vector<DenseVectorType> mQVector;
488  std::vector<DenseVectorType> mPVector;
489  std::vector<DenseVectorType> mRVector;
490 
494 
495 
499 
500 
504 
505 
509 
510 
514 
515 
517 
518 }; // Class RayleighQuotientIterationEigenvalueSolver
520 
523 
524 
528 
529 
531 template<class TSparseSpaceType, class TDenseSpaceType,
532  class TPreconditionerType,
533  class TReordererType>
534 inline std::istream& operator >> (std::istream& IStream,
535  RayleighQuotientIterationEigenvalueSolver<TSparseSpaceType, TDenseSpaceType,
536  TPreconditionerType, TReordererType>& rThis)
537 {
538  return IStream;
539 }
540 
542 template<class TSparseSpaceType, class TDenseSpaceType,
543  class TPreconditionerType,
544  class TReordererType>
545 inline std::ostream& operator << (std::ostream& OStream,
546  const RayleighQuotientIterationEigenvalueSolver<TSparseSpaceType, TDenseSpaceType,
547  TPreconditionerType, TReordererType>& rThis)
548 {
549  rThis.PrintInfo(OStream);
550  OStream << std::endl;
551  rThis.PrintData(OStream);
552 
553  return OStream;
554 }
556 
557 
558 } // namespace Kratos.
559 
560 #endif // KRATOS_RAYLEIGH_QUOTIENT_ITERATION_EIGENVALUE_SOLVER_H_INCLUDED defined
561 
562 
563 
564 
565 
566 
567 
568 
569 
570 
571 
572 
573 
574 
575 
576 
577 
578 
579 
580 
581 
582 
583 
584 
585 
586 
587 
588 
589 
590 
591 
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
Base class for all the iterative solvers in Kratos.
Definition: iterative_solver.h:68
void SetTolerance(double NewTolerance) override
This method allows to set the tolerance in the linear solver.
Definition: iterative_solver.h:305
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: iterative_solver.h:360
virtual void SetMaxIterationsNumber(unsigned int NewMaxIterationsNumber)
Definition: iterative_solver.h:285
IterativeSolver & operator=(const IterativeSolver &Other)
Assignment operator.
Definition: iterative_solver.h:176
virtual IndexType GetMaxIterationsNumber()
Definition: iterative_solver.h:290
double GetTolerance() override
This method allows to get the tolerance in the linear solver.
Definition: iterative_solver.h:310
virtual TPreconditionerType::Pointer GetPreconditioner(void)
Definition: iterative_solver.h:260
Definition: skyline_lu_factorization_solver.h:30
void copyFromCSRMatrix(SparseMatrixType &A)
Definition: skyline_lu_factorization_solver.h:68
void factorize()
Definition: skyline_lu_factorization_solver.h:404
double * entriesD
Definition: skyline_lu_factorization_solver.h:46
void backForwardSolve(int vector_size, const VectorType &b, VectorType &x)
Definition: skyline_lu_factorization_solver.h:496
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
double GetDouble() const
This method returns the double contained in the current Parameter.
Definition: kratos_parameters.cpp:657
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
void ValidateAndAssignDefaults(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing match the form prescribed by th...
Definition: kratos_parameters.cpp:1306
This is a eigen solver based on the Rayleigh quotient iteration algorithm.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:65
std::size_t SizeType
The size type definiton.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:89
std::size_t IndexType
The index type definition.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:92
void Solve(SparseMatrixType &K, SparseMatrixType &M, DenseVectorType &Eigenvalues, DenseMatrixType &Eigenvectors) override
The Rayleigh quotient iteration method.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:240
RayleighQuotientIterationEigenvalueSolver(double NewMaxTolerance, unsigned int NewMaxIterationsNumber, unsigned int NewRequiredEigenvalueNumber, typename TLinearSolverType::Pointer pLinearSolver, double ShiftingConvergence=0.25)
The "manual" settings constructor.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:111
RayleighQuotientIterationEigenvalueSolver(Parameters ThisParameters, typename TLinearSolverType::Pointer pLinearSolver)
The parameters constructor.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:130
virtual ~RayleighQuotientIterationEigenvalueSolver()
Destructor.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:166
static void InitializeSystem(VectorType &rR, const SparseMatrixType &rM)
This method initializes the system.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:189
RayleighQuotientIterationEigenvalueSolver()
Default constructor.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:99
RayleighQuotientIterationEigenvalueSolver & operator=(const RayleighQuotientIterationEigenvalueSolver &Other)
Assignment operator.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:173
SizeType SturmSequenceCheck(SparseMatrixType &ShiftedK)
This method performs a Sturm Sequence Check.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:213
KRATOS_CLASS_POINTER_DEFINITION(RayleighQuotientIterationEigenvalueSolver)
Pointer definition of RayleighQuotientIterationEigenvalueSolver.
TDenseSpaceType::VectorType DenseVectorType
The "dense" vector definition.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:86
std::string Info() const override
Turn back information as a string.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:407
RayleighQuotientIterationEigenvalueSolver(const RayleighQuotientIterationEigenvalueSolver &Other)
Copy constructor.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:156
TDenseSpaceType::MatrixType DenseMatrixType
The dense matrix definition.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:83
TSparseSpaceType::VectorType VectorType
The vector definition ("sparse")
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:80
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:421
IterativeSolver< TSparseSpaceType, TDenseSpaceType, TPreconditionerType, TReordererType > BaseType
The base class definition.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:74
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:415
TSparseSpaceType::MatrixType SparseMatrixType
The sparse matrix defintion.
Definition: rayleigh_quotient_iteration_eigenvalue_solver.h:77
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_INFO_IF(label, conditional)
Definition: logger.h:251
Vector VectorType
Definition: geometrical_transformation_utilities.h:56
Matrix MatrixType
Definition: geometrical_transformation_utilities.h:55
LinearSolver< TSpaceType< TDataType >, TLocalSpaceType< TOtherDataType > > TLinearSolverType
Definition: add_linear_solvers_to_python.cpp:50
void Mult(TSpaceType &dummy, typename TSpaceType::MatrixType &rA, typename TSpaceType::VectorType &rX, typename TSpaceType::VectorType &rY)
Definition: add_strategies_to_python.cpp:98
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
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
y
Other simbols definition.
Definition: generate_axisymmetric_navier_stokes_element.py:54
def Index()
Definition: hdf5_io_tools.py:38
int counter
Definition: script_THERMAL_CORRECT.py:218
x
Definition: sensitivityMatrix.py:49
K
Definition: sensitivityMatrix.py:73
integer i
Definition: TensorModule.f:17