density_atom.m

Be(a)ware of the units...

Contents

Version

2.11

Contact

Please report problems/bugs to michael.holmboe@umu.se

Examples

  1. [Bins,Element_density] = density_atom(atom,Box_dim)
  2. [Bins,Element_density] = density_atom(atom,Box_dim,0.05)
  3. [Bins,Element_density] = density_atom(atom,Box_dim,0.05,'z')
  4. [Bins,Element_density] = density_atom(atom,Box_dim,0.05,'z',2.3) % sigma [>0] value for Gaussian smoothing
  5. [Bins,Element_density] = density_atom(atom,Box_dim,0.05,'z',1,1) % mirror/symmetrize [0/1]
  6. [Bins,Element_density] = density_atom(atom,Box_dim,0.05,'z',1,1,4.57) % Arbitrary value to shift all coords before mirroring etc
function [Bins,Total_Density] = density_atom(atom,Box_dim,varargin)
Fontsize=18;
q=1.602176634E-19; % 1 charge eq is q Coloumb (C)
epsilon_null = 8.854187817E-12; % A2·s4·kg-1·m-3
epsilon=1; % Dielectric constant
Na=6.02214086E23; % Avogadros constant

Atom_label = unique([atom.type]); % Cell containing strings with the atomtypes you want to include in the analysis
% If you want to exclude some atomtypes...
% Atoms_include     = unique([atom.type]);
% Atoms_exclude     = unique([atom(strcmp([atom.resname],'LAC')).type]);
% Atom_label        = setdiff(Atoms_include,Atoms_exclude);

if size(Box_dim,2)>6
    if find(Box_dim(1,6:end))>0
        atom = orto_atom(atom,Box_dim);
        Box_dim=orto_Box_dim;
    end
end

Limits=Box_dim(1:3);
if size(Limits,2)==3
    Limits(4)=Limits(1);
    Limits(5)=Limits(2);
    Limits(6)=Limits(3);
    Limits(1)=0;
    Limits(2)=0;
    Limits(3)=0;
end

if nargin<3
    ds=0.02;
else
    ds=varargin{1};
end

if nargin<4
    dimension='z';
else
    dimension=varargin{2};
end

Distance=0:ds:Box_dim(3);

if strcmpi(dimension,'x')
    Distance=0:ds:Box_dim(1);
    Area=(Limits(5)-Limits(2))*(Limits(6)-Limits(3));
elseif strcmpi(dimension,'y')
    Distance=0:ds:Box_dim(2);
    Area=(Limits(4)-Limits(1))*(Limits(6)-Limits(3));
elseif strcmpi(dimension,'z')
    Distance=0:ds:Box_dim(3);
    Area=(Limits(4)-Limits(1))*(Limits(5)-Limits(2));
end

DistanceMax=Distance(end);
Bins = (0:ds:Distance(end)+ds)';
nBins = numel(Bins);
assignin('base','Distance',Bins);

Set the occupancy of all sites

occ=1;
if ~isfield(atom,'occupancy')
    occ=1;
    try
        atom = occupancy_atom(atom,Box_dim);
    catch
        [atom.occupancy]=deal(1);
    end
end
Occupancy=[atom.occupancy];

Total_Density=zeros(ceil(Distance(end)/ds),1);
Total_Density_SI=Total_Density;
Total_Electron_density=Total_Density;
Total_Electron_density_SI=Total_Density;
Total_Charge_density=Total_Density;
Total_Charge_density_SI=Total_Density;
Total_EField=Total_Density;
Total_EField_SI=Total_Density;
Total_EPot=Total_Density;
Total_EPot_SI=Total_Density;
Element_count=0;
for h=1:length(Atom_label)
    Element_count = Element_count+1;
    % Extract the trajectory data along the selected dimension dim
    ind_atom = find(strncmpi([atom.type],Atom_label(h),3))';
    if size(ind_atom,1)<1
        ind_atom = find(strncmpi([atom.type],Atom_label(h),2))';
        if size(ind_atom,1)<1
            ind_atom = find(strcmpi([atom.type],Atom_label(h)))';
        end
    end

    if strcmpi(dimension,'x')
        Coords=[atom(ind_atom).x]';
    elseif strcmpi(dimension,'y')
        Coords=[atom(ind_atom).y]';
    elseif strcmpi(dimension,'z')
        Coords=[atom(ind_atom).z]';
    end
    Occupancy=[atom(ind_atom).occupancy];

    if nargin>6
        center_vec=varargin{5};
        Coords=Coords-center_vec;
    end

    Coords(Coords<0) = Coords(Coords<0) + Distance(end);
    Coords(Coords>Distance(end)) = Coords(Coords>Distance(end)) - Distance(end);

