Polar Laplacian
5 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Excuse my n00bness but I was hoping I could bet some pointers as to how to compute the Laplacian in polar coordinates. I'm using Trefethen's Chebyshev grid.
Below is how I compute the gradient. This seems to work fine
N = 31;
[D,r] = cheb(N); %function found at %https://people.maths.ox.ac.uk/trefethen/cheb.m
N2 = (N-1)/2;
M = 40;
dt = 2*pi/M;
t = dt*(1:M)';
M2 = M/2;
[tt, rr] = meshgrid(t([M 1:M]), r(1:N2+1));
ff = rr.^3; %test function
[xx,yy] = pol2cart(tt,rr);
%first derivative d/dr+1/r*d/dt
[dudt, dudr] = gradient(ff, t([M 1:M]), r(1:N2+1));
V1 = dudr + dudt./rr;
clf, mesh(xx,yy,V1)
Now computing the Laplacian is proving more problematic. I've tried computing it from V1 using `gradient' again but I get this sort of `lip' near the boundary and it also messes up near the centre for more exotic functions.
[d2udt2, d2udtdr] = gradient((dudt./rr), t([M 1:M]), r(1:N2+1));
[d2udrdt, d2udr2] = gradient(dudr, t([M 1:M]), r(1:N2+1));
V2 = d2udr2 + dudr./rr + d2udt2./(rr.^2);
clf, mesh(xx, yy, V2)
Any help would be much appreciated. Thanks!
0 Kommentare
Antworten (2)
Andrew Newell
am 28 Apr. 2011
The Laplacian is close to correct except at the boundaries (r=0 and r=1). Try plotting, for example,
plot(rr(:,1),V2(:,1),rr(:,1),9*rr(:,1))
(the correct Laplacian being 9*r, of course). The problem is that gradient does a one-sided approximation to the derivative at the boundaries, and the errors are compounded when you take the gradient of the gradient. There doesn't seem to be a polar Laplacian in the File Exchange, so you may need to write your own on the lines of del2, which calculates centered second differences in the interior and then extrapolates to the boundaries.
EDIT: It occurred to me that the gradients might be more accurate if r were evenly spaced. It is better in the interior - but the outer lip folds over!
EDIT 2: If you happen to know that your solution depends on r only, you could use this little cheat to calculate the Laplacian:
d2udr2 = del2(ff, t([M 1:M]), r(1:N2+1))*4;
V2 = d2udr2 + dudr./rr;
EDIT 3: I only have time to sketch the more general approach you could use. Basically, del2 calculates the second derivative with respect to the first variable in the first loop, then the second derivative with respect to the second variable. It permutes the array so it can use the same equations for both. You could assign the results to d2udr2 and d2udt2 instead of adding them both to v. Cross-derivatives, unfortunately, don't fit in this framework. You'll need to add some more code that implements the finite difference formulae for the cross derivatives.
4 Kommentare
Andrew Newell
am 28 Apr. 2011
If you can provide a function to calculate your potential (?) at any point, you can do much better. First, download John D'Errico's differentiation package. Then you can do the following:
N = 31;
r = cos(pi*(0:N)/N)'; % This is the relevant part of cheb(N)
N2 = (N-1)/2;
M = 40;
dt = 2*pi/M;
t = dt*(1:M)';
[tt, rr] = meshgrid(t([M 1:M]), r(1:N2+1));
[xx,yy] = pol2cart(tt,rr);
Provide a function f(y), where y = [theta radius]:
f = @(y) y(2).^3; % This is your example function
Calculate all the derivatives:
grad = zeros(numel(tt),2);
hess = zeros(2,2,numel(tt));
for i=1:numel(tt)
grad(i,:) = gradest(f,[tt(i) rr(i)]);
hess(:,:,i) = hessian(f,[tt(i) rr(i)]);
end
This is the interpretation of the output:
dudt = reshape(grad(:,1),size(rr));
dudr = reshape(grad(:,2),size(rr));
d2udt2 = reshape(hess(1,1,:),size(rr));
d2udtdr = reshape(hess(1,2,:),size(rr));
d2udrdt = reshape(hess(2,1,:),size(rr));
d2udr2 = reshape(hess(2,2,:),size(rr));
Now you can plot the gradient and Laplacian:
V1 = dudr + dudt./rr;
mesh(xx,yy,V1)
V2 = d2udr2 + dudr./rr + d2udt2./(rr.^2);
figure, mesh(xx, yy, V2)
This is really accurate - often good to machine precision.
2 Kommentare
Siehe auch
Kategorien
Mehr zu Eigenvalue Problems finden Sie in Help Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!