# Mesh becoming overly fine during adaptation

**URL:** <https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614>\
**Category:** General Discussion\
**Created:** [July 18, 2023, 11:55am UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614 "2023-07-18T11:55:16Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![jna1g18](https://avatars.discourse-cdn.com/v4/letter/j/77aa72/32.png) [@jna1g18](https://community.freefem.org/u/jna1g18)\
**Post date:** [July 18, 2023, 11:55am UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/1 "2023-07-18T11:55:16Z")

</div>

Hi all, I’m quite new to freefem so please try to bear with me. I’ve been trying to implement a mesh adapation into my code for a nonlinear system of three equations in order to make it more efficient. My code uses a Newton scheme to deal with the nonlinearity, which seems to work fine, but I cannot get the mesh adaptation to behave properly; my problem is that with each timestep, the adapted mesh becomes increasingly fine to point where it makes my code less efficient than it was without any mesh adaptation and I see no reason why it should be doing this. The mesh adaptation does not seem to be following the contours of u1, u2 and phi. See below the initial mesh:

 ![initial_mesh](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/7/703e6538fd5addaf2a8fddf0ea6a3e2bdc752d8f.png)

At timestep t=0.1, the adapted mesh looks good and seems to match u1, u2 and phi:

 ![t=0.1](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/8/8491f6b4f931a84dd7168fbfd4df60ded252e858.jpeg)

But then it becomes unnecessarily fine for t=0.2 and t=0.3 etc.:

 ![t=0.2](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/6/63255d01129e96a3044579c59ec7cf13b4dc0f69.jpeg)

 ![t=0.3](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/e/ead3cc0f75417f972b00af3540fb7c5f619fa413.jpeg)

Why is this happening? Why does the mesh become so fine? The mesh does not seem to be adapting to the functions that I have input into the adaptmesh() function. Below I have attached my code for reference (apologies, it is a little messy). Please let me know if my question is not clear.

//Time step  
real dt = 0.1;

//Model parameters  
real mu1 = 0.001;  
real mu2 = 0.001;  
real mu3 = 0.001;  
real V = 0.2;  
real D = 0.01;  
real Vr = 0.0015;  
real F = 96485.3;  
real T = 298;  
real R = 8.31;  
real k0pb = 0.00000021;  
real k0pb02 = 0.00000025;  
real Eminus = 0.13;  
real Eplus = 1.56;

//Initial adaptation error  
real Eadapt = 0.1;

//Error threshold and initial error for Newton loop  
real eps = 1e-6;  
real err = 1;

//Construction of initial mesh  
real L = 0.02;  
real W = 0.012;  
int meshSize2 = 40;  
int meshsize3 = meshSize2\*(L/W);

int wall1 = 1;  
int wall2 = 2;  
int inlet = 3;  
int outlet = 4;

mesh dom4;

border b1(t=0., 1.){x=W_t; y=0; label=inlet;};  
border b2(t=0., 1.){x=W; y=L_t; label=wall2;};  
border b3(t=0., 1.){x=W-W_t; y=L; label=outlet;};  
border b4(t=0., 1.){x=0; y=L-L_t; label=wall1;};

dom4 = buildmesh(b1(meshSize2) + b2(meshsize3) + b3(meshSize2) + b4(meshsize3));  
plot(dom4, wait=true);

//Defining function spaces, variables and test functions (note, test functions are denoted as v followed by a number e.g. v1)  
fespace Vh(dom4, P2);  
Vh du1, v1, u1, uu1, uin1, uin01, uout01;

fespace Vh2(dom4, P2);  
Vh2 du2, v2, u2, uu2, uin2, uin02, uout02;

fespace Vh3(dom4, P2);  
Vh3 dphi, v3, phi;

//Setting up problem (the unknowns are the corrections du1, du2 and dphi to the variables u1, u2 and phi)  
problem dHeat (du1, du2, dphi, v1, v2, v3)  
=int2d(dom4)(  
du1_v1  
+ du2_v2  
+ dt_mu1_(dx(du1)_dx(v1) + dy(du1)dy(v1))  
+ 2dt_mu1\*(F/(R_T))_(u1\*(dx(dphi)_dx(v1) + dy(dphi)dy(v1)) + du1(dx(phi)dx(v1) + dy(phi)dy(v1)))  
- dt(6V/(W^2))x(W-x)_(du1_dy(v1))  
+ dt_mu2\*(dx(du2)_dx(v2) + dy(du2)dy(v2))  
+ dtmu2_(F/(R_T))_(u2\*(dx(dphi)_dx(v2) + dy(dphi)dy(v2)) + du2(dx(phi)dx(v2) + dy(phi)dy(v2)))  
- dt(6V/(W^2))x(W-x)_(du2_dy(v2))  
+ dt_F\*(2_mu1-2_mu3)_(dx(du1)dx(v3) + dy(du1)dy(v3))  
+ dtF(mu2-mu3)_(dx(du2)_dx(v3) + dy(du2)dy(v3))  
+ dt(F^2/(R_T))_((4_mu1+2_mu3)_(u1\*(dx(dphi)_dx(v3) + dy(dphi)dy(v3)) + du1(dx(phi)dx(v3) + dy(phi)dy(v3))) + (mu2+mu3)(u2(dx(dphi)dx(v3) + dy(dphi)dy(v3)) + du2(dx(phi)dx(v3) + dy(phi)dy(v3))))  
)  
+ int2d(dom4)(  
u1v1  
+ u2v2  
+ dtmu1_(dx(u1)_dx(v1) + dy(u1)dy(v1))  
+ 2dt_mu1\*(F/(R_T))u1(dx(phi)dx(v1) + dy(phi)dy(v1))  
- dt(6V/(W^2))x(W-x)_(u1_dy(v1))  
+ dt_mu2\*(dx(u2)_dx(v2) + dy(u2)dy(v2))  
+ dtmu2_(F/(R_T))u2(dx(phi)dx(v2) + dy(phi)dy(v2))  
- dt(6V/(W^2))x(W-x)_(u2_dy(v2))  
+ dt_F\*(2_mu1-2_mu3)_(dx(u1)dx(v3) + dy(u1)dy(v3))  
+ dtF(mu2-mu3)_(dx(u2)_dx(v3) + dy(u2)dy(v3))  
+ dt(F^2/(R_T))_((4_mu1+2_mu3)u1(dx(phi)dx(v3) + dy(phi)dy(v3)) + (mu2+mu3)u2(dx(phi)dx(v3) + dy(phi)dy(v3)))  
)  
+ int2d(dom4)(  
-uu1v1  
-uu2v2  
)  
+ int1d(dom4, outlet)(dt(6V/(W^2))x(W-x)_(v1_u1) + dt_(6_V/(W^2))x(W-x)_(v2_u2))  
- int1d(dom4, wall2)(dt_(1/(2_F))v1(4_F_k0pb_u1_sinh((F/(R_T))_(-phi-Eminus-(R_T/(2_F))log(abs(u1)))))  
+ dtv3_(4_F_k0pb_u1_sinh((F/(R_T))_(-phi-Eminus-(R_T/(2_F))_log(abs(u1))))))  
+ int1d(dom4, wall1)(dt_(1/(2_F))v1(4_F_k0pb_u1\*(u2/1.5)_sinh((F/(R_T))_(3-phi-Eplus+(R_T/(2_F))log(abs(u1/u2)))))  
-dt(2/F)v2(4_F_k0pb_u1\*(u2/1.5)_sinh((F/(R_T))_(3-phi-Eplus+(R_T/(2_F))log(abs(u1/u2)))))  
-dtv3_(4_F_k0pb_u1_(u2/1.5)_sinh((F/(R_T))_(3-phi-Eplus+(R_T/(2\*F))\*log(abs(u1/u2))))))

```
+ int1d(dom4, outlet)(dt*(6*V/(W^2))*x*(W-x)*(v1*du1) + dt*(6*V/(W^2))*x*(W-x)*(v2*du2))
- int1d(dom4, wall2)(dt*(1/(2*F))*v1*(du1*4*F*k0pb*(sinh((F/(R*T))*(-phi-Eminus-(R*T/(2*F))*log(abs(u1)))) - 0.5*cosh((F/(R*T))*(-phi-Eminus-(R*T/(2*F))*log(abs(u1))))) + dphi*(-4*F^2*k0pb/(R*T))*u1*cosh((F/(R*T))*(-phi-Eminus-(R*T/(2*F))*log(abs(u1)))))
+ dt*v3*(du1*4*F*k0pb*(sinh((F/(R*T))*(-phi-Eminus-(R*T/(2*F))*log(abs(u1)))) - 0.5*cosh((F/(R*T))*(-phi-Eminus-(R*T/(2*F))*log(abs(u1))))) + dphi*(-4*F^2*k0pb/(R*T))*u1*cosh((F/(R*T))*(-phi-Eminus-(R*T/(2*F))*log(abs(u1))))))
+ int1d(dom4, wall1)(dt*(1/(2*F))*v1*(du1*4*F*k0pb02*(u2/1.5)*(sinh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))) + 0.5*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))))
+ du2*4*F*k0pb02*(u1/1.5)*(sinh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))) - 0.5*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2))))) + dphi*(-4*F^2*k0pb02/(R*T))*u1*(u2/1.5)*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))))
-dt*(2/F)*v2*(du1*4*F*k0pb02*(u2/1.5)*(sinh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))) + 0.5*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))))
+ du2*4*F*k0pb02*(u1/1.5)*(sinh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))) - 0.5*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2))))) + dphi*(-4*F^2*k0pb02/(R*T))*u1*(u2/1.5)*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))))
-dt*v3*(du1*4*F*k0pb02*(u2/1.5)*(sinh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))) + 0.5*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))))
+ du2*4*F*k0pb02*(u1/1.5)*(sinh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2)))) - 0.5*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2))))) + dphi*(-4*F^2*k0pb02/(R*T))*u1*(u2/1.5)*cosh((F/(R*T))*(3-phi-Eplus+(R*T/(2*F))*log(abs(u1/u2))))))
+ on(inlet, du1=uin1-u1)
+ on(inlet, du2=uin2-u2)
;

```

//initialisation

real t=0;

uu1=0.7; //old value of u1 (value at the previous time step)  
uin01=0.7; //initial inlet value of u1  
uout01=0.7; //intial outlet value of u1  
u1=0.7; //Initial guess for Newton iteration (note, this is just the value at t=0)

uu2=1.5; //old value of u2 (value at the previous time step)  
uin02=1.5; //initial inlet value of u2  
uout02=1.5; //intial outlet value of u2  
u2=1.5; //Initial guess for Newton iteration (note, this is just the value at t=0)

phi=1; //starting guess for phi in Newton iteration

for (int m=0; m\<=5/dt; m++){ //Time loop

```
t = t+dt;

uin1 = uin01 + dt*(V*D*W/Vr)*(uout01-uin01); //forward difference scheme applied to equation for inlet value of u1
uin01 = uin1;   

uin2 = uin02 + dt*(V*D*W/Vr)*(uout02-uin02); //forward difference scheme applied to equation for inlet value of u2
uin02 = uin2;

for(int G=0; G<4; G++){ //Mesh adaptation loop
    for (int i=0; i<=50; i++){ //Newton iteration loop
        dHeat;  
        u1[]+=du1[]; //add the corrections to the current approximations for the unknowns i.e. u1=u1+du1 etc.
        u2[]+=du2[];
        phi[]+=dphi[];
        real Lu1= u1[].linfty, Lu2=u2[].linfty, Lphi=phi[].linfty;
        err = du1[].linfty/Lu1 + du2[].linfty/Lu2 + dphi[].linfty/Lphi;
        cout<<i<<"err="<<err<<" eps="<<eps<<endl;

        if(err<eps) break; //If the error is less than the threshold value, end the Newton loop
        if(i>3 && err>10) break; //If the error begins to diverge, end the Newton loop
}
dom4 = adaptmesh(dom4, u1, u2, phi, err=Eadapt, nbvx=40000, hmin=0.0001); //Adapt the mesh to the newly obtained solutions
u1=u1;  
u2=u2; //Interpolate the newly found solutions upon the new version of the mesh 
phi=phi;
Eadapt=Eadapt/2; 
}

uu1 = u1; //update solution at previous timestep
uout01 = int1d(dom4, outlet)(u1)/W; //Update the old outlet value

uu2 = u2;
uout02 = int1d(dom4, outlet)(u2)/W;

//Plot the results for this current timestep
plot(phi, value=true, wait=true); 
    

plot(u2, value=true, wait=true); //fill=true,
    

plot(u1, value=true, wait=true); //fill=true,

```

}

---

<div class="post-metadata">

**Author:** ![aszaboa](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/aszaboa/32/2918_2.png) [@aszaboa](https://community.freefem.org/u/aszaboa)\
**Post date:** [July 18, 2023, 3:00pm UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/2 "2023-07-18T15:00:36Z")

</div>

I played around with 2D mesh adaptation a few years ago. For me, it turned out not to be worth it.  
Since your problem is not that big (mesh limit max 40000) you might just do better with creating a sufficiently fine mesh by hand.

I think the adaptation is based of the change (derivative) of the function you supply. As your solution seems to be sufficiently smooth, the program just refines everywhere.

You can play around with the error parameter, max mesh size, and specify different functions to adapt to (e.g., solution^2 or something).

---

<div class="post-metadata">

**Author:** ![marchywka](https://avatars.discourse-cdn.com/v4/letter/m/ee59a6/32.png) [@marchywka](https://community.freefem.org/u/marchywka)\
**Post date:** [July 18, 2023, 3:22pm UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/3 "2023-07-18T15:22:20Z")

</div>

The documentation on adaptmesh should help but probably you want  
it to be fine where things vary quickly. I guess if you have an expoential,  
it will vary more quickly where it is large but you can play with that  
and also the number of veritcies allowed.

---

<div class="post-metadata">

**Author:** ![jna1g18](https://avatars.discourse-cdn.com/v4/letter/j/77aa72/32.png) [@jna1g18](https://community.freefem.org/u/jna1g18)\
**Post date:** [July 18, 2023, 6:45pm UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/4 "2023-07-18T18:45:50Z")

</div>

Hi, thanks for taking the time to reply. I’ll take onboard what you’ve told me! The code I posted is a solution to a toy model; in the real model, the diffusion coefficients (parameters mu1, mu2, mu3) are significantly smaller and, consequently, a boundary layer forms at both wall1 and wall2, over which the variables u1 and u2 vary quite rapidly. Do you think that a mesh adaptation would be good to employ in this case?

---

<div class="post-metadata">

**Author:** ![jna1g18](https://avatars.discourse-cdn.com/v4/letter/j/77aa72/32.png) [@jna1g18](https://community.freefem.org/u/jna1g18)\
**Post date:** [July 18, 2023, 6:48pm UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/5 "2023-07-18T18:48:54Z")

</div>

Hi, thanks for the response! I’ve had quite a close look at the adaptmesh section and I tried a few different things, such as lowering nbvx and increasing hmin; I had some success, however it merely shifted the issues onto a later timestep unfortunately.

---

<div class="post-metadata">

**Author:** ![marchywka](https://avatars.discourse-cdn.com/v4/letter/m/ee59a6/32.png) [@marchywka](https://community.freefem.org/u/marchywka)\
**Post date:** [July 18, 2023, 8:22pm UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/6 "2023-07-18T20:22:43Z")

</div>

I’m working on a phase boundary problem and used something like this,  
“c” is the phase dof and the others are things like charge distribution.

` Thnew=adaptmesh(Thnew, 1.0_Grad22(c)+10_Grad22(pmn)+10_Grad22(cln)+1e5_Grad22(v),hmin=0.2\*.001_szy ,hmax=.03_szy,abserror=1, nbvx=1e5);

 ![phaseff](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/8/8b2c04f00bf858971bd9a40e310ec1e75faa9d62.jpeg)

or closer,

 ![phaseff2](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/a/aebcf70669451b7e92600bd7b9aea6843abff949.jpeg)

but the reason I’m posting is to show this lol,

 ![phasemjm](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/5/59eb904055653c2e33aaaa98809c83e79cbb7394.jpeg)

which gives me more control over how the mesh is organized. In this case,  
I’m defining a local etch rate based on concentrations solved by FF iteration.  
that move this phase boundary down from the liquid above. You could probably  
do something similar by manipulating isoline implemented by freefem  
but there are a lot of complexities when actually moving a surface, see  
for example the freefem movemesh situation. I just trash the existing mesh,  
create an array of points at multiples of the local etch amount and use freefem  
triangulate on the points. I guess regular meshes could be pathological  
and with enough points the result should not be sensitive to the mesh but  
there are issues with adaptation like conserving amount of stuff etc.  
This also lets me play with interpolation issues. fwiw.

`

---

<div class="post-metadata">

**Author:** ![jna1g18](https://avatars.discourse-cdn.com/v4/letter/j/77aa72/32.png) [@jna1g18](https://community.freefem.org/u/jna1g18)\
**Post date:** [July 19, 2023, 2:30pm UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/7 "2023-07-19T14:30:24Z")

</div>

This looks interesting, I’ll certainly have a close look at this!

---

<div class="post-metadata">

**Author:** ![cmd](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/cmd/32/67_2.png) [@cmd](https://community.freefem.org/u/cmd)\
**Post date:** [July 20, 2023, 11:09am UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/8 "2023-07-20T11:09:54Z")

</div>

@aszaboa I would encourage you to try again with adaptation. It is very powerful, and I personally haven’t encountered problems on “smooth” solutions (quite the opposite, in fact). If the mesh becomes too coarse for your liking, you can adjust the `err` or `hmax` parameters.

---

<div class="post-metadata">

**Author:** ![cmd](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/cmd/32/67_2.png) [@cmd](https://community.freefem.org/u/cmd)\
**Post date:** [July 20, 2023, 11:11am UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/9 "2023-07-20T11:11:20Z")

</div>

Can you re-post the file that is giving you issues as an attachment? The code did not paste correctly.

---

<div class="post-metadata">

**Author:** ![jna1g18](https://avatars.discourse-cdn.com/v4/letter/j/77aa72/32.png) [@jna1g18](https://community.freefem.org/u/jna1g18)\
**Post date:** [July 20, 2023, 11:28am UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/10 "2023-07-20T11:28:11Z")

</div>

Hi Chris, hopefully this works. Let me know if it doesn’t or if there is a better way to upload my code.

[ToPostOnForum.edp](https://community.freefem.org/uploads/short-url/zWLfiT26YCmhq9t25D3Ksnr7HyV.edp) (7.7 KB)

---

<div class="post-metadata">

**Author:** ![cmd](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/cmd/32/67_2.png) [@cmd](https://community.freefem.org/u/cmd)\
**Post date:** [July 20, 2023, 11:44am UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/11 "2023-07-20T11:44:28Z")

</div>

It is just a silly mistake: you are overwriting the value of `Eadapt`. Here’s a fix:  
[forumfix.edp](https://community.freefem.org/uploads/short-url/nJpwpN0qKVst24sLB5U4zGZO8DB.edp) (7.5 KB)

---

<div class="post-metadata">

**Author:** ![jna1g18](https://avatars.discourse-cdn.com/v4/letter/j/77aa72/32.png) [@jna1g18](https://community.freefem.org/u/jna1g18)\
**Post date:** [July 20, 2023, 3:12pm UTC](https://community.freefem.org/t/mesh-becoming-overly-fine-during-adaptation/2614/12 "2023-07-20T15:12:16Z")

</div>

Ah wow, thank you! I’m not sure how I missed this XD
