v2DM-DOCI  1.0
doci_bp.cpp
Go to the documentation of this file.
1 /*
2  * @BEGIN LICENSE
3  *
4  * Copyright (C) 2014-2015 Ward Poelmans
5  *
6  * This file is part of v2DM-DOCI.
7  *
8  * v2DM-DOCI is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * Foobar is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
20  *
21  * @END LICENSE
22  */
23 
24 #include <iostream>
25 #include <fstream>
26 #include <cstring>
27 #include <getopt.h>
28 #include <signal.h>
29 
30 #include "include.h"
31 #include "BoundaryPoint.h"
32 #include "LocalMinimizer.h"
33 
34 // from CheMPS2
35 #include "Hamiltonian.h"
36 #include "OptIndex.h"
37 
38 // if set, the signal has been given to stop the calculation and write current step to file
39 sig_atomic_t stopping = 0;
40 sig_atomic_t stopping_min = 0;
41 
42 void stopcalcsignal(int sig);
43 void stopminsignal(int sig);
44 
45 int main(int argc,char **argv)
46 {
47  using std::cout;
48  using std::endl;
49  using namespace doci2DM;
51 
52  cout.precision(10);
53 
54  std::string integralsfile = "mo-integrals.h5";
55  std::string unitary;
56  std::string rdmfile;
57  bool random = false;
58  bool localmini = false;
59  bool scan = false;
60  bool localmininoopt = false;
61 
62  struct option long_options[] =
63  {
64  {"integrals", required_argument, 0, 'i'},
65  {"unitary", required_argument, 0, 'u'},
66  {"rdm", required_argument, 0, 'd'},
67  {"random", no_argument, 0, 'r'},
68  {"scan", no_argument, 0, 's'},
69  {"local-minimizer", no_argument, 0, 'l'},
70  {"local-minimizer-no-opt", no_argument, 0, 'n'},
71  {"help", no_argument, 0, 'h'},
72  {0, 0, 0, 0}
73  };
74 
75  int i,j;
76 
77  while( (j = getopt_long (argc, argv, "d:rlhi:u:sn", long_options, &i)) != -1)
78  switch(j)
79  {
80  case 'h':
81  case '?':
82  cout << "Usage: " << argv[0] << " [OPTIONS]\n"
83  "\n"
84  " -i, --integrals=integrals-file Set the input integrals file\n"
85  " -d, --rdm=rdm-file Use this rdm as starting point\n"
86  " -u, --unitary=unitary-file Use the unitary matrix in this file\n"
87  " -r, --random Perform a random unitary transformation on the Hamiltonian\n"
88  " -l, --local-minimizer Use the local minimizer\n"
89  " -n, --local-minimizer-no-opt Use the local minimizer without optimalization\n"
90  " -h, --help Display this help\n"
91  "\n";
92  return 0;
93  break;
94  case 'i':
95  integralsfile = optarg;
96  break;
97  case 'u':
98  unitary = optarg;
99  break;
100  case 'd':
101  rdmfile = optarg;
102  break;
103  case 'r':
104  random = true;
105  break;
106  case 'l':
107  localmini = true;
108  break;
109  case 's':
110  scan = true;
111  break;
112  case 'n':
113  localmininoopt = true;
114  break;
115  }
116 
117  cout << "Reading: " << integralsfile << endl;
118 
119  // make sure we have a save path, even if it's not specify already
120  // This will not overwrite an already set SAVE_H5_PATH
121  setenv("SAVE_H5_PATH", "./", 0);
122 
123  cout << "Using save path: " << getenv("SAVE_H5_PATH") << endl;
124 
125  auto ham = CheMPS2::Hamiltonian::CreateFromH5(integralsfile);
126 
127  const auto L = ham.getL(); //dim sp hilbert space
128  const auto N = ham.getNe(); //nr of particles
129 
130  cout << "Starting with L=" << L << " N=" << N << endl;
131 
132  if(!unitary.empty() && !localmini)
133  {
134  cout << "Reading transform: " << unitary << endl;
135 
136  simanneal::OrbitalTransform orbtrans(ham);
137 
138  orbtrans.get_unitary().loadU(unitary);
139  orbtrans.fillHamCI(ham);
140  }
141 
142  const simanneal::OptIndex opt(ham);
143 
144  if(random)
145  {
147  X.fill_random();
149  X.print_unitary();
150  simanneal::OrbitalTransform orbtrans(ham);
151  orbtrans.update_unitary(X, false);
152  std::string filename = getenv("SAVE_H5_PATH");
153  filename += "/random-start-unitary.h5";
154  orbtrans.get_unitary().saveU(filename);
155  orbtrans.fillHamCI(ham);
156  }
157 
158 
159  BoundaryPoint method(ham);
160  method.set_tol_PD(1e-7);
161 // method.getLineq() = Lineq(L,N,true);
162 
163  char *X_env = getenv("v2DM_DOCI_SUP_X");
164  if(X_env && strlen(X_env) > 0)
165  {
166  cout << "Reading X from " << X_env << endl;
167  method.getX().ReadFromFile(X_env);
168  }
169 
170  char *Z_env = getenv("v2DM_DOCI_SUP_Z");
171  if(Z_env && strlen(Z_env) > 0)
172  {
173  cout << "Reading Z from " << Z_env << endl;
174  method.getZ().ReadFromFile(Z_env);
175  }
176 
177  // set up everything to handle SIGALRM
178  struct sigaction act;
179  act.sa_flags = 0;
180  act.sa_handler = &stopcalcsignal;
181 
182  sigset_t blockset;
183  sigemptyset(&blockset); // we don't block anything in the handler
184  act.sa_mask = blockset;
185 
186  sigaction(SIGALRM, &act, 0);
187 
188  act.sa_handler = &stopminsignal;
189 
190  sigaction(SIGUSR1, &act, 0);
191 
192  if(!rdmfile.empty())
193  {
194  cout << "Reading rdm: " << rdmfile << endl;
195  method.getRDM().ReadFromFile(rdmfile);
196  }
197 
198  if(localmini)
199  {
200  LocalMinimizer minimize(ham);
201 
202  if(!unitary.empty())
203  {
204  cout << "Starting local minimizer from: " << unitary << endl;
205  minimize.getOrbitalTf().get_unitary().loadU(unitary);
206  }
207 
208  minimize.UseBoundaryPoint();
209  minimize.getMethod_BP().getX() = method.getX();
210  minimize.getMethod_BP().getZ() = method.getZ();
211  minimize.getMethod_BP().set_use_prev_result(true);
212  minimize.getMethod_BP().set_tol_PD(1e-7);
213 // minimize.getMethod_BP().getLineq() = Lineq(L,N,true);
214  minimize.set_conv_steps(10);
215 // minimize.getMethod_BP().set_max_iter(5);
216 
217  minimize.set_conv_crit(1e-6);
218 
219  if(localmininoopt)
220  minimize.Minimize_noOpt(1e-2);
221  else
222  minimize.Minimize();
223 
224  cout << "Bottom is " << minimize.get_energy() << endl;
225 
226  method = minimize.getMethod_BP();
227  ham = minimize.getHam();
228  }
229 
230  method.set_use_prev_result(false);
231  method.Reset_avg_iters();
232  method.Run();
233 
234  cout << "The optimal energy is " << method.evalEnergy() << std::endl;
235 
236  if(scan)
237  Tools::scan_all_bp(method.getRDM(), ham);
238 
239 
240 
241 /* // for(int k_in=0;k_in<L;k_in++)
242  * // for(int l_in=k_in+1;l_in<L;l_in++)
243  * int k_in = 2;
244  * int l_in = 3;
245  * if(ham.getOrbitalIrrep(k_in) == ham.getOrbitalIrrep(l_in))
246  * {
247  * std::fstream fs;
248  * std::string filename = "orbs-scan-" + std::to_string(k_in) + "-" + std::to_string(l_in) + ".txt";
249  * fs.open(filename, std::fstream::out | std::fstream::trunc);
250  *
251  * fs.precision(10);
252  *
253  * fs << "# theta\trot\trot+v2dm" << endl;
254  *
255  * auto found = rdm.find_min_angle(k_in,l_in,0.3,getT3,getV3);
256  *
257  * cout << "Min:\t" << k_in << "\t" << l_in << "\t" << found.first << "\t" << found.second << endl;
258  *
259  * cout << "######################" << endl;
260  *
261  * int Na = 200;
262  * #pragma omp parallel for
263  * for(int a=0;a<=Na;a++)
264  * {
265  * double theta = 2.0*M_PI/(1.0*Na) * a;
266  *
267  * BoundaryPoint mymethod(ham);
268  *
269  * mymethod.getRDM() = orig_rdm;
270  * mymethod.getHam() = orig_ham;
271  * mymethod.getHam().rotate(k_in, l_in, theta, getT3, getV3);
272  *
273  * simanneal::OrbitalTransform orbtrans2(ham2);
274  * orbtrans2.DoJacobiRotation(ham, k_in, l_in, theta);
275  * orbtrans2.get_unitary().jacobi_rotation(ham2.getOrbitalIrrep(k_in), k_in, l_in, theta);
276  * //orbtrans2.fillHamCI(ham);
277  *
278  * mymethod.BuildHam(new_ham);
279  *
280  * double new_en = orig_rdm.ddot(mymethod.getHam());
281  *
282  * mymethod.Run();
283  *
284  * #pragma omp critical
285  * fs << theta << "\t" << new_en << "\t" << mymethod.getEnergy() << endl;
286  * }
287  * fs.close();
288  * }
289  */
290 
291 
292  std::string h5_name = getenv("SAVE_H5_PATH");
293  h5_name += "/optimal-rdm.h5";
294 
295  method.getRDM().WriteToFile(h5_name);
296 
297  h5_name = getenv("SAVE_H5_PATH");
298  h5_name += "/optimal-ham.h5";
299 
300  ham.save2(h5_name);
301 
302  return 0;
303 }
304 
305 void stopcalcsignal(int sig)
306 {
307  stopping=1;
308 }
309 
310 void stopminsignal(int sig)
311 {
312  stopping_min=1;
313 }
314 
315 /* vim: set ts=3 sw=3 expandtab :*/
void ReadFromFile(std::string filename)
Definition: TPM.cpp:442
static Hamiltonian CreateFromH5(const string filename)
sig_atomic_t stopping_min
Definition: doci_bp.cpp:40
sig_atomic_t stopping
Definition: doci_bp.cpp:39
void update_unitary(double *step)
void fillHamCI(CheMPS2::Hamiltonian &HamCI)
int main(int argc, char **argv)
Definition: doci_bp.cpp:45
void stopcalcsignal(int sig)
Definition: doci_bp.cpp:305
static void scan_all_bp(const TPM &rdm, const CheMPS2::Hamiltonian &ham)
Definition: Tools.cpp:160
double evalEnergy() const
UnitaryMatrix & get_unitary()
void WriteToFile(hid_t &group_id) const
Definition: TPM.cpp:304
void stopminsignal(int sig)
Definition: doci_bp.cpp:310
void ReadFromFile(std::string filename)
Definition: SUP.cpp:412