Skip to content

Commit

Permalink
ADD:adding Helheim SHAKTI tutorials
Browse files Browse the repository at this point in the history
  • Loading branch information
aleahsommers committed Jan 6, 2025
1 parent a43ae18 commit fa33a8e
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 0 deletions.
94 changes: 94 additions & 0 deletions examples/Helheim/Greenland.par
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
%required Data
accpath = ['/home/ModelData/Greenland/RACMO2Accumulation/SMBGreenland/smb_1961-1990.mat'];
velpath = ['/home/ModelData/Greenland/VelMouginot/RignotGreenland2012Vel.mat'];

%WARNING: we do have a levelset here, so we must set it to one even for stressbalances...
md.transient.ismovingfront=1;

disp(' Interpolating mask');
mask = int8(interpBedmachineGreenland(md.mesh.x,md.mesh.y,'mask'));
md.mask.ice_levelset= -1*ones(md.mesh.numberofvertices,1);
pos = find(mask<1);
md.mask.ice_levelset(pos)=1;

disp(' reading MC bed (assumes no floating ice)');
md.geometry.bed = interpBedmachineGreenland(md.mesh.x,md.mesh.y,'bed');
md.geometry.base = md.geometry.bed;

disp(' reading Howat surface');
md.geometry.surface=interpBedmachineGreenland(md.mesh.x,md.mesh.y,'surface');
pos = find(md.mask.ice_levelset>0);
md.geometry.surface(pos) = md.geometry.base(pos)+10; %Minimum thickness

md.geometry.thickness = md.geometry.surface - md.geometry.bed;
pos=find(md.geometry.thickness<=10);
md.geometry.surface(pos) = md.geometry.base(pos)+10; %Minimum thickness
md.geometry.thickness = md.geometry.surface - md.geometry.bed;

md.masstransport.min_thickness = 10;

disp(' Adjusting ice mask');
%Tricky part here: we want to offset the mask by one element so that we don't end up with a cliff at the transition
pos = find(max(md.mask.ice_levelset(md.mesh.elements),[],2)>0);
md.mask.ice_levelset(md.mesh.elements(pos,:)) = 1;
% For the region where surface is NaN, set thickness to small value (consistency requires >0)
pos=find((md.mask.ice_levelset<0).*(md.geometry.surface<0));
md.mask.ice_levelset(pos)=1;
pos=find((md.mask.ice_levelset<0).*(isnan(md.geometry.surface)));
md.mask.ice_levelset(pos)=1;

disp(' -- reconstruct thickness');
md.geometry.thickness=md.geometry.surface-md.geometry.base;

disp(' reading velocities ');
[md.inversion.vx_obs md.inversion.vy_obs]=interpJoughinCompositeGreenland(md.mesh.x,md.mesh.y);
pos=find(isnan(md.inversion.vx_obs) | isnan(md.inversion.vy_obs));
md.inversion.vx_obs(pos)=0;
md.inversion.vy_obs(pos)=0;
md.inversion.vel_obs = sqrt(md.inversion.vx_obs.^2+md.inversion.vy_obs.^2);
md.initialization.vx = md.inversion.vx_obs;
md.initialization.vy = md.inversion.vy_obs;
md.initialization.vz = zeros(md.mesh.numberofvertices,1);
md.initialization.vel = md.inversion.vel_obs;

%drag md.drag or stress
md.friction.coefficient = 20*ones(md.mesh.numberofvertices,1); %q = 1.
md.friction.p = ones(md.mesh.numberofelements,1);
md.friction.q = ones(md.mesh.numberofelements,1);

%No friction on PURELY ocean element
pos_e = find(min(md.mask.ice_levelset(md.mesh.elements),[],2)<0);
flags=ones(md.mesh.numberofvertices,1);
flags(md.mesh.elements(pos_e,:))=0;
md.friction.coefficient(find(flags))=0;

%flow law
disp(' Creating flow law parameters (assume ice is at 0°C for now)');
md.materials.rheology_n = 3*ones(md.mesh.numberofelements,1);
md.materials.rheology_B = cuffey(273.15 - 10)*ones(md.mesh.numberofvertices,1);

md.basalforcings.groundedice_melting_rate = zeros(md.mesh.numberofvertices,1);
md.basalforcings.floatingice_melting_rate = zeros(md.mesh.numberofvertices,1);

disp(' Geothermal flux from Shapiro et al.');
md.basalforcings.geothermalflux=interpSeaRISE(md.mesh.x,md.mesh.y,'bheatflx');

