4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
28 * For more info, check our website at http://www.gromacs.org
31 * Getting the Right Output Means no Artefacts in Calculating Stuff
64 static void sp_header(FILE *out
,const char *minimizer
,real ftol
,int nsteps
)
66 fprintf(out
,"%s:\n",minimizer
);
67 fprintf(out
," Tolerance = %12.5e\n",ftol
);
68 fprintf(out
," Number of steps = %12d\n",nsteps
);
71 static void warn_step(FILE *fp
,real ustep
,real ftol
,bool bConstrain
)
73 fprintf(fp
,"\nStepsize too small (%g nm)"
74 "Converged to machine precision,\n"
75 "but not to the requested precision (%g)\n",
78 fprintf(fp
,"You might need to increase your constraint accuracy, or turn\n"
79 "off constraints alltogether (set constraints = none in mdp file)\n");
82 static void print_converged(FILE *fp
,const char *alg
,real ftol
,int count
,bool bDone
,
83 int nsteps
,real epot
,real fmax
)
86 fprintf(fp
,"\n%s converged to %g in %d steps\n",alg
,ftol
,count
);
88 fprintf(fp
,"\n%s did not converge in %d steps\n",alg
,min(count
,nsteps
));
89 fprintf(fp
," Potential Energy = %12.5e\n",epot
);
90 fprintf(fp
,"Maximum force: %12.5e\n",fmax
);
93 static real
f_max(int left
,int right
,int nnodes
,
94 t_grpopts
*opts
,t_mdatoms
*mdatoms
,
95 int start
,int end
,rvec grad
[],int *nfmax
)
97 real fmax2
,fmax2_0
,fam
,nfm
;
100 /* This routine finds the largest force and returns it.
101 * On parallel machines the global max is taken.
105 for(i
=start
; i
<end
; i
++) {
106 gf
= mdatoms
->cFREEZE
[i
];
109 if (!opts
->nFreeze
[gf
][m
])
110 fam
+= sqr(grad
[i
][m
]);
119 for(i
=0; (i
<nnodes
-1); i
++) {
120 gmx_tx(left
,(void *)&fmax2
,sizeof(fmax2
));
121 gmx_rx(right
,(void *)&fmax2_0
,sizeof(fmax2_0
));
122 gmx_wait(left
,right
);
123 gmx_tx(left
,(void *)nfmax
,sizeof(*nfmax
));
124 gmx_rx(right
,(void *)&nfm
,sizeof(nfm
));
125 gmx_wait(left
,right
);
126 if (fmax2_0
> fmax2
) {
135 static real
f_norm(t_commrec
*cr
,
136 t_grpopts
*opts
,t_mdatoms
*mdatoms
,
137 int start
,int end
,rvec grad
[])
142 /* This routine returns the norm of the force */
145 for(i
=start
; i
<end
; i
++) {
146 gf
= mdatoms
->cFREEZE
[i
];
148 if (!opts
->nFreeze
[gf
][m
])
149 fnorm2
+= sqr(grad
[i
][m
]);
153 gmx_sumd(1,&fnorm2
,cr
);
158 static void init_em(FILE *log
,const char *title
,
159 t_parm
*parm
,real
*lambda
,t_nrnb
*mynrnb
,rvec mu_tot
,rvec box_size
,
160 t_forcerec
*fr
,t_mdatoms
*mdatoms
,t_topology
*top
,t_nsborder
*nsb
,
161 t_commrec
*cr
,t_vcm
**vcm
,int *start
,int *end
)
163 fprintf(log
,"Initiating %s\n",title
);
165 /* Initiate some variables */
166 if (parm
->ir
.efep
!= efepNO
)
167 *lambda
= parm
->ir
.init_lambda
;
174 calc_shifts(parm
->box
,box_size
,fr
->shift_vec
);
176 *start
= nsb
->index
[cr
->nodeid
];
177 *end
= nsb
->homenr
[cr
->nodeid
] + *start
;
179 /* Set initial values for invmass etc. */
180 update_mdatoms(mdatoms
,*lambda
,TRUE
);
182 *vcm
= init_vcm(log
,top
,cr
,mdatoms
,
183 *start
,HOMENR(nsb
),parm
->ir
.nstcomm
);
186 time_t do_cg(FILE *log
,int nfile
,t_filenm fnm
[],
187 t_parm
*parm
,t_topology
*top
,
188 t_groups
*grps
,t_nsborder
*nsb
,
189 rvec x
[],rvec grad
[],rvec buf
[],t_mdatoms
*mdatoms
,
190 tensor ekin
,real ener
[],t_fcdata
*fcd
,t_nrnb nrnb
[],
191 bool bVerbose
,bool bDummies
,t_comm_dummies
*dummycomm
,
192 t_commrec
*cr
,t_commrec
*mcr
,t_graph
*graph
,
193 t_forcerec
*fr
,rvec box_size
)
195 const char *CG
="Conjugate Gradients";
197 double EpotA
=0.0,EpotB
=0.0,a
=0.0,b
,beta
=0.0,zet
,w
;
198 real lambda
,fmax
,testf
,smin
;
199 rvec
*p
,*f
,*xprime
,*xx
,*ff
;
200 real fnorm
,pnorm
,fnorm_old
;
204 bool bNS
=TRUE
,bDone
,bLR
,bLJLR
,bBHAM
,b14
,bRand
,brerun
,bBeta0
=FALSE
;
207 tensor force_vir
,shake_vir
,pme_vir
;
208 int number_steps
,naccept
=0,nstcg
=parm
->ir
.nstcgsteep
;
210 int i
,m
,nfmax
,start
,end
,niti
,gf
;
214 init_em(log
,CG
,parm
,&lambda
,&mynrnb
,mu_tot
,box_size
,fr
,mdatoms
,top
,
215 nsb
,cr
,&vcm
,&start
,&end
);
217 /* Print to log file */
218 start_t
=print_date_and_time(log
,cr
->nodeid
,"Started Conjugate Gradients");
220 /* p is the search direction, f the force, xprime the new positions */
223 snew(xprime
,nsb
->natoms
);
225 /* Set some booleans for the epot routines */
226 set_pot_bools(&(parm
->ir
),top
,&bLR
,&bLJLR
,&bBHAM
,&b14
);
228 /* Open the energy file */
230 fp_ene
=open_enx(ftp2fn(efENX
,nfile
,fnm
),"w");
234 /* Init bin for energy stuff */
235 mdebin
=init_mdebin(fp_ene
,grps
,&(top
->atoms
),&(top
->idef
),
236 bLR
,bLJLR
,bBHAM
,b14
,parm
->ir
.efep
!=efepNO
,parm
->ir
.epc
,
237 parm
->ir
.eDispCorr
,TRICLINIC(parm
->ir
.compress
),
238 (parm
->ir
.etc
==etcNOSEHOOVER
),cr
);
240 /* Clear some matrix variables */
241 clear_mat(force_vir
);
242 clear_mat(shake_vir
);
244 if (fr
->ePBC
!= epbcNONE
)
245 /* Remove periodicity */
246 do_pbc_first(log
,parm
,box_size
,fr
,graph
,x
);
248 /* Max number of steps */
249 number_steps
=parm
->ir
.nsteps
;
252 sp_header(stderr
,CG
,parm
->ir
.em_tol
,number_steps
);
253 sp_header(log
,CG
,parm
->ir
.em_tol
,number_steps
);
256 construct_dummies(log
,x
,&(nrnb
[cr
->nodeid
]),1,NULL
,&top
->idef
,
257 graph
,cr
,parm
->box
,dummycomm
);
259 /* Call the force routine and some auxiliary (neighboursearching etc.) */
260 /* do_force always puts the charge groups in the box and shifts again
261 * We do not unshift, so molecules are always whole in congrad.c
263 do_force(log
,cr
,mcr
,parm
,nsb
,force_vir
,pme_vir
,0,&(nrnb
[cr
->nodeid
]),
264 top
,grps
,x
,buf
,f
,buf
,mdatoms
,ener
,fcd
,bVerbose
&& !(PAR(cr
)),
265 lambda
,graph
,bNS
,FALSE
,fr
,mu_tot
,FALSE
,0.0);
268 /* Spread the force on dummy particle to the other particles... */
270 spread_dummy_f(log
,x
,f
,&(nrnb
[cr
->nodeid
]),&top
->idef
,dummycomm
,cr
);
272 /* Sum the potential energy terms from group contributions */
273 sum_epot(&(parm
->ir
.opts
),grps
,ener
);
277 clear_mat(force_vir
);
280 /* Communicat energies etc. */
282 global_stat(log
,cr
,ener
,force_vir
,shake_vir
,
283 &(parm
->ir
.opts
),grps
,&mynrnb
,nrnb
,vcm
,&terminate
);
287 /* Copy stuff to the energy bin for easy printing etc. */
288 upd_mdebin(mdebin
,NULL
,mdatoms
->tmass
,count
,(real
)count
,
289 ener
,parm
->box
,shake_vir
,
290 force_vir
,parm
->vir
,parm
->pres
,grps
,mu_tot
,
291 (parm
->ir
.etc
==etcNOSEHOOVER
));
293 print_ebin_header(log
,count
,count
,lambda
);
294 print_ebin(fp_ene
,TRUE
,FALSE
,FALSE
,FALSE
,log
,count
,count
,eprNORMAL
,
295 TRUE
,mdebin
,fcd
,&(top
->atoms
),&(parm
->ir
.opts
));
299 /* This is the starting energy */
302 /* normalising step size, this saves a few hundred steps in the
303 * beginning of the run.
305 fnorm
= f_norm(cr
,&(parm
->ir
.opts
),mdatoms
,start
,end
,f
);
310 fprintf(stderr
," F-Norm = %12.5e\n",fnorm
);
311 fprintf(stderr
,"\n");
314 /* Here starts the loop, count is the counter for the number of steps
315 * bDone is a BOOLEAN variable, which will be set TRUE when
316 * the minimization has converged.
319 for(count
=1; (!bDone
&& (count
< number_steps
)); count
++) {
321 /* start conjugate gradient, determine search interval a,b */
323 for(i
=start
; (i
<end
); i
++) {
324 gf
= mdatoms
->cFREEZE
[i
];
326 if (!parm
->ir
.opts
.nFreeze
[gf
][m
]) {
327 p
[i
][m
] = f
[i
][m
] + beta
*p
[i
][m
];
328 gpa
= gpa
- p
[i
][m
]*f
[i
][m
];
333 pnorm
= f_norm(cr
,&(parm
->ir
.opts
),mdatoms
,start
,end
,p
);
335 /* Set variables for stepsize (in nm). This is the largest
336 * step that we are going to make in any direction.
339 b
= parm
->ir
.em_stepsize
/pnorm
;
342 /* search a,b iteratively, if necessary */
345 for (i
=start
; (i
<end
); i
++) {
346 for(m
=0; (m
<DIM
); m
++) {
347 xprime
[i
][m
] = x
[i
][m
] + b
*p
[i
][m
];
350 bNS
= (parm
->ir
.nstlist
> 0);
353 construct_dummies(log
,xprime
,&(nrnb
[cr
->nodeid
]),1,NULL
,&top
->idef
,
354 graph
,cr
,parm
->box
,dummycomm
);
357 /* Calc force & energy on new trial position */
358 /* do_force always puts the charge groups in the box and shifts again
359 * We do not unshift, so molecules are always whole in conjugate
362 do_force(log
,cr
,mcr
,parm
,nsb
,force_vir
,pme_vir
,
363 count
,&(nrnb
[cr
->nodeid
]),top
,grps
,xprime
,buf
,f
,
364 buf
,mdatoms
,ener
,fcd
,bVerbose
&& !(PAR(cr
)),
365 lambda
,graph
,bNS
,FALSE
,fr
,mu_tot
,FALSE
,0.0);
367 /* Spread the force on dummy particle to the other particles... */
369 spread_dummy_f(log
,xprime
,f
,&(nrnb
[cr
->nodeid
]),&top
->idef
,
372 /* Sum the potential energy terms from group contributions */
373 sum_epot(&(parm
->ir
.opts
),grps
,ener
);
376 bNS
= (parm
->ir
.nstlist
> 0);
379 for(i
=start
; (i
<end
); i
++)
380 gpb
-= iprod(p
[i
],f
[i
]);
385 /* Sum the potential energy terms from group contributions */
386 sum_epot(&(parm
->ir
.opts
),grps
,ener
);
388 /* Clear stuff again */
389 clear_mat(force_vir
);
390 clear_mat(shake_vir
);
392 /* Communicate stuff when parallel */
394 global_stat(log
,cr
,ener
,force_vir
,shake_vir
,
395 &(parm
->ir
.opts
),grps
,&mynrnb
,nrnb
,vcm
,&terminate
);
397 EpotB
= ener
[F_EPOT
];
399 if ((gpb
>= 0.0) || (EpotB
>= EpotA
))
409 /* End of while loop searching for a and b */
411 /* find stepsize smin in interval a-b */
412 zet
= 3.0 * (EpotA
-EpotB
) / (b
-a
) + gpa
+ gpb
;
413 w
= zet
*zet
- gpa
*gpb
;
416 fprintf(debug
,"Negative w: %20.12e\n",w
);
417 fprintf(debug
,"z= %20.12e\n",zet
);
418 fprintf(debug
,"gpa= %20.12e, gpb= %20.12e\n",gpa
,gpb
);
419 fprintf(debug
,"a= %20.12e, b= %20.12e\n",a
,b
);
420 fprintf(debug
,"EpotA= %20.12e, EpotB= %20.12e\n",EpotA
,EpotB
);
426 smin
= b
- ((gpb
+w
-zet
)*(b
-a
))/((gpb
-gpa
)+2.0*w
);
429 for (i
=start
; i
<end
; i
++)
431 xprime
[i
][m
] = x
[i
][m
] + smin
*p
[i
][m
];
434 construct_dummies(log
,xprime
,&(nrnb
[cr
->nodeid
]),1,NULL
,&top
->idef
,
435 graph
,cr
,parm
->box
,dummycomm
);
437 /* new energy, forces
438 * do_force always puts the charge groups in the box and shifts again
439 * We do not unshift, so molecules are always whole in congrad.c
441 do_force(log
,cr
,mcr
,parm
,nsb
,force_vir
,pme_vir
,
442 count
,&(nrnb
[cr
->nodeid
]),top
,grps
,xprime
,buf
,f
,
443 buf
,mdatoms
,ener
,fcd
,bVerbose
&& !(PAR(cr
)),
444 lambda
,graph
,bNS
,FALSE
,fr
,mu_tot
,FALSE
,0.0);
446 /* Spread the force on dummy particle to the other particles... */
448 spread_dummy_f(log
,xprime
,f
,&(nrnb
[cr
->nodeid
]),&top
->idef
,dummycomm
,cr
);
450 /* Sum the potential energy terms from group contributions */
451 sum_epot(&(parm
->ir
.opts
),grps
,ener
);
452 fnorm
= f_norm(cr
,&(parm
->ir
.opts
),mdatoms
,start
,end
,f
);
454 /* Clear stuff again */
455 clear_mat(force_vir
);
456 clear_mat(shake_vir
);
458 /* Communicate stuff when parallel */
460 global_stat(log
,cr
,ener
,force_vir
,shake_vir
,
461 &(parm
->ir
.opts
),grps
,&mynrnb
,nrnb
,vcm
,&terminate
);
463 EpotA
= ener
[F_EPOT
];
467 /* new search direction */
468 /* beta = 0 means steepest descents */
469 if (bBeta0
|| (nstcg
&& ((count
% nstcg
)==0))) {
471 fprintf(stderr
,"\rNew search direction\n");
475 beta
= sqr(fnorm
/fnorm_old
);
477 /* update x, fnorm_old */
478 for (i
=start
; i
<end
; i
++)
479 copy_rvec(xprime
[i
],x
[i
]);
482 /* Test whether the convergence criterion is met */
483 fmax
=f_max(cr
->left
,cr
->right
,nsb
->nnodes
,&(parm
->ir
.opts
),mdatoms
,
486 /* Print it if necessary */
487 if (bVerbose
&& MASTER(cr
)) {
488 fprintf(stderr
,"\rStep %d, E-Pot = %16.10e, Fmax = %12.5e, atom = %d\n",
489 count
,EpotA
,fmax
,nfmax
);
490 /* Store the new (lower) energies */
491 upd_mdebin(mdebin
,NULL
,mdatoms
->tmass
,count
,(real
)count
,
492 ener
,parm
->box
,shake_vir
,
493 force_vir
,parm
->vir
,parm
->pres
,grps
,mu_tot
,
494 (parm
->ir
.etc
==etcNOSEHOOVER
));
495 /* Print the energies allways when we should be verbose */
496 print_ebin_header(log
,count
,count
,lambda
);
497 print_ebin(fp_ene
,TRUE
,FALSE
,FALSE
,FALSE
,log
,count
,count
,eprNORMAL
,
498 TRUE
,mdebin
,fcd
,&(top
->atoms
),&(parm
->ir
.opts
));
501 /* Stop when the maximum force lies below tolerance */
502 bDone
=(fmax
< parm
->ir
.em_tol
);
503 } /* End of the loop */
505 /* Print some shit... */
507 fprintf(stderr
,"\nwriting lowest energy coordinates.\n");
510 write_traj(log
,cr
,ftp2fn(efTRN
,nfile
,fnm
),
511 nsb
,count
,(real
) count
,
512 lambda
,nrnb
,nsb
->natoms
,xx
,NULL
,ff
,parm
->box
);
514 write_sto_conf(ftp2fn(efSTO
,nfile
,fnm
),
515 *top
->name
, &(top
->atoms
),xx
,NULL
,parm
->box
);
517 fmax
=f_max(cr
->left
,cr
->right
,nsb
->nnodes
,&(parm
->ir
.opts
),mdatoms
,
520 print_converged(stderr
,CG
,parm
->ir
.em_tol
,count
,bDone
,
521 number_steps
,EpotA
,fmax
);
522 print_converged(log
,CG
,parm
->ir
.em_tol
,count
,bDone
,
523 number_steps
,EpotA
,fmax
);
527 /* To print the actual number of steps we needed somewhere */
528 parm
->ir
.nsteps
=count
;
531 } /* That's all folks */
533 time_t do_steep(FILE *log
,int nfile
,t_filenm fnm
[],
534 t_parm
*parm
,t_topology
*top
,
535 t_groups
*grps
,t_nsborder
*nsb
,
536 rvec x
[],rvec grad
[],rvec buf
[],t_mdatoms
*mdatoms
,
537 tensor ekin
,real ener
[],t_fcdata
*fcd
,t_nrnb nrnb
[],
538 bool bVerbose
,bool bDummies
, t_comm_dummies
*dummycomm
,
539 t_commrec
*cr
,t_commrec
*mcr
,t_graph
*graph
,
540 t_forcerec
*fr
,rvec box_size
)
542 const char *SD
="Steepest Descents";
543 real stepsize
,constepsize
,lambda
,fmax
;
544 rvec
*pos
[2],*force
[2],*xcf
=NULL
;
548 real ustep
,dvdlambda
;
553 bool bDone
,bAbort
,bLR
,bLJLR
,bBHAM
,b14
;
555 tensor force_vir
,shake_vir
,pme_vir
;
559 int i
,m
,start
,end
,gf
;
561 int steps_accepted
=0;
567 init_em(log
,SD
,parm
,&lambda
,&mynrnb
,mu_tot
,box_size
,fr
,mdatoms
,top
,
568 nsb
,cr
,&vcm
,&start
,&end
);
570 /* Print to log file */
571 start_t
=print_date_and_time(log
,cr
->nodeid
,"Started Steepest Descents");
573 /* We need two coordinate arrays and two force arrays */
574 for(i
=0; (i
<2); i
++) {
575 snew(pos
[i
],nsb
->natoms
);
576 snew(force
[i
],nsb
->natoms
);
579 /* Set some booleans for the epot routines */
580 set_pot_bools(&(parm
->ir
),top
,&bLR
,&bLJLR
,&bBHAM
,&b14
);
582 /* Open the enrgy file */
584 fp_ene
=open_enx(ftp2fn(efENX
,nfile
,fnm
),"w");
588 /* Init bin for energy stuff */
589 mdebin
=init_mdebin(fp_ene
,grps
,&(top
->atoms
),&(top
->idef
),bLR
,bLJLR
,
590 bBHAM
,b14
,parm
->ir
.efep
!=efepNO
,parm
->ir
.epc
,
591 parm
->ir
.eDispCorr
,TRICLINIC(parm
->ir
.compress
),
592 (parm
->ir
.etc
==etcNOSEHOOVER
),cr
);
594 /* Clear some matrix variables */
595 clear_mat(force_vir
);
596 clear_mat(shake_vir
);
598 if (fr
->ePBC
!= epbcNONE
)
599 /* Remove periodicity */
600 do_pbc_first(log
,parm
,box_size
,fr
,graph
,x
);
602 /* Initiate constraint stuff */
603 bConstrain
=init_constraints(stdlog
,top
,&(parm
->ir
),mdatoms
,
607 snew(xcf
,nsb
->natoms
);
609 /* Copy coord vectors to our temp array */
610 for(i
=0; (i
<nsb
->natoms
); i
++) {
611 copy_rvec(x
[i
],pos
[Min
][i
]);
612 copy_rvec(x
[i
],pos
[TRY
][i
]);
615 /* Set variables for stepsize (in nm). This is the largest
616 * step that we are going to make in any direction.
618 ustep
= parm
->ir
.em_stepsize
;
621 /* Max number of steps */
622 nsteps
=parm
->ir
.nsteps
;
625 /* Print to the screen */
626 sp_header(stderr
,SD
,parm
->ir
.em_tol
,nsteps
);
627 sp_header(log
,SD
,parm
->ir
.em_tol
,nsteps
);
629 /**** HERE STARTS THE LOOP ****
630 * count is the counter for the number of steps
631 * bDone will be TRUE when the minimization has converged
632 * bAbort will be TRUE when nsteps steps have been performed or when
633 * the stepsize becomes smaller than is reasonable for machine precision
638 while( !bDone
&& !bAbort
) {
639 bAbort
= (nsteps
> 0) && (count
==nsteps
);
641 /* set new coordinates, except for first step */
643 for(i
=start
; i
<end
; i
++) {
644 gf
= mdatoms
->cFREEZE
[i
];
646 if (parm
->ir
.opts
.nFreeze
[gf
][m
])
647 pos
[TRY
][i
][m
] = pos
[Min
][i
][m
];
649 pos
[TRY
][i
][m
] = pos
[Min
][i
][m
] + stepsize
* force
[Min
][i
][m
];
654 constrain(stdlog
,top
,&(parm
->ir
),count
,mdatoms
,start
,end
,
655 pos
[Min
],pos
[TRY
],NULL
,parm
->box
,lambda
,&dvdlambda
,nrnb
,
660 construct_dummies(log
,pos
[TRY
],&(nrnb
[cr
->nodeid
]),1,NULL
,&top
->idef
,
661 graph
,cr
,parm
->box
,dummycomm
);
663 /* Calc force & energy on new positions
664 * do_force always puts the charge groups in the box and shifts again
665 * We do not unshift, so molecules are always whole in steep.c
667 do_force(log
,cr
,mcr
,parm
,nsb
,force_vir
,pme_vir
,
668 count
,&(nrnb
[cr
->nodeid
]),top
,grps
,pos
[TRY
],buf
,force
[TRY
],buf
,
669 mdatoms
,ener
,fcd
,bVerbose
&& !(PAR(cr
)),
670 lambda
,graph
,parm
->ir
.nstlist
>0 || count
==0,FALSE
,fr
,mu_tot
,
673 /* Spread the force on dummy particle to the other particles... */
675 spread_dummy_f(log
,pos
[TRY
],force
[TRY
],&(nrnb
[cr
->nodeid
]),
676 &top
->idef
,dummycomm
,cr
);
678 /* Sum the potential energy terms from group contributions */
679 sum_epot(&(parm
->ir
.opts
),grps
,ener
);
682 print_ebin_header(log
,count
,count
,lambda
);
685 fmax
=f_max(cr
->left
,cr
->right
,nsb
->nnodes
,&(parm
->ir
.opts
),mdatoms
,start
,end
,
687 constepsize
=ustep
/fmax
;
688 for(i
=start
; (i
<end
); i
++)
690 xcf
[i
][m
] = pos
[TRY
][i
][m
] + constepsize
*force
[TRY
][i
][m
];
693 constrain(stdlog
,top
,&(parm
->ir
),count
,mdatoms
,start
,end
,
694 pos
[TRY
],xcf
,NULL
,parm
->box
,lambda
,&dvdlambda
,nrnb
,TRUE
);
696 for(i
=start
; (i
<end
); i
++)
698 force
[TRY
][i
][m
] = (xcf
[i
][m
] - pos
[TRY
][i
][m
])/constepsize
;
701 /* Clear stuff again */
702 clear_mat(force_vir
);
703 clear_mat(shake_vir
);
705 /* Communicat stuff when parallel */
707 global_stat(log
,cr
,ener
,force_vir
,shake_vir
,
708 &(parm
->ir
.opts
),grps
,&mynrnb
,nrnb
,vcm
,&terminate
);
710 /* This is the new energy */
711 Fmax
[TRY
]=f_max(cr
->left
,cr
->right
,nsb
->nnodes
,&(parm
->ir
.opts
),mdatoms
,
712 start
,end
,force
[TRY
],&nfmax
);
713 Epot
[TRY
]=ener
[F_EPOT
];
715 Epot
[Min
] = Epot
[TRY
]+1;
717 /* Print it if necessary */
720 fprintf(stderr
,"Step=%5d, Dmax= %6.1e nm, Epot= %12.5e Fmax= %11.5e, atom= %d%c",
721 count
,ustep
,Epot
[TRY
],Fmax
[TRY
],nfmax
+1,
722 (Epot
[TRY
]<Epot
[Min
])?'\n':'\r');
725 if (Epot
[TRY
] < Epot
[Min
]) {
726 /* Store the new (lower) energies */
727 upd_mdebin(mdebin
,NULL
,mdatoms
->tmass
,count
,(real
)count
,
728 ener
,parm
->box
,shake_vir
,
729 force_vir
,parm
->vir
,parm
->pres
,grps
,mu_tot
,(parm
->ir
.etc
==etcNOSEHOOVER
));
730 print_ebin(fp_ene
,TRUE
,
731 do_per_step(steps_accepted
,parm
->ir
.nstdisreout
),
732 do_per_step(steps_accepted
,parm
->ir
.nstorireout
),
733 do_per_step(steps_accepted
,parm
->ir
.nstdihreout
),
734 log
,count
,count
,eprNORMAL
,TRUE
,mdebin
,fcd
,&(top
->atoms
),&(parm
->ir
.opts
));
739 /* Now if the new energy is smaller than the previous...
740 * or if this is the first step!
741 * or if we did random steps!
744 if ( (count
==0) || (Epot
[TRY
] < Epot
[Min
]) ) {
746 if (do_per_step(steps_accepted
,parm
->ir
.nstfout
))
750 if (do_per_step(steps_accepted
,parm
->ir
.nstxout
)) {
752 write_traj(log
,cr
,ftp2fn(efTRN
,nfile
,fnm
),
753 nsb
,count
,(real
) count
,
754 lambda
,nrnb
,nsb
->natoms
,xx
,NULL
,ff
,parm
->box
);
758 /* Test whether the convergence criterion is met... */
759 bDone
=(Fmax
[TRY
] < parm
->ir
.em_tol
);
761 /* Copy the arrays for force, positions and energy */
762 /* The 'Min' array always holds the coords and forces of the minimal
766 /* increase step size */
771 /* If energy is not smaller make the step smaller... */
774 /* Determine new step */
775 fmax
= f_max(cr
->left
,cr
->right
,nsb
->nnodes
,&(parm
->ir
.opts
),mdatoms
,start
,end
,
779 /* Check if stepsize is too small, with 1 nm as a characteristic length */
785 warn_step(stderr
,ustep
,parm
->ir
.em_tol
,bConstrain
);
786 warn_step(log
,ustep
,parm
->ir
.em_tol
,bConstrain
);
791 } /* End of the loop */
793 /* Print some shit... */
795 fprintf(stderr
,"\nwriting lowest energy coordinates.\n");
798 write_traj(log
,cr
,ftp2fn(efTRN
,nfile
,fnm
),
799 nsb
,count
,(real
) count
,
800 lambda
,nrnb
,nsb
->natoms
,xx
,NULL
,ff
,parm
->box
);
802 write_sto_conf(ftp2fn(efSTO
,nfile
,fnm
),
803 *top
->name
, &(top
->atoms
),xx
,NULL
,parm
->box
);
805 print_converged(stderr
,SD
,parm
->ir
.em_tol
,count
,bDone
,nsteps
,Epot
[Min
],Fmax
[Min
]);
806 print_converged(log
,SD
,parm
->ir
.em_tol
,count
,bDone
,nsteps
,Epot
[Min
],Fmax
[Min
]);
810 /* Put the coordinates back in the x array (otherwise the whole
811 * minimization would be in vain)
813 for(i
=0; (i
<nsb
->natoms
); i
++)
814 copy_rvec(pos
[Min
][i
],x
[i
]);
816 /* To print the actual number of steps we needed somewhere */
817 parm
->ir
.nsteps
=count
;
820 } /* That's all folks */
822 time_t do_nm(FILE *log
,t_commrec
*cr
,int nfile
,t_filenm fnm
[],
823 bool bVerbose
,bool bCompact
,int stepout
,
824 t_parm
*parm
,t_groups
*grps
,
825 t_topology
*top
,real ener
[],t_fcdata
*fcd
,
826 rvec x
[],rvec vold
[],rvec v
[],rvec vt
[],rvec f
[],
827 rvec buf
[],t_mdatoms
*mdatoms
,
828 t_nsborder
*nsb
,t_nrnb nrnb
[],
829 t_graph
*graph
,t_edsamyn
*edyn
,
830 t_forcerec
*fr
,rvec box_size
)
835 real t
,lambda
,t0
,lam0
;
836 bool bNS
,bStopCM
,bTYZ
,bLR
,bLJLR
,bBHAM
,b14
,bBox
;
837 tensor force_vir
,shake_vir
,pme_vir
;
843 /* added with respect to mdrun */
845 real der_range
=1.0e-6,fmax
;
847 snew(dfdx
,top
->atoms
.nr
);
852 /* end nmrun differences */
856 "WARNING: This version of GROMACS has been compiled in single precision,\n"
857 " which is usually not accurate enough for normal mode analysis.\n"
858 " For reliable results you should compile GROMACS in double precision.\n\n");
862 t0
= parm
->ir
.init_t
;
863 lam0
= parm
->ir
.init_lambda
;
867 /* Check Environment variables */
868 bTYZ
=getenv("TYZ") != NULL
;
872 bBox
= (fr
->ePBC
!= epbcNONE
);
874 calc_shifts(parm
->box
,box_size
,fr
->shift_vec
);
875 fprintf(log
,"Removing pbc first time\n");
876 mk_mshift(log
,graph
,parm
->box
,x
);
877 shift_self(graph
,parm
->box
,x
);
881 set_pot_bools(&(parm
->ir
),top
,&bLR
,&bLJLR
,&bBHAM
,&b14
);
882 mdebin
=init_mdebin(fp_ene
,grps
,&(top
->atoms
),&(top
->idef
),bLR
,bLJLR
,
883 bBHAM
,b14
,parm
->ir
.efep
!=efepNO
,parm
->ir
.epc
,
884 parm
->ir
.eDispCorr
,TRICLINIC(parm
->ir
.compress
),(parm
->ir
.etc
==etcNOSEHOOVER
),cr
);
886 ener
[F_TEMP
]=sum_ekin(&(parm
->ir
.opts
),grps
,parm
->ekin
,bTYZ
);
887 if(parm
->ir
.etc
==etcBERENDSEN
)
888 berendsen_tcoupl(&(parm
->ir
.opts
),grps
,parm
->ir
.delta_t
);
889 else if(parm
->ir
.etc
==etcNOSEHOOVER
)
890 nosehoover_tcoupl(&(parm
->ir
.opts
),grps
,parm
->ir
.delta_t
);
894 /* Write start time and temperature */
895 start_t
=print_date_and_time(log
,cr
->nodeid
,"Started nmrun");
897 fprintf(stderr
,"starting nmrun '%s'\n%d steps.\n\n",*(top
->name
),
901 /* Call do_force once to make pairlist */
902 clear_mat(force_vir
);
905 do_force(log
,cr
,NULL
,parm
,nsb
,force_vir
,pme_vir
,0,&mynrnb
,
906 top
,grps
,x
,v
,f
,buf
,mdatoms
,ener
,fcd
,bVerbose
&& !PAR(cr
),
907 lambda
,graph
,bNS
,FALSE
,fr
,mu_tot
,FALSE
,0.0);
910 /* Shift back the coordinates, since we're not calling update */
911 unshift_self(graph
,parm
->box
,x
);
914 /* if forces not small, warn user */
915 fmax
=f_max(cr
->left
,cr
->right
,nsb
->nnodes
,&(parm
->ir
.opts
),mdatoms
,
916 0,top
->atoms
.nr
,f
,&nfmax
);
917 fprintf(stderr
,"Maximum force:%12.5e\n",fmax
);
919 fprintf(stderr
,"Maximum force probably not small enough to");
920 fprintf(stderr
," ensure that you are in a \nenergy well. ");
921 fprintf(stderr
,"Be aware that negative eigenvalues may occur");
922 fprintf(stderr
," when the\nresulting matrix is diagonalized.\n");
925 /***********************************************************
927 * Loop over all pairs in matrix
929 * do_force called twice. Once with positive and
930 * once with negative displacement
932 ************************************************************/
934 /* fudge nr of steps to nr of atoms */
936 parm
->ir
.nsteps
=top
->atoms
.nr
;
938 for (step
=0; (step
<parm
->ir
.nsteps
); step
++) {
940 for (idum
=0; (idum
<DIM
); idum
++) {
942 x
[step
][idum
]=x
[step
][idum
]-der_range
;
944 clear_mat(force_vir
);
946 do_force(log
,cr
,NULL
,parm
,nsb
,force_vir
,pme_vir
,2*(step
*DIM
+idum
),
948 top
,grps
,x
,v
,f
,buf
,mdatoms
,ener
,fcd
,bVerbose
&& !PAR(cr
),
949 lambda
,graph
,bNS
,FALSE
,fr
,mu_tot
,FALSE
,0.0);
951 /* Shift back the coordinates, since we're not calling update */
952 unshift_self(graph
,parm
->box
,x
);
954 for (jdum
=0; (jdum
<top
->atoms
.nr
); jdum
++) {
955 for (kdum
=0; (kdum
<DIM
); kdum
++) {
956 dfdx
[jdum
][kdum
]=f
[jdum
][kdum
];
960 x
[step
][idum
]=x
[step
][idum
]+2.0*der_range
;
962 clear_mat(force_vir
);
964 do_force(log
,cr
,NULL
,parm
,nsb
,force_vir
,pme_vir
,2*(step
*DIM
+idum
)+1,
966 top
,grps
,x
,v
,f
,buf
,mdatoms
,ener
,fcd
,bVerbose
&& !PAR(cr
),
967 lambda
,graph
,bNS
,FALSE
,fr
,mu_tot
,FALSE
,0.0);
969 /* Shift back the coordinates, since we're not calling update */
970 unshift_self(graph
,parm
->box
,x
);
972 for (jdum
=0; (jdum
<top
->atoms
.nr
); jdum
++) {
973 for (kdum
=0; (kdum
<DIM
); kdum
++) {
974 dfdx
[jdum
][kdum
]=(f
[jdum
][kdum
]-dfdx
[jdum
][kdum
])/(2*der_range
);
978 /* store derivatives now, diagonalization later */
980 write_traj(log
,cr
,ftp2fn(efMTX
,nfile
,fnm
),
981 nsb
,step
,t
,lambda
,nrnb
,nsb
->natoms
,xx
,vv
,ff
,parm
->box
);
983 /* x is restored to original */
984 x
[step
][idum
]=x
[step
][idum
]-der_range
;
989 /*if (MASTER(cr) && bVerbose && ((step % stepout)==0))
990 print_time(stderr,start_t,step,&parm->ir);*/
993 if (MASTER(cr
) && bVerbose
) {
994 fprintf(stderr
,"\rFinished step %d out of %d",step
+1,top
->atoms
.nr
);
998 t
=t0
+step
*parm
->ir
.delta_t
;
999 lambda
=lam0
+step
*parm
->ir
.delta_lambda
;
1002 print_ebin(-1,FALSE
,FALSE
,FALSE
,FALSE
,log
,step
,t
,eprAVER
,
1003 FALSE
,mdebin
,fcd
,&(top
->atoms
),&(parm
->ir
.opts
));
1004 print_ebin(-1,FALSE
,FALSE
,FALSE
,FALSE
,log
,step
,t
,eprRMS
,
1005 FALSE
,mdebin
,fcd
,&(top
->atoms
),&(parm
->ir
.opts
));
1008 /* Construct dummy particles, for last output frame */
1009 /* NB: I have not included the communication for parallel
1010 * dummies here, since the rest of nm doesn't seem to
1011 * be parallelized. Be sure to copy the correct code from
1012 * e.g. md.c or steep.c if you make nm parallel!
1014 construct_dummies(log
,x
,&mynrnb
,parm
->ir
.delta_t
,v
,&top
->idef
,
1015 graph
,cr
,parm
->box
,NULL
);
1017 /*free_nslist(log);*/