Solving a problem with the Energy method with Hermite cubic function
Mostra commenti meno recenti
I tried to solve the problem written below with the energy method using the cubic Hermite function, but only the final value of the approximation is incorrect.
How can I fix this error?
Equation:
-((1+x)y')'+(2+x)/(1+x)y=1
BC:
y(0)=0 ESSENTIAL
y(2)+3y'(2)=1
Exact solution (to be able to compare results): y=x./(1+x)
For testing
>>[x,u]= EnergyHermiteCubicFunctionEssential(58,63);
>> y=x./(1+x);
>>plot(x,u,'r*',x,y,'k-')
My code is:
[x,u]= EnergyHermiteCubicFunctionEssential(58,63);
y=x./(1+x);
plot(x,u,'r*',x,y,'k-')
function [x,u]= EnergyHermiteCubicFunctionEssential(m,nv)
%Energy method with Hermite cubic function
%Input:
%m: number of element of basis
%nv: number of visualization point
%Output:
% x: Vector containing the points at which the solution is approximated
% u: Approximated solution
%Equation:
%-((1+x)y')'+(2+x)/(1+x)y=1
%BC:
%y(0)=0 ESSENTIAL
%y(2)+3y'(2)=1
%Exact solution: y=x./(1+x);
h=2/m;
xc=0:h:2;
%we have 2m+1 elements on the basis
A=zeros(2*m+1); %matrix squared
b=zeros(2*m+1,1); %coloumn vector
for l=1:2*m+1
for j=1:2*m+1
if abs(l-j)<=3 %indices have distance minore o uguale a 3
[al,bl]=support(l,xc);
[aj,bj]=support(j,xc);
lb=max(al,aj); %massimo estremo sinistro
rb=min(bl,bj); %minimo estremo destro
if abs(lb-rb)>10^(-10) %tol
%
% i termini di bordo li hO già inseriti (vedi linea 35)
A(l,j)=integral (@(x) fA(x,l,j,xc),lb,rb);
end
end
end
[lb,rb]=support(l,xc);
if abs(rb-lb)>10^(-10) %is the toll
b(l)=integral(@(x) fB(x,l,xc),lb,rb);
end
end
A(2*m,2*m)=A(2*m,2*m)+1; %1 is the boundery therm
delta=A\b; %delta of approximated solution
h=2/nv; %insert the visualization points
x=0:h:2;
u=zeros(1,nv+1); %row vector %nv+1
%for l=0:m-1 %there are m elements
% devi usare gli indici formali
for l=1:2*m+1 %there are m elements
u=u+delta(l)*fu(x,l,xc);
end
u=u+(1/5.*x); %u(x)=z(x)+l(x); l(x)=1/5 * x;
end
function y=fH(x,l,xc)
m=length(xc)-1;
y=zeros(size(x));
for j=1:length(x)
if l==0 %first special case
if xc(1)<=x(j) && x(j)< xc(2) %mi trovo in [x0,x1) left
y(j)=3.*((x(j)-xc(1))./(xc(2)-xc(1))).^2-2.*((x(j)-xc(1))./(xc(2)-xc(1))).^3;
end
elseif l==m %second special case
if xc(m)<x(j) && x(j)<= xc(m+1) %xc(m) is xm-1, xc(m+1) is xm
%mi trovo in (xm-1,xm] right
y(j)=3.*((xc(m+1)-x(j))./(xc(m+1)-xc(m))).^2-2.*((xc(m+1)-x(j))./(xc(m+1)-xc(m))).^3;
end
else
if xc(l)<x(j) && x(j)<= xc(l+1) %right
y(j)=3.*((xc(l+1)-x(j))./(xc(l+1)-xc(l))).^2-2.*((xc(l+1)-x(j))./(xc(l+1)-xc(l))).^3;
elseif xc(l+1)<=x(j) && x(j)< xc(l+2) %left
y(j)=3.*((x(j)-xc(l+1))./(xc(l+2)-xc(l+1))).^2-2.*((x(j)-xc(l+1))./(xc(l+2)-xc(l+1))).^3;
end
end
end
end
function y=fS(x,l,xc)
m=length(xc)-1;
y=zeros(size(x));
for j=1:length(x)
if l==0 %first special case
if xc(1)<=x(j) && x(j)< xc(2) %xc(1) is x0, xc(2) is x1
y(j)=-(x(j)-xc(1)).^2./(xc(2)-xc(1))+(x(j)-xc(1)).^3./(xc(2)-xc(1)).^2;
end
elseif l==m %second special case
if xc(m)<x(j) && x(j)<= xc(m+1) %xc(m) is xm-1, xc(m+1) is xm
%ho cambiato l'uguale perchè il valore della funzione era uguale
%a 0
y(j)=((xc(m+1)-x(j)).^2./(xc(m+1)-xc(m)))-((xc(m+1)-x(j)).^3./(xc(m+1)-xc(m)).^2);
end
else
if xc(l)<x(j) && x(j)<= xc(l+1)
y(j)=((xc(l+1)-x(j)).^2./(xc(l+1)-xc(l)))-((xc(l+1)-x(j)).^3./(xc(l+1)-xc(l)).^2);
elseif xc(l+1)<=x(j) && x(j)< xc(l+2)
y(j)=-(x(j)-xc(l+1)).^2./(xc(l+2)-xc(l+1))+((x(j)-xc(l+1)).^3./(xc(l+2)-xc(l+1)).^2);
end
end
end
end
function y=dH(x,l,xc)
m=length(xc)-1;
y=zeros(size(x));
for j=1:length(x)
if l==0 %first special case
if xc(1)<=x(j) && x(j)< xc(2) %xc(1) is x0, xc(2) is x1
y(j)= 6 .* (x(j)-xc(1)) ./ (xc(2)-xc(1)).^2 + ...
6 .* (x(j)-xc(1)).^2 ./ (xc(1)-xc(2)) .^3;
end
elseif l==m %second special case
if xc(m)<x(j) && x(j)<= xc(m+1) %xc(m) is xm-1, xc(m+1) is xm
y(j)= - 6 .* (xc(m+1)- x(j)) ./ (xc(m+1)-xc(m)).^2 + ...
6 .* (xc(m+1)-x(j)).^2 ./ (xc(m+1)-xc(m)) .^3;
end
else
if xc(l)<x(j) && x(j)<= xc(l+1)
y(j)= - 6.*(xc(l+1)-x(j))./(xc(l+1)-xc(l)).^2+ ...
6.*(xc(l+1)-x(j)).^2./(xc(l+1)-xc(l)).^3;
elseif xc(l+1)<=x(j) && x(j)< xc(l+2)
y(j)= 6 .* (x(j)-xc(l+1)) ./ (xc(l+2)-xc(l+1)).^2 + ...
6 .* ( x(j)- xc(l+1)).^2 ./ (xc(l+1)-xc(l+2)) .^3;
end
end
end
end
function y=dS(x,l,xc)
m=length(xc)-1;
y=zeros(size(x));
for j=1:length(x)
if l==0 %first special case
if xc(1)<=x(j) && x(j)< xc(2) %xc(1) is x0, xc(2) is x1
y(j)= 2 .* (x(j)-xc(1)) ./ (xc(1)-xc(2)) + ...
3 .* ( x(j)-xc(1) ).^2 ./ (xc(1)-xc(2)) .^2;
end
elseif l==m %second special case
if xc(m)<x(j) && x(j)<= xc(m+1) %xc(m) is xm-1, xc(m+1) is xm
y(j)= 2 .* (xc(m+1)-x(j)) ./(xc(m)-xc(m+1)) +...
3 .* (xc(m+1)-x(j)).^2 ./ (xc(m+1)-xc(m)).^2;
end
else
if xc(l)<x(j) && x(j)<= xc(l+1)
y(j)= 2 .* (xc(l+1)-x(j)) ./(xc(l)-xc(l+1)) +...
3 .* ( xc(l+1)-x(j)).^2 ./ (xc(l+1)-xc(l)).^2;
elseif xc(l+1)<=x(j) && x(j)< xc(l+2)
y(j)= 2 .* (x(j)-xc(l+1)) ./ (xc(l+1)-xc(l+2)) + ...
3 .* (x(j)-xc(l+1)).^2 ./ (xc(l+1)-xc(l+2)).^2;
end
end
end
end
function y=fu(x,l,xc)
%selection function
y=zeros(size(x));
if mod(l,2)==1 %dispari, verifico il resto della divisione per 2
y=fS(x,(l-1)/2, xc);
else
y=fH(x,l/2, xc);
end
end
function y=du(x,l,xc)
y=zeros(size(x));
if mod(l,2)==1 %dispari
y=dS(x,(l-1)/2, xc);
else
y=dH(x,l/2, xc);
end
end
function [lb,rb]=support(l,xc)
m=length(xc)-1;
if l==1 %case s0
lb=xc(1);
rb=xc(2);
elseif l>=2*m
lb=xc(m);
rb=xc(m+1);
elseif mod(l,2)==1 %caso dispari
lb=xc((l-1)/2); %(l-1)/2 because of the matlab translation
rb=xc((l-1)/2+2);
else
%caso pari
lb=xc(l/2);
rb=xc(l/2+2);
end
end
function y=fA(x,l,j,xc)
%we may write in therms of fu and du, not with fS and fH
y=(1+x).*du(x,l,xc).*du(x,j,xc)+((2+x)./(1+x)).*fu(x,l,xc).*fu(x,j,xc);
end
function y=fB(x,l,xc)
y=fu(x,l,xc).*(6/5-1/5.*x.*(2+x)./(1+x));
end
1 Commento
Aurora
il 5 Nov 2023
Ho un problema con il supporto nel caso in cui si hanno due condizioni essenziali, per caso potresti aiutarmi?
Risposta accettata
Più risposte (0)
Categorie
Scopri di più su Image Arithmetic in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
