I am trying to embed a Fsolve to solve this non-linear system in Scilab.
I have solved the problem with the DAE, so I know what to expect, but I am struggling with embedding the Fsolve.
Here is the full copy of the code, DAE included.
I'm not sure where to embed the fsolve function.
//dassl approach
//given data
p=[20.086, 8100, 20.086, 20.086, 4050, 1E-17, 1E-11, 1E-17] //mol/kgh
ynames = ['y1' 'y2' 'y3' 'y4' 'y5' 'y6' 'y7' 'y8' 'y9' 'y10']
y0=[1.5776, 0.32, 0, 0, 0, 0.0131, 4.0E-06, 4.0E-06, 0, 0]'//initial conditions
t0=0
t=linspace(0,1,1000)
dy0 = [0 0 0 0 0 0 0 0 0 0]'
function [f,r]=BatchRXorDassl(t,y,dy)
f(1)=-p(3)*y(2)*y(8)-dy(1)
f(2)=-p(1)*y(2)*y(6)+p(2)*y(10)-p(3)*y(2)*y(8)-dy(2)
f(3)=p(3)*y(2)*y(8)+p(4)*y(4)*y(6)-p(5)*y(9)-dy(3)
f(4)=-p(4)*y(4)*y(6)+p(5)*y(9)-dy(4)
f(5)=p(1)*y(2)*y(6)-p(2)*y(10)-dy(5)
f(6)=-p(1)*y(2)*y(6)-p(4)*y(4)*y(6)+p(2)*y(10)+p(5)*y(9)-dy(6)
f(7)=-0.0131+y(6)+y(8)+y(9)+y(10)-y(7)
f(8)=p(7)*y(1)-y(8)*(p(7)+y(7))
f(9)=p(8)*y(3)-y(9)*(p(8)+y(7))
f(10)=p(6)*y(5)-y(10)*(p(6)+y(7))
r=0
endfunction
y=dassl([y0,dy0],t0,t,BatchRXorDassl)
y=y'
tplot = y(:,1)
yplot = y(:,2:11)
clf(11), scf(11)
plot(tplot,yplot)
xlabel('t (s)')
ylabel('C')
legend(ynames,-4)
xtitle('Batch Reactor Concentration Profiles')
////embedded fsolve approach
////given data
//p=[20.086, 8100, 20.086, 20.086, 4050, 1E-17, 1E-11, 1E-17] //mol/kgh
//ynames = ['y1' 'y2' 'y3' 'y4' 'y5' 'y6' 'y7' 'y8' 'y9' 'y10']
//y0=[1.5776, 0.32, 0, 0, 0, 0.0131, 4.0E-06, 4.0E-06, 0, 0]'//initial conditions
//t0=0
//t=linspace(0,1,1000)
//function ff=fsolvve(y)
// y1 = y(1)
// y2 = y(2)
// y3 = y(3)
// y4 = y(4)
// y5 = y(5)
// y6 = y(6)
// y7 = y(7)
// y8 = y(8)
// y9 = y(9)
// y10 = y(10)
// ff(1) = -0.0131+y(6)+y(8)+y(9)+y(10)-y(7)
// ff(2) = p(7)*y(1)-y(8)*(p(7)+y(7))
// ff(3) = p(8)*y(3)-y(9)*(p(8)+y(7))
// ff(4) = p(6)*y(5)-y(10)*(p(6)+y(7))
// ff(5) = -p(3)*y(2)*y(8)
// ff(6) = -p(1)*y(2)*y(6)+p(2)*y(10)-p(3)*y(2)*y(8)
// ff(7) = p(3)*y(2)*y(8)+p(4)*y(4)*y(6)-p(5)*y(9)
// ff(8) = -p(4)*y(4)*y(6)+p(5)*y(9)
// ff(9) = p(1)*y(2)*y(6)-p(2)*y(10)
// ff(10) = -p(1)*y(2)*y(6)-p(4)*y(4)*y(6)+p(2)*y(10)+p(5)*y(9)
//endfunction
//yfsolve0 = [0 0 0 0 0 0 0 0 0 0]'
//yfsolve = fsolve(yfsolve0,fsolvve)
The following code does what you want if you considerably relax the default RTOL and ATOL of ode:
p = [20.086, 8100, 20.086, 20.086, 4050, 1E-17, 1E-11, 1E-17] //mol/kgh
ynames = ['y1' 'y2' 'y3' 'y4' 'y5' 'y6' 'y7' 'y8' 'y9' 'y10']
y0 = [1.5776, 0.32, 0, 0, 0, 0.0131, 4.0E-06, 4.0E-06, 0, 0]'//initial condition
t0 = 0
t = linspace(0,1,1000)
function dy = rhs(t,y1)
y2 = fsolve([1;1;1;1],list(cstr,y1));
y = [y1;y2];
dy = [-p(3)*y(2)*y(8)
p(1)*y(2)*y(6)+p(2)*y(10)-p(3)*y(2)*y(8)
p(3)*y(2)*y(8)+p(4)*y(4)*y(6)-p(5)*y(9)
-p(4)*y(4)*y(6)+p(5)*y(9)
p(1)*y(2)*y(6)-p(2)*y(10)
-p(1)*y(2)*y(6)-p(4)*y(4)*y(6)+p(2)*y(10)+p(5)*y(9)];
endfunction
function g = cstr(y2,y1)
g = [-0.0131+y1(6)+y2(2)+y2(3)+y2(4)-y2(1)
p(7)*y1(1)-y2(2)*(p(7)+y2(1))
p(8)*y1(3)-y2(3)*(p(8)+y2(1))
p(6)*y1(5)-y2(4)*(p(6)+y2(1))];
endfunction
y1 = ode(y0(1:6),t0,t,1e-3,1e-3,rhs)
Having to do that show that it is nonsense to proceed that way. Please realize that fsolve
uses an iterative algorithm and that with this approach you even cannot even take an adequate initial vector for it. If you absolutely want to use ode I can propose a much better approach using implicit differentiation.