iMSTK
Interactive Medical Simulation Toolkit
imstkGaussSeidel.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkGaussSeidel.h"
8 #include "imstkLogger.h"
9 
10 namespace imstk
11 {
12 GaussSeidel::GaussSeidel(const SparseMatrixd& A, const Vectord& rhs) : GaussSeidel()
13 {
14  this->setSystem(std::make_shared<LinearSystem<SparseMatrixd>>(A, rhs));
15 }
16 
17 void
18 GaussSeidel::solve(Vectord& x)
19 {
20  if (!m_linearSystem)
21  {
22  LOG(WARNING) << "Gauss-Seidel::solve: Linear system is not supplied for Gauss-Seidel solver!";
23  return;
24  }
25 
26  if (!m_FixedLinearProjConstraints)
27  {
28  this->gaussSeidelSolve(x);
29  }
30  else
31  {
32  // Do nothing for now!
33  }
34 }
35 
36 void
37 GaussSeidel::solve(Vectord& x, const double tolerance)
38 {
39  this->setTolerance(tolerance);
40  this->solve(x);
41 }
42 
43 void
45 {
46  const auto& b = m_linearSystem->getRHSVector();
47  const auto& A = m_linearSystem->getMatrix();
48 
49  // Set the initial guess to zero
50  x.setZero();
51 
52  auto xOld = x;
53  size_t iterNum = 0;
54  while (iterNum < this->getMaxNumIterations())
55  {
56  for (auto k = 0; k < A.outerSize(); ++k)
57  {
58  double diagEle = 0.;
59  double aggregate = 0.;
60  for (SparseMatrixd::InnerIterator it(A, k); it; ++it)
61  {
62  auto col = it.col();
63  if (k != col)
64  {
65  aggregate += it.value() * x[col];
66  }
67  else
68  {
69  diagEle = it.value();
70  }
71  }
72  x[k] = (b[k] - aggregate) / diagEle; // div by zero is possible!
73  }
74 
75  if ((x - xOld).norm() < 1.0e-4)
76  {
77  return;
78  }
79  xOld = x;
80  iterNum++;
81  }
82 }
83 
84 double
85 GaussSeidel::getResidual(const Vectord&)
86 {
87  return 0;
88 }
89 
90 void
91 GaussSeidel::setTolerance(const double epsilon)
92 {
94 }
95 
96 void
97 GaussSeidel::setMaxNumIterations(const size_t maxIter)
98 {
100 }
101 
102 void
104 {
106 }
107 
108 void
110 {
112 
113  LOG(INFO) << "Solver: Gauss-Seidel";
114  LOG(INFO) << "Tolerance: " << m_tolerance;
115  LOG(INFO) << "max. iterations: " << m_maxIterations;
116 }
117 } // namespace imstk
void setTolerance(const double tolerance)
Set solver tolerance.
void setSystem(std::shared_ptr< LinearSystemType > newSystem) override
Sets the system. System of linear equations.
virtual void setMaxNumIterations(const size_t maxIter) override
set/get the maximum number of iterations for the iterative solver.
void print() const override
Print solver information.
Compound Geometry.
void gaussSeidelSolve(Vectord &x)
Do one iteration of the method.
virtual void setMaxNumIterations(const size_t maxIter)
Do one iteration of the method.
void print() const override
Print solver information.
Represents the linear system of the form .
void solve(Vectord &x) override
Solve the system of equations.
void setTolerance(const double tolerance)
Set solver tolerance.
double getResidual(const Vectord &x) override
Return the error calculated by the solver.
virtual void setSystem(std::shared_ptr< LinearSystemType > newSystem)
Set/get the system. Replaces/Returns the stored linear system of equations.