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