1 | import numpy as np
|
---|
2 | from averaging import averaging
|
---|
3 | #from plotmodel import plotmodel
|
---|
4 | from thomasparams import thomasparams
|
---|
5 |
|
---|
6 | def analyticaldamage(md,**kwargs):
|
---|
7 | '''
|
---|
8 | ANALYTICALDAMAGE - compute damage for an ice shelf
|
---|
9 |
|
---|
10 | This routine computes damage as a function of water/ice
|
---|
11 | material properties, ice thickness, strain rate, and ice
|
---|
12 | rigidity. The model must contain computed strain rates,
|
---|
13 | either from observed or modeled ice velocities.
|
---|
14 |
|
---|
15 | Available options:
|
---|
16 | -eq : analytical equation to use in the calculation. Must be one of:
|
---|
17 | 'Weertman1D' for a confined ice shelf free to flow in one direction
|
---|
18 | 'Weertman2D' for an unconfined ice shelf free to spread in any direction
|
---|
19 | 'Thomas' for a 2D ice shelf, taking into account full strain rate tensor (default)
|
---|
20 | -smoothing : the amount of smoothing to be applied to the strain rate data.
|
---|
21 | Type 'help averaging' for more information on its usage.
|
---|
22 | -coordsys : coordinate system for calculating the strain rate
|
---|
23 | components. Must be one of:
|
---|
24 | -sigmab : a compressive backstress term to be subtracted from the driving stress
|
---|
25 | in the damage calculation
|
---|
26 |
|
---|
27 | Return values:
|
---|
28 | 'damage' which is truncated in the range [0,1-1e-9]
|
---|
29 |
|
---|
30 | 'B' is the rigidity, which is equal to md.materials.rheology_B in areas outside
|
---|
31 | those defined by 'mask.' Within areas defined by 'mask,' where negative damage
|
---|
32 | is inferred, 'B' is updated to make damage equal to zero.
|
---|
33 |
|
---|
34 | 'backstress' is the inferred backstress necessary to balance the analytical solution
|
---|
35 | (keeping damage within its appropriate limits, e.g. D in [0,1]).
|
---|
36 |
|
---|
37 | Usage:
|
---|
38 | damage,B,backstress=analyticaldamage(md,kwargs)
|
---|
39 |
|
---|
40 | Example:
|
---|
41 | damage,B,backstress=analyticaldamage(md,eq='Weertman2D',smoothing=2,sigmab=10e3)
|
---|
42 | '''
|
---|
43 |
|
---|
44 | #unpack kwargs
|
---|
45 | eq=kwargs.pop('eq','Thomas')
|
---|
46 | if 'eq' in kwargs: del kwargs['eq']
|
---|
47 | smoothing=kwargs.pop('smoothing',0)
|
---|
48 | if 'smoothing' in kwargs: del kwargs['smoothing']
|
---|
49 | coordsys=kwargs.pop('coordsys','longitudinal')
|
---|
50 | if 'coordsys' in kwargs: del kwargs['coordsys']
|
---|
51 | sigmab=kwargs.pop('sigmab',0)
|
---|
52 | if 'sigmab' in kwargs: del kwargs['sigmab']
|
---|
53 | assert len(kwargs)==0, 'error, unexpected or misspelled kwargs'
|
---|
54 |
|
---|
55 | if isinstance(sigmab,(int,float)):
|
---|
56 | sigmab=sigmab*np.ones((md.mesh.numberofvertices,))
|
---|
57 |
|
---|
58 | # check inputs
|
---|
59 | if 'strainrate' not in md.results.__dict__:
|
---|
60 | raise Exception('md.results.strainrate not present. Calculate using md=mechanicalproperties(md,vx,vy)')
|
---|
61 | if not '2d' in md.mesh.__doc__:
|
---|
62 | raise Exception('only 2d (planview) model supported currently')
|
---|
63 | if np.any(md.flowequation.element_equation!=2):
|
---|
64 | print('Warning: the model has some non SSA elements. These will be treated like SSA elements')
|
---|
65 |
|
---|
66 | a,b,theta,ex=thomasparams(md,eq=eq,smoothing=smoothing,coordsys=coordsys)
|
---|
67 |
|
---|
68 | # spreading stress
|
---|
69 | rhoi=md.materials.rho_ice
|
---|
70 | rhow=md.materials.rho_water
|
---|
71 | C=0.5*rhoi*md.constants.g*(1.-rhoi/rhow)
|
---|
72 | T=C*md.geometry.thickness
|
---|
73 |
|
---|
74 | # rheology
|
---|
75 | B=md.materials.rheology_B
|
---|
76 | n=averaging(md,md.materials.rheology_n,0)
|
---|
77 |
|
---|
78 | D=1.-(1.+a+a**2+b**2)**((n-1.)/(2.*n))/np.abs(ex)**(1./n)*(T-sigmab)/B/(2.+a)/np.sign(ex)
|
---|
79 |
|
---|
80 | # D>1 where (2+a).*sign(ex)<0, compressive regions where high backstress needed
|
---|
81 | pos=np.nonzero(D>1)
|
---|
82 | D[pos]=0
|
---|
83 |
|
---|
84 | backstress=np.zeros((md.mesh.numberofvertices,))
|
---|
85 |
|
---|
86 | # backstress to bring D down to one
|
---|
87 | backstress[pos]=T[pos]-(1.-D[pos])*B[pos]*np.sign(ex[pos])*(2.+a[pos])*np.abs(ex[pos])**(1./n[pos])/(1.+a[pos]+a[pos]**2)**((n[pos]-1.)/2./n[pos])
|
---|
88 |
|
---|
89 | pos=np.nonzero(D<0)
|
---|
90 | #mask=ismember(1:md.mesh.numberofvertices,pos);
|
---|
91 | D[pos]=0
|
---|
92 |
|
---|
93 | # backstress to bring negative damage to zero
|
---|
94 | backstress[pos]=T[pos]-(1.-D[pos])*B[pos]*np.sign(ex[pos])*(2.+a[pos])*np.abs(ex[pos])**(1./n[pos])/(1.+a[pos]+a[pos]**2)**((n[pos]-1.)/2./n[pos])
|
---|
95 |
|
---|
96 | pos=np.nonzero(backstress<0)
|
---|
97 | backstress[pos]=0
|
---|
98 |
|
---|
99 | # rigidity from Thomas relation for D=0 and backstress=0
|
---|
100 | B=np.sign(ex)/(2.+a)*(1.+a+a**2)**((n-1.)/2./n)*T/(np.abs(ex)**(1./n))
|
---|
101 | pos=np.nonzero(B<0)
|
---|
102 | B[pos]=md.materials.rheology_B[pos]
|
---|
103 |
|
---|
104 | damage=D
|
---|
105 |
|
---|
106 | return damage, B, backstress
|
---|