source: issm/branches/trunk-larour-SLPS2020/src/m/mech/analyticaldamage.py@ 25588

Last change on this file since 25588 was 25065, checked in by jdquinn, 5 years ago

CHG: Saving progress on SLR/Solid Earth translation

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