/** * @file test-negative-epsilon.cc * @author Konstantin Ladutenko * @date Mon Mar 9 13:21:37 2015 * * @brief test negative epsilon case * // 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 . // * */ #include "nmie.h" #include template inline T pow2(const T value) {return value*value;}; const double PI=3.14159265358979323846; nmie::MultiLayerMie multi_layer_mie_; double lambda_work_ = 3.75; // cm double a_ = 0.75*lambda_work_; // 2.8125 cm - size of PEC core double min_index_ = 1e-11; // ********************************************************************** // // ********************************************************************** // // ********************************************************************** // double EvaluateScatterOnlyIndex(std::vector input) { double Qsca; std::vector> cindex; cindex.clear(); double k = min_index_, n=min_index_; for (double epsilon : input) { // sqrt(epsilon) = n + i*k k = min_index_; n=min_index_; if (epsilon > 0.0) n=std::sqrt(epsilon); else k = std::sqrt(-epsilon); if (n < min_index_) n = min_index_; if (k < min_index_) k = min_index_; //printf("eps= %g, n=%g, k=%g\n", epsilon, n, k); cindex.push_back(std::complex(n, k)); } multi_layer_mie_.SetCoatingIndex(cindex); try { multi_layer_mie_.RunMieCalculations(); Qsca = multi_layer_mie_.GetQsca(); } catch( const std::invalid_argument &ia ) { Qsca = 0; printf("#"); // Will catch if multi_layer_mie_ fails or other errors. //std::cerr << "Invalid argument: " << ia.what() << std::endl; } double total_r = multi_layer_mie_.GetTotalRadius(); return Qsca*PI*pow2(total_r); } int main(int argc, char *argv[]) { try { // Only PEC target multi_layer_mie_.SetTargetPEC(a_); multi_layer_mie_.SetWavelength(lambda_work_); multi_layer_mie_.RunMieCalculations(); double PEC_Qsca = multi_layer_mie_.GetQsca(); double PEC_r = multi_layer_mie_.GetTotalRadius(); double PEC_RCS = PEC_Qsca*PI*pow2(PEC_r); // PEC target covered with with air layer multi_layer_mie_.SetCoatingWidth({0.1}); multi_layer_mie_.SetCoatingIndex({{1.0,0.0}}); multi_layer_mie_.RunMieCalculations(); double Qsca1 = multi_layer_mie_.GetQsca(); double total_r1 = multi_layer_mie_.GetTotalRadius(); double initial_RCS1 = Qsca1*PI*pow2(total_r1); printf("RCS = %g cm^2 with (r=%g) and RCS=%g cm^2 without (r=%g)air coating.\n", initial_RCS1, total_r1, PEC_RCS, PEC_r); //multi_layer_mie.SetMaxTermsNumber(150); // Bi-layer, inner layer = lossless metall. std::vector> cindex; cindex.clear(); double n=min_index_; double k=std::sqrt(0.29); cindex.push_back(std::complex(n, k)); n=std::sqrt(24.6); k=min_index_; cindex.push_back(std::complex(n, k)); multi_layer_mie_.SetCoatingWidth({0.1,0.1}); multi_layer_mie_.SetCoatingIndex(cindex); multi_layer_mie_.RunMieCalculations(); double Qsca = multi_layer_mie_.GetQsca(); double total_r = multi_layer_mie_.GetTotalRadius(); double initial_RCS = Qsca*PI*pow2(total_r); printf("RCS=%g for bi-layer coating (total R=%g).\n", initial_RCS,total_r); n=1.0; k=min_index_; cindex.push_back(std::complex(n, k)); multi_layer_mie_.SetCoatingWidth({0.1,0.1,0.1}); multi_layer_mie_.SetCoatingIndex(cindex); multi_layer_mie_.RunMieCalculations(); Qsca = multi_layer_mie_.GetQsca(); total_r = multi_layer_mie_.GetTotalRadius(); initial_RCS = Qsca*PI*pow2(total_r); printf("RCS=%g for bi-layer+air coating (total R=%g).\n", initial_RCS,total_r); //multi_layer_mie_.SetMaxTermsNumber(15); multi_layer_mie_.SetCoatingWidth({0.1,0.1}); printf("With %g coating= (26.24).\n", EvaluateScatterOnlyIndex({-0.29, 24.6})); multi_layer_mie_.SetCoatingWidth({0.1,0.1,0.1}); printf("With %g coating> (26.24).\n", EvaluateScatterOnlyIndex({-0.29, 24.6, 1.0})); //multi_layer_mie_.SetMaxTermsNumber(-1); // 26.24: 25|| -0.29 +24.60 // 28.48: 38|| -0.29 +24.60 +1.00 } 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; }