Hello again,
So everything seemed to be working great, and then I realized that I left out an important constant from the ODE. When I added this (1/Dno3) to the code, now it keeps running and never seems to converge on a 'final' solution.
I've tried turning on the options in bvpset so that I can see the stats as it's running and change the tolerance, but it never comes to a solution (I let it run overnight)
I've tried reducing the number of points it generates, changing the initial guess, and reducing the tolerance, but nothing seems to get it to converge anymore and it appears to be stuck in some sort of loop. The bvp4c stats keep coming back with nearly the same numbers each time for mesh points, residual, and number of calls.
Any advice on how to get the solver 'unstuck' would be much appreciated.
My code is below, but the only thing that has really changed from the last posting is adding (1/Dno3) to the ODE function
dydx= [y(2); (1/Dno3)*((A)*(p(1,1)*exp(-p(1,2)*x(i))+ p(1,3)*exp(-p(1,4)*x(i)) ) - (1-A)*(p(1,5)*exp(-p(1,6)*x(i)))*y(1))];
~~~~~
function numeric
%define the constants, etc
global Gm N0 xhat p xmin xmax g Dno3
%Data - column 1 is depth, column 2 is concentration in umol/cm3
Data = ...
[0 0.0220
0.12 0.0235
0.28 0.0248
0.47 0.0275
0.65 0.0287
0.82 0.0289
1.02 0.0292
1.21 0.0295
1.905 0.0278
3.81 0.0310
5.72 0.0335
11.42 0.0310
13.32 0.0267
15.23 0.0225
18.08 0.0180
22.85 0.0096
27.61 0.0043
27.61 0.0043
32.37 0.0007
41.90 0.0004];
xdata = Data(:,1);
ydata = Data(:,2);
xmin=min(Data(:,1));
xmax=max(Data(:,1));
%concentration gradient at deepest depth
Gm = (Data(end-1,2)-Data(end,2))/(Data(end-1,1)-Data(end,1));
Dno3=4.2e-06;
DO2=5.1e-06;
O2zero=.240;
N0=0.022; %NO3 concentration at the surface
g = .1; %gamma, the ratio of NO3/O2
xhat = 18.4;%boundary between production and consumption
%vector of initial guesses for the parameters
p = [.00076 .00004 .0002 .00006 .0005 .00005]; %initial guess for parameters p1-6
%Setup to fit the data with the solution of the ODE
options=optimset('FunValCheck','on','MaxIter',5000,'MaxFunEvals',100000,'TolX',1e-8,'Tolfun',1e-8);
[pfinal,resnorm,exitflag,output]=lsqcurvefit(@fitN,p,xdata,ydata,[],[],options);
%Plot output of lsqcurvefit
xsim = linspace(xmin,xmax,50);
yout = fitN(pfinal,xsim);
exitflag
output
pfinal
%plot the solution to the ODE from bvp4c
figure(1)
plot(xsim,yout,'b-');
hold on
plot(xdata,ydata,'go');
xlabel('Depth')
ylabel('Nitrate (µol/cm3)')
legend('Nitrate model','Nitrate data')
%connects bvp4c to lsqcurvefit
function F = fitN(x,xdata)
global Gm N0 xhat p xmin xmax Dno3
p=x;
options= bvpset('Stats','on','RelTol',1e-4,'abstol',1e-3);
solinit = bvpinit(linspace(xmin,xmax,50),[0.022,0.03]);
sol = bvp4c(@ode, @bc, solinit,options);
ydata_sim = deval(sol,xdata)'; %evaluates solution of bvp at the xdata points
F = ydata_sim(:,1);
%The ODE for Nitrogen
function dydx = ode(x,y)
global Gm N0 xhat p xmin xmax Dno3
f=zeros(length(x),1);
for i=1:length(x)
if (x(i) <= xhat)
A = 1;
else
A = 0;
end
end
dydx= [y(2); (1/Dno3)*((A)*(p(1,1)*exp(-p(1,2)*x(i))+ p(1,3)*exp(-p(1,4)*x(i)) ) - (1-A)*(p(1,5)*exp(-p(1,6)*x(i)))*y(1))];
%The boundary conditions for Nitrogen
function boundary = bc(ya,yb)
global Gm N0 xhat p xmin xmax Dno3