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; }
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; }
Session::Session(int fd_, const sockaddr_in& sender_) : fd(fd_), sender(sender_), aes {}, authenticated(false), lb {}, ip(print_ip()), hostname(print_hostname()) { }
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; }
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; }
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; }
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; }