Exemplo n.º 1
0
def getScatteredField(d,subkeys):
	
	'''
	Loads jFDFD grid objects and manipulates them to return the scattered field from a simulation.
	'inc' refers to a simulation with only an excitation source in free space.  
	'sub' inlcudes some background structure such as a substrate, but not the scatterer of interest.
	'tot' includes the total problem.
	
	if TFSF sourcing was used (which implies no inc or sub files exist) the incident field is 
	calculated by transfer matrix and subtracted.
	'''
	# Load fields	
	fnbase = jfdfdUtil.generate_filename(d, subkeys=subkeys)	
	inc_name = 'fields/inc-' + fnbase + '.h5'
	sub_name = 'fields/sub-' + fnbase + '.h5'
	tot_name = 'fields/tot-' + fnbase + '.h5'
	
	if os.path.exists(os.path.join(os.getcwd(), tot_name)):
		
		if d.inc: g_inc = jfdfd.h5inputGrid2D(inc_name)
		if d.sub: g_sub = jfdfd.h5inputGrid2D(sub_name)
		g_tot = jfdfd.h5inputGrid2D(tot_name)
		
		# Set coordinates for flux calculation
		Lx, Ly = jfdfdUtil.get_grid_size(g_tot)
		nx = g_tot.nx
		ny = g_tot.ny
		
		# Subtract incident field from total
		if d.sub:
			for i in range(nx):
				for j in range(ny):
					Fz_sub = jfdfd.getFz(g_sub,i,j)
					Fz_tot = jfdfd.getFz(g_tot,i,j)
					jfdfd.setFz(g_tot,i,j,Fz_tot - Fz_sub)
					
			jfdfd.computeComplimentaryFields(g_tot)
		
		elif d.inc:
			for i in range(nx):
				for j in range(ny):
					Fz_inc = jfdfd.getFz(g_inc,i,j)
					Fz_tot = jfdfd.getFz(g_tot,i,j)
					jfdfd.setFz(g_tot,i,j,Fz_tot - Fz_inc)
					
			jfdfd.computeComplimentaryFields(g_tot)
			
		#elif d.source == 'TFSF':
		'''
		ideally the total field region would be completely subtracted here.
		'''
		
		output = [g_tot]
		if d.inc: output.append(g_inc)
		if d.sub: output.append(g_sub)
		return output
		
	else:
		print 'Simulation files do not exist!'
		return 0
Exemplo n.º 2
0
def calc_power_conversion_one(d, subkeys, redo=False):
	"""
	Calculates SPP power conversion efficiency
	"""
	
	
	# Load fields
	fnbase = jfdfdUtil.generate_filename(d, subkeys=subkeys)
	sname = 'data/raw/pce - ' + fnbase + '.dat'
	
	if os.path.exists(os.path.join(os.getcwd(), sname)):
		absval = numpy.loadtxt('data/raw/pce - ' + fnbase + '.dat')
		if not redo and absval.all()!=0:
			print 'Analyzed data already exists -', fnbase
			return
				
	tot_name = 'fields/tot-' + fnbase + '.h5'
	print fnbase
	
	if d.source == 'dipole':
		gs = getScatteredField(d,subkeys)
		g_tot = gs[0]
		
	else: g_tot = jfdfd.h5inputGrid2D(tot_name)
	
	resonator = putil.LoadResonator(tot_name)
	
	res_imin = resonator['nw_imin']
	res_imax = resonator['nw_imax']
	res_jmin = resonator['nw_jmin']
	res_jmax = resonator['nw_jmax']
	res_xmin = resonator['nw_xmin']
	res_xmax = resonator['nw_xmax']
	
	if d.inc:
		g_inc = gs[1]
		i0f = res_imin
		i1f = res_imax
		j0f = int(g_tot.ny/2.)
		f1 = jfdfd.calculateFluxHorizontal(g_inc, i0f, i1f, j0f)
		
		flux_inc = -f1 / (res_xmax-res_xmin)
	else:
		flux_inc = 0.5
		
	if d.sub: g_sub = gs[2]

	if os.path.exists(os.path.join(os.getcwd(), tot_name)):
		#try:
		PCE = Plasmons.GetPlasmons_TFSF(tot_name,flux_inc=flux_inc)
		#except:
		#	os.remove(tot_name)
		
	else:
		print 'Simulation files do not exist!'
		PCE = 0
	
	# Save data
	xsections = pylab.zeros(1, 'd')
	xsections[0] = PCE
	
	numpy.savetxt(sname, xsections)
	
	if d.inc: jfdfd.freeGrid2D(g_inc)
	if d.sub: jfdfd.freeGrid2D(g_sub)
	jfdfd.freeGrid2D(g_tot)
