Cartoon of the generation of a secondary-electron cascade 

Matlab code 

% Cartoon of the generation of thermalized secondary electrons

% The cartoon is semi-physical, insofar it conserves energy. However, it

% ignores binding energies, which is semi-valid for the higher electron

% energies but certainly not so for the lower ones. It assumes that each

% inelastic collision divides the energy of the incoming electron equally

% between it and the electron it releases. Like I say, this is just a

% cartoon...

 

clear

close all

vid = VideoWriter('SecondaryElectrons.mp4','MPEG-4');

vid.Quality = 100;

vid.FrameRate = 60;

open(vid);

figure('units','pixels','position',[0 0 1920 1080],'ToolBar','none');

set(0,'defaultfigurecolor',[1 1 1]);

set(gca,'linewidth',7);

 

% Plotting area

pos1 = [0 0 1 1]; % Cartoon electron orbiting nucleus

 

Ang = char(197); % ASCII symbol for good ol' Angstrom

lp = [7 5 8]; % Angle of lighting

myBlue = [0.4 0.44 0.73];

myGold = [0.7969 0.6406 0.2383];

LL = 100; % Half size of 3D volume in Angstroms [i.e. V = (2*LL)^3]

% rCube = Body diagonal of semitransparent cube representing condensed matter

rCube = 0.9*sqrt(3)*LL; % Half size of cube in Angstroms [i.e. V = (1.8*LL)^3]

er = LL/125; % Radius of electron

 

% Determine time scale

EkinInit = 1000; % Initial KE of electrons in eV. Typically, a 1000-eV

% electron will produce ca. 500 quasi-thermalized electrons after 3500

% frames

tt = 0; % Start at t = 0

vReal = (2*1.6022e-19*EkinInit/9.1094e-31)^0.5; % Initial electron velocity in m/s

IMFPinit = 1e-10*(300/EkinInit^1.52 + 0.54*EkinInit^0.5); % Initial IMFP in m

tReal = IMFPinit/vReal; % Time to travel IMFP for initial electron with initial energy

stepsInit = round(IMFPinit*1e10); % Move 1 AA per frame for initial electron. Defines frame rate

Deltt = 10^15*(tReal/stepsInit); % Calculated time between steps for initial electron

 

[a,b,c] = sphere(17); % Electron template sphere

[aa,bb,cc] = sphere(50); % Photon template sphere

% noElsMax = Max number of electrons - should significantly exceed the

% number actually produced within framesMax events

noElsMax = 5000;

framesMax = 3500; % Max number of frames of secondary electron production

 

alp = ones(1,noElsMax+1); % Initial opacity of all electrons = 1

 

subplot('position',pos1);

% Incoming photon

newplot

hold off

[V,F] = platonic_solid(2,rCube); % Cube

patch('Faces',F,'Vertices',V,'FaceColor',myBlue,'FaceAlpha',0.16, ...

    'EdgeColor','none','FaceLighting','flat','DiffuseStrength',1,'AmbientStrength',1,'SpecularStrength',0);

hold on

for ii = LL:-LL/30:0

    pr = (ii+40)/40; % Radius of incoming photon

    pAlp = 0.25+0.75*(LL-ii)/LL; % Opacity of photon

    surf(pr*aa+ii,pr*bb+ii,pr*cc+ii,...

        'FaceColor',myGold,'LineStyle','none','FaceAlpha',pAlp,...

        'FaceLighting','flat','DiffuseStrength',1);

    hold on

    [V,F] = platonic_solid(2,rCube); % Cube

    patch('Faces',F,'Vertices',V,'FaceColor',myBlue,'FaceAlpha',0.16, ...

        'EdgeColor','none','FaceLighting','flat','DiffuseStrength',1,'AmbientStrength',1,'SpecularStrength',0);

    

    hold off

    axis equal

    axis off

    axis tight

    light('Position',lp,'Style','infinite');

    set(gca, 'Projection','perspective');

    set(gca,'View',[70,-1]);

    xlim([-LL LL]);

    ylim([-LL LL]);

    zlim([-LL LL]);

    frame = getframe(gcf);

    writeVideo(vid,frame);

    

end

 

% First photoelectron produced at origin

surf(er*a,er*b,er*c,...

    'FaceColor',myBlue,'LineStyle','none',...

    'FaceLighting','flat','DiffuseStrength',1);

hold on

[V,F] = platonic_solid(2,rCube); % Cube

ps = patch('Faces',F,'Vertices',V,'FaceColor',myBlue,'FaceAlpha',0.16, ...

    'EdgeColor','none','FaceLighting','flat','DiffuseStrength',1,'AmbientStrength',1,'SpecularStrength',0);

hold off

axis equal

axis off

axis tight

light('Position',lp,'Style','infinite');

set(gca, 'Projection','perspective');

set(gca,'View',[70,-1]);

xlim([-LL LL]);

ylim([-LL LL]);

zlim([-LL LL]);

 

frame = getframe(gcf);

writeVideo(vid,frame);

 

% Set up initial conditions for generating secondary electrons

 

R = zeros(1,noElsMax+1); % IMFP

x = zeros(1,noElsMax+1); % x-coordinates of electrons

y = zeros(1,noElsMax+1); % y-coordinates of electrons

z = zeros(1,noElsMax+1); % z-coordinates of electrons

phi = pi*rand(1,noElsMax+1); % Random angular trajectories

