function [x,H_out,S_out,L_out] = SMsolver2_function(A_in,x_in,user_grid) %SMsolver2_function % % Function version of the script SMsolver2 % % Solves for grounding line position for marine ice sheet with % grounding line flux given as per Schoof, 2007, Ice sheet % grounding line dynamics: steady states, stability and % hysteresis, JGR, 112, F03S28, doi:10.1029/2006JF000664. % % Input data for this program are % A_Glen = value of Glen's law parameter % x_in = initial guess for grounding line position % user_grid = grid points at which ice thickness, surface and base % elevation are to be computed, listed in ascending order as a row vector. This is optional, % default is the MISMIP mode 2 grid % % % Output from he program is a grounding line position x, grid point positions X_out (= user_grid, if specified), % ice thickness H_out, ice surface elevation S_out and base elevation L_out. For grid % points < x, ice is grounded, otherwise floating. % % Ensure that the remaining physical parameters are entered % correctly below under `Parameters as defined in Schoof 2007...'; % By specifying the experiment number (1,2,3) as expt_no and the experiment type (a,b) % as expt_type, the relevant parameter values are selected. Specify benchmark as A or B % to select which of the Schoof (2007) boundary layer models you wish to use. % % The depth to bed below sea level is defined in subroutine % SMcold_bedheight. DESPITE ITS NAME, this function computes % depth BELOW sea level, not height above, i.e. it returns b(x) % as in the MISMIP draft. SMcold_bedslope is the first derivative % of SMcold_bedheight, and must agree with SMcold_bedheight or % the Newton solver below may not converge; you will also get the % wrong surface elevation. % % As above, SMcold_bedheight uses the expteriment number expt_no to determine which bed % specification to use %----------------------------------------------------------------------- %Definition of global variables %----------------------------------------------------------------------- global m n r A C rho_g a theta global expt_no expt_type benchmark expt_no = 1; expt_type = 'a'; benchmark = 'A'; n = 3; %Glen's law exponent if expt_type == 'a' m = 1/3; %sliding exponent C = 7.624e6; %m = 1/3 value elseif expt_type == 'b' m = 1; C = 7.2082e+010; %m = 1 value else error('invalid experiment type') end r = 0.9; %ratio of ice to water density rho_g = 8820; %900 kg m^{-3} * 9.8 m s^{-2} A = A_in; %Glen's law parameter in SI units % NB Paterson (1994) does not use SI units! x = x_in; a = 0.3/(365*24*3600); if benchmark == 'A' theta = 1; %cold (theta = 1) elseif benchmark == 'B' theta = 0; %warm (theta = 0) boundary layer specifications, else error('incorrect benchmark model specification') end %models A and B respectively in Schoof 2007 %----------------------------------------------------------------------- %Newton iteration parameters %----------------------------------------------------------------------- delta_x = 10; %finite difference step size (metres) for gradient calculation tolf = 1e-4; %tolerance for finding zeros normf = tolf + eps; toldelta = 1e1; %Newton step size tolerance dx = toldelta + 1; %----------------------------------------------------------------------- %Newton iteration %----------------------------------------------------------------------- delta_x; while normf > tolf | abs(dx) > toldelta f = SMcold_function(x); normf = abs(f); grad = (SMcold_function(x+delta_x)-f)/delta_x; dx = -f/grad; x = x + dx; end %computes steady state grounding line position x based %on intial guess in line 35, using equations (20) and %(24) in Schoof 2007 %----------------------------------------------------------------------- %Calculate ice surface elevation S_Soln for grounded sheet %----------------------------------------------------------------------- if nargin < 3, user_grid = linspace(0,1.8e6,1500); end %user grid must be a ROW vector in metres grounded = user_grid(user_grid < x).'; x_grid = [x; grounded(length(grounded):-1:1)]; %specifies the grid points on which ice surface elevations are to be calculated %these are in reverse order, i.e. counting %backwards from the grounding line at x to the ice %divide at zero. FIRST POINT MUST BE GROUNDING LINE %POSITION x COMPUTED ABOVE, EVEN IF THIS IS NOT %INCLUDED IN YOUR COMPUTATIONAL GRID h_f = SMcold_bedheight(x)/r; %computes ice thickness at the grounding line as %initial condition options = odeset('AbsTol',1e-6,'RelTol',1e-6);%odeset('AbsTol',f/1e-3); [X_soln,H_soln] = ode45(@SMsurface,x_grid,[h_f],options); %computes ice THICKNESS H_soln at points with %position X_soln S_soln = H_soln - SMcold_bedheight(X_soln); %computes ice surface elevation by adding bed %elevation figure hold on plot(X_soln,-SMcold_bedheight(X_soln),'k') plot(X_soln,S_soln,'b') %H_soln is now rearranged and the point %corresponding to the grounding line location is expunged to input these data into your %computational grid: S_soln = S_soln(length(S_soln):-1:2); H_soln = H_soln(length(H_soln):-1:2); %----------------------------------------------------------------------- %Calculate ice thickness for shelf from van der Veen (1986) %----------------------------------------------------------------------- floating = user_grid(user_grid > x).'; q_0 = a*x; H_soln2 = h_f*(q_0 + a*(floating-x))./(q_0^(n+1) + h_f^(n+1)*((1-r)*rho_g/4)^n*A*((q_0 + a*(floating-x)).^(n+1) - q_0^(n+1))/a).^(1/(n+1)); plot([x; floating],(1-r)*[h_f; H_soln2],'b'); plot([x; floating],-r*[h_f; H_soln2],'b'); H_out = [H_soln;H_soln2]; S_out = [S_soln;(1-r)*H_soln2]; L_out = [-SMcold_bedheight(grounded);-r*H_soln2]; %----------------------------------------------------------------------- %%%%%%%%%%%%%%%%%%%%%%%%%% Subfunctions %%%%%%%%%%%%%%%%%%%%%%%%%%%% %----------------------------------------------------------------------- function z = SMcold_function(x) %Evaluates function whose zeros define x_g in `cold' steady marine sheet %problem global m n A C rho_g r a theta h_f = r^(-1)*SMcold_bedheight(x); b_x = SMcold_bedslope(x); s = a*x; z = theta*a + C*s.^(m+1)./(rho_g*h_f.^(m+2)) - theta*s.*b_x./h_f - A*(rho_g*(1-r)/4)^n*h_f.^(n+1); function z = SMcold_bedheight(x) %DEPTH OF BED BELOW SEA LEVEL, i.e. gives b(x) in Schoof 2007. %NOTE the sign convention, SMcold_bedheight is positive if the bed is below %sea level, negative if above sea level. global expt_no if expt_no == 1 || expt_no == 2 z = -720 +778.5*(x/7.5e5); elseif expt_no == 3 z = -(729 - 2184.8*(x/7.5e5).^2 + 1031.72*(x/7.5e5).^4 - 151.72*(x/7.5e5).^6); else error('Invalid experiment number') end function z = SMcold_bedslope(x) %FIRST DERIVATIVE OF DEPTH OF BED BELOW SEA LEVEL; must agree with %SMcold_bedheight. global expt_no if expt_no == 1 || expt_no == 2 z = 778.5/7.5e5; elseif expt_no == 3 z = -(-2184.8*2*x/7.5e5^2 + 1031.72*4*x.^3/7.5e5^4 - 151.72*6*x.^5/7.5e5^6); else error('Invalid experiment number') end function z = SMsurface(x,h) global n m epsilon a C rho_g b_x = SMcold_bedslope(x); s = a*x; z = b_x - (C/rho_g)*s.^m./h.^(m+1);