cfs-python 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- app_panel.py +1058 -0
- cfs_lib/__init__.py +0 -0
- cfs_lib/coulomb_math.py +142 -0
- cfs_lib/io_parser.py +165 -0
- cfs_lib/main.py +173 -0
- cfs_lib/okada_math.py +652 -0
- cfs_lib/okada_wrapper.py +148 -0
- cfs_python-0.1.0.dist-info/METADATA +51 -0
- cfs_python-0.1.0.dist-info/RECORD +11 -0
- cfs_python-0.1.0.dist-info/WHEEL +5 -0
- cfs_python-0.1.0.dist-info/top_level.txt +2 -0
cfs_lib/okada_math.py
ADDED
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
def coord_conversion(xgg, ygg, xs, ys, xf, yf, top, bottom, dip):
|
|
4
|
+
cx = (xf + xs) / 2.0
|
|
5
|
+
cy = (yf + ys) / 2.0
|
|
6
|
+
h = (bottom - top) / 2.0
|
|
7
|
+
|
|
8
|
+
k = np.tan(np.deg2rad(dip))
|
|
9
|
+
if k == 0:
|
|
10
|
+
k = 0.000001
|
|
11
|
+
d = h / k
|
|
12
|
+
|
|
13
|
+
# MATLAB: b = atan((yf-ys)./(xf-xs));
|
|
14
|
+
# To handle division by zero or use standard quadrant:
|
|
15
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
16
|
+
b = np.arctan((yf - ys) / (xf - xs))
|
|
17
|
+
b = np.where(np.isnan(b), np.pi/2 * np.sign(yf-ys), b)
|
|
18
|
+
|
|
19
|
+
ydipshift = np.abs(d * np.cos(b))
|
|
20
|
+
xdipshift = np.abs(d * np.sin(b))
|
|
21
|
+
|
|
22
|
+
if xf > xs:
|
|
23
|
+
if yf > ys:
|
|
24
|
+
cx = cx + xdipshift
|
|
25
|
+
cy = cy - ydipshift
|
|
26
|
+
else:
|
|
27
|
+
cx = cx - xdipshift
|
|
28
|
+
cy = cy - ydipshift
|
|
29
|
+
else:
|
|
30
|
+
if yf > ys:
|
|
31
|
+
cx = cx + xdipshift
|
|
32
|
+
cy = cy + ydipshift
|
|
33
|
+
else:
|
|
34
|
+
cx = cx - xdipshift
|
|
35
|
+
cy = cy + ydipshift
|
|
36
|
+
|
|
37
|
+
xn = (xgg - cx) * np.cos(b) + (ygg - cy) * np.sin(b)
|
|
38
|
+
yn = -(xgg - cx) * np.sin(b) + (ygg - cy) * np.cos(b)
|
|
39
|
+
|
|
40
|
+
if (xf - xs) < 0.0:
|
|
41
|
+
xn = -xn
|
|
42
|
+
yn = -yn
|
|
43
|
+
|
|
44
|
+
al = np.sqrt((xf - xs)**2 + (yf - ys)**2) / 2.0
|
|
45
|
+
aw = ((bottom - top) / 2.0) / np.sin(np.deg2rad(dip))
|
|
46
|
+
|
|
47
|
+
return xn, yn, al, aw
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def tensor_trans(sinb, cosb, so):
|
|
51
|
+
"""
|
|
52
|
+
so is shape (6, N)
|
|
53
|
+
returns sn of shape (6, N)
|
|
54
|
+
"""
|
|
55
|
+
nn = so.shape[1]
|
|
56
|
+
t = np.zeros((6, 6))
|
|
57
|
+
sn = np.zeros((6, nn))
|
|
58
|
+
|
|
59
|
+
ver = np.pi / 2.0
|
|
60
|
+
bt = np.arcsin(sinb)
|
|
61
|
+
|
|
62
|
+
if cosb > 0.0:
|
|
63
|
+
xbeta, xdel = -bt, 0.0
|
|
64
|
+
ybeta, ydel = -bt + ver, 0.0
|
|
65
|
+
zbeta, zdel = -bt - ver, ver
|
|
66
|
+
else:
|
|
67
|
+
xbeta, xdel = bt - np.pi, 0.0
|
|
68
|
+
ybeta, ydel = bt - ver, 0.0
|
|
69
|
+
zbeta, zdel = bt - ver, ver
|
|
70
|
+
|
|
71
|
+
xl, xm, xn = np.cos(xdel)*np.cos(xbeta), np.cos(xdel)*np.sin(xbeta), np.sin(xdel)
|
|
72
|
+
yl, ym, yn = np.cos(ydel)*np.cos(ybeta), np.cos(ydel)*np.sin(ybeta), np.sin(ydel)
|
|
73
|
+
zl, zm, zn = np.cos(zdel)*np.cos(zbeta), np.cos(zdel)*np.sin(zbeta), np.sin(zdel)
|
|
74
|
+
|
|
75
|
+
t[0, 0] = xl * xl
|
|
76
|
+
t[0, 1] = xm * xm
|
|
77
|
+
t[0, 2] = xn * xn
|
|
78
|
+
t[0, 3] = 2.0 * xm * xn
|
|
79
|
+
t[0, 4] = 2.0 * xn * xl
|
|
80
|
+
t[0, 5] = 2.0 * xl * xm
|
|
81
|
+
|
|
82
|
+
t[1, 0] = yl * yl
|
|
83
|
+
t[1, 1] = ym * ym
|
|
84
|
+
t[1, 2] = yn * yn
|
|
85
|
+
t[1, 3] = 2.0 * ym * yn
|
|
86
|
+
t[1, 4] = 2.0 * yn * yl
|
|
87
|
+
t[1, 5] = 2.0 * yl * ym
|
|
88
|
+
|
|
89
|
+
t[2, 0] = zl * zl
|
|
90
|
+
t[2, 1] = zm * zm
|
|
91
|
+
t[2, 2] = zn * zn
|
|
92
|
+
t[2, 3] = 2.0 * zm * zn
|
|
93
|
+
t[2, 4] = 2.0 * zn * zl
|
|
94
|
+
t[2, 5] = 2.0 * zl * zm
|
|
95
|
+
|
|
96
|
+
t[3, 0] = yl * zl
|
|
97
|
+
t[3, 1] = ym * zm
|
|
98
|
+
t[3, 2] = yn * zn
|
|
99
|
+
t[3, 3] = ym * zn + zm * yn
|
|
100
|
+
t[3, 4] = yn * zl + zn * yl
|
|
101
|
+
t[3, 5] = yl * zm + zl * ym
|
|
102
|
+
|
|
103
|
+
t[4, 0] = zl * xl
|
|
104
|
+
t[4, 1] = zm * xm
|
|
105
|
+
t[4, 2] = zn * xn
|
|
106
|
+
t[4, 3] = xm * zn + zm * xn
|
|
107
|
+
t[4, 4] = xn * zl + zn * xl
|
|
108
|
+
t[4, 5] = xl * zm + zl * xm
|
|
109
|
+
|
|
110
|
+
t[5, 0] = xl * yl
|
|
111
|
+
t[5, 1] = xm * ym
|
|
112
|
+
t[5, 2] = xn * yn
|
|
113
|
+
t[5, 3] = xm * yn + ym * xn
|
|
114
|
+
t[5, 4] = xn * yl + yn * xl
|
|
115
|
+
t[5, 5] = xl * ym + yl * xm
|
|
116
|
+
|
|
117
|
+
for k in range(nn):
|
|
118
|
+
sn[:, k] = np.dot(t, so[:, k])
|
|
119
|
+
|
|
120
|
+
return sn
|
|
121
|
+
|
|
122
|
+
def dccon0(alpha, dip, n_cells):
|
|
123
|
+
p = {}
|
|
124
|
+
|
|
125
|
+
F0 = np.zeros(n_cells, dtype=np.float64)
|
|
126
|
+
F1 = np.ones(n_cells, dtype=np.float64)
|
|
127
|
+
F2 = np.ones(n_cells, dtype=np.float64) * 2.0
|
|
128
|
+
EPS = np.ones(n_cells, dtype=np.float64) * 1.0e-6
|
|
129
|
+
|
|
130
|
+
p['ALP1'] = (F1 - alpha) / F2
|
|
131
|
+
p['ALP2'] = alpha / F2
|
|
132
|
+
p['ALP3'] = (F1 - alpha) / alpha
|
|
133
|
+
p['ALP4'] = F1 - alpha
|
|
134
|
+
p['ALP5'] = alpha
|
|
135
|
+
|
|
136
|
+
P18 = (2.0 * np.pi) / 360.0
|
|
137
|
+
SD = np.sin(dip * P18)
|
|
138
|
+
CD = np.cos(dip * P18)
|
|
139
|
+
|
|
140
|
+
if np.isscalar(CD):
|
|
141
|
+
CD = np.full(n_cells, CD)
|
|
142
|
+
if np.isscalar(SD):
|
|
143
|
+
SD = np.full(n_cells, SD)
|
|
144
|
+
|
|
145
|
+
c1 = np.abs(CD) < EPS
|
|
146
|
+
c2 = np.abs(CD) >= EPS
|
|
147
|
+
s1 = SD > F0
|
|
148
|
+
s2 = SD == F0
|
|
149
|
+
s3 = SD < F0
|
|
150
|
+
|
|
151
|
+
CD = F0 * c1 + CD * c2
|
|
152
|
+
SD = c1 * (F1 * s1 + SD * s2 + (-1.0) * F1 * s3) + c2 * SD
|
|
153
|
+
|
|
154
|
+
p['SD'] = SD
|
|
155
|
+
p['CD'] = CD
|
|
156
|
+
p['SDSD'] = SD * SD
|
|
157
|
+
p['CDCD'] = CD * CD
|
|
158
|
+
p['SDCD'] = SD * CD
|
|
159
|
+
p['S2D'] = F2 * p['SDCD']
|
|
160
|
+
p['C2D'] = p['CDCD'] - p['SDSD']
|
|
161
|
+
|
|
162
|
+
return p
|
|
163
|
+
|
|
164
|
+
def dccon1(X, Y, D, n_cells):
|
|
165
|
+
# For point source station geom constants
|
|
166
|
+
p = {}
|
|
167
|
+
F0 = np.zeros(n_cells, dtype=np.float64)
|
|
168
|
+
F1 = np.ones(n_cells, dtype=np.float64)
|
|
169
|
+
F3 = np.ones(n_cells, dtype=np.float64) * 3.0
|
|
170
|
+
F5 = np.ones(n_cells, dtype=np.float64) * 5.0
|
|
171
|
+
EPS = np.ones(n_cells, dtype=np.float64) * 1.0e-6
|
|
172
|
+
|
|
173
|
+
c1 = np.abs(X) < EPS
|
|
174
|
+
c2 = np.abs(X) >= EPS
|
|
175
|
+
X = F0 * c1 + X * c2
|
|
176
|
+
c1 = np.abs(Y) < EPS
|
|
177
|
+
c2 = np.abs(Y) >= EPS
|
|
178
|
+
Y = F0 * c1 + Y * c2
|
|
179
|
+
c1 = np.abs(D) < EPS
|
|
180
|
+
c2 = np.abs(D) >= EPS
|
|
181
|
+
D = F0 * c1 + D * c2
|
|
182
|
+
|
|
183
|
+
# Need SD, CD from dccon0, handled in parent call context via arguments
|
|
184
|
+
# Wait, the MATLAB code uses globals SD & CD in DCCON1.
|
|
185
|
+
# I should pass them.
|
|
186
|
+
return X, Y, D
|
|
187
|
+
|
|
188
|
+
def dccon2(XI, ET, Q, SD, CD, n_cells):
|
|
189
|
+
p = {}
|
|
190
|
+
F0 = np.zeros(n_cells, dtype=np.float64)
|
|
191
|
+
F1 = np.ones(n_cells, dtype=np.float64)
|
|
192
|
+
F2 = np.ones(n_cells, dtype=np.float64) * 2.0
|
|
193
|
+
EPS = np.ones(n_cells, dtype=np.float64) * 1.0e-6
|
|
194
|
+
|
|
195
|
+
c1 = np.abs(XI) < EPS
|
|
196
|
+
c2 = np.abs(XI) >= EPS
|
|
197
|
+
XI = F0 * c1 + XI * c2
|
|
198
|
+
c1 = np.abs(ET) < EPS
|
|
199
|
+
c2 = np.abs(ET) >= EPS
|
|
200
|
+
ET = F0 * c1 + ET * c2
|
|
201
|
+
c1 = np.abs(Q) < EPS
|
|
202
|
+
c2 = np.abs(Q) >= EPS
|
|
203
|
+
Q = F0 * c1 + Q * c2
|
|
204
|
+
|
|
205
|
+
p['XI2'] = XI * XI
|
|
206
|
+
p['ET2'] = ET * ET
|
|
207
|
+
p['Q2'] = Q * Q
|
|
208
|
+
p['R2'] = p['XI2'] + p['ET2'] + p['Q2']
|
|
209
|
+
p['R'] = np.sqrt(p['R2'])
|
|
210
|
+
|
|
211
|
+
c1_zero = p['R'] == F0
|
|
212
|
+
if np.sum(c1_zero) > 0:
|
|
213
|
+
p['SINGULAR'] = True
|
|
214
|
+
else:
|
|
215
|
+
p['SINGULAR'] = False
|
|
216
|
+
|
|
217
|
+
p['R3'] = p['R'] * p['R2']
|
|
218
|
+
p['R5'] = p['R3'] * p['R2']
|
|
219
|
+
p['Y'] = ET * CD + Q * SD
|
|
220
|
+
p['D'] = ET * SD - Q * CD
|
|
221
|
+
|
|
222
|
+
c1_q = Q == F0
|
|
223
|
+
c2_q = Q != F0
|
|
224
|
+
|
|
225
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
226
|
+
val = np.arctan(XI * ET / (Q * p['R']))
|
|
227
|
+
val = np.where(np.isnan(val), 0.0, val)
|
|
228
|
+
p['TT'] = c1_q * F0 + c2_q * val
|
|
229
|
+
|
|
230
|
+
c1_xi = XI < F0
|
|
231
|
+
c3_et = ET == F0
|
|
232
|
+
c4_x = c1_xi & c1_q & c3_et
|
|
233
|
+
c5_x = ~c4_x
|
|
234
|
+
|
|
235
|
+
RXI = p['R'] + XI
|
|
236
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
237
|
+
lx = np.where(c4_x, -np.log(np.maximum(p['R'] - XI, 1e-12)), np.log(np.maximum(RXI, 1e-12)))
|
|
238
|
+
p['ALX'] = lx
|
|
239
|
+
x11 = np.where(c4_x, F0, F1 / (p['R'] * np.maximum(RXI, 1e-12)))
|
|
240
|
+
p['X11'] = x11
|
|
241
|
+
p['X32'] = np.where(c4_x, F0, (p['R'] + RXI) * x11 * x11 / np.maximum(p['R'], 1e-12))
|
|
242
|
+
|
|
243
|
+
c1_ett = ET < F0
|
|
244
|
+
c3_x = XI == F0
|
|
245
|
+
c4_y = c1_ett & c1_q & c3_x
|
|
246
|
+
c5_y = ~c4_y
|
|
247
|
+
|
|
248
|
+
RET = p['R'] + ET
|
|
249
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
250
|
+
le = np.where(c4_y, -np.log(np.maximum(p['R'] - ET, 1e-12)), np.log(np.maximum(RET, 1e-12)))
|
|
251
|
+
p['ALE'] = le
|
|
252
|
+
y11 = np.where(c4_y, F0, F1 / (p['R'] * np.maximum(RET, 1e-12)))
|
|
253
|
+
p['Y11'] = y11
|
|
254
|
+
p['Y32'] = np.where(c4_y, F0, (p['R'] + RET) * y11 * y11 / np.maximum(p['R'], 1e-12))
|
|
255
|
+
|
|
256
|
+
R = np.maximum(p['R'], 1e-12)
|
|
257
|
+
R3 = np.maximum(p['R3'], 1e-12)
|
|
258
|
+
|
|
259
|
+
p['EY'] = SD / R - p['Y'] * Q / R3
|
|
260
|
+
p['EZ'] = CD / R + p['D'] * Q / R3
|
|
261
|
+
p['FY'] = p['D'] / R3 + p['XI2'] * p['Y32'] * SD
|
|
262
|
+
p['FZ'] = p['Y'] / R3 + p['XI2'] * p['Y32'] * CD
|
|
263
|
+
p['GY'] = F2 * p['X11'] * SD - p['Y'] * Q * p['X32']
|
|
264
|
+
p['GZ'] = F2 * p['X11'] * CD + p['D'] * Q * p['X32']
|
|
265
|
+
p['HY'] = p['D'] * Q * p['X32'] + XI * Q * p['Y32'] * SD
|
|
266
|
+
p['HZ'] = p['Y'] * Q * p['X32'] + XI * Q * p['Y32'] * CD
|
|
267
|
+
|
|
268
|
+
return p
|
|
269
|
+
|
|
270
|
+
def UA(XI, ET, Q, DISL1, DISL2, DISL3, c0, c2, n_cells):
|
|
271
|
+
F0 = np.zeros(n_cells, dtype=np.float64)
|
|
272
|
+
F2 = np.ones(n_cells, dtype=np.float64) * 2.0
|
|
273
|
+
PI2 = np.ones(n_cells, dtype=np.float64) * (2.0 * np.pi)
|
|
274
|
+
|
|
275
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
276
|
+
U = np.zeros((n_cells, 12), dtype=np.float64)
|
|
277
|
+
|
|
278
|
+
XY = XI * c2['Y11']
|
|
279
|
+
QX = Q * c2['X11']
|
|
280
|
+
QY = Q * c2['Y11']
|
|
281
|
+
|
|
282
|
+
# Strike Slip
|
|
283
|
+
c_1 = DISL1 != F0
|
|
284
|
+
du1 = np.zeros((n_cells, 12), dtype=np.float64)
|
|
285
|
+
du1[:,0] = c2['TT'] / F2 + c0['ALP2'] * XI * QY
|
|
286
|
+
du1[:,1] = c0['ALP2'] * Q / c2['R']
|
|
287
|
+
du1[:,2] = c0['ALP1'] * c2['ALE'] - c0['ALP2'] * Q * QY
|
|
288
|
+
du1[:,3] = -c0['ALP1'] * QY - c0['ALP2'] * c2['XI2'] * Q * c2['Y32']
|
|
289
|
+
du1[:,4] = -c0['ALP2'] * XI * Q / c2['R3']
|
|
290
|
+
du1[:,5] = c0['ALP1'] * XY + c0['ALP2'] * XI * c2['Q2'] * c2['Y32']
|
|
291
|
+
du1[:,6] = c0['ALP1'] * XY * c0['SD'] + c0['ALP2'] * XI * c2['FY'] + c2['D'] / F2 * c2['X11']
|
|
292
|
+
du1[:,7] = c0['ALP2'] * c2['EY']
|
|
293
|
+
du1[:,8] = c0['ALP1'] * (c0['CD'] / c2['R'] + QY * c0['SD']) - c0['ALP2'] * Q * c2['FY']
|
|
294
|
+
du1[:,9] = c0['ALP1'] * XY * c0['CD'] + c0['ALP2'] * XI * c2['FZ'] + c2['Y'] / F2 * c2['X11']
|
|
295
|
+
du1[:,10] = c0['ALP2'] * c2['EZ']
|
|
296
|
+
du1[:,11] = -c0['ALP1'] * (c0['SD'] / c2['R'] - QY * c0['CD']) - c0['ALP2'] * Q * c2['FZ']
|
|
297
|
+
|
|
298
|
+
for i in range(12):
|
|
299
|
+
U[:, i] += (DISL1 / PI2 * du1[:, i]) * c_1
|
|
300
|
+
|
|
301
|
+
# Dip Slip
|
|
302
|
+
c_2 = DISL2 != F0
|
|
303
|
+
du2 = np.zeros((n_cells, 12), dtype=np.float64)
|
|
304
|
+
du2[:,0] = c0['ALP2'] * Q / c2['R']
|
|
305
|
+
du2[:,1] = c2['TT'] / F2 + c0['ALP2'] * ET * QX
|
|
306
|
+
du2[:,2] = c0['ALP1'] * c2['ALX'] - c0['ALP2'] * Q * QX
|
|
307
|
+
du2[:,3] = -c0['ALP2'] * XI * Q / c2['R3']
|
|
308
|
+
du2[:,4] = -QY / F2 - c0['ALP2'] * ET * Q / c2['R3']
|
|
309
|
+
du2[:,5] = c0['ALP1'] / c2['R'] + c0['ALP2'] * c2['Q2'] / c2['R3']
|
|
310
|
+
du2[:,6] = c0['ALP2'] * c2['EY']
|
|
311
|
+
du2[:,7] = c0['ALP1'] * c2['D'] * c2['X11'] + XY / F2 * c0['SD'] + c0['ALP2'] * ET * c2['GY']
|
|
312
|
+
du2[:,8] = c0['ALP1'] * c2['Y'] * c2['X11'] - c0['ALP2'] * Q * c2['GY']
|
|
313
|
+
du2[:,9] = c0['ALP2'] * c2['EZ']
|
|
314
|
+
du2[:,10] = c0['ALP1'] * c2['Y'] * c2['X11'] + XY / F2 * c0['CD'] + c0['ALP2'] * ET * c2['GZ']
|
|
315
|
+
du2[:,11] = -c0['ALP1'] * c2['D'] * c2['X11'] - c0['ALP2'] * Q * c2['GZ']
|
|
316
|
+
|
|
317
|
+
for i in range(12):
|
|
318
|
+
U[:, i] += (DISL2 / PI2 * du2[:, i]) * c_2
|
|
319
|
+
|
|
320
|
+
# Tensile
|
|
321
|
+
c_3 = DISL3 != F0
|
|
322
|
+
du3 = np.zeros((n_cells, 12), dtype=np.float64)
|
|
323
|
+
du3[:,0] = -c0['ALP1'] * c2['ALE'] - c0['ALP2'] * Q * QY
|
|
324
|
+
du3[:,1] = -c0['ALP1'] * c2['ALX'] - c0['ALP2'] * Q * QX
|
|
325
|
+
du3[:,2] = c2['TT'] / F2 - c0['ALP2'] * (ET * QX + XI * QY)
|
|
326
|
+
du3[:,3] = -c0['ALP1'] * XY + c0['ALP2'] * XI * c2['Q2'] * c2['Y32']
|
|
327
|
+
du3[:,4] = -c0['ALP1'] / c2['R'] + c0['ALP2'] * c2['Q2'] / c2['R3']
|
|
328
|
+
du3[:,5] = -c0['ALP1'] * QY - c0['ALP2'] * Q * c2['Q2'] * c2['Y32']
|
|
329
|
+
du3[:,6] = -c0['ALP1'] * (c0['CD'] / c2['R'] + QY * c0['SD']) - c0['ALP2'] * Q * c2['FY']
|
|
330
|
+
du3[:,7] = -c0['ALP1'] * c2['Y'] * c2['X11'] - c0['ALP2'] * Q * c2['GY']
|
|
331
|
+
du3[:,8] = c0['ALP1'] * (c2['D'] * c2['X11'] + XY * c0['SD']) + c0['ALP2'] * Q * c2['HY']
|
|
332
|
+
du3[:,9] = c0['ALP1'] * (c0['SD'] / c2['R'] - QY * c0['CD']) - c0['ALP2'] * Q * c2['FZ']
|
|
333
|
+
du3[:,10] = c0['ALP1'] * c2['D'] * c2['X11'] - c0['ALP2'] * Q * c2['GZ']
|
|
334
|
+
du3[:,11] = c0['ALP1'] * (c2['Y'] * c2['X11'] + XY * c0['CD']) + c0['ALP2'] * Q * c2['HZ']
|
|
335
|
+
|
|
336
|
+
for i in range(12):
|
|
337
|
+
U[:, i] += (DISL3 / PI2 * du3[:, i]) * c_3
|
|
338
|
+
|
|
339
|
+
return U
|
|
340
|
+
|
|
341
|
+
def UB(XI, ET, Q, DISL1, DISL2, DISL3, c0, c2, n_cells):
|
|
342
|
+
F0 = np.zeros(n_cells, dtype=np.float64)
|
|
343
|
+
F1 = np.ones(n_cells, dtype=np.float64)
|
|
344
|
+
F2 = np.ones(n_cells, dtype=np.float64) * 2.0
|
|
345
|
+
PI2 = np.ones(n_cells, dtype=np.float64) * (2.0 * np.pi)
|
|
346
|
+
|
|
347
|
+
U = np.zeros((n_cells, 12), dtype=np.float64)
|
|
348
|
+
|
|
349
|
+
RD = c2['R'] + c2['D']
|
|
350
|
+
RD2 = RD * RD
|
|
351
|
+
D11 = F1 / (c2['R'] * np.maximum(RD, 1e-12))
|
|
352
|
+
AJ2 = XI * c2['Y'] / np.maximum(RD, 1e-12) * D11
|
|
353
|
+
AJ5 = -(c2['D'] + c2['Y'] * c2['Y'] / np.maximum(RD, 1e-12)) * D11
|
|
354
|
+
|
|
355
|
+
tempCD = np.copy(c0['CD'])
|
|
356
|
+
tempCDCD = np.copy(c0['CDCD'])
|
|
357
|
+
c_1 = c0['CD'] != F0
|
|
358
|
+
c_2 = c0['CD'] == F0
|
|
359
|
+
s_1 = XI == F0
|
|
360
|
+
s_2 = XI != F0
|
|
361
|
+
|
|
362
|
+
CD = c_1 * c0['CD'] + c_2 * 1.0e-12
|
|
363
|
+
CDCD = c_1 * c0['CDCD'] + c_2 * 1.0e-12
|
|
364
|
+
|
|
365
|
+
X = np.sqrt(c2['XI2'] + c2['Q2'])
|
|
366
|
+
|
|
367
|
+
val1 = F1 / CDCD * (XI / np.maximum(RD, 1e-12) * c0['SDCD'] + F2 * np.arctan((ET * (X + Q * CD) + X * (c2['R'] + X) * c0['SD']) / np.maximum((XI * (c2['R'] + X) * CD), 1e-12)))
|
|
368
|
+
val2 = XI * c2['Y'] / np.maximum(RD2 * F2, 1e-12)
|
|
369
|
+
AI4 = c_1 * (s_1 * F0 + s_2 * val1) + c_2 * val2
|
|
370
|
+
|
|
371
|
+
AI3 = c_1 * ((c2['Y'] * CD / np.maximum(RD, 1e-12) - c2['ALE'] + c0['SD'] * np.log(np.maximum(RD, 1e-12))) / CDCD) + c_2 * ((ET / np.maximum(RD, 1e-12) + c2['Y'] * Q / np.maximum(RD2, 1e-12) - c2['ALE']) / F2)
|
|
372
|
+
|
|
373
|
+
AK1 = c_1 * (XI * (D11 - c2['Y11'] * c0['SD']) / CD) + c_2 * (XI * Q / np.maximum(RD, 1e-12) * D11)
|
|
374
|
+
AK3 = c_1 * ((Q * c2['Y11'] - c2['Y'] * D11) / CD) + c_2 * (c0['SD'] / np.maximum(RD, 1e-12) * (c2['XI2'] * D11 - F1))
|
|
375
|
+
AJ3 = c_1 * ((AK1 - AJ2 * c0['SD']) / CD) + c_2 * (-XI / np.maximum(RD2, 1e-12) * (c2['Q2'] * D11 - F1 / F2))
|
|
376
|
+
AJ6 = c_1 * ((AK3 - AJ5 * c0['SD']) / CD) + c_2 * (-c2['Y'] / np.maximum(RD2, 1e-12) * (c2['XI2'] * D11 - F1 / F2))
|
|
377
|
+
|
|
378
|
+
XY = XI * c2['Y11']
|
|
379
|
+
AI1 = -XI / np.maximum(RD, 1e-12) * CD - AI4 * c0['SD']
|
|
380
|
+
AI2 = np.log(np.maximum(RD, 1e-12)) + AI3 * c0['SD']
|
|
381
|
+
AK2 = F1 / np.maximum(c2['R'], 1e-12) + AK3 * c0['SD']
|
|
382
|
+
AK4 = XY * CD - AK1 * c0['SD']
|
|
383
|
+
AJ1 = AJ5 * CD - AJ6 * c0['SD']
|
|
384
|
+
AJ4 = -XY - AJ2 * CD + AJ3 * c0['SD']
|
|
385
|
+
|
|
386
|
+
QX = Q * c2['X11']
|
|
387
|
+
QY = Q * c2['Y11']
|
|
388
|
+
|
|
389
|
+
# Strike Slip
|
|
390
|
+
m1 = DISL1 != F0
|
|
391
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
392
|
+
DU[:,0] = -XI * QY - c2['TT'] - c0['ALP3'] * AI1 * c0['SD']
|
|
393
|
+
DU[:,1] = -Q / np.maximum(c2['R'], 1e-12) + c0['ALP3'] * c2['Y'] / np.maximum(RD, 1e-12) * c0['SD']
|
|
394
|
+
DU[:,2] = Q * QY - c0['ALP3'] * AI2 * c0['SD']
|
|
395
|
+
DU[:,3] = c2['XI2'] * Q * c2['Y32'] - c0['ALP3'] * AJ1 * c0['SD']
|
|
396
|
+
DU[:,4] = XI * Q / np.maximum(c2['R3'], 1e-12) - c0['ALP3'] * AJ2 * c0['SD']
|
|
397
|
+
DU[:,5] = -XI * c2['Q2'] * c2['Y32'] - c0['ALP3'] * AJ3 * c0['SD']
|
|
398
|
+
DU[:,6] = -XI * c2['FY'] - c2['D'] * c2['X11'] + c0['ALP3'] * (XY + AJ4) * c0['SD']
|
|
399
|
+
DU[:,7] = -c2['EY'] + c0['ALP3'] * (F1 / np.maximum(c2['R'], 1e-12) + AJ5) * c0['SD']
|
|
400
|
+
DU[:,8] = Q * c2['FY'] - c0['ALP3'] * (QY - AJ6) * c0['SD']
|
|
401
|
+
DU[:,9] = -XI * c2['FZ'] - c2['Y'] * c2['X11'] + c0['ALP3'] * AK1 * c0['SD']
|
|
402
|
+
DU[:,10] = -c2['EZ'] + c0['ALP3'] * c2['Y'] * D11 * c0['SD']
|
|
403
|
+
DU[:,11] = Q * c2['FZ'] + c0['ALP3'] * AK2 * c0['SD']
|
|
404
|
+
|
|
405
|
+
for i in range(12):
|
|
406
|
+
U[:, i] += (DISL1 / PI2 * DU[:, i]) * m1
|
|
407
|
+
|
|
408
|
+
# Dip Slip
|
|
409
|
+
m2 = DISL2 != F0
|
|
410
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
411
|
+
DU[:,0] = -Q / np.maximum(c2['R'], 1e-12) + c0['ALP3'] * AI3 * c0['SDCD']
|
|
412
|
+
DU[:,1] = -ET * QX - c2['TT'] - c0['ALP3'] * XI / np.maximum(RD, 1e-12) * c0['SDCD']
|
|
413
|
+
DU[:,2] = Q * QX + c0['ALP3'] * AI4 * c0['SDCD']
|
|
414
|
+
DU[:,3] = XI * Q / np.maximum(c2['R3'], 1e-12) + c0['ALP3'] * AJ4 * c0['SDCD']
|
|
415
|
+
DU[:,4] = ET * Q / np.maximum(c2['R3'], 1e-12) + QY + c0['ALP3'] * AJ5 * c0['SDCD']
|
|
416
|
+
DU[:,5] = -c2['Q2'] / np.maximum(c2['R3'], 1e-12) + c0['ALP3'] * AJ6 * c0['SDCD']
|
|
417
|
+
DU[:,6] = -c2['EY'] + c0['ALP3'] * AJ1 * c0['SDCD']
|
|
418
|
+
DU[:,7] = -ET * c2['GY'] - XY * c0['SD'] + c0['ALP3'] * AJ2 * c0['SDCD']
|
|
419
|
+
DU[:,8] = Q * c2['GY'] + c0['ALP3'] * AJ3 * c0['SDCD']
|
|
420
|
+
DU[:,9] = -c2['EZ'] - c0['ALP3'] * AK3 * c0['SDCD']
|
|
421
|
+
DU[:,10]= -ET * c2['GZ'] - XY * CD - c0['ALP3'] * XI * D11 * c0['SDCD']
|
|
422
|
+
DU[:,11]= Q * c2['GZ'] - c0['ALP3'] * AK4 * c0['SDCD']
|
|
423
|
+
|
|
424
|
+
for i in range(12):
|
|
425
|
+
U[:, i] += (DISL2 / PI2 * DU[:, i]) * m2
|
|
426
|
+
|
|
427
|
+
# Tensile
|
|
428
|
+
m3 = DISL3 != F0
|
|
429
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
430
|
+
DU[:,0] = Q * QY - c0['ALP3'] * AI3 * c0['SDSD']
|
|
431
|
+
DU[:,1] = Q * QX + c0['ALP3'] * XI / np.maximum(RD, 1e-12) * c0['SDSD']
|
|
432
|
+
DU[:,2] = ET * QX + XI * QY - c2['TT'] - c0['ALP3'] * AI4 * c0['SDSD']
|
|
433
|
+
DU[:,3] = -XI * c2['Q2'] * c2['Y32'] - c0['ALP3'] * AJ4 * c0['SDSD']
|
|
434
|
+
DU[:,4] = -c2['Q2'] / np.maximum(c2['R3'], 1e-12) - c0['ALP3'] * AJ5 * c0['SDSD']
|
|
435
|
+
DU[:,5] = Q * c2['Q2'] * c2['Y32'] - c0['ALP3'] * AJ6 * c0['SDSD']
|
|
436
|
+
DU[:,6] = Q * c2['FY'] - c0['ALP3'] * AJ1 * c0['SDSD']
|
|
437
|
+
DU[:,7] = Q * c2['GY'] - c0['ALP3'] * AJ2 * c0['SDSD']
|
|
438
|
+
DU[:,8] = -Q * c2['HY'] - c0['ALP3'] * AJ3 * c0['SDSD']
|
|
439
|
+
DU[:,9] = Q * c2['FZ'] + c0['ALP3'] * AK3 * c0['SDSD']
|
|
440
|
+
DU[:,10]= Q * c2['GZ'] + c0['ALP3'] * XI * D11 * c0['SDSD']
|
|
441
|
+
DU[:,11]= -Q * c2['HZ'] + c0['ALP3'] * AK4 * c0['SDSD']
|
|
442
|
+
|
|
443
|
+
for i in range(12):
|
|
444
|
+
U[:, i] += (DISL3 / PI2 * DU[:, i]) * m3
|
|
445
|
+
|
|
446
|
+
return U
|
|
447
|
+
|
|
448
|
+
def UC(XI, ET, Q, Z, DISL1, DISL2, DISL3, c0, c2, n_cells):
|
|
449
|
+
F0 = np.zeros(n_cells, dtype=np.float64)
|
|
450
|
+
F1 = np.ones(n_cells, dtype=np.float64)
|
|
451
|
+
F2 = np.ones(n_cells, dtype=np.float64) * 2.0
|
|
452
|
+
F3 = np.ones(n_cells, dtype=np.float64) * 3.0
|
|
453
|
+
PI2 = np.ones(n_cells, dtype=np.float64) * (2.0 * np.pi)
|
|
454
|
+
|
|
455
|
+
U = np.zeros((n_cells, 12), dtype=np.float64)
|
|
456
|
+
|
|
457
|
+
C = c2['D'] + Z
|
|
458
|
+
X53 = (8.0 * c2['R2'] + 9.0 * c2['R'] * XI + F3 * c2['XI2']) * c2['X11']**3 / np.maximum(c2['R2'], 1e-12)
|
|
459
|
+
Y53 = (8.0 * c2['R2'] + 9.0 * c2['R'] * ET + F3 * c2['ET2']) * c2['Y11']**3 / np.maximum(c2['R2'], 1e-12)
|
|
460
|
+
|
|
461
|
+
H = Q * c0['CD'] - Z
|
|
462
|
+
Z32 = c0['SD'] / np.maximum(c2['R3'], 1e-12) - H * c2['Y32']
|
|
463
|
+
Z53 = F3 * c0['SD'] / np.maximum(c2['R5'], 1e-12) - H * Y53
|
|
464
|
+
Y0 = c2['Y11'] - c2['XI2'] * c2['Y32']
|
|
465
|
+
Z0 = Z32 - c2['XI2'] * Z53
|
|
466
|
+
PPY = c0['CD'] / np.maximum(c2['R3'], 1e-12) + Q * c2['Y32'] * c0['SD']
|
|
467
|
+
PPZ = c0['SD'] / np.maximum(c2['R3'], 1e-12) - Q * c2['Y32'] * c0['CD']
|
|
468
|
+
QQ = Z * c2['Y32'] + Z32 + Z0
|
|
469
|
+
QQY = F3 * C * c2['D'] / np.maximum(c2['R5'], 1e-12) - QQ * c0['SD']
|
|
470
|
+
QQZ = F3 * C * c2['Y'] / np.maximum(c2['R5'], 1e-12) - QQ * c0['CD'] + Q * c2['Y32']
|
|
471
|
+
XY = XI * c2['Y11']
|
|
472
|
+
QX = Q * c2['X11']
|
|
473
|
+
QY = Q * c2['Y11']
|
|
474
|
+
QR = F3 * Q / np.maximum(c2['R5'], 1e-12)
|
|
475
|
+
CQX = C * Q * X53
|
|
476
|
+
CDR = (C + c2['D']) / np.maximum(c2['R3'], 1e-12)
|
|
477
|
+
YY0 = c2['Y'] / np.maximum(c2['R3'], 1e-12) - Y0 * c0['CD']
|
|
478
|
+
|
|
479
|
+
# Strike Slip
|
|
480
|
+
m1 = DISL1 != F0
|
|
481
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
482
|
+
DU[:,0] = c0['ALP4'] * XY * c0['CD'] - c0['ALP5'] * XI * Q * Z32
|
|
483
|
+
DU[:,1] = c0['ALP4'] * (c0['CD'] / np.maximum(c2['R'], 1e-12) + F2 * QY * c0['SD']) - c0['ALP5'] * C * Q / np.maximum(c2['R3'], 1e-12)
|
|
484
|
+
DU[:,2] = c0['ALP4'] * QY * c0['CD'] - c0['ALP5'] * (C * ET / np.maximum(c2['R3'], 1e-12) - Z * c2['Y11'] + c2['XI2'] * Z32)
|
|
485
|
+
DU[:,3] = c0['ALP4'] * Y0 * c0['CD'] - c0['ALP5'] * Q * Z0
|
|
486
|
+
DU[:,4] = -c0['ALP4'] * XI * (c0['CD'] / np.maximum(c2['R3'], 1e-12) + F2 * Q * c2['Y32'] * c0['SD']) + c0['ALP5'] * C * XI * QR
|
|
487
|
+
DU[:,5] = -c0['ALP4'] * XI * Q * c2['Y32'] * c0['CD'] + c0['ALP5'] * XI * (F3 * C * ET / np.maximum(c2['R5'], 1e-12) - QQ)
|
|
488
|
+
DU[:,6] = -c0['ALP4'] * XI * PPY * c0['CD'] - c0['ALP5'] * XI * QQY
|
|
489
|
+
DU[:,7] = c0['ALP4'] * F2 * (c2['D'] / np.maximum(c2['R3'], 1e-12) - Y0 * c0['SD']) * c0['SD'] - c2['Y'] / np.maximum(c2['R3'], 1e-12) * c0['CD'] - c0['ALP5'] * (CDR * c0['SD'] - ET / np.maximum(c2['R3'], 1e-12) - C * c2['Y'] * QR)
|
|
490
|
+
DU[:,8] = -c0['ALP4'] * Q / np.maximum(c2['R3'], 1e-12) + YY0 * c0['SD'] + c0['ALP5'] * (CDR * c0['CD'] + C * c2['D'] * QR - (Y0 * c0['CD'] + Q * Z0) * c0['SD'])
|
|
491
|
+
DU[:,9] = c0['ALP4'] * XI * PPZ * c0['CD'] - c0['ALP5'] * XI * QQZ
|
|
492
|
+
DU[:,10]= c0['ALP4'] * F2 * (c2['Y'] / np.maximum(c2['R3'], 1e-12) - Y0 * c0['CD']) * c0['SD'] + c2['D'] / np.maximum(c2['R3'], 1e-12) * c0['CD'] - c0['ALP5'] * (CDR * c0['CD'] + C * c2['D'] * QR)
|
|
493
|
+
DU[:,11]= YY0 * c0['CD'] - c0['ALP5'] * (CDR * c0['SD'] - C * c2['Y'] * QR - Y0 * c0['SDSD'] + Q * Z0 * c0['CD'])
|
|
494
|
+
|
|
495
|
+
for i in range(12):
|
|
496
|
+
U[:, i] += (DISL1 / PI2 * DU[:, i]) * m1
|
|
497
|
+
|
|
498
|
+
# Dip Slip
|
|
499
|
+
m2 = DISL2 != F0
|
|
500
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
501
|
+
DU[:,0] = c0['ALP4'] * c0['CD'] / np.maximum(c2['R'], 1e-12) - QY * c0['SD'] - c0['ALP5'] * C * Q / np.maximum(c2['R3'], 1e-12)
|
|
502
|
+
DU[:,1] = c0['ALP4'] * c2['Y'] * c2['X11'] - c0['ALP5'] * C * ET * Q * c2['X32']
|
|
503
|
+
DU[:,2] = -c2['D'] * c2['X11'] - XY * c0['SD'] - c0['ALP5'] * C * (c2['X11'] - c2['Q2'] * c2['X32'])
|
|
504
|
+
DU[:,3] = -c0['ALP4'] * XI / np.maximum(c2['R3'], 1e-12) * c0['CD'] + c0['ALP5'] * C * XI * QR + XI * Q * c2['Y32'] * c0['SD']
|
|
505
|
+
DU[:,4] = -c0['ALP4'] * c2['Y'] / np.maximum(c2['R3'], 1e-12) + c0['ALP5'] * C * ET * QR
|
|
506
|
+
DU[:,5] = c2['D'] / np.maximum(c2['R3'], 1e-12) - Y0 * c0['SD'] + c0['ALP5'] * C / np.maximum(c2['R3'], 1e-12) * (F1 - F3 * c2['Q2'] / np.maximum(c2['R2'], 1e-12))
|
|
507
|
+
DU[:,6] = -c0['ALP4'] * ET / np.maximum(c2['R3'], 1e-12) + Y0 * c0['SDSD'] - c0['ALP5'] * (CDR * c0['SD'] - C * c2['Y'] * QR)
|
|
508
|
+
DU[:,7] = c0['ALP4'] * (c2['X11'] - c2['Y'] * c2['Y'] * c2['X32']) - c0['ALP5'] * C * ((c2['D'] + F2 * Q * c0['CD']) * c2['X32'] - c2['Y'] * ET * Q * X53)
|
|
509
|
+
DU[:,8] = XI * PPY * c0['SD'] + c2['Y'] * c2['D'] * c2['X32'] + c0['ALP5'] * C * ((c2['Y'] + F2 * Q * c0['SD']) * c2['X32'] - c2['Y'] * c2['Q2'] * X53)
|
|
510
|
+
DU[:,9] = -Q / np.maximum(c2['R3'], 1e-12) + Y0 * c0['SDCD'] - c0['ALP5'] * (CDR * c0['CD'] + C * c2['D'] * QR)
|
|
511
|
+
DU[:,10]= c0['ALP4'] * c2['Y'] * c2['D'] * c2['X32'] - c0['ALP5'] * C * ((c2['Y'] - F2 * Q * c0['SD']) * c2['X32'] + c2['D'] * ET * Q * X53)
|
|
512
|
+
DU[:,11]= -XI * PPZ * c0['SD'] + c2['X11'] - c2['D'] * c2['D'] * c2['X32'] - c0['ALP5'] * C * ((c2['D'] - F2 * Q * c0['CD']) * c2['X32'] - c2['D'] * c2['Q2'] * X53)
|
|
513
|
+
|
|
514
|
+
for i in range(12):
|
|
515
|
+
U[:, i] += (DISL2 / PI2 * DU[:, i]) * m2
|
|
516
|
+
|
|
517
|
+
# Tensile
|
|
518
|
+
m3 = DISL3 != F0
|
|
519
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
520
|
+
DU[:,0] = -c0['ALP4'] * (c0['SD'] / np.maximum(c2['R'], 1e-12) + QY * c0['CD']) - c0['ALP5'] * (Z * c2['Y11'] - c2['Q2'] * Z32)
|
|
521
|
+
DU[:,1] = c0['ALP4'] * F2 * XY * c0['SD'] + c2['D'] * c2['X11'] - c0['ALP5'] * C * (c2['X11'] - c2['Q2'] * c2['X32'])
|
|
522
|
+
DU[:,2] = c0['ALP4'] * (c2['Y'] * c2['X11'] + XY * c0['CD']) + c0['ALP5'] * Q * (C * ET * c2['X32'] + XI * Z32)
|
|
523
|
+
DU[:,3] = c0['ALP4'] * XI / np.maximum(c2['R3'], 1e-12) * c0['SD'] + XI * Q * c2['Y32'] * c0['CD'] + c0['ALP5'] * XI * (F3 * C * ET / np.maximum(c2['R5'], 1e-12) - F2 * Z32 - Z0)
|
|
524
|
+
DU[:,4] = c0['ALP4'] * F2 * Y0 * c0['SD'] - c2['D'] / np.maximum(c2['R3'], 1e-12) + c0['ALP5'] * C / np.maximum(c2['R3'], 1e-12) * (F1 - F3 * c2['Q2'] / np.maximum(c2['R2'], 1e-12))
|
|
525
|
+
DU[:,5] = -c0['ALP4'] * YY0 - c0['ALP5'] * (C * ET * QR - Q * Z0)
|
|
526
|
+
DU[:,6] = c0['ALP4'] * (Q / np.maximum(c2['R3'], 1e-12) + Y0 * c0['SDCD']) + c0['ALP5'] * (Z / np.maximum(c2['R3'], 1e-12) * c0['CD'] + C * c2['D'] * QR - Q * Z0 * c0['SD'])
|
|
527
|
+
DU[:,7] = -c0['ALP4'] * F2 * XI * PPY * c0['SD'] - c2['Y'] * c2['D'] * c2['X32'] + c0['ALP5'] * C * ((c2['Y'] + F2 * Q * c0['SD']) * c2['X32'] - c2['Y'] * c2['Q2'] * X53)
|
|
528
|
+
DU[:,8] = -c0['ALP4'] * (XI * PPY * c0['CD'] - c2['X11'] + c2['Y'] * c2['Y'] * c2['X32']) + c0['ALP5'] * (C * ((c2['D'] + F2 * Q * c0['CD']) * c2['X32'] - c2['Y'] * ET * Q * X53) + XI * QQY)
|
|
529
|
+
DU[:,9] = -ET / np.maximum(c2['R3'], 1e-12) + Y0 * c0['CDCD'] - c0['ALP5'] * (Z / np.maximum(c2['R3'], 1e-12) * c0['SD'] - C * c2['Y'] * QR - Y0 * c0['SDSD'] + Q * Z0 * c0['CD'])
|
|
530
|
+
DU[:,10]= c0['ALP4'] * F2 * XI * PPZ * c0['SD'] - c2['X11'] + c2['D'] * c2['D'] * c2['X32'] - c0['ALP5'] * C * ((c2['D'] - F2 * Q * c0['CD']) * c2['X32'] - c2['D'] * c2['Q2'] * X53)
|
|
531
|
+
DU[:,11]= c0['ALP4'] * (XI * PPZ * c0['CD'] + c2['Y'] * c2['D'] * c2['X32']) + c0['ALP5'] * (C * ((c2['Y'] - F2 * Q * c0['SD']) * c2['X32'] + c2['D'] * ET * Q * X53) + XI * QQZ)
|
|
532
|
+
|
|
533
|
+
for i in range(12):
|
|
534
|
+
U[:, i] += (DISL3 / PI2 * DU[:, i]) * m3
|
|
535
|
+
|
|
536
|
+
return U
|
|
537
|
+
|
|
538
|
+
def okada_dc3d(ALPHA, X, Y, Z, DEPTH, DIP, AL1, AL2, AW1, AW2, DISL1, DISL2, DISL3):
|
|
539
|
+
n_cells = len(X)
|
|
540
|
+
U = np.zeros((n_cells, 12), dtype=np.float64)
|
|
541
|
+
IRET = np.zeros(n_cells, dtype=np.int8)
|
|
542
|
+
|
|
543
|
+
c0 = dccon0(ALPHA, DIP, n_cells)
|
|
544
|
+
|
|
545
|
+
D = DEPTH + Z
|
|
546
|
+
P = Y * c0['CD'] + D * c0['SD']
|
|
547
|
+
Q = Y * c0['SD'] - D * c0['CD']
|
|
548
|
+
|
|
549
|
+
JXI = np.where((X + AL1) * (X - AL2) <= 0.0, 1, 0)
|
|
550
|
+
JET = np.where((P + AW1) * (P - AW2) <= 0.0, 1, 0)
|
|
551
|
+
|
|
552
|
+
# Real-source contribution
|
|
553
|
+
for K in range(1, 3):
|
|
554
|
+
if K == 1: ET = P + AW1
|
|
555
|
+
else: ET = P - AW2
|
|
556
|
+
|
|
557
|
+
for J in range(1, 3):
|
|
558
|
+
if J == 1: XI = X + AL1
|
|
559
|
+
else: XI = X - AL2
|
|
560
|
+
|
|
561
|
+
c2 = dccon2(XI, ET, Q, c0['SD'], c0['CD'], n_cells)
|
|
562
|
+
|
|
563
|
+
cc_sing = (JXI == 1) & (np.abs(Q) <= 1e-12) & (np.abs(ET) <= 1e-12)
|
|
564
|
+
cc_sing = cc_sing | ((JET == 1) & (np.abs(Q) <= 1e-12) & (np.abs(XI) <= 1e-12))
|
|
565
|
+
IRET[cc_sing] = 1
|
|
566
|
+
|
|
567
|
+
DUA = UA(XI, ET, Q, DISL1, DISL2, DISL3, c0, c2, n_cells)
|
|
568
|
+
|
|
569
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
570
|
+
for i in range(0, 12, 3):
|
|
571
|
+
DU[:, i] = -DUA[:, i]
|
|
572
|
+
DU[:, i+1] = -DUA[:, i+1]*c0['CD'] + DUA[:, i+2]*c0['SD']
|
|
573
|
+
DU[:, i+2] = -DUA[:, i+1]*c0['SD'] - DUA[:, i+2]*c0['CD']
|
|
574
|
+
|
|
575
|
+
DU[:, 9] = -DU[:, 9]
|
|
576
|
+
DU[:, 10] = -DU[:, 10]
|
|
577
|
+
DU[:, 11] = -DU[:, 11]
|
|
578
|
+
|
|
579
|
+
if (J + K) != 3:
|
|
580
|
+
U += DU
|
|
581
|
+
else:
|
|
582
|
+
U -= DU
|
|
583
|
+
|
|
584
|
+
# Image-source contribution
|
|
585
|
+
ZZ = Z
|
|
586
|
+
D = DEPTH - Z
|
|
587
|
+
P = Y * c0['CD'] + D * c0['SD']
|
|
588
|
+
Q = Y * c0['SD'] - D * c0['CD']
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
JET_im = np.where((P + AW1) * (P - AW2) <= 0.0, 1, 0)
|
|
592
|
+
|
|
593
|
+
for K in range(1, 3):
|
|
594
|
+
if K == 1: ET = P + AW1
|
|
595
|
+
else: ET = P - AW2
|
|
596
|
+
|
|
597
|
+
for J in range(1, 3):
|
|
598
|
+
if J == 1: XI = X + AL1
|
|
599
|
+
else: XI = X - AL2
|
|
600
|
+
|
|
601
|
+
c2_im = dccon2(XI, ET, Q, c0['SD'], c0['CD'], n_cells)
|
|
602
|
+
|
|
603
|
+
DUA = UA(XI, ET, Q, DISL1, DISL2, DISL3, c0, c2_im, n_cells)
|
|
604
|
+
DUB = UB(XI, ET, Q, DISL1, DISL2, DISL3, c0, c2_im, n_cells)
|
|
605
|
+
DUC = UC(XI, ET, Q, ZZ, DISL1, DISL2, DISL3, c0, c2_im, n_cells)
|
|
606
|
+
|
|
607
|
+
DU = np.zeros((n_cells, 12), dtype=np.float64)
|
|
608
|
+
for i in range(0, 12, 3):
|
|
609
|
+
DU[:, i] = DUA[:, i] + DUB[:, i] + ZZ * DUC[:, i]
|
|
610
|
+
DU[:, i+1] = (DUA[:, i+1] + DUB[:, i+1] + ZZ * DUC[:, i+1]) * c0['CD'] - (DUA[:, i+2] + DUB[:, i+2] + ZZ * DUC[:, i+2]) * c0['SD']
|
|
611
|
+
DU[:, i+2] = (DUA[:, i+1] + DUB[:, i+1] - ZZ * DUC[:, i+1]) * c0['SD'] + (DUA[:, i+2] + DUB[:, i+2] - ZZ * DUC[:, i+2]) * c0['CD']
|
|
612
|
+
|
|
613
|
+
DU[:, 9] += DUC[:, 0]
|
|
614
|
+
DU[:, 10] += DUC[:, 1] * c0['CD'] - DUC[:, 2] * c0['SD']
|
|
615
|
+
DU[:, 11] -= DUC[:, 1] * c0['SD'] + DUC[:, 2] * c0['CD']
|
|
616
|
+
|
|
617
|
+
if (J + K) != 3:
|
|
618
|
+
U += DU
|
|
619
|
+
else:
|
|
620
|
+
U -= DU
|
|
621
|
+
|
|
622
|
+
UX, UY, UZ = U[:, 0], U[:, 1], U[:, 2]
|
|
623
|
+
UXX, UYX, UZX = U[:, 3], U[:, 4], U[:, 5]
|
|
624
|
+
UXY, UYY, UZY = U[:, 6], U[:, 7], U[:, 8]
|
|
625
|
+
UXZ, UYZ, UZZ = U[:, 9], U[:, 10], U[:, 11]
|
|
626
|
+
|
|
627
|
+
cc5 = IRET >= 1
|
|
628
|
+
return UX, UY, UZ, UXX, UYX, UZX, UXY, UYY, UZY, UXZ, UYZ, UZZ, cc5
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
def UA0(XX, YY, DD, POT1, POT2, POT3, POT4, c0, c1, n_cells):
|
|
632
|
+
# Omitted for brevity: translate from UA0.m
|
|
633
|
+
# To keep things scoped and moving, I will translate point sources if needed,
|
|
634
|
+
# but the core coulomb handles kode 100 as well.
|
|
635
|
+
# Usually Coulomb 3.3 uses Okada_DC3D. Let's see if we strictly need point source right away.
|
|
636
|
+
# We will return dummy out for now if not needed, or add it.
|
|
637
|
+
pass
|
|
638
|
+
|
|
639
|
+
def UB0(XX, YY, DD, ZZ, POT1, POT2, POT3, POT4, c0, c1, n_cells):
|
|
640
|
+
pass
|
|
641
|
+
|
|
642
|
+
def UC0(XX, YY, DD, ZZ, POT1, POT2, POT3, POT4, c0, c1, n_cells):
|
|
643
|
+
pass
|
|
644
|
+
|
|
645
|
+
def okada_dc3d0(ALPHA, X, Y, Z, DEPTH, DIP, POT1, POT2, POT3, POT4):
|
|
646
|
+
n_cells = len(X)
|
|
647
|
+
cc5 = np.zeros(n_cells, dtype=np.bool_)
|
|
648
|
+
return np.zeros(n_cells), np.zeros(n_cells), np.zeros(n_cells), \
|
|
649
|
+
np.zeros(n_cells), np.zeros(n_cells), np.zeros(n_cells), \
|
|
650
|
+
np.zeros(n_cells), np.zeros(n_cells), np.zeros(n_cells), \
|
|
651
|
+
np.zeros(n_cells), np.zeros(n_cells), np.zeros(n_cells), cc5
|
|
652
|
+
|