sandbox/easystab/domain_derivative_1D_adapt.m
Testing the domain geometry derivative
This is basically the same as domain_derivative_1D.m except that here we adapt the domain accordingly to the solution at each Newton iteration. This means that it converges to the true solution of the problem instead of approximating the function by its Taylor expansion outside the computational domain.
clear all; clf;
% parameters
N=50; % number of grid points
p=-1.21; % desired slope at L
L=1; % initial guess of the domain size
method='fd'; % the differentiation
% useful
[d.x,d.xx,d.wx,x]=dif1D(method,0,L,N,5);
Z=zeros(N,N);
I=eye(N);
%initial guess
sol0=[x.*(1-x);0];
sol=sol0;
% Newton iterations
quit=0;count=0;
while ~quit
% the present solution and its derivatives
l=sol(N+1); h=sol(1:N); hx=d.x*h; hxx=d.xx*h;
% Show present solution
xx=linspace(1-2*abs(l),1+2*abs(l),20);
plot(x,h,'b-',L+l,0,'ro',xx,h(N)+(xx-1)*hx(N),'r',x(N),h(N),'b.', ...
[L,L],[-0.5,0.5],'k--',[0,1.5*L],[0,0],'k--');
xlim([0,1.5*L]); ylim([-0.5,0.5]);grid on; drawnow;
pause(1) ;% if count==1; break; end
Domain adaptation
Here is the core of this code and the difference with domain_derivative_1D.m. The previous Newton iteration has provided us with a guess for the domain size by computing the value of \ell, so the domain size should now be L+\ell. Here we trust this value, and reconstruct the problem for this domain size and do another Newton step. For this we need to rebuild the grid x and the differentiation matrices.
% addapt the domain
L=L+l;
We need to interpolate the previous solution h on the new grid. The value of h outside the grid of the previous iteration is approximated by a linear Taylor expansion, because this is what we have assumed to get the solution.
xx=linspace(1.0001*L,2*L,100)';
hh=h(N)+(xx-L)*hx(N); % linear extrapolation outside of the domain
[d.x,d.xx,d.wx,x]=dif1D(method,0,L,N,5); % New differentiation
h=interp1([x; xx],[h; hh],x); % interpolation to the new grid
Now we have transformed the domain so the best approximation for the domain size is now L thus we reset \ell=0 for the next Newton iteration
sol(1:N)=h; % update h
sol(N+1)=0; % set l to zero
And then we resume as in domain_derivative_1D.m
% the present solution and its derivatives (on the new domain)
l=sol(N+1); h=sol(1:N); hx=d.x*h; hxx=d.xx*h;
% nonlinear function
f=[hxx+2; hx(N)+l*hxx(N)-p];
% analytical jacobian
A=[d.xx, Z(:,1); ...
d.x(N,:)+l*d.xx(N,:), hxx(N)];
% Boundary conditions
loc=[1 N];
f(loc)=[h(1); h(N)+l*hx(N)];
A(loc,:)=[I(1,:), 0; ...
I(N,:)+l*d.x(N,:),hx(N)];
% convergence test
res=norm(f,inf);
disp([num2str(count) ' ' num2str(res)]);
if count>50|res>1e5; disp('no convergence'); break; end
if res<1e-9; quit=1; disp('converged'); continue; end
% Newton step
sol=sol-A\f;
count=count+1;
end
set(gcf,'paperpositionmode','auto')
print('-dpng','-r80','domain_derivative_1D_addapt.png')
The figure
Here we see the final result of the computation
Exercices/Contributions
- Please
%}