NESSi
v1.0.2
The NonEquilibrium Systems Simulation Library
cntr_response_convolution_impl.hpp
Go to the documentation of this file.
1
#ifndef CNTR_RESPONSE_CONVOLUTION_IMPL_H
2
#define CNTR_RESPONSE_CONVOLUTION_IMPL_H
3
4
#include "
cntr_response_convolution_decl.hpp
"
5
6
namespace
cntr
{
7
8
/*////////////////////////////////////////////////////////////////
9
10
computing the response to a retarded response function
11
12
c(t) = \int_C dt' W(t,t') f(t')
13
14
NOTES:
15
- assumes that W is hermitian
16
- uses points 0...kt if t<kt (thus a version using W only as timestep
17
works only for t>=kt and t==-1
18
20
21
#define CPLX std::complex<T>
22
23
// res = int_0^n dt f(t), f(i*dt)=f[sf*i+idxf], i=0..,n
25
template <typename T>
26
void response_integrate(int n, T dt, CPLX &res, CPLX *f, int sf, int idxf,
27
integration::Integrator<T> &I) {
28
int kt = I.k(), i, k2 = 2 * (kt + 1);
29
res = 0;
30
if (n >= k2) {
31
for (i = 0; i <= kt; i++)
32
res += f[i * sf + idxf] * I.gregory_weights(n, i);
33
for (i = kt + 1; i < n - kt; i++)
34
res += f[i * sf + idxf];
35
for (i = n - kt; i <= n; i++)
36
res += f[i * sf + idxf] * I.gregory_weights(n, i);
37
} else if (n > 0) {
38
int n1 = (n <= kt ? kt : n);
39
for (i = 0; i <= n1; i++)
40
res += f[i * sf + idxf] * I.gregory_weights(n, i);
41
}
42
res *= dt;
43
}
44
// res = int_0^n dt f(t)g(t), f(i*dt)=f[sf*i+idxf], g(i*dt)=g[sg*i+idxg], i=0..,n
46
template <typename T>
47
void response_integrate(int n, T dt, CPLX &res, CPLX *f, int sf, int idxf, CPLX *g, int sg,
48
int idxg, integration::Integrator<T> &I) {
49
int kt = I.k(), i, k2 = 2 * (kt + 1);
50
res = 0;
51
if (n >= k2) {
52
for (i = 0; i <= kt; i++)
53
res += f[i * sf + idxf] * g[i * sg + idxg] * I.gregory_weights(n, i);
54
for (i = kt + 1; i < n - kt; i++)
55
res += f[i * sf + idxf] * g[i * sg + idxg];
56
for (i = n - kt; i <= n; i++)
57
res += f[i * sf + idxf] * g[i * sg + idxg] * I.gregory_weights(n, i);
58
} else if (n > 0) {
59
int n1 = (n <= kt ? kt : n);
60
for (i = 0; i <= n1; i++)
61
res += f[i * sf + idxf] * g[i * sg + idxg] * I.gregory_weights(n, i);
62
}
63
res *= dt;
64
}
65
66
// USING THE ASSUMPTION THAT W IS HERMITIAN
67
template <typename T>
68
void response_convolution(int tstp, CPLX &cc, GREEN_TSTP &W, int a1, int a2, function<T> &f,
69
int b1, int b2, int SolveOrder, T beta, T h) {
70
int ntau = W.ntau();
71
T dtau = beta / ntau;
72
int sizew = W.size1(), idxw = a1 * sizew + a2, sw = sizew * sizew;
73
int sizef = f.size1(), idxf = b1 * sizef + b2, sf = sizef * sizef;
74
CPLX res;
75
76
assert(W.tstp() >= tstp);
77
assert(tstp == -1 || tstp >= SolveOrder);
78
assert(SolveOrder <= ntau);
79
assert(b1 >= 0 && b1 <= sizef-1);
80
assert(b2 >= 0 && b2 <= sizef-1);
81
assert(a1 >= 0 && a1 <= sizew-1);
82
assert(a2 >= 0 && a2 <= sizew-1);
83
84
if (tstp == -1) {
85
response_integrate<T>(ntau, dtau, res, W.matptr(0), sw, idxw, integration::I<T>(SolveOrder));
86
cc = res * f.ptr(-1)[idxf];
87
} else {
88
response_integrate<T>(ntau, dtau, res, W.tvptr(0), sw, idxw, integration::I<T>(SolveOrder));
89
cc = res * (CPLX(0, -1.0) * f.ptr(-1)[idxf]);
90
response_integrate<T>(tstp, h, res, W.retptr(0), sw, idxw, f.ptr(0), sf, idxf,
91
integration::I<T>(SolveOrder));
92
cc += res;
93
}
94
}
95
template <typename T>
96
void response_convolution(int tstp, CPLX &cc, GREEN &W, int a1, int a2, function<T> &f,
97
int b1, int b2, int SolveOrder, T beta, T h) {
98
int ntau = W.ntau();
99
T dtau = beta / ntau;
100
int sizew = W.size1(), idxw = a1 * sizew + a2, sw = sizew * sizew;
101
int sizef = f.size1(), idxf = b1 * sizef + b2, sf = sizef * sizef;
102
int n1 = (tstp == -1 || tstp >= SolveOrder ? SolveOrder : SolveOrder);
103
CPLX res;
104
105
assert(W.nt() >= tstp);
106
assert(tstp == -1 || tstp >= SolveOrder);
107
assert(SolveOrder <= ntau);
108
assert(b1 >= 0 && b1 <= sizef-1);
109
assert(b2 >= 0 && b2 <= sizef-1);
110
assert(a1 >= 0 && a1 <= sizew-1);
111
assert(a2 >= 0 && a2 <= sizew-1);
112
113
if (tstp == -1) {
114
response_integrate<T>(ntau, dtau, res, W.matptr(0), sw, idxw, integration::I<T>(SolveOrder));
115
cc = res * f.ptr(-1)[idxf];
116
} else if (tstp >= SolveOrder) {
117
response_integrate<T>(ntau, dtau, res, W.tvptr(tstp, 0), sw, idxw,
118
integration::I<T>(SolveOrder));
119
cc = res * (CPLX(0, -1.0) * f.ptr(-1)[idxf]);
120
response_integrate<T>(tstp, h, res, W.retptr(tstp, 0), sw, idxw, f.ptr(0), sf, idxf,
121
integration::I<T>(SolveOrder));
122
cc += res;
123
} else {
124
response_integrate<T>(ntau, dtau, res, W.tvptr(tstp, 0), sw, idxw,
125
integration::I<T>(SolveOrder));
126
cc = res * (CPLX(0, -1.0) * f.ptr(-1)[idxf]);
127
// need to extrapolate W(t,t') for t'>t
128
// ** USING THE ASSUMPTION THAT W IS HERMITIAN**
129
// i.e., Wret(t,t') = -Wret(t',t)^*
130
CPLX *wtmp = new CPLX[SolveOrder + 1];
131
for (int i = 0; i <= tstp; i++)
132
wtmp[i] = W.retptr(tstp, i)[a1 * sizew + a2];
133
for (int i = tstp + 1; i <= SolveOrder; i++)
134
wtmp[i] = -conj(W.retptr(i, tstp)[a2 * sizew + a1]);
135
response_integrate<T>(tstp, h, res, wtmp, 1, 0, f.ptr(0), sf, idxf,
136
integration::I<T>(SolveOrder));
137
cc += res;
138
delete[] wtmp;
139
}
140
}
141
142
#undef GREEN
143
#undef GREEN_TSTP
144
#undef CPLX
145
146
} // namespace cntr
147
148
#endif // CNTR_RESPONSE_CONVOLUTION_IMPL_H
cntr_response_convolution_decl.hpp
cntr
Definition:
cntr_bubble_decl.hpp:6
cntr
cntr_response_convolution_impl.hpp
Generated by
1.8.15