void rhf_guess(double *F, double *H, double *P, double *S, double *X, double *C, double *E, Molecule_t *molecule, BasisFunc_t *bfns, int M) { int Nelecs = nelec(molecule); int guess_type; rtdb_get("scf:guess", &guess_type); printf("\nInitial guess: %s\n", guess_type == GUESS_EHT ? "extended Huckel theory" : "bare nuclei"); timer_new_entry("guess", "Initial guess"); timer_start("guess"); if (guess_type == GUESS_EHT) guess_F_eht(F, S, bfns, M); else memcpy(F, H, M*M*sizeof(double)); diag_fock(F, X, C, E, M); rhf_makedensity(P, C, Nelecs, M); // generate initial density guess timer_stop("guess"); printf("Initial energy = %.8f\n\n", rhf_energy(P, F, H, M)); }
void FATR util_debug_(Integer *rtdb) { pid_t child; char *argv[20]; char display[256], path[256], title[256], pid[256], xterm[256]; sprintf(title, "Debugging NWChem process %d", GA_Nodeid()); sprintf(pid, "%d", getpid()); if (!rtdb_get(*rtdb, "dbg:path", MT_CHAR, sizeof(path), path)) strcpy(path, "nwchem"); if (!rtdb_get(*rtdb, "dbg:xterm", MT_CHAR, sizeof(xterm), xterm)) xterm[0] = 0; if (!rtdb_get(*rtdb, "dbg:display", MT_CHAR, sizeof(display), display)) { char *disp = getenv("DISPLAY"); if (!disp) disp = "unix:0.0"; strcpy(display, disp); } argv[1] = "-T"; argv[2] = title; argv[3] = "-display"; argv[4] = display; argv[5] = "-e"; #if defined(SOLARIS) && !defined(FUJITSU_SOLARIS) argv[6] = "dbx"; argv[7] = path; argv[8] = pid; argv[9] = 0; if (!xterm[0]) strcpy(xterm, "/usr/openwin/bin/xterm"); #elif defined(AIX) || defined(IBM) || defined(IBMSP) || defined(LAPI) argv[6] = "dbx"; argv[7] = "-f"; argv[8] = "-a"; argv[9] = pid; argv[10] = 0; if (!xterm[0]) strcpy(xterm, "/usr/bin/X11/xterm"); #elif defined(IFCLINUX) && defined(LINUXIA64) argv[6] = "idb"; argv[7] = "-pid"; argv[8] = pid; argv[9] = path; argv[10] = 0; if (!xterm[0]) strcpy(xterm, "/usr/bin/X11/xterm"); #elif defined(LINUX) || defined(MACX) argv[6] = "gdb"; argv[7] = path; argv[8] = pid; argv[9] = 0; if (!xterm[0]) strcpy(xterm, "/usr/X11R6/bin/xterm"); #elif defined(HPUX) argv[6] = "gdb"; argv[7] = path; argv[8] = pid; argv[9] = 0; if (!xterm[0]) strcpy(xterm, "/usr/bin/X11/xterm"); #elif defined(SGI_N32) || defined(SGI) || defined(SGITFP) argv[6] = "dbx"; argv[7] = "-p"; argv[8] = pid; argv[9] = 0; if (!xterm[0]) strcpy(xterm, "/usr/bin/X11/xterm"); #else GA_Error("Don't know how to debug on this machine", 0); #endif argv[0] = xterm; if (GA_Nodeid() == 0) { int i; printf("\n Starting xterms with debugger using command\n\n "); for (i=0; argv[i]; i++) printf("'%s' ", argv[i]); printf("\n\n"); fflush(stdout); } GA_Sync(); child = fork(); if (child < 0) { GA_Error("util_debug: fork failed?", 0); } else if (child > 0) { sleep(5); /* Release cpu while debugger starts*/ } else { execv(xterm, argv); perror(""); GA_Error("util_debug: execv of xterm with debugger failed", 0); } }
void rhf_loop(Molecule_t *molecule, BasisFunc_t *bfns, int M) { int i, n, Nelecs; double t0; double hfe, olde, deltap; double diiserror; double *H; // core Hamiltonian double *S; // overlap double *X; // transformation to orthonormal basis, stored by rows double *F; // Fock matrix double *P; // density double *P0; // stored density from previous step double *C; // AO coefficients in MO double *E; // orbital energies double *ErrM;// error matrix, e=FDS-SDF int nbytes; // bytes in matrix to allocate int maxiter; // max # scf iterations int direct; // enable direct scf (1/0) int do_diis; // is diis enabled (0/1) int diisbas; // diis subspace dimension int molden_out; // print vectors to molden format or not double Enuc; // nuclei repulsion energy DIISList_t *diislist; // list with stored Fock and error matrices // read parameters from the rtdb rtdb_get("scf:maxiter", &maxiter); rtdb_get("scf:direct", &direct ); rtdb_get("scf:diis", &do_diis); rtdb_get("scf:diisbas", &diisbas); rtdb_get("visual:molden", &molden_out); n = 1; // iteration number 1 t0 = MPI_Wtime(); nbytes = M * M * sizeof(double); diislist = NULL; Enuc = enuc(molecule); Nelecs = nelec(molecule); H = (double *) qalloc(nbytes); S = (double *) qalloc(nbytes); X = (double *) qalloc(nbytes); F = (double *) qalloc(nbytes); P = (double *) qalloc(nbytes); P0= (double *) qalloc(nbytes); C = (double *) qalloc(nbytes); E = (double *) qalloc(M*sizeof(double)); // compute core Hamiltonian and overlap matrices read_1e_integrals(H, S, bfns, M); // basis orthogonalization orthobasis(S, X, M); // guess rhf_guess(F, H, P, S, X, C, E, molecule, bfns, M); olde = rhf_energy(P, F, H, M) + Enuc; printf(" iter. Energy Delta E RMS-Dens DIIS-Err time\n"); printf("----------------------------------------------------------------------------\n"); while (1) { if (n > maxiter) { printf("----------------------------------------------------------------------------\n"); printf(" not converged!\n"); errquit("no convergence of SCF equations! Try to increase scf:maxiter\n"); } memcpy(P0, P, nbytes); // store actual P if (direct) { // integral-direct rhf_makefock_direct(F, H, P, bfns, M); } else { // conventional scf (2e int-s from disk) rhf_makefock(F, H, P, M); } // in fact, now we have Fi and Di, used to contruct this Fi ErrM = (double *) qalloc(nbytes); make_error_matrix(ErrM, F, P, S, M); diiserror = maxerr(ErrM, M); // if DIIS is enabled if (do_diis && diisbas != 0) { if (!diislist) diislist = newDIISList(ErrM, F, M); else diis_store(diislist, ErrM, F, M, diisbas); // extrapolate new F: diis_extrapolate(F, diislist, diisbas); } diag_fock(F, X, C, E, M); rhf_makedensity(P, C, Nelecs, M); deltap = rmsdens(P, P0, M); hfe = rhf_energy(P, F, H, M) + Enuc; printf("%4d%17.8f%15.8f%15.8f%15.8f%8.2f\n", n, hfe, hfe-olde, deltap, diiserror, MPI_Wtime()-t0); if (deltap < 1e-6) break; olde = hfe; n++; } printf("----------------------------------------------------------------------------\n"); printf(" Total SCF energy =%15.8f\n", hfe); printf(" Nuclear repulsion energy =%15.8f\n", Enuc); printf("\n\n"); /* save results to rtdb */ rtdb_set("scf:etot", "%d", hfe); rtdb_set("scf:enuc", "%d", Enuc); // Освобождение ресурсов, которые были заняты DIIS if (do_diis && diislist) removeDIISList(diislist); // Вывод результатов // Энергии орбиталей printf("\n"); printf(" Molecular Orbitals Summary\n"); printf(" +-----+-----+----------------+----------+\n"); printf(" | No | Occ | Energy | Symmetry |\n"); printf(" +-----+-----+----------------+----------+\n"); for (i = 0; i < M; i++) printf(" | %-3d | %1d | %14.8f | ? |\n", i+1, (i < Nelecs/2) ? 2 : 0, E[i]); printf(" +-----+-----+----------------+----------+\n"); // Вывод векторов в файл в формате Molden if (molden_out) { int i; int *occ = (int *) qalloc(sizeof(int) * M); memset(occ, 0, sizeof(int) * M); for (i = 0; i < Nelecs/2; i++) occ[i] = 2; vectors_molden(molecule, C, E, occ, M); qfree(occ, sizeof(int) * M); } // population analysis mulliken(molecule, bfns, P, S, M); loewdin (molecule, bfns, P, S, M); // properties scf_properties_rhf(molecule, P, M); qfree(H, nbytes); qfree(S, nbytes); qfree(X, nbytes); qfree(F, nbytes); qfree(P, nbytes); qfree(P0,nbytes); qfree(C, nbytes); qfree(E, M*sizeof(double)); }