HubbardGPU
Hubbard diagonalisation on the GPU (and CPU)
 All Classes Files Functions Variables Typedefs Friends Macros
ham.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 <cstdlib>
21 #include <cmath>
22 #include "ham.h"
23 
32 Hamiltonian::Hamiltonian(int L, int Nu, int Nd, double J, double U) : BareHamiltonian(L,Nu,Nd,J,U)
33 {
34 }
35 
40 {
41 }
42 
47 {
48  if( !baseUp.size() || !baseDown.size() )
49  {
50  std::cerr << "Build base before building Hamiltonian" << std::endl;
51  return;
52  }
53 
54  ham = new double[dim*dim];
55 
56  int NumDown = CalcDim(L,Nd);
57 
58  int upjumpsign, downjumpsign;
59 
60  if( Nu % 2 == 0)
61  upjumpsign = -1;
62  else
63  upjumpsign = 1;
64 
65  if( Nd % 2 == 0)
66  downjumpsign = -1;
67  else
68  downjumpsign = 1;
69 
70  for(unsigned int a=0;a<baseUp.size();a++)
71  for(unsigned int b=0;b<baseDown.size();b++)
72  {
73  int i = a * NumDown + b;
74 
75  for(unsigned int c=a;c<baseUp.size();c++)
76  for(unsigned int d=0;d<baseDown.size();d++)
77  {
78  int j = c * NumDown + d;
79 
80  ham[j+dim*i] = 0;
81 
82  if(b == d)
83  ham[j+dim*i] += J * hopping(baseUp[a], baseUp[c],upjumpsign);
84 
85  if(a == c)
86  ham[j+dim*i] += J * hopping(baseDown[b], baseDown[d],downjumpsign);
87 
88  ham[i+dim*j] = ham[j+dim*i];
89  }
90 
91  // count number of double occupied states
92  ham[i+dim*i] = U * CountBits(baseUp[a] & baseDown[b]);
93  }
94 }
95 
105 int Hamiltonian::hopping(myint a, myint b,int jumpsign) const
106 {
107  int result = 0;
108  int sign;
109  myint cur = a;
110  // move all electrons one site to the right
111  cur <<= 1;
112 
113  // periodic boundary condition
114  if( cur & Hb )
115  cur ^= Hb + 0x1; // flip highest bit and lowest bit
116 
117  // find places where a electron can jump into
118  cur &= ~a;
119 
120  while(cur)
121  {
122  // isolate the rightmost 1 bit
123  myint hop = cur & (~cur + 1);
124 
125  cur ^= hop;
126 
127  sign = 1;
128 
129  if(hop & 0x1)
130  {
131  hop += Hb>>1;
132  sign = jumpsign;
133  }
134  else
135  hop += hop>>1;
136 
137  if( (a ^ hop) == b )
138  {
139  result -= sign;
140  break;
141  }
142  }
143 
144  cur = a;
145  // move all electrons one site to the left
146  cur >>= 1;
147 
148  // periodic boundary condition
149  if( a & 0x1 )
150  cur ^= Hb>>1; // flip highest bit
151 
152  // find places where a electron can jump into
153  cur &= ~a;
154 
155  while(cur)
156  {
157  // isolate the rightmost 1 bit
158  myint hop = cur & (~cur + 1);
159 
160  cur ^= hop;
161 
162  sign = 1;
163 
164  if(hop & Hb>>1)
165  {
166  hop += 0x1;
167  sign = jumpsign;
168  }
169  else
170  hop += hop<<1;
171 
172  if( (a ^ hop) == b )
173  {
174  result -= sign;
175  break;
176  }
177  }
178 
179  return result;
180 }
181 
188 void Hamiltonian::mvprod(double *x, double *y, double alpha) const
189 {
190  double beta = 1;
191  int incx = 1;
192  char uplo = 'U';
193 
194  dsymv_(&uplo,&dim,&beta,ham,&dim,x,&incx,&alpha,y,&incx);
195 }
196 
197 /* vim: set ts=8 sw=4 tw=0 expandtab :*/