Hi, it’s me again.
Problem
I want to solve the hydrogen atom using FF. The eigenvalue problem is like
I built a cylinder mesh (r = 15A, h = 30A) as the FE space:
Then defined the problem via
varf a(u1, u2) =
// ka and kc are coefficients before nabla^2 and 1/r
int3d(Th) ( -ka * Grad(u1)' * Grad(u2)
// + 0.0001 to avoid the singularity of 1/r at r=0
- (kc/sqrt(x^2 + y^2 + z^2 + 0.0001)) * u1 * u2);
varf b(u1, u2) =
int3d(Th) (u1 * u2);
Since the ground state locates at -13.6eV, I set sigma = -10.0
, but the code ended up with no solutions.
What should I do the make it work as expected?
P.S. When I ran it via ff-mpirun -np 5
, 5 processes were running, but each process consumed only 50% CPU occupation.
In fact, I’ve implemented a finite difference version here, but it is too slow. This is why I turn to FEM.
Code
Here is what I wrote:
load "PETSc"
load "msh3"
load "medit"
include "macro_ddm.idp"
int nEV = getARGV("-nev", 10);
real sigma = -10;
real ka = 3.8099821161548593; // hbar^2 / 2m_e
real kc = 14.39964547842567; // e^2 / (4pi epsilon_0)
real r = 15.0;
border C(t=0, 2*pi) { x = r*cos(t); y = r*sin(t); label=1; }
mesh Baseh = buildmesh(C(60));
int[int] rup=[0, 1], rdown=[0, 2], rmid=[1,3];
func zmin=-15;
func zmax= 15;
int nlayer = 30;
mesh3 Th = buildlayers(Baseh, nlayer,
coef=1.0,
zbound = [zmin, zmax],
labelmid = rmid,
reffaceup = rup,
reffacelow = rdown
);
plot(Th, wait=1);
fespace Vh(Th, P1);
Vh u1, u2;
macro Grad(u) [dx(u), dy(u), dz(u)] // EOM
varf a(u1, u2) =
int3d(Th) ( -ka * Grad(u1)' * Grad(u2)
- (kc/sqrt(x^2 + y^2 + z^2 + 0.0001)) * u1 * u2);
varf b(u1, u2) =
int3d(Th) (u1 * u2);
matrix<real> A = a(Vh, Vh);
matrix<real> B = b(Vh, Vh);
Mat DistA(A);
Mat DistB(B);
real[int] EigenVAL(0);
Vh<real>[int] EigenVEC(1);
string ssparams =
" -eps_nev " + nEV +
" -eps_type krylovschur" +
" -eps_target " + sigma +
" -eps_view " +
" -eps_gen_hermitian "
;
int k = EPSSolve(
DistA,
DistB,
vectors = EigenVEC,
values = EigenVAL,
sparams = ssparams
);
k = min(k, nEV);
if(mpirank) {
cout << " Found " << k << " solutions" << endl;
}
Vh<real> Temp;
for (int i=0; i<k; ++i) {
if(!mpirank) {
cout << " Eigenvalue $" + i + " = " + EigenVAL[i] << endl;
}
Temp = EigenVEC[i];
if (!mpirank) {
plot(Temp, cmm = "Psi("+i+") EV = " + EigenVAL[i],
wait=true, value=1, ps="eigen"+i+".eps");
}
}
Log
dump.log (253.3 KB)