Subido por c217escr

matlab codes

Anuncio
function bergschrund()
% solve ode for steady glacier thickness with ice flux q = x*(1-x/2)
%% Parameters
n = 3;
mu = 0.1;
%% Numerical solutions of rescaled boundary layer problems
opts = odeset('reltol',1e-6);
xinf = 10; xeps = 1e-4; Heps =
2^(n/(2*n+2))*(n+2)^(1/(2*n+2))*xeps^(1/2); % analytical approximation
of singular behaviour
[xh2,Hh2] = ode45(@(x,H) ((n+2)*x.*H.^(-(n+2))).^(1/n)-1 , [xeps xinf]
, Heps , opts);
xinf = 10; Hinf = ((n+2)*xinf).^(1/(n+2)); % analytical approximation
of far field behaviour
[xh1,Hh1] = ode45(@(x,H) 1-((n+2)*x.*H.^(-(n+2))).^(1/n) , [xinf 0] ,
Hinf , opts);
Hhstar = Hh1(end),
%% Numerical solution
opts = odeset('reltol',1e-6);
xeps = 1e-4; Heps = mu^(n/(2*n+2))*2^(n/(2*n+2))*(n+2)^(1/(2*n+2))*xeps^(1/2); % analytical
approximation of singular behaviour at x = 2
[xn,Hn] = ode45(@ode_fun,[2-xeps 0],Heps,opts);
function dHdx = ode_fun(x,H)
dHdx = (1-((n+2)*x.*(1-x/2).*H.^(-(n+2))).^(1/n))/mu;
end
%% Outer solution
x = linspace(0,2,100);
H = ((n+2)*x.*(1-x/2)).^(1/(n+2));
%%
x1
H1
x2
H2
Inner solutions
= mu^((n+2)/(n+1))*xh1;
= mu^(1/(n+1))*Hh1;
= 2-mu^((n+2)/(n+1))*xh2;
= mu^(1/(n+1))*Hh2;
%% Plot solutions
figure(1); clf;
set(gcf,'Paperpositionmode','auto','units','centimeters','position',[2
4 12 8]);
set(gcf,'DefaultAxesFontSize',12,'DefaultTextFontSize',12);
plot(xn,Hn,'b-','linewidth',2);
hold on;
plot(x,H,'k--',x1,H1,'r--',x2,H2,'r--');
xlabel('$x$','interpreter','latex');
ylabel('$H$','interpreter','latex');
xlim([0 2]);
% %% Save figure
% print(gcf,'-depsc2',mfilename,'-loose');
%% Plot other numerical solutions of boundary layer at x = 0
figure(2); clf;
set(gcf,'Paperpositionmode','auto','units','centimeters','position',[2
4 12 8]);
set(gcf,'DefaultAxesFontSize',12,'DefaultTextFontSize',12);
xinf = 10;
x = linspace(0,xinf,100);
plot(x,((n+2)*x).^(1/(n+2)),'k--','linewidth',2); % far-field
behaviour
hold on;
xinf = 10; H0s = [0.9:.02:1.1]*Hhstar; % guesses at initial value
for H0 = H0s
[xh1,Hh1] = ode45(@(x,H) 1-((n+2)*x.*H.^(-(n+2))).^(1/n) , [0
xinf] , H0 );
plot(xh1,Hh1,'-');
end
xlabel('$\hat{x}$','interpreter','latex');
ylabel('$\hat{H}$','interpreter','latex');
% %% Save figure
% print(gcf,'-depsc2',[mfilename,'2'],'-loose');
end
function carbon_cycles()
% solves equations for albedo and CO2 partial pressure
%
da/dt = B(T) - a
%
dp/dt = alpha*(1-w*p^mu*e^T)
%
T = T(a,p)
% plots trajectories on phase plane
%
% IJH 28 Sept 2016
%% Dimensionless parameters
ap = 0.58;
am = 0.11;
c1 = 0.2;
c2 = 0.6;
mu = 0.3;
q = 1.37;
lambda = 0.25;
nu = 0.18;
alpha = .01; % 1.05 / .01
w = 1; % 1 / .15
%% Scaling parameters (for plotting dimesional quantity)
sc.p = 36; % [Pa]
sc.p = 1; % to plot as dimensionless
%% Functions
B = @(theta) ap-(ap-am)/2*(1+tanh(c1+c2*theta));
Theta = @(a,p) q/nu*(1-a)-1/nu+lambda*p;
dadt = @(a,p) B(Theta(a,p)) - a;
dpdt = @(a,p) alpha*(1-w*p.^mu.*exp(Theta(a,p)));
dydt = @(t,y) [ dadt(y(1),y(2)) ; dpdt(y(1),y(2)) ]; % y = [a,p]
%% Nullclines
a = linspace(am,ap,100+2); a = a(2:end-1);
p = NaN*a;
for i = 1:length(a)
p(i) = fzero(@(x) dadt(a(i),x),[-1e3 1e3]);
each a along a nullcline
end
a1 = a; p1 = p;
p = NaN*a;
for i = 1:length(a)
p(i) = fzero(@(x) dpdt(a(i),x),[0 1e3]);
each a along p nullcline
end
a2 = a; p2 = p;
% root-finding for
% root-finding for
%% Plot phase plane with nullclines and setup axes for solutions
figure(1); clf; width = 2; fontsize = 14;
set(gcf,'DefaultAxesFontSize',fontsize,'DefaultTextFontSize',fontsize)
;
%
set(gcf,'units','centimeters','Paperpositionmode','auto','position',[2
2 20 10]);
ax(1) = axes('position',[0.1 0.2 0.35 0.75]);
plot(sc.p*p1,a1,'k-',sc.p*p2,a2,'b-','linewidth',width);
%
nullclines
xlabel('$p / [p]$','interpreter','latex');
ylabel('$a$','interpreter','latex');
ylim([am,ap]);
xlim([0 2*sc.p]);
hold on;
ax(2) = axes('position',[0.6 0.6 0.35 0.35]);
hold on;
box on;
set(gca,'XTickLabel',{});
ylabel('$a$','interpreter','latex');
ax(3) = axes('position',[0.6 0.2 0.35 0.35]);
hold on;
box on;
xlabel('$t / [t]$','interpreter','latex');
ylabel('$p / [p]$','interpreter','latex');
%% Solve trajectories and add to figures
n_trajectories = 1;
length_trajectory = 10/alpha;
for n = 1:n_trajectories
p0 = 2*rand; a0 = am+(ap-am)*rand;
%
random starting point
%
[p0,a0] = ginput(1); p0 = p0/sc.p;
%
graphical input for trajectory starting point (click on phase plane)
opts = odeset('reltol',1e-6);
[t,y] = ode45(dydt,[0 length_trajectory],[a0,p0],opts);
% use
ode45 to solve equations
a = y(:,1); p = y(:,2);
axes(ax(1));
plot(sc.p*p,a,'r-',sc.p*p(1),a(1),'ro','linewidth',width);
axes(ax(2));
plot(t,a,'r-','linewidth',width);
axes(ax(3));
plot(t,sc.p*p,'r-','linewidth',width);
end
% %% Save figure
% axes(ax(1)); text(0.95,0.95,['$\alpha =
$',num2str(alpha)],'units','normalized','horizontalalignment','right',
'verticalalignment','top','interpreter','latex');
% print(gcf,'-depsc2',[mfilename,'_alpha',num2str(alpha),'.eps'],'loose');
end
% greenhouse factor gamma for varying tau_s when T = T_s
(tau/tau_s)^(R/M_a/c_p)
% IJH 22 Sept 2018
clear;
%% Parameters
M_a = 29e-3; %kg/mol
R = 8.3; %J/K/mol
g = 9.8; %m/s^2
c_p = 10^3; %J/kg/K
%% Calculate gamma(tau_s)
z = linspace(0,1,101); % pts to discretise integral
tau_ss = linspace(0,10,101); % values of tau_s
gammas = NaN*tau_ss;
for j = 1:length(tau_ss)
tau_s = tau_ss(j);
gammas(j) = exp(-2*tau_s) +
tau_s*trapz(z,2*z.^(4*R/M_a/c_p).*exp(-2*tau_s*z)); % calculate
integral expression for gamma using trapezium rule
end
%% Plot gamma(tau_s)
figure(1); clf;
set(gcf,'Paperpositionmode','auto','units','centimeters','position',[2
4 12 8]);
set(gcf,'DefaultAxesFontSize',12,'DefaultTextFontSize',12);
plot(tau_ss,gammas,'b-','linewidth',2);
ylim([0 1]);
hold on;
plot(tau_ss,1-2*tau_ss*4*R/(4*R+M_a*c_p),'r--'); % small tau_s
approx
plot(tau_ss,(2*tau_ss).^(-4*R/M_a/c_p).*gamma(1+4*R/M_a/c_p),'r-'); % large tau_s approx
xlabel('Optical thickness $\tau_s$','interpreter','latex');
ylabel('Greenhouse factor $\gamma$','interpreter','latex');
%% Save figure
% print(gcf,'-depsc2',mfilename,'-loose');
% mountain glacier model
% IJH 18 October 2020
clear;
set(0,'DefaultTextInterpreter','latex');
set(0,'DefaultTextFontSize',12);
set(0,'DefaultAxesFontSize',12);
fn = mfilename;
% dimensionless parameters
pp.n = 3; % flow-law exponent
pp.a_fun = @(x) 1-x; % net accumulation funtion
pp.dt = 1e-2; % timestep
% steady state
x_st = linspace(0,2,101)';
H_st = ((pp.n+2)*x_st.*(1-x_st/2)).^(1/(pp.n+2));
% initial condition
t = 0;
l = 1;
% sigma = l*10.^(linspace(-6,0,101))'; % exponential spacing
n = 400; dx0 = 1e-7; r = fzero(@(r) 1/dx0-(r.^(n+1)-1)/(r-1),1.1); sigma =
l*[cumsum(dx0*r.^(0:n)')]; % geometric spacing
% sigma = [0.1*sigma(1:end-1); linspace(0.1,1,201)']; % geometric spacing +
constant spacing
x = sigma;
H = max(0,(pp.n+2)*x.*(l/2-x/2)).^(1/(pp.n+2));
x2 = linspace(-4,0,401)'; % ghost characteristics in x<0
H2 = 0*x2.^0;
x = [x2; x];
H = [H2; H];
s = zeros(size(x));
% solve characteristic equations
ts = t;
xs = x;
Hs = H;
ss = s;
i1 = 1:length(x); % indices of characeteristics
i2 = []; % indices of shocks
while t+pp.dt<3
i2
i3
i4
i1
=
=
=
=
find(s); % indices of shocks
find(isnan(x)); % indices of terminated characteristics
find(x<0); % indices of 'ghost' characteristics
setdiff(1:length(x),union(i2,[i3;i4])); % indices of characeteristics
a = pp.a_fun(x).*(x>=0); % accumulation rate
H(i1) = H(i1) + pp.dt*a(i1); % advance H along characteristics
H(i2) = H(i2) + pp.dt*a(i2); % advance H along shock
H(H<=0) = 0; % cap H = 0
x(i1) = x(i1) + pp.dt*H(i1).^(pp.n+1); % advance characteristics
x(i2) = x(i2) + pp.dt*(H(i2).^(pp.n+1)-H(s(i2)).^(pp.n+1))/(pp.n+2); %
advance shocks
x(i4) = min(x(i4)+pp.dt*1,0); % advance 'ghost' charatacteristics at speed
1 in x<0
t = t + pp.dt; % advance time
ii = union(i1,i2); % indices of characteristics and shocks
tmps = find(x(ii(1:end-1))>x(ii(2:end))); % locate intersections
% label downstream characteristics of shocks
if ~isempty(tmps)
for tmp = flip(tmps')
if s(ii(tmp+1))>0
s(ii(tmp)) = s(ii(tmp+1)); % if crashed into a shock, take
over that shock
else
s(ii(tmp)) = ii(tmp+1); % if crashed into a characteristic,
that becomes downstream characteristic
end
x(ii(tmp+1)) = NaN; % terminated characteristics
s(ii(tmp+1)) = 0;
end
end
ts
xs
Hs
ss
=
=
=
=
[ts
[xs
[Hs
[ss
end
% blank out
xs(xs<=0) =
xs(Hs<=0) =
Hs(Hs<=0) =
ss(ss<=0) =
t];
x];
H];
s];
various entries
NaN;
NaN;
NaN;
NaN;
% plot solutions
figure(1); clf;
set(gcf,'Paperpositionmode','auto','Units','centimeters','Position',[2 4 20
8]);
width = 1;
ax(1) = subplot(1,2,1);
xpts = 1:10:size(xs,1);
plot(xs(xpts,:)',ts(:)','k-','linewidth',width); % characteristics curves
hold on; plot(xs'.*ss'.^0,ts(:)','r.'); % shocks
xlabel('$x$')
ylabel('$t$');
xlim([0 3]);
box off;
ax(2) = subplot(1,2,2);
xpts = 1:10:size(xs,1);
plot3(xs(xpts,:)',ts(:)',0*Hs(xpts,:)','-','color',0.8*[1 1
1],'linewidth',width); % characteristics curves
hold on; plot3(xs'.*ss'.^0,ts(:)',0*Hs','r.'); % shocks
tpts = 1:20:size(ts,2);
hold on; plot3(xs(:,tpts),ones(length(x),1)*ts(tpts),Hs(:,tpts),'b','linewidth',width); % solution through time
xlabel('$x$')
ylabel('$t$');
zlabel('$H$');
xlim([0 3]);
ylim([0 3]);
ax(2).Position = ax(2).Position + [0 0.05 0 0];
% axes(ax(2)); view(10,40); print(gcf,'-depsc2',[fn]);
% axes(ax(2)); view(10,40); print(gcf,'-depsc2',[fn,'_fig1']); % l = 3;
% axes(ax(2)); view(10,40); print(gcf,'-depsc2',[fn,'_fig2']); % l = 1;
function sea_ice()
% solves sea ice model
%
dH/dt = - Fo - Q/(1+H) Q<=0
%
- Fo - Q
Q>0
%
for H>=0, OR H = 0
% uses a single ODE for both cases H>=0 and H<0. Numerical errors
% causes H to go slightly below 0; dHdt is then set to zero until it
% becomes positive allowing ice to start to grow again
%% Parameters
Fo = 0;
Q0 = 0;
omega = 2*pi*.1;
Q = @(t) Q0 + cos(omega*t);
%% Solve ODE
opts = odeset('reltol',1e-8);
[t,H] = ode45(@dHdt_fun,[0 2*2*pi/omega],0,opts);
% ODE
function dHdt = dHdt_fun(t,H)
dHdt = ( -Fo-Q(t)./(1+H) ).*( Q(t)<=0 ).*( H>=0 ) + ...
( -Fo-Q(t) ).*( Q(t)>0 ).*( H>=0 ) + ...
max(0,-Fo-Q(t)./(1+H)).*( H<0 );
end
%% Plot solution
figure(1); clf; width = 2; fontsize = 14;
set(gcf,'DefaultAxesFontSize',fontsize,'DefaultTextFontSize',fontsize)
;
set(gcf,'units','centimeters','Paperpositionmode','auto','position',[2
2 20 10]);
plot(omega/2/pi*t,H,'linewidth',width);
%
hold on; plot(omega/2/pi*t,dHdt_fun(t,H)); % derivative
hold on; plot(omega/2/pi*t,max(0,-1-Q(t)/Fo),'r--'); % quasisteady approximation (small omega)
xlabel('$\omega t / 2\pi$','interpreter','latex');
ylabel('$H / [H]$','interpreter','latex');
% %% Save figure
% text(0.02,0.95,['$\omega/2\pi =
$',num2str(omega/2/pi)],'interpreter','latex','units','normalized','ho
rizontalalignment','left','verticalalignment','top');
% print(gcf,'depsc2',[mfilename,'_omega',num2str(omega/2/pi),'.eps'],'-loose');
end
Descargar