disp(' Setting up thermal model');
md.initialization.temperature=min(0,interpSeaRISE(md.mesh.x,md.mesh.y,'surftemp'))+273.15;
md.initialization.waterfraction=zeros(md.mesh.numberofvertices,1);
md.initialization.watercolumn=zeros(md.mesh.numberofvertices,1);
md.thermal.spctemperature=md.initialization.temperature;
md.thermal.isenthalpy=1;
md.thermal.isdynamicbasalspc=1;

%Deal with boundary conditions:
disp(' Set Boundary conditions');
md.stressbalance.spcvx=NaN*ones(md.mesh.numberofvertices,1);
md.stressbalance.spcvy=NaN*ones(md.mesh.numberofvertices,1);
md.stressbalance.spcvz=NaN*ones(md.mesh.numberofvertices,1);
md.stressbalance.referential=NaN*ones(md.mesh.numberofvertices,6);
md.stressbalance.loadingforce=0*ones(md.mesh.numberofvertices,3);
pos=find((md.mask.ice_levelset<0).*(md.mesh.vertexonboundary));
md.stressbalance.spcvx(pos)=md.initialization.vx(pos);
md.stressbalance.spcvy(pos)=md.initialization.vy(pos);
md.stressbalance.spcvz(pos)=0;
20 changes: 20 additions & 0 deletions examples/Helheim/Helheim_tut.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Name:./Exp/Domain_TEMP.exp
## Icon:0
# Points Count Value
14 1.000000
# X pos Y pos
251808.9599315871 -2519299.1448521991
232017.0235357451 -2526258.4544728124
232815.0354161858 -2578466.8389138547
256982.9213724715 -2601667.2788287275
302263.2150846492 -2594953.0557058132
309967.1091796352 -2586747.6107035289
315046.5997917140 -2581507.9891960463
313861.3853155622 -2571621.9108800408
310644.3745945790 -2567964.0619031191
309120.5274109554 -2557188.2365386733
306496.1239280481 -2552245.1973806708
305818.8585131043 -2537910.3838224630
285125.3861979210 -2517350.5381584275
251808.9599315871 -2519299.1448521991

86 changes: 86 additions & 0 deletions examples/Helheim/runme.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
% runme script to perform a stress balance inversion for basal friction
% on Helheim Glacier (SE Greenland)

% Step 1: Set up model domain outline and mesh
% Step 2: Set parameters
% Step 3: Inversion for basal friction

% Note that Steps 1 and 2 require previously downloading data for velocities,
% surface elevation and bed elevation.

steps = [1:3]; % Choose which steps to run here

cluster=generic('name',oshostname(),'np',8);

org=organizer('repository',['./Models'],'prefix',['Model_Helheim_'],'steps',steps); clear steps;

if perform(org,'Mesh'),% {{{

% Initialize uniform mesh
md=triangle(model,['Helheim_tut.exp'],500);

[velx vely]=interpJoughinCompositeGreenland(md.mesh.x,md.mesh.y);
vel = sqrt(velx.^2+vely.^2);

% Refine mesh based on surface velocities
md=bamg(md,'hmin',100,'hmax',1500,'field',vel,'err',5);
[md.mesh.lat,md.mesh.long] = xy2ll(md.mesh.x,md.mesh.y,+1,45,70);
md.mesh.epsg=3413;

savemodel(org,md);
end %}}}
if perform(org,'Param'),% {{{

md=loadmodel(org,'Mesh');
md=setflowequation(md,'SSA','all'); % Set flow law to SSA

md=setmask(md,'','');
md=parameterize(md,'Greenland.par');
md.miscellaneous.name = 'Helheim';

savemodel(org,md);
end%}}}
if perform(org,'Inversion_drag'),% {{{

md=loadmodel(org,'Param');

%Control general
md.inversion=m1qn3inversion(md.inversion);
md.inversion.iscontrol=1;
md.verbose=verbose('solution',false,'control',true);
md.transient.amr_frequency = 0;

%Cost functions
md.inversion.cost_functions=[101 103 501];
md.inversion.cost_functions_coefficients=zeros(md.mesh.numberofvertices,numel(md.inversion.cost_functions));
md.inversion.cost_functions_coefficients(:,1)=5000;
md.inversion.cost_functions_coefficients(:,2)=10;
md.inversion.cost_functions_coefficients(:,3)=2*50^-3;
pos=find(md.mask.ice_levelset>0);
md.inversion.cost_functions_coefficients(pos,1:2)=0;

%Controls
md.inversion.control_parameters={'FrictionCoefficient'};
md.inversion.maxsteps=100;
md.inversion.maxiter =100;
md.inversion.min_parameters=0.05*ones(md.mesh.numberofvertices,1);
md.inversion.max_parameters=4000*ones(md.mesh.numberofvertices,1);
md.inversion.control_scaling_factors=1;

%Additional parameters
md.stressbalance.restol=0.01;
md.stressbalance.reltol=0.1;
md.stressbalance.abstol=NaN;

%Go solve
md.cluster=cluster;

md=solve(md,'sb');

%Put results back into the model
md.friction.coefficient=md.results.StressbalanceSolution.FrictionCoefficient;
md.initialization.vx=md.results.StressbalanceSolution.Vx;
md.initialization.vy=md.results.StressbalanceSolution.Vy;

savemodel(org,md);
end%}}}
72 changes: 72 additions & 0 deletions examples/HelheimSHAKTI/runme.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
% Coupled SHAKTI-ISSM simulation of Helheim, starting from previous inversion
clear all;close all

