|
@@ -87,50 +87,57 @@ int Nmax(int L, int fl, int pl,
|
|
|
}
|
|
|
|
|
|
//**********************************************************************************//
|
|
|
-// This function calculates the spherical Bessel functions (jn and hn) for a given //
|
|
|
-// value of z. //
|
|
|
+// This function calculates the spherical Bessel functions (jn and yn) for a given //
|
|
|
+// real value r. See pag. 87 B&H. //
|
|
|
// //
|
|
|
// Input parameters: //
|
|
|
-// z: Real argument to evaluate jn and hn //
|
|
|
-// n_max: Maximum number of terms to calculate jn and hn //
|
|
|
+// r: Real argument to evaluate jn and yn //
|
|
|
+// n_max: Maximum number of terms to calculate jn and yn //
|
|
|
// //
|
|
|
// Output parameters: //
|
|
|
-// jn, hn: Spherical Bessel functions (complex) //
|
|
|
+// jn, yn: Spherical Bessel functions (double) //
|
|
|
//**********************************************************************************//
|
|
|
-void sphericalBessel(std::complex<double> r, int n_max, std::vector<std::complex<double> > &j, std::vector<std::complex<double> > &h) {
|
|
|
+void sphericalBessel(double r, int n_max, std::vector<double> &j, std::vector<double> &y) {
|
|
|
int n;
|
|
|
|
|
|
- j[0] = sin(r)/r;
|
|
|
- j[1] = sin(r)/r/r - cos(r)/r;
|
|
|
- h[0] = -cos(r)/r;
|
|
|
- h[1] = -cos(r)/r/r - sin(r)/r;
|
|
|
+ if (n_max >= 1) {
|
|
|
+ j[0] = sin(r)/r;
|
|
|
+ y[0] = -cos(r)/r;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (n_max >= 2) {
|
|
|
+ j[1] = sin(r)/r/r - cos(r)/r;
|
|
|
+ y[1] = -cos(r)/r/r - sin(r)/r;
|
|
|
+ }
|
|
|
+
|
|
|
for (n = 2; n < n_max; n++) {
|
|
|
j[n] = double(n + n + 1)*j[n - 1]/r - j[n - 2];
|
|
|
- h[n] = double(n + n + 1)*h[n - 1]/r - h[n - 2];
|
|
|
+ y[n] = double(n + n + 1)*y[n - 1]/r - h[n - 2];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//**********************************************************************************//
|
|
|
-// This function calculates the spherical Bessel functions (jn and hn) for a given //
|
|
|
-// value of r. //
|
|
|
+// This function calculates the spherical Hankel functions (h1n and h2n) for a //
|
|
|
+// given real value r. See eqs. (4.13) and (4.14), pag. 87 B&H. //
|
|
|
// //
|
|
|
// Input parameters: //
|
|
|
-// r: Real argument to evaluate jn and hn //
|
|
|
-// n_max: Maximum number of terms to calculate jn and hn //
|
|
|
+// r: Real argument to evaluate h1n and h2n //
|
|
|
+// n_max: Maximum number of terms to calculate h1n and h2n //
|
|
|
// //
|
|
|
// Output parameters: //
|
|
|
-// jn, hn: Spherical Bessel functions (double) //
|
|
|
+// h1n, h2n: Spherical Hankel functions (complex) //
|
|
|
//**********************************************************************************//
|
|
|
-void sphericalBessel(double r, int n_max, std::vector<double> &j, std::vector<double> &h) {
|
|
|
+void sphericalHankel(double r, int n_max, std::vector<std::complex<double> > &h1, std::vector<std::complex<double> > &h2) {
|
|
|
int n;
|
|
|
+ std::complex<double> j, y;
|
|
|
+ j.resize(n_max);
|
|
|
+ h.resize(n_max);
|
|
|
|
|
|
- j[0] = sin(r)/r;
|
|
|
- j[1] = sin(r)/r/r - cos(r)/r;
|
|
|
- h[0] = -cos(r)/r;
|
|
|
- h[1] = -cos(r)/r/r - sin(r)/r;
|
|
|
- for (n = 2; n < n_max; n++) {
|
|
|
- j[n] = double(n + n + 1)*j[n - 1]/r - j[n - 2];
|
|
|
- h[n] = double(n + n + 1)*h[n - 1]/r - h[n - 2];
|
|
|
+ sphericalBessel(r, n_max, j, y);
|
|
|
+
|
|
|
+ for (n = 0; n < n_max; n++) {
|
|
|
+ h1[n] = std::complex<double> (j[n], y[n]);
|
|
|
+ h2[n] = std::complex<double> (j[n], -y[n]);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -733,69 +740,62 @@ int nField(int L, int pl, std::vector<double> x, std::vector<std::complex<double
|
|
|
std::vector<std::complex<double> > &E, std::vector<std::complex<double> > &H) {
|
|
|
|
|
|
int i, n, c;
|
|
|
-/* double **Pi, **Tau;
|
|
|
- complex *an, *bn;
|
|
|
- double *Rho = (double *) malloc(nCoords*sizeof(double));
|
|
|
- double *Phi = (double *) malloc(nCoords*sizeof(double));
|
|
|
- double *Theta = (double *) malloc(nCoords*sizeof(double));
|
|
|
-
|
|
|
- for (c = 0; c < nCoords; c++) {
|
|
|
- Rho[c] = sqrt(Xp[c]*Xp[c] + Yp[c]*Yp[c] + Zp[c]*Zp[c]);
|
|
|
- if (Rho[c] < 1e-3) {
|
|
|
- Rho[c] = 1e-3;
|
|
|
- }
|
|
|
- Phi[c] = acos(Xp[c]/sqrt(Xp[c]*Xp[c] + Yp[c]*Yp[c]));
|
|
|
- Theta[c] = acos(Xp[c]/Rho[c]);
|
|
|
- }
|
|
|
+ std::vector<std::complex<double> > an, bn;
|
|
|
|
|
|
+ // Calculate scattering coefficients
|
|
|
n_max = ScattCoeffs(L, pl, x, m, n_max, an, bn);
|
|
|
|
|
|
- Pi = (double **) malloc(n_max*sizeof(double *));
|
|
|
- Tau = (double **) malloc(n_max*sizeof(double *));
|
|
|
+ std::vector< std::vector<double> > Pi, Tau;
|
|
|
+ Pi.resize(n_max);
|
|
|
+ Tau.resize(n_max);
|
|
|
for (n = 0; n < n_max; n++) {
|
|
|
- Pi[n] = (double *) malloc(nCoords*sizeof(double));
|
|
|
- Tau[n] = (double *) malloc(nCoords*sizeof(double));
|
|
|
+ Pi[n].resize(nCoords);
|
|
|
+ Tau[n].resize(nCoords);
|
|
|
}
|
|
|
|
|
|
- calcPiTau(n_max, nCoords, Theta, &Pi, &Tau);
|
|
|
+ std::vector<double> Rho, Phi, Theta;
|
|
|
+ Rho.resize(nCoords);
|
|
|
+ Phi.resize(nCoords);
|
|
|
+ Theta.resize(nCoords);
|
|
|
|
|
|
- double x2 = x[L - 1]*x[L - 1];
|
|
|
-
|
|
|
- // Initialize the fields
|
|
|
for (c = 0; c < nCoords; c++) {
|
|
|
- E[c] = C_ZERO;
|
|
|
- H[c] = C_ZERO;
|
|
|
- }*/
|
|
|
-
|
|
|
- //*******************************************************//
|
|
|
- // external scattering field = incident + scattered //
|
|
|
- // BH p.92 (4.37), 94 (4.45), 95 (4.50) //
|
|
|
- // assume: medium is non-absorbing; refim = 0; Uabs = 0 //
|
|
|
- //*******************************************************//
|
|
|
-
|
|
|
- // Firstly the easiest case, we want the field outside the particle
|
|
|
-// if (Rho[c] >= x[L - 1]) {
|
|
|
-// }
|
|
|
- for (i = 1; i < (n_max - 1); i++) {
|
|
|
-// n = i - 1;
|
|
|
-/* // Equation (27)
|
|
|
- *Qext = *Qext + (double)(n + n + 1)*(an[i].r + bn[i].r);
|
|
|
- // Equation (28)
|
|
|
- *Qsca = *Qsca + (double)(n + n + 1)*(an[i].r*an[i].r + an[i].i*an[i].i + bn[i].r*bn[i].r + bn[i].i*bn[i].i);
|
|
|
- // Equation (29)
|
|
|
- *Qpr = *Qpr + ((n*(n + 2)/(n + 1))*((Cadd(Cmul(an[i], std::conj(an[n])), Cmul(bn[i], std::conj(bn[n])))).r) + ((double)(n + n + 1)/(n*(n + 1)))*(Cmul(an[i], std::conj(bn[i])).r));
|
|
|
+ // Convert to spherical coordinates
|
|
|
+ Rho = sqrt(Xp[c]*Xp[c] + Yp[c]*Yp[c] + Zp[c]*Zp[c]);
|
|
|
+ if (Rho < 1e-3) {
|
|
|
+ Rho = 1e-3;
|
|
|
+ }
|
|
|
+ Phi = acos(Xp[c]/sqrt(Xp[c]*Xp[c] + Yp[c]*Yp[c]));
|
|
|
+ Theta = acos(Xp[c]/Rho[c]);
|
|
|
+ }
|
|
|
|
|
|
- // Equation (33)
|
|
|
- Qbktmp = Cadd(Qbktmp, RCmul((double)((n + n + 1)*(1 - 2*(n % 2))), Csub(an[i], bn[i])));
|
|
|
-*/
|
|
|
- //****************************************************//
|
|
|
- // Calculate the scattering amplitudes (S1 and S2) //
|
|
|
- // Equations (25a) - (25b) //
|
|
|
- //****************************************************//
|
|
|
-/* for (t = 0; t < nTheta; t++) {
|
|
|
- S1[t] = Cadd(S1[t], calc_S1(n, an[i], bn[i], Pi[i][t], Tau[i][t]));
|
|
|
- S2[t] = Cadd(S2[t], calc_S2(n, an[i], bn[i], Pi[i][t], Tau[i][t]));
|
|
|
- }*/
|
|
|
+ calcPiTau(n_max, nCoords, Theta, Pi, Tau);
|
|
|
+
|
|
|
+ std::vector<double > j, y;
|
|
|
+ std::vector<std::complex<double> > h1, h2;
|
|
|
+ j.resize(n_max);
|
|
|
+ y.resize(n_max);
|
|
|
+ h1.resize(n_max);
|
|
|
+ h2.resize(n_max);
|
|
|
+
|
|
|
+ for (c = 0; c < nCoords; c++) {
|
|
|
+ //*******************************************************//
|
|
|
+ // external scattering field = incident + scattered //
|
|
|
+ // BH p.92 (4.37), 94 (4.45), 95 (4.50) //
|
|
|
+ // assume: medium is non-absorbing; refim = 0; Uabs = 0 //
|
|
|
+ //*******************************************************//
|
|
|
+
|
|
|
+ // Calculate spherical Bessel and Hankel functions
|
|
|
+ sphericalBessel(Rho, n_max, j, y);
|
|
|
+ sphericalHankel(Rho, n_max, h1, h2);
|
|
|
+
|
|
|
+ // Initialize the fields
|
|
|
+ E[c] = std::complex<double>(0.0, 0.0);
|
|
|
+ H[c] = std::complex<double>(0.0, 0.0);
|
|
|
+
|
|
|
+ // Firstly the easiest case, we want the field outside the particle
|
|
|
+ if (Rho >= x[L - 1]) {
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return n_max;
|