0% found this document useful (0 votes)
61 views

H2+ Matlab

PHY.F20 Molecular and Solid State Physics: Molecular orbitals of the molecular ion H2+ The files in this project can be used to calculate the matrices occuring in the Roothaan- equations for some of the simplest molecules. The definition of the molecule is done via the variables Z and xAtom, yAtom and zAtom. These are simple Nx1-vectors containing the atomic numbers and the position of the nuclei.

Uploaded by

Andrea Schuhmann
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views

H2+ Matlab

PHY.F20 Molecular and Solid State Physics: Molecular orbitals of the molecular ion H2+ The files in this project can be used to calculate the matrices occuring in the Roothaan- equations for some of the simplest molecules. The definition of the molecule is done via the variables Z and xAtom, yAtom and zAtom. These are simple Nx1-vectors containing the atomic numbers and the position of the nuclei.

Uploaded by

Andrea Schuhmann
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

H2+-MATLAB PROGRAMME

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%
PHY.F20 Molecular and Solid State Physics: Molecular orbitals of the
molecular ion H2+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%

The files in this project can be used to calculate the matrices


occuring in the Roothaan- equations for some of the simplest
molecules.

The definition of the molecule is done via the variables Z and


xAtom, yAtom and zAtom.
These are simple Nx1-vectors containing the atomic numbers and the
position of the nuclei.

e.g: two protons 1m apart.


Z = [1; 1];
xAtom = [-1/2; 1/2];
yAtom = [0; 0];
zAtom = [0; 0];

Then one can define the atomic orbitals to be used for the
approximation of the molecular orbitals. This is done inside a cell
called orb. It contains one cell for each nuclei with strings giving
the name of the orbitals we want to use for this nuclei.

e.g: use the first two s orbitals of both nuclei.


orb = {{'1s', '2s'}; {'1s', '2s'}};

Then one also has to set the limits of the finite integration area.
This is done via a single variable called universallimit. The
integration will be done inside a shape at least as big as a sphere
with that radius.

Integration will be much faster for linear molecules where all the
nuclei are on the x-axis and only s and px orbitals are used. This
will be detected automatically and the code switches from the full
3d integration to an equivalent 2d integration over a cylinder with
radius universallimit.

Most of the files can be called with the parameters explained above:
orb, Z, xAtom, yAtom, zAtom and universallimit

constants.m:
This file can be run to load some useful constants.
Dividing variables in SI units by ec or a0 will give the energy and
distance in eV and bohr respectively.
e.g:
-2.1799e-18 J / ec = -13.6057 eV
1.27e-10 m / a0 = 2.4 bohr

atorbit.m:
Defines the first few atomic orbitals. It is used by the other
files.
calcHamiltonian.m:
function [H,S] =
calcHamiltonian(orb,Z,xAtom,yAtom,zAtom,universallimit)
As one can see in the definition, this function calculates the two
matrices H and S.
You can see if the area of integration is large enough be checking
the diagonal entries of S. They should be very close to 1. If they
are considerably smaller your results mighthave errors and you
should increase the integration area.

The smallest eigenvalue of S\H is the ground state energy in this


approximation.
The corresponding eigenvector gives the coefficients V that define
the ground state orbital.

There is an old version of this function as well, but it is usually


slower and not as stable with higher orbitals.

calcDensity.m:
function ZZ = calcDensity(orb, Z, xAtom, yAtom, zAtom, V, XX, YY)
This function calculates the electron density defined by a given
LCAO coefficient vector V for a xy-grid XX, YY. Alter this script
if you want the wavefunctions of a calculated orbital.

plot_molecule.m:
function plot_molecule(orb, Z, xAtom, yAtom, zAtom, V_min,
plotlimit)
This function plots the xy-plane density of the given orbital
defined by the LCAO coefficients V. The area that is plotted is a
square defined by plotlimit.

plot_S.m, plot_H.m:
function plot_X(orb, Z, xAtom, yAtom, zAtom, plotlimit)
These functions are helpful to visualize the integrals done when
calculating thematrices S and H.

