Найти тему
Мария К.

Расчёт молярной массы в Matlab

Написанная мной функция

[mass,matStoichCoeff,elChem1]=formula(A0,elChem1_0)

для списка веществ A0 выводит молярную массу mass, при необходимости матрицу стехиометрических коэффициентов matStoichCoeff и соответствующий этой матрице список химических элементов elChem1. Стехиометрическая матрица – это число атомов элемента в каждом веществе. Если для стехиометрической матрицы нас интересуют конкретные элементы в исходном списке, можно задать их через elChem1_0. Если в введённой формуле для одного вещества более одной звёздочки/точки и/или неправильно расставлены скобки, программа выдаст ошибку.

Вводим исходный список веществ A0 в таком формате:

A0={'FeO(OH)' 'H2O' 'PbSO4*7H2O' 'CuSO4·5H2O' 'K3[Al(OH)6]' ...

'Ca(H2PO4)2' 'CO2' '(Fe(OH)2)2SO4' 'Ca(H2PO4)2*12H2O'}.

Данный список - пример для расчётов.

Пример 1. При выполнении

mass=formula(A0)

получаем:

Пример 1
Пример 1

Пример 2. Для того же исходного списка, теперь нас интересует и матрица, и список всех элементов для исходного списка веществ:

[mass,A,r]=formula(A0)

Получаем:

Рисунок 2 - Вывод стехиометрической матрицы и соответствующих коэффициентов
Рисунок 2 - Вывод стехиометрической матрицы и соответствующих коэффициентов

Пример 3. Если интересует, сколько атомов конкретных элементов в каждом веществ, например, элементы {'C' 'O'}:

[mass,A,r]=formula(A0,{'C' 'O'})

получаем:

Рисунок 3 - Конкретные элементы
Рисунок 3 - Конкретные элементы

А вот и сама функция:

function [mass,matStoichCoeff,elChem1]=formula(A0,elChem1_0)

% mass - молярная масса

% matStoichCoeff - матрица стехиометрических коэффициентов

% elChem1 - элементы

% A0 – список веществ;

% ==================

elChem={'H' 'He' 'Li' 'Be' 'B' 'C' 'N' 'O' 'F' 'Ne' 'Na' 'Mg' 'Al' 'Si' 'P' 'S' 'Cl' 'Ar' 'K' 'Ca' ...

'Sc' 'Ti' 'V' 'Cr' 'Mn' 'Fe' 'Co' 'Ni' 'Cu' 'Zn' 'Ga' 'Ge' 'As' 'Se' 'Br' 'Kr' 'Rb' 'Sr' 'Y' 'Zr' 'Nb' 'Mo' 'Tc' 'Ru' ...

'Rh' 'Pd' 'Ag' 'Cd' 'In' 'Sn' 'Sb' 'Te' 'I' 'Xe' 'Cs' 'Ba' 'La' 'Ce' 'Pr' 'Nd' 'Pm' 'Sm' 'Eu' 'Gd' 'Tb' 'Dy' 'Ho' 'Er' ...

'Tm' 'Yb' 'Lu' 'Hf' 'Ta' 'W' 'Re' 'Os' 'Ir' 'Pt' 'Au' 'Hg' 'Tl' 'Pb' 'Bi' 'Po' 'At' 'Rn' 'Fr' 'Ra' 'Ac' 'Th' 'Pa' 'U' ...

'Np' 'Pu' 'Am' 'Cm' 'Bk' 'Cf' 'Es' 'Fm' 'Md' 'No' 'Lr' 'Ku' 'Ns'};

elMassNum=[1.008 4.0026 6.941 9.0123 10.81 12.011 14.0067 15.9994 18.9994 20.179...

22.98977 24.305 26.98154 28.0855 30.97376 32.06 35.453 39.948 39.0983 40.08...

44.9559 47.9 50.9415 51.996 54.938 55.847 58.9332 58.7 63.546 65.38 69.72 72.59...

74.9216 78.96 79.904 83.8 85.4678 87.62 88.9059 91.22 92.9064 95.94 98 101.07...

102.9055 106.4 107.868 112.41 114.82 118.69 121.75 127.6 126.9045 131.3 132.9054...

137.33 138.9055 140.12 140.9077 144.24 145 150.4 151.96 157.25 158.9254 162.5...

164.9304 167.26 168.9342 173.04 174.967 178.49 180.9478 183.85 186.207 190.2 192.22...

195.09 196.9665 200.59 204.37 207.2 208.9804 209 210 222 223 226.0254 227.0278...

232.0381 231.0359 238.029 237.0482 244 243 247 247 251 252 257 258 259 260 261 262];

