How can I make a bvp4c solution more stable?
조회 수: 10 (최근 30일)
이전 댓글 표시
Hello community,
I have a problem with the stability of the BVP4C-solution when the derivative becomes very small. The equation system describes the molar flow of four components along a membrane. The gradient of each species along the membrane is the product of the respective permeability Q and the difference of partial pressure between the high pressure side (retentate) and low pressure side (permeate). Problems occur when the partial pressure of the fast diffusing component on both sides is more or less equal.
I am solving a boundary value problem of the following form
y'= dy/dx = f(y,yo)
y is a vector of the molar flow of 4 species in the retentate side of the membrane. At x=0 I have to solve an implicit equation system for a set of parameters yPo
g(yo,yPo)=0
and calculate the derivative
y'(x=0)=f(yo,yPo)
yo is y(x=0), an unknown parameter (my left boundary value - the retentate molar flows at the end of the membrane) which I fit with the bvp4c-solver. I know the right boundary value at x=1 where the feed enters the membrane on the retentate side.
The ODE is quite simple:
function dydx=ydot(x,y,yo,n)
Q = [2.3369E-08; 1.17095E-06; 3.81087E-08; 2.36619E-07]*n;
pR = 1e6;
pP = 1e5;
if x==0
options=optimset('display','none');
yPo=fsolve(@(yPo) PermOmega(yPo),Q/sum(Q),options);
dydx=Q.*(y/sum(y)*pR-yPo*pP);
else
dydx=Q.*(y/sum(y)*pR-(y-yo)/sum(y-yo)*pP);
end
function g=PermOmega(yPo)
%Permeate composition at x = 0
g=yPo-Q.*(yo/sum(yo)*pR-yPo*pP)/sum(Q.*(yo/sum(yo)*pR-yPo*pP));
end
end
My initial guess for the solution is a straight line between the two boundary values with a mesh-size of 10. The problem is in the second line of the code, where the permeability is multiplied with the number of membranes n. The solution is stable for n=1 (one membrane) but when I increase the number of membranes the partial pressure become similar and the ODE becomes unstable (see pictures)
What can I do to improve stability when the gradient over the membrane becomes small?
So far I have provided the Jacobian matrices (using implicit differentiation at x=0), which made it faster but not more accurate. I have changed the relative and absolute error tolerances of the BVP4C-solver. I have tried BVP5C. And I have boiled down my original ODE-system with three stages each with 7 variables (pressure in retentate and permeate plus retentate temperature) to the essential system with only 4 variables.
The reason why I need stability is that I want to use the solution in a FMINCON-optimizer which will sometimes select parameters which will lead to unstable solutions.
Any ideas?
댓글 수: 0
채택된 답변
Torsten
2018년 2월 9일
편집: Torsten
2018년 2월 9일
Thanks for the detailed explanation of the problem.
I used the following problem formulation in COMSOL Multiphysics and it works without problems:
Solution variables:
y, yo
Equations:
dydx=Q.*(y/sum(y)*pR-(y-yo)/sum(y-yo)*pP)
dyodx = 0
Initial conditions:
y=yo0+x*(yalpha-yo0)
yo=yo0
Boundary conditions:
yo(x=0)=y
y(x=1)=yalpha
Note that I solve for 8 unknown functions, not only 4.
Note further that ydot is only called at the inner grid points, not at x=0. Thus a division by zero does not occur.
Best wishes
Torsten.
댓글 수: 0
추가 답변 (6개)
Torsten
2018년 2월 7일
You must specify the retentate molar flows at x=0 in the boundary routine of bvp4c, not in the routine where you specify the ODE.
Best wishes
Torsten.
댓글 수: 0
JK
2018년 2월 7일
댓글 수: 1
Torsten
2018년 2월 8일
Try
% initial conditions at x=1 (retentate inlet)
yalpha = [0.3;0.25;0.01;0.01];
% estimated retentate values at the end of the membrane (x=0)
yo0=[0.95;0.60;0.92;0.70].*yalpha;
% Boundary value solver
bcfun = @(ya,yb,yo) bc(ya,yb,yo,n,yalpha);
initguess = @(x) yo0+x*(yalpha-yo0);
odefun =@(x,y,yo) ydot(x,y,yo,n);
solinit = bvpinit(linspace(0,1,11),initguess,yo0);
options = bvpset('stats','on','RelTol',1e-3);
sol=bvp4c(odefun,bcfun,solinit,options);
function dydx=ydot(x,y,yo,n)
Q = [2.3369E-08; 1.17095E-06; 3.81087E-08; 2.36619E-07]*n;
pR = 1e6;
pP = 1e5;
dydx=Q.*(y/sum(y)*pR-(y-yo)/sum(y-yo)*pP);
end
function res=bc(ya,yb,yo,n,yalpha)
Q = [2.3369E-08; 1.17095E-06; 3.81087E-08; 2.36619E-07]*n;
pR = 1e6;
pP = 1e5;
options=optimset('display','none');
yPo=fsolve(@(yPo) PermOmega(yPo),Q/sum(Q),options);
res = [ya-yPo;yb-yalpha];
function g=PermOmega(yPo)
%Permeate composition at x = 0
g=yPo-Q.*(yo/sum(yo)*pR-yPo*pP)/sum(Q.*(yo/sum(yo)*pR-yPo*pP));
end
end
Nadeem Abbas
2019년 9월 3일
Hello Dear
How to find the stability of the solutions of BVP4C method?
댓글 수: 1
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!