Adsorption Modelling - Solving PDE - Axial Dispersion Model

Dear all,
I am trying to develop a simple model for an adsorption column. I have attached a file that contains the equations that I am trying to solve.
To solve the system, I am trying to solve the axial dispersion model (neglecting pressure drop, and hence, the dv/dz term) alongside the Linear Driving Force (LDF) model, which gives an expression for dq/dt in the axial dispersion PDE (see attached file). I am also using the Langmuir equation to give an expression for q* (equilibrium concentration) in the LDF equation.
Unknown variables are q and c, all other variables are known (i.e. D, v, epsilon etc.( / are the independent variables (i.e. time, t, and length, z).
I have tried using the Method of Lines to solve this system (again, see attached file), but I am aware that the system I have developed is flawed.
Any suggestions on how to approach this problem would be appreciated. I would preferably like to solve the system using either a PDE solver or ode45 applied to the method of lines.
My code so far is as follows:
Data File:
%%Constants
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
bH = 2.5*10^-5; % Langmuir parameter for H2
L = 1; % Column length
%%MoL Coefficients & Mesh Generation
N = 20;
dz = L/N;
z = [0:dz:L];
% MoL Coefficients from Discretisation
alph = ((D/(dz^2)) + ((v)/(2*dz)));
bet = ((-2*D)/(dz^2));
gamm = ((D/(dz^2)) - ((v)/(2*dz)));
%%Initial / Boundary Conditions
% Initial condition for ODE 1:
c0 = 0; % C at t = 0 for all z
% Boundary Condition for ODE 1:
cFeed = 10; % C at z = 0 for all t
qs = (1+bH*cFeed)/(bH*cFeed); % Conc. of adsorbed phase at surface saturation
% Initial Condition for ODE 2:
q0 = qs*((bH*cFeed)/(1+bH*cFeed))-1; % Initial concentration in adsorbed phase
% Time Boundaries
t0 = 0;
tf = 10000;
% Initial equilibrium conc.
qeq0 = qs*((bH*c0)/(1+bH*c0));
dq0 = k*qeq0;
Solving using ODE45:
close all
clear all
clc
% Call Data File
DataFile;
tspan = [0:10000];
[t,c] = ode45('cprime', tspan, c0);
Cprime file
function [ dcdt ] = cprime(~, c)
% Call data file to define constants
DataFile;
t=t0;
q = q0;
[dqdt] = qprime(t, q, k, qs, bH, c);
%%Create Tri-diagonal Matrix A
A = zeros(N,N);
for i = 2 : N-1
A(i, i-1) = alph;
A(i, i) = bet;
A(i, i+1) = gamm;
end
A(1,1) = bet;
A(1,2) = gamm;
A(N,N-1) = alph+gamm;
A(N-1, N) = gamm;
A(N,N) = bet;
b = ones(N,1);
b(1) = cFeed*alph-((1-epsilon)/(epsilon)*(k*(qeq-q)));
dcdt = (A*c + b);
end
qprime file:
function [dqdt] = qprime(~, q, k, qs, bH, c)
DataFile;
qeq = qs*((bH*c)/(1+bH*c));
dqdt = k*(qeq-q);
end
I am really struggling to figure out how to structure my code / approach these equations.
Any help would be muchly appreciated!
Thanks!

46 Comments

Ashley Gratton
I am also developing the same the model. Can you please send me the code as I am having problem in generating it?
Thanks
Alok Prasad
Hello Alok, I do have a fully functional simple isothermal, isobaric adsorption column model. I will try and publish the code at some point soon.
Ashley, That will of great use. I have just started modelling so I am using only one adsorbate and neglecting the axial dispersion term and also trying to get the breakthrough curves.Your help will be of great use. Actually I am discretizing in both spatial and time domain.Thus getting nonlinear algebraic equations. Can you suggest me any numerical method by which it can be solved? Thanks
I used the method of lines using the ode45 solver as the time stepper. I'd suggest not excluding the axial dispersion term as it caused instability in my model.
Thanks a lot. Actually I am assuming it to be a plug flow that's why neglected the axial term .What's the problem in your mentioned code?
Assuming plug flow is fine, as long as you have a plug flow model derived from first principles, rather than cancelling the axial dispersion term from the axial dispersion model.
Hello Alok,
Attached is a three-page extract from my dissertation, detailing the discretisation of the axial dispersion model and other mathematical manipulation. I hope this is useful to you and others. If you need any further clarification, please let me know.
Reference [41] used in attached document extract: Sircar, S., Hufton, J. R., 2000. "Why Does the Linear Driving Force Model for Adsorption Kinetics Work?". Adsorption 6, 137-147. Available from: http://link.springer.com/10.1023/A:1008965317983.
Note: I am the author of the attached 3-page extract, if anyone would like to reference or otherwise use it, please contact me prior to doing so, as I consider the attached document my own intellectual property.
Ashley, Thanks a lot. Actually I am having problem in selection of step size in both time and size domain. Can you suggest me any way to get rid of such problem? Thanks Alok
Hey Ashley, Thanks a lot. I am able to run the program, but the problem is that I am not able to get the proper breakthrough curves. In the curve, concentration remains zero for sometime and it starts increasing which is quite obvious as the adsorbent is on the verge of saturation. But after sometime the curve should attain a constant value but instead of that its oscillating. What could be the possible reason? Your help will be very much appreciated. Thanks, Alok
What numerical method/solver are you using? It could be unstable because of your time step size or mesh grid size. Or your boundary conditions don't tell the program that there is no further changes to concentration at Z=L (I. E. The end of the column), hence dc/dz=0 at Z =L.
ODE 45..chosen boundary conditions are c(z=0,t)=co(constant feed concentration) , c(z,t=0)=0 and q(z,t=0)=0. How to choose time step size or mesh grid size to make it stable? Could you please help me in sorting it out? Thanks
Hello Sir, Can we use the same technique for the system having multiadsorbate? Thanks
Hello, the material balance included in my attached file is infact a component balance, so to solve a multicomponent system, all you need to do is solve two (binary mixture) / three (ternary mixture) axial dispersion PDEs instead of the one. Obviously with the relevant initial and boundary conditions of the second/third components. My system was designed to model the separation of a binary feed, so I just had two main sections to my function file - one for the first component and the other for the second.
Let me know if that helps or you want me to clarify.
Ash
Thanks Ashley for such a great help. But I am having the same problem as the curve begin to oscillate after reaching the the inlet bulk phase adsorbate concentration value.Can you provide me your email so that I can forward my program to you. I have attached the plot that I got. Thanks
hey ashley, in case of multiadsorbate system, velocity should not be taken as a constant value. Then how to evaluate the the du/dt term? Can this be calculated using overall mass balance? Thanks
By all means if you can find an expression for the C_i * dv/dz term, be my guest. I struggled to find/develop one, as such, I assumed constant superficial velocity (v) throughout the column as a result of negligible pressure drop due to friction and adsorption. It turns out if you calculate pressure drop using the Ergun packed bed equation, it comes out as negligible anyway (for my system \DeltaP was around 1 Pa). Depends how rigorous you want to be, whether or not you include or neglect the C_i * dv/dz term. I'd suggest the book on Adsorption Technology and Design by Barry Crittenden,I seem to recall there being a section in there that gives an expression for the aforementioned term, the book is also a good reference for general adsorption processes. Hope that helps.
Thanks a lot Ashley I just want to know that how have you discretized dc/dz. I know that ode45 uses unequispaced grid points so we have to discretized it by considering the same. But how to do that? Thanks
I think you are misunderstanding. When solving a multivariate equation (PDE) such as the axial dispersion model (ADM), that varies both spatially and with time, you only need to discretise the PDE in the spatial domain. Then, you are effectively left with a system of ODEs, which can be solved using any iterative ODE method you like, be it ode45/ode23, Euler's method, RK4 etc. So the process looks something like this:
  • Disctretise the PDE in the spatial domain using the centralised difference method (a step in the method of lines). You will have to choose how many mesh points to have along your spatial domain (N) - i.e. how many slices to split your adsorption column up into. Your mesh grid step size (\delta x) is then defined as the column length (L) divided by the number of mesh points (N) ==> \delta x = L/N. Now you have a column that is discretised spatially (i.e. split up into a tangible number of sections - not a continuum).
  • Now, at each of these mesh points along the column, the ADM can be applied. For example, this means that for 20 mesh points (N = 20), you will have an ODE (Equation 3.23 in my previously attached document) at each point that varies ONLY with time - giving you 20 ODEs (i.e. a system of ODEs) to solve however you would usually solve an ODE.
  • Set up a loop to solve this system of ODEs between your initial (t0) and final (tf) times. I used a function file that defines the ADM and calls said function file in the main script using ode45.
  • Plot the outlet concentration (Cout) against time (t) for the breakthrough curve. Plot a given column of the concentration vector (C) against length (z) to obtain a concentration profile at a given time (determined by which column of the C matrix you plot). Note: I created the z vector as z = [0 : \delta x : L].
Hope this is clear, I've tried to explain as best I can, but I understand it may all be a bit confusing - this project was effectively my entire dissertation, so trying to explain in a few paragraphs is tricky! If you want any more info, let me know, I will try to help.
Best,
Ash
Whatever you said I got that very well. But the way you have discretized the term dc/dz and d2c/dz2 is the main problem. Using central difference on dc/dz at any point I will get (c(i+1)-c(i-1))/2*dz. But you had different way in you program. Please can you clarify my doubts? Thanks
Formula (3.14) from Ash's pdf-document is exactly the approximation for dc/dz you also want to use.
If you discretise as I have done in the attached file, you will have a system that can then be programmed and subsequently solved in MATLAB. The only thing you must do after having done as I have done in the pdf file is to solve the system in MATLAB.
Thanks Ashley, In case of multiadsorbate apart from the langmuir extended equation, what are the modification that one should kept in mind to make the program? Thanks
None, as long as you have Equation 3.14 (plus relevant boundary conditions) for each component in your program, you can solve a multi-adsorbate system.
I have applied the relevant boundary conditions but still not getting the proper breakthrough curves for multi-adsorbate system. Here is my attached file. Can you please check it?
I have run the code, it seems like you have only included one component, I am confused as to what you're asking. The breakthrough curve you have obtained looks fine, just a bit jagged.
Extremely sorry. I have send you the wrong code. The code for multi-adsorbate system is attached below.
hey Ashley can you please look at the program? Thanks
Hey Ashley. Can you please tell me that what can we do with the D2c/Dz2 term at z=L? Thanks
HEY ASHLEY CAN YOU PLEASE LOOK AT THE ATTACHED PROGRAM IN ABOVE COMMENTS? THANKS
Hi Ashley .. Can we use ODE 15s for in case of multiadsorbate? Thanks
Hi Ashley, From where I can get the values of qmax ,Kldf and b(langmuir parameter) for the adsorption of Carbondioxide and nitrogen on activated carbon? Thanks
Hi Ashley, hope you are doing well. I have a question, suppose I have a fixed bed and I have to operate it at 10 bar pressure and gas is entering the column at atmospheric pressure, I know the mole fraction of species in the gas and thus I can calculate their partial pressure using Ptot * mole_fraction where Ptot is the atmospheric pressure. Now I have the mass balance equation for the component using that I can easily get the breakthrough curves. The question is that no where I have used the column pressure in my equation so how to accommodate that 10 bar pressure in my calculation? Thanks
Hello, were you able to run the multiadsorbate breakthrough code?
Yes @Nelson Guy
Are you doing the same thing?
Hi,
Can we code the desorption of a bed saturated with some gas by applying vacuum?
Can you tell me the governing equations associated with the same?
Thanks
Hello Ashok
Yes i am tryin to do the same thing.
I would also need to mimick breakthroughs binary system propane/propylene 50/50 on zeolite using perhaps the code above, any ideas?
Regards
Nelson
ashok were you able to get the vaccum desorption equations?
Hello Nelson Guy
The rate of adsorption and desorption is governed by difference in adsorbed phase concentration at the particle surface in equilibrium with local and instantaneous bulk phase concentration and average adsorbed phase concentration.
Hence the governing equations wll remain same as that of we used in the adsorption process.But still I am not able to get the solution. Did you get the equations and solution for vaccum desorption? Any kind of help will help me a lot.
Regards
Alok
Hi Alok. No, i was not able to resolve the VA.
In a differenot note were you able to generate the code for binary gases mixtures (say Propane/Propylene etc) on Zeolite or porous media?
I used an IAST code but does not seem to work. Can you share your code for 2 gases mixtures?
best
Nelson
Hi,
I just saw the model in the pdf document, and I noticed that the linear driving force model applied is a function of the same "q". Shouldnt it be expresed as a concentration difference?
I really appreciate your help
Best regards
Luis
alok can you please share the multiadsorbate breakthrough code?
are you done with the single adsorbate case?
Hi Alok, I am solving the same kind of problem but unable to get breakthrough curve can you share your code so that I can see where I am going wrong.
What are the units of x-axis 'time'?
Hello @Ashley Gratton please Did you find a solution to your problem? I am havin this exact same challenge with my project too
hi halok
did you manage to define the matlab code for multiadsorbate system?
I can't go ahead, can you publish it?
if you want I can give you a contact to write to us in private
Thanks in advance
federico

Sign in to comment.

 Accepted Answer

The code I provided here for a very similar problem might help:
https://de.mathworks.com/matlabcentral/answers/371313-error-in-solving-system-of-two-reaction-diffusion-equations
Best wishes
Torsten.

20 Comments

Hello,
Thank you for your answer.
I have had a look at your example, but still cannot seem to get this to work. The problem that I am getting stuck on is that I have an ODE within a PDE and need to solve the two simultaneously, but the PDE's first solution in the method of lines matrix depends on the first solution of the ODE, which depends on the first solution of the PDE... It seems like a circular argument...
How would you discretise the PDE when I have two variables (c and q, where q* = fn(c) [see attached file])?
Essentially I am unsure on:
a) How to discretise the PDE using MoL due to the complexity of the system
b) How to solve the system of ODEs generated by the MoL and the dq/dt ODE simultaneously. (Usually, I would know how to solve a system of ODEs, but in this case, I have a system of ODEs from the MoL plus another ODE, which throws me off).
Any further suggestions on how to tackle this problem would be great! If you would like me to provide any further info, let me know, as I understand what I am trying to communicate may not be entirely clear!
Thanks again!
a) In the example, the PDE is essentially the same as yours and discretized using MOL.
b) dC/dt and dq/dt are solved simultaneusly in the example (a PDE and an ODE equation).
Please take a closer look at the code and the underlying equations in the example. The only thing which is different to your problem is that the feed is supplied at z=L and dC/dz = 0 at z=0. But this problem is easily solved by changing the direction of flow for your case.
If questions remain, I'll try to answer them.
Best wishes
Torsten.
Thank you again for your answer, I really appreciate your help.
I have modified your provided code for my problem, however, I am not sure where I have made errors. I will provide the code below. Please note: I have commented the code to make my interpretation of your code clear to you, alongside any questions.
% Initialisation
close all
clear all
clc
%System Set-up %
%Define Variables
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 2*10^4; % Saturation capacity
cFeed = 10; % Feed concentration
L = 1; % Column length
t0 = 0; % Initial Time
tf = 1000; % Final time
dt = 0.5; % Time step
z = [0:0.1:L]; % Mesh generation
t = [t0:dt:tf];% Time vector
n = numel(z); % Size of mesh grid
%Initial Conditions / Vector Creation
c0 = ones(n,1); % t = 0, c = 0 for all z, so shouldn't this be zeros too?
q0 = zeros(n,1); % t = 0, q = 0 for all z, this makes sense to me
y0 = [c0 ; q0]; % Appends conditions together
%ODE15S Solver
[T, Y] = ode15s(@(t,y) MyFun(t,y,z,n),t,y0);
% Expected results:
% c is the concentration in the gas phase, so should eventually reach the
% feed concentration (cFeed) when the adsorbent in the column is fully saturated.
% So effectively, the column should reach steady-state whereby
% for all z, c = cfeed.
% Note q = concentration of gas adsorbed (i.e. on the adsorbent surface)
% Problems:
% I am unsure where to code in the cFeed condition so that the above result
% is achieved.
% Y matrix just displays loads of ones for 1/2 of the matrix, but then does
% give something for the latter half?
Function:
function DyDt=MyFun(~, y, z, n)
% Defining Constants
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 20000; % Saturation capacity
cFeed = 10; % Feed concentration
% Variables being allocated empty vectors
c = zeros(n,1);
q = zeros(n,1);
DcDt = zeros(n,1);
DqDt = zeros(n,1);
DyDt = zeros(2*n,1);
zhalf = zeros(n-1,1);
DcDz = zeros(n-1,1);
D2cDz2 = zeros(n-1,1);
c = y(1:n);
q = y(n+1:2*n);
% Interior mesh points
zhalf(1:n-1)=(z(1:n-1)+z(2:n))/2;
% Boundary Condition at z = L (dc/dz = 0 at z = L)
%DuDx(1) = 0.0;
DcDz(n) = 0; % Changed from commented-out part above, can I do this?
% Since my BC is dc/dz = 0 at z = L (i.e. at the Nth point)
% Discretisation process
D2cDz2(1) = zhalf(1)/(zhalf(1)-z(1)) * (c(2)-c(1))/(z(2)-z(1));
for i=2:n-1
DcDz(i) = ((z(i)-z(i-1))/(z(i+1)-z(i))*(c(i+1)-c(i))+(z(i+1)-z(i))/(z(i)-z(i-1))*(c(i)-c(i-1)))/(z(i+1)-z(i-1));
D2cDz2(i) = (zhalf(i)*(c(i+1)-c(i))/(z(i+1)-z(i))-zhalf(i-1)*(c(i)-c(i-1))/(z(i)-z(i-1)))/(zhalf(i)-zhalf(i-1));
end
for i=1:n-1
%Equation: dc/dt = D * d2c/dz2 - v*dc/dz - ((1-e)/(e))*dq/dt
DcDt(i) = D*D2cDz2(i) - v*DcDz(i) - ((1-epsilon)/(epsilon))*DqDt(i);
%Equation: dq/dt = k(q*-q) where q* = qs * (b*c)/(1+b*c)
DqDt(i) = k*( ((qs*b*c(i))/(1 + b*c(i))) - q(i) );
end
% Unsure of the purpose of these? %%%%%%%%%%%
DcDt(n) = 0.0; %
%
DqDt(n) = k*(((qs*b*c(n))/(1+b*c(n)))-q(n));%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Regardless, I have changed them to fit my equations.
DyDt = [DcDt;DqDt];
end
I understand how you have set up the system (i.e. discretised the PDE) for the most part, I have commented parts that I do not understand if I have modified them correctly for my problem. You have discretised the system slightly differently to how I learned to do it, hence my trouble understanding!
I have tried but am not certain on how to enter my boundary / initial conditions, which are as follows:
t = 0, c = 0 & q = 0, for all z
z = 0, c = cfeed, for t>0
z = L, dc/dz = 0, for t>0
Again, thank you so much for your help, I appreciate it.
function main
% Initialisation
close all
clear all
clc
%System Set-up %
%Define Variables
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 2*10^4; % Saturation capacity
cFeed = 10; % Feed concentration
L = 1; % Column length
t0 = 0; % Initial Time
tf = 1000; % Final time
dt = 0.5; % Time step
z = [0:0.01:L]; % Mesh generation
t = [t0:dt:tf];% Time vector
n = numel(z); % Size of mesh grid
%Initial Conditions / Vector Creation
c0 = zeros(n,1);
c0(1) = cFeed;
q0 = zeros(n,1); % t = 0, q = 0 for all z, this makes sense to me
y0 = [c0 ; q0]; % Appends conditions together
%ODE15S Solver
[T, Y] = ode15s(@(t,y) MyFun(t,y,z,n),t,y0);
function DyDt=MyFun(~, y, z, n)
% Defining Constants
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 20000; % Saturation capacity
% Variables being allocated zero vectors
c = zeros(n,1);
q = zeros(n,1);
DcDt = zeros(n,1);
DqDt = zeros(n,1);
DyDt = zeros(2*n,1);
zhalf = zeros(n-1,1);
DcDz = zeros(n,1);
D2cDz2 = zeros(n,1);
c = y(1:n);
q = y(n+1:2*n);
% Interior mesh points
zhalf(1:n-1)=(z(1:n-1)+z(2:n))/2;
for i=2:n-1
DcDz(i) = ((z(i)-z(i-1))/(z(i+1)-z(i))*(c(i+1)-c(i))+(z(i+1)-z(i))/(z(i)-z(i-1))*(c(i)-c(i-1)))/(z(i+1)-z(i-1));
D2cDz2(i) = (zhalf(i)*(c(i+1)-c(i))/(z(i+1)-z(i))-zhalf(i-1)*(c(i)-c(i-1))/(z(i)-z(i-1)))/(zhalf(i)-zhalf(i-1));
end
% Calculate DcDz and D2cDz2 at z=L for boundary condition dc/dz = 0
DcDz(n) = 0;
D2cDz2(n) = -1.0/(z(n)-zhalf(n-1))*(c(n)-c(n-1))/(z(n)-z(n-1));
% Set time derivatives at z=0
% DcDt = 0 since c=cFeed remains constant over time and is already set as initial condition
% Standard setting for q
DqDt(1) = k*( ((qs*b*c(1))/(1 + b*c(1))) - q(1) );
DcDt(1) = 0.0;
% Set time derivatives in remaining points
for i=2:n
%Equation: dq/dt = k(q*-q) where q* = qs * (b*c)/(1+b*c)
DqDt(i) = k*( ((qs*b*c(i))/(1 + b*c(i))) - q(i) );
%Equation: dc/dt = D * d2c/dz2 - v*dc/dz - ((1-e)/(e))*dq/dt
DcDt(i) = D*D2cDz2(i) - v*DcDz(i) - ((1-epsilon)/(epsilon))*DqDt(i);
end
% Concatenate vector of time derivatives
DyDt = [DcDt;DqDt];
end
Torsten,
That works! Excellent, thank you very much for your help!
Ash
Tortsen, While implementing your code on Matlab its showing an error as 'Function definitions are not permitted in this context'.How to get rid of this? Thank You
Put an end statement after
[T, Y] = ode15s(@(t,y) MyFun(t,y,z,n),t,y0);
and save the code as "main.m".
Then you should be able to run it.
Best wishes
Torsten.
thanks a lot. But now the error is showing that the value assigned here to T might be unused [T, Y] = ode15s(@(t,y) MyFun(t,y,z,n),t,y0); Similar is the case for Y. Thanks Alok Prasad
Plot the solution, and the warning message will vanish.
I have also done the same thing like I used plot(T,Y'r') but its showing that, this statement is not inside any function. (It follows the END that terminates the definition of the function "main".)
Torsten, I am discretizing both spatially and with respect to time also. Thus I am getting non linear algebraic equations. Can you suggest me a way to move further? Thanks Alok
hey Tortsen, In the problem mentioned by Ashley, I want to update the value of concentration at each dz. That means whatever is coming out from the first bed step, I am not sending it directly to second bed step, instead I am updating it. So where should I start updating the concentration? Should I update it in the for loop that I have used to write the equation or should I generate a for loop for ODE45? Thanks
I don't know anything about the code you are using. Thus it is impossible for me to answer your question.
I have attached the matlab files. Here Ca_vec_bed_1_1 is concentration of CO2 and Ca_vec_bed_1_2 concentration in of CO2 in solid phase. Similarly Ca_vec_bed_1_3 is concentration of N2 and Ca_vec_bed_1_4 concentration in of N2 in solid phase. Ptot is total pressure.
And what do you mean by
I want to update the value of concentration at each dz. That means whatever is coming out from the first bed step, I am not sending it directly to second bed step, instead I am updating it.
?
You will have to solve the following conservation equations:
1. Total mass balance to calculate pressure
2. Darcy's law to calculate velocity
3. Species equation to calculate mass fraction of CO2
4. Equation of State to calculate density
5. Energy equation to calculate temperature
This way, the effect you describe above is represented adequately. No need to update anything - you just have to solve additional partial differential equations.
Here is the link to a publication in German in which the relevant equations are derived:
https://onlinelibrary.wiley.com/doi/abs/10.1002/cite.201200105
Best wishes
Torsten.
Hey, Can you suggest me a way in which a time-dependent parameter can be incorporated in ODE solver? Like in the problem asked by Ashley the inlet feed is constant but I have to vary it with respect to time i.e. the feed concentration at the inlet is changing with time and I have a vector associated with it. How to show this change in the code? Thanks
Boundary condition for the species equation reads:
-Di*rho*dyi/dx = Ndot_ein(t)/Area_ein*(yi_ein-yi)
Di: Diffusivity component i [m^2/s]
rho: molar density of gas mixture at inlet boundary [mol/m^3]
Ndot_ein: Molar flow in domain (can be time-dependent) [mol/s]
Area_ein: Inlet area [m^2]
yi_ein: Molar fraction of component i in inlet flow [mol/mol]
yi : molar fraction component i at inlet boundary [mol/mol]
function main
% Initialisation
close all
clear all
clc
%System Set-up %
%Define Variables
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 2*10^4; % Saturation capacity
cFeed = 10; % Feed concentration
L = 1; % Column length
t0 = 0; % Initial Time
tf = 1000; % Final time
dt = 0.5; % Time step
z = [0:0.01:L]; % Mesh generation
t = [t0:dt:tf];% Time vector
n = numel(z); % Size of mesh grid
%Initial Conditions / Vector Creation
c0 = zeros(n,1);
c0(1) = cFeed;
q0 = zeros(n,1); % t = 0, q = 0 for all z, this makes sense to me
y0 = [c0 ; q0]; % Appends conditions together
%ODE15S Solver
[T, Y] = ode15s(@(t,y) MyFun(t,y,z,n),t,y0);
function DyDt=MyFun(~, y, z, n)
% Defining Constants
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 20000; % Saturation capacity
% Variables being allocated zero vectors
c = zeros(n,1);
q = zeros(n,1);
DcDt = zeros(n,1);
DqDt = zeros(n,1);
DyDt = zeros(2*n,1);
zhalf = zeros(n-1,1);
DcDz = zeros(n,1);
D2cDz2 = zeros(n,1);
c = y(1:n);
q = y(n+1:2*n);
% Interior mesh points
zhalf(1:n-1)=(z(1:n-1)+z(2:n))/2;
for i=2:n-1
DcDz(i) = ((z(i)-z(i-1))/(z(i+1)-z(i))*(c(i+1)-c(i))+(z(i+1)-z(i))/(z(i)-z(i-1))*(c(i)-c(i-1)))/(z(i+1)-z(i-1));
D2cDz2(i) = (zhalf(i)*(c(i+1)-c(i))/(z(i+1)-z(i))-zhalf(i-1)*(c(i)-c(i-1))/(z(i)-z(i-1)))/(zhalf(i)-zhalf(i-1));
end
% Calculate DcDz and D2cDz2 at z=L for boundary condition dc/dz = 0
DcDz(n) = 0;
D2cDz2(n) = -1.0/(z(n)-zhalf(n-1))*(c(n)-c(n-1))/(z(n)-z(n-1));
% Set time derivatives at z=0
% DcDt = 0 since c=cFeed remains constant over time and is already set as initial condition
% Standard setting for q
DqDt(1) = k*( ((qs*b*c(1))/(1 + b*c(1))) - q(1) );
DcDt(1) = 0.0;
% Set time derivatives in remaining points
for i=2:n
%Equation: dq/dt = k(q*-q) where q* = qs * (b*c)/(1+b*c)
DqDt(i) = k*( ((qs*b*c(i))/(1 + b*c(i))) - q(i) );
%Equation: dc/dt = D * d2c/dz2 - v*dc/dz - ((1-e)/(e))*dq/dt
DcDt(i) = D*D2cDz2(i) - v*DcDz(i) - ((1-epsilon)/(epsilon))*DqDt(i);
end
% Concatenate vector of time derivatives
DyDt = [DcDt;DqDt];
end
When i try to run this code in matlab, it does not produce any result, my problem is quite similar with the above code, if anyone can provide me with the working code it will be very helpful.
Hi Ashley, Torsten,
I have been trying to model a system that is similar to this one. So far I have had trouble understanding the system, but after analysing it closely, I realized that it is very similar to your system, except that there is an extra term in the equation to account for transport under electric field. Basically this is a coupled ion exchange - electrodialysis system that I am trying to model. I have attached the model equations in the first snapshot. In the second snapshot I have rearranged the equations to match the model that you have provoided in this post. As you can see, the difference is the extra term containing phi (electric field).
Your model is with respect to time and one direction. In my model, the bulk concentration is varying with time and the z direction, and the solid concentration is varying with time and the x direction. The electric potential gradient is in the x direction only.
Please let me know what changes to make to your MATLAB code so that I can model my system. Is it even possible to use this kind of code to model my system?
Thanks in advance.