%     Element_density=histcounts(Coords(:,1),Bins(1:end-1))';
    Element_density=zeros(length(Bins),1);
    for i=1:numel(Coords)
        Coords(i)
        bin_ind=floor((Coords(i)/DistanceMax)*nBins+1)
        Element_density(bin_ind)=Element_density(bin_ind)+Occupancy(i);
    end

    if numel(Element_density)~=numel(Total_Density)
        Element_density=interp1(1:numel(Element_density),Element_density,1:numel(Total_Density),'spline')';
    end

    Element_density=Element_density/(ds*Area*1E-30*6.022e23*1000); % mol/L

    if nargin>4
        sigma = varargin{3};
        if sigma>0
            window = 100;
            x = linspace(-window / 2, window / 2, window);
            gaussFilter = exp(-x .^ 2 / (2 * sigma ^ 2));
            gaussFilter = gaussFilter / sum(gaussFilter); % normalize
            Element_density(:)=conv(Element_density(:)', gaussFilter, 'same');
        end
    end

    if nargin>5
        if varargin{4}>0
            Element_density=(Element_density+flipud(Element_density))/2;
        end
    end

    Element_density_SI=Element_density*1000*Na; % npart/m^3.

    nElectrons = atomic_scattering_factors(Atom_label(h),1.542,0,0); % From X-ray scattering tables, hence not identical to electron density
    Element_electron_density=nElectrons*Element_density; % mol eq/L
    Element_electron_density_SI=q*nElectrons*Element_density_SI; % C/m^3

    if isfield(atom,'charge')
        if sum(unique([atom(ind_atom).charge]))>1
            disp('Averaging the atom type charge for')
            Atom_label(h)
            unique([atom(ind_atom).charge])
        end
        Element_Charge_density = Na*1E-24*Element_density*mean([atom(ind_atom).charge]); % q_ev/nm^3
        Element_EField = cumsum((Element_Charge_density + flipud(Element_Charge_density))/2)*ds*1E-10*1E27*q/(1E9*epsilon_null*epsilon);
        Element_EPot = -cumsum(Element_EField)*ds*1e-10*1E9; %

        Element_Charge_density_SI = q*Element_density_SI*mean([atom(ind_atom).charge]); % npart*A*s / m3  == npart*C / m3
        Element_EField_SI = cumsum((Element_Charge_density_SI + flipud(Element_Charge_density_SI))/2)*ds*1e-10/(epsilon_null*epsilon); % 1e-10m/(epsilon_null*epsilon)
        Element_EPot_SI = -cumsum(Element_EField_SI)*ds*1e-10; % *1e-10m; % V=kg*m2/(A*s2)
    end

    disp('Atom_label')
    Atom_label(h)
    size(ind_atom)
    sum(Element_density)
    disp('-----------')

    % Here we keep track of the atoms we analyze
    UC(Element_count).type=char(Atom_label(h));
    UC(Element_count).N=sum(Element_density);

    % Collect all the data
    Total_Density=Total_Density+Element_density;
    Total_Electron_density=Total_Electron_density+Element_electron_density;
    Total_Density_SI=Total_Density_SI+Element_density_SI;
    if isfield(atom,'charge')
        Total_Charge_density=Total_Charge_density+Element_Charge_density;
        Total_EField=Total_EField+Element_EField;
        Total_EPot=Total_EPot+Element_EPot;

        Total_Charge_density_SI=Total_Charge_density_SI+Element_Charge_density_SI;
        Total_EField_SI=Total_EField_SI+Element_EField_SI;
        Total_EPot_SI=Total_EPot_SI+Element_EPot_SI;
    end

    % Assign the data to atomtype specific variables
    if sum(Element_density) > 0
        assignin('base',strcat(char(Atom_label(h)),'_density'),[Element_density Element_density_SI]);
        assignin('base',strcat(char(Atom_label(h)),'_density'),[Element_electron_density Element_electron_density_SI]);
        if isfield(atom,'charge')
            assignin('base',strcat(char(Atom_label(h)),'_charge_density'),[Element_Charge_density Element_Charge_density_SI]);
            assignin('base',strcat(char(Atom_label(h)),'_efield'),[Element_EField Element_EField_SI]);
            assignin('base',strcat(char(Atom_label(h)),'_epot'),[Element_EPot Element_EPot_SI]);
        end
        hold on
        plot(Distance(1:length(Element_density)),Element_density)
        xlabel('Distance [Å]','FontSize',Fontsize); ylabel('mol/L','FontSize',Fontsize);
    end
end

atom = mass_atom(atom,Box_dim);
assignin('caller','Mw',Mw);
assignin('caller','Box_volume',Box_volume);
assignin('caller','Box_density',Box_density);

hold on;
plot(Distance(1:length(Total_Density)),circshift(Total_Density,[0 0]),'k')
xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Concentration profile [mol/L]','FontSize',Fontsize);
legend([Atom_label {'Total'}]);
hold off

figure
plot(Distance(1:length(Total_Density)),circshift(Total_Electron_density,[0 0]),'r')
xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Concentration profile [mol eqv/L]','FontSize',Fontsize);

if isfield(atom,'charge')
    figure
    plot(Distance(1:length(Total_Density)),circshift(Total_Charge_density,[0 0]))
    xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Charge density [q/nm^3]','FontSize',Fontsize);
    figure
    plot(Distance(1:length(Total_Density)),circshift(Total_EField,[0 0]))
    xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Electric field [V/nm]','FontSize',Fontsize);
    figure
    plot(Distance(1:length(Total_Density)),circshift(Total_EPot,[0 0]))
    xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Electrostatic potential [V]','FontSize',Fontsize);
    figure
    plot(Distance(1:length(Total_Density)),circshift(Total_Charge_density_SI,[0 0]))
    xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Charge density [C/m^3]','FontSize',Fontsize);
    figure
    plot(Distance(1:length(Total_Density)),circshift(Total_EField_SI,[0 0]))
    xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Electric field [V/m]','FontSize',Fontsize);
    figure
    plot(Distance(1:length(Total_Density)),circshift(Total_EPot_SI,[0 0]))
    xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Electrostatic potential [V]','FontSize',Fontsize);
end
% if strcmpi(Unit,'conc')
% else
%     xlabel('Distance [Å]','FontSize',Fontsize); ylabel('Num','FontSize',Fontsize);
% end

% save(strcat('density_profs_',filename))