diff options
Diffstat (limited to 'openEMS/python/Tutorials')
-rw-r--r-- | openEMS/python/Tutorials/Bent_Patch_Antenna.py | 198 | ||||
-rw-r--r-- | openEMS/python/Tutorials/CRLH_Extraction.py | 239 | ||||
-rw-r--r-- | openEMS/python/Tutorials/Helical_Antenna.py | 191 | ||||
-rw-r--r-- | openEMS/python/Tutorials/MSL_NotchFilter.py | 123 | ||||
-rw-r--r-- | openEMS/python/Tutorials/RCS_Sphere.py | 126 | ||||
-rw-r--r-- | openEMS/python/Tutorials/Rect_Waveguide.py | 125 | ||||
-rw-r--r-- | openEMS/python/Tutorials/Simple_Patch_Antenna.py | 151 |
7 files changed, 1153 insertions, 0 deletions
diff --git a/openEMS/python/Tutorials/Bent_Patch_Antenna.py b/openEMS/python/Tutorials/Bent_Patch_Antenna.py new file mode 100644 index 0000000..ef2cb0e --- /dev/null +++ b/openEMS/python/Tutorials/Bent_Patch_Antenna.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +""" + Bent Patch Antenna Tutorial + + Tested with + - python 3.4 + - openEMS v0.0.33+ + + (C) 2016 Thorsten Liebig <thorsten.liebig@gmx.de> + +""" + +### Import Libraries +import os, tempfile +from pylab import * +from mpl_toolkits.mplot3d import Axes3D + +from CSXCAD import CSXCAD + +from openEMS.openEMS import openEMS +from openEMS.physical_constants import * + + +### Setup the simulation +Sim_Path = os.path.join(tempfile.gettempdir(), 'Bent_Patch') + +post_proc_only = False + +unit = 1e-3 # all length in mm + +f0 = 2.4e9 # center frequency, frequency of interest! +lambda0 = round(C0/f0/unit) # wavelength in mm +fc = 0.5e9 # 20 dB corner frequency + +# patch width in alpha-direction +patch_width = 32 # resonant length in alpha-direction +patch_radius = 50 # radius +patch_length = 40 # patch length in z-direction + +#substrate setup +substrate_epsR = 3.38 +substrate_kappa = 1e-3 * 2*pi*2.45e9 * EPS0*substrate_epsR +substrate_width = 80 +substrate_length = 90 +substrate_thickness = 1.524 +substrate_cells = 4 + +#setup feeding +feed_pos = -5.5 #feeding position in x-direction +feed_width = 2 #feeding port width +feed_R = 50 #feed resistance + +# size of the simulation box +SimBox_rad = 2*100 +SimBox_height = 1.5*200 + +### Setup FDTD parameter & excitation function +FDTD = openEMS(CoordSystem=1) # init a cylindrical FDTD +f0 = 2e9 # center frequency +fc = 1e9 # 20 dB corner frequency +FDTD.SetGaussExcite(f0, fc) +FDTD.SetBoundaryCond(['MUR', 'MUR', 'MUR', 'MUR', 'MUR', 'MUR']) # boundary conditions + +### Setup the Geometry & Mesh +# init a cylindrical mesh +CSX = CSXCAD.ContinuousStructure(CoordSystem=1) +FDTD.SetCSX(CSX) +mesh = CSX.GetGrid() +mesh.SetDeltaUnit(unit) + +### Setup the geometry using cylindrical coordinates +# calculate some width as an angle in radiant +patch_ang_width = patch_width/(patch_radius+substrate_thickness) +substr_ang_width = substrate_width/patch_radius +feed_angle = feed_pos/patch_radius + +# create patch +patch = CSX.AddMetal('patch') # create a perfect electric conductor (PEC) +start = [patch_radius+substrate_thickness, -patch_ang_width/2, -patch_length/2 ] +stop = [patch_radius+substrate_thickness, patch_ang_width/2, patch_length/2 ] +CSX.AddBox(patch, priority=10, start=start, stop=stop, edges2grid='all') # add a box-primitive to the metal property 'patch' + +# create substrate +substrate = CSX.AddMaterial('substrate', epsilon=substrate_epsR, kappa=substrate_kappa ) +start = [patch_radius , -substr_ang_width/2, -substrate_length/2] +stop = [patch_radius+substrate_thickness, substr_ang_width/2, substrate_length/2] +substrate.AddBox(start=start, stop=stop, edges2grid='all') + +# save current density oon the patch +jt_patch = CSX.AddDump('Jt_patch', dump_type=3, file_type=1) +start = [patch_radius+substrate_thickness, -substr_ang_width/2, -substrate_length/2] +stop = [patch_radius+substrate_thickness, +substr_ang_width/2, substrate_length/2] +jt_patch.AddBox(start=start, stop=stop) + +# create ground +gnd = CSX.AddMetal('gnd') # create a perfect electric conductor (PEC) +start = [patch_radius, -substr_ang_width/2, -substrate_length/2] +stop = [patch_radius, +substr_ang_width/2, +substrate_length/2] +gnd.AddBox(priority=10, start=start, stop=stop, edges2grid='all') + +# apply the excitation & resist as a current source +start = [patch_radius , feed_angle, 0] +stop = [patch_radius+substrate_thickness, feed_angle, 0] +port = FDTD.AddLumpedPort(1 ,feed_R, start, stop, 'r', 1.0, priority=50, edges2grid='all') + +### Finalize the Mesh +# add the simulation domain size +mesh.AddLine('r', patch_radius+np.array([-20, SimBox_rad])) +mesh.AddLine('a', [-0.75*pi, 0.75*pi]) +mesh.AddLine('z', [-SimBox_height/2, SimBox_height/2]) + +# add some lines for the substrate +mesh.AddLine('r', patch_radius+np.linspace(0,substrate_thickness,substrate_cells)) + +# generate a smooth mesh with max. cell size: lambda_min / 20 +max_res = C0 / (f0+fc) / unit / 20 +max_ang = max_res/(SimBox_rad+patch_radius) # max res in radiant +mesh.SmoothMeshLines(0, max_res, 1.4) +mesh.SmoothMeshLines(1, max_ang, 1.4) +mesh.SmoothMeshLines(2, max_res, 1.4) + +## Add the nf2ff recording box +nf2ff = FDTD.CreateNF2FFBox() + +### Run the simulation +if 0: # debugging only + CSX_file = os.path.join(Sim_Path, 'bent_patch.xml') + if not os.path.exists(Sim_Path): + os.mkdir(Sim_Path) + CSX.Write2XML(CSX_file) + os.system(r'AppCSXCAD "{}"'.format(CSX_file)) + + +if not post_proc_only: + FDTD.Run(Sim_Path, verbose=3, cleanup=True) + +### Postprocessing & plotting +f = np.linspace(max(1e9,f0-fc),f0+fc,401) +port.CalcPort(Sim_Path, f) +Zin = port.uf_tot / port.if_tot +s11 = port.uf_ref/port.uf_inc +s11_dB = 20.0*np.log10(np.abs(s11)) + +figure() +plot(f/1e9, s11_dB) +grid() +ylabel('s11 (dB)') +xlabel('frequency (GHz)') + +P_in = 0.5*np.real(port.uf_tot * np.conj(port.if_tot)) # antenna feed power + +# plot feed point impedance +figure() +plot( f/1e6, real(Zin), 'k-', linewidth=2, label=r'$\Re(Z_{in})$' ) +grid() +plot( f/1e6, imag(Zin), 'r--', linewidth=2, label=r'$\Im(Z_{in})$' ) +title( 'feed point impedance' ) +xlabel( 'frequency (MHz)' ) +ylabel( 'impedance ($\Omega$)' ) +legend( ) + + +idx = np.where((s11_dB<-10) & (s11_dB==np.min(s11_dB)))[0] +if not len(idx)==1: + print('No resonance frequency found for far-field calulation') +else: + f_res = f[idx[0]] + theta = np.arange(-180.0, 180.0, 2.0) + print("Calculate NF2FF") + nf2ff_res_phi0 = nf2ff.CalcNF2FF(Sim_Path, f_res, theta, 0, center=np.array([patch_radius+substrate_thickness, 0, 0])*unit, read_cached=True, outfile='nf2ff_xz.h5') + + figure(figsize=(15, 7)) + ax = subplot(121, polar=True) + E_norm = 20.0*np.log10(nf2ff_res_phi0.E_norm/np.max(nf2ff_res_phi0.E_norm)) + nf2ff_res_phi0.Dmax + ax.plot(np.deg2rad(theta), 10**(np.squeeze(E_norm)/20), linewidth=2, label='xz-plane') + ax.grid(True) + ax.set_xlabel('theta (deg)') + ax.set_theta_zero_location('N') + ax.set_theta_direction(-1) + ax.legend(loc=3) + + phi = theta + nf2ff_res_theta90 = nf2ff.CalcNF2FF(Sim_Path, f_res, 90, phi, center=np.array([patch_radius+substrate_thickness, 0, 0])*unit, read_cached=True, outfile='nf2ff_xy.h5') + + ax = subplot(122, polar=True) + E_norm = 20.0*np.log10(nf2ff_res_theta90.E_norm/np.max(nf2ff_res_theta90.E_norm)) + nf2ff_res_theta90.Dmax + ax.plot(np.deg2rad(phi), 10**(np.squeeze(E_norm)/20), linewidth=2, label='xy-plane') + ax.grid(True) + ax.set_xlabel('phi (deg)') + suptitle('Bent Patch Anteanna Pattern\nFrequency: {} GHz'.format(f_res/1e9), fontsize=14) + ax.legend(loc=3) + + print( 'radiated power: Prad = {:.2e} Watt'.format(nf2ff_res_theta90.Prad[0])) + print( 'directivity: Dmax = {:.1f} ({:.1f} dBi)'.format(nf2ff_res_theta90.Dmax[0], 10*np.log10(nf2ff_res_theta90.Dmax[0]))) + print( 'efficiency: nu_rad = {:.1f} %'.format(100*nf2ff_res_theta90.Prad[0]/real(P_in[idx[0]]))) + +show() + diff --git a/openEMS/python/Tutorials/CRLH_Extraction.py b/openEMS/python/Tutorials/CRLH_Extraction.py new file mode 100644 index 0000000..4e1850e --- /dev/null +++ b/openEMS/python/Tutorials/CRLH_Extraction.py @@ -0,0 +1,239 @@ +# -*- coding: utf-8 -*- +""" + Tutorials / CRLH_Extraction + + Describtion at: + http://openems.de/index.php/Tutorial:_CRLH_Extraction + + Tested with + - python 3.4 + - openEMS v0.0.34+ + + (C) 2016 Thorsten Liebig <thorsten.liebig@gmx.de> +""" + + +### Import Libraries +import os, tempfile +from pylab import * + +from CSXCAD import ContinuousStructure +from openEMS import openEMS +from openEMS.physical_constants import * + +### Class to represent single CRLH unit cells +class CRLH_Cells: + def __init__(self, LL, LW, Top, Bot, GLT, GLB, SL, SW, VR): + self.LL = LL # Line length + self.LW = LW # Line width + self.Top = Top # top signal height + self.Bot = Bot # bottom signal height + self.GLT = GLT # gap length top + self.GLB = GLB # gap length bottom + self.SL = SL # stub length + self.SW = SW # stub width + self.VR = VR # via radius + self.props = dict() # property dictionary + self.edge_resolution = None + + def createProperties(self, CSX): + for p in ['metal_top', 'metal_bot', 'via']: + self.props[p] = CSX.AddMetal(p) + + def setEdgeResolution(self, res): + self.edge_resolution = res + + def createCell(self, translate = [0,0,0]): + def append_mesh(mesh1, mesh2): + for n in range(3): + if mesh1[n] is None: + mesh1[n] = mesh2[n] + elif mesh2[n] is None: + continue + else: + mesh1[n] += mesh2[n] + return mesh1 + translate = array(translate) + start = [-self.LL/2 , -self.LW/2, self.Top] + translate + stop = [-self.GLT/2, self.LW/2, self.Top] + translate + box = self.props['metal_top'].AddBox(start, stop, priority=10) + mesh = box.GetGridHint('x', metal_edge_res=self.edge_resolution, down_dir=False) + append_mesh(mesh, box.GetGridHint('y', metal_edge_res=self.edge_resolution) ) + + start = [+self.LL/2 , -self.LW/2, self.Top] + translate + stop = [+self.GLT/2, self.LW/2, self.Top] + translate + box = self.props['metal_top'].AddBox(start, stop, priority=10) + append_mesh(mesh, box.GetGridHint('x', metal_edge_res=self.edge_resolution, up_dir=False) ) + + start = [-(self.LL-self.GLB)/2, -self.LW/2, self.Bot] + translate + stop = [+(self.LL-self.GLB)/2, self.LW/2, self.Bot] + translate + box = self.props['metal_bot'].AddBox(start, stop, priority=10) + append_mesh(mesh, box.GetGridHint('x', metal_edge_res=self.edge_resolution) ) + + start = [-self.SW/2, -self.LW/2-self.SL, self.Bot] + translate + stop = [+self.SW/2, self.LW/2+self.SL, self.Bot] + translate + box = self.props['metal_bot'].AddBox(start, stop, priority=10) + append_mesh(mesh, box.GetGridHint('xy', metal_edge_res=self.edge_resolution) ) + + start = [0, -self.LW/2-self.SL+self.SW/2, 0 ] + translate + stop = [0, -self.LW/2-self.SL+self.SW/2, self.Bot] + translate + + self.props['via'].AddCylinder(start, stop, radius=self.VR, priority=10) + + start[1] *= -1 + stop [1] *= -1 + self.props['via'].AddCylinder(start, stop, radius=self.VR, priority=10) + + return mesh + + +if __name__ == '__main__': + ### Setup the simulation + Sim_Path = os.path.join(tempfile.gettempdir(), 'CRLH_Extraction') + post_proc_only = False + + unit = 1e-6 # specify everything in um + + feed_length = 30000 + + substrate_thickness = [1524, 101 , 254 ] + substrate_epsr = [3.48, 3.48, 3.48] + + CRLH = CRLH_Cells(LL = 14e3, LW = 4e3, GLB = 1950, GLT = 4700, SL = 7800, SW = 1000, VR = 250 , \ + Top = sum(substrate_thickness), \ + Bot = sum(substrate_thickness[:-1])) + + # frequency range of interest + f_start = 0.8e9 + f_stop = 6e9 + + ### Setup FDTD parameters & excitation function + CSX = ContinuousStructure() + FDTD = openEMS(EndCriteria=1e-5) + FDTD.SetCSX(CSX) + mesh = CSX.GetGrid() + mesh.SetDeltaUnit(unit) + + CRLH.createProperties(CSX) + + FDTD.SetGaussExcite((f_start+f_stop)/2, (f_stop-f_start)/2 ) + BC = {'PML_8' 'PML_8' 'MUR' 'MUR' 'PEC' 'PML_8'} + FDTD.SetBoundaryCond( ['PML_8', 'PML_8', 'MUR', 'MUR', 'PEC', 'PML_8'] ) + + ### Setup a basic mesh and create the CRLH unit cell + resolution = C0/(f_stop*sqrt(max(substrate_epsr)))/unit /30 # resolution of lambda/30 + CRLH.setEdgeResolution(resolution/4) + + mesh.SetLines('x', [-feed_length-CRLH.LL/2, 0, feed_length+CRLH.LL/2]) + mesh.SetLines('y', [-30000, 0, 30000]) + + substratelines = cumsum(substrate_thickness) + mesh.SetLines('z', [0, 20000]) + mesh.AddLine('z', cumsum(substrate_thickness)) + mesh.AddLine('z', linspace(substratelines[-2],substratelines[-1],4)) + + # create the CRLH unit cell (will define additional fixed mesh lines) + mesh_hint = CRLH.createCell() + mesh.AddLine('x', mesh_hint[0]) + mesh.AddLine('y', mesh_hint[1]) + + # Smooth the given mesh + mesh.SmoothMeshLines('all', resolution, 1.2) + + ### Setup the substrate layer + substratelines = [0] + substratelines.tolist() + start, stop = mesh.GetSimArea() + + for n in range(len(substrate_thickness)): + sub = CSX.AddMaterial( 'substrate_{}'.format(n), epsilon=substrate_epsr[n] ) + start[2] = substratelines[n] + stop [2] = substratelines[n+1] + + sub.AddBox( start, stop ) + + ### Add the feeding MSL ports + pec = CSX.AddMetal( 'PEC' ) + port = [None, None] + x_lines = mesh.GetLines('x') + portstart = [ x_lines[0], -CRLH.LW/2, substratelines[-1]] + portstop = [ -CRLH.LL/2, CRLH.LW/2, 0] + port[0] = FDTD.AddMSLPort( 1, pec, portstart, portstop, 'x', 'z', excite=-1, FeedShift=10*resolution, MeasPlaneShift=feed_length/2, priority=10) + + + portstart = [ x_lines[-1], -CRLH.LW/2, substratelines[-1]] + portstop = [ +CRLH.LL/2 , CRLH.LW/2, 0] + port[1] = FDTD.AddMSLPort( 2, pec, portstart, portstop, 'x', 'z', MeasPlaneShift=feed_length/2, priority=10) + + ### Run the simulation + if 1: # debugging only + CSX_file = os.path.join(Sim_Path, 'CRLH_Extraction.xml') + if not os.path.exists(Sim_Path): + os.mkdir(Sim_Path) + CSX.Write2XML(CSX_file) + os.system(r'AppCSXCAD "{}"'.format(CSX_file)) + + if not post_proc_only: + FDTD.Run(Sim_Path, verbose=3, cleanup=True) + + ### Post-Processing + f = linspace( f_start, f_stop, 1601 ) + for p in port: + p.CalcPort( Sim_Path, f, ref_impedance = 50, ref_plane_shift = feed_length) + + # calculate and plot scattering parameter + s11 = port[0].uf_ref / port[0].uf_inc + s21 = port[1].uf_ref / port[0].uf_inc + + plot(f/1e9,20*log10(abs(s11)),'k-' , linewidth=2, label='$S_{11}$') + plot(f/1e9,20*log10(abs(s21)),'r--', linewidth=2, label='$S_{21}$') + grid() + legend(loc=3) + ylabel('S-Parameter (dB)') + xlabel('frequency (GHz)') + ylim([-40, 2]) + + ### Extract CRLH parameter form ABCD matrix + A = ((1+s11)*(1-s11) + s21*s21)/(2*s21) + C = ((1-s11)*(1-s11) - s21*s21)/(2*s21) / port[1].Z_ref + + Y = C + Z = 2*(A-1)/C + + iZ = imag(Z) + iY = imag(Y) + + fse = interp(0, iZ, f) + fsh = interp(0, iY, f) + + df = f[1]-f[0] + fse_idx = np.where(f>fse)[0][0] + fsh_idx = np.where(f>fsh)[0][0] + + LR = 0.5*(iZ[fse_idx]-iZ[fse_idx-1])/(2*pi*df) + CL = 1/(2*pi*fse)**2/LR + + CR = 0.5*(iY[fsh_idx]-iY[fsh_idx-1])/(2*pi*df) + LL = 1/(2*pi*fsh)**2/CR + + print(' Series tank: CL = {:.2f} pF, LR = {:.2f} nH -> f_se = {:.2f} GHz '.format(CL*1e12, LR*1e9, fse*1e-9)) + print(' Shunt tank: CR = {:.2f} pF, LL = {:.2f} nH -> f_sh = {:.2f} GHz '.format(CR*1e12, LL*1e9, fsh*1e-9)) + + ### Calculate analytical wave-number of an inf-array of cells + w = 2*pi*f + wse = 2*pi*fse + wsh = 2*pi*fsh + beta_calc = real(arccos(1-(w**2-wse**2)*(w**2-wsh**2)/(2*w**2/CR/LR))) + + # plot + figure() + beta = -angle(s21)/CRLH.LL/unit + plot(abs(beta)*CRLH.LL*unit/pi,f*1e-9,'k-', linewidth=2, label=r'$\beta_{CRLH,\ 1\ cell}$' ) + grid() + plot(beta_calc/pi,f*1e-9,'c--', linewidth=2, label=r'$\beta_{CRLH,\ \infty\ cells}$') + plot(real(port[1].beta)*CRLH.LL*unit/pi,f*1e-9,'g-', linewidth=2, label=r'$\beta_{MSL}$') + ylim([1, 6]) + xlabel(r'$|\beta| p / \pi$') + ylabel('frequency (GHz)') + legend(loc=2) + + show()
\ No newline at end of file diff --git a/openEMS/python/Tutorials/Helical_Antenna.py b/openEMS/python/Tutorials/Helical_Antenna.py new file mode 100644 index 0000000..3211ec8 --- /dev/null +++ b/openEMS/python/Tutorials/Helical_Antenna.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- +""" + Helical Antenna Tutorial + + Tested with + - python 3.4 + - openEMS v0.0.33+ + + (C) 2015-2016 Thorsten Liebig <thorsten.liebig@gmx.de> + +""" + +### Import Libraries +import os, tempfile +from pylab import * + +from CSXCAD import CSXCAD + +from openEMS import openEMS +from openEMS.physical_constants import * + + +### Setup the simulation +Sim_Path = os.path.join(tempfile.gettempdir(), 'Helical_Ant') +post_proc_only = False + +unit = 1e-3 # all length in mm + +f0 = 2.4e9 # center frequency, frequency of interest! +lambda0 = round(C0/f0/unit) # wavelength in mm +fc = 0.5e9 # 20 dB corner frequency + +Helix_radius = 20 # --> diameter is ~ lambda/pi +Helix_turns = 10 # --> expected gain is G ~ 4 * 10 = 40 (16dBi) +Helix_pitch = 30 # --> pitch is ~ lambda/4 +Helix_mesh_res = 3 + +gnd_radius = lambda0/2 + +# feeding +feed_heigth = 3 +feed_R = 120 #feed impedance + +# size of the simulation box +SimBox = array([1, 1, 1.5])*2.0*lambda0 + +### Setup FDTD parameter & excitation function +FDTD = openEMS(EndCriteria=1e-4) +FDTD.SetGaussExcite( f0, fc ) +FDTD.SetBoundaryCond( ['MUR', 'MUR', 'MUR', 'MUR', 'MUR', 'PML_8'] ) + +### Setup Geometry & Mesh +CSX = CSXCAD.ContinuousStructure() +FDTD.SetCSX(CSX) +mesh = CSX.GetGrid() +mesh.SetDeltaUnit(unit) + +max_res = floor(C0 / (f0+fc) / unit / 20) # cell size: lambda/20 + +# create helix mesh +mesh.AddLine('x', [-Helix_radius, 0, Helix_radius]) +mesh.SmoothMeshLines('x', Helix_mesh_res) +# add the air-box +mesh.AddLine('x', [-SimBox[0]/2-gnd_radius, SimBox[0]/2+gnd_radius]) +# create a smooth mesh between specified fixed mesh lines +mesh.SmoothMeshLines('x', max_res, ratio=1.4) + +# copy x-mesh to y-direction +mesh.SetLines('y', mesh.GetLines('x')) + +# create helix mesh in z-direction +mesh.AddLine('z', [0, feed_heigth, Helix_turns*Helix_pitch+feed_heigth]) +mesh.SmoothMeshLines('z', Helix_mesh_res) + +# add the air-box +mesh.AddLine('z', [-SimBox[2]/2, max(mesh.GetLines('z'))+SimBox[2]/2 ]) +# create a smooth mesh between specified fixed mesh lines +mesh.SmoothMeshLines('z', max_res, ratio=1.4) + +### Create the Geometry +## * Create the metal helix using the wire primitive. +## * Create a metal gorund plane as cylinder. +# create a perfect electric conductor (PEC) +helix_metal = CSX.AddMetal('helix' ) + +ang = linspace(0,2*pi,21) +coil_x = Helix_radius*cos(ang) +coil_y = Helix_radius*sin(ang) +coil_z = ang/2/pi*Helix_pitch + +Helix_x=np.array([]) +Helix_y=np.array([]) +Helix_z=np.array([]) +zpos = feed_heigth +for n in range(Helix_turns-1): + Helix_x = r_[Helix_x, coil_x] + Helix_y = r_[Helix_y, coil_y] + Helix_z = r_[Helix_z ,coil_z+zpos] + zpos = zpos + Helix_pitch + +p = np.array([Helix_x, Helix_y, Helix_z]) +helix_metal.AddCurve(p) + +# create ground circular ground +gnd = CSX.AddMetal( 'gnd' ) # create a perfect electric conductor (PEC) + +# add a box using cylindrical coordinates +start = [0, 0, -0.1] +stop = [0, 0, 0.1] +gnd.AddCylinder(start, stop, radius=gnd_radius) + +# apply the excitation & resist as a current source +start = [Helix_radius, 0, 0] +stop = [Helix_radius, 0, feed_heigth] +port = FDTD.AddLumpedPort(1 ,feed_R, start, stop, 'z', 1.0, priority=5) + +# nf2ff calc +nf2ff = FDTD.CreateNF2FFBox(opt_resolution=[lambda0/15]*3) + +### Run the simulation +if 0: # debugging only + CSX_file = os.path.join(Sim_Path, 'helix.xml') + if not os.path.exists(Sim_Path): + os.mkdir(Sim_Path) + CSX.Write2XML(CSX_file) + os.system(r'AppCSXCAD "{}"'.format(CSX_file)) + +if not post_proc_only: + FDTD.Run(Sim_Path, verbose=3, cleanup=True) + +### Postprocessing & plotting +freq = linspace( f0-fc, f0+fc, 501 ) +port.CalcPort(Sim_Path, freq) + +Zin = port.uf_tot / port.if_tot +s11 = port.uf_ref / port.uf_inc + +## Plot the feed point impedance +figure() +plot( freq/1e6, real(Zin), 'k-', linewidth=2, label=r'$\Re(Z_{in})$' ) +grid() +plot( freq/1e6, imag(Zin), 'r--', linewidth=2, label=r'$\Im(Z_{in})$' ) +title( 'feed point impedance' ) +xlabel( 'frequency (MHz)' ) +ylabel( 'impedance ($\Omega$)' ) +legend( ) + +## Plot reflection coefficient S11 +figure() +plot( freq/1e6, 20*log10(abs(s11)), 'k-', linewidth=2 ) +grid() +title( 'reflection coefficient $S_{11}$' ) +xlabel( 'frequency (MHz)' ) +ylabel( 'reflection coefficient $|S_{11}|$' ) + +### Create the NFFF contour +## * calculate the far field at phi=0 degrees and at phi=90 degrees +theta = arange(0.,180.,1.) +phi = arange(-180,180,2) +disp( 'calculating the 3D far field...' ) + +nf2ff_res = nf2ff.CalcNF2FF(Sim_Path, f0, theta, phi, read_cached=True, verbose=True ) + +Dmax_dB = 10*log10(nf2ff_res.Dmax[0]) +E_norm = 20.0*log10(nf2ff_res.E_norm[0]/np.max(nf2ff_res.E_norm[0])) + 10*log10(nf2ff_res.Dmax[0]) + +theta_HPBW = theta[ np.where(squeeze(E_norm[:,phi==0])<Dmax_dB-3)[0][0] ] + +## * Display power and directivity +print('radiated power: Prad = {} W'.format(nf2ff_res.Prad[0])) +print('directivity: Dmax = {} dBi'.format(Dmax_dB)) +print('efficiency: nu_rad = {} %'.format(100*nf2ff_res.Prad[0]/interp(f0, freq, port.P_acc))) +print('theta_HPBW = {} °'.format(theta_HPBW)) + +E_norm = 20.0*log10(nf2ff_res.E_norm[0]/np.max(nf2ff_res.E_norm[0])) + 10*log10(nf2ff_res.Dmax[0]) +E_CPRH = 20.0*log10(np.abs(nf2ff_res.E_cprh[0])/np.max(nf2ff_res.E_norm[0])) + 10*log10(nf2ff_res.Dmax[0]) +E_CPLH = 20.0*log10(np.abs(nf2ff_res.E_cplh[0])/np.max(nf2ff_res.E_norm[0])) + 10*log10(nf2ff_res.Dmax[0]) + +## * Plot the pattern +figure() +plot(theta, E_norm[:,phi==0],'k-' , linewidth=2, label='$|E|$') +plot(theta, E_CPRH[:,phi==0],'g--', linewidth=2, label='$|E_{CPRH}|$') +plot(theta, E_CPLH[:,phi==0],'r-.', linewidth=2, label='$|E_{CPLH}|$') +grid() +xlabel('theta (deg)') +ylabel('directivity (dBi)') +title('Frequency: {} GHz'.format(nf2ff_res.freq[0]/1e9)) +legend() + +show() + diff --git a/openEMS/python/Tutorials/MSL_NotchFilter.py b/openEMS/python/Tutorials/MSL_NotchFilter.py new file mode 100644 index 0000000..f036e0f --- /dev/null +++ b/openEMS/python/Tutorials/MSL_NotchFilter.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- +""" + Microstrip Notch Filter Tutorial + + Describtion at: + http://openems.de/doc/openEMS/Tutorials.html#microstrip-notch-filter + + Tested with + - python 3.4 + - openEMS v0.0.34+ + + (C) 2016 Thorsten Liebig <thorsten.liebig@gmx.de> + +""" + +### Import Libraries +import os, tempfile +from pylab import * + +from CSXCAD import ContinuousStructure +from openEMS import openEMS +from openEMS.physical_constants import * + + +### Setup the simulation +Sim_Path = os.path.join(tempfile.gettempdir(), 'NotchFilter') +post_proc_only = False + +unit = 1e-6 # specify everything in um +MSL_length = 50000 +MSL_width = 600 +substrate_thickness = 254 +substrate_epr = 3.66 +stub_length = 12e3 +f_max = 7e9 + +### Setup FDTD parameters & excitation function +FDTD = openEMS() +FDTD.SetGaussExcite( f_max/2, f_max/2 ) +FDTD.SetBoundaryCond( ['PML_8', 'PML_8', 'MUR', 'MUR', 'PEC', 'MUR'] ) + +### Setup Geometry & Mesh +CSX = ContinuousStructure() +FDTD.SetCSX(CSX) +mesh = CSX.GetGrid() +mesh.SetDeltaUnit(unit) + +resolution = C0/(f_max*sqrt(substrate_epr))/unit/50 # resolution of lambda/50 +third_mesh = array([2*resolution/3, -resolution/3])/4 + +## Do manual meshing +mesh.AddLine('x', 0) +mesh.AddLine('x', MSL_width/2+third_mesh) +mesh.AddLine('x', -MSL_width/2-third_mesh) +mesh.SmoothMeshLines('x', resolution/4) + +mesh.AddLine('x', [-MSL_length, MSL_length]) +mesh.SmoothMeshLines('x', resolution) + +mesh.AddLine('y', 0) +mesh.AddLine('y', MSL_width/2+third_mesh) +mesh.AddLine('y', -MSL_width/2-third_mesh) +mesh.SmoothMeshLines('y', resolution/4) + +mesh.AddLine('y', [-15*MSL_width, 15*MSL_width+stub_length]) +mesh.AddLine('y', (MSL_width/2+stub_length)+third_mesh) +mesh.SmoothMeshLines('y', resolution) + +mesh.AddLine('z', linspace(0,substrate_thickness,5)) +mesh.AddLine('z', 3000) +mesh.SmoothMeshLines('z', resolution) + +## Add the substrate +substrate = CSX.AddMaterial( 'RO4350B', epsilon=substrate_epr) +start = [-MSL_length, -15*MSL_width, 0] +stop = [+MSL_length, +15*MSL_width+stub_length, substrate_thickness] +substrate.AddBox(start, stop ) + +## MSL port setup +port = [None, None] +pec = CSX.AddMetal( 'PEC' ) +portstart = [ -MSL_length, -MSL_width/2, substrate_thickness] +portstop = [ 0, MSL_width/2, 0] +port[0] = FDTD.AddMSLPort( 1, pec, portstart, portstop, 'x', 'z', excite=-1, FeedShift=10*resolution, MeasPlaneShift=MSL_length/3, priority=10) + +portstart = [MSL_length, -MSL_width/2, substrate_thickness] +portstop = [0 , MSL_width/2, 0] +port[1] = FDTD.AddMSLPort( 2, pec, portstart, portstop, 'x', 'z', MeasPlaneShift=MSL_length/3, priority=10 ) + +## Filter-Stub Definition +start = [-MSL_width/2, MSL_width/2, substrate_thickness] +stop = [ MSL_width/2, MSL_width/2+stub_length, substrate_thickness] +pec.AddBox(start, stop, priority=10 ) + +### Run the simulation +if 0: # debugging only + CSX_file = os.path.join(Sim_Path, 'notch.xml') + if not os.path.exists(Sim_Path): + os.mkdir(Sim_Path) + CSX.Write2XML(CSX_file) + os.system(r'AppCSXCAD "{}"'.format(CSX_file)) + + +if not post_proc_only: + FDTD.Run(Sim_Path, verbose=3, cleanup=True) + +### Post-processing and plotting +f = linspace( 1e6, f_max, 1601 ) +for p in port: + p.CalcPort( Sim_Path, f, ref_impedance = 50) + +s11 = port[0].uf_ref / port[0].uf_inc +s21 = port[1].uf_ref / port[0].uf_inc + +plot(f/1e9,20*log10(abs(s11)),'k-',linewidth=2 , label='$S_{11}$') +grid() +plot(f/1e9,20*log10(abs(s21)),'r--',linewidth=2 , label='$S_{21}$') +legend() +ylabel('S-Parameter (dB)') +xlabel('frequency (GHz)') +ylim([-40, 2]) + +show() diff --git a/openEMS/python/Tutorials/RCS_Sphere.py b/openEMS/python/Tutorials/RCS_Sphere.py new file mode 100644 index 0000000..df801ce --- /dev/null +++ b/openEMS/python/Tutorials/RCS_Sphere.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +""" + Tutorials / radar cross section of a metal sphere + + Tested with + - python 3.4 + - openEMS v0.0.34+ + + (C) 2016 Thorsten Liebig <thorsten.liebig@gmx.de> +""" + +### Import Libraries +import os, tempfile +from pylab import * + +from CSXCAD import ContinuousStructure +from openEMS import openEMS +from openEMS.physical_constants import * +from openEMS.ports import UI_data + +### Setup the simulation +Sim_Path = os.path.join(tempfile.gettempdir(), 'RCS_Sphere') +post_proc_only = False + +unit = 1e-3 # all length in mm + +sphere_rad = 200 + +inc_angle = 0 #incident angle (to x-axis) in deg + +# size of the simulation box +SimBox = 1200 +PW_Box = 750 + +### Setup FDTD parameters & excitation function +FDTD = openEMS(EndCriteria=1e-5) + +f_start = 50e6 # start frequency +f_stop = 1000e6 # stop frequency +f0 = 500e6 +FDTD.SetGaussExcite( 0.5*(f_start+f_stop), 0.5*(f_stop-f_start) ) + +FDTD.SetBoundaryCond( ['PML_8', 'PML_8', 'PML_8', 'PML_8', 'PML_8', 'PML_8'] ) + +### Setup Geometry & Mesh +CSX = ContinuousStructure() +FDTD.SetCSX(CSX) +mesh = CSX.GetGrid() +mesh.SetDeltaUnit(unit) + +#create mesh +mesh.SetLines('x', [-SimBox/2, 0, SimBox/2]) +mesh.SmoothMeshLines('x', C0 / f_stop / unit / 20) # cell size: lambda/20 +mesh.SetLines('y', mesh.GetLines('x')) +mesh.SetLines('z', mesh.GetLines('x')) + +### Create a metal sphere and plane wave source +sphere_metal = CSX.AddMetal( 'sphere' ) # create a perfect electric conductor (PEC) +sphere_metal.AddSphere(priority=10, center=[0, 0, 0], radius=sphere_rad) + +# plane wave excitation +k_dir = [cos(inc_angle), sin(inc_angle), 0] # plane wave direction +E_dir = [0, 0, 1] # plane wave polarization --> E_z + +pw_exc = CSX.AddExcitation('plane_wave', exc_type=10, exc_val=E_dir) +pw_exc.SetPropagationDir(k_dir) +pw_exc.SetFrequency(f0) + +start = np.array([-PW_Box/2, -PW_Box/2, -PW_Box/2]) +stop = -start +pw_exc.AddBox(start, stop) + +# nf2ff calc +nf2ff = FDTD.CreateNF2FFBox() + +### Run the simulation +if 0: # debugging only + CSX_file = os.path.join(Sim_Path, 'RCS_Sphere.xml') + if not os.path.exists(Sim_Path): + os.mkdir(Sim_Path) + CSX.Write2XML(CSX_file) + os.system(r'AppCSXCAD "{}"'.format(CSX_file)) + + +if not post_proc_only: + FDTD.Run(Sim_Path, verbose=3, cleanup=True) + +### Postprocessing & plotting +# get Gaussian pulse stength at frequency f0 +ef = UI_data('et', Sim_Path, freq=f0) + +Pin = 0.5*norm(E_dir)**2/Z0 * abs(ef.ui_f_val[0])**2 +# +nf2ff_res = nf2ff.CalcNF2FF(Sim_Path, f0, 90, arange(-180, 180.1, 2)) +RCS = 4*pi/Pin[0]*nf2ff_res.P_rad[0] + +fig = figure() +ax = fig.add_subplot(111, polar=True) +ax.plot( nf2ff_res.phi, RCS[0], 'k-', linewidth=2 ) +ax.grid(True) + +# calculate RCS over frequency +freq = linspace(f_start,f_stop,100) +ef = UI_data( 'et', Sim_Path, freq ) # time domain/freq domain voltage +Pin = 0.5*norm(E_dir)**2/Z0 * abs(np.array(ef.ui_f_val[0]))**2 + +nf2ff_res = nf2ff.CalcNF2FF(Sim_Path, freq, 90, 180+inc_angle, outfile='back_nf2ff.h5') + +back_scat = np.array([4*pi/Pin[fn]*nf2ff_res.P_rad[fn][0][0] for fn in range(len(freq))]) + +figure() +plot(freq/1e6,back_scat, linewidth=2) +grid() +xlabel('frequency (MHz)') +ylabel('RCS ($m^2$)') +title('radar cross section') + +figure() +semilogy(sphere_rad*unit/C0*freq,back_scat/(pi*sphere_rad*unit*sphere_rad*unit), linewidth=2) +ylim([10^-2, 10^1]) +grid() +xlabel('sphere radius / wavelength') +ylabel('RCS / ($\pi a^2$)') +title('normalized radar cross section') + +show()
\ No newline at end of file diff --git a/openEMS/python/Tutorials/Rect_Waveguide.py b/openEMS/python/Tutorials/Rect_Waveguide.py new file mode 100644 index 0000000..5d38115 --- /dev/null +++ b/openEMS/python/Tutorials/Rect_Waveguide.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +""" + Rectangular Waveguide Tutorial + + Describtion at: + http://openems.de/doc/openEMS/Tutorials.html#rectangular-waveguide + + Tested with + - python 3.4 + - openEMS v0.0.34+ + + (C) 2015-2016 Thorsten Liebig <thorsten.liebig@gmx.de> + +""" + +### Import Libraries +import os, tempfile +from pylab import * + +from CSXCAD import ContinuousStructure +from openEMS import openEMS +from openEMS.physical_constants import * + +### Setup the simulation +Sim_Path = os.path.join(tempfile.gettempdir(), 'Rect_WG') + +post_proc_only = False +unit = 1e-6; #drawing unit in um + +# waveguide dimensions +# WR42 +a = 10700; #waveguide width +b = 4300; #waveguide heigth +length = 50000; + +# frequency range of interest +f_start = 20e9; +f_0 = 24e9; +f_stop = 26e9; +lambda0 = C0/f_0/unit; + +#waveguide TE-mode definition +TE_mode = 'TE10'; + +#targeted mesh resolution +mesh_res = lambda0/30 + +### Setup FDTD parameter & excitation function +FDTD = openEMS(NrTS=1e4); +FDTD.SetGaussExcite(0.5*(f_start+f_stop),0.5*(f_stop-f_start)); + +# boundary conditions +FDTD.SetBoundaryCond([0, 0, 0, 0, 3, 3]); + +### Setup geometry & mesh +CSX = ContinuousStructure() +FDTD.SetCSX(CSX) +mesh = CSX.GetGrid() +mesh.SetDeltaUnit(unit) + +mesh.AddLine('x', [0, a]) +mesh.AddLine('y', [0, b]) +mesh.AddLine('z', [0, length]) + +## Apply the waveguide port +ports = [] +start=[0, 0, 10*mesh_res]; +stop =[a, b, 15*mesh_res]; +mesh.AddLine('z', [start[2], stop[2]]) +ports.append(FDTD.AddRectWaveGuidePort( 0, start, stop, 'z', a*unit, b*unit, TE_mode, 1)) + +start=[0, 0, length-10*mesh_res]; +stop =[a, b, length-15*mesh_res]; +mesh.AddLine('z', [start[2], stop[2]]) +ports.append(FDTD.AddRectWaveGuidePort( 1, start, stop, 'z', a*unit, b*unit, TE_mode)) + +mesh.SmoothMeshLines('all', mesh_res, ratio=1.4) + +### Define dump box... +Et = CSX.AddDump('Et', file_type=0, sub_sampling=[2,2,2]) +start = [0, 0, 0]; +stop = [a, b, length]; +Et.AddBox(start, stop); + +### Run the simulation +if 0: # debugging only + CSX_file = os.path.join(Sim_Path, 'rect_wg.xml') + if not os.path.exists(Sim_Path): + os.mkdir(Sim_Path) + CSX.Write2XML(CSX_file) + os.system(r'AppCSXCAD "{}"'.format(CSX_file)) + +if not post_proc_only: + FDTD.Run(Sim_Path, verbose=3, cleanup=True) + +### Postprocessing & plotting +freq = linspace(f_start,f_stop,201) +for port in ports: + port.CalcPort(Sim_Path, freq) + +s11 = ports[0].uf_ref / ports[0].uf_inc +s21 = ports[1].uf_ref / ports[0].uf_inc +ZL = ports[0].uf_tot / ports[0].if_tot +ZL_a = ports[0].ZL # analytic waveguide impedance + +## Plot s-parameter +figure() +plot(freq*1e-6,20*log10(abs(s11)),'k-',linewidth=2, label='$S_{11}$') +grid() +plot(freq*1e-6,20*log10(abs(s21)),'r--',linewidth=2, label='$S_{21}$') +legend(); +ylabel('S-Parameter (dB)') +xlabel(r'frequency (MHz) $\rightarrow$') + +## Compare analytic and numerical wave-impedance +figure() +plot(freq*1e-6,real(ZL), linewidth=2, label='$\Re\{Z_L\}$') +grid() +plot(freq*1e-6,imag(ZL),'r--', linewidth=2, label='$\Im\{Z_L\}$') +plot(freq*1e-6,ZL_a,'g-.',linewidth=2, label='$Z_{L, analytic}$') +ylabel('ZL $(\Omega)$') +xlabel(r'frequency (MHz) $\rightarrow$') +legend() + +show() diff --git a/openEMS/python/Tutorials/Simple_Patch_Antenna.py b/openEMS/python/Tutorials/Simple_Patch_Antenna.py new file mode 100644 index 0000000..cd80f78 --- /dev/null +++ b/openEMS/python/Tutorials/Simple_Patch_Antenna.py @@ -0,0 +1,151 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Dec 18 20:56:53 2015 + +@author: thorsten +""" + +### Import Libraries +import os, tempfile +from pylab import * + +from CSXCAD import ContinuousStructure +from openEMS import openEMS +from openEMS.physical_constants import * + +### General parameter setup +Sim_Path = os.path.join(tempfile.gettempdir(), 'Simp_Patch') + +post_proc_only = False + +# patch width (resonant length) in x-direction +patch_width = 32 # +# patch length in y-direction +patch_length = 40 + +#substrate setup +substrate_epsR = 3.38 +substrate_kappa = 1e-3 * 2*pi*2.45e9 * EPS0*substrate_epsR +substrate_width = 60 +substrate_length = 60 +substrate_thickness = 1.524 +substrate_cells = 4 + +#setup feeding +feed_pos = -6 #feeding position in x-direction +feed_R = 50 #feed resistance + +# size of the simulation box +SimBox = np.array([200, 200, 150]) + +# setup FDTD parameter & excitation function +f0 = 2e9 # center frequency +fc = 1e9 # 20 dB corner frequency + +### FDTD setup +## * Limit the simulation to 30k timesteps +## * Define a reduced end criteria of -40dB +FDTD = openEMS(NrTS=30000, EndCriteria=1e-4) +FDTD.SetGaussExcite( f0, fc ) +FDTD.SetBoundaryCond( ['MUR', 'MUR', 'MUR', 'MUR', 'MUR', 'MUR'] ) + + +CSX = ContinuousStructure() +FDTD.SetCSX(CSX) +mesh = CSX.GetGrid() +mesh.SetDeltaUnit(1e-3) +mesh_res = C0/(f0+fc)/1e-3/20 + +### Generate properties, primitives and mesh-grid +#initialize the mesh with the "air-box" dimensions +mesh.AddLine('x', [-SimBox[0]/2, SimBox[0]/2]) +mesh.AddLine('y', [-SimBox[1]/2, SimBox[1]/2] ) +mesh.AddLine('z', [-SimBox[2]/3, SimBox[2]*2/3] ) + +# create patch +patch = CSX.AddMetal( 'patch' ) # create a perfect electric conductor (PEC) +start = [-patch_width/2, -patch_length/2, substrate_thickness] +stop = [ patch_width/2 , patch_length/2, substrate_thickness] +patch.AddBox(priority=10, start=start, stop=stop) # add a box-primitive to the metal property 'patch' +FDTD.AddEdges2Grid(dirs='xy', properties=patch, metal_edge_res=mesh_res/2) + +# create substrate +substrate = CSX.AddMaterial( 'substrate', epsilon=substrate_epsR, kappa=substrate_kappa) +start = [-substrate_width/2, -substrate_length/2, 0] +stop = [ substrate_width/2, substrate_length/2, substrate_thickness] +substrate.AddBox( priority=0, start=start, stop=stop ) + +# add extra cells to discretize the substrate thickness +mesh.AddLine('z', linspace(0,substrate_thickness,substrate_cells+1)) + +# create ground (same size as substrate) +gnd = CSX.AddMetal( 'gnd' ) # create a perfect electric conductor (PEC) +start[2]=0 +stop[2] =0 +gnd.AddBox(start, stop, priority=10) + +FDTD.AddEdges2Grid(dirs='xy', properties=gnd) + +# apply the excitation & resist as a current source +start = [feed_pos, 0, 0] +stop = [feed_pos, 0, substrate_thickness] +port = FDTD.AddLumpedPort(1, feed_R, start, stop, 'z', 1.0, priority=5, edges2grid='xy') + +mesh.SmoothMeshLines('all', mesh_res, 1.4) + +# Add the nf2ff recording box +nf2ff = FDTD.CreateNF2FFBox() + +### Run the simulation +if 0: # debugging only + CSX_file = os.path.join(Sim_Path, 'simp_patch.xml') + if not os.path.exists(Sim_Path): + os.mkdir(Sim_Path) + CSX.Write2XML(CSX_file) + os.system(r'AppCSXCAD "{}"'.format(CSX_file)) + +if not post_proc_only: + FDTD.Run(Sim_Path, verbose=3, cleanup=True) + + +### Post-processing and plotting +f = np.linspace(max(1e9,f0-fc),f0+fc,401) +port.CalcPort(Sim_Path, f) +s11 = port.uf_ref/port.uf_inc +s11_dB = 20.0*np.log10(np.abs(s11)) +figure() +plot(f/1e9, s11_dB, 'k-', linewidth=2, label='$S_{11}$') +grid() +legend() +ylabel('S-Parameter (dB)') +xlabel('Frequency (GHz)') + +idx = np.where((s11_dB<-10) & (s11_dB==np.min(s11_dB)))[0] +if not len(idx)==1: + print('No resonance frequency found for far-field calulation') +else: + f_res = f[idx[0]] + theta = np.arange(-180.0, 180.0, 2.0) + phi = [0., 90.] + nf2ff_res = nf2ff.CalcNF2FF(Sim_Path, f_res, theta, phi, center=[0,0,1e-3]) + + figure() + E_norm = 20.0*np.log10(nf2ff_res.E_norm[0]/np.max(nf2ff_res.E_norm[0])) + nf2ff_res.Dmax[0] + plot(theta, np.squeeze(E_norm[:,0]), 'k-', linewidth=2, label='xz-plane') + plot(theta, np.squeeze(E_norm[:,1]), 'r--', linewidth=2, label='yz-plane') + grid() + ylabel('Directivity (dBi)') + xlabel('Theta (deg)') + title('Frequency: {} GHz'.format(f_res/1e9)) + legend() + +Zin = port.uf_tot/port.if_tot +figure() +plot(f/1e9, np.real(Zin), 'k-', linewidth=2, label='$\Re\{Z_{in}\}$') +plot(f/1e9, np.imag(Zin), 'r--', linewidth=2, label='$\Im\{Z_{in}\}$') +grid() +legend() +ylabel('Zin (Ohm)') +xlabel('Frequency (GHz)') + +show() |