Remove hack to support old version tpr version 80
[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     { 90, 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         if ((block->nalloc_index > 0) && (NULL != block->index))
2103         {
2104             sfree(block->index);
2105         }
2106         block->nalloc_index = block->nr+1;
2107         snew(block->index, block->nalloc_index);
2108     }
2109     bDum = gmx_fio_ndo_int(fio, block->index, block->nr+1);
2110
2111     if (file_version < 51 && dum_nra > 0)
2112     {
2113         snew(dum_a, dum_nra);
2114         bDum = gmx_fio_ndo_int(fio, dum_a, dum_nra);
2115         sfree(dum_a);
2116     }
2117 }
2118
2119 static void do_blocka(t_fileio *fio, t_blocka *block, gmx_bool bRead,
2120                       int file_version)
2121 {
2122     int      i, idum;
2123     gmx_bool bDum = TRUE;
2124
2125     if (file_version < 44)
2126     {
2127         for (i = 0; i < MAXNODES; i++)
2128         {
2129             gmx_fio_do_int(fio, idum);
2130         }
2131     }
2132     gmx_fio_do_int(fio, block->nr);
2133     gmx_fio_do_int(fio, block->nra);
2134     if (bRead)
2135     {
2136         block->nalloc_index = block->nr+1;
2137         snew(block->index, block->nalloc_index);
2138         block->nalloc_a = block->nra;
2139         snew(block->a, block->nalloc_a);
2140     }
2141     bDum = gmx_fio_ndo_int(fio, block->index, block->nr+1);
2142     bDum = gmx_fio_ndo_int(fio, block->a, block->nra);
2143 }
2144
2145 static void do_atom(t_fileio *fio, t_atom *atom, int ngrp, gmx_bool bRead,
2146                     int file_version, gmx_groups_t *groups, int atnr)
2147 {
2148     int i, myngrp;
2149
2150     gmx_fio_do_real(fio, atom->m);
2151     gmx_fio_do_real(fio, atom->q);
2152     gmx_fio_do_real(fio, atom->mB);
2153     gmx_fio_do_real(fio, atom->qB);
2154     gmx_fio_do_ushort(fio, atom->type);
2155     gmx_fio_do_ushort(fio, atom->typeB);
2156     gmx_fio_do_int(fio, atom->ptype);
2157     gmx_fio_do_int(fio, atom->resind);
2158     if (file_version >= 52)
2159     {
2160         gmx_fio_do_int(fio, atom->atomnumber);
2161     }
2162     else if (bRead)
2163     {
2164         atom->atomnumber = NOTSET;
2165     }
2166     if (file_version < 23)
2167     {
2168         myngrp = 8;
2169     }
2170     else if (file_version < 39)
2171     {
2172         myngrp = 9;
2173     }
2174     else
2175     {
2176         myngrp = ngrp;
2177     }
2178
2179     if (file_version < 57)
2180     {
2181         unsigned char uchar[egcNR];
2182         gmx_fio_ndo_uchar(fio, uchar, myngrp);
2183         for (i = myngrp; (i < ngrp); i++)
2184         {
2185             uchar[i] = 0;
2186         }
2187         /* Copy the old data format to the groups struct */
2188         for (i = 0; i < ngrp; i++)
2189         {
2190             groups->grpnr[i][atnr] = uchar[i];
2191         }
2192     }
2193 }
2194
2195 static void do_grps(t_fileio *fio, int ngrp, t_grps grps[], gmx_bool bRead,
2196                     int file_version)
2197 {
2198     int      i, j, myngrp;
2199     gmx_bool bDum = TRUE;
2200
2201     if (file_version < 23)
2202     {
2203         myngrp = 8;
2204     }
2205     else if (file_version < 39)
2206     {
2207         myngrp = 9;
2208     }
2209     else
2210     {
2211         myngrp = ngrp;
2212     }
2213
2214     for (j = 0; (j < ngrp); j++)
2215     {
2216         if (j < myngrp)
2217         {
2218             gmx_fio_do_int(fio, grps[j].nr);
2219             if (bRead)
2220             {
2221                 snew(grps[j].nm_ind, grps[j].nr);
2222             }
2223             bDum = gmx_fio_ndo_int(fio, grps[j].nm_ind, grps[j].nr);
2224         }
2225         else
2226         {
2227             grps[j].nr = 1;
2228             snew(grps[j].nm_ind, grps[j].nr);
2229         }
2230     }
2231 }
2232
2233 static void do_symstr(t_fileio *fio, char ***nm, gmx_bool bRead, t_symtab *symtab)
2234 {
2235     int ls;
2236
2237     if (bRead)
2238     {
2239         gmx_fio_do_int(fio, ls);
2240         *nm = get_symtab_handle(symtab, ls);
2241     }
2242     else
2243     {
2244         ls = lookup_symtab(symtab, *nm);
2245         gmx_fio_do_int(fio, ls);
2246     }
2247 }
2248
2249 static void do_strstr(t_fileio *fio, int nstr, char ***nm, gmx_bool bRead,
2250                       t_symtab *symtab)
2251 {
2252     int  j;
2253
2254     for (j = 0; (j < nstr); j++)
2255     {
2256         do_symstr(fio, &(nm[j]), bRead, symtab);
2257     }
2258 }
2259
2260 static void do_resinfo(t_fileio *fio, int n, t_resinfo *ri, gmx_bool bRead,
2261                        t_symtab *symtab, int file_version)
2262 {
2263     int  j;
2264
2265     for (j = 0; (j < n); j++)
2266     {
2267         do_symstr(fio, &(ri[j].name), bRead, symtab);
2268         if (file_version >= 63)
2269         {
2270             gmx_fio_do_int(fio, ri[j].nr);
2271             gmx_fio_do_uchar(fio, ri[j].ic);
2272         }
2273         else
2274         {
2275             ri[j].nr = j + 1;
2276             ri[j].ic = ' ';
2277         }
2278     }
2279 }
2280
2281 static void do_atoms(t_fileio *fio, t_atoms *atoms, gmx_bool bRead, t_symtab *symtab,
2282                      int file_version,
2283                      gmx_groups_t *groups)
2284 {
2285     int i;
2286
2287     gmx_fio_do_int(fio, atoms->nr);
2288     gmx_fio_do_int(fio, atoms->nres);
2289     if (file_version < 57)
2290     {
2291         gmx_fio_do_int(fio, groups->ngrpname);
2292         for (i = 0; i < egcNR; i++)
2293         {
2294             groups->ngrpnr[i] = atoms->nr;
2295             snew(groups->grpnr[i], groups->ngrpnr[i]);
2296         }
2297     }
2298     if (bRead)
2299     {
2300         snew(atoms->atom, atoms->nr);
2301         snew(atoms->atomname, atoms->nr);
2302         snew(atoms->atomtype, atoms->nr);
2303         snew(atoms->atomtypeB, atoms->nr);
2304         snew(atoms->resinfo, atoms->nres);
2305         if (file_version < 57)
2306         {
2307             snew(groups->grpname, groups->ngrpname);
2308         }
2309         atoms->pdbinfo = NULL;
2310     }
2311     for (i = 0; (i < atoms->nr); i++)
2312     {
2313         do_atom(fio, &atoms->atom[i], egcNR, bRead, file_version, groups, i);
2314     }
2315     do_strstr(fio, atoms->nr, atoms->atomname, bRead, symtab);
2316     if (bRead && (file_version <= 20))
2317     {
2318         for (i = 0; i < atoms->nr; i++)
2319         {
2320             atoms->atomtype[i]  = put_symtab(symtab, "?");
2321             atoms->atomtypeB[i] = put_symtab(symtab, "?");
2322         }
2323     }
2324     else
2325     {
2326         do_strstr(fio, atoms->nr, atoms->atomtype, bRead, symtab);
2327         do_strstr(fio, atoms->nr, atoms->atomtypeB, bRead, symtab);
2328     }
2329     do_resinfo(fio, atoms->nres, atoms->resinfo, bRead, symtab, file_version);
2330
2331     if (file_version < 57)
2332     {
2333         do_strstr(fio, groups->ngrpname, groups->grpname, bRead, symtab);
2334
2335         do_grps(fio, egcNR, groups->grps, bRead, file_version);
2336     }
2337 }
2338
2339 static void do_groups(t_fileio *fio, gmx_groups_t *groups,
2340                       gmx_bool bRead, t_symtab *symtab,
2341                       int file_version)
2342 {
2343     int      g, n, i;
2344     gmx_bool bDum = TRUE;
2345
2346     do_grps(fio, egcNR, groups->grps, bRead, file_version);
2347     gmx_fio_do_int(fio, groups->ngrpname);
2348     if (bRead)
2349     {
2350         snew(groups->grpname, groups->ngrpname);
2351     }
2352     do_strstr(fio, groups->ngrpname, groups->grpname, bRead, symtab);
2353     for (g = 0; g < egcNR; g++)
2354     {
2355         gmx_fio_do_int(fio, groups->ngrpnr[g]);
2356         if (groups->ngrpnr[g] == 0)
2357         {
2358             if (bRead)
2359             {
2360                 groups->grpnr[g] = NULL;
2361             }
2362         }
2363         else
2364         {
2365             if (bRead)
2366             {
2367                 snew(groups->grpnr[g], groups->ngrpnr[g]);
2368             }
2369             bDum = gmx_fio_ndo_uchar(fio, groups->grpnr[g], groups->ngrpnr[g]);
2370         }
2371     }
2372 }
2373
2374 static void do_atomtypes(t_fileio *fio, t_atomtypes *atomtypes, gmx_bool bRead,
2375                          t_symtab *symtab, int file_version)
2376 {
2377     int      i, j;
2378     gmx_bool bDum = TRUE;
2379
2380     if (file_version > 25)
2381     {
2382         gmx_fio_do_int(fio, atomtypes->nr);
2383         j = atomtypes->nr;
2384         if (bRead)
2385         {
2386             snew(atomtypes->radius, j);
2387             snew(atomtypes->vol, j);
2388             snew(atomtypes->surftens, j);
2389             snew(atomtypes->atomnumber, j);
2390             snew(atomtypes->gb_radius, j);
2391             snew(atomtypes->S_hct, j);
2392         }
2393         bDum = gmx_fio_ndo_real(fio, atomtypes->radius, j);
2394         bDum = gmx_fio_ndo_real(fio, atomtypes->vol, j);
2395         bDum = gmx_fio_ndo_real(fio, atomtypes->surftens, j);
2396         if (file_version >= 40)
2397         {
2398             bDum = gmx_fio_ndo_int(fio, atomtypes->atomnumber, j);
2399         }
2400         if (file_version >= 60)
2401         {
2402             bDum = gmx_fio_ndo_real(fio, atomtypes->gb_radius, j);
2403             bDum = gmx_fio_ndo_real(fio, atomtypes->S_hct, j);
2404         }
2405     }
2406     else
2407     {
2408         /* File versions prior to 26 cannot do GBSA,
2409          * so they dont use this structure
2410          */
2411         atomtypes->nr         = 0;
2412         atomtypes->radius     = NULL;
2413         atomtypes->vol        = NULL;
2414         atomtypes->surftens   = NULL;
2415         atomtypes->atomnumber = NULL;
2416         atomtypes->gb_radius  = NULL;
2417         atomtypes->S_hct      = NULL;
2418     }
2419 }
2420
2421 static void do_symtab(t_fileio *fio, t_symtab *symtab, gmx_bool bRead)
2422 {
2423     int       i, nr;
2424     t_symbuf *symbuf;
2425     char      buf[STRLEN];
2426
2427     gmx_fio_do_int(fio, symtab->nr);
2428     nr     = symtab->nr;
2429     if (bRead)
2430     {
2431         snew(symtab->symbuf, 1);
2432         symbuf          = symtab->symbuf;
2433         symbuf->bufsize = nr;
2434         snew(symbuf->buf, nr);
2435         for (i = 0; (i < nr); i++)
2436         {
2437             gmx_fio_do_string(fio, buf);
2438             symbuf->buf[i] = strdup(buf);
2439         }
2440     }
2441     else
2442     {
2443         symbuf = symtab->symbuf;
2444         while (symbuf != NULL)
2445         {
2446             for (i = 0; (i < symbuf->bufsize) && (i < nr); i++)
2447             {
2448                 gmx_fio_do_string(fio, symbuf->buf[i]);
2449             }
2450             nr    -= i;
2451             symbuf = symbuf->next;
2452         }
2453         if (nr != 0)
2454         {
2455             gmx_fatal(FARGS, "nr of symtab strings left: %d", nr);
2456         }
2457     }
2458 }
2459
2460 static void do_cmap(t_fileio *fio, gmx_cmap_t *cmap_grid, gmx_bool bRead)
2461 {
2462     int i, j, ngrid, gs, nelem;
2463
2464     gmx_fio_do_int(fio, cmap_grid->ngrid);
2465     gmx_fio_do_int(fio, cmap_grid->grid_spacing);
2466
2467     ngrid = cmap_grid->ngrid;
2468     gs    = cmap_grid->grid_spacing;
2469     nelem = gs * gs;
2470
2471     if (bRead)
2472     {
2473         snew(cmap_grid->cmapdata, ngrid);
2474
2475         for (i = 0; i < cmap_grid->ngrid; i++)
2476         {
2477             snew(cmap_grid->cmapdata[i].cmap, 4*nelem);
2478         }
2479     }
2480
2481     for (i = 0; i < cmap_grid->ngrid; i++)
2482     {
2483         for (j = 0; j < nelem; j++)
2484         {
2485             gmx_fio_do_real(fio, cmap_grid->cmapdata[i].cmap[j*4]);
2486             gmx_fio_do_real(fio, cmap_grid->cmapdata[i].cmap[j*4+1]);
2487             gmx_fio_do_real(fio, cmap_grid->cmapdata[i].cmap[j*4+2]);
2488             gmx_fio_do_real(fio, cmap_grid->cmapdata[i].cmap[j*4+3]);
2489         }
2490     }
2491 }
2492
2493
2494 void tpx_make_chain_identifiers(t_atoms *atoms, t_block *mols)
2495 {
2496     int  m, a, a0, a1, r;
2497     char c, chainid;
2498     int  chainnum;
2499
2500     /* We always assign a new chain number, but save the chain id characters
2501      * for larger molecules.
2502      */
2503 #define CHAIN_MIN_ATOMS 15
2504
2505     chainnum = 0;
2506     chainid  = 'A';
2507     for (m = 0; m < mols->nr; m++)
2508     {
2509         a0 = mols->index[m];
2510         a1 = mols->index[m+1];
2511         if ((a1-a0 >= CHAIN_MIN_ATOMS) && (chainid <= 'Z'))
2512         {
2513             c = chainid;
2514             chainid++;
2515         }
2516         else
2517         {
2518             c = ' ';
2519         }
2520         for (a = a0; a < a1; a++)
2521         {
2522             atoms->resinfo[atoms->atom[a].resind].chainnum = chainnum;
2523             atoms->resinfo[atoms->atom[a].resind].chainid  = c;
2524         }
2525         chainnum++;
2526     }
2527
2528     /* Blank out the chain id if there was only one chain */
2529     if (chainid == 'B')
2530     {
2531         for (r = 0; r < atoms->nres; r++)
2532         {
2533             atoms->resinfo[r].chainid = ' ';
2534         }
2535     }
2536 }
2537
2538 static void do_moltype(t_fileio *fio, gmx_moltype_t *molt, gmx_bool bRead,
2539                        t_symtab *symtab, int file_version,
2540                        gmx_groups_t *groups)
2541 {
2542     int i;
2543
2544     if (file_version >= 57)
2545     {
2546         do_symstr(fio, &(molt->name), bRead, symtab);
2547     }
2548
2549     do_atoms(fio, &molt->atoms, bRead, symtab, file_version, groups);
2550
2551     if (bRead && gmx_debug_at)
2552     {
2553         pr_atoms(debug, 0, "atoms", &molt->atoms, TRUE);
2554     }
2555
2556     if (file_version >= 57)
2557     {
2558         do_ilists(fio, molt->ilist, bRead, file_version);
2559
2560         do_block(fio, &molt->cgs, bRead, file_version);
2561         if (bRead && gmx_debug_at)
2562         {
2563             pr_block(debug, 0, "cgs", &molt->cgs, TRUE);
2564         }
2565     }
2566
2567     /* This used to be in the atoms struct */
2568     do_blocka(fio, &molt->excls, bRead, file_version);
2569 }
2570
2571 static void do_molblock(t_fileio *fio, gmx_molblock_t *molb, gmx_bool bRead,
2572                         int file_version)
2573 {
2574     int i;
2575
2576     gmx_fio_do_int(fio, molb->type);
2577     gmx_fio_do_int(fio, molb->nmol);
2578     gmx_fio_do_int(fio, molb->natoms_mol);
2579     /* Position restraint coordinates */
2580     gmx_fio_do_int(fio, molb->nposres_xA);
2581     if (molb->nposres_xA > 0)
2582     {
2583         if (bRead)
2584         {
2585             snew(molb->posres_xA, molb->nposres_xA);
2586         }
2587         gmx_fio_ndo_rvec(fio, molb->posres_xA, molb->nposres_xA);
2588     }
2589     gmx_fio_do_int(fio, molb->nposres_xB);
2590     if (molb->nposres_xB > 0)
2591     {
2592         if (bRead)
2593         {
2594             snew(molb->posres_xB, molb->nposres_xB);
2595         }
2596         gmx_fio_ndo_rvec(fio, molb->posres_xB, molb->nposres_xB);
2597     }
2598
2599 }
2600
2601 static t_block mtop_mols(gmx_mtop_t *mtop)
2602 {
2603     int     mb, m, a, mol;
2604     t_block mols;
2605
2606     mols.nr = 0;
2607     for (mb = 0; mb < mtop->nmolblock; mb++)
2608     {
2609         mols.nr += mtop->molblock[mb].nmol;
2610     }
2611     mols.nalloc_index = mols.nr + 1;
2612     snew(mols.index, mols.nalloc_index);
2613
2614     a             = 0;
2615     m             = 0;
2616     mols.index[m] = a;
2617     for (mb = 0; mb < mtop->nmolblock; mb++)
2618     {
2619         for (mol = 0; mol < mtop->molblock[mb].nmol; mol++)
2620         {
2621             a += mtop->molblock[mb].natoms_mol;
2622             m++;
2623             mols.index[m] = a;
2624         }
2625     }
2626
2627     return mols;
2628 }
2629
2630 static void add_posres_molblock(gmx_mtop_t *mtop)
2631 {
2632     t_ilist        *il, *ilfb;
2633     int             am, i, mol, a;
2634     gmx_bool        bFE;
2635     gmx_molblock_t *molb;
2636     t_iparams      *ip;
2637
2638     /* posres reference positions are stored in ip->posres (if present) and
2639        in ip->fbposres (if present). If normal and flat-bottomed posres are present,
2640        posres.pos0A are identical to fbposres.pos0. */
2641     il   = &mtop->moltype[0].ilist[F_POSRES];
2642     ilfb = &mtop->moltype[0].ilist[F_FBPOSRES];
2643     if (il->nr == 0 && ilfb->nr == 0)
2644     {
2645         return;
2646     }
2647     am  = 0;
2648     bFE = FALSE;
2649     for (i = 0; i < il->nr; i += 2)
2650     {
2651         ip = &mtop->ffparams.iparams[il->iatoms[i]];
2652         am = max(am, il->iatoms[i+1]);
2653         if (ip->posres.pos0B[XX] != ip->posres.pos0A[XX] ||
2654             ip->posres.pos0B[YY] != ip->posres.pos0A[YY] ||
2655             ip->posres.pos0B[ZZ] != ip->posres.pos0A[ZZ])
2656         {
2657             bFE = TRUE;
2658         }
2659     }
2660     /* This loop is required if we have only flat-bottomed posres:
2661        - set am
2662        - bFE == FALSE (no B-state for flat-bottomed posres) */
2663     if (il->nr == 0)
2664     {
2665         for (i = 0; i < ilfb->nr; i += 2)
2666         {
2667             ip = &mtop->ffparams.iparams[ilfb->iatoms[i]];
2668             am = max(am, ilfb->iatoms[i+1]);
2669         }
2670     }
2671     /* Make the posres coordinate block end at a molecule end */
2672     mol = 0;
2673     while (am >= mtop->mols.index[mol+1])
2674     {
2675         mol++;
2676     }
2677     molb             = &mtop->molblock[0];
2678     molb->nposres_xA = mtop->mols.index[mol+1];
2679     snew(molb->posres_xA, molb->nposres_xA);
2680     if (bFE)
2681     {
2682         molb->nposres_xB = molb->nposres_xA;
2683         snew(molb->posres_xB, molb->nposres_xB);
2684     }
2685     else
2686     {
2687         molb->nposres_xB = 0;
2688     }
2689     for (i = 0; i < il->nr; i += 2)
2690     {
2691         ip                     = &mtop->ffparams.iparams[il->iatoms[i]];
2692         a                      = il->iatoms[i+1];
2693         molb->posres_xA[a][XX] = ip->posres.pos0A[XX];
2694         molb->posres_xA[a][YY] = ip->posres.pos0A[YY];
2695         molb->posres_xA[a][ZZ] = ip->posres.pos0A[ZZ];
2696         if (bFE)
2697         {
2698             molb->posres_xB[a][XX] = ip->posres.pos0B[XX];
2699             molb->posres_xB[a][YY] = ip->posres.pos0B[YY];
2700             molb->posres_xB[a][ZZ] = ip->posres.pos0B[ZZ];
2701         }
2702     }
2703     if (il->nr == 0)
2704     {
2705         /* If only flat-bottomed posres are present, take reference pos from them.
2706            Here: bFE == FALSE      */
2707         for (i = 0; i < ilfb->nr; i += 2)
2708         {
2709             ip                     = &mtop->ffparams.iparams[ilfb->iatoms[i]];
2710             a                      = ilfb->iatoms[i+1];
2711             molb->posres_xA[a][XX] = ip->fbposres.pos0[XX];
2712             molb->posres_xA[a][YY] = ip->fbposres.pos0[YY];
2713             molb->posres_xA[a][ZZ] = ip->fbposres.pos0[ZZ];
2714         }
2715     }
2716 }
2717
2718 static void set_disres_npair(gmx_mtop_t *mtop)
2719 {
2720     int        mt, i, npair;
2721     t_iparams *ip;
2722     t_ilist   *il;
2723     t_iatom   *a;
2724
2725     ip = mtop->ffparams.iparams;
2726
2727     for (mt = 0; mt < mtop->nmoltype; mt++)
2728     {
2729         il = &mtop->moltype[mt].ilist[F_DISRES];
2730         if (il->nr > 0)
2731         {
2732             a     = il->iatoms;
2733             npair = 0;
2734             for (i = 0; i < il->nr; i += 3)
2735             {
2736                 npair++;
2737                 if (i+3 == il->nr || ip[a[i]].disres.label != ip[a[i+3]].disres.label)
2738                 {
2739                     ip[a[i]].disres.npair = npair;
2740                     npair                 = 0;
2741                 }
2742             }
2743         }
2744     }
2745 }
2746
2747 static void do_mtop(t_fileio *fio, gmx_mtop_t *mtop, gmx_bool bRead,
2748                     int file_version)
2749 {
2750     int      mt, mb, i;
2751     t_blocka dumb;
2752
2753     if (bRead)
2754     {
2755         init_mtop(mtop);
2756     }
2757     do_symtab(fio, &(mtop->symtab), bRead);
2758     if (bRead && debug)
2759     {
2760         pr_symtab(debug, 0, "symtab", &mtop->symtab);
2761     }
2762
2763     do_symstr(fio, &(mtop->name), bRead, &(mtop->symtab));
2764
2765     if (file_version >= 57)
2766     {
2767         do_ffparams(fio, &mtop->ffparams, bRead, file_version);
2768
2769         gmx_fio_do_int(fio, mtop->nmoltype);
2770     }
2771     else
2772     {
2773         mtop->nmoltype = 1;
2774     }
2775     if (bRead)
2776     {
2777         snew(mtop->moltype, mtop->nmoltype);
2778         if (file_version < 57)
2779         {
2780             mtop->moltype[0].name = mtop->name;
2781         }
2782     }
2783     for (mt = 0; mt < mtop->nmoltype; mt++)
2784     {
2785         do_moltype(fio, &mtop->moltype[mt], bRead, &mtop->symtab, file_version,
2786                    &mtop->groups);
2787     }
2788
2789     if (file_version >= 57)
2790     {
2791         gmx_fio_do_int(fio, mtop->nmolblock);
2792     }
2793     else
2794     {
2795         mtop->nmolblock = 1;
2796     }
2797     if (bRead)
2798     {
2799         snew(mtop->molblock, mtop->nmolblock);
2800     }
2801     if (file_version >= 57)
2802     {
2803         for (mb = 0; mb < mtop->nmolblock; mb++)
2804         {
2805             do_molblock(fio, &mtop->molblock[mb], bRead, file_version);
2806         }
2807         gmx_fio_do_int(fio, mtop->natoms);
2808     }
2809     else
2810     {
2811         mtop->molblock[0].type       = 0;
2812         mtop->molblock[0].nmol       = 1;
2813         mtop->molblock[0].natoms_mol = mtop->moltype[0].atoms.nr;
2814         mtop->molblock[0].nposres_xA = 0;
2815         mtop->molblock[0].nposres_xB = 0;
2816     }
2817
2818     do_atomtypes (fio, &(mtop->atomtypes), bRead, &(mtop->symtab), file_version);
2819     if (bRead && debug)
2820     {
2821         pr_atomtypes(debug, 0, "atomtypes", &mtop->atomtypes, TRUE);
2822     }
2823
2824     if (file_version < 57)
2825     {
2826         /* Debug statements are inside do_idef */
2827         do_idef (fio, &mtop->ffparams, &mtop->moltype[0], bRead, file_version);
2828         mtop->natoms = mtop->moltype[0].atoms.nr;
2829     }
2830
2831     if (file_version >= 65)
2832     {
2833         do_cmap(fio, &mtop->ffparams.cmap_grid, bRead);
2834     }
2835     else
2836     {
2837         mtop->ffparams.cmap_grid.ngrid        = 0;
2838         mtop->ffparams.cmap_grid.grid_spacing = 0;
2839         mtop->ffparams.cmap_grid.cmapdata     = NULL;
2840     }
2841
2842     if (file_version >= 57)
2843     {
2844         do_groups(fio, &mtop->groups, bRead, &(mtop->symtab), file_version);
2845     }
2846
2847     if (file_version < 57)
2848     {
2849         do_block(fio, &mtop->moltype[0].cgs, bRead, file_version);
2850         if (bRead && gmx_debug_at)
2851         {
2852             pr_block(debug, 0, "cgs", &mtop->moltype[0].cgs, TRUE);
2853         }
2854         do_block(fio, &mtop->mols, bRead, file_version);
2855         /* Add the posres coordinates to the molblock */
2856         add_posres_molblock(mtop);
2857     }
2858     if (bRead)
2859     {
2860         if (file_version >= 57)
2861         {
2862             done_block(&mtop->mols);
2863             mtop->mols = mtop_mols(mtop);
2864         }
2865         if (gmx_debug_at)
2866         {
2867             pr_block(debug, 0, "mols", &mtop->mols, TRUE);
2868         }
2869     }
2870
2871     if (file_version < 51)
2872     {
2873         /* Here used to be the shake blocks */
2874         do_blocka(fio, &dumb, bRead, file_version);
2875         if (dumb.nr > 0)
2876         {
2877             sfree(dumb.index);
2878         }
2879         if (dumb.nra > 0)
2880         {
2881             sfree(dumb.a);
2882         }
2883     }
2884
2885     if (bRead)
2886     {
2887         close_symtab(&(mtop->symtab));
2888     }
2889 }
2890
2891 /* If TopOnlyOK is TRUE then we can read even future versions
2892  * of tpx files, provided the file_generation hasn't changed.
2893  * If it is FALSE, we need the inputrecord too, and bail out
2894  * if the file is newer than the program.
2895  *
2896  * The version and generation if the topology (see top of this file)
2897  * are returned in the two last arguments.
2898  *
2899  * If possible, we will read the inputrec even when TopOnlyOK is TRUE.
2900  */
2901 static void do_tpxheader(t_fileio *fio, gmx_bool bRead, t_tpxheader *tpx,
2902                          gmx_bool TopOnlyOK, int *file_version,
2903                          int *file_generation)
2904 {
2905     char      buf[STRLEN];
2906     char      file_tag[STRLEN];
2907     gmx_bool  bDouble;
2908     int       precision;
2909     int       fver, fgen;
2910     int       idum = 0;
2911     real      rdum = 0;
2912
2913     gmx_fio_checktype(fio);
2914     gmx_fio_setdebug(fio, bDebugMode());
2915
2916     /* NEW! XDR tpb file */
2917     precision = sizeof(real);
2918     if (bRead)
2919     {
2920         gmx_fio_do_string(fio, buf);
2921         if (strncmp(buf, "VERSION", 7))
2922         {
2923             gmx_fatal(FARGS, "Can not read file %s,\n"
2924                       "             this file is from a Gromacs version which is older than 2.0\n"
2925                       "             Make a new one with grompp or use a gro or pdb file, if possible",
2926                       gmx_fio_getname(fio));
2927         }
2928         gmx_fio_do_int(fio, precision);
2929         bDouble = (precision == sizeof(double));
2930         if ((precision != sizeof(float)) && !bDouble)
2931         {
2932             gmx_fatal(FARGS, "Unknown precision in file %s: real is %d bytes "
2933                       "instead of %d or %d",
2934                       gmx_fio_getname(fio), precision, sizeof(float), sizeof(double));
2935         }
2936         gmx_fio_setprecision(fio, bDouble);
2937         fprintf(stderr, "Reading file %s, %s (%s precision)\n",
2938                 gmx_fio_getname(fio), buf, bDouble ? "double" : "single");
2939     }
2940     else
2941     {
2942         gmx_fio_write_string(fio, GromacsVersion());
2943         bDouble = (precision == sizeof(double));
2944         gmx_fio_setprecision(fio, bDouble);
2945         gmx_fio_do_int(fio, precision);
2946         fver = tpx_version;
2947         sprintf(file_tag, "%s", tpx_tag);
2948         fgen = tpx_generation;
2949     }
2950
2951     /* Check versions! */
2952     gmx_fio_do_int(fio, fver);
2953
2954     /* This is for backward compatibility with development versions 77-79
2955      * where the tag was, mistakenly, placed before the generation,
2956      * which would cause a segv instead of a proper error message
2957      * when reading the topology only from tpx with <77 code.
2958      */
2959     if (fver >= 77 && fver <= 79)
2960     {
2961         gmx_fio_do_string(fio, file_tag);
2962     }
2963
2964     if (fver >= 26)
2965     {
2966         gmx_fio_do_int(fio, fgen);
2967     }
2968     else
2969     {
2970         fgen = 0;
2971     }
2972
2973     if (fver >= 81)
2974     {
2975         gmx_fio_do_string(fio, file_tag);
2976     }
2977     if (bRead)
2978     {
2979         if (fver < 77)
2980         {
2981             /* Versions before 77 don't have the tag, set it to release */
2982             sprintf(file_tag, "%s", TPX_TAG_RELEASE);
2983         }
2984
2985         if (strcmp(file_tag, tpx_tag) != 0)
2986         {
2987             fprintf(stderr, "Note: file tpx tag '%s', software tpx tag '%s'\n",
2988                     file_tag, tpx_tag);
2989
2990             /* We only support reading tpx files with the same tag as the code
2991              * or tpx files with the release tag and with lower version number.
2992              */
2993             if (!strcmp(file_tag, TPX_TAG_RELEASE) == 0 && fver < tpx_version)
2994             {
2995                 gmx_fatal(FARGS, "tpx tag/version mismatch: reading tpx file (%s) version %d, tag '%s' with program for tpx version %d, tag '%s'",
2996                           gmx_fio_getname(fio), fver, file_tag,
2997                           tpx_version, tpx_tag);
2998             }
2999         }
3000     }
3001
3002     if (file_version != NULL)
3003     {
3004         *file_version = fver;
3005     }
3006     if (file_generation != NULL)
3007     {
3008         *file_generation = fgen;
3009     }
3010
3011
3012     if ((fver <= tpx_incompatible_version) ||
3013         ((fver > tpx_version) && !TopOnlyOK) ||
3014         (fgen > tpx_generation) || 
3015         tpx_version == 80) /*80 was used by both 5.0-dev and 4.6-dev*/
3016     {
3017         gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program",
3018                   gmx_fio_getname(fio), fver, tpx_version);
3019     }
3020
3021     do_section(fio, eitemHEADER, bRead);
3022     gmx_fio_do_int(fio, tpx->natoms);
3023     if (fver >= 28)
3024     {
3025         gmx_fio_do_int(fio, tpx->ngtc);
3026     }
3027     else
3028     {
3029         tpx->ngtc = 0;
3030     }
3031     if (fver < 62)
3032     {
3033         gmx_fio_do_int(fio, idum);
3034         gmx_fio_do_real(fio, rdum);
3035     }
3036     /*a better decision will eventually (5.0 or later) need to be made
3037        on how to treat the alchemical state of the system, which can now
3038        vary through a simulation, and cannot be completely described
3039        though a single lambda variable, or even a single state
3040        index. Eventually, should probably be a vector. MRS*/
3041     if (fver >= 79)
3042     {
3043         gmx_fio_do_int(fio, tpx->fep_state);
3044     }
3045     gmx_fio_do_real(fio, tpx->lambda);
3046     gmx_fio_do_int(fio, tpx->bIr);
3047     gmx_fio_do_int(fio, tpx->bTop);
3048     gmx_fio_do_int(fio, tpx->bX);
3049     gmx_fio_do_int(fio, tpx->bV);
3050     gmx_fio_do_int(fio, tpx->bF);
3051     gmx_fio_do_int(fio, tpx->bBox);
3052
3053     if ((fgen > tpx_generation))
3054     {
3055         /* This can only happen if TopOnlyOK=TRUE */
3056         tpx->bIr = FALSE;
3057     }
3058 }
3059
3060 static int do_tpx(t_fileio *fio, gmx_bool bRead,
3061                   t_inputrec *ir, t_state *state, rvec *f, gmx_mtop_t *mtop,
3062                   gmx_bool bXVallocated)
3063 {
3064     t_tpxheader     tpx;
3065     t_inputrec      dum_ir;
3066     gmx_mtop_t      dum_top;
3067     gmx_bool        TopOnlyOK, bDum = TRUE;
3068     int             file_version, file_generation;
3069     int             i;
3070     rvec           *xptr, *vptr;
3071     int             ePBC;
3072     gmx_bool        bPeriodicMols;
3073
3074     if (!bRead)
3075     {
3076         tpx.natoms    = state->natoms;
3077         tpx.ngtc      = state->ngtc; /* need to add nnhpres here? */
3078         tpx.fep_state = state->fep_state;
3079         tpx.lambda    = state->lambda[efptFEP];
3080         tpx.bIr       = (ir       != NULL);
3081         tpx.bTop      = (mtop     != NULL);
3082         tpx.bX        = (state->x != NULL);
3083         tpx.bV        = (state->v != NULL);
3084         tpx.bF        = (f        != NULL);
3085         tpx.bBox      = TRUE;
3086     }
3087
3088     TopOnlyOK = (ir == NULL);
3089
3090     do_tpxheader(fio, bRead, &tpx, TopOnlyOK, &file_version, &file_generation);
3091
3092     if (bRead)
3093     {
3094         state->flags  = 0;
3095         /* state->lambda = tpx.lambda;*/ /*remove this eventually? */
3096         /* The init_state calls initialize the Nose-Hoover xi integrals to zero */
3097         if (bXVallocated)
3098         {
3099             xptr = state->x;
3100             vptr = state->v;
3101             init_state(state, 0, tpx.ngtc, 0, 0, 0); /* nose-hoover chains */ /* eventually, need to add nnhpres here? */
3102             state->natoms = tpx.natoms;
3103             state->nalloc = tpx.natoms;
3104             state->x      = xptr;
3105             state->v      = vptr;
3106         }
3107         else
3108         {
3109             init_state(state, tpx.natoms, tpx.ngtc, 0, 0, 0); /* nose-hoover chains */
3110         }
3111     }
3112
3113 #define do_test(fio, b, p) if (bRead && (p != NULL) && !b) gmx_fatal(FARGS, "No %s in %s",#p, gmx_fio_getname(fio))
3114
3115     do_test(fio, tpx.bBox, state->box);
3116     do_section(fio, eitemBOX, bRead);
3117     if (tpx.bBox)
3118     {
3119         gmx_fio_ndo_rvec(fio, state->box, DIM);
3120         if (file_version >= 51)
3121         {
3122             gmx_fio_ndo_rvec(fio, state->box_rel, DIM);
3123         }
3124         else
3125         {
3126             /* We initialize box_rel after reading the inputrec */
3127             clear_mat(state->box_rel);
3128         }
3129         if (file_version >= 28)
3130         {
3131             gmx_fio_ndo_rvec(fio, state->boxv, DIM);
3132             if (file_version < 56)
3133             {
3134                 matrix mdum;
3135                 gmx_fio_ndo_rvec(fio, mdum, DIM);
3136             }
3137         }
3138     }
3139
3140     if (state->ngtc > 0 && file_version >= 28)
3141     {
3142         real *dumv;
3143         /*ndo_double(state->nosehoover_xi,state->ngtc,bDum);*/
3144         /*ndo_double(state->nosehoover_vxi,state->ngtc,bDum);*/
3145         /*ndo_double(state->therm_integral,state->ngtc,bDum);*/
3146         snew(dumv, state->ngtc);
3147         if (file_version < 69)
3148         {
3149             bDum = gmx_fio_ndo_real(fio, dumv, state->ngtc);
3150         }
3151         /* These used to be the Berendsen tcoupl_lambda's */
3152         bDum = gmx_fio_ndo_real(fio, dumv, state->ngtc);
3153         sfree(dumv);
3154     }
3155
3156     /* Prior to tpx version 26, the inputrec was here.
3157      * I moved it to enable partial forward-compatibility
3158      * for analysis/viewer programs.
3159      */
3160     if (file_version < 26)
3161     {
3162         do_test(fio, tpx.bIr, ir);
3163         do_section(fio, eitemIR, bRead);
3164         if (tpx.bIr)
3165         {
3166             if (ir)
3167             {
3168                 do_inputrec(fio, ir, bRead, file_version,
3169                             mtop ? &mtop->ffparams.fudgeQQ : NULL);
3170                 if (bRead && debug)
3171                 {
3172                     pr_inputrec(debug, 0, "inputrec", ir, FALSE);
3173                 }
3174             }
3175             else
3176             {
3177                 do_inputrec(fio, &dum_ir, bRead, file_version,
3178                             mtop ? &mtop->ffparams.fudgeQQ : NULL);
3179                 if (bRead && debug)
3180                 {
3181                     pr_inputrec(debug, 0, "inputrec", &dum_ir, FALSE);
3182                 }
3183                 done_inputrec(&dum_ir);
3184             }
3185
3186         }
3187     }
3188
3189     do_test(fio, tpx.bTop, mtop);
3190     do_section(fio, eitemTOP, bRead);
3191     if (tpx.bTop)
3192     {
3193         if (mtop)
3194         {
3195             do_mtop(fio, mtop, bRead, file_version);
3196         }
3197         else
3198         {
3199             do_mtop(fio, &dum_top, bRead, 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 static void done_gmx_groups_t(gmx_groups_t *g)
3440 {
3441     int i;
3442
3443     for (i = 0; (i < egcNR); i++)
3444     {
3445         if (NULL != g->grps[i].nm_ind)
3446         {
3447             sfree(g->grps[i].nm_ind);
3448             g->grps[i].nm_ind = NULL;
3449         }
3450         if (NULL != g->grpnr[i])
3451         {
3452             sfree(g->grpnr[i]);
3453             g->grpnr[i] = NULL;
3454         }
3455     }
3456     /* The contents of this array is in symtab, don't free it here */
3457     sfree(g->grpname);
3458 }
3459
3460 gmx_bool read_tps_conf(const char *infile, char *title, t_topology *top, int *ePBC,
3461                        rvec **x, rvec **v, matrix box, gmx_bool bMass)
3462 {
3463     t_tpxheader      header;
3464     int              natoms, i, version, generation;
3465     gmx_bool         bTop, bXNULL = FALSE;
3466     gmx_mtop_t      *mtop;
3467     t_topology      *topconv;
3468     gmx_atomprop_t   aps;
3469
3470     bTop  = fn2bTPX(infile);
3471     *ePBC = -1;
3472     if (bTop)
3473     {
3474         read_tpxheader(infile, &header, TRUE, &version, &generation);
3475         if (x)
3476         {
3477             snew(*x, header.natoms);
3478         }
3479         if (v)
3480         {
3481             snew(*v, header.natoms);
3482         }
3483         snew(mtop, 1);
3484         *ePBC = read_tpx(infile, NULL, box, &natoms,
3485                          (x == NULL) ? NULL : *x, (v == NULL) ? NULL : *v, NULL, mtop);
3486         *top = gmx_mtop_t_to_t_topology(mtop);
3487         /* In this case we need to throw away the group data too */
3488         done_gmx_groups_t(&mtop->groups);
3489         sfree(mtop);
3490         strcpy(title, *top->name);
3491         tpx_make_chain_identifiers(&top->atoms, &top->mols);
3492     }
3493     else
3494     {
3495         get_stx_coordnum(infile, &natoms);
3496         init_t_atoms(&top->atoms, natoms, (fn2ftp(infile) == efPDB));
3497         if (x == NULL)
3498         {
3499             snew(x, 1);
3500             bXNULL = TRUE;
3501         }
3502         snew(*x, natoms);
3503         if (v)
3504         {
3505             snew(*v, natoms);
3506         }
3507         read_stx_conf(infile, title, &top->atoms, *x, (v == NULL) ? NULL : *v, ePBC, box);
3508         if (bXNULL)
3509         {
3510             sfree(*x);
3511             sfree(x);
3512         }
3513         if (bMass)
3514         {
3515             aps = gmx_atomprop_init();
3516             for (i = 0; (i < natoms); i++)
3517             {
3518                 if (!gmx_atomprop_query(aps, epropMass,
3519                                         *top->atoms.resinfo[top->atoms.atom[i].resind].name,
3520                                         *top->atoms.atomname[i],
3521                                         &(top->atoms.atom[i].m)))
3522                 {
3523                     if (debug)
3524                     {
3525                         fprintf(debug, "Can not find mass for atom %s %d %s, setting to 1\n",
3526                                 *top->atoms.resinfo[top->atoms.atom[i].resind].name,
3527                                 top->atoms.resinfo[top->atoms.atom[i].resind].nr,
3528                                 *top->atoms.atomname[i]);
3529                     }
3530                 }
3531             }
3532             gmx_atomprop_destroy(aps);
3533         }
3534         top->idef.ntypes = -1;
3535     }
3536
3537     return bTop;
3538 }