| 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 |
|
|---|