HILA
Loading...
Searching...
No Matches
gaugefield.h
Go to the documentation of this file.
1#ifndef HILA_GAUGEFIELD_H_
2#define HILA_GAUGEFIELD_H_
3
4/**
5 * @file gaugefield.h
6 * @brief Definition of Gauge Field
7 * @details This file contains the definition for the GaugeField class
8 */
9
10#include "hila.h"
11
12/**
13 * @brief Gauge field class
14 * @details Stores and defines links between Lattice Field elements. Number of links is
15 * `lattice.size()*NDIM`, since for each point there is a link in all directions.
16 *
17 * @param fdir std::array<Field<T>,NDIM> type element which stores GaugeField links in back to back
18 * direction wise ordering.
19 *
20 * @tparam T Group that GaugeField consists of
21 */
22template <typename T>
24 private:
25 std::array<Field<T>, NDIM> fdir;
26
27 // somewhat arbitrary fingerprint flag for configuration files
28 static constexpr int64_t config_flag = 394824242;
29
30 public:
31 // Default constructor
32 GaugeField() = default;
33
34 // Straightforward copy constructor seems to be necessary
35 GaugeField(const GaugeField &other) = default;
36
37 // copy constructor - from fields which can be assigned
38 template <typename A, std::enable_if_t<std::is_convertible<A, T>::value, int> = 0>
39 GaugeField(const GaugeField<A> &other) {
40 foralldir(d) fdir[d] = other[d];
41 }
42
43 // constructor with compatible scalar
44 template <typename A, std::enable_if_t<hila::is_assignable<T &, A>::value, int> = 0>
45 GaugeField(const A &val) {
46 foralldir(d) fdir[d] = val;
47 }
48
49 // constructor from 0 - nullptr trick in use
50 GaugeField(const std::nullptr_t z) {
51 foralldir(d) fdir[d] = 0;
52 }
53
54
55 /////////////////////////////////////////////////
56 /// Destructor
57
58 ~GaugeField() = default;
59
60 /////////////////////////////////////////////////
61 /// Access components with []
62
64 return fdir[d];
65 }
66
67 inline const Field<T> &operator[](Direction d) const {
68 return fdir[d];
69 }
70
71 //////////////////////////////////////////////////
72 /// Assign from anything the field allows
73 template <typename A>
74 GaugeField &operator=(const A &val) {
75 foralldir(d) fdir[d] = val;
76 return *this;
77 }
78
79 /// Separate 0 assignment
80 GaugeField &operator=(std::nullptr_t np) {
81 foralldir(d) fdir[d] = 0;
82 return *this;
83 }
84
85 template <typename A>
87 foralldir(d) fdir[d] = rhs[d];
88 return *this;
89 }
90
91 /**
92 * @brief Reunitarize Gauge Field consisting of \f$ SU(N)\f$ matrices
93 * @details Only defined for \f$ SU(N) \f$ matrices and Fields
94 */
96 foralldir(d) {
97 onsites(ALL)(*this)[d][X].reunitarize();
98 }
99 }
100
101 /**
102 * @brief Computes Wilson action
103 * @details \f{align}{ S &= \beta\sum_{\textbf{dir}_1 < \textbf{dir}_2}\sum_{X} \frac{1}{N}
104 * \Re\mathrm{Tr}\left[ 1- U_{\textbf{dir}_1 \textbf{dir}_2}(X) \right] \f} Where \f$\beta =
105 * 2N/g^2\f$
106 *
107 * @return double
108 */
109 double measure_plaq() const {
111 plaq.allreduce(false);
112
113 foralldir(dir1) foralldir(dir2) if (dir1 < dir2) {
114
115 onsites(ALL) {
116 plaq += 1.0 -
117 real(trace((*this)[dir1][X] * (*this)[dir2][X + dir1] *
118 (*this)[dir1][X + dir2].dagger() * (*this)[dir2][X].dagger())) /
119 T::size();
120 }
121 }
122
123 return plaq.value();
124 }
125 ////////////////////////////////////////////////////////
126 // I/O operations for gauge fields (here only binary)
127
128 void write(std::ofstream &outputfile) const {
129 foralldir(d) {
130 fdir[d].write(outputfile);
131 }
132 }
133
134 void write(const std::string &filename) const {
135 std::ofstream outputfile;
136 hila::open_output_file(filename, outputfile);
137 write(outputfile);
138 hila::close_file(filename, outputfile);
139 }
140
141 void read(std::ifstream &inputfile) {
142 foralldir(d) {
143 fdir[d].read(inputfile);
144 }
145 }
146
147 void read(std::ifstream &inputfile, CoordinateVector &insize) {
148 foralldir(d) {
149 fdir[d].read(inputfile, insize);
150 }
151 }
152
153 void read(const std::string &filename) {
154 std::ifstream inputfile;
155 hila::open_input_file(filename, inputfile);
156 read(inputfile);
157 hila::close_file(filename, inputfile);
158 }
159
160 /// config_write writes the gauge field to file, with additional "verifying" header
161
162 void config_write(const std::string &filename) const {
163 std::ofstream outputfile;
164 hila::open_output_file(filename, outputfile);
165
166 // write header
167 if (hila::myrank() == 0) {
168 int64_t f = config_flag;
169 outputfile.write(reinterpret_cast<char *>(&f), sizeof(int64_t));
170 f = NDIM;
171 outputfile.write(reinterpret_cast<char *>(&f), sizeof(int64_t));
172 f = sizeof(T);
173 outputfile.write(reinterpret_cast<char *>(&f), sizeof(int64_t));
174
175 foralldir(d) {
176 f = lattice.size(d);
177 outputfile.write(reinterpret_cast<char *>(&f), sizeof(int64_t));
178 }
179 }
180
181 write(outputfile);
182 hila::close_file(filename, outputfile);
183 }
184
185 void config_read(const std::string &filename) {
186 std::ifstream inputfile;
187 hila::open_input_file(filename, inputfile);
188 std::string conferr("CONFIG ERROR in file " + filename + ": ");
189
190 // read header
191 bool ok = true;
192 int64_t f;
193 if (hila::myrank() == 0) {
194 inputfile.read(reinterpret_cast<char *>(&f), sizeof(int64_t));
195 ok = (f == config_flag);
196 if (!ok)
197 hila::out0 << conferr << "wrong id, should be " << config_flag << " is " << f
198 << '\n';
199 }
200
201 if (ok && hila::myrank() == 0) {
202 inputfile.read(reinterpret_cast<char *>(&f), sizeof(int64_t));
203 ok = (f == NDIM);
204 if (!ok)
205 hila::out0 << conferr << "wrong dimensionality, should be " << NDIM << " is " << f
206 << '\n';
207 }
208
209 if (ok && hila::myrank() == 0) {
210 inputfile.read(reinterpret_cast<char *>(&f), sizeof(int64_t));
211 ok = (f == sizeof(T));
212 if (!ok)
213 hila::out0 << conferr << "wrong size of field element, should be " << sizeof(T)
214 << " is " << f << '\n';
215 }
216
217 CoordinateVector insize = lattice.size();
218 if (ok && hila::myrank() == 0) {
219 foralldir(d) {
220 inputfile.read(reinterpret_cast<char *>(&f), sizeof(int64_t));
221 insize[d] = f;
222 ok = ok && (lattice.size(d) % insize[d] == 0);
223 if (!ok)
224 hila::out0 << conferr << "incorrect lattice dimension " << hila::prettyprint(d)
225 << " is " << f << " should be (or divide)" << lattice.size(d) << '\n';
226 }
227 }
228
229 if (!hila::broadcast(ok)) {
231 } else {
232 hila::broadcast_array(insize.c, NDIM);
233 }
234
235 read(inputfile, insize);
236 hila::close_file(filename, inputfile);
237 }
238};
239
240
241/// Implement hila::swap for gauge fields
242namespace hila {
243template <typename T>
244void swap(GaugeField<T> &A, GaugeField<T> &B) {
245 foralldir(d) hila::swap(A[d], B[d]);
246}
247} // namespace std
248
249
250///////////////////////////////////////////////////////
251/// Alias VectorField to GaugeField
252template <typename T>
254
255
256#endif
Array< n, m, hila::arithmetic_type< T > > real(const Array< n, m, T > &arg)
Return real part of Array.
Definition array.h:689
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Definition field.h:62
Gauge field class.
Definition gaugefield.h:23
~GaugeField()=default
Destructor.
GaugeField & operator=(std::nullptr_t np)
Separate 0 assignment.
Definition gaugefield.h:80
Field< T > & operator[](Direction d)
Access components with [].
Definition gaugefield.h:63
GaugeField & operator=(const A &val)
Assign from anything the field allows.
Definition gaugefield.h:74
void reunitarize_gauge()
Reunitarize Gauge Field consisting of matrices.
Definition gaugefield.h:95
double measure_plaq() const
Computes Wilson action.
Definition gaugefield.h:109
void config_write(const std::string &filename) const
config_write writes the gauge field to file, with additional "verifying" header
Definition gaugefield.h:162
int size(Direction d) const
lattice.size() -> CoordinateVector or lattice.size(d) -> int returns the dimensions of the lattice,...
Definition lattice.h:433
T c[n *m]
The data as a one dimensional array.
Definition matrix.h:110
Special reduction class: enables delayed and non-blocking reductions, which are not possible with the...
Definition reduction.h:14
const T value()
Return value of the reduction variable. Wait for the comms if needed.
Definition reduction.h:151
Reduction & allreduce(bool b=true)
allreduce(bool) turns allreduce on or off. By default on.
Definition reduction.h:124
Complex< T > dagger(const Complex< T > &val)
Return dagger of Complex number.
Definition cmplx.h:1302
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:80
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
Definition coordinates.h:34
constexpr Parity ALL
bit pattern: 011
Implement hila::swap for gauge fields.
Definition array.h:982
void broadcast_array(T *var, int n, int rank=0)
Broadcast for arrays where size must be known and same for all nodes.
Definition com_mpi.h:247
int myrank()
rank of this node
Definition com_mpi.cpp:237
std::ostream out0
This writes output only from main process (node 0)
T broadcast(T &var, int rank=0)
Broadcast the value of var to all MPI ranks from rank (default=0).
Definition com_mpi.h:170
void terminate(int status)