00001 #include <fstream>
00002 #include <iomanip>
00003 #include "tools.h"
00004 #include "GratingLayer1D.h"
00005
00006
00007 #ifndef STD
00008 #define STD
00009 using namespace std;
00010 #endif
00011 using TBCI::F_Matrix;
00012 using TBCI::F_BandMatrix;
00013 using TBCI::Vector;
00014
00015
00020 GratingLayer1D::GratingLayer(int truncate, int segments){
00021 nOrds = truncate; maxOrd=(nOrds-1)/2; minOrd=-maxOrd;
00022 nPermSegs = segments;
00023 minPermCoeff = -(nOrds-1);
00024 maxPermCoeff = nOrds-1;
00025 nPermCoeffs = maxPermCoeff-minPermCoeff+1;
00026 permCoeff.resize(2*nOrds-1);
00027 permCoeffInv.resize(2*nOrds-1);
00028 eigVal.resize(nOrds);
00029 alpha.resize(nOrds);
00030 transPt.resize(segments);
00031 refInd.resize(segments);
00032 gamma.resize(nOrds);
00033 I = complex<double>(0.,1.);
00034 B.resize(nOrds, nOrds);
00035 epsMat.resize(nOrds, nOrds);
00036 invEpsMat.resize(nOrds, nOrds);
00037 epsMat_inv.resize(nOrds, nOrds);
00038 invEpsMat_inv.resize(nOrds, nOrds);
00039 eigMat.resize(nOrds, nOrds);
00040 polMode="TM";
00041 eigVecE.resize(nOrds, nOrds);
00042 eigVecH.resize(nOrds, nOrds);
00043 invEigVecE.resize(nOrds, nOrds);
00044 invEigVecH.resize(nOrds, nOrds);
00045 }
00046
00047 GratingLayer1D::~GratingLayer()
00048 {}
00049
00050
00051
00055 void GratingLayer1D::setPolMode(string polarisation){polMode=polarisation;}
00057 string GratingLayer1D::getPolMode(void){return polMode;}
00058
00060 void GratingLayer1D::setThickness(double layerThickness) {thickness=layerThickness;}
00062 double GratingLayer1D::getThickness() {return thickness;}
00064 void GratingLayer1D::setLambda(double wavelength){lambda=wavelength;}
00066 double GratingLayer1D::getLambda(){return lambda;}
00067
00069 void GratingLayer1D::setN0(complex<double> n){n0=n;}
00071 complex<double> GratingLayer1D::getN0(void){return n0;}
00073 void GratingLayer1D::setPeriod(double per){period = per;}
00075 double GratingLayer1D::getPeriod(void){return period;}
00077 int GratingLayer1D::getnOrds(void){return nOrds;}
00078
00082 void GratingLayer1D::setnPermSegs(int segments)
00083 {
00084 nPermSegs = segments;
00085 refInd.resize(segments);
00086 transPt.resize(segments);
00087 }
00089 int GratingLayer1D::getnPermSegs() {return nPermSegs;}
00091 void GratingLayer1D::setTransPt(Vector<double> point) {for (int i=0; i<nPermSegs; i++){transPt[i]=point[i];}}
00096 double GratingLayer1D::getTransPt(int comp) {return transPt[comp];}
00097
00099 void GratingLayer1D::setAngle(double angle){theta = angle*M_PI/180.;}
00100
00101 void GratingLayer1D::setRefInd(Vector < complex<double> > index){for (int i = 0; i<nPermSegs; i++){refInd[i]=index[i];}}
00102 complex<double> GratingLayer1D::getRefInd(int comp){return refInd[comp];}
00103
00104 complex<double> GratingLayer1D::getPermCoeff(int order){return permCoeff[order+maxPermCoeff];}
00105 complex<double> GratingLayer1D::getAlpha(int order){return alpha[order];}
00106 complex<double> GratingLayer1D::getEigVal(int order){return eigVal[order];}
00107 complex<double> GratingLayer1D::getEigMat(int row, int column){return eigMat(row,column);}
00109 complex<double> GratingLayer1D::getGamma(int order){return gamma[order];}
00110 complex<double> GratingLayer1D::getEigVecE(int vec, int comp){return eigVecE(vec,comp);}
00111 complex<double> GratingLayer1D::getEigVecH(int vec, int comp){return eigVecH(vec,comp);}
00112 complex<double> GratingLayer1D::getInvEigVecE(int vec, int comp){return invEigVecE(vec,comp);}
00113 complex<double> GratingLayer1D::getInvEigVecH(int vec, int comp){return invEigVecH(vec,comp);}
00114
00127 void GratingLayer1D::setParameters(double wavelength, double angle, complex<double>ind0, double period, double height, Vector <double> points, Vector < complex<double> > indices, string pol){
00128 setLambda(wavelength);
00129 setPeriod(period);
00130 setThickness(height);
00131 setTransPt(points);
00132 setN0(ind0);
00133 setAngle(angle);
00134 setRefInd(indices);
00135 setPolMode(pol);
00136 }
00137
00148 void GratingLayer1D::solve(string method="T")
00149 {
00150 CalculatePermitivity();
00151 createEigMat();
00152 solveEigMat();
00153 if (method=="S")
00154 {
00155 calcSMatrix();
00156 }
00157 }
00158
00162 void GratingLayer1D::CalculatePermitivity(void)
00163 {
00164
00165 int p = minPermCoeff;
00166 complex<double> prev, curr;
00167 for(int i=0; i<nPermCoeffs; i++)
00168 {
00169 permCoeff[i] = complex<double>(0., 0.);
00170 permCoeffInv[i] = complex<double>(0., 0.);
00171 prev = complex<double>((p!=0 ? 1. : 0.), 0.);
00172
00173 for(int j=0; j<nPermSegs; j++){
00174 if (p!=0) {curr = 1.*exp(-I*2.*M_PI*(1.*p)*transPt[j]) ;}
00175 else {curr = complex<double>(transPt[j], 0.);}
00176
00177 permCoeff[i] += pow(refInd[j],2) * (curr - prev);
00178 if (polMode == "TM") permCoeffInv[i] += (1./pow(refInd[j],2.)) * (curr - prev);
00179 prev = curr;
00180 }
00181 if(p!=0){
00182 permCoeff[i] *= complex<double>(0., 1./(2.*M_PI*p));
00183 if (polMode == "TM") permCoeffInv[i] *= complex<double>(0., 1./(2.*M_PI*p));
00184 }
00185 p++;
00186 }
00187 }
00188
00189
00190
00191 void GratingLayer1D::createEigMat(void)
00192 {
00193 int l, m;
00194 complex<double> z;
00195 double ksq = pow((2.*M_PI/lambda), 2);
00196
00197
00198 gamma0=n0*2.*M_PI/lambda*sin(theta);
00199 for(int i=0;i<nOrds;i++) {gamma[i] = gamma0 + 2*M_PI*(i+minOrd)/period;}
00200
00201
00202 if (polMode == "TE")
00203 {
00204 l= minOrd;
00205 for(int i=0;i<nOrds;i++){
00206 m=minOrd;
00207 for(int j=0;j<nOrds;j++)
00208 {
00209 z=permCoeff[nOrds-1+l-m] * ksq;
00210 if(l==m) {z -= pow(gamma[m+maxOrd],2);}
00211 eigMat(i,j) = z;
00212 if (norm(eigMat(i,j))<1e-12) eigMat(i,j)=0.;
00213 m++;
00214 }
00215 l++;
00216 }
00217 }
00218
00219
00220 else if (polMode == "TM")
00221 {
00222 for (int i=0;i<nOrds;i++)
00223 {
00224 for (int j=0;j<nOrds;j++)
00225 {
00226 epsMat(i,j)=permCoeff[nOrds-1+i-j];
00227 invEpsMat(i,j)=permCoeffInv[nOrds-1+i-j];
00228 }
00229 }
00230 epsMat_inv=inv(epsMat);
00231 invEpsMat_inv=inv(invEpsMat);
00232
00233 for (int i=0;i<nOrds;i++)
00234 {
00235 for (int j=0;j<nOrds;j++)
00236 {
00237 B(i,j)=complex<double>(((i==j) ? ksq : 0.),0.) - epsMat_inv(i,j)*gamma[i]*gamma[j];
00238 }
00239 }
00240 eigMat=invEpsMat_inv*B;
00241 }
00242 }
00243
00244
00245 void GratingLayer1D::solveEigMat(void){
00246 tiny=1e-12;
00247 for (int i=0;i<nOrds;i++)
00248 {
00249 for (int j=0;j<nOrds;j++)
00250 {
00251 if (fabs(real(eigMat(i,j)))<tiny) {eigMat(i,j)=complex<double>(0.,imag(eigMat(i,j)));}
00252 if (fabs(imag(eigMat(i,j)))<tiny) {eigMat(i,j)=complex<double>(real(eigMat(i,j)), 0.); }
00253 }
00254 }
00255 if (eig(eigMat,eigVal,eigVecE)!=0) cout<<"Problems with Eigenvector calculation\n";;
00256
00257 for(int i=0;i<nOrds;i++)
00258 {
00259 alpha[i] = sqrt(eigVal[i]);
00260 alpha[i] = complex<double>(fabs(real(alpha[i])),fabs(imag(alpha[i])));
00261 }
00262 }
00263
00264 void GratingLayer1D::calcSMatrix(void)
00265 {
00266 complex<double> z;
00267
00268 if (polMode=="TE")
00269 {
00270 for (int i=0;i<nOrds; i++)
00271 {
00272 eigVecH.set_col(alpha[i]*eigVecE.get_col(i),i);
00273 }
00274 }
00275 if (polMode=="TM")
00276 {
00277 eigVecH=invEpsMat*eigVecE;
00278 for (int i=0;i<nOrds;i++)
00279 {
00280 eigVecH.set_col(eigVecH.get_col(i)*alpha[i],i);
00281 }
00282 }
00283
00284
00285
00286 double normal;
00287 for (int i=0;i<nOrds;i++)
00288 {
00289 normal=0.;
00290 for (int j=0;j<nOrds;j++) normal+=norm(eigVecH(j,i));
00291 for (int j=0;j<nOrds;j++)
00292 {
00293 invEigVecE(i,j)=conj(eigVecE(j,i));
00294 invEigVecH(i,j)=conj(eigVecH(j,i))/normal;
00295 }
00296 }
00297 }
00298
00299
00300 void GratingLayer1D::writeIndex(int orders=-1, string filename="index.dat")
00301 {
00302 if (orders==-1) orders=nOrds;
00303 int size = 1000;
00304 Vector < complex<double> > index(size);
00305 if (orders%2==0) orders++;
00306 ofstream out;
00307 out.open("filename");
00308 for (int i=0; i<size;i++)
00309 {
00310 index[i]=0.;
00311 for (int p=-(orders-1)/2;p<=(orders-1)/2; p++)
00312 {
00313 index[i]+=getPermCoeff(p)*exp(I*(2*M_PI*p*i/size));
00314 }
00315 out<<index[i]<<"\n";
00316 }
00317 out.close();
00318 }