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 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 example2(): """2. Creating families of fibers: list of parameters""" # Varying core radius factory = FiberFactory() factory.addLayer(name="core", radius=[1e-6, 2e-6, 3e-6, 4e-6, 5e-6], index=1.474) factory.addLayer() for i, fiber in enumerate(factory): print(factory.layers[0].radius[i], fiber.neff(Mode("HE", 1, 1), 1550e-9)) # Varying core index n = numpy.linspace(1.454, 1.494) factory = FiberFactory() factory.addLayer(name="core", radius=4e-6, index=n) factory.addLayer(name="cladding") fibers = list(factory) print(fibers) neff = numpy.zeros(n.shape) for i, fiber in enumerate(factory): neff[i] = fiber.neff(Mode("HE", 1, 1), 1550e-9) pyplot.plot(n, neff) pyplot.title("neff as function of core index (HE 1,1 mode)") pyplot.xlabel("core index") pyplot.ylabel("effective index") pyplot.show()
def clear_all_caches(self): """Clear caches from the simulator. """ self.modes = [] self.values = {} for fiber in self.simulator.fibers: fiber.co_cache = {Mode("HE", 1, 1): 0, Mode("LP", 0, 1): 0} fiber.ne_cache = {}
def printDNeff2(fnum, wl, measured): sim.setWavelength(wl) sim.setRadius(1, b[fnum-1] * 1e-6) neff = [] for m in [Mode("EH", 1, 1), Mode("HE", 3, 1)]: neff.append(sim.getNeff(m)) print("{:.2e}".format(measured[0] - measured[1])) print("{:.2e}".format(neff[0] - neff[1]))
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 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 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 testNeff(self): sim = self.Simulator( os.path.join(__dir__, '..', 'fiber', 'smf28.fiber'), 1550e-9, delta=1e-4) neff = list(sim.neff()) self.assertEqual(len(neff), 1) self.assertAlmostEqual(neff[0][0][Mode('HE', 1, 1)], 1.446386514937099)
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 _findHEcutoff(self, mode): if mode.m > 1: pm = Mode(mode.family, mode.nu, mode.m - 1) lowbound = self.fiber.cutoff(pm) if isnan(lowbound) or isinf(lowbound): raise AssertionError("_findHEcutoff: no previous cutoff for" "{} mode".format(str(mode))) delta = 1 / lowbound if lowbound else self._MCD lowbound += delta else: lowbound = delta = self._MCD ipoints = numpy.concatenate( (jn_zeros(mode.nu, mode.m), jn_zeros(mode.nu - 2, mode.m))) ipoints.sort() ipoints = list(ipoints[ipoints > lowbound]) co = self._findFirstRoot(self._cutoffHE, args=(mode.nu, ), lowbound=lowbound, ipoints=ipoints, delta=delta) if isnan(co): self.logger.error("_findHEcutoff: no cutoff found for " "{} mode".format(str(mode))) return 0 return co
def plotcutoff(f): for n in (1.46, 1.48, 1.50): if f.n[0] > f.n[1]: f.n[0] = n else: f.n[1] = n mu = abs(f.n[2]**2 - f.n[0]**2) / abs(f.n[2]**2 - f.n[1]**2) if mu > 1: mu = 1 / mu rho = numpy.linspace(0, 1) v0 = numpy.zeros(rho.shape) for i, r in enumerate(rho): f.rho[0] = r * f.rho[1] roots = findRoots(f, Mode("TE", 0, 1), numpy.linspace(2, 15, 500)) if roots: v0[i] = roots[0] v0 = numpy.ma.masked_equal(v0, 0) pyplot.plot(v0, rho, label="$\\mu = {:.2f}$".format(mu) if mu else '') rj0 = jn_zeros(0, 1)[0] pyplot.axvline(rj0, ls='--', color='k') pyplot.xlim((2, 6)) pyplot.ylim((0, 1)) pyplot.legend(loc='best') pyplot.xlabel('Normalized frequency $V_0$') pyplot.ylabel('Radii ratio $\\rho$') pyplot.title(f.name)
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 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 testCutoff(self): sim = self.Simulator( os.path.join(__dir__, '..', 'fiber', 'rcfs.fiber'), 1550e-9) co = list(sim.cutoff()) self.assertEqual(len(co), 5) for fco in co: self.assertEqual(len(fco), 1) self.assertEqual(fco[0][Mode('HE', 1, 1)], 0)
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 testLPCutoffE(self): rho = [4e-6, 6e-6] n = [1.44, 1.47, 1.44] cutoffs = { Mode('LP', 1, 1): 2.85904035776636975, Mode('LP', 2, 1): 4.2866039225676404, Mode('LP', 3, 1): 5.540915061306307, Mode('LP', 4, 1): 6.725406031775626, Mode('LP', 5, 1): 7.8752953434136135, Mode('LP', 6, 1): 9.006117838838101, Mode('LP', 7, 1): 10.125608397188888, Mode('LP', 0, 2): 9.482807865823602, Mode('LP', 1, 2): 10.27844425627377, } self._testFiberCutoff(rho, n, cutoffs)
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 testModesSMF(self): sim = self.Simulator( os.path.join(__dir__, '..', 'fiber', 'smf28.fiber'), 1550e-9, scalar=True) modes = list(sim.modes()) self.assertEqual(len(modes), 1) modesf1 = modes[0] self.assertEqual(len(modesf1), 1) modeswl1 = modesf1[0] self.assertEqual(len(modeswl1), 2) self.assertTrue(HE11 in modeswl1) self.assertTrue(Mode(ModeFamily.LP, 0, 1) in modeswl1)
def __init__(self, parent): super().__init__(parent) self.setWindowTitle(self.tr("Field Visualizer")) self.doc = parent.doc self.fiber = parent.doc.simulator.fibers[ parent.fiberSlider.fiberInput.value() - 1] self.wl = parent.doc.simulator.wavelengths[ parent.wavelengthSlider.wavelengthInput.value() - 1] actions = { 'options': (self.tr("Show/Hide Plot &Options"), 'document-properties', [QtGui.QKeySequence("F4")], self.toggleOptions) } menus = [ (self.tr("&Window"), ['options']), ] toolbars = [['options']] self.initActions(actions) self.initMenubars(self.menuBar(), menus) self.initToolbars(toolbars) self.actions['options'].setCheckable(True) self.actions['options'].setChecked(True) self.options = PlotOptions(self) self.options.hidden.connect(self.actions['options'].toggle) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.options) self.options.plotLayers.toggled.connect(self.plotLayers) self.options.cm.sigGradientChanged.connect(self.setImageColor) self.options.field.currentIndexChanged.connect(self.updatePlot) self.options.np.valueChanged.connect(self.updatePlot) self.options.radius.valueChanged.connect(self.updatePlot) self.modes = [[Mode("HE", 1, 1), 0, 0, 1]] self.__layers = None self.__quiver = [] self.initFields() self.graph = pg.PlotWidget() self.image = pg.ImageItem() self.graph.addItem(self.image) self.graph.setAspectLocked(True) self.graph.sigRangeChanged.connect(self.updateRange) self.setCentralWidget(self.graph) self.updatePlot()
def __call__(self, wl, mode, delta, lowbound): epsilon = 1e-12 co = self.fiber.cutoff(mode) if self.fiber.V0(wl) < co: return float("nan") nco = self.fiber.maxIndex(0, wl) r = self.fiber.outerRadius(0) highbound = sqrt(nco**2 - (co / (r * wl.k0))**2) - epsilon if mode.family is ModeFamily.LP: nm = Mode(ModeFamily.LP, mode.nu + 1, mode.m) elif mode.family is ModeFamily.HE: nm = Mode(ModeFamily.LP, mode.nu, mode.m) elif mode.family is ModeFamily.EH: nm = Mode(ModeFamily.LP, mode.nu + 2, mode.m) else: nm = Mode(ModeFamily.LP, 1, mode.m + 1) co = self.fiber.cutoff(nm) try: lowbound = max( sqrt(nco**2 - (co / (r * wl.k0))**2) + epsilon, self.fiber.minIndex(-1, wl) + epsilon) except ValueError: lowbound = nco fct = { ModeFamily.LP: self._lpceq, ModeFamily.TE: self._teceq, ModeFamily.TM: self._tmceq, ModeFamily.HE: self._heceq, ModeFamily.EH: self._ehceq } return self._findBetween(fct[mode.family], lowbound, highbound, args=(wl, mode.nu))
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 __init__(self, r, f, fp, m, mp, names, Cutoff=None, Neff=None): self._r = r self._names = names self.layers = [] for i, (f_, fp_, m_, mp_) in enumerate(zip(f, fp, m, mp)): ri = self._r[i - 1] if i else 0 ro = self._r[i] if i < len(r) else float("inf") layer = geometry.__dict__[f_](ri, ro, *fp_, m=m_, mp=mp_, cm=m[-1], cmp=mp[-1]) self.layers.append(layer) self.co_cache = {Mode("HE", 1, 1): 0, Mode("LP", 0, 1): 0} self.ne_cache = {} self.setSolvers(Cutoff, Neff)
def testLPCutoffC(self): rho = [4e-6, 6e-6] n = [1.43, 1.47, 1.44] cutoffs = { Mode('LP', 1, 1): 3.010347467577181, Mode('LP', 2, 1): 4.404178238529268, Mode('LP', 3, 1): 5.631998448700369, Mode('LP', 4, 1): 6.7965518925242865, Mode('LP', 5, 1): 7.93118037952865, Mode('LP', 6, 1): 9.050134813376669, Mode('LP', 7, 1): 10.160295215952916, Mode('LP', 0, 2): 10.813986300277824, } self._testFiberCutoff(rho, n, cutoffs)
def _lowbound(self, mode, i): wl = self._wavelengths[i] lowbound = max(layer.maxIndex(wl) for layer in self._fiber.layers) if i > 0: lowbound = min(lowbound, self._neff(mode, i - 1)) pm = None if mode.family is ModeFamily.EH: pm = Mode(ModeFamily.HE, mode.nu, mode.m) elif mode.m > 1: if mode.family is ModeFamily.HE: pm = Mode(ModeFamily.EH, mode.nu, mode.m - 1) else: pm = Mode(mode.family, mode.nu, mode.m - 1) if pm is not None: lowbound = min(lowbound, self._neff(pm, i)) if (mode.family is ModeFamily.LP and mode.nu > 0): # or mode.nu > 1: pm = Mode(mode.family, mode.nu - 1, mode.m) lowbound = min(lowbound, self._neff(pm, i)) return lowbound
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 testLPCutoffA(self): rho = [4e-6, 6e-6] n = [1.47, 1.43, 1.44] cutoffs = { Mode('LP', 1, 1): 4.034844259728652, Mode('LP', 2, 1): 6.1486114063146005, Mode('LP', 3, 1): 8.07126756792508, Mode('LP', 4, 1): 9.911798124561814, Mode('LP', 0, 2): 6.568180843774973, Mode('LP', 1, 2): 8.922361377477307, Mode('LP', 2, 2): 11.06585974653044, } self._testFiberCutoff(rho, n, cutoffs)
class Parameters(object): """Parameters to use in tests.""" nr1 = 5 nr2 = 9 r2 = (2e-6, 10e-6) cn2 = 0.2 modes = [ Mode("HE", 2, 1), Mode("TE", 0, 1), Mode("TM", 0, 1), Mode("HE", 3, 1), Mode("EH", 1, 1), Mode("HE", 4, 1), Mode("EH", 2, 1) ]
def compute_fiber(filename, nrho, R2, C2, wl, numax=None, mmax=None): # Initialize simulators sim = [] for i, r2 in enumerate(R2): r1 = numpy.linspace(0, r2, nrho, endpoint=False) factory = FiberFactory() factory.addLayer(radius=r1, material='Silica') factory.addLayer(radius=r2, material='SiO2GeO2', x=C2) factory.addLayer(material='Silica') sim.append(Simulator(factory, wl)) nr2 = R2.size nc2 = C2.size ckfile, _ = os.path.splitext(filename) ckfile += '.ckp.npz' if os.path.isfile(ckfile): # Restore checkpoint data = numpy.load(ckfile) modes = [Mode(*a) for a in data['modes']] results = {'modes': modes} for fct in ('cutoff', 'neff', 'beta1', 'beta2', 'beta3'): results[fct] = data[fct] else: # Find modes sim[-1].numax = numax sim[-1].mmax = mmax modes = find_mode_list(sim[-1]) # Initialize arrays shape = (nrho, nr2, C2.size, len(modes)) results = {'modes': modes} for fct in ('cutoff', 'neff', 'beta1', 'beta2', 'beta3'): results[fct] = numpy.empty(shape) results[fct].fill(numpy.nan) Rho = numpy.linspace(0, 1, nrho, endpoint=False) for i, r2 in enumerate(R2[::-1], 1): print("Solving when r2={:.3f}µm".format(r2 * 1e6)) if numpy.all(numpy.isnan(results['cutoff'][:, nr2 - i, :, :])): numax, mmax = compute_fiber_r2(results, modes, sim[-i], nr2 - i, Rho, r2, nc2, numax, mmax) numpy.savez_compressed(ckfile, **results) # Save checkpoint os.rename(ckfile, filename) return results