//**********************************************************************************// // Copyright (C) 2009-2015 Ovidio Pena <ovidio@bytesfall.com> // // Copyright (C) 2013-2015 Konstantin Ladutenko <kostyfisik@gmail.com> // // // // This file is part of scattnlay // // // // This program is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // The only additional remark is that we expect that all publications // // describing work using this software, or all commercial products // // using it, cite the following reference: // // [1] O. Pena and U. Pal, "Scattering of electromagnetic radiation by // // a multilayered sphere," Computer Physics Communications, // // vol. 180, Nov. 2009, pp. 2348-2354. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see <http://www.gnu.org/licenses/>. // //**********************************************************************************// // This program returns expansion coefficents of Mie series #include <complex> #include <cstdio> #include <string> #include "../src/nmie-applied.hpp" #include "../src/nmie-applied-impl.hpp" #include "../src/nmie-precision.hpp" #include "./read-spectra.h" // template<class T> inline T pow2(const T value) {return value*value;} int main(int argc, char *argv[]) { using namespace nmie ; try { read_spectra::ReadSpectra Si_index, Ag_index; read_spectra::ReadSpectra plot_core_index_, plot_TiN_; std::string core_filename("Si-int.txt"); //std::string core_filename("Ag.txt"); //std::string TiN_filename("TiN.txt"); std::string TiN_filename("Ag-int.txt"); //std::string TiN_filename("Si.txt"); std::string shell_filename(core_filename); nmie::MultiLayerMieApplied<nmie::FloatType> multi_layer_mie; const std::complex<double> epsilon_Si(18.4631066585, 0.6259727805); const std::complex<double> epsilon_Ag(-8.5014154589, 0.7585845411); const std::complex<double> index_Si = std::sqrt(epsilon_Si); const std::complex<double> index_Ag = std::sqrt(epsilon_Ag); double WL=500; //nm double core_width = 5.27; //nm Si double inner_width = 8.22; //nm Ag double outer_width = 67.91; //nm Si bool isSiAgSi = true; double delta_width = 25.0; //bool isSiAgSi = false; if (isSiAgSi) { core_width = 5.27; //nm Si inner_width = 8.22; //nm Ag outer_width = 67.91; //nm Si multi_layer_mie.AddTargetLayer(core_width, index_Si); multi_layer_mie.AddTargetLayer(inner_width, index_Ag); multi_layer_mie.AddTargetLayer(outer_width+delta_width, index_Si); } else { inner_width = 31.93; //nm Ag outer_width = 4.06; //nm Si multi_layer_mie.AddTargetLayer(inner_width, index_Ag); multi_layer_mie.AddTargetLayer(outer_width+delta_width, index_Si); } for (int dd = 0; dd<50; ++dd) { delta_width = dd; FILE *fp; std::string fname = "absorb-layered-spectra-d"+std::to_string(dd)+".dat"; fp = fopen(fname.c_str(), "w"); multi_layer_mie.SetWavelength(WL); multi_layer_mie.RunMieCalculation(); double Qabs = static_cast<double>(multi_layer_mie.GetQabs()); printf("Qabs = %g\n", Qabs); std::vector< std::vector<std::complex<nmie::FloatType> > > aln, bln, cln, dln; multi_layer_mie.GetExpanCoeffs(aln, bln, cln, dln); std::vector< std::vector<std::complex<double> > > d_aln = nmie::ConvertComplexVectorVector<double>(aln); std::string str = std::string("#WL "); for (int l = 0; l<d_aln.size(); ++l) { for (int n = 0; n<3; ++n) { str+="|a|^2+|d|^2_ln"+std::to_string(l)+std::to_string(n)+" " + "|b|^2+|c|^2_ln"+std::to_string(l)+std::to_string(n)+" "; } } str+="\n"; fprintf(fp, "%s", str.c_str()); fprintf(fp, "# |a|+|d|"); str.clear(); double from_WL = 400; double to_WL = 600; int total_points = 401; double delta_WL = std::abs(to_WL - from_WL)/(total_points-1.0); Si_index.ReadFromFile(core_filename).ResizeToComplex(from_WL, to_WL, total_points) .ToIndex(); Ag_index.ReadFromFile(TiN_filename).ResizeToComplex(from_WL, to_WL, total_points) .ToIndex(); auto Si_data = Si_index.GetIndex(); auto Ag_data = Ag_index.GetIndex(); for (int i=0; i < Si_data.size(); ++i) { const double& WL = Si_data[i].first; const std::complex<double>& Si = Si_data[i].second; const std::complex<double>& Ag = Ag_data[i].second; str+=std::to_string(WL); multi_layer_mie.ClearTarget(); if (isSiAgSi) { multi_layer_mie.AddTargetLayer(core_width, Si); multi_layer_mie.AddTargetLayer(inner_width, Ag); multi_layer_mie.AddTargetLayer(outer_width+delta_width, Si); } else { inner_width = 31.93; //nm Ag outer_width = 4.06; //nm Si multi_layer_mie.AddTargetLayer(inner_width, Ag); multi_layer_mie.AddTargetLayer(outer_width+delta_width, Si); } multi_layer_mie.SetWavelength(WL); multi_layer_mie.RunMieCalculation(); multi_layer_mie.GetQabs(); multi_layer_mie.GetExpanCoeffs(aln, bln, cln, dln); for (int l = 0; l<aln.size(); ++l) { for (int n = 0; n<3; ++n) { str+=" "+std::to_string(static_cast<double>(pow2(std::abs(aln[l][n]))+ pow2(std::abs(dln[l][n])))) + " " + std::to_string(static_cast<double>(pow2(std::abs(bln[l][n])) + pow2(std::abs(cln[l][n])) )); // str+=" "+std::to_string(aln[l][n].real() - pow2(std::abs(aln[l][n])) // +dln[l][n].real() - pow2(std::abs(dln[l][n]))) // + " " // + std::to_string(bln[l][n].real() - pow2(std::abs(bln[l][n])) // +cln[l][n].real() - pow2(std::abs(cln[l][n])) ); } } str+="\n"; fprintf(fp, "%s", str.c_str()); str.clear(); } fclose(fp); } // WL = 500; // multi_layer_mie.SetWavelength(WL); // multi_layer_mie.RunMieCalculation(); // multi_layer_mie.GetQabs(); // multi_layer_mie.GetExpanCoeffs(aln, bln, cln, dln); // printf("\n Scattering"); // for (int l = 0; l<aln.size(); ++l) { // int n = 0; // printf("aln[%i][%i] = %g, %gi\n", l, n+1, aln[l][n].real(), aln[l][n].imag()); // printf("bln[%i][%i] = %g, %gi\n", l, n+1, bln[l][n].real(), bln[l][n].imag()); // printf("cln[%i][%i] = %g, %gi\n", l, n+1, cln[l][n].real(), cln[l][n].imag()); // printf("dln[%i][%i] = %g, %gi\n", l, n+1, dln[l][n].real(), dln[l][n].imag()); // n = 1; // printf("aln[%i][%i] = %g, %gi\n", l, n+1, aln[l][n].real(), aln[l][n].imag()); // printf("bln[%i][%i] = %g, %gi\n", l, n+1, bln[l][n].real(), bln[l][n].imag()); // printf("cln[%i][%i] = %g, %gi\n", l, n+1, cln[l][n].real(), cln[l][n].imag()); // printf("dln[%i][%i] = %g, %gi\n", l, n+1, dln[l][n].real(), dln[l][n].imag()); // // n = 2; // // printf("aln[%i][%i] = %g, %gi\n", l, n+1, aln[l][n].real(), aln[l][n].imag()); // // printf("bln[%i][%i] = %g, %gi\n", l, n+1, bln[l][n].real(), bln[l][n].imag()); // // printf("cln[%i][%i] = %g, %gi\n", l, n+1, cln[l][n].real(), cln[l][n].imag()); // // printf("dln[%i][%i] = %g, %gi\n", l, n+1, dln[l][n].real(), dln[l][n].imag()); // } // printf("\n Absorbtion\n"); // for (int l = 0; l<aln.size(); ++l) { // if (l == aln.size()-1) printf(" Total "); // printf("===== l=%i =====\n", l); // int n = 0; // printf("aln[%i][%i] = %g\n", l, n+1, aln[l][n].real() - pow2(std::abs(aln[l][n]))); // printf("bln[%i][%i] = %g\n", l, n+1, bln[l][n].real() - pow2(std::abs(bln[l][n]))); // printf("cln[%i][%i] = %g\n", l, n+1, cln[l][n].real() - pow2(std::abs(cln[l][n]))); // printf("dln[%i][%i] = %g\n", l, n+1, dln[l][n].real() - pow2(std::abs(dln[l][n]))); // n = 1; // printf("aln[%i][%i] = %g\n", l, n+1, aln[l][n].real() - pow2(std::abs(aln[l][n]))); // printf("bln[%i][%i] = %g\n", l, n+1, bln[l][n].real() - pow2(std::abs(bln[l][n]))); // printf("cln[%i][%i] = %g\n", l, n+1, cln[l][n].real() - pow2(std::abs(cln[l][n]))); // printf("dln[%i][%i] = %g\n", l, n+1, dln[l][n].real() - pow2(std::abs(dln[l][n]))); // // n = 2; // // printf("aln[%i][%i] = %g\n", l, n+1, aln[l][n].real() - pow2(std::abs(aln[l][n]))); // // printf("bln[%i][%i] = %g\n", l, n+1, bln[l][n].real() - pow2(std::abs(bln[l][n]))); // // printf("cln[%i][%i] = %g\n", l, n+1, cln[l][n].real() - pow2(std::abs(cln[l][n]))); // // printf("dln[%i][%i] = %g\n", l, n+1, dln[l][n].real() - pow2(std::abs(dln[l][n]))); // } } catch( const std::invalid_argument& ia ) { // Will catch if multi_layer_mie fails or other errors. std::cerr << "Invalid argument: " << ia.what() << std::endl; return -1; } return 0; }