//****************************************************************************** //** SCATMECH: Polarized Light Scattering C++ Class Library //** //** File: roughnes.cpp //** //** Thomas A. Germer //** Sensor Science Division, National Institute of Standards and Technology //** 100 Bureau Dr. Stop 8443; Gaithersburg, MD 20899-8443 //** Phone: (301) 975-2876 //** Email: thomas.germer@nist.gov //** //****************************************************************************** #include "scatmech.h" #include "roughnes.h" #include "allrough.h" #include using namespace std; namespace SCATMECH { // // Jones scattering matrix for scattering from a single rough interface... // JonesMatrix Roughness_Stack_BRDF_Model:: jones() { double theta0=thetai; double theta=thetas; double phi=phis; // This program follows the derivation outlined in: // J. M. Elson, "Multilayer-coated optics: guided-wave coupling // and scattering by means of interface random // roughness," J. Opt. Soc. Am. A 12(4) 729 (1995). // J. M. Elson, "Theory and Software for Light Scattering From // Multilayer Optical Components with Interfacial // Roughness," Naval Air Warfare Center Weapons // Division (NAWCWPNS), Tech. Pub. 8084 (1992). // // Define variables with names in line with those used by Elson. // Note that I use C/C++ conventions and start counting at zero, // instead of 1. // // Note use of class JonesMatrix for doing 2x2 matrix calculations. // These matrices have nothing to do with the Jones formalism, but // rather with transfer matrices, and are used only for convenience. // // Note that I assume omega_0/c = 1 and I(ntensity) = 1. // (Use I to be sqrt(-1).) // SETUP(); const int M11=1,M12=2,M21=3,M22=0; int L=stack->get_n(); int m = is_forward() ? this_layer : L-this_layer; int n; if (this_layer<0) error("this_layer<0"); if (this_layer>L) error("this_layer>number of layers"); COMPLEX I(0,1); vector d(L+1); vector eps(L+2); vector q0(L+2); vector q1(L+2); // // The parameter theta is defined differently for // reflection than for transmission... // double sintheta = sin(theta); COMPLEX scatter_medium = is_reflection() ? COMPLEX(1.,0.) : (COMPLEX)(substrate.index(lambda)); COMPLEX k = sin(theta)*scatter_medium; double k0 = sin(theta0); double _lambda = lambda; // // Define variables as per Figure 1 of paper. // if (is_forward()) { eps[0]=(COMPLEX)(substrate.epsilon(lambda)); for (n=1; nget_e()[n-1].epsilon(lambda)); } eps[L+1]=1; d[0]=0; for (n=1; nget_t()[n-1]/lambda; } else { // is_backward() _lambda = lambda/substrate.n(lambda); scatter_medium = is_reflection() ? 1. : 1/substrate.n(lambda); k = sin(theta)*scatter_medium; eps[0]=1./(COMPLEX)(substrate.epsilon(lambda)); for (n=1; nget_e()[L-n].epsilon(lambda))/(COMPLEX)(substrate.epsilon(lambda)); } eps[L+1]=1.; d[0]=0; for (n=1; nget_t()[L-n]/_lambda; } // // Symbols defined in the paper: // alpha_i, q^(0)_i, q^(1)_i, beta_i, mu_i, p_i // for (n=0; npsd(fx,fy)); J.PP() = mu_pp/P11L1[M11]; J.SS() = -mu_ss/S11L1[M11]; J.SP() = (mu_ps)/P11L1[M11]; J.PS() = (-mu_sp)/S11L1[M11]; J = J*prefactor; } else { // is_transmission() COMPLEX eta3 = P11m1[M21]*exp(-I*q1[m]*d[m])+P11m1[M22]*exp(I*q1[m]*d[m]); COMPLEX eta4 = P11m1[M21]*exp(-I*q1[m]*d[m])-P11m1[M22]*exp(I*q1[m]*d[m]); COMPLEX alpha_pp = -k*sqrt(eps[m])*Y1p/q1[m]*(eta1*P11L1[M21]-eta3*P11L1[M11]) + Y2p/sqrt(eps[m])*(eta2*P11L1[M21]-eta4*P11L1[M11]); COMPLEX alpha_sp = Xp/q1[m]*(xi2*S11L1[M11]-xi1*S11L1[M21]); COMPLEX alpha_ps = k*sqrt(eps[m])*Y1s/q1[m]*(eta1*P11L1[M21]-eta3*P11L1[M11]) + Y2s/sqrt(eps[m])*(eta2*P11L1[M21]-eta4*P11L1[M11]); COMPLEX alpha_ss = Xs/q1[m]*(xi2*S11L1[M11]-xi1*S11L1[M21]); double fx,fy; Bragg_Frequency(fx,fy); COMPLEX prefactor = sqrt( pow(2.*pi/_lambda,4.)*q1[0]*eps[0]/(16.*sqr(pi)*q0[L+1]) * psd->psd(fx,fy) ); J.PP() = alpha_pp/P11L1[M11]; J.SS() = alpha_ss/S11L1[M11]; J.SP() = alpha_ps/P11L1[M11]; J.PS() = alpha_sp/S11L1[M11]; J = J*prefactor; } if (is_forward()) { return J; } else { return JonesMatrix(J[0],J[1],-J[2],-J[3]); } } void Register(const Roughness_Stack_BRDF_Model* x) { static bool Models_Registered = false; if (!Models_Registered) { Models_Registered=true; Register_Model(Roughness_Stack_BRDF_Model); Register_Model(Correlated_Roughness_Stack_BRDF_Model); Register_Model(Uncorrelated_Roughness_Stack_BRDF_Model); Register_Model(Growth_Roughness_Stack_BRDF_Model); } } DEFINE_MODEL(Roughness_Stack_BRDF_Model,Roughness_BRDF_Model, "Scattering by a single rough interface in a stack of films."); DEFINE_PTRPARAMETER(Roughness_Stack_BRDF_Model,StackModel_Ptr,stack,"Film stack on substrate","No_StackModel",0xFF); DEFINE_PARAMETER(Roughness_Stack_BRDF_Model,int,this_layer,"Rough interface","0",0xFF); } // namespace SCATMECH