8
8
Note that mode-matching (such as NFC-HOA, SDM) are equivalent
9
9
to ESA in their specific geometries (spherical/circular, planar/linear).
10
10
11
+ .. plot::
12
+ :context: reset
13
+
14
+ import matplotlib.pyplot as plt
15
+ import numpy as np
16
+ import sfs
17
+
18
+ plt.rcParams['figure.figsize'] = 6, 6
19
+
20
+ f = 343 # Hz
21
+ omega = 2 * np.pi * f # rad / s
22
+ k = omega / sfs.default.c # rad / m
23
+
24
+ npw = sfs.util.direction_vector(np.radians(-45))
25
+ xs = np.array([-0.828427, 0.828427, 0])
26
+
27
+ grid = sfs.util.xyz_grid([-1, 5], [-5, 1], 0, spacing=0.02)
28
+ dx, L = 0.05, 4 # m
29
+ N = int(L / dx)
30
+ array = sfs.array.edge(N, dx, center=[0, 0, 0],
31
+ orientation=[0, -1, 0])
32
+
33
+ xref = np.array([2, -2, 0])
34
+ x_norm = np.linalg.norm(xs - xref)
35
+ norm_ls = (np.sqrt(8 * np.pi * k * x_norm) *
36
+ np.exp(+1j * np.pi / 4) *
37
+ np.exp(-1j * k * x_norm))
38
+ norm_pw = np.exp(+1j * 4*np.pi*np.sqrt(2))
39
+
40
+
41
+ def plot(d, selection, secondary_source, norm_ref):
42
+ # the series expansion is numerically tricky, hence
43
+ d = np.nan_to_num(d)
44
+ # especially handle the origin loudspeaker
45
+ d[N] = 0 # as it tends to nan/inf
46
+ p = sfs.fd.synthesize(d, selection, array, secondary_source, grid=grid)
47
+ sfs.plot2d.amplitude(p * norm_ref, grid)
48
+ sfs.plot2d.loudspeakers(array.x, array.n,
49
+ selection * array.a, size=0.15)
50
+ plt.xlim(-0.5, 4.5)
51
+ plt.ylim(-4.5, 0.5)
52
+ plt.grid(True)
53
+
11
54
"""
12
55
import numpy as _np
13
56
from scipy .special import jn as _jn , hankel2 as _hankel2
@@ -59,6 +102,15 @@ def plane_2d_edge(omega, x0, n=[0, 1, 0], *, alpha=_np.pi*3/2, Nc=None,
59
102
60
103
Derived from :cite:`Spors2016`
61
104
105
+ Examples
106
+ --------
107
+ .. plot::
108
+ :context: close-figs
109
+
110
+ d, selection, secondary_source = sfs.fd.esa.plane_2d_edge(
111
+ omega, array.x, npw, alpha=np.pi*3/2)
112
+ plot(d, selection, secondary_source, norm_pw)
113
+
62
114
"""
63
115
x0 = _np .asarray (x0 )
64
116
n = _util .normalize_vector (n )
@@ -71,7 +123,7 @@ def plane_2d_edge(omega, x0, n=[0, 1, 0], *, alpha=_np.pi*3/2, Nc=None,
71
123
phi = _np .where (phi < 0 , phi + 2 * _np .pi , phi )
72
124
73
125
if Nc is None :
74
- Nc = _np .ceil (2 * k * _np .max (r ) * alpha / _np .pi )
126
+ Nc = int ( _np .ceil (2 * k * _np .max (r ) * alpha / _np .pi ) )
75
127
76
128
epsilon = _np .ones (Nc ) # weights for series expansion
77
129
epsilon [0 ] = 2
@@ -130,6 +182,15 @@ def plane_2d_edge_dipole_ssd(omega, x0, n=[0, 1, 0], *, alpha=_np.pi*3/2,
130
182
131
183
Derived from :cite:`Spors2016`
132
184
185
+ Examples
186
+ --------
187
+ .. plot::
188
+ :context: close-figs
189
+
190
+ d, selection, secondary_source = sfs.fd.esa.plane_2d_edge_dipole_ssd(
191
+ omega, array.x, npw, alpha=np.pi*3/2)
192
+ plot(d, selection, secondary_source, norm_ref=1)
193
+
133
194
"""
134
195
x0 = _np .asarray (x0 )
135
196
n = _util .normalize_vector (n )
@@ -142,7 +203,7 @@ def plane_2d_edge_dipole_ssd(omega, x0, n=[0, 1, 0], *, alpha=_np.pi*3/2,
142
203
phi = _np .where (phi < 0 , phi + 2 * _np .pi , phi )
143
204
144
205
if Nc is None :
145
- Nc = _np .ceil (2 * k * _np .max (r ) * alpha / _np .pi )
206
+ Nc = int ( _np .ceil (2 * k * _np .max (r ) * alpha / _np .pi ) )
146
207
147
208
epsilon = _np .ones (Nc ) # weights for series expansion
148
209
epsilon [0 ] = 2
@@ -153,7 +214,8 @@ def plane_2d_edge_dipole_ssd(omega, x0, n=[0, 1, 0], *, alpha=_np.pi*3/2,
153
214
d = d + 1 / epsilon [m ] * _np .exp (1j * nu * _np .pi / 2 ) * _np .cos (nu * phi_s ) \
154
215
* _np .cos (nu * phi ) * _jn (nu , k * r )
155
216
156
- return 4 * _np .pi / alpha * d
217
+ selection = _util .source_selection_all (len (x0 ))
218
+ return 4 * _np .pi / alpha * d , selection , _secondary_source_line (omega , c )
157
219
158
220
159
221
def line_2d_edge (omega , x0 , xs , * , alpha = _np .pi * 3 / 2 , Nc = None , c = None ):
@@ -197,6 +259,15 @@ def line_2d_edge(omega, x0, xs, *, alpha=_np.pi*3/2, Nc=None, c=None):
197
259
198
260
Derived from :cite:`Spors2016`
199
261
262
+ Examples
263
+ --------
264
+ .. plot::
265
+ :context: close-figs
266
+
267
+ d, selection, secondary_source = sfs.fd.esa.line_2d_edge(
268
+ omega, array.x, xs, alpha=np.pi*3/2)
269
+ plot(d, selection, secondary_source, norm_ls)
270
+
200
271
"""
201
272
x0 = _np .asarray (x0 )
202
273
k = _util .wavenumber (omega , c )
@@ -211,7 +282,7 @@ def line_2d_edge(omega, x0, xs, *, alpha=_np.pi*3/2, Nc=None, c=None):
211
282
phi = _np .where (phi < 0 , phi + 2 * _np .pi , phi )
212
283
213
284
if Nc is None :
214
- Nc = _np .ceil (2 * k * _np .max (r ) * alpha / _np .pi )
285
+ Nc = int ( _np .ceil (2 * k * _np .max (r ) * alpha / _np .pi ) )
215
286
216
287
epsilon = _np .ones (Nc ) # weights for series expansion
217
288
epsilon [0 ] = 2
@@ -272,6 +343,15 @@ def line_2d_edge_dipole_ssd(omega, x0, xs, *, alpha=_np.pi*3/2, Nc=None,
272
343
273
344
Derived from :cite:`Spors2016`
274
345
346
+ Examples
347
+ --------
348
+ .. plot::
349
+ :context: close-figs
350
+
351
+ d, selection, secondary_source = sfs.fd.esa.line_2d_edge_dipole_ssd(
352
+ omega, array.x, xs, alpha=np.pi*3/2)
353
+ plot(d, selection, secondary_source, norm_ref=1)
354
+
275
355
"""
276
356
x0 = _np .asarray (x0 )
277
357
k = _util .wavenumber (omega , c )
@@ -286,7 +366,7 @@ def line_2d_edge_dipole_ssd(omega, x0, xs, *, alpha=_np.pi*3/2, Nc=None,
286
366
phi = _np .where (phi < 0 , phi + 2 * _np .pi , phi )
287
367
288
368
if Nc is None :
289
- Nc = _np .ceil (2 * k * _np .max (r ) * alpha / _np .pi )
369
+ Nc = int ( _np .ceil (2 * k * _np .max (r ) * alpha / _np .pi ) )
290
370
291
371
epsilon = _np .ones (Nc ) # weights for series expansion
292
372
epsilon [0 ] = 2
@@ -299,7 +379,8 @@ def line_2d_edge_dipole_ssd(omega, x0, xs, *, alpha=_np.pi*3/2, Nc=None,
299
379
d [idx ] = d [idx ] + f [idx ] * _jn (nu , k * r [idx ]) * _hankel2 (nu , k * r_s )
300
380
d [~ idx ] = d [~ idx ] + f [~ idx ] * _jn (nu , k * r_s ) * _hankel2 (nu , k * r [~ idx ])
301
381
302
- return - 1j * _np .pi / alpha * d
382
+ selection = _util .source_selection_all (len (x0 ))
383
+ return - 1j * _np .pi / alpha * d , selection , _secondary_source_line (omega , c )
303
384
304
385
305
386
def point_25d_edge (omega , x0 , xs , * , xref = [2 , - 2 , 0 ], alpha = _np .pi * 3 / 2 ,
@@ -346,6 +427,15 @@ def point_25d_edge(omega, x0, xs, *, xref=[2, -2, 0], alpha=_np.pi*3/2,
346
427
347
428
Derived from :cite:`Spors2016`
348
429
430
+ Examples
431
+ --------
432
+ .. plot::
433
+ :context: close-figs
434
+
435
+ d, selection, secondary_source = sfs.fd.esa.point_25d_edge(
436
+ omega, array.x, xs, xref=xref, alpha=np.pi*3/2)
437
+ plot(d, selection, secondary_source, norm_ref=1)
438
+
349
439
"""
350
440
x0 = _np .asarray (x0 )
351
441
xs = _np .asarray (xs )
0 commit comments