Skip to content
Snippets Groups Projects
Commit 408c0310 authored by Oliver Sander's avatar Oliver Sander Committed by sander
Browse files

Start using a dedicated implementation of a symmetric matrix

[[Imported from SVN: r9582]]
parent 26d119b2
No related branches found
No related tags found
No related merge requests found
......@@ -2,8 +2,8 @@
#define DUNE_GFE_GRAMSCHMIDTSOLVER_HH
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>
#include <dune/gfe/symmetricmatrix.hh>
/** \brief Direct solver for a dense symmetric linear system, using an orthonormal basis
*
......@@ -24,16 +24,10 @@ class GramSchmidtSolver
* \param matrix The matrix inducing the matrix norm
* \param[in,out] v The vector to normalize
*/
static void normalize(const Dune::FieldMatrix<field_type,embeddedDim,embeddedDim>& matrix,
static void normalize(const Dune::SymmetricMatrix<field_type,embeddedDim>& matrix,
Dune::FieldVector<field_type,embeddedDim>& v)
{
field_type energyNormSquared = 0;
for (int i=0; i<v.size(); i++)
for (int j=0; j<v.size(); j++)
energyNormSquared += matrix[i][j]*v[i]*v[j];
v /= std::sqrt(energyNormSquared);
v /= std::sqrt(matrix.energyScalarProduct(v,v));
}
......@@ -41,16 +35,12 @@ class GramSchmidtSolver
*
* \param matrix The matrix the defines the scalar product
*/
static void project(const Dune::FieldMatrix<field_type,embeddedDim,embeddedDim>& matrix,
static void project(const Dune::SymmetricMatrix<field_type,embeddedDim>& matrix,
const Dune::FieldVector<field_type,embeddedDim>& vi,
Dune::FieldVector<field_type,embeddedDim>& vj)
{
field_type energyScalarProduct = 0;
for (int i=0; i<vi.size(); i++)
for (int j=0; j<vj.size(); j++)
energyScalarProduct += matrix[i][j]*vi[i]*vj[j];
field_type energyScalarProduct = matrix.energyScalarProduct(vi,vj);
for (int i=0; i<vj.size(); i++)
vj[i] -= energyScalarProduct * vi[i];
......@@ -59,7 +49,7 @@ class GramSchmidtSolver
public:
/** Solve linear system by constructing an energy-orthonormal basis */
static void solve(const Dune::FieldMatrix<field_type,embeddedDim,embeddedDim>& matrix,
static void solve(const Dune::SymmetricMatrix<field_type,embeddedDim>& matrix,
Dune::FieldVector<field_type,embeddedDim>& x,
const Dune::FieldVector<field_type,embeddedDim>& rhs,
const Dune::FieldMatrix<field_type,dim,embeddedDim>& basis)
......
#ifndef DUNE_GFE_SYMMETRICMATRIX_HH
#define DUNE_GFE_SYMMETRICMATRIX_HH
#include <dune/common/fvector.hh>
namespace Dune {
/** \brief A class implementing a symmetric matrix with compile-time size
*
* A \f$ dim\times dim \f$ matrix is stored internally as a <tt>Dune::FieldVector<double, dim*(dim+1)/2></tt>
* The components are assumed to be \f$ [ E(1,1),\ E(2,1),\ E(2,2),\ E(3,1),\ E(3,2),\ E(3,3) ]\f$
* and analogous for other dimensions
* \tparam dim number of lines/columns of the matrix
*/
template <class T, int N>
class SymmetricMatrix
{
public:
/** \brief Default constructor
*
* Tensor is initialized containing zeros if no argument is given.
* \param eye if true tensor is initialized as identity
*/
SymmetricMatrix()
{}
/** \brief Matrix style random read/write access to components
* \param i line index
* \param j column index
* \note You need to know what you are doing: You can only access the lower
* left triangular submatrix using this methods. It requires i<=j.
*/
T& operator() (int i, int j)
{
assert(i>=j);
return data_[i*(i+1)/2+j];
}
/** \brief Matrix style random read access to components
* \param i line index
* \param j column index
* \note You need to know what you are doing: You can only access the lower
* left triangular submatrix using this methods. It requires i<=j.
*/
const T& operator() (int i, int j) const
{
assert(i>=j);
return data_[i*(i+1)/2+j];
}
T energyScalarProduct (const FieldVector<T,N>& v1, const FieldVector<T,N>& v2) const
{
T result = 0;
for (size_t i=0; i<N; i++)
for (size_t j=0; j<=i; j++)
result += (1+(i!=j)) * operator()(i,j) * v1[i] * v2[j];
return result;
}
private:
Dune::FieldVector<T,N*(N+1)/2> data_;
};
}
#endif
......@@ -107,8 +107,14 @@ void TargetSpaceRiemannianTRSolver<TargetSpace>::solve()
#ifdef USE_GAUSS_SEIDEL_SOLVER
innerSolver_->solve();
#else
Dune::SymmetricMatrix<field_type, embeddedBlocksize> symmetricHessian;
for (size_t j=0; j<embeddedBlocksize; j++)
for (size_t k=0; k<=j; k++)
symmetricHessian(j,k) = hesseMatrix[0][0][j][k];
Dune::FieldMatrix<field_type,blocksize,embeddedBlocksize> basis = x_.orthonormalFrame();
GramSchmidtSolver<field_type, blocksize, embeddedBlocksize>::solve(hesseMatrix[0][0], corr[0], rhs[0], basis);
GramSchmidtSolver<field_type, blocksize, embeddedBlocksize>::solve(symmetricHessian, corr[0], rhs[0], basis);
#endif
#ifdef USE_GAUSS_SEIDEL_SOLVER
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment