810 {
811
814 int group_size[Dim]{};
815 int group_of[Dim];
816 int nb_groups = 0;
817
818 auto is_equal = [](
const V a,
const V b) {
819 const V eps = 100 * std::numeric_limits<V>::epsilon();
820 const V scale = std::max(
V(1), std::max(std::abs(
a), std::abs(b)));
822 };
823
824 for (int aa = 0; aa != Dim; ++aa) {
825 int gg = 0;
826 for (; gg != nb_groups; ++gg)
827 if (is_equal(
tVal(aa), group_ref[gg]))
828 break;
829
830 if (gg == nb_groups) {
831 group_ref[gg] =
tVal(aa);
832 ++nb_groups;
833 }
834 group_of[aa] = gg;
835 group_val[gg] +=
tVal(aa);
836 ++group_size[gg];
837 }
838
842 for (int aa = 0; aa != nb_groups; ++aa) {
843 group_val[aa] /= group_size[aa];
844 f_val[aa] =
f(group_val[aa]);
845 df_val[aa] =
d_f(group_val[aa]);
846 ddf_val[aa] =
dd_f(group_val[aa]);
847 }
848
849 auto first_divided_difference = [&](const int aa, const int bb) {
850 if (aa == bb)
851 return df_val[aa];
852 return (f_val[aa] - f_val[bb]) / (group_val[aa] - group_val[bb]);
853 };
854
855 auto second_divided_difference = [&](const int aa, const int bb,
856 const int cc) {
857 if (aa == bb && bb == cc)
858 return ddf_val[aa] / 2;
859
860 if (aa == bb) {
861 const V d1 = first_divided_difference(aa, cc);
862 return (df_val[aa] - d1) / (group_val[aa] - group_val[cc]);
863 }
864 if (aa == cc) {
865 const V d1 = first_divided_difference(aa, bb);
866 return (df_val[aa] - d1) / (group_val[aa] - group_val[bb]);
867 }
868 if (bb == cc) {
869 const V d1 = first_divided_difference(aa, bb);
870 return (d1 - df_val[bb]) / (group_val[aa] - group_val[bb]);
871 }
872
873 const V d1_ab = first_divided_difference(aa, bb);
874 const V d1_bc = first_divided_difference(bb, cc);
875 return (d1_ab - d1_bc) / (group_val[aa] - group_val[cc]);
876 };
877
878 V ddf[Dim][Dim][Dim];
879 for (int aa = 0; aa != Dim; ++aa)
880 for (int bb = 0; bb != Dim; ++bb)
881 for (int cc = 0; cc != Dim; ++cc)
882 ddf[aa][bb][cc] = second_divided_difference(
883 group_of[aa], group_of[bb], group_of[cc]);
884
886 for (int aa = 0; aa != Dim; ++aa)
887 for (int cc = 0; cc != Dim; ++cc)
888 for (int ii = 0; ii != Dim; ++ii)
889 for (int jj = 0; jj != Dim; ++jj)
890 s_hat[aa][cc] +=
tVec(aa, ii) * t_S(ii, jj) *
tVec(cc, jj);
891
895
896 for (int ii = 0; ii != Dim; ++ii)
897 for (int jj = ii; jj != Dim; ++jj) {
899 pair_0[LL] = ii;
900 pair_1[LL] = jj;
901 for (int aa = 0; aa != Dim; ++aa)
902 for (int bb = 0; bb != Dim; ++bb)
903 basis_hat[LL][aa][bb] =
905 }
906
908 for (
int LL = 0; LL !=
sizeSymm; ++LL)
909 for (int JJ = 0; JJ <= LL; ++JJ) {
911 for (int aa = 0; aa != Dim; ++aa)
912 for (int bb = 0; bb != Dim; ++bb)
913 for (int cc = 0; cc != Dim; ++cc)
914 v += s_hat[aa][cc] * ddf[aa][bb][cc] *
915 (basis_hat[LL][aa][bb] * basis_hat[JJ][bb][cc] +
916 basis_hat[JJ][aa][bb] * basis_hat[LL][bb][cc]);
917
918 t_diff_A(pair_0[LL], pair_1[LL], pair_0[JJ], pair_1[JJ]) =
v;
919 if (JJ != LL)
920 t_diff_A(pair_0[JJ], pair_1[JJ], pair_0[LL], pair_1[LL]) =
v;
921 }
922
923 return t_diff_A;
924 }
const double v
phase velocity of light in medium (cm/ns)
auto get_sym_index(const Number< N1 > &, const Number< N2 > &, const Number< Dim > &)
static constexpr int sizeSymm