Exemplo n.º 3
0
def calc_sca_one(d, subkeys,redo=False,tight=False):
	"""
	Calculates Qsca by collecting all flux leaving boundaries of the simulation.  Works for dipole
	simulations where the incident plane wave is subtracted, or for TFSF simulations.
	
	Options:
	tight - flux box placed immediately outside of resonator.  Useful for problems with lossy substrates.
	"""
	
	# Load fields
	fnbase = jfdfdUtil.generate_filename(d, subkeys=subkeys)
	sname = 'data/raw/sca - ' + fnbase + '.dat'
	
	if os.path.exists(os.path.join(os.getcwd(), sname)):
		scaval = numpy.loadtxt('data/raw/sca - ' + fnbase + '.dat')
		if not redo and scaval[0]!=0 and scaval[1]!=0:
			print 'Analyzed data already exists - ', fnbase
			return
			
	inc_name = 'fields/inc-' + fnbase + '.h5'
	sub_name = 'fields/sub-' + fnbase + '.h5'
	tot_name = 'fields/tot-' + fnbase + '.h5'
	print fnbase
	
	if os.path.exists(os.path.join(os.getcwd(), tot_name)):
		
		if d.inc: g_inc = jfdfd.h5inputGrid2D(inc_name)
		if d.sub: g_sub = jfdfd.h5inputGrid2D(sub_name)
		g_tot = jfdfd.h5inputGrid2D(tot_name)
		
		#fd = putil.LoadFields(tot_name,PMLpad=15)	
		
		
		# Set coordinates for flux calculation
		Lx, Ly = jfdfdUtil.get_grid_size(g_tot)
		nx = g_tot.nx
		ny = g_tot.ny
		
		#res_steps = d.res_steps
		#PML = d.PML
		
		resonator = putil.LoadResonator(tot_name)
		
		res_imin = resonator['res_imin']
		res_imax = resonator['res_imax']
		res_jmin = resonator['res_jmin']
		res_jmax = resonator['res_jmax']
		res_xmin = resonator['res_xmin']
		res_xmax = resonator['res_xmax']
		
		cross_section = res_xmax - res_xmin
		
		# Calculate incident flux per unit length
		if d.inc:
			i0f = res_imin
			i1f = res_imax
			j0f = int(ny/2.)
			f1 = jfdfd.calculateFluxHorizontal(g_inc, i0f, i1f, j0f)
			
			flux_inc = -f1 / cross_section
		else:
			flux_inc = 0.5											# power density S = |E|^2/2Z, Z=1, |E|=1
			pass
			
		# Subtract incident field from total
		if d.sub:
			for i in range(nx):
				for j in range(ny):
					Fz_sub = jfdfd.getFz(g_sub,i,j)
					Fz_tot = jfdfd.getFz(g_tot,i,j)
					jfdfd.setFz(g_tot,i,j,Fz_tot - Fz_sub)
					
			jfdfd.computeComplimentaryFields(g_tot)
		
		elif d.inc:
			for i in range(nx):
				for j in range(ny):
					Fz_inc = jfdfd.getFz(g_inc,i,j)
					Fz_tot = jfdfd.getFz(g_tot,i,j)
					jfdfd.setFz(g_tot,i,j,Fz_tot - Fz_inc)
					
			jfdfd.computeComplimentaryFields(g_tot)
			
		# Calculate scattering cross-section in resonator
		if not tight:
			pad = 10
			i0a = d.PML+pad
			i1a = nx-d.PML-pad
			j0a = d.PML+pad
			j1a = ny-d.PML-pad

		else:
			pad = 2
			i0a = res_imin - pad
			i1a = res_imax + pad
			j0a = res_jmin-pad											# no pad -- don't want box to penetrate substrate if lossy
			j1a = res_jmax + pad

		up = jfdfd.calculateFluxHorizontal(g_tot,i0a,i1a,j1a)
		down = jfdfd.calculateFluxHorizontal(g_tot,i0a,i1a,j0a)
		left = jfdfd.calculateFluxVertical(g_tot,j0a,j1a,i0a)
		right = jfdfd.calculateFluxVertical(g_tot,j0a,j1a,i1a)
		
		print up, down, left, right
		Psca = up-down-left+right
		
		
		Qsca = Psca / (flux_inc*cross_section)
		
		if d.inc: jfdfd.freeGrid2D(g_inc)
		if d.sub: jfdfd.freeGrid2D(g_sub)
		jfdfd.freeGrid2D(g_tot)

		#PlotBox(tot_name,i0a,i1a,j0a,j1a)
		#exit()
		
	else:
		print 'Simulation files do not exist!'
		flux_inc = 0
		Qsca = 0	
	
	# Save data
	xsections = pylab.zeros(2, 'd')
	xsections[0] = flux_inc
	xsections[1] = Qsca
	
	print "Incident flux -", flux_inc
	print "Psca -", Psca
	print "Qsca -", Qsca
	
	numpy.savetxt(sname, xsections)
