Rectangular matrix assempling

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):

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