LatticeYangMills
lattice.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 *
3 * MIT License
4 *
5 * Copyright (c) 2018 Giovanni Pederiva
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 ******************************************************************************/
25 
34 #include "Utils/clusterspecifier.h"
35 #ifndef LACONIA
36 #include <mpi/mpi.h>
37 #else
38 #include <mpi.h>
39 #endif
40 #include "Math/lattice.h"
41 #include "Math/point.h"
42 #include "Math/su3.h"
43 #include "ParallelTools/parallel.h"
44 #include "Math/random.h"
45 #include <cstdio>
46 
51  for(int i = 0; i < su3lat.sites; i++){
52  su3lat.lattice.at(i).setSU3Zero();
53  su3lat.lattice.at(i).mat[1]= lat.at(i);
54  su3lat.lattice.at(i).mat[9]= lat.at(i);
55  su3lat.lattice.at(i).mat[17]= lat.at(i);
56  }
57 }
58 
60  for(int i = 0; i < su3lat.sites; i++){
61  su3lat.lattice.at(i).setSU3Zero();
62  su3lat.lattice.at(i).mat[1]= lat.at(i);
63  su3lat.lattice.at(i).mat[9]= lat.at(i);
64  su3lat.lattice.at(i).mat[17]= lat.at(i);
65  }
66 }
67 
71 void setToZero(Lattice<SU3> &su3lat){
72  for(int i = 0; i < su3lat.sites; i++)
73  su3lat.lattice.at(i).setSU3Zero();
74 }
75 
80  for(int i = 0; i < su3lat.sites; i++)
81  su3lat.lattice.at(i).setSU3Identity();
82 }
83 
84 
88 void Lattice::setToRandom(){
89  for(int x = 0; x < size[0]; x++){
90  for(int y = 0; y < size[1]; y++){
91  for(int z = 0; z < size[2]; z++){
92  for(int t = 0; t < size[3]; t++){
93  for(int mu = 0; mu < 4; mu++){
94  lattice[x][y][z][t][mu] = Random::randSU3();
95  }
96  }}}}
97 }
98 
99 
103 void Lattice::setToUnity(){
104  for(int x = 0; x < size[0]; x++){
105  for(int y = 0; y < size[1]; y++){
106  for(int z = 0; z < size[2]; z++){
107  for(int t = 0; t < size[3]; t++){
108  for(int mu = 0; mu < 4; mu++){
109  lattice[x][y][z][t][mu].setSU3Identity();
110  }
111  }}}}
112 }
113 
114 
120 SU3 Lattice::shift(int x, int y, int z, int t, int mu, int shiftDir, int shiftSign){
121  std::vector<int> idx = {x,y,z,t};
122  int mpiShifts = 0, mpiShiftDir = -1, mpiShiftSign;
123 
124  // set the index for the new link and compute the MPI calls to perform
125  for(int i = 0; i < 4; i++){
126  if(shiftDir == i) idx[i] += shiftSign;
127 
128  if(idx[i] == -1) {
129  mpiShifts++;
130  mpiShiftDir = i;
131  }
132  if(idx[i] == size[i]){
133  mpiShifts++;
134  mpiShiftDir = i;
135  }
136  }
137 
138  // if there is no MPI call
139  if(mpiShifts == 0) return lattice[idx[0]][idx[1]][idx[2]][idx[3]][mu];
140 
141  // create return link
142  SU3 msg;
143 
144  // if only one MPI call is needed
145  if(mpiShifts == 1){
146  std::vector<int> sendIdx = {x,y,z,t};
147  for(int i = 0; i < 4; i++){
148  if(mpiShiftDir == i && idx[i] == -1){
149  sendIdx[i] = size[i]-1;
150  mpiShiftSign = 1;
151  }
152  else if(mpiShiftDir == i && idx[i] == size[i]){
153  sendIdx[i] = 0;
154  mpiShiftSign = 0;
155  }
156  else
157  sendIdx[i] = idx[i];
158 
159  }
160  MPI_Sendrecv(lattice[sendIdx[0]][sendIdx[1]][sendIdx[2]][sendIdx[3]][mu].mat.data(), 18, MPI_DOUBLE, Parallel::getNeighbor(mpiShiftDir, mpiShiftSign), 0,
161  msg.mat.data(), 18, MPI_DOUBLE, Parallel::getNeighbor(mpiShiftDir, abs(mpiShiftSign-1)), 0,
162  MPI_COMM_WORLD, MPI_STATUS_IGNORE);
163  return std::move(msg);
164  }
165 }
166 
174 SU3 Lattice::shift2(int x, int y, int z, int t, int mu, int shiftDir, int shiftSign, int shiftDir2, int shiftSign2){
175  std::vector<int> idx = {x,y,z,t};
176  int mpiShifts = 0, mpiShiftDir = -1, mpiShiftDir2, mpiShiftSign, mpiShiftSign2;
177 
178  // set the index for the new link and compute the MPI calls to perform
179  for(int i = 0; i < 4; i++){
180  if(shiftDir == i) idx[i] += shiftSign;
181  if(shiftDir2 == i) idx[i] += shiftSign2;
182 
183  if(idx[i] == -1) {
184  mpiShifts++;
185  if(mpiShiftDir == -1) mpiShiftDir = i;
186  else mpiShiftDir2 = i;
187  }
188  if(idx[i] == size[i]){
189  mpiShifts++;
190  if(mpiShiftDir == -1) mpiShiftDir = i;
191  else mpiShiftDir2 = i;
192  }
193  }
194 
195  // if there is no MPI call
196  if(mpiShifts == 0) return lattice[idx[0]][idx[1]][idx[2]][idx[3]][mu];
197 
198  // create return link
199  SU3 msg;
200 
201  // if only one MPI call is needed
202  if(mpiShifts == 1){
203  std::vector<int> sendIdx = {x,y,z,t};
204  for(int i = 0; i < 4; i++){
205  if(mpiShiftDir == i && idx[i] == -1){
206  sendIdx[i] = size[i]-1;
207  mpiShiftSign = 1;
208  }
209  else if(mpiShiftDir == i && idx[i] == size[i]){
210  sendIdx[i] = 0;
211  mpiShiftSign = 0;
212  }
213  else
214  sendIdx[i] = idx[i];
215 
216  }
217  MPI_Sendrecv(lattice[sendIdx[0]][sendIdx[1]][sendIdx[2]][sendIdx[3]][mu].mat.data(), 18, MPI_DOUBLE, Parallel::getNeighbor(mpiShiftDir, mpiShiftSign), 0,
218  msg.mat.data(), 18, MPI_DOUBLE, Parallel::getNeighbor(mpiShiftDir, abs(mpiShiftSign-1)), 0,
219  MPI_COMM_WORLD, MPI_STATUS_IGNORE);
220  return std::move(msg);
221  }
222 
223  if(mpiShifts == 2){
224 
225  // first shift
226  std::vector<int> sendIdx = {x,y,z,t};
227  for(int i = 0; i < 4; i++){
228  if(mpiShiftDir == i && idx[i] == -1){
229  sendIdx[i] = size[i]-1;
230  mpiShiftSign = 1;
231  }
232  else if(mpiShiftDir == i && idx[i] == size[i]){
233  sendIdx[i] = 0;
234  mpiShiftSign = 0;
235  }
236  else if(mpiShiftDir2 == i && idx[i] == -1){
237  sendIdx[i] = size[i]-1;
238  mpiShiftSign2 = 1;
239  }
240  else if(mpiShiftDir2 == i && idx[i] == size[i]){
241  sendIdx[i] = 0;
242  mpiShiftSign2 = 0;
243  }
244  else
245  sendIdx[i] = idx[i];
246  }
247  MPI_Sendrecv(lattice[sendIdx[0]][sendIdx[1]][sendIdx[2]][sendIdx[3]][mu].mat.data(), 18, MPI_DOUBLE,
248  Parallel::getSecondNeighbor(mpiShiftDir, mpiShiftSign, mpiShiftDir2, mpiShiftSign2), 0,
249  msg.mat.data(), 18, MPI_DOUBLE, Parallel::getSecondNeighbor(mpiShiftDir, abs(mpiShiftSign-1), mpiShiftDir2, abs(mpiShiftSign2-1)), 0,
250  MPI_COMM_WORLD, MPI_STATUS_IGNORE);
251  return std::move(msg);
252  }
253 }
254 
255 
256 
static SU3 randSU3()
returns random SU3 matrix, by choosing 2 random complex vectors as the first two columns, orthogonalizing them and taking the outer product as a third column
Definition: random.cpp:54
Contains the definition of the Lattice class.
Implementation of a class to perform arithmetics between links.
Definition: su3.h:53
void setToIdentity(Lattice< SU3 > &su3lat)
sets a lattice object to all identity matrices
Definition: lattice.cpp:79
Utilities for parallelization.
Basic library to implement SU3 matrix arithmetics and functions.
void setToZero(Lattice< SU3 > &su3lat)
sets a lattice object to all zero matrices
Definition: lattice.cpp:71
void setLatticeImagIdentityValue(Lattice< SU3 > &su3lat, const Lattice< double > &lat)
sets a lattice object to only diagonal matrices with complex values
Definition: lattice.cpp:50
static int getSecondNeighbor(int direction1, int sign1, int direction2, int sign2)
return the rank of the neighbor along the two given directions and signs
Definition: parallel.cpp:210
static int getNeighbor(int direction, int sign)
return the rank of the neighbor along the given direction and sign
Definition: parallel.cpp:203
Contains the definition of the Random class.