This package provides three classes:
In a typical program, one can use the focus3d class to generate the focal fields or the excitation fields and pipe this field distribution as the dipole field to the dipole_radiation class to calculate the far-field radiation.
) at wavelength
with wavevector magnitude
due to a lens of focal length
is given in angular spectrum representation as
where the variable
is the polar angle and
is the azimuthal angle; the limit of integration
corresponds to the numerical apaerture of the lens;
is the refractive index before the refraction at the lens and
is the refractive index after the refraction at the lens;
is the incident field on the lens;
and
are the coordinate transformation
matrices are given by
The opeartion
on
leads to refraction of the incident fields due to the curvature of the lens. If a scattering medium is present between the lens surface and the focal point, the rays that reach the focal point from the lens get perturbed and their amplitudes and phases get scrambled. This scrambling of phase and amplitude by the scattering medium can be modeled as a scalar angular weight function,
. These angular weights for various
are calculated using Monte-carlo simulations. This weight function can be included in the above formula as
where
,
, and
are the x- y- and z-components of the incident field and the sine and cosine functions are abbreviated as
and
respectively. Evaluation of thie above double integral gives the three components of the electric field at
near the focus of the lens. In this package, the numerical integration is performed using the Simpson 1/3-rule.
The above Eq. is used for calculating the focal field for various wavelengths. In the case of CARS, the focal fields for the pump and the Stokes wavelengths are calculated. The CARS excitation at the focal volume is generated by simply multiplying the fields according the relationship
The excitation volume is modeled as a collection of dipoles with their magnitude and orientation being equal to those of the excitation field at that point. Thus the electric vector at a far-field point, say at the surface of the collection lens of focal length f',
is simply a coherent sum of the fields originating from individual points
near the focus.
where
with
,
, and
. After performing the vector product operations, we have the far-field electric vector as
where
,
, and
are the x,y, and z-components of the dipole field. This is the field on the spherical surface of the collecting lens. If the collecting lens a complete sphere, then the above Eq. gives the radiation pattern from the dipole distribution. The three dimensional integral in the above equation is numerically calculated in this software package using Simpson 1/3-rule.
The field after refraction at the spherical surface is obtained by pre-multiplying
with the coordinate transformation matrix combination
where the matrices
and
are defined in the beginning of this section. Hence the refracted field
is
The c++ code implemented in this package defines one class, focus3d, to compute
and a second one, dipole_radiation, to compute
and
. In this software package, the effects of refractive index mismatch are neglected.
LIBDIR = <focal-fields package dir>/lib/
INCLUDES = <focal-fields package dir>/include/
mysource.exe : mysource.cpp
g++ mysource.cpp -Wall -I$(INCLUDES) -L$(LIBDIR) -lm -lblitz -lfocalfields -o mysource.exe
Below is a listing of some of the example programs written using the focal fields package. They provide a good review of the essential commands required for efficiently using this package.
#ifndef __FOCAL_VOLUME_H__ #define __FOCAL_VOLUME_H__ #include "focalfields.h" #endif
#include "focal_volume.h" int main(int argc, char** argv) { if(argc < 3) { cerr << "Usage: " << argv[0] << " <parameters file> <output directory>\n"; exit(-1); } string param_file = argv[1]; string outputdir = argv[2]; focus3d_parameters p; if(!p.load(param_file)) {exit (-1);} // load the parameters file p.print(); Array<complex<double>,3> E_focus1_x, E_focus1_y, E_focus1_z; Array<complex<double>,2> E_inc_x, E_inc_y, E_inc_z; E_focus1_x.resize(p.Nx,p.Ny,p.Nz); E_focus1_x = 0; E_focus1_y.resize(p.Nx,p.Ny,p.Nz); E_focus1_y = 0; E_focus1_z.resize(p.Nx,p.Ny,p.Nz); E_focus1_z = 0; E_inc_x.resize(p.Ntheta,p.Nphi); E_inc_y.resize(p.Ntheta,p.Nphi); E_inc_z.resize(p.Ntheta,p.Nphi); E_inc_x = 1.0; E_inc_y = 0.0; E_inc_z = 0.0; focus3d focus1(p); focus1.set_incident_field(E_inc_x,E_inc_y,E_inc_z); focus1.calculate_focus(E_focus1_x,E_focus1_y,E_focus1_z); focus1.save_results(outputdir); return(0); }
#ifndef __RADIATION_FROM_FOCAL_VOLUME_H__ #define __RADIATION_FROM_FOCAL_VOLUME_H__ #include "focalfields.h" #endif
#include "radiation_from_focal_volume.h" int main(int argc, char** argv) { if(argc < 3) { cerr << "Usage: " << argv[0] << " <parameters file> <output directory>\n"; exit(-1); } string param_file = argv[1]; string outputdir = argv[2]; focus3d_parameters p; if(!p.load(param_file)) {exit (-1);} // load the parameters file Array<complex<double>,2> E_rad_x, E_rad_y, E_rad_z; E_rad_x.resize(p.Ntheta,p.Nphi); E_rad_y.resize(p.Ntheta,p.Nphi); E_rad_z.resize(p.Ntheta,p.Nphi); E_rad_x = 0.0; E_rad_y = 0.0; E_rad_z = 0.0; dipole_radiation drad(p); drad.set_dipole_field("successive/focus1_lambda_0.8/E_focus_x.bar", \ "successive/focus1_lambda_0.8/E_focus_y.bar", \ "successive/focus1_lambda_0.8/E_focus_z.bar"); drad.calculate_refracted_radiation(E_rad_x,E_rad_y,E_rad_z); drad.save_results(outputdir); return(0); }
#ifndef __SUCCESSIVE_FOCUS_RADIATE_FOCUS_H__ #define __SUCCESSIVE_FOCUS_RADIATE_FOCUS_H__ #include "focalfields.h" #endif
#include "successive_focus_radiate_focus.h" int main(int argc, char** argv) { if(argc < 3) { cerr << "Usage: " << argv[0] << " <parameters file> <output directory>\n"; exit(-1); } string param_file = argv[1]; string outputdir = argv[2]; focus3d_parameters p; if(!p.load(param_file)) {exit (-1);} // load the parameters file Array<complex<double>,2> E_inc_x, E_inc_y, E_inc_z; Array<complex<double>,3> E_focus1_x, E_focus1_y, E_focus1_z; Array<complex<double>,2> E_rad_x, E_rad_y, E_rad_z; Array<complex<double>,3> E_focus2_x, E_focus2_y, E_focus2_z; E_inc_x.resize(p.Ntheta,p.Nphi); E_inc_y.resize(p.Ntheta,p.Nphi); E_inc_z.resize(p.Ntheta,p.Nphi); E_inc_x = 1.0; E_inc_y = 0.0; E_inc_z = 0.0; E_focus1_x.resize(p.Nx,p.Ny,p.Nz); E_focus1_x = 0; E_focus1_y.resize(p.Nx,p.Ny,p.Nz); E_focus1_y = 0; E_focus1_z.resize(p.Nx,p.Ny,p.Nz); E_focus1_z = 0; E_rad_x.resize(p.Ntheta,p.Nphi); E_rad_x = 0; E_rad_y.resize(p.Ntheta,p.Nphi); E_rad_y = 0; E_rad_z.resize(p.Ntheta,p.Nphi); E_rad_z = 0; E_focus2_x.resize(p.Nx,p.Ny,p.Nz); E_focus2_x = 0; E_focus2_y.resize(p.Nx,p.Ny,p.Nz); E_focus2_y = 0; E_focus2_z.resize(p.Nx,p.Ny,p.Nz); E_focus2_z = 0; cout << "---------------------------------------------\n"; cout << "---------------- first focus ----------------\n"; cout << "---------------------------------------------\n"; focus3d focus1(p); focus1.set_incident_field(E_inc_x,E_inc_y,E_inc_z); focus1.calculate_focus(E_focus1_x,E_focus1_y,E_focus1_z); focus1.save_results(string(outputdir + "/coarse_focus1")); cout << "---------------------------------------------\n"; cout << "------------------ radiation ----------------\n"; cout << "---------------------------------------------\n"; dipole_radiation drad(p); drad.set_dipole_field(E_focus1_x,E_focus1_y,E_focus1_z); drad.calculate_refracted_radiation(E_rad_x,E_rad_y,E_rad_z); drad.save_results(string(outputdir + "/coarse_radiation")); cout << "---------------------------------------------\n"; cout << "---------------- second focus ---------------\n"; cout << "---------------------------------------------\n"; focus3d focus2(p); focus2.set_incident_field(E_rad_x,E_rad_y,E_rad_z); focus2.calculate_focus(E_focus2_x,E_focus2_y,E_focus2_z); focus2.save_results(string(outputdir+"/coarse_focus2")); return(0); }
#ifndef __CARS_EXCITATION_H__ #define __CARS_EXCITATION_H__ #include "focalfields.h" #endif
#include "cars_excitation.h" int main(int argc, char** argv) { if(argc < 4) { cerr << "Usage: " << argv[0] << " <pump-parameters file> <stokes-parameters file> <output directory>\n"; exit(-1); } string param_file_p = argv[1]; string param_file_s = argv[2]; string outputdir = argv[3]; stringstream filename; focus3d_parameters pp, ps, pc, temp; if(!pp.load(param_file_p)) {exit (-1);} // load the parameters file if(!ps.load(param_file_s)) {exit (-1);} // load the parameters file cout << "PUMP PARAMETERS:\n"; pp.print(); cout << "STOKES PARAMETERS:\n"; ps.print(); temp = pp; temp.lambda = ps.lambda; if(temp != ps) { cerr << "Input error! The spatial parameters in the two files do not match! Exiting\n"; exit(-1); } pc = ps; pc.lambda = 1.0/((2.0/pp.lambda) - (1.0/ps.lambda)); cout << "CARS PARAMETERS:\n"; pc.print(); Array<complex<double>,3> E_focus_pump_x, E_focus_pump_y, E_focus_pump_z; Array<complex<double>,3> E_focus_stokes_x, E_focus_stokes_y, E_focus_stokes_z; Array<complex<double>,3> cars_pol_x, cars_pol_y, cars_pol_z; Array<complex<double>,2> E_inc_x, E_inc_y, E_inc_z; E_focus_pump_x.resize(pp.Nx,pp.Ny,pp.Nz); E_focus_pump_x = 0; E_focus_pump_y.resize(pp.Nx,pp.Ny,pp.Nz); E_focus_pump_y = 0; E_focus_pump_z.resize(pp.Nx,pp.Ny,pp.Nz); E_focus_pump_z = 0; E_focus_stokes_x.resize(ps.Nx,ps.Ny,ps.Nz); E_focus_stokes_x = 0; E_focus_stokes_y.resize(ps.Nx,ps.Ny,ps.Nz); E_focus_stokes_y = 0; E_focus_stokes_z.resize(ps.Nx,ps.Ny,ps.Nz); E_focus_stokes_z = 0; cars_pol_x.resize(ps.Nx,ps.Ny,ps.Nz); cars_pol_x = 0; cars_pol_y.resize(ps.Nx,ps.Ny,ps.Nz); cars_pol_y = 0; cars_pol_z.resize(ps.Nx,ps.Ny,ps.Nz); cars_pol_z = 0; E_inc_x.resize(pp.Ntheta,pp.Nphi); E_inc_y.resize(pp.Ntheta,pp.Nphi); E_inc_z.resize(pp.Ntheta,pp.Nphi); E_inc_x = 1.0; E_inc_y = 0.0; E_inc_z = 0.0; cout << "Calculating pump focal field\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; focus3d focus_pump(pp); focus_pump.set_incident_field(E_inc_x,E_inc_y,E_inc_z); focus_pump.calculate_focus(E_focus_pump_x,E_focus_pump_y,E_focus_pump_z); focus_pump.save_results(outputdir+"pump"); E_inc_x.resize(ps.Ntheta,ps.Nphi); E_inc_y.resize(ps.Ntheta,ps.Nphi); E_inc_z.resize(ps.Ntheta,ps.Nphi); E_inc_x = 1.0; E_inc_y = 0.0; E_inc_z = 0.0; cout << "Calculating stokes focal field\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; focus3d focus_stokes(ps); focus_stokes.set_incident_field(E_inc_x,E_inc_y,E_inc_z); focus_stokes.calculate_focus(E_focus_stokes_x,E_focus_stokes_y,E_focus_stokes_z); focus_stokes.save_results(outputdir+"stokes"); complex<double> chi = 2.0; cout << "Calculating CARS excitation\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; cars_pol_x = chi*E_focus_pump_x*E_focus_pump_x*conj(E_focus_stokes_x); cars_pol_y = chi*E_focus_pump_y*E_focus_pump_y*conj(E_focus_stokes_y); cars_pol_z = chi*E_focus_pump_z*E_focus_pump_z*conj(E_focus_stokes_z); cout << "Saving CARS excitation\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; ofstream fout; filename.str(string()); filename << outputdir << "cars_excitation_x.bar"; cout << filename.str() << endl; fout.open(filename.str().c_str()); if(!fout) { cerr << "File error!! Unable to write " << filename.str() << endl; exit(-1); } fout << cars_pol_x; fout.close(); filename.str(string()); filename << outputdir << "cars_excitation_y.bar"; cout << filename.str() << endl; fout.open(filename.str().c_str()); if(!fout) { cerr << "File error!! Unable to write " << filename.str() << endl; exit(-1); } fout << cars_pol_y; fout.close(); filename.str(string()); filename << outputdir << "cars_excitation_z.bar"; cout << filename.str() << endl; fout.open(filename.str().c_str()); if(!fout) { cerr << "File error!! Unable to write " << filename.str() << endl; exit(-1); } fout << cars_pol_z; fout.close(); filename.str(string()); filename << outputdir << "cars_simulation_parameters.dat"; cout << filename.str() << endl; pc.save(filename.str()); return(0); }
1.5.5