[12854] | 1 | import os
|
---|
[21759] | 2 | import numpy as np
|
---|
[17480] | 3 | from ContourToMesh import ContourToMesh
|
---|
| 4 | import MatlabFuncs as m
|
---|
[12854] | 5 |
|
---|
[12191] | 6 | def SetIceShelfBC(md,icefrontfile=''):
|
---|
[12854] | 7 | """
|
---|
[15771] | 8 | SETICESHELFBC - Create the boundary conditions for stressbalance and thermal models for a Ice Shelf with Ice Front
|
---|
[12944] | 9 |
|
---|
[13462] | 10 | Neumann BC are used on the ice front (an ARGUS contour around the ice front
|
---|
[12944] | 11 | must be given in input)
|
---|
[15771] | 12 | Dirichlet BC are used elsewhere for stressbalance
|
---|
[12944] | 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
|
---|
[12854] | 22 | """
|
---|
[12127] | 23 |
|
---|
| 24 | #node on Dirichlet (boundary and ~icefront)
|
---|
[12854] | 25 | if icefrontfile:
|
---|
| 26 | if not os.path.exists(icefrontfile):
|
---|
| 27 | raise IOError("SetIceShelfBC error message: ice front file '%s' not found." % icefrontfile)
|
---|
[20910] | 28 | nodeinsideicefront=ContourToMesh(md.mesh.elements,md.mesh.x,md.mesh.y,icefrontfile,'node',2)
|
---|
[21759] | 29 | nodeonicefront=np.logical_and(md.mesh.vertexonboundary,nodeinsideicefront.reshape(-1))
|
---|
[12127] | 30 | else:
|
---|
[21759] | 31 | nodeonicefront=np.zeros((md.mesh.numberofvertices),bool)
|
---|
[12127] | 32 |
|
---|
[12854] | 33 | # pos=find(md.mesh.vertexonboundary & ~nodeonicefront);
|
---|
[21759] | 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))
|
---|
[12854] | 40 |
|
---|
[15806] | 41 | #Icefront position
|
---|
[21759] | 42 | pos=np.nonzero(nodeonicefront)[0]
|
---|
[15946] | 43 | md.mask.ice_levelset[pos]=0
|
---|
[15806] | 44 |
|
---|
[15801] | 45 | #First find segments that are not completely on the front
|
---|
[17686] | 46 | if m.strcmp(md.mesh.elementtype(),'Penta'):
|
---|
[16318] | 47 | numbernodesfront=4;
|
---|
[17686] | 48 | elif m.strcmp(md.mesh.elementtype(),'Tria'):
|
---|
[16318] | 49 | numbernodesfront=2;
|
---|
[15801] | 50 | else:
|
---|
[16318] | 51 | raise error('mesh type not supported yet')
|
---|
[15946] | 52 | if any(md.mask.ice_levelset<=0):
|
---|
| 53 | values=md.mask.ice_levelset[md.mesh.segments[:,0:-1]-1]
|
---|
[15807] | 54 | segmentsfront=1-values
|
---|
[21759] | 55 | np.sum(segmentsfront,axis=1)!=numbernodesfront
|
---|
| 56 | segments=np.nonzero(np.sum(segmentsfront,axis=1)!=numbernodesfront)[0]
|
---|
[15807] | 57 | #Find all nodes for these segments and spc them
|
---|
[15816] | 58 | pos=md.mesh.segments[segments,0:-1]-1
|
---|
[15807] | 59 | else:
|
---|
[21759] | 60 | pos=np.nonzero(md.mesh.vertexonboundary)[0]
|
---|
[17876] | 61 | md.stressbalance.spcvx[pos]=0
|
---|
| 62 | md.stressbalance.spcvy[pos]=0
|
---|
| 63 | md.stressbalance.spcvz[pos]=0
|
---|
[15815] | 64 |
|
---|
[12127] | 65 | #Dirichlet Values
|
---|
[21759] | 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:
|
---|
[13970] | 67 | #reshape to rank-2 if necessary to match spc arrays
|
---|
[21759] | 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,)
|
---|
[15771] | 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]
|
---|
[12191] | 75 | else:
|
---|
[15771] | 76 | print " boundary conditions for stressbalance model: spc set as zero"
|
---|
[12127] | 77 |
|
---|
[19527] | 78 | #Create zeros basalforcings and smb
|
---|
| 79 | md.smb.initialize(md)
|
---|
[17071] | 80 | md.basalforcings.initialize(md)
|
---|
| 81 |
|
---|
| 82 | #Deal with other boundary conditions
|
---|
[21759] | 83 | if np.all(np.isnan(md.balancethickness.thickening_rate)):
|
---|
| 84 | md.balancethickness.thickening_rate=np.zeros((md.mesh.numberofvertices))
|
---|
[13470] | 85 | print " no balancethickness.thickening_rate specified: values set as zero"
|
---|
[21759] | 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))
|
---|
[12127] | 89 |
|
---|
[21759] | 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))
|
---|
[16318] | 92 | if hasattr(md.mesh,'vertexonsurface'):
|
---|
[21759] | 93 | pos=np.nonzero(md.mesh.vertexonsurface)[0]
|
---|
[16318] | 94 | md.thermal.spctemperature[pos]=md.initialization.temperature[pos] #impose observed temperature on surface
|
---|
[21759] | 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))
|
---|
[12191] | 97 | else:
|
---|
[13470] | 98 | print " no thermal boundary conditions created: no observed temperature found"
|
---|
[12191] | 99 |
|
---|
| 100 | return md
|
---|
[12854] | 101 |
|
---|