102 #ifdef ENABLE_TMATRIX
336 #ifdef ENABLE_TMATRIX
343 #ifndef ENABLE_TMATRIX
378 throw std::runtime_error(
"This version of ARTS was compiled without T-Matrix support.");
397 throw std::runtime_error(
"This version of ARTS was compiled without T-Matrix support.");
415 throw std::runtime_error(
"This version of ARTS was compiled without T-Matrix support.");
420 throw std::runtime_error(
"This version of ARTS was compiled without T-Matrix support.");
440 ampl_(nmax, lam, thet0, thet, phi0, phi, alpha,
beta, s11, s12, s21, s22);
466 z(0, 0) = 0.5 * ( s11 * conj(s11) + s12 * conj(s12)
467 + s21 * conj(s21) + s22 * conj(s22)).
real();
468 z(0, 1) = 0.5 * ( s11 * conj(s11) - s12 * conj(s12)
469 + s21 * conj(s21) - s22 * conj(s22)).
real();
470 z(0, 2) = ( -s11 * conj(s12) - s22 * conj(s21)).
real();
471 z(0, 3) = (
Complex(0., 1.) * ( s11 * conj(s12) - s22 * conj(s21))).real();
473 z(1, 0) = 0.5 * ( s11 * conj(s11) + s12 * conj(s12)
474 - s21 * conj(s21) - s22 * conj(s22)).
real();
475 z(1, 1) = 0.5 * ( s11 * conj(s11) - s12 * conj(s12)
476 - s21 * conj(s21) + s22 * conj(s22)).
real();
477 z(1, 2) = ( -s11 * conj(s12) + s22 * conj(s21)).
real();
478 z(1, 3) = (
Complex(0., 1.) * ( s11 * conj(s12) + s22 * conj(s21))).real();
480 z(2, 0) = ( -s11 * conj(s21) - s22 * conj(s12)).
real();
481 z(2, 1) = ( -s11 * conj(s21) + s22 * conj(s12)).
real();
482 z(2, 2) = ( s11 * conj(s22) + s12 * conj(s21)).
real();
483 z(2, 3) = (
Complex(0., -1.) * ( s11 * conj(s22) + s21 * conj(s12))).real();
485 z(3, 0) = (
Complex(0., 1.) * ( s21 * conj(s11) + s22 * conj(s12))).real();
486 z(3, 1) = (
Complex(0., 1.) * ( s21 * conj(s11) - s22 * conj(s12))).real();
487 z(3, 2) = (
Complex(0., -1.) * ( s22 * conj(s11) - s12 * conj(s21))).real();
488 z(3, 3) = ( s22 * conj(s11) - s12 * conj(s21)).
real();
494 static const Numeric GaussLeg6[][3] = {
495 {0.23861918, 0.66120939, 0.93246951},
496 {0.46791393, 0.36076157, 0.17132449}
499 static const Numeric GaussLeg10[][5] = {
500 {0.14887434, 0.43339539, 0.67940957, 0.86506337, 0.97390653},
501 {0.29552422, 0.26926672, 0.21908636, 0.14945135, 0.06667134}
534 const Numeric c = 0.5 * (alpha_2+alpha_1);
535 const Numeric m = 0.5 * (alpha_2-alpha_1);
541 for (
Index i = 0; i < 5; ++i)
543 const Numeric abscissa = GaussLeg10[0][i];
544 const Numeric weight = GaussLeg10[1][i];
546 calc_phamat(z, nmax, lam, thet0, thet, phi0, phi,
beta, c + m*abscissa);
550 calc_phamat(z, nmax, lam, thet0, thet, phi0, phi,
beta, c - m*abscissa);
587 const Numeric c = 0.5 * (alpha_2+alpha_1);
588 const Numeric m = 0.5 * (alpha_2-alpha_1);
594 for (
Index i = 0; i < 3; ++i)
596 const Numeric abscissa = GaussLeg6[0][i];
597 const Numeric weight = GaussLeg6[1][i];
599 calc_phamat(z, nmax, lam, thet0, thet, phi0, phi,
beta, c + m*abscissa);
603 calc_phamat(z, nmax, lam, thet0, thet, phi0, phi,
beta, c - m*abscissa);
649 const Numeric c_thet0 = 0.5 * (thet0_2+thet0_1);
650 const Numeric m_thet0 = 0.5 * (thet0_2-thet0_1);
651 const Numeric c_phi = 0.5 * (phi_2+phi_1);
652 const Numeric m_phi = 0.5 * (phi_2-phi_1);
654 for (
Index t = 0; t < 5; ++t)
656 const Numeric abscissa_thet0 = GaussLeg10[0][t];
657 const Numeric weight_thet0 = GaussLeg10[1][t];
659 Matrix phamat_phi(4, 4, 0.);
661 for (
Index p = 0; p < 5; ++p)
663 const Numeric abscissa_phi = GaussLeg10[0][p];
664 const Numeric weight_phi = GaussLeg10[1][p];
666 Numeric this_thet0 = c_thet0 + m_thet0 * abscissa_thet0;
667 calc_phamat(z, nmax, lam, this_thet0, thet, phi0, c_phi + m_phi * abscissa_phi,
beta, alpha);
668 z *= weight_phi * sin(this_thet0*
PI/180.);
671 calc_phamat(z, nmax, lam, this_thet0, thet, phi0, c_phi - m_phi * abscissa_phi,
beta, alpha);
672 z *= weight_phi * sin(this_thet0*
PI/180.);
675 this_thet0 = c_thet0 - m_thet0 * abscissa_thet0;
676 calc_phamat(z, nmax, lam, this_thet0, thet, phi0, c_phi + m_phi * abscissa_phi,
beta, alpha);
677 z *= weight_phi * sin(this_thet0*
PI/180.);
680 calc_phamat(z, nmax, lam, this_thet0, thet, phi0, c_phi - m_phi * abscissa_phi,
beta, alpha);
681 z *= weight_phi * sin(this_thet0*
PI/180.);
684 phamat_phi *= m_phi * weight_thet0;
685 phamat += phamat_phi;
733 const Numeric c_thet0 = 0.5 * (thet0_2+thet0_1);
734 const Numeric m_thet0 = 0.5 * (thet0_2-thet0_1);
735 const Numeric c_phi = 0.5 * (phi_2+phi_1);
736 const Numeric m_phi = 0.5 * (phi_2-phi_1);
741 for (
Index t = 0; t < 3; ++t)
743 const Numeric abscissa_thet0 = GaussLeg6[0][t];
744 const Numeric weight_thet0 = GaussLeg6[1][t];
748 for (
Index p = 0; p < 3; ++p)
750 const Numeric abscissa_phi = GaussLeg6[0][p];
751 const Numeric weight_phi = GaussLeg6[1][p];
753 Numeric this_thet0 = c_thet0 + m_thet0 * abscissa_thet0;
755 z *= weight_phi * sin(this_thet0*
PI/180.);
759 z *= weight_phi * sin(this_thet0*
PI/180.);
762 this_thet0 = c_thet0 - m_thet0 * abscissa_thet0;
764 z *= weight_phi * sin(this_thet0*
PI/180.);
768 z *= weight_phi * sin(this_thet0*
PI/180.);
771 phamat_phi *= m_phi * weight_thet0;
772 phamat += phamat_phi;
818 const Index quiet = 1)
825 char errmsg[1024] =
"";
827 f11.
resize(nza); f11 = NAN;
828 f22.
resize(nza); f22 = NAN;
829 f33.
resize(nza); f33 = NAN;
830 f44.
resize(nza); f44 = NAN;
831 f12.
resize(nza); f12 = NAN;
832 f34.
resize(nza); f34 = NAN;
837 #pragma omp critical(tmatrix_code)
872 std::ostringstream os;
873 os <<
"T-Matrix code failed: " << errmsg;
874 throw std::runtime_error(os.str());
906 const Index quiet = 1)
908 char errmsg[1024] =
"";
913 #pragma omp critical(tmatrix_code)
914 tmatrix_(1., equiv_radius, np, lam, aspect_ratio,
915 ref_index_real, ref_index_imag,
precision, quiet,
916 nmax, csca, cext, errmsg);
920 std::ostringstream os;
921 os <<
"T-Matrix code failed: " << errmsg;
922 throw std::runtime_error(os.str());
943 if (ref_index_real.
nrows() != nf)
944 throw std::runtime_error(
"Number of rows of refractive index real part must match ssd.f_grid.");
945 if (ref_index_real.
ncols() != nT)
946 throw std::runtime_error(
"Number of cols of refractive index real part must match ssd.T_grid.");
947 if (ref_index_imag.
nrows() != nf)
948 throw std::runtime_error(
"Number of rows of refractive index imaginary part must match ssd.f_grid.");
949 if (ref_index_imag.
ncols() != nT)
950 throw std::runtime_error(
"Number of cols of refractive index imaginary part must match ssd.T_grid.");
976 Matrix mono_pha_mat_data(nza, 6, NAN);
978 #pragma omp critical(tmatrix_ssp)
979 for (
Index f_index = 0; f_index < nf; ++f_index)
980 for (
Index T_index = 0; T_index < nT; ++T_index)
985 f11, f22, f33, f44, f12, f34,
986 equiv_radius, aspect_ratio, np, lam[f_index],
987 ref_index_real(f_index, T_index),
988 ref_index_imag(f_index, T_index),
991 }
catch (std::runtime_error e) {
993 os <<
"Calculation of SingleScatteringData properties failed for\n"
994 <<
"f_grid[" << f_index <<
"] = " << ssd.
f_grid[f_index] <<
"\n"
995 <<
"T_grid[" << T_index <<
"] = " << ssd.
T_grid[T_index] <<
"\n"
997 throw std::runtime_error(os.str());
1003 mono_pha_mat_data(
joker, 0) = f11;
1004 mono_pha_mat_data(
joker, 1) = f12;
1005 mono_pha_mat_data(
joker, 2) = f22;
1006 mono_pha_mat_data(
joker, 3) = f33;
1007 mono_pha_mat_data(
joker, 4) = f34;
1008 mono_pha_mat_data(
joker, 5) = f44;
1010 mono_pha_mat_data *= csca/4./
PI;
1014 ssd.
abs_vec_data(f_index, T_index, 0, 0, 0) = cext - csca;
1021 Index nza_inc = (nza-1)/2 + 1;
1037 Tensor5 csca_data(nf, nT, nza_inc, 1, 2);
1039 #pragma omp critical(tmatrix_ssp)
1040 for (
Index f_index = 0; f_index < nf; ++f_index)
1042 const Numeric lam_f = lam[f_index];
1044 for (
Index T_index = 0; T_index < nT; ++T_index)
1049 equiv_radius, aspect_ratio, np, lam_f,
1050 ref_index_real(f_index, T_index),
1051 ref_index_imag(f_index, T_index),
1053 }
catch (std::runtime_error e) {
1055 os <<
"Calculation of SingleScatteringData properties failed for\n"
1056 <<
"f_grid[" << f_index <<
"] = " << ssd.
f_grid[f_index] <<
"\n"
1057 <<
"T_grid[" << T_index <<
"] = " << ssd.
T_grid[T_index] <<
"\n"
1059 throw std::runtime_error(os.str());
1064 for (
Index za_scat_index = 0; za_scat_index < nza; ++za_scat_index)
1065 for (
Index aa_index = 0; aa_index < naa; ++aa_index)
1066 for (
Index za_inc_index = 0; za_inc_index < nza_inc; ++za_inc_index)
1068 if (aspect_ratio < 1.0)
1093 za_scat_index, aa_index, za_inc_index,
1096 za_scat_index, aa_index, za_inc_index,
1099 za_scat_index, aa_index, za_inc_index,
1102 za_scat_index, aa_index, za_inc_index,
1107 for (
Index za_scat_index = 0; za_scat_index < nza_inc; ++za_scat_index)
1110 if (aspect_ratio < 1.0)
1120 csca_integral /= 180.;
1132 csca_data(f_index, T_index, za_scat_index, 0,
joker) = csca_integral(
Range(0, 2), 0);
1136 if (aspect_ratio < 1.0)
1142 for (
Index za_inc_index = 0; za_inc_index < nza_inc; ++za_inc_index)
1157 s11, s12, s21, s22);
1160 K[0] = (
Complex(0., -1.) * (s11+s22)).real();
1161 K[1] = (
Complex(0., 1.) * (s22-s11)).real();
1162 K[2] = (s22-s11).
real();
1170 csca_data *= 2.*
PI*
PI/32400.;
1178 std::ostringstream os;
1179 os <<
"Only particle types 20 and 30 are currently supported: "
1181 throw std::runtime_error(os.str());
1193 out0 <<
"======================================================\n";
1194 out0 <<
"Test for nonspherical particles in a fixed orientation\n";
1195 out0 <<
"Output should match 3rdparty/tmatrix/tmatrix_ampld.ref\n";
1196 out0 <<
"======================================================\n";
1214 char errmsg[1024] =
"";
1216 tmatrix_(rat, axi, np, lam, eps, mrr, mri, ddelt, quiet,
1217 nmax, csca, cext, errmsg);
1219 out0 <<
"nmax: " << nmax <<
"\n";
1220 out0 <<
"csca: " << csca <<
"\n";
1221 out0 <<
"cext: " << cext <<
"\n";
1223 out0 <<
"Error message: " << (strlen(errmsg)?errmsg:
"None") <<
"\n";
1238 ampl_(nmax, lam, thet0, thet, phi0, phi, alpha,
beta,
1239 s11, s12, s21, s22);
1241 out0 <<
"AMPLITUDE MATRIX: \n";
1242 out0 <<
"s11: " << s11 <<
"\n";
1243 out0 <<
"s12: " << s12 <<
"\n";
1244 out0 <<
"s21: " << s21 <<
"\n";
1245 out0 <<
"s22: " << s22 <<
"\n";
1251 out0 <<
"PHASE MATRIX: \n" << z <<
"\n";
1260 out0 <<
"======================================================\n";
1261 out0 <<
"Test for randomly oriented nonspherical particles\n";
1262 out0 <<
"Output should match 3rdparty/tmatrix/tmatrix_tmd.ref\n";
1263 out0 <<
"======================================================\n";
1299 char errmsg[1024] =
"";
1333 out0 <<
"reff: " << reff <<
"\n";
1334 out0 <<
"veff: " << veff <<
"\n";
1335 out0 <<
"cext: " << cext <<
"\n";
1336 out0 <<
"csca: " << csca <<
"\n";
1337 out0 <<
"walb: " << walb <<
"\n";
1338 out0 <<
"asymm: " << asymm <<
"\n";
1339 out0 <<
"f11: " << f11 <<
"\n";
1340 out0 <<
"f22: " << f22 <<
"\n";
1341 out0 <<
"f33: " << f33 <<
"\n";
1342 out0 <<
"f44: " << f44 <<
"\n";
1343 out0 <<
"f12: " << f12 <<
"\n";
1344 out0 <<
"f34: " << f34 <<
"\n";
1346 out0 <<
"Error message: " << (strlen(errmsg)?errmsg:
"None") <<
"\n";
1354 out0 <<
"======================================================\n";
1355 out0 <<
"Test calculation of single scattering data\n";
1356 out0 <<
"for randomly oriented, oblate particles\n";
1357 out0 <<
"======================================================\n";
1373 mrr(0, 0) = 1.78031135; mrr(0, 1) = 1.78150475;
1374 mrr(1, 0) = 1.78037238; mrr(1, 1) = 1.78147686;
1376 mri(0, 0) = 0.00278706; mri(0, 1) = 0.00507565;
1377 mri(1, 0) = 0.00287245; mri(1, 1) = 0.00523012;
1384 out0 <<
"ssd.pha_mat_data(0, 0, joker, 0, 0, joker, joker):\n"
1387 out0 <<
"ssd.ext_mat_data:\n" << ssd.
ext_mat_data <<
"\n\n";
1388 out0 <<
"ssd.abs_vec_data:\n" << ssd.
abs_vec_data <<
"\n\n";
1390 out0 <<
"======================================================\n";
1391 out0 <<
"Test calculation of single scattering data\n";
1392 out0 <<
"for randomly oriented, prolate particles\n";
1393 out0 <<
"======================================================\n";
1400 out0 <<
"ssd.pha_mat_data(0, 0, joker, 0, 0, joker, joker):\n"
1403 out0 <<
"ssd.ext_mat_data:\n" << ssd.
ext_mat_data <<
"\n\n";
1404 out0 <<
"ssd.abs_vec_data:\n" << ssd.
abs_vec_data <<
"\n\n";
1412 out0 <<
"======================================================\n";
1413 out0 <<
"Test calculation of single scattering data\n";
1414 out0 <<
"for oblate particles with fixed orientation\n";
1415 out0 <<
"======================================================\n";
1431 mrr(0, 0) = 1.78031135; mrr(0, 1) = 1.78150475;
1432 mrr(1, 0) = 1.78037238; mrr(1, 1) = 1.78147686;
1434 mri(0, 0) = 0.00278706; mri(0, 1) = 0.00507565;
1435 mri(1, 0) = 0.00287245; mri(1, 1) = 0.00523012;
1442 out0 <<
"ssd.pha_mat_data(0, 0, joker, 0, 0, joker, joker):\n"
1445 out0 <<
"ssd.ext_mat_data(0, 0, joker, joker, joker):\n"
1448 out0 <<
"abs_vec_data:\n" << ssd.
abs_vec_data <<
"\n\n";
1450 out0 <<
"======================================================\n";
1451 out0 <<
"Test calculation of single scattering data\n";
1452 out0 <<
"for prolate particles with fixed orientation\n";
1453 out0 <<
"======================================================\n";
1459 out0 <<
"ssd.pha_mat_data(0, 0, joker, 0, 0, joker, joker):\n"
1462 out0 <<
"ssd.ext_mat_data(0, 0, joker, joker, joker):\n"
1465 out0 <<
"abs_vec_data:\n" << ssd.
abs_vec_data <<
"\n\n";