CheMPS2
executable.cpp
1 /*
2  CheMPS2: a spin-adapted implementation of DMRG for ab initio quantum chemistry
3  Copyright (C) 2013-2016 Sebastian Wouters
4 
5  This program 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 2 of the License, or
8  (at your option) any later version.
9 
10  This program 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 along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #include <iostream>
21 #include <fstream>
22 #include <algorithm>
23 #include <math.h>
24 #include <string.h>
25 #include <getopt.h>
26 #include <sys/stat.h>
27 
28 #include "Initialize.h"
29 #include "CASSCF.h"
30 #include "Molden.h"
31 #include "MPIchemps2.h"
32 #include "EdmistonRuedenberg.h"
33 
34 using namespace std;
35 
36 void fetch_ints( const string rawdata, int * result, const int num ){
37 
38  int pos = 0;
39  int pos2 = 0;
40  for ( int no = 0; no < num; no++ ){
41  pos2 = rawdata.find( ",", pos );
42  if ( pos2 == string::npos ){ pos2 = rawdata.length(); }
43  result[ no ] = atoi( rawdata.substr( pos, pos2-pos ).c_str() );
44  pos = pos2 + 1;
45  }
46 
47 }
48 
49 void fetch_doubles( const string rawdata, double * result, const int num ){
50 
51  int pos = 0;
52  int pos2 = 0;
53  for ( int no = 0; no < num; no++ ){
54  pos2 = rawdata.find( ",", pos );
55  if ( pos2 == string::npos ){ pos2 = rawdata.length(); }
56  result[ no ] = atof( rawdata.substr( pos, pos2-pos ).c_str() );
57  pos = pos2 + 1;
58  }
59 
60 }
61 
62 bool file_exists( const string filename, const string tag ){
63 
64  #ifdef CHEMPS2_MPI_COMPILATION
65  const bool am_i_master = ( CheMPS2::MPIchemps2::mpi_rank() == MPI_CHEMPS2_MASTER );
66  #else
67  const bool am_i_master = true;
68  #endif
69 
70  struct stat file_info;
71  const bool on_disk = (( filename.length() > 0 ) && ( stat( filename.c_str(), &file_info ) == 0 ));
72  if (( on_disk == false ) && ( am_i_master )){
73  cerr << "Unable to retrieve file " << filename << "!" << endl;
74  cerr << "Invalid option for " << tag << "!" << endl;
75  }
76  return on_disk;
77 
78 }
79 
80 bool find_integer( int * result, const string line, const string tag, const bool lower_bound, const int val_lower, const bool upper_bound, const int val_upper ){
81 
82  #ifdef CHEMPS2_MPI_COMPILATION
83  const bool am_i_master = ( CheMPS2::MPIchemps2::mpi_rank() == MPI_CHEMPS2_MASTER );
84  #else
85  const bool am_i_master = true;
86  #endif
87 
88  if ( line.find( tag ) != string::npos ){
89 
90  const int pos = line.find( "=" ) + 1;
91  result[ 0 ] = atoi( line.substr( pos, line.length() - pos ).c_str() );
92 
93  const bool lower_ok = (( lower_bound == false ) || ( result[ 0 ] >= val_lower ));
94  const bool upper_ok = (( upper_bound == false ) || ( result[ 0 ] <= val_upper ));
95 
96  if (( lower_ok == false ) || ( upper_ok == false )){
97  if ( am_i_master ){
98  cerr << line << endl;
99  cerr << "Invalid option for " << tag << "!" << endl;
100  }
101  return false;
102  }
103  }
104 
105  return true;
106 
107 }
108 
109 bool find_double( double * result, const string line, const string tag, const bool lower_bound, const double val_lower ){
110 
111  #ifdef CHEMPS2_MPI_COMPILATION
112  const bool am_i_master = ( CheMPS2::MPIchemps2::mpi_rank() == MPI_CHEMPS2_MASTER );
113  #else
114  const bool am_i_master = true;
115  #endif
116 
117  if ( line.find( tag ) != string::npos ){
118 
119  const int pos = line.find( "=" ) + 1;
120  result[ 0 ] = atof( line.substr( pos, line.length() - pos ).c_str() );
121 
122  const bool lower_ok = (( lower_bound == false ) || ( result[ 0 ] >= val_lower ));
123 
124  if ( lower_ok == false ){
125  if ( am_i_master ){
126  cerr << line << endl;
127  cerr << "Invalid option for " << tag << "!" << endl;
128  }
129  return false;
130  }
131  }
132 
133  return true;
134 
135 }
136 
137 bool find_character( char * result, const string line, const string tag, char * options, const int num_options ){
138 
139  #ifdef CHEMPS2_MPI_COMPILATION
140  const bool am_i_master = ( CheMPS2::MPIchemps2::mpi_rank() == MPI_CHEMPS2_MASTER );
141  #else
142  const bool am_i_master = true;
143  #endif
144 
145  if ( line.find( tag ) != string::npos ){
146 
147  const int pos = line.find( "=" ) + 1;
148  string temp = line.substr( pos, line.length() - pos );
149  temp.erase( std::remove( temp.begin(), temp.end(), ' ' ), temp.end() );
150  result[ 0 ] = temp.c_str()[ 0 ];
151 
152  bool encountered = false;
153  for ( int cnt = 0; cnt < num_options; cnt++ ){
154  if ( options[ cnt ] == result[ 0 ] ){ encountered = true; }
155  }
156 
157  if ( encountered == false ){
158  if ( am_i_master ){
159  cerr << line << endl;
160  cerr << "Invalid option for " << tag << "!" << endl;
161  }
162  return false;
163  }
164  }
165 
166  return true;
167 
168 }
169 
170 bool find_boolean( bool * result, const string line, const string tag ){
171 
172  #ifdef CHEMPS2_MPI_COMPILATION
173  const bool am_i_master = ( CheMPS2::MPIchemps2::mpi_rank() == MPI_CHEMPS2_MASTER );
174  #else
175  const bool am_i_master = true;
176  #endif
177 
178  if ( line.find( tag ) != string::npos ){
179 
180  const int pos = line.find( "=" ) + 1;
181  const int pos_true = line.substr( pos, line.length() - pos ).find( "TRUE" );
182  const int pos_false = line.substr( pos, line.length() - pos ).find( "FALSE" );
183  result[ 0 ] = ( pos_true != string::npos );
184 
185  if (( pos_true == string::npos ) && ( pos_false == string::npos )){
186  if ( am_i_master ){
187  cerr << line << endl;
188  cerr << "Invalid option for " << tag << "!" << endl;
189  }
190  return false;
191  }
192  }
193 
194  return true;
195 
196 }
197 
198 int clean_exit( const int return_code ){
199 
200  #ifdef CHEMPS2_MPI_COMPILATION
201  CheMPS2::MPIchemps2::mpi_finalize();
202  #endif
203 
204  return return_code;
205 
206 }
207 
208 void print_help(){
209 
210 cout << "\n"
211 "CheMPS2: a spin-adapted implementation of DMRG for ab initio quantum chemistry\n"
212 "Copyright (C) 2013-2016 Sebastian Wouters\n"
213 "\n"
214 "Usage: chemps2 [OPTIONS]\n"
215 "\n"
216 
217 /**************************************************
218 * The following is copied directly from chemps2.1 *
219 **************************************************/
220 
221 " SYMMETRY\n"
222 " Conventions for the symmetry group and irrep numbers (same as psi4):\n"
223 "\n"
224 " | 0 1 2 3 4 5 6 7\n"
225 " ---------|-----------------------------------------\n"
226 " 0 : c1 | A\n"
227 " 1 : ci | Ag Au\n"
228 " 2 : c2 | A B\n"
229 " 3 : cs | Ap App\n"
230 " 4 : d2 | A B1 B2 B3\n"
231 " 5 : c2v | A1 A2 B1 B2\n"
232 " 6 : c2h | Ag Bg Au Bu\n"
233 " 7 : d2h | Ag B1g B2g B3g Au B1u B2u B3u\n"
234 "\n"
235 " ARGUMENTS\n"
236 " -f, --file=inputfile\n"
237 " Specify the input file.\n"
238 "\n"
239 " -v, --version\n"
240 " Print the version of chemps2.\n"
241 "\n"
242 " -h, --help\n"
243 " Display this help.\n"
244 "\n"
245 " INPUT FILE\n"
246 " FCIDUMP = /path/to/fcidump\n"
247 " Note that orbital irreps in the FCIDUMP file follow molpro convention!\n"
248 "\n"
249 " GROUP = int\n"
250 " Set the psi4 symmetry group number [0-7] which corresponds to the FCIDUMP file.\n"
251 "\n"
252 " MULTIPLICITY = int\n"
253 " Overwrite the spin multiplicity [2S+1] of the FCIDUMP file.\n"
254 "\n"
255 " NELECTRONS = int\n"
256 " Overwrite the number of electrons of the FCIDUMP file.\n"
257 "\n"
258 " IRREP = int\n"
259 " Overwrite the target wavefunction irrep [0-7] of the FCIDUMP file (psi4 convention).\n"
260 "\n"
261 " EXCITATION = int\n"
262 " Set which excitation should be calculated. If zero, the ground state is calculated (default 0).\n"
263 "\n"
264 " SWEEP_STATES = int, int, int\n"
265 " Set the number of reduced renormalized basis states for the successive sweep instructions (positive integers).\n"
266 "\n"
267 " SWEEP_ENERGY_CONV = flt, flt, flt\n"
268 " Set the energy convergence to stop the successive sweep instructions (positive floats).\n"
269 "\n"
270 " SWEEP_MAX_SWEEPS = int, int, int\n"
271 " Set the maximum number of sweeps for the successive sweep instructions (positive integers).\n"
272 "\n"
273 " SWEEP_NOISE_PREFAC = flt, flt, flt\n"
274 " Set the noise prefactors for the successive sweep instructions (floats).\n"
275 "\n"
276 " SWEEP_DVDSON_RTOL = flt, flt, flt\n"
277 " Set the residual norm tolerance for the Davidson algorithm for the successive sweep instructions (positive floats).\n"
278 "\n"
279 " NOCC = int, int, int, int\n"
280 " Set the number of occupied (external core) orbitals per irrep (psi4 irrep ordering).\n"
281 "\n"
282 " NACT = int, int, int, int\n"
283 " Set the number of active orbitals per irrep (psi4 irrep ordering).\n"
284 "\n"
285 " NVIR = int, int, int, int\n"
286 " Set the number of virtual (secondary) orbitals per irrep (psi4 irrep ordering).\n"
287 "\n"
288 " MOLCAS_2RDM = /path/to/2rdm/output\n"
289 " When all orbitals are active orbitals, write out the 2-RDM in HDF5 format when specified (default unspecified).\n"
290 "\n"
291 " MOLCAS_3RDM = /path/to/3rdm/output\n"
292 " When all orbitals are active orbitals, write out the 3-RDM in HDF5 format when specified (default unspecified).\n"
293 "\n"
294 " MOLCAS_F4RDM = /path/to/f4rdm/output\n"
295 " When all orbitals are active orbitals, write out the 4-RDM contracted with the Fock operator in HDF5 format when specified (default unspecified).\n"
296 "\n"
297 " MOLCAS_FOCK = /path/to/fock/input\n"
298 " When all orbitals are active orbitals, read in this file containing the Fock operator (default unspecified).\n"
299 "\n"
300 " MOLCAS_REORDER = bool\n"
301 " When all orbitals are active orbitals, switch on orbital reordering based on the Fiedler vector of the exchange matrix (TRUE or FALSE; default FALSE).\n"
302 "\n"
303 " SCF_STATE_AVG = bool\n"
304 " Switch on state-averaging (TRUE or FALSE; default FALSE).\n"
305 "\n"
306 " SCF_DIIS_THR = flt\n"
307 " Switch on DIIS when the update norm is smaller than the given threshold (default 0.0).\n"
308 "\n"
309 " SCF_GRAD_THR = flt\n"
310 " Gradient norm threshold for convergence of the DMRG-SCF orbital rotations (default 1e-6).\n"
311 "\n"
312 " SCF_MAX_ITER = int\n"
313 " Specify the maximum number of DMRG-SCF iterations (default 100).\n"
314 "\n"
315 " SCF_ACTIVE_SPACE = char\n"
316 " Rotate the active space orbitals: no additional rotations (I), natural orbitals (N), localized and ordered orbitals (L), or ordered orbitals only (F) (default I).\n"
317 "\n"
318 " SCF_MOLDEN = /path/to/molden\n"
319 " Rotate the FCIDUMP orbitals to the DMRG-SCF occupied (external core), active, and virtual (secondary) orbitals.\n"
320 "\n"
321 " CASPT2_CALC = bool\n"
322 " Switch on the CASPT2 calculation (TRUE or FALSE; default FALSE).\n"
323 "\n"
324 " CASPT2_ORBS = char\n"
325 " Perform the DMRG calculation for the 4-RDM in the SCF_ACTIVE_SPACE orbitals (A) or in the pseudocanonical orbitals (P) (default A).\n"
326 "\n"
327 " CASPT2_IPEA = flt\n"
328 " Ionization potential - electron affinity shift (default 0.0).\n"
329 "\n"
330 " CASPT2_IMAG = flt\n"
331 " Imaginary level shift (default 0.0).\n"
332 "\n"
333 " CASPT2_CHECKPT = bool\n"
334 " Create checkpoints to continue the CASPT2 4-RDM calculation over multiple runs (TRUE or FALSE; default FALSE).\n"
335 "\n"
336 " CASPT2_CUMUL = bool\n"
337 " Use a cumulant approximation for the CASPT2 4-RDM and overwrite CASPT2_CHECKPT to FALSE (TRUE or FALSE; default FALSE).\n"
338 "\n"
339 " PRINT_CORR = bool\n"
340 " Print correlation functions (TRUE or FALSE; default FALSE).\n"
341 "\n"
342 " TMP_FOLDER = /path/to/tmp/folder\n"
343 " Overwrite the tmp folder for the renormalized operators. With MPI, separate folders per process can (but do not have to) be used (default /tmp).\n"
344 "\n"
345 " EXAMPLE\n"
346 " $ cd /tmp\n"
347 " $ wget \'https://github.com/SebWouters/CheMPS2/raw/master/tests/matrixelements/N2.CCPVDZ.FCIDUMP\'\n"
348 " $ ls -al N2.CCPVDZ.FCIDUMP\n"
349 " $ wget \'https://github.com/SebWouters/CheMPS2/raw/master/tests/test14.input\'\n"
350 " $ sed -i \"s/path\\/to/tmp/\" test14.input\n"
351 " $ cat test14.input\n"
352 " $ chemps2 --file=test14.input\n"
353 " " << endl;
354 
355 }
356 
357 int main( int argc, char ** argv ){
358 
359  #ifdef CHEMPS2_MPI_COMPILATION
360  CheMPS2::MPIchemps2::mpi_init();
361  const bool am_i_master = ( CheMPS2::MPIchemps2::mpi_rank() == MPI_CHEMPS2_MASTER );
362  #else
363  const bool am_i_master = true;
364  #endif
365 
366  /************************
367  * Read in the options *
368  *************************/
369 
370  string inputfile = "";
371  string fcidump = "";
372 
373  int group = -1;
374  int multiplicity = -1;
375  int nelectrons = -1;
376  int irrep = -1;
377  int excitation = 0;
378 
379  string sweep_states = "";
380  string sweep_econv = "";
381  string sweep_maxit = "";
382  string sweep_noise = "";
383  string sweep_rtol = "";
384 
385  string nocc = "";
386  string nact = "";
387  string nvir = "";
388 
389  string molcas_2rdm = "";
390  string molcas_3rdm = "";
391  string molcas_f4rdm = "";
392  string molcas_fock = "";
393  bool molcas_reorder = false;
394 
395  bool scf_state_avg = false;
396  double scf_diis_thr = 0.0;
397  double scf_grad_thr = 1e-6;
398  int scf_max_iter = 100;
399  char scf_active_space = 'I';
400  string scf_molden = "";
401 
402  bool caspt2_calc = false;
403  char caspt2_orbs = 'A';
404  double caspt2_ipea = 0.0;
405  double caspt2_imag = 0.0;
406  bool caspt2_checkpt = false;
407  bool caspt2_cumul = false;
408 
409  bool print_corr = false;
410  string tmp_folder = "/tmp";
411 
412  struct option long_options[] =
413  {
414  {"file", required_argument, 0, 'f'},
415  {"version", no_argument, 0, 'v'},
416  {"help", no_argument, 0, 'h'},
417  {0, 0, 0, 0}
418  };
419 
420  int option_index = 0;
421  int c;
422  while (( c = getopt_long( argc, argv, "hvf:", long_options, &option_index )) != -1 ){
423  switch( c ){
424  case 'h':
425  case '?':
426  if ( am_i_master ){ print_help(); }
427  return clean_exit( 0 );
428  break;
429  case 'v':
430  if ( am_i_master ){ cout << "chemps2 version " << CHEMPS2_VERSION << endl; }
431  return clean_exit( 0 );
432  break;
433  case 'f':
434  inputfile = optarg;
435  if ( file_exists( inputfile, "--file" ) == false ){ return clean_exit( -1 ); }
436  break;
437  }
438  }
439 
440  if ( inputfile.length() == 0 ){
441  if ( am_i_master ){ cerr << "The input file should be specified!" << endl; }
442  return clean_exit( -1 );
443  }
444 
445  ifstream input( inputfile.c_str() );
446  string line;
447  while ( input.eof() == false ){
448 
449  getline( input, line );
450 
451  if ( line.find( "FCIDUMP" ) != string::npos ){
452  const int pos = line.find( "=" ) + 1;
453  fcidump = line.substr( pos, line.length() - pos );
454  fcidump.erase( remove( fcidump.begin(), fcidump.end(), ' ' ), fcidump.end() );
455  if ( file_exists( fcidump, "FCIDUMP" ) == false ){ return clean_exit( -1 ); }
456  }
457 
458  if ( line.find( "MOLCAS_2RDM" ) != string::npos ){
459  const int pos = line.find( "=" ) + 1;
460  molcas_2rdm = line.substr( pos, line.length() - pos );
461  molcas_2rdm.erase( remove( molcas_2rdm.begin(), molcas_2rdm.end(), ' ' ), molcas_2rdm.end() );
462  }
463 
464  if ( line.find( "MOLCAS_3RDM" ) != string::npos ){
465  const int pos = line.find( "=" ) + 1;
466  molcas_3rdm = line.substr( pos, line.length() - pos );
467  molcas_3rdm.erase( remove( molcas_3rdm.begin(), molcas_3rdm.end(), ' ' ), molcas_3rdm.end() );
468  }
469 
470  if ( line.find( "MOLCAS_F4RDM" ) != string::npos ){
471  const int pos = line.find( "=" ) + 1;
472  molcas_f4rdm = line.substr( pos, line.length() - pos );
473  molcas_f4rdm.erase( remove( molcas_f4rdm.begin(), molcas_f4rdm.end(), ' ' ), molcas_f4rdm.end() );
474  }
475 
476  if ( line.find( "MOLCAS_FOCK" ) != string::npos ){
477  const int pos = line.find( "=" ) + 1;
478  molcas_fock = line.substr( pos, line.length() - pos );
479  molcas_fock.erase( remove( molcas_fock.begin(), molcas_fock.end(), ' ' ), molcas_fock.end() );
480  if ( file_exists( molcas_fock, "MOLCAS_FOCK" ) == false ){ return clean_exit( -1 ); }
481  }
482 
483  if ( line.find( "SCF_MOLDEN" ) != string::npos ){
484  const int pos = line.find( "=" ) + 1;
485  scf_molden = line.substr( pos, line.length() - pos );
486  scf_molden.erase( remove( scf_molden.begin(), scf_molden.end(), ' ' ), scf_molden.end() );
487  if ( file_exists( scf_molden, "SCF_MOLDEN" ) == false ){ return clean_exit( -1 ); }
488  }
489 
490  if ( line.find( "TMP_FOLDER" ) != string::npos ){
491  const int pos = line.find( "=" ) + 1;
492  tmp_folder = line.substr( pos, line.length() - pos );
493  tmp_folder.erase( remove( tmp_folder.begin(), tmp_folder.end(), ' ' ), tmp_folder.end() );
494  if ( file_exists( tmp_folder, "TMP_FOLDER" ) == false ){ return clean_exit( -1 ); }
495  }
496 
497  if ( find_integer( &group, line, "GROUP", true, 0, true, 7 ) == false ){ return clean_exit( -1 ); }
498  if ( find_integer( &multiplicity, line, "MULTIPLICITY", true, 1, false, -1 ) == false ){ return clean_exit( -1 ); }
499  if ( find_integer( &nelectrons, line, "NELECTRONS", true, 2, false, -1 ) == false ){ return clean_exit( -1 ); }
500  if ( find_integer( &irrep, line, "IRREP", true, 0, true, 7 ) == false ){ return clean_exit( -1 ); }
501  if ( find_integer( &excitation, line, "EXCITATION", true, 0, false, -1 ) == false ){ return clean_exit( -1 ); }
502  if ( find_integer( &scf_max_iter, line, "SCF_MAX_ITER", true, 1, false, -1 ) == false ){ return clean_exit( -1 ); }
503 
504  if ( find_double( &scf_diis_thr, line, "SCF_DIIS_THR", true, 0.0 ) == false ){ return clean_exit( -1 ); }
505  if ( find_double( &scf_grad_thr, line, "SCF_GRAD_THR", true, 0.0 ) == false ){ return clean_exit( -1 ); }
506  if ( find_double( &caspt2_ipea, line, "CASPT2_IPEA", true, 0.0 ) == false ){ return clean_exit( -1 ); }
507  if ( find_double( &caspt2_imag, line, "CASPT2_IMAG", true, 0.0 ) == false ){ return clean_exit( -1 ); }
508 
509  char options1[] = { 'I', 'N', 'L', 'F' };
510  char options2[] = { 'A', 'P' };
511  if ( find_character( &scf_active_space, line, "SCF_ACTIVE_SPACE", options1, 4 ) == false ){ return clean_exit( -1 ); }
512  if ( find_character( &caspt2_orbs, line, "CASPT2_ORBS", options2, 2 ) == false ){ return clean_exit( -1 ); }
513 
514  if ( find_boolean( &molcas_reorder, line, "MOLCAS_REORDER" ) == false ){ return clean_exit( -1 ); }
515  if ( find_boolean( &scf_state_avg, line, "SCF_STATE_AVG" ) == false ){ return clean_exit( -1 ); }
516  if ( find_boolean( &caspt2_calc, line, "CASPT2_CALC" ) == false ){ return clean_exit( -1 ); }
517  if ( find_boolean( &caspt2_checkpt, line, "CASPT2_CHECKPT" ) == false ){ return clean_exit( -1 ); }
518  if ( find_boolean( &caspt2_cumul, line, "CASPT2_CUMUL" ) == false ){ return clean_exit( -1 ); }
519  if ( find_boolean( &print_corr, line, "PRINT_CORR" ) == false ){ return clean_exit( -1 ); }
520 
521  if ( line.find( "SWEEP_STATES" ) != string::npos ){
522  const int pos = line.find( "=" ) + 1;
523  sweep_states = line.substr( pos, line.length() - pos );
524  }
525 
526  if ( line.find( "SWEEP_ENERGY_CONV" ) != string::npos ){
527  const int pos = line.find( "=" ) + 1;
528  sweep_econv = line.substr( pos, line.length() - pos );
529  }
530 
531  if ( line.find( "SWEEP_MAX_SWEEPS" ) != string::npos ){
532  const int pos = line.find( "=" ) + 1;
533  sweep_maxit = line.substr( pos, line.length() - pos );
534  }
535 
536  if ( line.find( "SWEEP_NOISE_PREFAC" ) != string::npos ){
537  const int pos = line.find( "=" ) + 1;
538  sweep_noise = line.substr( pos, line.length() - pos );
539  }
540 
541  if ( line.find( "SWEEP_DVDSON_RTOL" ) != string::npos ){
542  const int pos = line.find( "=" ) + 1;
543  sweep_rtol = line.substr( pos, line.length() - pos );
544  }
545 
546  if ( line.find( "NOCC" ) != string::npos ){
547  const int pos = line.find( "=" ) + 1;
548  nocc = line.substr( pos, line.length() - pos );
549  }
550 
551  if ( line.find( "NACT" ) != string::npos ){
552  const int pos = line.find( "=" ) + 1;
553  nact = line.substr( pos, line.length() - pos );
554  }
555 
556  if ( line.find( "NVIR" ) != string::npos ){
557  const int pos = line.find( "=" ) + 1;
558  nvir = line.substr( pos, line.length() - pos );
559  }
560 
561  }
562  input.close();
563 
564  /*******************************
565  * Check the target symmetry *
566  *******************************/
567 
568  if ( group == -1 ){
569  if ( am_i_master ){ cerr << "GROUP is a mandatory option!" << endl; }
570  return clean_exit( -1 );
571  }
572  CheMPS2::Irreps Symmhelper( group );
573  const int num_irreps = Symmhelper.getNumberOfIrreps();
574 
575  int fcidump_norb = -1;
576  int fcidump_nelec = -1;
577  int fcidump_two_s = -1;
578  int fcidump_irrep = -1;
579  {
580  ifstream thefcidump( fcidump.c_str() );
581  string line;
582  int pos, pos2;
583  getline( thefcidump, line ); // &FCI NORB= X,NELEC= Y,MS2= Z,
584  pos = line.find( "FCI" );
585  if ( pos == string::npos ){
586  if ( am_i_master ){ cerr << "The file " << fcidump << " is not a fcidump file!" << endl; }
587  return clean_exit( -1 );
588  }
589  pos = line.find( "NORB" ); pos = line.find( "=", pos ); pos2 = line.find( ",", pos );
590  fcidump_norb = atoi( line.substr( pos+1, pos2-pos-1 ).c_str() );
591  pos = line.find( "NELEC" ); pos = line.find( "=", pos ); pos2 = line.find( ",", pos );
592  fcidump_nelec = atoi( line.substr( pos+1, pos2-pos-1 ).c_str() );
593  pos = line.find( "MS2" ); pos = line.find( "=", pos ); pos2 = line.find( ",", pos );
594  fcidump_two_s = atoi( line.substr( pos+1, pos2-pos-1 ).c_str() );
595  do { getline( thefcidump, line ); } while ( line.find( "ISYM" ) == string::npos );
596  pos = line.find( "ISYM" ); pos = line.find( "=", pos ); pos2 = line.find( ",", pos );
597  const int molpro_wfn_irrep = atoi( line.substr( pos+1, pos2-pos-1 ).c_str() );
598  thefcidump.close();
599 
600  int * psi2molpro = new int[ num_irreps ];
601  Symmhelper.symm_psi2molpro( psi2molpro );
602  for ( int cnt = 0; cnt < num_irreps; cnt++ ){
603  if ( molpro_wfn_irrep == psi2molpro[ cnt ] ){ fcidump_irrep = cnt; }
604  }
605  if ( fcidump_irrep == -1 ){
606  if ( am_i_master ){ cerr << "Could not find the molpro wavefunction symmetry (ISYM) in the fcidump file!" << endl; }
607  return clean_exit( -1 );
608  }
609  delete [] psi2molpro;
610  }
611  if ( multiplicity == -1 ){ multiplicity = fcidump_two_s + 1; }
612  if ( nelectrons == -1 ){ nelectrons = fcidump_nelec; }
613  if ( irrep == -1 ){ irrep = fcidump_irrep; }
614 
615  /*********************************
616  * Check the sweep instructions *
617  **********************************/
618 
619  if (( sweep_states.length() == 0 ) || ( sweep_econv.length() == 0 ) || ( sweep_maxit.length() == 0 ) || ( sweep_noise.length() == 0 ) || ( sweep_rtol.length() == 0 )){
620  if ( am_i_master ){ cerr << "SWEEP_* are mandatory options!" << endl; }
621  return clean_exit( -1 );
622  }
623  const int ni_d = count( sweep_states.begin(), sweep_states.end(), ',' ) + 1;
624  const int ni_econv = count( sweep_econv.begin(), sweep_econv.end(), ',' ) + 1;
625  const int ni_maxit = count( sweep_maxit.begin(), sweep_maxit.end(), ',' ) + 1;
626  const int ni_noise = count( sweep_noise.begin(), sweep_noise.end(), ',' ) + 1;
627  const int ni_rtol = count( sweep_rtol.begin(), sweep_rtol.end(), ',' ) + 1;
628  const bool num_eq = (( ni_d == ni_econv ) && ( ni_d == ni_maxit ) && ( ni_d == ni_noise ) && ( ni_d == ni_rtol ));
629 
630  if ( num_eq == false ){
631  if ( am_i_master ){ cerr << "The number of instructions in SWEEP_* should be equal!" << endl; }
632  return clean_exit( -1 );
633  }
634 
635  int * value_states = new int [ ni_d ]; fetch_ints( sweep_states, value_states, ni_d );
636  double * value_econv = new double[ ni_d ]; fetch_doubles( sweep_econv, value_econv, ni_d );
637  int * value_maxit = new int [ ni_d ]; fetch_ints( sweep_maxit, value_maxit, ni_d );
638  double * value_noise = new double[ ni_d ]; fetch_doubles( sweep_noise, value_noise, ni_d );
639  double * value_rtol = new double[ ni_d ]; fetch_doubles( sweep_rtol, value_rtol, ni_d );
640 
641  /*****************************************
642  * Check the active space specification *
643  ******************************************/
644 
645  if (( nocc.length() == 0 ) || ( nact.length() == 0 ) || ( nvir.length() == 0 )){
646  if ( am_i_master ){ cerr << "NOCC, NACT, and NVIR are mandatory options!" << endl; }
647  return clean_exit( -1 );
648  }
649 
650  const int ni_occ = count( nocc.begin(), nocc.end(), ',' ) + 1;
651  const int ni_act = count( nact.begin(), nact.end(), ',' ) + 1;
652  const int ni_vir = count( nvir.begin(), nvir.end(), ',' ) + 1;
653  const bool cas_ok = (( ni_occ == ni_act ) && ( ni_occ == ni_vir ) && ( ni_occ == num_irreps ));
654 
655  if ( cas_ok == false ){
656  if ( am_i_master ){ cerr << "There should be " << num_irreps << " numbers in NOCC, NACT, and NVIR!" << endl; }
657  return clean_exit( -1 );
658  }
659 
660  int * nocc_parsed = new int[ ni_occ ]; fetch_ints( nocc, nocc_parsed, ni_occ );
661  int * nact_parsed = new int[ ni_act ]; fetch_ints( nact, nact_parsed, ni_act );
662  int * nvir_parsed = new int[ ni_vir ]; fetch_ints( nvir, nvir_parsed, ni_vir );
663 
664  /**************************************
665  * Check consistency MOLCAS_ options *
666  ***************************************/
667 
668  bool full_active_space_calculation = true;
669  for ( int cnt = 0; cnt < num_irreps; cnt++ ){
670  if ( nocc_parsed[ cnt ] != 0 ){ full_active_space_calculation = false; }
671  if ( nvir_parsed[ cnt ] != 0 ){ full_active_space_calculation = false; }
672  }
673 
674  if ( ( molcas_2rdm.length() != 0 ) || ( molcas_3rdm.length() != 0 ) || ( molcas_f4rdm.length() != 0 ) || ( molcas_fock.length() != 0 ) ){
675  if ( full_active_space_calculation == false ){
676  if ( am_i_master ){ cerr << "The options MOLCAS_* can only be specified for full active space calculations (when NOCC = NVIR = 0)!" << endl; }
677  return clean_exit( -1 );
678  }
679  }
680 
681  if ( ( molcas_f4rdm.length() != 0 ) && ( molcas_fock.length() == 0 ) ){
682  if ( am_i_master ){ cerr << "When MOLCAS_F4RDM should be written, MOLCAS_FOCK should be specified as well!" << endl; }
683  return clean_exit( -1 );
684  }
685 
686  /**********************
687  * Print the options *
688  ***********************/
689 
690  if ( am_i_master ){
691  cout << "\nRunning chemps2 version " << CHEMPS2_VERSION << " with the following options:\n" << endl;
692  cout << " FCIDUMP = " << fcidump << endl;
693  cout << " GROUP = " << Symmhelper.getGroupName() << endl;
694  cout << " MULTIPLICITY = " << multiplicity << endl;
695  cout << " NELECTRONS = " << nelectrons << endl;
696  cout << " IRREP = " << Symmhelper.getIrrepName( irrep ) << endl;
697  cout << " EXCITATION = " << excitation << endl;
698  cout << " SWEEP_STATES = [ " << value_states[ 0 ]; for ( int cnt = 1; cnt < ni_d; cnt++ ){ cout << " ; " << value_states[ cnt ]; } cout << " ]" << endl;
699  cout << " SWEEP_ENERGY_CONV = [ " << value_econv [ 0 ]; for ( int cnt = 1; cnt < ni_d; cnt++ ){ cout << " ; " << value_econv [ cnt ]; } cout << " ]" << endl;
700  cout << " SWEEP_MAX_SWEEPS = [ " << value_maxit [ 0 ]; for ( int cnt = 1; cnt < ni_d; cnt++ ){ cout << " ; " << value_maxit [ cnt ]; } cout << " ]" << endl;
701  cout << " SWEEP_NOISE_PREFAC = [ " << value_noise [ 0 ]; for ( int cnt = 1; cnt < ni_d; cnt++ ){ cout << " ; " << value_noise [ cnt ]; } cout << " ]" << endl;
702  cout << " SWEEP_DVDSON_RTOL = [ " << value_rtol [ 0 ]; for ( int cnt = 1; cnt < ni_d; cnt++ ){ cout << " ; " << value_rtol [ cnt ]; } cout << " ]" << endl;
703  cout << " NOCC = [ " << nocc_parsed[ 0 ]; for ( int cnt = 1; cnt < num_irreps; cnt++ ){ cout << " ; " << nocc_parsed[ cnt ]; } cout << " ]" << endl;
704  cout << " NACT = [ " << nact_parsed[ 0 ]; for ( int cnt = 1; cnt < num_irreps; cnt++ ){ cout << " ; " << nact_parsed[ cnt ]; } cout << " ]" << endl;
705  cout << " NVIR = [ " << nvir_parsed[ 0 ]; for ( int cnt = 1; cnt < num_irreps; cnt++ ){ cout << " ; " << nvir_parsed[ cnt ]; } cout << " ]" << endl;
706  if ( full_active_space_calculation ){
707  cout << " MOLCAS_2RDM = " << molcas_2rdm << endl;
708  cout << " MOLCAS_3RDM = " << molcas_3rdm << endl;
709  cout << " MOLCAS_F4RDM = " << molcas_f4rdm << endl;
710  cout << " MOLCAS_FOCK = " << molcas_fock << endl;
711  cout << " MOLCAS_REORDER = " << (( molcas_reorder ) ? "TRUE" : "FALSE" ) << endl;
712  } else {
713  cout << " SCF_STATE_AVG = " << (( scf_state_avg ) ? "TRUE" : "FALSE" ) << endl;
714  cout << " SCF_DIIS_THR = " << scf_diis_thr << endl;
715  cout << " SCF_GRAD_THR = " << scf_grad_thr << endl;
716  cout << " SCF_MAX_ITER = " << scf_max_iter << endl;
717  cout << " SCF_ACTIVE_SPACE = " << (( scf_active_space == 'I' ) ? "I : no additional rotations" :
718  (( scf_active_space == 'N' ) ? "N : natural orbitals" :
719  (( scf_active_space == 'L' ) ? "L : localized and ordered orbitals" : "F : ordered orbitals only" ))) << endl;
720  cout << " SCF_MOLDEN = " << scf_molden << endl;
721  cout << " CASPT2_CALC = " << (( caspt2_calc ) ? "TRUE" : "FALSE" ) << endl;
722  cout << " CASPT2_ORBS = " << (( caspt2_orbs == 'A' ) ? "A : as specified in SCF_ACTIVE_SPACE" : "P : pseudocanonical orbitals" ) << endl;
723  cout << " CASPT2_IPEA = " << caspt2_ipea << endl;
724  cout << " CASPT2_IMAG = " << caspt2_imag << endl;
725  cout << " CASPT2_CHECKPT = " << (( caspt2_checkpt ) ? "TRUE" : "FALSE" ) << endl;
726  cout << " CASPT2_CUMUL = " << (( caspt2_cumul ) ? "TRUE" : "FALSE" ) << endl;
727  }
728  cout << " PRINT_CORR = " << (( print_corr ) ? "TRUE" : "FALSE" ) << endl;
729  cout << " TMP_FOLDER = " << tmp_folder << endl;
730  cout << " " << endl;
731  }
732 
733  /********************************
734  * Running the DMRG calculation *
735  ********************************/
736 
738  CheMPS2::Hamiltonian * ham = new CheMPS2::Hamiltonian( fcidump, group );
739  CheMPS2::ConvergenceScheme * opt_scheme = new CheMPS2::ConvergenceScheme( ni_d );
740  for ( int count = 0; count < ni_d; count++ ){
741  opt_scheme->set_instruction( count, value_states[ count ],
742  value_econv [ count ],
743  value_maxit [ count ],
744  value_noise [ count ],
745  value_rtol [ count ] );
746  }
747  delete [] value_states;
748  delete [] value_econv;
749  delete [] value_maxit;
750  delete [] value_noise;
751  delete [] value_rtol;
752 
753  if ( full_active_space_calculation ){
754 
755  CheMPS2::Problem * prob = new CheMPS2::Problem( ham, multiplicity - 1, nelectrons, irrep );
756 
757  // Reorder the orbitals if desired
758  if (( group == 7 ) && ( molcas_reorder == false )){ prob->SetupReorderD2h(); }
759  if ( molcas_reorder ){
760  int * dmrg2ham = new int[ ham->getL() ];
761  if ( am_i_master ){
762  CheMPS2::EdmistonRuedenberg * fiedler = new CheMPS2::EdmistonRuedenberg( ham->getVmat(), group );
763  fiedler->FiedlerGlobal( dmrg2ham );
764  delete fiedler;
765  }
766  #ifdef CHEMPS2_MPI_COMPILATION
767  CheMPS2::MPIchemps2::broadcast_array_int( dmrg2ham, ham->getL(), MPI_CHEMPS2_MASTER );
768  #endif
769  prob->setup_reorder_custom( dmrg2ham );
770  delete [] dmrg2ham;
771  }
772 
773  CheMPS2::DMRG * dmrgsolver = new CheMPS2::DMRG( prob, opt_scheme, CheMPS2::DMRG_storeMpsOnDisk, tmp_folder );
774 
775  // Solve for the correct root
776  double DMRG_ENERGY;
777  for ( int state = 0; state < ( excitation + 1 ); state++ ){
778  if ( state > 0 ){ dmrgsolver->newExcitation( fabs( DMRG_ENERGY ) ); }
779  DMRG_ENERGY = dmrgsolver->Solve();
780  if (( state == 0 ) && ( excitation > 0 )){ dmrgsolver->activateExcitations( excitation ); }
781  }
782 
783  // Calculate the RDMs and correlations
784  const bool calc_3rdm = (( molcas_3rdm.length() != 0 ) || ( molcas_f4rdm.length() != 0 ));
785  const bool calc_2rdm = (( print_corr == true ) || ( molcas_2rdm.length() != 0 ));
786  if (( calc_2rdm ) || ( calc_3rdm )){
787  dmrgsolver->calc_rdms_and_correlations( calc_3rdm, false );
788  if ( molcas_2rdm.length() != 0 ){ dmrgsolver->get2DM()->save_HAM( molcas_2rdm ); }
789  if ( molcas_3rdm.length() != 0 ){ dmrgsolver->get3DM()->save_HAM( molcas_3rdm ); }
790  if ( molcas_f4rdm.length() != 0 ){
791  const int LAS = ham->getL();
792  const int LAS_pow6 = LAS * LAS * LAS * LAS * LAS * LAS;
793  double * fockmx = new double[ LAS * LAS ];
794  double * work = new double[ LAS_pow6 ];
795  double * result = new double[ LAS_pow6 ];
796  for ( int cnt = 0; cnt < LAS_pow6; cnt++ ){ result[ cnt ] = 0.0; }
797  ham->readfock( molcas_fock, fockmx, true );
798  CheMPS2::CASSCF::fock_dot_4rdm( fockmx, dmrgsolver, ham, 0, 0, work, result, false, false );
799  CheMPS2::ThreeDM::save_HAM_generic( molcas_f4rdm, LAS, "F.4-RDM", result );
800  delete [] fockmx;
801  delete [] work;
802  delete [] result;
803  }
804  if ( print_corr ){ dmrgsolver->getCorrelations()->Print(); }
805  }
806 
807  // Clean up
808  if ( CheMPS2::DMRG_storeMpsOnDisk ){ dmrgsolver->deleteStoredMPS(); }
809  if ( CheMPS2::DMRG_storeRenormOptrOnDisk ){ dmrgsolver->deleteStoredOperators(); }
810  delete dmrgsolver;
811  delete prob;
812 
813  } else {
814 
815  CheMPS2::CASSCF koekoek( ham, NULL, NULL, nocc_parsed, nact_parsed, nvir_parsed, tmp_folder );
816 
817  const int root_num = excitation + 1;
818  CheMPS2::DMRGSCFoptions * scf_options = new CheMPS2::DMRGSCFoptions();
819  scf_options->setDoDIIS( true );
820  scf_options->setDIISGradientBranch( scf_diis_thr );
821  scf_options->setStoreDIIS( true );
822  scf_options->setMaxIterations( scf_max_iter );
823  scf_options->setGradientThreshold( scf_grad_thr );
824  scf_options->setStoreUnitary( true );
825  scf_options->setStateAveraging( scf_state_avg );
826  if ( scf_active_space == 'I' ){ scf_options->setWhichActiveSpace( 0 ); }
827  if ( scf_active_space == 'N' ){ scf_options->setWhichActiveSpace( 1 ); }
828  if ( scf_active_space == 'L' ){ scf_options->setWhichActiveSpace( 2 ); }
829  if ( scf_active_space == 'F' ){ scf_options->setWhichActiveSpace( 3 ); }
830  scf_options->setDumpCorrelations( print_corr );
831  scf_options->setStartLocRandom( true );
832 
833  const double E_CASSCF = koekoek.solve( nelectrons, multiplicity - 1, irrep, opt_scheme, root_num, scf_options );
834  double E_CASPT2 = 0.0;
835  if ( caspt2_calc ){
836  E_CASPT2 = koekoek.caspt2( nelectrons, multiplicity - 1, irrep, opt_scheme, root_num, scf_options, caspt2_ipea, caspt2_imag, ( caspt2_orbs == 'P' ), caspt2_checkpt, caspt2_cumul );
837  if ( am_i_master ){
838  cout << "E_CASSCF + E_CASPT2 = E_0 + E_1 + E_2 = " << E_CASSCF + E_CASPT2 << endl;
839  }
840  }
841 
842  if ( ( am_i_master ) && ( scf_molden.length() > 0 ) ){
843  int * norb_ham = new int[ Symmhelper.getNumberOfIrreps() ];
844  for ( int irrep = 0; irrep < Symmhelper.getNumberOfIrreps(); irrep++ ){ norb_ham[ irrep ] = 0; }
845  for ( int orb = 0; orb < ham->getL(); orb++ ){ norb_ham[ ham->getOrbitalIrrep( orb ) ] += 1; }
846  CheMPS2::Molden * molden_rotator = new CheMPS2::Molden( ham->getL(), Symmhelper.getGroupNumber(), norb_ham );
847  molden_rotator->read_molden( scf_molden );
848  molden_rotator->read_unitary( scf_options->getUnitaryStorageName() );
849  molden_rotator->print( scf_molden, scf_molden + ".rotated" );
850  delete [] norb_ham;
851  delete molden_rotator;
852  }
853 
854  // Clean up
855  if (( scf_options->getStoreDIIS() ) && ( am_i_master )){ koekoek.deleteStoredDIIS( scf_options->getDIISStorageName() ); }
856  delete scf_options;
857 
858  }
859 
860  delete [] nocc_parsed;
861  delete [] nact_parsed;
862  delete [] nvir_parsed;
863  delete opt_scheme;
864  delete ham;
865 
866  return clean_exit( 0 );
867 
868 }
869 
870 
void setDumpCorrelations(const bool DumpCorrelations_in)
Set whether the correlations and two-orbital mutual information should be printed.
void print(const string original, const string output)
Multiply and print the new molden file.
Definition: Molden.cpp:152
void setDoDIIS(const bool DoDIIS_in)
Set whether DIIS should be performed.
void setStartLocRandom(const bool StartLocRandom_in)
Set whether the localization procedure should start from a random unitary.
void readfock(const string fockfile, double *fockmx, const bool printinfo) const
Read in a FOCK file.
void read_molden(const string filename)
Read a molden file.
Definition: Molden.cpp:68
void setGradientThreshold(const double GradientThreshold_in)
Set the threshold for DMRGSCF convergence.
void save_HAM(const string filename) const
Save the 3-RDM to disk in Hamiltonian indices.
Definition: ThreeDM.cpp:371
void set_instruction(const int instruction, const int D, const double energy_conv, const int max_sweeps, const double noise_prefactor, const double davidson_rtol)
Set an instruction.
STL namespace.
void deleteStoredMPS()
Call "rm " + CheMPS2::DMRG_MPS_storage_prefix + "*.h5".
Definition: DMRGmpsio.cpp:164
void read_unitary(const string filename)
Read a unitary matrix.
Definition: Molden.cpp:146
void Print(const int precision=6, const int columnsPerLine=8) const
Print the correlation functions and two-orbital mutual information.
int getOrbitalIrrep(const int nOrb) const
Get an orbital irrep number.
Definition: Hamiltonian.cpp:97
static int mpi_rank()
Get the rank of this MPI process.
Definition: MPIchemps2.h:131
double getVmat(const int index1, const int index2, const int index3, const int index4) const
Get a Vmat element.
Correlations * getCorrelations()
Get the pointer to the Correlations.
Definition: DMRG.h:128
static void save_HAM_generic(const string filename, const int LAS, const string tag, double *array)
Generic save routine for objects of size LAS**6.
Definition: ThreeDM.cpp:378
TwoDM * get2DM()
Get the pointer to the 2-RDM.
Definition: DMRG.h:113
void setWhichActiveSpace(const int WhichActiveSpace_in)
Set which active space should be considered in the DMRG routine.
double Solve()
Solver.
Definition: DMRG.cpp:199
void setup_reorder_custom(int *dmrg2ham)
Reorder the orbitals to a custom ordering. Previous reorderings are cleared.
Definition: Problem.cpp:150
void FiedlerGlobal(int *dmrg2ham) const
Permute the orbitals so that the bandwidth of the exchange matrix is (approximately) minimized...
string getDIISStorageName() const
Get the DIIS checkpoint filename.
void newExcitation(const double EshiftIn)
Push back current calculation and set everything up to calculate a (new) excitation.
Definition: DMRG.cpp:395
static void fock_dot_4rdm(double *fockmx, CheMPS2::DMRG *dmrgsolver, CheMPS2::Hamiltonian *ham, int next_orb1, int next_orb2, double *work, double *result, const bool CHECKPOINT, const bool PSEUDOCANONICAL)
Build the contraction of the fock matrix with the 4-RDM.
Definition: CASSCFpt2.cpp:140
void setStoreDIIS(const bool StoreDIIS_in)
Set whether the DIIS checkpoint should be stored to disk.
void setMaxIterations(const int MaxIterations_in)
Set the maximum number of DMRGSCF iterations.
bool getStoreDIIS() const
Get whether the DIIS checkpoint should be stored to disk.
void SetupReorderD2h()
Reorder the orbitals, so that they form irrep blocks, with order of irreps Ag B1u B3u B2g B2u B3g B1g...
Definition: Problem.cpp:56
void activateExcitations(const int maxExcIn)
Activate the necessary storage and machinery to handle excitations.
Definition: DMRG.cpp:384
static void Init()
Initialize the random number generator and the cout.precision.
Definition: Initialize.cpp:26
ThreeDM * get3DM()
Get the pointer to the 3-RDM.
Definition: DMRG.h:117
void calc_rdms_and_correlations(const bool do_3rdm, const bool disk_3rdm=false)
Calculate the reduced density matrices and correlations. Afterwards the MPS is again in LLLLLLLC gaug...
void setStoreUnitary(const bool StoreUnitary_in)
Set whether the Orbital Rotation checkpoint should be stored to disk.
void save_HAM(const string filename) const
Save the 2-RDM-A to disk in Hamiltonian indices.
Definition: TwoDM.cpp:278
void deleteStoredOperators()
Call "rm " + tempfolder + "/" + CheMPS2::DMRG_OPERATOR_storage_prefix + string(thePID) + "*...
int getL() const
Get the number of orbitals.
Definition: Hamiltonian.cpp:93
void setDIISGradientBranch(const double DIISGradientBranch_in)
Set the threshold for when DIIS should start.
string getUnitaryStorageName() const
Get the Orbital Rotation checkpoint filename.
void setStateAveraging(const bool StateAveraging_in)
Set whether state-averaging or state-specific DMRGSCF should be performed.