h2_plus.m:
An example how to use the files to calculate the dissociation energy
of H2+ is given with this file. After calculation finish it will
save the results in a results.mat file. This file can be used by
plot_animation.m to visualize all the densities for all given
distances of the protons.

ATORBIT

function [ result ] =
atorbit(xlocal,ylocal,zlocal,Zlocal,laplace,type)
%ATORBIT Atomic orbital centered at specified coordinates
%
% xlocal ... x-coordinate of the center of the atom (in m)
% ylocal ... y-coordinate (in m)
% zlocal ... z-coordinate (in m)
% Zlocal ... atomic number of the atom
% laplace ... boolean. true - laplace operator is appled to atomic
orbital
% false - "pure" atomic orbital is returned
% type ... string specifying the orbital (1s, 2s, 2px, 2py, 2pz)

result = [];

%[x_mesh,xAtom_mesh] = meshgrid(x,xAtom);
%xlocal = x - xAtom;
%[y_mesh,yAtom_mesh] = meshgrid(y,yAtom);
%ylocal = y - yAtom;
%[z_mesh,zAtom_mesh] = meshgrid(z,zAtom);
%zlocal = z - zAtom;

%Zlocal = repmat(Z,length(x),1);

a0 = 5.2917721E-11; % Bohr radius in meters

r = sqrt(xlocal.^2 + ylocal.^2 + zlocal.^2);


if ~laplace
switch lower(type)
case '1s'
result = sqrt(Zlocal.^3./(pi*a0.^3)).*exp(
Zlocal.*r/a0);
case '2s'
result= 1/4*sqrt(Zlocal.^3./(2*pi*a0.^3)).*(2-
Zlocal.*r/a0).*exp(-Zlocal.*r/(2*a0));
case '2px'
result=
1/4*sqrt(Zlocal.^5./(2*pi*a0.^5)).*xlocal.*exp(-Zlocal.*r/(2*a0));
case '2py'
result=
1/4*sqrt(Zlocal.^5./(2*pi*a0.^5)).*ylocal.*exp(-Zlocal.*r/(2*a0));
case '2pz'
result=
1/4*sqrt(Zlocal.^5./(2*pi*a0.^5)).*zlocal.*exp(-Zlocal.*r/(2*a0));
case '3s'
result= 1/27*sqrt(3*Zlocal.^3./(pi*a0.^3)).*(3-
2*Zlocal.*r/a0+2*Zlocal.^2*r.^2/(9*a0^2)).*exp(-Zlocal.*r/(3*a0));
case '3px'
result=
1/27*sqrt(Zlocal.^5./(2*pi*a0.^5)).*xlocal.*(4-
2*Zlocal.*r/(3*a0)).*exp(-Zlocal.*r/(3*a0));
case '3py'
result=
1/27*sqrt(Zlocal.^5./(2*pi*a0.^5)).*ylocal.*(4-
2*Zlocal.*r/(3*a0)).*exp(-Zlocal.*r/(3*a0));
case '3pz'
result=
1/27*sqrt(Zlocal.^5./(2*pi*a0.^5)).*zlocal.*(4-
2*Zlocal.*r/(3*a0)).*exp(-Zlocal.*r/(3*a0));
case '4s'
result= 1/32*sqrt(Zlocal.^3./(pi*a0.^3)).*(4-
3*Zlocal.*r/a0+Zlocal.^2*r.^2/(2*a0^2)-
Zlocal.^3*r.^3/(48*a0^3)).*exp(-Zlocal.*r/(4*a0));
end
else
switch(lower(type))
case '1s'
result = sqrt(Zlocal.^5./(pi*a0.^5)).*(Zlocal/a0 -
2./r).*exp(-Zlocal.*r/a0);
case '2s'
result = 1/4*sqrt(Zlocal.^5./(2*pi*a0.^5)).*(-
Zlocal.^2.*r/(4*a0^2) + 5*Zlocal/(2*a0) - 4./r).*exp(-
Zlocal.*r/(2*a0));
case '2px'
result =
1/4*sqrt(Zlocal.^7./(2*pi*a0.^7)).*(Zlocal.*r/(4*a0)-
2).*xlocal./r.*exp(-Zlocal.*r/(2*a0));
case '2py'
result =
1/4*sqrt(Zlocal.^7./(2*pi*a0.^7)).*(Zlocal.*r/(4*a0)-
2).*ylocal./r.*exp(-Zlocal.*r/(2*a0));
case '2pz'
result =
1/4*sqrt(Zlocal.^7./(2*pi*a0.^7)).*(Zlocal.*r/(4*a0)-
2).*zlocal./r.*exp(-Zlocal.*r/(2*a0));
end
end
end

