3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * GROwing Monsters And Cloning Shrimps
39 #ifdef GMX_QMMM_GAUSSIAN
65 #include "gmx_fatal.h"
70 /* TODO: this should be made thread-safe */
72 /* Gaussian interface routines */
74 void init_gaussian(t_commrec
*cr
, t_QMrec
*qm
, t_MMrec
*mm
)
77 *rffile
=NULL
,*out
=NULL
;
79 basissets
[eQMbasisNR
]={{0,3,0},
80 {0,3,0},/*added for double sto-3g entry in names.c*/
94 /* using the ivec above to convert the basis read form the mdp file
95 * in a human readable format into some numbers for the gaussian
96 * route. This is necessary as we are using non standard routes to
100 /* per layer we make a new subdir for integral file, checkpoint
101 * files and such. These dirs are stored in the QMrec for
106 if(!qm
->nQMcpus
){ /* this we do only once per layer
107 * as we call g01 externally
111 qm
->SHbasis
[i
]=basissets
[qm
->QMbasis
][i
];
113 /* init gradually switching on of the SA */
115 /* we read the number of cpus and environment from the environment
119 buf
= getenv("NCPUS");
121 sscanf(buf
,"%d",&qm
->nQMcpus
);
124 fprintf(stderr
,"number of CPUs for gaussian = %d\n",qm
->nQMcpus
);
128 sscanf(buf
,"%d",&qm
->QMmem
);
131 fprintf(stderr
,"memory for gaussian = %d\n",qm
->QMmem
);
135 sscanf(buf
,"%d",&qm
->accuracy
);
138 fprintf(stderr
,"accuracy in l510 = %d\n",qm
->accuracy
);
140 buf
= getenv("CPMCSCF");
144 qm
->cpmcscf
= (i
!=0);
149 fprintf(stderr
,"using cp-mcscf in l1003\n");
151 fprintf(stderr
,"NOT using cp-mcscf in l1003\n");
153 buf
= getenv("SASTEP");
155 sscanf(buf
,"%d",&qm
->SAstep
);
157 /* init gradually switching on of the SA */
159 /* we read the number of cpus and environment from the environment
162 fprintf(stderr
,"Level of SA at start = %d\n",qm
->SAstep
);
165 /* punch the LJ C6 and C12 coefficients to be picked up by
166 * gaussian and usd to compute the LJ interaction between the
169 if(qm
->bTS
||qm
->bOPT
){
170 out
= fopen("LJ.dat","w");
171 for(i
=0;i
<qm
->nrQMatoms
;i
++){
174 fprintf(out
,"%3d %10.7lf %10.7lf\n",
175 qm
->atomicnumberQM
[i
],qm
->c6
[i
],qm
->c12
[i
]);
177 fprintf(out
,"%3d %10.7f %10.7f\n",
178 qm
->atomicnumberQM
[i
],qm
->c6
[i
],qm
->c12
[i
]);
183 /* gaussian settings on the system */
185 buf
= getenv("GAUSS_DIR");
186 fprintf(stderr
,"%s",buf
);
189 snew(qm
->gauss_dir
,200);
190 sscanf(buf
,"%s",qm
->gauss_dir
);
193 gmx_fatal(FARGS
,"no $GAUSS_DIR, check gaussian manual\n");
196 buf
= getenv("GAUSS_EXE");
198 snew(qm
->gauss_exe
,200);
199 sscanf(buf
,"%s",qm
->gauss_exe
);
202 gmx_fatal(FARGS
,"no $GAUSS_EXE, check gaussian manual\n");
205 buf
= getenv("DEVEL_DIR");
207 snew(qm
->devel_dir
,200);
208 sscanf(buf
,"%s",qm
->devel_dir
);
211 gmx_fatal(FARGS
,"no $DEVEL_DIR, this is were the modified links reside.\n");
215 /* reactionfield, file is needed using gaussian */
216 /* rffile=fopen("rf.dat","w");*/
217 /* fprintf(rffile,"%f %f\n",fr->epsilon_r,fr->rcoulomb/BOHR2NM);*/
221 fprintf(stderr
,"gaussian initialised...\n");
226 void write_gaussian_SH_input(int step
,gmx_bool swap
,
227 t_forcerec
*fr
, t_QMrec
*qm
, t_MMrec
*mm
)
238 bSA
= (qm
->SAstep
>0);
240 out
= fopen("input.com","w");
241 /* write the route */
242 fprintf(out
,"%s","%scr=input\n");
243 fprintf(out
,"%s","%rwf=input\n");
244 fprintf(out
,"%s","%int=input\n");
245 fprintf(out
,"%s","%d2e=input\n");
247 * fprintf(out,"%s","%nosave\n");
249 fprintf(out
,"%s","%chk=input\n");
250 fprintf(out
,"%s%d\n","%mem=",qm
->QMmem
);
251 fprintf(out
,"%s%3d\n","%nprocshare=",qm
->nQMcpus
);
253 /* use the versions of
254 * l301 that computes the interaction between MM and QM atoms.
255 * l510 that can punch the CI coefficients
256 * l701 that can do gradients on MM atoms
260 fprintf(out
,"%s%s%s",
264 fprintf(out
,"%s%s%s",
268 fprintf(out
,"%s%s%s",
273 fprintf(out
,"%s%s%s",
277 fprintf(out
,"%s%s%s",
281 /* print the nonstandard route
284 "#P nonstd\n 1/18=10,20=1,38=1/1;\n");
286 " 2/9=110,15=1,17=6,18=5,40=1/2;\n");
289 " 3/5=%d,6=%d,7=%d,25=1,32=1,43=1,94=-2/1,2,3;\n",
292 qm
->SHbasis
[2]); /*basisset stuff */
295 " 3/5=%d,6=%d,7=%d,25=1,32=1,43=0,94=-2/1,2,3;\n",
298 qm
->SHbasis
[2]); /*basisset stuff */
300 if (step
+1) /* fetch initial guess from check point file */
301 /* hack, to alyays read from chk file!!!!! */
302 fprintf(out
,"%s%d,%s%d%s"," 4/5=1,7=6,17=",
304 "18=",qm
->CASorbitals
,"/1,5;\n");
305 else /* generate the first checkpoint file */
306 fprintf(out
,"%s%d,%s%d%s"," 4/5=0,7=6,17=",
308 "18=",qm
->CASorbitals
,"/1,5;\n");
309 /* the rest of the input depends on where the system is on the PES
311 if(swap
&& bSA
){ /* make a slide to the other surface */
312 if(qm
->CASorbitals
>6){ /* use direct and no full diag */
313 fprintf(out
," 5/5=2,16=-2,17=10000000,28=2,32=2,38=6,97=100/10;\n");
317 fprintf(out
," 5/5=2,6=%d,17=31000200,28=2,32=2,38=6,97=100/10;\n",
320 fprintf(out
," 7/7=1,16=-2,30=1/1;\n");
321 fprintf(out
," 11/31=1,42=1,45=1/1;\n");
322 fprintf(out
," 10/6=1,10=700006,28=2,29=1,31=1,97=100/3;\n");
323 fprintf(out
," 7/30=1/16;\n 99/10=4/99;\n");
326 fprintf(out
," 5/5=2,6=%d,17=11000000,28=2,32=2,38=6,97=100/10;\n",
328 fprintf(out
," 7/7=1,16=-2,30=1/1,2,3,16;\n 99/10=4/99;\n");
332 else if(bSA
){ /* do a "state-averaged" CAS calculation */
333 if(qm
->CASorbitals
>6){ /* no full diag */
334 fprintf(out
," 5/5=2,16=-2,17=10000000,28=2,32=2,38=6/10;\n");
338 fprintf(out
," 5/5=2,6=%d,17=31000200,28=2,32=2,38=6/10;\n",
341 fprintf(out
," 7/7=1,16=-2,30=1/1;\n");
342 fprintf(out
," 11/31=1,42=1,45=1/1;\n");
343 fprintf(out
," 10/6=1,10=700006,28=2,29=1,31=1/3;\n");
344 fprintf(out
," 7/30=1/16;\n 99/10=4/99;\n");
347 fprintf(out
," 5/5=2,6=%d,17=11000000,28=2,32=2,38=6/10;\n",
349 fprintf(out
," 7/7=1,16=-2,30=1/1,2,3,16;\n 99/10=4/99;\n");
353 else if(swap
){/* do a "swapped" CAS calculation */
354 if(qm
->CASorbitals
>6)
355 fprintf(out
," 5/5=2,16=-2,17=0,28=2,32=2,38=6,97=100/10;\n");
357 fprintf(out
," 5/5=2,6=%d,17=1000000,28=2,32=2,38=6,97=100/10;\n",
359 fprintf(out
," 7/7=1,16=-2,30=1/1,2,3,16;\n 99/10=4/99;\n");
361 else {/* do a "normal" CAS calculation */
362 if(qm
->CASorbitals
>6)
363 fprintf(out
," 5/5=2,16=-2,17=0,28=2,32=2,38=6/10;\n");
365 fprintf(out
," 5/5=2,6=%d,17=1000000,28=2,32=2,38=6/10;\n",
367 fprintf(out
," 7/7=1,16=-2,30=1/1,2,3,16;\n 99/10=4/99;\n");
369 fprintf(out
, "\ninput-file generated by gromacs\n\n");
370 fprintf(out
,"%2d%2d\n",qm
->QMcharge
,qm
->multiplicity
);
371 for (i
=0;i
<qm
->nrQMatoms
;i
++){
373 fprintf(out
,"%3d %10.7lf %10.7lf %10.7lf\n",
374 qm
->atomicnumberQM
[i
],
375 qm
->xQM
[i
][XX
]/BOHR2NM
,
376 qm
->xQM
[i
][YY
]/BOHR2NM
,
377 qm
->xQM
[i
][ZZ
]/BOHR2NM
);
379 fprintf(out
,"%3d %10.7f %10.7f %10.7f\n",
380 qm
->atomicnumberQM
[i
],
381 qm
->xQM
[i
][XX
]/BOHR2NM
,
382 qm
->xQM
[i
][YY
]/BOHR2NM
,
383 qm
->xQM
[i
][ZZ
]/BOHR2NM
);
386 /* MM point charge data */
387 if(QMMMrec
->QMMMscheme
!=eQMMMschemeoniom
&& mm
->nrMMatoms
){
389 for(i
=0;i
<mm
->nrMMatoms
;i
++){
391 fprintf(out
,"%10.7lf %10.7lf %10.7lf %8.4lf\n",
392 mm
->xMM
[i
][XX
]/BOHR2NM
,
393 mm
->xMM
[i
][YY
]/BOHR2NM
,
394 mm
->xMM
[i
][ZZ
]/BOHR2NM
,
397 fprintf(out
,"%10.7f %10.7f %10.7f %8.4f\n",
398 mm
->xMM
[i
][XX
]/BOHR2NM
,
399 mm
->xMM
[i
][YY
]/BOHR2NM
,
400 mm
->xMM
[i
][ZZ
]/BOHR2NM
,
405 if(bSA
) {/* put the SA coefficients at the end of the file */
407 fprintf(out
,"\n%10.8lf %10.8lf\n",
408 qm
->SAstep
*0.5/qm
->SAsteps
,
409 1-qm
->SAstep
*0.5/qm
->SAsteps
);
411 fprintf(out
,"\n%10.8f %10.8f\n",
412 qm
->SAstep
*0.5/qm
->SAsteps
,
413 1-qm
->SAstep
*0.5/qm
->SAsteps
);
415 fprintf(stderr
,"State Averaging level = %d/%d\n",qm
->SAstep
,qm
->SAsteps
);
419 } /* write_gaussian_SH_input */
421 void write_gaussian_input(int step
,t_forcerec
*fr
, t_QMrec
*qm
, t_MMrec
*mm
)
431 out
= fopen("input.com","w");
432 /* write the route */
434 if(qm
->QMmethod
>=eQMmethodRHF
)
441 fprintf(out
,"%s%3d\n",
442 "%nprocshare=",qm
->nQMcpus
);
443 fprintf(out
,"%s%d\n",
445 /* use the modified links that include the LJ contribution at the QM level */
446 if(qm
->bTS
||qm
->bOPT
){
447 fprintf(out
,"%s%s%s",
448 "%subst l701 ",qm
->devel_dir
,"/l701_LJ\n");
449 fprintf(out
,"%s%s%s",
450 "%subst l301 ",qm
->devel_dir
,"/l301_LJ\n");
453 fprintf(out
,"%s%s%s",
454 "%subst l701 ",qm
->devel_dir
,"/l701\n");
455 fprintf(out
,"%s%s%s",
456 "%subst l301 ",qm
->devel_dir
,"/l301\n");
458 fprintf(out
,"%s%s%s",
459 "%subst l9999 ",qm
->devel_dir
,"/l9999\n");
467 if(qm
->QMmethod
==eQMmethodB3LYPLAN
){
469 "B3LYP/GEN Pseudo=Read");
473 eQMmethod_names
[qm
->QMmethod
]);
475 if(qm
->QMmethod
>=eQMmethodRHF
){
477 eQMbasis_names
[qm
->QMbasis
]);
478 if(qm
->QMmethod
==eQMmethodCASSCF
){
479 /* in case of cas, how many electrons and orbitals do we need?
481 fprintf(out
,"(%d,%d)",
482 qm
->CASelectrons
,qm
->CASorbitals
);
486 if(QMMMrec
->QMMMscheme
==eQMMMschemenormal
){
490 if (step
|| qm
->QMmethod
==eQMmethodCASSCF
){
491 /* fetch guess from checkpoint file, always for CASSCF */
492 fprintf(out
,"%s"," guess=read");
494 fprintf(out
,"\nNosymm units=bohr\n");
497 fprintf(out
,"OPT=(Redundant,TS,noeigentest,ModRedundant) Punch=(Coord,Derivatives) ");
500 fprintf(out
,"OPT=(Redundant,ModRedundant) Punch=(Coord,Derivatives) ");
503 fprintf(out
,"FORCE Punch=(Derivatives) ");
505 fprintf(out
,"iop(3/33=1)\n\n");
506 fprintf(out
, "input-file generated by gromacs\n\n");
507 fprintf(out
,"%2d%2d\n",qm
->QMcharge
,qm
->multiplicity
);
508 for (i
=0;i
<qm
->nrQMatoms
;i
++){
510 fprintf(out
,"%3d %10.7lf %10.7lf %10.7lf\n",
511 qm
->atomicnumberQM
[i
],
512 qm
->xQM
[i
][XX
]/BOHR2NM
,
513 qm
->xQM
[i
][YY
]/BOHR2NM
,
514 qm
->xQM
[i
][ZZ
]/BOHR2NM
);
516 fprintf(out
,"%3d %10.7f %10.7f %10.7f\n",
517 qm
->atomicnumberQM
[i
],
518 qm
->xQM
[i
][XX
]/BOHR2NM
,
519 qm
->xQM
[i
][YY
]/BOHR2NM
,
520 qm
->xQM
[i
][ZZ
]/BOHR2NM
);
524 /* Pseudo Potential and ECP are included here if selected (MEthod suffix LAN) */
525 if(qm
->QMmethod
==eQMmethodB3LYPLAN
){
527 for(i
=0;i
<qm
->nrQMatoms
;i
++){
528 if(qm
->atomicnumberQM
[i
]<21){
529 fprintf(out
,"%d ",i
+1);
532 fprintf(out
,"\n%s\n****\n",eQMbasis_names
[qm
->QMbasis
]);
534 for(i
=0;i
<qm
->nrQMatoms
;i
++){
535 if(qm
->atomicnumberQM
[i
]>21){
536 fprintf(out
,"%d ",i
+1);
539 fprintf(out
,"\n%s\n****\n\n","lanl2dz");
541 for(i
=0;i
<qm
->nrQMatoms
;i
++){
542 if(qm
->atomicnumberQM
[i
]>21){
543 fprintf(out
,"%d ",i
+1);
546 fprintf(out
,"\n%s\n","lanl2dz");
551 /* MM point charge data */
552 if(QMMMrec
->QMMMscheme
!=eQMMMschemeoniom
&& mm
->nrMMatoms
){
553 fprintf(stderr
,"nr mm atoms in gaussian.c = %d\n",mm
->nrMMatoms
);
555 if(qm
->bTS
||qm
->bOPT
){
556 /* freeze the frontier QM atoms and Link atoms. This is
557 * important only if a full QM subsystem optimization is done
558 * with a frozen MM environmeent. For dynamics, or gromacs's own
559 * optimization routines this is not important.
561 for(i
=0;i
<qm
->nrQMatoms
;i
++){
562 if(qm
->frontatoms
[i
]){
563 fprintf(out
,"%d F\n",i
+1); /* counting from 1 */
566 /* MM point charges include LJ parameters in case of QM optimization
568 for(i
=0;i
<mm
->nrMMatoms
;i
++){
570 fprintf(out
,"%10.7lf %10.7lf %10.7lf %8.4lf 0.0 %10.7lf %10.7lf\n",
571 mm
->xMM
[i
][XX
]/BOHR2NM
,
572 mm
->xMM
[i
][YY
]/BOHR2NM
,
573 mm
->xMM
[i
][ZZ
]/BOHR2NM
,
575 mm
->c6
[i
],mm
->c12
[i
]);
577 fprintf(out
,"%10.7f %10.7f %10.7f %8.4f 0.0 %10.7f %10.7f\n",
578 mm
->xMM
[i
][XX
]/BOHR2NM
,
579 mm
->xMM
[i
][YY
]/BOHR2NM
,
580 mm
->xMM
[i
][ZZ
]/BOHR2NM
,
582 mm
->c6
[i
],mm
->c12
[i
]);
588 for(i
=0;i
<mm
->nrMMatoms
;i
++){
590 fprintf(out
,"%10.7lf %10.7lf %10.7lf %8.4lf\n",
591 mm
->xMM
[i
][XX
]/BOHR2NM
,
592 mm
->xMM
[i
][YY
]/BOHR2NM
,
593 mm
->xMM
[i
][ZZ
]/BOHR2NM
,
596 fprintf(out
,"%10.7f %10.7f %10.7f %8.4f\n",
597 mm
->xMM
[i
][XX
]/BOHR2NM
,
598 mm
->xMM
[i
][YY
]/BOHR2NM
,
599 mm
->xMM
[i
][ZZ
]/BOHR2NM
,
610 } /* write_gaussian_input */
612 real
read_gaussian_output(rvec QMgrad
[],rvec MMgrad
[],int step
,
613 t_QMrec
*qm
, t_MMrec
*mm
)
624 in
=fopen("fort.7","r");
628 /* in case of an optimization, the coordinates are printed in the
629 * fort.7 file first, followed by the energy, coordinates and (if
630 * required) the CI eigenvectors.
632 if(qm
->bTS
||qm
->bOPT
){
633 for(i
=0;i
<qm
->nrQMatoms
;i
++){
634 if( NULL
== fgets(buf
,300,in
))
636 gmx_fatal(FARGS
,"Error reading Gaussian output - not enough atom lines?");
640 sscanf(buf
,"%d %lf %lf %lf\n",
646 sscanf(buf
,"%d %f %f %f\n",
653 qm
->xQM
[i
][j
]*=BOHR2NM
;
657 /* the next line is the energy and in the case of CAS, the energy
658 * difference between the two states.
660 if(NULL
== fgets(buf
,300,in
))
662 gmx_fatal(FARGS
,"Error reading Gaussian output");
666 sscanf(buf
,"%lf\n",&QMener
);
668 sscanf(buf
,"%f\n", &QMener
);
670 /* next lines contain the gradients of the QM atoms */
671 for(i
=0;i
<qm
->nrQMatoms
;i
++){
672 if(NULL
== fgets(buf
,300,in
))
674 gmx_fatal(FARGS
,"Error reading Gaussian output");
677 sscanf(buf
,"%lf %lf %lf\n",
682 sscanf(buf
,"%f %f %f\n",
688 /* the next lines are the gradients of the MM atoms */
689 if(qm
->QMmethod
>=eQMmethodRHF
){
690 for(i
=0;i
<mm
->nrMMatoms
;i
++){
691 if(NULL
==fgets(buf
,300,in
))
693 gmx_fatal(FARGS
,"Error reading Gaussian output");
696 sscanf(buf
,"%lf %lf %lf\n",
701 sscanf(buf
,"%f %f %f\n",
712 real
read_gaussian_SH_output(rvec QMgrad
[],rvec MMgrad
[],int step
,
713 gmx_bool swapped
,t_QMrec
*qm
, t_MMrec
*mm
)
724 in
=fopen("fort.7","r");
725 /* first line is the energy and in the case of CAS, the energy
726 * difference between the two states.
728 if(NULL
== fgets(buf
,300,in
))
730 gmx_fatal(FARGS
,"Error reading Gaussian output");
734 sscanf(buf
,"%lf %lf\n",&QMener
,&DeltaE
);
736 sscanf(buf
,"%f %f\n", &QMener
,&DeltaE
);
739 /* switch on/off the State Averaging */
741 if(DeltaE
> qm
->SAoff
){
746 else if (DeltaE
< qm
->SAon
|| (qm
->SAstep
> 0)){
747 if (qm
->SAstep
< qm
->SAsteps
){
753 fprintf(stderr
,"Gap = %5f,SA = %3d\n",DeltaE
,(qm
->SAstep
>0));
754 /* next lines contain the gradients of the QM atoms */
755 for(i
=0;i
<qm
->nrQMatoms
;i
++){
756 if(NULL
==fgets(buf
,300,in
))
758 gmx_fatal(FARGS
,"Error reading Gaussian output");
762 sscanf(buf
,"%lf %lf %lf\n",
767 sscanf(buf
,"%f %f %f\n",
773 /* the next lines, are the gradients of the MM atoms */
775 for(i
=0;i
<mm
->nrMMatoms
;i
++){
776 if(NULL
==fgets(buf
,300,in
))
778 gmx_fatal(FARGS
,"Error reading Gaussian output");
781 sscanf(buf
,"%lf %lf %lf\n",
786 sscanf(buf
,"%f %f %f\n",
793 /* the next line contains the two CI eigenvector elements */
794 if(NULL
==fgets(buf
,300,in
))
796 gmx_fatal(FARGS
,"Error reading Gaussian output");
799 sscanf(buf
,"%d",&qm
->CIdim
);
800 snew(qm
->CIvec1
,qm
->CIdim
);
801 snew(qm
->CIvec1old
,qm
->CIdim
);
802 snew(qm
->CIvec2
,qm
->CIdim
);
803 snew(qm
->CIvec2old
,qm
->CIdim
);
805 /* before reading in the new current CI vectors, copy the current
806 * CI vector into the old one.
808 for(i
=0;i
<qm
->CIdim
;i
++){
809 qm
->CIvec1old
[i
] = qm
->CIvec1
[i
];
810 qm
->CIvec2old
[i
] = qm
->CIvec2
[i
];
814 for(i
=0;i
<qm
->CIdim
;i
++){
815 if(NULL
==fgets(buf
,300,in
))
817 gmx_fatal(FARGS
,"Error reading Gaussian output");
820 sscanf(buf
,"%lf\n",&qm
->CIvec1
[i
]);
822 sscanf(buf
,"%f\n", &qm
->CIvec1
[i
]);
826 for(i
=0;i
<qm
->CIdim
;i
++){
827 if(NULL
==fgets(buf
,300,in
))
829 gmx_fatal(FARGS
,"Error reading Gaussian output");
832 sscanf(buf
,"%lf\n",&qm
->CIvec2
[i
]);
834 sscanf(buf
,"%f\n", &qm
->CIvec2
[i
]);
841 real
inproduct(real
*a
, real
*b
, int n
)
848 /* computes the inner product between two vectors (a.b), both of
849 * which have length n.
857 int hop(int step
, t_QMrec
*qm
)
862 d11
=0.0,d12
=0.0,d21
=0.0,d22
=0.0;
864 /* calculates the inproduct between the current Ci vector and the
865 * previous CI vector. A diabatic hop will be made if d12 and d21
866 * are much bigger than d11 and d22. In that case hop returns true,
867 * otherwise it returns false.
869 if(step
){ /* only go on if more than one step has been done */
870 d11
= inproduct(qm
->CIvec1
,qm
->CIvec1old
,qm
->CIdim
);
871 d12
= inproduct(qm
->CIvec1
,qm
->CIvec2old
,qm
->CIdim
);
872 d21
= inproduct(qm
->CIvec2
,qm
->CIvec1old
,qm
->CIdim
);
873 d22
= inproduct(qm
->CIvec2
,qm
->CIvec2old
,qm
->CIdim
);
875 fprintf(stderr
,"-------------------\n");
876 fprintf(stderr
,"d11 = %13.8f\n",d11
);
877 fprintf(stderr
,"d12 = %13.8f\n",d12
);
878 fprintf(stderr
,"d21 = %13.8f\n",d21
);
879 fprintf(stderr
,"d22 = %13.8f\n",d22
);
880 fprintf(stderr
,"-------------------\n");
882 if((fabs(d12
)>0.5)&&(fabs(d21
)>0.5))
888 void do_gaussian(int step
,char *exe
)
893 /* make the call to the gaussian binary through system()
894 * The location of the binary will be picked up from the
895 * environment using getenv().
897 if(step
) /* hack to prevent long inputfiles */
898 sprintf(buf
,"%s < %s > %s",
903 sprintf(buf
,"%s < %s > %s",
907 fprintf(stderr
,"Calling '%s'\n",buf
);
909 printf("Warning-- No calls to system(3) supported on this platform.");
910 gmx_fatal(FARGS
,"Call to '%s' failed\n",buf
);
912 if ( system(buf
) != 0 )
913 gmx_fatal(FARGS
,"Call to '%s' failed\n",buf
);
917 real
call_gaussian(t_commrec
*cr
, t_forcerec
*fr
,
918 t_QMrec
*qm
, t_MMrec
*mm
, rvec f
[], rvec fshift
[])
920 /* normal gaussian jobs */
933 sprintf(exe
,"%s/%s",qm
->gauss_dir
,qm
->gauss_exe
);
934 snew(QMgrad
,qm
->nrQMatoms
);
935 snew(MMgrad
,mm
->nrMMatoms
);
937 write_gaussian_input(step
,fr
,qm
,mm
);
938 do_gaussian(step
,exe
);
939 QMener
= read_gaussian_output(QMgrad
,MMgrad
,step
,qm
,mm
);
940 /* put the QMMM forces in the force array and to the fshift
942 for(i
=0;i
<qm
->nrQMatoms
;i
++){
944 f
[i
][j
] = HARTREE_BOHR2MD
*QMgrad
[i
][j
];
945 fshift
[i
][j
] = HARTREE_BOHR2MD
*QMgrad
[i
][j
];
948 for(i
=0;i
<mm
->nrMMatoms
;i
++){
950 f
[i
+qm
->nrQMatoms
][j
] = HARTREE_BOHR2MD
*MMgrad
[i
][j
];
951 fshift
[i
+qm
->nrQMatoms
][j
] = HARTREE_BOHR2MD
*MMgrad
[i
][j
];
954 QMener
= QMener
*HARTREE2KJ
*AVOGADRO
;
959 } /* call_gaussian */
961 real
call_gaussian_SH(t_commrec
*cr
, t_forcerec
*fr
, t_QMrec
*qm
, t_MMrec
*mm
,
962 rvec f
[], rvec fshift
[])
964 /* a gaussian call routine intended for doing diabatic surface
965 * "sliding". See the manual for the theoretical background of this
975 swapped
=FALSE
; /* handle for identifying the current PES */
977 swap
=FALSE
; /* the actual swap */
986 sprintf(exe
,"%s/%s",qm
->gauss_dir
,qm
->gauss_exe
);
987 /* hack to do ground state simulations */
990 buf
= getenv("STATE");
992 sscanf(buf
,"%d",&state
);
1001 /* copy the QMMMrec pointer */
1002 snew(QMgrad
,qm
->nrQMatoms
);
1003 snew(MMgrad
,mm
->nrMMatoms
);
1004 /* at step 0 there should be no SA */
1007 /* temporray set to step + 1, since there is a chk start */
1008 write_gaussian_SH_input(step
,swapped
,fr
,qm
,mm
);
1010 do_gaussian(step
,exe
);
1011 QMener
= read_gaussian_SH_output(QMgrad
,MMgrad
,step
,swapped
,qm
,mm
);
1013 /* check for a surface hop. Only possible if we were already state
1018 swap
= (step
&& hop(step
,qm
));
1021 else { /* already on the other surface, so check if we go back */
1022 swap
= (step
&& hop(step
,qm
));
1023 swapped
=!swap
; /* so swapped shoud be false again */
1025 if (swap
){/* change surface, so do another call */
1026 write_gaussian_SH_input(step
,swapped
,fr
,qm
,mm
);
1027 do_gaussian(step
,exe
);
1028 QMener
= read_gaussian_SH_output(QMgrad
,MMgrad
,step
,swapped
,qm
,mm
);
1031 /* add the QMMM forces to the gmx force array and fshift
1033 for(i
=0;i
<qm
->nrQMatoms
;i
++){
1035 f
[i
][j
] = HARTREE_BOHR2MD
*QMgrad
[i
][j
];
1036 fshift
[i
][j
] = HARTREE_BOHR2MD
*QMgrad
[i
][j
];
1039 for(i
=0;i
<mm
->nrMMatoms
;i
++){
1041 f
[i
+qm
->nrQMatoms
][j
] = HARTREE_BOHR2MD
*MMgrad
[i
][j
];
1042 fshift
[i
+qm
->nrQMatoms
][j
] = HARTREE_BOHR2MD
*MMgrad
[i
][j
];
1045 QMener
= QMener
*HARTREE2KJ
*AVOGADRO
;
1046 fprintf(stderr
,"step %5d, SA = %5d, swap = %5d\n",
1047 step
,(qm
->SAstep
>0),swapped
);
1052 } /* call_gaussian_SH */
1054 /* end of gaussian sub routines */
1058 gmx_qmmm_gaussian_empty
;