1 | function md=SetMarineIceSheetBC(md,varargin)
|
---|
2 | %SETICEMARINESHEETBC - Create the boundary conditions for diagnostic and thermal models for a Marine Ice Sheet with Ice Front
|
---|
3 | %
|
---|
4 | % Neumann BC are used on the ice front (an ARGUS contour around the ice front
|
---|
5 | % can be given in input, or it will be deduced as onfloatingice & onboundary)
|
---|
6 | % Dirichlet BC are used elsewhere for diagnostic
|
---|
7 | %
|
---|
8 | % Usage:
|
---|
9 | % md=SetMarineIceSheetBC(md,icefrontfile)
|
---|
10 | % md=SetMarineIceSheetBC(md)
|
---|
11 | %
|
---|
12 | % Example:
|
---|
13 | % md=SetMarineIceSheetBC(md,'Front.exp')
|
---|
14 | % md=SetMarineIceSheetBC(md)
|
---|
15 | %
|
---|
16 | % See also: SETICESHELFBC, SETMARINEICESHEETBC
|
---|
17 |
|
---|
18 | %node on Dirichlet (boundary and ~icefront)
|
---|
19 | if nargin==2,
|
---|
20 | %User provided Front.exp, use it
|
---|
21 | icefrontfile=varargin{1};
|
---|
22 | if ~exist(icefrontfile)
|
---|
23 | error(['SetMarineIceSheetBC error message: ice front file ' icefrontfile ' not found']);
|
---|
24 | end
|
---|
25 | nodeinsideicefront=ContourToMesh(md.mesh.elements,md.mesh.x,md.mesh.y,icefrontfile,'node',2);
|
---|
26 | vertexonicefront=double(md.mesh.vertexonboundary & nodeinsideicefront);
|
---|
27 | else
|
---|
28 | %Guess where the ice front is
|
---|
29 | vertexonfloatingice=zeros(md.mesh.numberofvertices,1);
|
---|
30 | vertexonfloatingice(md.mesh.elements(find(md.mask.elementonfloatingice),:))=1;
|
---|
31 | vertexonicefront=double(md.mesh.vertexonboundary & vertexonfloatingice);
|
---|
32 | end
|
---|
33 | pos=find(md.mesh.vertexonboundary & ~vertexonicefront);
|
---|
34 | if isempty(pos),
|
---|
35 | warning('SetMarineIceSheetBC warning: ice front all around the glacier, no dirichlet found. Dirichlet must be added manually')
|
---|
36 | end
|
---|
37 | md.diagnostic.spcvx=NaN*ones(md.mesh.numberofvertices,1);
|
---|
38 | md.diagnostic.spcvy=NaN*ones(md.mesh.numberofvertices,1);
|
---|
39 | md.diagnostic.spcvz=NaN*ones(md.mesh.numberofvertices,1);
|
---|
40 | md.diagnostic.spcvx(pos)=0;
|
---|
41 | md.diagnostic.spcvy(pos)=0;
|
---|
42 | md.diagnostic.spcvz(pos)=0;
|
---|
43 | md.diagnostic.referential=NaN*ones(md.mesh.numberofvertices,6);
|
---|
44 |
|
---|
45 | %Dirichlet Values
|
---|
46 | if (length(md.inversion.vx_obs)==md.mesh.numberofvertices & length(md.inversion.vy_obs)==md.mesh.numberofvertices)
|
---|
47 | disp(' boundary conditions for diagnostic model: spc set as observed velocities');
|
---|
48 | md.diagnostic.spcvx(pos)=md.inversion.vx_obs(pos);
|
---|
49 | md.diagnostic.spcvy(pos)=md.inversion.vy_obs(pos);
|
---|
50 | else
|
---|
51 | disp(' boundary conditions for diagnostic model: spc set as zero');
|
---|
52 | end
|
---|
53 |
|
---|
54 | md.hydrology.spcwatercolumn=zeros(md.mesh.numberofvertices,2);
|
---|
55 | pos=find(md.mesh.vertexonboundary);
|
---|
56 | md.hydrology.spcwatercolumn(pos,1)=1;
|
---|
57 |
|
---|
58 | %segment on Neumann (Ice Front)
|
---|
59 | pos=find(vertexonicefront(md.mesh.segments(:,1)) | vertexonicefront(md.mesh.segments(:,2)));
|
---|
60 | if (md.mesh.dimension==2)
|
---|
61 | pressureload=md.mesh.segments(pos,:);
|
---|
62 | elseif md.mesh.dimension==3
|
---|
63 | pressureload_layer1=[md.mesh.segments(pos,1:2) md.mesh.segments(pos,2)+md.mesh.numberofvertices2d md.mesh.segments(pos,1)+md.mesh.numberofvertices2d md.mesh.segments(pos,3)];
|
---|
64 | pressureload=[];
|
---|
65 | for i=1:md.mesh.numberoflayers-1,
|
---|
66 | pressureload=[pressureload ;pressureload_layer1(:,1:4)+(i-1)*md.mesh.numberofvertices2d pressureload_layer1(:,5)+(i-1)*md.mesh.numberofelements2d ];
|
---|
67 | end
|
---|
68 | end
|
---|
69 |
|
---|
70 | %Add water or air enum depending on the element
|
---|
71 | pressureload=[pressureload 1*md.mask.elementonfloatingice(pressureload(:,end))+ 0*md.mask.elementongroundedice(pressureload(:,end))];
|
---|
72 |
|
---|
73 | %plug onto model
|
---|
74 | md.diagnostic.icefront=pressureload;
|
---|
75 |
|
---|
76 |
|
---|
77 | %Create zeros basalforcings and surfaceforcings
|
---|
78 | if (isnan(md.surfaceforcings.precipitation) & (md.surfaceforcings.ispdd==1)),
|
---|
79 | md.surfaceforcings.precipitation=zeros(md.mesh.numberofvertices,1);
|
---|
80 | disp(' no surfaceforcings.precipitation specified: values set as zero');
|
---|
81 | end
|
---|
82 | if (isnan(md.surfaceforcings.mass_balance) & (md.surfaceforcings.ispdd==0)),
|
---|
83 | md.surfaceforcings.mass_balance=zeros(md.mesh.numberofvertices,1);
|
---|
84 | disp(' no surfaceforcings.mass_balance specified: values set as zero');
|
---|
85 | end
|
---|
86 | if isnan(md.basalforcings.melting_rate),
|
---|
87 | md.basalforcings.melting_rate=zeros(md.mesh.numberofvertices,1);
|
---|
88 | disp(' no basalforcings.melting_rate specified: values set as zero');
|
---|
89 | end
|
---|
90 | if isnan(md.balancethickness.thickening_rate),
|
---|
91 | md.balancethickness.thickening_rate=zeros(md.mesh.numberofvertices,1);
|
---|
92 | disp(' no balancethickness.thickening_rate specified: values set as zero');
|
---|
93 | end
|
---|
94 |
|
---|
95 | md.prognostic.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
|
---|
96 | md.balancethickness.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
|
---|
97 |
|
---|
98 | if (length(md.initialization.temperature)==md.mesh.numberofvertices),
|
---|
99 | md.thermal.spctemperature=NaN*ones(md.mesh.numberofvertices,1);
|
---|
100 | pos=find(md.mesh.vertexonsurface); md.thermal.spctemperature(pos)=md.initialization.temperature(pos); %impose observed temperature on surface
|
---|
101 | if (length(md.basalforcings.geothermalflux)~=md.mesh.numberofvertices),
|
---|
102 | md.basalforcings.geothermalflux=zeros(md.mesh.numberofvertices,1);
|
---|
103 | md.basalforcings.geothermalflux(find(md.mask.vertexongroundedice))=50*10^-3; %50mW/m2
|
---|
104 | end
|
---|
105 | else
|
---|
106 | disp(' no thermal boundary conditions created: no observed temperature found');
|
---|
107 | end
|
---|