calDensity.m

function ZZ = calcDensity(orb, Z, xAtom, yAtom, zAtom, V, XX, YY)

ZZ = zeros(size(XX));

k = 1;
for atom = 1:numel(Z)
for orbital = 1:numel(orb{atom})
ZZ = ZZ + V(k)*atorbit(XX-xAtom(atom), YY-yAtom(atom),
zeros(size(XX))-zAtom(atom), Z(atom), false, orb{atom}{orbital});
k = k + 1;
end
end

ZZ = ZZ.^2;

calcHamiltonian.m

function [H,S] = calcHamiltonian(


orb,Z,xAtom,yAtom,zAtom,universallimit,ATol,RTol)
%CALCHAMILTONIAN calculates Hamiltonian and overlap matrix
% Uses molecular orbitals and doesn't take nuclei-nuclei interaction
into
% account.
%
% Z ... a [m x 1] matrix containing the atomic numbers of all atoms
in the
% molecule. Atoms with n orbitals have to mentioned n times
% xAtom, yAtom and zAtom are [m x 1] matrizes containing relative
positions
% of all molecules (in Meter).
% orb ... {m x 1} cell containing {1 x n} cells containing strings
% describing the n orbitals which
% should be used for calculation (1s, 2s, 2px, 2py, 2pz ...).
%
% H is a matrix containing energy expectation values, S is the
overlap matrix
%

constants

if nargin<6
universallimit = a0*50; %a0*50
end

%---------------------Set tolerance of integrals--------------------


-------
if nargin<7
ATol = 1E-6;
end

if nargin<8
RTol = 1E-6;
end

x_lim_l = -universallimit;
x_lim_u = universallimit;

y_lim_l = -universallimit;
y_lim_u = universallimit;

z_lim_l = -universallimit;
z_lim_u = universallimit;

r_lim = universallimit;

linear_molecule = all(yAtom == 0) & all(zAtom == 0);

num_orbs_per_atom = cellfun('size',orb,2);
nopa_cumsum = cumsum([0; num_orbs_per_atom]);
N_atom = length(Z);
N = sum(num_orbs_per_atom);
orblist = {};
for k = 1:length(orb)
orblist = [orblist orb{k}];
end

H = NaN(N);
S = H;

for k = 1:N
for l = k:N
atom_k = find(k > nopa_cumsum,1,'last');
atom_l = find(l > nopa_cumsum,1,'last');

%if(k==l) S(k,l) = 1; % because the atomic orbitals are an