theta = 2*pi*rand(1,noElsMax+1); % Ditto

Ekin = EkinInit*ones(1,noElsMax+1); % KE of electrons

noEls = 1; % Number of electrons

 

% Now loop to produce multiple secondary electrons

for ii = 1:framesMax % Total number of frames in video (not including incident photon)

    subplot('position',pos1);

    newplot

    % ii % Uncomment if you want to track progress

    hold off

    [V,F] = platonic_solid(2,rCube); % Cube

    ps = patch('Faces',F,'Vertices',V,'FaceColor',myBlue,'FaceAlpha',0.16, ...

        'EdgeColor','none','FaceLighting','flat','DiffuseStrength',1,'AmbientStrength',1,'SpecularStrength',0);

    hold on

    if (noEls < noElsMax)

        for jj = 1:noEls

            R(jj) = 1430/Ekin(jj)^2 + 0.54*Ekin(jj)^0.5; % Mean free path as function of electron KE

            v = (Ekin(jj)/EkinInit)^0.5; % Normalized velocity, starts as 1

            steps = round(R(jj)/v); % Nominal number of steps to travel R at speed v

            x(jj) = x(jj) + (R(jj)/steps)*cos(phi(jj))*sin(theta(jj));

            y(jj) = y(jj) + (R(jj)/steps)*cos(phi(jj))*cos(theta(jj));

            z(jj) = z(jj) + (R(jj)/steps)*cos(phi(jj));

            % If electron moves outside rCube, make it transparent

            if (abs(x(jj)) > rCube/sqrt(3)) || (abs(y(jj)) > rCube/sqrt(3))...

                    || (abs(z(jj)) > rCube/sqrt(3))

                alp(jj) = 0;

            end

            prob = 1/steps; % Probability of electron being inelastically scattered

            if (abs(x(jj)) < rCube/sqrt(3)) && (abs(y(jj)) < rCube/sqrt(3))...

                    && (abs(z(jj)) < rCube/sqrt(3)) % Inside box

                if (rand < prob) % Collision and production of a new electron

                    Ekin(jj) = Ekin(jj)/2; % Energy drops by half

                    phi(jj) = pi*rand; % Send off along new trajectory

                    theta(jj) = 2*pi*rand; % Send off along new trajectory

                    x(noEls+1) = x(jj); % New electron starts where collision occurred

                    y(noEls+1) = y(jj); % Ditto

                    z(noEls+1) = z(jj); % Ditto

                    Ekin(noEls+1) = Ekin(jj); % New electron takes on half of energy

                    if (noEls < noElsMax)

                        noEls = noEls + 1; % Total number of electrons increases by one

                    else

                        noEls = noElsMax;

                    end

                end

            end

            % Draw electron

            surf(er*a+x(jj),er*b+y(jj),er*c+z(jj),...

                'FaceColor',myBlue,'FaceAlpha',alp(jj),'LineStyle','none',...

                'FaceLighting','flat','DiffuseStrength',1);

        end

    end

    Esum = sum(Ekin(1:noEls)); % Should always equal initial photoelectron energy

    Eav = Esum/noEls; % Present mean electron energy

    imfp = 1430/Eav^2 + 0.54*Eav^0.5; % Present mean inelastic mean free path

    axis equal

    axis off

    axis tight

    light('Position',lp,'Style','infinite');

    set(gca, 'Projection','perspective');

    set(gca,'View',[70,-1]);

    xlim([-LL LL]);

    ylim([-LL LL]);

    zlim([-LL LL]);

    

    % Labelling of conditions. Values not to be taken seriously!

    str1 = 'Average KE = ';

    str2 = num2str(Eav,'% 4.1f');

    str3 = ' eV';

    Estr = [str1 str2 str3];

    str4 = 'Average IMFP = ';

    str5 = num2str(imfp,'% 4.1f');

    str6 = ' ';

    str7 = Ang;

    Rstr = [str4 str5 str6 str7];

    str8 = 't = ';

    str9 = num2str(tt,'% 6.4f');

    str10 = ' fs';

    Tstr = [str8 str9 str10];

    str11 = '# electrons = ';

    str12 = num2str(noEls,'% 4.0f');

    Elstr = [str11 str12];

    tt = tt + Deltt;

    annotation('textbox',[0.85 0.17 0.14 0.07],'String',Estr,'EdgeColor',...

        'none','FontSize',18,'FitBoxToText','on','HorizontalAlignment',...

        'left','verticalAlignment','bottom');

    annotation('textbox',[0.85 0.14 0.14 0.07],'String',Rstr,'EdgeColor',...

        'none','FontSize',18,'FitBoxToText','on','HorizontalAlignment',...

        'left','verticalAlignment','bottom');

    annotation('textbox',[0.85 0.11 0.14 0.07],'String',Tstr,'EdgeColor',...

        'none','FontSize',18,'FitBoxToText','on','HorizontalAlignment',...

        'left','verticalAlignment','bottom');

    annotation('textbox',[0.85 0.08 0.14 0.07],'String',Elstr,'EdgeColor',...

        'none','FontSize',18,'FitBoxToText','on','HorizontalAlignment',...

        'left','verticalAlignment','bottom');

    

    frame = getframe(gcf);

    writeVideo(vid,frame);

    delete(findall(gcf,'type','annotation'));

    hold off

end

 

 

% Output the movie as an mpg file

close(vid);