/* * PlanarWaveguide Class * * Methods for: * determining the refractive index of a waveguiding thin film * in an asymmetric slab waveguide from the effective refractive index, i.e. * the normalised propagation vector, and the core layer thickness * * determinimg the refractive index of the superstrate [waveguide coupler sensor] * * obtaining the normalised propagation vector versus guiding layer thickness * dispersion curve for an asymmetric slab waveguide * * * This is the superclass for the subclasses PrismCoupler and GratingCoupler * * Author: Dr Michael Thomas Flanagan. * * Created: March 2006 * Revised: 29 April 2006, 5-7 July 2008, 9 November 2009 * * DOCUMENTATION: * See Michael Thomas Flanagan's Java library on-line web page: * http://www.ee.ucl.ac.uk/~mflanaga/java/PlanarWaveguide.html * http://www.ee.ucl.ac.uk/~mflanaga/java/ * * Copyright (c) 2006 - 2009 Michael Thomas Flanagan * * PERMISSION TO COPY: * * Permission to use, copy and modify this software and its documentation for NON-COMMERCIAL purposes is granted, without fee, * provided that an acknowledgement to the author, Dr Michael Thomas Flanagan at www.ee.ucl.ac.uk/~mflanaga, appears in all copies * and associated documentation or publications. * * Redistributions of the source code of this source code, or parts of the source codes, must retain the above copyright notice, this list of conditions * and the following disclaimer and requires written permission from the Michael Thomas Flanagan: * * Redistribution in binary form of all or parts of this class must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials provided with the distribution and requires written permission from the Michael Thomas Flanagan: * * Dr Michael Thomas Flanagan makes no representations about the suitability or fitness of the software for any or for a particular purpose. * Dr Michael Thomas Flanagan shall not be liable for any damages suffered as a result of using, modifying or distributing this software * or its derivatives. * ***************************************************************************************/ package flanagan.optics; import flanagan.math.*; import flanagan.analysis.Stat; import flanagan.roots.*; import flanagan.plot.*; import flanagan.optics.RefractiveIndex; import java.util.ArrayList; public class PlanarWaveguide{ // CLASS VARIABLES protected double[][] measurementsTE = null; // experimental TE mode measurements // [film thickness][effective refractive index][weight][mode number] protected int numberOfTEmeasurements = 0; // number of TE mode experimental measurements protected double[] thicknessesUsedTE = null; // TE mode thicknesses used in calculation protected double[] calcEffectRefrIndicesTE = null; // TE mode calculated effective refractive indices for mean core refractive index protected boolean setMeasurementsTE = false; // = true when TE mode measurements entered protected boolean setErrorsTE = false; // = true when TE mode errors entered protected double maximumTEmodeEffectiveRefractiveIndex = 0.0D; // Maximum TE mode effective refractive index value protected double minimumTEmodeEffectiveRefractiveIndex = 0.0D; // Minimum TE mode effective refractive index value protected double[][] measurementsTM = null; // experimental TM mode measurements // [film thickness][effective refractive index][weight][mode number] protected int numberOfTMmeasurements = 0; // number of TM mode experimental measurements protected double[] thicknessesUsedTM = null; // TM mode thicknesses used in calculation protected double[] calcEffectRefrIndicesTM = null; // TM mode calculated effective refractive indices for mean core refractive index protected boolean setMeasurementsTM = false; // = true when TM mode measurements entered protected boolean setErrorsTM = false; // = true when TM mode errors entered protected double maximumTMmodeEffectiveRefractiveIndex = 0.0D; // Maximum TM mode effective refractive index value protected double minimumTMmodeEffectiveRefractiveIndex = 0.0D; // Minimum TM mode effective refractive index value protected double maximumEffectiveRefractiveIndex = 0.0D; // Maximum overall effective refractive index value protected double minimumEffectiveRefractiveIndex = 0.0D; // Minimum overall effective refractive index value protected int numberOfMeasurements = 0; // total number of experimental measurements protected boolean setMeasurements = false; // = true when measurements entered protected boolean setWeights = false; // = true when weights entered protected boolean[] eliminatedTE = null; // = true when TE point eliminated if effective refractive index lies below physical limit (Max[sub or superstrate] protected boolean[] eliminatedTM = null; // = true when TM point eliminated if effective refractive index lies below physical limit (Max[sub or superstrate] protected double wavelength = 0; // wavelength of the exciting light protected boolean setWavelength= false; // = true when wavelength entered protected double ko = 0.0D; // wave vector, 2pi/lambda protected double superstrateRefractiveIndex = 0.0D; // superstrate refractive index // default value: air protected double superstrateRefractiveIndex2 = 0.0D;// superstrate refractive index squared protected double[] calcSuperstrateTEmodeRI = null; // calculated TE mode superstrate refractive index values protected double[] calcSuperstrateTMmodeRI = null; // calculated TM mode superstrate refractive index values protected double meanTEmodeSuperstrateRefractiveIndex = Double.NaN; // mean of the TE mode superstrate refractive indices protected double meanTMmodeSuperstrateRefractiveIndex = Double.NaN; // mean of the TM mode superstrate refractive indices protected double sdTEmodeSuperstrateRefractiveIndex = Double.NaN; // standard deviation of the TE mode superstrate refractive indices protected double sdTMmodeSuperstrateRefractiveIndex = Double.NaN; // standard deviation of the TM mode superstrate refractive indices protected double sdSuperstrateRefractiveIndex = Double.NaN; // standard deviation of the superstrate refractive indices protected boolean setSuperstrate = false; // = true when superstrate refractive index entered protected boolean superCalculationDone = false; // = true when superstrate refractive index has been calculated protected double substrateRefractiveIndex = 0.0D; // substrate refractive index protected double substrateRefractiveIndex2 = 0.0D; // substrate refractive index squared protected boolean setSubstrate = false; // = true when substrate refractive index entered protected double coreFilmRefractiveIndex = 0.0D; // guiding layer thin film refractive index protected double coreFilmRefractiveIndex2 = 0.0D; // guiding layer thin film refractive index squared protected boolean setCore = false; // = true when guiding layer refractive index entered or calculated protected double[] coreFilmTEmodeRefractiveIndices = null; // core film TE mode refractive indices protected double[] coreFilmTMmodeRefractiveIndices = null; // core film TM mode refractive indices protected double meanTEmodeCoreFilmRefractiveIndex = Double.NaN; // mean of the TE mode core film refractive indices protected double meanTMmodeCoreFilmRefractiveIndex = Double.NaN; // mean of the TM mode core film refractive indices protected double meanCoreFilmRefractiveIndex = Double.NaN; // mean of the TE and TM mode core film refractive indices protected double meanCoreFilmRefractiveIndex2 = Double.NaN; // square of the mean of the TE and TM mode core film refractive indices protected double sdTEmodeCoreFilmRefractiveIndex = Double.NaN; // standard deviation of the TE mode core film refractive indices protected double sdTMmodeCoreFilmRefractiveIndex = Double.NaN; // standard deviation of the TM mode core film refractive indices protected double sdCoreFilmRefractiveIndex = Double.NaN; // standard deviation of the TE and TM mode core film refractive indices protected double lowerBound = 0.0D; // lower bound in a root search protected double upperBound = 0.0D; // upper bound in a root search protected double tolerance = 1e-9; // root search tolerance protected boolean calculationDone = false; // = true when calculation of core film refractive index/indices completed protected double prismToWaveguideGap = Double.POSITIVE_INFINITY; // prism to waveguide gap (subclass PrismCoupler) protected boolean setPrismToWaveguideGap = false; // = true when prism to waveguide gap set (subclass PrismCoupler) protected boolean fixedPrismToWaveguideGap = true; // = true when prism to waveguide gap set at a fixed value (subclass PrismCoupler) // = false when prism to waveguide gap is to be estimated (subclass PrismCoupler) protected double prismRefractiveIndex = 0.0D; // substrate refractive index protected double prismRefractiveIndex2 = 0.0D; // substrate refractive index squared // CONSTRUCTOR public PlanarWaveguide(){ } // THICKNESS (metres), EFFECTIVE REFRACTIVE INDEX AND MODE NUMBER DATA // Enter TE mode data for a single measurement with no weights public void enterTEmodeData(double thickness, double effectiveRI, double modeNumber){ if(setMeasurementsTE){ if(setErrorsTE)throw new IllegalArgumentException("All Entered data must either all have associated errors entered or all have no associated errors entered"); int nNew = this.numberOfTEmeasurements + 1; double[][] hold = new double[nNew][4]; for(int i=0; i0)this.eliminatedTE = new boolean[this.numberOfTEmeasurements]; int elimNumberTE = 0; for(int i=0; i0){ int newNumber = this.numberOfTEmeasurements - elimNumberTE; if(newNumber==0){ this.numberOfTEmeasurements = 0; } else{ double[][] temp = new double[newNumber][3]; int nIndex = 0; for(int i=0; i0)this.eliminatedTM = new boolean[this.numberOfTMmeasurements]; int elimNumberTM = 0; for(int i=0; i0){ int newNumber = this.numberOfTMmeasurements - elimNumberTM; if(newNumber==0){ this.numberOfTMmeasurements = 0; } else{ double[][] temp = new double[newNumber][3]; int nIndex = 0; for(int i=0; i arrayl = new ArrayList(); // initial gap distance this.prismToWaveguideGap = 1.e1; // set calculation to fixed gap for each gap decrement calculation this.fixedPrismToWaveguideGap = true; // arrays to store experimental and, at each gap decrement, the calculated effective refractive indices double[] effectExpl = new double[this.numberOfMeasurements]; double[] effectCalc = new double[this.numberOfMeasurements]; // Collect experimental effective refractive indices for(int i=0; i0)this.calcTEmodeCoreFilmRefractiveIndices(); if(this.numberOfTMmeasurements>0)this.calcTMmodeCoreFilmRefractiveIndices(); // Calculate the overall mean and standard deviation of the core refractive indices if(this.numberOfTEmeasurements>0 && this.numberOfTMmeasurements==0){ this.meanCoreFilmRefractiveIndex = this.meanTEmodeCoreFilmRefractiveIndex; this.coreFilmRefractiveIndex = this.meanCoreFilmRefractiveIndex; this.sdCoreFilmRefractiveIndex = this.sdTEmodeCoreFilmRefractiveIndex; } else{ if(this.numberOfTMmeasurements>0 && this.numberOfTEmeasurements==0){ this.meanCoreFilmRefractiveIndex = this.meanTMmodeCoreFilmRefractiveIndex; this.coreFilmRefractiveIndex = this.meanCoreFilmRefractiveIndex; this.sdCoreFilmRefractiveIndex = this.sdTMmodeCoreFilmRefractiveIndex; } else{ double[] values = new double[this.numberOfMeasurements]; double[] weights = new double[this.numberOfMeasurements]; for(int i=0; i1){ this.meanTEmodeCoreFilmRefractiveIndex = Stat.mean(this.coreFilmTEmodeRefractiveIndices, weights); this.sdTEmodeCoreFilmRefractiveIndex = Stat.standardDeviation(this.coreFilmTEmodeRefractiveIndices, weights); } else{ this.meanTEmodeCoreFilmRefractiveIndex = this.coreFilmTEmodeRefractiveIndices[0]; } } // Calculate TM mode refractive indices public void calcTMmodeCoreFilmRefractiveIndices(){ this.coreFilmTMmodeRefractiveIndices = new double[this.numberOfTMmeasurements]; // Create instance of the class holding the TE mode core film refractive index function FunctTM func = new FunctTM(); // Set function parameters func.substrateRefractiveIndex2 = this.substrateRefractiveIndex2; func.superstrateRefractiveIndex2 = this.superstrateRefractiveIndex2; func.prismRefractiveIndex2 = this.prismRefractiveIndex2; func.prismToWaveguideGap = this.prismToWaveguideGap; func.setPrismToWaveguideGap = this.setPrismToWaveguideGap; func.ko = this.ko; double[] weights = new double[this.numberOfTMmeasurements]; this.lowerBound = this.maximumTMmodeEffectiveRefractiveIndex; this.upperBound = 2.0D*this.lowerBound; for(int i=0; i1){ this.meanTMmodeCoreFilmRefractiveIndex = Stat.mean(this.coreFilmTMmodeRefractiveIndices, weights); this.sdTMmodeCoreFilmRefractiveIndex = Stat.standardDeviation(this.coreFilmTMmodeRefractiveIndices, weights); } else{ this.meanTMmodeCoreFilmRefractiveIndex = this.coreFilmTMmodeRefractiveIndices[0]; } } // Calculate a TE mode dispersion curve public double[][] dispersionCurveTE(double lowThickness, double highThickness, int numberOfPoints, double modeNumber){ if(!this.setWavelength)throw new IllegalArgumentException("No wavelength has been entered"); if(!this.setSubstrate)throw new IllegalArgumentException("No substrate refractive index has been entered"); if(!this.setCore)throw new IllegalArgumentException("No core film refractive index has been calculated or entered"); // Create arrays double[] thickness = new double[numberOfPoints]; double[] effective = new double[numberOfPoints]; double[][] returnedArray = new double[2][numberOfPoints]; double incr = (Fmath.log10(highThickness) - Fmath.log10(lowThickness))/(numberOfPoints - 1); thickness[0] = Fmath.log10(lowThickness); thickness[numberOfPoints-1] = Fmath.log10(highThickness); for(int i=1; i arraylTE = null; int pOrderNumberTE = 0; int pOrdersCheckedTE = 0; int maximumNumberOfPoints = 0; if(this.numberOfTEmeasurements>0){ arraylTE = new ArrayList(); boolean testModes = true; int pOrder = 0; int numberTestedPositive = 0; while(testModes){ int pNumber = 0; for(int i=0; i0)pOrderNumberTE++; if(pNumber>maximumNumberOfPoints)maximumNumberOfPoints = pNumber; if(numberTestedPositive==this.numberOfTEmeasurements){ testModes=false; } else{ pOrder++; } } pOrdersCheckedTE = pOrder; } int numberOfCurves = pOrderNumberTE; // separate TM mode orders ArrayList arraylTM = null; int pOrderNumberTM = 0; int pOrdersCheckedTM = 0; if(this.numberOfTMmeasurements>0){ arraylTM = new ArrayList(); boolean testModes = true; int pOrder = 0; int numberTestedPositive = 0; while(testModes){ int pNumber = 0; for(int i=0; i0)pOrderNumberTM++; if(pNumber>maximumNumberOfPoints)maximumNumberOfPoints = pNumber; if(numberTestedPositive==this.numberOfTMmeasurements){ testModes=false; } else{ pOrder++; } } pOrdersCheckedTM = pOrder; } numberOfCurves += pOrderNumberTM; numberOfCurves *= 2; if(maximumNumberOfPoints<200)maximumNumberOfPoints = 200; // Set up plotting data arrays double[][] plotData = PlotGraph.data(numberOfCurves, maximumNumberOfPoints); double[] modeNumber = new double[numberOfCurves]; String[] modeType = new String[numberOfCurves]; int atCurveNumber = 0; int plotNumber = 0; // TE mode curves int arraylIndex = 2*(pOrdersCheckedTE+1); int arraylHeaderIndex = 1; double tempD = 0.0D; int tempI = 0; if(this.numberOfTEmeasurements>0){ int testVec = 0; int arraylSize = arraylTE.size(); while(testVec0){ modeType[atCurveNumber] = "TE"; modeType[atCurveNumber+1] = "TE"; modeNumber[atCurveNumber] = ((Integer)arraylTE.get(arraylHeaderIndex-1)).intValue(); modeNumber[atCurveNumber+1] = modeNumber[atCurveNumber]; testVec++; // experimental data curve double[] tempThick = new double[tempI]; double[] tempRefra = new double[tempI]; for(int i=0; i0){ int testVec = 0; int arraylSize = arraylTM.size(); while(testVec0){ modeType[atCurveNumber] = "TM"; modeType[atCurveNumber+1] = "TM"; modeNumber[atCurveNumber] = ((Integer)arraylTM.get(arraylHeaderIndex-1)).intValue(); testVec++; modeNumber[atCurveNumber+1] = modeNumber[atCurveNumber]; // experimental data curve double[] tempThick = new double[tempI]; double[] tempRefra = new double[tempI]; for(int i=0; i0)this.eliminatedTE = new boolean[this.numberOfTEmeasurements]; int elimNumberTE = 0; for(int i=0; ithis.coreFilmRefractiveIndex){ System.out.println("TE mode measurement point, " + i + ", eliminated as the effective refractive index, " + this.measurementsTE[i][1] + ", lies above the physical limit, " + this.coreFilmRefractiveIndex); this.eliminatedTE[i] = true; elimNumberTE++; } else{ if(this.upperBound>this.measurementsTE[i][1])this.upperBound = this.measurementsTE[i][1]; } } if(elimNumberTE>0){ int newNumber = this.numberOfTEmeasurements - elimNumberTE; if(newNumber==0){ this.numberOfTEmeasurements = 0; } else{ double[][] temp = new double[newNumber][3]; int nIndex = 0; for(int i=0; i0)this.eliminatedTM = new boolean[this.numberOfTMmeasurements]; int elimNumberTM = 0; for(int i=0; ithis.coreFilmRefractiveIndex){ System.out.println("TM mode measurement point, " + i + ", eliminated as the effective refractive index, " + this.measurementsTM[i][1] + ", lies above the physical limit, " + this.coreFilmRefractiveIndex); this.eliminatedTM[i] = true; elimNumberTM++; } else{ if(this.upperBound>this.measurementsTM[i][1])this.upperBound = this.measurementsTM[i][1]; } } if(elimNumberTM>0){ int newNumber = this.numberOfTMmeasurements - elimNumberTM; if(newNumber==0){ this.numberOfTMmeasurements = 0; } else{ double[][] temp = new double[newNumber][3]; int nIndex = 0; for(int i=0; i0)this.calcTEmodeSuperstrateRefractiveIndices(); if(this.numberOfTMmeasurements>0)this.calcTMmodeSuperstrateRefractiveIndices(); // Calculate the overall mean and standard deviation of the superstrate refractive index if(this.numberOfTEmeasurements>0 && this.numberOfTMmeasurements==0){ this.superstrateRefractiveIndex = this.meanTEmodeSuperstrateRefractiveIndex; this.sdSuperstrateRefractiveIndex = this.sdTEmodeSuperstrateRefractiveIndex; } else{ if(this.numberOfTMmeasurements>0 && this.numberOfTEmeasurements==0){ this.superstrateRefractiveIndex = this.meanTMmodeSuperstrateRefractiveIndex; this.sdSuperstrateRefractiveIndex = this.sdTMmodeSuperstrateRefractiveIndex; } else{ double[] values = new double[this.numberOfMeasurements]; double[] weights = new double[this.numberOfMeasurements]; for(int i=0; i1){ this.meanTEmodeSuperstrateRefractiveIndex = Stat.mean(this.calcSuperstrateTEmodeRI, weights); this.sdTEmodeSuperstrateRefractiveIndex = Stat.standardDeviation(this.calcSuperstrateTEmodeRI, weights); } else{ this.meanTEmodeSuperstrateRefractiveIndex = this.calcSuperstrateTEmodeRI[0]; } } // Calculate TM mode refractive indices public void calcTMmodeSuperstrateRefractiveIndices(){ this.calcSuperstrateTMmodeRI = new double[this.numberOfTMmeasurements]; // Create instance of the class holding the TM mode core film refractive indexfunction FunctTMsuper func = new FunctTMsuper(); // Set function parameters func.coreFilmRefractiveIndex2 = this.coreFilmRefractiveIndex2; func.ko = this.ko; double[] weights = new double[this.numberOfTMmeasurements]; this.lowerBound = 1.0D; this.upperBound = this.minimumTMmodeEffectiveRefractiveIndex; for(int i=0; i1){ this.meanTMmodeSuperstrateRefractiveIndex = Stat.mean(this.calcSuperstrateTMmodeRI, weights); this.sdTMmodeSuperstrateRefractiveIndex = Stat.standardDeviation(this.calcSuperstrateTMmodeRI, weights); } else{ this.meanTMmodeSuperstrateRefractiveIndex = this.calcSuperstrateTMmodeRI[0]; } } } // Class containing function with the root search for the TE mode core film refractive index class FunctTE implements RealRootFunction{ public double substrateRefractiveIndex2 = 0.0D; public double superstrateRefractiveIndex2 = 0.0D; public double effectiveRefractiveIndex2 = 0.0D; public double prismRefractiveIndex2 = 0.0D; public double ko = 0.0D; public double prismToWaveguideGap = 0.0D; public boolean setPrismToWaveguideGap = false; public double thickness = 0.0D; public double modeNumber = 0; public double function(double x){ double y = 0.0D; // function calculation double coreFilmRefractiveIndex2 = x*x; double zetaSub = Math.sqrt(this.effectiveRefractiveIndex2 - this.substrateRefractiveIndex2); double zetaSuper = Math.sqrt(this.effectiveRefractiveIndex2 - this.superstrateRefractiveIndex2); double zetaFilm = Math.sqrt(coreFilmRefractiveIndex2 - this.effectiveRefractiveIndex2); double zetaPrism = Math.sqrt(this.prismRefractiveIndex2 - this.effectiveRefractiveIndex2); double gammaSuper = Math.atan2(zetaSuper, zetaFilm); y = Math.PI*modeNumber - this.thickness*this.ko*zetaFilm; y += (gammaSuper + Math.atan2(zetaSub, zetaFilm)); if(this.setPrismToWaveguideGap) y += (Math.sin(gammaSuper)*Math.cos( Math.atan2(zetaSuper, zetaPrism))*Math.exp(-2.0D*this.prismToWaveguideGap*this.ko*zetaSuper)); return y; } } // Class containing function with the root search for the TM mode core film refractive index class FunctTM implements RealRootFunction{ public double substrateRefractiveIndex2 = 0.0D; public double superstrateRefractiveIndex2 = 0.0D; public double effectiveRefractiveIndex2 = 0.0D; public double prismRefractiveIndex2 = 0.0D; public double ko = 0.0D; public double prismToWaveguideGap = 0.0D; public boolean setPrismToWaveguideGap = false; public double thickness = 0.0D; public double modeNumber = 0; public double function(double x){ double y = 0.0D; // function calculation double coreFilmRefractiveIndex2 = x*x; double zetaSub = Math.sqrt(this.effectiveRefractiveIndex2 - this.substrateRefractiveIndex2); double zetaSuper = Math.sqrt(this.effectiveRefractiveIndex2 - this.superstrateRefractiveIndex2); double zetaFilm = Math.sqrt(coreFilmRefractiveIndex2 - this.effectiveRefractiveIndex2); double zetaPrism = Math.sqrt(this.prismRefractiveIndex2 - this.effectiveRefractiveIndex2); double gammaSuper = Math.atan2(coreFilmRefractiveIndex2*zetaSuper, this.superstrateRefractiveIndex2*zetaFilm); y = Math.PI*modeNumber - this.thickness*this.ko*zetaFilm; y += (gammaSuper + Math.atan2(coreFilmRefractiveIndex2*zetaSub, this.substrateRefractiveIndex2*zetaFilm)); if(this.setPrismToWaveguideGap) y += (Math.sin(gammaSuper)*Math.cos( Math.atan2(zetaSuper*this.prismRefractiveIndex2, zetaPrism*this.superstrateRefractiveIndex2))*Math.exp(-2.0D*this.prismToWaveguideGap*zetaSuper)); return y; } } // Class containing function with the root search for the TE mode effective refractive index class FunctTEplot implements RealRootFunction{ public double substrateRefractiveIndex2 = 0.0D; public double superstrateRefractiveIndex2 = 0.0D; public double coreFilmRefractiveIndex2 = 0.0D; public double prismRefractiveIndex2 = 0.0D; public double ko = 0.0D; public double prismToWaveguideGap = 0.0D; public boolean setPrismToWaveguideGap = false; public double thickness = 0.0D; public double modeNumber = 0; public double function(double x){ double y = 0.0D; // function calculation double effectiveRefractiveIndex2 = x*x; double zetaSub = Math.sqrt(effectiveRefractiveIndex2 - this.substrateRefractiveIndex2); double zetaSuper = Math.sqrt(effectiveRefractiveIndex2 - this.superstrateRefractiveIndex2); double zetaFilm = Math.sqrt(this.coreFilmRefractiveIndex2 - effectiveRefractiveIndex2); double zetaPrism = Math.sqrt(this.prismRefractiveIndex2 - effectiveRefractiveIndex2); double gammaSuper = Math.atan2(zetaSuper, zetaFilm); y = Math.PI*modeNumber - this.thickness*this.ko*zetaFilm; y += (gammaSuper + Math.atan2(zetaSub, zetaFilm)); if(this.setPrismToWaveguideGap) y += (Math.sin(gammaSuper)*Math.cos( Math.atan2(zetaSuper, zetaPrism))*Math.exp(-2.0D*this.prismToWaveguideGap*this.ko*zetaSuper)); return y; } } // Class containing function with the root search for the TM mode effective refractive index class FunctTMplot implements RealRootFunction{ public double substrateRefractiveIndex2 = 0.0D; public double superstrateRefractiveIndex2 = 0.0D; public double coreFilmRefractiveIndex2 = 0.0D; public double prismRefractiveIndex2 = 0.0D; public double ko = 0.0D; public double prismToWaveguideGap = 0.0D; public boolean setPrismToWaveguideGap = false; public double thickness = 0.0D; public double modeNumber = 0; public double function(double x){ double y = 0.0D; double effectiveRefractiveIndex2 = x*x; double zetaSub = Math.sqrt(effectiveRefractiveIndex2 - this.substrateRefractiveIndex2); double zetaSuper = Math.sqrt(effectiveRefractiveIndex2 - this.superstrateRefractiveIndex2); double zetaFilm = Math.sqrt(this.coreFilmRefractiveIndex2 - effectiveRefractiveIndex2); double zetaPrism = Math.sqrt(this.prismRefractiveIndex2 - effectiveRefractiveIndex2); double gammaSuper = Math.atan2(this.coreFilmRefractiveIndex2*zetaSuper, this.superstrateRefractiveIndex2*zetaFilm); y = Math.PI*modeNumber - this.thickness*this.ko*zetaFilm; y += (gammaSuper + Math.atan2(this.coreFilmRefractiveIndex2*zetaSub, this.substrateRefractiveIndex2*zetaFilm)); if(this.setPrismToWaveguideGap) y += (Math.sin(gammaSuper)*Math.cos( Math.atan2(zetaSuper*this.prismRefractiveIndex2, zetaPrism*this.superstrateRefractiveIndex2))*Math.exp(-2.0D*this.prismToWaveguideGap*zetaSuper)); return y; } } // Class containing function with the root search for the TE mode superstrate refractive index class FunctTEsuper implements RealRootFunction{ public double substrateRefractiveIndex2 = 0.0D; public double effectiveRefractiveIndex2 = 0.0D; public double coreFilmRefractiveIndex2 = 0.0D; public double ko = 0.0D; public double thickness = 0.0D; public double modeNumber = 0; public double function(double x){ double y = 0.0D; // function calculation double superstrateRefractiveIndex2 = x*x; double zetaSub = Math.sqrt(this.effectiveRefractiveIndex2 - this.substrateRefractiveIndex2); double zetaSuper = Math.sqrt(effectiveRefractiveIndex2 - superstrateRefractiveIndex2); double zetaFilm = Math.sqrt(this.coreFilmRefractiveIndex2 - this.effectiveRefractiveIndex2); y = Math.PI*modeNumber - this.thickness*this.ko*zetaFilm; y += (Math.atan2(zetaSuper, zetaFilm) + Math.atan2(zetaSub, zetaFilm)); return y; } } // Class containing function with the root search for the TM mode superstrate refractive index class FunctTMsuper implements RealRootFunction{ public double substrateRefractiveIndex2 = 0.0D; public double effectiveRefractiveIndex2 = 0.0D; public double coreFilmRefractiveIndex2 = 0.0D; public double ko = 0.0D; public double thickness = 0.0D; public double modeNumber = 0; public double function(double x){ double y = 0.0D; double superstrateRefractiveIndex2 = x*x; double zetaSub = Math.sqrt(this.effectiveRefractiveIndex2 - this.substrateRefractiveIndex2); double zetaSuper = Math.sqrt(effectiveRefractiveIndex2 - superstrateRefractiveIndex2); double zetaFilm = Math.sqrt(this.coreFilmRefractiveIndex2 - this.effectiveRefractiveIndex2); y = Math.PI*modeNumber - this.thickness*this.ko*zetaFilm; y += (Math.atan2(this.coreFilmRefractiveIndex2*zetaSuper, superstrateRefractiveIndex2*zetaFilm) + Math.atan2(this.coreFilmRefractiveIndex2*zetaSub, this.substrateRefractiveIndex2*zetaFilm)); return y; } }