Solving PDE with non-trivial null space

More
7 years 6 months ago #354 by sxmeng
Could this be realized through defining a FE space incorporating that the solution u is orthogonal to gfu? If yes, does netgen provides such modifications?
More
7 years 6 months ago #367 by christopher
I don't think you can do this purely in NGSolve without some C++ hacking, but if efficiency is not the key point you can use NGSolve to assemble the matrices, then convert them to scipy matrices and do the orthogonalization and solving in scipy...
More
7 years 6 months ago #372 by sxmeng
Thanks for the reply. Efficiency is not an issue here :)
More
7 years 6 months ago #376 by joachim
Hello,

I think we need more information for this problem.

Have you computed the Eigenvalue/Eigenvector in advance, or should it be part of the same equation ?
Are your matrices symmetric and positive definite ?

If you know the Eigensystem, you can pose your equation orthogonal to the Eigenvector using a scalar Lagrange parameter (from NumberSpace).

Joachim
More
7 years 6 months ago #377 by sxmeng
Hi Joachim:

Thank you very much for the reply. I have computed the eigenvalues/eigenfunctions in advance using Arnoldi solver; the matrices are symmetric and non-negative definite.

I am not sure yet how to use a scalar Lagrange parameter (from NumberSpace), is there a short illustrative example on this?

Best,
Shixu
More
7 years 6 months ago #378 by christopher
Ok I'm sorry I was wrong... With Joachims comment I think it's actually quite easy...
I think this should do what you want:
Code:
from netgen.geom2d import unit_square from ngsolve import * mesh = Mesh(unit_square.GenerateMesh(maxh=0.3)) h1=H1(mesh,order=5,dirichlet="bottom|left|right|top",complex=True) u,v = h1.TnT() a = BilinearForm(h1) a += SymbolicBFI(grad(u)*grad(v)) b = BilinearForm(h1) b += SymbolicBFI(u*v) a.Assemble() b.Assemble() evecs = GridFunction(h1,multidim=50) vlam = ArnoldiSolver(a.mat,b.mat,h1.FreeDofs(),evecs.vecs,1) Draw(evecs) # get a non multidim GF out of the multidim one evec0 = GridFunction(h1) evec0.vec.data = evecs.vecs[0] number = NumberSpace(mesh,complex=True) fes = FESpace([h1,number]) (u,unum), (v,vnum) = fes.TnT() # The orthogonality condition is satisfied because vnum = 1 means that evec0 * u = 0 # unum incorporates the evec0 part of the right hand side, if the argument of f is orthogonal to # evec0, then unum should be 0 alam = BilinearForm(fes) alam += SymbolicBFI(grad(u) * grad(v) - vlam[0] * u * v + unum * v * evec0) alam += SymbolicBFI(evec0 * u * vnum) f = LinearForm(fes) f += SymbolicLFI(1*v) alam.Assemble() f.Assemble() sol = GridFunction(fes,"solution") sol.vec.data = alam.mat.Inverse(fes.FreeDofs()) * f.vec Draw(sol.components[0])
Time to create page: 0.121 seconds