Sign in to comment.

More Answers (7)

Hey Ashley, referring to Equation 1.1 in your paper, q appeared as a partial differential equation and then as an ODE in Eq 1.5, can you tell why it is so? If it is a PDE, what are the initial and boundary conditions on q (C has these conditions given but not for q, recall that when you solve an ODE without the initial conditions given, you obtain a general solution, with these conditions given, you can obtain a particular solution), these conditions are necessary to obtain reasonable solutions. Do you have an idea of the kind of plot that you are expecting from the solutions of your equations, a plot would be helpful to allow others to work on the problem. I am trying to apply finite difference method to solve the problem, but would need some answers to my questions.

8 Comments

Hello Abraham, thank you very much for your attention. To answer your questions, I have updated my prior attachment and attached it to this comment.
The variable 'q' did appear as a PDE and then an ODE as a result of my clumsiness. The attached file has been amended. It is a PDE in both occurances. I have updated the boundary conditions on the attached file. I have also detailed the plots that I am expecting and linked images I have found via Google, which should give you a good idea of what I am expecting to find!
Again, thank you very much for your help.
Best,
Ash
You are very much welcome Ash, I will keep you posted if I am successful. Good luck for now.
AB
Hello
I used the same code for mimicking breakthrough curve for single gas adsorption on solid zeolite- fixed bed.
%Assumed plug flow, langmuir, Dubinin-A, LDF
% Initialization
close all
clear all
clc
%System Set-up %
%Propane Zeolite
D = 3.37*10^-13; % Axial Dispersion coefficient [m^2/s]
v =1*10^-3; % Superficial velocity [m/s]
epsilon = 0.4; % Voidage fraction []
k = 0.02516; % Mass Transfer Coefficient [1/s]
cFeed = 10; % Feed concentration [mol/m^3]
d=1285720; % density zeolite [g/m^3]Y-DP
L = 0.1; % Column length [m]
%isotherm parameters
E=6224;
W0=41.72*4.4615;
n=0.8646;
b=10^(-4);
qs=2.5;
%Gas parameters
Temp=273.15+60; %Temperature
ps=869200; %Saturation pressure of gas
R=8.3144621; %Gas constant
Cs=ps/(R*Temp);
qe=@(C) qs*b*C/(1+b*C);
%qe=@(C) W0*exp(-(R*Temp*log(Cs./C)/E).^n);
t0 = 0; % Initial Time
tf = 10000; % Final time
dt = 100; % Time step
z = [0:L/20:L]; % Mesh generation
t = [t0:dt:tf]; % Time vector
n = numel(z); % Size of mesh grid
%Initial Conditions / Vector Creation
c0 = zeros(n,1);
c0(1) = cFeed;
q0 = zeros(n,1); % t = 0, q = 0 for all z, this makes sense to me
y0 = [c0 ; q0]; % Appends conditions together
%ODE15S Solver
[T, Y] = ode23s(@(t,y) user(t,y,z,n,D,v,epsilon,k,d,qe),t,y0);
plot(T,Y);
%filename = 'testdata.xlsx';
%xlswrite(filename,[t.' T Y])
function DyDt=user(~, y, z, n,D,v,epsilon,k,d,qe)
% Variables being allocated zero vectors
c = zeros(n,1);
q = zeros(n,1);
DcDt = zeros(n,1);
DqDt = zeros(n,1);
DyDt = zeros(2*n,1);
zhalf = zeros(n-1,1);
DcDz = zeros(n,1);
D2cDz2 = zeros(n,1);
c = y(1:n);
q = y(n+1:2*n);
% Interior mesh points
zhalf(1:n-1)=(z(1:n-1)+z(2:n))/2;
for i=2:n-1
DcDz(i) = ((z(i)-z(i-1))/(z(i+1)-z(i))*(c(i+1)-c(i))+(z(i+1)-z(i))/(z(i)-z(i-1))*(c(i)-c(i-1)))/(z(i+1)-z(i-1));
D2cDz2(i) = (zhalf(i)*(c(i+1)-c(i))/(z(i+1)-z(i))-zhalf(i-1)*(c(i)-c(i-1))/(z(i)-z(i-1)))/(zhalf(i)-zhalf(i-1));
end
% Calculate DcDz and D2cDz2 at z=L for boundary condition dc/dz = 0
DcDz(n) = 0;
D2cDz2(n) = -1.0/(z(n)-zhalf(n-1))*(c(n)-c(n-1))/(z(n)-z(n-1));
% Set time derivatives at z=0
% DcDt = 0 since c=cFeed remains constant over time and is already set as initial condition
% Standard setting for q
DqDt(1) = k*( qe(c(1)) - q(1) );
DcDt(1) = 0.0;
% Set time derivatives in remaining points
for i=2:n
%Equation: dq/dt = k(q*-q) where q* = qs * (b*c)/(1+b*c)
DqDt(i) = k*( qe(c(i)) - q(i) );
%Equation: dc/dt = D * d2c/dz2 - v/e*dc/dz - (d*(1-e)/(e))*dq/dt
DcDt(i) = D*D2cDz2(i) - (v/epsilon)*DcDz(i) - (d*(1-epsilon)/(epsilon))*DqDt(i);
end
% Concatenate vector of time derivatives
DyDt = [DcDt;DqDt];
end
But aftter sometimes the curve starts oscillating. AGAIN Same question above Why please? is this a bounday condition, mesh or time step issue etc?
Regards
Nelson
Hi Nelson,
Perhaps you've tried this already but I would suggest incrementally reducing the time step () to try and eliminate the oscillations in your concentration-time plot. Just be aware that as you decrease your time step, you will increase the computation time. If that doesn't work, then I'm out of ideas - personally I would try cycling between different ODE solvers (i.e. ode45/23/15 etc.) to see if the oscillations stop.
I also noticed that your density value is given in units of not in standard SI units (), so that could possibly be a source of instability if your other parameters are in SI units and you haven't accounted for the conversion. I would also do a sensitivity analysis on your system (i.e. observe the model response to changing different parameters, whilst keeping others constant). For example, I varied my axial dispersion coefficient across several orders of magnitude and ran the simulation with each value, to get an idea of how the system would respond - what I found was that higher values of the axial dispersion coefficient caused instability in the model. Performing a sensitivity analysis may highlight parameters that are particularly prone to causing instability in your model.
Hope this helps...
Ash
Change the corresponding lines to:
z = [0:L/500:L]; % Mesh generation
plot(z,Y(30,1:n).',z,Y(60,1:n).',z,Y(90,1:n).');
DcDz(i) = (c(i)-c(i-1))/(z(i)-z(i-1));
instead of
z = [0:L/20:L]; % Mesh generation
plot(T,Y);
DcDz(i) = ((z(i)-z(i-1))/(z(i+1)-z(i))*(c(i+1)-c(i))+(z(i+1)-z(i))/(z(i)-z(i-1))*(c(i)-c(i-1)))/(z(i+1)-z(i-1));
Thanks, it worked this way:
z = [0:L/500:L]; % Mesh generation
plot(T,Y);
DcDz(i) = (c(i)-c(i-1))/(z(i)-z(i-1));
I would like to perform a binary mixture 50% Propane and 50% Propylene breakthroughs for selectivity purposes?
Any ideas for the code below
%Assumed plug flow, langmuir, Dubinin-A, LDF
% Initialization
close all
clear all
clc
%System Set-up %
%Propane/Propylene zeolite
D1 =3.37E-13; % Axial Dispersion coefficient [m^2/s] of propane
D2= 1.61E-12; % Axial Dispersion coefficient [m^2/s] of propylene
v =1*10^-3; % Superficial velocity [m/s]
epsilon = 0.4; % Voidage fraction []
k1 =0.02516; % Mass Transfer Coefficient [1/s] of propane
k2 =0.2074; % Mass Transfer Coefficient [1/s] of propylene
c1Feed=5; % Feed concentration [mol/m^3]of propane
c2Feed=5; % Feed concentration [mol/m^3]of propylene
d=1285720; % density acetylftw [g/m^3]Y-DP
L = 0.1; % Column length [m]
%isotherm parameters
E=6224;
W0=41.72*4.4615;
n=0.8646;
b1=10^(-4);
qs1=53;
b2= 10^(-3);
qs2=56;
%Gas parameters
Temp=273.15+60; %Temperature
ps=869200; %Saturation pressure of gas
R=8.3144621; %Gas constant
Cs=ps/(R*Temp);
qe=@(C1,C2) (qs1*b1*C1/(1+b1*C1))+(qs2*b2*C2/(1+b2*C2));
%qe=@(C1,C2) W01*exp(-(R*Temp*log(Cs1./C1)/E1).^n1)+W02*exp(-(R*Temp*log(Cs2./C2)/E2).^n2);
t0 = 0; % Initial Time
tf = 10000; % Final time
dt = 100; % Time step
z = [0:L/500:L]; % Mesh generation
t = [t0:dt:tf]; % Time vector
n = numel(z); % Size of mesh grid
%Initial Conditions / Vector Creation
c01 = zeros(n,1);
C02=zeros(n,1);
c01(1) = c1Feed;
c02(1)=c2Feed;
q01 = zeros(n,1); % t = 0, q = 0 for all z
q02=zeros(n,1);
y01 = [c01 ; q01]; % Appends conditions together
y02=[c02;q02]
%ODE15S Solver
[T1, Y1] = ode23s(@(t,y1) user(t,y1,z,n,D1,v,epsilon,k1,d1,qe1),t,y01);
[T2, Y2] = ode23s(@(t,y2) user(t,y2,z,n,D2,v,epsilon,k2,d2,qe2),t,y02);
plot(T1,Y1);
plot(T2,Y2);
filename = 'testdata.xlsx';
xlswrite(filename,[t.' T1 Y1 T2 Y2])
function DyDt=user(~, y, z, n,D,v,epsilon,k,d,qe)
% Variables being allocated zero vectors
c1 = zeros(n,1);
c2= zeros(n,1);
q1 = zeros(n,1);
q2= zeros(n,1);
Dc1Dt = zeros(n,1);
Dc2Dt = zeros(n,1);
Dq1Dt = zeros(n,1);
Dq2Dt = zeros(n,1);
Dy1Dt = zeros(2*n,1);
Dy2Dt = zeros(2*n,1);
zhalf = zeros(n-1,1);
Dc1Dz = zeros(n,1);
Dc2Dz = zeros(n,1);
D2c1Dz2 = zeros(n,1);
D2c2Dz2 = zeros(n,1);
c1 = y1(1:n);
c2 = y2(1:n);
q1= y1(n+1:2*n);
q2= y2(n+1:2*n);
% Interior mesh points
zhalf(1:n-1)=(z(1:n-1)+z(2:n))/2;
for i=2:n-1
DcDz(i) = (c(i)-c(i-1))/(z(i)-z(i-1));
D2cDz2(i) = (zhalf(i)*(c(i+1)-c(i))/(z(i+1)-z(i))-zhalf(i-1)*(c(i)-c(i-1))/(z(i)-z(i-1)))/(zhalf(i)-zhalf(i-1));
end
% Calculate DcDz and D2cDz2 at z=L for boundary condition dc/dz = 0
DcDz(n) = 0;
D2cDz2(n) = -1.0/(z(n)-zhalf(n-1))*(c(n)-c(n-1))/(z(n)-z(n-1));
% Set time derivatives at z=0
% DcDt = 0 since c=cFeed remains constant over time and is already set as initial condition
% Standard setting for q
Dq1Dt(1) = k1*( qe1(c1(1)) - q1(1) );
Dq2Dt(1) = k2*( qe2(c2(1)) - q2(1) );
Dc1Dt(1) = 0.0;
Dc2Dt(1) = 0.0;
% Set time derivatives in remaining points
for i=2:n
%Equation: dq/dt = k(q*-q) where q* = qs * (b*c)/(1+b*c)
Dq1Dt(i) = k1*( qe1(c1(i)) - q1(i) );
Dq2Dt(i) = k2*( qe2(c2(i)) - q2(i) );
%Equation: dc/dt = D * d2c/dz2 - v/e*dc/dz - (d*(1-e)/(e))*dq/dt
Dc1Dt(i) = D1*D2c1Dz2(i) - (v/epsilon)*Dc1Dz(i) - (d1*(1-epsilon)/(epsilon))*Dq1Dt(i);
Dc2Dt(i) = D2*D2c2Dz2(i) - (v/epsilon)*Dc2Dz(i) - (d2*(1-epsilon)/(epsilon))*Dq2Dt(i);
end
% Concatenate vector of time derivatives
Dy1Dt = [Dc1Dt;Dq1Dt];
Dy2Dt = [Dc2Dt;Dq2Dt];
end
Regards
N
and Thanks Ash and Trosten.
Nelson
any clues Ash and Trosten for modeling binary gas mixtures in breakthrough mode? say Propane/Propylene

Sign in to comment.

I still have come up with a reasonable solution, but I am making some progress so far. Here is an image that I obtained from using the finite difference method. Take a look at it and tell me what you think.
An image-

2 Comments

Hello Abraham,
What do each of the axes represent?
Thank you,
Ash
The graphs represent the concentration profile. The x axis is the timeline and the vertical axis shows how the concentration depreciates over time.

Sign in to comment.

function main
% Initialisation
close all
clear all
clc
%System Set-up %
%Define Variables
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 2*10^4; % Saturation capacity
cFeed = 10; % Feed concentration
L = 1; % Column length
t0 = 0; % Initial Time
tf = 1000; % Final time
dt = 0.5; % Time step
z = [0:0.01:L]; % Mesh generation
t = [t0:dt:tf];% Time vector
n = numel(z); % Size of mesh grid
%Initial Conditions / Vector Creation
c0 = zeros(n,1);
c0(1) = cFeed;
q0 = zeros(n,1); % t = 0, q = 0 for all z, this makes sense to me
y0 = [c0 ; q0]; % Appends conditions together
%ODE15S Solver
[T, Y] = ode15s(@(t,y) MyFun(t,y,z,n),t,y0);
plot(T,Y);
end
function DyDt=MyFun(~, y, z, n)
% Defining Constants
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 20000; % Saturation capacity
% Variables being allocated zero vectors
c = zeros(n,1);
q = zeros(n,1);
DcDt = zeros(n,1);
DqDt = zeros(n,1);
DyDt = zeros(2*n,1);
zhalf = zeros(n-1,1);
DcDz = zeros(n,1);
D2cDz2 = zeros(n,1);
c = y(1:n);
q = y(n+1:2*n);
% Interior mesh points
zhalf(1:n-1)=(z(1:n-1)+z(2:n))/2;
for i=2:n-1
DcDz(i) = ((z(i)-z(i-1))/(z(i+1)-z(i))*(c(i+1)-c(i))+(z(i+1)-z(i))/(z(i)-z(i-1))*(c(i)-c(i-1)))/(z(i+1)-z(i-1));
D2cDz2(i) = (zhalf(i)*(c(i+1)-c(i))/(z(i+1)-z(i))-zhalf(i-1)*(c(i)-c(i-1))/(z(i)-z(i-1)))/(zhalf(i)-zhalf(i-1));
end
% Calculate DcDz and D2cDz2 at z=L for boundary condition dc/dz = 0
DcDz(n) = 0;
D2cDz2(n) = -1.0/(z(n)-zhalf(n-1))*(c(n)-c(n-1))/(z(n)-z(n-1));
% Set time derivatives at z=0
% DcDt = 0 since c=cFeed remains constant over time and is already set as initial condition
% Standard setting for q
DqDt(1) = k*( ((qs*b*c(1))/(1 + b*c(1))) - q(1) );
DcDt(1) = 0.0;
% Set time derivatives in remaining points
for i=2:n
%Equation: dq/dt = k(q*-q) where q* = qs * (b*c)/(1+b*c)
DqDt(i) = k*( ((qs*b*c(i))/(1 + b*c(i))) - q(i) );
%Equation: dc/dt = D * d2c/dz2 - v*dc/dz - ((1-e)/(e))*dq/dt
DcDt(i) = D*D2cDz2(i) - v*DcDz(i) - ((1-epsilon)/(epsilon))*DqDt(i);
end
% Concatenate vector of time derivatives
DyDt = [DcDt;DqDt];
end
This is the code which I am using. I don't have much knowledge about Matlab but I need to finish the code for my thesis. My question is, I need to model a fixed bed to obtain the breakthrough curves, so, I would like to know how to obtain these curves (C/C0 vs t) from this code. I would appreciate any help. Thank you very much!

4 Comments

function main
%System Set-up %
%Define Variables
%D = 3*10^-8; % Axial Dispersion coefficient
%v = 1*10^-3; % Superficial velocity
%epsilon = 0.4; % Voidage fraction
%k = 3*10^-5; % Mass Transfer Coefficient
%b = 2.5*10^-5; % Langmuir parameter
%qs = 2*10^4; % Saturation capacity
cFeed = 10; % Feed concentration
L = 1; % Column length
t0 = 0; % Initial Time
%tf = 1000; % Final time
tf = 2000; % Final time
dt = 0.5; % Time step
% z=[0:0.01:L]; %Mesh generation
z = [0:0.0005:L]; %Mesh generation
t = [t0:dt:tf];% Time vector
n = numel(z); % Size of mesh grid
%Initial Conditions / Vector Creation
c0 = zeros(n,1);
c0(1) = cFeed;
q0 = zeros(n,1); % t = 0, q = 0 for all z, this makes sense to me
y0 = [c0 ; q0]; % Appends conditions together
%ODE15S Solver
[T, Y] = ode15s(@(t,y) MyFun(t,y,z,n),t,y0);
%plot(T,Y);
plot(T,Y(:,n)/cFeed)
end
function DyDt=MyFun(~, y, z, n)
% Defining Constants
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
b = 2.5*10^-5; % Langmuir parameter
qs = 20000; % Saturation capacity
% Variables being allocated zero vectors
c = zeros(n,1);
q = zeros(n,1);
DcDt = zeros(n,1);
DqDt = zeros(n,1);
DyDt = zeros(2*n,1);
zhalf = zeros(n-1,1);
DcDz = zeros(n,1);
D2cDz2 = zeros(n,1);
c = y(1:n);
q = y(n+1:2*n);
% Interior mesh points
zhalf(1:n-1)=(z(1:n-1)+z(2:n))/2;
for i=2:n-1
%DcDz(i) = ((z(i)-z(i-1))/(z(i+1)-z(i))*(c(i+1)-c(i))+(z(i+1)-z(i))/(z(i)-z(i-1))*(c(i)-c(i-1)))/(z(i+1)-z(i-1));
DcDz(i) = (c(i)-c(i-1))/(z(i)-z(i-1));
D2cDz2(i) = (zhalf(i)*(c(i+1)-c(i))/(z(i+1)-z(i))-zhalf(i-1)*(c(i)-c(i-1))/(z(i)-z(i-1)))/(zhalf(i)-zhalf(i-1));
end
% Calculate DcDz and D2cDz2 at z=L for boundary condition dc/dz = 0
DcDz(n) = 0;
D2cDz2(n) = -1.0/(z(n)-zhalf(n-1))*(c(n)-c(n-1))/(z(n)-z(n-1));
% Set time derivatives at z=0
% DcDt = 0 since c=cFeed remains constant over time and is already set as initial condition
% Standard setting for q
DqDt(1) = k*( ((qs*b*c(1))/(1 + b*c(1))) - q(1) );
DcDt(1) = 0.0;
% Set time derivatives in remaining points
for i=2:n
%Equation: dq/dt = k(q*-q) where q* = qs * (b*c)/(1+b*c)
DqDt(i) = k*( ((qs*b*c(i))/(1 + b*c(i))) - q(i) );
%Equation: dc/dt = D * d2c/dz2 - v*dc/dz - ((1-e)/(e))*dq/dt
DcDt(i) = D*D2cDz2(i) - v*DcDz(i) - ((1-epsilon)/(epsilon))*DqDt(i);
end
% Concatenate vector of time derivatives
DyDt = [DcDt;DqDt];
end
Hi Torsten, The nth location is showing q data instead of c data. The typical breakthrough is obtained up to n-1th location, i.e., by plotting plot(T,Y(:,n-1)/cFeed), I am getting the breakthrough curve at the outlet. Please help me as I couldn't find the reason of this anomaly. Thanks! The code helps me a lot.
Hi there!
You have help me a lot with this code thank you so much. I was wondering what would happen if instead of a "step" change (breakthrough analysis) you make a rectangular pulse of concentration. I was trying to implement this change in the code unseccesfully because of my lack of experience. could you give some advice?
hi patricia ,
i want to ask you , your code doesnt study the effect of initial concentration, can you have a clue what if i want to study the effect of concentration with the column length and the velocity

Sign in to comment.

function main
%System Set-up %
%Define Variables
%D = 3*10^-8; % Axial Dispersion coefficient
%v = 1*10^-3; % Superficial velocity
%epsilon = 0.4; % Voidage fraction
%k = 3*10^-5; % Mass Transfer Coefficient
%Kf=2.5*10^-5; %freundlish parameter
%nf= 1.45; %freundlish constant
cFeed = 10; % Feed concentration
L = 1; % Column length
t0 = 0; % Initial Time
%tf = 1000; % Final time
tf = 2000; % Final time
dt = 0.5; % Time step
% z=[0:0.01:L]; %Mesh generation
z = [0:0.0005:L]; %Mesh generation
t = [t0:dt:tf];% Time vector
n = numel(z); % Size of mesh grid
%Initial Conditions / Vector Creation
c0 = zeros(n,1);
c0(1) = cFeed;
q0 = zeros(n,1); % t = 0, q = 0 for all z, this makes sense to me
y0 = [c0 ; q0]; % Appends conditions together
%ODE15S Solver
[T, Y] = ode15s(@(t,y) MyFun(t,y,z,n),t,y0);
%plot(T,Y);
plot(T,Y(:,n)/cFeed)
end
function DyDt=MyFun(~, y, z, n)
% Defining Constants
D = 3*10^-8; % Axial Dispersion coefficient
v = 1*10^-3; % Superficial velocity
epsilon = 0.4; % Voidage fraction
k = 3*10^-5; % Mass Transfer Coefficient
Kf=2.5*10^-5; %freundlish parameter
nf= 1.45; %freundlish constant
% Variables being allocated zero vectors
c = zeros(n,1);
q = zeros(n,1);
DcDt = zeros(n,1);
DqDt = zeros(n,1);
DyDt = zeros(2*n,1);
zhalf = zeros(n-1,1);
DcDz = zeros(n,1);
D2cDz2 = zeros(n,1);
c = y(1:n);
q = y(n+1:2*n);
% Interior mesh points
zhalf(1:n-1)=(z(1:n-1)+z(2:n))/2;
for i=2:n-1
%DcDz(i) = ((z(i)-z(i-1))/(z(i+1)-z(i))*(c(i+1)-c(i))+(z(i+1)-z(i))/(z(i)-z(i-1))*(c(i)-c(i-1)))/(z(i+1)-z(i-1));
DcDz(i) = (c(i)-c(i-1))/(z(i)-z(i-1));
D2cDz2(i) = (zhalf(i)*(c(i+1)-c(i))/(z(i+1)-z(i))-zhalf(i-1)*(c(i)-c(i-1))/(z(i)-z(i-1)))/(zhalf(i)-zhalf(i-1));
end
% Calculate DcDz and D2cDz2 at z=L for boundary condition dc/dz = 0
DcDz(n) = 0;
D2cDz2(n) = -1.0/(z(n)-zhalf(n-1))*(c(n)-c(n-1))/(z(n)-z(n-1));
% Set time derivatives at z=0
% DcDt = 0 since c=cFeed remains constant over time and is already set as initial condition
% Standard setting for q
DqDt(1) = k*(kf*(c(1)^(1/nf))-q(1));
DcDt(1) = 0.0;
% Set time derivatives in remaining points
for i=2:n
%Equation: dq/dt = K(q*-q) where q*=kf*(c^(1/nf))
DqDt(i) = k*(kf*(c(i)^(1/nf))-q(i));
%Equation: dc/dt = D * d2c/dz2 - v*dc/dz - ((1-e)/(e))*dq/dt
DcDt(i) = D*D2cDz2(i) - v*DcDz(i) - ((1-epsilon)/(epsilon))*DqDt(i);
end
% Concatenate vector of time derivatives
DyDt = [DcDt;DqDt];
end
This is the code which I am using. I don't have much knowledge about Matlab but I need to finish the code for my thesis. My question is, I need to model a fixed bed to obtain the breakthrough curves using freundlish isotherm, so, I would like to know how to obtain these curves (C/C0 vs t) from this code. i cant run this code i dont know where is the problem. I would appreciate any help. Thank you very much
hi does anyone have the matlab code to solve adsorption when you have multiple components and not just one?
I hope someone can answer, I can not go forward. thank you

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!