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,2018,2019, 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.
43 #include "gromacs/topology/ifunc.h"
44 #include "gromacs/utility/fatalerror.h"
45 #include "gromacs/utility/smalloc.h"
46 #include "gromacs/utility/stringstream.h"
47 #include "gromacs/utility/textwriter.h"
48 #include "gromacs/utility/txtdump.h"
50 static void printHarmonicInteraction(gmx::TextWriter* writer,
51 const t_iparams& iparams,
55 writer->writeLineFormatted("%sA=%12.5e, %sA=%12.5e, %sB=%12.5e, %sB=%12.5e", r,
56 iparams.harmonic.rA, kr, iparams.harmonic.krA, r,
57 iparams.harmonic.rB, kr, iparams.harmonic.krB);
60 void pr_iparams(FILE* fp, t_functype ftype, const t_iparams& iparams)
62 gmx::StringOutputStream stream;
64 gmx::TextWriter writer(&stream);
65 printInteractionParameters(&writer, ftype, iparams);
67 fputs(stream.toString().c_str(), fp);
70 void printInteractionParameters(gmx::TextWriter* writer, t_functype ftype, const t_iparams& iparams)
75 case F_G96ANGLES: printHarmonicInteraction(writer, iparams, "th", "ct"); break;
76 case F_CROSS_BOND_BONDS:
77 writer->writeLineFormatted("r1e=%15.8e, r2e=%15.8e, krr=%15.8e", iparams.cross_bb.r1e,
78 iparams.cross_bb.r2e, iparams.cross_bb.krr);
80 case F_CROSS_BOND_ANGLES:
81 writer->writeLineFormatted("r1e=%15.8e, r1e=%15.8e, r3e=%15.8e, krt=%15.8e",
82 iparams.cross_ba.r1e, iparams.cross_ba.r2e,
83 iparams.cross_ba.r3e, iparams.cross_ba.krt);
86 writer->writeLineFormatted("klinA=%15.8e, aA=%15.8e, klinB=%15.8e, aB=%15.8e",
87 iparams.linangle.klinA, iparams.linangle.aA,
88 iparams.linangle.klinB, iparams.linangle.aB);
91 writer->writeLineFormatted(
92 "thetaA=%15.8e, kthetaA=%15.8e, r13A=%15.8e, kUBA=%15.8e, thetaB=%15.8e, "
93 "kthetaB=%15.8e, r13B=%15.8e, kUBB=%15.8e",
94 iparams.u_b.thetaA, iparams.u_b.kthetaA, iparams.u_b.r13A, iparams.u_b.kUBA,
95 iparams.u_b.thetaB, iparams.u_b.kthetaB, iparams.u_b.r13B, iparams.u_b.kUBB);
97 case F_QUARTIC_ANGLES:
98 writer->writeStringFormatted("theta=%15.8e", iparams.qangle.theta);
99 for (int i = 0; i < 5; i++)
101 writer->writeStringFormatted(", c%c=%15.8e", '0' + i, iparams.qangle.c[i]);
103 writer->ensureLineBreak();
106 writer->writeLineFormatted("a=%15.8e, b=%15.8e, c=%15.8e", iparams.bham.a,
107 iparams.bham.b, iparams.bham.c);
111 case F_HARMONIC: printHarmonicInteraction(writer, iparams, "b0", "cb"); break;
112 case F_IDIHS: printHarmonicInteraction(writer, iparams, "xi", "cx"); break;
114 writer->writeLineFormatted(
115 "b0A=%15.8e, cbA=%15.8e, betaA=%15.8e, b0B=%15.8e, cbB=%15.8e, betaB=%15.8e",
116 iparams.morse.b0A, iparams.morse.cbA, iparams.morse.betaA, iparams.morse.b0B,
117 iparams.morse.cbB, iparams.morse.betaB);
120 writer->writeLineFormatted("b0=%15.8e, kb=%15.8e, kcub=%15.8e", iparams.cubic.b0,
121 iparams.cubic.kb, iparams.cubic.kcub);
123 case F_CONNBONDS: writer->ensureEmptyLine(); break;
125 writer->writeLineFormatted("bm=%15.8e, kb=%15.8e", iparams.fene.bm, iparams.fene.kb);
128 writer->writeLineFormatted(
129 "lowA=%15.8e, up1A=%15.8e, up2A=%15.8e, kA=%15.8e, lowB=%15.8e, up1B=%15.8e, "
130 "up2B=%15.8e, kB=%15.8e,",
131 iparams.restraint.lowA, iparams.restraint.up1A, iparams.restraint.up2A,
132 iparams.restraint.kA, iparams.restraint.lowB, iparams.restraint.up1B,
133 iparams.restraint.up2B, iparams.restraint.kB);
139 writer->writeLineFormatted("tab=%d, kA=%15.8e, kB=%15.8e", iparams.tab.table,
140 iparams.tab.kA, iparams.tab.kB);
143 writer->writeLineFormatted("alpha=%15.8e", iparams.polarize.alpha);
146 writer->writeLineFormatted("alpha=%15.8e drcut=%15.8e khyp=%15.8e",
147 iparams.anharm_polarize.alpha, iparams.anharm_polarize.drcut,
148 iparams.anharm_polarize.khyp);
151 writer->writeLineFormatted("a=%15.8e, alpha1=%15.8e, alpha2=%15.8e, rfac=%15.8e",
152 iparams.thole.a, iparams.thole.alpha1, iparams.thole.alpha2,
156 writer->writeLineFormatted(
157 "al_x=%15.8e, al_y=%15.8e, al_z=%15.8e, rOH=%9.6f, rHH=%9.6f, rOD=%9.6f",
158 iparams.wpol.al_x, iparams.wpol.al_y, iparams.wpol.al_z, iparams.wpol.rOH,
159 iparams.wpol.rHH, iparams.wpol.rOD);
162 writer->writeLineFormatted("c6=%15.8e, c12=%15.8e", iparams.lj.c6, iparams.lj.c12);
165 writer->writeLineFormatted("c6A=%15.8e, c12A=%15.8e, c6B=%15.8e, c12B=%15.8e",
166 iparams.lj14.c6A, iparams.lj14.c12A, iparams.lj14.c6B,
170 writer->writeLineFormatted("fqq=%15.8e, qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e",
171 iparams.ljc14.fqq, iparams.ljc14.qi, iparams.ljc14.qj,
172 iparams.ljc14.c6, iparams.ljc14.c12);
175 writer->writeLineFormatted("qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e", iparams.ljcnb.qi,
176 iparams.ljcnb.qj, iparams.ljcnb.c6, iparams.ljcnb.c12);
182 writer->writeLineFormatted("phiA=%15.8e, cpA=%15.8e, phiB=%15.8e, cpB=%15.8e, mult=%d",
183 iparams.pdihs.phiA, iparams.pdihs.cpA, iparams.pdihs.phiB,
184 iparams.pdihs.cpB, iparams.pdihs.mult);
187 writer->writeLineFormatted(
188 "label=%4d, type=%1d, low=%15.8e, up1=%15.8e, up2=%15.8e, fac=%15.8e)",
189 iparams.disres.label, iparams.disres.type, iparams.disres.low,
190 iparams.disres.up1, iparams.disres.up2, iparams.disres.kfac);
193 writer->writeLineFormatted(
194 "ex=%4d, label=%d, power=%4d, c=%15.8e, obs=%15.8e, kfac=%15.8e)",
195 iparams.orires.ex, iparams.orires.label, iparams.orires.power, iparams.orires.c,
196 iparams.orires.obs, iparams.orires.kfac);
199 writer->writeLineFormatted(
200 "phiA=%15.8e, dphiA=%15.8e, kfacA=%15.8e, phiB=%15.8e, dphiB=%15.8e, "
202 iparams.dihres.phiA, iparams.dihres.dphiA, iparams.dihres.kfacA,
203 iparams.dihres.phiB, iparams.dihres.dphiB, iparams.dihres.kfacB);
206 writer->writeLineFormatted(
207 "pos0A=(%15.8e,%15.8e,%15.8e), fcA=(%15.8e,%15.8e,%15.8e), "
208 "pos0B=(%15.8e,%15.8e,%15.8e), fcB=(%15.8e,%15.8e,%15.8e)",
209 iparams.posres.pos0A[XX], iparams.posres.pos0A[YY], iparams.posres.pos0A[ZZ],
210 iparams.posres.fcA[XX], iparams.posres.fcA[YY], iparams.posres.fcA[ZZ],
211 iparams.posres.pos0B[XX], iparams.posres.pos0B[YY], iparams.posres.pos0B[ZZ],
212 iparams.posres.fcB[XX], iparams.posres.fcB[YY], iparams.posres.fcB[ZZ]);
215 writer->writeLineFormatted(
216 "pos0=(%15.8e,%15.8e,%15.8e), geometry=%d, r=%15.8e, k=%15.8e",
217 iparams.fbposres.pos0[XX], iparams.fbposres.pos0[YY], iparams.fbposres.pos0[ZZ],
218 iparams.fbposres.geom, iparams.fbposres.r, iparams.fbposres.k);
221 for (int i = 0; i < NR_RBDIHS; i++)
223 writer->writeStringFormatted("%srbcA[%d]=%15.8e", i == 0 ? "" : ", ", i,
224 iparams.rbdihs.rbcA[i]);
226 writer->ensureLineBreak();
227 for (int i = 0; i < NR_RBDIHS; i++)
229 writer->writeStringFormatted("%srbcB[%d]=%15.8e", i == 0 ? "" : ", ", i,
230 iparams.rbdihs.rbcB[i]);
232 writer->ensureLineBreak();
236 /* Use the OPLS -> Ryckaert-Bellemans formula backwards to get
237 * the OPLS potential constants back.
239 const real* rbcA = iparams.rbdihs.rbcA;
240 const real* rbcB = iparams.rbdihs.rbcB;
243 VA[3] = -0.25 * rbcA[4];
244 VA[2] = -0.5 * rbcA[3];
245 VA[1] = 4.0 * VA[3] - rbcA[2];
246 VA[0] = 3.0 * VA[2] - 2.0 * rbcA[1];
248 VB[3] = -0.25 * rbcB[4];
249 VB[2] = -0.5 * rbcB[3];
250 VB[1] = 4.0 * VB[3] - rbcB[2];
251 VB[0] = 3.0 * VB[2] - 2.0 * rbcB[1];
253 for (int i = 0; i < NR_FOURDIHS; i++)
255 writer->writeStringFormatted("%sFourA[%d]=%15.8e", i == 0 ? "" : ", ", i, VA[i]);
257 writer->ensureLineBreak();
258 for (int i = 0; i < NR_FOURDIHS; i++)
260 writer->writeStringFormatted("%sFourB[%d]=%15.8e", i == 0 ? "" : ", ", i, VB[i]);
262 writer->ensureLineBreak();
268 writer->writeLineFormatted("dA=%15.8e, dB=%15.8e", iparams.constr.dA, iparams.constr.dB);
271 writer->writeLineFormatted("doh=%15.8e, dhh=%15.8e", iparams.settle.doh, iparams.settle.dhh);
273 case F_VSITE2: writer->writeLineFormatted("a=%15.8e", iparams.vsite.a); break;
277 writer->writeLineFormatted("a=%15.8e, b=%15.8e", iparams.vsite.a, iparams.vsite.b);
282 writer->writeLineFormatted("a=%15.8e, b=%15.8e, c=%15.8e", iparams.vsite.a,
283 iparams.vsite.b, iparams.vsite.c);
286 writer->writeLineFormatted("n=%2d, a=%15.8e", iparams.vsiten.n, iparams.vsiten.a);
288 case F_GB12_NOLONGERUSED:
289 case F_GB13_NOLONGERUSED:
290 case F_GB14_NOLONGERUSED:
291 // These could only be generated by grompp, not written in
292 // a .top file. Now that implicit solvent is not
293 // supported, they can't be generated, and the values are
294 // ignored if read from an old .tpr file. So there is
298 writer->writeLineFormatted("cmapA=%1d, cmapB=%1d", iparams.cmap.cmapA, iparams.cmap.cmapB);
300 case F_RESTRANGLES: printHarmonicInteraction(writer, iparams, "ktheta", "costheta0"); break;
302 writer->writeLineFormatted("phiA=%15.8e, cpA=%15.8e", iparams.pdihs.phiA, iparams.pdihs.cpA);
305 writer->writeLineFormatted("kphi=%15.8e", iparams.cbtdihs.cbtcA[0]);
306 for (int i = 1; i < NR_CBTDIHS; i++)
308 writer->writeStringFormatted(", cbtcA[%d]=%15.8e", i - 1, iparams.cbtdihs.cbtcA[i]);
310 writer->ensureLineBreak();
313 gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d", ftype,
314 interaction_function[ftype].name, __FILE__, __LINE__);
319 static void printIlist(FILE* fp,
322 const t_functype* functype,
324 gmx_bool bShowNumbers,
325 gmx_bool bShowParameters,
326 const t_iparams* iparams)
328 int i, j, k, type, ftype;
330 indent = pr_title(fp, indent, title);
331 pr_indent(fp, indent);
332 fprintf(fp, "nr: %d\n", ilist.size());
333 if (ilist.size() > 0)
335 pr_indent(fp, indent);
336 fprintf(fp, "iatoms:\n");
337 for (i = j = 0; i < ilist.size();)
339 pr_indent(fp, indent + INDENT);
340 type = ilist.iatoms[i];
341 ftype = functype[type];
344 fprintf(fp, "%d type=%d ", j, type);
347 printf("(%s)", interaction_function[ftype].name);
348 for (k = 0; k < interaction_function[ftype].nratoms; k++)
350 fprintf(fp, " %3d", ilist.iatoms[i + 1 + k]);
355 pr_iparams(fp, ftype, iparams[type]);
358 i += 1 + interaction_function[ftype].nratoms;
363 void pr_ilist(FILE* fp,
366 const t_functype* functype,
367 const InteractionList& ilist,
368 gmx_bool bShowNumbers,
369 gmx_bool bShowParameters,
370 const t_iparams* iparams)
372 printIlist(fp, indent, title, functype, ilist, bShowNumbers, bShowParameters, iparams);
375 void pr_idef(FILE* fp, int indent, const char* title, const t_idef* idef, gmx_bool bShowNumbers, gmx_bool bShowParameters)
379 if (available(fp, idef, indent, title))
381 indent = pr_title(fp, indent, title);
382 pr_indent(fp, indent);
383 fprintf(fp, "atnr=%d\n", idef->atnr);
384 pr_indent(fp, indent);
385 fprintf(fp, "ntypes=%d\n", idef->ntypes);
386 for (i = 0; i < idef->ntypes; i++)
388 pr_indent(fp, indent + INDENT);
389 fprintf(fp, "functype[%d]=%s, ", bShowNumbers ? i : -1,
390 interaction_function[idef->functype[i]].name);
391 pr_iparams(fp, idef->functype[i], idef->iparams[i]);
393 pr_real(fp, indent, "fudgeQQ", idef->fudgeQQ);
395 for (j = 0; (j < F_NRE); j++)
397 printIlist(fp, indent, interaction_function[j].longname, idef->functype, idef->il[j],
398 bShowNumbers, bShowParameters, idef->iparams);
403 void init_idef(t_idef* idef)
407 idef->functype = nullptr;
408 idef->iparams = nullptr;
410 idef->iparams_posres = nullptr;
411 idef->iparams_fbposres = nullptr;
412 for (int f = 0; f < F_NRE; ++f)
414 idef->il[f].iatoms = nullptr;
415 idef->il[f].nalloc = 0;
417 idef->il[f].nr_nonperturbed = 0;
419 idef->cmap_grid = nullptr;
420 idef->iparams_posres_nalloc = 0;
421 idef->iparams_fbposres_nalloc = 0;
425 void done_idef(t_idef* idef)
427 sfree(idef->functype);
428 sfree(idef->iparams);
429 sfree(idef->iparams_posres);
430 sfree(idef->iparams_fbposres);
431 for (int f = 0; f < F_NRE; ++f)
433 sfree(idef->il[f].iatoms);
436 delete idef->cmap_grid;
440 void copy_ilist(const t_ilist* src, t_ilist* dst)
443 dst->nr_nonperturbed = src->nr_nonperturbed;
444 dst->nalloc = src->nalloc;
446 snew(dst->iatoms, dst->nr);
447 for (int i = 0; i < dst->nr; ++i)
449 dst->iatoms[i] = src->iatoms[i];