Partial commit of the project to remove all static variables.
[gromacs.git] / src / mdlib / minimize.c
blob1c519e836fc5cefe919ff6c4c2796ec550a353bb
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.1
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
30 * And Hey:
31 * Getting the Right Output Means no Artefacts in Calculating Stuff
34 #include <string.h>
35 #include <time.h>
36 #include <math.h>
37 #include "sysstuff.h"
38 #include "string2.h"
39 #include "network.h"
40 #include "confio.h"
41 #include "copyrite.h"
42 #include "vcm.h"
43 #include "smalloc.h"
44 #include "nrnb.h"
45 #include "main.h"
46 #include "pbc.h"
47 #include "force.h"
48 #include "macros.h"
49 #include "random.h"
50 #include "names.h"
51 #include "fatal.h"
52 #include "txtdump.h"
53 #include "typedefs.h"
54 #include "update.h"
55 #include "random.h"
56 #include "constr.h"
57 #include "vec.h"
58 #include "statutil.h"
59 #include "tgroup.h"
60 #include "mdebin.h"
61 #include "dummies.h"
62 #include "mdrun.h"
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",
76 ustep,ftol);
77 if (bConstrain)
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)
85 if (bDone)
86 fprintf(fp,"\n%s converged to %g in %d steps\n",alg,ftol,count);
87 else
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;
98 int i,m,gf;
100 /* This routine finds the largest force and returns it.
101 * On parallel machines the global max is taken.
103 fmax2 = 0;
104 nfm = -1;
105 for(i=start; i<end; i++) {
106 gf = mdatoms->cFREEZE[i];
107 fam = 0;
108 for(m=0; m<DIM; m++)
109 if (!opts->nFreeze[gf][m])
110 fam += sqr(grad[i][m]);
111 if (fam > fmax2) {
112 fmax2 = fam;
113 nfm = i;
117 *nfmax = nfm;
118 if (nnodes > 1) {
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) {
127 fmax2 = fmax2_0;
128 *nfmax = nfm;
132 return sqrt(fmax2);
135 static real f_norm(t_commrec *cr,
136 t_grpopts *opts,t_mdatoms *mdatoms,
137 int start,int end,rvec grad[])
139 double fnorm2;
140 int i,m,gf;
142 /* This routine returns the norm of the force */
143 fnorm2 = 0;
145 for(i=start; i<end; i++) {
146 gf = mdatoms->cFREEZE[i];
147 for(m=0; m<DIM; m++)
148 if (!opts->nFreeze[gf][m])
149 fnorm2 += sqr(grad[i][m]);
152 if (PAR(cr))
153 gmx_sumd(1,&fnorm2,cr);
155 return sqrt(fnorm2);
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;
168 else
169 *lambda = 0.0;
171 init_nrnb(mynrnb);
173 clear_rvec(mu_tot);
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";
196 double gpa,gpb;
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;
201 t_vcm *vcm;
202 t_mdebin *mdebin;
203 t_nrnb mynrnb;
204 bool bNS=TRUE,bDone,bLR,bLJLR,bBHAM,b14,bRand,brerun,bBeta0=FALSE;
205 rvec mu_tot;
206 time_t start_t;
207 tensor force_vir,shake_vir,pme_vir;
208 int number_steps,naccept=0,nstcg=parm->ir.nstcgsteep;
209 int fp_ene,count=0;
210 int i,m,nfmax,start,end,niti,gf;
211 /* not used */
212 real terminate=0;
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 */
221 snew(p,nsb->natoms);
222 snew(f,nsb->natoms);
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 */
229 if (MASTER(cr))
230 fp_ene=open_enx(ftp2fn(efENX,nfile,fnm),"w");
231 else
232 fp_ene=-1;
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;
251 if (MASTER(cr))
252 sp_header(stderr,CG,parm->ir.em_tol,number_steps);
253 sp_header(log,CG,parm->ir.em_tol,number_steps);
255 if (bDummies)
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);
266 where();
268 /* Spread the force on dummy particle to the other particles... */
269 if (bDummies)
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);
274 where();
276 /* Clear var. */
277 clear_mat(force_vir);
278 where();
280 /* Communicat energies etc. */
281 if (PAR(cr))
282 global_stat(log,cr,ener,force_vir,shake_vir,
283 &(parm->ir.opts),grps,&mynrnb,nrnb,vcm,&terminate);
284 where();
286 if (MASTER(cr)) {
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));
297 where();
299 /* This is the starting energy */
300 EpotA=ener[F_EPOT];
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);
306 fnorm_old=fnorm;
308 /* Print stepsize */
309 if (MASTER(cr)) {
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.
318 bDone=FALSE;
319 for(count=1; (!bDone && (count < number_steps)); count++) {
321 /* start conjugate gradient, determine search interval a,b */
322 gpa = 0.0;
323 for(i=start; (i<end); i++) {
324 gf = mdatoms->cFREEZE[i];
325 for(m=0; m<DIM; m++)
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];
331 if (PAR(cr))
332 gmx_sumd(1,&gpa,cr);
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.
338 a = 0.0;
339 b = parm->ir.em_stepsize/pnorm;
340 niti = 0;
342 /* search a,b iteratively, if necessary */
343 brerun=TRUE;
344 while (brerun) {
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);
352 if (bDummies)
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
360 * gradients
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... */
368 if (bDummies)
369 spread_dummy_f(log,xprime,f,&(nrnb[cr->nodeid]),&top->idef,
370 dummycomm,cr);
372 /* Sum the potential energy terms from group contributions */
373 sum_epot(&(parm->ir.opts),grps,ener);
374 where();
376 bNS = (parm->ir.nstlist > 0);
378 gpb=0.0;
379 for(i=start; (i<end); i++)
380 gpb -= iprod(p[i],f[i]);
382 if (PAR(cr))
383 gmx_sumd(1,&gpb,cr);
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 */
393 if (PAR(cr))
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))
400 brerun=FALSE;
401 else {
402 a = b;
403 EpotA = EpotB;
404 gpa = gpb;
405 b = 2.0*b;
407 niti++;
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;
414 if (w < 0.0) {
415 if (debug) {
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);
422 bBeta0 = TRUE;
424 else {
425 w = sqrt(w);
426 smin = b - ((gpb+w-zet)*(b-a))/((gpb-gpa)+2.0*w);
428 /* new positions */
429 for (i=start; i<end; i++)
430 for(m=0; m<DIM; m++)
431 xprime[i][m] = x[i][m] + smin*p[i][m];
433 if (bDummies)
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... */
447 if(bDummies)
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 */
459 if (PAR(cr))
460 global_stat(log,cr,ener,force_vir,shake_vir,
461 &(parm->ir.opts),grps,&mynrnb,nrnb,vcm,&terminate);
463 EpotA = ener[F_EPOT];
465 bBeta0 = FALSE;
467 /* new search direction */
468 /* beta = 0 means steepest descents */
469 if (bBeta0 || (nstcg && ((count % nstcg)==0))) {
470 if (bVerbose)
471 fprintf(stderr,"\rNew search direction\n");
472 beta = 0.0;
474 else
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]);
480 fnorm_old=fnorm;
482 /* Test whether the convergence criterion is met */
483 fmax=f_max(cr->left,cr->right,nsb->nnodes,&(parm->ir.opts),mdatoms,
484 start,end,f,&nfmax);
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... */
506 if (MASTER(cr))
507 fprintf(stderr,"\nwriting lowest energy coordinates.\n");
508 xx=x;
509 ff=f;
510 write_traj(log,cr,ftp2fn(efTRN,nfile,fnm),
511 nsb,count,(real) count,
512 lambda,nrnb,nsb->natoms,xx,NULL,ff,parm->box);
513 if (MASTER(cr))
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,
518 start,end,f,&nfmax);
519 if (MASTER(cr)) {
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);
524 close_enx(fp_ene);
527 /* To print the actual number of steps we needed somewhere */
528 parm->ir.nsteps=count;
530 return start_t;
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;
545 rvec *xx,*ff;
546 real Fmax[2];
547 real Epot[2];
548 real ustep,dvdlambda;
549 t_vcm *vcm;
550 int fp_ene;
551 t_mdebin *mdebin;
552 t_nrnb mynrnb;
553 bool bDone,bAbort,bLR,bLJLR,bBHAM,b14;
554 time_t start_t;
555 tensor force_vir,shake_vir,pme_vir;
556 rvec mu_tot;
557 int nfmax,nsteps;
558 int count=0;
559 int i,m,start,end,gf;
560 int Min=0;
561 int steps_accepted=0;
562 bool bConstrain;
563 /* not used */
564 real terminate=0;
565 #define TRY (1-Min)
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 */
583 if (MASTER(cr))
584 fp_ene=open_enx(ftp2fn(efENX,nfile,fnm),"w");
585 else
586 fp_ene=-1;
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,
604 start,end,FALSE,cr);
606 if (bConstrain)
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;
619 stepsize = 0;
621 /* Max number of steps */
622 nsteps=parm->ir.nsteps;
624 if (MASTER(cr))
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
635 count=0;
636 bDone=FALSE;
637 bAbort=FALSE;
638 while( !bDone && !bAbort ) {
639 bAbort = (nsteps > 0) && (count==nsteps);
641 /* set new coordinates, except for first step */
642 if (count>0)
643 for(i=start; i<end; i++) {
644 gf = mdatoms->cFREEZE[i];
645 for(m=0; m<DIM; m++)
646 if (parm->ir.opts.nFreeze[gf][m])
647 pos[TRY][i][m] = pos[Min][i][m];
648 else
649 pos[TRY][i][m] = pos[Min][i][m] + stepsize * force[Min][i][m];
652 if (bConstrain) {
653 dvdlambda=0;
654 constrain(stdlog,top,&(parm->ir),count,mdatoms,start,end,
655 pos[Min],pos[TRY],NULL,parm->box,lambda,&dvdlambda,nrnb,
656 TRUE);
659 if (bDummies)
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,
671 FALSE,0.0);
673 /* Spread the force on dummy particle to the other particles... */
674 if (bDummies)
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);
681 if (MASTER(cr))
682 print_ebin_header(log,count,count,lambda);
684 if (bConstrain) {
685 fmax=f_max(cr->left,cr->right,nsb->nnodes,&(parm->ir.opts),mdatoms,start,end,
686 force[TRY],&nfmax);
687 constepsize=ustep/fmax;
688 for(i=start; (i<end); i++)
689 for(m=0;(m<DIM);m++)
690 xcf[i][m] = pos[TRY][i][m] + constepsize*force[TRY][i][m];
692 dvdlambda=0;
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++)
697 for(m=0;(m<DIM);m++)
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 */
706 if (PAR(cr))
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];
714 if (count == 0)
715 Epot[Min] = Epot[TRY]+1;
717 /* Print it if necessary */
718 if (MASTER(cr)) {
719 if (bVerbose) {
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));
735 fflush(log);
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]) ) {
745 steps_accepted++;
746 if (do_per_step(steps_accepted,parm->ir.nstfout))
747 ff=force[TRY];
748 else
749 ff=NULL;
750 if (do_per_step(steps_accepted,parm->ir.nstxout)) {
751 xx=pos[TRY];
752 write_traj(log,cr,ftp2fn(efTRN,nfile,fnm),
753 nsb,count,(real) count,
754 lambda,nrnb,nsb->natoms,xx,NULL,ff,parm->box);
755 } else
756 xx=NULL;
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
763 sampled energy */
764 Min = TRY;
766 /* increase step size */
767 if (count>0)
768 ustep *= 1.2;
770 } else
771 /* If energy is not smaller make the step smaller... */
772 ustep *= 0.5;
774 /* Determine new step */
775 fmax = f_max(cr->left,cr->right,nsb->nnodes,&(parm->ir.opts),mdatoms,start,end,
776 force[Min],&nfmax);
777 stepsize=ustep/fmax;
779 /* Check if stepsize is too small, with 1 nm as a characteristic length */
780 #ifdef DOUBLE
781 if (ustep < 1e-12) {
782 #else
783 if (ustep < 1e-6) {
784 #endif
785 warn_step(stderr,ustep,parm->ir.em_tol,bConstrain);
786 warn_step(log,ustep,parm->ir.em_tol,bConstrain);
787 bAbort=TRUE;
790 count++;
791 } /* End of the loop */
793 /* Print some shit... */
794 if (MASTER(cr))
795 fprintf(stderr,"\nwriting lowest energy coordinates.\n");
796 xx=pos[Min];
797 ff=force[Min];
798 write_traj(log,cr,ftp2fn(efTRN,nfile,fnm),
799 nsb,count,(real) count,
800 lambda,nrnb,nsb->natoms,xx,NULL,ff,parm->box);
801 if (MASTER(cr)) {
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]);
807 close_enx(fp_ene);
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;
819 return start_t;
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)
832 t_mdebin *mdebin;
833 int fp_ene,step,nre;
834 time_t start_t;
835 real t,lambda,t0,lam0;
836 bool bNS,bStopCM,bTYZ,bLR,bLJLR,bBHAM,b14,bBox;
837 tensor force_vir,shake_vir,pme_vir;
838 t_nrnb mynrnb;
839 int i,m,nfmax;
840 rvec mu_tot;
841 rvec *xx,*vv,*ff;
843 /* added with respect to mdrun */
844 int idum,jdum,kdum;
845 real der_range=1.0e-6,fmax;
846 rvec *dfdx;
847 snew(dfdx,top->atoms.nr);
849 vv=NULL;
850 ff=NULL;
852 /* end nmrun differences */
854 #ifndef DOUBLE
855 fprintf(stderr,
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");
859 #endif
861 /* Initial values */
862 t0 = parm->ir.init_t;
863 lam0 = parm->ir.init_lambda;
864 t = t0;
865 lambda = lam0;
867 /* Check Environment variables */
868 bTYZ=getenv("TYZ") != NULL;
870 init_nrnb(&mynrnb);
872 bBox = (fr->ePBC != epbcNONE);
873 if (bBox) {
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);
880 fp_ene=-1;
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);
892 where();
894 /* Write start time and temperature */
895 start_t=print_date_and_time(log,cr->nodeid,"Started nmrun");
896 if (MASTER(cr)) {
897 fprintf(stderr,"starting nmrun '%s'\n%d steps.\n\n",*(top->name),
898 top->atoms.nr);
901 /* Call do_force once to make pairlist */
902 clear_mat(force_vir);
904 bNS=TRUE;
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);
908 bNS=FALSE;
909 if (bBox)
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);
918 if (fmax > 1.0e-3) {
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),
947 &mynrnb,
948 top,grps,x,v,f,buf,mdatoms,ener,fcd,bVerbose && !PAR(cr),
949 lambda,graph,bNS,FALSE,fr,mu_tot,FALSE,0.0);
950 if (bBox)
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,
965 &mynrnb,
966 top,grps,x,v,f,buf,mdatoms,ener,fcd,bVerbose && !PAR(cr),
967 lambda,graph,bNS,FALSE,fr,mu_tot,FALSE,0.0);
968 if (bBox)
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 */
979 xx=dfdx;
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;
986 if (bVerbose)
987 fflush(log);
989 /*if (MASTER(cr) && bVerbose && ((step % stepout)==0))
990 print_time(stderr,start_t,step,&parm->ir);*/
992 /* write progress */
993 if (MASTER(cr) && bVerbose) {
994 fprintf(stderr,"\rFinished step %d out of %d",step+1,top->atoms.nr);
995 fflush(stderr);
998 t=t0+step*parm->ir.delta_t;
999 lambda=lam0+step*parm->ir.delta_lambda;
1001 if (MASTER(cr)) {
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);*/
1019 return start_t;