-clear all
-close all
-
-pkg load optim
-%{
-classdef Membrane
- properties
- D double {mustBePositive}
- P double {mustBePositive}
- S double {mustBePositive}
-
- r double {mustBePositive}
- d double {mustBePositive}
- A double {mustBePositive}
- l double {mustBePositive}
-
- material char
- endproperties
-endclassdef
-
-classdef MembraneSimulation
- properties
- membrane Membrane
-
- tstep double {mustBePositive}
- xstep double {mustBePositive}
-
- tend double {mustBePositive}
- tc double {mustBeNonnegative} = 0.5
-
- pmax double {mustBePositive}
- pvac double {mustBeNonnegative} = 0
-
- T double {mustBePositive} = 0
-
- endproperties
- methods
- function [t, p] = simulate();
- D = membrane.D
- P = membrane.P
- l = membrane.l
- A = membrane.A
- endfunction
- endmethods
-endclassdef
-%}
-
-
-[fname,path]=uigetfile;
-data=importdata([path fname], '\t', 2);
-
-datasize=size(data.data);
-t=data.data(:,1)';
-p1=data.data(:,datasize(2))';
-p2=data.data(:,datasize(2)-1)';
-
-pvac = min([p1 p2]);
-pmax = max(p1);
-
-xm=find(p1>0.5*max(p1),1,'first');
-tstart = t(xm);
-
-l = 350e-6;
-d = 32e-3;
-A = d^2/4*pi;
-V0 = 616e-9;
-V1 = 872e-9;
-V2 = 684e-9;
-
-
-
-pars_cur = [1e-3, 3.5e-5, tstart, 100, 3e-10, 3e-13, 3.5e-4, 32e-3, V0, V1, V2, pmax, 0.3];
-
-function [tmod, p] = cellmod(pars)
- % cellmod(tstep, xstep, tstart, tend, D, P, l, d, V0, V1, V2, pmax, tc=0.5, pvac=0, T = 298, all)
-
- tstep = pars(1);
- xstep = pars(2);
- tstart = pars(3);
- tend = pars(4);
- D = pars(5);
- P = pars(6);
- l = pars(7);
- d = pars(8);
- V0 = pars(9);
- V1 = pars(10);
- V2 = pars(11);
- pmax = pars(12);
-
-
- if length(pars)<16
- all = false;
- else
- all = pars(16);
- end
-
- if length(pars)<15
- T = 298;
- else
- T = pars(15);
- end
-
- if length(pars)<14
- pvac = 0;
- else
- pvac = pars(14);
- end
-
- if length(pars)<13
- tc = 0.5;
- else
- tc = pars(13);
- end
-
- A = d^2/4*pi;
-
- R = 8.314;
-
- m = floor(l/xstep)+1;
- xstep = l/m;
-
- n1 = floor(tc/tstep)+1;
- tstep1 = tc/n1;
-
- if tend>tc
- n2 = floor( (tend-tc)/tstep);
- tstep2 = (tend-tc)/n2;
- p = zeros(n1+n2-1, m);
- else
- tstep2 = tstep;
- p = zeros(n1, m);
- end
-
- % criterium for numerical stability
- crit = D*max([tstep1, tstep2])/xstep^2;
- while crit>1 % Meaning error grows
- if tstep1 > tstep2
- tstep1 = tstep1/2;
- n1 = n1*2;
- else
- tstep2 = tstep2/2;
- if tend > tc
- n2 = n2*2;
- end
- endif
- crit = D*max([tstep1, tstep2])/xstep^2;
- end
-
- tstep1;
- tstep2;
-
- tmod(1) = 0;
-
- p(1, :) = pvac;
- p(1,1) = pmax;
-
- for j=1:n1
- p(j+1, 2:end-1) = p(j, 2:end-1) + ...
- D*tstep1/xstep^2*( p(j, 1:end-2) - 2*p(j, 2:end-1) + p(j, 3:end));
- p(j+1, 1) = p(j, 1) + tstep1/2/xstep*P*R*T*A/(V0+V1)*...
- ( -3*p(j, 1) + 4*p(j, 2) - p(j, 3) );
- p(j+1, m) = p(j, m) - tstep1/2/xstep*P*R*T*A/V2*...
- ( p(j, m-2) - 4*p(j, m-1) + 3*p(j, m) );
-
- tmod(j+1) = tmod(j) + tstep1;
- end
- if tend > tc
- for j=n1+1:n1+n2-1
- p(j+1, 2:end-1) = p(j, 2:end-1) + ...
- D*tstep1/xstep^2*( p(j, 1:end-2) - 2*p(j, 2:end-1) + p(j, 3:end));
- p(j+1, 1) = p(j, 1) + tstep2/2/xstep*P*R*T*A/V1*...
- ( -3*p(j, 1) + 4*p(j, 2) - p(j, 3) );
- p(j+1, m) = p(j, m) - tstep2/2/xstep*P*R*T*A/V2*...
- ( p(j, m-2) - 4*p(j, m-1) + 3*p(j, m) );
-
- tmod(j+1) = tmod(j) + tstep2;
- end
- end
-
- tmod = [0 tstart tmod+tstart];
- p = [pvac*ones(2,size(p,2)); p];
-
- if all<0.5
- p = [p(:,1) p(:,end)]; %Erasing all but the boundary (cell) pressures
- endif
-end
-
-function Obj = objfun(model, pars, exp)
- xexp = exp(:,1);
- yexp = exp(:,2:end);
-
- [xmod, ymod] = model(pars);
-
- ymod_interpol = interp1(xmod, ymod, xexp);
-
- valid = ~isnan(ymod_interpol) & (yexp>0);
-
- Obj = 1/sum(sum(valid)) * sum(sum( (yexp(valid) - ymod_interpol(valid)).^2 ./ yexp(valid) ));
-end
-
-function grad = grad(field, pars, ind, step = 0.001)
- grad = zeros(size(pars));
- temp_pars = pars;
- for i = ind
- j = j+1;
-
- temp_pars_pos = pars;
- temp_pars_pos(i) = temp_pars_pos(i)*(1+step);
-
- val_pos = field(temp_pars_pos);
-
- temp_pars_neg = pars;
- temp_pars_neg(i) = temp_pars_neg(i)*(1-step);
-
- val_neg = field(temp_pars_neg);
-
- grad(i) = (val_pos - val_neg)/(temp_pars_pos(i) - temp_pars_neg(i));
- endfor
-end
-
-tolobj = 1e-4;
-
-curobjfun = @(pars) objfun(@cellmod, pars, [t; p1; p2]');
-
-
-pars_prev = pars_cur;
-pars_prev(5:6) = pars_prev(5:6)*1.01;
-gradF_prev = grad(curobjfun, pars_prev, [5 6]);
-F_prev = curobjfun(pars_prev);
-
-krit = tolobj+1;
-
-optstep = 1;
-
-while F_prev>tolobj
-
-
- gradF_cur = grad(curobjfun, pars_cur, [5 6])
-
- pars_cur = pars_cur - optstep * numhessian(curobjfun, pars_cur, [5 6]) \ gradF_cur
- F_cur = curobjfun(pars_cur)
-%{
- while F_cur > F_prev
- optstep = optstep/2;
- pars_cur = pars_prev - optstep * gradF;
- F_cur = curobjfun(pars_cur);
- endwhile
-
- krit = abs(F_prev - F_cur)
- F_cur
- optstep
- pars_cur
- gradF_cur
-%}
- F_prev = F_cur;
- gradF_prev = gradF_cur;
- pars_prev = pars_cur;
-
-end
-
-%{
-p1mod = p(:,1);
-p2mod = p(:,end);
-
-t = (0:0.01:tend);
-x = (0: 10e-6 : 350e-6);
-
-[X,T] = meshgrid(x,t);
-
-surf(X,T,p)
-%}