[421] | 1 | function md=SetMarineIceSheetBC(md,varargin)
|
---|
[15771] | 2 | %SETICEMARINESHEETBC - Create the boundary conditions for stressbalance and thermal models for a Marine Ice Sheet with Ice Front
|
---|
[33] | 3 | %
|
---|
[421] | 4 | % Neumann BC are used on the ice front (an ARGUS contour around the ice front
|
---|
[9641] | 5 | % can be given in input, or it will be deduced as onfloatingice & onboundary)
|
---|
[15771] | 6 | % Dirichlet BC are used elsewhere for stressbalance
|
---|
[33] | 7 | %
|
---|
| 8 | % Usage:
|
---|
| 9 | % md=SetMarineIceSheetBC(md,icefrontfile)
|
---|
[421] | 10 | % md=SetMarineIceSheetBC(md)
|
---|
[33] | 11 | %
|
---|
| 12 | % Example:
|
---|
| 13 | % md=SetMarineIceSheetBC(md,'Front.exp')
|
---|
[421] | 14 | % md=SetMarineIceSheetBC(md)
|
---|
[33] | 15 | %
|
---|
| 16 | % See also: SETICESHELFBC, SETMARINEICESHEETBC
|
---|
| 17 |
|
---|
[8298] | 18 | %node on Dirichlet (boundary and ~icefront)
|
---|
[421] | 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
|
---|
[16269] | 25 | [path,name,ext]=fileparts(icefrontfile);
|
---|
| 26 | if strcmp(ext,'.shp'),
|
---|
| 27 | contours=shpread(icefrontfile);
|
---|
| 28 | elseif strcmp(ext,'.exp'),
|
---|
| 29 | contours=expread(icefrontfile);
|
---|
| 30 | end
|
---|
| 31 | incontour=ContourToMesh(md.mesh.elements,md.mesh.x,md.mesh.y,contours,'node',2);
|
---|
[15993] | 32 | vertexonicefront=double(md.mesh.vertexonboundary & incontour);
|
---|
[421] | 33 | else
|
---|
| 34 | %Guess where the ice front is
|
---|
[27956] | 35 | %pos=find(sum(md.mask.ocean_levelset(md.mesh.elements)<0.,2) >0.);
|
---|
| 36 | %vertexonfloatingice=zeros(md.mesh.numberofvertices,1);
|
---|
| 37 | %vertexonfloatingice(md.mesh.elements(pos,:))=1.;
|
---|
| 38 | %vertexonicefront=double(md.mesh.vertexonboundary & vertexonfloatingice);
|
---|
| 39 |
|
---|
| 40 | only_ocean_levelset=-double(md.mask.ocean_levelset<=0. & md.mask.ice_levelset>=0.);
|
---|
| 41 | only_ocean_levelset_sum=sum(only_ocean_levelset(md.mesh.elements)<0.,2);
|
---|
| 42 | pos=find(only_ocean_levelset_sum >0. & only_ocean_levelset_sum < 3.);
|
---|
| 43 | vertexonicefront=zeros(md.mesh.numberofvertices,1);
|
---|
| 44 | vertexonicefront(md.mesh.elements(pos,:))=1.;
|
---|
[33] | 45 | end
|
---|
[9714] | 46 | pos=find(md.mesh.vertexonboundary & ~vertexonicefront);
|
---|
[421] | 47 | if isempty(pos),
|
---|
[26352] | 48 | disp('Warning: SetMarineIceSheetBC.m: ice front all around the glacier, no dirichlet applied')
|
---|
[421] | 49 | end
|
---|
[15771] | 50 | md.stressbalance.spcvx=NaN*ones(md.mesh.numberofvertices,1);
|
---|
| 51 | md.stressbalance.spcvy=NaN*ones(md.mesh.numberofvertices,1);
|
---|
| 52 | md.stressbalance.spcvz=NaN*ones(md.mesh.numberofvertices,1);
|
---|
| 53 | md.stressbalance.referential=NaN*ones(md.mesh.numberofvertices,6);
|
---|
| 54 | md.stressbalance.loadingforce=0*ones(md.mesh.numberofvertices,3);
|
---|
[33] | 55 |
|
---|
[15795] | 56 | %Position of ice front
|
---|
[15946] | 57 | md.mask.ice_levelset(find(vertexonicefront))=0;
|
---|
[15795] | 58 |
|
---|
| 59 | %First find segments that are not completely on the front
|
---|
[17687] | 60 | if strcmp(elementtype(md.mesh),'Penta'),
|
---|
| 61 | numbernodesfront=4;
|
---|
| 62 | elseif strcmp(elementtype(md.mesh),'Tria'),
|
---|
[15795] | 63 | numbernodesfront=2;
|
---|
[17687] | 64 | else
|
---|
| 65 | error('mesh type not supported yet');
|
---|
[15795] | 66 | end
|
---|
[27956] | 67 | %segmentsfront=md.mask.ice_levelset(md.mesh.segments(:,1:numbernodesfront))==0;
|
---|
| 68 | %segments=find(sum(segmentsfront,2)~=numbernodesfront);
|
---|
[15795] | 69 | %Find all nodes for these segments and spc them
|
---|
[27956] | 70 | %pos=md.mesh.segments(segments,1:numbernodesfront);
|
---|
| 71 |
|
---|
| 72 | numbernodesfront=3;
|
---|
| 73 | elementsfront=md.mask.ice_levelset(md.mesh.elements(:,1:numbernodesfront))==0;
|
---|
| 74 | elements=find(sum(elementsfront,2)>0);
|
---|
| 75 | pos=md.mesh.elements(elements,1:numbernodesfront);
|
---|
| 76 |
|
---|
[15795] | 77 | md.stressbalance.spcvx(pos(:))=0;
|
---|
| 78 | md.stressbalance.spcvy(pos(:))=0;
|
---|
[17308] | 79 | md.stressbalance.spcvz(pos(:))=0; % FIXME probably shouldn't spc vertical velocity here
|
---|
[15795] | 80 |
|
---|
[33] | 81 | %Dirichlet Values
|
---|
[9725] | 82 | if (length(md.inversion.vx_obs)==md.mesh.numberofvertices & length(md.inversion.vy_obs)==md.mesh.numberofvertices)
|
---|
[15771] | 83 | disp(' boundary conditions for stressbalance model: spc set as observed velocities');
|
---|
| 84 | md.stressbalance.spcvx(pos)=md.inversion.vx_obs(pos);
|
---|
| 85 | md.stressbalance.spcvy(pos)=md.inversion.vy_obs(pos);
|
---|
[33] | 86 | else
|
---|
[15771] | 87 | disp(' boundary conditions for stressbalance model: spc set as zero');
|
---|
[33] | 88 | end
|
---|
| 89 |
|
---|
[9725] | 90 | md.hydrology.spcwatercolumn=zeros(md.mesh.numberofvertices,2);
|
---|
[13470] | 91 | pos=find(md.mesh.vertexonboundary);
|
---|
[9617] | 92 | md.hydrology.spcwatercolumn(pos,1)=1;
|
---|
[7967] | 93 |
|
---|
[17071] | 94 | %Initialize surface and basal forcings
|
---|
[19527] | 95 | md.smb = initialize(md.smb,md);
|
---|
[17071] | 96 | md.basalforcings = initialize(md.basalforcings,md);
|
---|
| 97 |
|
---|
| 98 | %Deal with other boundary conditions
|
---|
[9646] | 99 | if isnan(md.balancethickness.thickening_rate),
|
---|
[9725] | 100 | md.balancethickness.thickening_rate=zeros(md.mesh.numberofvertices,1);
|
---|
[9646] | 101 | disp(' no balancethickness.thickening_rate specified: values set as zero');
|
---|
[3582] | 102 | end
|
---|
[33] | 103 |
|
---|
[15767] | 104 | md.masstransport.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
|
---|
[9725] | 105 | md.balancethickness.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
|
---|
[16187] | 106 | md.damage.spcdamage=NaN*ones(md.mesh.numberofvertices,1);
|
---|
[33] | 107 |
|
---|
[9725] | 108 | if (length(md.initialization.temperature)==md.mesh.numberofvertices),
|
---|
| 109 | md.thermal.spctemperature=NaN*ones(md.mesh.numberofvertices,1);
|
---|
[16318] | 110 | if isprop(md.mesh,'vertexonsurface'),
|
---|
| 111 | pos=find(md.mesh.vertexonsurface);
|
---|
| 112 | md.thermal.spctemperature(pos)=md.initialization.temperature(pos); %impose observed temperature on surface
|
---|
| 113 | end
|
---|
[9725] | 114 | if (length(md.basalforcings.geothermalflux)~=md.mesh.numberofvertices),
|
---|
| 115 | md.basalforcings.geothermalflux=zeros(md.mesh.numberofvertices,1);
|
---|
[24861] | 116 | md.basalforcings.geothermalflux(find(md.mask.ocean_levelset>0.))=50.*10.^-3; %50mW/m2
|
---|
[33] | 117 | end
|
---|
| 118 | else
|
---|
| 119 | disp(' no thermal boundary conditions created: no observed temperature found');
|
---|
| 120 | end
|
---|