Symbolic Integrators¶
Symbolic integrators can be used to define arbitrary (multi-)physical problems. The variational formulation of the (non-)linear problem can be implemented in a very natural way. Examples of the usage of these integrators can i.e. be found in Navier Stokes Equation, Magnetic Field or Nonlinear elasticity.
The finite element space provides placeholder coefficient functions by the methods TestFunction
and TrialFunction
. They have implemented canonical derivatives and traces of the finite element space and insert the basis functions of the FESpace during assembling of the system matrices.
Linear Problems¶
For linear problems we use the function Assemble
of the BilinearForm
to assemble the matrix and vector. For example for the \(H_\text{curl}\) linear problem
from example Magnetic Fields we have to define the space
V = HCurl(mesh, order=4, dirichlet="outer", flags = { "nograds" : True })
and the BilinearForm
a = BilinearForm(V, symmetric=True)
a += SymbolicBFI(nu*curl(u)*curl(v) + 1e-6*nu*u*v)
a.Assemble()
as well as the LinearForm
f = LinearForm(V)
f += SymbolicLFI(CoefficientFunction((y,-x,0)) * v, definedon=mesh.Materials("coil"))
f.Assemble()
The argument of the symbolic integrator must be a coefficient function depending linearily on the test and trial function.
-
BilinearForm.
Assemble
(self: ngsolve.comp.BilinearForm, heapsize: int=1000000, reallocate: bool=False) → None¶
Nonlinear Problems¶
If your left hand side of the variational formulation is nonlinear there are multiple ways to get a discretisation, depending on what you want.
Apply¶
The function Apply
applies the formulation to the given BaseVector
. You can get a BaseVector
form your GridFunction
with GridFunction.vec
. The output vector can be created with BaseVector.CreateVector
.
-
BilinearForm.
Apply
(self: ngsolve.comp.BilinearForm, x: ngsolve.la.BaseVector, y: ngsolve.la.BaseVector, heapsize: int=1000000) → None¶ Applies a (non-)linear variational formulation to x and stores the result in y.
Parameters
- x : ngsolve.BaseVector
- input vector
- y : ngsolve.BaseVector
- output vector
- heapsize : int
- Size of the LocalHeap for that operation. If you get an error about not enough heapsize increase this value.
AssembleLinearization¶
For a variational formulation
the method AssembleLinearization
computes
with automatic differentiation of \(f(u)\) and an input BaseVector
\(u_\text{in}\).
-
BilinearForm.
AssembleLinearization
(self: ngsolve.comp.BilinearForm, ulin: ngsolve.la.BaseVector, heapsize: int=1000000) → None¶
Assemble¶
You can do your own linearization as well using Assemble
and a GridFunction
as a CoefficientFunction
in your integrator. Let gfu_old
be this gridfunction then
a = BilinearForm(fes)
a += SymbolicBFI(gfu_old * u * v)
will be a linearization for
Every time you call Assemble
the bilinearform is updated with the new values of the GridFunction.
Symbolic Energy¶
SymbolicEnergy
can be used to solve a minimization problem. In this
tutorial we show how to solve the nonlinear problem
For this we use SymbolicEnergy
:
a = BilinearForm (V, symmetric=False)
a += SymbolicEnergy (0.05*grad(u)*grad(u) + u*u*u*u - 100*u)
from the GridFunction
we can create new BaseVector
:
u = GridFunction (V)
u.vec[:] = 0
res = u.vec.CreateVector()
w = u.vec.CreateVector()
With this we can use AssembleLinearization
to do a Newton iteration to solve the problem:
for it in range(20):
print ("Newton iteration", it)
print ("energy = ", a.Energy(u.vec))
a.Apply (u.vec, res)
a.AssembleLinearization (u.vec)
inv = a.mat.Inverse(V.FreeDofs())
w.data = inv * res
print ("w*r =", InnerProduct(w,res))
u.vec.data -= w
Redraw()