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 C_ARGS_N BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(C_ARGS_SEQ), 1)
29#define D_ARGS_N BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(D_ARGS_SEQ), 1)
30
31#define COLLIER_TYPE(Z, N, TEXT) const std::complex<double>*,
32#define COLLIER_ARGS(N) \
33 BOOST_PP_REPEAT(N, COLLIER_TYPE, ) const std::complex<double>*
34#define IMPL(R, ARGS, NAME) \
35 void BOOST_PP_CAT(NAME, _impl)(std::complex<double>*, COLLIER_ARGS(ARGS));
36
37// Imaginary parts of momentum invariants are not suppoted by COLLIER 1.2.4
38#define COLLIER_B(R, ARGS, NAME) \
39 std::complex<double> Collier::NAME ARGS noexcept \
40 { \
41 const std::complex<double> p10(p10_in.real(), 0.); \
42 const std::complex<double> m02 = m02_in; \
43 const std::complex<double> m12 = m12_in; \
44 std::complex<double> res = 0.0; \
45 set_mu2_uv(scl2_in); \
46 BOOST_PP_CAT(NAME, _impl)(&res, &p10, &m02, &m12); \
47 return res; \
48 }
49#define COLLIER_C(R, ARGS, NAME) \
50 std::complex<double> Collier::NAME ARGS noexcept \
51 { \
52 const std::complex<double> p10(p10_in.real(), 0.); \
53 const std::complex<double> p21(p21_in.real(), 0.); \
54 const std::complex<double> p20(p20_in.real(), 0.); \
55 const std::complex<double> m02 = m02_in; \
56 const std::complex<double> m12 = m12_in; \
57 const std::complex<double> m22 = m22_in; \
58 std::complex<double> res = 0.0; \
59 set_mu2_uv(scl2_in); \
60 BOOST_PP_CAT(NAME, _impl)(&res, &p10, &p21, &p20, &m02, &m12, &m22); \
61 return res; \
62 }
63#define COLLIER_D(R, ARGS, NAME) \
64 std::complex<double> Collier::NAME ARGS noexcept \
65 { \
66 const std::complex<double> p10(p10_in.real(), 0.); \
67 const std::complex<double> p21(p21_in.real(), 0.); \
68 const std::complex<double> p32(p32_in.real(), 0.); \
69 const std::complex<double> p30(p30_in.real(), 0.); \
70 const std::complex<double> p20(p20_in.real(), 0.); \
71 const std::complex<double> p31(p31_in.real(), 0.); \
72 const std::complex<double> m02 = m02_in; \
73 const std::complex<double> m12 = m12_in; \
74 const std::complex<double> m22 = m22_in; \
75 const std::complex<double> m32 = m32_in; \
76 std::complex<double> res = 0.0; \
77 set_mu2_uv(scl2_in); \
78 BOOST_PP_CAT(NAME, _impl) \
79 (&res, &p10, &p21, &p32, &p30, &p20, &p31, &m02, &m12, &m22, &m32); \
80 return res; \
81 }
82
83// Fortran wrapper routines
84extern "C" {
86void set_mu2_uv_impl(double*);
87
88BOOST_PP_SEQ_FOR_EACH(IMPL, A_ARGS_N, A_SEQ)
89BOOST_PP_SEQ_FOR_EACH(IMPL, B_ARGS_N, B_SEQ)
90BOOST_PP_SEQ_FOR_EACH(IMPL, C_ARGS_N, C_SEQ)
91BOOST_PP_SEQ_FOR_EACH(IMPL, D_ARGS_N, D_SEQ)
92
93void get_A_impl(const std::complex<double>[A_N], COLLIER_ARGS(A_ARGS_N));
94void get_B_impl(const std::complex<double>[B_N], COLLIER_ARGS(B_ARGS_N));
95void get_C_impl(const std::complex<double>[C_N], COLLIER_ARGS(C_ARGS_N));
96void get_D_impl(const std::complex<double>[D_N], COLLIER_ARGS(D_ARGS_N));
97}
98
99namespace flexiblesusy
100{
101namespace looplibrary
102{
103
104void Collier::initialize() noexcept
105{
106 futils::swap();
109 futils::swap();
110}
111
112void Collier::set_mu2_uv(double scl2_in) noexcept
113{
114 double scl2 = scl2_in;
115 if (std::abs(scl2 - this->current_mu2_uv) >
117 set_mu2_uv_impl(&scl2);
118 this->current_mu2_uv = scl2;
119 }
120}
121
122std::complex<double> Collier::A0(A_ARGS) noexcept
123{
124 const std::complex<double> m02 = m02_in;
125 std::complex<double> res = 0.0;
126 set_mu2_uv(scl2_in);
127 A0_impl(&res, &m02);
128 return res;
129}
130
131BOOST_PP_SEQ_FOR_EACH(COLLIER_B, (B_ARGS), B_SEQ)
132BOOST_PP_SEQ_FOR_EACH(COLLIER_C, (C_ARGS), C_SEQ)
133BOOST_PP_SEQ_FOR_EACH(COLLIER_D, (D_ARGS), D_SEQ)
134
135void Collier::A(Acoeff_t& a, A_ARGS) noexcept
136{
137 const std::complex<double> m02 = m02_in;
138
139 set_mu2_uv(scl2_in);
140 get_A_impl(a.data(), &m02);
141}
142
143void Collier::B(Bcoeff_t& b, B_ARGS) noexcept
144{
145 const std::complex<double> p10(p10_in.real(), 0.);
146 const std::complex<double> m02 = m02_in;
147 const std::complex<double> m12 = m12_in;
148
149 set_mu2_uv(scl2_in);
150 get_B_impl(b.data(), &p10, &m02, &m12);
151}
152
153void Collier::C(Ccoeff_t& c, C_ARGS) noexcept
154{
155 const std::complex<double> p10(p10_in.real(), 0.);
156 const std::complex<double> p21(p21_in.real(), 0.);
157 const std::complex<double> p20(p20_in.real(), 0.);
158 const std::complex<double> m02 = m02_in;
159 const std::complex<double> m12 = m12_in;
160 const std::complex<double> m22 = m22_in;
161
162 set_mu2_uv(scl2_in);
163 get_C_impl(c.data(), &p10, &p21, &p20, &m02, &m12, &m22);
164}
165
166void Collier::D(Dcoeff_t& d, D_ARGS) noexcept
167{
168 const std::complex<double> p10(p10_in.real(), 0.);
169 const std::complex<double> p21(p21_in.real(), 0.);
170 const std::complex<double> p32(p32_in.real(), 0.);
171 const std::complex<double> p30(p30_in.real(), 0.);
172 const std::complex<double> p20(p20_in.real(), 0.);
173 const std::complex<double> p31(p31_in.real(), 0.);
174 const std::complex<double> m02 = m02_in;
175 const std::complex<double> m12 = m12_in;
176 const std::complex<double> m22 = m22_in;
177 const std::complex<double> m32 = m32_in;
178
179 set_mu2_uv(scl2_in);
180 get_D_impl(d.data(), &p10, &p21, &p32, &p30, &p20, &p31, &m02, &m12, &m22,
181 &m32);
182}
183
184} // namespace looplibrary
185} // 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 > *)
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_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 C_SEQ
#define A_N
#define A_ARGS
#define D_N
#define A_SEQ
#define C_N
void flush() noexcept
Flushes output of fortran routines.
void swap() noexcept
Swaps stdout and stderr descriptors.
void() C(cc)) coeff_t &arr
std::array< std::complex< double >, BOOST_PP_SEQ_SIZE((0)(1)(2)(00)(11)(12)(22)) > Ccoeff_t
void() D(dd)) coeff_t &arr
void() A(aa)) coeff_t &arr
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
void() B(bb)) coeff_t &arr
const Real epsilon
Definition: mathdefs.hpp:18