//Update the data output format in example_layer(). #include "layer.h" #include #include #include #include "stim/parser/arguments.h" using namespace std; #define PI 3.14159265358979323846264338328 bool ASCII_output = false; bool CPU_op = false; void advertise() { std::cout << std::endl << std::endl; std::cout << "=========================================================================" << std::endl; //std::cout << "Thank you for using the NetMets network comparison tool!" << std::endl; std::cout << "Scalable Tissue Imaging and Modeling (STIM) Lab, University of Houston" << std::endl; std::cout << "=========================================================================" << std::endl << std::endl; } //Calculate Ez from vector d and Ex Ey. void E_Cal(vector>* E, vector>* d) { if (d->size() == 2) { complex dz = sqrt(1.0 + 0i - pow((*d)[0], 2) - pow((*d)[1], 2)); d->push_back(dz); } E->push_back(-((*E)[0] * (*d)[0] + (*E)[1] * (*d)[1]) / (*d)[2]); } void output_binary(std::string filename, layersample& layers) { size_t L = layers.n.size(); // get the number of layers std::ofstream outFile; outFile.open(filename, std::ofstream::binary); // open the output file for binary writing if (outFile) { outFile.write((char*)&layers.k, sizeof(double)); outFile.write((char*)&layers.d[0], sizeof(double)); outFile.write((char*)&layers.d[1], sizeof(double)); outFile.write((char*)&layers.n[0], sizeof(double) * 2); for (size_t i = 0; i < L; i++) { outFile.write((char*)&layers.z[i], sizeof(double)); outFile.write((char*)&layers.sz[i], 2 * sizeof(double)); outFile.write((char*)&layers.Pt[i], 2 * sizeof(double)); outFile.write((char*)&layers.Pt[i + L], 2 * sizeof(double)); outFile.write((char*)&layers.Pt[i + 2 * L], 2 * sizeof(double)); outFile.write((char*)&layers.Pr[i], 2 * sizeof(double)); outFile.write((char*)&layers.Pr[i + L], 2 * sizeof(double)); outFile.write((char*)&layers.Pr[i + 2 * L], 2 * sizeof(double)); } outFile.close(); } else { std::cout << "ERROR opening output file for binary writing: " << filename << std::endl; } } void output_txt(std::string filename, layersample& layers) { size_t L = layers.n.size(); // get the number of layers std::ofstream outFile; outFile.open(filename); // open the output file for text writing if (!outFile) { std::cout << "ERROR: Could not open file " << filename << std::endl; exit(1); } int width = 15; outFile << "--------------------------------" << endl; outFile << "The wavenumber at free space is : " << layers.k << endl; for (size_t i = 0; i < L; i++) { if (i == 0) { outFile << "--------------------------------" << endl; outFile << "LAYER " << i << " (z = " << layers.z[i] << ")" << endl; outFile << "refractive index: " << layers.n[i].real() << " + i " << layers.n[i].imag() << endl; outFile << "----------------------" << endl; outFile << "sx = " << setw(width) << layers.s[0].real() << " + i " << layers.s[0].imag() << endl; outFile << "sy = " << setw(width) << layers.s[1].real() << " + i " << layers.s[1].imag() << endl; outFile << "sz = " << setw(width) << layers.sz[i].real() << " + i " << layers.sz[i].imag() << endl; outFile << "----->>>>>" << endl; outFile << " X = " << setw(width) << layers.Pt[i].real() << " + i " << layers.Pt[i].imag() << endl; outFile << " Y = " << setw(width) << layers.Pt[i + L].real() << " + i " << layers.Pt[i + L].imag() << endl; outFile << " Z = " << setw(width) << layers.Pt[i + 2 * L].real() << " + i " << layers.Pt[i + 2 * L].imag() << endl; outFile << "<<<<<-----" << endl; outFile << " X = " << setw(width) << layers.Pr[i].real() << " + i " << layers.Pr[i].imag() << endl; outFile << " Y = " << setw(width) << layers.Pr[i + L].real() << " + i " << layers.Pr[i + L].imag() << endl; outFile << " Z = " << setw(width) << layers.Pr[i + 2 * L].real() << " + i " << layers.Pr[i + 2 * L].imag() << endl; } else { outFile << "----------------------" << endl; outFile << "LAYER " << i << " (z = " << layers.z[i] << ")" << endl; outFile << "refractive index: " << layers.n[i].real() << " + i " << layers.n[i].imag() << endl; outFile << "----------------------" << endl; outFile << "sx = " << setw(width) << layers.s[0].real() << " + i " << layers.s[0].imag() << endl; outFile << "sy = " << setw(width) << layers.s[1].real() << " + i " << layers.s[1].imag() << endl; outFile << "sz = " << setw(width) << layers.sz[i].real() << " + i " << layers.sz[i].imag() << endl; outFile << "----->>>>>" << endl; outFile << " X = " << setw(width) << layers.Pt[i].real() << " + i " << layers.Pt[i].imag() << endl; outFile << " Y = " << setw(width) << layers.Pt[i + L].real() << " + i " << layers.Pt[i + L].imag() << endl; outFile << " Z = " << setw(width) << layers.Pt[i + 2 * L].real() << " + i " << layers.Pt[i + 2 * L].imag() << endl; outFile << "<<<<<-----" << endl; outFile << " X = " << setw(width) << layers.Pr[i].real() << " + i " << layers.Pr[i].imag() << endl; outFile << " Y = " << setw(width) << layers.Pr[i + L].real() << " + i " << layers.Pr[i + L].imag() << endl; outFile << " Z = " << setw(width) << layers.Pr[i + 2 * L].real() << " + i " << layers.Pr[i + 2 * L].imag() << endl; } } outFile.close(); } void calculate_layer(std::string outName, vector>* ns, // the refractive index. vector* depths, // z-direction position. vector>* E0, // the initialized E0. vector>* d0, // direction of propagation of the plane wave. double k0) { // the wavenumber at free space. std::string outName_ext(outName, size(outName)-4, size(outName)-1); // extract the extension of the output file E_Cal(E0, d0); // make sure that both vectors are orthogonal. //Creat a new layersample and initialize. layersample Layer1; // create a layered sample Layer1.n = *ns; // set a pointer to the refractive indices Layer1.z = *depths; // set a pointer to the layer depths Layer1.d = *d0; Layer1.k = k0; LARGE_INTEGER t1, t2, tc; // Timing. QueryPerformanceFrequency(&tc); QueryPerformanceCounter(&t1); Layer1.solve(E0, CPU_op); // Solve for the substrate field in GPU. QueryPerformanceCounter(&t2); std::cout << "time for 'solving linear functions':" << (t2.QuadPart - t1.QuadPart) / (double)tc.QuadPart << "ms."<< std::endl; //output(outName, Layer1); if (ASCII_output) output_txt(outName, Layer1); else output_binary(outName, Layer1); } //Main function for example_layer. int main(int argc, char* argv[]) { stim::arglist args; //Basic argument lists. args.add("help", "prints this help"); args.add("s", "propagation direction vector (x, y)", "0.5 0.0", "[-1.0, 1.0]"); args.add("l", "wavelength", "5.0", "in arbitrary units (ex. um)"); args.add("Ex", "complex amplitude (x direction)", "0.5 0.0"); args.add("Ey", "complex amplitude (y direction)", "0.5 0.0"); args.add("z", "layer positions"); args.add("n", "layer optical path length (real refractive index)", "1.0 1.4 1.4 1.0"); args.add("kappa", "layer absorbance (imaginary refractive index)"); args.add("ascii", "output as an ASCII file"); args.add("CPU", "execute the program in CPU"); args.parse(argc, argv); if (args["help"].is_set()) { // test for help advertise(); // output the advertisement std::cout << args.str(); // output arguments exit(1); // exit } ASCII_output = args["ascii"]; // if the ascii flag is set, output an ascii file CPU_op = args["CPU"]; // if the CPU_op is set, run the program in CPU. std::string outName; if (args.nargs() == 1) { outName = args.arg(0); } else if (args.nargs() == 0) { if (ASCII_output) outName = "output.txt"; else outName = "output.lyr"; } else { std::cout << "ERROR: Too many arguments." << std::endl; exit(1); } vector> d; //direction of propagation of the plane wave Init: {0.5, 0} if (args["s"].nargs() == 2) { d.push_back({ (double)args["s"].as_float(0), 0 }); d.push_back({ (double)args["s"].as_float(1), 0 }); } double l0 = (double)args["l"].as_float(0); //wavelength.Init: l0 = 5; double k0 = 2 * PI / l0; //Calculate the free-space wavenumber. complex Ex = { (double)args["Ex"].as_float(0), (double)args["Ex"].as_float(1) }; //Input E. Init: {1, 1, 0} complex Ey = { (double)args["Ey"].as_float(0), (double)args["Ey"].as_float(1) }; vector> E0; E0.push_back(Ex); E0.push_back(Ey); //const int LAYERS = args["L"].as_int(); //LAYERS Init: 4 vector depths; vector> ns; size_t i = 0; while(args["n"].is_set() && args["n"].as_float(i)!=0) { //n is the real part. if (args["kappa"].is_set()) //kappa is the imaginary part. ns.push_back({ (double)args["n"].as_float(i), (double)args["kappa"].as_float(i) }); else ns.push_back({ (double)args["n"].as_float(i), 0 }); //ns <- n + i * kappa i++; } for (size_t j = 0; j < i; j++) if (args["z"].is_set()) depths.push_back((double)args["z"].as_float(i)); else { depths.push_back((double)-100 + j * 200 / i); } /*---------------------------------------example_layer--------------------------------------------*/ calculate_layer(outName, &ns, &depths, &E0, &d, k0); return 0; std::cin.get(); }