Merge branch release-5-1 into release-2016
[alexxy/gromacs.git] / src / gromacs / mdlib / minimize.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 /*! \internal \file
38  *
39  * \brief This file defines integrators for energy minimization
40  *
41  * \author Berk Hess <hess@kth.se>
42  * \author Erik Lindahl <erik@kth.se>
43  * \ingroup module_mdlib
44  */
45 #include "gmxpre.h"
46
47 #include "minimize.h"
48
49 #include "config.h"
50
51 #include <cmath>
52 #include <cstring>
53 #include <ctime>
54
55 #include <algorithm>
56 #include <vector>
57
58 #include "gromacs/commandline/filenm.h"
59 #include "gromacs/domdec/domdec.h"
60 #include "gromacs/domdec/domdec_struct.h"
61 #include "gromacs/ewald/pme.h"
62 #include "gromacs/fileio/confio.h"
63 #include "gromacs/fileio/mtxio.h"
64 #include "gromacs/gmxlib/md_logging.h"
65 #include "gromacs/gmxlib/network.h"
66 #include "gromacs/gmxlib/nrnb.h"
67 #include "gromacs/imd/imd.h"
68 #include "gromacs/linearalgebra/sparsematrix.h"
69 #include "gromacs/listed-forces/manage-threading.h"
70 #include "gromacs/math/functions.h"
71 #include "gromacs/math/vec.h"
72 #include "gromacs/mdlib/constr.h"
73 #include "gromacs/mdlib/force.h"
74 #include "gromacs/mdlib/forcerec.h"
75 #include "gromacs/mdlib/gmx_omp_nthreads.h"
76 #include "gromacs/mdlib/md_support.h"
77 #include "gromacs/mdlib/mdatoms.h"
78 #include "gromacs/mdlib/mdebin.h"
79 #include "gromacs/mdlib/mdrun.h"
80 #include "gromacs/mdlib/ns.h"
81 #include "gromacs/mdlib/shellfc.h"
82 #include "gromacs/mdlib/sim_util.h"
83 #include "gromacs/mdlib/tgroup.h"
84 #include "gromacs/mdlib/trajectory_writing.h"
85 #include "gromacs/mdlib/update.h"
86 #include "gromacs/mdlib/vsite.h"
87 #include "gromacs/mdtypes/commrec.h"
88 #include "gromacs/mdtypes/inputrec.h"
89 #include "gromacs/mdtypes/md_enums.h"
90 #include "gromacs/pbcutil/mshift.h"
91 #include "gromacs/pbcutil/pbc.h"
92 #include "gromacs/timing/wallcycle.h"
93 #include "gromacs/timing/walltime_accounting.h"
94 #include "gromacs/topology/mtop_util.h"
95 #include "gromacs/utility/cstringutil.h"
96 #include "gromacs/utility/exceptions.h"
97 #include "gromacs/utility/fatalerror.h"
98 #include "gromacs/utility/smalloc.h"
99
100 //! Utility structure for manipulating states during EM
101 typedef struct {
102     //! Copy of the global state
103     t_state  s;
104     //! Force array
105     rvec    *f;
106     //! Potential energy
107     real     epot;
108     //! Norm of the force
109     real     fnorm;
110     //! Maximum force
111     real     fmax;
112     //! Direction
113     int      a_fmax;
114 } em_state_t;
115
116 //! Initiate em_state_t structure and return pointer to it
117 static em_state_t *init_em_state()
118 {
119     em_state_t *ems;
120
121     snew(ems, 1);
122
123     /* does this need to be here?  Should the array be declared differently (staticaly)in the state definition? */
124     snew(ems->s.lambda, efptNR);
125
126     return ems;
127 }
128
129 //! Print the EM starting conditions
130 static void print_em_start(FILE                     *fplog,
131                            t_commrec                *cr,
132                            gmx_walltime_accounting_t walltime_accounting,
133                            gmx_wallcycle_t           wcycle,
134                            const char               *name)
135 {
136     walltime_accounting_start(walltime_accounting);
137     wallcycle_start(wcycle, ewcRUN);
138     print_start(fplog, cr, walltime_accounting, name);
139 }
140
141 //! Stop counting time for EM
142 static void em_time_end(gmx_walltime_accounting_t walltime_accounting,
143                         gmx_wallcycle_t           wcycle)
144 {
145     wallcycle_stop(wcycle, ewcRUN);
146
147     walltime_accounting_end(walltime_accounting);
148 }
149
150 //! Printing a log file and console header
151 static void sp_header(FILE *out, const char *minimizer, real ftol, int nsteps)
152 {
153     fprintf(out, "\n");
154     fprintf(out, "%s:\n", minimizer);
155     fprintf(out, "   Tolerance (Fmax)   = %12.5e\n", ftol);
156     fprintf(out, "   Number of steps    = %12d\n", nsteps);
157 }
158
159 //! Print warning message
160 static void warn_step(FILE *fp, real ftol, gmx_bool bLastStep, gmx_bool bConstrain)
161 {
162     char buffer[2048];
163     if (bLastStep)
164     {
165         sprintf(buffer,
166                 "\nEnergy minimization reached the maximum number "
167                 "of steps before the forces reached the requested "
168                 "precision Fmax < %g.\n", ftol);
169     }
170     else
171     {
172         sprintf(buffer,
173                 "\nEnergy minimization has stopped, but the forces have "
174                 "not converged to the requested precision Fmax < %g (which "
175                 "may not be possible for your system). It stopped "
176                 "because the algorithm tried to make a new step whose size "
177                 "was too small, or there was no change in the energy since "
178                 "last step. Either way, we regard the minimization as "
179                 "converged to within the available machine precision, "
180                 "given your starting configuration and EM parameters.\n%s%s",
181                 ftol,
182                 sizeof(real) < sizeof(double) ?
183                 "\nDouble precision normally gives you higher accuracy, but "
184                 "this is often not needed for preparing to run molecular "
185                 "dynamics.\n" :
186                 "",
187                 bConstrain ?
188                 "You might need to increase your constraint accuracy, or turn\n"
189                 "off constraints altogether (set constraints = none in mdp file)\n" :
190                 "");
191     }
192     fputs(wrap_lines(buffer, 78, 0, FALSE), fp);
193 }
194
195 //! Print message about convergence of the EM
196 static void print_converged(FILE *fp, const char *alg, real ftol,
197                             gmx_int64_t count, gmx_bool bDone, gmx_int64_t nsteps,
198                             real epot, real fmax, int nfmax, real fnorm)
199 {
200     char buf[STEPSTRSIZE];
201
202     if (bDone)
203     {
204         fprintf(fp, "\n%s converged to Fmax < %g in %s steps\n",
205                 alg, ftol, gmx_step_str(count, buf));
206     }
207     else if (count < nsteps)
208     {
209         fprintf(fp, "\n%s converged to machine precision in %s steps,\n"
210                 "but did not reach the requested Fmax < %g.\n",
211                 alg, gmx_step_str(count, buf), ftol);
212     }
213     else
214     {
215         fprintf(fp, "\n%s did not converge to Fmax < %g in %s steps.\n",
216                 alg, ftol, gmx_step_str(count, buf));
217     }
218
219 #if GMX_DOUBLE
220     fprintf(fp, "Potential Energy  = %21.14e\n", epot);
221     fprintf(fp, "Maximum force     = %21.14e on atom %d\n", fmax, nfmax+1);
222     fprintf(fp, "Norm of force     = %21.14e\n", fnorm);
223 #else
224     fprintf(fp, "Potential Energy  = %14.7e\n", epot);
225     fprintf(fp, "Maximum force     = %14.7e on atom %d\n", fmax, nfmax+1);
226     fprintf(fp, "Norm of force     = %14.7e\n", fnorm);
227 #endif
228 }
229
230 //! Compute the norm and max of the force array in parallel
231 static void get_f_norm_max(t_commrec *cr,
232                            t_grpopts *opts, t_mdatoms *mdatoms, rvec *f,
233                            real *fnorm, real *fmax, int *a_fmax)
234 {
235     double fnorm2, *sum;
236     real   fmax2, fam;
237     int    la_max, a_max, start, end, i, m, gf;
238
239     /* This routine finds the largest force and returns it.
240      * On parallel machines the global max is taken.
241      */
242     fnorm2 = 0;
243     fmax2  = 0;
244     la_max = -1;
245     start  = 0;
246     end    = mdatoms->homenr;
247     if (mdatoms->cFREEZE)
248     {
249         for (i = start; i < end; i++)
250         {
251             gf  = mdatoms->cFREEZE[i];
252             fam = 0;
253             for (m = 0; m < DIM; m++)
254             {
255                 if (!opts->nFreeze[gf][m])
256                 {
257                     fam += gmx::square(f[i][m]);
258                 }
259             }
260             fnorm2 += fam;
261             if (fam > fmax2)
262             {
263                 fmax2  = fam;
264                 la_max = i;
265             }
266         }
267     }
268     else
269     {
270         for (i = start; i < end; i++)
271         {
272             fam     = norm2(f[i]);
273             fnorm2 += fam;
274             if (fam > fmax2)
275             {
276                 fmax2  = fam;
277                 la_max = i;
278             }
279         }
280     }
281
282     if (la_max >= 0 && DOMAINDECOMP(cr))
283     {
284         a_max = cr->dd->gatindex[la_max];
285     }
286     else
287     {
288         a_max = la_max;
289     }
290     if (PAR(cr))
291     {
292         snew(sum, 2*cr->nnodes+1);
293         sum[2*cr->nodeid]   = fmax2;
294         sum[2*cr->nodeid+1] = a_max;
295         sum[2*cr->nnodes]   = fnorm2;
296         gmx_sumd(2*cr->nnodes+1, sum, cr);
297         fnorm2 = sum[2*cr->nnodes];
298         /* Determine the global maximum */
299         for (i = 0; i < cr->nnodes; i++)
300         {
301             if (sum[2*i] > fmax2)
302             {
303                 fmax2 = sum[2*i];
304                 a_max = (int)(sum[2*i+1] + 0.5);
305             }
306         }
307         sfree(sum);
308     }
309
310     if (fnorm)
311     {
312         *fnorm = sqrt(fnorm2);
313     }
314     if (fmax)
315     {
316         *fmax  = sqrt(fmax2);
317     }
318     if (a_fmax)
319     {
320         *a_fmax = a_max;
321     }
322 }
323
324 //! Compute the norm of the force
325 static void get_state_f_norm_max(t_commrec *cr,
326                                  t_grpopts *opts, t_mdatoms *mdatoms,
327                                  em_state_t *ems)
328 {
329     get_f_norm_max(cr, opts, mdatoms, ems->f, &ems->fnorm, &ems->fmax, &ems->a_fmax);
330 }
331
332 //! Initialize the energy minimization
333 void init_em(FILE *fplog, const char *title,
334              t_commrec *cr, t_inputrec *ir,
335              t_state *state_global, gmx_mtop_t *top_global,
336              em_state_t *ems, gmx_localtop_t **top,
337              rvec **f,
338              t_nrnb *nrnb, rvec mu_tot,
339              t_forcerec *fr, gmx_enerdata_t **enerd,
340              t_graph **graph, t_mdatoms *mdatoms, gmx_global_stat_t *gstat,
341              gmx_vsite_t *vsite, gmx_constr_t constr,
342              int nfile, const t_filenm fnm[],
343              gmx_mdoutf_t *outf, t_mdebin **mdebin,
344              int imdport, unsigned long gmx_unused Flags,
345              gmx_wallcycle_t wcycle)
346 {
347     int  i;
348     real dvdl_constr;
349
350     if (fplog)
351     {
352         fprintf(fplog, "Initiating %s\n", title);
353     }
354
355     state_global->ngtc = 0;
356
357     /* Initialize lambda variables */
358     initialize_lambdas(fplog, ir, &(state_global->fep_state), state_global->lambda, NULL);
359
360     init_nrnb(nrnb);
361
362     /* Interactive molecular dynamics */
363     init_IMD(ir, cr, top_global, fplog, 1, state_global->x,
364              nfile, fnm, NULL, imdport, Flags);
365
366     if (DOMAINDECOMP(cr))
367     {
368         *top = dd_init_local_top(top_global);
369
370         dd_init_local_state(cr->dd, state_global, &ems->s);
371
372         *f = NULL;
373
374         /* Distribute the charge groups over the nodes from the master node */
375         dd_partition_system(fplog, ir->init_step, cr, TRUE, 1,
376                             state_global, top_global, ir,
377                             &ems->s, &ems->f, mdatoms, *top,
378                             fr, vsite, constr,
379                             nrnb, NULL, FALSE);
380         dd_store_state(cr->dd, &ems->s);
381
382         *graph = NULL;
383     }
384     else
385     {
386         snew(*f, top_global->natoms);
387
388         /* Just copy the state */
389         ems->s = *state_global;
390         /* We need to allocate one element extra, since we might use
391          * (unaligned) 4-wide SIMD loads to access rvec entries.
392          */
393         snew(ems->s.x, ems->s.nalloc + 1);
394         snew(ems->f, ems->s.nalloc+1);
395         snew(ems->s.v, ems->s.nalloc+1);
396         for (i = 0; i < state_global->natoms; i++)
397         {
398             copy_rvec(state_global->x[i], ems->s.x[i]);
399         }
400         copy_mat(state_global->box, ems->s.box);
401
402         *top      = gmx_mtop_generate_local_top(top_global, ir->efep != efepNO);
403
404         setup_bonded_threading(fr, &(*top)->idef);
405
406         if (ir->ePBC != epbcNONE && !fr->bMolPBC)
407         {
408             *graph = mk_graph(fplog, &((*top)->idef), 0, top_global->natoms, FALSE, FALSE);
409         }
410         else
411         {
412             *graph = NULL;
413         }
414
415         atoms2md(top_global, ir, 0, NULL, top_global->natoms, mdatoms);
416
417         if (vsite)
418         {
419             set_vsite_top(vsite, *top, mdatoms, cr);
420         }
421     }
422
423     update_mdatoms(mdatoms, state_global->lambda[efptMASS]);
424
425     if (constr)
426     {
427         if (ir->eConstrAlg == econtSHAKE &&
428             gmx_mtop_ftype_count(top_global, F_CONSTR) > 0)
429         {
430             gmx_fatal(FARGS, "Can not do energy minimization with %s, use %s\n",
431                       econstr_names[econtSHAKE], econstr_names[econtLINCS]);
432         }
433
434         if (!DOMAINDECOMP(cr))
435         {
436             set_constraints(constr, *top, ir, mdatoms, cr);
437         }
438
439         if (!ir->bContinuation)
440         {
441             /* Constrain the starting coordinates */
442             dvdl_constr = 0;
443             constrain(PAR(cr) ? NULL : fplog, TRUE, TRUE, constr, &(*top)->idef,
444                       ir, cr, -1, 0, 1.0, mdatoms,
445                       ems->s.x, ems->s.x, NULL, fr->bMolPBC, ems->s.box,
446                       ems->s.lambda[efptFEP], &dvdl_constr,
447                       NULL, NULL, nrnb, econqCoord);
448         }
449     }
450
451     if (PAR(cr))
452     {
453         *gstat = global_stat_init(ir);
454     }
455     else
456     {
457         *gstat = NULL;
458     }
459
460     *outf = init_mdoutf(fplog, nfile, fnm, 0, cr, ir, top_global, NULL, wcycle);
461
462     snew(*enerd, 1);
463     init_enerdata(top_global->groups.grps[egcENER].nr, ir->fepvals->n_lambda,
464                   *enerd);
465
466     if (mdebin != NULL)
467     {
468         /* Init bin for energy stuff */
469         *mdebin = init_mdebin(mdoutf_get_fp_ene(*outf), top_global, ir, NULL);
470     }
471
472     clear_rvec(mu_tot);
473     calc_shifts(ems->s.box, fr->shift_vec);
474 }
475
476 //! Finalize the minimization
477 static void finish_em(t_commrec *cr, gmx_mdoutf_t outf,
478                       gmx_walltime_accounting_t walltime_accounting,
479                       gmx_wallcycle_t wcycle)
480 {
481     if (!(cr->duty & DUTY_PME))
482     {
483         /* Tell the PME only node to finish */
484         gmx_pme_send_finish(cr);
485     }
486
487     done_mdoutf(outf);
488
489     em_time_end(walltime_accounting, wcycle);
490 }
491
492 //! Swap two different EM states during minimization
493 static void swap_em_state(em_state_t *ems1, em_state_t *ems2)
494 {
495     em_state_t tmp;
496
497     tmp   = *ems1;
498     *ems1 = *ems2;
499     *ems2 = tmp;
500 }
501
502 //! Copy coordinate from an EM state to a "normal" state structure
503 static void copy_em_coords(em_state_t *ems, t_state *state)
504 {
505     int i;
506
507     for (i = 0; (i < state->natoms); i++)
508     {
509         copy_rvec(ems->s.x[i], state->x[i]);
510     }
511 }
512
513 //! Save the EM trajectory
514 static void write_em_traj(FILE *fplog, t_commrec *cr,
515                           gmx_mdoutf_t outf,
516                           gmx_bool bX, gmx_bool bF, const char *confout,
517                           gmx_mtop_t *top_global,
518                           t_inputrec *ir, gmx_int64_t step,
519                           em_state_t *state,
520                           t_state *state_global)
521 {
522     int      mdof_flags;
523     gmx_bool bIMDout = FALSE;
524
525
526     /* Shall we do IMD output? */
527     if (ir->bIMD)
528     {
529         bIMDout = do_per_step(step, IMD_get_step(ir->imd->setup));
530     }
531
532     if ((bX || bF || bIMDout || confout != NULL) && !DOMAINDECOMP(cr))
533     {
534         copy_em_coords(state, state_global);
535     }
536
537     mdof_flags = 0;
538     if (bX)
539     {
540         mdof_flags |= MDOF_X;
541     }
542     if (bF)
543     {
544         mdof_flags |= MDOF_F;
545     }
546
547     /* If we want IMD output, set appropriate MDOF flag */
548     if (ir->bIMD)
549     {
550         mdof_flags |= MDOF_IMD;
551     }
552
553     mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags,
554                                      top_global, step, (double)step,
555                                      &state->s, state_global, state->f);
556
557     if (confout != NULL && MASTER(cr))
558     {
559         if (ir->ePBC != epbcNONE && !ir->bPeriodicMols && DOMAINDECOMP(cr))
560         {
561             /* Make molecules whole only for confout writing */
562             do_pbc_mtop(fplog, ir->ePBC, state_global->box, top_global,
563                         state_global->x);
564         }
565
566         write_sto_conf_mtop(confout,
567                             *top_global->name, top_global,
568                             state_global->x, NULL, ir->ePBC, state_global->box);
569     }
570 }
571
572 //! \brief Do one minimization step
573 //
574 // \returns true when the step succeeded, false when a constraint error occurred
575 static bool do_em_step(t_commrec *cr, t_inputrec *ir, t_mdatoms *md,
576                        gmx_bool bMolPBC,
577                        em_state_t *ems1, real a, rvec *f, em_state_t *ems2,
578                        gmx_constr_t constr, gmx_localtop_t *top,
579                        t_nrnb *nrnb, gmx_wallcycle_t wcycle,
580                        gmx_int64_t count)
581
582 {
583     t_state *s1, *s2;
584     int      start, end;
585     real     dvdl_constr;
586     int      nthreads gmx_unused;
587
588     bool     validStep = true;
589
590     s1 = &ems1->s;
591     s2 = &ems2->s;
592
593     if (DOMAINDECOMP(cr) && s1->ddp_count != cr->dd->ddp_count)
594     {
595         gmx_incons("state mismatch in do_em_step");
596     }
597
598     s2->flags = s1->flags;
599
600     if (s2->nalloc != s1->nalloc)
601     {
602         s2->nalloc = s1->nalloc;
603         /* We need to allocate one element extra, since we might use
604          * (unaligned) 4-wide SIMD loads to access rvec entries.
605          */
606         srenew(s2->x, s1->nalloc + 1);
607         srenew(ems2->f,  s1->nalloc);
608         if (s2->flags & (1<<estCGP))
609         {
610             srenew(s2->cg_p,  s1->nalloc + 1);
611         }
612     }
613
614     s2->natoms = s1->natoms;
615     copy_mat(s1->box, s2->box);
616     /* Copy free energy state */
617     for (int i = 0; i < efptNR; i++)
618     {
619         s2->lambda[i] = s1->lambda[i];
620     }
621     copy_mat(s1->box, s2->box);
622
623     start = 0;
624     end   = md->homenr;
625
626     // cppcheck-suppress unreadVariable
627     nthreads = gmx_omp_nthreads_get(emntUpdate);
628 #pragma omp parallel num_threads(nthreads)
629     {
630         rvec *x1 = s1->x;
631         rvec *x2 = s2->x;
632
633         int   gf = 0;
634 #pragma omp for schedule(static) nowait
635         for (int i = start; i < end; i++)
636         {
637             try
638             {
639                 if (md->cFREEZE)
640                 {
641                     gf = md->cFREEZE[i];
642                 }
643                 for (int m = 0; m < DIM; m++)
644                 {
645                     if (ir->opts.nFreeze[gf][m])
646                     {
647                         x2[i][m] = x1[i][m];
648                     }
649                     else
650                     {
651                         x2[i][m] = x1[i][m] + a*f[i][m];
652                     }
653                 }
654             }
655             GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
656         }
657
658         if (s2->flags & (1<<estCGP))
659         {
660             /* Copy the CG p vector */
661             rvec *p1 = s1->cg_p;
662             rvec *p2 = s2->cg_p;
663 #pragma omp for schedule(static) nowait
664             for (int i = start; i < end; i++)
665             {
666                 // Trivial OpenMP block that does not throw
667                 copy_rvec(p1[i], p2[i]);
668             }
669         }
670
671         if (DOMAINDECOMP(cr))
672         {
673             s2->ddp_count = s1->ddp_count;
674             if (s2->cg_gl_nalloc < s1->cg_gl_nalloc)
675             {
676 #pragma omp barrier
677                 s2->cg_gl_nalloc = s1->cg_gl_nalloc;
678                 try
679                 {
680                     /* We need to allocate one element extra, since we might use
681                      * (unaligned) 4-wide SIMD loads to access rvec entries.
682                      */
683                     srenew(s2->cg_gl, s2->cg_gl_nalloc + 1);
684                 }
685                 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
686 #pragma omp barrier
687             }
688             s2->ncg_gl = s1->ncg_gl;
689 #pragma omp for schedule(static) nowait
690             for (int i = 0; i < s2->ncg_gl; i++)
691             {
692                 s2->cg_gl[i] = s1->cg_gl[i];
693             }
694             s2->ddp_count_cg_gl = s1->ddp_count_cg_gl;
695         }
696     }
697
698     if (constr)
699     {
700         wallcycle_start(wcycle, ewcCONSTR);
701         dvdl_constr = 0;
702         validStep   =
703             constrain(NULL, TRUE, TRUE, constr, &top->idef,
704                       ir, cr, count, 0, 1.0, md,
705                       s1->x, s2->x, NULL, bMolPBC, s2->box,
706                       s2->lambda[efptBONDED], &dvdl_constr,
707                       NULL, NULL, nrnb, econqCoord);
708         wallcycle_stop(wcycle, ewcCONSTR);
709
710         // We should move this check to the different minimizers
711         if (!validStep && ir->eI != eiSteep)
712         {
713             gmx_fatal(FARGS, "The coordinates could not be constrained. Minimizer '%s' can not handle constraint failures, use minimizer '%s' before using '%s'.",
714                       EI(ir->eI), EI(eiSteep), EI(ir->eI));
715         }
716     }
717
718     return validStep;
719 }
720
721 //! Prepare EM for using domain decomposition parallellization
722 static void em_dd_partition_system(FILE *fplog, int step, t_commrec *cr,
723                                    gmx_mtop_t *top_global, t_inputrec *ir,
724                                    em_state_t *ems, gmx_localtop_t *top,
725                                    t_mdatoms *mdatoms, t_forcerec *fr,
726                                    gmx_vsite_t *vsite, gmx_constr_t constr,
727                                    t_nrnb *nrnb, gmx_wallcycle_t wcycle)
728 {
729     /* Repartition the domain decomposition */
730     dd_partition_system(fplog, step, cr, FALSE, 1,
731                         NULL, top_global, ir,
732                         &ems->s, &ems->f,
733                         mdatoms, top, fr, vsite, constr,
734                         nrnb, wcycle, FALSE);
735     dd_store_state(cr->dd, &ems->s);
736 }
737
738 //! De one energy evaluation
739 static void evaluate_energy(FILE *fplog, t_commrec *cr,
740                             gmx_mtop_t *top_global,
741                             em_state_t *ems, gmx_localtop_t *top,
742                             t_inputrec *inputrec,
743                             t_nrnb *nrnb, gmx_wallcycle_t wcycle,
744                             gmx_global_stat_t gstat,
745                             gmx_vsite_t *vsite, gmx_constr_t constr,
746                             t_fcdata *fcd,
747                             t_graph *graph, t_mdatoms *mdatoms,
748                             t_forcerec *fr, rvec mu_tot,
749                             gmx_enerdata_t *enerd, tensor vir, tensor pres,
750                             gmx_int64_t count, gmx_bool bFirst)
751 {
752     real     t;
753     gmx_bool bNS;
754     tensor   force_vir, shake_vir, ekin;
755     real     dvdl_constr, prescorr, enercorr, dvdlcorr;
756     real     terminate = 0;
757
758     /* Set the time to the initial time, the time does not change during EM */
759     t = inputrec->init_t;
760
761     if (bFirst ||
762         (DOMAINDECOMP(cr) && ems->s.ddp_count < cr->dd->ddp_count))
763     {
764         /* This is the first state or an old state used before the last ns */
765         bNS = TRUE;
766     }
767     else
768     {
769         bNS = FALSE;
770         if (inputrec->nstlist > 0)
771         {
772             bNS = TRUE;
773         }
774     }
775
776     if (vsite)
777     {
778         construct_vsites(vsite, ems->s.x, 1, NULL,
779                          top->idef.iparams, top->idef.il,
780                          fr->ePBC, fr->bMolPBC, cr, ems->s.box);
781     }
782
783     if (DOMAINDECOMP(cr) && bNS)
784     {
785         /* Repartition the domain decomposition */
786         em_dd_partition_system(fplog, count, cr, top_global, inputrec,
787                                ems, top, mdatoms, fr, vsite, constr,
788                                nrnb, wcycle);
789     }
790
791     /* Calc force & energy on new trial position  */
792     /* do_force always puts the charge groups in the box and shifts again
793      * We do not unshift, so molecules are always whole in congrad.c
794      */
795     do_force(fplog, cr, inputrec,
796              count, nrnb, wcycle, top, &top_global->groups,
797              ems->s.box, ems->s.x, &ems->s.hist,
798              ems->f, force_vir, mdatoms, enerd, fcd,
799              ems->s.lambda, graph, fr, vsite, mu_tot, t, NULL, NULL, TRUE,
800              GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES |
801              GMX_FORCE_VIRIAL | GMX_FORCE_ENERGY |
802              (bNS ? GMX_FORCE_NS : 0));
803
804     /* Clear the unused shake virial and pressure */
805     clear_mat(shake_vir);
806     clear_mat(pres);
807
808     /* Communicate stuff when parallel */
809     if (PAR(cr) && inputrec->eI != eiNM)
810     {
811         wallcycle_start(wcycle, ewcMoveE);
812
813         global_stat(gstat, cr, enerd, force_vir, shake_vir, mu_tot,
814                     inputrec, NULL, NULL, NULL, 1, &terminate,
815                     NULL, FALSE,
816                     CGLO_ENERGY |
817                     CGLO_PRESSURE |
818                     CGLO_CONSTRAINT);
819
820         wallcycle_stop(wcycle, ewcMoveE);
821     }
822
823     /* Calculate long range corrections to pressure and energy */
824     calc_dispcorr(inputrec, fr, ems->s.box, ems->s.lambda[efptVDW],
825                   pres, force_vir, &prescorr, &enercorr, &dvdlcorr);
826     enerd->term[F_DISPCORR] = enercorr;
827     enerd->term[F_EPOT]    += enercorr;
828     enerd->term[F_PRES]    += prescorr;
829     enerd->term[F_DVDL]    += dvdlcorr;
830
831     ems->epot = enerd->term[F_EPOT];
832
833     if (constr)
834     {
835         /* Project out the constraint components of the force */
836         wallcycle_start(wcycle, ewcCONSTR);
837         dvdl_constr = 0;
838         constrain(NULL, FALSE, FALSE, constr, &top->idef,
839                   inputrec, cr, count, 0, 1.0, mdatoms,
840                   ems->s.x, ems->f, ems->f, fr->bMolPBC, ems->s.box,
841                   ems->s.lambda[efptBONDED], &dvdl_constr,
842                   NULL, &shake_vir, nrnb, econqForceDispl);
843         enerd->term[F_DVDL_CONSTR] += dvdl_constr;
844         m_add(force_vir, shake_vir, vir);
845         wallcycle_stop(wcycle, ewcCONSTR);
846     }
847     else
848     {
849         copy_mat(force_vir, vir);
850     }
851
852     clear_mat(ekin);
853     enerd->term[F_PRES] =
854         calc_pres(fr->ePBC, inputrec->nwall, ems->s.box, ekin, vir, pres);
855
856     sum_dhdl(enerd, ems->s.lambda, inputrec->fepvals);
857
858     if (EI_ENERGY_MINIMIZATION(inputrec->eI))
859     {
860         get_state_f_norm_max(cr, &(inputrec->opts), mdatoms, ems);
861     }
862 }
863
864 //! Parallel utility summing energies and forces
865 static double reorder_partsum(t_commrec *cr, t_grpopts *opts, t_mdatoms *mdatoms,
866                               gmx_mtop_t *top_global,
867                               em_state_t *s_min, em_state_t *s_b)
868 {
869     rvec          *fm, *fb, *fmg;
870     t_block       *cgs_gl;
871     int            ncg, *cg_gl, *index, c, cg, i, a0, a1, a, gf, m;
872     double         partsum;
873     unsigned char *grpnrFREEZE;
874
875     if (debug)
876     {
877         fprintf(debug, "Doing reorder_partsum\n");
878     }
879
880     fm = s_min->f;
881     fb = s_b->f;
882
883     cgs_gl = dd_charge_groups_global(cr->dd);
884     index  = cgs_gl->index;
885
886     /* Collect fm in a global vector fmg.
887      * This conflicts with the spirit of domain decomposition,
888      * but to fully optimize this a much more complicated algorithm is required.
889      */
890     snew(fmg, top_global->natoms);
891
892     ncg   = s_min->s.ncg_gl;
893     cg_gl = s_min->s.cg_gl;
894     i     = 0;
895     for (c = 0; c < ncg; c++)
896     {
897         cg = cg_gl[c];
898         a0 = index[cg];
899         a1 = index[cg+1];
900         for (a = a0; a < a1; a++)
901         {
902             copy_rvec(fm[i], fmg[a]);
903             i++;
904         }
905     }
906     gmx_sum(top_global->natoms*3, fmg[0], cr);
907
908     /* Now we will determine the part of the sum for the cgs in state s_b */
909     ncg         = s_b->s.ncg_gl;
910     cg_gl       = s_b->s.cg_gl;
911     partsum     = 0;
912     i           = 0;
913     gf          = 0;
914     grpnrFREEZE = top_global->groups.grpnr[egcFREEZE];
915     for (c = 0; c < ncg; c++)
916     {
917         cg = cg_gl[c];
918         a0 = index[cg];
919         a1 = index[cg+1];
920         for (a = a0; a < a1; a++)
921         {
922             if (mdatoms->cFREEZE && grpnrFREEZE)
923             {
924                 gf = grpnrFREEZE[i];
925             }
926             for (m = 0; m < DIM; m++)
927             {
928                 if (!opts->nFreeze[gf][m])
929                 {
930                     partsum += (fb[i][m] - fmg[a][m])*fb[i][m];
931                 }
932             }
933             i++;
934         }
935     }
936
937     sfree(fmg);
938
939     return partsum;
940 }
941
942 //! Print some stuff, like beta, whatever that means.
943 static real pr_beta(t_commrec *cr, t_grpopts *opts, t_mdatoms *mdatoms,
944                     gmx_mtop_t *top_global,
945                     em_state_t *s_min, em_state_t *s_b)
946 {
947     rvec  *fm, *fb;
948     double sum;
949     int    gf, i, m;
950
951     /* This is just the classical Polak-Ribiere calculation of beta;
952      * it looks a bit complicated since we take freeze groups into account,
953      * and might have to sum it in parallel runs.
954      */
955
956     if (!DOMAINDECOMP(cr) ||
957         (s_min->s.ddp_count == cr->dd->ddp_count &&
958          s_b->s.ddp_count   == cr->dd->ddp_count))
959     {
960         fm  = s_min->f;
961         fb  = s_b->f;
962         sum = 0;
963         gf  = 0;
964         /* This part of code can be incorrect with DD,
965          * since the atom ordering in s_b and s_min might differ.
966          */
967         for (i = 0; i < mdatoms->homenr; i++)
968         {
969             if (mdatoms->cFREEZE)
970             {
971                 gf = mdatoms->cFREEZE[i];
972             }
973             for (m = 0; m < DIM; m++)
974             {
975                 if (!opts->nFreeze[gf][m])
976                 {
977                     sum += (fb[i][m] - fm[i][m])*fb[i][m];
978                 }
979             }
980         }
981     }
982     else
983     {
984         /* We need to reorder cgs while summing */
985         sum = reorder_partsum(cr, opts, mdatoms, top_global, s_min, s_b);
986     }
987     if (PAR(cr))
988     {
989         gmx_sumd(1, &sum, cr);
990     }
991
992     return sum/gmx::square(s_min->fnorm);
993 }
994
995 namespace gmx
996 {
997
998 /*! \brief Do conjugate gradients minimization
999     \copydoc integrator_t (FILE *fplog, t_commrec *cr,
1000                            int nfile, const t_filenm fnm[],
1001                            const gmx_output_env_t *oenv, gmx_bool bVerbose,
1002                            int nstglobalcomm,
1003                            gmx_vsite_t *vsite, gmx_constr_t constr,
1004                            int stepout,
1005                            t_inputrec *inputrec,
1006                            gmx_mtop_t *top_global, t_fcdata *fcd,
1007                            t_state *state_global,
1008                            t_mdatoms *mdatoms,
1009                            t_nrnb *nrnb, gmx_wallcycle_t wcycle,
1010                            gmx_edsam_t ed,
1011                            t_forcerec *fr,
1012                            int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
1013                            gmx_membed_t gmx_unused *membed,
1014                            real cpt_period, real max_hours,
1015                            int imdport,
1016                            unsigned long Flags,
1017                            gmx_walltime_accounting_t walltime_accounting)
1018  */
1019 double do_cg(FILE *fplog, t_commrec *cr,
1020              int nfile, const t_filenm fnm[],
1021              const gmx_output_env_t gmx_unused *oenv, gmx_bool bVerbose,
1022              int gmx_unused nstglobalcomm,
1023              gmx_vsite_t *vsite, gmx_constr_t constr,
1024              int gmx_unused stepout,
1025              t_inputrec *inputrec,
1026              gmx_mtop_t *top_global, t_fcdata *fcd,
1027              t_state *state_global,
1028              t_mdatoms *mdatoms,
1029              t_nrnb *nrnb, gmx_wallcycle_t wcycle,
1030              gmx_edsam_t gmx_unused ed,
1031              t_forcerec *fr,
1032              int gmx_unused repl_ex_nst, int gmx_unused repl_ex_nex, int gmx_unused repl_ex_seed,
1033              gmx_membed_t gmx_unused *membed,
1034              real gmx_unused cpt_period, real gmx_unused max_hours,
1035              int imdport,
1036              unsigned long gmx_unused Flags,
1037              gmx_walltime_accounting_t walltime_accounting)
1038 {
1039     const char       *CG = "Polak-Ribiere Conjugate Gradients";
1040
1041     em_state_t       *s_min, *s_a, *s_b, *s_c;
1042     gmx_localtop_t   *top;
1043     gmx_enerdata_t   *enerd;
1044     rvec             *f;
1045     gmx_global_stat_t gstat;
1046     t_graph          *graph;
1047     rvec             *p, *sf;
1048     double            gpa, gpb, gpc, tmp, minstep;
1049     real              fnormn;
1050     real              stepsize;
1051     real              a, b, c, beta = 0.0;
1052     real              epot_repl = 0;
1053     real              pnorm;
1054     t_mdebin         *mdebin;
1055     gmx_bool          converged, foundlower;
1056     rvec              mu_tot;
1057     gmx_bool          do_log = FALSE, do_ene = FALSE, do_x, do_f;
1058     tensor            vir, pres;
1059     int               number_steps, neval = 0, nstcg = inputrec->nstcgsteep;
1060     gmx_mdoutf_t      outf;
1061     int               i, m, gf, step, nminstep;
1062
1063     step = 0;
1064
1065     s_min = init_em_state();
1066     s_a   = init_em_state();
1067     s_b   = init_em_state();
1068     s_c   = init_em_state();
1069
1070     /* Init em and store the local state in s_min */
1071     init_em(fplog, CG, cr, inputrec,
1072             state_global, top_global, s_min, &top, &f,
1073             nrnb, mu_tot, fr, &enerd, &graph, mdatoms, &gstat, vsite, constr,
1074             nfile, fnm, &outf, &mdebin, imdport, Flags, wcycle);
1075
1076     /* Print to log file */
1077     print_em_start(fplog, cr, walltime_accounting, wcycle, CG);
1078
1079     /* Max number of steps */
1080     number_steps = inputrec->nsteps;
1081
1082     if (MASTER(cr))
1083     {
1084         sp_header(stderr, CG, inputrec->em_tol, number_steps);
1085     }
1086     if (fplog)
1087     {
1088         sp_header(fplog, CG, inputrec->em_tol, number_steps);
1089     }
1090
1091     /* Call the force routine and some auxiliary (neighboursearching etc.) */
1092     /* do_force always puts the charge groups in the box and shifts again
1093      * We do not unshift, so molecules are always whole in congrad.c
1094      */
1095     evaluate_energy(fplog, cr,
1096                     top_global, s_min, top,
1097                     inputrec, nrnb, wcycle, gstat,
1098                     vsite, constr, fcd, graph, mdatoms, fr,
1099                     mu_tot, enerd, vir, pres, -1, TRUE);
1100     where();
1101
1102     if (MASTER(cr))
1103     {
1104         /* Copy stuff to the energy bin for easy printing etc. */
1105         upd_mdebin(mdebin, FALSE, FALSE, (double)step,
1106                    mdatoms->tmass, enerd, &s_min->s, inputrec->fepvals, inputrec->expandedvals, s_min->s.box,
1107                    NULL, NULL, vir, pres, NULL, mu_tot, constr);
1108
1109         print_ebin_header(fplog, step, step);
1110         print_ebin(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step, step, eprNORMAL,
1111                    mdebin, fcd, &(top_global->groups), &(inputrec->opts));
1112     }
1113     where();
1114
1115     /* Estimate/guess the initial stepsize */
1116     stepsize = inputrec->em_stepsize/s_min->fnorm;
1117
1118     if (MASTER(cr))
1119     {
1120         double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
1121         fprintf(stderr, "   F-max             = %12.5e on atom %d\n",
1122                 s_min->fmax, s_min->a_fmax+1);
1123         fprintf(stderr, "   F-Norm            = %12.5e\n",
1124                 s_min->fnorm/sqrtNumAtoms);
1125         fprintf(stderr, "\n");
1126         /* and copy to the log file too... */
1127         fprintf(fplog, "   F-max             = %12.5e on atom %d\n",
1128                 s_min->fmax, s_min->a_fmax+1);
1129         fprintf(fplog, "   F-Norm            = %12.5e\n",
1130                 s_min->fnorm/sqrtNumAtoms);
1131         fprintf(fplog, "\n");
1132     }
1133     /* Start the loop over CG steps.
1134      * Each successful step is counted, and we continue until
1135      * we either converge or reach the max number of steps.
1136      */
1137     converged = FALSE;
1138     for (step = 0; (number_steps < 0 || step <= number_steps) && !converged; step++)
1139     {
1140
1141         /* start taking steps in a new direction
1142          * First time we enter the routine, beta=0, and the direction is
1143          * simply the negative gradient.
1144          */
1145
1146         /* Calculate the new direction in p, and the gradient in this direction, gpa */
1147         p   = s_min->s.cg_p;
1148         sf  = s_min->f;
1149         gpa = 0;
1150         gf  = 0;
1151         for (i = 0; i < mdatoms->homenr; i++)
1152         {
1153             if (mdatoms->cFREEZE)
1154             {
1155                 gf = mdatoms->cFREEZE[i];
1156             }
1157             for (m = 0; m < DIM; m++)
1158             {
1159                 if (!inputrec->opts.nFreeze[gf][m])
1160                 {
1161                     p[i][m] = sf[i][m] + beta*p[i][m];
1162                     gpa    -= p[i][m]*sf[i][m];
1163                     /* f is negative gradient, thus the sign */
1164                 }
1165                 else
1166                 {
1167                     p[i][m] = 0;
1168                 }
1169             }
1170         }
1171
1172         /* Sum the gradient along the line across CPUs */
1173         if (PAR(cr))
1174         {
1175             gmx_sumd(1, &gpa, cr);
1176         }
1177
1178         /* Calculate the norm of the search vector */
1179         get_f_norm_max(cr, &(inputrec->opts), mdatoms, p, &pnorm, NULL, NULL);
1180
1181         /* Just in case stepsize reaches zero due to numerical precision... */
1182         if (stepsize <= 0)
1183         {
1184             stepsize = inputrec->em_stepsize/pnorm;
1185         }
1186
1187         /*
1188          * Double check the value of the derivative in the search direction.
1189          * If it is positive it must be due to the old information in the
1190          * CG formula, so just remove that and start over with beta=0.
1191          * This corresponds to a steepest descent step.
1192          */
1193         if (gpa > 0)
1194         {
1195             beta = 0;
1196             step--;   /* Don't count this step since we are restarting */
1197             continue; /* Go back to the beginning of the big for-loop */
1198         }
1199
1200         /* Calculate minimum allowed stepsize, before the average (norm)
1201          * relative change in coordinate is smaller than precision
1202          */
1203         minstep = 0;
1204         for (i = 0; i < mdatoms->homenr; i++)
1205         {
1206             for (m = 0; m < DIM; m++)
1207             {
1208                 tmp = fabs(s_min->s.x[i][m]);
1209                 if (tmp < 1.0)
1210                 {
1211                     tmp = 1.0;
1212                 }
1213                 tmp      = p[i][m]/tmp;
1214                 minstep += tmp*tmp;
1215             }
1216         }
1217         /* Add up from all CPUs */
1218         if (PAR(cr))
1219         {
1220             gmx_sumd(1, &minstep, cr);
1221         }
1222
1223         minstep = GMX_REAL_EPS/sqrt(minstep/(3*state_global->natoms));
1224
1225         if (stepsize < minstep)
1226         {
1227             converged = TRUE;
1228             break;
1229         }
1230
1231         /* Write coordinates if necessary */
1232         do_x = do_per_step(step, inputrec->nstxout);
1233         do_f = do_per_step(step, inputrec->nstfout);
1234
1235         write_em_traj(fplog, cr, outf, do_x, do_f, NULL,
1236                       top_global, inputrec, step,
1237                       s_min, state_global);
1238
1239         /* Take a step downhill.
1240          * In theory, we should minimize the function along this direction.
1241          * That is quite possible, but it turns out to take 5-10 function evaluations
1242          * for each line. However, we dont really need to find the exact minimum -
1243          * it is much better to start a new CG step in a modified direction as soon
1244          * as we are close to it. This will save a lot of energy evaluations.
1245          *
1246          * In practice, we just try to take a single step.
1247          * If it worked (i.e. lowered the energy), we increase the stepsize but
1248          * the continue straight to the next CG step without trying to find any minimum.
1249          * If it didn't work (higher energy), there must be a minimum somewhere between
1250          * the old position and the new one.
1251          *
1252          * Due to the finite numerical accuracy, it turns out that it is a good idea
1253          * to even accept a SMALL increase in energy, if the derivative is still downhill.
1254          * This leads to lower final energies in the tests I've done. / Erik
1255          */
1256         s_a->epot = s_min->epot;
1257         a         = 0.0;
1258         c         = a + stepsize; /* reference position along line is zero */
1259
1260         if (DOMAINDECOMP(cr) && s_min->s.ddp_count < cr->dd->ddp_count)
1261         {
1262             em_dd_partition_system(fplog, step, cr, top_global, inputrec,
1263                                    s_min, top, mdatoms, fr, vsite, constr,
1264                                    nrnb, wcycle);
1265         }
1266
1267         /* Take a trial step (new coords in s_c) */
1268         do_em_step(cr, inputrec, mdatoms, fr->bMolPBC, s_min, c, s_min->s.cg_p, s_c,
1269                    constr, top, nrnb, wcycle, -1);
1270
1271         neval++;
1272         /* Calculate energy for the trial step */
1273         evaluate_energy(fplog, cr,
1274                         top_global, s_c, top,
1275                         inputrec, nrnb, wcycle, gstat,
1276                         vsite, constr, fcd, graph, mdatoms, fr,
1277                         mu_tot, enerd, vir, pres, -1, FALSE);
1278
1279         /* Calc derivative along line */
1280         p   = s_c->s.cg_p;
1281         sf  = s_c->f;
1282         gpc = 0;
1283         for (i = 0; i < mdatoms->homenr; i++)
1284         {
1285             for (m = 0; m < DIM; m++)
1286             {
1287                 gpc -= p[i][m]*sf[i][m]; /* f is negative gradient, thus the sign */
1288             }
1289         }
1290         /* Sum the gradient along the line across CPUs */
1291         if (PAR(cr))
1292         {
1293             gmx_sumd(1, &gpc, cr);
1294         }
1295
1296         /* This is the max amount of increase in energy we tolerate */
1297         tmp = sqrt(GMX_REAL_EPS)*fabs(s_a->epot);
1298
1299         /* Accept the step if the energy is lower, or if it is not significantly higher
1300          * and the line derivative is still negative.
1301          */
1302         if (s_c->epot < s_a->epot || (gpc < 0 && s_c->epot < (s_a->epot + tmp)))
1303         {
1304             foundlower = TRUE;
1305             /* Great, we found a better energy. Increase step for next iteration
1306              * if we are still going down, decrease it otherwise
1307              */
1308             if (gpc < 0)
1309             {
1310                 stepsize *= 1.618034; /* The golden section */
1311             }
1312             else
1313             {
1314                 stepsize *= 0.618034; /* 1/golden section */
1315             }
1316         }
1317         else
1318         {
1319             /* New energy is the same or higher. We will have to do some work
1320              * to find a smaller value in the interval. Take smaller step next time!
1321              */
1322             foundlower = FALSE;
1323             stepsize  *= 0.618034;
1324         }
1325
1326
1327
1328
1329         /* OK, if we didn't find a lower value we will have to locate one now - there must
1330          * be one in the interval [a=0,c].
1331          * The same thing is valid here, though: Don't spend dozens of iterations to find
1332          * the line minimum. We try to interpolate based on the derivative at the endpoints,
1333          * and only continue until we find a lower value. In most cases this means 1-2 iterations.
1334          *
1335          * I also have a safeguard for potentially really pathological functions so we never
1336          * take more than 20 steps before we give up ...
1337          *
1338          * If we already found a lower value we just skip this step and continue to the update.
1339          */
1340         if (!foundlower)
1341         {
1342             nminstep = 0;
1343
1344             do
1345             {
1346                 /* Select a new trial point.
1347                  * If the derivatives at points a & c have different sign we interpolate to zero,
1348                  * otherwise just do a bisection.
1349                  */
1350                 if (gpa < 0 && gpc > 0)
1351                 {
1352                     b = a + gpa*(a-c)/(gpc-gpa);
1353                 }
1354                 else
1355                 {
1356                     b = 0.5*(a+c);
1357                 }
1358
1359                 /* safeguard if interpolation close to machine accuracy causes errors:
1360                  * never go outside the interval
1361                  */
1362                 if (b <= a || b >= c)
1363                 {
1364                     b = 0.5*(a+c);
1365                 }
1366
1367                 if (DOMAINDECOMP(cr) && s_min->s.ddp_count != cr->dd->ddp_count)
1368                 {
1369                     /* Reload the old state */
1370                     em_dd_partition_system(fplog, -1, cr, top_global, inputrec,
1371                                            s_min, top, mdatoms, fr, vsite, constr,
1372                                            nrnb, wcycle);
1373                 }
1374
1375                 /* Take a trial step to this new point - new coords in s_b */
1376                 do_em_step(cr, inputrec, mdatoms, fr->bMolPBC, s_min, b, s_min->s.cg_p, s_b,
1377                            constr, top, nrnb, wcycle, -1);
1378
1379                 neval++;
1380                 /* Calculate energy for the trial step */
1381                 evaluate_energy(fplog, cr,
1382                                 top_global, s_b, top,
1383                                 inputrec, nrnb, wcycle, gstat,
1384                                 vsite, constr, fcd, graph, mdatoms, fr,
1385                                 mu_tot, enerd, vir, pres, -1, FALSE);
1386
1387                 /* p does not change within a step, but since the domain decomposition
1388                  * might change, we have to use cg_p of s_b here.
1389                  */
1390                 p   = s_b->s.cg_p;
1391                 sf  = s_b->f;
1392                 gpb = 0;
1393                 for (i = 0; i < mdatoms->homenr; i++)
1394                 {
1395                     for (m = 0; m < DIM; m++)
1396                     {
1397                         gpb -= p[i][m]*sf[i][m]; /* f is negative gradient, thus the sign */
1398                     }
1399                 }
1400                 /* Sum the gradient along the line across CPUs */
1401                 if (PAR(cr))
1402                 {
1403                     gmx_sumd(1, &gpb, cr);
1404                 }
1405
1406                 if (debug)
1407                 {
1408                     fprintf(debug, "CGE: EpotA %f EpotB %f EpotC %f gpb %f\n",
1409                             s_a->epot, s_b->epot, s_c->epot, gpb);
1410                 }
1411
1412                 epot_repl = s_b->epot;
1413
1414                 /* Keep one of the intervals based on the value of the derivative at the new point */
1415                 if (gpb > 0)
1416                 {
1417                     /* Replace c endpoint with b */
1418                     swap_em_state(s_b, s_c);
1419                     c   = b;
1420                     gpc = gpb;
1421                 }
1422                 else
1423                 {
1424                     /* Replace a endpoint with b */
1425                     swap_em_state(s_b, s_a);
1426                     a   = b;
1427                     gpa = gpb;
1428                 }
1429
1430                 /*
1431                  * Stop search as soon as we find a value smaller than the endpoints.
1432                  * Never run more than 20 steps, no matter what.
1433                  */
1434                 nminstep++;
1435             }
1436             while ((epot_repl > s_a->epot || epot_repl > s_c->epot) &&
1437                    (nminstep < 20));
1438
1439             if (fabs(epot_repl - s_min->epot) < fabs(s_min->epot)*GMX_REAL_EPS ||
1440                 nminstep >= 20)
1441             {
1442                 /* OK. We couldn't find a significantly lower energy.
1443                  * If beta==0 this was steepest descent, and then we give up.
1444                  * If not, set beta=0 and restart with steepest descent before quitting.
1445                  */
1446                 if (beta == 0.0)
1447                 {
1448                     /* Converged */
1449                     converged = TRUE;
1450                     break;
1451                 }
1452                 else
1453                 {
1454                     /* Reset memory before giving up */
1455                     beta = 0.0;
1456                     continue;
1457                 }
1458             }
1459
1460             /* Select min energy state of A & C, put the best in B.
1461              */
1462             if (s_c->epot < s_a->epot)
1463             {
1464                 if (debug)
1465                 {
1466                     fprintf(debug, "CGE: C (%f) is lower than A (%f), moving C to B\n",
1467                             s_c->epot, s_a->epot);
1468                 }
1469                 swap_em_state(s_b, s_c);
1470                 gpb = gpc;
1471             }
1472             else
1473             {
1474                 if (debug)
1475                 {
1476                     fprintf(debug, "CGE: A (%f) is lower than C (%f), moving A to B\n",
1477                             s_a->epot, s_c->epot);
1478                 }
1479                 swap_em_state(s_b, s_a);
1480                 gpb = gpa;
1481             }
1482
1483         }
1484         else
1485         {
1486             if (debug)
1487             {
1488                 fprintf(debug, "CGE: Found a lower energy %f, moving C to B\n",
1489                         s_c->epot);
1490             }
1491             swap_em_state(s_b, s_c);
1492             gpb = gpc;
1493         }
1494
1495         /* new search direction */
1496         /* beta = 0 means forget all memory and restart with steepest descents. */
1497         if (nstcg && ((step % nstcg) == 0))
1498         {
1499             beta = 0.0;
1500         }
1501         else
1502         {
1503             /* s_min->fnorm cannot be zero, because then we would have converged
1504              * and broken out.
1505              */
1506
1507             /* Polak-Ribiere update.
1508              * Change to fnorm2/fnorm2_old for Fletcher-Reeves
1509              */
1510             beta = pr_beta(cr, &inputrec->opts, mdatoms, top_global, s_min, s_b);
1511         }
1512         /* Limit beta to prevent oscillations */
1513         if (fabs(beta) > 5.0)
1514         {
1515             beta = 0.0;
1516         }
1517
1518
1519         /* update positions */
1520         swap_em_state(s_min, s_b);
1521         gpa = gpb;
1522
1523         /* Print it if necessary */
1524         if (MASTER(cr))
1525         {
1526             if (bVerbose)
1527             {
1528                 double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
1529                 fprintf(stderr, "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n",
1530                         step, s_min->epot, s_min->fnorm/sqrtNumAtoms,
1531                         s_min->fmax, s_min->a_fmax+1);
1532                 fflush(stderr);
1533             }
1534             /* Store the new (lower) energies */
1535             upd_mdebin(mdebin, FALSE, FALSE, (double)step,
1536                        mdatoms->tmass, enerd, &s_min->s, inputrec->fepvals, inputrec->expandedvals, s_min->s.box,
1537                        NULL, NULL, vir, pres, NULL, mu_tot, constr);
1538
1539             do_log = do_per_step(step, inputrec->nstlog);
1540             do_ene = do_per_step(step, inputrec->nstenergy);
1541
1542             /* Prepare IMD energy record, if bIMD is TRUE. */
1543             IMD_fill_energy_record(inputrec->bIMD, inputrec->imd, enerd, step, TRUE);
1544
1545             if (do_log)
1546             {
1547                 print_ebin_header(fplog, step, step);
1548             }
1549             print_ebin(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE,
1550                        do_log ? fplog : NULL, step, step, eprNORMAL,
1551                        mdebin, fcd, &(top_global->groups), &(inputrec->opts));
1552         }
1553
1554         /* Send energies and positions to the IMD client if bIMD is TRUE. */
1555         if (do_IMD(inputrec->bIMD, step, cr, TRUE, state_global->box, state_global->x, inputrec, 0, wcycle) && MASTER(cr))
1556         {
1557             IMD_send_positions(inputrec->imd);
1558         }
1559
1560         /* Stop when the maximum force lies below tolerance.
1561          * If we have reached machine precision, converged is already set to true.
1562          */
1563         converged = converged || (s_min->fmax < inputrec->em_tol);
1564
1565     }   /* End of the loop */
1566
1567     /* IMD cleanup, if bIMD is TRUE. */
1568     IMD_finalize(inputrec->bIMD, inputrec->imd);
1569
1570     if (converged)
1571     {
1572         step--; /* we never took that last step in this case */
1573
1574     }
1575     if (s_min->fmax > inputrec->em_tol)
1576     {
1577         if (MASTER(cr))
1578         {
1579             warn_step(stderr, inputrec->em_tol, step-1 == number_steps, FALSE);
1580             warn_step(fplog, inputrec->em_tol, step-1 == number_steps, FALSE);
1581         }
1582         converged = FALSE;
1583     }
1584
1585     if (MASTER(cr))
1586     {
1587         /* If we printed energy and/or logfile last step (which was the last step)
1588          * we don't have to do it again, but otherwise print the final values.
1589          */
1590         if (!do_log)
1591         {
1592             /* Write final value to log since we didn't do anything the last step */
1593             print_ebin_header(fplog, step, step);
1594         }
1595         if (!do_ene || !do_log)
1596         {
1597             /* Write final energy file entries */
1598             print_ebin(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE,
1599                        !do_log ? fplog : NULL, step, step, eprNORMAL,
1600                        mdebin, fcd, &(top_global->groups), &(inputrec->opts));
1601         }
1602     }
1603
1604     /* Print some stuff... */
1605     if (MASTER(cr))
1606     {
1607         fprintf(stderr, "\nwriting lowest energy coordinates.\n");
1608     }
1609
1610     /* IMPORTANT!
1611      * For accurate normal mode calculation it is imperative that we
1612      * store the last conformation into the full precision binary trajectory.
1613      *
1614      * However, we should only do it if we did NOT already write this step
1615      * above (which we did if do_x or do_f was true).
1616      */
1617     do_x = !do_per_step(step, inputrec->nstxout);
1618     do_f = (inputrec->nstfout > 0 && !do_per_step(step, inputrec->nstfout));
1619
1620     write_em_traj(fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm),
1621                   top_global, inputrec, step,
1622                   s_min, state_global);
1623
1624
1625     if (MASTER(cr))
1626     {
1627         double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
1628         fnormn = s_min->fnorm/sqrtNumAtoms;
1629         print_converged(stderr, CG, inputrec->em_tol, step, converged, number_steps,
1630                         s_min->epot, s_min->fmax, s_min->a_fmax, fnormn);
1631         print_converged(fplog, CG, inputrec->em_tol, step, converged, number_steps,
1632                         s_min->epot, s_min->fmax, s_min->a_fmax, fnormn);
1633
1634         fprintf(fplog, "\nPerformed %d energy evaluations in total.\n", neval);
1635     }
1636
1637     finish_em(cr, outf, walltime_accounting, wcycle);
1638
1639     /* To print the actual number of steps we needed somewhere */
1640     walltime_accounting_set_nsteps_done(walltime_accounting, step);
1641
1642     return 0;
1643 }   /* That's all folks */
1644
1645
1646 /*! \brief Do L-BFGS conjugate gradients minimization
1647     \copydoc integrator_t (FILE *fplog, t_commrec *cr,
1648                            int nfile, const t_filenm fnm[],
1649                            const gmx_output_env_t *oenv, gmx_bool bVerbose,
1650                            int nstglobalcomm,
1651                            gmx_vsite_t *vsite, gmx_constr_t constr,
1652                            int stepout,
1653                            t_inputrec *inputrec,
1654                            gmx_mtop_t *top_global, t_fcdata *fcd,
1655                            t_state *state_global,
1656                            t_mdatoms *mdatoms,
1657                            t_nrnb *nrnb, gmx_wallcycle_t wcycle,
1658                            gmx_edsam_t ed,
1659                            t_forcerec *fr,
1660                            int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
1661                            real cpt_period, real max_hours,
1662                            int imdport,
1663                            unsigned long Flags,
1664                            gmx_walltime_accounting_t walltime_accounting)
1665  */
1666 double do_lbfgs(FILE *fplog, t_commrec *cr,
1667                 int nfile, const t_filenm fnm[],
1668                 const gmx_output_env_t gmx_unused *oenv, gmx_bool bVerbose,
1669                 int gmx_unused nstglobalcomm,
1670                 gmx_vsite_t *vsite, gmx_constr_t constr,
1671                 int gmx_unused stepout,
1672                 t_inputrec *inputrec,
1673                 gmx_mtop_t *top_global, t_fcdata *fcd,
1674                 t_state *state_global,
1675                 t_mdatoms *mdatoms,
1676                 t_nrnb *nrnb, gmx_wallcycle_t wcycle,
1677                 gmx_edsam_t gmx_unused ed,
1678                 t_forcerec *fr,
1679                 int gmx_unused repl_ex_nst, int gmx_unused repl_ex_nex, int gmx_unused repl_ex_seed,
1680                 gmx_membed_t gmx_unused *membed,
1681                 real gmx_unused cpt_period, real gmx_unused max_hours,
1682                 int imdport,
1683                 unsigned long gmx_unused Flags,
1684                 gmx_walltime_accounting_t walltime_accounting)
1685 {
1686     static const char *LBFGS = "Low-Memory BFGS Minimizer";
1687     em_state_t         ems;
1688     gmx_localtop_t    *top;
1689     gmx_enerdata_t    *enerd;
1690     rvec              *f;
1691     gmx_global_stat_t  gstat;
1692     t_graph           *graph;
1693     int                ncorr, nmaxcorr, point, cp, neval, nminstep;
1694     double             stepsize, step_taken, gpa, gpb, gpc, tmp, minstep;
1695     real              *rho, *alpha, *ff, *xx, *p, *s, *lastx, *lastf, **dx, **dg;
1696     real              *xa, *xb, *xc, *fa, *fb, *fc, *xtmp, *ftmp;
1697     real               a, b, c, maxdelta, delta;
1698     real               diag, Epot0, Epot, EpotA, EpotB, EpotC;
1699     real               dgdx, dgdg, sq, yr, beta;
1700     t_mdebin          *mdebin;
1701     gmx_bool           converged;
1702     rvec               mu_tot;
1703     real               fnorm, fmax;
1704     gmx_bool           do_log, do_ene, do_x, do_f, foundlower, *frozen;
1705     tensor             vir, pres;
1706     int                start, end, number_steps;
1707     gmx_mdoutf_t       outf;
1708     int                i, k, m, n, nfmax, gf, step;
1709     int                mdof_flags;
1710
1711     if (PAR(cr))
1712     {
1713         gmx_fatal(FARGS, "Cannot do parallel L-BFGS Minimization - yet.\n");
1714     }
1715
1716     if (NULL != constr)
1717     {
1718         gmx_fatal(FARGS, "The combination of constraints and L-BFGS minimization is not implemented. Either do not use constraints, or use another minimizer (e.g. steepest descent).");
1719     }
1720
1721     n        = 3*state_global->natoms;
1722     nmaxcorr = inputrec->nbfgscorr;
1723
1724     /* Allocate memory */
1725     /* Use pointers to real so we dont have to loop over both atoms and
1726      * dimensions all the time...
1727      * x/f are allocated as rvec *, so make new x0/f0 pointers-to-real
1728      * that point to the same memory.
1729      */
1730     snew(xa, n);
1731     snew(xb, n);
1732     snew(xc, n);
1733     snew(fa, n);
1734     snew(fb, n);
1735     snew(fc, n);
1736     snew(frozen, n);
1737
1738     snew(p, n);
1739     snew(lastx, n);
1740     snew(lastf, n);
1741     snew(rho, nmaxcorr);
1742     snew(alpha, nmaxcorr);
1743
1744     snew(dx, nmaxcorr);
1745     for (i = 0; i < nmaxcorr; i++)
1746     {
1747         snew(dx[i], n);
1748     }
1749
1750     snew(dg, nmaxcorr);
1751     for (i = 0; i < nmaxcorr; i++)
1752     {
1753         snew(dg[i], n);
1754     }
1755
1756     step  = 0;
1757     neval = 0;
1758
1759     /* Init em */
1760     init_em(fplog, LBFGS, cr, inputrec,
1761             state_global, top_global, &ems, &top, &f,
1762             nrnb, mu_tot, fr, &enerd, &graph, mdatoms, &gstat, vsite, constr,
1763             nfile, fnm, &outf, &mdebin, imdport, Flags, wcycle);
1764     /* Do_lbfgs is not completely updated like do_steep and do_cg,
1765      * so we free some memory again.
1766      */
1767     sfree(ems.s.x);
1768     sfree(ems.f);
1769
1770     xx = (real *)state_global->x;
1771     ff = (real *)f;
1772
1773     start = 0;
1774     end   = mdatoms->homenr;
1775
1776     /* Print to log file */
1777     print_em_start(fplog, cr, walltime_accounting, wcycle, LBFGS);
1778
1779     do_log = do_ene = do_x = do_f = TRUE;
1780
1781     /* Max number of steps */
1782     number_steps = inputrec->nsteps;
1783
1784     /* Create a 3*natoms index to tell whether each degree of freedom is frozen */
1785     gf = 0;
1786     for (i = start; i < end; i++)
1787     {
1788         if (mdatoms->cFREEZE)
1789         {
1790             gf = mdatoms->cFREEZE[i];
1791         }
1792         for (m = 0; m < DIM; m++)
1793         {
1794             frozen[3*i+m] = inputrec->opts.nFreeze[gf][m];
1795         }
1796     }
1797     if (MASTER(cr))
1798     {
1799         sp_header(stderr, LBFGS, inputrec->em_tol, number_steps);
1800     }
1801     if (fplog)
1802     {
1803         sp_header(fplog, LBFGS, inputrec->em_tol, number_steps);
1804     }
1805
1806     if (vsite)
1807     {
1808         construct_vsites(vsite, state_global->x, 1, NULL,
1809                          top->idef.iparams, top->idef.il,
1810                          fr->ePBC, fr->bMolPBC, cr, state_global->box);
1811     }
1812
1813     /* Call the force routine and some auxiliary (neighboursearching etc.) */
1814     /* do_force always puts the charge groups in the box and shifts again
1815      * We do not unshift, so molecules are always whole
1816      */
1817     neval++;
1818     ems.s.x = state_global->x;
1819     ems.f   = f;
1820     evaluate_energy(fplog, cr,
1821                     top_global, &ems, top,
1822                     inputrec, nrnb, wcycle, gstat,
1823                     vsite, constr, fcd, graph, mdatoms, fr,
1824                     mu_tot, enerd, vir, pres, -1, TRUE);
1825     where();
1826
1827     if (MASTER(cr))
1828     {
1829         /* Copy stuff to the energy bin for easy printing etc. */
1830         upd_mdebin(mdebin, FALSE, FALSE, (double)step,
1831                    mdatoms->tmass, enerd, state_global, inputrec->fepvals, inputrec->expandedvals, state_global->box,
1832                    NULL, NULL, vir, pres, NULL, mu_tot, constr);
1833
1834         print_ebin_header(fplog, step, step);
1835         print_ebin(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step, step, eprNORMAL,
1836                    mdebin, fcd, &(top_global->groups), &(inputrec->opts));
1837     }
1838     where();
1839
1840     /* This is the starting energy */
1841     Epot = enerd->term[F_EPOT];
1842
1843     fnorm = ems.fnorm;
1844     fmax  = ems.fmax;
1845     nfmax = ems.a_fmax;
1846
1847     /* Set the initial step.
1848      * since it will be multiplied by the non-normalized search direction
1849      * vector (force vector the first time), we scale it by the
1850      * norm of the force.
1851      */
1852
1853     if (MASTER(cr))
1854     {
1855         double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
1856         fprintf(stderr, "Using %d BFGS correction steps.\n\n", nmaxcorr);
1857         fprintf(stderr, "   F-max             = %12.5e on atom %d\n", fmax, nfmax+1);
1858         fprintf(stderr, "   F-Norm            = %12.5e\n", fnorm/sqrtNumAtoms);
1859         fprintf(stderr, "\n");
1860         /* and copy to the log file too... */
1861         fprintf(fplog, "Using %d BFGS correction steps.\n\n", nmaxcorr);
1862         fprintf(fplog, "   F-max             = %12.5e on atom %d\n", fmax, nfmax+1);
1863         fprintf(fplog, "   F-Norm            = %12.5e\n", fnorm/sqrtNumAtoms);
1864         fprintf(fplog, "\n");
1865     }
1866
1867     // Point is an index to the memory of search directions, where 0 is the first one.
1868     point = 0;
1869
1870     // Set initial search direction to the force (-gradient), or 0 for frozen particles.
1871     for (i = 0; i < n; i++)
1872     {
1873         if (!frozen[i])
1874         {
1875             dx[point][i] = ff[i]; /* Initial search direction */
1876         }
1877         else
1878         {
1879             dx[point][i] = 0;
1880         }
1881     }
1882
1883     // Stepsize will be modified during the search, and actually it is not critical
1884     // (the main efficiency in the algorithm comes from changing directions), but
1885     // we still need an initial value, so estimate it as the inverse of the norm
1886     // so we take small steps where the potential fluctuates a lot.
1887     stepsize  = 1.0/fnorm;
1888
1889     /* Start the loop over BFGS steps.
1890      * Each successful step is counted, and we continue until
1891      * we either converge or reach the max number of steps.
1892      */
1893
1894     ncorr = 0;
1895
1896     /* Set the gradient from the force */
1897     converged = FALSE;
1898     for (step = 0; (number_steps < 0 || step <= number_steps) && !converged; step++)
1899     {
1900
1901         /* Write coordinates if necessary */
1902         do_x = do_per_step(step, inputrec->nstxout);
1903         do_f = do_per_step(step, inputrec->nstfout);
1904
1905         mdof_flags = 0;
1906         if (do_x)
1907         {
1908             mdof_flags |= MDOF_X;
1909         }
1910
1911         if (do_f)
1912         {
1913             mdof_flags |= MDOF_F;
1914         }
1915
1916         if (inputrec->bIMD)
1917         {
1918             mdof_flags |= MDOF_IMD;
1919         }
1920
1921         mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags,
1922                                          top_global, step, (real)step, state_global, state_global, f);
1923
1924         /* Do the linesearching in the direction dx[point][0..(n-1)] */
1925
1926         /* make s a pointer to current search direction - point=0 first time we get here */
1927         s = dx[point];
1928
1929         // calculate line gradient in position A
1930         for (gpa = 0, i = 0; i < n; i++)
1931         {
1932             gpa -= s[i]*ff[i];
1933         }
1934
1935         /* Calculate minimum allowed stepsize along the line, before the average (norm)
1936          * relative change in coordinate is smaller than precision
1937          */
1938         for (minstep = 0, i = 0; i < n; i++)
1939         {
1940             tmp = fabs(xx[i]);
1941             if (tmp < 1.0)
1942             {
1943                 tmp = 1.0;
1944             }
1945             tmp      = s[i]/tmp;
1946             minstep += tmp*tmp;
1947         }
1948         minstep = GMX_REAL_EPS/sqrt(minstep/n);
1949
1950         if (stepsize < minstep)
1951         {
1952             converged = TRUE;
1953             break;
1954         }
1955
1956         // Before taking any steps along the line, store the old position
1957         for (i = 0; i < n; i++)
1958         {
1959             lastx[i] = xx[i];
1960             lastf[i] = ff[i];
1961         }
1962         Epot0 = Epot;
1963
1964         for (i = 0; i < n; i++)
1965         {
1966             xa[i] = xx[i];
1967         }
1968
1969         /* Take a step downhill.
1970          * In theory, we should find the actual minimum of the function in this
1971          * direction, somewhere along the line.
1972          * That is quite possible, but it turns out to take 5-10 function evaluations
1973          * for each line. However, we dont really need to find the exact minimum -
1974          * it is much better to start a new BFGS step in a modified direction as soon
1975          * as we are close to it. This will save a lot of energy evaluations.
1976          *
1977          * In practice, we just try to take a single step.
1978          * If it worked (i.e. lowered the energy), we increase the stepsize but
1979          * continue straight to the next BFGS step without trying to find any minimum,
1980          * i.e. we change the search direction too. If the line was smooth, it is
1981          * likely we are in a smooth region, and then it makes sense to take longer
1982          * steps in the modified search direction too.
1983          *
1984          * If it didn't work (higher energy), there must be a minimum somewhere between
1985          * the old position and the new one. Then we need to start by finding a lower
1986          * value before we change search direction. Since the energy was apparently
1987          * quite rough, we need to decrease the step size.
1988          *
1989          * Due to the finite numerical accuracy, it turns out that it is a good idea
1990          * to accept a SMALL increase in energy, if the derivative is still downhill.
1991          * This leads to lower final energies in the tests I've done. / Erik
1992          */
1993
1994         // State "A" is the first position along the line.
1995         // reference position along line is initially zero
1996         EpotA      = Epot0;
1997         a          = 0.0;
1998
1999         // Check stepsize first. We do not allow displacements
2000         // larger than emstep.
2001         //
2002         do
2003         {
2004             // Pick a new position C by adding stepsize to A.
2005             c        = a + stepsize;
2006
2007             // Calculate what the largest change in any individual coordinate
2008             // would be (translation along line * gradient along line)
2009             maxdelta = 0;
2010             for (i = 0; i < n; i++)
2011             {
2012                 delta = c*s[i];
2013                 if (delta > maxdelta)
2014                 {
2015                     maxdelta = delta;
2016                 }
2017             }
2018             // If any displacement is larger than the stepsize limit, reduce the step
2019             if (maxdelta > inputrec->em_stepsize)
2020             {
2021                 stepsize *= 0.1;
2022             }
2023         }
2024         while (maxdelta > inputrec->em_stepsize);
2025
2026         // Take a trial step and move the coordinate array xc[] to position C
2027         for (i = 0; i < n; i++)
2028         {
2029             xc[i] = lastx[i] + c*s[i];
2030         }
2031
2032         neval++;
2033         // Calculate energy for the trial step in position C
2034         ems.s.x = (rvec *)xc;
2035         ems.f   = (rvec *)fc;
2036         evaluate_energy(fplog, cr,
2037                         top_global, &ems, top,
2038                         inputrec, nrnb, wcycle, gstat,
2039                         vsite, constr, fcd, graph, mdatoms, fr,
2040                         mu_tot, enerd, vir, pres, step, FALSE);
2041         EpotC = ems.epot;
2042
2043         // Calc line gradient in position C
2044         for (gpc = 0, i = 0; i < n; i++)
2045         {
2046             gpc -= s[i]*fc[i]; /* f is negative gradient, thus the sign */
2047         }
2048         /* Sum the gradient along the line across CPUs */
2049         if (PAR(cr))
2050         {
2051             gmx_sumd(1, &gpc, cr);
2052         }
2053
2054         // This is the max amount of increase in energy we tolerate.
2055         // By allowing VERY small changes (close to numerical precision) we
2056         // frequently find even better (lower) final energies.
2057         tmp = sqrt(GMX_REAL_EPS)*fabs(EpotA);
2058
2059         // Accept the step if the energy is lower in the new position C (compared to A),
2060         // or if it is not significantly higher and the line derivative is still negative.
2061         if (EpotC < EpotA || (gpc < 0 && EpotC < (EpotA+tmp)))
2062         {
2063             // Great, we found a better energy. We no longer try to alter the
2064             // stepsize, but simply accept this new better position. The we select a new
2065             // search direction instead, which will be much more efficient than continuing
2066             // to take smaller steps along a line. Set fnorm based on the new C position,
2067             // which will be used to update the stepsize to 1/fnorm further down.
2068             foundlower = TRUE;
2069             fnorm      = ems.fnorm;
2070         }
2071         else
2072         {
2073             // If we got here, the energy is NOT lower in point C, i.e. it will be the same
2074             // or higher than in point A. In this case it is pointless to move to point C,
2075             // so we will have to do more iterations along the same line to find a smaller
2076             // value in the interval [A=0.0,C].
2077             // Here, A is still 0.0, but that will change when we do a search in the interval
2078             // [0.0,C] below. That search we will do by interpolation or bisection rather
2079             // than with the stepsize, so no need to modify it. For the next search direction
2080             // it will be reset to 1/fnorm anyway.
2081             foundlower = FALSE;
2082         }
2083
2084         if (!foundlower)
2085         {
2086             // OK, if we didn't find a lower value we will have to locate one now - there must
2087             // be one in the interval [a,c].
2088             // The same thing is valid here, though: Don't spend dozens of iterations to find
2089             // the line minimum. We try to interpolate based on the derivative at the endpoints,
2090             // and only continue until we find a lower value. In most cases this means 1-2 iterations.
2091             // I also have a safeguard for potentially really pathological functions so we never
2092             // take more than 20 steps before we give up.
2093             // If we already found a lower value we just skip this step and continue to the update.
2094             nminstep = 0;
2095             do
2096             {
2097                 // Select a new trial point B in the interval [A,C].
2098                 // If the derivatives at points a & c have different sign we interpolate to zero,
2099                 // otherwise just do a bisection since there might be multiple minima/maxima
2100                 // inside the interval.
2101                 if (gpa < 0 && gpc > 0)
2102                 {
2103                     b = a + gpa*(a-c)/(gpc-gpa);
2104                 }
2105                 else
2106                 {
2107                     b = 0.5*(a+c);
2108                 }
2109
2110                 /* safeguard if interpolation close to machine accuracy causes errors:
2111                  * never go outside the interval
2112                  */
2113                 if (b <= a || b >= c)
2114                 {
2115                     b = 0.5*(a+c);
2116                 }
2117
2118                 // Take a trial step to point B
2119                 for (i = 0; i < n; i++)
2120                 {
2121                     xb[i] = lastx[i] + b*s[i];
2122                 }
2123
2124                 neval++;
2125                 // Calculate energy for the trial step in point B
2126                 ems.s.x = (rvec *)xb;
2127                 ems.f   = (rvec *)fb;
2128                 evaluate_energy(fplog, cr,
2129                                 top_global, &ems, top,
2130                                 inputrec, nrnb, wcycle, gstat,
2131                                 vsite, constr, fcd, graph, mdatoms, fr,
2132                                 mu_tot, enerd, vir, pres, step, FALSE);
2133                 EpotB = ems.epot;
2134                 fnorm = ems.fnorm;
2135
2136                 // Calculate gradient in point B
2137                 for (gpb = 0, i = 0; i < n; i++)
2138                 {
2139                     gpb -= s[i]*fb[i]; /* f is negative gradient, thus the sign */
2140
2141                 }
2142                 /* Sum the gradient along the line across CPUs */
2143                 if (PAR(cr))
2144                 {
2145                     gmx_sumd(1, &gpb, cr);
2146                 }
2147
2148                 // Keep one of the intervals [A,B] or [B,C] based on the value of the derivative
2149                 // at the new point B, and rename the endpoints of this new interval A and C.
2150                 if (gpb > 0)
2151                 {
2152                     /* Replace c endpoint with b */
2153                     EpotC = EpotB;
2154                     c     = b;
2155                     gpc   = gpb;
2156                     /* swap coord pointers b/c */
2157                     xtmp = xb;
2158                     ftmp = fb;
2159                     xb   = xc;
2160                     fb   = fc;
2161                     xc   = xtmp;
2162                     fc   = ftmp;
2163                 }
2164                 else
2165                 {
2166                     /* Replace a endpoint with b */
2167                     EpotA = EpotB;
2168                     a     = b;
2169                     gpa   = gpb;
2170                     /* swap coord pointers a/b */
2171                     xtmp = xb;
2172                     ftmp = fb;
2173                     xb   = xa;
2174                     fb   = fa;
2175                     xa   = xtmp;
2176                     fa   = ftmp;
2177                 }
2178
2179                 /*
2180                  * Stop search as soon as we find a value smaller than the endpoints,
2181                  * or if the tolerance is below machine precision.
2182                  * Never run more than 20 steps, no matter what.
2183                  */
2184                 nminstep++;
2185             }
2186             while ((EpotB > EpotA || EpotB > EpotC) && (nminstep < 20));
2187
2188             if (fabs(EpotB-Epot0) < GMX_REAL_EPS || nminstep >= 20)
2189             {
2190                 /* OK. We couldn't find a significantly lower energy.
2191                  * If ncorr==0 this was steepest descent, and then we give up.
2192                  * If not, reset memory to restart as steepest descent before quitting.
2193                  */
2194                 if (ncorr == 0)
2195                 {
2196                     /* Converged */
2197                     converged = TRUE;
2198                     break;
2199                 }
2200                 else
2201                 {
2202                     /* Reset memory */
2203                     ncorr = 0;
2204                     /* Search in gradient direction */
2205                     for (i = 0; i < n; i++)
2206                     {
2207                         dx[point][i] = ff[i];
2208                     }
2209                     /* Reset stepsize */
2210                     stepsize = 1.0/fnorm;
2211                     continue;
2212                 }
2213             }
2214
2215             /* Select min energy state of A & C, put the best in xx/ff/Epot
2216              */
2217             if (EpotC < EpotA)
2218             {
2219                 Epot = EpotC;
2220                 /* Use state C */
2221                 for (i = 0; i < n; i++)
2222                 {
2223                     xx[i] = xc[i];
2224                     ff[i] = fc[i];
2225                 }
2226                 step_taken = c;
2227             }
2228             else
2229             {
2230                 Epot = EpotA;
2231                 /* Use state A */
2232                 for (i = 0; i < n; i++)
2233                 {
2234                     xx[i] = xa[i];
2235                     ff[i] = fa[i];
2236                 }
2237                 step_taken = a;
2238             }
2239
2240         }
2241         else
2242         {
2243             /* found lower */
2244             Epot = EpotC;
2245             /* Use state C */
2246             for (i = 0; i < n; i++)
2247             {
2248                 xx[i] = xc[i];
2249                 ff[i] = fc[i];
2250             }
2251             step_taken = c;
2252         }
2253
2254         /* Update the memory information, and calculate a new
2255          * approximation of the inverse hessian
2256          */
2257
2258         /* Have new data in Epot, xx, ff */
2259         if (ncorr < nmaxcorr)
2260         {
2261             ncorr++;
2262         }
2263
2264         for (i = 0; i < n; i++)
2265         {
2266             dg[point][i]  = lastf[i]-ff[i];
2267             dx[point][i] *= step_taken;
2268         }
2269
2270         dgdg = 0;
2271         dgdx = 0;
2272         for (i = 0; i < n; i++)
2273         {
2274             dgdg += dg[point][i]*dg[point][i];
2275             dgdx += dg[point][i]*dx[point][i];
2276         }
2277
2278         diag = dgdx/dgdg;
2279
2280         rho[point] = 1.0/dgdx;
2281         point++;
2282
2283         if (point >= nmaxcorr)
2284         {
2285             point = 0;
2286         }
2287
2288         /* Update */
2289         for (i = 0; i < n; i++)
2290         {
2291             p[i] = ff[i];
2292         }
2293
2294         cp = point;
2295
2296         /* Recursive update. First go back over the memory points */
2297         for (k = 0; k < ncorr; k++)
2298         {
2299             cp--;
2300             if (cp < 0)
2301             {
2302                 cp = ncorr-1;
2303             }
2304
2305             sq = 0;
2306             for (i = 0; i < n; i++)
2307             {
2308                 sq += dx[cp][i]*p[i];
2309             }
2310
2311             alpha[cp] = rho[cp]*sq;
2312
2313             for (i = 0; i < n; i++)
2314             {
2315                 p[i] -= alpha[cp]*dg[cp][i];
2316             }
2317         }
2318
2319         for (i = 0; i < n; i++)
2320         {
2321             p[i] *= diag;
2322         }
2323
2324         /* And then go forward again */
2325         for (k = 0; k < ncorr; k++)
2326         {
2327             yr = 0;
2328             for (i = 0; i < n; i++)
2329             {
2330                 yr += p[i]*dg[cp][i];
2331             }
2332
2333             beta = rho[cp]*yr;
2334             beta = alpha[cp]-beta;
2335
2336             for (i = 0; i < n; i++)
2337             {
2338                 p[i] += beta*dx[cp][i];
2339             }
2340
2341             cp++;
2342             if (cp >= ncorr)
2343             {
2344                 cp = 0;
2345             }
2346         }
2347
2348         for (i = 0; i < n; i++)
2349         {
2350             if (!frozen[i])
2351             {
2352                 dx[point][i] = p[i];
2353             }
2354             else
2355             {
2356                 dx[point][i] = 0;
2357             }
2358         }
2359
2360         /* Test whether the convergence criterion is met */
2361         get_f_norm_max(cr, &(inputrec->opts), mdatoms, f, &fnorm, &fmax, &nfmax);
2362
2363         /* Print it if necessary */
2364         if (MASTER(cr))
2365         {
2366             if (bVerbose)
2367             {
2368                 double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
2369                 fprintf(stderr, "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n",
2370                         step, Epot, fnorm/sqrtNumAtoms, fmax, nfmax+1);
2371                 fflush(stderr);
2372             }
2373             /* Store the new (lower) energies */
2374             upd_mdebin(mdebin, FALSE, FALSE, (double)step,
2375                        mdatoms->tmass, enerd, state_global, inputrec->fepvals, inputrec->expandedvals, state_global->box,
2376                        NULL, NULL, vir, pres, NULL, mu_tot, constr);
2377             do_log = do_per_step(step, inputrec->nstlog);
2378             do_ene = do_per_step(step, inputrec->nstenergy);
2379             if (do_log)
2380             {
2381                 print_ebin_header(fplog, step, step);
2382             }
2383             print_ebin(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE,
2384                        do_log ? fplog : NULL, step, step, eprNORMAL,
2385                        mdebin, fcd, &(top_global->groups), &(inputrec->opts));
2386         }
2387
2388         /* Send x and E to IMD client, if bIMD is TRUE. */
2389         if (do_IMD(inputrec->bIMD, step, cr, TRUE, state_global->box, state_global->x, inputrec, 0, wcycle) && MASTER(cr))
2390         {
2391             IMD_send_positions(inputrec->imd);
2392         }
2393
2394         // Reset stepsize in we are doing more iterations
2395         stepsize = 1.0/fnorm;
2396
2397         /* Stop when the maximum force lies below tolerance.
2398          * If we have reached machine precision, converged is already set to true.
2399          */
2400         converged = converged || (fmax < inputrec->em_tol);
2401
2402     }   /* End of the loop */
2403
2404     /* IMD cleanup, if bIMD is TRUE. */
2405     IMD_finalize(inputrec->bIMD, inputrec->imd);
2406
2407     if (converged)
2408     {
2409         step--; /* we never took that last step in this case */
2410
2411     }
2412     if (fmax > inputrec->em_tol)
2413     {
2414         if (MASTER(cr))
2415         {
2416             warn_step(stderr, inputrec->em_tol, step-1 == number_steps, FALSE);
2417             warn_step(fplog, inputrec->em_tol, step-1 == number_steps, FALSE);
2418         }
2419         converged = FALSE;
2420     }
2421
2422     /* If we printed energy and/or logfile last step (which was the last step)
2423      * we don't have to do it again, but otherwise print the final values.
2424      */
2425     if (!do_log) /* Write final value to log since we didn't do anythin last step */
2426     {
2427         print_ebin_header(fplog, step, step);
2428     }
2429     if (!do_ene || !do_log) /* Write final energy file entries */
2430     {
2431         print_ebin(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE,
2432                    !do_log ? fplog : NULL, step, step, eprNORMAL,
2433                    mdebin, fcd, &(top_global->groups), &(inputrec->opts));
2434     }
2435
2436     /* Print some stuff... */
2437     if (MASTER(cr))
2438     {
2439         fprintf(stderr, "\nwriting lowest energy coordinates.\n");
2440     }
2441
2442     /* IMPORTANT!
2443      * For accurate normal mode calculation it is imperative that we
2444      * store the last conformation into the full precision binary trajectory.
2445      *
2446      * However, we should only do it if we did NOT already write this step
2447      * above (which we did if do_x or do_f was true).
2448      */
2449     do_x = !do_per_step(step, inputrec->nstxout);
2450     do_f = !do_per_step(step, inputrec->nstfout);
2451     write_em_traj(fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm),
2452                   top_global, inputrec, step,
2453                   &ems, state_global);
2454
2455     if (MASTER(cr))
2456     {
2457         double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
2458         print_converged(stderr, LBFGS, inputrec->em_tol, step, converged,
2459                         number_steps, Epot, fmax, nfmax, fnorm/sqrtNumAtoms);
2460         print_converged(fplog, LBFGS, inputrec->em_tol, step, converged,
2461                         number_steps, Epot, fmax, nfmax, fnorm/sqrtNumAtoms);
2462
2463         fprintf(fplog, "\nPerformed %d energy evaluations in total.\n", neval);
2464     }
2465
2466     finish_em(cr, outf, walltime_accounting, wcycle);
2467
2468     /* To print the actual number of steps we needed somewhere */
2469     walltime_accounting_set_nsteps_done(walltime_accounting, step);
2470
2471     return 0;
2472 }   /* That's all folks */
2473
2474 /*! \brief Do steepest descents minimization
2475     \copydoc integrator_t (FILE *fplog, t_commrec *cr,
2476                            int nfile, const t_filenm fnm[],
2477                            const gmx_output_env_t *oenv, gmx_bool bVerbose,
2478                            int nstglobalcomm,
2479                            gmx_vsite_t *vsite, gmx_constr_t constr,
2480                            int stepout,
2481                            t_inputrec *inputrec,
2482                            gmx_mtop_t *top_global, t_fcdata *fcd,
2483                            t_state *state_global,
2484                            t_mdatoms *mdatoms,
2485                            t_nrnb *nrnb, gmx_wallcycle_t wcycle,
2486                            gmx_edsam_t ed,
2487                            t_forcerec *fr,
2488                            int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
2489                            real cpt_period, real max_hours,
2490                            int imdport,
2491                            unsigned long Flags,
2492                            gmx_walltime_accounting_t walltime_accounting)
2493  */
2494 double do_steep(FILE *fplog, t_commrec *cr,
2495                 int nfile, const t_filenm fnm[],
2496                 const gmx_output_env_t gmx_unused *oenv, gmx_bool bVerbose,
2497                 int gmx_unused nstglobalcomm,
2498                 gmx_vsite_t *vsite, gmx_constr_t constr,
2499                 int gmx_unused stepout,
2500                 t_inputrec *inputrec,
2501                 gmx_mtop_t *top_global, t_fcdata *fcd,
2502                 t_state *state_global,
2503                 t_mdatoms *mdatoms,
2504                 t_nrnb *nrnb, gmx_wallcycle_t wcycle,
2505                 gmx_edsam_t gmx_unused  ed,
2506                 t_forcerec *fr,
2507                 int gmx_unused repl_ex_nst, int gmx_unused repl_ex_nex, int gmx_unused repl_ex_seed,
2508                 gmx_membed_t gmx_unused *membed,
2509                 real gmx_unused cpt_period, real gmx_unused max_hours,
2510                 int imdport,
2511                 unsigned long gmx_unused Flags,
2512                 gmx_walltime_accounting_t walltime_accounting)
2513 {
2514     const char       *SD = "Steepest Descents";
2515     em_state_t       *s_min, *s_try;
2516     gmx_localtop_t   *top;
2517     gmx_enerdata_t   *enerd;
2518     rvec             *f;
2519     gmx_global_stat_t gstat;
2520     t_graph          *graph;
2521     real              stepsize;
2522     real              ustep, fnormn;
2523     gmx_mdoutf_t      outf;
2524     t_mdebin         *mdebin;
2525     gmx_bool          bDone, bAbort, do_x, do_f;
2526     tensor            vir, pres;
2527     rvec              mu_tot;
2528     int               nsteps;
2529     int               count          = 0;
2530     int               steps_accepted = 0;
2531
2532     s_min = init_em_state();
2533     s_try = init_em_state();
2534
2535     /* Init em and store the local state in s_try */
2536     init_em(fplog, SD, cr, inputrec,
2537             state_global, top_global, s_try, &top, &f,
2538             nrnb, mu_tot, fr, &enerd, &graph, mdatoms, &gstat, vsite, constr,
2539             nfile, fnm, &outf, &mdebin, imdport, Flags, wcycle);
2540
2541     /* Print to log file  */
2542     print_em_start(fplog, cr, walltime_accounting, wcycle, SD);
2543
2544     /* Set variables for stepsize (in nm). This is the largest
2545      * step that we are going to make in any direction.
2546      */
2547     ustep    = inputrec->em_stepsize;
2548     stepsize = 0;
2549
2550     /* Max number of steps  */
2551     nsteps = inputrec->nsteps;
2552
2553     if (MASTER(cr))
2554     {
2555         /* Print to the screen  */
2556         sp_header(stderr, SD, inputrec->em_tol, nsteps);
2557     }
2558     if (fplog)
2559     {
2560         sp_header(fplog, SD, inputrec->em_tol, nsteps);
2561     }
2562
2563     /**** HERE STARTS THE LOOP ****
2564      * count is the counter for the number of steps
2565      * bDone will be TRUE when the minimization has converged
2566      * bAbort will be TRUE when nsteps steps have been performed or when
2567      * the stepsize becomes smaller than is reasonable for machine precision
2568      */
2569     count  = 0;
2570     bDone  = FALSE;
2571     bAbort = FALSE;
2572     while (!bDone && !bAbort)
2573     {
2574         bAbort = (nsteps >= 0) && (count == nsteps);
2575
2576         /* set new coordinates, except for first step */
2577         bool validStep = true;
2578         if (count > 0)
2579         {
2580             validStep =
2581                 do_em_step(cr, inputrec, mdatoms, fr->bMolPBC,
2582                            s_min, stepsize, s_min->f, s_try,
2583                            constr, top, nrnb, wcycle, count);
2584         }
2585
2586         if (validStep)
2587         {
2588             evaluate_energy(fplog, cr,
2589                             top_global, s_try, top,
2590                             inputrec, nrnb, wcycle, gstat,
2591                             vsite, constr, fcd, graph, mdatoms, fr,
2592                             mu_tot, enerd, vir, pres, count, count == 0);
2593         }
2594         else
2595         {
2596             // Signal constraint error during stepping with energy=inf
2597             s_try->epot = std::numeric_limits<real>::infinity();
2598         }
2599
2600         if (MASTER(cr))
2601         {
2602             print_ebin_header(fplog, count, count);
2603         }
2604
2605         if (count == 0)
2606         {
2607             s_min->epot = s_try->epot;
2608         }
2609
2610         /* Print it if necessary  */
2611         if (MASTER(cr))
2612         {
2613             if (bVerbose)
2614             {
2615                 fprintf(stderr, "Step=%5d, Dmax= %6.1e nm, Epot= %12.5e Fmax= %11.5e, atom= %d%c",
2616                         count, ustep, s_try->epot, s_try->fmax, s_try->a_fmax+1,
2617                         ( (count == 0) || (s_try->epot < s_min->epot) ) ? '\n' : '\r');
2618                 fflush(stderr);
2619             }
2620
2621             if ( (count == 0) || (s_try->epot < s_min->epot) )
2622             {
2623                 /* Store the new (lower) energies  */
2624                 upd_mdebin(mdebin, FALSE, FALSE, (double)count,
2625                            mdatoms->tmass, enerd, &s_try->s, inputrec->fepvals, inputrec->expandedvals,
2626                            s_try->s.box, NULL, NULL, vir, pres, NULL, mu_tot, constr);
2627
2628                 /* Prepare IMD energy record, if bIMD is TRUE. */
2629                 IMD_fill_energy_record(inputrec->bIMD, inputrec->imd, enerd, count, TRUE);
2630
2631                 print_ebin(mdoutf_get_fp_ene(outf), TRUE,
2632                            do_per_step(steps_accepted, inputrec->nstdisreout),
2633                            do_per_step(steps_accepted, inputrec->nstorireout),
2634                            fplog, count, count, eprNORMAL,
2635                            mdebin, fcd, &(top_global->groups), &(inputrec->opts));
2636                 fflush(fplog);
2637             }
2638         }
2639
2640         /* Now if the new energy is smaller than the previous...
2641          * or if this is the first step!
2642          * or if we did random steps!
2643          */
2644
2645         if ( (count == 0) || (s_try->epot < s_min->epot) )
2646         {
2647             steps_accepted++;
2648
2649             /* Test whether the convergence criterion is met...  */
2650             bDone = (s_try->fmax < inputrec->em_tol);
2651
2652             /* Copy the arrays for force, positions and energy  */
2653             /* The 'Min' array always holds the coords and forces of the minimal
2654                sampled energy  */
2655             swap_em_state(s_min, s_try);
2656             if (count > 0)
2657             {
2658                 ustep *= 1.2;
2659             }
2660
2661             /* Write to trn, if necessary */
2662             do_x = do_per_step(steps_accepted, inputrec->nstxout);
2663             do_f = do_per_step(steps_accepted, inputrec->nstfout);
2664             write_em_traj(fplog, cr, outf, do_x, do_f, NULL,
2665                           top_global, inputrec, count,
2666                           s_min, state_global);
2667         }
2668         else
2669         {
2670             /* If energy is not smaller make the step smaller...  */
2671             ustep *= 0.5;
2672
2673             if (DOMAINDECOMP(cr) && s_min->s.ddp_count != cr->dd->ddp_count)
2674             {
2675                 /* Reload the old state */
2676                 em_dd_partition_system(fplog, count, cr, top_global, inputrec,
2677                                        s_min, top, mdatoms, fr, vsite, constr,
2678                                        nrnb, wcycle);
2679             }
2680         }
2681
2682         /* Determine new step  */
2683         stepsize = ustep/s_min->fmax;
2684
2685         /* Check if stepsize is too small, with 1 nm as a characteristic length */
2686 #if GMX_DOUBLE
2687         if (count == nsteps || ustep < 1e-12)
2688 #else
2689         if (count == nsteps || ustep < 1e-6)
2690 #endif
2691         {
2692             if (MASTER(cr))
2693             {
2694                 warn_step(stderr, inputrec->em_tol, count == nsteps, constr != NULL);
2695                 warn_step(fplog, inputrec->em_tol, count == nsteps, constr != NULL);
2696             }
2697             bAbort = TRUE;
2698         }
2699
2700         /* Send IMD energies and positions, if bIMD is TRUE. */
2701         if (do_IMD(inputrec->bIMD, count, cr, TRUE, state_global->box, state_global->x, inputrec, 0, wcycle) && MASTER(cr))
2702         {
2703             IMD_send_positions(inputrec->imd);
2704         }
2705
2706         count++;
2707     }   /* End of the loop  */
2708
2709     /* IMD cleanup, if bIMD is TRUE. */
2710     IMD_finalize(inputrec->bIMD, inputrec->imd);
2711
2712     /* Print some data...  */
2713     if (MASTER(cr))
2714     {
2715         fprintf(stderr, "\nwriting lowest energy coordinates.\n");
2716     }
2717     write_em_traj(fplog, cr, outf, TRUE, inputrec->nstfout, ftp2fn(efSTO, nfile, fnm),
2718                   top_global, inputrec, count,
2719                   s_min, state_global);
2720
2721     if (MASTER(cr))
2722     {
2723         double sqrtNumAtoms = sqrt(static_cast<double>(state_global->natoms));
2724         fnormn = s_min->fnorm/sqrtNumAtoms;
2725
2726         print_converged(stderr, SD, inputrec->em_tol, count, bDone, nsteps,
2727                         s_min->epot, s_min->fmax, s_min->a_fmax, fnormn);
2728         print_converged(fplog, SD, inputrec->em_tol, count, bDone, nsteps,
2729                         s_min->epot, s_min->fmax, s_min->a_fmax, fnormn);
2730     }
2731
2732     finish_em(cr, outf, walltime_accounting, wcycle);
2733
2734     /* To print the actual number of steps we needed somewhere */
2735     inputrec->nsteps = count;
2736
2737     walltime_accounting_set_nsteps_done(walltime_accounting, count);
2738
2739     return 0;
2740 }   /* That's all folks */
2741
2742 /*! \brief Do normal modes analysis
2743     \copydoc integrator_t (FILE *fplog, t_commrec *cr,
2744                            int nfile, const t_filenm fnm[],
2745                            const gmx_output_env_t *oenv, gmx_bool bVerbose,
2746                            int nstglobalcomm,
2747                            gmx_vsite_t *vsite, gmx_constr_t constr,
2748                            int stepout,
2749                            t_inputrec *inputrec,
2750                            gmx_mtop_t *top_global, t_fcdata *fcd,
2751                            t_state *state_global,
2752                            t_mdatoms *mdatoms,
2753                            t_nrnb *nrnb, gmx_wallcycle_t wcycle,
2754                            gmx_edsam_t ed,
2755                            t_forcerec *fr,
2756                            int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
2757                            real cpt_period, real max_hours,
2758                            int imdport,
2759                            unsigned long Flags,
2760                            gmx_walltime_accounting_t walltime_accounting)
2761  */
2762 double do_nm(FILE *fplog, t_commrec *cr,
2763              int nfile, const t_filenm fnm[],
2764              const gmx_output_env_t gmx_unused *oenv, gmx_bool bVerbose,
2765              int gmx_unused nstglobalcomm,
2766              gmx_vsite_t *vsite, gmx_constr_t constr,
2767              int gmx_unused stepout,
2768              t_inputrec *inputrec,
2769              gmx_mtop_t *top_global, t_fcdata *fcd,
2770              t_state *state_global,
2771              t_mdatoms *mdatoms,
2772              t_nrnb *nrnb, gmx_wallcycle_t wcycle,
2773              gmx_edsam_t  gmx_unused ed,
2774              t_forcerec *fr,
2775              int gmx_unused repl_ex_nst, int gmx_unused repl_ex_nex, int gmx_unused repl_ex_seed,
2776              gmx_membed_t gmx_unused *membed,
2777              real gmx_unused cpt_period, real gmx_unused max_hours,
2778              int imdport,
2779              unsigned long gmx_unused Flags,
2780              gmx_walltime_accounting_t walltime_accounting)
2781 {
2782     const char          *NM = "Normal Mode Analysis";
2783     gmx_mdoutf_t         outf;
2784     int                  nnodes, node;
2785     gmx_localtop_t      *top;
2786     gmx_enerdata_t      *enerd;
2787     rvec                *f;
2788     gmx_global_stat_t    gstat;
2789     t_graph             *graph;
2790     tensor               vir, pres;
2791     rvec                 mu_tot;
2792     rvec                *fneg, *dfdx;
2793     gmx_bool             bSparse; /* use sparse matrix storage format */
2794     size_t               sz;
2795     gmx_sparsematrix_t * sparse_matrix           = NULL;
2796     real           *     full_matrix             = NULL;
2797     em_state_t       *   state_work;
2798
2799     /* added with respect to mdrun */
2800     int                       row, col;
2801     real                      der_range = 10.0*sqrt(GMX_REAL_EPS);
2802     real                      x_min;
2803     bool                      bIsMaster = MASTER(cr);
2804
2805     if (constr != NULL)
2806     {
2807         gmx_fatal(FARGS, "Constraints present with Normal Mode Analysis, this combination is not supported");
2808     }
2809
2810     state_work = init_em_state();
2811
2812     /* Init em and store the local state in state_minimum */
2813     init_em(fplog, NM, cr, inputrec,
2814             state_global, top_global, state_work, &top,
2815             &f,
2816             nrnb, mu_tot, fr, &enerd, &graph, mdatoms, &gstat, vsite, constr,
2817             nfile, fnm, &outf, NULL, imdport, Flags, wcycle);
2818
2819     gmx_shellfc_t *shellfc = init_shell_flexcon(stdout,
2820                                                 top_global,
2821                                                 n_flexible_constraints(constr),
2822                                                 inputrec->nstcalcenergy,
2823                                                 DOMAINDECOMP(cr));
2824
2825     if (shellfc)
2826     {
2827         make_local_shells(cr, mdatoms, shellfc);
2828     }
2829     std::vector<size_t> atom_index = get_atom_index(top_global);
2830     snew(fneg, atom_index.size());
2831     snew(dfdx, atom_index.size());
2832
2833 #if !GMX_DOUBLE
2834     if (bIsMaster)
2835     {
2836         fprintf(stderr,
2837                 "NOTE: This version of GROMACS has been compiled in single precision,\n"
2838                 "      which MIGHT not be accurate enough for normal mode analysis.\n"
2839                 "      GROMACS now uses sparse matrix storage, so the memory requirements\n"
2840                 "      are fairly modest even if you recompile in double precision.\n\n");
2841     }
2842 #endif
2843
2844     /* Check if we can/should use sparse storage format.
2845      *
2846      * Sparse format is only useful when the Hessian itself is sparse, which it
2847      * will be when we use a cutoff.
2848      * For small systems (n<1000) it is easier to always use full matrix format, though.
2849      */
2850     if (EEL_FULL(fr->eeltype) || fr->rlist == 0.0)
2851     {
2852         md_print_info(cr, fplog, "Non-cutoff electrostatics used, forcing full Hessian format.\n");
2853         bSparse = FALSE;
2854     }
2855     else if (atom_index.size() < 1000)
2856     {
2857         md_print_info(cr, fplog, "Small system size (N=%d), using full Hessian format.\n", atom_index.size());
2858         bSparse = FALSE;
2859     }
2860     else
2861     {
2862         md_print_info(cr, fplog, "Using compressed symmetric sparse Hessian format.\n");
2863         bSparse = TRUE;
2864     }
2865
2866     /* Number of dimensions, based on real atoms, that is not vsites or shell */
2867     sz = DIM*atom_index.size();
2868
2869     fprintf(stderr, "Allocating Hessian memory...\n\n");
2870
2871     if (bSparse)
2872     {
2873         sparse_matrix = gmx_sparsematrix_init(sz);
2874         sparse_matrix->compressed_symmetric = TRUE;
2875     }
2876     else
2877     {
2878         snew(full_matrix, sz*sz);
2879     }
2880
2881     init_nrnb(nrnb);
2882
2883     where();
2884
2885     /* Write start time and temperature */
2886     print_em_start(fplog, cr, walltime_accounting, wcycle, NM);
2887
2888     /* fudge nr of steps to nr of atoms */
2889     inputrec->nsteps = atom_index.size()*2;
2890
2891     if (bIsMaster)
2892     {
2893         fprintf(stderr, "starting normal mode calculation '%s'\n%d steps.\n\n",
2894                 *(top_global->name), (int)inputrec->nsteps);
2895     }
2896
2897     nnodes = cr->nnodes;
2898
2899     /* Make evaluate_energy do a single node force calculation */
2900     cr->nnodes = 1;
2901     evaluate_energy(fplog, cr,
2902                     top_global, state_work, top,
2903                     inputrec, nrnb, wcycle, gstat,
2904                     vsite, constr, fcd, graph, mdatoms, fr,
2905                     mu_tot, enerd, vir, pres, -1, TRUE);
2906     cr->nnodes = nnodes;
2907
2908     /* if forces are not small, warn user */
2909     get_state_f_norm_max(cr, &(inputrec->opts), mdatoms, state_work);
2910
2911     md_print_info(cr, fplog, "Maximum force:%12.5e\n", state_work->fmax);
2912     if (state_work->fmax > 1.0e-3)
2913     {
2914         md_print_info(cr, fplog,
2915                       "The force is probably not small enough to "
2916                       "ensure that you are at a minimum.\n"
2917                       "Be aware that negative eigenvalues may occur\n"
2918                       "when the resulting matrix is diagonalized.\n\n");
2919     }
2920
2921     /***********************************************************
2922      *
2923      *      Loop over all pairs in matrix
2924      *
2925      *      do_force called twice. Once with positive and
2926      *      once with negative displacement
2927      *
2928      ************************************************************/
2929
2930     /* Steps are divided one by one over the nodes */
2931     bool bNS = true;
2932     for (unsigned int aid = cr->nodeid; aid < atom_index.size(); aid += nnodes)
2933     {
2934         size_t atom = atom_index[aid];
2935         for (size_t d = 0; d < DIM; d++)
2936         {
2937             gmx_bool    bBornRadii  = FALSE;
2938             gmx_int64_t step        = 0;
2939             int         force_flags = GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES;
2940             double      t           = 0;
2941
2942             x_min = state_work->s.x[atom][d];
2943
2944             for (unsigned int dx = 0; (dx < 2); dx++)
2945             {
2946                 if (dx == 0)
2947                 {
2948                     state_work->s.x[atom][d] = x_min - der_range;
2949                 }
2950                 else
2951                 {
2952                     state_work->s.x[atom][d] = x_min + der_range;
2953                 }
2954
2955                 /* Make evaluate_energy do a single node force calculation */
2956                 cr->nnodes = 1;
2957                 if (shellfc)
2958                 {
2959                     /* Now is the time to relax the shells */
2960                     (void) relax_shell_flexcon(fplog, cr, bVerbose, step,
2961                                                inputrec, bNS, force_flags,
2962                                                top,
2963                                                constr, enerd, fcd,
2964                                                &state_work->s, state_work->f, vir, mdatoms,
2965                                                nrnb, wcycle, graph, &top_global->groups,
2966                                                shellfc, fr, bBornRadii, t, mu_tot,
2967                                                vsite, NULL);
2968                     bNS = false;
2969                     step++;
2970                 }
2971                 else
2972                 {
2973                     evaluate_energy(fplog, cr,
2974                                     top_global, state_work, top,
2975                                     inputrec, nrnb, wcycle, gstat,
2976                                     vsite, constr, fcd, graph, mdatoms, fr,
2977                                     mu_tot, enerd, vir, pres, atom*2+dx, FALSE);
2978                 }
2979
2980                 cr->nnodes = nnodes;
2981
2982                 if (dx == 0)
2983                 {
2984                     for (size_t i = 0; i < atom_index.size(); i++)
2985                     {
2986                         copy_rvec(state_work->f[atom_index[i]], fneg[i]);
2987                     }
2988                 }
2989             }
2990
2991             /* x is restored to original */
2992             state_work->s.x[atom][d] = x_min;
2993
2994             for (size_t j = 0; j < atom_index.size(); j++)
2995             {
2996                 for (size_t k = 0; (k < DIM); k++)
2997                 {
2998                     dfdx[j][k] =
2999                         -(state_work->f[atom_index[j]][k] - fneg[j][k])/(2*der_range);
3000                 }
3001             }
3002
3003             if (!bIsMaster)
3004             {
3005 #if GMX_MPI
3006 #define mpi_type GMX_MPI_REAL
3007                 MPI_Send(dfdx[0], atom_index.size()*DIM, mpi_type, MASTER(cr),
3008                          cr->nodeid, cr->mpi_comm_mygroup);
3009 #endif
3010             }
3011             else
3012             {
3013                 for (node = 0; (node < nnodes && atom+node < atom_index.size()); node++)
3014                 {
3015                     if (node > 0)
3016                     {
3017 #if GMX_MPI
3018                         MPI_Status stat;
3019                         MPI_Recv(dfdx[0], atom_index.size()*DIM, mpi_type, node, node,
3020                                  cr->mpi_comm_mygroup, &stat);
3021 #undef mpi_type
3022 #endif
3023                     }
3024
3025                     row = (atom + node)*DIM + d;
3026
3027                     for (size_t j = 0; j < atom_index.size(); j++)
3028                     {
3029                         for (size_t k = 0; k < DIM; k++)
3030                         {
3031                             col = j*DIM + k;
3032
3033                             if (bSparse)
3034                             {
3035                                 if (col >= row && dfdx[j][k] != 0.0)
3036                                 {
3037                                     gmx_sparsematrix_increment_value(sparse_matrix,
3038                                                                      row, col, dfdx[j][k]);
3039                                 }
3040                             }
3041                             else
3042                             {
3043                                 full_matrix[row*sz+col] = dfdx[j][k];
3044                             }
3045                         }
3046                     }
3047                 }
3048             }
3049
3050             if (bVerbose && fplog)
3051             {
3052                 fflush(fplog);
3053             }
3054         }
3055         /* write progress */
3056         if (bIsMaster && bVerbose)
3057         {
3058             fprintf(stderr, "\rFinished step %d out of %d",
3059                     static_cast<int>(std::min(atom+nnodes, atom_index.size())),
3060                     static_cast<int>(atom_index.size()));
3061             fflush(stderr);
3062         }
3063     }
3064
3065     if (bIsMaster)
3066     {
3067         fprintf(stderr, "\n\nWriting Hessian...\n");
3068         gmx_mtxio_write(ftp2fn(efMTX, nfile, fnm), sz, sz, full_matrix, sparse_matrix);
3069     }
3070
3071     finish_em(cr, outf, walltime_accounting, wcycle);
3072
3073     walltime_accounting_set_nsteps_done(walltime_accounting, atom_index.size()*2);
3074
3075     return 0;
3076 }
3077
3078 } // namespace gmx