Appendix B. LTJ Matlab Code
Equation=1; % Chose rate equation as below:
% 1: madsnew(n)=mads(n)-dt*msalt(n)*((x(n)-xinitial)^yads)*Aads*(1.-peq/p)
% 2: madsnew(n)=mads(n)-dt*msalt(n)*((x(n)-xinitial)^yadsln)*C1ads*...
%exp(-Ea/R0/T)*log(p/peq)
dt=0.01; % Time step (s) for simulatiom If N=3 use 0.02
R0=8314; % Universal Gas Constant J/kmol K
RNH3=R0/17; % Approximate ammonia gas constant J/kg K
Cpgas = 2760; % Specific heat Cp of ammonia gas (mean) J/kg K
Cvgas =Cpgas-RNH3; % Specific heat Cv of ammonia gas (mean) J/kg K
Cpads=3120; % Specific heat of ammoniate J/kmol NH3 ***kg???
CpENG = 720; % Specific heat of ENG J/kg K
rhoENG=195.9; % Density of unfilled block of ENG kg/m^3
rhoads=817; % Density of solid ammoniate - ammonia ice from Wiki kg/m^3
MWamm=17.03; % MW ammonia
rhogra=2250; % density of graphite kg/m^3 to get true volume
experiment = menu('choose experiment number', '44-52', '53-56', '57-62')
if experiment == 1
%%%% Data from EXP 44-52 salt mass and ENG initial multiplier to smooth curves
MassSalt = 0.759e-3;
MassSalt = MassSalt*0.47;
MassENG = 0.67e-3;
end
if experiment == 2
%%%% Data from EXP 53-56 salt mass and ENG initial multiplier to smooth curves
MassSalt = 0.23e-3;
MassSalt = MassSalt*0.47;
MassENG = 0.642e-3;
end
if experiment == 3
%%%% Data from EXP 53-56 salt mass and ENG initial multiplier to smooth curves
MassSalt = 0.294e-3;
MassSalt = MassSalt*0.47;
MassENG = 0.632e-3;
end
% Input salt and reaction
saltname = menu('Choose Reaction', 'BaCl2', 'CaCl2(8-4)', 'CaCl2(4-2)')
if saltname==1 % All BaCl2 parameters below
Cpsalt=361.2; % Specific heat of BaCl2 J/kg K (Nist 75.22 J/(mol K))
rhosalt=3856; % Density of unammoniated salt kg/m^3 Wikipedia
MWsalt=208.23;% MW of salt - BaCl2
Xmax=8;% Max moles NH3 per mole salt assumed equal in all nodes
Xmin=0;% Min moles NH3 per mole salt assumed equal in all nodes
Xstart=8; % value of X at time zero
delHdes=48670.37e3; % Altered with LTJ results
delSdes=263.17772e3; % Altered with LTJ results
delSads=223.1352e3; % Altered with LTJ results Pretty certain
delHads=35338.96e3; % Altered with LTJ results about ads results
ydes=2; % Dynamic parameter desorption Eq 1
Ades=3.5; % Dynamic parameter desorption Eq 1
yads=0.2; % Dynamic parameter adsorption Eq 1
Aads=0.75; % Dynamic parameter adsorption Eq 1
yadsln=1; % Dynamic parameter desorption Eq 2
ydesln=1; % Dynamic parameter desorption Eq 2
C1ads=500; % Dynamic parameter desorption Eq 2 (1/s)
C1des=100; % Dynamic parameter desorption Eq 2 (1/s)
Eaads=25000;% Dynamic parameter ads Eq 2 (J/kmol K [as R0])
Eades=25000;% Dynamic parameter des Eq 2 (J/kmol K [as R0])
else
if saltname==2 % All CaCl2 8-4 parameters below
Cpsalt=656.8; % Cp of CaCl2 J/kg K (Wikipedia 72.89 J/(mol K))
rhosalt=2150; % Density of unammoniated salt kg/m^3 Wikipedia
MWsalt=110.984;% MW CaCl2
Xmax=8;% Max moles NH3 per mole salt assumed equal in all nodes
Xmin=0;% Min moles NH3 per mole salt assumed equal in all nodes
Xstart=8; % value of X at time zero
delHdes=41013000;% Reaction enthalpy J/mol for CaCl2 8-4
delSdes=230300; % Reaction entropy change for CaCl2 8-4 J/molK
delHads=41013000;% Reaction enthalpy J/mol for CaCl2 8-4
delSads=230300; % Reaction entropy change for CaCl2 8-4 J/molK
ydes=1.5; % Dynamic parameter desorption Eq 1
Ades=0.7; % Dynamic parameter desorption Eq 1
yads=1.5; % Dynamic parameter adsorption Eq 1
Aads=0.7; % Dynamic parameter adsorption Eq 1
yadsln=1; % Dynamic parameter desorption Eq 2
ydesln=1; % Dynamic parameter desorption Eq 2
C1ads=500; % Dynamic parameter desorption Eq 2 (1/s)
C1des=100; % Dynamic parameter desorption Eq 2 (1/s)
Eaads=25000;% Dynamic parameter ads Eq 2 (J/kmol K [as R0])
Eades=25000;% Dynamic parameter des Eq 2 (J/kmol K [as R0])
else
if saltname==3% All CaCl2 8-4 parameters below
Cpsalt=656.8; % Cp of CaCl2 J/kg K (Wikipedia 72.89 J/(mol K))
rhosalt=2150; % Density of unammoniated salt kg/m^3 Wikipedia
MWsalt=110.984;% MW CaCl2
Xmax=4;% Max moles NH3 per mole salt assumed equal in all nodes
Xmin=2;% Min moles NH3 per mole salt assumed equal in all nodes
Xstart=2; % value of X at time zero
delHdes=42268000;% Reaction enthalpy J/mol for CaCl2 4-2
delSdes=229920; % Reaction entropy change for CaCl2 4-2 J/molK
delHads=42268000;% Reaction enthalpy J/mol for CaCl2 4-2
delSads=229920; % Reaction entropy change for CaCl2 4-2 J/molK
ydes=1.5; % Dynamic parameter desorption Eq 1
Ades=0.7; % Dynamic parameter desorption Eq 1
yads=1.5; % Dynamic parameter adsorption Eq 1
Aads=0.7; % Dynamic parameter adsorption Eq 1
yadsln=1; % Dynamic parameter desorption Eq 2
ydesln=1; % Dynamic parameter desorption Eq 2
C1ads=500; % Dynamic parameter desorption Eq 2 (1/s)
C1des=100; % Dynamic parameter desorption Eq 2 (1/s)
Eaads=25000;% Dynamic parameter ads Eq 2 (J/kmol K [as R0])
Eades=25000;% Dynamic parameter des Eq 2 (J/kmol K [as R0])
else
'Incorrect salt entered';
end
end
end
Ve=11.423e-3; % Volume of expansion vessel and pipework in m^3
massfracsalt = MassSalt/MassENG;
N=3; % Number of nodes
Bore=0.01088;% LTJ tube bore (m)
TCbore = 1e-3; %tc hole
length=5*9.5e-3; % Total axial length of samples (m)
VvoidLTJ=0;%2.7e-5; %Void volume in LTJ tube (m^3)
hwall=5e5; % Wall to ENG heat transfer coefficient
kammgas=0.024; % Conductivty of gas W/mK
gap=0.0002; % Wall ENG gap in m
hwall=kammgas/gap;
% CHECK Radial conductivity of ENG + SALT
kENG=16;
% ********** END OF PARAMETERS FOR TWEAKING ***********
% Input experimental data
filename = input('Enter filename (without .xls)' ,'s')
figname=filename + string(' Xstart = ')+num2str(Xstart)+...
", gap = "+num2str(gap*1000)+string(', kENG = ')+...
num2str(kENG); % Figure titles
expt=xlsread(filename);
%Columns are t(s) Twall (C) Te (C) Tewall (C) Tcentre(C) p(bar)
% Convert to K and Pa
expt(:,2) = (expt(:,2)+expt(:,8))/2; % average wall temps
expt(:,2:5)=expt(:,2:5)+273; % Temperatures to K
expt(:,6)=expt(:,6)*1e5; % Pressures to bar (Check guage is absolute)
toff=expt(1,1); % Time offset
expt(:,1)=expt(:,1)-toff; % Time column begins at zero.
datasize=size(expt);
rows=datasize(1); % Number of rows
tmax=floor(expt(rows,1)/dt)*dt;% Max time rounded to whole number of dt's
jmax=floor(expt(rows,1)/dt);
% Rows in array to be used in simulation, start at dt, end tmax
tempoffe=-expt(1,4)+expt(1,3); % Offset to add to col 4 (Te)
expt(:,4)=expt(:,4)+tempoffe;
expt(:,6)=smooth(expt(:,6),20);
% 20 point moving average to smooth pressure data
expt(:,3)=smooth(expt(:,3),20); % smooth Te
expt(:,4)=smooth(expt(:,4),20); % smooth Tewall
dataarray=zeros(jmax,6);
for j=1:jmax; % Make data array from time dt to tmax
time=dt*j;
for ROW=1:rows-1
if time>=expt(ROW,1)& time<=expt(ROW+1,1);
row=ROW;
end
end
% row is lower row for interpolation
fract=(time-expt(row,1))/(expt(row+1,1)-expt(row,1));
dataarray(j,1)=time;
dataarray(j,2)=expt(row,2)+fract*(expt(row+1,2)-expt(row,2));
dataarray(j,3)=expt(row,3)+fract*(expt(row+1,3)-expt(row,3));
dataarray(j,4)=expt(row,4)+fract*(expt(row+1,4)-expt(row,4));
dataarray(j,5)=expt(row,5)+fract*(expt(row+1,5)-expt(row,5));
dataarray(j,6)=expt(row,6)+fract*(expt(row+1,6)-expt(row,6));
end
xinitial=Xmax*MWamm/MWsalt; % Maximum kg ammonia / kg salt
xfinal=Xmin*MWamm/MWsalt; % Minimum kg ammonia / kg salt
xstart=Xstart*MWamm/MWsalt; % kg ammonia / kg salt at time zero
Tinitial=300; % initial temperature of all nodes in K
Tinitial=expt(1,5);
% Expansion vessel properties
pinitial=3e5; % Initial pressure in Pa
pinitial=expt(1,6);
Teinitial=300;% Initial temperature in K
Teinitial=expt(1,3);
Te=Teinitial;
meinitial=pinitial*Ve/Teinitial/ramms(pinitial/1e5,Teinitial-273);
meinitial=pinitial*Ve/Teinitial/RNH3;
% Initial kg of NH3 in expansion vessel
me=meinitial;
%%% **********SET UP NODE VOLMES and UAs**************
T=ones(1,N)*Tinitial;
V=zeros(1,N);
for n=1:N
r(n)=Bore/2*n/N;% Radius of element
Aouter(n)=2*pi*r(n)*length; % Outer ht area of element (m^2)
if n==1
V(n)=0.5*pi*r(1)*r(1)*length; % Volume of elements in m^3
else V(n)=0.5*pi*r(n)*r(n)*length-0.5*pi*r(n-1)*r(n-1)*length;
end
if n==1
rmean(n)=r(1)/sqrt(2);
% Mean radius such that areas either side are equal (m)
else rmean(n)=sqrt((r(n)*r(n)+r(n-1)*r(n-1))/2);
end
end
Vtotnodes=sum(V);
% ************CALCULATE ALL UAs*************
if N==1
UAouter(1)=2*pi*length/(1/hwall/r(1)+log(r(1)/rmean(1))/kENG);
UAinner(1)=0;
else
for n=1:N-1
UAouter(n)=2*pi*kENG*length/(log(rmean(n+1)/rmean(n)));
if n==1
UAinner(n)=0;
else
UAinner(n)=2*pi*kENG*length/(log(rmean(n)/rmean(n-1)));
end
end
UAouter(N)=2*pi*length/(1/hwall/r(1)+log(r(1)/rmean(1))/kENG);
UAinner(N)=2*pi*kENG*length/(log(rmean(N)/rmean(N-1)));
end
% *********Calculate other parameters for elements******
for n=1:N
% mENG(n)=V(n)*rhoENG;
mENG(n) = MassENG/N;
msalt(n) = MassSalt/N;
% Mass of ENG in node(s)in kg. In general a 1-d array
% msalt(n)=massfracsalt*mENG(n); % Mass of salt in nodes (kg)
mads(n)=msalt(n)*xstart; % Mass of adsorbate in nodes (kg)
x(n)=mads(n)/msalt(n); % Mass NH3/mass salt in nodes
MCp(n)=mENG(n)*CpENG+msalt(n)*Cpsalt;
% Combined MCp for ENG and salt J/K
V0void(n)=(V(n)-mENG(n)/rhogra-msalt(n)/rhosalt);
% Void volume m^3 with zero adsorbate
% add VvoidLTJ proportional to node volumes
V0void(n)=V0void(n)+VvoidLTJ*V(n)/Vtotnodes;
Vvoid(n)=V0void(n)-mads(n)/rhoads; % initial void volume in node n in m^3
mgas(n)=pinitial*Vvoid(n)/Tinitial/ramms(pinitial/1e5,Tinitial-273);
mgas(n)=pinitial*Vvoid(n)/Tinitial/RNH3;
% Mass of gas in voids (kg)
T(n)=Tinitial; % Temperature of node (K)
end% of unchanging node or initial properties
p=pinitial;
mgasinitial=sum(mgas); %Initial mass of gas (kg).
% Assumes xinitial salt volume
totgasinitial=mgasinitial+me; % Initial total mass of gas (kg)
% Set up result storage arrays
mgasarray=zeros(N,ceil(tmax/dt));
madsarray=zeros(N,ceil(tmax/dt));
Tarray=zeros(N,ceil(tmax/dt));
xarray=zeros(N,ceil(tmax/dt));
Xarray=zeros(N,ceil(tmax/dt));
parray=zeros(1,ceil(tmax/dt));
mearray=zeros(1,ceil(tmax/dt));
Tearray=zeros(1,ceil(tmax/dt));
mtotarray=zeros(1,ceil(tmax/dt));
xexptarray=zeros(1,ceil(tmax/dt));
index=0; % Counter for time loop
for t=dt:dt:tmax; % Time in seconds
index=index+1;
Twall=dataarray(index,2); % Wall temperature (K)
%Calculate heat into nodes dQ (J)
if N==1
dQ=dt*UAouter(n)*(Twall-T(n));
else
for n=1:N-1
if n>1;
dQ(n)=dt*(UAouter(n)*(T(n+1)-T(n))+UAinner(n)*(T(n-1)-T(n)));
else
dQ(n)=dt*UAouter(n)*(T(n+1)-T(n));
end
end
dQ(N)=dt*UAouter(N)*(Twall-T(N));
end
dQwall=dt*UAouter(n)*(Twall-T(n));
%Joules into element
dQe=0.; % Joules into vessel in time step.
pnew=fzero(@saltmasserrornew,p+1000);
%T
%Tnew
%stop
% fzero finds pnew such that saltmasserror.m returns a zero
% Store masses in arrays
for j=1:N
mgasarray(j,index)=mgasnew(j);
madsarray(j,index)=madsnew(j);
Tarray(j,index)=Tnew(j);
xarray(j,index)=madsnew(j)/msalt(j);
Xarray(j,index)=xarray(j,index)*MWsalt/MWamm;
end
parray(1,index)=pnew;
peqadsarray(1,index)=peqads;
peqdesarray(1,index)=peqdes;
adsarray(1,index)=ads;
mearray(1,index)=menew;
mtotarray(1,index)=menew+sum(madsnew)+sum(mgasnew);
Tearray(1,index)=Tenew;
% Calculate experimental change in x
meexpt=dataarray(index,6)*Ve/RNH3/dataarray(index,3);
% pV/RT for experimental vessel gas mass
mgasexpt=dataarray(index,6)*sum(Vvoidnew)/RNH3/(dataarray(index,2)+...
dataarray(index,5))*2;% Expt gas mass using calculated Vvoid, mean T
totgasexpt=meexpt+mgasexpt;
delgas=totgasexpt-totgasinitial;
delxexpt=-delgas/sum(msalt); % Change in x from start
xexptarray(1,index)=xstart+delxexpt;
%if xexptarray(1,index)<0;xexptarray(1,index)=0;end; %Remove negatives
% Estimated x based on initial value and gas mass
%Carry out mass balance
Oldmass=sum(mgas)+sum(mads)+me;
Newmass=sum(mgasnew)+sum(madsnew)+menew;
Masschange=1-Oldmass/Newmass;
% Carry out energy balance on elements
for n=1:N
ENGplusSALTheat(n)=MCp(n)*(Tnew(n)-T(n));
deltaUgas(n)=Cvgas*(mgasnew(n)*Tnew(n)-mgas(n)*T(n));
deltaUads(n)=madsnew(n)*(Cpgas*Tnew(n)-pnew/rhoads-delHdes/MWamm)-.../
mads(n)*(Cpgas*T(n)-p/rhoads-delHdes/MWamm);
%Uadsnew=Cpgas*Tnew(n)-pnew/rhoads-delHdes/MWamm;
%Uads=Cpgas*T(n)-p/rhoads-delHdes/MWamm;
deltaH(n)=dmouthout(n);
end
sumheat=sum(ENGplusSALTheat+deltaUgas+deltaUads+deltaH);
ENGplusSALTheatarray(1,index)=sum(ENGplusSALTheat);
dQwall;
Heatfraction=(dQwall-sumheat)/dQwall;
Heatfractionarray(1,index)=Heatfraction;
dQarray(1,index)=dQwall;
%Uadsarray(1,index)=Uads;
sumheatarray(1,index)=sumheat;
deltaHarray(1,index)=sum(deltaH);
deltaUadsarray(1,index)=sum(deltaUads);
deltaUgasarray(1,index)=sum(deltaUgas);
% Energy balance on vessel
%stop
% Set old values to new ones
mgas=mgasnew;
mads=madsnew;
T=Tnew;
p=pnew;
x=xnew;
Te=Tenew;
me=menew;
Vvoid=Vvoidnew;
t;
end% of simulation, t=tmax
function F=saltmasserror (pnew)
for n=1:N
n;
% adsorbing (ads=1) or desorbing (ads=0) ??
peqads=exp(-delHads/R0/T(n)+delSads/R0); % Equilibrium p (ads) in Pa
peqdes=exp(-delHdes/R0/T(n)+delSdes/R0); % Equilibrium p (des) in Pa
ads;
if p<peqdes;
ads=0;
peq=peqdes;
delH=delHdes;
if Equation==1 % Linear model
madsnew(n)=mads(n)+dt*msalt(n)*((xinitial-xfinal)*...
(((x(n)-xfinal)/(xinitial-xfinal)))^ydes)*Ades*(1.-peq/p);
end
if Equation==2 % Log model with Arrhenius f(T)
madsnew(n)=mads(n)+dt*msalt(n)*(xinitial-xfinal)*...
(((x(n)-xfinal)/(xinitial-xfinal))^ydesln)*...
C1des*exp(-Eades/R0/T(n))*log(p/peq);
end
else
%%
if p>peqads;
ads=1;
peq=peqads;
delH=delHads;
if Equation==1 % Linear model
madsnew(n)=mads(n)+dt*msalt(n)*((xinitial-xfinal)*...
(((x(n)-xfinal)/(xinitial-xfinal)))^yads)*Aads*(1.-peq/p);
end
if Equation==2 % Log model with Arrhenius f(T)
madsnew(n)=mads(n)+dt*msalt(n)*(xinitial-xfinal)*...
(((xfinal-x(n)/(xinitial-xfinal))^yadsln))*...
C1ads*exp(-Eaads/R0/T(n))*log(p/peq);
end
else
% In hysteresis band keep going in the same direction.
% If starting in the band arbitrarily suppose desorption
if ads==[];
ads=0;
peq=peqdes;
delH=delHdes;
if Equation==1 % Linear model
madsnew(n)=mads(n)+dt*msalt(n)*((xinitial-xfinal)*...
(((x(n)-xfinal)/(xinitial-xfinal)))^ydes)*Ades*(1.-peq/p);
end
if Equation==2 % Log model with Arrhenius f(T)
madsnew(n)=mads(n)+dt*msalt(n)*((x(n)-xfinal)^ydesln)*...
C1des*exp(-Eades/R0/T(n))*log(p/peq);
end
end
end
end
% Limit x between max and min
xnew(n)=madsnew(n)/msalt(n);
if xnew(n)>xinitial; xnew(n)=xinitial;end
if xnew(n)<xfinal; xnew(n)=xfinal; end
madsnew(n)=xnew(n)*msalt(n);
R=RNH3;
Vvoidnew(n)=V0void(n)-madsnew(n)/rhoads;% new void volume in node n m^3
if ads==0; % Desorption
a=-Cpgas*(0.5*mads(n)+0.5*madsnew(n)+p*Vvoid(n)/2/R/T(n))-MCp(n);
b=dQ(n)+MCp(n)*T(n)-Cvgas/R*(pnew*Vvoidnew(n)-p*Vvoid(n))...
+mads(n)*(Cpgas*T(n)-p/rhoads-delH/MWamm)+...
madsnew(n)*(pnew/rhoads+delH/MWamm)...
-Cpgas/2*(T(n)*(mads(n)-madsnew(n)+p*Vvoid(n)/R/T(n))-pnew*Vvoidnew(n)/R);
c=Cpgas*T(n)*pnew*Vvoidnew(n)/2/R;
% a,b,c quadratic parameters for Tnew
else %adsorption
a=-MCp(n)-madsnew(n)*Cpgas;
b=dQ(n)+MCp(n)*T(n)-Cvgas/R*(pnew*Vvoidnew(n)-p*Vvoid(n))...
+mads(n)*(Cpgas*T(n)-p/rhoads-delH/MWamm)+...
madsnew(n)*(pnew/rhoads+delH/MWamm)...
-Cpgas*Te*(mads(n)-madsnew(n)+p*Vvoid(n)/R/T(n));
c=Cpgas*Te*pnew*Vvoidnew(n)/R;
end
%a, b, c % Check signs to get correct root.
Tnew(n)=(-b-sqrt(b*b-4*a*c))/2/a; % Positive root taken
if Tnew(n)==0;stop;end
mgasnew(n)=pnew*Vvoidnew(n)/R/Tnew(n); % New gas mass kg
dmout(n)=mads(n)-madsnew(n)+mgas(n)-mgasnew(n)%mass of gas expelled kg
dmouthout(n)=dmout(n)*Cpgas*(T(n)+Tnew(n))/2; % Enthalpy flow out
end
mout=sum(dmout); % Total mass to vessel kg
hout=sum(dmouthout); % Total enthalpy flow to vessel.
R=ramms(pnew/1e5,T(n)-273); % Accurate ammonia gas constant
R=RNH3;
Tenew=(dQe+me*Cvgas*Te+hout)/Cvgas/(me+mout); % New vessel temperature K
menew=pnew*Ve/R/Tenew; % New gas mass in vessel kg
F=menew-me-mout; % Mass imbalance kg
end