9cf04d86def7e006086eeacc5627dcce29f3a3b7
[alexxy/gromacs.git] / src / gromacs / gmxlib / tpxio.c
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2  *
3  *
4  *                This source code is part of
5  *
6  *                 G   R   O   M   A   C   S
7  *
8  *          GROningen MAchine for Chemical Simulations
9  *
10  *                        VERSION 3.2.0
11  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13  * Copyright (c) 2001-2004, The GROMACS development team,
14  * check out http://www.gromacs.org for more information.
15
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * If you want to redistribute modifications, please consider that
22  * scientific software is very special. Version control is crucial -
23  * bugs must be traceable. We will be happy to consider code for
24  * inclusion in the official distribution, but derived work must not
25  * be called official GROMACS. Details are found in the README & COPYING
26  * files - if they are missing, get the official version at www.gromacs.org.
27  *
28  * To help us fund GROMACS development, we humbly ask that you cite
29  * the papers on the package - you can find them in the top README file.
30  *
31  * For more info, check our website at http://www.gromacs.org
32  *
33  * And Hey:
34  * GROningen Mixture of Alchemy and Childrens' Stories
35  */
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 /* This file is completely threadsafe - keep it that way! */
41 #ifdef GMX_THREAD_MPI
42 #include <thread_mpi.h>
43 #endif
44
45
46 #include <ctype.h>
47 #include "sysstuff.h"
48 #include "smalloc.h"
49 #include "string2.h"
50 #include "gmx_fatal.h"
51 #include "macros.h"
52 #include "names.h"
53 #include "symtab.h"
54 #include "futil.h"
55 #include "filenm.h"
56 #include "gmxfio.h"
57 #include "topsort.h"
58 #include "tpxio.h"
59 #include "txtdump.h"
60 #include "confio.h"
61 #include "atomprop.h"
62 #include "copyrite.h"
63 #include "vec.h"
64 #include "mtop_util.h"
65
66 #define TPX_TAG_RELEASE  "release"
67
68 /* This is the tag string which is stored in the tpx file.
69  * Change this if you want to change the tpx format in a feature branch.
70  * This ensures that there will not be different tpx formats around which
71  * can not be distinguished.
72  */
73 static const char *tpx_tag = TPX_TAG_RELEASE;
74
75 /* This number should be increased whenever the file format changes! */
76 static const int tpx_version = 92;
77
78 /* This number should only be increased when you edit the TOPOLOGY section
79  * or the HEADER of the tpx format.
80  * This way we can maintain forward compatibility too for all analysis tools
81  * and/or external programs that only need to know the atom/residue names,
82  * charges, and bond connectivity.
83  *
84  * It first appeared in tpx version 26, when I also moved the inputrecord
85  * to the end of the tpx file, so we can just skip it if we only
86  * want the topology.
87  */
88 static const int tpx_generation = 25;
89
90 /* This number should be the most recent backwards incompatible version
91  * I.e., if this number is 9, we cannot read tpx version 9 with this code.
92  */
93 static const int tpx_incompatible_version = 9;
94
95
96
97 /* Struct used to maintain tpx compatibility when function types are added */
98 typedef struct {
99     int fvnr;  /* file version number in which the function type first appeared */
100     int ftype; /* function type */
101 } t_ftupd;
102
103 /*
104  * The entries should be ordered in:
105  * 1. ascending file version number
106  * 2. ascending function type number
107  */
108 /*static const t_ftupd ftupd[] = {
109    { 20, F_CUBICBONDS        },
110    { 20, F_CONNBONDS         },
111    { 20, F_HARMONIC          },
112    { 20, F_EQM,              },
113    { 22, F_DISRESVIOL        },
114    { 22, F_ORIRES            },
115    { 22, F_ORIRESDEV         },
116    { 26, F_FOURDIHS          },
117    { 26, F_PIDIHS            },
118    { 26, F_DIHRES            },
119    { 26, F_DIHRESVIOL        },
120    { 30, F_CROSS_BOND_BONDS  },
121    { 30, F_CROSS_BOND_ANGLES },
122    { 30, F_UREY_BRADLEY      },
123    { 30, F_POLARIZATION      },
124    { 54, F_DHDL_CON          },
125    };*/
126 /*
127  * The entries should be ordered in:
128  * 1. ascending function type number
129  * 2. ascending file version number
130  */
131 /* question; what is the purpose of the commented code above? */
132 static const t_ftupd ftupd[] = {
133     { 20, F_CUBICBONDS        },
134     { 20, F_CONNBONDS         },
135     { 20, F_HARMONIC          },
136     { 34, F_FENEBONDS         },
137     { 43, F_TABBONDS          },
138     { 43, F_TABBONDSNC        },
139     { 70, F_RESTRBONDS        },
140     { 76, F_LINEAR_ANGLES     },
141     { 30, F_CROSS_BOND_BONDS  },
142     { 30, F_CROSS_BOND_ANGLES },
143     { 30, F_UREY_BRADLEY      },
144     { 34, F_QUARTIC_ANGLES    },
145     { 43, F_TABANGLES         },
146     { 26, F_FOURDIHS          },
147     { 26, F_PIDIHS            },
148     { 43, F_TABDIHS           },
149     { 65, F_CMAP              },
150     { 60, F_GB12              },
151     { 61, F_GB13              },
152     { 61, F_GB14              },
153     { 72, F_GBPOL             },
154     { 72, F_NPSOLVATION       },
155     { 41, F_LJC14_Q           },
156     { 41, F_LJC_PAIRS_NB      },
157     { 32, F_BHAM_LR           },
158     { 32, F_RF_EXCL           },
159     { 32, F_COUL_RECIP        },
160     { 46, F_DPD               },
161     { 30, F_POLARIZATION      },
162     { 36, F_THOLE_POL         },
163     { 80, F_FBPOSRES          },
164     { 22, F_DISRESVIOL        },
165     { 22, F_ORIRES            },
166     { 22, F_ORIRESDEV         },
167     { 26, F_DIHRES            },
168     { 26, F_DIHRESVIOL        },
169     { 49, F_VSITE4FDN         },
170     { 50, F_VSITEN            },
171     { 46, F_COM_PULL          },
172     { 20, F_EQM               },
173     { 46, F_ECONSERVED        },
174     { 69, F_VTEMP_NOLONGERUSED},
175     { 66, F_PDISPCORR         },
176     { 54, F_DVDL_CONSTR       },
177     { 76, F_ANHARM_POL        },
178     { 79, F_DVDL_COUL         },
179     { 79, F_DVDL_VDW,         },
180     { 79, F_DVDL_BONDED,      },
181     { 79, F_DVDL_RESTRAINT    },
182     { 79, F_DVDL_TEMPERATURE  },
183 };
184 #define NFTUPD asize(ftupd)
185
186 /* Needed for backward compatibility */
187 #define MAXNODES 256
188
189 static void _do_section(t_fileio *fio, int key, gmx_bool bRead, const char *src,
190                         int line)
191 {
192     char     buf[STRLEN];
193     gmx_bool bDbg;
194
195     if (gmx_fio_getftp(fio) == efTPA)
196     {
197         if (!bRead)
198         {
199             gmx_fio_write_string(fio, itemstr[key]);
200             bDbg       = gmx_fio_getdebug(fio);
201             gmx_fio_setdebug(fio, FALSE);
202             gmx_fio_write_string(fio, comment_str[key]);
203             gmx_fio_setdebug(fio, bDbg);
204         }
205         else
206         {
207             if (gmx_fio_getdebug(fio))
208             {
209                 fprintf(stderr, "Looking for section %s (%s, %d)",
210                         itemstr[key], src, line);
211             }
212
213             do
214             {
215                 gmx_fio_do_string(fio, buf);
216             }
217             while ((gmx_strcasecmp(buf, itemstr[key]) != 0));
218
219             if (gmx_strcasecmp(buf, itemstr[key]) != 0)
220             {
221                 gmx_fatal(FARGS, "\nCould not find section heading %s", itemstr[key]);
222             }
223             else if (gmx_fio_getdebug(fio))
224             {
225                 fprintf(stderr, " and found it\n");
226             }
227         }
228     }
229 }
230
231 #define do_section(fio, key, bRead) _do_section(fio, key, bRead, __FILE__, __LINE__)
232
233 /**************************************************************
234  *
235  * Now the higer level routines that do io of the structures and arrays
236  *
237  **************************************************************/
238 static void do_pullgrp(t_fileio *fio, t_pullgrp *pgrp, gmx_bool bRead,
239                        int file_version)
240 {
241     gmx_bool bDum = TRUE;
242     int      i;
243
244     gmx_fio_do_int(fio, pgrp->nat);
245     if (bRead)
246     {
247         snew(pgrp->ind, pgrp->nat);
248     }
249     bDum = gmx_fio_ndo_int(fio, pgrp->ind, pgrp->nat);
250     gmx_fio_do_int(fio, pgrp->nweight);
251     if (bRead)
252     {
253         snew(pgrp->weight, pgrp->nweight);
254     }
255     bDum = gmx_fio_ndo_real(fio, pgrp->weight, pgrp->nweight);
256     gmx_fio_do_int(fio, pgrp->pbcatom);
257     gmx_fio_do_rvec(fio, pgrp->vec);
258     gmx_fio_do_rvec(fio, pgrp->init);
259     gmx_fio_do_real(fio, pgrp->rate);
260     gmx_fio_do_real(fio, pgrp->k);
261     if (file_version >= 56)
262     {
263         gmx_fio_do_real(fio, pgrp->kB);
264     }
265     else
266     {
267         pgrp->kB = pgrp->k;
268     }
269 }
270
271 static void do_expandedvals(t_fileio *fio, t_expanded *expand, t_lambda *fepvals, gmx_bool bRead, int file_version)
272 {
273     /* i is used in the ndo_double macro*/
274     int      i;
275     real     fv;
276     gmx_bool bDum = TRUE;
277     real     rdum;
278     int      n_lambda = fepvals->n_lambda;
279
280     /* reset the lambda calculation window */
281     fepvals->lambda_start_n = 0;
282     fepvals->lambda_stop_n  = n_lambda;
283     if (file_version >= 79)
284     {
285         if (n_lambda > 0)
286         {
287             if (bRead)
288             {
289                 snew(expand->init_lambda_weights, n_lambda);
290             }
291             bDum = gmx_fio_ndo_real(fio, expand->init_lambda_weights, n_lambda);
292             gmx_fio_do_gmx_bool(fio, expand->bInit_weights);
293         }
294
295         gmx_fio_do_int(fio, expand->nstexpanded);
296         gmx_fio_do_int(fio, expand->elmcmove);
297         gmx_fio_do_int(fio, expand->elamstats);
298         gmx_fio_do_int(fio, expand->lmc_repeats);
299         gmx_fio_do_int(fio, expand->gibbsdeltalam);
300         gmx_fio_do_int(fio, expand->lmc_forced_nstart);
301         gmx_fio_do_int(fio, expand->lmc_seed);
302         gmx_fio_do_real(fio, expand->mc_temp);
303         gmx_fio_do_int(fio, expand->bSymmetrizedTMatrix);
304         gmx_fio_do_int(fio, expand->nstTij);
305         gmx_fio_do_int(fio, expand->minvarmin);
306         gmx_fio_do_int(fio, expand->c_range);
307         gmx_fio_do_real(fio, expand->wl_scale);
308         gmx_fio_do_real(fio, expand->wl_ratio);
309         gmx_fio_do_real(fio, expand->init_wl_delta);
310         gmx_fio_do_gmx_bool(fio, expand->bWLoneovert);
311         gmx_fio_do_int(fio, expand->elmceq);
312         gmx_fio_do_int(fio, expand->equil_steps);
313         gmx_fio_do_int(fio, expand->equil_samples);
314         gmx_fio_do_int(fio, expand->equil_n_at_lam);
315         gmx_fio_do_real(fio, expand->equil_wl_delta);
316         gmx_fio_do_real(fio, expand->equil_ratio);
317     }
318 }
319
320 static void do_simtempvals(t_fileio *fio, t_simtemp *simtemp, int n_lambda, gmx_bool bRead,
321                            int file_version)
322 {
323     gmx_bool bDum = TRUE;
324
325     if (file_version >= 79)
326     {
327         gmx_fio_do_int(fio, simtemp->eSimTempScale);
328         gmx_fio_do_real(fio, simtemp->simtemp_high);
329         gmx_fio_do_real(fio, simtemp->simtemp_low);
330         if (n_lambda > 0)
331         {
332             if (bRead)
333             {
334                 snew(simtemp->temperatures, n_lambda);
335             }
336             bDum = gmx_fio_ndo_real(fio, simtemp->temperatures, n_lambda);
337         }
338     }
339 }
340
341 static void do_fepvals(t_fileio *fio, t_lambda *fepvals, gmx_bool bRead, int file_version)
342 {
343     /* i is defined in the ndo_double macro; use g to iterate. */
344     int      i, g;
345     real     fv;
346     gmx_bool bDum = TRUE;
347     real     rdum;
348
349     /* free energy values */
350
351     if (file_version >= 79)
352     {
353         gmx_fio_do_int(fio, fepvals->init_fep_state);
354         gmx_fio_do_double(fio, fepvals->init_lambda);
355         gmx_fio_do_double(fio, fepvals->delta_lambda);
356     }
357     else if (file_version >= 59)
358     {
359         gmx_fio_do_double(fio, fepvals->init_lambda);
360         gmx_fio_do_double(fio, fepvals->delta_lambda);
361     }
362     else
363     {
364         gmx_fio_do_real(fio, rdum);
365         fepvals->init_lambda = rdum;
366         gmx_fio_do_real(fio, rdum);
367         fepvals->delta_lambda = rdum;
368     }
369     if (file_version >= 79)
370     {
371         gmx_fio_do_int(fio, fepvals->n_lambda);
372         if (bRead)
373         {
374             snew(fepvals->all_lambda, efptNR);
375         }
376         for (g = 0; g < efptNR; g++)
377         {
378             if (fepvals->n_lambda > 0)
379             {
380                 if (bRead)
381                 {
382                     snew(fepvals->all_lambda[g], fepvals->n_lambda);
383                 }
384                 bDum = gmx_fio_ndo_double(fio, fepvals->all_lambda[g], fepvals->n_lambda);
385                 bDum = gmx_fio_ndo_int(fio, fepvals->separate_dvdl, efptNR);
386             }
387             else if (fepvals->init_lambda >= 0)
388             {
389                 fepvals->separate_dvdl[efptFEP] = TRUE;
390             }
391         }
392     }
393     else if (file_version >= 64)
394     {
395         gmx_fio_do_int(fio, fepvals->n_lambda);
396         if (bRead)
397         {
398             int g;
399
400             snew(fepvals->all_lambda, efptNR);
401             /* still allocate the all_lambda array's contents. */
402             for (g = 0; g < efptNR; g++)
403             {
404                 if (fepvals->n_lambda > 0)
405                 {
406                     snew(fepvals->all_lambda[g], fepvals->n_lambda);
407                 }
408             }
409         }
410         bDum = gmx_fio_ndo_double(fio, fepvals->all_lambda[efptFEP],
411                                   fepvals->n_lambda);
412         if (fepvals->init_lambda >= 0)
413         {
414             int g, h;
415
416             fepvals->separate_dvdl[efptFEP] = TRUE;
417
418             if (bRead)
419             {
420                 /* copy the contents of the efptFEP lambda component to all
421                    the other components */
422                 for (g = 0; g < efptNR; g++)
423                 {
424                     for (h = 0; h < fepvals->n_lambda; h++)
425                     {
426                         if (g != efptFEP)
427                         {
428                             fepvals->all_lambda[g][h] =
429                                 fepvals->all_lambda[efptFEP][h];
430                         }
431                     }
432                 }
433             }
434         }
435     }
436     else
437     {
438         fepvals->n_lambda     = 0;
439         fepvals->all_lambda   = NULL;
440         if (fepvals->init_lambda >= 0)
441         {
442             fepvals->separate_dvdl[efptFEP] = TRUE;
443         }
444     }
445     if (file_version >= 13)
446     {
447         gmx_fio_do_real(fio, fepvals->sc_alpha);
448     }
449     else
450     {
451         fepvals->sc_alpha = 0;
452     }
453     if (file_version >= 38)
454     {
455         gmx_fio_do_int(fio, fepvals->sc_power);
456     }
457     else
458     {
459         fepvals->sc_power = 2;
460     }
461     if (file_version >= 79)
462     {
463         gmx_fio_do_real(fio, fepvals->sc_r_power);
464     }
465     else
466     {
467         fepvals->sc_r_power = 6.0;
468     }
469     if (file_version >= 15)
470     {
471         gmx_fio_do_real(fio, fepvals->sc_sigma);
472     }
473     else
474     {
475         fepvals->sc_sigma = 0.3;
476     }
477     if (bRead)
478     {
479         if (file_version >= 71)
480         {
481             fepvals->sc_sigma_min = fepvals->sc_sigma;
482         }
483         else
484         {
485             fepvals->sc_sigma_min = 0;
486         }
487     }
488     if (file_version >= 79)
489     {
490         gmx_fio_do_int(fio, fepvals->bScCoul);
491     }
492     else
493     {
494         fepvals->bScCoul = TRUE;
495     }
496     if (file_version >= 64)
497     {
498         gmx_fio_do_int(fio, fepvals->nstdhdl);
499     }
500     else
501     {
502         fepvals->nstdhdl = 1;
503     }
504
505     if (file_version >= 73)
506     {
507         gmx_fio_do_int(fio, fepvals->separate_dhdl_file);
508         gmx_fio_do_int(fio, fepvals->dhdl_derivatives);
509     }
510     else
511     {
512         fepvals->separate_dhdl_file = esepdhdlfileYES;
513         fepvals->dhdl_derivatives   = edhdlderivativesYES;
514     }
515     if (file_version >= 71)
516     {
517         gmx_fio_do_int(fio, fepvals->dh_hist_size);
518         gmx_fio_do_double(fio, fepvals->dh_hist_spacing);
519     }
520     else
521     {
522         fepvals->dh_hist_size    = 0;
523         fepvals->dh_hist_spacing = 0.1;
524     }
525     if (file_version >= 79)
526     {
527         gmx_fio_do_int(fio, fepvals->bPrintEnergy);
528     }
529     else
530     {
531         fepvals->bPrintEnergy = FALSE;
532     }
533
534     /* handle lambda_neighbors */
535     if ((file_version >= 83 && file_version < 90) || file_version >= 92)
536     {
537         gmx_fio_do_int(fio, fepvals->lambda_neighbors);
538         if ( (fepvals->lambda_neighbors >= 0) && (fepvals->init_fep_state >= 0) &&
539              (fepvals->init_lambda < 0) )
540         {
541             fepvals->lambda_start_n = (fepvals->init_fep_state -
542                                        fepvals->lambda_neighbors);
543             fepvals->lambda_stop_n = (fepvals->init_fep_state +
544                                       fepvals->lambda_neighbors + 1);
545             if (fepvals->lambda_start_n < 0)
546             {
547                 fepvals->lambda_start_n = 0;;
548             }
549             if (fepvals->lambda_stop_n >= fepvals->n_lambda)
550             {
551                 fepvals->lambda_stop_n = fepvals->n_lambda;
552             }
553         }
554         else
555         {
556             fepvals->lambda_start_n = 0;
557             fepvals->lambda_stop_n  = fepvals->n_lambda;
558         }
559     }
560     else
561     {
562         fepvals->lambda_start_n = 0;
563         fepvals->lambda_stop_n  = fepvals->n_lambda;
564     }
565 }
566
567 static void do_pull(t_fileio *fio, t_pull *pull, gmx_bool bRead, int file_version)
568 {
569     int g;
570
571     gmx_fio_do_int(fio, pull->ngrp);
572     gmx_fio_do_int(fio, pull->eGeom);
573     gmx_fio_do_ivec(fio, pull->dim);
574     gmx_fio_do_real(fio, pull->cyl_r1);
575     gmx_fio_do_real(fio, pull->cyl_r0);
576     gmx_fio_do_real(fio, pull->constr_tol);
577     gmx_fio_do_int(fio, pull->nstxout);
578     gmx_fio_do_int(fio, pull->nstfout);
579     if (bRead)
580     {
581         snew(pull->grp, pull->ngrp+1);
582     }
583     for (g = 0; g < pull->ngrp+1; g++)
584     {
585         do_pullgrp(fio, &pull->grp[g], bRead, file_version);
586     }
587 }
588
589
590 static void do_rotgrp(t_fileio *fio, t_rotgrp *rotg, gmx_bool bRead, int file_version)
591 {
592     gmx_bool bDum = TRUE;
593     int      i;
594
595     gmx_fio_do_int(fio, rotg->eType);
596     gmx_fio_do_int(fio, rotg->bMassW);
597     gmx_fio_do_int(fio, rotg->nat);
598     if (bRead)
599     {
600         snew(rotg->ind, rotg->nat);
601     }
602     gmx_fio_ndo_int(fio, rotg->ind, rotg->nat);
603     if (bRead)
604     {
605         snew(rotg->x_ref, rotg->nat);
606     }
607     gmx_fio_ndo_rvec(fio, rotg->x_ref, rotg->nat);
608     gmx_fio_do_rvec(fio, rotg->vec);
609     gmx_fio_do_rvec(fio, rotg->pivot);
610     gmx_fio_do_real(fio, rotg->rate);
611     gmx_fio_do_real(fio, rotg->k);
612     gmx_fio_do_real(fio, rotg->slab_dist);
613     gmx_fio_do_real(fio, rotg->min_gaussian);
614     gmx_fio_do_real(fio, rotg->eps);
615     gmx_fio_do_int(fio, rotg->eFittype);
616     gmx_fio_do_int(fio, rotg->PotAngle_nstep);
617     gmx_fio_do_real(fio, rotg->PotAngle_step);
618 }
619
620 static void do_rot(t_fileio *fio, t_rot *rot, gmx_bool bRead, int file_version)
621 {
622     int g;
623
624     gmx_fio_do_int(fio, rot->ngrp);
625     gmx_fio_do_int(fio, rot->nstrout);
626     gmx_fio_do_int(fio, rot->nstsout);
627     if (bRead)
628     {
629         snew(rot->grp, rot->ngrp);
630     }
631     for (g = 0; g < rot->ngrp; g++)
632     {
633         do_rotgrp(fio, &rot->grp[g], bRead, file_version);
634     }
635 }
636
637
638 static void do_inputrec(t_fileio *fio, t_inputrec *ir, gmx_bool bRead,
639                         int file_version, real *fudgeQQ)
640 {
641     int      i, j, k, *tmp, idum = 0;
642     gmx_bool bDum = TRUE;
643     real     rdum, bd_temp;
644     rvec     vdum;
645     gmx_bool bSimAnn;
646     real     zerotemptime, finish_t, init_temp, finish_temp;
647
648     if (file_version != tpx_version)
649     {
650         /* Give a warning about features that are not accessible */
651         fprintf(stderr, "Note: file tpx version %d, software tpx version %d\n",
652                 file_version, tpx_version);
653     }
654
655     if (bRead)
656     {
657         init_inputrec(ir);
658     }
659
660     if (file_version == 0)
661     {
662         return;
663     }
664
665     /* Basic inputrec stuff */
666     gmx_fio_do_int(fio, ir->eI);
667     if (file_version >= 62)
668     {
669         gmx_fio_do_gmx_large_int(fio, ir->nsteps);
670     }
671     else
672     {
673         gmx_fio_do_int(fio, idum);
674         ir->nsteps = idum;
675     }
676     if (file_version > 25)
677     {
678         if (file_version >= 62)
679         {
680             gmx_fio_do_gmx_large_int(fio, ir->init_step);
681         }
682         else
683         {
684             gmx_fio_do_int(fio, idum);
685             ir->init_step = idum;
686         }
687     }
688     else
689     {
690         ir->init_step = 0;
691     }
692
693     if (file_version >= 58)
694     {
695         gmx_fio_do_int(fio, ir->simulation_part);
696     }
697     else
698     {
699         ir->simulation_part = 1;
700     }
701
702     if (file_version >= 67)
703     {
704         gmx_fio_do_int(fio, ir->nstcalcenergy);
705     }
706     else
707     {
708         ir->nstcalcenergy = 1;
709     }
710     if (file_version < 53)
711     {
712         /* The pbc info has been moved out of do_inputrec,
713          * since we always want it, also without reading the inputrec.
714          */
715         gmx_fio_do_int(fio, ir->ePBC);
716         if ((file_version <= 15) && (ir->ePBC == 2))
717         {
718             ir->ePBC = epbcNONE;
719         }
720         if (file_version >= 45)
721         {
722             gmx_fio_do_int(fio, ir->bPeriodicMols);
723         }
724         else
725         {
726             if (ir->ePBC == 2)
727             {
728                 ir->ePBC          = epbcXYZ;
729                 ir->bPeriodicMols = TRUE;
730             }
731             else
732             {
733                 ir->bPeriodicMols = FALSE;
734             }
735         }
736     }
737     if (file_version >= 81)
738     {
739         gmx_fio_do_int(fio, ir->cutoff_scheme);
740     }
741     else
742     {
743         ir->cutoff_scheme = ecutsGROUP;
744     }
745     gmx_fio_do_int(fio, ir->ns_type);
746     gmx_fio_do_int(fio, ir->nstlist);
747     gmx_fio_do_int(fio, ir->ndelta);
748     if (file_version < 41)
749     {
750         gmx_fio_do_int(fio, idum);
751         gmx_fio_do_int(fio, idum);
752     }
753     if (file_version >= 45)
754     {
755         gmx_fio_do_real(fio, ir->rtpi);
756     }
757     else
758     {
759         ir->rtpi = 0.05;
760     }
761     gmx_fio_do_int(fio, ir->nstcomm);
762     if (file_version > 34)
763     {
764         gmx_fio_do_int(fio, ir->comm_mode);
765     }
766     else if (ir->nstcomm < 0)
767     {
768         ir->comm_mode = ecmANGULAR;
769     }
770     else
771     {
772         ir->comm_mode = ecmLINEAR;
773     }
774     ir->nstcomm = abs(ir->nstcomm);
775
776     if (file_version > 25)
777     {
778         gmx_fio_do_int(fio, ir->nstcheckpoint);
779     }
780     else
781     {
782         ir->nstcheckpoint = 0;
783     }
784
785     gmx_fio_do_int(fio, ir->nstcgsteep);
786
787     if (file_version >= 30)
788     {
789         gmx_fio_do_int(fio, ir->nbfgscorr);
790     }
791     else if (bRead)
792     {
793         ir->nbfgscorr = 10;
794     }
795
796     gmx_fio_do_int(fio, ir->nstlog);
797     gmx_fio_do_int(fio, ir->nstxout);
798     gmx_fio_do_int(fio, ir->nstvout);
799     gmx_fio_do_int(fio, ir->nstfout);
800     gmx_fio_do_int(fio, ir->nstenergy);
801     gmx_fio_do_int(fio, ir->nstxtcout);
802     if (file_version >= 59)
803     {
804         gmx_fio_do_double(fio, ir->init_t);
805         gmx_fio_do_double(fio, ir->delta_t);
806     }
807     else
808     {
809         gmx_fio_do_real(fio, rdum);
810         ir->init_t = rdum;
811         gmx_fio_do_real(fio, rdum);
812         ir->delta_t = rdum;
813     }
814     gmx_fio_do_real(fio, ir->xtcprec);
815     if (file_version < 19)
816     {
817         gmx_fio_do_int(fio, idum);
818         gmx_fio_do_int(fio, idum);
819     }
820     if (file_version < 18)
821     {
822         gmx_fio_do_int(fio, idum);
823     }
824     if (file_version >= 81)
825     {
826         gmx_fio_do_real(fio, ir->verletbuf_drift);
827     }
828     else
829     {
830         ir->verletbuf_drift = 0;
831     }
832     gmx_fio_do_real(fio, ir->rlist);
833     if (file_version >= 67)
834     {
835         gmx_fio_do_real(fio, ir->rlistlong);
836     }
837     if (file_version >= 82 && file_version != 90)
838     {
839         gmx_fio_do_int(fio, ir->nstcalclr);
840     }
841     else
842     {
843         /* Calculate at NS steps */
844         ir->nstcalclr = ir->nstlist;
845     }
846     gmx_fio_do_int(fio, ir->coulombtype);
847     if (file_version < 32 && ir->coulombtype == eelRF)
848     {
849         ir->coulombtype = eelRF_NEC;
850     }
851     if (file_version >= 81)
852     {
853         gmx_fio_do_int(fio, ir->coulomb_modifier);
854     }
855     else
856     {
857         ir->coulomb_modifier = (ir->cutoff_scheme == ecutsVERLET ? eintmodPOTSHIFT : eintmodNONE);
858     }
859     gmx_fio_do_real(fio, ir->rcoulomb_switch);
860     gmx_fio_do_real(fio, ir->rcoulomb);
861     gmx_fio_do_int(fio, ir->vdwtype);
862     if (file_version >= 81)
863     {
864         gmx_fio_do_int(fio, ir->vdw_modifier);
865     }
866     else
867     {
868         ir->vdw_modifier = (ir->cutoff_scheme == ecutsVERLET ? eintmodPOTSHIFT : eintmodNONE);
869     }
870     gmx_fio_do_real(fio, ir->rvdw_switch);
871     gmx_fio_do_real(fio, ir->rvdw);
872     if (file_version < 67)
873     {
874         ir->rlistlong = max_cutoff(ir->rlist, max_cutoff(ir->rvdw, ir->rcoulomb));
875     }
876     gmx_fio_do_int(fio, ir->eDispCorr);
877     gmx_fio_do_real(fio, ir->epsilon_r);
878     if (file_version >= 37)
879     {
880         gmx_fio_do_real(fio, ir->epsilon_rf);
881     }
882     else
883     {
884         if (EEL_RF(ir->coulombtype))
885         {
886             ir->epsilon_rf = ir->epsilon_r;
887             ir->epsilon_r  = 1.0;
888         }
889         else
890         {
891             ir->epsilon_rf = 1.0;
892         }
893     }
894     if (file_version >= 29)
895     {
896         gmx_fio_do_real(fio, ir->tabext);
897     }
898     else
899     {
900         ir->tabext = 1.0;
901     }
902
903     if (file_version > 25)
904     {
905         gmx_fio_do_int(fio, ir->gb_algorithm);
906         gmx_fio_do_int(fio, ir->nstgbradii);
907         gmx_fio_do_real(fio, ir->rgbradii);
908         gmx_fio_do_real(fio, ir->gb_saltconc);
909         gmx_fio_do_int(fio, ir->implicit_solvent);
910     }
911     else
912     {
913         ir->gb_algorithm     = egbSTILL;
914         ir->nstgbradii       = 1;
915         ir->rgbradii         = 1.0;
916         ir->gb_saltconc      = 0;
917         ir->implicit_solvent = eisNO;
918     }
919     if (file_version >= 55)
920     {
921         gmx_fio_do_real(fio, ir->gb_epsilon_solvent);
922         gmx_fio_do_real(fio, ir->gb_obc_alpha);
923         gmx_fio_do_real(fio, ir->gb_obc_beta);
924         gmx_fio_do_real(fio, ir->gb_obc_gamma);
925         if (file_version >= 60)
926         {
927             gmx_fio_do_real(fio, ir->gb_dielectric_offset);
928             gmx_fio_do_int(fio, ir->sa_algorithm);
929         }
930         else
931         {
932             ir->gb_dielectric_offset = 0.009;
933             ir->sa_algorithm         = esaAPPROX;
934         }
935         gmx_fio_do_real(fio, ir->sa_surface_tension);
936
937         /* Override sa_surface_tension if it is not changed in the mpd-file */
938         if (ir->sa_surface_tension < 0)
939         {
940             if (ir->gb_algorithm == egbSTILL)
941             {
942                 ir->sa_surface_tension = 0.0049 * 100 * CAL2JOULE;
943             }
944             else if (ir->gb_algorithm == egbHCT || ir->gb_algorithm == egbOBC)
945             {
946                 ir->sa_surface_tension = 0.0054 * 100 * CAL2JOULE;
947             }
948         }
949
950     }
951     else
952     {
953         /* Better use sensible values than insane (0.0) ones... */
954         ir->gb_epsilon_solvent = 80;
955         ir->gb_obc_alpha       = 1.0;
956         ir->gb_obc_beta        = 0.8;
957         ir->gb_obc_gamma       = 4.85;
958         ir->sa_surface_tension = 2.092;
959     }
960
961
962     if (file_version >= 81)
963     {
964         gmx_fio_do_real(fio, ir->fourier_spacing);
965     }
966     else
967     {
968         ir->fourier_spacing = 0.0;
969     }
970     gmx_fio_do_int(fio, ir->nkx);
971     gmx_fio_do_int(fio, ir->nky);
972     gmx_fio_do_int(fio, ir->nkz);
973     gmx_fio_do_int(fio, ir->pme_order);
974     gmx_fio_do_real(fio, ir->ewald_rtol);
975
976     if (file_version >= 24)
977     {
978         gmx_fio_do_int(fio, ir->ewald_geometry);
979     }
980     else
981     {
982         ir->ewald_geometry = eewg3D;
983     }
984
985     if (file_version <= 17)
986     {
987         ir->epsilon_surface = 0;
988         if (file_version == 17)
989         {
990             gmx_fio_do_int(fio, idum);
991         }
992     }
993     else
994     {
995         gmx_fio_do_real(fio, ir->epsilon_surface);
996     }
997
998     gmx_fio_do_gmx_bool(fio, ir->bOptFFT);
999
1000     gmx_fio_do_gmx_bool(fio, ir->bContinuation);
1001     gmx_fio_do_int(fio, ir->etc);
1002     /* before version 18, ir->etc was a gmx_bool (ir->btc),
1003      * but the values 0 and 1 still mean no and
1004      * berendsen temperature coupling, respectively.
1005      */
1006     if (file_version >= 79)
1007     {
1008         gmx_fio_do_gmx_bool(fio, ir->bPrintNHChains);
1009     }
1010     if (file_version >= 71)
1011     {
1012         gmx_fio_do_int(fio, ir->nsttcouple);
1013     }
1014     else
1015     {
1016         ir->nsttcouple = ir->nstcalcenergy;
1017     }
1018     if (file_version <= 15)
1019     {
1020         gmx_fio_do_int(fio, idum);
1021     }
1022     if (file_version <= 17)
1023     {
1024         gmx_fio_do_int(fio, ir->epct);
1025         if (file_version <= 15)
1026         {
1027             if (ir->epct == 5)
1028             {
1029                 ir->epct = epctSURFACETENSION;
1030             }
1031             gmx_fio_do_int(fio, idum);
1032         }
1033         ir->epct -= 1;
1034         /* we have removed the NO alternative at the beginning */
1035         if (ir->epct == -1)
1036         {
1037             ir->epc  = epcNO;
1038             ir->epct = epctISOTROPIC;
1039         }
1040         else
1041         {
1042             ir->epc = epcBERENDSEN;
1043         }
1044     }
1045     else
1046     {
1047         gmx_fio_do_int(fio, ir->epc);
1048         gmx_fio_do_int(fio, ir->epct);
1049     }
1050     if (file_version >= 71)
1051     {
1052         gmx_fio_do_int(fio, ir->nstpcouple);
1053     }
1054     else
1055     {
1056         ir->nstpcouple = ir->nstcalcenergy;
1057     }
1058     gmx_fio_do_real(fio, ir->tau_p);
1059     if (file_version <= 15)
1060     {
1061         gmx_fio_do_rvec(fio, vdum);
1062         clear_mat(ir->ref_p);
1063         for (i = 0; i < DIM; i++)
1064         {
1065             ir->ref_p[i][i] = vdum[i];
1066         }
1067     }
1068     else
1069     {
1070         gmx_fio_do_rvec(fio, ir->ref_p[XX]);
1071         gmx_fio_do_rvec(fio, ir->ref_p[YY]);
1072         gmx_fio_do_rvec(fio, ir->ref_p[ZZ]);
1073     }
1074     if (file_version <= 15)
1075     {
1076         gmx_fio_do_rvec(fio, vdum);
1077         clear_mat(ir->compress);
1078         for (i = 0; i < DIM; i++)
1079         {
1080             ir->compress[i][i] = vdum[i];
1081         }
1082     }
1083     else
1084     {
1085         gmx_fio_do_rvec(fio, ir->compress[XX]);
1086         gmx_fio_do_rvec(fio, ir->compress[YY]);
1087         gmx_fio_do_rvec(fio, ir->compress[ZZ]);
1088     }
1089     if (file_version >= 47)
1090     {
1091         gmx_fio_do_int(fio, ir->refcoord_scaling);
1092         gmx_fio_do_rvec(fio, ir->posres_com);
1093         gmx_fio_do_rvec(fio, ir->posres_comB);
1094     }
1095     else
1096     {
1097         ir->refcoord_scaling = erscNO;
1098         clear_rvec(ir->posres_com);
1099         clear_rvec(ir->posres_comB);
1100     }
1101     if ((file_version > 25) && (file_version < 79))
1102     {
1103         gmx_fio_do_int(fio, ir->andersen_seed);
1104     }
1105     else
1106     {
1107         ir->andersen_seed = 0;
1108     }
1109     if (file_version < 26)
1110     {
1111         gmx_fio_do_gmx_bool(fio, bSimAnn);
1112         gmx_fio_do_real(fio, zerotemptime);
1113     }
1114
1115     if (file_version < 37)
1116     {
1117         gmx_fio_do_real(fio, rdum);
1118     }
1119
1120     gmx_fio_do_real(fio, ir->shake_tol);
1121     if (file_version < 54)
1122     {
1123         gmx_fio_do_real(fio, *fudgeQQ);
1124     }
1125
1126     gmx_fio_do_int(fio, ir->efep);
1127     if (file_version <= 14 && ir->efep != efepNO)
1128     {
1129         ir->efep = efepYES;
1130     }
1131     do_fepvals(fio, ir->fepvals, bRead, file_version);
1132
1133     if (file_version >= 79)
1134     {
1135         gmx_fio_do_gmx_bool(fio, ir->bSimTemp);
1136         if (ir->bSimTemp)
1137         {
1138             ir->bSimTemp = TRUE;
1139         }
1140     }
1141     else
1142     {
1143         ir->bSimTemp = FALSE;
1144     }
1145     if (ir->bSimTemp)
1146     {
1147         do_simtempvals(fio, ir->simtempvals, ir->fepvals->n_lambda, bRead, file_version);
1148     }
1149
1150     if (file_version >= 79)
1151     {
1152         gmx_fio_do_gmx_bool(fio, ir->bExpanded);
1153         if (ir->bExpanded)
1154         {
1155             ir->bExpanded = TRUE;
1156         }
1157         else
1158         {
1159             ir->bExpanded = FALSE;
1160         }
1161     }
1162     if (ir->bExpanded)
1163     {
1164         do_expandedvals(fio, ir->expandedvals, ir->fepvals, bRead, file_version);
1165     }
1166     if (file_version >= 57)
1167     {
1168         gmx_fio_do_int(fio, ir->eDisre);
1169     }
1170     gmx_fio_do_int(fio, ir->eDisreWeighting);
1171     if (file_version < 22)
1172     {
1173         if (ir->eDisreWeighting == 0)
1174         {
1175             ir->eDisreWeighting = edrwEqual;
1176         }
1177         else
1178         {
1179             ir->eDisreWeighting = edrwConservative;
1180         }
1181     }
1182     gmx_fio_do_gmx_bool(fio, ir->bDisreMixed);
1183     gmx_fio_do_real(fio, ir->dr_fc);
1184     gmx_fio_do_real(fio, ir->dr_tau);
1185     gmx_fio_do_int(fio, ir->nstdisreout);
1186     if (file_version >= 22)
1187     {
1188         gmx_fio_do_real(fio, ir->orires_fc);
1189         gmx_fio_do_real(fio, ir->orires_tau);
1190         gmx_fio_do_int(fio, ir->nstorireout);
1191     }
1192     else
1193     {
1194         ir->orires_fc   = 0;
1195         ir->orires_tau  = 0;
1196         ir->nstorireout = 0;
1197     }
1198     if (file_version >= 26 && file_version < 79)
1199     {
1200         gmx_fio_do_real(fio, ir->dihre_fc);
1201         if (file_version < 56)
1202         {
1203             gmx_fio_do_real(fio, rdum);
1204             gmx_fio_do_int(fio, idum);
1205         }
1206     }
1207     else
1208     {
1209         ir->dihre_fc = 0;
1210     }
1211
1212     gmx_fio_do_real(fio, ir->em_stepsize);
1213     gmx_fio_do_real(fio, ir->em_tol);
1214     if (file_version >= 22)
1215     {
1216         gmx_fio_do_gmx_bool(fio, ir->bShakeSOR);
1217     }
1218     else if (bRead)
1219     {
1220         ir->bShakeSOR = TRUE;
1221     }
1222     if (file_version >= 11)
1223     {
1224         gmx_fio_do_int(fio, ir->niter);
1225     }
1226     else if (bRead)
1227     {
1228         ir->niter = 25;
1229         fprintf(stderr, "Note: niter not in run input file, setting it to %d\n",
1230                 ir->niter);
1231     }
1232     if (file_version >= 21)
1233     {
1234         gmx_fio_do_real(fio, ir->fc_stepsize);
1235     }
1236     else
1237     {
1238         ir->fc_stepsize = 0;
1239     }
1240     gmx_fio_do_int(fio, ir->eConstrAlg);
1241     gmx_fio_do_int(fio, ir->nProjOrder);
1242     gmx_fio_do_real(fio, ir->LincsWarnAngle);
1243     if (file_version <= 14)
1244     {
1245         gmx_fio_do_int(fio, idum);
1246     }
1247     if (file_version >= 26)
1248     {
1249         gmx_fio_do_int(fio, ir->nLincsIter);
1250     }
1251     else if (bRead)
1252     {
1253         ir->nLincsIter = 1;
1254         fprintf(stderr, "Note: nLincsIter not in run input file, setting it to %d\n",
1255                 ir->nLincsIter);
1256     }
1257     if (file_version < 33)
1258     {
1259         gmx_fio_do_real(fio, bd_temp);
1260     }
1261     gmx_fio_do_real(fio, ir->bd_fric);
1262     gmx_fio_do_int(fio, ir->ld_seed);
1263     if (file_version >= 33)
1264     {
1265         for (i = 0; i < DIM; i++)
1266         {
1267             gmx_fio_do_rvec(fio, ir->deform[i]);
1268         }
1269     }
1270     else
1271     {
1272         for (i = 0; i < DIM; i++)
1273         {
1274             clear_rvec(ir->deform[i]);
1275         }
1276     }
1277     if (file_version >= 14)
1278     {
1279         gmx_fio_do_real(fio, ir->cos_accel);
1280     }
1281     else if (bRead)
1282     {
1283         ir->cos_accel = 0;
1284     }
1285     gmx_fio_do_int(fio, ir->userint1);
1286     gmx_fio_do_int(fio, ir->userint2);
1287     gmx_fio_do_int(fio, ir->userint3);
1288     gmx_fio_do_int(fio, ir->userint4);
1289     gmx_fio_do_real(fio, ir->userreal1);
1290     gmx_fio_do_real(fio, ir->userreal2);
1291     gmx_fio_do_real(fio, ir->userreal3);
1292     gmx_fio_do_real(fio, ir->userreal4);
1293
1294     /* AdResS stuff */
1295     if (file_version >= 77)
1296     {
1297         gmx_fio_do_gmx_bool(fio, ir->bAdress);
1298         if (ir->bAdress)
1299         {
1300             if (bRead)
1301             {
1302                 snew(ir->adress, 1);
1303             }
1304             gmx_fio_do_int(fio, ir->adress->type);
1305             gmx_fio_do_real(fio, ir->adress->const_wf);
1306             gmx_fio_do_real(fio, ir->adress->ex_width);
1307             gmx_fio_do_real(fio, ir->adress->hy_width);
1308             gmx_fio_do_int(fio, ir->adress->icor);
1309             gmx_fio_do_int(fio, ir->adress->site);
1310             gmx_fio_do_rvec(fio, ir->adress->refs);
1311             gmx_fio_do_int(fio, ir->adress->n_tf_grps);
1312             gmx_fio_do_real(fio, ir->adress->ex_forcecap);
1313             gmx_fio_do_int(fio, ir->adress->n_energy_grps);
1314             gmx_fio_do_int(fio, ir->adress->do_hybridpairs);
1315
1316             if (bRead)
1317             {
1318                 snew(ir->adress->tf_table_index, ir->adress->n_tf_grps);
1319             }
1320             if (ir->adress->n_tf_grps > 0)
1321             {
1322                 bDum = gmx_fio_ndo_int(fio, ir->adress->tf_table_index, ir->adress->n_tf_grps);
1323             }
1324             if (bRead)
1325             {
1326                 snew(ir->adress->group_explicit, ir->adress->n_energy_grps);
1327             }
1328             if (ir->adress->n_energy_grps > 0)
1329             {
1330                 bDum = gmx_fio_ndo_int(fio, ir->adress->group_explicit, ir->adress->n_energy_grps);
1331             }
1332         }
1333     }
1334     else
1335     {
1336         ir->bAdress = FALSE;
1337     }
1338
1339     /* pull stuff */
1340     if (file_version >= 48)
1341     {
1342         gmx_fio_do_int(fio, ir->ePull);
1343         if (ir->ePull != epullNO)
1344         {
1345             if (bRead)
1346             {
1347                 snew(ir->pull, 1);
1348             }
1349             do_pull(fio, ir->pull, bRead, file_version);
1350         }
1351     }
1352     else
1353     {
1354         ir->ePull = epullNO;
1355     }
1356
1357     /* Enforced rotation */
1358     if (file_version >= 74)
1359     {
1360         gmx_fio_do_int(fio, ir->bRot);
1361         if (ir->bRot == TRUE)
1362         {
1363             if (bRead)
1364             {
1365                 snew(ir->rot, 1);
1366             }
1367             do_rot(fio, ir->rot, bRead, file_version);
1368         }
1369     }
1370     else
1371     {
1372         ir->bRot = FALSE;
1373     }
1374
1375     /* grpopts stuff */
1376     gmx_fio_do_int(fio, ir->opts.ngtc);
1377     if (file_version >= 69)
1378     {
1379         gmx_fio_do_int(fio, ir->opts.nhchainlength);
1380     }
1381     else
1382     {
1383         ir->opts.nhchainlength = 1;
1384     }
1385     gmx_fio_do_int(fio, ir->opts.ngacc);
1386     gmx_fio_do_int(fio, ir->opts.ngfrz);
1387     gmx_fio_do_int(fio, ir->opts.ngener);
1388
1389     if (bRead)
1390     {
1391         snew(ir->opts.nrdf,   ir->opts.ngtc);
1392         snew(ir->opts.ref_t,  ir->opts.ngtc);
1393         snew(ir->opts.annealing, ir->opts.ngtc);
1394         snew(ir->opts.anneal_npoints, ir->opts.ngtc);
1395         snew(ir->opts.anneal_time, ir->opts.ngtc);
1396         snew(ir->opts.anneal_temp, ir->opts.ngtc);
1397         snew(ir->opts.tau_t,  ir->opts.ngtc);
1398         snew(ir->opts.nFreeze, ir->opts.ngfrz);
1399         snew(ir->opts.acc,    ir->opts.ngacc);
1400         snew(ir->opts.egp_flags, ir->opts.ngener*ir->opts.ngener);
1401     }
1402     if (ir->opts.ngtc > 0)
1403     {
1404         if (bRead && file_version < 13)
1405         {
1406             snew(tmp, ir->opts.ngtc);
1407             bDum = gmx_fio_ndo_int(fio, tmp, ir->opts.ngtc);
1408             for (i = 0; i < ir->opts.ngtc; i++)
1409             {
1410                 ir->opts.nrdf[i] = tmp[i];
1411             }
1412             sfree(tmp);
1413         }
1414         else
1415         {
1416             bDum = gmx_fio_ndo_real(fio, ir->opts.nrdf, ir->opts.ngtc);
1417         }
1418         bDum = gmx_fio_ndo_real(fio, ir->opts.ref_t, ir->opts.ngtc);
1419         bDum = gmx_fio_ndo_real(fio, ir->opts.tau_t, ir->opts.ngtc);
1420         if (file_version < 33 && ir->eI == eiBD)
1421         {
1422             for (i = 0; i < ir->opts.ngtc; i++)
1423             {
1424                 ir->opts.tau_t[i] = bd_temp;
1425             }
1426         }
1427     }
1428     if (ir->opts.ngfrz > 0)
1429     {
1430         bDum = gmx_fio_ndo_ivec(fio, ir->opts.nFreeze, ir->opts.ngfrz);
1431     }
1432     if (ir->opts.ngacc > 0)
1433     {
1434         gmx_fio_ndo_rvec(fio, ir->opts.acc, ir->opts.ngacc);
1435     }
1436     if (file_version >= 12)
1437     {
1438         bDum = gmx_fio_ndo_int(fio, ir->opts.egp_flags,
1439                                ir->opts.ngener*ir->opts.ngener);
1440     }
1441
1442     if (bRead && file_version < 26)
1443     {
1444         for (i = 0; i < ir->opts.ngtc; i++)
1445         {
1446             if (bSimAnn)
1447             {
1448                 ir->opts.annealing[i]      = eannSINGLE;
1449                 ir->opts.anneal_npoints[i] = 2;
1450                 snew(ir->opts.anneal_time[i], 2);
1451                 snew(ir->opts.anneal_temp[i], 2);
1452                 /* calculate the starting/ending temperatures from reft, zerotemptime, and nsteps */
1453                 finish_t                   = ir->init_t + ir->nsteps * ir->delta_t;
1454                 init_temp                  = ir->opts.ref_t[i]*(1-ir->init_t/zerotemptime);
1455                 finish_temp                = ir->opts.ref_t[i]*(1-finish_t/zerotemptime);
1456                 ir->opts.anneal_time[i][0] = ir->init_t;
1457                 ir->opts.anneal_time[i][1] = finish_t;
1458                 ir->opts.anneal_temp[i][0] = init_temp;
1459                 ir->opts.anneal_temp[i][1] = finish_temp;
1460             }
1461             else
1462             {
1463                 ir->opts.annealing[i]      = eannNO;
1464                 ir->opts.anneal_npoints[i] = 0;
1465             }
1466         }
1467     }
1468     else
1469     {
1470         /* file version 26 or later */
1471         /* First read the lists with annealing and npoints for each group */
1472         bDum = gmx_fio_ndo_int(fio, ir->opts.annealing, ir->opts.ngtc);
1473         bDum = gmx_fio_ndo_int(fio, ir->opts.anneal_npoints, ir->opts.ngtc);
1474         for (j = 0; j < (ir->opts.ngtc); j++)
1475         {
1476             k = ir->opts.anneal_npoints[j];
1477             if (bRead)
1478             {
1479                 snew(ir->opts.anneal_time[j], k);
1480                 snew(ir->opts.anneal_temp[j], k);
1481             }
1482             bDum = gmx_fio_ndo_real(fio, ir->opts.anneal_time[j], k);
1483             bDum = gmx_fio_ndo_real(fio, ir->opts.anneal_temp[j], k);
1484         }
1485     }
1486     /* Walls */
1487     if (file_version >= 45)
1488     {
1489         gmx_fio_do_int(fio, ir->nwall);
1490         gmx_fio_do_int(fio, ir->wall_type);
1491         if (file_version >= 50)
1492         {
1493             gmx_fio_do_real(fio, ir->wall_r_linpot);
1494         }
1495         else
1496         {
1497             ir->wall_r_linpot = -1;
1498         }
1499         gmx_fio_do_int(fio, ir->wall_atomtype[0]);
1500         gmx_fio_do_int(fio, ir->wall_atomtype[1]);
1501         gmx_fio_do_real(fio, ir->wall_density[0]);
1502         gmx_fio_do_real(fio, ir->wall_density[1]);
1503         gmx_fio_do_real(fio, ir->wall_ewald_zfac);
1504     }
1505     else
1506     {
1507         ir->nwall            = 0;
1508         ir->wall_type        = 0;
1509         ir->wall_atomtype[0] = -1;
1510         ir->wall_atomtype[1] = -1;
1511         ir->wall_density[0]  = 0;
1512         ir->wall_density[1]  = 0;
1513         ir->wall_ewald_zfac  = 3;
1514     }
1515     /* Cosine stuff for electric fields */
1516     for (j = 0; (j < DIM); j++)
1517     {
1518         gmx_fio_do_int(fio, ir->ex[j].n);
1519         gmx_fio_do_int(fio, ir->et[j].n);
1520         if (bRead)
1521         {
1522             snew(ir->ex[j].a,  ir->ex[j].n);
1523             snew(ir->ex[j].phi, ir->ex[j].n);
1524             snew(ir->et[j].a,  ir->et[j].n);
1525             snew(ir->et[j].phi, ir->et[j].n);
1526         }
1527         bDum = gmx_fio_ndo_real(fio, ir->ex[j].a,  ir->ex[j].n);
1528         bDum = gmx_fio_ndo_real(fio, ir->ex[j].phi, ir->ex[j].n);
1529         bDum = gmx_fio_ndo_real(fio, ir->et[j].a,  ir->et[j].n);
1530         bDum = gmx_fio_ndo_real(fio, ir->et[j].phi, ir->et[j].n);
1531     }
1532
1533     /* QMMM stuff */
1534     if (file_version >= 39)
1535     {
1536         gmx_fio_do_gmx_bool(fio, ir->bQMMM);
1537         gmx_fio_do_int(fio, ir->QMMMscheme);
1538         gmx_fio_do_real(fio, ir->scalefactor);
1539         gmx_fio_do_int(fio, ir->opts.ngQM);
1540         if (bRead)
1541         {
1542             snew(ir->opts.QMmethod,    ir->opts.ngQM);
1543             snew(ir->opts.QMbasis,     ir->opts.ngQM);
1544             snew(ir->opts.QMcharge,    ir->opts.ngQM);
1545             snew(ir->opts.QMmult,      ir->opts.ngQM);
1546             snew(ir->opts.bSH,         ir->opts.ngQM);
1547             snew(ir->opts.CASorbitals, ir->opts.ngQM);
1548             snew(ir->opts.CASelectrons, ir->opts.ngQM);
1549             snew(ir->opts.SAon,        ir->opts.ngQM);
1550             snew(ir->opts.SAoff,       ir->opts.ngQM);
1551             snew(ir->opts.SAsteps,     ir->opts.ngQM);
1552             snew(ir->opts.bOPT,        ir->opts.ngQM);
1553             snew(ir->opts.bTS,         ir->opts.ngQM);
1554         }
1555         if (ir->opts.ngQM > 0)
1556         {
1557             bDum = gmx_fio_ndo_int(fio, ir->opts.QMmethod, ir->opts.ngQM);
1558             bDum = gmx_fio_ndo_int(fio, ir->opts.QMbasis, ir->opts.ngQM);
1559             bDum = gmx_fio_ndo_int(fio, ir->opts.QMcharge, ir->opts.ngQM);
1560             bDum = gmx_fio_ndo_int(fio, ir->opts.QMmult, ir->opts.ngQM);
1561             bDum = gmx_fio_ndo_gmx_bool(fio, ir->opts.bSH, ir->opts.ngQM);
1562             bDum = gmx_fio_ndo_int(fio, ir->opts.CASorbitals, ir->opts.ngQM);
1563             bDum = gmx_fio_ndo_int(fio, ir->opts.CASelectrons, ir->opts.ngQM);
1564             bDum = gmx_fio_ndo_real(fio, ir->opts.SAon, ir->opts.ngQM);
1565             bDum = gmx_fio_ndo_real(fio, ir->opts.SAoff, ir->opts.ngQM);
1566             bDum = gmx_fio_ndo_int(fio, ir->opts.SAsteps, ir->opts.ngQM);
1567             bDum = gmx_fio_ndo_gmx_bool(fio, ir->opts.bOPT, ir->opts.ngQM);
1568             bDum = gmx_fio_ndo_gmx_bool(fio, ir->opts.bTS, ir->opts.ngQM);
1569         }
1570         /* end of QMMM stuff */
1571     }
1572 }
1573
1574
1575 static void do_harm(t_fileio *fio, t_iparams *iparams, gmx_bool bRead)
1576 {
1577     gmx_fio_do_real(fio, iparams->harmonic.rA);
1578     gmx_fio_do_real(fio, iparams->harmonic.krA);
1579     gmx_fio_do_real(fio, iparams->harmonic.rB);
1580     gmx_fio_do_real(fio, iparams->harmonic.krB);
1581 }
1582
1583 void do_iparams(t_fileio *fio, t_functype ftype, t_iparams *iparams,
1584                 gmx_bool bRead, int file_version)
1585 {
1586     int      idum;
1587     gmx_bool bDum;
1588     real     rdum;
1589
1590     if (!bRead)
1591     {
1592         gmx_fio_set_comment(fio, interaction_function[ftype].name);
1593     }
1594     switch (ftype)
1595     {
1596         case F_ANGLES:
1597         case F_G96ANGLES:
1598         case F_BONDS:
1599         case F_G96BONDS:
1600         case F_HARMONIC:
1601         case F_IDIHS:
1602             do_harm(fio, iparams, bRead);
1603             if ((ftype == F_ANGRES || ftype == F_ANGRESZ) && bRead)
1604             {
1605                 /* Correct incorrect storage of parameters */
1606                 iparams->pdihs.phiB = iparams->pdihs.phiA;
1607                 iparams->pdihs.cpB  = iparams->pdihs.cpA;
1608             }
1609             break;
1610         case F_LINEAR_ANGLES:
1611             gmx_fio_do_real(fio, iparams->linangle.klinA);
1612             gmx_fio_do_real(fio, iparams->linangle.aA);
1613             gmx_fio_do_real(fio, iparams->linangle.klinB);
1614             gmx_fio_do_real(fio, iparams->linangle.aB);
1615             break;
1616         case F_FENEBONDS:
1617             gmx_fio_do_real(fio, iparams->fene.bm);
1618             gmx_fio_do_real(fio, iparams->fene.kb);
1619             break;
1620         case F_RESTRBONDS:
1621             gmx_fio_do_real(fio, iparams->restraint.lowA);
1622             gmx_fio_do_real(fio, iparams->restraint.up1A);
1623             gmx_fio_do_real(fio, iparams->restraint.up2A);
1624             gmx_fio_do_real(fio, iparams->restraint.kA);
1625             gmx_fio_do_real(fio, iparams->restraint.lowB);
1626             gmx_fio_do_real(fio, iparams->restraint.up1B);
1627             gmx_fio_do_real(fio, iparams->restraint.up2B);
1628             gmx_fio_do_real(fio, iparams->restraint.kB);
1629             break;
1630         case F_TABBONDS:
1631         case F_TABBONDSNC:
1632         case F_TABANGLES:
1633         case F_TABDIHS:
1634             gmx_fio_do_real(fio, iparams->tab.kA);
1635             gmx_fio_do_int(fio, iparams->tab.table);
1636             gmx_fio_do_real(fio, iparams->tab.kB);
1637             break;
1638         case F_CROSS_BOND_BONDS:
1639             gmx_fio_do_real(fio, iparams->cross_bb.r1e);
1640             gmx_fio_do_real(fio, iparams->cross_bb.r2e);
1641             gmx_fio_do_real(fio, iparams->cross_bb.krr);
1642             break;
1643         case F_CROSS_BOND_ANGLES:
1644             gmx_fio_do_real(fio, iparams->cross_ba.r1e);
1645             gmx_fio_do_real(fio, iparams->cross_ba.r2e);
1646             gmx_fio_do_real(fio, iparams->cross_ba.r3e);
1647             gmx_fio_do_real(fio, iparams->cross_ba.krt);
1648             break;
1649         case F_UREY_BRADLEY:
1650             gmx_fio_do_real(fio, iparams->u_b.thetaA);
1651             gmx_fio_do_real(fio, iparams->u_b.kthetaA);
1652             gmx_fio_do_real(fio, iparams->u_b.r13A);
1653             gmx_fio_do_real(fio, iparams->u_b.kUBA);
1654             if (file_version >= 79)
1655             {
1656                 gmx_fio_do_real(fio, iparams->u_b.thetaB);
1657                 gmx_fio_do_real(fio, iparams->u_b.kthetaB);
1658                 gmx_fio_do_real(fio, iparams->u_b.r13B);
1659                 gmx_fio_do_real(fio, iparams->u_b.kUBB);
1660             }
1661             else
1662             {
1663                 iparams->u_b.thetaB  = iparams->u_b.thetaA;
1664                 iparams->u_b.kthetaB = iparams->u_b.kthetaA;
1665                 iparams->u_b.r13B    = iparams->u_b.r13A;
1666                 iparams->u_b.kUBB    = iparams->u_b.kUBA;
1667             }
1668             break;
1669         case F_QUARTIC_ANGLES:
1670             gmx_fio_do_real(fio, iparams->qangle.theta);
1671             bDum = gmx_fio_ndo_real(fio, iparams->qangle.c, 5);
1672             break;
1673         case F_BHAM:
1674             gmx_fio_do_real(fio, iparams->bham.a);
1675             gmx_fio_do_real(fio, iparams->bham.b);
1676             gmx_fio_do_real(fio, iparams->bham.c);
1677             break;
1678         case F_MORSE:
1679             gmx_fio_do_real(fio, iparams->morse.b0A);
1680             gmx_fio_do_real(fio, iparams->morse.cbA);
1681             gmx_fio_do_real(fio, iparams->morse.betaA);
1682             if (file_version >= 79)
1683             {
1684                 gmx_fio_do_real(fio, iparams->morse.b0B);
1685                 gmx_fio_do_real(fio, iparams->morse.cbB);
1686                 gmx_fio_do_real(fio, iparams->morse.betaB);
1687             }
1688             else
1689             {
1690                 iparams->morse.b0B   = iparams->morse.b0A;
1691                 iparams->morse.cbB   = iparams->morse.cbA;
1692                 iparams->morse.betaB = iparams->morse.betaA;
1693             }
1694             break;
1695         case F_CUBICBONDS:
1696             gmx_fio_do_real(fio, iparams->cubic.b0);
1697             gmx_fio_do_real(fio, iparams->cubic.kb);
1698             gmx_fio_do_real(fio, iparams->cubic.kcub);
1699             break;
1700         case F_CONNBONDS:
1701             break;
1702         case F_POLARIZATION:
1703             gmx_fio_do_real(fio, iparams->polarize.alpha);
1704             break;
1705         case F_ANHARM_POL:
1706             gmx_fio_do_real(fio, iparams->anharm_polarize.alpha);
1707             gmx_fio_do_real(fio, iparams->anharm_polarize.drcut);
1708             gmx_fio_do_real(fio, iparams->anharm_polarize.khyp);
1709             break;
1710         case F_WATER_POL:
1711             if (file_version < 31)
1712             {
1713                 gmx_fatal(FARGS, "Old tpr files with water_polarization not supported. Make a new.");
1714             }
1715             gmx_fio_do_real(fio, iparams->wpol.al_x);
1716             gmx_fio_do_real(fio, iparams->wpol.al_y);
1717             gmx_fio_do_real(fio, iparams->wpol.al_z);
1718             gmx_fio_do_real(fio, iparams->wpol.rOH);
1719             gmx_fio_do_real(fio, iparams->wpol.rHH);
1720             gmx_fio_do_real(fio, iparams->wpol.rOD);
1721             break;
1722         case F_THOLE_POL:
1723             gmx_fio_do_real(fio, iparams->thole.a);
1724             gmx_fio_do_real(fio, iparams->thole.alpha1);
1725             gmx_fio_do_real(fio, iparams->thole.alpha2);
1726             gmx_fio_do_real(fio, iparams->thole.rfac);
1727             break;
1728         case F_LJ:
1729             gmx_fio_do_real(fio, iparams->lj.c6);
1730             gmx_fio_do_real(fio, iparams->lj.c12);
1731             break;
1732         case F_LJ14:
1733             gmx_fio_do_real(fio, iparams->lj14.c6A);
1734             gmx_fio_do_real(fio, iparams->lj14.c12A);
1735             gmx_fio_do_real(fio, iparams->lj14.c6B);
1736             gmx_fio_do_real(fio, iparams->lj14.c12B);
1737             break;
1738         case F_LJC14_Q:
1739             gmx_fio_do_real(fio, iparams->ljc14.fqq);
1740             gmx_fio_do_real(fio, iparams->ljc14.qi);
1741             gmx_fio_do_real(fio, iparams->ljc14.qj);
1742             gmx_fio_do_real(fio, iparams->ljc14.c6);
1743             gmx_fio_do_real(fio, iparams->ljc14.c12);
1744             break;
1745         case F_LJC_PAIRS_NB:
1746             gmx_fio_do_real(fio, iparams->ljcnb.qi);
1747             gmx_fio_do_real(fio, iparams->ljcnb.qj);
1748             gmx_fio_do_real(fio, iparams->ljcnb.c6);
1749             gmx_fio_do_real(fio, iparams->ljcnb.c12);
1750             break;
1751         case F_PDIHS:
1752         case F_PIDIHS:
1753         case F_ANGRES:
1754         case F_ANGRESZ:
1755             gmx_fio_do_real(fio, iparams->pdihs.phiA);
1756             gmx_fio_do_real(fio, iparams->pdihs.cpA);
1757             if ((ftype == F_ANGRES || ftype == F_ANGRESZ) && file_version < 42)
1758             {
1759                 /* Read the incorrectly stored multiplicity */
1760                 gmx_fio_do_real(fio, iparams->harmonic.rB);
1761                 gmx_fio_do_real(fio, iparams->harmonic.krB);
1762                 iparams->pdihs.phiB = iparams->pdihs.phiA;
1763                 iparams->pdihs.cpB  = iparams->pdihs.cpA;
1764             }
1765             else
1766             {
1767                 gmx_fio_do_real(fio, iparams->pdihs.phiB);
1768                 gmx_fio_do_real(fio, iparams->pdihs.cpB);
1769                 gmx_fio_do_int(fio, iparams->pdihs.mult);
1770             }
1771             break;
1772         case F_DISRES:
1773             gmx_fio_do_int(fio, iparams->disres.label);
1774             gmx_fio_do_int(fio, iparams->disres.type);
1775             gmx_fio_do_real(fio, iparams->disres.low);
1776             gmx_fio_do_real(fio, iparams->disres.up1);
1777             gmx_fio_do_real(fio, iparams->disres.up2);
1778             gmx_fio_do_real(fio, iparams->disres.kfac);
1779             break;
1780         case F_ORIRES:
1781             gmx_fio_do_int(fio, iparams->orires.ex);
1782             gmx_fio_do_int(fio, iparams->orires.label);
1783             gmx_fio_do_int(fio, iparams->orires.power);
1784             gmx_fio_do_real(fio, iparams->orires.c);
1785             gmx_fio_do_real(fio, iparams->orires.obs);
1786             gmx_fio_do_real(fio, iparams->orires.kfac);
1787             break;
1788         case F_DIHRES:
1789             if (file_version < 72)
1790             {
1791                 gmx_fio_do_int(fio, idum);
1792                 gmx_fio_do_int(fio, idum);
1793             }
1794             gmx_fio_do_real(fio, iparams->dihres.phiA);
1795             gmx_fio_do_real(fio, iparams->dihres.dphiA);
1796             gmx_fio_do_real(fio, iparams->dihres.kfacA);
1797             if (file_version >= 72)
1798             {
1799                 gmx_fio_do_real(fio, iparams->dihres.phiB);
1800                 gmx_fio_do_real(fio, iparams->dihres.dphiB);
1801                 gmx_fio_do_real(fio, iparams->dihres.kfacB);
1802             }
1803             else
1804             {
1805                 iparams->dihres.phiB  = iparams->dihres.phiA;
1806                 iparams->dihres.dphiB = iparams->dihres.dphiA;
1807                 iparams->dihres.kfacB = iparams->dihres.kfacA;
1808             }
1809             break;
1810         case F_POSRES:
1811             gmx_fio_do_rvec(fio, iparams->posres.pos0A);
1812             gmx_fio_do_rvec(fio, iparams->posres.fcA);
1813             if (bRead && file_version < 27)
1814             {
1815                 copy_rvec(iparams->posres.pos0A, iparams->posres.pos0B);
1816                 copy_rvec(iparams->posres.fcA, iparams->posres.fcB);
1817             }
1818             else
1819             {
1820                 gmx_fio_do_rvec(fio, iparams->posres.pos0B);
1821                 gmx_fio_do_rvec(fio, iparams->posres.fcB);
1822             }
1823             break;
1824         case F_FBPOSRES:
1825             gmx_fio_do_int(fio, iparams->fbposres.geom);
1826             gmx_fio_do_rvec(fio, iparams->fbposres.pos0);
1827             gmx_fio_do_real(fio, iparams->fbposres.r);
1828             gmx_fio_do_real(fio, iparams->fbposres.k);
1829             break;
1830         case F_RBDIHS:
1831             bDum = gmx_fio_ndo_real(fio, iparams->rbdihs.rbcA, NR_RBDIHS);
1832             if (file_version >= 25)
1833             {
1834                 bDum = gmx_fio_ndo_real(fio, iparams->rbdihs.rbcB, NR_RBDIHS);
1835             }
1836             break;
1837         case F_FOURDIHS:
1838             /* Fourier dihedrals are internally represented
1839              * as Ryckaert-Bellemans since those are faster to compute.
1840              */
1841             bDum = gmx_fio_ndo_real(fio, iparams->rbdihs.rbcA, NR_RBDIHS);
1842             bDum = gmx_fio_ndo_real(fio, iparams->rbdihs.rbcB, NR_RBDIHS);
1843             break;
1844         case F_CONSTR:
1845         case F_CONSTRNC:
1846             gmx_fio_do_real(fio, iparams->constr.dA);
1847             gmx_fio_do_real(fio, iparams->constr.dB);
1848             break;
1849         case F_SETTLE:
1850             gmx_fio_do_real(fio, iparams->settle.doh);
1851             gmx_fio_do_real(fio, iparams->settle.dhh);
1852             break;
1853         case F_VSITE2:
1854             gmx_fio_do_real(fio, iparams->vsite.a);
1855             break;
1856         case F_VSITE3:
1857         case F_VSITE3FD:
1858         case F_VSITE3FAD:
1859             gmx_fio_do_real(fio, iparams->vsite.a);
1860             gmx_fio_do_real(fio, iparams->vsite.b);
1861             break;
1862         case F_VSITE3OUT:
1863         case F_VSITE4FD:
1864         case F_VSITE4FDN:
1865             gmx_fio_do_real(fio, iparams->vsite.a);
1866             gmx_fio_do_real(fio, iparams->vsite.b);
1867             gmx_fio_do_real(fio, iparams->vsite.c);
1868             break;
1869         case F_VSITEN:
1870             gmx_fio_do_int(fio, iparams->vsiten.n);
1871             gmx_fio_do_real(fio, iparams->vsiten.a);
1872             break;
1873         case F_GB12:
1874         case F_GB13:
1875         case F_GB14:
1876             /* We got rid of some parameters in version 68 */
1877             if (bRead && file_version < 68)
1878             {
1879                 gmx_fio_do_real(fio, rdum);
1880                 gmx_fio_do_real(fio, rdum);
1881                 gmx_fio_do_real(fio, rdum);
1882                 gmx_fio_do_real(fio, rdum);
1883             }
1884             gmx_fio_do_real(fio, iparams->gb.sar);
1885             gmx_fio_do_real(fio, iparams->gb.st);
1886             gmx_fio_do_real(fio, iparams->gb.pi);
1887             gmx_fio_do_real(fio, iparams->gb.gbr);
1888             gmx_fio_do_real(fio, iparams->gb.bmlt);
1889             break;
1890         case F_CMAP:
1891             gmx_fio_do_int(fio, iparams->cmap.cmapA);
1892             gmx_fio_do_int(fio, iparams->cmap.cmapB);
1893             break;
1894         default:
1895             gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d",
1896                       ftype, interaction_function[ftype].name, __FILE__, __LINE__);
1897     }
1898     if (!bRead)
1899     {
1900         gmx_fio_unset_comment(fio);
1901     }
1902 }
1903
1904 static void do_ilist(t_fileio *fio, t_ilist *ilist, gmx_bool bRead, int file_version,
1905                      int ftype)
1906 {
1907     int      i, k, idum;
1908     gmx_bool bDum = TRUE;
1909
1910     if (!bRead)
1911     {
1912         gmx_fio_set_comment(fio, interaction_function[ftype].name);
1913     }
1914     if (file_version < 44)
1915     {
1916         for (i = 0; i < MAXNODES; i++)
1917         {
1918             gmx_fio_do_int(fio, idum);
1919         }
1920     }
1921     gmx_fio_do_int(fio, ilist->nr);
1922     if (bRead)
1923     {
1924         snew(ilist->iatoms, ilist->nr);
1925     }
1926     bDum = gmx_fio_ndo_int(fio, ilist->iatoms, ilist->nr);
1927     if (!bRead)
1928     {
1929         gmx_fio_unset_comment(fio);
1930     }
1931 }
1932
1933 static void do_ffparams(t_fileio *fio, gmx_ffparams_t *ffparams,
1934                         gmx_bool bRead, int file_version)
1935 {
1936     int          idum, i, j;
1937     gmx_bool     bDum = TRUE;
1938     unsigned int k;
1939
1940     gmx_fio_do_int(fio, ffparams->atnr);
1941     if (file_version < 57)
1942     {
1943         gmx_fio_do_int(fio, idum);
1944     }
1945     gmx_fio_do_int(fio, ffparams->ntypes);
1946     if (bRead && debug)
1947     {
1948         fprintf(debug, "ffparams->atnr = %d, ntypes = %d\n",
1949                 ffparams->atnr, ffparams->ntypes);
1950     }
1951     if (bRead)
1952     {
1953         snew(ffparams->functype, ffparams->ntypes);
1954         snew(ffparams->iparams, ffparams->ntypes);
1955     }
1956     /* Read/write all the function types */
1957     bDum = gmx_fio_ndo_int(fio, ffparams->functype, ffparams->ntypes);
1958     if (bRead && debug)
1959     {
1960         pr_ivec(debug, 0, "functype", ffparams->functype, ffparams->ntypes, TRUE);
1961     }
1962
1963     if (file_version >= 66)
1964     {
1965         gmx_fio_do_double(fio, ffparams->reppow);
1966     }
1967     else
1968     {
1969         ffparams->reppow = 12.0;
1970     }
1971
1972     if (file_version >= 57)
1973     {
1974         gmx_fio_do_real(fio, ffparams->fudgeQQ);
1975     }
1976
1977     /* Check whether all these function types are supported by the code.
1978      * In practice the code is backwards compatible, which means that the
1979      * numbering may have to be altered from old numbering to new numbering
1980      */
1981     for (i = 0; (i < ffparams->ntypes); i++)
1982     {
1983         if (bRead)
1984         {
1985             /* Loop over file versions */
1986             for (k = 0; (k < NFTUPD); k++)
1987             {
1988                 /* Compare the read file_version to the update table */
1989                 if ((file_version < ftupd[k].fvnr) &&
1990                     (ffparams->functype[i] >= ftupd[k].ftype))
1991                 {
1992                     ffparams->functype[i] += 1;
1993                     if (debug)
1994                     {
1995                         fprintf(debug, "Incrementing function type %d to %d (due to %s)\n",
1996                                 i, ffparams->functype[i],
1997                                 interaction_function[ftupd[k].ftype].longname);
1998                         fflush(debug);
1999                     }
2000                 }
2001             }
2002         }
2003
2004         do_iparams(fio, ffparams->functype[i], &ffparams->iparams[i], bRead,
2005                    file_version);
2006         if (bRead && debug)
2007         {
2008             pr_iparams(debug, ffparams->functype[i], &ffparams->iparams[i]);
2009         }
2010     }
2011 }
2012
2013 static void add_settle_atoms(t_ilist *ilist)
2014 {
2015     int i;
2016
2017     /* Settle used to only store the first atom: add the other two */
2018     srenew(ilist->iatoms, 2*ilist->nr);
2019     for (i = ilist->nr/2-1; i >= 0; i--)
2020     {
2021         ilist->iatoms[4*i+0] = ilist->iatoms[2*i+0];
2022         ilist->iatoms[4*i+1] = ilist->iatoms[2*i+1];
2023         ilist->iatoms[4*i+2] = ilist->iatoms[2*i+1] + 1;
2024         ilist->iatoms[4*i+3] = ilist->iatoms[2*i+1] + 2;
2025     }
2026     ilist->nr = 2*ilist->nr;
2027 }
2028
2029 static void do_ilists(t_fileio *fio, t_ilist *ilist, gmx_bool bRead,
2030                       int file_version)
2031 {
2032     int          i, j, renum[F_NRE];
2033     gmx_bool     bDum = TRUE, bClear;
2034     unsigned int k;
2035
2036     for (j = 0; (j < F_NRE); j++)
2037     {
2038         bClear = FALSE;
2039         if (bRead)
2040         {
2041             for (k = 0; k < NFTUPD; k++)
2042             {
2043                 if ((file_version < ftupd[k].fvnr) && (j == ftupd[k].ftype))
2044                 {
2045                     bClear = TRUE;
2046                 }
2047             }
2048         }
2049         if (bClear)
2050         {
2051             ilist[j].nr     = 0;
2052             ilist[j].iatoms = NULL;
2053         }
2054         else
2055         {
2056             do_ilist(fio, &ilist[j], bRead, file_version, j);
2057             if (file_version < 78 && j == F_SETTLE && ilist[j].nr > 0)
2058             {
2059                 add_settle_atoms(&ilist[j]);
2060             }
2061         }
2062         /*
2063            if (bRead && gmx_debug_at)
2064            pr_ilist(debug,0,interaction_function[j].longname,
2065                functype,&ilist[j],TRUE);
2066          */
2067     }
2068 }
2069
2070 static void do_idef(t_fileio *fio, gmx_ffparams_t *ffparams, gmx_moltype_t *molt,
2071                     gmx_bool bRead, int file_version)
2072 {
2073     do_ffparams(fio, ffparams, bRead, file_version);
2074
2075     if (file_version >= 54)
2076     {
2077         gmx_fio_do_real(fio, ffparams->fudgeQQ);
2078     }
2079
2080     do_ilists(fio, molt->ilist, bRead, file_version);
2081 }
2082
2083 static void do_block(t_fileio *fio, t_block *block, gmx_bool bRead, int file_version)
2084 {
2085     int      i, idum, dum_nra, *dum_a;
2086     gmx_bool bDum = TRUE;
2087
2088     if (file_version < 44)
2089     {
2090         for (i = 0; i < MAXNODES; i++)
2091         {
2092             gmx_fio_do_int(fio, idum);
2093         }
2094     }
2095     gmx_fio_do_int(fio, block->nr);
2096     if (file_version < 51)
2097     {
2098         gmx_fio_do_int(fio, dum_nra);
2099     }
2100     if (bRead)
2101     {
2102         block->nalloc_index = block->nr+1;
2103         snew(block->index, block->nalloc_index);
2104     }
2105     bDum = gmx_fio_ndo_int(fio, block->index, block->nr+1);
2106
2107     if (file_version < 51 && dum_nra > 0)
2108     {
2109         snew(dum_a, dum_nra);
2110         bDum = gmx_fio_ndo_int(fio, dum_a, dum_nra);
2111         sfree(dum_a);
2112     }
2113 }
2114
2115 static void do_blocka(t_fileio *fio, t_blocka *block, gmx_bool bRead,
2116                       int file_version)
2117 {
2118     int      i, idum;
2119     gmx_bool bDum = TRUE;
2120
2121     if (file_version < 44)
2122     {
2123         for (i = 0; i < MAXNODES; i++)
2124         {
2125             gmx_fio_do_int(fio, idum);
2126         }
2127     }
2128     gmx_fio_do_int(fio, block->nr);
2129     gmx_fio_do_int(fio, block->nra);
2130     if (bRead)
2131     {
2132         block->nalloc_index = block->nr+1;
2133         snew(block->index, block->nalloc_index);
2134         block->nalloc_a = block->nra;
2135         snew(block->a, block->nalloc_a);
2136     }
2137     bDum = gmx_fio_ndo_int(fio, block->index, block->nr+1);
2138     bDum = gmx_fio_ndo_int(fio, block->a, block->nra);
2139 }
2140
2141 static void do_atom(t_fileio *fio, t_atom *atom, int ngrp, gmx_bool bRead,
2142                     int file_version, gmx_groups_t *groups, int atnr)
2143 {
2144     int i, myngrp;
2145
2146     gmx_fio_do_real(fio, atom->m);
2147     gmx_fio_do_real(fio, atom->q);
2148     gmx_fio_do_real(fio, atom->mB);
2149     gmx_fio_do_real(fio, atom->qB);
2150     gmx_fio_do_ushort(fio, atom->type);
2151     gmx_fio_do_ushort(fio, atom->typeB);
2152     gmx_fio_do_int(fio, atom->ptype);
2153     gmx_fio_do_int(fio, atom->resind);
2154     if (file_version >= 52)
2155     {
2156         gmx_fio_do_int(fio, atom->atomnumber);
2157     }
2158     else if (bRead)
2159     {
2160         atom->atomnumber = NOTSET;
2161     }
2162     if (file_version < 23)
2163     {
2164         myngrp = 8;
2165     }
2166     else if (file_version < 39)
2167     {
2168         myngrp = 9;
2169     }
2170     else
2171     {
2172         myngrp = ngrp;
2173     }
2174
2175     if (file_version < 57)
2176     {
2177         unsigned char uchar[egcNR];
2178         gmx_fio_ndo_uchar(fio, uchar, myngrp);
2179         for (i = myngrp; (i < ngrp); i++)
2180         {
2181             uchar[i] = 0;
2182         }
2183         /* Copy the old data format to the groups struct */
2184         for (i = 0; i < ngrp; i++)
2185         {
2186             groups->grpnr[i][atnr] = uchar[i];
2187         }
2188     }
2189 }
2190
2191 static void do_grps(t_fileio *fio, int ngrp, t_grps grps[], gmx_bool bRead,
2192                     int file_version)
2193 {
2194     int      i, j, myngrp;
2195     gmx_bool bDum = TRUE;
2196
2197     if (file_version < 23)
2198     {
2199         myngrp = 8;
2200     }
2201     else if (file_version < 39)
2202     {
2203         myngrp = 9;
2204     }
2205     else
2206     {
2207         myngrp = ngrp;
2208     }
2209
2210     for (j = 0; (j < ngrp); j++)
2211     {
2212         if (j < myngrp)
2213         {
2214             gmx_fio_do_int(fio, grps[j].nr);
2215             if (bRead)
2216             {
2217                 snew(grps[j].nm_ind, grps[j].nr);
2218             }
2219             bDum = gmx_fio_ndo_int(fio, grps[j].nm_ind, grps[j].nr);
2220         }
2221         else
2222         {
2223             grps[j].nr = 1;
2224             snew(grps[j].nm_ind, grps[j].nr);
2225         }
2226     }
2227 }
2228
2229 static void do_symstr(t_fileio *fio, char ***nm, gmx_bool bRead, t_symtab *symtab)
2230 {
2231     int ls;
2232
2233     if (bRead)
2234     {
2235         gmx_fio_do_int(fio, ls);
2236         *nm = get_symtab_handle(symtab, ls);
2237     }
2238     else
2239     {
2240         ls = lookup_symtab(symtab, *nm);
2241         gmx_fio_do_int(fio, ls);
2242     }
2243 }
2244
2245 static void do_strstr(t_fileio *fio, int nstr, char ***nm, gmx_bool bRead,
2246                       t_symtab *symtab)
2247 {
2248     int  j;
2249
2250     for (j = 0; (j < nstr); j++)
2251     {
2252         do_symstr(fio, &(nm[j]), bRead, symtab);
2253     }
2254 }
2255
2256 static void do_resinfo(t_fileio *fio, int n, t_resinfo *ri, gmx_bool bRead,
2257                        t_symtab *symtab, int file_version)
2258 {
2259     int  j;
2260
2261     for (j = 0; (j < n); j++)
2262     {
2263         do_symstr(fio, &(ri[j].name), bRead, symtab);
2264         if (file_version >= 63)
2265         {
2266             gmx_fio_do_int(fio, ri[j].nr);
2267             gmx_fio_do_uchar(fio, ri[j].ic);
2268         }
2269         else
2270         {
2271             ri[j].nr = j + 1;
2272             ri[j].ic = ' ';
2273         }
2274     }
2275 }
2276
2277 static void do_atoms(t_fileio *fio, t_atoms *atoms, gmx_bool bRead, t_symtab *symtab,
2278                      int file_version,
2279                      gmx_groups_t *groups)
2280 {
2281     int i;
2282
2283     gmx_fio_do_int(fio, atoms->nr);
2284     gmx_fio_do_int(fio, atoms->nres);
2285     if (file_version < 57)
2286     {
2287         gmx_fio_do_int(fio, groups->ngrpname);
2288         for (i = 0; i < egcNR; i++)
2289         {
2290             groups->ngrpnr[i] = atoms->nr;
2291             snew(groups->grpnr[i], groups->ngrpnr[i]);
2292         }
2293     }
2294     if (bRead)
2295     {
2296         snew(atoms->atom, atoms->nr);
2297         snew(atoms->atomname, atoms->nr);
2298         snew(atoms->atomtype, atoms->nr);
2299         snew(atoms->atomtypeB, atoms->nr);
2300         snew(atoms->resinfo, atoms->nres);
2301         if (file_version < 57)
2302         {
2303             snew(groups->grpname, groups->ngrpname);
2304         }
2305         atoms->pdbinfo = NULL;
2306     }
2307     for (i = 0; (i < atoms->nr); i++)
2308     {
2309         do_atom(fio, &atoms->atom[i], egcNR, bRead, file_version, groups, i);
2310     }
2311     do_strstr(fio, atoms->nr, atoms->atomname, bRead, symtab);
2312     if (bRead && (file_version <= 20))
2313     {
2314         for (i = 0; i < atoms->nr; i++)
2315         {
2316             atoms->atomtype[i]  = put_symtab(symtab, "?");
2317             atoms->atomtypeB[i] = put_symtab(symtab, "?");
2318         }
2319     }
2320     else
2321     {
2322         do_strstr(fio, atoms->nr, atoms->atomtype, bRead, symtab);
2323         do_strstr(fio, atoms->nr, atoms->atomtypeB, bRead, symtab);
2324     }
2325     do_resinfo(fio, atoms->nres, atoms->resinfo, bRead, symtab, file_version);
2326
2327     if (file_version < 57)
2328     {
2329         do_strstr(fio, groups->ngrpname, groups->grpname, bRead, symtab);
2330
2331         do_grps(fio, egcNR, groups->grps, bRead, file_version);
2332     }
2333 }
2334
2335 static void do_groups(t_fileio *fio, gmx_groups_t *groups,
2336                       gmx_bool bRead, t_symtab *symtab,
2337                       int file_version)
2338 {
2339     int      g, n, i;
2340     gmx_bool bDum = TRUE;
2341
2342     do_grps(fio, egcNR, groups->grps, bRead, file_version);
2343     gmx_fio_do_int(fio, groups->ngrpname);
2344     if (bRead)
2345     {
2346         snew(groups->grpname, groups->ngrpname);
2347     }
2348     do_strstr(fio, groups->ngrpname, groups->grpname, bRead, symtab);
2349     for (g = 0; g < egcNR; g++)
2350     {
2351         gmx_fio_do_int(fio, groups->ngrpnr[g]);
2352         if (groups->ngrpnr[g] == 0)
2353         {
2354             if (bRead)
2355             {
2356                 groups->grpnr[g] = NULL;
2357             }
2358         }
2359         else
2360         {
2361             if (bRead)
2362             {
2363                 snew(groups->grpnr[g], groups->ngrpnr[g]);
2364             }
2365             bDum = gmx_fio_ndo_uchar(fio, groups->grpnr[g], groups->ngrpnr[g]);
2366         }
2367     }
2368 }
2369
2370 static void do_atomtypes(t_fileio *fio, t_atomtypes *atomtypes, gmx_bool bRead,
2371                          t_symtab *symtab, int file_version)
2372 {
2373     int      i, j;
2374     gmx_bool bDum = TRUE;
2375
2376     if (file_version > 25)
2377     {
2378         gmx_fio_do_int(fio, atomtypes->nr);
2379         j = atomtypes->nr;
2380         if (bRead)
2381         {
2382             snew(atomtypes->radius, j);
2383             snew(atomtypes->vol, j);
2384             snew(atomtypes->surftens, j);
2385             snew(atomtypes->atomnumber, j);
2386             snew(atomtypes->gb_radius, j);
2387             snew(atomtypes->S_hct, j);
2388         }
2389         bDum = gmx_fio_ndo_real(fio, atomtypes->radius, j);
2390         bDum = gmx_fio_ndo_real(fio, atomtypes->vol, j);
2391         bDum = gmx_fio_ndo_real(fio, atomtypes->surftens, j);
2392         if (file_version >= 40)
2393         {
2394             bDum = gmx_fio_ndo_int(fio, atomtypes->atomnumber, j);
2395         }
2396         if (file_version >= 60)
2397         {
2398             bDum = gmx_fio_ndo_real(fio, atomtypes->gb_radius, j);
2399             bDum = gmx_fio_ndo_real(fio, atomtypes->S_hct, j);
2400         }
2401     }
2402     else
2403     {
2404         /* File versions prior to 26 cannot do GBSA,
2405          * so they dont use this structure
2406          */
2407         atomtypes->nr         = 0;
2408         atomtypes->radius     = NULL;
2409         atomtypes->vol        = NULL;
2410         atomtypes->surftens   = NULL;
2411         atomtypes->atomnumber = NULL;
2412         atomtypes->gb_radius  = NULL;
2413         atomtypes->S_hct      = NULL;
2414     }
2415 }
2416
2417 static void do_symtab(t_fileio *fio, t_symtab *symtab, gmx_bool bRead)
2418 {
2419     int       i, nr;
2420     t_symbuf *symbuf;
2421     char      buf[STRLEN];
2422
2423     gmx_fio_do_int(fio, symtab->nr);
2424     nr     = symtab->nr;
2425     if (bRead)
2426     {
2427         snew(symtab->symbuf, 1);
2428         symbuf          = symtab->symbuf;
2429         symbuf->bufsize = nr;
2430         snew(symbuf->buf, nr);
2431         for (i = 0; (i < nr); i++)
2432         {
2433             gmx_fio_do_string(fio, buf);
2434             symbuf->buf[i] = strdup(buf);
2435         }
2436     }
2437     else
2438     {
2439         symbuf = symtab->symbuf;
2440         while (symbuf != NULL)
2441         {
2442             for (i = 0; (i < symbuf->bufsize) && (i < nr); i++)
2443             {
2444                 gmx_fio_do_string(fio, symbuf->buf[i]);
2445             }
2446             nr    -= i;
2447             symbuf = symbuf->next;
2448         }
2449         if (nr != 0)
2450         {
2451             gmx_fatal(FARGS, "nr of symtab strings left: %d", nr);
2452         }
2453     }
2454 }
2455
2456 static void do_cmap(t_fileio *fio, gmx_cmap_t *cmap_grid, gmx_bool bRead)
2457 {
2458     int i, j, ngrid, gs, nelem;
2459
2460     gmx_fio_do_int(fio, cmap_grid->ngrid);
2461     gmx_fio_do_int(fio, cmap_grid->grid_spacing);
2462
2463     ngrid = cmap_grid->ngrid;
2464     gs    = cmap_grid->grid_spacing;
2465     nelem = gs * gs;
2466
2467     if (bRead)
2468     {
2469         snew(cmap_grid->cmapdata, ngrid);
2470
2471         for (i = 0; i < cmap_grid->ngrid; i++)
2472         {
2473             snew(cmap_grid->cmapdata[i].cmap, 4*nelem);
2474         }
2475     }
2476
2477     for (i = 0; i < cmap_grid->ngrid; i++)
2478     {
2479         for (j = 0; j < nelem; j++)
2480         {
2481             gmx_fio_do_real(fio, cmap_grid->cmapdata[i].cmap[j*4]);
2482             gmx_fio_do_real(fio, cmap_grid->cmapdata[i].cmap[j*4+1]);
2483             gmx_fio_do_real(fio, cmap_grid->cmapdata[i].cmap[j*4+2]);
2484             gmx_fio_do_real(fio, cmap_grid->cmapdata[i].cmap[j*4+3]);
2485         }
2486     }
2487 }
2488
2489
2490 void tpx_make_chain_identifiers(t_atoms *atoms, t_block *mols)
2491 {
2492     int  m, a, a0, a1, r;
2493     char c, chainid;
2494     int  chainnum;
2495
2496     /* We always assign a new chain number, but save the chain id characters
2497      * for larger molecules.
2498      */
2499 #define CHAIN_MIN_ATOMS 15
2500
2501     chainnum = 0;
2502     chainid  = 'A';
2503     for (m = 0; m < mols->nr; m++)
2504     {
2505         a0 = mols->index[m];
2506         a1 = mols->index[m+1];
2507         if ((a1-a0 >= CHAIN_MIN_ATOMS) && (chainid <= 'Z'))
2508         {
2509             c = chainid;
2510             chainid++;
2511         }
2512         else
2513         {
2514             c = ' ';
2515         }
2516         for (a = a0; a < a1; a++)
2517         {
2518             atoms->resinfo[atoms->atom[a].resind].chainnum = chainnum;
2519             atoms->resinfo[atoms->atom[a].resind].chainid  = c;
2520         }
2521         chainnum++;
2522     }
2523
2524     /* Blank out the chain id if there was only one chain */
2525     if (chainid == 'B')
2526     {
2527         for (r = 0; r < atoms->nres; r++)
2528         {
2529             atoms->resinfo[r].chainid = ' ';
2530         }
2531     }
2532 }
2533
2534 static void do_moltype(t_fileio *fio, gmx_moltype_t *molt, gmx_bool bRead,
2535                        t_symtab *symtab, int file_version,
2536                        gmx_groups_t *groups)
2537 {
2538     int i;
2539
2540     if (file_version >= 57)
2541     {
2542         do_symstr(fio, &(molt->name), bRead, symtab);
2543     }
2544
2545     do_atoms(fio, &molt->atoms, bRead, symtab, file_version, groups);
2546
2547     if (bRead && gmx_debug_at)
2548     {
2549         pr_atoms(debug, 0, "atoms", &molt->atoms, TRUE);
2550     }
2551
2552     if (file_version >= 57)
2553     {
2554         do_ilists(fio, molt->ilist, bRead, file_version);
2555
2556         do_block(fio, &molt->cgs, bRead, file_version);
2557         if (bRead && gmx_debug_at)
2558         {
2559             pr_block(debug, 0, "cgs", &molt->cgs, TRUE);
2560         }
2561     }
2562
2563     /* This used to be in the atoms struct */
2564     do_blocka(fio, &molt->excls, bRead, file_version);
2565 }
2566
2567 static void do_molblock(t_fileio *fio, gmx_molblock_t *molb, gmx_bool bRead,
2568                         int file_version)
2569 {
2570     int i;
2571
2572     gmx_fio_do_int(fio, molb->type);
2573     gmx_fio_do_int(fio, molb->nmol);
2574     gmx_fio_do_int(fio, molb->natoms_mol);
2575     /* Position restraint coordinates */
2576     gmx_fio_do_int(fio, molb->nposres_xA);
2577     if (molb->nposres_xA > 0)
2578     {
2579         if (bRead)
2580         {
2581             snew(molb->posres_xA, molb->nposres_xA);
2582         }
2583         gmx_fio_ndo_rvec(fio, molb->posres_xA, molb->nposres_xA);
2584     }
2585     gmx_fio_do_int(fio, molb->nposres_xB);
2586     if (molb->nposres_xB > 0)
2587     {
2588         if (bRead)
2589         {
2590             snew(molb->posres_xB, molb->nposres_xB);
2591         }
2592         gmx_fio_ndo_rvec(fio, molb->posres_xB, molb->nposres_xB);
2593     }
2594
2595 }
2596
2597 static t_block mtop_mols(gmx_mtop_t *mtop)
2598 {
2599     int     mb, m, a, mol;
2600     t_block mols;
2601
2602     mols.nr = 0;
2603     for (mb = 0; mb < mtop->nmolblock; mb++)
2604     {
2605         mols.nr += mtop->molblock[mb].nmol;
2606     }
2607     mols.nalloc_index = mols.nr + 1;
2608     snew(mols.index, mols.nalloc_index);
2609
2610     a             = 0;
2611     m             = 0;
2612     mols.index[m] = a;
2613     for (mb = 0; mb < mtop->nmolblock; mb++)
2614     {
2615         for (mol = 0; mol < mtop->molblock[mb].nmol; mol++)
2616         {
2617             a += mtop->molblock[mb].natoms_mol;
2618             m++;
2619             mols.index[m] = a;
2620         }
2621     }
2622
2623     return mols;
2624 }
2625
2626 static void add_posres_molblock(gmx_mtop_t *mtop)
2627 {
2628     t_ilist        *il, *ilfb;
2629     int             am, i, mol, a;
2630     gmx_bool        bFE;
2631     gmx_molblock_t *molb;
2632     t_iparams      *ip;
2633
2634     /* posres reference positions are stored in ip->posres (if present) and
2635        in ip->fbposres (if present). If normal and flat-bottomed posres are present,
2636        posres.pos0A are identical to fbposres.pos0. */
2637     il   = &mtop->moltype[0].ilist[F_POSRES];
2638     ilfb = &mtop->moltype[0].ilist[F_FBPOSRES];
2639     if (il->nr == 0 && ilfb->nr == 0)
2640     {
2641         return;
2642     }
2643     am  = 0;
2644     bFE = FALSE;
2645     for (i = 0; i < il->nr; i += 2)
2646     {
2647         ip = &mtop->ffparams.iparams[il->iatoms[i]];
2648         am = max(am, il->iatoms[i+1]);
2649         if (ip->posres.pos0B[XX] != ip->posres.pos0A[XX] ||
2650             ip->posres.pos0B[YY] != ip->posres.pos0A[YY] ||
2651             ip->posres.pos0B[ZZ] != ip->posres.pos0A[ZZ])
2652         {
2653             bFE = TRUE;
2654         }
2655     }
2656     /* This loop is required if we have only flat-bottomed posres:
2657        - set am
2658        - bFE == FALSE (no B-state for flat-bottomed posres) */
2659     if (il->nr == 0)
2660     {
2661         for (i = 0; i < ilfb->nr; i += 2)
2662         {
2663             ip = &mtop->ffparams.iparams[ilfb->iatoms[i]];
2664             am = max(am, ilfb->iatoms[i+1]);
2665         }
2666     }
2667     /* Make the posres coordinate block end at a molecule end */
2668     mol = 0;
2669     while (am >= mtop->mols.index[mol+1])
2670     {
2671         mol++;
2672     }
2673     molb             = &mtop->molblock[0];
2674     molb->nposres_xA = mtop->mols.index[mol+1];
2675     snew(molb->posres_xA, molb->nposres_xA);
2676     if (bFE)
2677     {
2678         molb->nposres_xB = molb->nposres_xA;
2679         snew(molb->posres_xB, molb->nposres_xB);
2680     }
2681     else
2682     {
2683         molb->nposres_xB = 0;
2684     }
2685     for (i = 0; i < il->nr; i += 2)
2686     {
2687         ip                     = &mtop->ffparams.iparams[il->iatoms[i]];
2688         a                      = il->iatoms[i+1];
2689         molb->posres_xA[a][XX] = ip->posres.pos0A[XX];
2690         molb->posres_xA[a][YY] = ip->posres.pos0A[YY];
2691         molb->posres_xA[a][ZZ] = ip->posres.pos0A[ZZ];
2692         if (bFE)
2693         {
2694             molb->posres_xB[a][XX] = ip->posres.pos0B[XX];
2695             molb->posres_xB[a][YY] = ip->posres.pos0B[YY];
2696             molb->posres_xB[a][ZZ] = ip->posres.pos0B[ZZ];
2697         }
2698     }
2699     if (il->nr == 0)
2700     {
2701         /* If only flat-bottomed posres are present, take reference pos from them.
2702            Here: bFE == FALSE      */
2703         for (i = 0; i < ilfb->nr; i += 2)
2704         {
2705             ip                     = &mtop->ffparams.iparams[ilfb->iatoms[i]];
2706             a                      = ilfb->iatoms[i+1];
2707             molb->posres_xA[a][XX] = ip->fbposres.pos0[XX];
2708             molb->posres_xA[a][YY] = ip->fbposres.pos0[YY];
2709             molb->posres_xA[a][ZZ] = ip->fbposres.pos0[ZZ];
2710         }
2711     }
2712 }
2713
2714 static void set_disres_npair(gmx_mtop_t *mtop)
2715 {
2716     int        mt, i, npair;
2717     t_iparams *ip;
2718     t_ilist   *il;
2719     t_iatom   *a;
2720
2721     ip = mtop->ffparams.iparams;
2722
2723     for (mt = 0; mt < mtop->nmoltype; mt++)
2724     {
2725         il = &mtop->moltype[mt].ilist[F_DISRES];
2726         if (il->nr > 0)
2727         {
2728             a     = il->iatoms;
2729             npair = 0;
2730             for (i = 0; i < il->nr; i += 3)
2731             {
2732                 npair++;
2733                 if (i+3 == il->nr || ip[a[i]].disres.label != ip[a[i+3]].disres.label)
2734                 {
2735                     ip[a[i]].disres.npair = npair;
2736                     npair                 = 0;
2737                 }
2738             }
2739         }
2740     }
2741 }
2742
2743 static void do_mtop(t_fileio *fio, gmx_mtop_t *mtop, gmx_bool bRead,
2744                     int file_version)
2745 {
2746     int      mt, mb, i;
2747     t_blocka dumb;
2748
2749     if (bRead)
2750     {
2751         init_mtop(mtop);
2752     }
2753     do_symtab(fio, &(mtop->symtab), bRead);
2754     if (bRead && debug)
2755     {
2756         pr_symtab(debug, 0, "symtab", &mtop->symtab);
2757     }
2758
2759     do_symstr(fio, &(mtop->name), bRead, &(mtop->symtab));
2760
2761     if (file_version >= 57)
2762     {
2763         do_ffparams(fio, &mtop->ffparams, bRead, file_version);
2764
2765         gmx_fio_do_int(fio, mtop->nmoltype);
2766     }
2767     else
2768     {
2769         mtop->nmoltype = 1;
2770     }
2771     if (bRead)
2772     {
2773         snew(mtop->moltype, mtop->nmoltype);
2774         if (file_version < 57)
2775         {
2776             mtop->moltype[0].name = mtop->name;
2777         }
2778     }
2779     for (mt = 0; mt < mtop->nmoltype; mt++)
2780     {
2781         do_moltype(fio, &mtop->moltype[mt], bRead, &mtop->symtab, file_version,
2782                    &mtop->groups);
2783     }
2784
2785     if (file_version >= 57)
2786     {
2787         gmx_fio_do_int(fio, mtop->nmolblock);
2788     }
2789     else
2790     {
2791         mtop->nmolblock = 1;
2792     }
2793     if (bRead)
2794     {
2795         snew(mtop->molblock, mtop->nmolblock);
2796     }
2797     if (file_version >= 57)
2798     {
2799         for (mb = 0; mb < mtop->nmolblock; mb++)
2800         {
2801             do_molblock(fio, &mtop->molblock[mb], bRead, file_version);
2802         }
2803         gmx_fio_do_int(fio, mtop->natoms);
2804     }
2805     else
2806     {
2807         mtop->molblock[0].type       = 0;
2808         mtop->molblock[0].nmol       = 1;
2809         mtop->molblock[0].natoms_mol = mtop->moltype[0].atoms.nr;
2810         mtop->molblock[0].nposres_xA = 0;
2811         mtop->molblock[0].nposres_xB = 0;
2812     }
2813
2814     do_atomtypes (fio, &(mtop->atomtypes), bRead, &(mtop->symtab), file_version);
2815     if (bRead && debug)
2816     {
2817         pr_atomtypes(debug, 0, "atomtypes", &mtop->atomtypes, TRUE);
2818     }
2819
2820     if (file_version < 57)
2821     {
2822         /* Debug statements are inside do_idef */
2823         do_idef (fio, &mtop->ffparams, &mtop->moltype[0], bRead, file_version);
2824         mtop->natoms = mtop->moltype[0].atoms.nr;
2825     }
2826
2827     if (file_version >= 65)
2828     {
2829         do_cmap(fio, &mtop->ffparams.cmap_grid, bRead);
2830     }
2831     else
2832     {
2833         mtop->ffparams.cmap_grid.ngrid        = 0;
2834         mtop->ffparams.cmap_grid.grid_spacing = 0;
2835         mtop->ffparams.cmap_grid.cmapdata     = NULL;
2836     }
2837
2838     if (file_version >= 57)
2839     {
2840         do_groups(fio, &mtop->groups, bRead, &(mtop->symtab), file_version);
2841     }
2842
2843     if (file_version < 57)
2844     {
2845         do_block(fio, &mtop->moltype[0].cgs, bRead, file_version);
2846         if (bRead && gmx_debug_at)
2847         {
2848             pr_block(debug, 0, "cgs", &mtop->moltype[0].cgs, TRUE);
2849         }
2850         do_block(fio, &mtop->mols, bRead, file_version);
2851         /* Add the posres coordinates to the molblock */
2852         add_posres_molblock(mtop);
2853     }
2854     if (bRead)
2855     {
2856         if (file_version >= 57)
2857         {
2858             mtop->mols = mtop_mols(mtop);
2859         }
2860         if (gmx_debug_at)
2861         {
2862             pr_block(debug, 0, "mols", &mtop->mols, TRUE);
2863         }
2864     }
2865
2866     if (file_version < 51)
2867     {
2868         /* Here used to be the shake blocks */
2869         do_blocka(fio, &dumb, bRead, file_version);
2870         if (dumb.nr > 0)
2871         {
2872             sfree(dumb.index);
2873         }
2874         if (dumb.nra > 0)
2875         {
2876             sfree(dumb.a);
2877         }
2878     }
2879
2880     if (bRead)
2881     {
2882         close_symtab(&(mtop->symtab));
2883     }
2884 }
2885
2886 /* If TopOnlyOK is TRUE then we can read even future versions
2887  * of tpx files, provided the file_generation hasn't changed.
2888  * If it is FALSE, we need the inputrecord too, and bail out
2889  * if the file is newer than the program.
2890  *
2891  * The version and generation if the topology (see top of this file)
2892  * are returned in the two last arguments.
2893  *
2894  * If possible, we will read the inputrec even when TopOnlyOK is TRUE.
2895  */
2896 static void do_tpxheader(t_fileio *fio, gmx_bool bRead, t_tpxheader *tpx,
2897                          gmx_bool TopOnlyOK, int *file_version,
2898                          int *file_generation)
2899 {
2900     char      buf[STRLEN];
2901     char      file_tag[STRLEN];
2902     gmx_bool  bDouble;
2903     int       precision;
2904     int       fver, fgen;
2905     int       idum = 0;
2906     real      rdum = 0;
2907
2908     gmx_fio_checktype(fio);
2909     gmx_fio_setdebug(fio, bDebugMode());
2910
2911     /* NEW! XDR tpb file */
2912     precision = sizeof(real);
2913     if (bRead)
2914     {
2915         gmx_fio_do_string(fio, buf);
2916         if (strncmp(buf, "VERSION", 7))
2917         {
2918             gmx_fatal(FARGS, "Can not read file %s,\n"
2919                       "             this file is from a Gromacs version which is older than 2.0\n"
2920                       "             Make a new one with grompp or use a gro or pdb file, if possible",
2921                       gmx_fio_getname(fio));
2922         }
2923         gmx_fio_do_int(fio, precision);
2924         bDouble = (precision == sizeof(double));
2925         if ((precision != sizeof(float)) && !bDouble)
2926         {
2927             gmx_fatal(FARGS, "Unknown precision in file %s: real is %d bytes "
2928                       "instead of %d or %d",
2929                       gmx_fio_getname(fio), precision, sizeof(float), sizeof(double));
2930         }
2931         gmx_fio_setprecision(fio, bDouble);
2932         fprintf(stderr, "Reading file %s, %s (%s precision)\n",
2933                 gmx_fio_getname(fio), buf, bDouble ? "double" : "single");
2934     }
2935     else
2936     {
2937         gmx_fio_write_string(fio, GromacsVersion());
2938         bDouble = (precision == sizeof(double));
2939         gmx_fio_setprecision(fio, bDouble);
2940         gmx_fio_do_int(fio, precision);
2941         fver = tpx_version;
2942         sprintf(file_tag, "%s", tpx_tag);
2943         fgen = tpx_generation;
2944     }
2945
2946     /* Check versions! */
2947     gmx_fio_do_int(fio, fver);
2948
2949     /* This is for backward compatibility with development versions 77-79
2950      * where the tag was, mistakenly, placed before the generation,
2951      * which would cause a segv instead of a proper error message
2952      * when reading the topology only from tpx with <77 code.
2953      */
2954     if (fver >= 77 && fver <= 79)
2955     {
2956         gmx_fio_do_string(fio, file_tag);
2957     }
2958
2959     if (fver >= 26)
2960     {
2961         gmx_fio_do_int(fio, fgen);
2962     }
2963     else
2964     {
2965         fgen = 0;
2966     }
2967
2968     if (fver >= 81)
2969     {
2970         gmx_fio_do_string(fio, file_tag);
2971     }
2972     if (bRead)
2973     {
2974         if (fver < 77)
2975         {
2976             /* Versions before 77 don't have the tag, set it to release */
2977             sprintf(file_tag, "%s", TPX_TAG_RELEASE);
2978         }
2979
2980         if (strcmp(file_tag, tpx_tag) != 0)
2981         {
2982             fprintf(stderr, "Note: file tpx tag '%s', software tpx tag '%s'\n",
2983                     file_tag, tpx_tag);
2984
2985             /* We only support reading tpx files with the same tag as the code
2986              * or tpx files with the release tag and with lower version number.
2987              */
2988             if (!strcmp(file_tag, TPX_TAG_RELEASE) == 0 && fver < tpx_version)
2989             {
2990                 gmx_fatal(FARGS, "tpx tag/version mismatch: reading tpx file (%s) version %d, tag '%s' with program for tpx version %d, tag '%s'",
2991                           gmx_fio_getname(fio), fver, file_tag,
2992                           tpx_version, tpx_tag);
2993             }
2994         }
2995     }
2996
2997     if (file_version != NULL)
2998     {
2999         *file_version = fver;
3000     }
3001     if (file_generation != NULL)
3002     {
3003         *file_generation = fgen;
3004     }
3005
3006
3007     if ((fver <= tpx_incompatible_version) ||
3008         ((fver > tpx_version) && !TopOnlyOK) ||
3009         (fgen > tpx_generation))
3010     {
3011         gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program",
3012                   gmx_fio_getname(fio), fver, tpx_version);
3013     }
3014
3015     do_section(fio, eitemHEADER, bRead);
3016     gmx_fio_do_int(fio, tpx->natoms);
3017     if (fver >= 28)
3018     {
3019         gmx_fio_do_int(fio, tpx->ngtc);
3020     }
3021     else
3022     {
3023         tpx->ngtc = 0;
3024     }
3025     if (fver < 62)
3026     {
3027         gmx_fio_do_int(fio, idum);
3028         gmx_fio_do_real(fio, rdum);
3029     }
3030     /*a better decision will eventually (5.0 or later) need to be made
3031        on how to treat the alchemical state of the system, which can now
3032        vary through a simulation, and cannot be completely described
3033        though a single lambda variable, or even a single state
3034        index. Eventually, should probably be a vector. MRS*/
3035     if (fver >= 79)
3036     {
3037         gmx_fio_do_int(fio, tpx->fep_state);
3038     }
3039     gmx_fio_do_real(fio, tpx->lambda);
3040     gmx_fio_do_int(fio, tpx->bIr);
3041     gmx_fio_do_int(fio, tpx->bTop);
3042     gmx_fio_do_int(fio, tpx->bX);
3043     gmx_fio_do_int(fio, tpx->bV);
3044     gmx_fio_do_int(fio, tpx->bF);
3045     gmx_fio_do_int(fio, tpx->bBox);
3046
3047     if ((fgen > tpx_generation))
3048     {
3049         /* This can only happen if TopOnlyOK=TRUE */
3050         tpx->bIr = FALSE;
3051     }
3052 }
3053
3054 static int do_tpx(t_fileio *fio, gmx_bool bRead,
3055                   t_inputrec *ir, t_state *state, rvec *f, gmx_mtop_t *mtop,
3056                   gmx_bool bXVallocated)
3057 {
3058     t_tpxheader     tpx;
3059     t_inputrec      dum_ir;
3060     gmx_mtop_t      dum_top;
3061     gmx_bool        TopOnlyOK, bDum = TRUE;
3062     int             file_version, file_generation;
3063     int             i;
3064     rvec           *xptr, *vptr;
3065     int             ePBC;
3066     gmx_bool        bPeriodicMols;
3067
3068     if (!bRead)
3069     {
3070         tpx.natoms    = state->natoms;
3071         tpx.ngtc      = state->ngtc; /* need to add nnhpres here? */
3072         tpx.fep_state = state->fep_state;
3073         tpx.lambda    = state->lambda[efptFEP];
3074         tpx.bIr       = (ir       != NULL);
3075         tpx.bTop      = (mtop     != NULL);
3076         tpx.bX        = (state->x != NULL);
3077         tpx.bV        = (state->v != NULL);
3078         tpx.bF        = (f        != NULL);
3079         tpx.bBox      = TRUE;
3080     }
3081
3082     TopOnlyOK = (ir == NULL);
3083
3084     do_tpxheader(fio, bRead, &tpx, TopOnlyOK, &file_version, &file_generation);
3085
3086     if (bRead)
3087     {
3088         state->flags  = 0;
3089         /* state->lambda = tpx.lambda;*/ /*remove this eventually? */
3090         /* The init_state calls initialize the Nose-Hoover xi integrals to zero */
3091         if (bXVallocated)
3092         {
3093             xptr = state->x;
3094             vptr = state->v;
3095             init_state(state, 0, tpx.ngtc, 0, 0, 0); /* nose-hoover chains */ /* eventually, need to add nnhpres here? */
3096             state->natoms = tpx.natoms;
3097             state->nalloc = tpx.natoms;
3098             state->x      = xptr;
3099             state->v      = vptr;
3100         }
3101         else
3102         {
3103             init_state(state, tpx.natoms, tpx.ngtc, 0, 0, 0); /* nose-hoover chains */
3104         }
3105     }
3106
3107 #define do_test(fio, b, p) if (bRead && (p != NULL) && !b) gmx_fatal(FARGS, "No %s in %s",#p, gmx_fio_getname(fio))
3108
3109     do_test(fio, tpx.bBox, state->box);
3110     do_section(fio, eitemBOX, bRead);
3111     if (tpx.bBox)
3112     {
3113         gmx_fio_ndo_rvec(fio, state->box, DIM);
3114         if (file_version >= 51)
3115         {
3116             gmx_fio_ndo_rvec(fio, state->box_rel, DIM);
3117         }
3118         else
3119         {
3120             /* We initialize box_rel after reading the inputrec */
3121             clear_mat(state->box_rel);
3122         }
3123         if (file_version >= 28)
3124         {
3125             gmx_fio_ndo_rvec(fio, state->boxv, DIM);
3126             if (file_version < 56)
3127             {
3128                 matrix mdum;
3129                 gmx_fio_ndo_rvec(fio, mdum, DIM);
3130             }
3131         }
3132     }
3133
3134     if (state->ngtc > 0 && file_version >= 28)
3135     {
3136         real *dumv;
3137         /*ndo_double(state->nosehoover_xi,state->ngtc,bDum);*/
3138         /*ndo_double(state->nosehoover_vxi,state->ngtc,bDum);*/
3139         /*ndo_double(state->therm_integral,state->ngtc,bDum);*/
3140         snew(dumv, state->ngtc);
3141         if (file_version < 69)
3142         {
3143             bDum = gmx_fio_ndo_real(fio, dumv, state->ngtc);
3144         }
3145         /* These used to be the Berendsen tcoupl_lambda's */
3146         bDum = gmx_fio_ndo_real(fio, dumv, state->ngtc);
3147         sfree(dumv);
3148     }
3149
3150     /* Prior to tpx version 26, the inputrec was here.
3151      * I moved it to enable partial forward-compatibility
3152      * for analysis/viewer programs.
3153      */
3154     if (file_version < 26)
3155     {
3156         do_test(fio, tpx.bIr, ir);
3157         do_section(fio, eitemIR, bRead);
3158         if (tpx.bIr)
3159         {
3160             if (ir)
3161             {
3162                 do_inputrec(fio, ir, bRead, file_version,
3163                             mtop ? &mtop->ffparams.fudgeQQ : NULL);
3164                 if (bRead && debug)
3165                 {
3166                     pr_inputrec(debug, 0, "inputrec", ir, FALSE);
3167                 }
3168             }
3169             else
3170             {
3171                 do_inputrec(fio, &dum_ir, bRead, file_version,
3172                             mtop ? &mtop->ffparams.fudgeQQ : NULL);
3173                 if (bRead && debug)
3174                 {
3175                     pr_inputrec(debug, 0, "inputrec", &dum_ir, FALSE);
3176                 }
3177                 done_inputrec(&dum_ir);
3178             }
3179
3180         }
3181     }
3182
3183     do_test(fio, tpx.bTop, mtop);
3184     do_section(fio, eitemTOP, bRead);
3185     if (tpx.bTop)
3186     {
3187         int mtop_file_version = file_version;
3188         /*allow reading of Gromacs 4.6 files*/
3189         if (mtop_file_version > 80 && mtop_file_version < 90)
3190         {
3191             mtop_file_version = 79;
3192         }
3193         if (mtop)
3194         {
3195             do_mtop(fio, mtop, bRead, mtop_file_version);
3196         }
3197         else
3198         {
3199             do_mtop(fio, &dum_top, bRead, mtop_file_version);
3200             done_mtop(&dum_top, TRUE);
3201         }
3202     }
3203     do_test(fio, tpx.bX, state->x);
3204     do_section(fio, eitemX, bRead);
3205     if (tpx.bX)
3206     {
3207         if (bRead)
3208         {
3209             state->flags |= (1<<estX);
3210         }
3211         gmx_fio_ndo_rvec(fio, state->x, state->natoms);
3212     }
3213
3214     do_test(fio, tpx.bV, state->v);
3215     do_section(fio, eitemV, bRead);
3216     if (tpx.bV)
3217     {
3218         if (bRead)
3219         {
3220             state->flags |= (1<<estV);
3221         }
3222         gmx_fio_ndo_rvec(fio, state->v, state->natoms);
3223     }
3224
3225     do_test(fio, tpx.bF, f);
3226     do_section(fio, eitemF, bRead);
3227     if (tpx.bF)
3228     {
3229         gmx_fio_ndo_rvec(fio, f, state->natoms);
3230     }
3231
3232     /* Starting with tpx version 26, we have the inputrec
3233      * at the end of the file, so we can ignore it
3234      * if the file is never than the software (but still the
3235      * same generation - see comments at the top of this file.
3236      *
3237      *
3238      */
3239     ePBC          = -1;
3240     bPeriodicMols = FALSE;
3241     if (file_version >= 26)
3242     {
3243         do_test(fio, tpx.bIr, ir);
3244         do_section(fio, eitemIR, bRead);
3245         if (tpx.bIr)
3246         {
3247             if (file_version >= 53)
3248             {
3249                 /* Removed the pbc info from do_inputrec, since we always want it */
3250                 if (!bRead)
3251                 {
3252                     ePBC          = ir->ePBC;
3253                     bPeriodicMols = ir->bPeriodicMols;
3254                 }
3255                 gmx_fio_do_int(fio, ePBC);
3256                 gmx_fio_do_gmx_bool(fio, bPeriodicMols);
3257             }
3258             if (file_generation <= tpx_generation && ir)
3259             {
3260                 do_inputrec(fio, ir, bRead, file_version, mtop ? &mtop->ffparams.fudgeQQ : NULL);
3261                 if (bRead && debug)
3262                 {
3263                     pr_inputrec(debug, 0, "inputrec", ir, FALSE);
3264                 }
3265                 if (file_version < 51)
3266                 {
3267                     set_box_rel(ir, state);
3268                 }
3269                 if (file_version < 53)
3270                 {
3271                     ePBC          = ir->ePBC;
3272                     bPeriodicMols = ir->bPeriodicMols;
3273                 }
3274             }
3275             if (bRead && ir && file_version >= 53)
3276             {
3277                 /* We need to do this after do_inputrec, since that initializes ir */
3278                 ir->ePBC          = ePBC;
3279                 ir->bPeriodicMols = bPeriodicMols;
3280             }
3281         }
3282     }
3283
3284     if (bRead)
3285     {
3286         if (tpx.bIr && ir)
3287         {
3288             if (state->ngtc == 0)
3289             {
3290                 /* Reading old version without tcoupl state data: set it */
3291                 init_gtc_state(state, ir->opts.ngtc, 0, ir->opts.nhchainlength);
3292             }
3293             if (tpx.bTop && mtop)
3294             {
3295                 if (file_version < 57)
3296                 {
3297                     if (mtop->moltype[0].ilist[F_DISRES].nr > 0)
3298                     {
3299                         ir->eDisre = edrSimple;
3300                     }
3301                     else
3302                     {
3303                         ir->eDisre = edrNone;
3304                     }
3305                 }
3306                 set_disres_npair(mtop);
3307             }
3308         }
3309
3310         if (tpx.bTop && mtop)
3311         {
3312             gmx_mtop_finalize(mtop);
3313         }
3314
3315         if (file_version >= 57)
3316         {
3317             char *env;
3318             int   ienv;
3319             env = getenv("GMX_NOCHARGEGROUPS");
3320             if (env != NULL)
3321             {
3322                 sscanf(env, "%d", &ienv);
3323                 fprintf(stderr, "\nFound env.var. GMX_NOCHARGEGROUPS = %d\n",
3324                         ienv);
3325                 if (ienv > 0)
3326                 {
3327                     fprintf(stderr,
3328                             "Will make single atomic charge groups in non-solvent%s\n",
3329                             ienv > 1 ? " and solvent" : "");
3330                     gmx_mtop_make_atomic_charge_groups(mtop, ienv == 1);
3331                 }
3332                 fprintf(stderr, "\n");
3333             }
3334         }
3335     }
3336
3337     return ePBC;
3338 }
3339
3340 /************************************************************
3341  *
3342  *  The following routines are the exported ones
3343  *
3344  ************************************************************/
3345
3346 t_fileio *open_tpx(const char *fn, const char *mode)
3347 {
3348     return gmx_fio_open(fn, mode);
3349 }
3350
3351 void close_tpx(t_fileio *fio)
3352 {
3353     gmx_fio_close(fio);
3354 }
3355
3356 void read_tpxheader(const char *fn, t_tpxheader *tpx, gmx_bool TopOnlyOK,
3357                     int *file_version, int *file_generation)
3358 {
3359     t_fileio *fio;
3360
3361     fio = open_tpx(fn, "r");
3362     do_tpxheader(fio, TRUE, tpx, TopOnlyOK, file_version, file_generation);
3363     close_tpx(fio);
3364 }
3365
3366 void write_tpx_state(const char *fn,
3367                      t_inputrec *ir, t_state *state, gmx_mtop_t *mtop)
3368 {
3369     t_fileio *fio;
3370
3371     fio = open_tpx(fn, "w");
3372     do_tpx(fio, FALSE, ir, state, NULL, mtop, FALSE);
3373     close_tpx(fio);
3374 }
3375
3376 void read_tpx_state(const char *fn,
3377                     t_inputrec *ir, t_state *state, rvec *f, gmx_mtop_t *mtop)
3378 {
3379     t_fileio *fio;
3380
3381     fio = open_tpx(fn, "r");
3382     do_tpx(fio, TRUE, ir, state, f, mtop, FALSE);
3383     close_tpx(fio);
3384 }
3385
3386 int read_tpx(const char *fn,
3387              t_inputrec *ir, matrix box, int *natoms,
3388              rvec *x, rvec *v, rvec *f, gmx_mtop_t *mtop)
3389 {
3390     t_fileio *fio;
3391     t_state   state;
3392     int       ePBC;
3393
3394     state.x = x;
3395     state.v = v;
3396     fio     = open_tpx(fn, "r");
3397     ePBC    = do_tpx(fio, TRUE, ir, &state, f, mtop, TRUE);
3398     close_tpx(fio);
3399     *natoms = state.natoms;
3400     if (box)
3401     {
3402         copy_mat(state.box, box);
3403     }
3404     state.x = NULL;
3405     state.v = NULL;
3406     done_state(&state);
3407
3408     return ePBC;
3409 }
3410
3411 int read_tpx_top(const char *fn,
3412                  t_inputrec *ir, matrix box, int *natoms,
3413                  rvec *x, rvec *v, rvec *f, t_topology *top)
3414 {
3415     gmx_mtop_t  mtop;
3416     t_topology *ltop;
3417     int         ePBC;
3418
3419     ePBC = read_tpx(fn, ir, box, natoms, x, v, f, &mtop);
3420
3421     *top = gmx_mtop_t_to_t_topology(&mtop);
3422
3423     return ePBC;
3424 }
3425
3426 gmx_bool fn2bTPX(const char *file)
3427 {
3428     switch (fn2ftp(file))
3429     {
3430         case efTPR:
3431         case efTPB:
3432         case efTPA:
3433             return TRUE;
3434         default:
3435             return FALSE;
3436     }
3437 }
3438
3439 gmx_bool read_tps_conf(const char *infile, char *title, t_topology *top, int *ePBC,
3440                        rvec **x, rvec **v, matrix box, gmx_bool bMass)
3441 {
3442     t_tpxheader      header;
3443     int              natoms, i, version, generation;
3444     gmx_bool         bTop, bXNULL = FALSE;
3445     gmx_mtop_t      *mtop;
3446     t_topology      *topconv;
3447     gmx_atomprop_t   aps;
3448
3449     bTop  = fn2bTPX(infile);
3450     *ePBC = -1;
3451     if (bTop)
3452     {
3453         read_tpxheader(infile, &header, TRUE, &version, &generation);
3454         if (x)
3455         {
3456             snew(*x, header.natoms);
3457         }
3458         if (v)
3459         {
3460             snew(*v, header.natoms);
3461         }
3462         snew(mtop, 1);
3463         *ePBC = read_tpx(infile, NULL, box, &natoms,
3464                          (x == NULL) ? NULL : *x, (v == NULL) ? NULL : *v, NULL, mtop);
3465         *top = gmx_mtop_t_to_t_topology(mtop);
3466         sfree(mtop);
3467         strcpy(title, *top->name);
3468         tpx_make_chain_identifiers(&top->atoms, &top->mols);
3469     }
3470     else
3471     {
3472         get_stx_coordnum(infile, &natoms);
3473         init_t_atoms(&top->atoms, natoms, (fn2ftp(infile) == efPDB));
3474         if (x == NULL)
3475         {
3476             snew(x, 1);
3477             bXNULL = TRUE;
3478         }
3479         snew(*x, natoms);
3480         if (v)
3481         {
3482             snew(*v, natoms);
3483         }
3484         read_stx_conf(infile, title, &top->atoms, *x, (v == NULL) ? NULL : *v, ePBC, box);
3485         if (bXNULL)
3486         {
3487             sfree(*x);
3488             sfree(x);
3489         }
3490         if (bMass)
3491         {
3492             aps = gmx_atomprop_init();
3493             for (i = 0; (i < natoms); i++)
3494             {
3495                 if (!gmx_atomprop_query(aps, epropMass,
3496                                         *top->atoms.resinfo[top->atoms.atom[i].resind].name,
3497                                         *top->atoms.atomname[i],
3498                                         &(top->atoms.atom[i].m)))
3499                 {
3500                     if (debug)
3501                     {
3502                         fprintf(debug, "Can not find mass for atom %s %d %s, setting to 1\n",
3503                                 *top->atoms.resinfo[top->atoms.atom[i].resind].name,
3504                                 top->atoms.resinfo[top->atoms.atom[i].resind].nr,
3505                                 *top->atoms.atomname[i]);
3506                     }
3507                 }
3508             }
3509             gmx_atomprop_destroy(aps);
3510         }
3511         top->idef.ntypes = -1;
3512     }
3513
3514     return bTop;
3515 }