-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a43ae18
commit fa33a8e
Showing
4 changed files
with
272 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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%}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); |