Algae growing. Concentration curve problem
Show older comments
Hi! i have made the following code:
function w = Bioreactor
clc
clear all
% Forward Euler method is used for solving the following boundary value problem:
% Problem parameters
alpha1 = 5*10^(-4); % Diffusion coefficient [m^2/s]
mu0 = 5;
mue = 3.5;
Hl = 5;
T = 5000; % [s]
nz = 100; nt = 1000;
KP = 2;
HP= 7;
PC = 1;
K = 2;
KN = 3;
HN = 14.5*10^(-6);
NC = 2;
KC = 5;
HC = 5 ;
PHs3 = 4 ;
PHs4 = 5;
lambda = 2 ;
rs= 10;
P(1)=3; % Initial chosen concentration of P [g/L]
N(1)=9; % Initial chosen concentration of N [g/L]
C(1)=30; % Initial chosen concentration of C [g/L]
Z = 10; % Lenght of the bioreactor [m]
%Check of the problem's parameters
if any([P(1)-PC N(1)-NC] <=0 )
error('Check problem parameters')
end
if any([alpha1 mu0 Hl Z T nz-2 nt-2 KP P(1) PC HC KN N(1) NC KC HC C(1) HN ] <= 0)
error('Check problem parameters')
end
% Stability
dz = Z/nz;
st = 1/2;
dt = st*dz^2/alpha1;
nt = T/dt;
% Initialization
z = linspace(0,Z,nz+1); t = linspace(0,T,nt+1);
nt = round(nt); % Round nt to an integer
nz = round(nz); % Round nz to an integer
N = zeros(1, nt+1); % Initialize N to zero
P = zeros(1, nt+1); % Initialize P to zero
C = zeros(1, nt+1); % Initialize C to zero
I0 = @(t) 100*max(sin ((t-0.4*3600)/(6.28)) , sin (0));
w = zeros(nz+1,nt+1);
% Finite-difference method
for j = 1:nt
f1= (KP*(P(j)-PC))/(HP+(P(j)-PC));
f2 = (KN*(N(j)-NC))/(HN+(N(j)-NC));
pH = (6.35 - log10(C(j))) /2 ;
f3 = 1/(1+exp(lambda*(pH-PHs3)));
f4 = 1/(1+exp(lambda*(pH-PHs4)));
I_in = I0(t(j)).*exp(-K*z.').*exp((-rs).*cumtrapz(z.',w(:,j)));
g = mu0*I_in./(Hl+I_in);
integral_term = f1 * f2 * f3 * trapz(z.',g.*w(:,j)); % Data organization
N(j+1) = N(j) + dt*( -1/Z*integral_term*N(j)); % Function of N over the time and space
P(j+1) = P(j) + dt*( -1/Z*integral_term*P(j)); % Function of P over the time and space
C(j+1) = C(j) + dt*( -1/Z*integral_term*C(j)); % Function of C over the time and space
w(nz+1,j+1) = 9; % Algae concentration at z=0 [Dirichlet]
w(2:nz,j+1) = w(2:nz,j) + dt*(f1*f2*f3*w(2:nz,j).*g(2:nz) + alpha1 * (w(3:nz+1,j)-2*w(2:nz,j)+w(1:nz-1,j))/dz^2);
w(1,j+1) = w(2,j+1); % Algae concentration at z=10 [Neumann]
plot(z,flipud(w(:,j+1)),'b');
%set(gca,'XDir','reverse');
xlabel('z'); ylabel('w');
title(['t=',num2str(t(j)),' s']);
axis([0 10 0 10]);
pause(0.0001);
end
end
And the code is working perfectly. But the W which is the algae concentration over space and time it has been fixed a value of 9 mg/L at the beginning of this bioreactor, so at z=0, im talking about the following row:
w(nz+1,j+1) = 9; % Algae concentration at z=0 [Dirichlet]
But now i would like to fix this concentration at a certain z which has to be equal to z=Z/2 so at the half of the bioreactor. I know that in order to make the code working for sure i have to modify this row:
w(2:nz,j+1) = w(2:nz,j) + dt*(f1*f2*f3*w(2:nz,j).*g(2:nz) + alpha1 * (w(3:nz+1,j)-2*w(2:nz,j)+w(1:nz-1,j))/dz^2);
Can you help me to do that? I've tried something but anything really worked.
Thanks, attached to this post there is the file from which i took the equations.
I should have a graph like this:

Answers (1)
Here is a code for a simple heat-conduction equation
dT/dt = d^2T/dz^2
T(z,0) = 0
T(0,t) = 200
T(1,t) = 340
T(0.5,t) = 90
You should be able to adapt it to your application.
L = 1;
zcut = L/2;
n1 = 50;
n2 = 50;
z1 = linspace(0,zcut,n1);
dz1 = z1(2)-z1(1);
z2 = linspace(zcut,L,n2);
dz2 = z2(2)-z2(1);
tstart = 0;
tend = 1;
dt = 1e-5;
nt = round((tend-tstart)/dt);
t = linspace(tstart,tend,nt);
T_at_zcut = 90;
T_at_0 = 200;
T_at_L = 340;
T = zeros(n1+n2-1,nt);
T(1,:) = T_at_0;
T(end,:) = T_at_L;
T(n1,:) = T_at_zcut;
for i = 1:nt-1
T(2:n1-1,i+1) = T(2:n1-1,i) + dt/dz1^2*(T(3:n1,i)-2*T(2:n1-1,i)+T(1:n1-2,i));
T(n1+1:n1+n2-2,i+1) = T(n1+1:n1+n2-2,i) + dt/dz2^2*(T(n1+2:n1+n2-1,i)-...
2*T(n1+1:n1+n2-2,i)+T(n1:n1+n2-3,i));
end
plot([z1,z2(2:end)],[T(:,1),T(:,100),T(:,250),T(:,500),T(:,750),T(:,1000),T(:,2500),T(:,5000),T(:,7500),T(:,end)])
26 Comments
Alfonso
on 24 Jan 2024
Yes. The partial differential equation for T is only applied in i=2,...,n1-1,n1+1,...,n1+n2-2. The temperatures in the two boundary points and in the center are kept constant and are excluded from updates over time.
This is equivalent to solving two problems separately:
Problem 1:
dT/dt = d^2T/dz^2 0 <= z <= 0.5
T(z,0) = 0
T(0,t) = 200
T(0.5,t) = 90
Problem 2:
dT/dt = d^2T/dz^2 0.5 <= z <= 1
T(z,0) = 0
T(0.5,t) = 90
T(1,t) = 340
and glue the solutions at the right resp. left boundary points together.
Alfonso
on 24 Jan 2024
The setting
w(nz+1,j+1) = w(nz,j+1);
seems to be out of order because at the position of the code where this line appears, w(nz,j+1) is still set to 0 from the line of initialization
w = zeros(nz+1, nt+1);
So your boundary conditions for w are
dw/dx(0) = 0, w(L) = 0, w(L/2) = 5
Is this the correct setting you intend ?
Torsten
on 25 Jan 2024
If you want dw/dz = 0 at both ends, use
w(2:50-1,j+1) = w(2:50-1,j) + dt * (f1*f2*f3*w(2:50-1,j).*g(2:50-1) + alpha1 * (w(3:50,j)-2*w(2:50-1,j)+w(1:50-2,j))/dz^2);
w(50+1:nz,j+1) = w(50+1:nz,j) + dt * (f1*f2*f3*w(50+1:nz,j).*g(50+1:nz) + alpha1 * (w(50+2:nz+1,j)-2*w(50+1:nz,j)+w(50:nz-1,j))/dz^2);
w(1,j+1) = w(2,j+1);
w(nz+1,j+1) = w(nz,j+1);
instead of
w(nz+1,j+1) = w(nz,j+1);
w(2:50-1,j+1) = w(2:50-1,j) + dt * (f1*f2*f3*w(2:50-1,j).*g(2:50-1) + alpha1 * (w(3:50,j)-2*w(2:50-1,j)+w(1:50-2,j))/dz^2);
w(50+1:nz,j+1) = w(50+1:nz,j) + dt * (f1*f2*f3*w(50+1:nz,j).*g(50+1:nz) + alpha1 * (w(50+2:nz+1,j)-2*w(50+1:nz,j)+w(50:nz-1,j))/dz^2);
w(1,j+1) = w(2,j+1);
And since you decouple the two regions at z = L/2, I'm not sure if your integrations with trapz and cumtrapz still have to be over the complete region [0 L] or over [0 L/2] and [L/2 L] separately.
Torsten
on 26 Jan 2024
I cannot help you to check whether your equations are adequate to model what you want to model. I can only help you to check whether predefined equations and boundary conditions are correctly implemented in MATLAB code.
Alfonso
on 26 Jan 2024
Torsten
on 26 Jan 2024
I cannot answer this.
At the moment, I_in is defined for all values of z and enters all equations for all values of z. Maybe you should save and plot the profiles to see what is happening.
Alfonso
on 28 Jan 2024
Alfonso
on 31 Jan 2024
Bioreactor_central()
function Bioreactor_central
% Forward Euler method is used for solving the following boundary value problem:
% Problem parameters
Dm = 5 * 10^(-4);
mu0 = 5;
mue = 2;
Hl = 5;
T = 5000;
nz = 100; %nt = 1000;
KP = 2;
HP = 7;
PC = 1;
K = 2;
KN = 3;
HN = 14.5 * 10^(-6);
NC = 2;
KC = 5;
HC = 5 ;
PHs3 = 4 ;
PHs4 = 5;
lambda = 2 ;
rs = 10;
P(1) = 3;
N(1) = 9;
C(1) = 30;
Z = 10;
% Stability
dz = Z / nz;
st = 1 / 2;
dt = st * dz^2 / Dm;
nt = T / dt;
% Check of the problem's parameters
if any([P(1) - PC N(1) - NC] <= 0 )
error('Check problem parameters')
end
if any([Dm mue mu0 Hl Z T nz-2 nt-2 KP P(1) PC HC KN N(1) NC KC HC C(1) HN ] <= 0)
error('Check problem parameters')
end
% Initialization
z = linspace(0, Z, nz + 1);
t = linspace(0, T, nt + 1);
nt = round(nt);
nz = round(nz);
N = zeros(1, nt + 1);
P = zeros(1, nt + 1);
C = zeros(1, nt + 1);
I0 = @(t) 100 * max(sin((t - 0.4 * 3600) / (6.28)), sin(0));
w = zeros(nz + 1, nt + 1);
w(50, :) = 5;
I_in = zeros(nz + 1,nt);
% Finite-difference method
for j = 1:nt
f1 = (KP * (P(j) - PC)) / (HP + (P(j) - PC));
f2 = (KN * (N(j) - NC)) / (HN + (N(j) - NC));
pH = (6.35 - log10(C(j))) / 2 ;
f3 = 1 / (1 + exp(lambda * (pH - PHs3)));
f4 = 1 / (1 + exp(lambda * (pH - PHs4)));
I_in(:,j) = I0(t(j)) .* exp(-K * z.') .* exp((-rs) .* cumtrapz(z.', w(:, j)));
I_in_10 = I_in(Z,j);
g_in_10 = mu0 * I_in_10 / (Hl + I_in_10);
integral_term = f1 * f2 * f3 * trapz(z, g_in_10 .* w(:, j));
N(j + 1) = N(j) + dt * (-1 / Z * integral_term * N(j));
P(j + 1) = P(j) + dt * (-1 / Z * integral_term * P(j));
C(j + 1) = C(j) + dt * (-1 / Z * integral_term * C(j));
w(2:50-1,j+1) = w(2:50-1,j) + dt * (f1*f2*f3*w(2:50-1,j).*g_in_10 + Dm * (w(3:50,j)-2*w(2:50-1,j)+w(1:50-2,j))/dz^2);
w(50+1:nz,j+1) = w(50+1:nz,j) + dt * (f1*f2*f3*w(50+1:nz,j).*g_in_10 + Dm * (w(50+2:nz+1,j)-2*w(50+1:nz,j)+w(50:nz-1,j))/dz^2);
w(1,j+1) = w(2,j+1);
w(nz+1,j+1) = w(nz,j+1);
end
plot(z,w(:,end))
end
Alfonso
on 1 Feb 2024
Torsten
on 1 Feb 2024
Use your old code without the splitting of the w-array and the length of the region halfed - that's all.
Alfonso
on 1 Feb 2024
Torsten
on 1 Feb 2024
My advice remains the same:
Plot
I_in=I0(t(j)).*exp(-K*z.').*exp((-rs).*cumtrapz(z.',w(:,j)));
as you plot w to see if it's equal to or almost equal to 0.
Alfonso
on 2 Feb 2024
Alfonso
on 2 Feb 2024
The parameters are all correctly used, but they are most probably far off. Did you take care about the units? In the article, some of them have time unit "day" and others have time unit "second". Did you convert them correctly to a common unit in your code ?
And the setting
w(nz+1,j+1) = 5;
is at the wrong position.
It should be set before the for-loop as
w(nz+1,:) = 5
Alfonso
on 2 Feb 2024
Alfonso
on 5 Feb 2024
Categories
Find more on Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!







