# Explanation of tgv = 0

**URL:** <https://community.freefem.org/t/explanation-of-tgv-0/4235>\
**Category:** General Discussion\
**Created:** [March 4, 2026, 11:00pm UTC](https://community.freefem.org/t/explanation-of-tgv-0/4235 "2026-03-04T23:00:27Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![marc2025](https://avatars.discourse-cdn.com/v4/letter/m/3e96dc/32.png) [@marc2025](https://community.freefem.org/u/marc2025)\
**Post date:** [March 4, 2026, 11:00pm UTC](https://community.freefem.org/t/explanation-of-tgv-0/4235/1 "2026-03-04T23:00:27Z")

</div>

Hello FreeFem community,

I’ve run into a situation recently where I’m solving a nonlinear PDE; to do this, I am writing a Newton solver, e.g. solving a system J p = F. In this case, F is a vector for my residual and J is my Jacobian matrix. When creating these objects, I must use `tgv = 0` for F otherwise my approximate solution becomes unbounded. Even when I use the exact solution of my problem as the initial guess for Newton’s method, my approximate solution will continue to grow after each iteration. (Note however, that the tgv for J does not matter, as any value will work as long as tgv for F is 0.)

I’ve tried reading some of the documentation as well as other discussions on here about the tgv, but I guess I’m still not sure theoretically why the tgv value of 0 works in this case. Does anyone have any thoughts on this?

Hopefully this is clear enough. Please let me know if any other information would be helpful. Thank you!

---

<div class="post-metadata">

**Author:** ![fb77](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/fb77/32/3796_2.png) [@fb77](https://community.freefem.org/u/fb77)\
**Post date:** [March 5, 2026, 10:07am UTC](https://community.freefem.org/t/explanation-of-tgv-0/4235/2 "2026-03-05T10:07:24Z")

</div>

Hi,  
Setting tgv=0 for the right-hand side means that you put zero as Dirichlet value.  
I suspect that you do not manage correctly the boundary condition related to your Newton method.  
Consider that you have to solve J(u\_{k+1}-u\_k)+F(u\_k)=0, with J the jacobian matrix of F at u\_k. There are two ways to do it: either you solve it in the unknown u\_{k+1}, or in the unknown \delta u\_{k+1}\equiv u\_{k+1}-u\_k. Let me consider the second choice, that seems to correspond to what you say.  
Assume that you want to set the Dirichlet boundary condition u=u\_b on the boundary.  
Then if you solve the problem in the unknown \delta u\_{k+1}, the boundary condition that you have to set is \delta u\_{k+1}=u\_b-u\_k on the boundary. If by chance u\_k has the right BC (u\_k=u\_b), the right-hand side becomes 0. This is maybe what you do by setting tgv=0. On the contrary if you set \delta u\_{k+1}=u\_b on the boundary, with tgv non zero, this is wrong (except if u\_b=0).

The correct way should be to set the BC \delta u\_{k+1}=u\_b-u\_k on the boundary, with tgv=-1 for matrix and right-hand side.

---

<div class="post-metadata">

**Author:** ![marc2025](https://avatars.discourse-cdn.com/v4/letter/m/3e96dc/32.png) [@marc2025](https://community.freefem.org/u/marc2025)\
**Post date:** [March 6, 2026, 9:05am UTC](https://community.freefem.org/t/explanation-of-tgv-0/4235/3 "2026-03-06T09:05:51Z")

</div>

Hi @fb77 , thank you very much for the explanation. Indeed, as you have described, I am trying to solve a system J (\delta u\_{k+1)} = -F(u\_k).  
I tried setting the boundary to u\_b - u\_k and then using tgv=-1 as you suggested, however my approximate solution still becomes unbounded after each Newton iteration. As before, the only time my algorithm converges is when the tgv for the right-hand side is 0. I’m not sure if perhaps I have misunderstood what you said or if there is some bug in my code. I am copying my code here, in case that is helpful.

int n = 100;  
real k1 = 0.1;  
real k2 = -0.16;  
int Ftgv = -1;  
int Jtgv = -1;  
//define the boundary: R in [0,1] and z in [−1,1]  
border Gamma1(t=0., 1.){x = t; y = -1;}  
border Gamma2(t=0., 1.){x = 1; y = -1+2_t;}  
border Gamma3(t=0., 1.){x = 1-t; y = 1;}  
border Gamma4(t=0., 1.){x = 0; y = 1-2_t;}  
mesh M = buildmesh(Gamma1(n) + Gamma2(n) + Gamma3(n) + Gamma4(n));  
int[int] lab = labels(M);  
//define finite element space  
fespace Vh(M, P2);  
Vh psi, phi, psiExact, error;  
//exact solution  
func Exact = -60./(9. \* x^2 + (y+2.)^2);  
psiExact = Exact;  
//define variational forms  
varf vJ(w,phi) = int2d(M)(dx(w)_dx(phi) + dy(w)dy(phi) + dx(w)phi/x - wpsiphi_(2_k1+3_k2_x^2_psi)) + on(lab, w=psiExact-psi);  
varf vF(w,phi) = int2d(M)(dx(psi)_dx(phi) + dy(psi)dy(phi) + dx(psi)phi/x - (psi^2(k1+k2x^2_psi))_phi) + on(lab, w=psiExact-psi);  
//initial guess  
psi = Exact_(1. + x\*(x-1.)_(z+1.)_(z-1.));  
plot(psiExact, wait=true, cmm=“Exact Solution”, value=true);  
//Newton’s Method  
int iter = 20;  
real tol = 1.0e-12;  
for(int i=1; i \< iter; ++i){  
matrix J = vJ(Vh, Vh, tgv = Jtgv);  
real[int] F = vF(0, Vh, tgv = Ftgv);  
real[int] inc = J^-1 \* F;  
psi -= inc;  
plot(psi, wait=true, cmm=“Solution at iteration #”+i, value=true);  
if(F.linfty \< tol) break;  
}  
error = abs(psi - Exact);  
real L2error = error.l2;  
cout \<\< "L2error = " \<\< L2error \<\< endl;

---

<div class="post-metadata">

**Author:** ![fb77](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/fb77/32/3796_2.png) [@fb77](https://community.freefem.org/u/fb77)\
**Post date:** [March 6, 2026, 10:23am UTC](https://community.freefem.org/t/explanation-of-tgv-0/4235/4 "2026-03-06T10:23:16Z")

</div>

In your code you solve the problem in the unknown inc=-\delta u\_{k+1}. Therefore you have to set the boundary condition as u\_k-u\_b.

```auto
int n = 100;
real k1 = 0.1;
real k2 = -0.16;
int Ftgv = -1;
int Jtgv = -1;
//define the boundary: R in [0,1] and y in [-1,1]
border Gamma1(t=0., 1.){x = t; y = -1;}
border Gamma2(t=0., 1.){x = 1; y = -1+2*t;}
border Gamma3(t=0., 1.){x = 1-t; y = 1;}
border Gamma4(t=0., 1.){x = 0; y = 1-2*t;}
mesh M = buildmesh(Gamma1(n) + Gamma2(n) + Gamma3(n) + Gamma4(n));
int[int] lab = labels(M);
//define finite element space
fespace Vh(M, P2);
Vh psi, phi, psiExact, error;
//exact solution
func Exact = -60./(9. * x^2 + (y+2.)^2);
psiExact = Exact;
//define variational forms
varf vJ(w,phi) = int2d(M)(dx(w)*dx(phi) + dy(w)*dy(phi) + dx(w)*phi/x - w*psi*phi*(2*k1+3*k2*x^2*psi)) + on(lab, w=psi-psiExact);
varf vF(w,phi) = int2d(M)(dx(psi)*dx(phi) + dy(psi)*dy(phi) + dx(psi)*phi/x - psi^2*(k1+k2*x^2*psi)*phi) + on(lab, w=psi-psiExact);
//initial guess
psi = Exact*(1. + x*(x-1.)*(z+1.)*(z-1.));
plot(psiExact, wait=true, cmm="Exact Solution", value=true);
//Newton's Method
int iter = 20;
real tol = 1.0e-12;
for(int i=1; i < iter; ++i){
matrix J = vJ(Vh, Vh, tgv = Jtgv);
real[int] F = vF(0, Vh, tgv = Ftgv);
real[int] inc = J^-1 * F;
psi[] -= inc;
plot(psi, wait=true, cmm="Solution at iteration #"+i, value=true);
if(F.linfty < tol) break;
}
error = abs(psi - Exact);
real L2error = error[].l2;
cout << "L2error = " << L2error << endl;

```

---

<div class="post-metadata">

**Author:** ![marc2025](https://avatars.discourse-cdn.com/v4/letter/m/3e96dc/32.png) [@marc2025](https://community.freefem.org/u/marc2025)\
**Post date:** [March 8, 2026, 7:40am UTC](https://community.freefem.org/t/explanation-of-tgv-0/4235/5 "2026-03-08T07:40:21Z")

</div>

You are absolutely correct, my sincerest apologies for this silly mistake. After changing the boundary condition, my code is now working as it should be. Additionally, the L^2 error is much more reasonable than before.  
Thank you for taking the time to help me!
