55template <
int N1,
int N2,
int Dim>
58 if constexpr (N1 > N2)
59 return N1 + (N2 * (2 * Dim - N2 - 1)) / 2;
61 return N2 + (N1 * (2 * Dim - N1 - 1)) / 2;
66 return N1 + (N2 * (2 * Dim - N2 - 1)) / 2;
68 return N2 + (N1 * (2 * Dim - N1 - 1)) / 2;
71template <
int N1,
int N2,
int Dim>
74 static_assert(N1 != N2,
"Bad index");
75 if constexpr (N2 > N1)
76 return (Dim - 1) * N1 + N2 - 1;
78 return (Dim - 1) * N1 + N2;
83 return (Dim - 1) * N1 + N2 - 1;
85 return (Dim - 1) * N1 + N2;
89 using Val =
typename E::Val;
90 using Vec =
typename E::Vec;
91 using Fun =
typename E::Fun;
101 template <
int a,
int b>
103 const int j,
const int k,
const int l,
107 e.fVal(
a) *
e.aF(
a, b);
110 template <
int a,
int b>
112 const int j,
const int k,
const int l,
114 if constexpr (
a == 1 || b == 1)
120 template <
int a,
int b>
122 const int j,
const int k,
const int l,
126 e.dfVal(
a) /
static_cast<C
>(2);
130template <
typename E,
typename C,
typename G>
struct d2MImpl {
131 using Val =
typename E::Val;
132 using Vec =
typename E::Vec;
133 using Fun =
typename E::Fun;
140 template <
int b,
int a>
141 inline C
term(
const int i,
const int j,
const int k,
const int l)
const {
142 if constexpr (
a != b) {
144 typename E::NumberNb());
149 template <
int nb,
int a>
151 const int k,
const int l)
const {
158 const int k,
const int l)
const {
159 return term<0, a>(
i,
j,
k,
l);
164 using Val =
typename E::Val;
165 using Vec =
typename E::Vec;
166 using Fun =
typename E::Fun;
174 template <
int A,
int a,
int b,
int I,
int J,
int K,
int L>
180 template <
int a,
int b,
int i,
int j,
int k,
int l,
int m,
int n>
184 if constexpr (
i ==
j &&
k ==
l) {
196 }
else if constexpr (
i ==
j)
200 fd2M<a, a, b, i, k, m, n>() *
206 fd2M<b, a, b, i, k, m, n>() *
211 else if constexpr (
k ==
l)
215 fd2M<a, a, b, i, k, m, n>() *
217 fd2M<b, a, b, j, l, m, n>() *
222 fd2M<b, a, b, i, k, m, n>() *
241 template <
int NB,
int a,
int b,
int i,
int j,
int k,
int l,
int m,
int n>
247 if constexpr (NB == 1) {
250 }
else if constexpr (NB == 2) {
252 if constexpr (
a == 1 || b == 1) {
283 template <
int nb,
int a,
int i,
int j,
int k,
int l,
int m,
int n>
287 if constexpr (
a != nb - 1)
297 template <
int a,
int i,
int j,
int k,
int l,
int m,
int n>
301 if constexpr (
a != 0)
308 template <
int nb,
int a,
int i,
int j,
int k,
int l,
int m,
int n>
312 if constexpr (
a != nb - 1)
324 template <
int a,
int i,
int j,
int k,
int l,
int m,
int n>
328 if constexpr (
a != 0)
336 template <
int nb,
int a,
int i,
int j,
int k,
int l,
int m,
int n>
354 using Val =
typename E::Val;
355 using Vec =
typename E::Vec;
356 using Fun =
typename E::Fun;
363 template <
int a,
int i,
int j>
inline C
term()
const {
367 template <
int nb,
int i,
int j>
370 return term<nb - 1,
i,
j>() +
374 template <
int i,
int j>
376 return term<0, i, j>();
381 using Val =
typename E::Val;
382 using Vec =
typename E::Vec;
383 using Fun =
typename E::Fun;
391 template <
int a,
int i,
int j,
int k,
int l>
inline C
term()
const {
401 template <
int nb,
int i,
int j,
int k,
int l>
409 template <
int i,
int j,
int k,
int l>
412 return term<0, i, j, k, l>();
417 using Val =
typename E::Val;
418 using Vec =
typename E::Vec;
419 using Fun =
typename E::Fun;
429 template <
int a,
int i,
int j,
int k,
int l,
int m,
int n>
435 template <
int a,
int i,
int j,
int k,
int l,
int m,
int n>
441 template <
int a,
int i,
int j,
int k,
int l,
int m,
int n>
447 template <
int a,
int i,
int j,
int k,
int l,
int m,
int n>
452 (term1<a, i, j, k, l, m, n>() + term2<a, i, j, k, l, m, n>() +
453 term3<a, i, j, k, l, m, n>()) *
469 template <
int nb,
int i,
int j,
int k,
int l,
int m,
int n>
481 template <
int i,
int j,
int k,
int l,
int m,
int n>
485 return term<0, i, j, k, l, m, n>();
489template <
typename E,
typename C,
typename T>
struct GetMatImpl {
490 using Val =
typename E::Val;
491 using Vec =
typename E::Vec;
492 using Fun =
typename E::Fun;
503 template <
int i,
int j>
527 using Val =
typename E::Val;
528 using Vec =
typename E::Vec;
529 using Fun =
typename E::Fun;
540 template <
int i,
int j,
int k,
int l>
551 template <
int j,
int k,
int l>
562 template <
int k,
int l>
591template <
typename E,
typename C,
typename T1,
typename T2>
593 using Val =
typename E::Val;
594 using Vec =
typename E::Vec;
595 using Fun =
typename E::Fun;
608 template <
int I,
int J,
int K,
int L,
int M,
int N>
611 if constexpr (
N !=
M)
612 return (
tS(
M - 1,
N - 1) +
tS(
N - 1,
M - 1)) *
633 template <
int I,
int J,
int K,
int L,
int M>
636 return (
tS(
M - 1, 0) +
tS(0,
M - 1)) *
649 template <
int I,
int J,
int K,
int L>
657 template <
int I,
int J,
int K,
int L>
664 if constexpr (K !=
I || L !=
J)
665 tA(K - 1, L - 1,
I - 1,
J - 1) =
tA(
I - 1,
J - 1, K - 1, L - 1);
668 template <
int I,
int J,
int K>
674 template <
int I,
int J>
680 template <
int I,
int K>
690template <
typename E,
typename C,
typename T1,
typename VT2,
int DimT2>
692 using Val =
typename E::Val;
693 using Vec =
typename E::Vec;
694 using Fun =
typename E::Fun;
708 template <
int I,
int J,
int K,
int L,
int M,
int N>
712 if constexpr (
N !=
M)
734 template <
int I,
int J,
int K,
int L,
int M>
748 template <
int I,
int J,
int K,
int L>
756 template <
int I,
int J,
int K,
int L>
767 if constexpr (K !=
I || L !=
J)
773 template <
int I,
int J,
int K>
779 template <
int I,
int J>
785 template <
int I,
int K>
796template <
typename T1,
typename T2,
int Dim>
804 static constexpr int sizeSymm = (Dim * (Dim + 1)) / 2;
809 template <
typename T>
814 int group_size[Dim]{};
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)));
824 for (
int aa = 0; aa != Dim; ++aa) {
826 for (; gg != nb_groups; ++gg)
827 if (is_equal(
tVal(aa), group_ref[gg]))
830 if (gg == nb_groups) {
831 group_ref[gg] =
tVal(aa);
835 group_val[gg] +=
tVal(aa);
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]);
849 auto first_divided_difference = [&](
const int aa,
const int bb) {
852 return (f_val[aa] - f_val[bb]) / (group_val[aa] - group_val[bb]);
855 auto second_divided_difference = [&](
const int aa,
const int bb,
857 if (aa == bb && bb == cc)
858 return ddf_val[aa] / 2;
861 const V d1 = first_divided_difference(aa, cc);
862 return (df_val[aa] - d1) / (group_val[aa] - group_val[cc]);
865 const V d1 = first_divided_difference(aa, bb);
866 return (df_val[aa] - d1) / (group_val[aa] - group_val[bb]);
869 const V d1 = first_divided_difference(aa, bb);
870 return (d1 - df_val[bb]) / (group_val[aa] - group_val[bb]);
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]);
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]);
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);
896 for (
int ii = 0; ii != Dim; ++ii)
897 for (
int jj = ii; jj != Dim; ++jj) {
901 for (
int aa = 0; aa != Dim; ++aa)
902 for (
int bb = 0; bb != Dim; ++bb)
903 basis_hat[LL][aa][bb] =
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]);
918 t_diff_A(pair_0[LL], pair_1[LL], pair_0[JJ], pair_1[JJ]) =
v;
920 t_diff_A(pair_0[JJ], pair_1[JJ], pair_0[LL], pair_1[LL]) =
v;
951 for (
auto aa = 0; aa != Dim; ++aa) {
953 for (
auto ii = 0; ii != Dim; ++ii)
954 for (
auto jj = 0; jj <= ii; ++jj)
958 for (
auto aa = 0; aa != Dim; ++aa) {
959 for (
auto bb = 0; bb != Dim; ++bb) {
962 auto &MM =
aMM[aa][bb];
963 MM(
i,
j,
k,
l) = Ma(
i,
j) * Mb(
k,
l);
967 for (
auto aa = 0; aa != Dim; ++aa) {
968 for (
auto bb = 0; bb != Dim; ++bb) {
970 auto &MM =
aMM[aa][bb];
971 auto &
G =
aG[aa][bb];
977 for (
auto aa = 0; aa != Dim; ++aa) {
978 for (
auto bb = 0; bb != Dim; ++bb) {
980 auto &Gab =
aG[aa][bb];
981 auto &Gba =
aG[bb][aa];
1008 for (
auto aa = 0; aa != Dim; ++aa)
1034 for (
auto aa = 0; aa != Dim; ++aa)
1037 for (
auto aa = 0; aa != Dim; ++aa)
1040 for (
auto aa = 0; aa != Dim; ++aa)
1041 for (
auto bb = 0; bb != aa; ++bb) {
1043 aF(bb, aa) = -
aF(aa, bb);
1044 aF2(aa, bb) =
aF(aa, bb) *
aF(aa, bb);
1071 template <
typename T>
1074 for (
auto aa = 0; aa != Dim; ++aa)
1077 for (
auto aa = 0; aa != Dim; ++aa)
1080 for (
auto aa = 0; aa != Dim; ++aa)
1083 for (
auto aa = 0; aa != Dim; ++aa)
1084 for (
auto bb = 0; bb != aa; ++bb) {
1086 aF(bb, aa) = -
aF(aa, bb);
1087 aF2(aa, bb) =
aF(aa, bb) *
aF(aa, bb);
1095 for (
auto aa = 0; aa != Dim; ++aa) {
1096 for (
auto bb = 0; bb != Dim; ++bb) {
1099 const auto &
M =
aM[aa];
1101 for (
auto mm = 0; mm != Dim; ++mm) {
1102 for (
auto nn = mm; nn != Dim; ++nn) {
1104 S(
i,
j,
k,
l) *
M(mm, nn);
1111 for (
auto aa = 0; aa != Dim; ++aa) {
1112 for (
auto mm = 0; mm != Dim; ++mm) {
1113 for (
auto nn = mm; nn != Dim; ++nn) {
1119 if constexpr (NB == 3)
1120 for (
auto aa = 0; aa != Dim; ++aa) {
1121 for (
auto bb = 0; bb != Dim; ++bb) {
1124 for (
auto mm = 0; mm != Dim; ++mm) {
1125 for (
auto nn = mm; nn != Dim; ++nn) {
1135 if constexpr (NB == 2)
1136 for (
auto aa = 0; aa != Dim; ++aa) {
1137 for (
auto bb = 0; bb != Dim; ++bb) {
1140 if (aa == 1 || bb == 1)
1144 for (
auto mm = 0; mm != Dim; ++mm) {
1145 for (
auto nn = mm; nn != Dim; ++nn) {
1155 if constexpr (NB == 1)
1156 for (
auto aa = 0; aa != Dim; ++aa) {
1157 for (
auto bb = 0; bb != Dim; ++bb) {
1160 for (
auto mm = 0; mm != Dim; ++mm) {
1161 for (
auto nn = mm; nn != Dim; ++nn) {
1171 for (
auto aa = 0; aa != Dim; ++aa) {
1172 for (
auto mm = 0; mm != Dim; ++mm) {
1173 for (
auto nn = 0; nn != Dim; ++nn) {
1180 if constexpr (NB == 3)
1181 for (
auto aa = 0; aa != Dim; ++aa) {
1182 for (
auto bb = 0; bb != Dim; ++bb) {
1185 const auto v0 =
aF(aa, bb);
1186 for (
auto cc = 0; cc != Dim; ++cc) {
1187 for (
auto dd = 0; dd != Dim; ++dd) {
1189 const double v1 =
fVal(cc) *
aF(cc, dd);
1191 (v1 * v0) * S(
i,
j,
k,
l);
1199 if constexpr (NB == 2)
1200 for (
auto aa = 0; aa != Dim; ++aa) {
1201 for (
auto bb = 0; bb != Dim; ++bb) {
1203 for (
auto cc = 0; cc != Dim; ++cc) {
1204 for (
auto dd = 0; dd != Dim; ++dd)
1209 if ((cc == 1 || dd == 1) && (aa == 1 || bb == 1))
1210 r =
fVal(cc) *
aF(cc, dd) *
aF(aa, bb);
1211 else if (cc != 1 && dd != 1 && aa != 1 && bb != 1) {
1213 if ((aa != bb && bb != dd) && (aa != dd && bb != cc))
1218 }
else if ((cc != 1 && dd != 1) && (aa == 1 || bb == 1))
1219 r =
dfVal(cc) *
aF(aa, bb) / 2;
1220 else if ((cc == 1 || dd == 1) && (aa != 1 && bb != 1)) {
1222 if ((cc == 2 && dd == 1) || (cc == 1 && dd == 2))
1246 if constexpr (NB == 1)
1247 for (
auto aa = 0; aa != Dim; ++aa) {
1248 for (
auto bb = 0; bb != Dim; ++bb) {
1250 for (
auto cc = 0; cc != Dim; ++cc) {
1251 for (
auto dd = 0; dd != Dim; ++dd) {
1253 if ((bb != dd) && (aa != dd && bb != cc)) {
1254 const double r =
ddfVal(cc) / 4;
1291 template <
typename E,
typename C,
typename G>
friend struct d2MImpl;
1297 template <
typename E,
typename C,
typename T3,
typename T4>
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
constexpr IntegrationType G
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto get_sym_index(const Number< N1 > &, const Number< N2 > &, const Number< Dim > &)
auto get_nodiag_index(const Number< N1 > &, const Number< N2 > &, const Number< Dim > &)
Tensors class implemented by Walter Landry.
constexpr IntegrationType I
FTensor::Index< 'm', 3 > m
EigenMatrixContractedHessianImp(Val &t_val, Vec &t_vec)
boost::function< double(const double)> Fun
auto getDiffDiffMat(Fun f, Fun d_f, Fun dd_f, T &t_S)
static constexpr int sizeSymm
FTensor::Tensor1< V, Dim > fVal
FTensor::Ddg< V, Dim, Dim > d2MType0[Dim][(Dim *(Dim+1))/2]
FTensor::Ddg< V, Dim, Dim > aMM[Dim][Dim]
FTensor::Tensor2_symmetric< V, Dim > aF2
FTensor::Ddg< V, Dim, Dim > aS[(Dim *(Dim+1))/2]
boost::function< double(const double)> Fun
auto getMat(Fun f)
Get matrix.
FTensor::Ddg< V, Dim, Dim > d2MType1[Dim][(Dim *(Dim+1))/2]
auto getDiffMat(Fun f, Fun d_f)
Get derivative of matrix.
EigenMatrixImp(Val &t_val, Vec &t_vec)
typename FTensor::Index< c, Dim > I
FTensor::Tensor1< V, Dim > ddfVal
FTensor::Tensor2_symmetric< V, Dim > aM[Dim]
FTensor::Ddg< V, Dim, Dim > aSM[(Dim - 1) *Dim][(Dim *(Dim+1))/2]
FTensor::Ddg< V, Dim, Dim > aG[Dim][Dim]
FTensor::Tensor2< V, Dim, Dim > aF
auto getDiffDiffMat(Fun f, Fun d_f, Fun dd_f, T &t_S)
Get second directive of matrix.
FTensor::Tensor1< V, Dim > dfVal
typename E::NumberDim NumberDim
C eval(const Number< nb > &, const Number< a > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
C eval_SM(const Number< nb > &, const Number< a > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
C eval_SM(const Number< 1 > &, const Number< a > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
auto term_fd2S(const Number< a > &, const Number< b > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
C term_SM(const Number< a > &, const Number< b > &, const Number< NB > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
typename E::NumberNb NumberNb
C eval_fdS2(const Number< 1 > &, const Number< a > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
C eval_fdS2(const Number< nb > &, const Number< a > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
C eval(const Number< nb > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &) const
C eval(const Number< 1 > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &) const
FirstMatrixDirectiveImpl(E &e)
d2MImpl< E, C, d2MCoefficients< E, C > > r
void set(const Number< I > &, const Number< J > &, const Number< 0 > &, const Number< 0 > &)
auto add(const Number< I > &, const Number< J > &, const Number< K > &, const Number< L > &, const Number< M > &, const Number< N > &)
typename E::NumberDim NumberDim
void set(const Number< 0 > &, const Number< 0 > &, const Number< 0 > &, const Number< 0 > &)
typename E::NumberNb NumberNb
void set(const Number< I > &, const Number< J > &, const Number< K > &, const Number< 0 > &)
auto add(const Number< I > &, const Number< J > &, const Number< K > &, const Number< L > &, const Number< M > &, const Number< 1 > &)
void set(const Number< I > &, const Number< J > &, const Number< K > &, const Number< L > &)
auto add(const Number< I > &, const Number< J > &, const Number< K > &, const Number< L > &, const Number< 1 > &, const Number< 1 > &)
SecondMatrixDirectiveImpl< E, C > r
FTensor::Tensor2_symmetric< VT2, DimT2 > & tS
GetDiffDiffMatImpl(E &e, T1 &t_a, FTensor::Tensor2_symmetric< VT2, DimT2 > &t_S)
void set(const Number< I > &, const Number< 0 > &, const Number< K > &, const Number< 0 > &)
typename E::NumberNb NumberNb
GetDiffDiffMatImpl(E &e, T1 &t_a, T2 &t_S)
void set(const Number< I > &, const Number< J > &, const Number< 0 > &, const Number< 0 > &)
void set(const Number< I > &, const Number< J > &, const Number< K > &, const Number< L > &)
auto add(const Number< I > &, const Number< J > &, const Number< K > &, const Number< L > &, const Number< M > &, const Number< N > &)
auto add(const Number< I > &, const Number< J > &, const Number< K > &, const Number< L > &, const Number< M > &, const Number< 1 > &)
typename E::NumberDim NumberDim
void set(const Number< I > &, const Number< J > &, const Number< K > &, const Number< 0 > &)
void set(const Number< 0 > &, const Number< 0 > &, const Number< 0 > &, const Number< 0 > &)
auto add(const Number< I > &, const Number< J > &, const Number< K > &, const Number< L > &, const Number< 1 > &, const Number< 1 > &)
SecondMatrixDirectiveImpl< E, C > r
void set(const Number< I > &, const Number< 0 > &, const Number< K > &, const Number< 0 > &)
typename E::NumberNb NumberNb
void set(const Number< 1 > &, const Number< 1 > &, const Number< k > &, const Number< l > &)
FirstMatrixDirectiveImpl< E, C > r
void set(const Number< 1 > &, const Number< 1 > &, const Number< 1 > &, const Number< l > &)
typename E::NumberDim NumberDim
void set(const Number< 1 > &, const Number< j > &, const Number< k > &, const Number< l > &)
void set(const Number< 1 > &, const Number< 1 > &, const Number< 1 > &, const Number< 1 > &)
GetDiffMatImpl(E &e, T &t_a)
void set(const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &)
typename E::NumberNb NumberNb
typename E::NumberDim NumberDim
void set(const Number< 1 > &, const Number< 1 > &)
ReconstructMatImpl< E, C > r
void set(const Number< i > &, const Number< j > &)
void set(const Number< i > &, const Number< 1 > &)
C eval(const Number< 1 > &, const Number< i > &, const Number< j > &) const
C eval(const Number< nb > &, const Number< i > &, const Number< j > &) const
SecondMatrixDirectiveImpl(E &e)
typename E::NumberDim NumberDim
C eval(const Number< 1 > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
C eval(const Number< nb > &, const Number< i > &, const Number< j > &, const Number< k > &, const Number< l > &, const Number< m > &, const Number< n > &) const
typename E::NumberNb NumberNb
auto get(const Number< a > &, const Number< b > &, const int i, const int j, const int k, const int l, const Number< 2 > &) const
typename E::NumberDim NumberDim
auto get(const Number< a > &, const Number< b > &, const int i, const int j, const int k, const int l, const Number< 3 > &) const
auto get(const Number< a > &, const Number< b > &, const int i, const int j, const int k, const int l, const Number< 1 >) const
C term(const int i, const int j, const int k, const int l) const
C eval(const Number< nb > &, const Number< a > &, const int i, const int j, const int k, const int l) const
C eval(const Number< 1 > &, const Number< a > &, const int i, const int j, const int k, const int l) const