sandbox/easystab/NavierStokesUnStationnary.m
clear all; clf; format compact;
warning('off')
Cartesian ,UNStationnary, Uncompressible, Navier-Stokes with Jacobian resolution
Coded by stab2014/Luis.m and stab2014/PaulValcke.m, on the initial NavierStokesStationnary code.
The structure of the code is the same as StationnaryNS. We changed the expression of the function, the Jacobi and added an Euler March in Time (first order). If you want to understand the structure of the code, take a look at StationnaryNS, then take a look at the comment of the function and the jacobi
Comments
We have no test for the moment, if you have any or experiment to compare, please contribute
You can use this program into find stationnary solutions, it will slowly goes to the solution (if it exist). If you have a very complicate flow to calculate, it might be a good way.
As the fluid is uncompressible, if it is laminar (then a stationnary solution exist), a Poiseuille flow will be instantly created in right conditions. A facingStep is a better test.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%PARAMETERS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%PHYSICAL PARAMETERS
Re=2000; % reynolds number
%GEOMETRIC PARAMETERS
Lx = 2;
Ly = 0.6;
DiamInlet = 0.025; % Diameter of inlet
tmax = 100; %WE ADD A MAXIMUM TIME
%NUMERICAL PARAMETERS=
Nx=200; % number of grid nodes in x
Ny=100; %number of grid nodes in y
dt = 0.1; %STEP BETWEEN TWO TIMES
maxIter = 200; % Maximum number of iteration for Newton method.
resSTOP = 1e-5; % Precision required to stop convergence
%FIXED PARAMETERS OR INTERMEDIATE FORMULAS
pts=5; % number of points in finite difference stencils
alpha=1; % No Under-relaxation
Uinlet = Re*1.79e-5/(1.225*DiamInlet);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%DIFFERENTIATION MATRIXES%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DIFFERENTIATION
[d.x,d.xx,d.wx,x]=dif1D('fd',0,Lx,Nx,pts);
[d.y,d.yy,d.wy,y]=dif1D('fd',0,Ly,Ny,pts);
[D,l,X,Y,Z,I,NN]=dif2D(d,x,y);
% PLAN TRANSFORMATION
%You can transform X and Y as done in geometry
D=map2D(X,Y,D);
D.lap=D.xx+D.yy;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%BOUNDARIES GESTION%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% POSITIONS OF EVERY VECTORS
u=(1:NN)'; v=u+NN; p=v+NN;
II=speye(3*NN);
%%%% EXAMPLE OF DIRICHLET ENTRY : POISEUILLE FLOW ON ONE PART OF ONE BOUNDARY OF THE DOMAIN
%Here this over the height DiamInlet
y_inlet_ind = find(Y(l.left)<=(Ly+DiamInlet)/2 &...
Y(l.left)>=(Ly-DiamInlet)/2);
y_inlet = Y(y_inlet_ind);
% BOUNDARY POSITIONS
dir=[l.ctl;l.ctr;l.cbl;l.cbr;l.left;l.top;l.bot;]; % where to put Dirichlet on u and v
dirInlet = y_inlet_ind;
% Loc will be used to apply boundary condition to the function
loc=[u(dir); v(dir);
u(l.right); ...
v(l.right)];
%MATRIX OF CONSTRAINTS
C=[II([u(dir);v(dir)],:); % ... % Dirichlet on u,v
D.x(l.right,:), Z(l.right,:), Z(l.right,:); ... % Neuman on u at outflow
Z(l.right,:), D.x(l.right,:),Z(l.right,:)]; % ... % Neumann on v at outflow
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INITIAL GUESS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
U = 0*ones(NN,1);
U(dirInlet) = 1.5.*Uinlet.*(1-((2.*(y_inlet-min(y_inlet)))./DiamInlet - 1).^2);
%Initial condition on V
V=zeros(NN,1);
V(y_inlet_ind) = 0;
%Initial condition on P
P=ones(NN,1);
%Initial Solution
sol0=[U(:);V(:);P(:)];
%%%%%%%%%%%%%%%%%RESOLUTION ALGORITHM%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% NEWTON ALGORITHM
sol=sol0;
solM=sol;
solNm1 = sol0; % WE TAKE THE SOLUTION OF PREVIOUS EQUATION
quit=0;
count=0;
for t = 0:dt:tmax
fprintf('t=%g\n',t);
while ~quit
%%%% RELAXATION METHOD
% PREVIOUS TERMS OF THE RESOLUTION
UM = solNm1(u);
VM = solNm1(v);
PM = solNm1(p);
% ACTUAL TERMES
U=alpha.*sol(u) + (1-alpha).*solM(u);
V=alpha.*sol(v) + (1-alpha).*solM(v);
P=alpha.*sol(p) + (1-alpha).*solM(p);
% DEFINITION OF THE DERIVATES
Ux=D.x*U; Uy=D.y*U;
Vx=D.x*V; Vy=D.y*V;
Px=D.x*P; Py=D.y*P;
%DEFINITION OF THE FUNCTIONS YOU WANT TO RESOLVE
% Here we solve Navier stokes in 2D, (conservation of the impulsion on X,Y,
% and conservation of mass). You just replace spatial operator with their
% equivalent in matrixes, the temporal derivative is replaced by (U-UM)/dt.
% Instead of a division by dt, because we integrate the equation, we
% multiply everything by dt.
f=[UM-U-(U.*Ux+V.*Uy+Px-(D.lap*U)/Re).*dt; ...
VM-V-(U.*Vx+V.*Vy+Py-(D.lap*V)/Re).*dt; ...
D.x*U+D.y*V];
%JACOBIAN OF THE EQUATIONS
% We take the previous Jacobi, we just multiply it with dt (like f). We add
% an Idendity because of the $\frac{d(U-Um)}{dU} (resp, $\frac{d(V-Vm)}{dV})
A=[-spd(ones(NN,1))+dt.*(-(spd(Ux)+spd(U)*D.x + spd(V)*D.y )+(D.lap)/Re), -spd(Uy).*dt, (-D.x).*dt; ...
-spd(Vx).*dt, -spd(ones(NN,1))+dt.*(-(spd(Vy) + spd(V)*D.y + spd(U)*D.x )+(D.lap)/Re), (-D.y).*dt; ...
D.x, D.y, Z];
%BOUNDARY CONDITIONS
f(loc)=C*(sol-sol0);
A(loc,:)=C;
%CONVERGENCE TEST
res=norm(f);
disp([num2str(count) ' ' num2str(res)]);
if (count>maxIter) || (res>1e5); disp('no convergence');break; end
if res<resSTOP; quit=1; disp('converged'); end
%NEWTON STEP FOR RESOLUTION
solM = sol;
sol=solM-A\f;
count=count+1;
end
solNm1 = sol;
count = 0;
quit = 0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%PLOTTING%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Place here figures you want at each step of the iterations
%Plot of the Module
figure(1)
Module = sqrt((U.^2+V.^2));
surf(X,Y,reshape(Module,Ny,Nx)); view(2); shading interp; hold on
axis equal
quiver3(X,Y,ones(Ny,Nx).*max(Module),reshape(U,Ny,Nx),reshape(V,Ny,Nx),...
zeros(Ny,Nx),'k');
xlabel('x'); ylabel('y'); title('Poiseuille Flow'); grid off;hold off
colorbar;
drawnow
set(gcf,'paperpositionmode','auto')
print('-dpng','-r80',sprintf('Jet_t%0.1fs.png',t));
end
%Place here figures you only want once at the end
% Creates animated gif
frame = 1;
for t = 3*dt:dt:tmax
im = imread(sprintf('Jet_t%0.1fs.png',t));
[imind,cm] = rgb2ind(im,256);
if frame ==1
imwrite(imind,cm,'Jet.gif','gif','Loopcount',inf);
else
imwrite(imind,cm,'Jet.gif','gif','WriteMode','append',...
'DelayTime',dt);
end
frame = frame+1;
end