Hi,
I have the following FE spaces:
V = H1(mesh, order=1)
V1 = FESpace([V, V])
V2 = FESpace([V])
I would like to define BilinearForm with V1 as test space and V2 as trial space, resulting in a rectangular matrix when assembled. Is it possible to do so? thanks and best regards Makis
Yes this is possible, but the definition of V2 is not necessary, you can use V here as well. Just give the BilinearForm a different test and trial space:
from netgen.geom2d import unit_square
from ngsolve import *
mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))
V = H1(mesh,order=1,dirichlet="top")
V1 = FESpace([V,V])
u = V.TrialFunction()
v1,v2 = V1.TestFunction()
a = BilinearForm(trialspace=V,testspace=V1)
a += SymbolicBFI(u * (v1 + 2*v2))
a.Assemble()
print(a.mat)
Best
Christopher
Dear Christopher, thank you for your quick and accurate response!
Furthermore, I would like to better understand if ngspy has capabilities to perform symbolic manipulation for what concerns coefficient functions, linear forms and bilinear forms.
Two typical cases that I would like to tackle are the definition of functions that:
- given as input a bilinear form a for a scalar elliptic problem: I would like to manipulate it to get (in a new bilinear form) its adjoint a* by swapping test and trial functions.
- given as input a linear form F, say F(v) = \int_{\Omega} f*v, where f is some coefficient function defined on \Omega: I would like to obtain a new bilinear form G(v) where f is replaced by a different coefficient function. I would like to have both F(v) and G(v) available, so I cannot simply re-assign in-place values in f.
Thanks,
best regards,
Makis
For the first point:
Is it enough if you can apply the transpose of the matrix? The matrix obtained by a.mat has operations like MultTrans and MultTransAdd which do
mat.MultTrans(s,x,y) does y = s * trans(mat) * x
mat.MultTransAdd(s,x,y) does y += s * trans(mat) * x
with s being a scalar.
Second question:
You can just use 2 linearforms for that.
Best
Christopher
Dear Christopher,
thank you very much for your response. Let me rephrase my questions: I am inquiring if it possible to generate a new form on the fly. For instance, in the case of the second question, ideally I would like to have the following function
[code]def generate_on_the_fly(original_linear_form):
create a copy of of original_linear_form into a new variable, say modified_linear_form
replace f with some other forcing term (say g) inside modified_linear_form (but not in original_linear_form)
return modified_linear_form[/code]
Of course I can define two linear forms (one with f and one with g), but I would be grateful to understand if capabilities like the one sketched in generate_on_the_fly() are available.
Thanks,
Makis