HubbardGPU
Hubbard diagonalisation on the GPU (and CPU)
 All Classes Files Functions Variables Typedefs Friends Macros
ham2D.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2012 Ward Poelmans
2 
3 This file is part of Hubbard-GPU.
4 
5 Hubbard-GPU is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 Hubbard-GPU is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with Hubbard-GPU. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <iostream>
20 #include "ham2D.h"
21 
31 HubHam2D::HubHam2D(int L, int D, int Nu, int Nd, double J, double U)
32  : Hamiltonian(L*D,Nu,Nd,J,U)
33 {
34  this->L = L;
35  this->D = D;
36 }
37 
42 {
43 }
44 
54 int HubHam2D::hopping(myint a, myint b, int jump) const
55 {
56  int result(0), sign;
57 
58  for(int i=0;i<L;i++)
59  if( a & 1<<i ) // is the i'th bit set?
60  {
61  int j;
62 
63  // jump up
64  j = (i + L) % L;
65  if( (~a & 1<<j) && ((a ^ ((1<<i)+(1<<j)) ) == b ) )
66  {
67  if(j>i)
68  sign = CalcSign(i,j,a);
69  else
70  sign = CalcSign(j,i,a);
71 
72  // a minus sign in the hamiltonian ( -J *)
73  result = -1 * sign;
74  break;
75  }
76 
77  // jump down
78  j = (i - L + L) % L;
79  if( (~a & 1<<j) && ((a ^ ((1<<i)+(1<<j)) ) == b ) )
80  {
81  if(j>i)
82  sign = CalcSign(i,j,a);
83  else
84  sign = CalcSign(j,i,a);
85 
86  result = -1 * sign;
87  break;
88  }
89 
90  // jump right
91  j = L * (i/L) + (i + 1) % L;
92  if( (~a & 1<<j) && ((a ^ ((1<<i)+(1<<j)) ) == b ) )
93  {
94  if(j>i)
95  sign = CalcSign(i,j,a);
96  else
97  sign = CalcSign(j,i,a);
98 
99  result = -1 * sign;
100  break;
101  }
102 
103  // jump left
104  j = L * (i/L) + (i - 1 + L) % L;
105  if( (~a & 1<<j) && ((a ^ ((1<<i)+(1<<j)) ) == b ) )
106  {
107  if(j>i)
108  sign = CalcSign(i,j,a);
109  else
110  sign = CalcSign(j,i,a);
111 
112  result = -1 * sign;
113  break;
114  }
115  }
116 
117  return result;
118 }
119 
124 {
125  if( !baseUp.size() || !baseDown.size() )
126  {
127  std::cerr << "Build base before building Hamiltonian" << std::endl;
128  return;
129  }
130 
131  ham = new double[dim*dim];
132 
133  int NumDown = CalcDim(L,Nd);
134 
135  for(unsigned int a=0;a<baseUp.size();a++)
136  for(unsigned int b=0;b<baseDown.size();b++)
137  {
138  int i = a * NumDown + b;
139 
140  for(unsigned int c=a;c<baseUp.size();c++)
141  for(unsigned int d=0;d<baseDown.size();d++)
142  {
143  int j = c * NumDown + d;
144 
145  ham[j+dim*i] = 0;
146 
147  if(b == d)
148  ham[j+dim*i] += J * hopping(baseUp[a], baseUp[c]);
149 
150  if(a == c)
151  ham[j+dim*i] += J * hopping(baseDown[b], baseDown[d]);
152 
153  ham[i+dim*j] = ham[j+dim*i];
154  }
155 
156  // count number of double occupied states
157  ham[i+dim*i] = U * CountBits(baseUp[a] & baseDown[b]);
158  }
159 }
160 
161 /* vim: set ts=8 sw=4 tw=0 expandtab :*/