0
votes

I've implemented an algorithm for my physics project which does exactly what I want. The problem that I'm stuck which is not the Physics content itself hence I think it might be somewhat trivial to explain what my code does. I'm mainly stuck with the way MATLAB's plotting works if I was to loop over the same algorithm to produce similar graphs with a slight change of a value of my parameter. Here's my code below:

clear; clc; close all;

% Parameters:
z_nn = 4;   % Number of nearest-neighbour in lattice (square = 4).
z_nnn = 4;  % Number of next-nearest-neighbours in lattice (square = 4).
Lx = 40;    % Number of sites along x-axis.
Ly = 40;    % Number of sites along y-axis.
sigma = 1;  % Size of a site (defines our units of length).
beta = 1.2; % Inverse temperature beta*epsilon.
mu = -2.53; % Chemical potential mu/epsilon.
mu_2 = -2.67; % Chemical potential mu/epsilon for 2nd line.
J = linspace(1, 11, 11);%J points for the line graph plot

potential = zeros(Ly);
attract = 1.6; %wall attraction constant
k = 1;         %wall depth


rho_0 = 0.4;   % Initial density.
tol = 1e-12;   % Convergence tolerance.
count = 30000; % Upper limit for iterations.
alpha  = 0.01; % Mixing parameter.

conv = 1; cnt = 1;       % Convergence value and counter.
rho = rho_0*ones(Ly); % Initialise rho to the starting guess(i-th rho_old) in Eq(47)
rho_rhs = zeros(Ly);  % Initialise rho_new to zeros.

% Solve equations iteratively:
while conv>=tol && cnt<count
  cnt = cnt + 1; % Increment counter.
  % Loop over all lattice sites:

    for j=1:Ly
        %Defining the Lennard-Jones potential
        if j<k
            potential(j) = 1000000000;
        else
            potential(j) = -attract*(j-k)^(-3); 
        end
        % Handle the periodic boundaries for x and y:
        %left = mod((i-1)-1,Lx) + 1; % i-1, maps 0 to Lx.
        %right = mod((i+1)-1,Lx) + 1; % i+1, maps Lx+1 to 1.
        if j<k+1 %depth of wall
          rho_rhs(j) = 0;
          rho(j) = 0;
        elseif j<(20+k)
          rho_rhs(j) = (1 - rho(j))*exp((beta*((3/2)*rho(j-1) + (3/2)*rho(j+1) + 2*rho(j) + mu) - potential(j)));
        else
          rho_rhs(j) = rho_rhs(j-1);
        end

    end

    conv = sum(sum((rho - rho_rhs).^2)); % Convergence value is the sum of the differences between new and current solution.
    rho = alpha*rho_rhs + (1 - alpha)*rho; % Mix the new and current solutions for next iteration.
end



% disp(['conv = ' num2str(conv_2) ' cnt = ' num2str(cnt)]); % Display final answer.
% figure(2);
% pcolor(rho_2);

figure(1);
plot(J, rho(1:11));
hold on;
% plot(J, rho_2(1,1:11));
hold off;

disp(['conv = ' num2str(conv) ' cnt = ' num2str(cnt)]); % Display final answer.
figure(3);
pcolor(rho);

Running this code should give you a graph like thisenter image description here

Now I want to produce a similar graph but with one of the variable's value changed and plotted on the same graph. My approach that I've tried is below:

clear; clc; close all;

% Parameters:
z_nn = 4;   % Number of nearest-neighbour in lattice (square = 4).
z_nnn = 4;  % Number of next-nearest-neighbours in lattice (square = 4).
Lx = 40;    % Number of sites along x-axis.
Ly = 40;    % Number of sites along y-axis.
sigma = 1;  % Size of a site (defines our units of length).
beta = 1.2; % Inverse temperature beta*epsilon.
mu = [-2.53,-2.67];     % Chemical potential mu/epsilon.
mu_2 = -2.67;           % Chemical potential mu/epsilon for 2nd line.
J = linspace(1, 10, 10);%J points for the line graph plot

potential = zeros(Ly, length(mu));
gamma = zeros(Ly, length(mu));
attract = 1.6; %wall attraction constant
k = 1;         %wall depth


rho_0 = 0.4;   % Initial density.
tol = 1e-12;   % Convergence tolerance.
count = 30000; % Upper limit for iterations.
alpha = 0.01;  % Mixing parameter.

conv = 1; cnt = 1;    % Convergence value and counter.
rho = rho_0*[Ly,length(mu)]; % Initialise rho to the starting guess(i-th rho_old) in Eq(47)
rho_rhs = zeros(Ly,length(mu));  % Initialise rho_new to zeros. 


figure(3);
hold on;
% Solve equations iteratively:
while conv>=tol && cnt<count
    cnt = cnt + 1; % Increment counter.
    % Loop over all lattice sites:


        for j=1:Ly

            for i=1:length(mu)
                y = 1:Ly;
                MU = mu(i).*ones(Ly)

                %Defining the Lennard-Jones potential
                if j<k
                    potential(j) = 1000000000;
                else
                    potential(j) = -attract*(j-k).^(-3); 
                end
                % Handle the periodic boundaries for x and y:
                %left = mod((i-1)-1,Lx) + 1; % i-1, maps 0 to Lx.
                %right = mod((i+1)-1,Lx) + 1; % i+1, maps Lx+1 to 1.
                if j<k+1 %depth of wall
                  rho_rhs(j) = 0;
                  rho(j) = 0;
                elseif j<(20+k)
                  rho_rhs(j) = (1 - rho(j))*exp((beta*((3/2)*rho(j-1) + (3/2)*rho(j+1) + 2*rho(j) + MU - potential(j)));
                    else
                      rho_rhs(j) = rho_rhs(j-1);
                end
            end
        end

        conv = sum(sum((rho - rho_rhs).^2));   % Convergence value is the sum of the differences between new and current solution.
        rho = alpha*rho_rhs + (1 - alpha)*rho; % Mix the new and current solutions for next iteration.

        disp(['conv = ' num2str(conv) ' cnt = ' num2str(cnt)]); % Display final answer.
        figure(1);
        pcolor(rho);


        plot(J, rho(1:10));

end
hold off;

The only variable that I'm changing here is mu. I would like to loop my first code so that I can enter an arbitrary amount of different values of mu and plot them on the same graph. Naturally I had to change all of the lists dimension from (1 to size of Ly) to (#of mu(s) to size of Ly), such that when the first code is being looped, the i-th mu value in that loop is being turned into lists with dimension as long as Ly. So I thought I would do the plotting within the loop and use "hold on" encapsulating the whole loop so that every plot that was generated in each loop won't be erased. But I've been spending hours on trying to figure out the semantics of MATLAB but ultimately I can't figure out what to do. So hopefully I can get some help on this!

1

1 Answers

0
votes

hold on only applies to the active figure, it is not a generic property shared among all figures. What is does is changing the value of the current figure NextPlot property, which governs the behavior when adding plots to a figure.

hold on is equivalent to set(gcf,'NextPlot','add');

hold off is equivalent to set(gcf,'NextPlot','replace');

In your code you have:

figure(3);  % Makes figure 3 the active figure
hold on;    % Sets figure 3 'NextPlot' property to 'add'
% Do some things %
while conv>=tol && cnt<count
   % Do many things %
   figure(1);  % Makes figure 1 the active figure; 'hold on' was not applied to that figure
   plot(J, rho(1:10));  % plots rho while erasing the previous plot
end

You should try to add another hold on statement after figure(1)

figure(1);  
hold on
plot(J, rho(1:10));