Exemple #1
0
int main(int argc, char **argv) {
  print_copyright();
  print_license();
#ifdef SVNRELEASE
  printf("At svn revision %s.\n\n",SVNREVISION);
#endif
  print_hostname();

  if(argc!=5) {
    printf("Usage: %s zeta l Nf method\n",argv[0]);
    printf("zeta is the STO exponent to fit\n");
    printf("l is angular momentum to use\n");
    printf("Nf is number of exponents to use\n");
    printf("method is 0 for even-tempered, 1 for well-tempered and 2 for full optimization, or 3 for midpoint quadrature.\n");
    return 1;
  }

  // Read parameteres
  double zeta=atof(argv[1]);
  double am=atoi(argv[2]);
  int Nf=atoi(argv[3]);
  int method=atoi(argv[4]);

  // Do the optimization
  std::vector<contr_t> contr;

  if(method>=0 && method<=2)
    contr=slater_fit(zeta,am,Nf,true,method);
  else if(method==3)
    contr=slater_fit_midpoint(zeta,am,Nf);
  else throw std::runtime_error("Unknown method.\n");

  // Print them out
  printf("\nExponential contraction\nc_i\t\tz_i\t\tlg z_i\n");
  for(size_t i=0;i<contr.size();i++)
    printf("% e\t%e\t% e\n",contr[i].c,contr[i].z,log10(contr[i].z));

  // Form basis set
  ElementBasisSet elbas("El");
  FunctionShell sh(am,contr);
  elbas.add_function(sh);

  // Save the basis set
  BasisSetLibrary baslib;
  baslib.add_element(elbas);
  baslib.save_gaussian94("slater-contr.gbs");

  // also in decontracted form
  baslib.decontract();
  baslib.save_gaussian94("slater-uncontr.gbs");

  return 0;
}
Exemple #2
0
int main(int argc, char **argv) {
#ifdef _OPENMP
  printf("ERKALE - Completeness optimization from Hel. OpenMP version, running on %i cores.\n",omp_get_max_threads());
#else
  printf("ERKALE - Completeness optimization from Hel. Serial version.\n");
#endif
  print_copyright();
  print_license();
#ifdef SVNRELEASE
  printf("At svn revision %s.\n\n",SVNREVISION);
#endif
  print_hostname();

  if(argc!=7 && argc!=8) {
    printf("Usage:   %s am n min max Nf/tol nfull (coulomb)\n",argv[0]);
    printf("am:      angular momentum of shell to optimize for.\n");
    printf("n:       moment to optimize for.\n");
    printf("         1 for maximal area, 2 for minimal rms deviation from unity.\n");
    printf("min:     profile lower limit, in log10.\n");
    printf("Nf:      amount of functions to place on shell.\n");
    printf("tol:     wanted tolerance.\n");
    printf("nfull:   number of outermost functions to fully optimize.\n");
    printf("coulomb: use Coulomb metric?\n");
    return 1;
  }

  // Get parameters
  int am=atoi(argv[1]);
  int n=atoi(argv[2]);
  double min=atof(argv[3]);
  int nf=atoi(argv[4]);
  double tol=atof(argv[5]);
  int nfull=atoi(argv[6]);

  bool coulomb=false;
  if(argc==8)
    coulomb=atoi(argv[7]);
  // The Coulomb metric is equivalent to the normal metric with am-1
  if(coulomb)
    am--;

  Timer t;

  // Form optimized set of primitives
  double w;
  arma::vec exps=move_exps(maxwidth_exps(am,tol,nf,w,n,nfull),min);

  // Return the original value if Coulomb metric was used
  if(coulomb)
    am++;

  // Create a basis set out of it. Print exponents in descending order
  ElementBasisSet el("El");
  for(size_t i=exps.size()-1;i<exps.size();i--) {
    // Create shell of functions
    FunctionShell tmp(am);
    tmp.add_exponent(1.0,exps[i]);
    // and add it to the basis set
    el.add_function(tmp);
  }

  BasisSetLibrary baslib;
  baslib.add_element(el);
  baslib.save_gaussian94("optimized.gbs");

  printf("Optimization performed in %s.\n",t.elapsed().c_str());
  printf("Completeness-optimized basis set saved to optimized.gbs.\n\n");

  printf("Width of profile is %.10e.\n",w);

  return 0;
}
int main(int argc, char **argv) {
#ifdef _OPENMP
  printf("ERKALE - population from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads());
#else
  printf("ERKALE - population from Hel, serial version.\n");
#endif
  print_copyright();
  print_license();
#ifdef SVNRELEASE
  printf("At svn revision %s.\n\n",SVNREVISION);
#endif
  print_hostname();

  if(argc!=2) {
    printf("Usage: %s runfile\n",argv[0]);
    return 1;
  }

  // Parse settings
  Settings set;
  set.add_string("LoadChk","Checkpoint file to load density from","erkale.chk");
  set.add_bool("Bader", "Run Bader analysis?", false);
  set.add_bool("Becke", "Run Becke analysis?", false);
  set.add_bool("Mulliken", "Run Mulliken analysis?", false);
  set.add_bool("Lowdin", "Run Löwdin analysis?", false);
  set.add_bool("IAO", "Run Intrinsic Atomic Orbital analysis?", false);
  set.add_string("IAOBasis", "Minimal basis set for IAO analysis", "MINAO.gbs");
  set.add_bool("Hirshfeld", "Run Hirshfeld analysis?", false);
  set.add_string("HirshfeldMethod", "Method to use for Hirshfeld(-I) analysis", "HF");
  set.add_bool("IterativeHirshfeld", "Run iterative Hirshfeld analysis?", false);
  set.add_bool("Stockholder", "Run Stockholder analysis?", false);
  set.add_bool("Voronoi", "Run Voronoi analysis?", false);
  set.add_double("Tol", "Grid tolerance to use for the charges", 1e-5);
  set.add_bool("OrbThr", "Compute orbital density thresholds", false);
  set.add_bool("SICThr", "Compute SIC orbital density thresholds", false);
  set.add_bool("DensThr", "Compute total density thresholds", false);
  set.add_double("OrbThrVal", "Which density threshold to calculate", 0.85);
  set.add_double("OrbThrGrid", "Accuracy of orbital density threshold integration grid", 1e-3);

  // Parse settings
  set.parse(argv[1]);

  // Print settings
  set.print();

  // Initialize libint
  init_libint_base();

  // Load checkpoint
  Checkpoint chkpt(set.get_string("LoadChk"),false);

  // Load basis set
  BasisSet basis;
  chkpt.read(basis);

  // Restricted calculation?
  bool restr;
  chkpt.read("Restricted",restr);

  arma::mat P, Pa, Pb;
  chkpt.read("P",P);
  if(!restr) {
    chkpt.read("Pa",Pa);
    chkpt.read("Pb",Pb);
  }

  double tol=set.get_double("Tol");

  if(set.get_bool("Bader")) {
    if(restr)
      bader_analysis(basis,P,tol);
    else
      bader_analysis(basis,Pa,Pb,tol);
  }

  if(set.get_bool("Becke")) {
    if(restr)
      becke_analysis(basis,P,tol);
    else
      becke_analysis(basis,Pa,Pb,tol);
  }

  std::string hmet=set.get_string("HirshfeldMethod");

  if(set.get_bool("Hirshfeld")) {
    if(restr)
      hirshfeld_analysis(basis,P,hmet,tol);
    else
      hirshfeld_analysis(basis,Pa,Pb,hmet,tol);
  }

  if(set.get_bool("IterativeHirshfeld")) {
    if(restr)
      iterative_hirshfeld_analysis(basis,P,hmet,tol);
    else
      iterative_hirshfeld_analysis(basis,Pa,Pb,hmet,tol);
  }

  if(set.get_bool("IAO")) {
    std::string minbas=set.get_string("IAOBasis");

    if(restr) {
      // Get amount of occupied orbitals
      int Nela;
      chkpt.read("Nel-a",Nela);

      // Get orbital coefficients
      arma::mat C;
      chkpt.read("C",C);

      // Do analysis
      IAO_analysis(basis,C.cols(0,Nela-1),P,minbas);
    } else {
      // Get amount of occupied orbitals
      int Nela, Nelb;
      chkpt.read("Nel-a",Nela);
      chkpt.read("Nel-b",Nelb);

      // Get orbital coefficients
      arma::mat Ca, Cb;
      chkpt.read("Ca",Ca);
      chkpt.read("Cb",Cb);

      // Do analysis
      IAO_analysis(basis,Ca.cols(0,Nela-1),Cb.cols(0,Nelb-1),Pa,Pb,minbas);
    }
  }

  if(set.get_bool("Lowdin")) {
    if(restr)
      lowdin_analysis(basis,P);
    else
      lowdin_analysis(basis,Pa,Pb);
  }

  if(set.get_bool("Mulliken")) {
    if(restr)
      mulliken_analysis(basis,P);
    else
      mulliken_analysis(basis,Pa,Pb);
  }

  if(set.get_bool("Stockholder")) {
    if(restr)
      stockholder_analysis(basis,P,tol);
    else
      stockholder_analysis(basis,Pa,Pb,tol);
  }

  if(set.get_bool("Voronoi")) {
    if(restr)
      voronoi_analysis(basis,P,tol);
    else
      voronoi_analysis(basis,Pa,Pb,tol);
  }

  if(set.get_bool("OrbThr")) {
    // Calculate orbital density thresholds

    // Integration grid
    DFTGrid intgrid(&basis,true);
    intgrid.construct_becke(set.get_double("OrbThrGrid"));

    // Threshold is
    double thr=set.get_double("OrbThrVal");

    if(restr) {
      // Get amount of occupied orbitals
      int Nela;
      chkpt.read("Nel-a",Nela);

      // Get orbital coefficients
      arma::mat C;
      chkpt.read("C",C);

      printf("\n%4s %9s %8s\n","orb","thr","t (s)");
      for(int io=0;io<Nela;io++) {
	Timer t;

	// Orbital density matrix is
	arma::mat Po=C.col(io)*arma::trans(C.col(io));
	double val=compute_threshold(intgrid,Po,thr,false);

	// Print out orbital threshold
	printf("%4i %8.3e %8.3f\n", io+1, val, t.get());
	fflush(stdout);
      }

    } else {
      // Get amount of occupied orbitals
      int Nela, Nelb;
      chkpt.read("Nel-a",Nela);
      chkpt.read("Nel-b",Nelb);

      // Get orbital coefficients
      arma::mat Ca, Cb;
      chkpt.read("Ca",Ca);
      chkpt.read("Cb",Cb);

      printf("\n%4s %9s %9s %8s\n","orb","thr-a","thr-b","t (s)");
      for(int io=0;io<Nela;io++) {
	Timer t;

	// Orbital density matrix is
	arma::mat Po=Ca.col(io)*arma::trans(Ca.col(io));
	double vala=compute_threshold(intgrid,Po,thr,false);

	if(io<Nelb) {
	  Po=Cb.col(io)*arma::trans(Cb.col(io));
	  double valb=compute_threshold(intgrid,Po,thr,false);

	  // Print out orbital threshold
	  printf("%4i %8.3e %8.3e %8.3f\n", io+1, vala, valb, t.get());
	  fflush(stdout);
	} else {
	  printf("%4i %8.3e %9s %8.3f\n", io+1, vala, "****", t.get());
	  fflush(stdout);
	}
      }

    }
  }

  if(set.get_bool("SICThr")) {
    // Calculate SIC orbital density thresholds

    // Integration grid
    DFTGrid intgrid(&basis,true);
    intgrid.construct_becke(set.get_double("OrbThrGrid"));

    // Threshold is
    double thr=set.get_double("OrbThrVal");

    if(restr) {
      // Get orbital coefficients
      arma::cx_mat CW;
      chkpt.cread("CW",CW);

      printf("\n%4s %9s %8s\n","orb","thr","t (s)");
      for(size_t io=0;io<CW.n_cols;io++) {
	Timer t;

	// Orbital density matrix is
	arma::mat Po=arma::real(CW.col(io)*arma::trans(CW.col(io)));
	double val=compute_threshold(intgrid,Po,thr,false);

	// Print out orbital threshold
	printf("%4i %8.3e %8.3f\n", (int) io+1, val, t.get());
	fflush(stdout);
      }

    } else {
      // Get orbital coefficients
      arma::cx_mat CWa, CWb;
      chkpt.cread("CWa",CWa);
      chkpt.cread("CWb",CWb);

      printf("\n%4s %9s %9s %8s\n","orb","thr-a","thr-b","t (s)");
      for(size_t io=0;io<CWa.n_cols;io++) {
	Timer t;

	// Orbital density matrix is
	arma::mat Po=arma::real(CWa.col(io)*arma::trans(CWa.col(io)));
	double vala=compute_threshold(intgrid,Po,thr,false);

	if(io<CWb.n_cols) {
	  Po=arma::real(CWb.col(io)*arma::trans(CWb.col(io)));
	  double valb=compute_threshold(intgrid,Po,thr,false);

	  // Print out orbital threshold
	  printf("%4i %8.3e %8.3e %8.3f\n", (int) io+1, vala, valb, t.get());
	  fflush(stdout);
	} else {
	  printf("%4i %8.3e %9s %8.3f\n", (int) io+1, vala, "****", t.get());
	  fflush(stdout);
	}
      }
    }
  }

  if(set.get_bool("DensThr")) {
    // Calculate SIC orbital density thresholds

    // Integration grid
    DFTGrid intgrid(&basis,true);
    intgrid.construct_becke(set.get_double("OrbThrGrid"));

    // Threshold is
    double thr=set.get_double("OrbThrVal");

    Timer t;

    printf("\n%10s %9s %8s\n","density","thr","t (s)");
    if(!restr) {
      double aval=compute_threshold(intgrid,Pa,thr*arma::trace(P*basis.overlap()),true);
      printf("%10s %8.3e %8.3f\n", "alpha", aval, t.get());
      fflush(stdout);
      t.set();

      double bval=compute_threshold(intgrid,Pb,thr*arma::trace(P*basis.overlap()),true);
      printf("%10s %8.3e %8.3f\n", "beta", bval, t.get());
      fflush(stdout);
      t.set();
    }

    double val=compute_threshold(intgrid,P,thr*arma::trace(P*basis.overlap()),true);
    printf("%10s %8.3e %8.3f\n", "total", val, t.get());
    fflush(stdout);
  }


  return 0;
}
Exemple #4
0
Session::Session(int fd_, const sockaddr_in& sender_) : fd(fd_), sender(sender_), aes {},
   authenticated(false), lb {}, ip(print_ip()), hostname(print_hostname())
{
}
Exemple #5
0
int main(int argc, char **argv) {
  printf("ERKALE - Basis set tools from Hel.\n");
  print_copyright();
  print_license();
#ifdef SVNRELEASE
  printf("At svn revision %s.\n\n",SVNREVISION);
#endif
  print_hostname();

  if(argc<3) {
    printf("Usage: %s input.gbs command\n\n",argv[0]);
    help();
    return 0;
  }

  // Get filename
  std::string filein(argv[1]);
  // Load input
  BasisSetLibrary bas;
  bas.load_gaussian94(filein);

  // Get command
  std::string cmd(argv[2]);
  // and determine what to do.
  if(stricmp(cmd,"cholesky")==0) {
    // Print completeness profile.

    if(argc!=7) {
      printf("\nUsage: %s input.gbs cholesky thr maxam ovlthr output.gbs\n",argv[0]);
      return 1;
    }

    double thr(atof(argv[3]));
    int maxam(atoi(argv[4]));
    double ovlthr(atof(argv[5]));
    std::string outfile(argv[6]);

    if(maxam>=LIBINT_MAX_AM) {
      printf("Setting maxam = %i because limitations in used version of LIBINT.\n",LIBINT_MAX_AM-1);
      maxam=LIBINT_MAX_AM-1;
    }
			       
    init_libint_base();
    BasisSetLibrary ret=bas.cholesky_set(thr,maxam,ovlthr);
    ret.save_gaussian94(outfile);
    
  } else if(stricmp(cmd,"completeness")==0) {
    // Print completeness profile.

    if(argc!=5 && argc!=6) {
      printf("\nUsage: %s input.gbs completeness element output.dat (coulomb)\n",argv[0]);
      return 1;
    }

    std::string el(argv[3]);
    std::string fileout(argv[4]);
    bool coulomb=false;
    if(argc==6)
      coulomb=atoi(argv[5]);

    // Get wanted element from basis
    ElementBasisSet elbas=bas.get_element(el);

    // Compute completeness profile
    compprof_t prof=compute_completeness(elbas,-10.0,10.0,2001,coulomb);

    // Print profile in output file
    FILE *out=fopen(fileout.c_str(),"w");
    for(size_t i=0;i<prof.lga.size();i++) {
      // Value of scanning exponent
      fprintf(out,"%13e",prof.lga[i]);
      // Print completeness of shells
      for(size_t j=0;j<prof.shells.size();j++)
	fprintf(out,"\t%13e",prof.shells[j].Y[i]);
      fprintf(out,"\n");
    }
    fclose(out);

  } else if(stricmp(cmd,"composition")==0) {
    // Determine composition of basis set.

    if(argc!=3 && argc!=4) {
      printf("\nUsage: %s input.gbs composition (El)\n",argv[0]);
      return 1;
    }

    // Elemental basis sets
    std::vector<ElementBasisSet> elbases;

    if(argc==4)
      elbases.push_back(bas.get_element(argv[3]));
    else
      elbases=bas.get_elements();

    printf("\n");
    printf("el at#  [npr|nbf] [primitive|contracted(?)]\n");
    printf("-------------------------------------------\n");

    // Loop over elements
    for(size_t iel=0;iel<elbases.size();iel++) {
      // Get the basis set
      ElementBasisSet elbas=elbases[iel];

      // Decontracted basis
      ElementBasisSet eldec(elbas);
      eldec.decontract();

      // Get the shells
      std::vector<FunctionShell> sh=elbas.get_shells();
      std::vector<FunctionShell> decsh=eldec.get_shells();

      // Count the shells
      arma::imat Nsh(max_am,2);
      Nsh.zeros();
      for(size_t ish=0;ish<decsh.size();ish++)
	Nsh(decsh[ish].get_am(),0)++;
      for(size_t ish=0;ish<sh.size();ish++)
	Nsh(sh[ish].get_am(),1)++;

      // Determine if basis set is contracted and the amount of
      // functions
      bool contr=false;
      size_t nbf=0;
      size_t nprim=0;
      for(int am=0;am<max_am;am++) {
	// Number of primitives
	nprim+=Nsh(am,0)*(2*am+1);
	// Number of contracted functions
	nbf+=Nsh(am,1)*(2*am+1);
      }
      if(nbf!=nprim)
	contr=true;

      // Print composition
      printf("%-2s %3i ",elbas.get_symbol().c_str(),(int) elbas.get_number());
      if(contr) {
	// Print amount of functions
	char cmp[20];
	sprintf(cmp,"[%i|%i]",(int) nprim,(int) nbf);
	printf("%10s [",cmp);

	// Print primitives
	for(int am=0;am<max_am;am++)
	  if(Nsh(am,0)>0)
	    printf("%i%c",Nsh(am,0),tolower(shell_types[am]));
	// Print contractions
	printf("|");
	for(int am=0;am<max_am;am++)
	  if(Nsh(am,0)!=Nsh(am,1))
	    printf("%i%c",Nsh(am,1),tolower(shell_types[am]));
	printf("]\n");
      } else {
	printf("%10i  ",(int) nbf);
	for(int am=0;am<max_am;am++)
	  if(Nsh(am,0)>0)
	    printf("%i%c",Nsh(am,0),tolower(shell_types[am]));
	printf("\n");
      }
    }
  } else if(stricmp(cmd,"daug")==0 || stricmp(cmd,"taug")==0) {
    // Augment basis set

    if(argc!=4) {
      printf("\nUsage: %s input.gbs %s output.gbs\n",argv[0],tolower(cmd).c_str());
      return 1;
    }

    int naug;
    if(stricmp(cmd,"daug")==0)
      naug=1;
    else
      naug=2;

    std::string fileout(argv[3]);
    bas.augment(naug);
    bas.save_gaussian94(fileout);
  } else if(stricmp(cmd,"decontract")==0) {
  // Decontract basis set.

    if(argc!=4) {
      printf("\nUsage: %s input.gbs decontract output.gbs\n",argv[0]);
      return 1;
    }

    std::string fileout(argv[3]);
    bas.decontract();
    bas.save_gaussian94(fileout);

  } else if(stricmp(cmd,"densityfit")==0) {
  // Generate density fitted set

    if(argc!=6) {
      printf("\nUsage: %s input.gbs densityfit lval fsam output.gbs\n",argv[0]);
      return 1;
    }

    int lval(atoi(argv[3]));
    double fsam(atof(argv[4]));
    std::string fileout(argv[5]);
    BasisSetLibrary dfit(bas.density_fitting(lval,fsam));
    dfit.save_gaussian94(fileout);

  } else if(stricmp(cmd,"dump")==0) {
    // Dump wanted element.

    if(argc!=5 && argc!=6) {
      printf("\nUsage: %s input.gbs dump element output.gbs (number)\n",argv[0]);
      return 1;
    }

    std::string el(argv[3]);
    std::string fileout(argv[4]);

    int no=0;
    if(argc==6)
      no=atoi(argv[5]);

    // Save output
    BasisSetLibrary elbas;
    elbas.add_element(bas.get_element(el,no));
    elbas.save_gaussian94(fileout);

  } else if(stricmp(cmd,"dumpdec")==0) {
    // Dump wanted element in decontracted form.

    if(argc!=5 && argc!=6) {
      printf("\nUsage: %s input.gbs dumpdec element output.gbs (number)\n",argv[0]);
      return 1;
    }

    std::string el(argv[3]);
    std::string fileout(argv[4]);

    int no=0;
    if(argc==6)
      no=atoi(argv[5]);

    // Save output
    BasisSetLibrary elbas;
    bas.decontract();
    elbas.add_element(bas.get_element(el,no));
    elbas.save_gaussian94(fileout);

  } else if(stricmp(cmd,"genbas")==0) {
    // Generate basis set for xyz file

    if(argc!=5) {
      printf("\nUsage: %s input.gbs genbas system.xyz output.gbs\n",argv[0]);
      return 1;
    }

    // Load atoms from xyz file
    std::vector<atom_t> atoms=load_xyz(argv[3]);
    // Output file
    std::string fileout(argv[4]);
    // Save output
    BasisSetLibrary elbas;

    // Collect elements
    std::vector<ElementBasisSet> els=bas.get_elements();
    // Loop over atoms in system
    for(size_t iat=0;iat<atoms.size();iat++) {
      bool found=false;

      // First, check if there is a special basis for the atom.
      for(size_t iel=0;iel<els.size();iel++)
	if(stricmp(atoms[iat].el,els[iel].get_symbol())==0 && atoms[iat].num == els[iel].get_number()) {
	  // Yes, add it.
	  elbas.add_element(els[iel]);
	  found=true;
	  break;
	}

      // Otherwise, check if a general basis is already in the basis
      if(!found) {
	std::vector<ElementBasisSet> added=elbas.get_elements();
	for(size_t j=0;j<added.size();j++)
	  if(added[j].get_number()==0 && stricmp(atoms[iat].el,added[j].get_symbol())==0)
	    found=true;
      }

      // If general basis not found, add it.
      if(!found) {
	for(size_t iel=0;iel<els.size();iel++)
	  if(stricmp(atoms[iat].el,els[iel].get_symbol())==0 && els[iel].get_number()==0) {
	    // Yes, add it.
	    elbas.add_element(els[iel]);
	    found=true;
	    break;
	  }
      }

      if(!found) {
	std::ostringstream oss;
	oss << "Basis set for element " << atoms[iat].el << " does not exist in " << filein << "!\n";
	throw std::runtime_error(oss.str());
      }
    }
    elbas.save_gaussian94(fileout);

  } else if(stricmp(cmd,"merge")==0) {
    // Merge functions with too big overlap

    if(argc!=5) {
      printf("\nUsage: %s input.gbs merge cutoff output.gbs\n",argv[0]);
      return 1;
    }

    // Cutoff value
    double cutoff=atof(argv[3]);
    bas.merge(cutoff);
    bas.save_gaussian94(argv[4]);

  } else if(stricmp(cmd,"norm")==0) {
    // Normalize basis

    if(argc!=4) {
      printf("\nUsage: %s input.gbs norm output.gbs\n",argv[0]);
      return 1;
    }

    std::string fileout=argv[3];
    bas.normalize();
    bas.save_gaussian94(fileout);

  } else if(stricmp(cmd,"orth")==0) {
    // Orthogonalize basis

    if(argc!=4) {
      printf("\nUsage: %s input.gbs orth output.gbs\n",argv[0]);
      return 1;
    }

    std::string fileout=argv[3];
    bas.orthonormalize();
    bas.save_gaussian94(fileout);

  } else if(stricmp(cmd,"overlap")==0) {
    // Primitive overlap

    if(argc!=4) {
      printf("\nUsage: %s input.gbs overlap element\n",argv[0]);
      return 1;
    }

    // Get element basis set
    ElementBasisSet elbas=bas.get_element(argv[3]);
    elbas.decontract();

    // Loop over angular momentum
    for(int am=0;am<=elbas.get_max_am();am++) {
      // Get primitives
      arma::vec exps;
      arma::mat contr;
      elbas.get_primitives(exps,contr,am);

      // Compute overlap matrix
      arma::mat S=overlap(exps,exps,am);

      // Print out overlap
      printf("*** %c shell ***\n",shell_types[am]);
      exps.t().print("Exponents");
      printf("\n");

      S.print("Overlap");
      printf("\n");
    }

  } else if(stricmp(cmd,"Porth")==0) {
    // P-orthogonalize basis

    if(argc!=6) {
      printf("\nUsage: %s input.gbs Porth cutoff Cortho output.gbs\n",argv[0]);
      return 1;
    }

    double cutoff=atof(argv[3]);
    double Cortho=atof(argv[4]);
    std::string fileout=argv[5];
    bas.P_orthogonalize(cutoff,Cortho);
    bas.save_gaussian94(fileout);

  } else if(stricmp(cmd,"prodset")==0) {
    // Generate product set
    
    if(argc!=6) {
      printf("\nUsage: %s input.gbs prodset lval fsam output.gbs\n",argv[0]);
      return 1;
    }

    int lval(atoi(argv[3]));
    double fsam(atof(argv[4]));
    std::string fileout(argv[5]);
    BasisSetLibrary dfit(bas.product_set(lval,fsam));
    dfit.save_gaussian94(fileout);
    
  } else if(stricmp(cmd,"save")==0) {
    // Save basis

    if(argc!=4) {
      printf("\nUsage: %s input.gbs save output.gbs\n",argv[0]);
      return 1;
    }

    std::string fileout=argv[3];
    bas.save_gaussian94(fileout);

  } else if(stricmp(cmd,"savecfour")==0) {
    // Save basis in CFOUR format

    if(argc!=5) {
      printf("\nUsage: %s input.gbs savecfour name basis.cfour\n",argv[0]);
      return 1;
    }

    std::string fileout=argv[3];
    std::string name=argv[4];
    bas.save_cfour(name,fileout);

  } else if(stricmp(cmd,"savedalton")==0) {
    // Save basis in Dalton format

    if(argc!=4) {
      printf("\nUsage: %s input.gbs savedalton output.dal\n",argv[0]);
      return 1;
    }

    std::string fileout=argv[3];
    bas.save_dalton(fileout);

  } else if(stricmp(cmd,"savemolpro")==0) {
    // Save basis in Molpro format

    if(argc!=4) {
      printf("\nUsage: %s input.gbs savemolpro output.mol\n",argv[0]);
      return 1;
    }

    std::string fileout=argv[3];
    bas.save_molpro(fileout);

  } else if(stricmp(cmd,"sort")==0) {
    // Sort basis set

    if(argc!=4) {
      printf("\nUsage: %s input.gbs sort output.gbs\n",argv[0]);
      return 1;
    }

    std::string fileout=argv[3];
    bas.sort();
    bas.save_gaussian94(fileout);
  } else {
    printf("\nInvalid command.\n");

    help();
  }

  return 0;
}
Exemple #6
0
int main(int argc, char **argv) {

#ifdef _OPENMP
  printf("ERKALE - Casida from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads());
#else
  printf("ERKALE - Casida from Hel, serial version.\n");
#endif
  print_copyright();
  print_license();
#ifdef SVNRELEASE
  printf("At svn revision %s.\n\n",SVNREVISION);
#endif
  print_hostname();

  if(argc!=1 && argc!=2) {
    printf("Usage: $ %s (runfile)\n",argv[0]);
    return 0;
  }

  // Initialize libint
  init_libint_base();

  Timer t;
  t.print_time();

  // Parse settings
  Settings set;
  set.add_string("FittingBasis","Basis set to use for density fitting (Auto for automatic)","Auto");
  set.add_string("CasidaX","Exchange functional for Casida","lda_x");
  set.add_string("CasidaC","Correlation functional for Casida","lda_c_vwn");
  set.add_bool("CasidaPol","Perform polarized Casida calculation (when using restricted wf)",false);
  set.add_int("CasidaCoupling","Coupling mode: 0 for IPA, 1 for RPA and 2 for TDLDA",2);
  set.add_double("CasidaTol","Tolerance for Casida grid",1e-4);
  set.add_string("CasidaStates","States to include in Casida calculation, eg ""1,3:7,10,13"" ","");
  set.add_string("CasidaQval","Values of Q to compute spectrum for","");
  set.add_string("LoadChk","Checkpoint to load","erkale.chk");

  if(argc==2)
    set.parse(std::string(argv[1]));
  else
    printf("\nDefault settings used.");

  // Print settings
  set.print();

  // Get functional strings
  int xfunc=find_func(set.get_string("CasidaX"));
  int cfunc=find_func(set.get_string("CasidaC"));

  if(is_correlation(xfunc))
    throw std::runtime_error("Refusing to use a correlation functional as exchange.\n");
  if(is_kinetic(xfunc))
    throw std::runtime_error("Refusing to use a kinetic energy functional as exchange.\n");
  if(is_exchange(cfunc))
    throw std::runtime_error("Refusing to use an exchange functional as correlation.\n");
  if(is_kinetic(cfunc))
    throw std::runtime_error("Refusing to use a kinetic energy functional as correlation.\n");
  set.add_int("CasidaXfunc","Internal variable",xfunc);
  set.add_int("CasidaCfunc","Internal variable",cfunc);

  // Print information about used functionals
  print_info(xfunc,cfunc);

  // Get values of q to compute spectrum for
  std::vector<double> qvals=parse_range_double(set.get_string("CasidaQval"));

  // Load checkpoint
  std::string fchk=set.get_string("LoadChk");
  Checkpoint chkpt(fchk,false);

  // Check that calculation was converged
  bool conv;
  chkpt.read("Converged",conv);
  if(!conv)
    throw std::runtime_error("Refusing to run Casida calculation based on a non-converged SCF density!\n");

  // Parse input states
  std::string states=set.get_string("CasidaStates");
  std::string newstates=parse_states(chkpt,states);
  set.set_string("CasidaStates",newstates);
  if(states.compare(newstates)!=0)
    printf("CasidaStates has been parsed to \"%s\".\n",newstates.c_str());

  // Load basis set
  BasisSet basis;
  chkpt.read(basis);

  Casida cas;
  bool restr;
  chkpt.read("Restricted",restr);

  if(restr) {
    // Load energy and orbitals
    arma::mat C, P;
    arma::vec E;
    std::vector<double> occs;

    chkpt.read("P",P);
    chkpt.read("C",C);
    chkpt.read("E",E);
    chkpt.read("occs",occs);

    // Check orthonormality
    check_orth(C,basis.overlap(),false);

    if(set.get_bool("CasidaPol")) {
      // Half occupancy (1.0 instead of 2.0)
      std::vector<double> hocc(occs);
      for(size_t i=0;i<hocc.size();i++)
	hocc[i]/=2.0;
      cas=Casida(set,basis,E,E,C,C,P/2.0,P/2.0,hocc,hocc);
    }
    else
      cas=Casida(set,basis,E,C,P,occs);

  } else {
    arma::mat Ca, Cb;
    arma::mat Pa, Pb;
    arma::vec Ea, Eb;
    std::vector<double> occa, occb;

    chkpt.read("Pa",Pa);
    chkpt.read("Pb",Pb);
    chkpt.read("Ca",Ca);
    chkpt.read("Cb",Cb);
    chkpt.read("Ea",Ea);
    chkpt.read("Eb",Eb);
    chkpt.read("occa",occa);
    chkpt.read("occb",occb);

    // Check orthonormality
    check_orth(Ca,basis.overlap(),false);
    check_orth(Cb,basis.overlap(),false);

    cas=Casida(set,basis,Ea,Eb,Ca,Cb,Pa,Pb,occa,occb);
  }

  // Dipole transition
  print_spectrum("casida.dat",cas.dipole_transition(basis));
  // Q dependent stuff
  for(size_t iq=0;iq<qvals.size();iq++) {
    // File to save output
    char fname[80];
    sprintf(fname,"casida-%.2f.dat",qvals[iq]);

    print_spectrum(fname,cas.transition(basis,qvals[iq]));
  }

  printf("\nRunning program took %s.\n",t.elapsed().c_str());
  t.print_time();

  return 0;
}
Exemple #7
0
int main(int argc, char **argv) {

#ifdef _OPENMP
  printf("ERKALE - Geometry optimization from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads());
#else
  printf("ERKALE - Geometry optimization from Hel, serial version.\n");
#endif
  print_copyright();
  print_license();
#ifdef SVNRELEASE
  printf("At svn revision %s.\n\n",SVNREVISION);
#endif
  print_hostname();

  if(argc!=2) {
    printf("Usage: $ %s runfile\n",argv[0]);
    return 0;
  }

  // Initialize libint
  init_libint_base();
  // Initialize libderiv
  init_libderiv_base();

  Timer tprog;
  tprog.print_time();

  // Parse settings
  Settings set;
  set.add_scf_settings();
  set.add_string("SaveChk","File to use as checkpoint","erkale.chk");
  set.add_string("LoadChk","File to load old results from","");
  set.add_bool("ForcePol","Force polarized calculation",false);
  set.add_bool("FreezeCore","Freeze the atomic cores?",false);
  set.add_string("Optimizer","Optimizer to use: CGFR, CGPR, BFGS, BFGS2 (default), SD","BFGS2");
  set.add_int("MaxSteps","Maximum amount of geometry steps",256);
  set.add_string("Criterion","Convergence criterion to use: LOOSE, NORMAL, TIGHT, VERYTIGHT","NORMAL");
  set.add_string("OptMovie","xyz movie to store progress in","optimize.xyz");
  set.add_string("Result","File to save optimized geometry in","optimized.xyz");
  set.set_string("Logfile","erkale_geom.log");
  set.parse(std::string(argv[1]),true);
  set.print();

  bool verbose=set.get_bool("Verbose");
  int maxiter=set.get_int("MaxSteps");
  std::string optmovie=set.get_string("OptMovie");
  std::string result=set.get_string("Result");

  // Interpret optimizer
  enum minimizer alg;
  std::string method=set.get_string("Optimizer");
  if(stricmp(method,"CGFR")==0)
    alg=gCGFR;
  else if(stricmp(method,"CGPR")==0)
    alg=gCGPR;
  else if(stricmp(method,"BFGS")==0)
    alg=gBFGS;
  else if(stricmp(method,"BFGS2")==0)
    alg=gBFGS2;
  else if(stricmp(method,"SD")==0)
    alg=gSD;
  else {
    ERROR_INFO();
    throw std::runtime_error("Unknown optimization method.\n");
  }

  // Interpret optimizer
  enum convergence crit;
  method=set.get_string("Criterion");
  if(stricmp(method,"LOOSE")==0)
    crit=LOOSE;
  else if(stricmp(method,"NORMAL")==0)
    crit=NORMAL;
  else if(stricmp(method,"TIGHT")==0)
    crit=TIGHT;
  else if(stricmp(method,"VERYTIGHT")==0)
    crit=VERYTIGHT;
  else {
    ERROR_INFO();
    throw std::runtime_error("Unknown optimization method.\n");
  }

  // Redirect output?
  std::string logfile=set.get_string("Logfile");
  if(stricmp(logfile,"stdout")!=0) {
    // Redirect stdout to file
    FILE *outstream=freopen(logfile.c_str(),"w",stdout);
    if(outstream==NULL) {
      ERROR_INFO();
      throw std::runtime_error("Unable to redirect output!\n");
    } else
      fprintf(stderr,"\n");
  }

  // Read in atoms.
  std::string atomfile=set.get_string("System");
  const std::vector<atom_t> origgeom=load_xyz(atomfile);
  std::vector<atom_t> atoms(origgeom);

  // Are any atoms fixed?
  std::vector<size_t> dofidx;
  for(size_t i=0;i<atoms.size();i++) {
    bool fixed=false;

    if(atoms[i].el.size()>3)
      if(stricmp(atoms[i].el.substr(atoms[i].el.size()-3),"-Fx")==0) {
	fixed=true;
	atoms[i].el=atoms[i].el.substr(0,atoms[i].el.size()-3);
      }

    // Add to degrees of freedom
    if(!fixed)
      dofidx.push_back(i);
  }

  // Read in basis set
  BasisSetLibrary baslib;
  std::string basfile=set.get_string("Basis");
  baslib.load_gaussian94(basfile);
  printf("\n");

  // Save to output
  save_xyz(atoms,"Initial configuration",optmovie,false);

  // Minimizer options
  opthelper_t pars;
  pars.atoms=atoms;
  pars.baslib=baslib;
  pars.set=set;
  pars.dofidx=dofidx;

  /* Starting point */
  gsl_vector *x = gsl_vector_alloc (3*dofidx.size());
  for(size_t i=0;i<dofidx.size();i++) {
    gsl_vector_set(x,3*i,atoms[dofidx[i]].x);
    gsl_vector_set(x,3*i+1,atoms[dofidx[i]].y);
    gsl_vector_set(x,3*i+2,atoms[dofidx[i]].z);
  }

  // GSL status
  int status;

  const gsl_multimin_fdfminimizer_type *T;
  gsl_multimin_fdfminimizer *s;

  gsl_multimin_function_fdf minimizer;

  minimizer.n = x->size;
  minimizer.f = calc_E;
  minimizer.df = calc_f;
  minimizer.fdf = calc_Ef;
  minimizer.params = (void *) &pars;

  if(alg==gCGFR) {
    T = gsl_multimin_fdfminimizer_conjugate_fr;
    if(verbose) printf("Using Fletcher-Reeves conjugate gradients.\n");
  } else if(alg==gCGPR) {
    T = gsl_multimin_fdfminimizer_conjugate_pr;
    if(verbose) printf("Using Polak-Ribière conjugate gradients.\n");
  } else if(alg==gBFGS) {
    T = gsl_multimin_fdfminimizer_vector_bfgs;
    if(verbose) printf("Using the BFGS minimizer.\n");
  } else if(alg==gBFGS2) {
    T = gsl_multimin_fdfminimizer_vector_bfgs2;
    if(verbose) printf("Using the BFGS2 minimizer.\n");
  } else if(alg==gSD) {
    T = gsl_multimin_fdfminimizer_steepest_descent;
    if(verbose) printf("Using the steepest descent minimizer.\n");
  } else {
    ERROR_INFO();
    throw std::runtime_error("Unsupported minimizer\n");
  }

  // Run an initial calculation
  double oldE=calc_E(x,minimizer.params);

  // Turn off verbose setting
  pars.set.set_bool("Verbose",false);
  // and load from old checkpoint
  pars.set.set_string("LoadChk",pars.set.get_string("SaveChk"));

  // Initialize minimizer
  s = gsl_multimin_fdfminimizer_alloc (T, minimizer.n);

  // Use initial step length of 0.02 bohr, and a line search accuracy
  // 1e-1 (recommended in the GSL manual for BFGS)
  gsl_multimin_fdfminimizer_set (s, &minimizer, x, 0.02, 1e-1);

  // Store old force
  arma::mat oldf=interpret_force(s->gradient);

  fprintf(stderr,"Geometry optimizer initialized in %s.\n",tprog.elapsed().c_str());
  fprintf(stderr,"Entering minimization loop with %s optimizer.\n",set.get_string("Optimizer").c_str());

  fprintf(stderr,"%4s %16s %10s %10s %9s %9s %9s %9s %s\n","iter","E","dE","dE/dEproj","disp max","disp rms","f max","f rms", "titer");

  std::vector<atom_t> oldgeom(atoms);

  bool convd=false;
  int iter;

  for(iter=1;iter<=maxiter;iter++) {
    printf("\nGeometry iteration %i\n",(int) iter);
    fflush(stdout);

    Timer titer;

    status = gsl_multimin_fdfminimizer_iterate (s);

    if (status) {
      fprintf(stderr,"GSL encountered error: \"%s\".\n",gsl_strerror(status));
      break;
    }

    // New geometry is
    std::vector<atom_t> geom=get_atoms(s->x,pars);

    // Calculate displacements
    double dmax, drms;
    get_displacement(geom, oldgeom, dmax, drms);

    // Calculate projected change of energy
    double dEproj=calculate_projection(geom,oldgeom,oldf,pars.dofidx);
    // Actual change of energy is
    double dE=s->f - oldE;

    // Switch geometries
    oldgeom=geom;
    // Save old force

    // Get forces
    double fmax, frms;
    get_forces(s->gradient, fmax, frms);

    // Save geometry step
    char comment[80];
    sprintf(comment,"Step %i",(int) iter);
    save_xyz(get_atoms(s->x,pars),comment,optmovie,true);

    // Check convergence
    bool fmaxconv=false, frmsconv=false;
    bool dmaxconv=false, drmsconv=false;

    switch(crit) {

    case(LOOSE):
      if(fmax < 2.5e-3)
	fmaxconv=true;
      if(frms < 1.7e-3)
	frmsconv=true;
      if(dmax < 1.0e-2)
	dmaxconv=true;
      if(drms < 6.7e-3)
	drmsconv=true;
      break;

    case(NORMAL):
      if(fmax < 4.5e-4)
	fmaxconv=true;
      if(frms < 3.0e-4)
	frmsconv=true;
      if(dmax < 1.8e-3)
	dmaxconv=true;
      if(drms < 1.2e-3)
	drmsconv=true;
      break;

    case(TIGHT):
      if(fmax < 1.5e-5)
	fmaxconv=true;
      if(frms < 1.0e-5)
	frmsconv=true;
      if(dmax < 6.0e-5)
	dmaxconv=true;
      if(drms < 4.0e-5)
	drmsconv=true;
      break;

    case(VERYTIGHT):
      if(fmax < 2.0e-6)
	fmaxconv=true;
      if(frms < 1.0e-6)
	frmsconv=true;
      if(dmax < 6.0e-6)
	dmaxconv=true;
      if(drms < 4.0e-6)
	drmsconv=true;
      break;

    default:
      ERROR_INFO();
      throw std::runtime_error("Not implemented!\n");
    }

    // Converged?
    const static char cconv[]=" *";

    double dEfrac;
    if(dEproj!=0.0)
      dEfrac=dE/dEproj;
    else
      dEfrac=0.0;

    fprintf(stderr,"%4d % 16.8f % .3e % .3e %.3e%c %.3e%c %.3e%c %.3e%c %s\n", (int) iter, s->f, dE, dEfrac, dmax, cconv[dmaxconv], drms, cconv[drmsconv], fmax, cconv[fmaxconv], frms, cconv[frmsconv], titer.elapsed().c_str());
    fflush(stderr);

    convd=dmaxconv && drmsconv && fmaxconv && frmsconv;

    if(convd) {
      fprintf(stderr,"Converged.\n");
      break;
    }

    // Store old energy
    oldE=s->f;
    // Store old force
    oldf=interpret_force(s->gradient);
  }

  if(convd)
    save_xyz(get_atoms(s->x,pars),"Optimized geometry",result);

  gsl_multimin_fdfminimizer_free (s);

  gsl_vector_free (x);

  if(iter==maxiter && !convd) {
    printf("Geometry convergence was not achieved!\n");
  }


  printf("Running program took %s.\n",tprog.elapsed().c_str());

  return 0;
}
Exemple #8
0
int main(int argc, char **argv) {

#ifdef _OPENMP
  printf("ERKALE - EMD from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads());
#else
  printf("ERKALE - EMD from Hel, serial version.\n");
#endif
  print_copyright();
  print_license();
#ifdef SVNRELEASE
  printf("At svn revision %s.\n\n",SVNREVISION);
#endif
  print_hostname();

  if(argc!=1 && argc!=2) {
    printf("Usage: $ %s (runfile)\n",argv[0]);
    return 0;
  }

  Timer t;

  // Parse settings
  Settings set;
  set.add_string("LoadChk","Checkpoint file to load density from","erkale.chk");
  set.add_bool("DoEMD", "Perform calculation of isotropic EMD (moments of EMD, Compton profile)", true);
  set.add_double("EMDTol", "Tolerance for the numerical integration of the radial EMD",1e-8);
  set.add_string("EMDlm", "Which projection of the radial EMD to compute","");
  set.add_bool("EMDAdapt", "Use adaptive grid to compute EMD?", true);
  set.add_string("EMDCube", "Calculate EMD on a cube? e.g. -10:.3:10 -5:.2:4 -2:.1:3", "");
  set.add_string("EMDOrbitals", "Compute EMD of given orbitals, e.g. 1,2,4:6","");
  set.add_string("Similarity", "Compute similarity measure to checkpoint","");
  set.add_string("SimilarityGrid", "Grid to use for computing similarity integrals","500 77");
  set.add_bool("SimilarityLM", "Seminumerical computation of similarity integrals?", false);
  set.add_int("SimilarityLmax", "Maximum angular momentum for seminumerical computation", 6);

  if(argc==2)
    set.parse(argv[1]);
  else
    printf("Using default settings.\n");
  set.print();

  // Get the tolerance
  double tol=set.get_double("EMDTol");

  // Load checkpoint
  Checkpoint chkpt(set.get_string("LoadChk"),false);

  // Load basis set
  BasisSet basis;
  chkpt.read(basis);

  // Load density matrix
  arma::cx_mat P;
  arma::mat Pr, Pi;
  chkpt.read("P",Pr);
  if(chkpt.exist("P_im")) {
    chkpt.read("P_im",Pi);
    P=Pr*COMPLEX1 + Pi*COMPLEXI;
  } else
    P=Pr*COMPLEX1;
  
  // The projection to calculate
  int l=0, m=0;
  std::string lmstr=set.get_string("EMDlm");
  if(lmstr.size()) {
    // Get l and m values
    std::vector<std::string> lmval=splitline(lmstr);
    if(lmval.size()!=2)
      throw std::runtime_error("Invalid specification of l and m values.\n");
    l=readint(lmval[0]);
    m=readint(lmval[1]);
  }
  bool adaptive=set.get_bool("EMDAdapt");

  // Compute orbital EMDs?
  if(set.get_string("EMDOrbitals")!="") {
    // Get orbitals
    std::vector<std::string> orbs=splitline(set.get_string("EMDOrbitals"));

    // Polarized calculation?
    bool restr;
    chkpt.read("Restricted",restr);
    if(restr!= (orbs.size()==1))
      throw std::runtime_error("Invalid occupancies for spin alpha and beta!\n");

    if(l!=0)
      printf("\nComputing the (%i %+i) projection of the orbital EMD.\n",l,m);

    for(size_t ispin=0;ispin<orbs.size();ispin++) {
      // Indices of orbitals to include.
      std::vector<size_t> idx=parse_range(orbs[ispin]);
      // Change into C++ indexing
      for(size_t i=0;i<idx.size();i++)
	idx[i]--;

      // Read orbitals
      arma::mat C;
      if(restr)
	chkpt.read("C",C);
      else {
	if(ispin==0)
	  chkpt.read("Ca",C);
	else
	  chkpt.read("Cb",C);
      }

      for(size_t i=0;i<idx.size();i++) {
	// Names of output files
	char emdname[80];
	char momname[80];
	char Jname[80];
	char Jintname[80];

	char suffix[80];
	if(l==0)
	  sprintf(suffix,".txt");
	else
	  sprintf(suffix,"_%i_%i.txt",l,m);

	if(restr) {
	  sprintf(emdname,"emd-%i%s",(int) idx[i]+1,suffix);
	  sprintf(momname,"moments-%i%s",(int) idx[i]+1,suffix);
	  sprintf(Jname,"compton-%i%s",(int) idx[i]+1,suffix);
	  sprintf(Jintname,"compton-interp-%i%s",(int) idx[i]+1,suffix);
	} else {
	  if(ispin==0) {
	    sprintf(emdname,"emd-a-%i%s",(int) idx[i]+1,suffix);
	    sprintf(momname,"moments-a-%i%s",(int) idx[i]+1,suffix);
	    sprintf(Jname,"compton-a-%i%s",(int) idx[i]+1,suffix);
	    sprintf(Jintname,"compton-interp-a-%i%s",(int) idx[i]+1,suffix);
	  } else {
	    sprintf(emdname,"emd-b-%i%s",(int) idx[i]+1,suffix);
	    sprintf(momname,"moments-b-%i%s",(int) idx[i]+1,suffix);
	    sprintf(Jname,"compton-b-%i%s",(int) idx[i]+1,suffix);
	    sprintf(Jintname,"compton-interp-b-%i%s",(int) idx[i]+1,suffix);
	  }
	}

	// Generate dummy density matrix
	arma::cx_mat Pdum=C.col(idx[i])*arma::trans(C.col(idx[i]))*COMPLEX1;

	Timer temd;

	GaussianEMDEvaluator *poseval=new GaussianEMDEvaluator(basis,Pdum,l,std::abs(m));
	GaussianEMDEvaluator *negeval;
	if(m!=0)
	  negeval=new GaussianEMDEvaluator(basis,Pdum,l,-std::abs(m));
	else
	  negeval=NULL;

	EMD emd(poseval, negeval, 1, l, m);
	if(adaptive) {
	  emd.initial_fill();
	  if(l==0 && m==0) emd.find_electrons();
	  emd.optimize_moments(true,tol);
	} else
	  emd.fixed_fill();

	emd.save(emdname);
	emd.moments(momname);
	if(l==0 && m==0) {
	  emd.compton_profile(Jname);
	  emd.compton_profile_interp(Jintname);
	}

	delete poseval;
	if(m!=0) delete negeval;
      }
    }
  }

  if(set.get_bool("DoEMD")) {
    t.print_time();

    printf("\nCalculating EMD properties.\n");
    printf("Please read and cite the reference:\n%s\n%s\n%s\n",	\
	   "J. Lehtola, M. Hakala, J. Vaara and K. Hämäläinen",		\
	   "Calculation of isotropic Compton profiles with Gaussian basis sets", \
	   "Phys. Chem. Chem. Phys. 13 (2011), pp. 5630 - 5641.");

    if(l!=0)
      printf("\nComputing the (%i %+i) projection of the EMD.\n",l,m);
    else
      printf("\nComputing the isotropic projection of the EMD.\n");

    // Amount of electrons is
    int Nel;
    chkpt.read("Nel",Nel);

    // Construct EMD evaluators
    Timer temd;
    GaussianEMDEvaluator *poseval=new GaussianEMDEvaluator(basis,P,l,std::abs(m));
    GaussianEMDEvaluator *negeval;
    if(m!=0)
      negeval=new GaussianEMDEvaluator(basis,P,l,-std::abs(m));
    else
      negeval=NULL;

    temd.set();
    EMD emd(poseval, negeval, Nel, l, m);
    if(adaptive) {
      emd.initial_fill();
      if(l==0 && m==0) emd.find_electrons();
      emd.optimize_moments(true,tol);
    } else
      emd.fixed_fill();

    if(l==0 && m==0) {
      emd.save("emd.txt");
      emd.moments("moments.txt");
      emd.compton_profile("compton.txt");
      emd.compton_profile_interp("compton-interp.txt");
    } else {
      char fname[80];
      sprintf(fname,"emd_%i_%i.txt",l,m);
      emd.save(fname);

      sprintf(fname,"moments_%i_%i.txt",l,m);
      emd.moments(fname);
    }

    if(l==0 && m==0)
      printf("Calculating isotropic EMD properties took %s.\n",temd.elapsed().c_str());
    else
      printf("Calculating projected EMD properties took %s.\n",temd.elapsed().c_str());

    delete poseval;
    if(m!=0) delete negeval;
  }

  // Do EMD on a cube?
  if(stricmp(set.get_string("EMDCube"),"")!=0) {
    t.print_time();
    Timer temd;

    // Form grid in p space.
    std::vector<double> px, py, pz;
    parse_cube(set.get_string("EMDCube"),px,py,pz);

    // Calculate EMD on cube
    emd_cube(basis,P,px,py,pz);

    printf("Calculating EMD on a cube took %s.\n",temd.elapsed().c_str());
  }

  // Compute similarity?
  if(stricmp(set.get_string("Similarity"),"")!=0) {

    // Load checkpoint
    Checkpoint simchk(set.get_string("Similarity"),false);

    // Get grid size
    std::vector<std::string> gridsize=splitline(set.get_string("SimilarityGrid"));
    if(gridsize.size()!=2) {
      throw std::runtime_error("Invalid grid size!\n");
    }
    int nrad=readint(gridsize[0]);
    int lmax=readint(gridsize[1]);
    int radlmax=set.get_int("SimilarityLmax");

    // Load basis set
    BasisSet simbas;
    simchk.read(simbas);

    // Load density matrix
    arma::mat simPr, simPi;
    arma::cx_mat simP;
    simchk.read("P",simPr);
    if(simchk.exist("P_im")) {
      simchk.read("P_im",simPi);
      simP=simPr*COMPLEX1 + simPi*COMPLEXI;
    } else
      simP=simPr*COMPLEX1;
    
    // Compute momentum density overlap
    arma::cube ovl;
    if(set.get_bool("SimilarityLM"))
      ovl=emd_overlap_semi(basis,P,simbas,simP,nrad,radlmax);
    else
      ovl=emd_overlap(basis,P,simbas,simP,nrad,lmax);

    // Amount of electrons
    int Nela, Nelb;
    chkpt.read("Nel", Nela);
    simchk.read("Nel", Nelb);

    // Shape function overlap
    arma::cube sh=emd_similarity(ovl,Nela,Nelb);
    sh.slice(0).save("similarity.dat",arma::raw_ascii);
    sh.slice(1).save("similarity_avg.dat",arma::raw_ascii);

    for(int s=0;s<2;s++) {
      if(s) {
	printf("%2s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\n","k","S0(AA)","S0(BB)","S0(AB)","I0(AA)","I0(BB)","I0(AB)","D0(AB)");
	for(int k=-1;k<3;k++)
	  // Vandenbussche don't include p^2 in the spherical average
	  printf("%2i\t%e\t%e\t%e\t%e\t%e\t%e\t%e\n", k+1, sh(k+1,0,s), sh(k+1,1,s), sh(k+1,2,s), sh(k+1,3,s), sh(k+1,4,s), sh(k+1,5,s), sh(k+1,6,s));
      } else {
	printf("%2s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\n","k","S(AA)","S(BB)","S(AB)","I(AA)","I(BB)","I(AB)","D(AB)");
	for(int k=-1;k<3;k++)
	  printf("%2i\t%e\t%e\t%e\t%e\t%e\t%e\t%e\n", k, sh(k+1,0,s), sh(k+1,1,s), sh(k+1,2,s), sh(k+1,3,s), sh(k+1,4,s), sh(k+1,5,s), sh(k+1,6,s));
      }
      printf("\n");
    }
  }

  return 0;
}