Xped
Loading...
Searching...
No Matches
S1xS2.hpp
Go to the documentation of this file.
1#ifndef XPED_S1xS2_H_
2#define XPED_S1xS2_H_
3
5#include <iostream>
6#include <unordered_map>
7#include <unordered_set>
8#include <utility>
10
12
14
15namespace Xped::Sym {
16
17template <typename S1, typename S2>
18struct S1xS2;
19
20template <typename S1, typename S2>
21struct SymTraits<S1xS2<S1, S2>>
22{
23 constexpr static int Nq = S1::Nq + S2::Nq;
25 typedef typename S1::Scalar Scalar;
26};
27
35template <typename S1_, typename S2_>
36struct S1xS2 : public SymBase<S1xS2<S1_, S2_>>
37{
38public:
39 typedef typename S1_::Scalar Scalar;
40
41 typedef S1_ S1;
42 typedef S2_ S2;
43
44 S1xS2(){};
45
46 static std::string name() { return S1_::name() + "×" + S2_::name(); }
47
48 static constexpr std::size_t Nq = S1_::Nq + S2_::Nq;
49
50 static constexpr std::array<bool, Nq> HAS_MULTIPLICITIES = util::join(S1::HAS_MULTIPLICITIES, S2::HAS_MULTIPLICITIES);
51 static constexpr std::array<bool, Nq> NON_ABELIAN = util::join(S1::NON_ABELIAN, S2::NON_ABELIAN);
52 static constexpr std::array<bool, Nq> ABELIAN = util::join(S1::ABELIAN, S2::ABELIAN);
53 static constexpr std::array<bool, Nq> IS_TRIVIAL = util::join(S1::IS_TRIVIAL, S2::IS_TRIVIAL);
54 static constexpr std::array<bool, Nq> IS_MODULAR = util::join(S1::IS_MODULAR, S2::IS_MODULAR);
55 static constexpr std::array<bool, Nq> IS_FERMIONIC = util::join(S1::IS_FERMIONIC, S2::IS_FERMIONIC);
56 static constexpr std::array<bool, Nq> IS_BOSONIC = util::join(S1::IS_BOSONIC, S2::IS_BOSONIC);
57 static constexpr std::array<bool, Nq> IS_SPIN = util::join(S1::IS_SPIN, S2::IS_SPIN);
58 static constexpr std::array<int, Nq> MOD_N = util::join(S1::MOD_N, S2::MOD_N);
59
60 static constexpr bool ANY_HAS_MULTIPLICITIES = S1::ANY_HAS_MULTIPLICITIES or S2::ANY_HAS_MULTIPLICITIES;
61 static constexpr bool ANY_NON_ABELIAN = S1::ANY_NON_ABELIAN or S2::ANY_NON_ABELIAN;
62 static constexpr bool ANY_ABELIAN = S1::ANY_ABELIAN or S2::ANY_ABELIAN;
63 static constexpr bool ANY_IS_TRIVIAL = S1::ANY_IS_TRIVIAL or S2::ANY_IS_TRIVIAL;
64 static constexpr bool ANY_IS_MODULAR = S1::ANY_IS_MODULAR or S2::ANY_IS_MODULAR;
65 static constexpr bool ANY_IS_FERMIONIC = S1::ANY_IS_FERMIONIC or S2::ANY_IS_FERMIONIC;
66 static constexpr bool ANY_IS_BOSONIC = S1::ANY_IS_BOSONIC or S2::ANY_IS_BOSONIC;
67 static constexpr bool ANY_IS_SPIN = S1::ANY_IS_SPIN or S2::ANY_IS_SPIN;
68
69 static constexpr bool ALL_HAS_MULTIPLICITIES = S1::ALL_HAS_MULTIPLICITIES and S2::ALL_HAS_MULTIPLICITIES;
70 static constexpr bool ALL_NON_ABELIAN = S1::ALL_NON_ABELIAN and S2::ALL_NON_ABELIAN;
71 static constexpr bool ALL_ABELIAN = S1::ALL_ABELIAN and S2::ALL_ABELIAN;
72 static constexpr bool ALL_IS_TRIVIAL = S1::ALL_IS_TRIVIAL and S2::ALL_IS_TRIVIAL;
73 static constexpr bool ALL_IS_MODULAR = S1::ALL_IS_MODULAR and S2::ALL_IS_MODULAR;
74 static constexpr bool ALL_IS_FERMIONIC = S1::ALL_IS_FERMIONIC and S2::ALL_IS_FERMIONIC;
75 static constexpr bool ALL_IS_BOSONIC = S1::ALL_IS_BOSONIC and S2::ALL_IS_BOSONIC;
76 static constexpr bool ALL_IS_SPIN = S1::ALL_IS_SPIN and S2::ALL_IS_SPIN;
77
78 static constexpr bool IS_CHARGE_SU2() { return S1_::IS_CHARGE_SU2() or S2_::IS_CHARGE_SU2(); }
79 static constexpr bool IS_SPIN_SU2() { return S1_::IS_SPIN_SU2() or S2_::IS_SPIN_SU2(); }
80
81 static constexpr bool IS_SPIN_U1() { return S1_::IS_SPIN_U1() or S2_::IS_SPIN_U1(); }
82
83 static constexpr bool NO_SPIN_SYM() { return S1_::NO_SPIN_SYM() and S2_::NO_SPIN_SYM(); }
84 static constexpr bool NO_CHARGE_SYM() { return S1_::NO_CHARGE_SYM() and S2_::NO_CHARGE_SYM(); }
85
87
88 inline static constexpr std::array<KIND, Nq> kind() { return util::join(S1_::kind(), S2_::kind()); }
89
90 inline static constexpr qType qvacuum() { return join(S1_::qvacuum(), S2_::qvacuum()); }
91 inline static constexpr std::array<qType, S1::lowest_qs().size() * S2::lowest_qs().size()> lowest_qs()
92 {
93 std::array<qType, S1::lowest_qs().size() * S2::lowest_qs().size()> out;
94 size_t index = 0;
95 for(const auto& q1 : S1::lowest_qs())
96 for(const auto& q2 : S2::lowest_qs()) {
97 out[index] = join(q1, q2);
98 index++;
99 }
100 return out;
101 }
102
103 inline static qType conj(const qType& q)
104 {
105 auto [ql, qr] = disjoin<S1_::Nq, S2_::Nq>(q);
106 return join(S1_::conj(ql), S2_::conj(qr));
107 }
108
109 inline static int degeneracy(const qType& q)
110 {
111 auto [ql, qr] = disjoin<S1_::Nq, S2_::Nq>(q);
112 return S1_::degeneracy(ql) * S2_::degeneracy(qr);
113 }
114
115 inline static qType random_q() { return join(S1_::random_q(), S2_::random_q()); }
116
118
121 static std::vector<qType> basis_combine(const qType& ql, const qType& qr);
123
124 static std::size_t multiplicity(const qType& q1, const qType& q2, const qType& q3)
125 {
126 auto [q1l, q1r] = disjoin<S1_::Nq, S2_::Nq>(q1);
127 auto [q2l, q2r] = disjoin<S1_::Nq, S2_::Nq>(q2);
128 auto [q3l, q3r] = disjoin<S1_::Nq, S2_::Nq>(q3);
129 return S1::multiplicity(q1l, q2l, q3l) * S2::multiplicity(q1r, q2r, q3r);
130 }
131
133
136 inline static Scalar coeff_dot(const qType& q1);
137
138 inline static Scalar coeff_twist(const qType& q)
139 {
140 auto [ql, qr] = disjoin<S1::Nq, S2::Nq>(q);
141 return S1::coeff_twist(ql) * S2::coeff_twist(qr);
142 }
143
144 static Scalar coeff_FS(const qType& q)
145 {
146 auto [ql, qr] = disjoin<S1_::Nq, S2_::Nq>(q);
147 return S1::coeff_FS(ql) * S2::coeff_FS(qr);
148 }
149
150 template <typename PlainLib>
151 static typename PlainLib::template TType<Scalar, 2> one_j_tensor(const qType& q, mpi::XpedWorld& world = mpi::getUniverse())
152 {
153 auto [ql, qr] = disjoin<S1_::Nq, S2_::Nq>(q);
154
155 auto Tl = S1::template one_j_tensor<PlainLib>(ql, world);
156 auto Tr = S2::template one_j_tensor<PlainLib>(qr, world);
157 return PlainLib::tensorProd(Tl, Tr);
158 }
159
160 static Scalar coeff_rightOrtho(const qType&, const qType&);
161
162 static Scalar coeff_3j(const qType& q1, const qType& q2, const qType& q3, int q1_z, int q2_z, int q3_z) { return 1.; }
163
164 template <typename PlainLib>
165 static typename PlainLib::template TType<Scalar, 3>
166 CGC(const qType& q1, const qType& q2, const qType& q3, const std::size_t alpha, mpi::XpedWorld& world = mpi::getUniverse())
167 {
168 auto [q1l, q1r] = disjoin<S1_::Nq, S2_::Nq>(q1);
169 auto [q2l, q2r] = disjoin<S1_::Nq, S2_::Nq>(q2);
170 auto [q3l, q3r] = disjoin<S1_::Nq, S2_::Nq>(q3);
171
172 auto Tl = S1::template CGC<PlainLib>(q1l, q2l, q3l, alpha, world);
173 auto Tr = S2::template CGC<PlainLib>(q1r, q2r, q3r, alpha, world);
175 }
176
177 static Scalar coeff_turn(const qType& ql, const qType& qr, const qType& qf)
178 {
179 auto [ql1, ql2] = disjoin<S1_::Nq, S2_::Nq>(ql);
180 auto [qr1, qr2] = disjoin<S1_::Nq, S2_::Nq>(qr);
181 auto [qf1, qf2] = disjoin<S1_::Nq, S2_::Nq>(qf);
182 return S1::coeff_turn(ql1, qr1, qf1) * S2::coeff_turn(ql2, qr2, qf2);
183 }
184
185 inline static Scalar coeff_6j(const qType& q1, const qType& q2, const qType& q3, const qType& q4, const qType& q5, const qType& q6);
186 inline static Scalar coeff_recouple(const qType& q1, const qType& q2, const qType& q3, const qType& Q, const qType& Q12, const qType& Q23)
187 {
188 auto [q1l, q1r] = disjoin<S1_::Nq, S2_::Nq>(q1);
189 auto [q2l, q2r] = disjoin<S1_::Nq, S2_::Nq>(q2);
190 auto [q3l, q3r] = disjoin<S1_::Nq, S2_::Nq>(q3);
191 auto [Ql, Qr] = disjoin<S1_::Nq, S2_::Nq>(Q);
192 auto [Q12l, Q12r] = disjoin<S1_::Nq, S2_::Nq>(Q12);
193 auto [Q23l, Q23r] = disjoin<S1_::Nq, S2_::Nq>(Q23);
194
195 Scalar out = S1_::coeff_recouple(q1l, q2l, q3l, Ql, Q12l, Q23l) * S2_::coeff_recouple(q1r, q2r, q3r, Qr, Q12r, Q23r);
196 return out;
197 }
198
199 static Scalar coeff_swap(const qType& ql, const qType& qr, const qType& qf)
200 {
201 auto [ql1, ql2] = disjoin<S1_::Nq, S2_::Nq>(ql);
202 auto [qr1, qr2] = disjoin<S1_::Nq, S2_::Nq>(qr);
203 auto [qf1, qf2] = disjoin<S1_::Nq, S2_::Nq>(qf);
204 return S1::coeff_swap(ql1, qr1, qf1) * S2::coeff_swap(ql2, qr2, qf2);
205 };
206
207 inline static Scalar coeff_9j(const qType& q1,
208 const qType& q2,
209 const qType& q3,
210 const qType& q4,
211 const qType& q5,
212 const qType& q6,
213 const qType& q7,
214 const qType& q8,
215 const qType& q9);
217 static bool triangle(const qType& q1, const qType& q2, const qType& q3);
218};
219
220template <typename S1_, typename S2_>
221std::vector<typename S1xS2<S1_, S2_>::qType> S1xS2<S1_, S2_>::basis_combine(const qType& ql, const qType& qr)
222{
223 auto [ql1, ql2] = disjoin<S1_::Nq, S2_::Nq>(ql);
224 auto [qr1, qr2] = disjoin<S1_::Nq, S2_::Nq>(qr);
225 std::vector<typename S1_::qType> firstSym = S1_::basis_combine(ql1, qr1);
226 std::vector<typename S2_::qType> secondSym = S2_::basis_combine(ql2, qr2);
227
228 std::vector<qType> vout;
229 for(const auto& q1 : firstSym)
230 for(const auto& q2 : secondSym) { vout.push_back(join(q1, q2)); }
231 return vout;
232}
233
234template <typename S1_, typename S2_>
235typename S1_::Scalar S1xS2<S1_, S2_>::coeff_dot(const qType& q1)
236{
237 auto [q1l, q1r] = disjoin<S1_::Nq, S2_::Nq>(q1);
238 Scalar out = S1_::coeff_dot(q1l) * S2_::coeff_dot(q1r);
239 return out;
240}
241
242template <typename S1_, typename S2_>
243typename S1_::Scalar S1xS2<S1_, S2_>::coeff_rightOrtho(const qType& q1, const qType& q2)
244{
245 auto [q1l, q1r] = disjoin<S1_::Nq, S2_::Nq>(q1);
246 auto [q2l, q2r] = disjoin<S1_::Nq, S2_::Nq>(q2);
247 Scalar out = S1_::coeff_rightOrtho(q1l, q2l) * S2_::coeff_rightOrtho(q1r, q2r);
248 return out;
249}
250
251// template<typename S1_, typename S2_>
252// typename S1_::Scalar S1xS2<S1_,S2_>::
253// coeff_3j(const qType& q1, const qType& q2, const qType& q3,
254// int q1_z, int q2_z, int q3_z)
255// {
256// Scalar out = S1_::coeff_3j({q1[0]}, {q2[0]}, {q3[0]}, q1_z, q2_z, q3_z) * S2_::coeff_3j({q1[1]}, {q2[1]}, {q3[1]}, q1_z, q2_z, q3_z);
257// return out;
258// }
259
260template <typename S1_, typename S2_>
261typename S1_::Scalar S1xS2<S1_, S2_>::coeff_6j(const qType& q1, const qType& q2, const qType& q3, const qType& q4, const qType& q5, const qType& q6)
262{
263 auto [q1l, q1r] = disjoin<S1_::Nq, S2_::Nq>(q1);
264 auto [q2l, q2r] = disjoin<S1_::Nq, S2_::Nq>(q2);
265 auto [q3l, q3r] = disjoin<S1_::Nq, S2_::Nq>(q3);
266 auto [q4l, q4r] = disjoin<S1_::Nq, S2_::Nq>(q4);
267 auto [q5l, q5r] = disjoin<S1_::Nq, S2_::Nq>(q5);
268 auto [q6l, q6r] = disjoin<S1_::Nq, S2_::Nq>(q6);
269
270 Scalar out = S1_::coeff_6j(q1l, q2l, q3l, q4l, q5l, q6l) * S2_::coeff_6j(q1r, q2r, q3r, q4r, q5r, q6r);
271 return out;
272}
273
274template <typename S1_, typename S2_>
275typename S1_::Scalar S1xS2<S1_, S2_>::coeff_9j(const qType& q1,
276 const qType& q2,
277 const qType& q3,
278 const qType& q4,
279 const qType& q5,
280 const qType& q6,
281 const qType& q7,
282 const qType& q8,
283 const qType& q9)
284{
285 auto [q1l, q1r] = disjoin<S1_::Nq, S2_::Nq>(q1);
286 auto [q2l, q2r] = disjoin<S1_::Nq, S2_::Nq>(q2);
287 auto [q3l, q3r] = disjoin<S1_::Nq, S2_::Nq>(q3);
288 auto [q4l, q4r] = disjoin<S1_::Nq, S2_::Nq>(q4);
289 auto [q5l, q5r] = disjoin<S1_::Nq, S2_::Nq>(q5);
290 auto [q6l, q6r] = disjoin<S1_::Nq, S2_::Nq>(q6);
291 auto [q7l, q7r] = disjoin<S1_::Nq, S2_::Nq>(q7);
292 auto [q8l, q8r] = disjoin<S1_::Nq, S2_::Nq>(q8);
293 auto [q9l, q9r] = disjoin<S1_::Nq, S2_::Nq>(q9);
294
295 Scalar out = S1_::coeff_9j(q1l, q2l, q3l, q4l, q5l, q6l, q7l, q8l, q9l) * S2_::coeff_9j(q1r, q2r, q3r, q4r, q5r, q6r, q7r, q8r, q9r);
296 return out;
297}
298
299template <typename S1_, typename S2_>
300bool S1xS2<S1_, S2_>::triangle(const qType& q1, const qType& q2, const qType& q3)
301{
302 auto [q1l, q1r] = disjoin<S1_::Nq, S2_::Nq>(q1);
303 auto [q2l, q2r] = disjoin<S1_::Nq, S2_::Nq>(q2);
304 auto [q3l, q3r] = disjoin<S1_::Nq, S2_::Nq>(q3);
305 return (S1_::triangle(q1l, q2l, q3l) and S2_::triangle(q1r, q2r, q3r));
306}
307
308} // namespace Xped::Sym
309
310#endif // end XPED_S1xS2_H_
Definition: CombSym.hpp:8
XpedWorld & getUniverse()
Definition: Mpi.hpp:49
constexpr std::array< T, LL+RL > join(const std::array< T, LL > rhs, const std::array< T, RL > lhs, detail::num_tuple< LLs... >, detail::num_tuple< RLs... >)
Definition: JoinArray.hpp:41
constexpr qarray< Nq1+Nq2 > join(qarray< Nq1 > rhs, qarray< Nq2 > lhs)
Definition: qarray.hpp:147
CTF::Tensor< Scalar > TType
Definition: PlainInterface_Cyclops_impl.cpp:13
Definition: S1xS2.hpp:37
static constexpr bool ALL_NON_ABELIAN
Definition: S1xS2.hpp:70
static Scalar coeff_dot(const qType &q1)
Definition: S1xS2.hpp:235
static constexpr std::array< int, Nq > MOD_N
Definition: S1xS2.hpp:58
static constexpr bool ALL_IS_BOSONIC
Definition: S1xS2.hpp:75
S2_ S2
Definition: S1xS2.hpp:42
static constexpr bool IS_CHARGE_SU2()
Definition: S1xS2.hpp:78
static Scalar coeff_turn(const qType &ql, const qType &qr, const qType &qf)
Definition: S1xS2.hpp:177
qarray< Nq > qType
Definition: S1xS2.hpp:86
static constexpr bool ALL_IS_FERMIONIC
Definition: S1xS2.hpp:74
static Scalar coeff_swap(const qType &ql, const qType &qr, const qType &qf)
Definition: S1xS2.hpp:199
static std::size_t multiplicity(const qType &q1, const qType &q2, const qType &q3)
Definition: S1xS2.hpp:124
static Scalar coeff_9j(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6, const qType &q7, const qType &q8, const qType &q9)
Definition: S1xS2.hpp:275
static constexpr std::array< bool, Nq > IS_TRIVIAL
Definition: S1xS2.hpp:53
static constexpr bool ANY_IS_SPIN
Definition: S1xS2.hpp:67
static constexpr bool NO_SPIN_SYM()
Definition: S1xS2.hpp:83
static constexpr bool ANY_IS_MODULAR
Definition: S1xS2.hpp:64
return PlainLib::tensorProd(Tl, Tr)
S1_::Scalar Scalar
Definition: S1xS2.hpp:39
static constexpr std::array< qType, S1::lowest_qs().size() *S2::lowest_qs().size()> lowest_qs()
Definition: S1xS2.hpp:91
static constexpr bool ALL_IS_SPIN
Definition: S1xS2.hpp:76
static constexpr bool ALL_ABELIAN
Definition: S1xS2.hpp:71
static Scalar coeff_3j(const qType &q1, const qType &q2, const qType &q3, int q1_z, int q2_z, int q3_z)
Definition: S1xS2.hpp:162
static constexpr bool NO_CHARGE_SYM()
Definition: S1xS2.hpp:84
static constexpr qType qvacuum()
Definition: S1xS2.hpp:90
static constexpr bool ALL_IS_TRIVIAL
Definition: S1xS2.hpp:72
static constexpr bool ALL_HAS_MULTIPLICITIES
Definition: S1xS2.hpp:69
static std::vector< qType > basis_combine(const qType &ql, const qType &qr)
Definition: S1xS2.hpp:221
static constexpr bool ANY_ABELIAN
Definition: S1xS2.hpp:62
static constexpr std::array< bool, Nq > NON_ABELIAN
Definition: S1xS2.hpp:51
static constexpr std::array< bool, Nq > ABELIAN
Definition: S1xS2.hpp:52
static qType random_q()
Definition: S1xS2.hpp:115
static bool triangle(const qType &q1, const qType &q2, const qType &q3)
Definition: S1xS2.hpp:300
static constexpr std::array< bool, Nq > IS_MODULAR
Definition: S1xS2.hpp:54
static constexpr bool IS_SPIN_U1()
Definition: S1xS2.hpp:81
static constexpr std::size_t Nq
Definition: S1xS2.hpp:48
static constexpr std::array< bool, Nq > HAS_MULTIPLICITIES
Definition: S1xS2.hpp:50
static constexpr bool ANY_NON_ABELIAN
Definition: S1xS2.hpp:61
static constexpr bool IS_SPIN_SU2()
Definition: S1xS2.hpp:79
static constexpr bool ANY_HAS_MULTIPLICITIES
Definition: S1xS2.hpp:60
static constexpr std::array< KIND, Nq > kind()
Definition: S1xS2.hpp:88
static constexpr bool ANY_IS_TRIVIAL
Definition: S1xS2.hpp:63
S1xS2()
Definition: S1xS2.hpp:44
static constexpr std::array< bool, Nq > IS_FERMIONIC
Definition: S1xS2.hpp:55
static Scalar coeff_rightOrtho(const qType &, const qType &)
Definition: S1xS2.hpp:243
static constexpr bool ANY_IS_BOSONIC
Definition: S1xS2.hpp:66
static Scalar coeff_6j(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
Definition: S1xS2.hpp:261
static int degeneracy(const qType &q)
Definition: S1xS2.hpp:109
S1_ S1
Definition: S1xS2.hpp:41
auto Tl
Definition: S1xS2.hpp:172
auto Tr
Definition: S1xS2.hpp:173
static Scalar coeff_recouple(const qType &q1, const qType &q2, const qType &q3, const qType &Q, const qType &Q12, const qType &Q23)
Definition: S1xS2.hpp:186
static PlainLib::template TType< Scalar, 2 > one_j_tensor(const qType &q, mpi::XpedWorld &world=mpi::getUniverse())
Definition: S1xS2.hpp:151
static Scalar coeff_twist(const qType &q)
Definition: S1xS2.hpp:138
static qType conj(const qType &q)
Definition: S1xS2.hpp:103
static std::string name()
Definition: S1xS2.hpp:46
static constexpr std::array< bool, Nq > IS_BOSONIC
Definition: S1xS2.hpp:56
static constexpr bool ALL_IS_MODULAR
Definition: S1xS2.hpp:73
static Scalar coeff_FS(const qType &q)
Definition: S1xS2.hpp:144
static constexpr bool ANY_IS_FERMIONIC
Definition: S1xS2.hpp:65
static constexpr std::array< bool, Nq > IS_SPIN
Definition: S1xS2.hpp:57
Definition: SymBase.hpp:14
S1::Scalar Scalar
Definition: S1xS2.hpp:25
qarray< Nq > qType
Definition: S1xS2.hpp:24
Definition: SymBase.hpp:10
Definition: Mpi.hpp:34
Definition: qarray.hpp:30