This page was generated from unit-2.4-Maxwell/Maxwellevp.ipynb.
2.4.1 Maxwell eigenvalue problem¶
We solve the Maxwell eigenvalue problem
\[\int \operatorname{curl} u \, \operatorname{curl} v
= \lambda \int u v\]
for \(u, v \; \bot \; \nabla H^1\) using a PINVIT solver from the ngsolve solvers module.
The orthogonality to gradient fields is important to eliminate the huge number of zero eigenvalues. The orthogonal sub-space is implemented using a Poisson projection:
\[P u = u - \nabla \Delta^{-1} \operatorname{div} u\]
The algorithm and example is take form the Phd thesis of Sabine Zaglmayr, p 145-150.
[1]:
import netgen.gui
from netgen.csg import *
from ngsolve import *
geom = CSGeometry()
cube1 = OrthoBrick(Pnt(-1,-1,-1), Pnt(1,1,1))
cube2 = OrthoBrick(Pnt(0,0,0), Pnt(2,2,2))
fichera = cube1-cube2
geom.Add (fichera)
# all edges defined by intersection of faces of
# cube2 and cube2 are marked for geometric edge refinement
geom.SingularEdge (cube2,cube2, 1)
geom.SingularPoint (cube2,cube2,cube2, 1)
mesh = Mesh(geom.GenerateMesh(maxh=0.5))
# two levels of hp-refinement
mesh.RefineHP(2, factor=0.2)
Draw (mesh)
[2]:
SetHeapSize(100*1000*1000)
fes = HCurl(mesh, order=3)
print ("ndof =", fes.ndof)
u,v = fes.TnT()
a = BilinearForm(fes)
a += curl(u)*curl(v)*dx
m = BilinearForm(fes)
m += u*v*dx
apre = BilinearForm(fes)
apre += curl(u)*curl(v)*dx + u*v*dx
pre = Preconditioner(apre, "direct", inverse="sparsecholesky")
ndof = 30460
[3]:
with TaskManager():
a.Assemble()
m.Assemble()
apre.Assemble()
# build gradient matrix as sparse matrix (and corresponding scalar FESpace)
gradmat, fesh1 = fes.CreateGradient()
gradmattrans = gradmat.CreateTranspose() # transpose sparse matrix
math1 = gradmattrans @ m.mat @ gradmat # multiply matrices
math1[0,0] += 1 # fix the 1-dim kernel
invh1 = math1.Inverse(inverse="sparsecholesky")
# build the Poisson projector with operator Algebra:
proj = IdentityMatrix() - gradmat @ invh1 @ gradmattrans @ m.mat
projpre = proj @ pre.mat
evals, evecs = solvers.PINVIT(a.mat, m.mat, pre=projpre, num=12, maxit=20)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-b9c9cf11f0eb> in <module>
18 projpre = proj @ pre.mat
19
---> 20 evals, evecs = solvers.PINVIT(a.mat, m.mat, pre=projpre, num=12, maxit=20)
/usr/lib/python3/dist-packages/ngsolve/eigenvalues.py in PINVIT(mata, matm, pre, num, maxit, printrates)
47 msmall[j,k] = InnerProduct(Mv, vecs[k])
48
---> 49 ev,evec = scipy.linalg.eigh(a=asmall, b=msmall)
50 lams[:] = ev[0:num]
51 if printrates:
/usr/local/lib/python3.6/dist-packages/scipy/linalg/decomp.py in eigh(a, b, lower, eigvals_only, overwrite_a, overwrite_b, turbo, eigvals, type, check_finite)
372
373 """
--> 374 a1 = _asarray_validated(a, check_finite=check_finite)
375 if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
376 raise ValueError('expected square matrix')
/usr/local/lib/python3.6/dist-packages/scipy/_lib/_util.py in _asarray_validated(a, check_finite, sparse_ok, objects_ok, mask_ok, as_inexact)
237 raise ValueError('masked arrays are not supported')
238 toarray = np.asarray_chkfinite if check_finite else np.asarray
--> 239 a = toarray(a)
240 if not objects_ok:
241 if a.dtype is np.dtype('O'):
/usr/lib/python3/dist-packages/numpy/lib/function_base.py in asarray_chkfinite(a, dtype, order)
1213 if a.dtype.char in typecodes['AllFloat'] and not np.isfinite(a).all():
1214 raise ValueError(
-> 1215 "array must not contain infs or NaNs")
1216 return a
1217
ValueError: array must not contain infs or NaNs
[4]:
print ("Eigenvalues")
for lam in evals:
print (lam)
Eigenvalues
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-4-22ead1bc97a9> in <module>
1 print ("Eigenvalues")
----> 2 for lam in evals:
3 print (lam)
NameError: name 'evals' is not defined
[5]:
Draw (mesh)
gfu = GridFunction(fes, multidim=len(evecs))
for i in range(len(evecs)):
gfu.vecs[i].data = evecs[i]
Draw (Norm(gfu), mesh, "u", sd=4)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-5-77fa5933e2a2> in <module>
1 Draw (mesh)
----> 2 gfu = GridFunction(fes, multidim=len(evecs))
3 for i in range(len(evecs)):
4 gfu.vecs[i].data = evecs[i]
5 Draw (Norm(gfu), mesh, "u", sd=4)
NameError: name 'evecs' is not defined
[ ]: