flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
library_collier.cpp
Go to the documentation of this file.
1// ====================================================================
2// This file is part of FlexibleSUSY.
3//
4// FlexibleSUSY is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published
6// by the Free Software Foundation, either version 3 of the License,
7// or (at your option) any later version.
8//
9// FlexibleSUSY is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with FlexibleSUSY. If not, see
16// <http://www.gnu.org/licenses/>.
17// ====================================================================
18
19#include "library_collier.hpp"
20#include "fortran_utils.hpp"
21#include <boost/preprocessor/arithmetic/sub.hpp>
22#include <boost/preprocessor/cat.hpp>
23#include <boost/preprocessor/repetition/repeat.hpp>
24#include <limits>
25
26#define A_ARGS_N BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(A_ARGS_SEQ), 1)
27#define B_ARGS_N BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(B_ARGS_SEQ), 1)
28#define DB_ARGS_N BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(DB_ARGS_SEQ), 1)
29#define C_ARGS_N BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(C_ARGS_SEQ), 1)
30#define D_ARGS_N BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(D_ARGS_SEQ), 1)
31
32#define COLLIER_TYPE(Z, N, TEXT) const std::complex<double>*,
33#define COLLIER_ARGS(N) \
34 BOOST_PP_REPEAT(N, COLLIER_TYPE, ) const std::complex<double>*
35#define IMPL(R, ARGS, NAME) \
36 void BOOST_PP_CAT(NAME, _impl)(std::complex<double>*, COLLIER_ARGS(ARGS));
37
38// Imaginary parts of momentum invariants are not suppoted by COLLIER 1.2.4
39#define COLLIER_B(R, ARGS, NAME) \
40 std::complex<double> Collier::NAME ARGS noexcept \
41 { \
42 const std::complex<double> p10(p10_in.real(), 0.); \
43 const std::complex<double> m02 = m02_in; \
44 const std::complex<double> m12 = m12_in; \
45 std::complex<double> res = 0.0; \
46 set_mu2_uv(scl2_in); \
47 BOOST_PP_CAT(NAME, _impl)(&res, &p10, &m02, &m12); \
48 return res; \
49 }
50#define COLLIER_C(R, ARGS, NAME) \
51 std::complex<double> Collier::NAME ARGS noexcept \
52 { \
53 const std::complex<double> p10(p10_in.real(), 0.); \
54 const std::complex<double> p21(p21_in.real(), 0.); \
55 const std::complex<double> p20(p20_in.real(), 0.); \
56 const std::complex<double> m02 = m02_in; \
57 const std::complex<double> m12 = m12_in; \
58 const std::complex<double> m22 = m22_in; \
59 std::complex<double> res = 0.0; \
60 set_mu2_uv(scl2_in); \
61 BOOST_PP_CAT(NAME, _impl)(&res, &p10, &p21, &p20, &m02, &m12, &m22); \
62 return res; \
63 }
64#define COLLIER_D(R, ARGS, NAME) \
65 std::complex<double> Collier::NAME ARGS noexcept \
66 { \
67 const std::complex<double> p10(p10_in.real(), 0.); \
68 const std::complex<double> p21(p21_in.real(), 0.); \
69 const std::complex<double> p32(p32_in.real(), 0.); \
70 const std::complex<double> p30(p30_in.real(), 0.); \
71 const std::complex<double> p20(p20_in.real(), 0.); \
72 const std::complex<double> p31(p31_in.real(), 0.); \
73 const std::complex<double> m02 = m02_in; \
74 const std::complex<double> m12 = m12_in; \
75 const std::complex<double> m22 = m22_in; \
76 const std::complex<double> m32 = m32_in; \
77 std::complex<double> res = 0.0; \
78 set_mu2_uv(scl2_in); \
79 BOOST_PP_CAT(NAME, _impl) \
80 (&res, &p10, &p21, &p32, &p30, &p20, &p31, &m02, &m12, &m22, &m32); \
81 return res; \
82 }
83
84// Fortran wrapper routines
85extern "C" {
87void set_mu2_uv_impl(double*);
88
89BOOST_PP_SEQ_FOR_EACH(IMPL, A_ARGS_N, A_SEQ)
90BOOST_PP_SEQ_FOR_EACH(IMPL, B_ARGS_N, B_SEQ)
91BOOST_PP_SEQ_FOR_EACH(IMPL, DB_ARGS_N, DB_SEQ)
92BOOST_PP_SEQ_FOR_EACH(IMPL, C_ARGS_N, C_SEQ)
93BOOST_PP_SEQ_FOR_EACH(IMPL, D_ARGS_N, D_SEQ)
94
95void get_A_impl(const std::complex<double>[A_N], COLLIER_ARGS(A_ARGS_N));
96void get_B_impl(const std::complex<double>[B_N], COLLIER_ARGS(B_ARGS_N));
97void get_DB_impl(const std::complex<double>[DB_N], COLLIER_ARGS(DB_ARGS_N));
98void get_C_impl(const std::complex<double>[C_N], COLLIER_ARGS(C_ARGS_N));
99void get_D_impl(const std::complex<double>[D_N], COLLIER_ARGS(D_ARGS_N));
100}
101
102namespace flexiblesusy
103{
104namespace looplibrary
105{
106
107void Collier::initialize() noexcept
108{
109 futils::swap();
111 futils::flush();
112 futils::swap();
113}
114
115void Collier::set_mu2_uv(double scl2_in) noexcept
116{
117 double scl2 = scl2_in;
118 if (std::abs(scl2 - this->current_mu2_uv) >
119 std::numeric_limits<double>::epsilon()) {
120 set_mu2_uv_impl(&scl2);
121 this->current_mu2_uv = scl2;
122 }
123}
124
125std::complex<double> Collier::A0(A_ARGS) noexcept
126{
127 const std::complex<double> m02 = m02_in;
128 std::complex<double> res = 0.0;
129 set_mu2_uv(scl2_in);
130 A0_impl(&res, &m02);
131 return res;
132}
133
134BOOST_PP_SEQ_FOR_EACH(COLLIER_B, (B_ARGS), B_SEQ)
135BOOST_PP_SEQ_FOR_EACH(COLLIER_B, (DB_ARGS), DB_SEQ)
136BOOST_PP_SEQ_FOR_EACH(COLLIER_C, (C_ARGS), C_SEQ)
137BOOST_PP_SEQ_FOR_EACH(COLLIER_D, (D_ARGS), D_SEQ)
138
139void Collier::A(Acoeff_t& a, A_ARGS) noexcept
140{
141 const std::complex<double> m02 = m02_in;
142
143 set_mu2_uv(scl2_in);
144 get_A_impl(a.data(), &m02);
145}
146
147void Collier::B(Bcoeff_t& b, B_ARGS) noexcept
148{
149 const std::complex<double> p10(p10_in.real(), 0.);
150 const std::complex<double> m02 = m02_in;
151 const std::complex<double> m12 = m12_in;
152
153 set_mu2_uv(scl2_in);
154 get_B_impl(b.data(), &p10, &m02, &m12);
155}
156
157void Collier::DB(DBcoeff_t& db, DB_ARGS) noexcept
158{
159 const std::complex<double> p10(p10_in.real(), 0.);
160 const std::complex<double> m02 = m02_in;
161 const std::complex<double> m12 = m12_in;
162
163 set_mu2_uv(scl2_in);
164 get_DB_impl(db.data(), &p10, &m02, &m12);
165}
166
167void Collier::C(Ccoeff_t& c, C_ARGS) noexcept
168{
169 const std::complex<double> p10(p10_in.real(), 0.);
170 const std::complex<double> p21(p21_in.real(), 0.);
171 const std::complex<double> p20(p20_in.real(), 0.);
172 const std::complex<double> m02 = m02_in;
173 const std::complex<double> m12 = m12_in;
174 const std::complex<double> m22 = m22_in;
175
176 set_mu2_uv(scl2_in);
177 get_C_impl(c.data(), &p10, &p21, &p20, &m02, &m12, &m22);
178}
179
180void Collier::D(Dcoeff_t& d, D_ARGS) noexcept
181{
182 const std::complex<double> p10(p10_in.real(), 0.);
183 const std::complex<double> p21(p21_in.real(), 0.);
184 const std::complex<double> p32(p32_in.real(), 0.);
185 const std::complex<double> p30(p30_in.real(), 0.);
186 const std::complex<double> p20(p20_in.real(), 0.);
187 const std::complex<double> p31(p31_in.real(), 0.);
188 const std::complex<double> m02 = m02_in;
189 const std::complex<double> m12 = m12_in;
190 const std::complex<double> m22 = m22_in;
191 const std::complex<double> m32 = m32_in;
192
193 set_mu2_uv(scl2_in);
194 get_D_impl(d.data(), &p10, &p21, &p32, &p30, &p20, &p31, &m02, &m12, &m22,
195 &m32);
196}
197
198} // namespace looplibrary
199} // namespace flexiblesusy
#define B_ARGS_N
#define C_ARGS_N
#define A_ARGS_N
void initialize_collier_impl()
#define COLLIER_ARGS(N)
void get_A_impl(const std::complex< double >[BOOST_PP_SEQ_SIZE((0))], BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_PP_SEQ_SIZE((m02_in)), 1), COLLIER_TYPE,) const std::complex< double > *)
#define DB_ARGS_N
void get_C_impl(const std::complex< double >[BOOST_PP_SEQ_SIZE((0)(1)(2)(00)(11)(12)(22))], BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_PP_SEQ_SIZE((p10_in)(p21_in)(p20_in)(m02_in)(m12_in)(m22_in)), 1), COLLIER_TYPE,) const std::complex< double > *)
#define D_ARGS_N
void set_mu2_uv_impl(double *)
void get_DB_impl(const std::complex< double >[BOOST_PP_SEQ_SIZE((0)(1)(00))], BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_PP_SEQ_SIZE((p10_in)(m02_in)(m12_in)), 1), COLLIER_TYPE,) const std::complex< double > *)
void get_B_impl(const std::complex< double >[BOOST_PP_SEQ_SIZE((0)(1)(00))], BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_PP_SEQ_SIZE((p10_in)(m02_in)(m12_in)), 1), COLLIER_TYPE,) const std::complex< double > *)
#define COLLIER_D(R, ARGS, NAME)
#define COLLIER_C(R, ARGS, NAME)
#define IMPL(R, ARGS, NAME)
#define COLLIER_B(R, ARGS, NAME)
void get_D_impl(const std::complex< double >[BOOST_PP_SEQ_SIZE((0)(1)(2)(3)(00)(11)(12)(13)(22)(23)(33))], BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_PP_SEQ_SIZE((p10_in)(p21_in)(p32_in)(p30_in)(p20_in)(p31_in)(m02_in)(m12_in)(m22_in)(m32_in)), 1), COLLIER_TYPE,) const std::complex< double > *)
#define B_ARGS
#define B_N
#define C_ARGS
#define D_ARGS
#define D_SEQ
#define B_SEQ
#define DB_N
#define C_SEQ
#define A_N
#define A_ARGS
#define D_N
#define A_SEQ
#define DB_ARGS
#define C_N
#define DB_SEQ
std::array< std::complex< double >, BOOST_PP_SEQ_SIZE((0)(1)(2)(00)(11)(12)(22)) > Ccoeff_t
std::array< std::complex< double >, BOOST_PP_SEQ_SIZE((0)(1)(00)) > DBcoeff_t
std::array< std::complex< double >, BOOST_PP_SEQ_SIZE((0)) > Acoeff_t
std::array< std::complex< double >, BOOST_PP_SEQ_SIZE((0)(1)(2)(3)(00)(11)(12)(13)(22)(23)(33)) > Dcoeff_t
std::array< std::complex< double >, BOOST_PP_SEQ_SIZE((0)(1)(00)) > Bcoeff_t