HubbardGPU
Hubbard diagonalisation on the GPU (and CPU)
 All Classes Files Functions Variables Typedefs Friends Macros
main.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2012-2014 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 <algorithm>
21 #include <memory>
22 #include <sstream>
23 #include <boost/timer.hpp>
24 #include <getopt.h>
25 #include "ham.h"
26 #include "hamsparse.h"
27 #include "ham-mom.h"
28 #include "nonp-ham.h"
29 #include "ham-spin.h"
30 
31 using namespace std;
32 
33 int main(int argc, char **argv)
34 {
35  int L = 4; // number of sites
36  int Nu = 2; // number of up electrons
37  int Nd = 3; // number of down electrons
38  double J = 1.0; // hopping term
39  double U = 1.0; // on-site interaction strength
40  int whichS = -1;
41 
42  bool exact = false;
43  bool lanczos = false;
44  bool momentum = false;
45  bool nonperiodic = false;
46  bool spin = false;
47 
48  struct option long_options[] =
49  {
50  {"up", required_argument, 0, 'u'},
51  {"down", required_argument, 0, 'd'},
52  {"sites", required_argument, 0, 's'},
53  {"interaction", required_argument, 0, 'U'},
54  {"hopping", required_argument, 0, 'J'},
55  {"exact", no_argument, 0, 'e'},
56  {"lanczos", no_argument, 0, 'l'},
57  {"momentum", no_argument, 0, 'p'},
58  {"nonperiodic", no_argument, 0, 'n'},
59  {"symspin", no_argument, 0, 'z'},
60  {"spin", required_argument, 0, 'S'},
61  {"help", no_argument, 0, 'h'},
62  {0, 0, 0, 0}
63  };
64 
65  int i,j;
66  while( (j = getopt_long (argc, argv, "hu:d:s:U:J:elpnzS:", long_options, &i)) != -1)
67  switch(j)
68  {
69  case 'h':
70  case '?':
71  cout << "Usage: " << argv[0] << " [OPTIONS]\n"
72  "\n"
73  " -s --sites=L The number of sites\n"
74  " -u --up=Nu The number of up electrons\n"
75  " -d --down=Nd The number of down electrons\n"
76  " -U --interaction=U The onsite interaction strength\n"
77  " -J --hopping=J The hopping strength\n"
78  " -e --exact Solve with exact diagonalisation\n"
79  " -l --lanczos Solve with Lanczos algorithm\n"
80  " -p --momentum Solve in the momentum basis\n"
81  " -n --nonperiodic Use non periodic boundary conditions\n"
82  " -z --symspin Use spin symmetry\n"
83  " -S --spin=S Limit to spin=S\n"
84  " -h, --help Display this help\n"
85  "\n";
86  return 0;
87  break;
88  case 'u':
89  Nu = atoi(optarg);
90  break;
91  case 'd':
92  Nd = atoi(optarg);
93  break;
94  case 's':
95  L = atoi(optarg);
96  break;
97  case 'U':
98  U = atof(optarg);
99  break;
100  case 'J':
101  J = atof(optarg);
102  break;
103  case 'l':
104  lanczos = true;
105  break;
106  case 'p':
107  momentum = true;
108  break;
109  case 'n':
110  nonperiodic = true;
111  break;
112  case 'z':
113  spin = true;
114  break;
115  case 'S':
116  whichS = atoi(optarg);
117  break;
118  case 'e':
119  exact = true;
120  break;
121  }
122 
123  cout << "L = " << L << "; Nu = " << Nu << "; Nd = " << Nd << "; J = " << J << "; U = " << U << ";" << endl;
124 
125  if(whichS!=-1)
126  cout << "Limiting to S=" << whichS << endl;
127 
128  if(whichS!=-1 && !spin)
129  {
130  cerr << "Need to use spin symmetry to select a spin!" << endl;
131  return 1;
132  }
133 
134  if(momentum && nonperiodic)
135  {
136  cerr << "Cannot use non periodic boundary conditions in the momentum base" << endl;
137  return 0;
138  }
139 
140  cout.precision(10);
141 
142  boost::timer tijd;
143 
144 
145  if(exact)
146  {
147  tijd.restart();
148 
149  std::unique_ptr<BareHamiltonian> ham;
150 
151  if(spin)
152  ham.reset(new SpinHamiltonian(L,Nu,Nd,J,U));
153  else if(momentum)
154  ham.reset(new MomHamiltonian(L,Nu,Nd,J,U));
155  else if(nonperiodic)
156  ham.reset(new NonPeriodicHamiltonian(L,Nu,Nd,J,U));
157  else
158  ham.reset(new Hamiltonian(L,Nu,Nd,J,U));
159 
160  if(!spin)
161  {
162  cout << "Memory needed: " << ham->MemoryNeededFull()*1.0/1024*1.0/1024 << " MB" << endl;
163  cout << "Building base..." << endl;
164  ham->BuildBase();
165  cout << "Building hamiltonian..." << endl;
166  ham->BuildFullHam();
167  }
168 
169  cout << "Dim: " << ham->getDim() << endl;
170 
171  double Egroundstate = 0;
172 
173  if(spin)
174  {
175  auto hampje = static_cast<SpinHamiltonian *>(ham.get());
176 
177  hampje->BuildBase();
178  cout << "Building hamiltonian..." << endl;
179 
180  if(whichS!=-1)
181  hampje->BuildHamWithS(whichS);
182  else
183  hampje->BuildFullHam();
184 
185  auto E = hampje->ExactSpinDiagonalizeFull(false);
186  Egroundstate = std::get<2>(E[0]);
187 
188  cout << "K\tS\tE" << endl;
189  for(auto p : E)
190  cout << std::get<0>(p) << "\t" << std::get<1>(p) << "\t" << std::get<2>(p) << endl;
191 
192 // hampje->GenerateData(0,20,0.1,"data-S-6-3-3.h5");
193  }
194  else if(momentum)
195  {
196  auto E = (static_cast<MomHamiltonian *>(ham.get()))->ExactMomDiagonalizeFull(false);
197 
198  cout << "Energy levels: " << endl;
199  for(auto p : E)
200  cout << p.second << "\t" << p.first << endl;
201 
202  Egroundstate = E[0].second;
203 
204 // (static_cast<MomHamiltonian *>(ham.get()))->GenerateData(0,10,1,"data-test.h5");
205  }
206  else
207  {
208  auto E = ham->ExactDiagonalizeFull(true);
209  stringstream name;
210  name << "results-" << L << "-" << Nu << "-" << Nd << "-" << U << ".h5";
211  ham->SaveToFile(name.str());
212 
213  ham->PrintGroundstateVector();
214  cout << "Energy levels: " << endl;
215  for(auto p : E)
216  cout << p << endl;
217 
218  Egroundstate = E[0];
219  }
220 
221  cout << endl;
222  cout << "lowest E = " << Egroundstate << endl;
223 
224  cout << "Time: " << tijd.elapsed() << " s" << endl;
225  }
226 
227  if(lanczos)
228  {
229  tijd.restart();
230 
231  std::unique_ptr<BareHamiltonian> sham;
232 
233  if(nonperiodic)
234  sham.reset(new SparseHamiltonian<NonPeriodicHamiltonian>(L,Nu,Nd,J,U));
235  else
236  sham.reset(new SparseHamiltonian<Hamiltonian>(L,Nu,Nd,J,U));
237 
238  cout << "Memory needed: " << sham->MemoryNeededArpack()*1.0/1024*1.0/1024 << " MB" << endl;
239 
240  sham->BuildBase();
241  sham->BuildHam();
242 
243  cout << "Dim: " << sham->getDim() << endl;
244 
245  double E = sham->arpackDiagonalize();
246  cout << "E = " << E << endl;
247 
248  cout << "Time: " << tijd.elapsed() << " s" << endl;
249  }
250 
251  return 0;
252 }
253 
254 /* vim: set ts=8 sw=4 tw=0 expandtab :*/