等振幅リニアアレーのアレーファクタ

モジュールのインポートや初期設定など

import numpy as np  
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
np.set_printoptions(precision=5)
import scienceplots
#Warning : As of version 2.0.0, you need to add import scienceplots before setting the style (plt.style.use('science')).
plt.style.use(['science', 'notebook'])
#plt.rcParams['font.family'] = 'Times New Roman' # font familyの設定
plt.rcParams['font.family'] = 'serif' # font familyの設定
plt.rcParams['mathtext.fontset'] = 'cm' # math fontの設定
#plt.rcParams["font.size"] = 12

ユーザ関数

任意の数の配列をフォーマット付き出力するため,
def table(*args):
    n1, n2 = np.shape(args)
    for i in range(n2):
        [print(f'{args[j][i]:8.3f}',end=' ') for j in range(n1)]
        print("")
    return
アレーファクタは,
def afactor(n,u):
    f = np.sin(n*u/2)/np.sin(u/2)/n
    return f
パラーメータ $u$ は,
def theta_to_u(th,dd,th0):
    akd = 2*np.pi*dd
    u = akd * (np.cos(th)-np.cos(th0))
    return u
素子間隔 $d = \lambda$ の5素子リニアアレーを $\theta_0=30^\circ $ の方向に共相励振するため,
n = 5 # N elements
dd = 1.0 # Element spacing normalized by wave-length [mm]
th0deg = 30 # Beam direction [deg]
akd = 2*np.pi*dd
qq = 180.0/np.pi
th0 = th0deg/qq
th = np.linspace(0, np.pi, 1800+1)
thdeg = th*qq
u = akd * (np.cos(th)-np.cos(th0))
uoverpi = u/np.pi
この条件よりアレーファクタを計算して,
f = afactor(n,u)
p = 20.0*np.log10(np.abs(f))
アレーファクタのピーク値を求めると,
locs, _ = find_peaks(p) # ピーク値
print(f"{'u/pi[rad]':>10s} {'th[deg]':>10s} {'f(u)':>10s} {'p(th)[dB]':>10s}")
for i in locs:
    print(f"{uoverpi[i]:10.5f} {thdeg[i]:10.5f} {f[i]:10.5f} {p[i]:10.5f}")
 u/pi[rad]    th[deg]       f(u)  p(th)[dB]
  -0.00000   30.00000    1.00000    0.00000
  -0.57919   54.80000   -0.24999  -12.04160
  -0.99905   68.50000    0.19999  -13.97963
  -1.41918   81.00000   -0.25000  -12.04124
  -2.00002   97.70000    1.00000   -0.00000
  -2.58045  115.10000   -0.25000  -12.04120
  -2.99881  129.30000    0.19999  -13.97976
  -3.41883  147.50000   -0.25000  -12.04134
これより,サイドローブレベルのピーク値は,
pp = p[locs][p[locs]<-0.001]
peak_sl = 0.0
if len(pp)!=0:
    peak_sl = np.max(pp)
print(peak_sl,'[dB]') # ピークサイドローブレベル
-12.041199919690888 [dB]
また,ヌル点は,
locs_null, _ = find_peaks(-p) # ヌル点
print(f"{'u/pi[rad]':>10s} {'th[deg]':>10s} {'f(u)':>10s} {'p(th)[dB]':>10s}")
for i in locs_null:
    print(f"{uoverpi[i]:10.5f} {thdeg[i]:10.5f} {f[i]:10.5f} {p[i]:10.5f}")
 u/pi[rad]    th[deg]       f(u)  p(th)[dB]
  -0.39899   48.20000    0.00272  -51.32109
  -0.79928   62.20000   -0.00119  -58.46213
  -1.20094   74.60000   -0.00155  -56.18828
  -1.59950   86.20000   -0.00133  -57.54431
  -2.39966  109.50000    0.00090  -60.94251
  -2.80076  122.30000    0.00125  -58.08036
  -3.19951  137.20000    0.00081  -61.84951
  -3.60046  159.10000    0.00123  -58.20280
