DUNE PDELab (2.7)

dynmatrixev.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_DYNMATRIXEIGENVALUES_HH
4#define DUNE_DYNMATRIXEIGENVALUES_HH
5
6#include <algorithm>
7#include <memory>
8
9#include "dynmatrix.hh"
10#include "fmatrixev.hh"
11
20namespace Dune {
21
22 namespace DynamicMatrixHelp {
23
24 using Dune::FMatrixHelp::eigenValuesNonsymLapackCall;
25
34 template <typename K, class C>
35 static void eigenValuesNonSym(const DynamicMatrix<K>& matrix,
36 DynamicVector<C>& eigenValues,
37 std::vector<DynamicVector<K>>* eigenVectors = nullptr
38 )
39 {
40 {
41 const long int N = matrix.rows();
42 const char jobvl = 'n';
43 const char jobvr = eigenVectors ? 'v' : 'n';
44
45
46 // matrix to put into dgeev
47 auto matrixVector = std::make_unique<double[]>(N*N);
48
49 // copy matrix
50 int row = 0;
51 for(int i=0; i<N; ++i)
52 {
53 for(int j=0; j<N; ++j, ++row)
54 {
55 matrixVector[ row ] = matrix[ i ][ j ];
56 }
57 }
58
59 // working memory
60 auto eigenR = std::make_unique<double[]>(N);
61 auto eigenI = std::make_unique<double[]>(N);
62
63 const long int lwork = eigenVectors ? 4*N : 3*N;
64 auto work = std::make_unique<double[]>(lwork);
65 auto vr = eigenVectors ? std::make_unique<double[]>(N*N) : std::unique_ptr<double[]>{};
66
67 // return value information
68 long int info = 0;
69
70 // call LAPACK routine (see fmatrixev_ext.cc)
71 eigenValuesNonsymLapackCall(&jobvl, &jobvr, &N, matrixVector.get(), &N,
72 eigenR.get(), eigenI.get(), nullptr, &N, vr.get(), &N, work.get(),
73 &lwork, &info);
74
75 if( info != 0 )
76 {
77 std::cerr << "For matrix " << matrix << " eigenvalue calculation failed! " << std::endl;
78 DUNE_THROW(InvalidStateException,"eigenValues: Eigenvalue calculation failed!");
79 }
80
81 eigenValues.resize(N);
82 for (int i=0; i<N; ++i)
83 eigenValues[i] = std::complex<double>(eigenR[i], eigenI[i]);
84
85 if (eigenVectors) {
86 eigenVectors->resize(N);
87 for (int i = 0; i < N; ++i) {
88 auto& v = (*eigenVectors)[i];
89 v.resize(N);
90 std::copy(vr.get() + N*i, vr.get() + N*(i+1), &v[0]);
91 }
92 }
93 }
94 }
95
96 }
97
98}
100#endif
size_type rows() const
number of rows
Definition: densematrix.hh:736
Construct a matrix with a dynamic size.
Definition: dynmatrix.hh:59
Construct a vector with a dynamic size.
Definition: dynvector.hh:57
Default exception if a function was called while the object is not in a valid state for that function...
Definition: exceptions.hh:279
This file implements a dense matrix with dynamic numbers of rows and columns.
static void eigenValuesNonSym(const DynamicMatrix< K > &matrix, DynamicVector< C > &eigenValues, std::vector< DynamicVector< K > > *eigenVectors=nullptr)
calculates the eigenvalues of a symmetric field matrix
Definition: dynmatrixev.hh:35
Eigenvalue computations for the FieldMatrix class.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Dune namespace.
Definition: alignedallocator.hh:14
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)