Hi, I am trying to solve the time Independent Schrödinger with periodic boundary conditions. I am facing a problem while solving SLEPc eigenvalue solver.
When I run the program, I get the following error:
*** Error: Unable to extract eigenpair from SLEPc eigenvalue solver.
*** Reason: Requested eigenpair (0) has not been computed.
*** Where: This error was encountered inside SLEPcEigenSolver.cpp.
I am writing the code in C++. My UFC file MyForms.ufl is found below.
element = FiniteElement("Lagrange", triangle, 1)
u = TrialFunction(element)
v = TestFunction(element)
Mass = Coefficient(element)
U = Coefficient(element)
a = Mass*inner(grad(v), grad(u))*dx+v*u*U*dx
m=v*u*dx
forms=[a,m]
Additionally, the main part of my program is
#include <string>
#include <iostream>
#include <fstream>
#include "MyForms.h"
#include "input.cpp"
using namespace dolfin;
/*-----------------------------------------------------------------
Periodic Boundary Class
------------------------------------------------------------------*/
class Periodic :public SubDomain
{
public:
bool inside(const Array<double>&x,bool on_boundary) const
{
bool left=std::fabs(x[0])< DOLFIN_EPS;
bool bottom=std::fabs(x[1])<DOLFIN_EPS;
bool right=std::fabs(x[0]-Width)<DOLFIN_EPS;
bool top=std::fabs(x[1]-Height)<DOLFIN_EPS;
return (left||bottom) &&(!(right||top)) &on_boundary;
}
void map(const Array<double>&x,Array<double>&y) const {
y[0]=x[0];
y[1]=x[1];
if(std::fabs(x[0]-Width)<DOLFIN_EPS)
y[0]-=Width;
if(std::fabs(x[1]-Height)<DOLFIN_EPS)
y[1]-=Height;
}
private:
};
/*------------------------------------------------------------------------
Effective Mass class
-------------------------------------------------------------------------*/
class EffectiveMass : public Expression {
public:
void eval(
Array<double>& values,
const Array<double> &x,
const ufc::cell &cell
) const {
//Inside QD
if( (*regions)[cell.index] == 1 ) {
values[0] =-H_BAR*H_BAR/(2*ME*EFFIN*Q) ;
//If Outside QD
} else if( (*regions)[cell.index] == 2 ) {
values[0] = -H_BAR*H_BAR/(2*ME*EFFOUT*Q);
}
}
std::shared_ptr<MeshFunction<std::size_t>> regions;
private:
};
/*---------------------------------------------------------------------
Potential Class
---------------------------------------------------------------------*/
class Potential: public Expression{
public:
void eval(Array<double>&values,
const Array<double>&x,
const ufc::cell &cell
) const {
//Inside QD
if( (*regions)[cell.index]==1){
values[0]=0.0;
//If Outside QD
} else if( (*regions)[cell.index]==2){
values[0]=OFFSET;
}
}
std::shared_ptr<MeshFunction<std::size_t>> regions;
private:
};
int main(int argc, char** argv){
//Input mesh from file
File meshData("Total.xml");
auto mesh=std::make_shared<Mesh>();
meshData >> *mesh;
//Input physical regions from file
auto MyFunction=std::make_shared<MeshFunction<std::size_t>>(mesh,"./Total_physical_region.xml");//get physic
//Check if MyFunction is empty... if it is then exit with warrning
if( MyFunction->empty()){
std::cerr<<"Could not find make MeshFunction for subdomains";
return 1;
}
//create periodic boundary condition and FunctionSpace
auto pcb=std::make_shared<Periodic>();
auto V=std::make_shared<MyForms::FunctionSpace>(mesh,pcb);
//set up Av=EMv
//Assemble A Matrix
MyForms::Form_a a(V,V);
auto Mass=std::make_shared<EffectiveMass>();
Mass->regions=MyFunction;
auto Pot =std::make_shared<Potential>();
Pot->regions=MyFunction;
a.Mass=Mass;
a.U=Pot;
auto A=std::make_shared<PETScMatrix>();
assemble(*A,a);
//Assemble M Matrix
MyForms::Form_m m(V,V);
auto M=std::make_shared<PETScMatrix>();
assemble(*M,m);
//Create eigensolver
SLEPcEigenSolver esolver(A,M);
esolver.parameters["solver"]="krylov-schur";
esolver.parameters["problem_type"]="gen_hermitian";
esolver.parameters["spectrum"]="smallest real";
esolver.parameters["tolerance"]=1e-14;
esolver.solve();
double r,c;
PETScVector rx,cx;
Function u(V);
//First specified number of quantum states
for(int i=0;i<SavedStates;i++)
{
esolver.get_eigenpair(r,c,rx,cx,i);
*u.vector()=rx;
File file("./DNSSolutions/WF"+std::to_string(i)+".pvd");
file<<u;
HDF5File file2(MPI_COMM_SELF,"./DNSSolutions/WF"+std::to_string(i)+".hdf5","w");
file2.write(u,"WF"+std::to_string(i));
}
//Save EigenValues to a file
for(int i=0;i<SavedStates;i++){
std::ofstream file;
file.open("./DNSSolutions/Eigenvalue"+std::to_string(i)+".txt");
file<<r;
file.close();
}
}
Thanks