HubbardGPU
Hubbard diagonalisation on the GPU (and CPU)
 All Classes Files Functions Variables Typedefs Friends Macros
hamsparse2D.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 "hamsparse2D.h"
23 
33 SparseHamiltonian2D::SparseHamiltonian2D(int L,int D, int Nu, int Nd, double J, double U)
34  : SparseHamiltonian2D_CSR(L,D,Nu,Nd,J,U)
35 {
36  Up_data = 0;
37  Down_data = 0;
38 
39  Up_ind = 0;
40  Down_ind = 0;
41 
42  size_Up = 0;
43  size_Down = 0;
44 }
45 
50 {
51  if(Up_data)
52  delete [] Up_data;
53 
54  if(Down_data)
55  delete [] Down_data;
56 
57  if(Up_ind)
58  delete [] Up_ind;
59 
60  if(Down_ind)
61  delete [] Down_ind;
62 }
63 
68 {
70 
71  unsigned int NumUp = baseUp.size();
72  unsigned int NumDown = baseDown.size();
73 
74  unsigned int max = 0;
75  for(unsigned int i=0;i<NumUp;i++)
76  if( (Up_row[i+1]-Up_row[i]) > max )
77  max = Up_row[i+1]-Up_row[i];
78 
79  size_Up = max;
80 
81  max = 0;
82  for(unsigned int i=0;i<NumDown;i++)
83  if( (Down_row[i+1]-Down_row[i]) > max )
84  max = Down_row[i+1]-Down_row[i];
85 
86  size_Down = max;
87 
88  Up_data = new double [NumUp*size_Up];
89  Up_ind = new unsigned int [NumUp*size_Up];
90 
91  Down_data = new double [NumDown*size_Down];
92  Down_ind = new unsigned int [NumDown*size_Down];
93 
94  std::cout << "Sizes: " << size_Up << "\t" << size_Down << std::endl;
95 
96  for(unsigned int a=0;a<NumUp;a++)
97  {
98  int count = 0;
99 
100  for(unsigned int b=Up_row[a];b<Up_row[a+1];b++)
101  {
102  Up_data[a+count*NumUp] = Up_data_CSR[b];
103  Up_ind[a+count*NumUp] = Up_col[b];
104  count++;
105  }
106 
107  if(count < size_Up)
108  for(int i=count;i<size_Up;i++)
109  {
110  Up_data[a+i*NumUp] = 0;
111  Up_ind[a+i*NumUp] = 0;
112  }
113  else if(count > size_Up)
114  std::cerr << "Something went terribly wrong!" << std::endl;
115  }
116 
117  for(unsigned int a=0;a<NumDown;a++)
118  {
119  int count = 0;
120 
121  for(unsigned int b=Down_row[a];b<Down_row[a+1];b++)
122  {
123  Down_data[a+count*NumDown] = Down_data_CSR[b];
124  Down_ind[a+count*NumDown] = Down_col[b];
125  count++;
126  }
127 
128  if(count < size_Down)
129  for(int i=count;i<size_Down;i++)
130  {
131  Down_data[a+i*NumDown] = 0;
132  Down_ind[a+i*NumDown] = 0;
133  }
134  else if(count > size_Down)
135  std::cerr << "Something went terribly wrong!" << std::endl;
136  }
137 }
138 
143 {
144  unsigned int NumUp = baseUp.size();
145  unsigned int NumDown = baseDown.size();
146 
147  std::cout << "Up:" << std::endl;
148 
149  for(unsigned int i=0;i<NumUp;i++)
150  {
151  int count = 0;
152 
153  for(unsigned int j=0;j<NumUp;j++)
154  if(count < size_Up && Up_ind[i+count*NumUp] == j)
155  std::cout << Up_data[i + NumUp*count++] << "\t";
156  else
157  std::cout << "0\t";
158 
159  std::cout << std::endl;
160  }
161 
162  std::cout << "Down:" << std::endl;
163 
164  for(unsigned int i=0;i<NumDown;i++)
165  {
166  int count = 0;
167 
168  for(unsigned int j=0;j<NumDown;j++)
169  if(count < size_Down && Down_ind[i + count*NumDown] == j)
170  std::cout << Down_data[i + NumDown*count++] << "\t";
171  else
172  std::cout << "0\t";
173 
174  std::cout << std::endl;
175  }
176 }
177 
179 {
180  unsigned int NumUp = baseUp.size();
181  unsigned int NumDown = baseDown.size();
182 
183  std::cout << "Up:" << std::endl;
184 
185  std::cout << "Data:" << std::endl;
186  for(unsigned int i=0;i<NumUp;i++)
187  {
188  for(int j=0;j<size_Up;j++)
189  std::cout << Up_data[i+j*NumUp] << "\t";
190 
191  std::cout << std::endl;
192  }
193 
194  std::cout << "Indices:" << std::endl;
195  for(unsigned int i=0;i<NumUp;i++)
196  {
197  for(int j=0;j<size_Up;j++)
198  std::cout << Up_ind[i+j*NumUp] << "\t";
199 
200  std::cout << std::endl;
201  }
202 
203  std::cout << "Down:" << std::endl;
204 
205  std::cout << "Data:" << std::endl;
206  for(unsigned int i=0;i<NumDown;i++)
207  {
208  for(int j=0;j<size_Down;j++)
209  std::cout << Down_data[i+j*NumDown] << "\t";
210 
211  std::cout << std::endl;
212  }
213 
214  std::cout << "Indices:" << std::endl;
215  for(unsigned int i=0;i<NumDown;i++)
216  {
217  for(int j=0;j<size_Down;j++)
218  std::cout << Down_ind[i+j*NumDown] << "\t";
219 
220  std::cout << std::endl;
221  }
222 }
223 
230 void SparseHamiltonian2D::mvprod(double *x, double *y, double alpha) const
231 {
232  int NumUp = baseUp.size();
233  int NumDown = baseDown.size();
234 
235  int incx = 1;
236 
237  for(int i=0;i<NumUp;i++)
238  {
239 #pragma omp parallel for
240  for(int k=0;k<NumDown;k++)
241  {
242  // the interaction part
243  y[i*NumDown+k] = alpha*y[i*NumDown+k] + U * CountBits(baseUp[i] & baseDown[k]) * x[i*NumDown+k];
244 
245  // the Hop_down part
246  for(int l=0;l<size_Down;l++)
247  y[i*NumDown+k] += Down_data[k+l*NumDown] * x[i*NumDown + Down_ind[k+l*NumDown]];
248  }
249 
250  // the Hop_Up part
251  for(int l=0;l<size_Up;l++)
252  daxpy_(&NumDown,&Up_data[i+l*NumUp],&x[Up_ind[i+l*NumUp]*NumDown],&incx,&y[i*NumDown],&incx);
253  }
254 }
255 
256 /* vim: set ts=8 sw=4 tw=0 expandtab :*/