% Load Helheim Glacier model
load Models/Model_Helheim_Inversion_drag.mat

% Turn off inversion
md.inversion.iscontrol=0;

% HYDROLOGY SPECIFIC PARAMETERIZATION:
% Change hydrology class to SHAKTI model
md.hydrology=hydrologyshakti();

% Define distributed englacial input to the subglacial system (m/yr)
md.hydrology.englacial_input = .0*ones(md.mesh.numberofvertices,1);

% Define initial water head such that water pressure is 80% of ice overburden pressure
md.hydrology.head = 0.8*md.materials.rho_ice/md.materials.rho_freshwater*md.geometry.thickness + md.geometry.base;

% Initial subglacial gap height of 0.01m everywhere
md.hydrology.gap_height = 0.01*ones(md.mesh.numberofelements,1);

% Typical bed bump bump spacing -- must be non-zero
md.hydrology.bump_spacing = 1.0*ones(md.mesh.numberofelements,1);

% Typical bed bump height -- set to zero to turn off opening by sliding
md.hydrology.bump_height = 0.0*ones(md.mesh.numberofelements,1);

% Initial Reynolds number (start at Re=1000 everywhere)
md.hydrology.reynolds= 1000*ones(md.mesh.numberofelements,1);

% Boundary conditions
md.hydrology.spchead = NaN(md.mesh.numberofvertices,1);

% Set head=0 for thin ice, everywhere <=10m ice thickness
pos=find(md.geometry.thickness==10);
md.hydrology.spchead(pos)=0;

% Set pressure in fjord equal to hydrostatic pressure of fjord water
pos=find(md.mask.ice_levelset>0);
md.hydrology.spchead(pos)=0;

% % Deal with terminus b.c. in SHAKTI
% terminus=ContourToNodes(md.mesh.x,md.mesh.y,'Exp/terminus_big.exp',1);
% pos=find(terminus & md.mask.ice_levelset<=0);
% md.hydrology.spchead(pos)=0;

md.hydrology.moulin_input = zeros(md.mesh.numberofvertices,1); % No moulin inputs
md.hydrology.neumannflux=zeros(md.mesh.numberofelements,1); % No-flux b.c. on domain boundary

% Coupling and friction
md.transient=deactivateall(md.transient);
md.transient.isstressbalance=1; % 1=Solve for ice velocity, 0=turn off stress balance
md.transient.ishydrology=1;

% Friction
Neff = md.materials.rho_ice*md.constants.g*md.geometry.thickness-md.materials.rho_water*md.constants.g*(md.hydrology.head - md.geometry.base); %Initial effective pressure
md.friction.effective_pressure=Neff;
md.friction.coupling = 4; % Change this to couple (4) /uncouple with prescribed N (3) ***

% Specify that you want to run the model on your current computer
% Change the number of processors according to your machine
md.cluster=generic('np',8);

% Define the time stepping scheme
md.timestepping.time_step=1*3600/md.constants.yts; % Time step (in years)
md.timestepping.final_time=30/365; % Final time (in years)
md.settings.output_frequency=24; % To save model output less frequently than every time step

md.verbose.solution=1;

md=solve(md,'Transient');

0 comments on commit fa33a8e

Please sign in to comment.