Exemplo n.º 4
0
def calc_ref_one(d, subkeys,redo=False):
	"""
	Calculates reflection just above bottom PML layer
	"""
	
	# Load fields
	fnbase = jfdfdUtil.generate_filename(d, subkeys=subkeys)
	sname = 'data/raw/ref - ' + fnbase + '.dat'
	
	if os.path.exists(os.path.join(os.getcwd(), sname)):
		refval = numpy.loadtxt('data/raw/ref - ' + fnbase + '.dat')
		if not redo and refval[0]!=0 and refval[1]!=0:
			print 'Analyzed data already exists - ', fnbase
			return
			
	inc_name = 'fields/inc-' + str(d.wavelength) + '.h5'
	sub_name = 'fields/sub-' + fnbase + '.h5'
	tot_name = 'fields/tot-' + fnbase + '.h5'
	print fnbase

	if os.path.exists(os.path.join(os.getcwd(), tot_name)):
		
		if d.inc: g_inc = jfdfd.h5inputGrid2D(inc_name)
		if d.sub: g_sub = jfdfd.h5inputGrid2D(sub_name)
		g_tot = jfdfd.h5inputGrid2D(tot_name)		
		
		# Set coordinates for flux calculation
		Lx, Ly = jfdfdUtil.get_grid_size(g_tot)
		nx = g_tot.nx
		ny = g_tot.ny
		
		# subtract incident plane wave
		if d.inc:
			for i in range(nx):
				for j in range(ny):
					Fz_inc = jfdfd.getFz(g_inc,i,j)
					Fz_tot = jfdfd.getFz(g_tot,i,j)
					jfdfd.setFz(g_tot,i,j,Fz_tot - Fz_inc)
					
			jfdfd.computeComplimentaryFields(g_tot)

		# Calculate incident flux per unit length
		if d.inc:
			nxi = g_inc.nx
			nyi = g_inc.ny

			i0f = 0
			i1f = nxi
			j0f = int(nyi/2.)
			f1 = jfdfd.calculateFluxHorizontal(g_inc, i0f, i1f, j0f)
			
			Lx_inc, Ly_inc = jfdfdUtil.get_grid_size(g_inc)
			flux_inc = -f1/Lx_inc
		else:
			flux_inc = -0.5
			
		# Calculate reflection just above PML
		i0 = 0
		i1 = nx
		j0 = ny - d.PML - 15

		ref = jfdfd.calculateFluxHorizontal(g_tot, i0, i1, j0) / Lx / flux_inc
		
		if d.inc: jfdfd.freeGrid2D(g_inc)
		if d.sub: jfdfd.freeGrid2D(g_sub)
		jfdfd.freeGrid2D(g_tot)
		
	else:
		print 'Simulation files do not exist!'
		flux_inc = 0
		ref = 0	
	
	# Save data
	xsections = pylab.zeros(2, 'd')
	xsections[0] = flux_inc
	xsections[1] = ref
	
	print "reflection - ", ref
	
	numpy.savetxt(sname, xsections)
