Skip to content
Snippets Groups Projects
maxeigenvalue.hh 1.79 KiB
Newer Older
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_TECTONIC_UTILS_MAXEIGENVALUES_HH
#define DUNE_TECTONIC_UTILS_MAXEIGENVALUES_HH

/** \file
 * \brief max eigenvalue computations for the FieldMatrix class
 */

#include <iostream>
#include <cmath>

#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>
#include <dune/common/fmatrixev.hh>

template <typename K>
static K maxEigenvalue(const Dune::FieldMatrix<K, 1, 1>& matrix) {
    return matrix[0][0];
}

/** \brief calculates the eigenvalues of a symmetric field matrix
    \param[in]  matrix matrix eigenvalues are calculated for
    \param[out] max eigenvalue
*/
template <typename K>
static K maxEigenvalue(const Dune::FieldMatrix<K, 2, 2>& matrix) {
    const K p = 0.5 * (matrix[0][0] + matrix [1][1]);
    const K p2 = p - matrix[1][1];
    K q = p2 * p2 + matrix[1][0] * matrix[0][1];
    if( q < 0 && q > -1e-14 ) q = 0;
    if (q < 0) {
        std::cout << matrix << std::endl;
        // Complex eigenvalues are either caused by non-symmetric matrices or by round-off errors
        DUNE_THROW(Dune::MathError, "Complex eigenvalue detected (which this implementation cannot handle).");
    }

    // get square root
    q = std::sqrt(q);

    return p + q;
}

/** \brief Calculates the eigenvalues of a symmetric 3x3 field matrix
    \param[in]  matrix eigenvalues are calculated for
    \param[out] max eigenvalue

    \note If the input matrix is not symmetric the behavior of this method is undefined.
 */
template <typename K>
static K maxEigenvalue(const Dune::FieldMatrix<K, 3, 3>& matrix) {
    Dune::FieldVector<K, 3> eigenvalues;
    Dune::FMatrixHelp::eigenValues(matrix, eigenvalues);
    return eigenvalues[0];
}

  /** @} end documentation */

#endif