Nodal interpolant available?

More
5 years 1 month ago #2111 by cpfeiler
Hey there,

The symbolic definition of (bi-) linearforms makes a lot of things easier.
But, I wonder whether one can also define a form including the nodal interpolant?

More specific: Consider the space of first order vector-valued H1 conforming elements, i.e., X = VectorH1(mesh, order=1).
The nodal interpolant I_h should now map a given (continuous) function f to a function f_h in the FE-space X, such that f(z) = f_h(z) for all nodes z in the mesh.

For two GridFunctions u and v in X, i can get the nodal interpolant of the cross-product denoted by I_h(u x v) quite easily (for example) by accessing the vectors of their nodal values.

But I struggle to use the nodal interpolant I_h in combination with test functions:
For example, is there a way to define a bilinear form like

<psi , curl( I_h(phi x v))>

in NgSolve?
Here again v denotes a GridFunction, while psi and phi denote a TrialFunction and a TestFunction, respectively. <.,.> denotes the L2 inner prduct.

Thanks in advance,
Best regards,
Carl
More
5 years 1 month ago - 5 years 1 month ago #2112 by christopher
just a quick idea: can you introduce a new variable w = l_h(phi x v) in the system and use this for a second equation for w?
ngsolve.org/docu/latest/i-tutorials/unit...basis/dualbasis.html
Last edit: 5 years 1 month ago by christopher.
More
5 years 1 month ago #2113 by cpfeiler
Thank you Christopher for the suggestion - I will have a look into that.
Best, Carl
More
5 years 1 week ago #2230 by cpfeiler
Hey there,

introducing a new variable as suggested by Christopher did the trick.
However, I used a mass-lumped integration rule rather than the dual basis you suggested.

For future reference I quickly describe the solution which worked for me,
in case somebody else runs into a similar problem.

Notation:
a x b denotes the cross-product of a and b.
<., .> denotes the L2-inner product;
<., .>_h denotes the mass-lumped inner-product (defined in the code below)

For given GridFunction eta in X, consider the problem of finding a GridFunction u (in X), such that

<u, phi> + <u, curl(I_h(phi x eta))> = <f, phi>

for all TestFunctions phi in X.

Introducing a new variable v = I_h(phi x eta) one arrives at a system on XX = FESpace([X, X]) :
Find (u, w) in XX, such that

<u, phi> - <eta x w, phi>_h = <f, phi>

<u, curl(v)> + <w, v>_h = 0

for all TestFunctions (phi, v) in XX.

Plugging in v = I_h(phi x eta), one sees that the original equation is satisfied.

The NGS-Python code snippet for defining the bilinear form looks like this

Code:
myCurl = lambda Df : (Df[2,1] - Df[1,2], Df[0,2] - Df[2,0], Df[1,0] - Df[0,1]) massLumping = IntegrationRule( points = [(0,0,0), (1,0,0), (0,1,0), (0,0,1)], weights = [1/24, 1/24, 1/24, 1/24] ) X = VectorH1(mesh, order=1) XX = FESpace([X, X]) u, w = XX.TrialFunction() phi, v = XX.TestFunction() A = BilinearForm(XX) A += SymbolicBFI(u * phi) A += SymbolicBFI(u * myCurl(v.Deriv())) A += SymbolicBFI(-Cross(eta, w) * phi, intrule=massLumping) A += SymbolicBFI(w * v, intrule=massLumping)

The resulting (larger) system, however, takes pretty long to be solved.
So make sure to additionally decouple the DOFs of the Lagrange multiplier w
by using XX = FESpace([X, Discontinuous(X)]) instead,
and static condensation as described at:
ngsolve.org/docu/latest/i-tutorials/unit...cond/staticcond.html

Thank you Joachim for your further help,
Best regards,
Carl
Time to create page: 0.133 seconds