orthonormal basis
%else
if linear_molecule && ~(any(contains([orblist{k},
orblist{l}],'y')) || any(contains([orblist{k}, orblist{l}],'z'))) %
just do an equivalent 2d integral
S(k,l) = integral2(@(x,y) 2*pi*y.*atorbit(x-
xAtom(atom_k),y,0,Z(atom_k),false,orblist{k}).* ...
atorbit(x-
xAtom(atom_l),y,0,Z(atom_l),false,orblist{l}), ...

x_lim_l,x_lim_u,0,r_lim,'AbsTol',ATol,'RelTol',RTol);
else % do the full 3d integral
S(k,l) = integral3(@(x,y,z) atorbit(x-xAtom(atom_k),y-
yAtom(atom_k), z-zAtom(atom_k),Z(atom_k),false,orblist{k}).* ...
atorbit(x-xAtom(atom_l),y-yAtom(atom_l),z-
zAtom(atom_l),Z(atom_l),false,orblist{l}), ...

x_lim_l,x_lim_u,y_lim_l,y_lim_u,z_lim_l,z_lim_u,'AbsTol',ATol,'RelTo
l',RTol);
end
%end
%fprintf('Done S(%i,%i): %i-%s, %i-%s\n', k, l, atom_k,
orblist{k}, atom_l, orblist{l});
end
end

S = triu(S) + triu(S,1)';

for k = 1:N
for l = 1:N
atom_k = find(k > nopa_cumsum,1,'last');
atom_l = find(l > nopa_cumsum,1,'last');

orb1 = orblist{k};
orb2 = orblist{l};

pos1 = [xAtom(atom_k) yAtom(atom_k) zAtom(atom_k)];


pos2 = [xAtom(atom_l) yAtom(atom_l) zAtom(atom_l)];

%n1 = str2double(orb1(1));
n2 = str2double(orb2(1));

%eigenE1 = -me*ec^4/(2*(4*pi*eps0)^2*hbar^2)/n1^2*Z1^2;
eigenE2 = -
me*ec^4/(2*(4*pi*eps0)^2*hbar^2)/n2^2*Z(atom_l)^2;

H(k,l) = eigenE2*S(k,l);

% Exclude atom corresponding to right eigenfunction (atom_l)


for j = [1:atom_l-1 atom_l+1:N_atom]
if linear_molecule && ~(any(contains([orb1, orb2],'y'))
|| any(contains([orb1, orb2],'z'))) % just do an equivalent 2d
integral
H(k,l) = H(k,l) - k2*Z(j)*...
integral2(@(x,y) 2*pi*y.*atorbit(x-
pos1(1),y,0,Z(atom_k),false,orb1)...
./sqrt((x-xAtom(j)).^2+y.^2).* ...
atorbit(x-pos2(1),y,0,Z(atom_l),false,orb2),...
x_lim_l,x_lim_u,0,r_lim,'AbsTol',ATol,'RelTol',RTol);
else % do the full 3d integral
H(k,l) = H(k,l) - k2*Z(j)*...
integral3(@(x,r,phi) r.*atorbit(x-
pos1(1),yAtom(j)+r.*cos(phi)-pos1(2),zAtom(j)+r.*sin(phi)-
pos1(3),Z(atom_k),false,orb1)...
./sqrt((x-xAtom(j)).^2+r.^2) ...
.*atorbit(x-pos2(1),yAtom(j)+r.*cos(phi)-
pos2(2),zAtom(j)+r.*sin(phi)-pos2(3),Z(atom_l),false,orb2),...

x_lim_l,x_lim_u,0,r_lim+sqrt(yAtom(j)^2+zAtom(j)^2),0,2*pi,'AbsTol',
ATol,'RelTol',RTol);
end
%fprintf('Done H(%i,%i) - Atom %i\n',k,l,j);
end
end
end

end

calcHamiltonian.m

function [H,S] = calcHamiltonian_old(


orb,Z,xAtom,yAtom,zAtom,universallimit,ATol,RTol)
%CALCHAMILTONIAN calculates Hamiltonian and overlap matrix
% Uses molecular orbitals and doesn't take nuclei-nuclei interaction
into
% account.
%
% Z ... a [m x 1] matrix containing the atomic numbers of all atoms
in the
% molecule. Atoms with n orbitals have to mentioned n times
% xAtom, yAtom and zAtom are [m x 1] matrizes containing relative
positions
% of all molecules (in Meter).
% orb ... {m x 1} cell containing {1 x n} cells containing strings
% describing the n orbitals which
% should be used for calculation (1s, 2s, 2px, 2py, 2pz ...).
%
% H is a matrix containing energy expectation values, S is the
overlap matrix
%

constants

if nargin<6
universallimit = 5.2917721E-11*50; %a0*50
end

%---------------------Set tolerance of integrals--------------------


-------
if nargin<7
ATol = 1E-6;
end

if nargin<8
RTol = 1E-6;
end

x_lim_l = -universallimit;
x_lim_u = universallimit;

y_lim_l = -universallimit;
y_lim_u = universallimit;

z_lim_l = -universallimit;
z_lim_u = universallimit;

num_orbs_per_atom = cellfun('size',orb,2);
nopa_cumsum = cumsum([0; num_orbs_per_atom]);
N_atom = length(Z);
N = sum(num_orbs_per_atom);
orblist = {};
for k = 1:length(orb)
orblist = [orblist orb{k}];
end

H = NaN(N);
S = H;

for k = 1:N
for l = k:N
atom_k = find(k > nopa_cumsum,1,'last');
atom_l = find(l > nopa_cumsum,1,'last');

%if(k==l) S(k,l) = 1; % because the atomic orbitals are an


orthonormal basis
%else
S(k,l) = integral3(@(x,y,z) atorbit(x-xAtom(atom_k),y-
yAtom(atom_k), z-zAtom(atom_k),Z(atom_k),false,orblist{k}).* ...
atorbit(x-xAtom(atom_l),y-yAtom(atom_l),z-
zAtom(atom_l),Z(atom_l),false,orblist{l}), ...

x_lim_l,x_lim_u,y_lim_l,y_lim_u,z_lim_l,z_lim_u,'AbsTol',ATol,'RelTo
l',RTol);

%end
fprintf('Done S(%i,%i): %i-%s, %i-%s\n', k, l, atom_k,
orblist{k}, atom_l, orblist{l});
end
end

S = triu(S) + triu(S,1)';

for k = 1:N
for l = 1:N
atom_k = find(k > nopa_cumsum,1,'last');
atom_l = find(l > nopa_cumsum,1,'last');

orb1 = orblist{k};
orb2 = orblist{l};

pos1 = [xAtom(atom_k) yAtom(atom_k) zAtom(atom_k)];


pos2 = [xAtom(atom_l) yAtom(atom_l) zAtom(atom_l)];

%n1 = str2double(orb1(1));
n2 = str2double(orb2(1));

%eigenE1 = -me*ec^4/(2*(4*pi*eps0)^2*hbar^2)/n1^2*Z1^2;
eigenE2 = -
me*ec^4/(2*(4*pi*eps0)^2*hbar^2)/n2^2*Z(atom_l)^2;

H(k,l) = eigenE2*S(k,l);

% Exclude atom corresponding to right eigenfunction (atom_l)


for j = [1:atom_l-1 atom_l+1:N_atom]
H(k,l) = H(k,l) - k2*Z(j)*...
integral3(@(x,y,z) atorbit(x-pos1(1),y-
pos1(2),z-pos1(3),Z(atom_k),false,orb1)...
./sqrt((x-xAtom(j)).^2+(y-yAtom(j)).^2+(z-
zAtom(j)).^2) ...
.*atorbit(x-pos2(1),y-pos2(2),z-
pos2(3),Z(atom_l),false,orb2),...

x_lim_l,x_lim_u,y_lim_l,y_lim_u,z_lim_l,z_lim_u,'AbsTol',ATol,'RelTo
l',RTol);
fprintf('Done H(%i,%i) - Atom %i\n',k,l,j);
end
end
end

end

constants.m

a0 = 5.2917721E-11;
hbar = 1.05457266E-34;
me = 9.1093897E-31;
eps0 = 8.854187817E-12;
ec = 1.60217733E-19;
Eh = hbar^2/(me*a0^2);
k1 = 1/2*hbar^2/me;
k2 = ec^2/(4*pi*eps0);

h2+.m

% this defines the charge of the nuclei in the molecule we are


analysing
Z = [1; 1];
% this defines the atomic orbitals we are using for LCAO
orb = {{'1s', '2s', '2px', '2py'}; {'1s', '2s', '2px', '2py'}};

constants

% integration area: [-univlim, univlim]x[-univlim, univlim]


universallimit = 50*a0;
plotlimit = 8*a0;
ATol = 1E-6;
RTol = 1E-6;
% we want to calculate the energy for different distances of the
protons
d_list = linspace(0, 2*pi, 4);%a0*[0.5:0.25:2 2.1:0.1:3 3.25 3.5
4:1:8];

% functions giving the position of the atoms dependent on the


parameter
xAtom_d = @(d) 2.4/2*a0*[-cos(d), cos(d)];%[-d/2, d/2];
yAtom_d = @(d) 2.4/2*a0*[-sin(d), sin(d)];%[0, 0];
zAtom_d = @(d) [0, 0];

% these arrays will hold the energies and LCAO coefficients for all
d
E_list = [];
V_list = [];

for d = d_list
fprintf('\ndistance: %f\n', d/a0)
xAtom = xAtom_d(d);
yAtom = yAtom_d(d);
zAtom = zAtom_d(d);

[H, S] = calcHamiltonian(orb, Z, xAtom, yAtom, zAtom,


universallimit,ATol,RTol);
fprintf('max error on diagonal of S: %f\n', max(abs(diag(S) -
1)))

% find the lowest eigenvalue and it's eigenvector


[V,D] = eig(S\H);
[~,ind] = sort(real(diag(D)));
Ds = D(ind,ind);
Vs = V(:,ind);

E_list(:, end+1) = diag(Ds); % save all energies


V_list(:, end+1) = Vs(:, 1); % save only the coefficients of the
lowest energy
end

% this term is the additional proton-proton energy


E_protons = k2./abs(d_list);
E_total = E_list + E_protons;

% find the distance with the lowest energy and set some variables
with it
[E_min, min_index] = min(real(E_total(1, :)));
d_min = d_list(min_index);
V_min = V_list(:, min_index);
xAtom_min = xAtom_d(d_min);
yAtom_min = yAtom_d(d_min);
zAtom_min = zAtom_d(d_min);

% energy of the unbounded parts


E_inf = -0.5*Eh;

% figure 1 plots the energies over distance with the bonding energy
figure(1)
plot(d_list/a0, E_total/ec)
hold on
plot([0, max(d_list)]/a0, E_inf/ec*[1, 1], '--k')

plot([d_min/a0, d_min/a0], [E_min/ec, E_inf/ec], '-k')


text(d_min/a0, (E_min + E_inf)/2/ec, [' ', num2str((E_inf -
E_min)/ec, 3), ' eV'])

hold off
title('H_2^+ bonding energy')
ylim([-17, 0])
xlabel('d / a_0 distance between protons')
ylabel('Energy / eV')
%legend('plus, bonding', 'minus, antibonding')

% figure 2 plots the energy values without the proton-proton term


figure(2)
plot(d_list/a0, E_list/ec)
hold on
plot(d_list/a0, E_protons/ec, '--k')
hold off
title('H_2^+ orbital energy')
xlabel('d / a_0')
ylabel('Energy / eV')
%legend('plus', 'minus')

% plot the density in the xy plane of the solution


plot_molecule(orb, Z, xAtom_min, yAtom_min, zAtom_min, V_min,
plotlimit)

fprintf('\nLCAO coefficients:\n')
disp(V_min)
fprintf('dissociation energy: %f eV\n', (E_inf - E_min)/ec)

save('results.mat', 'orb', 'Z', 'universallimit', 'd_list',


'E_list', 'E_protons', 'V_list', 'd_min', 'E_min', 'E_inf', 'V_min')

plot_animation.m

load('results.mat')
constants

plotlimit = universallimit;

figure
x = linspace(-universallimit, universallimit, 1000);
y = linspace(-universallimit, universallimit, 1000);
[XX, YY] = meshgrid(x, y);
ZZ = zeros(size(XX));

frame = 1;
for d = d_list
xAtom = [-d/2; d/2];
yAtom = [0; 0];
zAtom = [0; 0];
ZZ = calcDensity(orb, Z, xAtom, yAtom, zAtom, V_list(:, frame),
XX, YY);
s = surf(XX, YY, ZZ);
s.EdgeColor = 'none';
xlim([-plotlimit, plotlimit])
ylim([-plotlimit, plotlimit])
axis off
%zlim([0, 3E30])
view(25,60)

saveas(gcf, ['fig_', num2str(frame, '%02d'), '.png'])


frame = frame + 1;
end

plot_h.m

function plot_H(orb, Z, xAtom, yAtom, zAtom, plotlimit)


constants

num_orbs_per_atom = cellfun('size',orb,2);
nopa_cumsum = cumsum([0; num_orbs_per_atom]);
N_atom = length(Z);
N = sum(num_orbs_per_atom);
orblist = {};
for k = 1:length(orb)
orblist = [orblist orb{k}];
end

x = linspace(-plotlimit, plotlimit, 100);


y = linspace(-plotlimit, plotlimit, 100);
[XX, YY] = meshgrid(x, y);
ZZ = zeros(size(XX));

figure

for k = 1:N
for l = 1:N
atom_k = find(k > nopa_cumsum,1,'last');
atom_l = find(l > nopa_cumsum,1,'last');

orb1 = orblist{k};
orb2 = orblist{l};

pos1 = [xAtom(atom_k) yAtom(atom_k) zAtom(atom_k)];


pos2 = [xAtom(atom_l) yAtom(atom_l) zAtom(atom_l)];

subplot(N, N, N*(k-1)+l)

for j = [1:atom_l-1 atom_l+1:N_atom]


ZZ = atorbit(XX-pos1(1),YY-
pos1(2),0,Z(atom_k),false,orb1)...
./sqrt((XX-xAtom(j)).^2+(YY-yAtom(j)).^2).* ...
atorbit(XX-pos2(1),YY-
pos2(2),0,Z(atom_l),false,orb2);
end

s = surf(XX, YY, ZZ);


s.EdgeColor = 'none';
xlim([-plotlimit, plotlimit])
ylim([-plotlimit, plotlimit])
axis off tight
view(25,75)

title([num2str(atom_k), '-', orblist{k}, '*',


num2str(atom_l), '-', orblist{l}])
end
end

plot_molecule.m

function plot_molecule(orb, Z, xAtom, yAtom, zAtom, V_min,


plotlimit)
constants

figure
x = linspace(-plotlimit, plotlimit, 1000);
y = linspace(-plotlimit, plotlimit, 1000);
[XX, YY] = meshgrid(x, y);
ZZ = zeros(size(XX));

k = 1;
for atom = 1:numel(Z)
for orbital = 1:numel(orb{atom})
ZZ = ZZ + V_min(k)*atorbit(XX-xAtom(atom), YY-yAtom(atom),
zeros(size(XX))-zAtom(atom), Z(atom), false, orb{atom}{orbital});
k = k + 1;
end
end

s = surf(XX, YY, ZZ.^2);


s.EdgeColor = 'none';
xlim([-plotlimit, plotlimit])
ylim([-plotlimit, plotlimit])
axis off
view(25,60)

plot_S.m

function plot_S(orb, Z, xAtom, yAtom, zAtom, plotlimit)


constants

num_orbs_per_atom = cellfun('size',orb,2);
nopa_cumsum = cumsum([0; num_orbs_per_atom]);
N_atom = length(Z);
N = sum(num_orbs_per_atom);
orblist = {};
for k = 1:length(orb)
orblist = [orblist orb{k}];
end

x = linspace(-plotlimit, plotlimit, 100);


y = linspace(-plotlimit, plotlimit, 100);
[XX, YY] = meshgrid(x, y);
ZZ = zeros(size(XX));
figure

for k = 1:N
for l = k:N
atom_k = find(k > nopa_cumsum,1,'last');
atom_l = find(l > nopa_cumsum,1,'last');

subplot(N, N, N*(k-1)+l)

ZZ = atorbit(XX-xAtom(atom_k),YY-yAtom(atom_k),-
zAtom(atom_k),Z(atom_k),false,orblist{k}).* ...
atorbit(XX-xAtom(atom_l),YY-yAtom(atom_l),-
zAtom(atom_l),Z(atom_l),false,orblist{l});

s = surf(XX, YY, ZZ);


s.EdgeColor = 'none';
xlim([-plotlimit, plotlimit])
ylim([-plotlimit, plotlimit])
axis off tight
view(25,75)

title([num2str(atom_k), '-', orblist{k}, '*',


num2str(atom_l), '-', orblist{l}])
end
end

You might also like