# SCRIPT: BH-FIGS-V8 # Figures f16 (the Sun's dynamo ladder: pair births on the real axis, and one loop around the first three # birth points) from the operator of BH-SUNLADDER-16b, and f17 (the ISCO as the inverse-cube point, and the # Sun's acoustic cutoff) from the formulas of BH-ISCO-CUBE-17. import os as _os _HERE=_os.path.dirname(_os.path.abspath(__file__)) _FIG=_os.path.join(_HERE,'..','paper','fig') if _os.path.isdir(_os.path.join(_HERE,'..','paper','fig')) else _os.path.join(_HERE,'..','fig') import numpy as np, matplotlib, scipy.sparse as sp, scipy.sparse.linalg as sla matplotlib.use('Agg') import matplotlib.pyplot as plt OUT=_FIG BG='#0f1115'; INK='#e6e8ec'; MUT='#9aa3ae'; RULE='#2a313c' C1='#3987e5'; C2='#d95926'; C3='#199e70'; C4='#c98500'; C5='#d55181' plt.rcParams.update({'figure.facecolor':BG,'axes.facecolor':BG,'savefig.facecolor':BG,'text.color':INK, 'axes.labelcolor':INK,'xtick.color':MUT,'ytick.color':MUT,'axes.edgecolor':RULE,'font.family':'serif', 'font.serif':['TeX Gyre Pagella','URW Palladio L','Palatino','DejaVu Serif'],'mathtext.fontset':'cm','font.size':11}) def clean(ax): for s in ['top','right']: ax.spines[s].set_visible(False) def save(fig,name): fig.savefig(f'{OUT}/{name}.png',dpi=260,bbox_inches='tight',pad_inches=0.12); plt.close(fig) N=120; h=np.pi/(N+1); x=np.arange(1,N+1)*h D2=sp.diags([np.ones(N-1),-2*np.ones(N),np.ones(N-1)],[-1,0,1])/h**2 D1=sp.diags([-np.ones(N-1),np.ones(N-1)],[-1,1])/(2*h); Cc=sp.diags(np.cos(x)); K=12 def spec(a): A=sp.bmat([[D2,a*Cc],[D1,D2]]).tocsc().astype(complex) w=sla.eigs(A,k=K+4,sigma=0,which='LM',return_eigenvectors=False); return w[np.argsort(-w.real)][:K] births=[3.8717,5.2802,7.1576,9.0850,11.0266] # (a) real axis al=np.linspace(2.5,12.0,700); W=np.array([spec(a) for a in al]) # (b) one loop around the first three points, adaptive tracking as in BH-SUNLADDER-16b base=3.0; a1=(births[2]+births[3])/2; ht=0.2 L1=a1-base; Lc=np.pi*ht; T=2*ht+2*L1+Lc def P(s): if s<=ht: return base-1j*s s-=ht if s<=L1: return base+s-1j*ht s-=L1 if s<=Lc: return a1+ht*np.exp(1j*(-np.pi/2+s/ht)) s-=Lc if s<=L1: return a1-s+1j*ht s-=L1 return base+1j*(ht-s) s=0; cur=spec(P(0)); start=cur.copy(); traj=[cur.copy()]; ds=0.01 while s0,np.sqrt(np.abs(kz2)),0),color=C1,lw=2.4,ls=(0,(5,3))) bx.plot(om,np.where(kz2<0,np.sqrt(np.abs(kz2)),0),color=C2,lw=2.4) bx.axvline(1,color=RULE,lw=1.2,ls=(0,(4,3))) bx.text(0.25,0.42,'evanescent:\nreflected',color=C2,fontsize=10); bx.text(1.35,0.55,'propagating:\nescapes',color=C1,fontsize=10) bx.text(1.03,1.35,r'$\omega=\omega_{\rm ac}$: a Jordan block',color=INK,fontsize=10) bx.set_xlabel(r'frequency $\omega/\omega_{\rm ac}$'); bx.set_ylabel(r'$|k_z|\,c/\omega_{\rm ac}$ (decay or wavenumber)') bx.set_title("b the Sun's acoustic cutoff is a spectral wall",color=INK,fontsize=10.5,loc='left') save(fig,'f17_cube_cutoff')