Exemplo n.º 5
0
def calc_trans_one(d, subkeys,redo=False):
	"""
	Calculates transmission just above bottom PML layer
	"""
	
	# Load fields
	fnbase = jfdfdUtil.generate_filename(d, subkeys=subkeys)
	sname = 'data/raw/trans - ' + fnbase + '.dat'
	
	if os.path.exists(os.path.join(os.getcwd(), sname)):
		transval = numpy.loadtxt('data/raw/trans - ' + fnbase + '.dat')
		if not redo and transval[0]!=0 and transval[1]!=0:
			print 'Analyzed data already exists - ', fnbase
			return
			
	inc_name = 'fields/inc-' + str(d.wavelength) + '.h5'
	tot_name = 'fields/tot-' + fnbase + '.h5'
	print fnbase

	if os.path.exists(os.path.join(os.getcwd(), tot_name)):
		
		g_inc = jfdfd.h5inputGrid2D(inc_name)
		g_tot = jfdfd.h5inputGrid2D(tot_name)		
		
		# Set coordinates for flux calculation
		Lx, Ly = jfdfdUtil.get_grid_size(g_tot)
		nx = g_tot.nx
		ny = g_tot.ny
		
		# Calculate incident flux per unit length
		nxi = g_inc.nx
		nyi = g_inc.ny

		i0f = 0
		i1f = nxi
		j0f = int(nyi/2.)
		f1 = jfdfd.calculateFluxHorizontal2(g_inc, i0f, i1f, j0f)
		
		Lx_inc, Ly_inc = jfdfdUtil.get_grid_size(g_inc)
		flux_inc = -f1/Lx_inc
		
		# Calculate transmission just above PML
		i0 = 0
		i1 = nx
		j0 = d.PML + 5

		trans = -1 * jfdfd.calculateFluxHorizontal2(g_tot, i0, i1, j0) / Lx / flux_inc
		
		jfdfd.freeGrid2D(g_inc)
		jfdfd.freeGrid2D(g_tot)
		
	else:
		print 'Simulation files do not exist!'
		flux_inc = 0
		trans = 0	
	
	# Save data
	xsections = pylab.zeros(2, 'd')
	xsections[0] = flux_inc
	xsections[1] = trans
	
	print "Transmission - ", trans
	
	numpy.savetxt(sname, xsections)
Exemplo n.º 6
0
def calc_abs_one(d, subkeys,redo=False):
	"""
	Calculates absorption all layers
	"""
	
	# Load fields
	fnbase = jfdfdUtil.generate_filename(d, subkeys=subkeys)
	sname = 'data/raw/abs - ' + fnbase + '.dat'
	
	if os.path.exists(os.path.join(os.getcwd(), sname)):
		absval = numpy.loadtxt('data/raw/abs - ' + fnbase + '.dat')
		if not redo and absval[0]!=0 and absval[1]!=0:
			print 'Analyzed data already exists - ', fnbase
			return
			
	inc_name = 'fields/inc-' + fnbase + '.h5'
	tot_name = 'fields/tot-' + fnbase + '.h5'
	print fnbase
	#if os.path.exists(os.path.join(os.getcwd(), inc_name)) and os.path.exists(os.path.join(os.getcwd(), tot_name)):
	if os.path.exists(os.path.join(os.getcwd(), tot_name)):
		
		if d.inc: g_inc = jfdfd.h5inputGrid2D(inc_name)
		g_tot = jfdfd.h5inputGrid2D(tot_name)

		fd = putil.LoadFields(tot_name,PMLpad=-19)	
		
		
		# Set coordinates for flux calculation
		Lx, Ly = jfdfdUtil.get_grid_size(g_tot)
		nx = g_tot.nx
		ny = g_tot.ny
		
		resonator = putil.LoadResonator(tot_name)
		
		res_ymin = resonator['res_ymin']
		res_ymax = resonator['res_ymax']
		res_xmin = resonator['res_xmin']
		res_xmax = resonator['res_xmax']
		
		theta = 45.
		cross_section = (res_xmax - res_xmin)*sp.cos(theta*sp.pi/180.) + (res_ymax - res_ymin)*sp.sin(theta*sp.pi/180.)
		
		# Calculate incident flux per unit length
		if d.inc:
			x0f = res_xmin
			x1f = res_xmax
			y0f = int(Ly/2.)
			f1 = jfdfd.calculateFluxHorizontalC(g_inc, x0f, x1f, y0f)
			
			flux_inc = -f1 / (cross_section)
		else:
			flux_inc = 0.5
		
		# Calculate absorption cross-section in resonator
		x0a = res_xmin
		x1a = res_xmax
		y0a = res_ymin
		y1a = res_ymax

		abs_res = jfdfd.calculateOhmicAbsorptionRectangleC(g_tot, x0a, y0a, x1a, y1a) / (flux_inc*cross_section)

		if d.inc: jfdfd.freeGrid2D(g_inc)
		jfdfd.freeGrid2D(g_tot)
		
	else:
		print 'Simulation files do not exist!'
		flux_inc = 0
		abs_res = 0	
	
	# Save data
	xsections = pylab.zeros(2, 'd')
	xsections[0] = flux_inc
	xsections[1] = abs_res
	
	print "Incident flux - ", flux_inc
	print "Res Abs - ", abs_res
	
	numpy.savetxt(sname, xsections)