Пример #1
0
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));
}
Пример #2
0
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);
  }
}
Пример #3
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));
}