% ----------------------

if nargout>1

m=length(A0); % количество столбцов

n=length(elChem); % количество строк

matStoichCoeff=zeros(n,m);

end

% ------------------------------------------------

for ii=1:length(A0)

A=A0(ii);

cc=char(A);cc0=cc;

c=double(cc);

c(c==91)=40; c(c==93)=41;

% -------------------

indL1=c>64 & c<91;

indL2=c>96 & c<123;

indL=[(indL1(1:end-1)+indL2(2:end))==2,0];

letter1=cc(indL1);

ind1=[0,indL1(1:end-1)];

letter2=cc(ind1~=0);

ind=indL(indL1~=0);

EL=[];numCh=[];

for j=1:length(letter1)

if ind(j)~=0

EL0={letter1(j),letter2(j)};

else

EL0={letter1(j)};

end

EL=[EL,{EL0}];

numCh=[numCh,strmatch(EL0, elChem, 'exact')];

end

at_mass=elMassNum(numCh);

% -----------------

cc([0,indL]~=0)=[];c([0,indL]~=0)=[];

indD=c>47 & c<58;

indL=c>64 & c<91;

%-------------------------------------

I=[indD,0]; N=length(I);

ss0=sign(I);

NN0=1:N;I00=NN0*0;

in1=NN0(ss0(1:end-1)~=ss0(2:end));

l=length(in1);

num1=(1:N)*0+1;

while l>1

I0=I00;

I0(in1(1)+1:in1(2))=I(in1(1)+1:in1(2));

num0=str2double(cc(I0~=0));

if isempty(num0)==0

num1(in1(1))=num0;

end

in1(1)=[];

l=l-1;

end

num=num1(indL);

num00=(1:N-1)*0;num00(indL)=num;

% --------------скобки-------

indBrac1=c==40; indBrac2=c==41;

liu=sum(indBrac1);

if liu~=sum(indBrac2)

error(['Некорректно введённая формула: ',cc0])

end

N=length(c);NN0=1:N;

while liu>0

c1=c;

c1(indBrac1==0 & indBrac2==0)=0;

in=NN0(c1~=0);

c1(c1==0)=[];

% ----------------------------------

liu0=(c1(1:end-1)==40 & c1(2:end)==41);

liu1=[liu0,0];liu2=[0,liu0];

liu1=in(liu1~=0);liu2=in(liu2~=0);

for k=1:sum(liu0)

num00(liu1(k):liu2(k))=num00(liu1(k):liu2(k))*num1(liu2(k));

indBrac1(liu1(k))=0;

indBrac2(liu2(k))=0;

end

liu=sum(indBrac1);

end

% ---------звёздочка-----------------------

indStar=(c==42 | c==183); % ( * or ·)

if sum(indStar)==1

indd=NN0(indStar);

num00(indd:end)=num00(indd:end)*num1(indStar);

end

if sum(indStar)>1

error(['Некорректно введённая формула: ',cc0])

end

% ---------------------------------------

num00=num00(indL);

mass(ii)=at_mass*num00';

% -------матрица стехеометрических коэффициентов---------------

if nargout>1

while isempty(numCh)==0

ind=numCh(1);

rt=(numCh==numCh(1));

numC=sum(num00(rt));

matStoichCoeff(ind,ii)=numC;

numCh(rt)=[];num00(rt)=[];

end

end

% --------------------------------------------------

end

% -------матрица стехеометрических коэффициентов---------------

if nargout>1

if nargin > 1

for i=1:length(elChem1_0)

ind(i)=strmatch(elChem1_0(i),elChem,'exact');

end

elChem1=elChem(ind);

matStoichCoeff=matStoichCoeff(ind,:);

else

elChem1=elChem';

elChem1(sum(matStoichCoeff,2)==0)=[];

matStoichCoeff((sum(matStoichCoeff,2)==0),:)=[];

end

end

% ---------------------------------------------------