Non homogeneous boundary and initial conditions

Hi,
i try to write a code who calculate the solution of the problem:

\partial_t u + u \partial_x u - \nu \partial^2_x u =1+x, \ x \in [0,1], t \in [0,1]

with initial condition:

u(x,0)= -4 \nu \dfrac{x+3/2}{ (x+3/2)^2+\nu } - (x+2)

and boundary conditions:

u(0,t)= -4 \nu \dfrac{1+1/2 e^t}{ (1+1/2 e^t)^2 +\nu }-(1+e^t),
u(1,t)= -4 \nu \dfrac{ 2+1/2 e^t }{ (2+1/2 e^t)^2 +\nu} -(2+e^t).

The exact solution of this problem is:

u(x,t)=-4 \nu \dfrac{1+x+1/2 e^t} { (1+x+1/2 e^t)^2+\nu } -(1+x+e^t)

We can take \nu=1..

The goal is to calculate the approximate solution with FF+ and compare it to the exact solution compring the graphs of the two functions. I try to write the Following code but there is an error and i Don’t find how correct it.
Thank you in advance to the help.

load "iovtk"

verbosity=1;
real nu=1.;
int n = 100; 
real a=0, b=1;
mesh Th=square(n,1,[a+x*(b-a),y/10]);
//plot(Th,wait=false);
fespace Vh(Th,P2,periodic=[[1,x],[3,x]]);
Vh u,v;
u = 0;
real T=0;
func f = 1+x;

func real uex(real t) //The exact solution
{
return -4*nu* (1.+x+(1./2.)*exp(t))/ ( (1.+x+(1./2.)*exp(t))^2+nu) - (1.+x+exp(t));
};

func up= -4*nu* (x+(3./2.))/((x+(3./2.))^2+nu)-(x+2.);//Initial condition

func real g(real t) //Boundary condition u(x=0,t)
{
return -4*nu*(1.+(1./2.)*exp(t))/((1+(1./2.)*exp(-t))^2+nu) -(1+exp(t));
};

func real r(real t) //Boundary condition u(x=1,t)
{
return -4*nu*(2.+(1./2.)*exp(t))/((2.+(1./2.)*exp(t))^2+nu) -(2+exp(t));
};

Vh fh=f;
Vh gh=g;
Vh rh=r;
Vh uph=up; 
real dt = 0.1;
Vh g0,g1;
Vh nith = 0.0; // for nonlinear iterations


problem Pb(u,v) = int2d(Th)( u*v/dt + nu*dx(u)*dx(v) ) - int2d(Th)( up*v/dt + f*v)
+ int2d(Th) (g0*v) + int2d(Th) (g1*u*v) + int2d(Th) (nith*dx(u)*v)+ on(2,u=g)+ on(4,u=r);


int k=0;        
int noit = 10; // maximum of iterations
real errnlpb = 0;  // error of iteration of Pb
real normuh = 0;
 
ofstream fout("uh.txt");
fout << "# t uh" << endl;


ofstream fouti("U.txt");
fouti << "# t U" << endl;

for(int it=0; it<1.; ++it)
{
     T += dt; 
    // Nonlinear iterations for Pb solution
    nith = u; // start nonlinear iterations  with last solution for Pb
    g0=u*dx(u);
    g1=dx(u);
    cout << "    Solving nonlinear problem.\n";
    for(k=1;k<noit; ++k) {
     up[]=u[];
     Pb;
      normuh = sqrt(int1d(Th,1)(square(u))); // L^2 nor of the solution of Pb
      errnlpb = sqrt(int1d(Th,1)(square(u - nith))); // L^2 norm of the error in nonlinear iteration of Pb
      cout << "        " << k << ": error = " << errnlpb << endl;
      if(errnlpb <= 1E-5*normuh) // stopping criteria. If relative error
      break;        // is less than 1E-5 stop nonlinear iterations of Pb
      nith = u; // prepare new iteration
      g0=u*dx(u);
      g1=dx(u);
      }
    // Check convergence for Pb  
    if(k >= noit) {
      cout << "Nonlinear solver for Pb did not converged.\n";
      cout << "Error = " << errnlpb << endl;
      cout << "|| u|| = " << normuh << endl;
      exit(1); // exit the program with error code 1
      }
Vh uh=uex;

 plot(u,wait=1,dim=1,fill=true,cmm=it,value=1);

 plot(uh,wait=1,dim=1,fill=true,cmm=it,value=1);


fout.flush;

fouti.flush;

}

You are solving a time-dependant nonlinear problem. There are tools out there to help you so that you don’t have to reimplement everything yourself. You should use TSSolve, cf. this linear example + this paper. You need to supply two FreeFEM functions to update the Jacobian of your problem as well as evaluate the residual.

