HILA
Loading...
Searching...
No Matches
plaquettefield.h
1/**
2 * @file PlaquetteField.h
3 * @brief Definition of Gauge Field
4 * @details This file contains the definition for the PlaquetteField class
5 */
6#ifndef PlaquetteField_H_
7#define PlaquetteField_H_
8
9#include "hila.h"
10
11/**
12 * @brief Plaquette field class
13 * @details Stores and defines plaquette Lattice Field elements. Number of plaquettes is
14 * `lattice.size()*NDIM*NDIM` since at each point any pair of directions (dir1,dir2) can span a
15 * plaquette. Degenerate plaquettes (dir1=dir2) are included for simplicity to be able to define
16 * PlaquetteField in terms of VectorField.
17 *
18 * @param fdir std::array<VectorField<T>,NDIM> type element which stores PlaquetteField.
19 *
20 * @tparam T Group that PlaquetteField consists of
21 */
22template <typename T>
24 private:
25 std::array<VectorField<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 PlaquetteField() = default;
33
34 // Straightforward copy constructor seems to be necessary
35 PlaquetteField(const PlaquetteField &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 PlaquetteField(const PlaquetteField<A> &other) {
40 foralldir(d1) fdir[d1] = other[d1];
41 }
42
43 // constructor with compatible Vector field
44 template <typename A, std::enable_if_t<std::is_convertible<A, T>::value, int> = 0>
45 PlaquetteField(const VectorField<A> &other) {
46 foralldir(d1) fdir[d1] = other;
47 }
48
49 // constructor with compatible scalar
50 template <typename A, std::enable_if_t<hila::is_assignable<T &, A>::value, int> = 0>
51 PlaquetteField(const A &val) {
52 foralldir(d1) fdir[d1] = val;
53 }
54
55 // constructor from 0 - nullptr trick in use
56 PlaquetteField(const std::nullptr_t z) {
57 foralldir(d1) fdir[d1] = 0;
58 }
59
60
61 /////////////////////////////////////////////////
62 /// Destructor
63
64 ~PlaquetteField() = default;
65
66 /////////////////////////////////////////////////
67 /// Access components with []
68
70 return fdir[d1];
71 }
72
73 inline const VectorField<T> &operator[](Direction d1) const {
74 return fdir[d1];
75 }
76
77 //////////////////////////////////////////////////
78 /// Assign from anything the field allows
79 template <typename A>
80 PlaquetteField &operator=(const A &val) {
81 foralldir(d1) fdir[d1] = val;
82 return *this;
83 }
84
85 /// Separate 0 assignment
86 PlaquetteField &operator=(std::nullptr_t np) {
87 foralldir(d1) fdir[d1] = 0;
88 return *this;
89 }
90
91 template <typename A>
93 foralldir(d1) fdir[d1] = rhs[d1];
94 return *this;
95 }
96
97 ////////////////////////////////////////////////////////
98 // I/O operations for plaquette fields (here only binary)
99
100 void write(std::ofstream &outputfile) const {
101 foralldir(d1) {
102 fdir[d1].write(outputfile);
103 }
104 }
105
106 void write(const std::string &filename) const {
107 std::ofstream outputfile;
108 hila::open_output_file(filename, outputfile);
109 write(outputfile);
110 hila::close_file(filename, outputfile);
111 }
112
113 void read(std::ifstream &inputfile) {
114 foralldir(d1) {
115 fdir[d1].read(inputfile);
116 }
117 }
118
119 void read(std::ifstream &inputfile, CoordinateVector &insize) {
120 foralldir(d1) {
121 fdir[d1].read(inputfile, insize);
122 }
123 }
124
125 void read(const std::string &filename) {
126 std::ifstream inputfile;
127 hila::open_input_file(filename, inputfile);
128 read(inputfile);
129 hila::close_file(filename, inputfile);
130 }
131
132 /// config_write writes the gauge field to file, with additional "verifying" header
133
134 void config_write(const std::string &filename) const {
135 std::ofstream outputfile;
136 hila::open_output_file(filename, outputfile);
137
138 // write header
139 if (hila::myrank() == 0) {
140 int64_t f = config_flag;
141 outputfile.write(reinterpret_cast<char *>(&f), sizeof(int64_t));
142 f = NDIM;
143 outputfile.write(reinterpret_cast<char *>(&f), sizeof(int64_t));
144 f = sizeof(T);
145 outputfile.write(reinterpret_cast<char *>(&f), sizeof(int64_t));
146
147 foralldir(d) {
148 f = lattice.size(d);
149 outputfile.write(reinterpret_cast<char *>(&f), sizeof(int64_t));
150 }
151 }
152
153 write(outputfile);
154 hila::close_file(filename, outputfile);
155 }
156
157 void config_read(const std::string &filename) {
158 std::ifstream inputfile;
159 hila::open_input_file(filename, inputfile);
160 std::string conferr("CONFIG ERROR in file " + filename + ": ");
161
162 // read header
163 bool ok = true;
164 int64_t f;
165 if (hila::myrank() == 0) {
166 inputfile.read(reinterpret_cast<char *>(&f), sizeof(int64_t));
167 ok = (f == config_flag);
168 if (!ok)
169 hila::out0 << conferr << "wrong id, should be " << config_flag << " is " << f
170 << '\n';
171 }
172
173 if (ok && hila::myrank() == 0) {
174 inputfile.read(reinterpret_cast<char *>(&f), sizeof(int64_t));
175 ok = (f == NDIM);
176 if (!ok)
177 hila::out0 << conferr << "wrong dimensionality, should be " << NDIM << " is " << f
178 << '\n';
179 }
180
181 if (ok && hila::myrank() == 0) {
182 inputfile.read(reinterpret_cast<char *>(&f), sizeof(int64_t));
183 ok = (f == sizeof(T));
184 if (!ok)
185 hila::out0 << conferr << "wrong size of field element, should be " << sizeof(T)
186 << " is " << f << '\n';
187 }
188
189 CoordinateVector insize = lattice.size();
190 if (ok && hila::myrank() == 0) {
191
192 foralldir(d) {
193 inputfile.read(reinterpret_cast<char *>(&f), sizeof(int64_t));
194 insize[d] = f;
195 ok = ok && (lattice.size(d) % insize[d] == 0);
196 if (!ok)
197 hila::out0 << conferr << "incorrect lattice dimension " << hila::prettyprint(d)
198 << " is " << f << " should be (or divide) " << lattice.size(d) << '\n';
199 }
200 }
201
202 if (!hila::broadcast(ok)) {
204 } else {
205 hila::broadcast_array(insize.c, NDIM);
206 }
207
208 read(inputfile, insize);
209 hila::close_file(filename, inputfile);
210 }
211};
212
213
214/// Implement hila::swap for gauge fields
215namespace hila {
216template <typename T>
217void swap(PlaquetteField<T> &A, PlaquetteField<T> &B) {
218 foralldir(d1) hila::swap(A[d1], B[d1]);
219}
220} // namespace std
221
222
223
224#endif
Gauge field class.
Definition gaugefield.h:23
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
Plaquette field class.
PlaquetteField & operator=(const A &val)
Assign from anything the field allows.
PlaquetteField & operator=(std::nullptr_t np)
Separate 0 assignment.
void config_write(const std::string &filename) const
config_write writes the gauge field to file, with additional "verifying" header
VectorField< T > & operator[](Direction d1)
Access components with [].
~PlaquetteField()=default
Destructor.
#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
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)