Behavior of varf with rhs and on()

Can anyone comment on the extraction of the linear part in varf() ?
There is an issue of sign, it seems that it is treated differently depending if it is an integral source or an on() boundary condition. The simple code

``````int n=3;
mesh Th=square(n,n);
//plot(Th);

real a=1.,b=1.;

fespace Vh(Th,P1);
Vh u,v;
real[int] tab(Vh.ndof),sol(Vh.ndof),solprob(Vh.ndof),diff(Vh.ndof);

solve prob(u,v)
=int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v))
-int2d(Th)(a*v)
+on(1,2,3,4,u=b)
;
solprob=u[];
//cout << "solprob = " << solprob << endl;

varf test(u,v)
=int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v))
-int2d(Th)(a*v)
+on(1,2,3,4,u=b)
;
matrix A=test(Vh,Vh);
tab=test(0,Vh);
tab=-tab;// it seems necessary for the source "a", but not for boundary "b"
sol=A^-1*tab;
//cout << "sol = " << sol << endl;

diff=solprob-sol;
cout << "error = " << sqrt(diff'*diff) << endl;
``````

considers either solve() or varf() with the same problem, but they do not give the same solution.
??

`solve` supposes the linear and bilinear form represent the LHS and RHS of an equation system. `varf` defines a linear or bilinear form that is not necessarily part of an equation.

Since you impose inhomogeneous BC, the sign flip in the latter is changing the BC, not just the forcing.

``````varf test(u,v)
=int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v))
+int2d(Th)(a*v) // note: sign flip is here now
+on(1,2,3,4,u=b)
;
matrix A=test(Vh,Vh);
tab=test(0,Vh);
// line removed here
sol=A^-1*tab;
``````

Another equivalent option would be:

``````varf test(u,v)
=int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v))
-int2d(Th)(a*v)
+on(1,2,3,4,u=-b) // note: sign flip is here now
;
matrix A=test(Vh,Vh);
tab=test(0,Vh);
tab=-tab;// it seems necessary for the source "a", but not for boundary "b"
sol=A^-1*tab;
``````

Thank you. It is quite puzzling that `solve` and `varf` do not use the same conventions. Additionally in `varf` the convention for `int2d` or `int1d` is opposite to that of `on()`. Then I have to remind of it when changing from one formulation to the other. Setting `u=-b` instead of `u=b` is very much counterintuitive (your second option). The first option is also counterintuitive since it looks like we are not solving the right equation (-\Delta u+a=0 instead of -\Delta u-a=0).

Additionally in `varf` the convention for `int2d` or `int1d` is opposite to that of `on()`

You are thinking that there is a convention, but there is none. `int2d` or `int1d` are used to discretise linear or bilinear form (which may be related or not, as Chris highlighted). `on()` is used to impose Dirichlet boundary conditions. That’s two different things, hence there is no convention between one and the other.

Hi Chris,
I noticed that A and tab are constructed from same varf, but A won’t include the linear part `a*v`, right?

Yes, That is correct.

To complete the post of Chris, a third option is to use

``````varf test(u,v)
=int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v))
-int2d(Th)(a*v)
+int1d(Th)(tgv*u*v)
-int1d(Th)(tgv*b*v)
;
``````

This formulation is valid for `solve` and `varf` without change (the latter must use the line `tab=-tab;`). This formulation avoids the use of on().

Why would you want to avoid the use of `on()`? That allows more flexibility in terms of how Dirichlet BC’s are enforced via penalization `tgv>0`, or elimination (asymmetric `tgv=-1` or symmetric `tgv=-2`). It also allows you to ignore BC with `tgv=0`.

``````matrix A=test(Vh,Vh,tgv=...);
tab=test(0,Vh,tgv=...);
``````

It depends of course of what you want to do.

You are not answering to the question “Why would you want to avoid the use of `on()` ?”

On the generic problems of the type I mentioned on my first post, it is possible to use the third option, which does the job in any type of formulation (solve, problem, varf).
This does not mean I “want” to avoid on().