2#ifndef DUNE_GENEO_LIPTONBABUSKA_HH
3#define DUNE_GENEO_LIPTONBABUSKA_HH
5#include "subdomainbasis.hh"
6#include "arpackpp_fork.hh"
11template<
class GFS,
class M,
class X,
class Y,
int dim>
12class LBBasis :
public SubdomainBasis<X>
14 typedef Dune::PDELab::Backend::Native<M> ISTLM;
15 typedef Dune::PDELab::Backend::Native<X> ISTLX;
18 LBBasis(
const GFS& gfs,
const M& AF_neumann,
const M& AF_ovlp,
const double eigenvalue_threshold, X& part_unity,
int& nev,
int nev_arpack,
double shift) {
19 using Dune::PDELab::Backend::native;
21 auto AF_interior = AF_neumann;
22 native(AF_interior) -= native(AF_ovlp);
24 ArpackFork::ArPackPlusPlus_Algorithms<ISTLM, ISTLX> arpack(native(AF_neumann));
30 std::vector<double> eigenvalues;
31 std::vector<ISTLX> eigenvectors;
32 eigenvectors.resize(nev_arpack);
33 for (
int i = 0; i < nev_arpack; i++) {
34 eigenvectors[i] = native(X(gfs,0.0));
37 arpack.computeGenNonSymMinMagnitude(native(AF_interior), eps, nev_arpack, eigenvectors, eigenvalues, shift);
53 if (configuration.get<
bool>(
"threshold_eigenvectors",
false)) {
54 for (
int i = 0; i < nev; i++) {
55 if (eigenvalues[i] > eigenvalue_threshold) {
60 if (configuration.get<
bool>(
"verbose",
false))
61 std::cout <<
"Process " << gfs.gridView().comm().rank() <<
" picked " << cnt <<
" eigenvectors" << std::endl;
63 DUNE_THROW(Dune::ISTLError,
"No eigenvalue above threshold - not enough eigenvalue solves!");
68 this->local_basis.resize(cnt);
70 for (
int base_id = 0; base_id < cnt; base_id++) {
71 this->local_basis[base_id] = std::make_shared<X>(part_unity);
72 for (
int it = 0; it < native(eigenvectors[base_id]).N(); it++) {
73 for(
int j = 0; j < dim; j++)
74 native(*this->local_basis[base_id])[it][j] *= eigenvectors[base_id][it][j];
78 if (configuration.get<
bool>(
"AddPartUnityToEigenvectors",
false) && eigenvalues[0] > 1E-10) {
79 auto part_unity_basis = std::make_shared<X>(gfs,0.0);
80 *part_unity_basis = part_unity;
81 this->local_basis.insert (this->local_basis.begin(), part_unity_basis);
82 this->local_basis.pop_back();