放射パターンは,
print(f"{'th[deg]':>8s} {'u/pi':>8s} {'f':>8s} {'p[dB]':>8s}")
table(thdeg[::100],uoverpi[::100],f[::100],p[::100])
 th[deg]     u/pi        f    p[dB]
   0.000    0.268    0.421   -7.505 
  10.000    0.238    0.525   -5.599 
  20.000    0.147    0.798   -1.955 
  30.000   -0.000    1.000    0.000 
  40.000   -0.200    0.647   -3.777 
  50.000   -0.446   -0.111  -19.121 
  60.000   -0.732   -0.111  -19.057 
  70.000   -1.048    0.186  -14.587 
  80.000   -1.385   -0.241  -12.348 
  90.000   -1.732    0.421   -7.505 
 100.000   -2.079    0.939   -0.547 
 110.000   -2.416   -0.041  -27.648 
 120.000   -2.732   -0.111  -19.057 
 130.000   -3.018    0.198  -14.060 
 140.000   -3.264   -0.105  -19.535 
 150.000   -3.464   -0.235  -12.583 
 160.000   -3.611    0.031  -30.089 
 170.000   -3.702    0.317   -9.974 
 180.000   -3.732    0.421   -7.505
放射パターンをプロットすると,
im = 1 # ピーク値およびナル点のプロットの有無, =0:なし,=1:あり
fig = plt.figure() # グラフ領域の作成
plt.ion()
plt.subplot(2,1,1)
if im == 1:
    plt.plot([0,0],[-1,1],'--',color='gray',alpha=0.5)
    plt.plot([-4,4],[0,0],'--',color='gray',alpha=0.5)
plt.plot(uoverpi,f)
if im == 1:
    plt.plot(uoverpi[locs],f[locs],'.')
    plt.plot(uoverpi[locs_null],np.zeros(len(locs_null)),'.')
plt.axis([-4,4,-1,1])
plt.xlabel(r'$u/\pi = 2d ( \cos \theta - \cos \theta_0)/\lambda$')
plt.ylabel('Array factor $f(u)$')
plt.text(0.95,-0.3,'$N=$'+str(n))
plt.text(0.95,-0.55,'Element spacing: $d = $'+str(dd)+r'$\lambda$')
plt.text(0.95,-0.8,r'Beam direction: $\theta_0 = $'+str(th0deg)+r'$^\circ$')

plt.subplot(2,1,2)
if im == 1:
    plt.plot(np.ones(2)*th0deg,[-50,0],'--',color='gray',alpha=0.5)
    plt.plot([0,180],np.ones(2)*(-3),'--',color='gray',alpha=0.5)
plt.plot(thdeg,p)
if im == 1:
    plt.plot(thdeg[locs],p[locs],'o')
    plt.plot(thdeg[locs_null],np.ones(len(locs_null))*-40,'o')
plt.axis([0, 180, -40, 0])
plt.xlabel(r'Angle $\theta$ [deg]')
plt.ylabel(r'$20 \log_{10} |f(u)|$ [dB]')
plt.text(th0deg-7,2.5,r'$\theta_0 = $'+str(th0deg)+r'$^\circ$')
if peak_sl!=0.0:
    plt.text(35,-10.0,f'Peak sidelobe level $={peak_sl:.2f}$ dB')
plt.xticks(np.linspace(0,180,5))

fig.tight_layout()
fig.savefig('p3_ap_array_factor_N'+str(n)+'_beam'+str(th0deg)+'deg_d'+str(dd)+'wl_im'+str(im)+'.pdf')

上のような素子間隔にすると,グレーティングローブが発生してしまう. 素子間隔を狭くして $d=\lambda/2$ とすると,

$d=0.45\lambda$ では,

5素子リニアアレーをグレーティングローブが発生しないように$\theta_0=60^\circ $ の方向に共相励振するため, 素子間隔 $d = 0.55 \lambda$ として,