BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
fn_BZ_eigen.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California,
4 * through Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
12#ifndef BELFEM_FN_BZ_EIGEN_HPP
13#define BELFEM_FN_BZ_EIGEN_HPP
14#include <blaze/util/typetraits/IsComplex.h>
15
16#include "typedefs.hpp"
17#include "assert.hpp"
18#include "cl_BZ_Vector.hpp"
19#include "cl_BZ_Matrix.hpp"
20
21namespace belfem
22{
23//------------------------------------------------------------------------------
24
25 inline int_t
26 eigen( const Matrix< real > & aMatrix,
27 Vector< real > & aValues,
28 const bool aAbortOnComplex = true )
29 {
30 BELFEM_ASSERT( aMatrix.n_cols() == aMatrix.n_rows(),
31 "Matrix must be quadratic");
32
33 blaze::DynamicVector<blaze::complex<real>, blaze::columnVector > tValues ;
34 blaze::eigen( aMatrix.matrix_data(), tValues );
35
36 size_t tN = aMatrix.n_cols() ;
37 aValues.set_size( aMatrix.n_cols() );
38
39 int_t tNumComplex = 0 ;
40
41 for( size_t k=0; k<tN; ++k )
42 {
43 if( std::abs( std::imag( tValues[ k ] ) ) > BELFEM_EPSILON )
44 {
45 BELFEM_ERROR( ! aAbortOnComplex,
46 "eigen(): eigenvalue %u of this matrix is complex ( %g %+g i ), and a real "
47 "Vector cannot hold it. Use eigen_sym() if the matrix is symmetric, or pass "
48 "aAbortOnComplex = false to receive a count and NaN entries instead.",
49 ( unsigned int ) k,
50 ( double ) std::real( tValues[ k ] ),
51 ( double ) std::imag( tValues[ k ] ) );
52
53 aValues( k ) = BELFEM_QUIET_NAN ;
54 ++tNumComplex ;
55 }
56 else
57 {
58 aValues( k ) = std::real( tValues[ k ] );
59 }
60 }
61
62 return tNumComplex ;
63 }
64
65//------------------------------------------------------------------------------
66
67 inline void
68 eigen_sym( const Matrix< real > & aMatrix,
69 Vector< real > & aValues )
70 {
71 BELFEM_ASSERT( aMatrix.n_cols() == aMatrix.n_rows(),
72 "Matrix must be quadratic");
73
74 aValues.set_size( aMatrix.n_cols() );
75
76 // blaze::syev overwrites the matrix it is given, so it gets a copy
77 Matrix< real > tWork( aMatrix.matrix_data() );
78
79 // 'N' = eigenvalues only. 'U' = read the upper triangle, matching what
80 // arma::eig_sym does, so both backends agree even when the caller passes a
81 // matrix that is not actually symmetric.
82 blaze::syev( tWork.matrix_data(), aValues.vector_data(), 'N', 'U' );
83 }
84
85//------------------------------------------------------------------------------
86}
87#endif //BELFEM_FN_BZ_EIGEN_HPP
#define BELFEM_ERROR(aCheck,...)
Definition assert.hpp:264
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
int_t eigen(const Matrix< real > &aMatrix, Vector< real > &aValues, const bool aAbortOnComplex=true)
Eigenvalues of a general (not necessarily symmetric) square matrix.
Definition fn_AR_eigen.hpp:24
void eigen_sym(const Matrix< real > &aMatrix, Vector< real > &aValues)
Eigenvalues of a symmetric matrix.
Definition fn_AR_eigen.hpp:67
USER GUIDES:
Definition cl_Capacitor.cpp:16
constexpr real BELFEM_EPSILON
Definition typedefs.hpp:90
int32_t int_t
Definition typedefs.hpp:51
#define BELFEM_QUIET_NAN
Definition typedefs.hpp:87