1#ifndef DUNE_GENEO_GENEOBASIS_HH
2#define DUNE_GENEO_GENEOBASIS_HH
4#include "subdomainbasis.hh"
5#include "arpackpp_fork.hh"
10 template<
class GFS,
class M,
class X,
class Y,
class SI,
int dim>
11 class GenEOBasis :
public SubdomainBasis<X>
13 typedef Dune::PDELab::Backend::Native<M> ISTLM;
14 typedef Dune::PDELab::Backend::Native<X> ISTLX;
17 GenEOBasis(
const GFS& gfs,
const M& AF_neumann,
const M& AF_ovlp,
const double eigenvalue_threshold, X& part_unity, SI& solver_info){
18 using Dune::PDELab::Backend::native;
21 for (
auto row_iter = native(ovlp_mat).begin(); row_iter != native(ovlp_mat).end(); row_iter++) {
22 for (
auto col_iter = row_iter->begin(); col_iter != row_iter->end(); col_iter++) {
23 *col_iter *= native(part_unity)[row_iter.index()] * native(part_unity)[col_iter.index()];
27 ArpackFork::ArPackPlusPlus_Algorithms<ISTLM, ISTLX> arpack(native(AF_neumann));
30 if (solver_info.nev_arpack < solver_info.nev)
31 DUNE_THROW(Dune::ISTLError,
"eigenvectors_compute is less then eigenvectors or not specified!");
33 std::vector<double> eigenvalues;
34 std::vector<ISTLX> eigenvectors;
35 eigenvectors.resize(solver_info.nev_arpack);
36 for (
int i = 0; i < solver_info.nev_arpack; i++) {
37 eigenvectors[i] = native(X(gfs,0.0));
40 if (configuration.get<
bool>(
"EigenvectorVTK",
false)) {
41 for (
int i = 0; i < solver_info.nev; i++) {
42 auto gv = gfs.gridView();
43 typedef typename GFS::Traits::GridView GV;
44 Dune::SubsamplingVTKWriter<GV> vtkwriter(gv,0);
45 X eigenvector(gfs, eigenvectors[i]);
46 Dune::PDELab::addSolutionToVTKWriter(vtkwriter,gfs,eigenvector);
47 vtkwriter.write(
"eigenvector"+std::to_string(i),Dune::VTK::appendedraw);
51 arpack.computeGenNonSymMinMagnitude(native(ovlp_mat), eps, solver_info.nev_arpack, eigenvectors, eigenvalues, solver_info.eigen_shift);
55 if (eigenvalue_threshold != 0) {
62 for (
int i = 0; i < solver_info.nev; i++) {
63 if (eigenvalues[i] > eigenvalue_threshold) {
68 std::cout <<
"Process " << gfs.gridView().comm().rank() <<
" picked " << cnt <<
" eigenvectors" << std::endl;
71 std:: cout <<
"No eigenvalue above threshold - not enough eigenvalue solves!" << std::endl;
72 cnt = solver_info.nev;
79 cnt = solver_info.nev;
91 this->local_basis.resize(cnt);
94 for (
int base_id = 0; base_id < cnt; base_id++) {
95 this->local_basis[base_id] = std::make_shared<X>(part_unity);
97 for (
unsigned int it = 0; it < native(eigenvectors[base_id]).N(); it++) {
98 for(
int j = 0; j < dim; j++){
99 native(*this->local_basis[base_id])[it][j] *= eigenvectors[base_id][it][j];
105 if (configuration.get<
bool>(
"AddPartUnityToEigenvectors",
false) && eigenvalues[0] > 1E-10) {
106 auto part_unity_basis = std::make_shared<X>(gfs,0.0);
107 *part_unity_basis = part_unity;
108 this->local_basis.insert (this->local_basis.begin(), part_unity_basis);
109 this->local_basis.pop_back();