ELECTRIC POTENTIAL - How to speed up the code? (COMPLETE CODE INCLUDED)
Mostrar comentarios más antiguos
Hi.
I have a code which calculates an electrical potential around stormy cloud, which is placed above the lighthouse. I compute this using "Finite difference method". A "box" is an 320x320 matrix with known boundary conditions (V=0) and V of a cloud is also known (V1). V of a lighthouse is 0.
Now I have 2 nested "for" loops which go from left to right side of a matrix and from top to bottom. Every round I compare new and old value of matrix. When they differentiate for less than 0.01 I am happy and quit.
That method works OK, except it is very slow. It needs more than 4 hours to complete. Do you have any idea how to speed it up? Is possible not to use nested "for" loops? I read a lot about vectorization, but still don't know how to put this into my code.
I include a complete code, so you are welcome to look at it.
Thanks
clc; clear;
% Cloud Potential
V1 = 6500;
% Cloud Radius
CloudRad = 20;
% Cloud Height
CloudHeight = 40;
% Number of points (vertically * horizontally)
n = 320;
% Height and Radius of a Space (width is 2 * rho)
h = 80;
rho = 40;
% Space Width - Cloud Width
Width = 2*rho - 2*CloudRad;
% Lighthouse measurements
rad1 = 6;
rad2 = 7;
h1 = 22;
h2 = 17;
r = linspace(0,2*rho,n);
z = linspace(h,0,n);
% Mesh
[rr,zz] = meshgrid(r,z);
% Cloud measurements based on mesh
RelCloudHeight = round(((h-CloudHeight)/h) * n);
if RelCloudHeight == 0
RelCloudHeight = 1;
end
RelCloudWidth = round(((2*rho-Width)/(2*rho))*n);
% Matrix of calculated Potential
V = zeros(n);
% Cloud is always on V1
V(RelCloudHeight,(n/2-RelCloudWidth/2)+1:(n/2+RelCloudWidth/2)) = V1;
% Boundary conditions - Potential there is 0
V(1:n,1) = zeros(n,1);
V(1:n,n) = zeros(n,1);
% Lighthouse measurements based on mesh
UpperHight = (round(((h-h1)/h)*n));
MiddleHight = (round((h-h2)/h*n));
ExtremeLeft = round(((rho-rad1)/(2*rho))*n)+1;
ExtremeRight = round(((rho+rad1)/(2*rho))*n);
Left = round(((rho-rad2)/(2*rho))*n);
Right = round(((rho+rad2)/(2*rho))*n);
Finite difference method
difference = 100;
while difference > 0.01 % Desired final accuracy
VV = V;
for i = 2:n-1 % Along the rows of matrix V
for j = 2:n-1 % Along the columns of matrix V
% Lighthouse is always on V=0
V(UpperHight:MiddleHight,ExtremeLeft:ExtremeRight) = 0;
V(MiddleHight:n,Left:Right) = 0;
% Cloud is always on V1
V(RelCloudHeight,(n/2-RelCloudWidth/2)+1:(n/2+RelCloudWidth/2)) = V1;
% Iteration equation
V(i,j) = (1/6)*(2*V(i,j+1)+2*V(i,j-1)+V(i+1,j)+V(i-1,j));
end
end
% Watching the difference between old and new value of V
difference = max(max(abs(V-VV)));
end
% At the end I set the predetermined elements of V to the required value
% for the last time
V(UpperHight:MiddleHight,ExtremeLeft:ExtremeRight) = 0;
V(MiddleHight:n,Left:Right) = 0;
V(RelCloudHeight,(n/2-RelCloudWidth/2)+1:(n/2+RelCloudWidth/2)) = V1;
save LighthouseOUT.mat
PLOTTING
figure;
EkvNum = 150; % Number of equipotential contours
contour(rr,zz,V,EkvNum); axis equal;
% Plotting area
xlim([0 2*rho]); ylim([0 h]);
set(gca,'fontsize',14,'fontname','Times','box','on');
title(['Equipotentials (' num2str(EkvNum) ')']);
xlabel('{\itWidth} / m');
ylabel('{\itHeight} / m');
% Plotting lighthouse:
line([rho-rad2 rho-rad2],[0 h2],'LineWidth',2,'Color','black');
line([rho+rad2 rho+rad2],[0 h2],'LineWidth',2,'Color','black');
line([rho-rad2 rho-rad1],[h2 h2],'LineWidth',2,'Color','black');
line([rho+rad2 rho+rad1],[h2 h2],'LineWidth',2,'Color','black');
line([rho-rad1 rho-rad1],[h2 h1],'LineWidth',2,'Color','black');
line([rho+rad1 rho+rad1],[h2 h1],'LineWidth',2,'Color','black');
line([rho-rad1 rho+rad1],[h1 h1],'LineWidth',2,'Color','black');
% Plotting cloud:
line([rho-CloudRad rho+CloudRad],[CloudHeight CloudHeight],...
'LineWidth',2,'Color','black');
Respuesta aceptada
Más respuestas (0)
Categorías
Más información sobre Descriptive Statistics and Visualization en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!