/* Random vectors of default colors * S:gaussian_ColorVector() */ int q_M_gaussian(lua_State *L) { mLatRandom *a = qlua_checkLatRandom(L, 1, NULL); mLattice *S = qlua_ObjLattice(L, 1); return do_gaussian(L, a, S, S->nc); }
/* Random vectors of NC colors * S:gaussian_ColorVectorN(nc) */ int q_M_gaussian_N(lua_State *L) { mLatRandom *a = qlua_checkLatRandom(L, 1, NULL); mLattice *S = qlua_ObjLattice(L, 1); int nc = luaL_checkint(L, 2); if (nc < 1) return luaL_error(L, "bad number of colors"); return do_gaussian(L, a, S, nc); }
real call_gaussian(t_commrec *cr, t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) { /* normal gaussian jobs */ static int step = 0; int i, j; real QMener = 0.0; rvec *QMgrad, *MMgrad; char *exe; snew(exe, 30); sprintf(exe, "%s/%s", qm->gauss_dir, qm->gauss_exe); snew(QMgrad, qm->nrQMatoms); snew(MMgrad, mm->nrMMatoms); write_gaussian_input(step, fr, qm, mm); do_gaussian(step, exe); QMener = read_gaussian_output(QMgrad, MMgrad, step, qm, mm); /* put the QMMM forces in the force array and to the fshift */ for (i = 0; i < qm->nrQMatoms; i++) { for (j = 0; j < DIM; j++) { f[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; fshift[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; } } for (i = 0; i < mm->nrMMatoms; i++) { for (j = 0; j < DIM; j++) { f[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; fshift[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; } } QMener = QMener*HARTREE2KJ*AVOGADRO; step++; free(exe); return(QMener); } /* call_gaussian */
real call_gaussian_SH(t_commrec *cr, t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) { /* a gaussian call routine intended for doing diabatic surface * "sliding". See the manual for the theoretical background of this * TSH method. */ static int step=0; int state,i,j; real QMener=0.0; static gmx_bool swapped=FALSE; /* handle for identifying the current PES */ gmx_bool swap=FALSE; /* the actual swap */ rvec *QMgrad,*MMgrad; char *buf; char *exe; snew(exe,30); sprintf(exe,"%s/%s",qm->gauss_dir,qm->gauss_exe); /* hack to do ground state simulations */ if(!step){ snew(buf,20); buf = getenv("STATE"); if (buf) sscanf(buf,"%d",&state); else state=2; if(state==1) swapped=TRUE; } /* end of hack */ /* copy the QMMMrec pointer */ snew(QMgrad,qm->nrQMatoms); snew(MMgrad,mm->nrMMatoms); /* at step 0 there should be no SA */ /* if(!step) * qr->bSA=FALSE;*/ /* temporray set to step + 1, since there is a chk start */ write_gaussian_SH_input(step,swapped,fr,qm,mm); do_gaussian(step,exe); QMener = read_gaussian_SH_output(QMgrad,MMgrad,step,swapped,qm,mm); /* check for a surface hop. Only possible if we were already state * averaging. */ if(qm->SAstep>0){ if(!swapped){ swap = (step && hop(step,qm)); swapped = swap; } else { /* already on the other surface, so check if we go back */ swap = (step && hop(step,qm)); swapped =!swap; /* so swapped shoud be false again */ } if (swap){/* change surface, so do another call */ write_gaussian_SH_input(step,swapped,fr,qm,mm); do_gaussian(step,exe); QMener = read_gaussian_SH_output(QMgrad,MMgrad,step,swapped,qm,mm); } } /* add the QMMM forces to the gmx force array and fshift */ for(i=0;i<qm->nrQMatoms;i++){ for(j=0;j<DIM;j++){ f[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; fshift[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; } } for(i=0;i<mm->nrMMatoms;i++){ for(j=0;j<DIM;j++){ f[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; fshift[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; } } QMener = QMener*HARTREE2KJ*AVOGADRO; fprintf(stderr,"step %5d, SA = %5d, swap = %5d\n", step,(qm->SAstep>0),swapped); step++; free(exe); return(QMener); } /* call_gaussian_SH */