Hi
i try the idea but it’s the same, i obtain no good results. Can any one help me please to write a code who resolve the problem
$$\partial_t u + u \partial_x u - \nu \partial_x^2 u = 1+x, \ t >0, x \in ]0,1[,$$
with initial condition
u(x,0)= \dfrac{- 2 \nu}{x+3/2} +2+x,
and boundary conditions
u(0,t)= \dfrac{-2 \nu}{1+1/2 e^{-t}} +1+e^{-t} and u(1,t)= \dfrac{-2 \nu}{2+1/2 e^{-t}} +2+e^{-t}.

and compare the approximate solution with the exact solution
$$u(x,t)= -2 \nu \dfrac{1}{1+x+1/2 e^{-t}} +x+1+e^{-t}$$

Thank’s in advance to the help.

Here is an example code I created for TSSolve with Navier Stokes that may be helpful for you (or anyone else). It is not at all optimal, but does show the basic steps involved using TSSolve for nonlinear systems.
NS-TSSolve.edp (2.9 KB)

How does this compare to SNESSolve? The one example of this I thought
was useful and it has been producing believable ( I have not checked details )
results for me in a simple drift-diffusion problem.

TSSolve uses SNESSolve to resolve the nonlinear problems at each time step.

Since the range of t appears to be limited and the mesh is not likely to change
unpredictably, with time, what is wrong with just using the y axis for time?
Since the OP provides an analytical solution, I’ll see if I can set it up this
way :slight_smile: SNESSolve shouldn’t know the difference between y and t…

Frankly this looks too good to be accurate but the reason I’m responding is
to test my knowledge and scripts :slight_smile: See if the attached is helpful. The relevant function
and jacobian are included but a lot of the snes stuff is in my macro which I can post
but would like to clean up first. Fortuitous or accidental agreements may be quite
common and there are likely errors here so comments appreciated. Thanks.
Note that “y” is time and the diff is the analytical soln minus the FF soln.
See the code for details.

l2=4.354910e-09 l2soln=2.196520e+01 mssoln=2.178491e+01 sd-1.802880e-01
times: compile 1.298770e-01s, execution 1.074365e+00s,  mpirank:0
 ######## We forget of deleting   27 Nb pointer,   0Bytes  ,  mpirank 0, memory leak =508272
 CodeAlloc : nb ptr  8250,  size :716256 mpirank: 0
Ok: Normal End



forum11snes.edp (2.4 KB)


// forum11snes.edp
// https://community.freefem.org/t/non-homogeneous-boundary-and-initial-conditions/154/7

load "PETSc"
load "MUMPS_mpi"
 macro dimension()2// EOM
include "macro_ddm.idp"
include "cube.idp"
include "mysness.idp"

// needed for mysness.idp
include "myboxes.idp"
include "surfaces.idp"
include "mjmio.idp"



func Pk = P1;                    // Finite-element space

int nx   = getARGV("-nx" , 20) ; //
int nt   = getARGV("-nt" , 20) ; //
real nu   = getARGV("-nu" ,1.0) ; //
int split= getARGV("-split", 1);

// b,r,t,l
int[int] lbl=[1,2,3,4];
mesh Th = square(nx,nt,label=lbl);

// boundary funcs  and known solutions
func real exact(real xx, real t) { 
real et=exp(t);
real p1=1+xx+.5*et;
return -4.0*nu*(p1)/( p1*p1+nu)-(1+xx+et);
} // exact
func real uinit(real xx)
	{real p1=xx+1.5; return -4.0*nu*(p1)/(p1*p1+nu)-(xx+2); }
func real uzt(real t){real et=exp(t); real p1=1+.5*et; 
	return -4.0*nu*(p1)/(p1*p1+nu)-(1+et); }
func real uonet(real t){real et=exp(t); real p1=2+.5*et; 
	return -4.0*nu*(p1)/(p1*p1+nu)-(2+et); }

fespace Vh(Th,Pk);
// a bunch of stuff for my macros I need to work out yet. 
// this defines u and A etc
Mat A;
buildMat(Th, split, A, Pk, mpiCommWorld);
int solnguessidx=0;

Vh u = 0;
Vh soln=exact(x,y);
mesh ThBackup=Th;

// the boundary conditions 
macro EQUBC +on(1,phi=uinit(x))  +on(2,phi=uonet(y))  +on(4,phi=uzt(y))    // EOM

// needed functions, a bit idiosyncratic maybe need to fix macro
// but should be more or less decipherable
varf equpro(phi,vphi)
=int2d(Th)(dy(phi)*vphi+u*dx(phi)*vphi+nu*dx(phi)*dx(vphi))
-int2d(Th)(vphi*(1+x))
EQUBC
;
// use u here not phi... 
varf equres(phi,vphi)
=int2d(Th)(dy(u)*vphi+u*dx(u)*vphi+nu*dx(u)*dx(vphi))
-int2d(Th)(vphi*(1+x))
EQUBC ;
// diff wrt "u"
varf equj(phi,vphi)
=int2d(Th)(dy(phi)*vphi+dx(phi)*vphi+nu*dx(phi)*dx(vphi))
EQUBC  ;

snesjac(equJ,equj)
// define the evaluate function
sneseval(equRes,equres)
// the third parameter is probably not right in general
mysnesflags(u,equpro,equJ,equRes,equj,0);
// my macro returns u;
Vh diff=soln-u;
real l2=int2d(Th)(diff*diff);
real l2soln=int2d(Th)(soln*soln);
real mssoln=int2d(Th)(soln);
mssoln=mssoln*mssoln;
cout<<" l2="<<l2<<" l2soln="<<l2soln<<" mssoln="<<mssoln<<" sd-"<<(l2soln-mssoln)<<endl; cout.flush;

plot(soln,cmm="analyical", fill=1,wait=1,value=1);
plot(u,cmm="ff soln",fill=1,wait=1,value=1);
plot(diff,cmm="diff", fill=1,wait=1,value=1);
mmsave("forummacrotest.txt",u,Vh);







here is the output file fwiw,

forummacrotest.zip (2.4 KB)