Example #1
0
double df1dim(double x)
{
	int j;
	double df1=0.0;
	matrix xt=NULL,df=NULL;

	alloc_mtx(&xt,dncom,1);
	alloc_mtx(&df,dncom,1);

	for (j=1;j<=dncom;j++) xt[j][1]=dpcom[j][1]+x*dxicom[j][1];
	(*nrdfun)(xt,df);
	for (j=1;j<=dncom;j++) df1 += df[j][1]*dxicom[j][1];
	free_mtx(&df);
	free_mtx(&xt);
	return (df1);
}
Example #2
0
File: vdw.c Project: tidatida/mpmc
//calculate energies for isolated molecules
//if we don't know it, calculate it and save the value
double calc_e_iso ( system_t * system, double * sqrtKinv, molecule_t * mptr ) {
    int nstart, nsize; // , curr_dimM;  (unused variable)
    double e_iso; //total vdw energy of isolated molecules
    struct mtx * Cm_iso; //matrix Cm_isolated
    double * eigvals; //eigenvalues of Cm_cm
    molecule_t * molecule_ptr;
    atom_t * atom_ptr;

    nstart=nsize=0; //loop through each individual molecule
    for ( molecule_ptr = system->molecules; molecule_ptr; molecule_ptr=molecule_ptr->next ) {
        if ( molecule_ptr != mptr ) {  //count atoms then skip to next molecule
            for ( atom_ptr = molecule_ptr->atoms; atom_ptr; atom_ptr = atom_ptr->next ) nstart++;
            continue;
        }

        //now that we've found the molecule of interest, count natoms, and calc energy
        for ( atom_ptr = molecule_ptr->atoms; atom_ptr; atom_ptr = atom_ptr->next ) nsize++;

        //build matrix for calculation of vdw energy of isolated molecule
        Cm_iso = build_M(3*(nsize), 3*nstart, system->A_matrix, sqrtKinv);
        //diagonalize M and extract eigenvales -> calculate energy
        eigvals=lapack_diag(Cm_iso,1); //no eigenvectors
        e_iso=eigen2energy(eigvals,Cm_iso->dim,system->temperature);

        //free memory
        free(eigvals);
        free_mtx(Cm_iso);

        //convert a.u. -> s^-1 -> K
        return e_iso * au2invsec * halfHBAR ;
    }

    //unmatched molecule
    return NAN; //we should never get here
}
Example #3
0
File: vdw.c Project: tidatida/mpmc
//returns interaction VDW energy
double vdw(system_t *system) {

    int N; //  dimC;  (unused variable)  //number of atoms, number of non-zero rows in C-Matrix
    double e_total, e_iso; //total energy, isolation energy (atoms @ infinity)
    double * sqrtKinv; //matrix K^(-1/2); cholesky decomposition of K
    double ** Am = system->A_matrix; //A_matrix
    struct mtx * Cm; //C_matrix (we use single pointer due to LAPACK requirements)
    double * eigvals; //eigenvales
    double fh_corr, lr_corr;

    N=system->natoms;

    //allocate arrays. sqrtKinv is a diagonal matrix. d,e are used for matrix diag.
    sqrtKinv = getsqrtKinv(system,N);

    //calculate energy vdw of isolated molecules
    e_iso = sum_eiso_vdw ( system, sqrtKinv );

    //Build the C_Matrix
    Cm = build_M (3*N, 0, Am, sqrtKinv);

    //setup and use lapack diagonalization routine dsyev_()
    eigvals = lapack_diag (Cm, system->polarvdw); //eigenvectors if system->polarvdw == 2
    if ( system->polarvdw == 2 )
        printevects(Cm);

    //return energy in inverse time (a.u.) units
    e_total = eigen2energy(eigvals, Cm->dim, system->temperature);
    e_total *= au2invsec * halfHBAR; //convert a.u. -> s^-1 -> K

    //vdw energy comparison
    if ( system->polarvdw == 3 )
        printf("VDW Two-Body | Many Body = %lf | %lf\n", twobody(system),e_total-e_iso);

    if ( system->feynman_hibbs ) {
        if ( system->vdw_fh_2be ) fh_corr = fh_vdw_corr_2be(system); //2be method
        else fh_corr = fh_vdw_corr(system); //mpfd
    }
    else fh_corr=0;

    if ( system->rd_lrc ) lr_corr = lr_vdw_corr(system);
    else lr_corr=0;

//cleanup and return
    free(sqrtKinv);
    free(eigvals);
    free_mtx(Cm);

    return e_total - e_iso + fh_corr + lr_corr;

}
Example #4
0
File: vdw.c Project: tidatida/mpmc
//calculate T matrix element for a particular separation
double e2body(system_t * system, atom_t * atom, pair_t * pair, double r) {
    double energy;
    double lr = system->polar_damp * r;
    double lr2 = lr*lr;
    double lr3 = lr*lr2;
    double Txx = pow(r,-3)*(-2.0+(0.5*lr3+lr2+2*lr+2)*exp(-lr));
    double Tyy = pow(r,-3)*(1-(0.5*lr2+lr+1)*exp(-lr));
    double * eigvals;
    struct mtx * M = alloc_mtx(6);

    //only the sub-diagonals are non-zero
    M->val[1]=M->val[2]=M->val[4]=M->val[5]=M->val[6]=M->val[8]=M->val[9]=M->val[11]=0;
    M->val[12]=M->val[13]=M->val[15]=M->val[16]=M->val[19]=M->val[20]=M->val[22]=M->val[23]=0;
    M->val[24]=M->val[26]=M->val[27]=M->val[29]=M->val[30]=M->val[31]=M->val[33]=M->val[34]=0;

    //true diagonals
    M->val[0]=M->val[7]=M->val[14]=(atom->omega)*(atom->omega);
    M->val[21]=M->val[28]=M->val[35]=(pair->atom->omega)*(pair->atom->omega);

    //sub-diagonals
    M->val[3]=M->val[18]=
                  (atom->omega)*(pair->atom->omega)*sqrt(atom->polarizability*pair->atom->polarizability)*Txx;
    M->val[10]=M->val[17]=M->val[25]=M->val[32]=
                                         (atom->omega)*(pair->atom->omega)*sqrt(atom->polarizability*pair->atom->polarizability)*Tyy;

    eigvals=lapack_diag(M,1);
    energy = eigen2energy(eigvals, 6, system->temperature);

    //subtract energy of atoms at infinity
//	energy -= 3*wtanh(atom->omega, system->temperature);
    energy -= 3*atom->omega;
//	energy -= 3*wtanh(pair->atom->omega, system->temperature);
    energy -= 3*pair->atom->omega;

    free(eigvals);
    free_mtx(M);

    return energy * au2invsec * halfHBAR;
}