def testCase5Vector(self): """Annular-core fiber.""" self.f.addLayer(radius=10e-6, index=1.4489) self.f.addLayer(radius=16e-6, index=1.4444) self.f.addLayer(index=1.4474) fiber = self.f[0] wl = Wavelength(1550e-9) sols = [(Mode('HE', 1, 1), 1.448089116517021)] vmodes = fiber.findVmodes(wl) self.assertEqual(len(vmodes), len(sols)) for mode, neff in sols: self.assertAlmostEqual(fiber.neff(mode, wl, delta=1e-6), neff) wl = Wavelength(800e-9) sols = [ (Mode('HE', 1, 1), 1.448638518377151), (Mode('TE', 0, 1), 1.4482384223480635), (Mode('TM', 0, 1), 1.448237707949158), (Mode('EH', 1, 1), 1.4477149), # Values from OptiFiber (Mode('HE', 1, 2), 1.4475354), (Mode('HE', 2, 1), 1.4482380), (Mode('HE', 3, 1), 1.4477146) ] vmodes = fiber.findVmodes(wl) self.assertEqual(len(vmodes), len(sols)) for mode, neff in sols: self.assertAlmostEqual(fiber.neff(mode, wl, delta=1e-6), neff)
def testConcentrationOne(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") self.assertEqual(Germania.n(Wavelength(0.5876e-6)), SiO2GeO2.n(Wavelength(0.5876e-6), 1)) self.assertEqual(Germania.n(Wavelength(1.55e-6)), SiO2GeO2.n(Wavelength(1.55e-6), 1))
def testBuresEx334(self): self.f.addLayer(material="SiO2GeO2", radius=4.5e-6, index=1.448918, wl=1550e-9) self.f.addLayer(material="Silica", radius=62.5e-6) self.f.addLayer(material="Air") fiber = self.f[0] # Fig 3.31 wl = Wavelength(900e-9) vgc = 1 / fiber.ng(Mode("HE", 1, 1), wl) self.assertGreater(vgc, 0.680) self.assertLess(vgc, 0.6805) vgc = 1 / fiber.ng(Mode("EH", 1, 1), wl) self.assertGreater(vgc, 0.6825) self.assertLess(vgc, 0.683) wl = Wavelength(1600e-9) vgc = 1 / fiber.ng(Mode("HE", 1, 1), wl) self.assertGreater(vgc, 0.6805) self.assertLess(vgc, 0.6815) vgc = 1 / fiber.ng(Mode("EH", 1, 1), wl) self.assertGreater(vgc, 0.683) self.assertLess(vgc, 0.6836)
def testConcentrationZero(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") self.assertEqual(Silica.n(Wavelength(0.5876e-6)), SiO2GeO2.n(Wavelength(0.5876e-6), 0)) self.assertEqual(Silica.n(Wavelength(1.55e-6)), SiO2GeO2.n(Wavelength(1.55e-6), 0))
def testDopedSilica(self): """Warning: test values based on results! It only ensures that function works and that results stay the same. Please find official tables to compare with. """ self.assertAlmostEqual(SiO2GeO2.n(Wavelength(1.55e-6), 0.05), 1.451526777142772) self.assertAlmostEqual(SiO2GeO2.n(Wavelength(1.55e-6), 0.1), 1.4589885105632852) self.assertAlmostEqual(SiO2GeO2.n(Wavelength(1.55e-6), 0.2), 1.473791249750968)
def bFctV0(n1, n2, rho, b, V0, modes, delta): NA = sqrt(n1**2 - n2**2) pyplot.figure() sim = Simulator(delta=delta) sim.setWavelength(Wavelength(k0=(v0 / b / NA)) for v0 in V0) sim.setMaterials(Fixed, Fixed, Fixed) sim.setRadii((rho * b, ), (b, )) sim.setMaterialsParams((n2, ), (n1, ), (n2, )) fiber = fixedFiber(0, [rho * b, b], [n2, n1, n2]) for m in modes: neff = sim.getNeff(m) bnorm = (neff - n2) / (n1 - n2) pyplot.plot(V0, bnorm, color=COLORS[m.family], label=str(m)) c = fiber.cutoffV0(m) pyplot.axvline(c, color=COLORS[m.family], ls='--') pyplot.xlim((0, V0[-1])) pyplot.title("$n_1 = {}, n_2 = {}, \\rho = {}$".format(n1, n2, rho)) pyplot.xlabel("Normalized frequency ($V_0$)") pyplot.ylabel("Normalized propagation constant ($\widetilde{\\beta}$)")
def main(): wl = Wavelength(1550e-9) ff1 = FiberFactory() ff1.addLayer(name="core", radius=8e-6, material="Fixed", geometry="StepIndex", index=1.454) ff1.addLayer(name="cladding", index=1.444) fiber1 = ff1[0] neff1 = fiber1.neff(Mode("HE", 1, 1), wl) print(neff1) ff2 = FiberFactory() ff2.addLayer(name="core", radius=8e-6, material="Fixed", geometry="SuperGaussian", tparams=[0, 2e-6, 1], index=1.454) ff2.addLayer(name="cladding", index=1.444) fiber2 = ff2[0] neff2 = fiber2.neff(Mode("HE", 1, 1), wl, lowbound=neff1) print(neff2)
def testCutoffV(self): """Values from Bures, Table 3.6.""" delta = 0.3 V = 5 wl = Wavelength(1.55e-6) n2 = 1.444 n1 = sqrt(n2**2 / (1 - 2 * delta)) rho = V / (sqrt(n1**2 - n2**2) * wl.k0) f = FiberFactory() f.addLayer(radius=rho, index=n1) f.addLayer(index=n2) fiber = f[0] sols = [(Mode('TE', 0, 1), 2.4048), (Mode('TM', 0, 1), 2.4048), (Mode('HE', 1, 1), 0), (Mode('EH', 1, 1), 3.8317), (Mode('TE', 0, 2), 5.5201), (Mode('TM', 0, 2), 5.5201), (Mode('HE', 1, 2), 3.8317), (Mode('EH', 1, 2), 7.0156), (Mode('HE', 2, 1), 2.8526), (Mode('EH', 2, 1), 5.1356), (Mode('HE', 3, 1), 4.3423), (Mode('EH', 2, 2), 8.4172)] for mode, V0 in sols: self.assertAlmostEqual(fiber.cutoff(mode), V0, 4, msg=str(mode))
def testBures_4_2_8(self): n2 = 1.457420 n1 = 1.462420 rho = 8.335e-6 wl = Wavelength(0.6328e-6) f = FiberFactory() f.addLayer(radius=rho, index=n1) f.addLayer(index=n2) fiber = f[0] modes = fiber.findLPmodes(wl) sols = { Mode('LP', 0, 1): 2.1845, Mode('LP', 0, 2): 4.9966, Mode('LP', 0, 3): 7.7642, Mode('LP', 1, 1): 3.4770, Mode('LP', 1, 2): 6.3310, Mode('LP', 1, 3): 9.0463, Mode('LP', 2, 1): 4.6544, Mode('LP', 2, 2): 7.5667, Mode('LP', 3, 1): 5.7740, Mode('LP', 3, 2): 8.7290, Mode('LP', 4, 1): 6.8560, Mode('LP', 4, 2): 9.8153, Mode('LP', 5, 1): 7.9096, Mode('LP', 6, 1): 8.9390, Mode('LP', 7, 1): 9.9451 } self.assertEqual(len(modes), len(sols)) for m in modes: neff = fiber.neff(m, wl) u = wl.k0 * rho * sqrt(n1**2 - neff**2) self.assertAlmostEqual(u, sols[m], 3)
def testBures3_6(self): delta = 0.3 V = 5 wl = Wavelength(1.55e-6) n2 = 1.444 n1 = sqrt(n2**2 / (1 - 2 * delta)) rho = V / (sqrt(n1**2 - n2**2) * wl.k0) f = FiberFactory() f.addLayer(radius=rho, index=n1) f.addLayer(index=n2) fiber = f[0] modes = fiber.findVmodes(wl) sols = { Mode('HE', 1, 1): 2.119, Mode('TE', 0, 1): 3.153, Mode('TM', 0, 1): 3.446, Mode('HE', 2, 1): 3.377, Mode('EH', 1, 1): 4.235, Mode('HE', 3, 1): 4.507, Mode('HE', 1, 2): 4.638 } self.assertEqual(len(modes), len(sols)) for m in modes: neff = fiber.neff(m, wl) u = wl.k0 * rho * sqrt(n1**2 - neff**2) self.assertAlmostEqual(u, sols[m], 3)
def neff(self, mode, wl, delta=1e-6, lowbound=None): try: return self.ne_cache[wl][mode] except KeyError: neff = self._neff(Wavelength(wl), mode, delta, lowbound) self.set_ne_cache(wl, mode, neff) return neff
def toWl(self, V0, maxiter=500, tol=1e-15): """Convert V0 number to wavelength. An iterative method is used, since the index can be wavelength dependant. """ if V0 == 0: return float("inf") if isinf(V0): return 0 def f(x): return constants.tpi / V0 * b * self.NA(x) b = self.innerRadius(-1) wl = f(1.55e-6) if abs(wl - f(wl)) > tol: for w in (1.55e-6, 5e-6, 10e-6): try: wl = fixed_point(f, w, xtol=tol, maxiter=maxiter) except RuntimeError: # FIXME: What should we do if it does not converge? self.logger.info("toWl: did not converged from {}µm " "for V0 = {} (wl={})".format( w * 1e6, V0, wl)) if wl > 0: break if wl == 0: self.logger.error("toWl: did not converged for " "V0 = {} (wl={})".format(V0, wl)) return Wavelength(wl)
def __init__(self, parent=None, f=QtCore.Qt.Widget): super().__init__(parent, f) self.wl = Wavelength(1550e-9) self.setWindowTitle(self.tr("Wavelength Calculator")) layout = QtGui.QGridLayout() llabel = QtGui.QLabel("λ") self.linput = QtGui.QDoubleSpinBox() self.linput.setDecimals(3) self.linput.setRange(1, 50000) self.linput.setSingleStep(1) self.linput.setSuffix(" nm") self.linput.valueChanged.connect(self.lvalueChanged) llabel.setBuddy(self.linput) layout.addWidget(llabel, 0, 0, alignment=QtCore.Qt.AlignRight) layout.addWidget(self.linput, 0, 1) klabel = QtGui.QLabel("k₀") self.kinput = QtGui.QDoubleSpinBox() self.kinput.setDecimals(3) self.kinput.setRange(125662, 6283185308) self.kinput.setSingleStep(1) self.kinput.setSuffix(" m⁻¹") self.kinput.valueChanged.connect(self.kvalueChanged) klabel.setBuddy(self.kinput) layout.addWidget(klabel, 0, 2, alignment=QtCore.Qt.AlignRight) layout.addWidget(self.kinput, 0, 3) wlabel = QtGui.QLabel("ω") self.winput = QtGui.QDoubleSpinBox() self.winput.setDecimals(3) self.winput.setRange(36, 1883652) self.winput.setSingleStep(1) self.winput.setSuffix(" Trad/s") self.winput.valueChanged.connect(self.wvalueChanged) wlabel.setBuddy(self.winput) layout.addWidget(wlabel, 1, 0, alignment=QtCore.Qt.AlignRight) layout.addWidget(self.winput, 1, 1) flabel = QtGui.QLabel("f") self.finput = QtGui.QDoubleSpinBox() self.finput.setDecimals(3) self.finput.setRange(0, 1e12) self.finput.setSingleStep(1) self.finput.setSuffix(" THz") self.finput.valueChanged.connect(self.fvalueChanged) flabel.setBuddy(self.finput) layout.addWidget(flabel, 1, 2, alignment=QtCore.Qt.AlignRight) layout.addWidget(self.finput, 1, 3) self.band = QtGui.QLabel() self.band.setAlignment(QtCore.Qt.AlignCenter) layout.addWidget(self.band, 2, 0, 1, 4, alignment=QtCore.Qt.AlignCenter) self.setLayout(layout) self._updateInputs()
def beta(self, omega, mode, p=0, delta=1e-6, lowbound=None): wl = Wavelength(omega=omega) if p == 0: neff = self.neff(mode, wl, delta, lowbound) return neff * wl.k0 m = 5 j = (m - 1) // 2 h = 1e12 # This value is critical for accurate computation lb = lowbound for i in range(m - 1, -1, -1): # Precompute neff using previous wavelength o = omega + (i - j) * h wl = Wavelength(omega=o) lb = self.neff(mode, wl, delta, lb) + delta * 1.1 return derivative(self.beta, omega, p, m, j, h, mode, 0, delta, lowbound)
def testFindLPmodes(self): f = FiberFactory() f.addLayer(radius=4.5e-6, index=1.448918) f.addLayer(index=1.444418) fiber = f[0] wl = Wavelength(800e-9) modes = fiber.findLPmodes(wl) self.assertEqual(len(modes), 4)
def __call__(self, wl, mode, delta, lowbound): if mode.nu == 0 or mode.family is ModeFamily.LP: return super().__call__(wl, mode, delta, lowbound) wl = Wavelength(wl) nmin = self.fiber.minIndex(-1, wl) nmax = max(layer.maxIndex(wl) for layer in self.fiber.layers) neff = numpy.linspace(nmin, nmax, self.NSOLVERS).astype(numpy.float32) cuda.memcpy_htod(self.gpu_neff, neff) n = numpy.fromiter((layer.minIndex(wl) for layer in self.fiber.layers), dtype=numpy.float32, count=len(self.fiber)) cuda.memcpy_htod(self.gpu_n, n) nu = numpy.array([mode.nu], dtype=numpy.int32) cuda.memcpy_htod(self.gpu_nu, nu) self.chareq.prepared_call((neff.size, nu.size), (5, 4, 2), self.gpu_neff, numpy.float32(wl.k0), self.gpu_r, self.gpu_n, numpy.uint32(n.size), self.gpu_nu, self.gpu_x, shared_size=5 * 4 * 2 * 4) cuda.memcpy_dtoh(self.x, self.gpu_x) sols = [] for i in range(self.NSOLVERS - 1, 0, -1): if (abs(self.x[0, i]) > 1e5) or (abs(self.x[0, i - 1]) > 1e5): continue if ((self.x[0, i - 1] < 0 and self.x[0, i] > 0) or (self.x[0, i - 1] > 0 and self.x[0, i] < 0)): sols.append((neff[i - 1], neff[i])) # sols.append(self._findBetween( # self._heceq, neff[i-1], neff[i], args=(wl, mode.nu))) famc = cycle((ModeFamily.HE, ModeFamily.EH)) m = 1 for n in sols: fam = next(famc) self.fiber.set_ne_cache(wl, Mode(fam, mode.nu, m), n) if fam == ModeFamily.EH: m += 1 try: return self.fiber.ne_cache[wl][mode] except KeyError: return float("nan")
def __init__(self, fiber, mode, wl, r, np=101): self.fiber = fiber self.mode = mode self.wl = Wavelength(wl) self.np = np self.xlim = (-r, r) self.ylim = (-r, r) p = numpy.linspace(-r, r, np) self.X, self.Y = numpy.meshgrid(p, p) self.R = numpy.sqrt(numpy.square(self.X) + numpy.square(self.Y)) self.Phi = numpy.arctan2(self.Y, self.X)
def set_wavelengths(self, value): """Set the list of wavelengths. It can be used if this was not done in the constructor, or to modify the current list of wavelengths. Args: value(list): List of wavelengths (in meters) """ self._wavelengths = tuple(Wavelength(w) for w in iter(SLRC(value))) self._build_fsims()
def testFundamental(self): f = FiberFactory() f.addLayer(radius=4.5e-6, index=1.448918) f.addLayer(index=1.444418) fiber = f[0] wl = Wavelength(1550e-9) neff = fiber.neff(Mode('HE', 1, 1), wl) self.assertAlmostEqual(neff, 1.4464045, places=5) lp01 = fiber.neff(Mode('LP', 0, 1), wl) self.assertAlmostEqual(lp01, neff, places=5)
def _compareWithCo(self, fiber, mode, neff): co = fiber.cutoff(mode) wl = Wavelength(1550e-9) n = max(l.maxIndex(wl) for l in fiber.layers) r = fiber.innerRadius(-1) nmax = sqrt(n**2 - (co / (r * wl.k0))**2) self.assertLess(neff, nmax) ms = Mode(mode.family, mode.nu + 1, mode.m) co = fiber.cutoff(ms) nmin = sqrt(n**2 - (co / (r * wl.k0))**2) self.assertGreater(neff, nmin)
def test1550(self): w = Wavelength(1550e-9) self.assertEqual(w, 1550e-9) self.assertEqual(w.wavelength, 1550e-9) self.assertEqual(w.wl, 1550e-9) self.assertAlmostEqual(w.frequency, 193.41448903225806e12) self.assertAlmostEqual(w.v, 193.41448903225806e12) self.assertAlmostEqual(w.omega, 1.215259075683131e15) self.assertAlmostEqual(w.w, 1.215259075683131e15) self.assertAlmostEqual(w.k0, 4053667.940115862)
def testComp(self): w1 = Wavelength(1550e-9) w2 = Wavelength(1530e-9) self.assertTrue(w1 == w1) self.assertFalse(w1 == w2) self.assertTrue(w1 > w2) self.assertFalse(w2 > w1) self.assertTrue(w2 < w1) self.assertFalse(w1 < w2) self.assertTrue(w1 != w2) self.assertFalse(w1 != w1) self.assertTrue(w1 >= w2) self.assertTrue(w1 >= w1) self.assertFalse(w2 >= w1) self.assertTrue(w2 <= w1) self.assertTrue(w2 <= w2) self.assertFalse(w1 <= w2)
def testCase4LP(self): self.f.addLayer(radius=4e-6, index=1.4444) self.f.addLayer(radius=10e-6, index=1.4489) self.f.addLayer(index=1.4474) fiber = self.f[0] wl = Wavelength(1550e-9) sols = [(Mode('LP', 0, 1), 1.447761788), (Mode('LP', 1, 1), 1.447424556)] lpmodes = fiber.findLPmodes(wl) self.assertEqual(len(lpmodes), len(sols)) for mode, neff in sols: self.assertAlmostEqual(fiber.neff(mode, wl, delta=1e-5), neff)
def testCase5LP(self): """W-type fiber.""" self.f.addLayer(radius=10e-6, index=1.4489) self.f.addLayer(radius=16e-6, index=1.4444) self.f.addLayer(index=1.4474) fiber = self.f[0] wl = Wavelength(1550e-9) sols = [(Mode('LP', 0, 1), 1.44809)] # From OptiFiber lpmodes = fiber.findLPmodes(wl) self.assertEqual(len(lpmodes), len(sols)) for mode, neff in sols: self.assertAlmostEqual(fiber.neff(mode, wl, delta=1e-5), neff)
def testCase2LP(self): """Annular-core fiber.""" self.f.addLayer(radius=4e-6, index=1.4444) self.f.addLayer(radius=10e-6, index=1.4489) self.f.addLayer(index=1.4444) fiber = self.f[0] wl = Wavelength(1550e-9) sols = [(Mode('LP', 0, 1), 1.4472296), (Mode('LP', 1, 1), 1.4465947), (Mode('LP', 2, 1), 1.4452985)] lpmodes = fiber.findLPmodes(wl) self.assertEqual(len(lpmodes), len(sols)) for mode, neff in sols: self.assertAlmostEqual(fiber.neff(mode, wl, delta=1e-4), neff)
def testCase1LP(self): self.f.addLayer(radius=4e-6, index=1.4489) self.f.addLayer(radius=10e-6, index=1.4474) self.f.addLayer(index=1.4444) fiber = self.f[0] wl = Wavelength(1550e-9) sols = [(Mode('LP', 0, 1), 1.4472309), (Mode('LP', 1, 1), 1.4457064), (Mode('LP', 0, 2), 1.4445245)] lpmodes = fiber.findLPmodes(wl) self.assertEqual(len(lpmodes), len(sols)) for mode, neff in sols: self._compareWithCo(fiber, mode, neff) self.assertAlmostEqual(fiber.neff(mode, wl, delta=1e-5), neff)
def testCase4Vector(self): self.f.addLayer(radius=4e-6, index=1.4444) self.f.addLayer(radius=10e-6, index=1.4489) self.f.addLayer(index=1.4474) fiber = self.f[0] wl = Wavelength(1550e-9) sols = [(Mode('HE', 1, 1), 1.4477608163543525), (Mode('TE', 0, 1), 1.447424556045192), (Mode('HE', 2, 1), 1.4474241401608832), (Mode('TM', 0, 1), 1.4474235819526378)] vmodes = fiber.findVmodes(wl) self.assertEqual(len(vmodes), len(sols)) for mode, neff in sols: self.assertAlmostEqual(fiber.neff(mode, wl, delta=1e-5), neff)
def testCase1Vector(self): self.f.addLayer(radius=4e-6, index=1.4489) self.f.addLayer(radius=10e-6, index=1.4474) self.f.addLayer(index=1.4444) fiber = self.f[0] wl = Wavelength(1550e-9) sols = [(Mode('HE', 1, 1), 1.44722991), (Mode('TE', 0, 1), 1.44570643), (Mode('TM', 0, 1), 1.445706197), (Mode('HE', 2, 1), 1.445704747), (Mode('EH', 1, 1), 1.44452366)] vmodes = fiber.findVmodes(wl) self.assertEqual(len(vmodes), len(sols)) for mode, neff in sols: self.assertAlmostEqual(fiber.neff(mode, wl, delta=1e-5), neff)
def testFindVmodes(self): f = FiberFactory() f.addLayer(radius=4.5e-6, index=1.448918) f.addLayer(index=1.444418) fiber = f[0] wl = Wavelength(800e-9) modes = fiber.findVmodes(wl) sols = [(Mode('HE', 1, 1), 1.4479082), (Mode('TE', 0, 1), 1.44643), (Mode('HE', 2, 1), 1.446427), (Mode('TM', 0, 1), 1.4464268), (Mode('EH', 1, 1), 1.444673), (Mode('HE', 3, 1), 1.444669), (Mode('HE', 1, 2), 1.4444531)] self.assertEqual(len(modes), len(sols)) for mode, neff in sols: self.assertTrue(mode in modes) self.assertAlmostEqual(fiber.neff(mode, wl), neff)
def Alberto(): # R = 25e-6 R = 20e-6 NP = 201 wl = Wavelength(1550e-9) # fiber = ACF() fiber = RCF2() for i in range(len(fiber)): print(fiber.maxIndex(i, wl)) modes = fiber.findVmodes(wl) # modes = (Mode("HE", 1, 1),) for mode in modes: if mode.family not in (ModeFamily.HE, ModeFamily.EH): continue # mode = Mode("LP", 0, 1) print() print(str(mode)) fields = fiber.field(mode, wl, R, np=NP) Er = numpy.zeros(((NP - 1) // 2 + 1, 3)) Hr = numpy.zeros(Er.shape) for i, r in enumerate(numpy.linspace(0, R, Er.shape[0])): Er[i, :], Hr[i, :] = fiber._rfield(mode, wl, r) mdict = { 'name': str(mode), 'neff': fiber.neff(mode, wl), 'Aeff': fields.Aeff(), 'Nm': fields.N(), 'Im': fields.I(), 'Er': Er, 'Hr': Hr, } print("neff: {:.4f}".format(mdict['neff'])) print("Aeff: {:.4f} µm²".format(mdict['Aeff'] * 1e12)) print("Nm: {:.4g}".format(mdict['Nm'])) print("Im: {:.4g}".format(mdict['Im'])) print() io.savemat(str(mode), mdict) plotEHProfile(fiber, mode, wl, R, NP) pyplot.savefig(str(mode) + '.pdf')