Clean up make_at2con
[gromacs.git] / src / gromacs / mdlib / constr.cpp
blob9448b953b541c65158ab7dfd715dd9309626ed7c
1 /*
2 * This file is part of the GROMACS molecular simulation package.
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,2018, 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.
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.
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.
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.
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.
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.
37 /*! \internal \file
38 * \brief Defines the high-level constraint code.
40 * \author Berk Hess <hess@kth.se>
41 * \author Mark Abraham <mark.j.abraham@gmail.com>
42 * \ingroup module_mdlib
44 #include "gmxpre.h"
46 #include "constr.h"
48 #include <assert.h>
49 #include <stdlib.h>
51 #include <cmath>
53 #include <algorithm>
55 #include "gromacs/domdec/domdec.h"
56 #include "gromacs/domdec/domdec_struct.h"
57 #include "gromacs/essentialdynamics/edsam.h"
58 #include "gromacs/fileio/confio.h"
59 #include "gromacs/fileio/gmxfio.h"
60 #include "gromacs/fileio/pdbio.h"
61 #include "gromacs/gmxlib/nrnb.h"
62 #include "gromacs/math/utilities.h"
63 #include "gromacs/math/vec.h"
64 #include "gromacs/mdlib/gmx_omp_nthreads.h"
65 #include "gromacs/mdlib/lincs.h"
66 #include "gromacs/mdlib/mdrun.h"
67 #include "gromacs/mdlib/settle.h"
68 #include "gromacs/mdlib/shake.h"
69 #include "gromacs/mdtypes/commrec.h"
70 #include "gromacs/mdtypes/inputrec.h"
71 #include "gromacs/mdtypes/md_enums.h"
72 #include "gromacs/mdtypes/mdatom.h"
73 #include "gromacs/mdtypes/state.h"
74 #include "gromacs/pbcutil/pbc.h"
75 #include "gromacs/pulling/pull.h"
76 #include "gromacs/topology/block.h"
77 #include "gromacs/topology/ifunc.h"
78 #include "gromacs/topology/mtop_lookup.h"
79 #include "gromacs/topology/mtop_util.h"
80 #include "gromacs/utility/exceptions.h"
81 #include "gromacs/utility/fatalerror.h"
82 #include "gromacs/utility/gmxassert.h"
83 #include "gromacs/utility/pleasecite.h"
84 #include "gromacs/utility/smalloc.h"
85 #include "gromacs/utility/txtdump.h"
87 namespace gmx
90 /* \brief Impl class for Constraints
92 * \todo Members like md, idef are valid only for the lifetime of a
93 * domain, which would be good to make clearer in the structure of the
94 * code. It should not be possible to call apply() if setConstraints()
95 * has not been called. For example, this could be achieved if
96 * setConstraints returned a valid object with such a method. That
97 * still requires that we manage the lifetime of that object
98 * correctly, however. */
99 class Constraints::Impl
101 public:
102 Impl(const gmx_mtop_t &mtop_p,
103 const t_inputrec &ir_p,
104 FILE *log_p,
105 const t_mdatoms &md_p,
106 const t_commrec *cr_p,
107 const gmx_multisim_t &ms,
108 t_nrnb *nrnb,
109 gmx_wallcycle *wcycle_p,
110 bool pbcHandlingRequired,
111 int numConstraints,
112 int numSettles);
113 void setConstraints(const gmx_localtop_t &top,
114 const t_mdatoms &md);
115 bool apply(bool bLog,
116 bool bEner,
117 gmx_int64_t step,
118 int delta_step,
119 real step_scaling,
120 rvec *x,
121 rvec *xprime,
122 rvec *min_proj,
123 matrix box,
124 real lambda,
125 real *dvdlambda,
126 rvec *v,
127 tensor *vir,
128 ConstraintVariable econq);
129 //! The total number of constraints.
130 int ncon_tot = 0;
131 //! The number of flexible constraints.
132 int nflexcon = 0;
133 //! The size of at2con = number of moltypes.
134 int n_at2con_mt = 0;
135 //! A list of atoms to constraints.
136 t_blocka *at2con_mt = nullptr;
137 //! The size of at2settle = number of moltypes
138 int n_at2settle_mt = 0;
139 //! A list of atoms to settles.
140 int **at2settle_mt = nullptr;
141 //! Whether any SETTLES cross charge-group boundaries.
142 bool bInterCGsettles = false;
143 //! LINCS data.
144 Lincs *lincsd = nullptr;
145 //! SHAKE data.
146 shakedata *shaked = nullptr;
147 //! SETTLE data.
148 settledata *settled = nullptr;
149 //! The maximum number of warnings.
150 int maxwarn = 0;
151 //! The number of warnings for LINCS.
152 int warncount_lincs = 0;
153 //! The number of warnings for SETTLE.
154 int warncount_settle = 0;
155 //! The essential dynamics data.
156 gmx_edsam_t ed = nullptr;
158 //! Thread-local virial contribution.
159 tensor *vir_r_m_dr_th = {0};
160 //! Did a settle error occur?
161 bool *bSettleErrorHasOccurred = nullptr;
163 //! Pointer to the global topology - only used for printing warnings.
164 const gmx_mtop_t &mtop;
165 //! Parameters for the interactions in this domain.
166 const t_idef *idef = nullptr;
167 //! Data about atoms in this domain.
168 const t_mdatoms &md;
169 //! Whether we need to do pbc for handling bonds.
170 bool pbcHandlingRequired_ = false;
172 //! Logging support.
173 FILE *log = nullptr;
174 //! Communication support.
175 const t_commrec *cr = nullptr;
176 //! Multi-sim support.
177 const gmx_multisim_t &ms;
178 /*!\brief Input options.
180 * \todo Replace with IMdpOptions */
181 const t_inputrec &ir;
182 //! Flop counting support.
183 t_nrnb *nrnb = nullptr;
184 //! Tracks wallcycle usage.
185 gmx_wallcycle *wcycle;
188 Constraints::~Constraints() = default;
190 int Constraints::numFlexibleConstraints() const
192 return impl_->nflexcon;
195 //! Clears constraint quantities for atoms in nonlocal region.
196 static void clear_constraint_quantity_nonlocal(gmx_domdec_t *dd, rvec *q)
198 int nonlocal_at_start, nonlocal_at_end, at;
200 dd_get_constraint_range(dd, &nonlocal_at_start, &nonlocal_at_end);
202 for (at = nonlocal_at_start; at < nonlocal_at_end; at++)
204 clear_rvec(q[at]);
208 void too_many_constraint_warnings(int eConstrAlg, int warncount)
210 gmx_fatal(FARGS,
211 "Too many %s warnings (%d)\n"
212 "If you know what you are doing you can %s"
213 "set the environment variable GMX_MAXCONSTRWARN to -1,\n"
214 "but normally it is better to fix the problem",
215 (eConstrAlg == econtLINCS) ? "LINCS" : "SETTLE", warncount,
216 (eConstrAlg == econtLINCS) ?
217 "adjust the lincs warning threshold in your mdp file\nor " : "\n");
220 //! Writes out coordinates.
221 static void write_constr_pdb(const char *fn, const char *title,
222 const gmx_mtop_t &mtop,
223 int start, int homenr, const t_commrec *cr,
224 const rvec x[], matrix box)
226 char fname[STRLEN];
227 FILE *out;
228 int dd_ac0 = 0, dd_ac1 = 0, i, ii, resnr;
229 gmx_domdec_t *dd;
230 const char *anm, *resnm;
232 dd = nullptr;
233 if (DOMAINDECOMP(cr))
235 dd = cr->dd;
236 dd_get_constraint_range(dd, &dd_ac0, &dd_ac1);
237 start = 0;
238 homenr = dd_ac1;
241 if (PAR(cr))
243 sprintf(fname, "%s_n%d.pdb", fn, cr->sim_nodeid);
245 else
247 sprintf(fname, "%s.pdb", fn);
250 out = gmx_fio_fopen(fname, "w");
252 fprintf(out, "TITLE %s\n", title);
253 gmx_write_pdb_box(out, -1, box);
254 int molb = 0;
255 for (i = start; i < start+homenr; i++)
257 if (dd != nullptr)
259 if (i >= dd->nat_home && i < dd_ac0)
261 continue;
263 ii = dd->gatindex[i];
265 else
267 ii = i;
269 mtopGetAtomAndResidueName(mtop, ii, &molb, &anm, &resnr, &resnm, nullptr);
270 gmx_fprintf_pdb_atomline(out, epdbATOM, ii+1, anm, ' ', resnm, ' ', resnr, ' ',
271 10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], 1.0, 0.0, "");
273 fprintf(out, "TER\n");
275 gmx_fio_fclose(out);
278 //! Writes out domain contents to help diagnose crashes.
279 static void dump_confs(FILE *log, gmx_int64_t step, const gmx_mtop_t &mtop,
280 int start, int homenr, const t_commrec *cr,
281 const rvec x[], rvec xprime[], matrix box)
283 char buf[STRLEN], buf2[22];
285 char *env = getenv("GMX_SUPPRESS_DUMP");
286 if (env)
288 return;
291 sprintf(buf, "step%sb", gmx_step_str(step, buf2));
292 write_constr_pdb(buf, "initial coordinates",
293 mtop, start, homenr, cr, x, box);
294 sprintf(buf, "step%sc", gmx_step_str(step, buf2));
295 write_constr_pdb(buf, "coordinates after constraining",
296 mtop, start, homenr, cr, xprime, box);
297 if (log)
299 fprintf(log, "Wrote pdb files with previous and current coordinates\n");
301 fprintf(stderr, "Wrote pdb files with previous and current coordinates\n");
304 bool
305 Constraints::apply(bool bLog,
306 bool bEner,
307 gmx_int64_t step,
308 int delta_step,
309 real step_scaling,
310 rvec *x,
311 rvec *xprime,
312 rvec *min_proj,
313 matrix box,
314 real lambda,
315 real *dvdlambda,
316 rvec *v,
317 tensor *vir,
318 ConstraintVariable econq)
320 return impl_->apply(bLog,
321 bEner,
322 step,
323 delta_step,
324 step_scaling,
326 xprime,
327 min_proj,
328 box,
329 lambda,
330 dvdlambda,
332 vir,
333 econq);
336 bool
337 Constraints::Impl::apply(bool bLog,
338 bool bEner,
339 gmx_int64_t step,
340 int delta_step,
341 real step_scaling,
342 rvec *x,
343 rvec *xprime,
344 rvec *min_proj,
345 matrix box,
346 real lambda,
347 real *dvdlambda,
348 rvec *v,
349 tensor *vir,
350 ConstraintVariable econq)
352 bool bOK, bDump;
353 int start, homenr;
354 tensor vir_r_m_dr;
355 real scaled_delta_t;
356 real invdt, vir_fac = 0, t;
357 int nsettle;
358 t_pbc pbc, *pbc_null;
359 char buf[22];
360 int nth, th;
362 wallcycle_start(wcycle, ewcCONSTR);
364 if (econq == ConstraintVariable::ForceDispl && !EI_ENERGY_MINIMIZATION(ir.eI))
366 gmx_incons("constrain called for forces displacements while not doing energy minimization, can not do this while the LINCS and SETTLE constraint connection matrices are mass weighted");
369 bOK = TRUE;
370 bDump = FALSE;
372 start = 0;
373 homenr = md.homenr;
375 scaled_delta_t = step_scaling * ir.delta_t;
377 /* Prepare time step for use in constraint implementations, and
378 avoid generating inf when ir.delta_t = 0. */
379 if (ir.delta_t == 0)
381 invdt = 0.0;
383 else
385 invdt = 1.0/scaled_delta_t;
388 if (ir.efep != efepNO && EI_DYNAMICS(ir.eI))
390 /* Set the constraint lengths for the step at which this configuration
391 * is meant to be. The invmasses should not be changed.
393 lambda += delta_step*ir.fepvals->delta_lambda;
396 if (vir != nullptr)
398 clear_mat(vir_r_m_dr);
400 const t_ilist *settle = &idef->il[F_SETTLE];
401 nsettle = settle->nr/(1+NRAL(F_SETTLE));
403 if (nsettle > 0)
405 nth = gmx_omp_nthreads_get(emntSETTLE);
407 else
409 nth = 1;
412 /* We do not need full pbc when constraints do not cross charge groups,
413 * i.e. when dd->constraint_comm==NULL.
414 * Note that PBC for constraints is different from PBC for bondeds.
415 * For constraints there is both forward and backward communication.
417 if (ir.ePBC != epbcNONE &&
418 (cr->dd || pbcHandlingRequired_) && !(cr->dd && cr->dd->constraint_comm == nullptr))
420 /* With pbc=screw the screw has been changed to a shift
421 * by the constraint coordinate communication routine,
422 * so that here we can use normal pbc.
424 pbc_null = set_pbc_dd(&pbc, ir.ePBC,
425 DOMAINDECOMP(cr) ? cr->dd->nc : nullptr,
426 FALSE, box);
428 else
430 pbc_null = nullptr;
433 /* Communicate the coordinates required for the non-local constraints
434 * for LINCS and/or SETTLE.
436 if (cr->dd)
438 dd_move_x_constraints(cr->dd, box, x, xprime, econq == ConstraintVariable::Positions);
440 if (v != nullptr)
442 /* We need to initialize the non-local components of v.
443 * We never actually use these values, but we do increment them,
444 * so we should avoid uninitialized variables and overflows.
446 clear_constraint_quantity_nonlocal(cr->dd, v);
450 if (lincsd != nullptr)
452 bOK = constrain_lincs(log, bLog, bEner, ir, step, lincsd, md, cr, ms,
453 x, xprime, min_proj,
454 box, pbc_null, lambda, dvdlambda,
455 invdt, v, vir != nullptr, vir_r_m_dr,
456 econq, nrnb,
457 maxwarn, &warncount_lincs);
458 if (!bOK && maxwarn < INT_MAX)
460 if (log != nullptr)
462 fprintf(log, "Constraint error in algorithm %s at step %s\n",
463 econstr_names[econtLINCS], gmx_step_str(step, buf));
465 bDump = TRUE;
469 if (shaked != nullptr)
471 bOK = constrain_shake(log, shaked,
472 md.invmass,
473 *idef, ir, x, xprime, min_proj, nrnb,
474 lambda, dvdlambda,
475 invdt, v, vir != nullptr, vir_r_m_dr,
476 maxwarn < INT_MAX, econq);
478 if (!bOK && maxwarn < INT_MAX)
480 if (log != nullptr)
482 fprintf(log, "Constraint error in algorithm %s at step %s\n",
483 econstr_names[econtSHAKE], gmx_step_str(step, buf));
485 bDump = TRUE;
489 if (nsettle > 0)
491 bool bSettleErrorHasOccurred0 = false;
493 switch (econq)
495 case ConstraintVariable::Positions:
496 #pragma omp parallel for num_threads(nth) schedule(static)
497 for (th = 0; th < nth; th++)
501 if (th > 0)
503 clear_mat(vir_r_m_dr_th[th]);
506 csettle(settled,
507 nth, th,
508 pbc_null,
509 x[0], xprime[0],
510 invdt, v ? v[0] : nullptr,
511 vir != nullptr,
512 th == 0 ? vir_r_m_dr : vir_r_m_dr_th[th],
513 th == 0 ? &bSettleErrorHasOccurred0 : &bSettleErrorHasOccurred[th]);
515 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
517 inc_nrnb(nrnb, eNR_SETTLE, nsettle);
518 if (v != nullptr)
520 inc_nrnb(nrnb, eNR_CONSTR_V, nsettle*3);
522 if (vir != nullptr)
524 inc_nrnb(nrnb, eNR_CONSTR_VIR, nsettle*3);
526 break;
527 case ConstraintVariable::Velocities:
528 case ConstraintVariable::Derivative:
529 case ConstraintVariable::Force:
530 case ConstraintVariable::ForceDispl:
531 #pragma omp parallel for num_threads(nth) schedule(static)
532 for (th = 0; th < nth; th++)
536 int calcvir_atom_end;
538 if (vir == nullptr)
540 calcvir_atom_end = 0;
542 else
544 calcvir_atom_end = md.homenr;
547 if (th > 0)
549 clear_mat(vir_r_m_dr_th[th]);
552 int start_th = (nsettle* th )/nth;
553 int end_th = (nsettle*(th+1))/nth;
555 if (start_th >= 0 && end_th - start_th > 0)
557 settle_proj(settled, econq,
558 end_th-start_th,
559 settle->iatoms+start_th*(1+NRAL(F_SETTLE)),
560 pbc_null,
562 xprime, min_proj, calcvir_atom_end,
563 th == 0 ? vir_r_m_dr : vir_r_m_dr_th[th]);
566 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
568 /* This is an overestimate */
569 inc_nrnb(nrnb, eNR_SETTLE, nsettle);
570 break;
571 case ConstraintVariable::Deriv_FlexCon:
572 /* Nothing to do, since the are no flexible constraints in settles */
573 break;
574 default:
575 gmx_incons("Unknown constraint quantity for settle");
578 if (vir != nullptr)
580 /* Reduce the virial contributions over the threads */
581 for (int th = 1; th < nth; th++)
583 m_add(vir_r_m_dr, vir_r_m_dr_th[th], vir_r_m_dr);
587 if (econq == ConstraintVariable::Positions)
589 for (int th = 1; th < nth; th++)
591 bSettleErrorHasOccurred0 = bSettleErrorHasOccurred0 || bSettleErrorHasOccurred[th];
594 if (bSettleErrorHasOccurred0)
596 char buf[STRLEN];
597 sprintf(buf,
598 "\nstep " "%" GMX_PRId64 ": One or more water molecules can not be settled.\n"
599 "Check for bad contacts and/or reduce the timestep if appropriate.\n",
600 step);
601 if (log)
603 fprintf(log, "%s", buf);
605 fprintf(stderr, "%s", buf);
606 warncount_settle++;
607 if (warncount_settle > maxwarn)
609 too_many_constraint_warnings(-1, warncount_settle);
611 bDump = TRUE;
613 bOK = FALSE;
618 if (vir != nullptr)
620 /* The normal uses of constrain() pass step_scaling = 1.0.
621 * The call to constrain() for SD1 that passes step_scaling =
622 * 0.5 also passes vir = NULL, so cannot reach this
623 * assertion. This assertion should remain until someone knows
624 * that this path works for their intended purpose, and then
625 * they can use scaled_delta_t instead of ir.delta_t
626 * below. */
627 assert(gmx_within_tol(step_scaling, 1.0, GMX_REAL_EPS));
628 switch (econq)
630 case ConstraintVariable::Positions:
631 vir_fac = 0.5/(ir.delta_t*ir.delta_t);
632 break;
633 case ConstraintVariable::Velocities:
634 vir_fac = 0.5/ir.delta_t;
635 break;
636 case ConstraintVariable::Force:
637 case ConstraintVariable::ForceDispl:
638 vir_fac = 0.5;
639 break;
640 default:
641 gmx_incons("Unsupported constraint quantity for virial");
644 if (EI_VV(ir.eI))
646 vir_fac *= 2; /* only constraining over half the distance here */
648 for (int i = 0; i < DIM; i++)
650 for (int j = 0; j < DIM; j++)
652 (*vir)[i][j] = vir_fac*vir_r_m_dr[i][j];
657 if (bDump)
659 dump_confs(log, step, mtop, start, homenr, cr, x, xprime, box);
662 if (econq == ConstraintVariable::Positions)
664 if (ir.bPull && pull_have_constraint(ir.pull_work))
666 if (EI_DYNAMICS(ir.eI))
668 t = ir.init_t + (step + delta_step)*ir.delta_t;
670 else
672 t = ir.init_t;
674 set_pbc(&pbc, ir.ePBC, box);
675 pull_constraint(ir.pull_work, &md, &pbc, cr, ir.delta_t, t, x, xprime, v, *vir);
677 if (ed && delta_step > 0)
679 /* apply the essential dynamics constraints here */
680 do_edsam(&ir, step, cr, xprime, v, box, ed);
683 wallcycle_stop(wcycle, ewcCONSTR);
685 return bOK;
688 real *Constraints::rmsdData() const
690 if (impl_->lincsd)
692 return lincs_rmsd_data(impl_->lincsd);
694 else
696 return nullptr;
700 real Constraints::rmsd() const
702 if (impl_->lincsd)
704 return lincs_rmsd(impl_->lincsd);
706 else
708 return 0;
712 FlexibleConstraintTreatment flexibleConstraintTreatment(bool haveDynamicsIntegrator)
714 if (haveDynamicsIntegrator)
716 return FlexibleConstraintTreatment::Include;
718 else
720 return FlexibleConstraintTreatment::Exclude;
724 t_blocka make_at2con(int numAtoms,
725 const t_ilist *ilists,
726 const t_iparams *iparams,
727 FlexibleConstraintTreatment flexibleConstraintTreatment)
729 GMX_ASSERT(flexibleConstraintTreatment == FlexibleConstraintTreatment::Include || iparams != nullptr, "With flexible constraint detection we need valid iparams");
731 std::vector<int> count(numAtoms);
733 for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
735 const t_ilist &ilist = ilists[ftype];
736 const int stride = 1 + NRAL(ftype);
737 for (int i = 0; i < ilist.nr; i += stride)
739 if (flexibleConstraintTreatment == FlexibleConstraintTreatment::Include ||
740 !isConstraintFlexible(iparams, ilist.iatoms[i]))
742 for (int j = 1; j < 3; j++)
744 int a = ilist.iatoms[i + j];
745 count[a]++;
751 t_blocka at2con;
752 at2con.nr = numAtoms;
753 at2con.nalloc_index = at2con.nr + 1;
754 snew(at2con.index, at2con.nalloc_index);
755 at2con.index[0] = 0;
756 for (int a = 0; a < numAtoms; a++)
758 at2con.index[a + 1] = at2con.index[a] + count[a];
759 count[a] = 0;
761 at2con.nra = at2con.index[at2con.nr];
762 at2con.nalloc_a = at2con.nra;
763 snew(at2con.a, at2con.nalloc_a);
765 /* The F_CONSTRNC constraints have constraint numbers
766 * that continue after the last F_CONSTR constraint.
768 int numConstraints = 0;
769 for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
771 const t_ilist &ilist = ilists[ftype];
772 const int stride = 1 + NRAL(ftype);
773 for (int i = 0; i < ilist.nr; i += stride)
775 if (flexibleConstraintTreatment == FlexibleConstraintTreatment::Include ||
776 !isConstraintFlexible(iparams, ilist.iatoms[i]))
778 for (int j = 1; j < 3; j++)
780 int a = ilist.iatoms[i + j];
781 at2con.a[at2con.index[a] + count[a]++] = numConstraints;
784 numConstraints++;
788 return at2con;
791 int countFlexibleConstraints(const t_ilist *ilist,
792 const t_iparams *iparams)
794 int nflexcon = 0;
795 for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
797 const int numIatomsPerConstraint = 3;
798 int ncon = ilist[ftype].nr / numIatomsPerConstraint;
799 t_iatom *ia = ilist[ftype].iatoms;
800 for (int con = 0; con < ncon; con++)
802 if (iparams[ia[0]].constr.dA == 0 &&
803 iparams[ia[0]].constr.dB == 0)
805 nflexcon++;
807 ia += numIatomsPerConstraint;
811 return nflexcon;
814 //! Returns the index of the settle to which each atom belongs.
815 static int *make_at2settle(int natoms, const t_ilist *ilist)
817 int *at2s;
818 int a, stride, s;
820 snew(at2s, natoms);
821 /* Set all to no settle */
822 for (a = 0; a < natoms; a++)
824 at2s[a] = -1;
827 stride = 1 + NRAL(F_SETTLE);
829 for (s = 0; s < ilist->nr; s += stride)
831 at2s[ilist->iatoms[s+1]] = s/stride;
832 at2s[ilist->iatoms[s+2]] = s/stride;
833 at2s[ilist->iatoms[s+3]] = s/stride;
836 return at2s;
839 void
840 Constraints::Impl::setConstraints(const gmx_localtop_t &top,
841 const t_mdatoms &md)
843 idef = &top.idef;
845 if (ncon_tot > 0)
847 /* With DD we might also need to call LINCS on a domain no constraints for
848 * communicating coordinates to other nodes that do have constraints.
850 if (ir.eConstrAlg == econtLINCS)
852 set_lincs(top.idef, md, EI_DYNAMICS(ir.eI), cr, lincsd);
854 if (ir.eConstrAlg == econtSHAKE)
856 if (cr->dd)
858 // We are using the local topology, so there are only
859 // F_CONSTR constraints.
860 make_shake_sblock_dd(shaked, &idef->il[F_CONSTR], &top.cgs, cr->dd);
862 else
864 make_shake_sblock_serial(shaked, idef, md);
869 if (settled)
871 settle_set_constraints(settled,
872 &idef->il[F_SETTLE], md);
875 /* Make a selection of the local atoms for essential dynamics */
876 if (ed && cr->dd)
878 dd_make_local_ed_indices(cr->dd, ed);
882 void
883 Constraints::setConstraints(const gmx_localtop_t &top,
884 const t_mdatoms &md)
886 impl_->setConstraints(top, md);
889 Constraints::Constraints(const gmx_mtop_t &mtop,
890 const t_inputrec &ir,
891 FILE *log,
892 const t_mdatoms &md,
893 const t_commrec *cr,
894 const gmx_multisim_t &ms,
895 t_nrnb *nrnb,
896 gmx_wallcycle *wcycle,
897 bool pbcHandlingRequired,
898 int numConstraints,
899 int numSettles)
900 : impl_(new Impl(mtop,
902 log,
906 nrnb,
907 wcycle,
908 pbcHandlingRequired,
909 numConstraints,
910 numSettles))
914 Constraints::Impl::Impl(const gmx_mtop_t &mtop_p,
915 const t_inputrec &ir_p,
916 FILE *log_p,
917 const t_mdatoms &md_p,
918 const t_commrec *cr_p,
919 const gmx_multisim_t &ms_p,
920 t_nrnb *nrnb_p,
921 gmx_wallcycle *wcycle_p,
922 bool pbcHandlingRequired,
923 int numConstraints,
924 int numSettles)
925 : ncon_tot(numConstraints),
926 mtop(mtop_p),
927 md(md_p),
928 pbcHandlingRequired_(pbcHandlingRequired),
929 log(log_p),
930 cr(cr_p),
931 ms(ms_p),
932 ir(ir_p),
933 nrnb(nrnb_p),
934 wcycle(wcycle_p)
936 if (numConstraints + numSettles > 0 && ir.epc == epcMTTK)
938 gmx_fatal(FARGS, "Constraints are not implemented with MTTK pressure control.");
941 nflexcon = 0;
942 if (numConstraints > 0)
944 n_at2con_mt = mtop.moltype.size();
945 snew(at2con_mt, n_at2con_mt);
946 for (int mt = 0; mt < static_cast<int>(mtop.moltype.size()); mt++)
948 at2con_mt[mt] = make_at2con(mtop.moltype[mt].atoms.nr,
949 mtop.moltype[mt].ilist,
950 mtop.ffparams.iparams,
951 flexibleConstraintTreatment(EI_DYNAMICS(ir_p.eI)));
954 for (const gmx_molblock_t &molblock : mtop.molblock)
956 int count = countFlexibleConstraints(mtop.moltype[molblock.type].ilist,
957 mtop.ffparams.iparams);
958 nflexcon += molblock.nmol*count;
961 if (nflexcon > 0)
963 if (log)
965 fprintf(log, "There are %d flexible constraints\n",
966 nflexcon);
967 if (ir.fc_stepsize == 0)
969 fprintf(log, "\n"
970 "WARNING: step size for flexible constraining = 0\n"
971 " All flexible constraints will be rigid.\n"
972 " Will try to keep all flexible constraints at their original length,\n"
973 " but the lengths may exhibit some drift.\n\n");
974 nflexcon = 0;
977 if (nflexcon > 0)
979 please_cite(log, "Hess2002");
983 if (ir.eConstrAlg == econtLINCS)
985 lincsd = init_lincs(log, mtop,
986 nflexcon, at2con_mt,
987 DOMAINDECOMP(cr) && cr->dd->bInterCGcons,
988 ir.nLincsIter, ir.nProjOrder);
991 if (ir.eConstrAlg == econtSHAKE)
993 if (DOMAINDECOMP(cr) && cr->dd->bInterCGcons)
995 gmx_fatal(FARGS, "SHAKE is not supported with domain decomposition and constraint that cross charge group boundaries, use LINCS");
997 if (nflexcon)
999 gmx_fatal(FARGS, "For this system also velocities and/or forces need to be constrained, this can not be done with SHAKE, you should select LINCS");
1001 please_cite(log, "Ryckaert77a");
1002 if (ir.bShakeSOR)
1004 please_cite(log, "Barth95a");
1007 shaked = shake_init();
1011 if (numSettles > 0)
1013 please_cite(log, "Miyamoto92a");
1015 bInterCGsettles = inter_charge_group_settles(mtop);
1017 settled = settle_init(mtop);
1019 /* Make an atom to settle index for use in domain decomposition */
1020 n_at2settle_mt = mtop.moltype.size();
1021 snew(at2settle_mt, n_at2settle_mt);
1022 for (size_t mt = 0; mt < mtop.moltype.size(); mt++)
1024 at2settle_mt[mt] =
1025 make_at2settle(mtop.moltype[mt].atoms.nr,
1026 &mtop.moltype[mt].ilist[F_SETTLE]);
1029 /* Allocate thread-local work arrays */
1030 int nthreads = gmx_omp_nthreads_get(emntSETTLE);
1031 if (nthreads > 1 && vir_r_m_dr_th == nullptr)
1033 snew(vir_r_m_dr_th, nthreads);
1034 snew(bSettleErrorHasOccurred, nthreads);
1038 maxwarn = 999;
1039 char *env = getenv("GMX_MAXCONSTRWARN");
1040 if (env)
1042 maxwarn = 0;
1043 sscanf(env, "%8d", &maxwarn);
1044 if (maxwarn < 0)
1046 maxwarn = INT_MAX;
1048 if (log)
1050 fprintf(log,
1051 "Setting the maximum number of constraint warnings to %d\n",
1052 maxwarn);
1054 if (MASTER(cr))
1056 fprintf(stderr,
1057 "Setting the maximum number of constraint warnings to %d\n",
1058 maxwarn);
1061 warncount_lincs = 0;
1062 warncount_settle = 0;
1065 void Constraints::saveEdsamPointer(gmx_edsam_t ed)
1067 impl_->ed = ed;
1070 const t_blocka *Constraints::atom2constraints_moltype() const
1072 return impl_->at2con_mt;
1075 const int **Constraints::atom2settle_moltype() const
1077 return (const int **)impl_->at2settle_mt;
1081 bool inter_charge_group_constraints(const gmx_mtop_t &mtop)
1083 const gmx_moltype_t *molt;
1084 const t_block *cgs;
1085 const t_ilist *il;
1086 int *at2cg, cg, a, ftype, i;
1087 bool bInterCG;
1089 bInterCG = FALSE;
1090 for (size_t mb = 0; mb < mtop.molblock.size() && !bInterCG; mb++)
1092 molt = &mtop.moltype[mtop.molblock[mb].type];
1094 if (molt->ilist[F_CONSTR].nr > 0 ||
1095 molt->ilist[F_CONSTRNC].nr > 0 ||
1096 molt->ilist[F_SETTLE].nr > 0)
1098 cgs = &molt->cgs;
1099 snew(at2cg, molt->atoms.nr);
1100 for (cg = 0; cg < cgs->nr; cg++)
1102 for (a = cgs->index[cg]; a < cgs->index[cg+1]; a++)
1104 at2cg[a] = cg;
1108 for (ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
1110 il = &molt->ilist[ftype];
1111 for (i = 0; i < il->nr && !bInterCG; i += 1+NRAL(ftype))
1113 if (at2cg[il->iatoms[i+1]] != at2cg[il->iatoms[i+2]])
1115 bInterCG = TRUE;
1120 sfree(at2cg);
1124 return bInterCG;
1127 bool inter_charge_group_settles(const gmx_mtop_t &mtop)
1129 const gmx_moltype_t *molt;
1130 const t_block *cgs;
1131 const t_ilist *il;
1132 int *at2cg, cg, a, ftype, i;
1133 bool bInterCG;
1135 bInterCG = FALSE;
1136 for (size_t mb = 0; mb < mtop.molblock.size() && !bInterCG; mb++)
1138 molt = &mtop.moltype[mtop.molblock[mb].type];
1140 if (molt->ilist[F_SETTLE].nr > 0)
1142 cgs = &molt->cgs;
1143 snew(at2cg, molt->atoms.nr);
1144 for (cg = 0; cg < cgs->nr; cg++)
1146 for (a = cgs->index[cg]; a < cgs->index[cg+1]; a++)
1148 at2cg[a] = cg;
1152 for (ftype = F_SETTLE; ftype <= F_SETTLE; ftype++)
1154 il = &molt->ilist[ftype];
1155 for (i = 0; i < il->nr && !bInterCG; i += 1+NRAL(F_SETTLE))
1157 if (at2cg[il->iatoms[i+1]] != at2cg[il->iatoms[i+2]] ||
1158 at2cg[il->iatoms[i+1]] != at2cg[il->iatoms[i+3]])
1160 bInterCG = TRUE;
1165 sfree(at2cg);
1169 return bInterCG;
1172 } // namespace