1 | import os
|
---|
2 | import numpy as np
|
---|
3 | from ContourToMesh import ContourToMesh
|
---|
4 | import MatlabFuncs as m
|
---|
5 |
|
---|
6 | def SetIceShelfBC(md,icefrontfile=''):
|
---|
7 | """
|
---|
8 | SETICESHELFBC - Create the boundary conditions for stressbalance and thermal models for a Ice Shelf with Ice Front
|
---|
9 |
|
---|
10 | Neumann BC are used on the ice front (an ARGUS contour around the ice front
|
---|
11 | must be given in input)
|
---|
12 | Dirichlet BC are used elsewhere for stressbalance
|
---|
13 |
|
---|
14 | Usage:
|
---|
15 | md=SetIceShelfBC(md,varargin)
|
---|
16 |
|
---|
17 | Example:
|
---|
18 | md=SetIceShelfBC(md);
|
---|
19 | md=SetIceShelfBC(md,'Front.exp');
|
---|
20 |
|
---|
21 | See also: SETICESHEETBC, SETMARINEICESHEETBC
|
---|
22 | """
|
---|
23 |
|
---|
24 | #node on Dirichlet (boundary and ~icefront)
|
---|
25 | if icefrontfile:
|
---|
26 | if not os.path.exists(icefrontfile):
|
---|
27 | raise IOError("SetIceShelfBC error message: ice front file '%s' not found." % icefrontfile)
|
---|
28 | nodeinsideicefront=ContourToMesh(md.mesh.elements,md.mesh.x,md.mesh.y,icefrontfile,'node',2)
|
---|
29 | nodeonicefront=np.logical_and(md.mesh.vertexonboundary,nodeinsideicefront.reshape(-1))
|
---|
30 | else:
|
---|
31 | nodeonicefront=np.zeros((md.mesh.numberofvertices),bool)
|
---|
32 |
|
---|
33 | # pos=find(md.mesh.vertexonboundary & ~nodeonicefront);
|
---|
34 | pos=np.nonzero(np.logical_and(md.mesh.vertexonboundary,np.logical_not(nodeonicefront)))[0]
|
---|
35 | md.stressbalance.spcvx=float('nan')*np.ones(md.mesh.numberofvertices)
|
---|
36 | md.stressbalance.spcvy=float('nan')*np.ones(md.mesh.numberofvertices)
|
---|
37 | md.stressbalance.spcvz=float('nan')*np.ones(md.mesh.numberofvertices)
|
---|
38 | md.stressbalance.referential=float('nan')*np.ones((md.mesh.numberofvertices,6))
|
---|
39 | md.stressbalance.loadingforce=0*np.ones((md.mesh.numberofvertices,3))
|
---|
40 |
|
---|
41 | #Icefront position
|
---|
42 | pos=np.nonzero(nodeonicefront)[0]
|
---|
43 | md.mask.ice_levelset[pos]=0
|
---|
44 |
|
---|
45 | #First find segments that are not completely on the front
|
---|
46 | if m.strcmp(md.mesh.elementtype(),'Penta'):
|
---|
47 | numbernodesfront=4;
|
---|
48 | elif m.strcmp(md.mesh.elementtype(),'Tria'):
|
---|
49 | numbernodesfront=2;
|
---|
50 | else:
|
---|
51 | raise error('mesh type not supported yet')
|
---|
52 | if any(md.mask.ice_levelset<=0):
|
---|
53 | values=md.mask.ice_levelset[md.mesh.segments[:,0:-1]-1]
|
---|
54 | segmentsfront=1-values
|
---|
55 | np.sum(segmentsfront,axis=1)!=numbernodesfront
|
---|
56 | segments=np.nonzero(np.sum(segmentsfront,axis=1)!=numbernodesfront)[0]
|
---|
57 | #Find all nodes for these segments and spc them
|
---|
58 | pos=md.mesh.segments[segments,0:-1]-1
|
---|
59 | else:
|
---|
60 | pos=np.nonzero(md.mesh.vertexonboundary)[0]
|
---|
61 | md.stressbalance.spcvx[pos]=0
|
---|
62 | md.stressbalance.spcvy[pos]=0
|
---|
63 | md.stressbalance.spcvz[pos]=0
|
---|
64 |
|
---|
65 | #Dirichlet Values
|
---|
66 | if isinstance(md.inversion.vx_obs,np.ndarray) and np.size(md.inversion.vx_obs,axis=0)==md.mesh.numberofvertices and isinstance(md.inversion.vy_obs,np.ndarray) and np.size(md.inversion.vy_obs,axis=0)==md.mesh.numberofvertices:
|
---|
67 | #reshape to rank-2 if necessary to match spc arrays
|
---|
68 | if np.ndim(md.inversion.vx_obs)==1:
|
---|
69 | md.inversion.vx_obs=md.inversion.vx_obs.reshape(-1,)
|
---|
70 | if np.ndim(md.inversion.vy_obs)==1:
|
---|
71 | md.inversion.vy_obs=md.inversion.vy_obs.reshape(-1,)
|
---|
72 | print " boundary conditions for stressbalance model: spc set as observed velocities"
|
---|
73 | md.stressbalance.spcvx[pos]=md.inversion.vx_obs[pos]
|
---|
74 | md.stressbalance.spcvy[pos]=md.inversion.vy_obs[pos]
|
---|
75 | else:
|
---|
76 | print " boundary conditions for stressbalance model: spc set as zero"
|
---|
77 |
|
---|
78 | #Create zeros basalforcings and smb
|
---|
79 | md.smb.initialize(md)
|
---|
80 | md.basalforcings.initialize(md)
|
---|
81 |
|
---|
82 | #Deal with other boundary conditions
|
---|
83 | if np.all(np.isnan(md.balancethickness.thickening_rate)):
|
---|
84 | md.balancethickness.thickening_rate=np.zeros((md.mesh.numberofvertices))
|
---|
85 | print " no balancethickness.thickening_rate specified: values set as zero"
|
---|
86 | md.masstransport.spcthickness=float('nan')*np.ones((md.mesh.numberofvertices))
|
---|
87 | md.balancethickness.spcthickness=float('nan')*np.ones((md.mesh.numberofvertices))
|
---|
88 | md.damage.spcdamage=float('nan')*np.ones((md.mesh.numberofvertices))
|
---|
89 |
|
---|
90 | if isinstance(md.initialization.temperature,np.ndarray) and np.size(md.initialization.temperature,axis=0)==md.mesh.numberofvertices:
|
---|
91 | md.thermal.spctemperature=float('nan')*np.ones((md.mesh.numberofvertices))
|
---|
92 | if hasattr(md.mesh,'vertexonsurface'):
|
---|
93 | pos=np.nonzero(md.mesh.vertexonsurface)[0]
|
---|
94 | md.thermal.spctemperature[pos]=md.initialization.temperature[pos] #impose observed temperature on surface
|
---|
95 | if not isinstance(md.basalforcings.geothermalflux,np.ndarray) or not np.size(md.basalforcings.geothermalflux,axis=0)==md.mesh.numberofvertices:
|
---|
96 | md.basalforcings.geothermalflux=np.zeros((md.mesh.numberofvertices))
|
---|
97 | else:
|
---|
98 | print " no thermal boundary conditions created: no observed temperature found"
|
---|
99 |
|
---|
100 | return md
|
---|
101 |
|
---|