Merge branch 'master' of git@git.gromacs.org:gromacs
authorSzilard Pall <pszilard@cbr.su.se>
Thu, 24 Jun 2010 19:23:32 +0000 (21:23 +0200)
committerSzilard Pall <pszilard@cbr.su.se>
Thu, 24 Jun 2010 19:23:32 +0000 (21:23 +0200)
138 files changed:
CMakeLists.txt
admin/programs.txt
cmake/gmxCFlags.cmake
configure.ac
include/Makefile.am
include/checkpoint.h
include/enxio.h
include/fftgrid.h [deleted file]
include/gmx_ana.h
include/gmxfio.h
include/mdrun.h
include/nrama.h
include/pme.h
include/pppm.h
include/smalloc.h
include/statusio.h [deleted file]
include/statutil.h
include/tpxio.h
include/trnio.h
include/types/qmmmrec.h
include/vec.h
include/vmdio.h
include/xdrf.h
include/xtcio.h
share/html/online/mdp_opt.html
share/top/charmm27.ff/atomtypes.atp
src/config.h.cmakein
src/gmxlib/Makefile.am
src/gmxlib/checkpoint.c
src/gmxlib/enxio.c
src/gmxlib/futil.c
src/gmxlib/gmxcpp.c
src/gmxlib/gmxfio.c
src/gmxlib/gmxfio_asc.c [new file with mode: 0644]
src/gmxlib/gmxfio_bin.c [new file with mode: 0644]
src/gmxlib/gmxfio_int.h [new file with mode: 0644]
src/gmxlib/gmxfio_rw.c [new file with mode: 0644]
src/gmxlib/gmxfio_xdr.c [new file with mode: 0644]
src/gmxlib/libxdrf.c
src/gmxlib/mshift.c
src/gmxlib/mtxio.c
src/gmxlib/nonbonded/nb_kernel_ia32_sse/nb_kernel400_ia32_sse.c
src/gmxlib/nonbonded/nb_kernel_ia32_sse2/nb_kernel400_ia32_sse2.c
src/gmxlib/nonbonded/nb_kernel_ia32_sse2/nb_kernel410_ia32_sse2.c
src/gmxlib/nonbonded/nb_kernel_ia32_sse2/nb_kernel430_ia32_sse2.c
src/gmxlib/nonbonded/nb_kernel_sse2_single/nb_kernel400_sse2_single.c
src/gmxlib/nonbonded/nb_kernel_x86_64_sse/nb_kernel400_x86_64_sse.c
src/gmxlib/sfactor.c
src/gmxlib/smalloc.c
src/gmxlib/tpxio.c
src/gmxlib/trajana/trajana.c
src/gmxlib/trnio.c
src/gmxlib/trxio.c
src/gmxlib/xdrd.c
src/gmxlib/xtcio.c
src/kernel/g_protonate.c
src/kernel/gmxcheck.c
src/kernel/gmxdump.c
src/kernel/grompp.c
src/kernel/md.c
src/kernel/pdb2gmx.c
src/kernel/readir.c
src/kernel/tpbcmp.c
src/kernel/tpbconv.c
src/mdlib/Makefile.am
src/mdlib/ewald.c
src/mdlib/fftgrid.c [deleted file]
src/mdlib/ghat.c
src/mdlib/pppm.c
src/mdlib/qm_orca.c [new file with mode: 0644]
src/mdlib/qmmm.c
src/mdlib/stat.c
src/mdlib/tables.c
src/mdlib/tpi.c
src/ngmx/manager.c
src/ngmx/manager.h
src/ngmx/molps.c
src/ngmx/ngmx.c
src/ngmx/nmol.c
src/tools/CMakeLists.txt
src/tools/anadih.c
src/tools/do_dssp.c
src/tools/eigio.c
src/tools/gmx_anaeig.c
src/tools/gmx_angle.c
src/tools/gmx_bond.c
src/tools/gmx_bundle.c
src/tools/gmx_cluster.c
src/tools/gmx_clustsize.c
src/tools/gmx_covar.c
src/tools/gmx_current.c
src/tools/gmx_density.c
src/tools/gmx_densmap.c
src/tools/gmx_dipoles.c
src/tools/gmx_disre.c
src/tools/gmx_dist.c
src/tools/gmx_dyndom.c
src/tools/gmx_eneconv.c
src/tools/gmx_filter.c
src/tools/gmx_genconf.c
src/tools/gmx_gyrate.c
src/tools/gmx_h2order.c
src/tools/gmx_hbond.c
src/tools/gmx_helix.c
src/tools/gmx_helixorient.c
src/tools/gmx_mdmat.c
src/tools/gmx_membed.c
src/tools/gmx_mindist.c
src/tools/gmx_morph.c
src/tools/gmx_msd.c
src/tools/gmx_nmens.c
src/tools/gmx_nmtraj.c
src/tools/gmx_order.c
src/tools/gmx_polystat.c
src/tools/gmx_potential.c
src/tools/gmx_principal.c
src/tools/gmx_rdf.c
src/tools/gmx_rms.c
src/tools/gmx_rmsdist.c
src/tools/gmx_rmsf.c
src/tools/gmx_rotacf.c
src/tools/gmx_rotmat.c
src/tools/gmx_saltbr.c
src/tools/gmx_sas.c
src/tools/gmx_sdf.c
src/tools/gmx_sgangle.c
src/tools/gmx_sorient.c
src/tools/gmx_spatial.c
src/tools/gmx_spol.c
src/tools/gmx_tcaf.c
src/tools/gmx_traj.c
src/tools/gmx_trjcat.c
src/tools/gmx_trjconv.c
src/tools/gmx_trjorder.c
src/tools/gmx_tune_pme.c
src/tools/gmx_vanhove.c
src/tools/gmx_velacc.c
tests/CMakeLists.txt [new file with mode: 0644]

index e73260d731dc85ff3a587c19ee0117a31af68e1e..7238ed45c929fd06cd1a99d8db181f0a84aeb7eb 100644 (file)
@@ -32,7 +32,7 @@ set(GMX_FFT_LIBRARY "fftw3"
 option(GMX_DISABLE_FFTW_MEASURE 
        "Do not optimize FFTW setups (not needed with SSE)" OFF)
 set(GMX_QMMM_PROGRAM "none" 
-    CACHE STRING "QM package choices: none,gaussian,mopac,gamess")
+    CACHE STRING "QM package choices: none,gaussian,mopac,gamess,orca")
 option(GMX_BROKEN_CALLOC "Work around broken calloc()" OFF)
 option(BUILD_SHARED_LIBS "Enable shared libraries (can be problematic with MPI)" OFF)
 option(GMX_MPI_IN_PLACE "Enable MPI_IN_PLACE for MPIs that have it defined" ON)
@@ -156,6 +156,8 @@ check_function_exists(strcasecmp        HAVE_STRCASECMP)
 check_function_exists(strdup            HAVE_STRDUP)
 check_function_exists(vprintf           HAVE_VPRINTF)
 check_function_exists(memcmp            HAVE_MEMCMP)
+check_function_exists(posix_memalign    HAVE_POSIX_MEMALIGN)
+check_function_exists(memalign          HAVE_MEMALIGN)
 check_function_exists(gettimeofday      HAVE_GETTIMEOFDAY)
 check_function_exists(isnan             HAVE_ISNAN)
 check_function_exists(_isnan            HAVE__ISNAN)
@@ -450,10 +452,12 @@ elseif(${GMX_QMMM_PROGRAM} STREQUAL "MOPAC")
     set(GMX_QMMM_MOPAC 1)
 elseif(${GMX_QMMM_PROGRAM} STREQUAL "GAMESS")
     set(GMX_QMMM_GAMESS 1)
+elseif(${GMX_QMMM_PROGRAM} STREQUAL "ORCA")
+    set(GMX_QMMM_ORCA 1)
 elseif(${GMX_QMMM_PROGRAM} STREQUAL "NONE")
     # nothing to do
 else(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
-    MESSAGE(FATAL_ERROR "Invalid QM/MM program option: ${GMX_QMMM_PROGRAM}. Choose one of: Gaussian, Mopac, Gamess, None")
+    MESSAGE(FATAL_ERROR "Invalid QM/MM program option: ${GMX_QMMM_PROGRAM}. Choose one of: Gaussian, Mopac, Gamess, Orca, None")
 endif(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
 
 # Process FFT library settings - if not OpenMM build 
@@ -569,4 +573,11 @@ add_subdirectory(man)
 
 add_subdirectory(src)
 
+########################################################################
+# Tests                                                                #
+########################################################################
+
+enable_testing()
+add_test(TestBuildAll make)
 
+add_subdirectory(tests)
index 54e53170f1483257cdee32e1fa57d20fb2e7ec00..0dd5172b0fb90de91e49bd71585bae9df9a3a1b3 100644 (file)
@@ -139,6 +139,7 @@ g_densmap|calculates 2D planar or axial-radial density maps
 g_order|computes the order parameter per atom for carbon tails
 g_h2order|computes the orientation of water molecules
 g_bundle|analyzes bundles of axes, e.g. transmembrane helices
+g_membed|embeds a protein into a lipid bilayer
 END
 
 
index 4ec969a92fee373fbae8ac3805fc23c98ff4d267..f4ff02ca5ff957cfb23b2975f989a387a21c5497 100644 (file)
@@ -15,10 +15,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
     set(GMXC_C_FLAGS "-Wall -Wno-unused ${GMXC_C_FLAGS}")
   endif()
 
-  CHECK_C_COMPILER_FLAG( "-std=gnu99" XFLAGS_GNU99)
-  if (XFLAGS_GNU99)
-    set(GMXC_C_FLAGS "-std=gnu99 ${GMXC_C_FLAGS}")
-  endif()
+#  CHECK_C_COMPILER_FLAG( "-std=gnu99" XFLAGS_GNU99)
+#  if (XFLAGS_GNU99)
+#    set(GMXC_C_FLAGS "-std=gnu99 ${GMXC_C_FLAGS}")
+#  endif()
 
   CHECK_C_COMPILER_FLAG( "-march=native" XFLAGS_MARCH)
   if (XFLAGS_MARCH)
index cd4c2e7ee46cdbcbea6d9c57f36f1e9c67c1a726..cc3836a1a97bbdee30cf3bb4105eb3281dde6db4 100644 (file)
@@ -14,7 +14,7 @@ AC_PREFIX_DEFAULT(/usr/local/gromacs)
 AM_CONFIG_HEADER(src/config.h)
 dnl This is the version info according to the libtool versioning system.
 dnl It does *not* correspond to the release number.
-SHARED_VERSION_INFO="5:0:0"
+SHARED_VERSION_INFO="6:0:0"
 AC_SUBST(SHARED_VERSION_INFO)
 
 AC_DISABLE_SHARED
@@ -128,6 +128,13 @@ if test "$enable_ppc_altivec" = "undef"; then
   esac
 fi
 
+###################################
+## Detect buggy version of gcc
+###################################
+AC_ARG_ENABLE(gcc41_check,
+              [AC_HELP_STRING([--disable-gcc41-check],
+                              [Disable the check for buggy gcc 4.1])],,enable_gcc41_check=yes)
+
 
 
 ### ia64 assembly code
@@ -263,6 +270,15 @@ if test "$with_qmmm_mopac" = "yes"; then
   AC_DEFINE(GMX_QMMM_MOPAC,,[Use (modified) Mopac 7 for QM-MM calculations])
 fi
 
+
+AC_ARG_WITH(qmmm_orca,
+              [AC_HELP_STRING([--without-qmmm-mopac],
+                              [Use ORCA for QM-MM])],,with_qmmm_orca=no)
+if test "$with_qmmm_orca"="yes"; then
+  AC_DEFINE(GMX_QMMM_ORCA,,[Use ORCA for QM-MM calculations])
+fi
+
+
 AC_ARG_WITH(dlopen,
             [AC_HELP_STRING([--without-dlopen],
                             [do not compile with dlopen, needed to read VMD]
@@ -270,8 +286,6 @@ AC_ARG_WITH(dlopen,
 
 
 
-   
-
 ############################################################
 # Add some debug info: Who is building, and on what machine?
 ############################################################
@@ -324,6 +338,18 @@ AC_PROG_CC( $cc_names )
 if test -z "$CC_FOR_BUILD"; then
   CC_FOR_BUILD=$CC
 fi
+
+if test "$enable_gcc41_check" = "yes"; then
+    if $CC --version 2>&1 | grep 'gcc.* 4\.1' > /dev/null 2>&1; then
+        AC_MSG_ERROR([Uh-oh. Your compilers appears to be GCC version 4.1, which unfortunately produces]
+[buggy code at high optimimzation levels. It would be a good idea to update or]
+[use a different compiler. If you are ABSOLUTELY sure what you are doing, you]
+[can override this check with --disable-gcc41-check.])
+    fi
+fi
+
+
+
 AC_SUBST(CC_FOR_BUILD) 
 
 if test "$enable_fortran" = "yes"; then 
@@ -734,6 +760,8 @@ AC_CHECK_FUNCS(copyfile)
 
 # check for bool (must come late, since CFLAGS/includes might affect it)
 AC_CHECK_TYPES([bool])
+AC_SEARCH_LIBS(posix_memalign, c, AC_DEFINE(HAVE_POSIX_MEMALIGN, 1, Define to 1 if you have the posix_memalign function))
+AC_SEARCH_LIBS(memalign, c, AC_DEFINE(HAVE_MEMALIGN, 1, Define to 1 if you have the memalign function))
 
 
 
index cfeecc2f0521a747f63796015e880913ef28f57e..984fef87f8d224e84568a4da2e00409812e02470 100644 (file)
@@ -122,7 +122,6 @@ sortwater.h \
 sparsematrix.h \
 split.h \
 splitter.h \
-statusio.h \
 statutil.h \
 strdb.h \
 string2.h \
index b76bbb85986950003b91a1245de1c512d915d8c6..cc828bee84b5f0ecfa1de751390d50e89acd3940 100644 (file)
@@ -74,7 +74,7 @@ extern void read_checkpoint_state(const char *fn,int *simulation_part,
                                  gmx_large_int_t *step,double *t,t_state *state);
 
 /* Read everything that can be stored in t_trxframe from a checkpoint file */
-extern void read_checkpoint_trxframe(int fp,t_trxframe *fr);
+extern void read_checkpoint_trxframe(t_fileio *fp,t_trxframe *fr);
 
 /* Print the complete contents of checkpoint file fn to out */
 extern void list_checkpoint(const char *fn,FILE *out);
index 57e612affded4e9f1dbfdc3337fd30de802b83df..04e2677c17b52288d77752f135c230077c9f999f 100644 (file)
@@ -43,6 +43,7 @@
 #include "sysstuff.h"
 #include "typedefs.h"
 #include "pbc.h"
+#include "gmxfio.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -79,9 +80,9 @@ extern "C" {
 
   typedef struct {
     double   t;                    /* Timestamp of this frame                       */
-    gmx_large_int_t step;        /* MD step                                         */
-    gmx_large_int_t nsteps;      /* The number of steps between frames            */
-    gmx_large_int_t nsum;        /* The number of terms for the sums in ener      */
+    gmx_large_int_t step;   /* MD step                                      */
+    gmx_large_int_t nsteps; /* The number of steps between frames            */
+    int      nsum;          /* The number of terms for the sums in ener      */
     int      nre;           /* Number of energies                           */
     int      ndisre;        /* Number of distance restraints                */
     int      nblock;        /* Number of following energy blocks              */
@@ -123,7 +124,7 @@ extern "C" {
 
   extern ener_file_t open_enx(const char *fn,const char *mode);
 
-  extern int enx_file_pointer(const ener_file_t ef);
+  extern t_fileio *enx_file_pointer(const ener_file_t ef);
 
   extern void close_enx(ener_file_t ef);
   
diff --git a/include/fftgrid.h b/include/fftgrid.h
deleted file mode 100644 (file)
index f26eed4..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 
- *                This source code is part of
- * 
- *                 G   R   O   M   A   C   S
- * 
- *          GROningen MAchine for Chemical Simulations
- * 
- *                        VERSION 3.2.0
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
- * 
- * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- * 
- * For more info, check our website at http://www.gromacs.org
- * 
- * And Hey:
- * Gromacs Runs On Most of All Computer Systems
- */
-
-#ifndef _fftgrid_h
-#define _fftgrid_h
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include "typedefs.h"
-#include "gmxcomplex.h"
-#include "network.h"
-#include "gmx_fft.h"
-
-#ifdef GMX_MPI
-#include "gmx_parallel_3dfft.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Use FFTW */
-
-#define INDEX(i,j,k)             ((i)*la12+(j)*la2+(k))      
-
-typedef struct {
-  int local_nx,local_x_start,local_ny_after_transpose;
-  int local_y_start_after_transpose;
-} t_parfft;
-
-typedef struct {
-    real *                 ptr;
-    bool                   bParallel;
-    real *                 workspace;    
-    int                    nx,ny,nz,la2r,la2c,la12r,la12c;
-    int                    nptr,nxyz;
-    gmx_fft_t              fft_setup;
-#ifdef GMX_MPI
-    gmx_parallel_3dfft_t   mpi_fft_setup;
-    t_parfft               pfft;
-#endif
-} t_fftgrid;
-
-extern t_fftgrid *mk_fftgrid(int          nx,
-                             int          ny,
-                             int          nz,
-                             int          *node2slab,
-                            int          *slab2grid_x,
-                             t_commrec *  cr,
-                             bool         bReproducible);
-
-/* Create an FFT grid (1 Dimensional), to be indexed by the INDEX macro 
- * Setup FFT plans and extract local sizes for the grid.
- * If the file pointer is given, information is printed to it.
- * If cr is non-NULL and cr->nnodes>1, a parallel grid and FFT will be created.
- * The node2slab array translates to node ids to slab indices,
- * when NULL the slab ids are assumed to be identical to the node ids.
- * The slab2grid_x array determines which grid x-indices beling to which slab
- * (array size nnodes+1), when NULL this is determined automatically.
- * Set bReproducible to avoid FFTW timing and other optimizations that
- * could affect reproducibility of simulations.
- */
-
-extern void pr_fftgrid(FILE *fp,char *title,t_fftgrid *grid);
-/* Dump a grid to a file */
-
-extern void done_fftgrid(t_fftgrid *grid);
-/* And throw it away again */
-
-extern void gmxfft3D(t_fftgrid *grid,enum gmx_fft_direction dir,t_commrec *cr);
-/* Do the FFT, direction may be either 
- * FFTW_FORWARD (sign -1) for real -> complex transform 
- * FFTW_BACKWARD (sign 1) for complex -> real transform
- */
-extern void clear_fftgrid(t_fftgrid *grid);
-/* Set it to zero */
-
-extern void unpack_fftgrid(t_fftgrid *grid,int *nx,int *ny,int *nz,
-                          int *nx2,int *ny2,int *nz2,
-                          int *la2, int *la12,bool bReal, real **ptr);
-
-/* Get the values for the constants into local copies */
-
-
-
-
-/************************************************************************
- * 
- * For backward compatibility (for testing the ewald code vs. PPPM etc)
- * some old grid routines are retained here.
- *
- ************************************************************************/
-extern real ***mk_rgrid(int nx,int ny,int nz);
-
-extern void free_rgrid(real ***grid,int nx,int ny);
-
-extern real print_rgrid(FILE *fp,char *title,int nx,int ny,int nz,
-                       real ***grid);
-
-extern void print_rgrid_pdb(char *fn,int nx,int ny,int nz,real ***grid);
-
-extern t_complex ***mk_cgrid(int nx,int ny,int nz);
-
-extern void free_cgrid(t_complex ***grid,int nx,int ny);
-
-extern t_complex print_cgrid(FILE *fp,char *title,int nx,int ny,int nz,
-                          t_complex ***grid);
-
-extern void clear_cgrid(int nx,int ny,int nz,t_complex ***grid);
-
-extern void clear_rgrid(int nx,int ny,int nz,real ***grid);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
-
-
-
-
index 48e3fd08ba72871b5bb8e0b588c9d751f7b7213f..3f4bedaf07d2691e34b45a4509d29598102875ff 100644 (file)
@@ -261,6 +261,9 @@ gmx_wheel(int argc,char *argv[]);
 int 
 gmx_xpm2ps(int argc,char *argv[]);
 
+int 
+gmx_membed(int argc,char *argv[]);
+
 #ifdef __cplusplus
 }
 #endif
index 51eb6f2fc89c77d3aebee4b233c1ec2558664ad5..fc2ee7a119882a828196d8a210676c8df5cf682d 100644 (file)
 #include "typedefs.h"
 #include "xdrf.h"
 
-/* Note that some functions list beow are NOT THREADSAFE
- * when multiple threads use the same file pointer.
- */
-
-/* Highest number of open input/output files. This is usually limited to 1024 by the OS, anyway. */
-#define GMX_MAXFILES    1024
+/* types */
 
 /* Enumerated for different items in files */
 enum { eitemHEADER, eitemIR, eitemBOX, 
@@ -61,21 +56,17 @@ enum { eioREAL, eioDOUBLE, eioINT, eioGMX_LARGE_INT,
        eioUCHAR, eioNUCHAR, eioUSHORT,
        eioRVEC, eioNRVEC, eioIVEC, eioSTRING, eioNR };
 
-/* Functions for reading and writing data */
-typedef bool do_func(void *item,int nitem,int eio,
-                    const char *desc,const char *srcfile,int line);
-                    
-/* Global variables defined in gmxfio.h */
-extern do_func *do_read;
-extern do_func *do_write;
+typedef struct t_fileio t_fileio;
+
 extern const char *itemstr[eitemNR];
 extern const char *comment_str[eitemNR];
 
+
 /********************************************************
  * Open and Close 
  ********************************************************/
 
-int gmx_fio_open(const char *fn,const char *mode);
+t_fileio *gmx_fio_open(const char *fn,const char *mode);
 /* Open a new file for reading or writing.
  * The file type will be deduced from the file name.
  * If fn is NULL, stdin / stdout will be used for Ascii I/O (TPA type)
@@ -85,13 +76,13 @@ int gmx_fio_open(const char *fn,const char *mode);
  * unix, but is important on windows.
  */
  
-int gmx_fio_close(int fp);
+int gmx_fio_close(t_fileio *fp);
 /* Close the file corresponding to fp (if not stdio)
  * The routine will exit when an invalid fio is handled.
  * Returns 0 on success.
  */
 
-int gmx_fio_fp_close(int fp);
+int gmx_fio_fp_close(t_fileio *fp);
 /* Close the file corresponding to fp without closing the FIO entry
  * Needed e.g. for trxio because the FIO entries are used to store 
  * additional data.
@@ -100,79 +91,84 @@ int gmx_fio_fp_close(int fp);
  * Returns 0 on success.
  */
 
-void gmx_fio_select(int fp);
-/* This routine sets the global variables do_read and do_write
- * to point to the correct routines for fp.
- */
+
+/* Open a file, return a stream, record the entry in internal FIO object */
+FILE* gmx_fio_fopen(const char *fn,const char *mode);
+
+/* Close a file previously opened with gmx_fio_fopen. 
+ * Do not mix these calls with standard fopen/fclose ones!
+ * Returns 0 on success.  */
+int gmx_fio_fclose(FILE *fp);
+
+
 
 /********************************************************
  * Change properties of the open file
  ********************************************************/
 
-extern void gmx_fio_setprecision(int fio,bool bDouble);
+extern void gmx_fio_setprecision(t_fileio *fio,bool bDouble);
 /* Select the floating point precision for reading and writing files */
 
-extern char *gmx_fio_getname(int fio);
+extern char *gmx_fio_getname(t_fileio *fio);
 /* Return the filename corresponding to the fio index */
 
-extern int gmx_fio_getftp(int fio);
-/* Return the filetype corresponding to the fio index */
+extern int gmx_fio_getftp(t_fileio *fio);
+/* Return the filetype corresponding to the fio index. 
+    There is as of now no corresponding setftp function because the file
+    was opened as a specific file type and changing that midway is most 
+    likely an evil hack. */
 
-extern void gmx_fio_setftp_fio(int fio,int ftp);
-/* And set it */
-
-extern void gmx_fio_setdebug(int fio,bool bDebug);
+extern void gmx_fio_setdebug(t_fileio *fio,bool bDebug);
 /* Set the debug mode */
 
-extern bool gmx_fio_getdebug(int fio);
+extern bool gmx_fio_getdebug(t_fileio *fio);
 /* Return  whether debug mode is on in fio  */
 
-extern bool gmx_fio_getread(int fio);
+extern bool gmx_fio_getread(t_fileio *fio);
 /* Return  whether read mode is on in fio  */
 
+
+extern void gmx_fio_checktype(t_fileio *fio);
+/* Check whether the fio is of a sane type */
+
 /***************************************************
  * FILE Operations
  ***************************************************/
 
-extern void gmx_fio_rewind(int fio);
+extern void gmx_fio_rewind(t_fileio *fio);
 /* Rewind the tpa file in fio */
 
-int gmx_fio_flush(int fio);
+int gmx_fio_flush(t_fileio *fio);
 /* Flush the fio, returns 0 on success */
 
-int gmx_fio_fsync(int fio);
+int gmx_fio_fsync(t_fileio *fio);
 /* fsync the fio, returns 0 on success. 
    NOTE: don't use fsync function unless you're absolutely sure you need it
    because it deliberately interferes with the OS's caching mechanisms and
    can cause dramatically slowed down IO performance. Some OSes (Linux, 
    for example), may implement fsync as a full sync() point. */
 
-extern off_t gmx_fio_ftell(int fio);
+extern off_t gmx_fio_ftell(t_fileio *fio);
 /* Return file position if possible */
 
-extern int gmx_fio_seek(int fio,off_t fpos);
+extern int gmx_fio_seek(t_fileio *fio,off_t fpos);
 /* Set file position if possible, quit otherwise */
 
-extern FILE *gmx_fio_getfp(int fio);
+extern FILE *gmx_fio_getfp(t_fileio *fio);
 /* Return the file pointer itself */
 
-extern XDR *gmx_fio_getxdr(int fio);
+extern XDR *gmx_fio_getxdr(t_fileio *fio);
 /* Return the file pointer itself */
 
-/* Open a file, return a stream, record the entry in internal FIO object */
-FILE * gmx_fio_fopen(const char *fn,const char *mode);
 
-/* Close a file previously opened with gmx_fio_fopen. 
- * Do not mix these calls with standard fopen/fclose ones!
- * Returns 0 on success.
- */
-int gmx_fio_fclose(FILE *fp);
+
+
 
 /* Element with information about position in a currently open file.
  * off_t should be defined by autoconf if your system does not have it.
- * If you do not have it on some other platform you do not have largefile support
- * at all, and you can define it to int (or better, find out how to enable large files).
- */
+ * If you do not have it on some other platform you do not have largefile 
+ * support at all, and you can define it to int (or better, find out how to 
+ * enable large files).  */
 typedef struct
 {
        char      filename[STRLEN];
@@ -183,25 +179,22 @@ typedef struct
 gmx_file_position_t;
 
 
-/*
- * Check if the file position is out of the range of off_t.
+int gmx_fio_check_file_position(t_fileio *fio);
+/* Check if the file position is out of the range of off_t.
  * The result is stored along with the other file data of fio.
  */
-int
-gmx_fio_check_file_position(int fio);
 
-/*
- * Return the name and file pointer positions for all currently open
+int gmx_fio_get_output_file_positions(gmx_file_position_t ** outputfiles,
+                                      int *nfiles );
+/* Return the name and file pointer positions for all currently open
  * output files. This is used for saving in the checkpoint files, so we
  * can truncate output files upon restart-with-appending.
  *
  * For the first argument you should use a pointer, which will be set to
  * point to a list of open files.
  */
-int
-gmx_fio_get_output_file_positions (gmx_file_position_t ** outputfiles,
-                                   int *nfiles );
 
+int gmx_fio_all_output_fsync(void);
 /* fsync all open output files. This is used for checkpointing, where
    we need to ensure that all output is actually written out to 
    disk. 
@@ -209,136 +202,220 @@ gmx_fio_get_output_file_positions (gmx_file_position_t ** outputfiles,
    where data is not synced with the file server until close() or 
    fsync(), so data could remain in cache for days.
    Note the caveats reported with gmx_fio_fsync(). */
-int gmx_fio_all_output_fsync(void);
 
 
-int gmx_fio_get_file_md5(int fio, off_t offset,  unsigned char digest[]);
+int gmx_fio_get_file_md5(t_fileio *fio, off_t offset,  unsigned char digest[]);
 
 
-extern int xtc_seek_frame(int frame, int fio, int natoms);
+extern int xtc_seek_frame(t_fileio *fio, int frame, int natoms);
 
-extern int xtc_seek_time(real time, int fio, int natoms);
+extern int xtc_seek_time(t_fileio *fio, real time, int natoms);
 
        
-extern void set_comment(const char *comment);
 /* Add this to the comment string for debugging */
+extern void gmx_fio_set_comment(t_fileio *fio, const char *comment);
 
-extern void unset_comment(void);
 /* Remove previously set comment */
+extern void gmx_fio_unset_comment(t_fileio *fio);
+
+
 
 
 /********************************************************
- * Dirty C macros... Try this in FORTRAN 
- * (Oh, and you can do structured programming in C too) 
- *********************************************************/
-#define do_real(item)         (bRead ?\
-  do_read ((void *)&(item),1,eioREAL,(#item),__FILE__,__LINE__) : \
-  do_write((void *)&(item),1,eioREAL,(#item),__FILE__,__LINE__))
-
-#define do_double(item)         (bRead ?                                 \
-  do_read ((void *)&(item),1,eioDOUBLE,(#item),__FILE__,__LINE__) : \
-  do_write((void *)&(item),1,eioDOUBLE,(#item),__FILE__,__LINE__))
-#define do_int(item)          (bRead ?\
-  do_read ((void *)&(item),1,eioINT,(#item),__FILE__,__LINE__) :\
-  do_write((void *)&(item),1,eioINT,(#item),__FILE__,__LINE__))
+ * Read and write
+ ********************************************************/
+
+
+/* basic reading & writing */
+bool gmx_fio_reade_real(t_fileio *fio, real *item, 
+                        const char *desc, const char *srcfile, int line);
+bool gmx_fio_reade_double(t_fileio *fio, double *item, 
+                          const char *desc, const char *srcfile, int line);
+bool gmx_fio_reade_int(t_fileio *fio, int *item, 
+                       const char *desc, const char *srcfile, int line);
+bool gmx_fio_reade_gmx_large_int(t_fileio *fio, gmx_large_int_t *item, 
+                                 const char *desc, const char *srcfile, int line);
+bool gmx_fio_reade_uchar(t_fileio *fio, unsigned char *item, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_reade_ushort(t_fileio *fio, unsigned short *item, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_reade_rvec(t_fileio *fio, rvec *item, 
+                        const char *desc, const char *srcfile, int line);
+bool gmx_fio_reade_ivec(t_fileio *fio, ivec *item, 
+                        const char *desc, const char *srcfile, int line);
+bool gmx_fio_reade_string(t_fileio *fio, char *item, 
+                          const char *desc, const char *srcfile, int line);
+
+bool gmx_fio_writee_real(t_fileio *fio, real item, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_writee_double(t_fileio *fio, double item, 
+                           const char *desc, const char *srcfile, int line);
+bool gmx_fio_writee_int(t_fileio *fio, int item, 
+                        const char *desc, const char *srcfile, int line);
+bool gmx_fio_writee_gmx_large_int(t_fileio *fio, gmx_large_int_t item, 
+                                  const char *desc, const char *srcfile, int line);
+bool gmx_fio_writee_uchar(t_fileio *fio, unsigned char item, 
+                          const char *desc, const char *srcfile, int line);
+bool gmx_fio_writee_ushort(t_fileio *fio, unsigned short item, 
+                          const char *desc, const char *srcfile, int line);
+bool gmx_fio_writee_rvec(t_fileio *fio, rvec *item, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_writee_ivec(t_fileio *fio, ivec *item, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_writee_string(t_fileio *fio, const char *item, 
+                           const char *desc, const char *srcfile, int line);
+
+/* reading or writing, depending on the file's opening mode string */
+bool gmx_fio_doe_real(t_fileio *fio, real *item, 
+                      const char *desc, const char *srcfile, int line);
+bool gmx_fio_doe_double(t_fileio *fio, double *item, 
+                        const char *desc, const char *srcfile, int line);
+bool gmx_fio_doe_int(t_fileio *fio, int *item, 
+                     const char *desc, const char *srcfile, int line);
+bool gmx_fio_doe_gmx_large_int(t_fileio *fio, gmx_large_int_t *item, 
+                               const char *desc, const char *srcfile, int line);
+bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item, 
+                       const char *desc, const char *srcfile, int line);
+bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item, 
+                       const char *desc, const char *srcfile, int line);
+bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item, 
+                      const char *desc, const char *srcfile, int line);
+bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item, 
+                      const char *desc, const char *srcfile, int line);
+bool gmx_fio_doe_string(t_fileio *fio, char *item, 
+                        const char *desc, const char *srcfile, int line);
+
+
+
+
+/* array reading & writing */
+bool gmx_fio_nreade_real(t_fileio *fio, real *item, int n, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_nreade_double(t_fileio *fio, double *item, int n, 
+                           const char *desc, const char *srcfile, int line);
+bool gmx_fio_nreade_int(t_fileio *fio, int *item, int n, 
+                        const char *desc, const char *srcfile, int line);
+bool gmx_fio_nreade_gmx_large_int(t_fileio *fio, gmx_large_int_t *item, int n, 
+                                  const char *desc, const char *srcfile, 
+                                  int line);
+bool gmx_fio_nreade_uchar(t_fileio *fio, unsigned char *item, int n, 
+                          const char *desc, const char *srcfile, int line);
+bool gmx_fio_nreade_ushort(t_fileio *fio, unsigned short *item, int n, 
+                          const char *desc, const char *srcfile, int line);
+bool gmx_fio_nreade_rvec(t_fileio *fio, rvec *item, int n, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_nreade_ivec(t_fileio *fio, ivec *item, int n, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_nreade_string(t_fileio *fio, char *item[], int n, 
+                           const char *desc, const char *srcfile, int line);
+
+bool gmx_fio_nwritee_real(t_fileio *fio, const real *item, int n, 
+                          const char *desc, const char *srcfile, int line);
+bool gmx_fio_nwritee_double(t_fileio *fio, const double *item, int n, 
+                            const char *desc, const char *srcfile, int line);
+bool gmx_fio_nwritee_int(t_fileio *fio, const int *item, int n, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_nwritee_gmx_large_int(t_fileio *fio, 
+                                   const gmx_large_int_t *item, int n,
+                                   const char *desc, const char *srcfile, 
+                                   int line);
+bool gmx_fio_nwritee_uchar(t_fileio *fio, const unsigned char *item, int n, 
+                           const char *desc, const char *srcfile, int line);
+bool gmx_fio_nwritee_ushort(t_fileio *fio, const unsigned short *item, int n, 
+                           const char *desc, const char *srcfile, int line);
+bool gmx_fio_nwritee_rvec(t_fileio *fio, const rvec *item, int n, 
+                          const char *desc, const char *srcfile, int line);
+bool gmx_fio_nwritee_ivec(t_fileio *fio, const ivec *item, int n, 
+                          const char *desc, const char *srcfile, int line);
+bool gmx_fio_nwritee_string(t_fileio *fio, const char *item[], int n, 
+                            const char *desc, const char *srcfile, int line);
+
+bool gmx_fio_ndoe_real(t_fileio *fio, real *item, int n, 
+                       const char *desc, const char *srcfile, int line);
+bool gmx_fio_ndoe_double(t_fileio *fio, double *item, int n, 
+                         const char *desc, const char *srcfile, int line);
+bool gmx_fio_ndoe_int(t_fileio *fio, int *item, int n, 
+                      const char *desc, const char *srcfile, int line);
+bool gmx_fio_ndoe_gmx_large_int(t_fileio *fio, gmx_large_int_t *item, int n, 
+                                const char *desc, const char *srcfile, 
+                                int line);
+bool gmx_fio_ndoe_uchar(t_fileio *fio, unsigned char *item, int n, 
+                        const char *desc, const char *srcfile, int line);
+bool gmx_fio_ndoe_ushort(t_fileio *fio, unsigned short *item, int n, 
+                        const char *desc, const char *srcfile, int line);
+bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n, 
+                       const char *desc, const char *srcfile, int line);
+bool gmx_fio_ndoe_ivec(t_fileio *fio, ivec *item, int n, 
+                       const char *desc, const char *srcfile, int line);
+bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n, 
+                         const char *desc, const char *srcfile, int line);
+
+
+
+/* convenience macros */
+#define gmx_fio_read_real(fio, item)           gmx_fio_reade_real(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_read_double(fio, item)         gmx_fio_reade_double(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_read_int(fio, item)            gmx_fio_reade_int(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_read_gmx_large_int(fio, item)  gmx_fio_reade_gmx_large_int(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_read_uchar(fio, item)          gmx_fio_reade_uchar(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_read_ushort(fio, item)         gmx_fio_reade_ushort(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_read_rvec(fio, item)           gmx_fio_reade_rvec(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_read_ivec(fio, item)           gmx_fio_reade_ivec(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_read_string(fio, item)         gmx_fio_reade_string(fio, item, (#item), __FILE__, __LINE__)
+
+#define gmx_fio_write_real(fio, item)           gmx_fio_writee_real(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_write_double(fio, item)         gmx_fio_writee_double(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_write_int(fio, item)            gmx_fio_writee_int(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_write_gmx_large_int(fio, item)  gmx_fio_writee_gmx_large_int(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_write_uchar(fio, item)          gmx_fio_writee_uchar(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_write_ushort(fio, item)         gmx_fio_writee_ushort(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_write_rvec(fio, item)           gmx_fio_writee_rvec(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_write_ivec(fio, item)           gmx_fio_writee_ivec(fio, item, (#item), __FILE__, __LINE__)
+#define gmx_fio_write_string(fio, item)         gmx_fio_writee_string(fio, item, (#item), __FILE__, __LINE__)
+
+#define gmx_fio_do_real(fio, item)              gmx_fio_doe_real(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_double(fio, item)            gmx_fio_doe_double(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_int(fio, item)               gmx_fio_doe_int(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_gmx_large_int(fio, item)     gmx_fio_doe_gmx_large_int(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_uchar(fio, item)             gmx_fio_doe_uchar(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_ushort(fio, item)            gmx_fio_doe_ushort(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_rvec(fio, item)              gmx_fio_doe_rvec(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_ivec(fio, item)              gmx_fio_doe_ivec(fio, &item, (#item), __FILE__, __LINE__)
+#define gmx_fio_do_string(fio, item)            gmx_fio_doe_string(fio, item, (#item), __FILE__, __LINE__)
+
+
+
+
+#define gmx_fio_nread_real(fio, item, n)            gmx_fio_nreade_real(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nread_double(fio, item, n)          gmx_fio_nreade_double(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nread_int(fio, item, n)             gmx_fio_nreade_int(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nread_gmx_large_int(fio, item, n)   gmx_fio_nreade_gmx_large_int(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nread_uchar(fio, item, n)           gmx_fio_nreade_uchar(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nread_ushort(fio, item, n)          gmx_fio_nreade_ushort(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nread_rvec(fio, item, n)            gmx_fio_nreade_rvec(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nread_ivec(fio, item, n)            gmx_fio_nreade_ivec(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nread_string(fio, item, n)          gmx_fio_nreade_string(fio, item, n, (#item), __FILE__, __LINE__)
+
+#define gmx_fio_nwrite_real(fio, item, n)           gmx_fio_nwritee_real(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nwrite_double(fio, item, n)         gmx_fio_nwritee_double(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nwrite_int(fio, item, n)            gmx_fio_nwritee_int(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nwrite_gmx_large_int(fio, item, n)  gmx_fio_nwritee_gmx_large_int(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nwrite_uchar(fio, item, n)          gmx_fio_nwritee_uchar(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nwrite_ushort(fio, item, n)         gmx_fio_nwritee_ushort(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nwrite_rvec(fio, item, n)           gmx_fio_nwritee_rvec(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nwrite_ivec(fio, item, n)           gmx_fio_nwritee_ivec(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_nwrite_string(fio, item, n)         gmx_fio_nwritee_string(fio, item, n, (#item), __FILE__, __LINE__)
+
+#define gmx_fio_ndo_real(fio, item, n)              gmx_fio_ndoe_real(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_double(fio, item, n)            gmx_fio_ndoe_double(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_int(fio, item, n)               gmx_fio_ndoe_int(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_gmx_large_int(fio, item, n)     gmx_fio_ndoe_gmx_large_int(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_uchar(fio, item, n)             gmx_fio_ndoe_uchar(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_ushort(fio, item, n)            gmx_fio_ndoe_ushort(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_rvec(fio, item, n)              gmx_fio_ndoe_rvec(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_ivec(fio, item, n)              gmx_fio_ndoe_ivec(fio, item, n, (#item), __FILE__, __LINE__)
+#define gmx_fio_ndo_string(fio, item, n)            gmx_fio_ndoe_string(fio, item, n, (#item), __FILE__, __LINE__)
+
 
-#define do_gmx_large_int(item)          (bRead ?                       \
-  do_read ((void *)&(item),1,eioGMX_LARGE_INT,(#item),__FILE__,__LINE__) :\
-  do_write((void *)&(item),1,eioGMX_LARGE_INT,(#item),__FILE__,__LINE__))
-#define do_uchar(item)        (bRead ?\
-  do_read ((void *)&(item),1,eioUCHAR,(#item),__FILE__,__LINE__) :\
-  do_write((void *)&(item),1,eioUCHAR,(#item),__FILE__,__LINE__))
-
-#define do_nuchar(item,n)     (bRead ?\
-  do_read ((void *)(item),n,eioNUCHAR,(#item),__FILE__,__LINE__) :\
-  do_write((void *)(item),n,eioNUCHAR,(#item),__FILE__,__LINE__))
-  
-#define do_ushort(item)          (bRead ?\
-  do_read ((void *)&(item),1,eioUSHORT,(#item),__FILE__,__LINE__) :\
-  do_write((void *)&(item),1,eioUSHORT,(#item),__FILE__,__LINE__))
-  
-#define do_rvec(item)         (bRead ?\
-  do_read ((void *)(item),1,eioRVEC,(#item),__FILE__,__LINE__) :\
-  do_write((void *)(item),1,eioRVEC,(#item),__FILE__,__LINE__))
-  
-#define do_ivec(item)         (bRead ?\
-  do_read ((void *)(item),1,eioIVEC,(#item),__FILE__,__LINE__) :\
-  do_write((void *)(item),1,eioIVEC,(#item),__FILE__,__LINE__))
-  
-#define do_string(item)       (bRead ?\
-  do_read ((void *)(item),1,eioSTRING,(#item),__FILE__,__LINE__) :\
-  do_write((void *)(item),1,eioSTRING,(#item),__FILE__,__LINE__))
-  
-#define ndo_real(item,n,bOK) {\
-  bOK=TRUE;\
-  for(i=0; (i<n); i++) {\
-    char buf[128];\
-    sprintf(buf,"%s[%d]",#item,i);\
-    bOK = bOK && (bRead ?\
-      do_read ((void *)&((item)[i]),1,eioREAL,buf,__FILE__,__LINE__):\
-      do_write((void *)&(item[i]),1,eioREAL,buf,__FILE__,__LINE__));\
-  }\
-}
-
-#define ndo_double(item,n,bOK) {\
-  bOK=TRUE;\
-  for(i=0; (i<n); i++) {\
-    char buf[128];\
-    sprintf(buf,"%s[%d]",#item,i);\
-    bOK = bOK && (bRead ?\
-      do_read ((void *)&((item)[i]),1,eioDOUBLE,buf,__FILE__,__LINE__):\
-      do_write((void *)&(item[i]),1,eioDOUBLE,buf,__FILE__,__LINE__));\
-  }\
-}
-     
-#define ndo_int(item,n,bOK)  {\
-  bOK=TRUE;\
-  for(i=0; (i<n); i++) {\
-    char buf[128];\
-    sprintf(buf,"%s[%d]",#item,i);\
-    bOK = bOK && (bRead ?\
-      do_read ((void *)&(item[i]),1,eioINT,buf,__FILE__,__LINE__):\
-      do_write((void *)&(item[i]),1,eioINT,buf,__FILE__,__LINE__));\
-  }\
-}
-
-#define ndo_nuchar(item,n,bOK)  {\
-  bOK=TRUE;\
-  for(i=0; (i<n); i++) {\
-    char buf[128];\
-    sprintf(buf,"%s[%d]",#item,i);\
-    bOK = bOK && (bRead ?\
-      do_read ((void *)&(item[i]),1,eioNUCHAR,buf,__FILE__,__LINE__):\
-      do_write((void *)&(item[i]),1,eioNUCHAR,buf,__FILE__,__LINE__));\
-  }\
-}
-  
-#define ndo_rvec(item,n)      (bRead ?\
-  do_read ((void *)(item),n,eioNRVEC,(#item),__FILE__,__LINE__) :\
-  do_write((void *)(item),n,eioNRVEC,(#item),__FILE__,__LINE__))
-  
-#define ndo_ivec(item,n,bOK) {\
-  bOK=TRUE;\
-  for(i=0; (i<n); i++) {\
-    char buf[128];\
-    sprintf(buf,"%s[%d]",#item,i);\
-    bOK = bOK && (bRead ?\
-      do_read ((void *)(item)[i],1,eioIVEC,buf,__FILE__,__LINE__):\
-      do_write((void *)(item)[i],1,eioIVEC,buf,__FILE__,__LINE__));\
-  }\
-}
-  
-#define ndo_string(item,n,bOK) {\
-  bOK=TRUE;\
-  for(i=0; (i<n); i++) {\
-    char buf[128];\
-    sprintf(buf,"%s[%d]",#item,i);\
-    bOK = bOK && (bRead ?\
-      do_read ((void *)(item)[i],1,eioSTRING,buf,__FILE__,__LINE__):\
-      do_write((void *)(item)[i],1,eioSTRING,buf,__FILE__,__LINE__));\
-  }\
-}
 
 #endif
index 007f00dbe32c83aeefc6ca932187347360c8e22f..a233dd282eb1940512d82f1d776c0e2dd8e18f20 100644 (file)
@@ -126,8 +126,8 @@ typedef struct {
 } gmx_runtime_t;
 
 typedef struct {
-  int  fp_trn;
-  int  fp_xtc;
+  t_fileio *fp_trn;
+  t_fileio *fp_xtc;
   int  xtc_prec;
   ener_file_t fp_ene;
   const char *fn_cpt;
index 09d6f4d6497a3b2eef44dddb75275dc380fb00a3..334c65fda251b9d96cd30d2b1abe99581aecc7c2 100644 (file)
@@ -66,7 +66,7 @@ typedef struct {
   t_dih     *dih;
   int       npp;
   t_phipsi  *pp;
-  int       traj;
+  t_trxstatus *traj;
   int       natoms;
   int       amin,amax;
   real      t;
index 9d81d315ec57ff42eb7e235639d0a57025368869..4aaa12185cc7480654bd8304b906b2785b59c2b4 100644 (file)
@@ -43,7 +43,6 @@
 #include <stdio.h>
 #include "typedefs.h"
 #include "gmxcomplex.h"
-#include "fftgrid.h"
 #include "gmx_wallcycle.h"
 
 #ifdef __cplusplus
@@ -93,9 +92,6 @@ extern int gmx_pmeonly(gmx_pme_t pme,
 /* Called on the nodes that do PME exclusively (as slaves) 
  */
 
-extern void gmx_sum_qgrid(gmx_pme_t pme,t_commrec *cr,t_fftgrid *grid,
-                         int direction);
-
 extern void gmx_pme_calc_energy(gmx_pme_t pme,int n,rvec *x,real *q,real *V);
 /* Calculate the PME grid energy V for n charges with a potential
  * in the pme struct determined before with a call to gmx_pme_do
index f27e1ec0cddf3b1a510d547710a7852c5181b65e..f2a4cee64fa46e8a2547b891dc9193752f5c4fae 100644 (file)
@@ -43,7 +43,6 @@
 #include <stdio.h>
 #include "typedefs.h"
 #include "gmxcomplex.h"
-#include "fftgrid.h"
 
 #ifdef __cplusplus
 extern "C" {
index 1cce2353114d841450e567a212d1faec5a82a817..6f1d8d7707d3c551c91f4f6301ece03e6b182463 100644 (file)
  * sfree(ptr)
  *    Frees memory referenced by ptr.
  *
+ * snew_aligned(ptr,nelem,alignment)
+ *    Allocates memory for nelem elements and returns this in ptr.
+ *    The allocated memory is initialized to zeroes.
+ *    alignment=n will constrain ptr to be n-byte aligned.
+ *    This pointer should only be freed with sfree_aligned, since
+ *    it may not be the value returned by the underlying malloc.
+ *
+ * sfree_aligned(ptr)
+ *    Frees aligned memory referenced by ptr.
+ *
  ****************************************************************************
  *
  * Functions which are used by the macro's:
  *    the sum of the previously allocated space. As mentioned with maxavail,
  *    it is important that free can undo the effect of a malloc.
  * 
+ * extern void *save_malloc_aligned(char *name,char *file,int line,size_t size,size_t alignment);
+ *    Like alloc, returns a pointer to the allocated space, uses name, file
+ *    and line to generate an error message when allocation failed.
+ *    The returned pointer will be n-byte aligned, where n=alignment.
+ *    The pointer should only be freed with a call to save_free.
+ *
+ * extern void save_free_aligned(char *name,char *file,int line, void *ptr);
+ *    Like free, uses name, file and line to generate an error message when 
+ *    the free failed. This function is intended to be called for
+ *    pointers allocated with save_malloc_aligned, and may not work
+ *    on normal pointers.
  */
 
 #ifdef __cplusplus
@@ -122,6 +143,12 @@ void save_free(const char *name,const char *file,int line, void *ptr);
 size_t maxavail(void);
 size_t memavail(void);
 
+/* Aligned-memory counterparts */
+
+void *save_calloc_aligned(char *name,char *file,int line,
+                         unsigned nelem,size_t elsize,size_t alignment); 
+void save_free_aligned(char *name,char *file,int line, void *ptr);
+
 #ifdef __cplusplus
 }
 
@@ -161,11 +188,18 @@ void _srealloc(const char *name, const char *file, int line, T *&ptr, size_t siz
 {
     ptr = (T *)save_realloc(name, file, line, ptr, size, sizeof(char));
 }
+template <typename T>
+void _snew_aligned(const char *name, const char *file, int line,
+                  T *&ptr, size_t nelem, size_t elsize,size_t alignment)
+{
+    ptr = (T *)save_calloc_aligned(name, file, line, nelem, elsize, alignment);
+}
 
 #define snew(ptr,nelem) _snew(#ptr,__FILE__,__LINE__,(ptr),(nelem),sizeof(*(ptr)))
 #define srenew(ptr,nelem) _srenew(#ptr,__FILE__,__LINE__,(ptr),(nelem),sizeof(*(ptr)))
 #define smalloc(ptr, size) _smalloc(#ptr,__FILE__,__LINE__,(ptr),(size))
 #define srealloc(ptr, size) _srealloc(#ptr,__FILE__,__LINE__,(ptr),(size))
+#define snew_aligned(ptr,nelem,alignment) _snew_aligned(#ptr,__FILE__,__LINE__,(ptr),(nelem),sizeof(*(ptr)),alignment)
 
 #else
 
@@ -179,8 +213,10 @@ void _srealloc(const char *name, const char *file, int line, T *&ptr, size_t siz
                (ptr)=save_calloc(#ptr,__FILE__,__LINE__,nelem,elsize)
 #define srealloc(ptr,size) (ptr)=save_realloc(#ptr,__FILE__,__LINE__,\
                        (ptr),size,1)
+#define snew_aligned(ptr,nelem,alignment) (ptr)=save_calloc_aligned(#ptr,__FILE__,__LINE__,(nelem),sizeof(*(ptr)),alignment)
 #endif
 
 #define sfree(ptr) save_free(#ptr,__FILE__,__LINE__,(ptr))
+#define sfree_aligned(ptr) save_free_aligned(#ptr,__FILE__,__LINE__,(ptr))
 
 #endif /* _smalloc_h */
diff --git a/include/statusio.h b/include/statusio.h
deleted file mode 100644 (file)
index 575a98b..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 
- *                This source code is part of
- * 
- *                 G   R   O   M   A   C   S
- * 
- *          GROningen MAchine for Chemical Simulations
- * 
- *                        VERSION 3.2.0
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
- * 
- * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- * 
- * For more info, check our website at http://www.gromacs.org
- * 
- * And Hey:
- * Gromacs Runs On Most of All Computer Systems
- */
-
-#ifndef _statusio_h
-#define _statusio_h
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "typedefs.h"
-#include "sheader.h"
-
-/*
- * This module handles status file io. All read and write operations from
- * and to a status file should use this functions to be independent of the
- * actual file layout (text versus binary file).
- */
-#ifdef __cplusplus
-extern "C" { 
-#endif
-
-extern size_t wr_status(FILE *fp,int step,real t,real lambda,
-                       t_inputrec *ir,rvec *box,rvec *vir,rvec *pres,
-                       int natoms,rvec *x,rvec *v,rvec *f,
-                       int nre,t_energy *e,t_topology *top);
-/*
- * Writes a complete status to the file, specified by fp. NULL pointers
- * indicate that this field should not be written. The function returns
- * the number of bytes written.
- */
-
-extern char *rd_hstatus(FILE *fp,t_statheader *sh,int *step,real *t,
-                        real *lambda,t_inputrec *ir,rvec *box,
-                       rvec *vir,rvec *pres,int *natoms,
-                        rvec *x,rvec *v,rvec *f,int *nre,t_energy *e,
-                        t_topology *top);
-/*
- * Reads a complete status from the file, specified by fp. It uses
- * the status header to find the items in the file, also the file
- * should be positioned right for reading the first item. The function
- * returns the version string from the header.
- */
-
-extern char *rd_status(FILE *fp,int *step,real *t,real *lambda,
-                       t_inputrec *ir,rvec *box,rvec *vir,rvec *pres,
-                      int *natoms,rvec *x,
-                       rvec *v,rvec *f,int *nre,t_energy *e,
-                       t_topology *top);
-/*
- * Reads a complete status from the file, specified by fp. First it
- * reads the header and then invokes rd_hstatus() to read the rest
- * of the status. It returns the version returned from rd_hstatus().
- */
-
-extern void write_status(char *fn,int step,real t,real lambda,t_inputrec *ir,
-                         rvec *box,rvec *vir,rvec *pres,
-                        int natoms,rvec *x,rvec *v,rvec *f,
-                         int nre,t_energy *e,t_topology *top);
-/*
- * Writes a complete status to the file, specified by fn. NULL pointers
- * indicate that this field should not be written.
- */
-
-extern char *read_status(char *fn,int *step,real *t,real *lambda,
-                         t_inputrec *ir,rvec *box,rvec *vir,rvec *pres,
-                        int *natoms,rvec *x,
-                         rvec *v,rvec *f,int *nre,t_energy *e,
-                         t_topology *top);
-/*
- * Reads a complete status from the file, specified by fn. It returns
- * the version returned from rd_hstatus().
- */
-
-extern void read_status_header(char *fn,t_statheader *header);
-/*
- * Reads a (status) header from the file, specified by fn. If
- * available, it returns the version string from the file, else
- * it returns a version string from the statusio module.
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _statusio_h */
index 44344c3a2a680526d40bd5f34726c42ef42918d2..e164d76adf6512575c2947b160227c27ac7777fe 100644 (file)
@@ -48,6 +48,7 @@
 #include "wman.h"
 #include "pdbio.h"
 #include "oenv.h"
+#include "gmxfio.h"
 
 
 #ifdef __cplusplus
@@ -71,10 +72,15 @@ extern real rTimeValue(int tcontrol);
 extern void setTimeValue(int tcontrol,real value);
 
 /* End trajectory time control */
+
+/* a dedicated status type contains fp, etc. */
+typedef struct t_trxstatus t_trxstatus;
   
-typedef int t_first_x(int *status,const char *fn,real *t,rvec **x,matrix box);
+typedef int t_first_x(t_trxstatus **status,const char *fn,real *t,rvec **x,
+                      matrix box);
 
-typedef bool t_next_x(int status,real *t,int natoms,rvec x[],matrix box);
+typedef bool t_next_x(t_trxstatus *status,real *t,int natoms,rvec x[],
+                      matrix box);
 
 /* I/O function types */
 
@@ -116,14 +122,14 @@ extern void clear_trxframe(t_trxframe *fr,bool bFirst);
 extern void set_trxframe_ePBC(t_trxframe *fr,int ePBC);
 /* Set the type of periodic boundary conditions, ePBC=-1 is not set */
 
-extern int nframes_read(void);
+extern int nframes_read(t_trxstatus *status);
 /* Returns the number of frames read from the trajectory */
 
-int write_trxframe_indexed(int status,t_trxframe *fr,int nind,atom_id *ind,
-                           gmx_conect gc);
+int write_trxframe_indexed(t_trxstatus *status,t_trxframe *fr,int nind,
+                           atom_id *ind, gmx_conect gc);
 /* Write an indexed frame to a TRX file, see write_trxframe. gc may be NULL */
 
-int write_trxframe(int status,t_trxframe *fr,gmx_conect gc);
+int write_trxframe(t_trxstatus *status,t_trxframe *fr,gmx_conect gc);
 /* Write a frame to a TRX file. 
  * Only entries for which the boolean is TRUE will be written,
  * except for step, time, lambda and/or box, which may not be
@@ -133,7 +139,7 @@ int write_trxframe(int status,t_trxframe *fr,gmx_conect gc);
  * gc is important for pdb file writing only and may be NULL.
  */
 
-int write_trx(int status,int nind,atom_id *ind,t_atoms *atoms,
+int write_trx(t_trxstatus *status,int nind,atom_id *ind,t_atoms *atoms,
               int step,real time,matrix box,rvec x[],rvec *v,
               gmx_conect gc);
 /* Write an indexed frame to a TRX file.
@@ -141,13 +147,17 @@ int write_trx(int status,int nind,atom_id *ind,t_atoms *atoms,
  * atoms can be NULL for file types which don't need atom names.
  */ 
 
-void close_trx(int status);
+void close_trx(t_trxstatus *status);
 /* Close trj file as opened with read_first_x, read_frist_frame
  * or open_trx. Identical to close_trj.
  */
 
-int open_trx(const char *outfile,const char *filemode);
-/* Open a TRX file and return the file number */
+t_trxstatus *open_trx(const char *outfile,const char *filemode);
+/* Open a TRX file and return the status number */
+
+/* get a fileio from a trxstatus */
+t_fileio *trx_get_fileio(t_trxstatus *status);
+
 
 extern bool bRmod_fd(double a, double b, double c,bool bDouble);
 /* Returns TRUE when (a - b) MOD c = 0, using a margin which is slightly
@@ -201,8 +211,8 @@ extern int check_times(real t);
 #define DATA_NOT_OK   (1<<1)
 #define FRAME_NOT_OK  (HEADER_NOT_OK | DATA_NOT_OK)
 
-extern int read_first_frame(const output_env_t oenv,int *status,const char *fn,
-                            t_trxframe *fr,int flags);
+extern int read_first_frame(const output_env_t oenv,t_trxstatus **status,
+                            const char *fn, t_trxframe *fr,int flags);
   /* Read the first frame which is in accordance with flags, which are
    * defined further up in this file. 
    * Returns natoms when succeeded, 0 otherwise.
@@ -211,32 +221,33 @@ extern int read_first_frame(const output_env_t oenv,int *status,const char *fn,
    * Returns TRUE when succeeded, FALSE otherwise.
    */
 
-extern bool read_next_frame(const output_env_t oenv,int status,t_trxframe *fr);
+extern bool read_next_frame(const output_env_t oenv,t_trxstatus *status,
+                            t_trxframe *fr);
   /* Reads the next frame which is in accordance with fr->flags.
    * Returns TRUE when succeeded, FALSE otherwise.
    */
 
-extern int read_first_x(const output_env_t oenv,int *status,const char *fn,
-                        real *t,rvec **x,matrix box);
+extern int read_first_x(const output_env_t oenv,t_trxstatus **status,
+                        const char *fn, real *t,rvec **x,matrix box);
 /* These routines read first coordinates and box, and allocates 
  * memory for the coordinates, for a trajectory file.
  * The routine returns the number of atoms, or 0 when something is wrong.
  * The integer in status should be passed to calls of read_next_x
  */
 
-extern bool read_next_x(const output_env_t oenv,int status,real *t,int natoms,
+extern bool read_next_x(const output_env_t oenv,t_trxstatus *status,real *t,int natoms,
                         rvec x[],matrix box);
 /* Read coordinates and box from a trajectory file. Return TRUE when all well,
  * or FALSE when end of file (or last frame requested by user).
  * status is the integer set in read_first_x.
  */
 
-extern void close_trj(int status);
+extern void close_trj(t_trxstatus *status);
 /* Close trj file as opened with read_first_x, read_frist_frame
  * or open_trx. Identical to close_trx.
  */
 
-extern void rewind_trj(int status);
+extern void rewind_trj(t_trxstatus *status);
 /* Rewind trj file as opened with read_first_x */
 
 extern t_topology *read_top(const char *fn,int *ePBC);
index 48bd7e35e12f2b977b7a8dafaa6669decb40746a..47ca78188f16eefdeb178f8a12e091be510e754a 100644 (file)
@@ -49,6 +49,7 @@
    *
    **************************************************************/
 #include "typedefs.h"
+#include "gmxfio.h"
 
 #ifdef __cplusplus 
 extern "C" {
@@ -81,11 +82,11 @@ typedef struct
  * but double and single precision can be read by either.
  */
 
-extern int open_tpx(const char *fn, const char *mode);
-/* Return an integer corresponding to the file you have just opened */
+extern t_fileio *open_tpx(const char *fn, const char *mode);
+/* Return an file pointer corresponding to the file you have just opened */
   
-extern void close_tpx(int fp);
-/*  Close the file corresponding to fp */
+extern void close_tpx(t_fileio *fio);
+/*  Close the file corresponding to fio */
   
 extern void read_tpxheader(const char *fn, t_tpxheader *tpx, bool TopOnlyOK,
                            int *version, int *generation);
@@ -136,8 +137,7 @@ extern bool read_tps_conf(const char *infile,char *title,t_topology *top,
  * else if bMass=TRUE, read the masses into top.atoms from the mass database.
  */
 
-void
-tpx_make_chain_identifiers(t_atoms *atoms,t_block *mols);
+void tpx_make_chain_identifiers(t_atoms *atoms,t_block *mols);
        
 #ifdef __cplusplus
 }
index 5e25e76a8a3784f9848feb71d3506d7eac66e06f..01ee5a0ad72d8dc97c4ec328bfab36dfaa1ff56b 100644 (file)
@@ -56,6 +56,7 @@
  **************************************************************/
        
 #include "typedefs.h"
+#include "gmxfio.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -83,13 +84,13 @@ typedef struct              /* This struct describes the order and the      */
   real lambda;         /* Current value of lambda                      */
 } t_trnheader;
 
-extern int open_trn(const char *fn,const char *mode);
+extern t_fileio *open_trn(const char *fn,const char *mode);
 /* Open a trj / trr file */
 
-extern void close_trn(int fp);
+extern void close_trn(t_fileio *fio);
 /* Close it */
 
-extern bool fread_trnheader(int fp,t_trnheader *trn,bool *bOK);
+extern bool fread_trnheader(t_fileio *fio,t_trnheader *trn,bool *bOK);
 /* Read the header of a trn file. Return FALSE if there is no frame.
  * bOK will be FALSE when the header is incomplete.
  */
@@ -106,18 +107,18 @@ extern bool is_trn(FILE *fp);
  * afterwards.
  */
 
-extern void fwrite_trn(int fp,int step,real t,real lambda,
+extern void fwrite_trn(t_fileio *fio,int step,real t,real lambda,
                       rvec *box,int natoms,rvec *x,rvec *v,rvec *f);
 /* Write a trn frame to file fp, box, x, v, f may be NULL */
 
-extern bool fread_htrn(int fp,t_trnheader *sh,
+extern bool fread_htrn(t_fileio *fio,t_trnheader *sh,
                       rvec *box,rvec *x,rvec *v,rvec *f);
 /* Extern read a frame except the header (that should be pre-read,
  * using routine read_trnheader, see above) from a trn file.
  * Return FALSE on error
  */
  
-extern bool fread_trn(int fp,int *step,real *t,real *lambda,
+extern bool fread_trn(t_fileio *fio,int *step,real *t,real *lambda,
                      rvec *box,int *natoms,rvec *x,rvec *v,rvec *f);
 /* Read a trn frame, including the header from fp. box, x, v, f may
  * be NULL, in which case the data will be skipped over.
index 56bd84bdf7ee15798518afbddf5335fb32e38cef..09aaa816b9b60ec98a93dec60fc78c3c6a3a9d4b 100644 (file)
@@ -41,44 +41,45 @@ extern "C" {
 #endif
 
 typedef struct {
-  int           nrQMatoms;      /* total nr of QM atoms              */
-  rvec          *xQM;           /* shifted to center of box          */  
-  int           *indexQM;       /* atom i = atom indexQM[i] in mdrun */
-  int           *atomicnumberQM;/* atomic numbers of QM atoms        */  
-  real          *QMcharges;     /* atomic charges of QM atoms(ONIOM) */
-  int           *shiftQM;
-  int           QMcharge;       /* charge of the QM system           */
-  int           multiplicity;   /* multipicity (no of unpaired eln)  */
-  int           QMmethod;       /* see enums.h for all methods       */
-  int           QMbasis;        /* see enums.h for all bases         */
-  int           nelectrons;     /* total number of elecs in QM region*/
-  bool          bTS;            /* Optimize a TS, only steep, no md  */
-  bool          bOPT;          /* Optimize QM subsys, only steep, no md  */
-  bool          *frontatoms;   /* qm atoms on the QM side of a QM-MM bond */
-  /* Gaussian specific stuff */
-  int           nQMcpus;        /* no. of CPUs used for the QM calc. */
-  int           QMmem;          /* memory for the gaussian calc.     */
-  int           accuracy;       /* convergence criterium (E(-x))     */
-  bool          cpmcscf;        /* using cpmcscf(l1003)*/
-  char          *gauss_dir;
-  char          *gauss_exe;
-  char          *devel_dir;
-  real          *c6;
-  real          *c12;
-  /* Surface hopping stuff */
-  bool          bSH;            /* surface hopping (diabatic only)   */
-  real          SAon;           /* at which energy gap the SA starts */
-  real          SAoff;          /* at which energy gap the SA stops  */
-  int           SAsteps;        /* stepwise switchinng on the SA     */
-  int           SAstep;         /* current state of SA               */
-  int           CIdim;
-  real          *CIvec1;
-  real          *CIvec2;
-  real          *CIvec1old;
-  real          *CIvec2old;
-  ivec          SHbasis;
-  int           CASelectrons;
-  int           CASorbitals;
+ int           nrQMatoms;      /* total nr of QM atoms              */
+ rvec          *xQM;           /* shifted to center of box          */  
+ int           *indexQM;       /* atom i = atom indexQM[i] in mdrun */
+ int           *atomicnumberQM;/* atomic numbers of QM atoms        */  
+ real          *QMcharges;     /* atomic charges of QM atoms(ONIOM) */
+ int           *shiftQM;
+ int           QMcharge;       /* charge of the QM system           */
+ int           multiplicity;   /* multipicity (no of unpaired eln)  */
+ int           QMmethod;       /* see enums.h for all methods       */
+ int           QMbasis;        /* see enums.h for all bases         */
+ int           nelectrons;     /* total number of elecs in QM region*/
+ bool          bTS;            /* Optimize a TS, only steep, no md  */
+ bool          bOPT;          /* Optimize QM subsys, only steep, no md  */
+ bool          *frontatoms;   /* qm atoms on the QM side of a QM-MM bond */
+ /* Gaussian specific stuff */
+ int           nQMcpus;        /* no. of CPUs used for the QM calc. */
+ int           QMmem;          /* memory for the gaussian calc.     */
+ int           accuracy;       /* convergence criterium (E(-x))     */
+ bool          cpmcscf;        /* using cpmcscf(l1003)*/
+ char          *gauss_dir;
+ char          *gauss_exe;
+ char          *devel_dir;
+ char          *orca_basename; /* basename for I/O with orca        */
+ real          *c6;
+ real          *c12;
+ /* Surface hopping stuff */
+ bool          bSH;            /* surface hopping (diabatic only)   */
+ real          SAon;           /* at which energy gap the SA starts */
+ real          SAoff;          /* at which energy gap the SA stops  */
+ int           SAsteps;        /* stepwise switchinng on the SA     */
+ int           SAstep;         /* current state of SA               */
+ int           CIdim;
+ real          *CIvec1;
+ real          *CIvec2;
+ real          *CIvec1old;
+ real          *CIvec2old;
+ ivec          SHbasis;
+ int           CASelectrons;
+ int           CASorbitals;
 } t_QMrec;
 
 typedef struct {
index 0c2f17b27736779bb1f9eb8e70dd9834a6cf08f6..54519a0f197a04159509379ccd68f979fe1e7fac 100644 (file)
@@ -264,11 +264,7 @@ extern void vecrecip(real in[],real out[],int n);
  * versions if your hardware supports it.
  *
  * To use those routines, your memory HAS TO BE CACHE-ALIGNED.
- * Start by allocating 31 bytes more than you need, put
- * this in a temp variable (e.g. _buf, so you can free it later), and
- * create your aligned array buf with
- * 
- *  buf=(real *) ( ( (unsigned long int)_buf + 31 ) & (~0x1f) );
+ * Use snew_aligned(ptr,size,32) to allocate and sfree_aligned to free.
  */
 
 
index b1b91592d2f854eebf8804ea450d4114ce4210af..f9f0df8aa014f020ad1fd047f9ccc2079b1d8d12 100644 (file)
@@ -36,7 +36,7 @@ typedef struct
     bool bV;
 } t_gmxvmdplugin;
     
-int read_first_vmd_frame(int *status,const char *fn, struct trxframe *fr,int flags);
+int read_first_vmd_frame(int  *status,const char *fn, struct trxframe *fr,int flags);
 bool read_next_vmd_frame(int status,struct trxframe *fr);
 int load_vmd_library(const char *fn, t_gmxvmdplugin *vmdplugin);
 
index c9fb61ac6082ce198f3763afb459315fe6db51bc..0b62dd222d2b07bd584aeb3a806e04f63f36cbd8 100644 (file)
 extern "C" {
 #endif
 
-int xdropen(XDR *xdrs, const char *filename, const char *type);
-
 
+/* THESE 3 FUNCTIONS (xdropen, xdrclose and xdr_get_fp) ARE NOW OBSOLETE 
+   AND ONLY PROVIDED FOR BACKWARD COMPATIBILITY OF 3D PARTY TOOLS. 
+   THEY SHOULD NOT BE USED ANYWHERE IN GROMACS ITSELF. 
+int xdropen(XDR *xdrs, const char *filename, const char *type);
 int xdrclose(XDR *xdrs);
+*/
 
-FILE * xdr_get_fp(int xdrid);
 
 
 /* Read or write reduced precision *float* coordinates */
-int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision);
+int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision, bool bRead);
 
 
 /* Read or write a *real* value (stored as float) */
@@ -75,7 +77,7 @@ int xdr_real(XDR *xdrs,real *r);
 
 
 /* Read or write reduced precision *real* coordinates */
-int xdr3drcoord(XDR *xdrs,real *fp,int *size,real *precision);
+int xdr3drcoord(XDR *xdrs,real *fp,int *size,real *precision, bool bRead);
 
 
 extern int xdr_gmx_large_int(XDR *xdrs,gmx_large_int_t *i,const char *warn);
index 8717e14ada0aed89f4b161f63b3ffe8c10aeea2a..56f0c924eb7191fff0eec9d08475c60faeabad31 100644 (file)
@@ -42,6 +42,7 @@
 
 
 #include "typedefs.h"
+#include "gmxfio.h"
 #include "xdrf.h"
 
 #ifdef __cplusplus
@@ -52,23 +53,23 @@ extern "C" {
  * bOK tells if a frame is not corrupted 
  */  
 
-extern int open_xtc(const char *filename,const char *mode);
+extern t_fileio *open_xtc(const char *filename,const char *mode);
 /* Open a file for xdr I/O */
   
-extern void close_xtc(int fp);
+extern void close_xtc(t_fileio *fio);
 /* Close the file for xdr I/O */
   
-extern int read_first_xtc(int fp,
+extern int read_first_xtc(t_fileio *fio,
                          int *natoms,int *step,real *time,
                          matrix box,rvec **x,real *prec,bool *bOK);
 /* Open xtc file, read xtc file first time, allocate memory for x */
 
-extern int read_next_xtc(int fp,
+extern int read_next_xtc(t_fileio *fio,
                         int natoms,int *step,real *time,
                         matrix box,rvec *x,real *prec,bool *bOK);
 /* Read subsequent frames */
 
-extern int write_xtc(int fp,
+extern int write_xtc(t_fileio *fio,
                     int natoms,int step,real time,
                     matrix box,rvec *x,real prec);
 /* Write a frame to xtc file */
index e1e23de9897ffff7ed5902b8f920013697adfce9..c814ad45fa49ae4a87aef48742537288d4d150db 100644 (file)
@@ -515,7 +515,8 @@ The grid dimensions are controlled by <b>fourierspacing</b>.
 Reasonable grid spacing for PPPM is 0.05-0.1 nm.
 See <tt>Shift</tt> for the details of the particle-particle potential.
 <br>
-NOTE: the pressure in incorrect when using PPPM.</dd>
+NOTE: PPPM is not functional in the current version, we plan to implement
+PPPM through a small modification of the PME code.</dd>
 
 <dt><b><!--Idx-->Reaction-Field<!--EIdx--></b></dt>
 <dd>Reaction field with Coulomb cut-off <b>rcoulomb</b>,
index 52d6dc5d0d788d4aca61304fd4c09bd462dd306d..e9954d0f23212367d09b9e3c266ceef8fc63b24c 100644 (file)
@@ -190,19 +190,6 @@ ON6B       15.999400 ;     Nucleic acid ribose ring oxygen  ### For DNA
 ON2B   15.999400 ;     Nucleic acid phosphate ester oxygen (pres tp1/tp2, toppar_tyr_ser_thr_phosphate.str)  ### For DNA 
 FN1    18.998400 ;     Fluorine for sugar derivatives (NF)  ### For DNA 
 FNA    18.998400 ;     Aromatic fluorine  ### For DNA 
-CC1A   12.011000 ;     alkene conjugation  ### For DNA 
-CC1B   12.011000 ;     alkene conjugation  ### For DNA 
-CC2    12.011000 ;     alkene conjugation  ### For DNA 
-NS1    14.007000 ;     N for deprotonated Schiff's base  ### For DNA 
-NS2    14.007000 ;     N for protonated Schiff's base  ### For DNA 
-SP     32.060000 ;     positive Sulphur, S-adenosylmethionine (SAM)  ### For DNA 
-CPH1   12.011000 ;     For imidazole model compound (NF) 
-CPH2   12.011000 ;     For imidazole model compound (NF) 
-HR3    1.008000 ;      For imidazole model compound (NF) 
-HR1    1.008000 ;      For imidazole model compound (NF) 
-NR1    14.007000 ;     For nitrogen in imidazol (NF) 
-NR2    14.007000 ;     For nitrogen in imidazol (NF) 
-
 OWT4   15.999400 ;     For TIP4P
 HWT4   1.008000 ;      For TIP4P
 MWT4   0.000000 ;      For TIP4P
index ad17079339ae40fd3ebbee682f345ef2e29dab75..9ddf5627c558fc474c5ad9a5edcf6603303431f9 100644 (file)
 /* Define to 1 if you have the memcmp() function. */
 #cmakedefine HAVE_MEMCMP
 
+/* Define to 1 if you have the posix_memalign() function. */
+#cmakedefine HAVE_POSIX_MEMALIGN
+
+/* Define to 1 if you have the memalign() function. */
+#cmakedefine HAVE_MEMALIGN
+
 /* Define to 1 if you have the gettimeofday() function. */
 #cmakedefine HAVE_GETTIMEOFDAY
 
index 1b6a831d3e53e83893563ad6391cdccf91c19857..82d803f2da55d10c48f4e6c51430c2aed4f9c56c 100644 (file)
@@ -73,7 +73,8 @@ libgmx@LIBSUFFIX@_la_SOURCES = \
        dihres.c        gmx_random_gausstable.h         \
        tcontrol.c      splitter.c      gmx_cyclecounter.c              \
        gmx_system_xdr.c md5.c vmdio.c vmddlopen.c      sighandler.c    \
-       oenv.c
+       oenv.c          gmxfio_rw.c     gmxfio_asc.c    gmxfio_bin.c    \
+       gmxfio_xdr.c
 
 pkgconfigdir = ${libdir}/pkgconfig
 pkgconfig_DATA = libgmx@LIBSUFFIX@.pc
index 3c943359e4a5507c9066c57a4b041a2d83e3293f..a1dde71fb8f5d33468c26b71366b09029dcc2fb5 100644 (file)
@@ -1035,7 +1035,7 @@ void write_checkpoint(const char *fn,FILE *fplog,t_commrec *cr,
                       int eIntegrator,int simulation_part,
                       gmx_large_int_t step,double t,t_state *state)
 {
-    int  fp;
+    t_fileio *fp;
     int  file_version;
     char *version;
     char *btime;
@@ -1305,7 +1305,8 @@ static void read_checkpoint(const char *fn,FILE **pfplog,
                             t_state *state,bool *bReadRNG,bool *bReadEkin,
                             int *simulation_part,bool bAppendOutputFiles)
 {
-    int  fp,i,j,rc;
+    t_fileio *fp;
+    int  i,j,rc;
     int  file_version;
     char *version,*btime,*buser,*bmach,*fprog,*ftime;
        char filename[STRLEN],buf[STEPSTRSIZE];
@@ -1316,11 +1317,11 @@ static void read_checkpoint(const char *fn,FILE **pfplog,
     int  ret;
        gmx_file_position_t *outputfiles;
        int  nfiles;
-       int chksum_file;
+       t_fileio *chksum_file;
        FILE* fplog = *pfplog;
        unsigned char digest[16];
 #if !((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
-       struct flock fl = { F_WRLCK, SEEK_SET, 0,       0,     0 }; 
+       struct flock fl = { 0, SEEK_SET, 0,       F_WRLCK,     0 }; 
 #endif
        
     const char *int_warn=
@@ -1679,12 +1680,15 @@ void load_checkpoint(const char *fn,FILE **fplog,
       gmx_bcast(sizeof(*bReadEkin),bReadEkin,cr);
     }
     ir->bContinuation    = TRUE;
-    ir->nsteps          += ir->init_step - step;
+    if (ir->nsteps >= 0)
+    {
+        ir->nsteps          += ir->init_step - step;
+    }
     ir->init_step        = step;
        ir->simulation_part += 1;
 }
 
-static void read_checkpoint_data(int fp,int *simulation_part,
+static void read_checkpoint_data(t_fileio *fp,int *simulation_part,
                                  gmx_large_int_t *step,double *t,t_state *state,
                                  bool bReadRNG,
                                  int *nfiles,gmx_file_position_t **outputfiles)
@@ -1754,7 +1758,7 @@ void
 read_checkpoint_state(const char *fn,int *simulation_part,
                       gmx_large_int_t *step,double *t,t_state *state)
 {
-    int  fp;
+    t_fileio *fp;
     
     fp = gmx_fio_open(fn,"r");
     read_checkpoint_data(fp,simulation_part,step,t,state,TRUE,NULL,NULL);
@@ -1764,7 +1768,7 @@ read_checkpoint_state(const char *fn,int *simulation_part,
        }
 }
 
-void read_checkpoint_trxframe(int fp,t_trxframe *fr)
+void read_checkpoint_trxframe(t_fileio *fp,t_trxframe *fr)
 {
     t_state state;
     int simulation_part;
@@ -1808,7 +1812,7 @@ void read_checkpoint_trxframe(int fp,t_trxframe *fr)
 
 void list_checkpoint(const char *fn,FILE *out)
 {
-    int  fp;
+    t_fileio *fp;
     int  file_version;
     char *version,*btime,*buser,*bmach,*fprog,*ftime;
     int  eIntegrator,simulation_part,nppnodes,npme;
@@ -1874,7 +1878,7 @@ bool read_checkpoint_simulation_part(const char *filename, int *simulation_part,
                                      bool bAppendReq,
                                      const char *part_suffix,bool *bAddPart)
 {
-    int  fp;
+    t_fileio *fp;
     gmx_large_int_t step=0;
        double t;
     t_state state;
@@ -1887,7 +1891,7 @@ bool read_checkpoint_simulation_part(const char *filename, int *simulation_part,
     bAppend = FALSE;
 
     if (SIMMASTER(cr)) {
-        if(!gmx_fexist(filename) || ( (fp = gmx_fio_open(filename,"r")) < 0 ))
+        if(!gmx_fexist(filename) || (!(fp = gmx_fio_open(filename,"r")) ))
         {
             *simulation_part = 0;
         }
index c75503d744c61829fc2124a1799eb985e0d6a783..54edb6ed6fa826206ca52ac4c9d8b27dbf33cdf3 100644 (file)
@@ -65,7 +65,7 @@ typedef struct {
 struct ener_file
 {
     ener_old_t eo;
-    int fp;
+    t_fileio *fio;
     int framenr;
     real frametime;
 };
@@ -147,13 +147,13 @@ void do_enxnms(ener_file_t ef,int *nre,gmx_enxnm_t **nms)
 {
     int  magic=-55555;
     XDR  *xdr;
-    bool bRead = gmx_fio_getread(ef->fp);
+    bool bRead = gmx_fio_getread(ef->fio);
     int  file_version;
     int  i;
-    
-    gmx_fio_select(ef->fp);
+   
+    gmx_fio_checktype(ef->fio); 
 
-    xdr = gmx_fio_getxdr(ef->fp);
+    xdr = gmx_fio_getxdr(ef->fio);
     
     if (!xdr_int(xdr,&magic))
     {
@@ -185,7 +185,7 @@ void do_enxnms(ener_file_t ef,int *nre,gmx_enxnm_t **nms)
         xdr_int(xdr,&file_version);
         if (file_version > enx_version)
         {
-            gmx_fatal(FARGS,"reading tpx file (%s) version %d with version %d program",gmx_fio_getname(ef->fp),file_version,enx_version);
+            gmx_fatal(FARGS,"reading tpx file (%s) version %d with version %d program",gmx_fio_getname(ef->fio),file_version,enx_version);
         }
         xdr_int(xdr,nre);
     }
@@ -204,7 +204,7 @@ static bool do_eheader(ener_file_t ef,int *file_version,t_enxframe *fr,
     int  magic=-7777777;
     real r;
     int  block,i,zero=0,dum=0;
-    bool bRead = gmx_fio_getread(ef->fp);
+    bool bRead = gmx_fio_getread(ef->fio);
     int  tempfix_nr=0;
     
     if (nre_test >= 0)
@@ -224,7 +224,7 @@ static bool do_eheader(ener_file_t ef,int *file_version,t_enxframe *fr,
      * number of blocks, where this number is read before).
      */
     r = -2e10;
-    if (!do_real(r))
+    if (!gmx_fio_do_real(ef->fio, r))
     {
         return FALSE;
     }
@@ -233,44 +233,44 @@ static bool do_eheader(ener_file_t ef,int *file_version,t_enxframe *fr,
         /* Assume we are reading an old format */
         *file_version = 1;
         fr->t = r;
-        if (!do_int(dum))   *bOK = FALSE;
+        if (!gmx_fio_do_int(ef->fio, dum))   *bOK = FALSE;
         fr->step = dum;
     }
     else
     {
-        if (!do_int(magic))       *bOK = FALSE;
+        if (!gmx_fio_do_int(ef->fio, magic))       *bOK = FALSE;
         if (magic != -7777777)
         {
             gmx_fatal(FARGS,"Energy header magic number mismatch, this is not a GROMACS edr file");
         }
         *file_version = enx_version;
-        if (!do_int (*file_version)) *bOK = FALSE;
+        if (!gmx_fio_do_int(ef->fio, *file_version)) *bOK = FALSE;
         if (*bOK && *file_version > enx_version)
         {
-            gmx_fatal(FARGS,"reading tpx file (%s) version %d with version %d program",gmx_fio_getname(ef->fp),file_version,enx_version);
+            gmx_fatal(FARGS,"reading tpx file (%s) version %d with version %d program",gmx_fio_getname(ef->fio),file_version,enx_version);
         }
-        if (!do_double(fr->t))       *bOK = FALSE;
-        if (!do_gmx_large_int(fr->step)) *bOK = FALSE;
+        if (!gmx_fio_do_double(ef->fio, fr->t))       *bOK = FALSE;
+        if (!gmx_fio_do_gmx_large_int(ef->fio, fr->step)) *bOK = FALSE;
         if (!bRead && fr->nsum == 1) {
             /* Do not store sums of length 1,
              * since this does not add information.
              */
-            if (!do_int (zero))      *bOK = FALSE;
+            if (!gmx_fio_do_int(ef->fio, zero))      *bOK = FALSE;
         } else {
-            if (!do_int (fr->nsum))  *bOK = FALSE;
+            if (!gmx_fio_do_int(ef->fio, fr->nsum))  *bOK = FALSE;
         }
         if (*file_version >= 3)
         {
-            do_gmx_large_int(fr->nsteps);
+            gmx_fio_do_gmx_large_int(ef->fio, fr->nsteps);
         }
         else
         {
             fr->nsteps = max(1,fr->nsum);
         }
     }
-    if (!do_int (fr->nre))     *bOK = FALSE;
-    if (!do_int (fr->ndisre))  *bOK = FALSE;
-    if (!do_int (fr->nblock))  *bOK = FALSE;
+    if (!gmx_fio_do_int(ef->fio, fr->nre))     *bOK = FALSE;
+    if (!gmx_fio_do_int(ef->fio, fr->ndisre))  *bOK = FALSE;
+    if (!gmx_fio_do_int(ef->fio, fr->nblock))  *bOK = FALSE;
 
     /* Frames could have nre=0, so we can not rely only on the fr->nre check */
     if (bRead && nre_test >= 0 &&
@@ -294,15 +294,15 @@ static bool do_eheader(ener_file_t ef,int *file_version,t_enxframe *fr,
     }
     for(block=0; block<fr->nblock; block++)
     {
-        if (!do_int (fr->nr[block])) 
+        if (!gmx_fio_do_int(ef->fio, fr->nr[block])) 
         {
             *bOK = FALSE;
         }
     }
-    if (!do_int (fr->e_size))  *bOK = FALSE;
-    if (!do_int (fr->d_size))  *bOK = FALSE;
+    if (!gmx_fio_do_int(ef->fio, fr->e_size))  *bOK = FALSE;
+    if (!gmx_fio_do_int(ef->fio, fr->d_size))  *bOK = FALSE;
     /* Do a dummy int to keep the format compatible with the old code */
-    if (!do_int (dum))         *bOK = FALSE;
+    if (!gmx_fio_do_int(ef->fio, dum))         *bOK = FALSE;
     
     if (*bOK && *file_version == 1 && nre_test < 0)
     {
@@ -343,7 +343,7 @@ void free_enxnms(int n,gmx_enxnm_t *nms)
 
 void close_enx(ener_file_t ef)
 {
-    if(gmx_fio_close(ef->fp) != 0)
+    if(gmx_fio_close(ef->fio) != 0)
     {
         gmx_file("Cannot close energy file; it might be corrupt, or maybe you are out of quota?");  
     }
@@ -377,9 +377,9 @@ ener_file_t open_enx(const char *fn,const char *mode)
     snew(ef,1);
 
     if (mode[0]=='r') {
-        ef->fp=gmx_fio_open(fn,mode);
-        gmx_fio_select(ef->fp);
-        gmx_fio_setprecision(ef->fp,FALSE);
+        ef->fio=gmx_fio_open(fn,mode);
+        gmx_fio_checktype(ef->fio);
+        gmx_fio_setprecision(ef->fio,FALSE);
         do_enxnms(ef,&nre,&nms);
         snew(fr,1);
         do_eheader(ef,&file_version,fr,nre,&bWrongPrecision,&bDum);
@@ -401,9 +401,9 @@ ener_file_t open_enx(const char *fn,const char *mode)
         }
         else
         {
-            gmx_fio_rewind(ef->fp);
-            gmx_fio_select(ef->fp);
-            gmx_fio_setprecision(ef->fp,TRUE);
+            gmx_fio_rewind(ef->fio);
+            gmx_fio_checktype(ef->fio);
+            gmx_fio_setprecision(ef->fio,TRUE);
             do_enxnms(ef,&nre,&nms);
             do_eheader(ef,&file_version,fr,nre,&bWrongPrecision,&bDum);
             if(!bDum)
@@ -430,10 +430,10 @@ ener_file_t open_enx(const char *fn,const char *mode)
         }
         free_enxframe(fr);
         sfree(fr);
-        gmx_fio_rewind(ef->fp);
+        gmx_fio_rewind(ef->fio);
     }
     else 
-        ef->fp = gmx_fio_open(fn,mode);
+        ef->fio = gmx_fio_open(fn,mode);
 
     ef->framenr=0;
     ef->frametime=0;
@@ -441,9 +441,9 @@ ener_file_t open_enx(const char *fn,const char *mode)
     return ef;
 }
 
-int enx_file_pointer(const ener_file_t ef)
+t_fileio *enx_file_pointer(const ener_file_t ef)
 {
-    return ef->fp;
+    return ef->fio;
 }
 
 static void convert_full_sums(ener_old_t *ener_old,t_enxframe *fr)
@@ -519,15 +519,15 @@ bool do_enx(ener_file_t ef,t_enxframe *fr)
     char      buf[22];
     
     bOK = TRUE;
-    bRead = gmx_fio_getread(ef->fp);
+    bRead = gmx_fio_getread(ef->fio);
     if (!bRead)
     {  
         fr->e_size = fr->nre*sizeof(fr->ener[0].e)*4;
         fr->d_size = fr->ndisre*(sizeof(fr->disre_rm3tav[0]) + 
                                  sizeof(fr->disre_rt[0]));
     }
-    gmx_fio_select(ef->fp);
-    
+    gmx_fio_checktype(ef->fio);
+
     if (!do_eheader(ef,&file_version,fr,-1,NULL,&bOK))
     {
         if (bRead)
@@ -568,7 +568,7 @@ bool do_enx(ener_file_t ef,t_enxframe *fr)
     if (!((fr->step >= 0) && bSane))
     {
         fprintf(stderr,"\nWARNING: there may be something wrong with energy file %s\n",
-                gmx_fio_getname(ef->fp));
+                gmx_fio_getname(ef->fio));
         fprintf(stderr,"Found: step=%s, nre=%d, ndisre=%d, nblock=%d, time=%g.\n"
                 "Trying to skip frame expect a crash though\n",
                 gmx_step_str(fr->step,buf),fr->nre,fr->ndisre,fr->nblock,fr->t);
@@ -587,7 +587,7 @@ bool do_enx(ener_file_t ef,t_enxframe *fr)
     
     for(i=0; i<fr->nre; i++)
     {
-        bOK = bOK && do_real(fr->ener[i].e);
+        bOK = bOK && gmx_fio_do_real(ef->fio, fr->ener[i].e);
         
         /* Do not store sums of length 1,
          * since this does not add information.
@@ -596,13 +596,13 @@ bool do_enx(ener_file_t ef,t_enxframe *fr)
             (bRead && fr->nsum > 0) || fr->nsum > 1)
         {
             tmp1 = fr->ener[i].eav;
-            bOK = bOK && do_real(tmp1);
+            bOK = bOK && gmx_fio_do_real(ef->fio, tmp1);
             if (bRead)
                 fr->ener[i].eav = tmp1;
             
             /* This is to save only in single precision (unless compiled in DP) */
             tmp2 = fr->ener[i].esum;
-            bOK = bOK && do_real(tmp2);
+            bOK = bOK && gmx_fio_do_real(ef->fio, tmp2);
             if (bRead)
                 fr->ener[i].esum = tmp2;
             
@@ -610,7 +610,7 @@ bool do_enx(ener_file_t ef,t_enxframe *fr)
             {
                 /* Old, unused real */
                 rdum = 0;
-                bOK = bOK && do_real(rdum);
+                bOK = bOK && gmx_fio_do_real(ef->fio, rdum);
             }
         }
     }
@@ -631,9 +631,9 @@ bool do_enx(ener_file_t ef,t_enxframe *fr)
             srenew(fr->disre_rt,fr->ndisre);
             fr->d_alloc = fr->ndisre;
         }
-        ndo_real(fr->disre_rm3tav,fr->ndisre,bOK1);
+        bOK1=gmx_fio_ndo_real(ef->fio, fr->disre_rm3tav,fr->ndisre);
         bOK = bOK && bOK1;
-        ndo_real(fr->disre_rt,fr->ndisre,bOK1);
+        bOK1=gmx_fio_ndo_real(ef->fio, fr->disre_rt,fr->ndisre);
         bOK = bOK && bOK1;
     }
     for(block=0; block<fr->nblock; block++)
@@ -643,13 +643,13 @@ bool do_enx(ener_file_t ef,t_enxframe *fr)
             srenew(fr->block[block],fr->nr[block]);
             fr->b_alloc[block] = fr->nr[block];
         }
-        ndo_real(fr->block[block],fr->nr[block],bOK1);
+        bOK1=gmx_fio_ndo_real(ef->fio, fr->block[block],fr->nr[block]);
         bOK = bOK && bOK1;
     }
     
     if(!bRead)
     {
-        if( gmx_fio_flush(ef->fp) != 0)
+        if( gmx_fio_flush(ef->fio) != 0)
         {
             gmx_file("Cannot write energy file; maybe you are out of quota?");
         }
index 0b6099d68012865c0f0764d43f9e81052e51499f..35856438a7800cf565fa08052e6a94f82ab5f558 100644 (file)
@@ -276,7 +276,7 @@ bool gmx_fexist(const char *fname)
     if (test == NULL) 
         return FALSE;
     else {
-        ffclose(test);
+        fclose(test);
         return TRUE;
     }
 }
index f40c290183669f912daadad0ff7a3b34f8eb7a97..938f74c685ca7df8695818d52e9eb711a5618260 100644 (file)
@@ -191,7 +191,7 @@ int cpp_open_file(const char *filenm,gmx_cpp_t *handle, char **cppopts)
 {
   gmx_cpp_t cpp;
   char *buf,*pdum;
-  const char *ptr;
+  char *ptr;
   int i;
   unsigned int i1;
   
@@ -212,22 +212,51 @@ int cpp_open_file(const char *filenm,gmx_cpp_t *handle, char **cppopts)
   
   snew(cpp,1);
   *handle      = cpp;
-  ptr = strrchr(filenm,'/');
-  if (NULL == ptr) {
+  cpp->fn      = NULL;
+  /* Find the file. First check whether it is in the current directory. */
+  if (gmx_fexist(filenm))
+  {
+    cpp->fn = strdup(filenm);
+  }
+  else
+  {
+    /* If not, check all the paths given with -I. */
+    for (i = 0; i < nincl; ++i)
+    {
+      snew(buf, strlen(incl[i]) + strlen(filenm) + 2);
+      sprintf(buf, "%s%c%s", incl[i], DIR_SEPARATOR, filenm);
+      if (gmx_fexist(buf))
+      {
+        cpp->fn = buf;
+        break;
+      }
+      sfree(buf);
+    }
+    /* If still not found, check the Gromacs library search path. */
+    if (!cpp->fn)
+    {
+      cpp->fn = low_gmxlibfn(filenm, FALSE);
+    }
+  }
+  if (!cpp->fn)
+  {
+    gmx_fatal(FARGS, "Topology include file \"%s\" not found", filenm);
+  }
+  /* If the file name has a path component, we need to change to that
+   * directory. */
+  ptr = strrchr(cpp->fn, DIR_SEPARATOR);
+  if (!ptr)
+  {
     cpp->path = NULL;
     cpp->cwd  = NULL;
-    cpp->fn   = strdup(filenm);
   }
-  else {
-    buf = strdup(filenm);
-    buf[ptr-filenm] = '\0';
+  else
+  {
+    cpp->path = cpp->fn;
+    *ptr      = '\0';
     cpp->fn   = strdup(ptr+1);
     snew(cpp->cwd,STRLEN);
 
-    /* Search for the directory in cwd and the GROMACS search path */
-    cpp->path = gmxlibfn(buf);
-    sfree(buf);
-      
 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
       pdum=_getcwd(cpp->cwd,STRLEN);
       _chdir(cpp->path);
@@ -249,19 +278,8 @@ int cpp_open_file(const char *filenm,gmx_cpp_t *handle, char **cppopts)
   cpp->ifdefs  = NULL;
   cpp->child   = NULL;
   cpp->parent  = NULL;
-  i = 0;
-  while (((cpp->fp = fopen(cpp->fn,"r")) == NULL) && (i<nincl)) {
-    snew(buf,strlen(incl[i])+strlen(filenm)+2);
-    sprintf(buf,"%s/%s",incl[i],filenm);
-    sfree(cpp->fn);
-    cpp->fn = strdup(buf);
-    sfree(buf);
-    i++;
-  }
   if (cpp->fp == NULL) {
-    sfree(cpp->fn);
-    cpp->fn = strdup(filenm);
-    cpp->fp = libopen(filenm);
+    cpp->fp = fopen(cpp->fn, "r");
   }
   if (cpp->fp == NULL) {
     switch(errno) {
index 1bf52a12487305952eb10b0c9f4c17fb447999af..e011ed8a69884d90d637501e7d6c704666ff5f23 100644 (file)
 #include "thread_mpi.h"
 #endif
 
-/* The source code in this file should be thread-safe. 
- * But some functions are NOT THREADSAFE when multiple threads
- * use the same file pointer.
- * Please keep it that way.
- */
+#include "gmxfio_int.h"
+
+/* This is the new improved and thread safe version of gmxfio. */
 
-/* XDR should be available on all platforms now, 
- * but we keep the possibility of turning it off...
- */
-#define USE_XDR
 
-typedef struct
-{
-    int iFTP;
-    bool bOpen, bRead, bDouble, bDebug, bStdio;
-    char *fn;
-    FILE *fp;
-    XDR *xdr;
-    bool bLargerThan_off_t, bReadWrite;
-} t_fileio;
+
+/* the list of open files is a linked list, with a dummy element at its head; 
+       it is initialized when the first file is opened. */
+static t_fileio *open_files = NULL;
+
+
+#ifdef GMX_THREADS
+/* this mutex locks the open_files structure so that no two threads can 
+   modify it.        
+
+   For now, we use this as a coarse grained lock on all file 
+   insertion/deletion operations because it makes avoiding deadlocks 
+   easier, and adds almost no overhead . */
+static tMPI_Thread_mutex_t open_file_mutex=TMPI_THREAD_MUTEX_INITIALIZER;
+#endif
+
 
 /* These simple lists define the I/O type for these files */
 static const int ftpXDR[] =
@@ -90,7 +91,62 @@ static const int ftpXML[] =
     {   efXML};
 #endif
 
-bool in_ftpset(int ftp, int nset, const int set[])
+const char *itemstr[eitemNR] =
+    { "[header]", "[inputrec]", "[box]", "[topology]", "[coordinates]",
+                "[velocities]", "[forces]" };
+
+const char *eioNames[eioNR] =
+    { "REAL", "INT", "GMX_STE_T", "UCHAR", "NUCHAR", "USHORT", "RVEC", "NRVEC",
+                "IVEC", "STRING" };
+
+
+
+/* Comment strings for TPA only */
+const char *comment_str[eitemNR] = {
+"; The header holds information on the number of atoms etc. and on whether\n"
+"; certain items are present in the file or not.\n"
+"; \n"
+";                             WARNING\n"
+";                   DO NOT EDIT THIS FILE BY HAND\n"
+"; The GROMACS preprocessor performs a lot of checks on your input that\n"
+"; you ignore when editing this. Your simulation may crash because of this\n",
+"; The inputrec holds the parameters for MD such as the number of steps,\n"
+"; the timestep and the cut-offs.\n",
+"; The simulation box in nm.\n",
+"; The topology section describes the topology of the molecules\n"
+"; i.e. bonds, angles and dihedrals etc. and also holds the force field\n"
+"; parameters.\n", 
+"; The atomic coordinates in nm\n",
+"; The atomic velocities in nm/ps\n",
+"; The forces on the atoms in nm/ps^2\n" };
+
+
+
+
+/******************************************************************
+ *
+ * Internal functions: 
+ *
+ ******************************************************************/
+
+static int gmx_fio_int_flush(t_fileio* fio)
+{
+    int rc = 0;
+
+    if (fio->fp)
+    {
+        rc = fflush(fio->fp);
+    }
+    else if (fio->xdr)
+    {
+        rc = fflush((FILE *) fio->xdr->x_private);
+    }
+
+    return rc;
+}
+
+/* returns TRUE if the file type ftp is in the set set */
+static bool in_ftpset(int ftp, int nset, const int set[])
 {
     int i;
     bool bResult;
@@ -103,751 +159,288 @@ bool in_ftpset(int ftp, int nset, const int set[])
     return bResult;
 }
 
-static bool do_dummy(void *item, int nitem, int eio, const char *desc,
-                     const char *srcfile, int line)
-{
-    gmx_fatal(FARGS, "gmx_fio_select not called!");
 
-    return FALSE;
-}
 
-/* Global variables */
-do_func *do_read = do_dummy;
-do_func *do_write = do_dummy;
-const char *itemstr[eitemNR] =
-    { "[header]", "[inputrec]", "[box]", "[topology]", "[coordinates]",
-        "[velocities]", "[forces]" };
-/* Comment strings for TPA only */
-const char
-*comment_str[eitemNR] =
-    {
-        "; The header holds information on the number of atoms etc. and on whether\n"
-        "; certain items are present in the file or not.\n"
-        "; \n"
-        ";                             WARNING\n"
-        ";                   DO NOT EDIT THIS FILE BY HAND\n"
-        "; The GROMACS preprocessor performs a lot of checks on your input that\n"
-        "; you ignore when editing this. Your simulation may crash because of this\n",
-
-        "; The inputrec holds the parameters for MD such as the number of steps,\n"
-        "; the timestep and the cut-offs.\n",
-        "; The simulation box in nm.\n",
-        "; The topology section describes the topology of the molcecules\n"
-        "; i.e. bonds, angles and dihedrals etc. and also holds the force field\n"
-        "; parameters.\n", "; The atomic coordinates in nm\n",
-        "; The atomic velocities in nm/ps\n",
-        "; The forces on the atoms in nm/ps^2\n" };
-
-/* Local variables */
-static t_fileio *FIO = NULL;
-static t_fileio *curfio = NULL;
-static int nFIO = 0;
-static const char *eioNames[eioNR] =
-    { "REAL", "INT", "GMX_STE_T", "UCHAR", "NUCHAR", "USHORT", "RVEC", "NRVEC",
-        "IVEC", "STRING" };
-static char *add_comment = NULL;
+extern void gmx_fio_set_comment(t_fileio *fio, const char *comment)
+{
+    fio->comment=comment;
+}
 
-#ifdef GMX_THREADS
-static tMPI_Thread_mutex_t fio_mutex=TMPI_THREAD_MUTEX_INITIALIZER;
-/* this mutex locks concurrent access to the FIO and curfio arrays, the
- nFIO counter, and the add_comment string.  For now this is 
- the easiest way to make this all thread-safe. Because I/O is mostly
- done by the master node, this won't cause any performance issues 
- (locking/unlocking mutexes is very cheap as long as no thread get 
- scheduled out). */
-#endif
+extern void gmx_fio_unset_comment(t_fileio *fio)
+{
+    fio->comment=NULL;
+}
 
-/* these functions are all called from functions that lock the fio_mutex
- themselves, and need to make sure that the called function doesn't 
- try to lock that mutex again. */
-static int gmx_fio_flush_lock(int fio, bool do_lock);
-static int gmx_fio_fsync_lock(int fio, bool do_lock);
-static int gmx_fio_close_lock(int fio, bool do_lock);
-static bool do_xdr_lock(void *item, int nitem, int eio, const char *desc,
-                        const char *srcfile, int line, bool do_lock);
 
-static const char *dbgstr(const char *desc)
+const char *gmx_fio_dbgstr(t_fileio *fio, const char *desc, char *buf)
 {
-    static const char *null_str = "";
-    static char buf[STRLEN];
-
-    if (!curfio->bDebug)
+    if (!fio->bDebug)
     {
-        return null_str;
+        /* set to empty string */
+        buf[0]=0;
     }
     else
     {
-        sprintf(buf, "  ; %s %s", add_comment ? add_comment : "", desc);
-        return buf;
-    }
-}
-
-void set_comment(const char *comment)
-{
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    if (comment)
-        add_comment = strdup(comment);
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
+#if (defined( _WIN32 ) || defined( _WIN64 ) )
+        /* windows doesn't do standard C */
+#define snprintf sprintf_s
 #endif
+        snprintf(buf, GMX_FIO_BUFLEN, "  ; %s %s", 
+                 fio->comment ? fio->comment : "", desc);
+    }
+    return buf;
 }
 
-void unset_comment(void)
-{
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    if (add_comment)
-        sfree(add_comment);
-    add_comment = NULL;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-}
 
-static void _check_nitem(int eio, int nitem, const char *file, int line)
+/* check the number of items given against the type */
+void gmx_fio_check_nitem(t_fileio *fio, int eio, int nitem, const char *file, 
+                         int line)
 {
     if ((nitem != 1) && !((eio == eioNRVEC) || (eio == eioNUCHAR)))
-        gmx_fatal(FARGS, "nitem (%d) may differ from 1 only for %s or %s, not for %s"
+        gmx_fatal(FARGS, 
+                  "nitem (%d) may differ from 1 only for %s or %s, not   for %s"
                   "(%s, %d)",nitem,eioNames[eioNUCHAR],eioNames[eioNRVEC],
                   eioNames[eio],file,line);
 }
 
-#define check_nitem() _check_nitem(eio,nitem,__FILE__,__LINE__)
 
-static void fe(int eio, const char *desc, const char *srcfile, int line)
+/* output a data type error. */
+void gmx_fio_fe(t_fileio *fio, int eio, const char *desc, 
+                const char *srcfile, int line)
 {
 
     gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d",
-              curfio->bRead ? "read" : "write",desc,eio,
-                  ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown",
-                      srcfile,line);
+              fio->bRead ? "read" : "write",desc,eio,
+              ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown",
+              srcfile,line);
 }
 
-#define FE() fe(eio,desc,__FILE__,__LINE__)
 
-static void encode_string(int maxlen, char dst[], char src[])
+/* set the reader/writer functions based on the file type */
+static void gmx_fio_set_iotype(t_fileio *fio)
 {
-    int i;
-
-    for (i = 0; (src[i] != '\0') && (i < maxlen - 1); i++)
-        if ((src[i] == ' ') || (src[i] == '\t'))
-            dst[i] = '_';
-        else
-            dst[i] = src[i];
-    dst[i] = '\0';
-
-    if (i == maxlen)
-        fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
-}
-
-static void decode_string(int maxlen, char dst[], char src[])
-{
-    int i;
-
-    for (i = 0; (src[i] != '\0') && (i < maxlen - 1); i++)
+    if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR))
     {
-        if (src[i] == '_')
-        {
-            dst[i] = ' ';
-        }
-        else
-        {
-            dst[i] = src[i];
-        }
+#ifdef USE_XDR    
+        fio->iotp=&xdr_iotype;
+#else
+        gmx_fatal(FARGS,"Sorry, no XDR");
+#endif
     }
-    dst[i] = '\0';
-
-    if (i == maxlen)
+    else if (in_ftpset(fio->iFTP, asize(ftpASC), ftpASC))
+    {
+        fio->iotp=&asc_iotype;
+    }
+    else if (in_ftpset(fio->iFTP, asize(ftpBIN), ftpBIN))
     {
-        fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
+        fio->iotp=&bin_iotype;
     }
+#ifdef HAVE_XMl
+    else if (in_ftpset(fio->iFTP,asize(ftpXML),ftpXML))
+    {
+        fio->iotp=&dummy_iotype;
+    }
+#endif
+    else
+        fio->iotp=&dummy_iotype;
 }
 
-static bool do_ascwrite(void *item, int nitem, int eio, const char *desc,
-                        const char *srcfile, int line)
-{
-    int i;
-    int res = 0, *iptr;
-    real *ptr;
-    char strbuf[256];
-    unsigned char *ucptr;
 
+/* lock the mutex associated with this fio. This needs to be done for every
+   type of access to the fio's elements. */
+void gmx_fio_lock(t_fileio *fio)
+{
 #ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
+    tMPI_Spinlock_lock(&(fio->mtx));
 #endif
-    check_nitem();
-    switch (eio)
-    {
-    case eioREAL:
-    case eioDOUBLE:
-        res = fprintf(curfio->fp, "%18.10e%s\n", *((real *) item), dbgstr(desc));
-        break;
-    case eioINT:
-        res = fprintf(curfio->fp, "%18d%s\n", *((int *) item), dbgstr(desc));
-        break;
-    case eioGMX_LARGE_INT:
-        sprintf(strbuf, "%s%s%s", "%", gmx_large_int_fmt, "\n");
-        res = fprintf(curfio->fp, strbuf, *((gmx_large_int_t *) item),
-                      dbgstr(desc));
-        break;
-    case eioUCHAR:
-        res = fprintf(curfio->fp, "%4d%s\n", *((unsigned char *) item),
-                      dbgstr(desc));
-        break;
-    case eioNUCHAR:
-        ucptr = (unsigned char *) item;
-        for (i = 0; (i < nitem); i++)
-            res = fprintf(curfio->fp, "%4d", (int) ucptr[i]);
-        fprintf(curfio->fp, "%s\n", dbgstr(desc));
-        break;
-    case eioUSHORT:
-        res = fprintf(curfio->fp, "%18d%s\n", *((unsigned short *) item),
-                      dbgstr(desc));
-        break;
-    case eioRVEC:
-        ptr = (real *) item;
-        res = fprintf(curfio->fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
-                      ptr[YY], ptr[ZZ], dbgstr(desc));
-        break;
-    case eioNRVEC:
-        for (i = 0; (i < nitem); i++)
-        {
-            ptr = ((rvec *) item)[i];
-            res = fprintf(curfio->fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
-                          ptr[YY], ptr[ZZ], dbgstr(desc));
-        }
-        break;
-    case eioIVEC:
-        iptr = (int *) item;
-        res = fprintf(curfio->fp, "%18d%18d%18d%s\n", iptr[XX], iptr[YY],
-                      iptr[ZZ], dbgstr(desc));
-        break;
-    case eioSTRING:
-        encode_string(256, strbuf, (char *) item);
-        res = fprintf(curfio->fp, "%-18s%s\n", strbuf, dbgstr(desc));
-        break;
-    default:
-        FE();
-    }
-    if ((res <= 0) && curfio->bDebug)
-        fprintf(stderr,
-                "Error writing %s %s to file %s (source %s, line %d)\n",
-                eioNames[eio], desc, curfio->fn, srcfile, line);
+}
+/* unlock the mutex associated with this fio.  */
+void gmx_fio_unlock(t_fileio *fio)
+{
 #ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
+    tMPI_Spinlock_unlock(&(fio->mtx));
 #endif
-    return (res > 0);
 }
 
-/* This is a global variable that is reset when a file is opened. */
-/*static  int  nbuf=0;*/
-
-static char *next_item(FILE *fp, char *buf, int buflen)
+/* make a dummy head element, assuming we locked everything. */
+static void gmx_fio_make_dummy(void)
 {
-    int rd;
-    bool in_comment = FALSE;
-    bool in_token = FALSE;
-    int i = 0;
-    /* This routine reads strings from the file fp, strips comment
-     * and buffers. For thread-safety reasons, It reads through getc()  */
-
-    rd = getc(fp);
-    if (rd == EOF)
-        gmx_file("End of file");
-    do
+    if (!open_files)
     {
-        if (in_comment)
-        {
-            if (rd == '\n')
-                in_comment = FALSE;
-        }
-        else if (in_token)
-        {
-            if (isspace(rd) || rd == ';')
-                break;
-            buf[i++] = (char) rd;
-        }
-        else
-        {
-            if (!isspace(rd))
-            {
-                if (rd == ';')
-                    in_comment = TRUE;
-                else
-                {
-                    in_token = TRUE;
-                    buf[i++] = (char) (rd);
-                }
-            }
-        }
-        if (i >= buflen - 2)
-            break;
-    } while ((rd = getc(fp)) != EOF);
+        snew(open_files,1);
+        open_files->fp=NULL;
+        open_files->fn=NULL;
+        open_files->next=open_files;
+        open_files->prev=open_files;
+#ifdef GMX_THREADS
+        tMPI_Spinlock_init(&(open_files->mtx));
+#endif
+    }
+}
 
-    fprintf(stderr, "WARNING, ftpASC file type not tested!\n");
 
-    buf[i] = 0;
 
-    return buf;
-}
 
-static bool do_ascread(void *item, int nitem, int eio, const char *desc,
-                       const char *srcfile, int line)
-{
-    FILE *fp = curfio->fp;
-    int i, m, res = 0, *iptr, ix;
-    gmx_large_int_t s;
-    double d, x;
-    real *ptr;
-    unsigned char uc, *ucptr;
-    char *cptr;
-#define NEXT_ITEM_BUF_LEN 128
-    char ni_buf[NEXT_ITEM_BUF_LEN];
-
-    check_nitem();
-    switch (eio)
-    {
-    case eioREAL:
-    case eioDOUBLE:
-        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf", &d);
-        if (item)
-            *((real *) item) = d;
-        break;
-    case eioINT:
-        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
-        if (item)
-            *((int *) item) = i;
-        break;
-    case eioGMX_LARGE_INT:
-        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN),
-                     gmx_large_int_pfmt, &s);
-        if (item)
-            *((gmx_large_int_t *) item) = s;
-        break;
-    case eioUCHAR:
-        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%c", &uc);
-        if (item)
-            *((unsigned char *) item) = uc;
-        break;
-    case eioNUCHAR:
-        ucptr = (unsigned char *) item;
-        for (i = 0; (i < nitem); i++)
-        {
-            res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &ix);
-            if (item)
-                ucptr[i] = ix;
-        }
-        break;
-    case eioUSHORT:
-        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
-        if (item)
-            *((unsigned short *) item) = i;
-        break;
-    case eioRVEC:
-        ptr = (real *) item;
-        for (m = 0; (m < DIM); m++)
-        {
-            res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n", &x);
-            ptr[m] = x;
-        }
-        break;
-    case eioNRVEC:
-        for (i = 0; (i < nitem); i++)
-        {
-            ptr = ((rvec *) item)[i];
-            for (m = 0; (m < DIM); m++)
-            {
-                res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n",
-                             &x);
-                if (item)
-                    ptr[m] = x;
-            }
-        }
-        break;
-    case eioIVEC:
-        iptr = (int *) item;
-        for (m = 0; (m < DIM); m++)
-        {
-            res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d\n", &ix);
-            if (item)
-                iptr[m] = ix;
-        }
-        break;
-    case eioSTRING:
-        cptr = next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN);
-        if (item)
-        {
-            decode_string(strlen(cptr) + 1, (char *) item, cptr);
-            /* res = sscanf(cptr,"%s",(char *)item);*/
-            res = 1;
-        }
-        break;
-    default:
-        FE();
-    }
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    if ((res <= 0) && curfio->bDebug)
-        fprintf(stderr,
-                "Error reading %s %s from file %s (source %s, line %d)\n",
-                eioNames[eio], desc, curfio->fn, srcfile, line);
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    return (res > 0);
-}
 
-static bool do_binwrite(void *item, int nitem, int eio, const char *desc,
-                        const char *srcfile, int line)
-{
-    size_t size = 0, wsize;
-    int ssize;
 
-    check_nitem();
-    switch (eio)
-    {
-    case eioREAL:
-        size = sizeof(real);
-        break;
-    case eioDOUBLE:
-        size = sizeof(double);
-        break;
-    case eioINT:
-        size = sizeof(int);
-        break;
-    case eioGMX_LARGE_INT:
-        size = sizeof(gmx_large_int_t);
-        break;
-    case eioUCHAR:
-        size = sizeof(unsigned char);
-        break;
-    case eioNUCHAR:
-        size = sizeof(unsigned char);
-        break;
-    case eioUSHORT:
-        size = sizeof(unsigned short);
-        break;
-    case eioRVEC:
-        size = sizeof(rvec);
-        break;
-    case eioNRVEC:
-        size = sizeof(rvec);
-        break;
-    case eioIVEC:
-        size = sizeof(ivec);
-        break;
-    case eioSTRING:
-        size = ssize = strlen((char *) item) + 1;
-        do_binwrite(&ssize, 1, eioINT, desc, srcfile, line);
-        break;
-    default:
-        FE();
-    }
+/***********************************************************************
+ *
+ * FILE LIST OPERATIONS
+ *
+***********************************************************************/
 
-    wsize = fwrite(item, size, nitem, curfio->fp);
 
+/* insert a new t_fileio into the list */
+static void gmx_fio_insert(t_fileio *fio)
+{
+    t_fileio *prev;
 #ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    if ((wsize != nitem) && curfio->bDebug)
+    /* first lock the big open_files mutex. */
+    tMPI_Thread_mutex_lock(&open_file_mutex);
+#endif
+    /* now check whether the dummy element has been allocated, 
+       and allocate it if it hasn't */
+    gmx_fio_make_dummy();
+
+    /* and lock the fio we got and the list's head **/
+    gmx_fio_lock(fio);
+    gmx_fio_lock(open_files);
+    prev=open_files->prev;
+    /* lock the element after the current one */
+    if (prev != open_files)
     {
-        fprintf(stderr,
-                "Error writing %s %s to file %s (source %s, line %d)\n",
-                eioNames[eio], desc, curfio->fn, srcfile, line);
-        fprintf(stderr, "written size %u bytes, source size %u bytes\n",
-                (unsigned int) wsize, (unsigned int) size);
+        gmx_fio_lock(prev);
     }
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    return (wsize == nitem);
-}
 
-static bool do_binread(void *item, int nitem, int eio, const char *desc,
-                       const char *srcfile, int line)
-{
-    size_t size = 0, rsize;
-    int ssize;
+    /* now do the actual insertion: */
+    fio->next=open_files;
+    open_files->prev=fio;
+    prev->next=fio;
+    fio->prev=prev;
 
-    check_nitem();
-    switch (eio)
+    /* now unlock all our locks */
+    if (prev != open_files)
     {
-    case eioREAL:
-        if (curfio->bDouble)
-            size = sizeof(double);
-        else
-            size = sizeof(float);
-        break;
-    case eioDOUBLE:
-        size = sizeof(double);
-        break;
-    case eioINT:
-        size = sizeof(int);
-        break;
-    case eioGMX_LARGE_INT:
-        size = sizeof(gmx_large_int_t);
-        break;
-    case eioUCHAR:
-        size = sizeof(unsigned char);
-        break;
-    case eioNUCHAR:
-        size = sizeof(unsigned char);
-        break;
-    case eioUSHORT:
-        size = sizeof(unsigned short);
-        break;
-    case eioRVEC:
-    case eioNRVEC:
-        if (curfio->bDouble)
-            size = sizeof(double) * DIM;
-        else
-            size = sizeof(float) * DIM;
-        break;
-    case eioIVEC:
-        size = sizeof(ivec);
-        break;
-    case eioSTRING:
-        do_binread(&ssize, 1, eioINT, desc, srcfile, line);
-        size = ssize;
-        break;
-    default:
-        FE();
+        gmx_fio_unlock(prev);
     }
+    gmx_fio_unlock(open_files);
+    gmx_fio_unlock(fio);
 
 #ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
+    /* now unlock the big open_files mutex.  */
+    tMPI_Thread_mutex_unlock(&open_file_mutex);
 #endif
-    if (item)
-        rsize = fread(item, size, nitem, curfio->fp);
-    else
-    {
-        /* Skip over it if we have a NULL pointer here */
-#ifdef HAVE_FSEEKO
-        fseeko(curfio->fp, (off_t) (size * nitem), SEEK_CUR);
-#else
-        fseek(curfio->fp,(size*nitem),SEEK_CUR);
-#endif    
-        rsize = nitem;
-    }
-    if ((rsize != nitem) && (curfio->bDebug))
-        fprintf(stderr,
-                "Error reading %s %s from file %s (source %s, line %d)\n",
-                eioNames[eio], desc, curfio->fn, srcfile, line);
+}
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    return (rsize == nitem);
+/* remove a t_fileio into the list. We assume the fio is locked, and we leave 
+   it locked. */
+static void gmx_fio_remove(t_fileio *fio)
+{    
+    t_fileio *prev;
+
+    /* this looks a bit complicated because we're trying to avoid a 
+       deadlock with threads that are walking through the structure
+       with gmx_fio_get_next(): if they're trying to lock our current structure
+       while we are trying to lock the previous structure, we get a deadlock.
+       */
+    do
+    {
+        /* we remember the prev */
+        prev=fio->prev;
+        /* and unlock it to prevent deadlocks */
+        gmx_fio_unlock(fio);
+        /* lock the prev nbr */
+        gmx_fio_lock(prev);
+        /* now that that one is locked, we can safely lock original one again */
+        gmx_fio_lock(fio);
+
+        /* and normally, we should be able to get out of this loop, but maybe
+           things have changed when we unlocked our original fio */
+    } while((prev->next != fio) || (fio->prev != prev)); 
+    /* now set the prev's pointer */
+    fio->prev->next=fio->next;
+    gmx_fio_unlock(fio->prev);
+
+    /* with the next ptr, we can simply lock while the original was locked */
+    gmx_fio_lock(fio->next);
+    fio->next->prev=fio->prev;
+    gmx_fio_unlock(fio->next);
+
+    /* and make sure we point nowhere in particular */
+    fio->next=fio->prev=fio;
 }
 
-#ifdef USE_XDR
 
-/* this is a recursive function that does mutex locking, so
- there is an a function that locks (do_xdr) and the real function
- that calls itself without locking.  */
-static bool do_xdr_lock(void *item, int nitem, int eio, const char *desc,
-                        const char *srcfile, int line, bool do_lock)
+/* get the first open file, or NULL if there is none. 
+   Returns a locked fio. */
+static t_fileio *gmx_fio_get_first(void)
 {
-    unsigned char ucdum, *ucptr;
-    bool_t res = 0;
-    float fvec[DIM];
-    double dvec[DIM];
-    int j, m, *iptr, idum;
-    gmx_large_int_t sdum;
-    real *ptr;
-    unsigned short us;
-    double d = 0;
-    float f = 0;
+    t_fileio *ret;
+    /* first lock the big open_files mutex and the dummy's mutex */
 
+    gmx_fio_make_dummy();
 #ifdef GMX_THREADS
-    if (do_lock)
-        tMPI_Thread_mutex_lock(&fio_mutex);
+    /* first lock the big open_files mutex. */
+    tMPI_Thread_mutex_lock(&open_file_mutex);
 #endif
-    check_nitem();
-    switch (eio)
-    {
-    case eioREAL:
-        if (curfio->bDouble)
-        {
-            if (item && !curfio->bRead)
-                d = *((real *) item);
-            res = xdr_double(curfio->xdr, &d);
-            if (item)
-                *((real *) item) = d;
-        }
-        else
-        {
-            if (item && !curfio->bRead)
-                f = *((real *) item);
-            res = xdr_float(curfio->xdr, &f);
-            if (item)
-                *((real *) item) = f;
-        }
-        break;
-    case eioDOUBLE:
-        if (item && !curfio->bRead)
-            d = *((double *) item);
-        res = xdr_double(curfio->xdr, &d);
-        if (item)
-            *((double *) item) = d;
-        break;
-    case eioINT:
-        if (item && !curfio->bRead)
-            idum = *(int *) item;
-        res = xdr_int(curfio->xdr, &idum);
-        if (item)
-            *(int *) item = idum;
-        break;
-    case eioGMX_LARGE_INT:
-        /* do_xdr will not generate a warning when a 64bit gmx_large_int_t
-         * value that is out of 32bit range is read into a 32bit gmx_large_int_t.
-         */
-        if (item && !curfio->bRead)
-            sdum = *(gmx_large_int_t *) item;
-        res = xdr_gmx_large_int(curfio->xdr, &sdum, NULL);
-        if (item)
-            *(gmx_large_int_t *) item = sdum;
-        break;
-    case eioUCHAR:
-        if (item && !curfio->bRead)
-            ucdum = *(unsigned char *) item;
-        res = xdr_u_char(curfio->xdr, &ucdum);
-        if (item)
-            *(unsigned char *) item = ucdum;
-        break;
-    case eioNUCHAR:
-        ucptr = (unsigned char *) item;
-        res = 1;
-        for (j = 0; (j < nitem) && res; j++)
-        {
-            res = xdr_u_char(curfio->xdr, &(ucptr[j]));
-        }
-        break;
-    case eioUSHORT:
-        if (item && !curfio->bRead)
-            us = *(unsigned short *) item;
-        res = xdr_u_short(curfio->xdr, (unsigned short *) &us);
-        if (item)
-            *(unsigned short *) item = us;
-        break;
-    case eioRVEC:
-        if (curfio->bDouble)
-        {
-            if (item && !curfio->bRead)
-                for (m = 0; (m < DIM); m++)
-                    dvec[m] = ((real *) item)[m];
-            res = xdr_vector(curfio->xdr, (char *) dvec, DIM,
-                             (unsigned int) sizeof(double),
-                             (xdrproc_t) xdr_double);
-            if (item)
-                for (m = 0; (m < DIM); m++)
-                    ((real *) item)[m] = dvec[m];
-        }
-        else
-        {
-            if (item && !curfio->bRead)
-                for (m = 0; (m < DIM); m++)
-                    fvec[m] = ((real *) item)[m];
-            res = xdr_vector(curfio->xdr, (char *) fvec, DIM,
-                             (unsigned int) sizeof(float),
-                             (xdrproc_t) xdr_float);
-            if (item)
-                for (m = 0; (m < DIM); m++)
-                    ((real *) item)[m] = fvec[m];
-        }
-        break;
-    case eioNRVEC:
-        ptr = NULL;
-        res = 1;
-        for (j = 0; (j < nitem) && res; j++)
-        {
-            if (item)
-                ptr = ((rvec *) item)[j];
-            res = do_xdr_lock(ptr, 1, eioRVEC, desc, srcfile, line, FALSE);
-        }
-        break;
-    case eioIVEC:
-        iptr = (int *) item;
-        res = 1;
-        for (m = 0; (m < DIM) && res; m++)
-        {
-            if (item && !curfio->bRead)
-                idum = iptr[m];
-            res = xdr_int(curfio->xdr, &idum);
-            if (item)
-                iptr[m] = idum;
-        }
-        break;
-    case eioSTRING:
-    {
-        char *cptr;
-        int slen;
 
-        if (item)
-        {
-            if (!curfio->bRead)
-                slen = strlen((char *) item) + 1;
-            else
-                slen = 0;
-        }
-        else
-            slen = 0;
+    gmx_fio_lock(open_files);
+    ret=open_files->next;
 
-        if (xdr_int(curfio->xdr, &slen) <= 0)
-            gmx_fatal(FARGS, "wrong string length %d for string %s"
-                      " (source %s, line %d)",slen,desc,srcfile,line);
-        if (!item && curfio->bRead)
-            snew(cptr,slen);
-        else
-            cptr=(char *)item;
-        if (cptr)
-            res = xdr_string(curfio->xdr,&cptr,slen);
-        else
-            res = 1;
-        if (!item && curfio->bRead)
-            sfree(cptr);
-        break;
+#ifdef GMX_THREADS
+    tMPI_Thread_mutex_unlock(&open_file_mutex);
+#endif
+
+    /* check whether there were any to begin with */
+    if (ret==open_files)
+    {
+        /* after this, the open_file pointer should never change */
+        ret=NULL;
     }
-    default:
-        FE();
+    else
+    {
+        gmx_fio_lock(open_files->next);
     }
-    if ((res == 0) && (curfio->bDebug))
-        fprintf(stderr,"Error in xdr I/O %s %s to file %s (source %s, line %d)\n",
-                eioNames[eio],desc,curfio->fn,srcfile,line);
+    gmx_fio_unlock(open_files);
 
-#ifdef GMX_THREADS
-    if (do_lock)
-        tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    return (res != 0);
+
+    return ret;
 }
 
-static bool do_xdr(void *item, int nitem, int eio, const char *desc,
-                   const char *srcfile, int line)
+/* get the next open file, or NULL if there is none. 
+   Unlocks the previous fio and locks the next one. */
+static t_fileio *gmx_fio_get_next(t_fileio *fio)
 {
-    /* this is a recursive function that does mutex locking, so
-     it needs to be called with locking here, but without locking
-     from itself */
-    return do_xdr_lock(item, nitem, eio, desc, srcfile, line, TRUE);
+    t_fileio *ret;
+
+    ret=fio->next;
+    /* check if that was the last one */
+    if (fio->next==open_files)
+    {
+        ret=NULL;
+    }
+    else
+    {
+        gmx_fio_lock(ret);
+    }
+    gmx_fio_unlock(fio);
+
+    return ret;
 }
-#endif
 
-#define gmx_fio_check(fio) range_check(fio,0,nFIO)
+
+
 
 /*****************************************************************
  *
  *                     EXPORTED SECTION
  *
  *****************************************************************/
-int gmx_fio_open(const char *fn, const char *mode)
+t_fileio *gmx_fio_open(const char *fn, const char *mode)
 {
     t_fileio *fio = NULL;
-    int i, nfio = 0;
+    int i;
     char newmode[5];
     bool bRead, bReadWrite;
     int xdrid;
@@ -858,6 +451,7 @@ int gmx_fio_open(const char *fn, const char *mode)
     }
     else
     {
+        /* sanitize the mode string */
         if (strncmp(mode, "r+", 2) == 0)
         {
             strcpy(newmode, "r+");
@@ -898,28 +492,10 @@ int gmx_fio_open(const char *fn, const char *mode)
         }
     }
 
+    snew(fio, 1);
 #ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
+    tMPI_Spinlock_init(&(fio->mtx));
 #endif
-    /* Determine whether we have to make a new one */
-    for(i=0; (i<nFIO); i++)
-    {
-        if (!FIO[i].bOpen)
-        {
-            fio = &(FIO[i]);
-            nfio = i;
-            break;
-        }
-    }
-
-    if (i == nFIO)
-    {
-        nFIO++;
-        srenew(FIO,nFIO);
-        fio = &(FIO[nFIO-1]);
-        nfio = nFIO-1;
-    }
-
     bRead = (newmode[0]=='r' && newmode[1]!='+');
     bReadWrite = (newmode[1]=='+');
     fio->fp = NULL;
@@ -951,16 +527,21 @@ int gmx_fio_open(const char *fn, const char *mode)
                     gmx_open(fn);
                 }
             }
-            snew(fio->xdr,1);
-            xdrid = xdropen(fio->xdr,fn,newmode); 
-            if (xdrid == 0)
+            /* Open the file */
+            fio->fp = ffopen(fn,newmode);
+
+            /* determine the XDR direction */
+            if (newmode[0] == 'w' || newmode[0]=='a')
+            {
+                fio->xdrmode=XDR_ENCODE;
+            }
+            else
             {
-                if(newmode[0]=='r' && newmode[1]!='+') 
-                    gmx_fatal(FARGS,"Cannot open file %s for reading\nCheck permissions if it exists.",fn); 
-                else
-                    gmx_fatal(FARGS,"Cannot open file %s for writing.\nCheck your permissions, disk space and/or quota.",fn);
+                fio->xdrmode=XDR_DECODE;
             }
-            fio->fp = xdr_get_fp(xdrid);
+
+            snew(fio->xdr,1);
+            xdrstdio_create(fio->xdr, fio->fp, fio->xdrmode);
         }
         else
         {
@@ -983,213 +564,162 @@ int gmx_fio_open(const char *fn, const char *mode)
     fio->bOpen  = TRUE;
     fio->bLargerThan_off_t = FALSE;
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    return nfio;
+    /* set the reader/writer functions */
+    gmx_fio_set_iotype(fio);
+
+    /* and now insert this file into the list of open files. */
+    gmx_fio_insert(fio);
+    return fio;
 }
 
-/* this function may be called from a function that locks the fio_mutex, 
-   which is why it exists in the first place. */
-static int gmx_fio_close_lock(int fio, bool do_lock)
+int gmx_fio_close(t_fileio *fio)
 {
     int rc = 0;
 
-#ifdef GMX_THREADS
-    if (do_lock)
-        tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
+    gmx_fio_lock(fio);
+    /* first remove it from the list */
+    gmx_fio_remove(fio);
 
-    if (in_ftpset(FIO[fio].iFTP, asize(ftpXDR), ftpXDR))
+    if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR))
     {
-        rc = !xdrclose(FIO[fio].xdr); /* xdrclose returns 1 if happy, 
-         negate it */
-        sfree(FIO[fio].xdr);
-    }
-    else
-    {
-        /* Don't close stdin and stdout! */
-        if (!FIO[fio].bStdio && FIO[fio].fp!=NULL)
-            rc = ffclose(FIO[fio].fp); /* fclose returns 0 if happy */
+        xdr_destroy(fio->xdr);
+        sfree(fio->xdr);
     }
 
-    sfree(FIO[fio].fn);
-    FIO[fio].bOpen = FALSE;
-    do_read = do_dummy;
-    do_write = do_dummy;
-#ifdef GMX_THREADS
-    if (do_lock)
-        tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    /* Don't close stdin and stdout! */
+    if (!fio->bStdio && fio->fp!=NULL)
+        rc = ffclose(fio->fp); /* fclose returns 0 if happy */
 
-    return rc;
-}
+    fio->bOpen = FALSE;
 
-int gmx_fio_close(int fio)
-{
-    return gmx_fio_close_lock(fio, TRUE);
+    gmx_fio_unlock(fio);
+
+    sfree(fio);
+
+    return rc;
 }
 
 /* close only fp but keep FIO entry. */
-int gmx_fio_fp_close(int fio)
+int gmx_fio_fp_close(t_fileio *fio)
 {
     int rc=0;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (!in_ftpset(FIO[fio].iFTP,asize(ftpXDR),ftpXDR) && !FIO[fio].bStdio)
+    gmx_fio_lock(fio);
+    if (!in_ftpset(fio->iFTP,asize(ftpXDR),ftpXDR) && !fio->bStdio)
     {
-        rc = ffclose(FIO[fio].fp); /* fclose returns 0 if happy */
-        FIO[fio].fp = NULL; 
+        rc = ffclose(fio->fp); /* fclose returns 0 if happy */
+        fio->fp = NULL; 
     }
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    gmx_fio_unlock(fio);
+
     return rc;
 }
 
 FILE * gmx_fio_fopen(const char *fn, const char *mode)
 {
     FILE *fp, *ret;
-    int fd;
+    t_fileio *fio;
+
+    fio = gmx_fio_open(fn, mode);
+    gmx_fio_lock(fio);
+    ret = fio->fp;
+    gmx_fio_unlock(fio);
 
-    fd = gmx_fio_open(fn, mode);
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    ret = FIO[fd].fp;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
     return ret;
 }
 
 int gmx_fio_fclose(FILE *fp)
 {
-    int i, rc, found;
+    t_fileio *cur;
+    t_fileio *found=NULL;
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    found = 0;
-    rc = -1;
-
-    for (i = 0; i < nFIO && !found; i++)
+    cur=gmx_fio_get_first();
+    while(cur)
     {
-        if (fp == FIO[i].fp)
+        if (cur->fp == fp)
         {
-            rc = gmx_fio_close_lock(i, FALSE);
-            found = 1;
+            gmx_fio_unlock(cur);
+            found=cur;
+            /* we let it loop until  the end */
         }
+        cur=gmx_fio_get_next(cur);
     }
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    return rc;
+
+    if (!found)
+        return -1;
+    return gmx_fio_close(found);
 }
 
-/*
- * fio: file to computer md5 from
- * offset: starting pointer of region to use for md5
- * digest: return array of md5 sum 
- * do_lock: whether to lock the fio array
- *
- * this function may be called from a function that locks the fio_mutex, 
- which is why it exists in the first place. 
- */
-int gmx_fio_get_file_md5_lock(int fio, off_t offset, unsigned char digest[],
-                              bool do_lock)
+/* internal variant of get_file_md5 that operates on a locked file */
+static int gmx_fio_int_get_file_md5(t_fileio *fio, off_t offset, 
+                                    unsigned char digest[])
 {
     /*1MB: large size important to catch almost identical files */
 #define CPT_CHK_LEN  1048576 
-
     md5_state_t state;
     unsigned char buf[CPT_CHK_LEN];
     off_t read_len;
     off_t seek_offset;
     int ret = -1;
-    seek_offset = offset - CPT_CHK_LEN;
 
+    seek_offset = offset - CPT_CHK_LEN;
     if (seek_offset < 0)
     {
         seek_offset = 0;
     }
     read_len = offset - seek_offset;
 
-#ifdef GMX_THREADS 
-    if (do_lock)
-    {
-        tMPI_Thread_mutex_lock(&fio_mutex);
-    }
-#endif
 
-    gmx_fio_check(fio);
-    if (FIO[fio].fp && FIO[fio].bReadWrite)
+    if (fio->fp && fio->bReadWrite)
     {
 #ifdef HAVE_FSEEKO
-        ret = fseeko(FIO[fio].fp, seek_offset, SEEK_SET);
+        ret = fseeko(fio->fp, seek_offset, SEEK_SET);
 #else
-        ret=fseek(FIO[fio].fp,seek_offset,SEEK_SET);
+        ret=fseek(fio->fp,seek_offset,SEEK_SET);
 #endif
         if (ret)
         {
-            fseek(FIO[fio].fp, 0, SEEK_END);
+            fseek(fio->fp, 0, SEEK_END);
         }
     }
     if (ret) /*either no fp, not readwrite, or fseek not successful */
     {
-#ifdef GMX_THREADS 
-        if (do_lock)
-        {
-            tMPI_Thread_mutex_unlock(&fio_mutex);
-        }
-#endif
         return -1;
     }
 
     /* the read puts the file position back to offset */
-    if (fread(buf, 1, read_len, FIO[fio].fp) != read_len)
+    if (fread(buf, 1, read_len, fio->fp) != read_len)
     {
         /* not fatal: md5sum check to prevent overwriting files
          * works (less safe) without
          * */
-        if (ferror(FIO[fio].fp))
+        if (ferror(fio->fp))
         {
-            fprintf(stderr, "\nTrying to get md5sum: %s: %s\n", FIO[fio].fn,
+            fprintf(stderr, "\nTrying to get md5sum: %s: %s\n", fio->fn,
                     strerror(errno));
         }
-        else if (feof(FIO[fio].fp))
+        else if (feof(fio->fp))
         {
-            fprintf(stderr, "\nTrying to get md5sum: EOF: %s\n", FIO[fio].fn);
+            fprintf(stderr, "\nTrying to get md5sum: EOF: %s\n", fio->fn);
         }
         else
         {
             fprintf(
                 stderr,
                 "\nTrying to get md5sum: Unknown reason for short read: %s\n",
-                FIO[fio].fn);
+                fio->fn);
         }
 
-        fseek(FIO[fio].fp, 0, SEEK_END);
+        fseek(fio->fp, 0, SEEK_END);
 
         ret = -1;
     }
-    fseek(FIO[fio].fp, 0, SEEK_END); /*is already at end, but under windows 
+    fseek(fio->fp, 0, SEEK_END); /*is already at end, but under windows 
      it gives problems otherwise*/
 
     if (debug)
     {
-        fprintf(debug, "chksum %s readlen %ld\n", FIO[fio].fn,
-                (long int) read_len);
+        fprintf(debug, "chksum %s readlen %ld\n", fio->fn, (long int)read_len);
     }
-#ifdef GMX_THREADS 
-    if (do_lock)
-    {
-        tMPI_Thread_mutex_unlock(&fio_mutex);
-    }
-#endif
 
     if (!ret)
     {
@@ -1204,29 +734,36 @@ int gmx_fio_get_file_md5_lock(int fio, off_t offset, unsigned char digest[],
     }
 }
 
+
 /*
- * fio: file to computer md5 from
+ * fio: file to compute md5 for
  * offset: starting pointer of region to use for md5
  * digest: return array of md5 sum 
  */
-int gmx_fio_get_file_md5(int fio, off_t offset, unsigned char digest[])
+int gmx_fio_get_file_md5(t_fileio *fio, off_t offset, unsigned char digest[])
 {
-    return gmx_fio_get_file_md5_lock(fio, offset, digest, TRUE);
+    int ret;
+
+    gmx_fio_lock(fio);
+    ret=gmx_fio_int_get_file_md5(fio, offset, digest);
+    gmx_fio_unlock(fio);
+
+    return ret;
 }
 
 /* The fio_mutex should ALWAYS be locked when this function is called */
-static int gmx_fio_get_file_position(int fio, off_t *offset)
+static int gmx_fio_int_get_file_position(t_fileio *fio, off_t *offset)
 {
     char buf[STRLEN];
 
     /* Flush the file, so we are sure it is written */
-    if (gmx_fio_flush_lock(fio, FALSE))
+    if (gmx_fio_int_flush(fio))
     {
         char buf[STRLEN];
         sprintf(
             buf,
             "Cannot write file '%s'; maybe you are out of disk space or quota?",
-            FIO[fio].fn);
+            fio->fn);
         gmx_file(buf);
     }
 
@@ -1237,15 +774,15 @@ static int gmx_fio_get_file_position(int fio, off_t *offset)
      this when exabyte-size output files are common...
      */
 #ifdef HAVE_FSEEKO
-    *offset = ftello(FIO[fio].fp);
+    *offset = ftello(fio->fp);
 #else
-    *offset = ftell(FIO[fio].fp);
+    *offset = ftell(fio->fp);
 #endif
 
     return 0;
 }
 
-int gmx_fio_check_file_position(int fio)
+int gmx_fio_check_file_position(t_fileio *fio)
 {
     /* If off_t is 4 bytes we can not store file offset > 2 GB.
      * If we do not have ftello, we will play it safe.
@@ -1253,20 +790,16 @@ int gmx_fio_check_file_position(int fio)
 #if (SIZEOF_OFF_T == 4 || !defined HAVE_FSEEKO)
     off_t offset;
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_get_file_position(fio,&offset);
+    gmx_fio_lock(fio);
+    gmx_fio_int_get_file_position(fio,&offset);
     /* We have a 4 byte offset,
      * make sure that we will detect out of range for all possible cases.
      */
     if (offset < 0 || offset > 2147483647)
     {
-        FIO[fio].bLargerThan_off_t = TRUE;
+        fio->bLargerThan_off_t = TRUE;
     }
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    gmx_fio_unlock(fio);
 #endif
 
     return 0;
@@ -1280,21 +813,25 @@ int gmx_fio_get_output_file_positions(gmx_file_position_t **p_outputfiles,
     long pos;
     gmx_file_position_t * outputfiles;
     char buf[STRLEN];
+    t_fileio *cur;
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
     nfiles = 0;
 
+    /* pre-allocate 100 files */
     nalloc = 100;
     snew(outputfiles,nalloc);
 
-    for (i = 0; i < nFIO; i++)
+    cur=gmx_fio_get_first();
+    while(cur)
     {
-        /* Skip the checkpoint files themselves, since they could be open when we call this routine... */
+        /* Skip the checkpoint files themselves, since they could be open when 
+           we call this routine... */
         /* also skip debug files (shoud be the only iFTP==efNR) */
-        if (FIO[i].bOpen && !FIO[i].bRead && !FIO[i].bStdio && FIO[i].iFTP
-            != efCPT && FIO[i].iFTP != efNR)
+        if (cur->bOpen && 
+            !cur->bRead && 
+            !cur->bStdio && 
+            cur->iFTP != efCPT && 
+            cur->iFTP != efNR)
         {
             int ret;
             /* This is an output file currently open for writing, add it */
@@ -1304,10 +841,10 @@ int gmx_fio_get_output_file_positions(gmx_file_position_t **p_outputfiles,
                 srenew(outputfiles,nalloc);
             }
 
-            strncpy(outputfiles[nfiles].filename, FIO[i].fn, STRLEN - 1);
+            strncpy(outputfiles[nfiles].filename, cur->fn, STRLEN - 1);
 
             /* Get the file position */
-            if (FIO[i].bLargerThan_off_t)
+            if (cur->bLargerThan_off_t)
             {
                 /* -1 signals out of range */
                 outputfiles[nfiles].offset = -1;
@@ -1315,200 +852,132 @@ int gmx_fio_get_output_file_positions(gmx_file_position_t **p_outputfiles,
             }
             else
             {
-                gmx_fio_get_file_position(i, &outputfiles[nfiles].offset);
+                gmx_fio_int_get_file_position(cur, &outputfiles[nfiles].offset);
 #ifndef GMX_FAHCORE
                 outputfiles[nfiles].chksum_size
-                = gmx_fio_get_file_md5_lock(i, outputfiles[nfiles].offset,
-                                            outputfiles[nfiles].chksum,
-                                            FALSE);
+                    = gmx_fio_int_get_file_md5(cur, 
+                                               outputfiles[nfiles].offset,
+                                               outputfiles[nfiles].chksum);
 #endif
             }
 
             nfiles++;
         }
+
+        cur=gmx_fio_get_next(cur);
     }
     *p_nfiles = nfiles;
     *p_outputfiles = outputfiles;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
 
     return 0;
 }
 
-void gmx_fio_select(int fio)
-{
-#ifdef DEBUG
-    fprintf(stderr,"Select fio called with type %d for file %s\n",
-            FIO[fio].iFTP,FIO[fio].fn);
-#endif
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (in_ftpset(FIO[fio].iFTP, asize(ftpXDR), ftpXDR))
+void gmx_fio_checktype(t_fileio *fio)
+{
+    if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR))
     {
-#ifdef USE_XDR    
-        do_read = do_xdr;
-        do_write = do_xdr;
-#else
-        gmx_fatal(FARGS,"Sorry, no XDR");
-#endif
+        return;
     }
-    else if (in_ftpset(FIO[fio].iFTP, asize(ftpASC), ftpASC))
+    else if (in_ftpset(fio->iFTP, asize(ftpASC), ftpASC))
     {
-        do_read = do_ascread;
-        do_write = do_ascwrite;
+        return;
     }
-    else if (in_ftpset(FIO[fio].iFTP, asize(ftpBIN), ftpBIN))
+    else if (in_ftpset(fio->iFTP, asize(ftpBIN), ftpBIN))
     {
-        do_read = do_binread;
-        do_write = do_binwrite;
+        return;
     }
 #ifdef HAVE_XMl
-    else if (in_ftpset(FIO[fio].iFTP,asize(ftpXML),ftpXML))
+    else if (in_ftpset(fio->iFTP,asize(ftpXML),ftpXML))
     {
-        do_read = do_dummy;
-        do_write = do_dummy;
+        return;
     }
 #endif
     else
         gmx_fatal(FARGS, "Can not read/write topologies to file type %s",
-                  ftp2ext(curfio->iFTP));
+                  ftp2ext(fio->iFTP));
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    curfio = &(FIO[fio]);
 }
 
-void gmx_fio_setprecision(int fio, bool bDouble)
+
+void gmx_fio_setprecision(t_fileio *fio, bool bDouble)
 {
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    FIO[fio].bDouble = bDouble;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    gmx_fio_lock(fio);
+    fio->bDouble = bDouble;
+    gmx_fio_unlock(fio);
 }
 
-bool gmx_fio_getdebug(int fio)
+bool gmx_fio_getdebug(t_fileio *fio)
 {
     bool ret;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    ret = FIO[fio].bDebug;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    return FIO[fio].bDebug;
+
+    gmx_fio_lock(fio);
+    ret = fio->bDebug;
+    gmx_fio_unlock(fio);
+
+    return ret;
 }
 
-void gmx_fio_setdebug(int fio, bool bDebug)
+void gmx_fio_setdebug(t_fileio *fio, bool bDebug)
 {
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    FIO[fio].bDebug = bDebug;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    gmx_fio_lock(fio);
+    fio->bDebug = bDebug;
+    gmx_fio_unlock(fio);
 }
 
-char *gmx_fio_getname(int fio)
+char *gmx_fio_getname(t_fileio *fio)
 {
     char *ret;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    ret = curfio->fn;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-    return ret;
-}
+    gmx_fio_lock(fio);
+    ret = fio->fn;
+    gmx_fio_unlock(fio);
 
-void gmx_fio_setftp(int fio, int ftp)
-{
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    FIO[fio].iFTP = ftp;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    return ret;
 }
 
-int gmx_fio_getftp(int fio)
+int gmx_fio_getftp(t_fileio* fio)
 {
     int ret;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    ret = FIO[fio].iFTP;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+
+    gmx_fio_lock(fio);
+    ret = fio->iFTP;
+    gmx_fio_unlock(fio);
+
     return ret;
 }
 
-void gmx_fio_rewind(int fio)
+void gmx_fio_rewind(t_fileio* fio)
 {
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (FIO[fio].xdr)
+    gmx_fio_lock(fio);
+
+    if (fio->xdr)
     {
-        xdrclose(FIO[fio].xdr);
-        /* File is always opened as binary by xdropen */
-        xdropen(FIO[fio].xdr, FIO[fio].fn, FIO[fio].bRead ? "r" : "w");
+        xdr_destroy(fio->xdr);
+        frewind(fio->fp);
+        xdrstdio_create(fio->xdr, fio->fp, fio->xdrmode);
     }
     else
-        frewind(FIO[fio].fp);
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    {
+        frewind(fio->fp);
+    }
+    gmx_fio_unlock(fio);
 }
 
-static int gmx_fio_flush_lock(int fio, bool do_lock)
-{
-    int rc = 0;
 
-#ifdef GMX_THREADS
-    if (do_lock)
-        tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (FIO[fio].fp)
-        rc = fflush(FIO[fio].fp);
-    else if (FIO[fio].xdr)
-        rc = fflush((FILE *) FIO[fio].xdr->x_private);
-#ifdef GMX_THREADS
-    if (do_lock)
-        tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+int gmx_fio_flush(t_fileio* fio)
+{
+    int ret;
 
-    return rc;
-}
+    gmx_fio_lock(fio);
+    ret=gmx_fio_int_flush(fio);
+    gmx_fio_unlock(fio);
 
-int gmx_fio_flush(int fio)
-{
-    return gmx_fio_flush_lock(fio, TRUE);
+    return ret;
 }
 
 
 
-static int gmx_fio_fsync_lock(int fio, bool do_lock)
+static int gmx_fio_int_fsync(t_fileio *fio)
 {
     int rc = 0;
     int filen=-1;
@@ -1516,31 +985,26 @@ static int gmx_fio_fsync_lock(int fio, bool do_lock)
 #if ( ( (defined(HAVE_FILENO) || (defined(HAVE__FILENO) ) ) && \
        (defined(HAVE_FSYNC))  || defined(HAVE__COMMIT)  ) || \
         defined(FAHCORE) )
-#ifdef GMX_THREADS
-    if (do_lock)
-        tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (FIO[fio].fp)
+    if (fio->fp)
     {
 #ifdef GMX_FAHCORE
        /* the fahcore defines its own os-independent fsync */
-       rc=fah_fsync(FIO[fio].fp); 
+       rc=fah_fsync(fio->fp); 
 #elif defined(HAVE_FILENO)
-        filen=fileno(FIO[fio].fp);
+        filen=fileno(fio->fp);
 #elif defined(HAVE__FILENO)
-        filen=_fileno(FIO[fio].fp);
+        filen=_fileno(fio->fp);
 #endif
     }
-    else if (FIO[fio].xdr)
+    else if (fio->xdr)
     {
 #ifdef GMX_FAHCORE
        /* the fahcore defines its own os-independent fsync */
-        rc=fah_fsync((FILE *) FIO[fio].xdr->x_private);
+        rc=fah_fsync((FILE *) fio->xdr->x_private);
 #elif defined(HAVE_FILENO)
-        filen=fileno((FILE *) FIO[fio].xdr->x_private);
+        filen=fileno((FILE *) fio->xdr->x_private);
 #elif defined(HAVE__FILENO)
-        filen=_fileno((FILE *) FIO[fio].xdr->x_private);
+        filen=_fileno((FILE *) fio->xdr->x_private);
 #endif
     }
 
@@ -1570,53 +1034,53 @@ static int gmx_fio_fsync_lock(int fio, bool do_lock)
     if (rc && errno==EINVAL)
         rc=0;
 #endif
-
-
-#ifdef GMX_THREADS
-    if (do_lock)
-        tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
 #endif
 
     return rc;
 }
 
 
-int gmx_fio_fsync(int fio)
+int gmx_fio_fsync(t_fileio *fio)
 {
-    int rc = 0;
+    int rc;
+
+    gmx_fio_lock(fio);
+    rc=gmx_fio_int_fsync(fio);
+    gmx_fio_unlock(fio);
 
-    return gmx_fio_fsync_lock(fio, TRUE);
+    return rc;
 }
 
 
 
 int gmx_fio_all_output_fsync(void)
 {
-    int i;
     int ret=0;
+    t_fileio *cur;
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    for (i = 0; i < nFIO; i++)
+
+    cur=gmx_fio_get_first();
+    while(cur)
     {
         /* skip debug files (shoud be the only iFTP==efNR) */
-        if (FIO[i].bOpen && !FIO[i].bRead && !FIO[i].bStdio && 
-            FIO[i].iFTP != efNR)
+        if (cur->bOpen && 
+            !cur->bRead && 
+            !cur->bStdio && 
+            cur->iFTP != efNR)
         {
             /* if any of them fails, return failure code */
-            int rc=gmx_fio_fsync_lock(i, FALSE);
+            int rc=gmx_fio_int_fsync(cur);
             if (rc != 0) 
             {
                 char buf[STRLEN];
                 sprintf(buf,
                         "Cannot fsync file '%s'; maybe you are out of disk space or quota?",
-                        FIO[i].fn);
+                        cur->fn);
                 gmx_file(buf);
                 ret=-1;
             }
         }
+        cur=gmx_fio_get_next(cur);
     }
 
     /* in addition, we force these to be written out too, if they're being
@@ -1630,106 +1094,97 @@ int gmx_fio_all_output_fsync(void)
     fsync(STDERR_FILENO);
 #endif
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
-
     return 0;
 }
 
 
-off_t gmx_fio_ftell(int fio)
+off_t gmx_fio_ftell(t_fileio* fio)
 {
     off_t ret = 0;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (FIO[fio].fp)
-        ret = ftell(FIO[fio].fp);
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+
+    gmx_fio_lock(fio);
+    if (fio->fp)
+        ret = ftell(fio->fp);
+    gmx_fio_unlock(fio);
     return ret;
 }
 
-int gmx_fio_seek(int fio, off_t fpos)
+int gmx_fio_seek(t_fileio* fio, off_t fpos)
 {
     int rc;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (FIO[fio].fp)
+
+    gmx_fio_lock(fio);
+    if (fio->fp)
     {
 #ifdef HAVE_FSEEKO
-        rc = fseeko(FIO[fio].fp, fpos, SEEK_SET);
+        rc = fseeko(fio->fp, fpos, SEEK_SET);
 #else
-        rc = fseek(FIO[fio].fp,fpos,SEEK_SET);
+        rc = fseek(fio->fp,fpos,SEEK_SET);
 #endif
     }
     else
     {
-        gmx_file(FIO[fio].fn);
+        gmx_file(fio->fn);
         rc = -1;
     }
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    gmx_fio_unlock(fio);
     return rc;
 }
 
-FILE *gmx_fio_getfp(int fio)
+FILE *gmx_fio_getfp(t_fileio *fio)
 {
     FILE *ret = NULL;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (FIO[fio].fp)
-        ret = FIO[fio].fp;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+
+    gmx_fio_lock(fio);
+    if (fio->fp)
+        ret = fio->fp;
+    gmx_fio_unlock(fio);
     return ret;
 }
 
-XDR *gmx_fio_getxdr(int fio)
+XDR *gmx_fio_getxdr(t_fileio* fio)
 {
     XDR *ret = NULL;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    if (FIO[fio].xdr)
-        ret = FIO[fio].xdr;
 
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+    gmx_fio_lock(fio);
+    if (fio->xdr)
+        ret = fio->xdr;
+    gmx_fio_unlock(fio);
+
     return ret;
 }
 
-bool gmx_fio_getread(int fio)
+bool gmx_fio_getread(t_fileio* fio)
 {
     bool ret;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_lock(&fio_mutex);
-#endif
-    gmx_fio_check(fio);
-    ret = FIO[fio].bRead;
-#ifdef GMX_THREADS
-    tMPI_Thread_mutex_unlock(&fio_mutex);
-#endif
+
+    gmx_fio_lock(fio);
+    ret = fio->bRead;
+    gmx_fio_unlock(fio);
+
     return ret;
 }
 
-int xtc_seek_frame(int frame, int fio, int natoms)
+int xtc_seek_frame(t_fileio *fio, int frame, int natoms)
 {
-    return xdr_xtc_seek_frame(frame, FIO[fio].fp, FIO[fio].xdr, natoms);
+    int ret;
+
+    gmx_fio_lock(fio);
+    ret=xdr_xtc_seek_frame(frame, fio->fp, fio->xdr, natoms);
+    gmx_fio_unlock(fio);
+
+    return ret;
 }
 
-int xtc_seek_time(real time, int fio, int natoms)
+int xtc_seek_time(t_fileio *fio, real time, int natoms)
 {
-    return xdr_xtc_seek_time(time, FIO[fio].fp, FIO[fio].xdr, natoms);
+    int ret;
+
+    gmx_fio_lock(fio);
+    ret=xdr_xtc_seek_time(time, fio->fp, fio->xdr, natoms);
+    gmx_fio_unlock(fio);
+
+    return ret;
 }
+
+
diff --git a/src/gmxlib/gmxfio_asc.c b/src/gmxlib/gmxfio_asc.c
new file mode 100644 (file)
index 0000000..937a807
--- /dev/null
@@ -0,0 +1,370 @@
+/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
+ *
+ * 
+ *                This source code is part of
+ * 
+ *                 G   R   O   M   A   C   S
+ * 
+ *          GROningen MAchine for Chemical Simulations
+ * 
+ *                        VERSION 3.2.0
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ * 
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ * 
+ * For more info, check our website at http://www.gromacs.org
+ * 
+ * And Hey:
+ * GROningen Mixture of Alchemy and Childrens' Stories
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#include "gmx_fatal.h"
+#include "macros.h"
+#include "smalloc.h"
+#include "futil.h"
+#include "filenm.h"
+#include "string2.h"
+#include "gmxfio.h"
+#include "md5.h"
+
+#ifdef GMX_THREADS
+#include "thread_mpi.h"
+#endif
+
+#include "gmxfio_int.h"
+
+
+/* This is the part that reads dummy and ascii files.  */
+
+
+
+
+/* file type functions */
+static bool do_ascread(t_fileio *fio, void *item, int nitem, int eio, 
+                       const char *desc, const char *srcfile, int line);
+static bool do_ascwrite(t_fileio *fio, const void *item, int nitem, int eio, 
+                        const char *desc, const char *srcfile, int line);
+static bool do_dummyread(t_fileio *fio, void *item, int nitem, int eio,
+                         const char *desc, const char *srcfile, int line);
+static bool do_dummywrite(t_fileio *fio, const void *item, int nitem, int eio,
+                          const char *desc, const char *srcfile, int line);
+
+
+const t_iotype asc_iotype={do_ascread, do_ascwrite};
+const t_iotype dummy_iotype={do_dummyread, do_dummywrite};
+
+
+
+
+
+
+static bool do_dummyread(t_fileio *fio, void *item, int nitem, int eio,
+                         const char *desc, const char *srcfile, int line)
+{
+    gmx_fatal(FARGS, "File type not set!");
+    return FALSE;
+}
+
+static bool do_dummywrite(t_fileio *fio, const void *item, int nitem, int eio,
+                          const char *desc, const char *srcfile, int line)
+{
+    gmx_fatal(FARGS, "File type not set!");
+    return FALSE;
+}
+
+
+
+static void encode_string(int maxlen, char dst[], const char src[])
+{
+    int i;
+
+    for (i = 0; (src[i] != '\0') && (i < maxlen - 1); i++)
+        if ((src[i] == ' ') || (src[i] == '\t'))
+            dst[i] = '_';
+        else
+            dst[i] = src[i];
+    dst[i] = '\0';
+
+    if (i == maxlen)
+        fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
+}
+
+static void decode_string(int maxlen, char dst[], const char src[])
+{
+    int i;
+
+    for (i = 0; (src[i] != '\0') && (i < maxlen - 1); i++)
+    {
+        if (src[i] == '_')
+        {
+            dst[i] = ' ';
+        }
+        else
+        {
+            dst[i] = src[i];
+        }
+    }
+    dst[i] = '\0';
+
+    if (i == maxlen)
+    {
+        fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
+    }
+}
+
+static bool do_ascwrite(t_fileio *fio, const void *item, int nitem, int eio, 
+                        const char *desc, const char *srcfile, int line)
+{
+    int i;
+    int res = 0, *iptr;
+    real *ptr;
+    char strbuf[256];
+    char buf[GMX_FIO_BUFLEN];
+    unsigned char *ucptr;
+    FILE *fp=fio->fp;
+
+    gmx_fio_check_nitem(fio, eio, nitem, srcfile, line);
+    switch (eio)
+    {
+    case eioREAL:
+    case eioDOUBLE:
+        res = fprintf(fp, "%18.10e%s\n", *((real *) item), 
+                      gmx_fio_dbgstr(fio, desc, buf));
+        break;
+    case eioINT:
+        res = fprintf(fp, "%18d%s\n", *((int *) item), gmx_fio_dbgstr(fio, 
+                                                                      desc, 
+                                                                      buf));
+        break;
+    case eioGMX_LARGE_INT:
+        sprintf(strbuf, "%s%s%s", "%", gmx_large_int_fmt, "\n");
+        res = fprintf(fp, strbuf, *((gmx_large_int_t *) item),
+                      gmx_fio_dbgstr(fio, desc, buf));
+        break;
+    case eioUCHAR:
+        res = fprintf(fp, "%4d%s\n", *((unsigned char *) item),
+                      gmx_fio_dbgstr(fio, desc, buf));
+        break;
+    case eioNUCHAR:
+        ucptr = (unsigned char *) item;
+        for (i = 0; (i < nitem); i++)
+            res = fprintf(fp, "%4d", (int) ucptr[i]);
+        fprintf(fio->fp, "%s\n", gmx_fio_dbgstr(fio, desc, buf));
+        break;
+    case eioUSHORT:
+        res = fprintf(fp, "%18d%s\n", *((unsigned short *) item),
+                      gmx_fio_dbgstr(fio, desc, buf));
+        break;
+    case eioRVEC:
+        ptr = (real *) item;
+        res = fprintf(fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
+                      ptr[YY], ptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
+        break;
+    case eioNRVEC:
+        for (i = 0; (i < nitem); i++)
+        {
+            ptr = ((rvec *) item)[i];
+            res = fprintf(fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
+                          ptr[YY], ptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
+        }
+        break;
+    case eioIVEC:
+        iptr = (int *) item;
+        res = fprintf(fp, "%18d%18d%18d%s\n", iptr[XX], iptr[YY],
+                      iptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
+        break;
+    case eioSTRING:
+        encode_string(256, strbuf, (char *) item);
+        res = fprintf(fp, "%-18s%s\n", strbuf, gmx_fio_dbgstr(fio, desc, buf));
+        break;
+    default:
+        gmx_fio_fe(fio, eio, desc, srcfile, line);
+    }
+    if ((res <= 0) && fio->bDebug)
+        fprintf(stderr,
+                "Error writing %s %s to file %s (source %s, line %d)\n",
+                eioNames[eio], desc, fio->fn, srcfile, line);
+
+    return (res > 0);
+}
+
+
+static char *next_item(FILE *fp, char *buf, int buflen)
+{
+    int rd;
+    bool in_comment = FALSE;
+    bool in_token = FALSE;
+    int i = 0;
+    /* This routine reads strings from the file fp, strips comment
+     * and buffers. For thread-safety reasons, It reads through getc()  */
+
+    rd = getc(fp);
+    if (rd == EOF)
+        gmx_file("End of file");
+    do
+    {
+        if (in_comment)
+        {
+            if (rd == '\n')
+                in_comment = FALSE;
+        }
+        else if (in_token)
+        {
+            if (isspace(rd) || rd == ';')
+                break;
+            buf[i++] = (char) rd;
+        }
+        else
+        {
+            if (!isspace(rd))
+            {
+                if (rd == ';')
+                    in_comment = TRUE;
+                else
+                {
+                    in_token = TRUE;
+                    buf[i++] = (char) (rd);
+                }
+            }
+        }
+        if (i >= buflen - 2)
+            break;
+    } while ((rd = getc(fp)) != EOF);
+
+    fprintf(stderr, "WARNING, ftpASC file type not tested!\n");
+
+    buf[i] = 0;
+
+    return buf;
+}
+
+static bool do_ascread(t_fileio *fio, void *item, int nitem, int eio, 
+                       const char *desc, const char *srcfile, int line)
+{
+    FILE *fp = fio->fp;
+    int i, m, res = 0, *iptr, ix;
+    gmx_large_int_t s;
+    double d, x;
+    real *ptr;
+    unsigned char uc, *ucptr;
+    char *cptr;
+#define NEXT_ITEM_BUF_LEN 128
+    char ni_buf[NEXT_ITEM_BUF_LEN];
+
+    gmx_fio_check_nitem(fio, eio, nitem, srcfile, line);
+    switch (eio)
+    {
+    case eioREAL:
+    case eioDOUBLE:
+        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf", &d);
+        if (item)
+            *((real *) item) = d;
+        break;
+    case eioINT:
+        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
+        if (item)
+            *((int *) item) = i;
+        break;
+    case eioGMX_LARGE_INT:
+        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN),
+                     gmx_large_int_pfmt, &s);
+        if (item)
+            *((gmx_large_int_t *) item) = s;
+        break;
+    case eioUCHAR:
+        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%c", &uc);
+        if (item)
+            *((unsigned char *) item) = uc;
+        break;
+    case eioNUCHAR:
+        ucptr = (unsigned char *) item;
+        for (i = 0; (i < nitem); i++)
+        {
+            res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &ix);
+            if (item)
+                ucptr[i] = ix;
+        }
+        break;
+    case eioUSHORT:
+        res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
+        if (item)
+            *((unsigned short *) item) = i;
+        break;
+    case eioRVEC:
+        ptr = (real *) item;
+        for (m = 0; (m < DIM); m++)
+        {
+            res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n", &x);
+            ptr[m] = x;
+        }
+        break;
+    case eioNRVEC:
+        for (i = 0; (i < nitem); i++)
+        {
+            ptr = ((rvec *) item)[i];
+            for (m = 0; (m < DIM); m++)
+            {
+                res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n",
+                             &x);
+                if (item)
+                    ptr[m] = x;
+            }
+        }
+        break;
+    case eioIVEC:
+        iptr = (int *) item;
+        for (m = 0; (m < DIM); m++)
+        {
+            res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d\n", &ix);
+            if (item)
+                iptr[m] = ix;
+        }
+        break;
+    case eioSTRING:
+        cptr = next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN);
+        if (item)
+        {
+            decode_string(strlen(cptr) + 1, (char *) item, cptr);
+            /* res = sscanf(cptr,"%s",(char *)item);*/
+            res = 1;
+        }
+        break;
+    default:
+        gmx_fio_fe(fio, eio, desc, srcfile, line);
+    }
+
+    if ((res <= 0) && fio->bDebug)
+        fprintf(stderr,
+                "Error reading %s %s from file %s (source %s, line %d)\n",
+                eioNames[eio], desc, fio->fn, srcfile, line);
+    return (res > 0);
+}
+
diff --git a/src/gmxlib/gmxfio_bin.c b/src/gmxlib/gmxfio_bin.c
new file mode 100644 (file)
index 0000000..578e546
--- /dev/null
@@ -0,0 +1,204 @@
+/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
+ *
+ * 
+ *                This source code is part of
+ * 
+ *                 G   R   O   M   A   C   S
+ * 
+ *          GROningen MAchine for Chemical Simulations
+ * 
+ *                        VERSION 3.2.0
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ * 
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ * 
+ * For more info, check our website at http://www.gromacs.org
+ * 
+ * And Hey:
+ * GROningen Mixture of Alchemy and Childrens' Stories
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#include "gmx_fatal.h"
+#include "macros.h"
+#include "smalloc.h"
+#include "futil.h"
+#include "filenm.h"
+#include "string2.h"
+#include "gmxfio.h"
+#include "md5.h"
+
+#ifdef GMX_THREADS
+#include "thread_mpi.h"
+#endif
+
+#include "gmxfio_int.h"
+
+/* This is the part that reads dummy and ascii files.  */
+
+
+static bool do_binread(t_fileio *fio, void *item, int nitem, int eio, 
+                       const char *desc, const char *srcfile, int line);
+static bool do_binwrite(t_fileio *fio, const void *item, int nitem, int eio, 
+                        const char *desc, const char *srcfile, int line);
+
+
+const t_iotype bin_iotype={do_binread, do_binwrite};
+
+
+static bool do_binwrite(t_fileio *fio, const void *item, int nitem, int eio, 
+                        const char *desc, const char *srcfile, int line)
+{
+    size_t size = 0, wsize;
+    int ssize;
+
+    gmx_fio_check_nitem(fio, eio, nitem, srcfile, line);
+    switch (eio)
+    {
+    case eioREAL:
+        size = sizeof(real);
+        break;
+    case eioDOUBLE:
+        size = sizeof(double);
+        break;
+    case eioINT:
+        size = sizeof(int);
+        break;
+    case eioGMX_LARGE_INT:
+        size = sizeof(gmx_large_int_t);
+        break;
+    case eioUCHAR:
+        size = sizeof(unsigned char);
+        break;
+    case eioNUCHAR:
+        size = sizeof(unsigned char);
+        break;
+    case eioUSHORT:
+        size = sizeof(unsigned short);
+        break;
+    case eioRVEC:
+        size = sizeof(rvec);
+        break;
+    case eioNRVEC:
+        size = sizeof(rvec);
+        break;
+    case eioIVEC:
+        size = sizeof(ivec);
+        break;
+    case eioSTRING:
+        size = ssize = strlen((char *) item) + 1;
+        do_binwrite(fio, &ssize, 1, eioINT, desc, srcfile, line);
+        break;
+    default:
+        gmx_fio_fe(fio, eio, desc, srcfile, line);
+    }
+
+    wsize = fwrite(item, size, nitem, fio->fp);
+
+    if ((wsize != nitem) && fio->bDebug)
+    {
+        fprintf(stderr,
+                "Error writing %s %s to file %s (source %s, line %d)\n",
+                eioNames[eio], desc, fio->fn, srcfile, line);
+        fprintf(stderr, "written size %u bytes, source size %u bytes\n",
+                (unsigned int) wsize, (unsigned int) size);
+    }
+    return (wsize == nitem);
+}
+
+static bool do_binread(t_fileio *fio, void *item, int nitem, int eio, 
+                       const char *desc, const char *srcfile, int line)
+{
+    size_t size = 0, rsize;
+    int ssize;
+
+    gmx_fio_check_nitem(fio, eio, nitem, srcfile, line);
+    switch (eio)
+    {
+    case eioREAL:
+        if (fio->bDouble)
+            size = sizeof(double);
+        else
+            size = sizeof(float);
+        break;
+    case eioDOUBLE:
+        size = sizeof(double);
+        break;
+    case eioINT:
+        size = sizeof(int);
+        break;
+    case eioGMX_LARGE_INT:
+        size = sizeof(gmx_large_int_t);
+        break;
+    case eioUCHAR:
+        size = sizeof(unsigned char);
+        break;
+    case eioNUCHAR:
+        size = sizeof(unsigned char);
+        break;
+    case eioUSHORT:
+        size = sizeof(unsigned short);
+        break;
+    case eioRVEC:
+    case eioNRVEC:
+        if (fio->bDouble)
+            size = sizeof(double) * DIM;
+        else
+            size = sizeof(float) * DIM;
+        break;
+    case eioIVEC:
+        size = sizeof(ivec);
+        break;
+    case eioSTRING:
+        do_binread(fio, &ssize, 1, eioINT, desc, srcfile, line);
+        size = ssize;
+        break;
+    default:
+        gmx_fio_fe(fio, eio, desc, srcfile, line);
+    }
+    if (item)
+        rsize = fread(item, size, nitem, fio->fp);
+    else
+    {
+        /* Skip over it if we have a NULL pointer here */
+#ifdef HAVE_FSEEKO
+        fseeko(fio->fp, (off_t) (size * nitem), SEEK_CUR);
+#else
+        fseek(fio->fp,(size*nitem),SEEK_CUR);
+#endif    
+        rsize = nitem;
+    }
+    if ((rsize != nitem) && (fio->bDebug))
+        fprintf(stderr,
+                "Error reading %s %s from file %s (source %s, line %d)\n",
+                eioNames[eio], desc, fio->fn, srcfile, line);
+
+    return (rsize == nitem);
+}
+
+
diff --git a/src/gmxlib/gmxfio_int.h b/src/gmxlib/gmxfio_int.h
new file mode 100644 (file)
index 0000000..0b84154
--- /dev/null
@@ -0,0 +1,132 @@
+/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
+ *
+ * 
+ *                This source code is part of
+ * 
+ *                 G   R   O   M   A   C   S
+ * 
+ *          GROningen MAchine for Chemical Simulations
+ * 
+ *                        VERSION 3.2.0
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ * 
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ * 
+ * For more info, check our website at http://www.gromacs.org
+ * 
+ * And Hey:
+ * GROningen Mixture of Alchemy and Childrens' Stories
+ */
+
+
+
+/* This is the new improved and thread safe version of gmxfio.  */
+
+
+/* WARNING WARNING WARNING WARNING
+   The data types used here are PRIVATE to gmxfio routines. DO NOT use them
+   directly in your own code, but use the external functions provided in 
+   include/gmxfio.h 
+
+   If you don't heed this warning, your code will suddenly stop working 
+   at some point in the not-so-distant future. 
+
+   WARNING WARNING WARNING WARNING */
+
+
+/* XDR should be available on all platforms now, 
+ * but we keep the possibility of turning it off...
+ */
+#define USE_XDR
+
+
+
+/* the reader/writer functions  for t_iotype */
+typedef bool read_func(t_fileio *fio, void *item, int nitem, int eio,
+                       const char *desc,const char *srcfile,int line);
+typedef bool write_func(t_fileio *fio, const void *item, int nitem, int eio,
+                        const char *desc,const char *srcfile,int line);
+
+
+/* these are pointers to the actual reading & writing functions */
+typedef struct
+{
+    read_func *nread;
+    write_func *nwrite;
+} t_iotype;
+
+
+
+struct t_fileio
+{
+    FILE *fp; /* the file pointer */
+    const t_iotype *iotp;  /* file type */
+    bool bOpen,  /* the file is open */
+         bRead,  /* the file is open for reading */
+         bDouble, /* write doubles instead of floats */
+         bDebug, /* the file ops should come with debug info */
+         bStdio, /* the file is actually stdin or stdout */
+         bLargerThan_off_t,  /* if the file position is largen than off_t 
+                                could hold */
+         bReadWrite; /* the file is open for reading and writing */
+    char *fn; /* the file name */
+    XDR *xdr; /* the xdr data pointer */
+    enum xdr_op xdrmode; /* the xdr mode */
+    int iFTP; /* the file type identifier */
+
+    const char *comment; /* a comment string for debugging */
+
+    t_fileio *next, *prev; /* next and previous file pointers in the
+                              linked list */
+#ifdef GMX_THREADS
+    tMPI_Spinlock_t  mtx;  /* content locking mutex. This is a spinlock
+                              for performance reasons: in some cases every
+                              single byte that gets read/written requires
+                              a lock */
+#endif
+}; 
+
+
+
+extern const t_iotype asc_iotype;
+extern const t_iotype bin_iotype;
+extern const t_iotype xdr_iotype;
+extern const t_iotype dummy_iotype;
+
+extern const char *eioNames[eioNR];
+
+
+
+#define GMX_FIO_BUFLEN 256
+
+/* make a debug string if that is requested in the fio */
+const char *gmx_fio_dbgstr(t_fileio *fio, const char *desc, char *buf);
+/* check the number of items against the allowed number of items */
+void gmx_fio_check_nitem(t_fileio *fio, int eio, int nitem, const char *file, 
+                         int line);
+/* check the output type against allowed values */
+void gmx_fio_fe(t_fileio *fio, int eio, const char *desc, const char *srcfile, 
+                int line);
+
+/* lock/unlock the mutex associated with a fio  */
+void gmx_fio_lock(t_fileio *fio);
+void gmx_fio_unlock(t_fileio *fio);
+
+
+
diff --git a/src/gmxlib/gmxfio_rw.c b/src/gmxlib/gmxfio_rw.c
new file mode 100644 (file)
index 0000000..c13edee
--- /dev/null
@@ -0,0 +1,835 @@
+/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
+ *
+ * 
+ *                This source code is part of
+ * 
+ *                 G   R   O   M   A   C   S
+ * 
+ *          GROningen MAchine for Chemical Simulations
+ * 
+ *                        VERSION 3.2.0
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ * 
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ * 
+ * For more info, check our website at http://www.gromacs.org
+ * 
+ * And Hey:
+ * GROningen Mixture of Alchemy and Childrens' Stories
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#include "gmx_fatal.h"
+#include "macros.h"
+#include "smalloc.h"
+#include "futil.h"
+#include "filenm.h"
+#include "string2.h"
+#include "gmxfio.h"
+#include "md5.h"
+
+#ifdef GMX_THREADS
+#include "thread_mpi.h"
+#endif
+
+#include "gmxfio_int.h"
+
+
+/*******************************************************************
+ *
+ * READ/WRITE FUNCTIONS 
+ *
+*******************************************************************/
+
+bool gmx_fio_reade_real(t_fileio *fio, real *item,
+                        const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioREAL, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_reade_double(t_fileio *fio, double *item,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioDOUBLE, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_reade_int(t_fileio *fio, int *item,
+                       const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioINT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_reade_gmx_large_int(t_fileio *fio, gmx_large_int_t *item,
+                             const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioGMX_LARGE_INT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_reade_uchar(t_fileio *fio, unsigned char *item,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioUCHAR, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_reade_ushort(t_fileio *fio, unsigned short *item,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioUSHORT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_reade_rvec(t_fileio *fio, rvec *item,
+                        const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioRVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_reade_ivec(t_fileio *fio, ivec *item,
+                        const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioIVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_reade_string(t_fileio *fio, char *item,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, 1, eioSTRING, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+/* Write */
+
+bool gmx_fio_writee_real(t_fileio *fio, real item,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, &item, 1, eioREAL, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_writee_double(t_fileio *fio, double item,
+                           const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, &item, 1, eioDOUBLE, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_writee_int(t_fileio *fio, int item,
+                        const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, &item, 1, eioINT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_writee_gmx_large_int(t_fileio *fio, gmx_large_int_t item,
+                              const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, &item, 1, eioGMX_LARGE_INT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_writee_uchar(t_fileio *fio, unsigned char item,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, &item, 1, eioUCHAR, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_writee_ushort(t_fileio *fio, unsigned short item,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, &item, 1, eioUSHORT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_writee_rvec(t_fileio *fio, rvec *item,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, item, 1, eioRVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_writee_ivec(t_fileio *fio, ivec *item,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, item, 1, eioIVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_writee_string(t_fileio *fio, const char *item,
+                           const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, item, 1, eioSTRING, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+/* Read/write functions */
+
+bool gmx_fio_doe_real(t_fileio *fio, real *item,
+                      const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioREAL, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioREAL, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_doe_double(t_fileio *fio, double *item,
+                        const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioDOUBLE, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioDOUBLE, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_doe_int(t_fileio *fio, int *item,
+                     const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioINT, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioINT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_doe_gmx_large_int(t_fileio *fio, gmx_large_int_t *item,
+                           const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioGMX_LARGE_INT, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioGMX_LARGE_INT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item,
+                       const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioUCHAR, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioUCHAR, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item,
+                       const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioUSHORT, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioUSHORT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item,
+                      const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioRVEC, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioRVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item,
+                      const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioIVEC, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioIVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_doe_string(t_fileio *fio, char *item,
+                        const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+        ret=fio->iotp->nread(fio, item, 1, eioSTRING, desc, srcfile, line);
+    else
+        ret=fio->iotp->nwrite(fio, item, 1, eioSTRING, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+
+
+
+
+/* Array reading & writing */
+
+bool gmx_fio_nreade_real(t_fileio *fio, real *item, int n,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioREAL, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nreade_double(t_fileio *fio, double *item, int n,
+                            const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret= ret && fio->iotp->nread(fio, &(item[i]), 1, eioDOUBLE, desc, srcfile, 
+                               line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nreade_int(t_fileio *fio, int *item, int n,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioINT, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nreade_gmx_large_int(t_fileio *fio, gmx_large_int_t *item, int n,
+                               const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioGMX_LARGE_INT, desc, 
+                              srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_nreade_uchar(t_fileio *fio, unsigned char *item, int n,
+                           const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, n, eioNUCHAR, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nreade_ushort(t_fileio *fio, unsigned short *item, int n,
+                           const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioUSHORT, desc, 
+                                    srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nreade_rvec(t_fileio *fio, rvec *item, int n,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nread(fio, item, n, eioNRVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nreade_ivec(t_fileio *fio, ivec *item, int n,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nread(fio, item[i], 1, eioIVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nreade_string(t_fileio *fio, char *item[], int n,
+                           const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nread(fio, item[i], 1, eioSTRING, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+
+/* Array writing */
+
+bool gmx_fio_nwritee_real(t_fileio *fio, const real *item, int n,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioREAL, desc, 
+                                     srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_nwritee_double(t_fileio *fio, const double *item, int n,
+                            const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioDOUBLE, desc, 
+                                     srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_nwritee_int(t_fileio *fio, const int *item, int n,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioINT, desc, srcfile, 
+                                     line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nwritee_gmx_large_int(t_fileio *fio, 
+                               const gmx_large_int_t *item, int n,
+                               const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioGMX_LARGE_INT, 
+                                     desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nwritee_uchar(t_fileio *fio, const unsigned char *item, int n,
+                           const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, item, n, eioNUCHAR, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nwritee_ushort(t_fileio *fio, const unsigned short *item, int n,
+                           const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioUSHORT, desc, 
+                                     srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_nwritee_rvec(t_fileio *fio, const rvec *item, int n,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret;
+    gmx_fio_lock(fio);
+    ret=fio->iotp->nwrite(fio, item, n, eioNRVEC, desc, srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+bool gmx_fio_nwritee_ivec(t_fileio *fio, const ivec *item, int n,
+                          const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioIVEC, desc, 
+                                     srcfile, line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+bool gmx_fio_nwritee_string(t_fileio *fio, const char *item[], int n,
+                            const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+        ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioSTRING, desc, srcfile, 
+                               line);
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+/* array read/write functions */
+
+bool gmx_fio_ndoe_real(t_fileio *fio, real *item, int n,
+                       const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+    {
+        if (fio->bRead)
+        {
+            ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioREAL, desc, 
+                                  srcfile, line);
+        }
+        else
+        {
+            ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioREAL, desc, 
+                                   srcfile, line);
+        }
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+bool gmx_fio_ndoe_double(t_fileio *fio, double *item, int n,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+    {
+        if (fio->bRead)
+        {
+            ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioDOUBLE, desc, 
+                                  srcfile, line);
+        }
+        else
+        {
+            ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioDOUBLE, desc, 
+                                   srcfile, line);
+        }
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+bool gmx_fio_ndoe_int(t_fileio *fio, int *item, int n,
+                      const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+    {
+        if (fio->bRead)
+        {
+            ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioINT, desc, 
+                                  srcfile, line);
+        }
+        else
+        {
+            ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioINT, desc, 
+                                   srcfile, line);
+        }
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+bool gmx_fio_ndoe_gmx_large_int(t_fileio *fio, gmx_large_int_t *item, int n,
+                            const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+    {
+        if (fio->bRead)
+        {
+            ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioGMX_LARGE_INT, desc, 
+                                  srcfile, line);
+        }
+        else
+        {
+            ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioGMX_LARGE_INT, desc, 
+                                   srcfile, line);
+        }
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+bool gmx_fio_ndoe_uchar(t_fileio *fio, unsigned char *item, int n,
+                        const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+    {
+        ret=ret && fio->iotp->nread(fio, item, n, eioNUCHAR, desc, 
+                                    srcfile, line);
+    }
+    else
+    {
+        ret=ret && fio->iotp->nwrite(fio, item, n, eioNUCHAR, desc, 
+                                     srcfile, line);
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+bool gmx_fio_ndoe_ushort(t_fileio *fio, unsigned short *item, int n,
+                        const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+    {
+        if (fio->bRead)
+        {
+            ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioUSHORT, desc, 
+                                  srcfile, line);
+        }
+        else
+        {
+            ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioUSHORT, desc, 
+                                   srcfile, line);
+        }
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n,
+                       const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    gmx_fio_lock(fio);
+    if (fio->bRead)
+    {
+        ret=ret && fio->iotp->nread(fio, item, n, eioNRVEC, desc, srcfile, line);
+    }
+    else
+    {
+        ret=ret && fio->iotp->nwrite(fio, item, n, eioNRVEC, desc, srcfile, 
+                               line);
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+bool gmx_fio_ndoe_ivec(t_fileio *fio, ivec *item, int n,
+                       const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+    {
+        if (fio->bRead)
+        {
+            ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioIVEC, desc, 
+                                  srcfile, line);
+        }
+        else
+        {
+            ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioIVEC, desc, 
+                                   srcfile, line);
+        }
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n,
+                         const char *desc, const char *srcfile, int line)
+{
+    bool ret=TRUE;
+    int i;
+    gmx_fio_lock(fio);
+    for(i=0;i<n;i++)
+    {
+        if (fio->bRead)
+        {
+            ret=ret && fio->iotp->nread(fio, &(item[i]), 1, eioSTRING, desc, 
+                                  srcfile, line);
+        }
+        else
+        {
+            ret=ret && fio->iotp->nwrite(fio, &(item[i]), 1, eioSTRING, desc, 
+                                   srcfile, line);
+        }
+    }
+    gmx_fio_unlock(fio);
+    return ret;
+}
+
+
+
+
+
diff --git a/src/gmxlib/gmxfio_xdr.c b/src/gmxlib/gmxfio_xdr.c
new file mode 100644 (file)
index 0000000..c451c85
--- /dev/null
@@ -0,0 +1,263 @@
+/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
+ *
+ * 
+ *                This source code is part of
+ * 
+ *                 G   R   O   M   A   C   S
+ * 
+ *          GROningen MAchine for Chemical Simulations
+ * 
+ *                        VERSION 3.2.0
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ * 
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ * 
+ * For more info, check our website at http://www.gromacs.org
+ * 
+ * And Hey:
+ * GROningen Mixture of Alchemy and Childrens' Stories
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#include "gmx_fatal.h"
+#include "macros.h"
+#include "smalloc.h"
+#include "futil.h"
+#include "filenm.h"
+#include "string2.h"
+#include "gmxfio.h"
+#include "md5.h"
+
+#ifdef GMX_THREADS
+#include "thread_mpi.h"
+#endif
+
+#include "gmxfio_int.h"
+
+/* This is the part that reads xdr files.  */
+
+
+/* file type functions */
+static bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio, 
+                       const char *desc, const char *srcfile, int line);
+static bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio, 
+                        const char *desc, const char *srcfile, int line);
+
+
+const t_iotype xdr_iotype={do_xdrread, do_xdrwrite};
+
+
+#ifdef USE_XDR
+
+static bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, 
+                   const char *desc, const char *srcfile, int line)
+{
+    unsigned char ucdum, *ucptr;
+    bool_t res = 0;
+    float fvec[DIM];
+    double dvec[DIM];
+    int j, m, *iptr, idum;
+    gmx_large_int_t sdum;
+    real *ptr;
+    unsigned short us;
+    double d = 0;
+    float f = 0;
+
+    gmx_fio_check_nitem(fio, eio, nitem, srcfile, line);
+    switch (eio)
+    {
+    case eioREAL:
+        if (fio->bDouble)
+        {
+            if (item && !fio->bRead)
+                d = *((real *) item);
+            res = xdr_double(fio->xdr, &d);
+            if (item)
+                *((real *) item) = d;
+        }
+        else
+        {
+            if (item && !fio->bRead)
+                f = *((real *) item);
+            res = xdr_float(fio->xdr, &f);
+            if (item)
+                *((real *) item) = f;
+        }
+        break;
+    case eioDOUBLE:
+        if (item && !fio->bRead)
+            d = *((double *) item);
+        res = xdr_double(fio->xdr, &d);
+        if (item)
+            *((double *) item) = d;
+        break;
+    case eioINT:
+        if (item && !fio->bRead)
+            idum = *(int *) item;
+        res = xdr_int(fio->xdr, &idum);
+        if (item)
+            *(int *) item = idum;
+        break;
+    case eioGMX_LARGE_INT:
+        /* do_xdr will not generate a warning when a 64bit gmx_large_int_t
+         * value that is out of 32bit range is read into a 32bit gmx_large_int_t.
+         */
+        if (item && !fio->bRead)
+            sdum = *(gmx_large_int_t *) item;
+        res = xdr_gmx_large_int(fio->xdr, &sdum, NULL);
+        if (item)
+            *(gmx_large_int_t *) item = sdum;
+        break;
+    case eioUCHAR:
+        if (item && !fio->bRead)
+            ucdum = *(unsigned char *) item;
+        res = xdr_u_char(fio->xdr, &ucdum);
+        if (item)
+            *(unsigned char *) item = ucdum;
+        break;
+    case eioNUCHAR:
+        ucptr = (unsigned char *) item;
+        res = 1;
+        for (j = 0; (j < nitem) && res; j++)
+        {
+            res = xdr_u_char(fio->xdr, &(ucptr[j]));
+        }
+        break;
+    case eioUSHORT:
+        if (item && !fio->bRead)
+            us = *(unsigned short *) item;
+        res = xdr_u_short(fio->xdr, (unsigned short *) &us);
+        if (item)
+            *(unsigned short *) item = us;
+        break;
+    case eioRVEC:
+        if (fio->bDouble)
+        {
+            if (item && !fio->bRead)
+                for (m = 0; (m < DIM); m++)
+                    dvec[m] = ((real *) item)[m];
+            res = xdr_vector(fio->xdr, (char *) dvec, DIM,
+                             (unsigned int) sizeof(double),
+                             (xdrproc_t) xdr_double);
+            if (item)
+                for (m = 0; (m < DIM); m++)
+                    ((real *) item)[m] = dvec[m];
+        }
+        else
+        {
+            if (item && !fio->bRead)
+                for (m = 0; (m < DIM); m++)
+                    fvec[m] = ((real *) item)[m];
+            res = xdr_vector(fio->xdr, (char *) fvec, DIM,
+                             (unsigned int) sizeof(float),
+                             (xdrproc_t) xdr_float);
+            if (item)
+                for (m = 0; (m < DIM); m++)
+                    ((real *) item)[m] = fvec[m];
+        }
+        break;
+    case eioNRVEC:
+        ptr = NULL;
+        res = 1;
+        for (j = 0; (j < nitem) && res; j++)
+        {
+            if (item)
+                ptr = ((rvec *) item)[j];
+            res = do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line);
+        }
+        break;
+    case eioIVEC:
+        iptr = (int *) item;
+        res = 1;
+        for (m = 0; (m < DIM) && res; m++)
+        {
+            if (item && !fio->bRead)
+                idum = iptr[m];
+            res = xdr_int(fio->xdr, &idum);
+            if (item)
+                iptr[m] = idum;
+        }
+        break;
+    case eioSTRING:
+    {
+        char *cptr;
+        int slen;
+
+        if (item)
+        {
+            if (!fio->bRead)
+                slen = strlen((char *) item) + 1;
+            else
+                slen = 0;
+        }
+        else
+            slen = 0;
+
+        if (xdr_int(fio->xdr, &slen) <= 0)
+            gmx_fatal(FARGS, "wrong string length %d for string %s"
+                      " (source %s, line %d)",slen,desc,srcfile,line);
+        if (!item && fio->bRead)
+            snew(cptr,slen);
+        else
+            cptr=(char *)item;
+        if (cptr)
+            res = xdr_string(fio->xdr,&cptr,slen);
+        else
+            res = 1;
+        if (!item && fio->bRead)
+            sfree(cptr);
+        break;
+    }
+    default:
+        gmx_fio_fe(fio, eio, desc, srcfile, line);
+    }
+    if ((res == 0) && (fio->bDebug))
+        fprintf(stderr,"Error in xdr I/O %s %s to file %s (source %s, line %d)\n",
+                eioNames[eio],desc,fio->fn,srcfile,line);
+
+    return (res != 0);
+}
+
+
+static bool do_xdrread(t_fileio *fio, void *item, int nitem, int eio, 
+                       const char *desc, const char *srcfile, int line)
+{
+    return do_xdr(fio, item, nitem, eio, desc, srcfile, line);
+}
+
+
+static bool do_xdrwrite(t_fileio *fio, const void *item, int nitem, int eio, 
+                        const char *desc, const char *srcfile, int line)
+{
+    void *it=(void*)item; /* ugh.. */
+    return do_xdr(fio, it, nitem, eio, desc, srcfile, line);
+}
+
+#endif
+
+
index 41550a57b78270bb943368227f7a41ef0ed8f505..73587cdbd10be668a603feecc54984045c18d24f 100644 (file)
 #endif
 
 
+/* This is just for clarity - it can never be anything but 4! */
+#define XDR_INT_SIZE 4
+
+
+
+#ifndef GMX_THREADS
+
+/* NOTE: DO NOT USE THESE ANYWHERE IN GROMACS ITSELF. 
+   These are necessary for the backward-compatile io routines for 3d party
+   tools */
 #define MAXID 256
 static FILE *xdrfiles[MAXID];
 static XDR *xdridptr[MAXID];
 static char xdrmodes[MAXID];
 static unsigned int cnt;
 
-/* This is just for clarity - it can never be anything but 4! */
-#define XDR_INT_SIZE 4
+#endif
 
 #ifdef GMX_FORTRAN
 
+#ifdef GMX_THREADS
+#error The Fortran IO routines cannot be thread safe.
+#endif
+
+/* the open&close prototypes */
+int xdropen(XDR *xdrs, const char *filename, const char *type);
+int xdrclose(XDR *xdrs);
+
 typedef void (* F77_FUNC(xdrfproc,XDRFPROC))(int *, void *, int *);
 
 int ftocstr(char *ds, int dl, char *ss, int sl)
@@ -275,48 +292,18 @@ F77_FUNC(xdrfopen,XDRFOPEN)(int *xdrid, char *fp_ptr, char *mode_ptr,
 }
 #endif /* GMX_FORTRAN */
 
-/*___________________________________________________________________________
- |
- | what follows are the C routines for opening, closing xdr streams
- | and the routine to read/write compressed coordinates together
- | with some routines to assist in this task (those are marked
- | static and cannot be called from user programs)
-*/
-#define MAXABS INT_MAX-2
-
-#ifndef MIN
-#define MIN(x,y) ((x) < (y) ? (x):(y))
-#endif
-#ifndef MAX
-#define MAX(x,y) ((x) > (y) ? (x):(y))
-#endif
-#ifndef SQR
-#define SQR(x) ((x)*(x))
-#endif
-static int magicints[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0,
-    8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
-    80, 101, 128, 161, 203, 256, 322, 406, 512, 645,
-    812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501,
-    8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536,
-    82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
-    832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042,
-    8388607, 10568983, 13316085, 16777216 };
-
-#define FIRSTIDX 9
-/* note that magicints[FIRSTIDX-1] == 0 */
-#define LASTIDX (sizeof(magicints) / sizeof(*magicints))
-
-
+#ifndef GMX_THREADS
 /*__________________________________________________________________________
  |
  | xdropen - open xdr file
  |
  | This versions differs from xdrstdio_create, because I need to know
- | the state of the file (read or write) so I can use xdr3dfcoord
- | in eigther read or write mode, and the file descriptor
+ | the state of the file (read or write)  and the file descriptor
  | so I can close the file (something xdr_destroy doesn't do).
  |
+ | NOTE: THIS FUNCTION IS NOW OBSOLETE AND ONLY PROVIDED FOR BACKWARD
+ |       COMPATIBILITY OF 3D PARTY TOOLS. IT SHOULD NOT BE USED ANYWHERE 
+ |       IN GROMACS ITSELF. 
 */
 
 int xdropen(XDR *xdrs, const char *filename, const char *type) {
@@ -383,7 +370,6 @@ int xdropen(XDR *xdrs, const char *filename, const char *type) {
     }
     return xdrid;
 }
-
 /*_________________________________________________________________________
  |
  | xdrclose - close a xdr file
@@ -392,6 +378,9 @@ int xdropen(XDR *xdrs, const char *filename, const char *type) {
  | It also closes the associated file descriptor (this is *not*
  | done by xdr_destroy).
  |
+ | NOTE: THIS FUNCTION IS NOW OBSOLETE AND ONLY PROVIDED FOR BACKWARD
+ |       COMPATIBILITY OF 3D PARTY TOOLS. IT SHOULD NOT BE USED ANYWHERE 
+ |       IN GROMACS ITSELF. 
 */
  
 int xdrclose(XDR *xdrs) {
@@ -418,11 +407,39 @@ int xdrclose(XDR *xdrs) {
     return 0;    
 }
 
-FILE *
-xdr_get_fp(int xdrid)
-{
-       return xdrfiles[xdrid];
-}
+#endif
+
+
+/*___________________________________________________________________________
+ |
+ | what follows are the C routine to read/write compressed coordinates together
+ | with some routines to assist in this task (those are marked
+ | static and cannot be called from user programs)
+*/
+#define MAXABS INT_MAX-2
+
+#ifndef MIN
+#define MIN(x,y) ((x) < (y) ? (x):(y))
+#endif
+#ifndef MAX
+#define MAX(x,y) ((x) > (y) ? (x):(y))
+#endif
+#ifndef SQR
+#define SQR(x) ((x)*(x))
+#endif
+static int magicints[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0,
+    8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
+    80, 101, 128, 161, 203, 256, 322, 406, 512, 645,
+    812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501,
+    8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536,
+    82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
+    832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042,
+    8388607, 10568983, 13316085, 16777216 };
+
+#define FIRSTIDX 9
+/* note that magicints[FIRSTIDX-1] == 0 */
+#define LASTIDX (sizeof(magicints) / sizeof(*magicints))
 
 
 /*____________________________________________________________________________
@@ -696,9 +713,8 @@ static void receiveints(int buf[], const int num_of_ints, int num_of_bits,
  |
  */
  
-int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) {
-    
-
+int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision, bool bRead) 
+{
     static int *ip = NULL;
     static int oldsize;
     static int *buf;
@@ -721,18 +737,9 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) {
        
     bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0;
     prevcoord[0]  = prevcoord[1]  = prevcoord[2]  = 0;
-    
-    /* find out if xdrs is opened for reading or for writing */
-    xdrid = 0;
-    while (xdridptr[xdrid] != xdrs) {
-       xdrid++;
-       if (xdrid >= MAXID) {
-           fprintf(stderr, "xdr error. no open xdr stream\n");
-           exit (1);
-       }
-    }
-    if ((xdrmodes[xdrid] == 'w') || (xdrmodes[xdrid] == 'a')) {
-
+   
+    if (!bRead)
+    {
        /* xdrs is open for writing */
 
        if (xdr_int(xdrs, size) == 0)
index a210b70d4876c03caf3aec6d537506e860cb0334..b650767b75d63c5358b2ede7ee599a204689338e 100644 (file)
@@ -850,47 +850,3 @@ void unshift_self(t_graph *g,matrix box,rvec x[])
   }
 }
 #undef GCHECK
-
-#ifdef DEBUGMSHIFT
-void main(int argc,char *argv[])
-{
-  FILE         *out;
-  t_args       targ;
-  t_topology   top;
-  t_statheader sh;
-  rvec         *x;
-  ivec         *mshift;
-  matrix       box;
-
-  t_graph      *g;
-  int          i,idum,pid;
-  real         rdum;
-
-  CopyRight(stderr,argv[0]);
-  parse_common_args(&argc,argv,&targ,PCA_NEED_INOUT,NULL);
-  if (argc > 1)
-    pid=strtol(argv[1], NULL, 10);
-  else
-    pid=0;
-  
-  read_status_header(targ.infile,&sh);
-  snew(x,sh.natoms);
-  snew(mshift,sh.natoms);
-
-  fprintf(stderr,"Reading Status %s\n",targ.infile);
-  read_status(targ.infile,&idum,&rdum,&rdum,NULL,
-             box,NULL,NULL,&idum,x,NULL,NULL,&idum,NULL,&top);
-
-  fprintf(stderr,"Making Graph Structure...\n");
-  g=mk_graph(&(top.idef),top.atoms.nr,FALSE,FALSE);
-
-  out=gmx_fio_fopen(targ.outfile,"w");
-
-  fprintf(stderr,"Making Shift...\n");
-  mk_mshift(out,g,box,x,mshift);
-
-  p_graph(out,"In Den Haag daar woont een graaf...",g);
-  gmx_fio_fclose(out);
-}
-#endif
-
index d019e4fb5951ef190f195c68c949a9d1640bd612..67da84cd0b40cd0204b8f2414c1accd8e2accf91 100644 (file)
@@ -47,6 +47,7 @@
 #include "copyrite.h"
 #include "gmx_fatal.h"
 #include "mtxio.h"
+#include "gmxfio.h"
 
 
 /* Just a number to identify our file type */
  *         Each entry consists of an integer column index and floating-point data value.
  */
 
-void
-gmx_mtxio_write(const char *             filename,
-                int                      nrow,
-                int                      ncol,
-                real *                   full_matrix,
-                gmx_sparsematrix_t *     sparse_matrix)
+void gmx_mtxio_write(const char *             filename,
+                     int                      nrow,
+                     int                      ncol,
+                     real *                   full_matrix,
+                     gmx_sparsematrix_t *     sparse_matrix)
 {
-    int     fd;
+    t_fileio *fio;
     XDR *   xd;
     int     i,j,prec;
     bool    bDum = TRUE;
@@ -97,58 +97,58 @@ gmx_mtxio_write(const char *             filename,
         gmx_fatal(FARGS,"Both full AND sparse matrix specified to gmx_mtxio_write().\n");
     }
     
-    fd = gmx_fio_open(filename,"w");
-    gmx_fio_select(fd);
-    xd = gmx_fio_getxdr(fd);
+    fio = gmx_fio_open(filename,"w");
+    gmx_fio_checktype(fio);
+    xd = gmx_fio_getxdr(fio);
     
     /* Write magic number */
     i = GMX_MTXIO_MAGIC_NUMBER;
-    do_int(i);
+    gmx_fio_do_int(fio, i);
     
     /* Write generating Gromacs version */
-    do_string(GromacsVersion());
+    gmx_fio_write_string(fio, GromacsVersion());
     
     /* Write 1 for double, 0 for single precision */
     if(sizeof(real)==sizeof(double))
         prec = 1;
     else
         prec = 0;
-    do_int(prec);
+    gmx_fio_do_int(fio, prec);
     
-    do_int(nrow);
-    do_int(ncol);
+    gmx_fio_do_int(fio, nrow);
+    gmx_fio_do_int(fio, ncol);
     
     if(full_matrix!=NULL)
     {
         /* Full matrix storage format */
         i = GMX_MTXIO_FULL_MATRIX;
-        do_int(i);
+        gmx_fio_do_int(fio, i);
         sz = nrow*ncol;        
-        ndo_real(full_matrix,sz,bDum);
+        bDum=gmx_fio_ndo_real(fio, full_matrix,sz);
     }
     else
     {
         /* Sparse storage */
         i = GMX_MTXIO_SPARSE_MATRIX;
-        do_int(i);
+        gmx_fio_do_int(fio, i);
         
-        do_int(sparse_matrix->compressed_symmetric);
-        do_int(sparse_matrix->nrow);
+        gmx_fio_do_int(fio, sparse_matrix->compressed_symmetric);
+        gmx_fio_do_int(fio, sparse_matrix->nrow);
         if(sparse_matrix->nrow != nrow)
         {
             gmx_fatal(FARGS,"Internal inconsistency in sparse matrix.\n");
         }
-        ndo_int(sparse_matrix->ndata,sparse_matrix->nrow,bDum);
+        bDum=gmx_fio_ndo_int(fio, sparse_matrix->ndata,sparse_matrix->nrow);
         for(i=0;i<sparse_matrix->nrow;i++)
         {
             for(j=0;j<sparse_matrix->ndata[i];j++)
             {
-                do_int(sparse_matrix->data[i][j].col);
-                do_real(sparse_matrix->data[i][j].value);
+                gmx_fio_do_int(fio, sparse_matrix->data[i][j].col);
+                gmx_fio_do_real(fio, sparse_matrix->data[i][j].value);
             }
         }
     }
-    gmx_fio_close(fd);
+    gmx_fio_close(fio);
 }
 
 
@@ -159,7 +159,7 @@ gmx_mtxio_read (const char *            filename,
                 real **                 full_matrix,
                 gmx_sparsematrix_t **   sparse_matrix)
 {
-    int     fd;
+    t_fileio  *fio;
     XDR *   xd;
     int     i,j,prec;
     bool    bDum = TRUE;
@@ -167,13 +167,13 @@ gmx_mtxio_read (const char *            filename,
     char    gmxver[256];
     size_t  sz;
     
-    fd = gmx_fio_open(filename,"r");
-    gmx_fio_select(fd);
-    xd = gmx_fio_getxdr(fd);
+    fio = gmx_fio_open(filename,"r");
+    gmx_fio_checktype(fio);
+    xd = gmx_fio_getxdr(fio);
     
     /* Read and check magic number */
     i = GMX_MTXIO_MAGIC_NUMBER;
-    do_int(i);
+    gmx_fio_do_int(fio, i);
 
     if(i!=GMX_MTXIO_MAGIC_NUMBER)
     {
@@ -183,24 +183,24 @@ gmx_mtxio_read (const char *            filename,
     }
     
     /* Read generating Gromacs version */
-    do_string(gmxver);
+    gmx_fio_do_string(fio, gmxver);
     
     /* Write 1 for double, 0 for single precision */
     if(sizeof(real)==sizeof(double))
         prec = 1;
     else
         prec = 0;
-    do_int(prec);
+    gmx_fio_do_int(fio, prec);
 
     fprintf(stderr,"Reading %s precision matrix generated by Gromacs %s\n",
             (prec == 1) ? "double" : "single",gmxver);
     
-    do_int(i);
+    gmx_fio_do_int(fio, i);
     *nrow=i;
-    do_int(i);
+    gmx_fio_do_int(fio, i);
     *ncol=i;
 
-    do_int(i);
+    gmx_fio_do_int(fio, i);
     
     if(i==GMX_MTXIO_FULL_MATRIX)
     {
@@ -208,7 +208,7 @@ gmx_mtxio_read (const char *            filename,
 
         sz = (*nrow) * (*ncol);
         snew((*full_matrix),sz);
-        ndo_real((*full_matrix),sz,bDum);
+        bDum=gmx_fio_ndo_real(fio, (*full_matrix),sz);
     }
     else
     {
@@ -216,8 +216,8 @@ gmx_mtxio_read (const char *            filename,
         printf("Sparse matrix storage format, nrow=%d, ncols=%d\n",*nrow,*ncol);
 
         snew((*sparse_matrix),1);
-        do_int((*sparse_matrix)->compressed_symmetric);
-        do_int((*sparse_matrix)->nrow);        
+        gmx_fio_do_int(fio, (*sparse_matrix)->compressed_symmetric);
+        gmx_fio_do_int(fio, (*sparse_matrix)->nrow);        
         if((*sparse_matrix)->nrow != *nrow)
         {
             gmx_fatal(FARGS,"Internal inconsistency in sparse matrix.\n");
@@ -225,7 +225,8 @@ gmx_mtxio_read (const char *            filename,
         snew((*sparse_matrix)->ndata,(*sparse_matrix)->nrow);
         snew((*sparse_matrix)->nalloc,(*sparse_matrix)->nrow);
         snew((*sparse_matrix)->data,(*sparse_matrix)->nrow);
-        ndo_int((*sparse_matrix)->ndata,(*sparse_matrix)->nrow,bDum);
+        bDum=gmx_fio_ndo_int(fio, (*sparse_matrix)->ndata,
+                             (*sparse_matrix)->nrow);
 
         for(i=0;i<(*sparse_matrix)->nrow;i++)
         {
@@ -234,12 +235,12 @@ gmx_mtxio_read (const char *            filename,
             
             for(j=0;j<(*sparse_matrix)->ndata[i];j++)
             {
-                do_int((*sparse_matrix)->data[i][j].col);
-                do_real((*sparse_matrix)->data[i][j].value);
+                gmx_fio_do_int(fio, (*sparse_matrix)->data[i][j].col);
+                gmx_fio_do_real(fio, (*sparse_matrix)->data[i][j].value);
             }
         }
     }
-    gmx_fio_close(fd);
+    gmx_fio_close(fio);
 }
 
 
index 68cd6e1e9bc8a344c3ca49886ddc99f79f3ad6bd..6d62a93eb57324a9eb2f81140cd1904afe879fc3 100644 (file)
@@ -512,7 +512,9 @@ void nb_kernel400_ia32_sse(int *           p_nri,
                gmx_mm_update_iforce_1atom_ps(fix,fiy,fiz,faction+ii3,fshift+is3);
                
         ggid             = gid[n];         
-               gmx_mm_update_2pot_ps(vctot,vc+ggid,vgbtot,gpol+ggid);
+
+               gmx_mm_update_1pot_ps(vctot,vc+ggid);
+               gmx_mm_update_1pot_ps(vgbtot,gpol+ggid);
                gmx_mm_update_1pot_ps(dvdasum,dvda+ii);
     }
        
index 4a6221664f0f5e8a952a47efba0f0d0184a0c2b9..9f7b48236845c590a54c1a14c1c31b6b1366cbdf 100644 (file)
@@ -105,7 +105,7 @@ void nb_kernel400_ia32_sse2(int *           p_nri,
        nri        = *p_nri;
        ntype      = *p_ntype;
        nthreads   = *p_nthreads; 
-  facel      = *p_facel    
+  facel      = *p_facel;    
        krf        = *p_krf;
        crf        = *p_crf;
        tabscl     = *p_tabscale;
index b4c29fed08bf03ab5ba040bb12571526dd108418..99f6ef37ef2befaa704e88a03ef497f61874e01f 100644 (file)
@@ -108,7 +108,7 @@ void nb_kernel410_ia32_sse2(int *           p_nri,
        nri        = *p_nri;
        ntype      = *p_ntype;
        nthreads   = *p_nthreads; 
-  facel      = *p_facel     
+  facel      = *p_facel;     
        krf        = *p_krf;
        crf        = *p_crf;
        tabscl     = *p_tabscale;
index cb90701cc6a895cb09aa6306e70f20a4bccc812c..e0d5545e85d74605810b9f75845963460bb968be 100644 (file)
@@ -110,7 +110,7 @@ void nb_kernel430_ia32_sse2(int *           p_nri,
        nri        = *p_nri;
        ntype      = *p_ntype;
        nthreads   = *p_nthreads; 
-  facel      = *p_facel      
+  facel      = *p_facel;      
        krf        = *p_krf;
        crf        = *p_crf;
        tabscl     = *p_tabscale;
index ddc6e273342da0164c05aae7afa55b4586d09a6a..79ad695b8438213a4a628bd1d9fb86dc624daaac 100644 (file)
@@ -512,7 +512,9 @@ void nb_kernel400_sse2_single(int *           p_nri,
                gmx_mm_update_iforce_1atom_ps(fix,fiy,fiz,faction+ii3,fshift+is3);
                
         ggid             = gid[n];         
-               gmx_mm_update_2pot_ps(vctot,vc+ggid,vgbtot,gpol+ggid);
+
+               gmx_mm_update_1pot_ps(vctot,vc+ggid);
+               gmx_mm_update_1pot_ps(vgbtot,gpol+ggid);
                gmx_mm_update_1pot_ps(dvdasum,dvda+ii);
     }
        
index 536b48b7efdb9184889c8526c00744587f76c9fa..d87325d4550a21d2a46d72aa5e571baaa8ce8845 100644 (file)
@@ -512,7 +512,9 @@ void nb_kernel400_x86_64_sse(int *           p_nri,
                gmx_mm_update_iforce_1atom_ps(fix,fiy,fiz,faction+ii3,fshift+is3);
                
         ggid             = gid[n];         
-               gmx_mm_update_2pot_ps(vctot,vc+ggid,vgbtot,gpol+ggid);
+
+               gmx_mm_update_1pot_ps(vctot,vc+ggid);
+               gmx_mm_update_1pot_ps(vgbtot,gpol+ggid);
                gmx_mm_update_1pot_ps(dvdasum,dvda+ii);
     }
        
index b154339f9e45f6bf83f746d406a3dbac8cde2ae1..5d955d56afb505183b611c91596198f59115245f 100644 (file)
@@ -410,7 +410,8 @@ extern int do_scattering_intensity (const char* fnTPS, const char* fnNDX,
                              real start_q,real end_q,
                              real energy,int ng,const output_env_t oenv)
 {
-    int i,*isize,status,flags = TRX_READ_X,**index_atp;
+    int i,*isize,flags = TRX_READ_X,**index_atp;
+    t_trxstatus *status;
     char **grpname,title[STRLEN];
     atom_id **index;
     t_topology top;
index f533d6cac9a549bf813d7d37d25fcc61c41643fe..156a7e0b22ee5b23d6db33779da1619c860ab432 100644 (file)
@@ -252,3 +252,120 @@ size_t memavail(void)
   }
   return size;
 }
+
+/* If we don't have useful routines for allocating aligned memory,
+ * then we have to use the old-style GROMACS approach bitwise-ANDing
+ * pointers to ensure alignment. Freeing such a pointer requires
+ * keeping track of the original pointer, so we set up an array
+ * to store the original and aligned pointers. */
+
+#if (!defined HAVE_POSIX_MEMALIGN && !defined HAVE_MEMALIGN)
+
+#define SAVED_POINTERS_REALLOC 32
+
+typedef struct
+{
+    void *freeable_ptr;
+    void *aligned_ptr;
+} saved_ptr_t;
+
+static saved_ptr_t *saved_ptrs = NULL;
+static int num_saved_ptrs = 0;
+
+#endif
+
+/* Pointers allocated with this routine should only be freed
+ * with save_free_aligned, however this will only matter
+ * on systems that lack posix_memalign() and memalign() when 
+ * freeing memory that needed to be adjusted to achieve
+ * the necessary alignment. */
+void *save_calloc_aligned(char *name,char *file,int line,unsigned nelem,
+                          size_t elsize,size_t alignment)
+{
+    void *p0,*p;
+    bool allocate_fail;
+
+    if (alignment == 0)
+    {
+        gmx_fatal(errno,__FILE__,__LINE__,
+                  "Cannot allocate aligned memory with alignment of zero!\n(called from file %s, line %d)",file,line);
+    }
+
+#if (!defined HAVE_POSIX_MEMALIGN && !defined HAVE_MEMALIGN)
+    if (0 == num_saved_ptrs % SAVED_POINTERS_REALLOC) {
+#ifdef DEBUG
+        log_action(0,name,file,line,0,0,ptr);
+#endif
+        srealloc(saved_ptrs, num_saved_ptrs + SAVED_POINTERS_REALLOC);
+    }
+#endif
+    
+    p0 = NULL;
+    if (nelem ==0 || elsize == 0)
+    {
+        p  = NULL;
+    }
+    else
+    {
+#ifdef PRINT_ALLOC_KB
+        if (nelem*elsize >= PRINT_ALLOC_KB*1024)
+        {
+            printf("Allocating %.1f MB for %s\n",
+                   nelem*elsize/(PRINT_ALLOC_KB*1024.0),name);
+        }
+#endif
+
+        allocate_fail = FALSE; /* stop compiler warnings */
+#ifdef HAVE_POSIX_MEMALIGN
+        allocate_fail = (0 != posix_memalign(&p, alignment, nelem*elsize));
+#elif HAVE_MEMALIGN
+        allocate_fail = ((p = memalign(alignment, nelem*elsize)) == NULL);
+#else
+        allocate_fail = ((p0 = malloc(nelem*elsize+alignment))==NULL);
+#endif
+        if (allocate_fail)
+        {
+            gmx_fatal(errno,__FILE__,__LINE__,
+                      "Not enough memory. Failed to allocate %u aligned elements of size %u for %s\n(called from file %s, line %d)",nelem,elsize,name,file,line);
+        }
+  
+#if (!defined HAVE_POSIX_MEMALIGN && !defined HAVE_MEMALIGN)
+       /* Make the aligned pointer p, and save the underlying pointer that
+        * we're allowed to free(). */
+       p = (void *) (((size_t) p0 + alignment - 1) & (~((size_t) (alignment-1))));
+       saved_ptrs[num_saved_ptrs].freeable_ptr = p0;
+       saved_ptrs[num_saved_ptrs].aligned_ptr = p;
+       num_saved_ptrs++;
+#endif
+
+       memset(p, 0,(size_t) (nelem * elsize));
+    }
+    return p;
+}
+
+/* This routine can be called with any pointer */
+void save_free_aligned(char *name,char *file,int line,void *ptr)
+{
+    int i, j;
+    if (NULL != ptr)
+    {
+#if (!defined HAVE_POSIX_MEMALIGN && !defined HAVE_MEMALIGN)
+        /* Manage the saved-pointers data structure. */
+        for (i = num_saved_ptrs-1; i >= 0; i--)
+        {
+            if ((size_t) ptr == (size_t) saved_ptrs[i].aligned_ptr)
+            {
+               ptr = saved_ptrs[i].freeable_ptr;
+                /* Now remove the record of this saved pointer, replacing
+                 * it with the one at the end of the array. */
+               saved_ptrs[i] = saved_ptrs[num_saved_ptrs-1];
+                num_saved_ptrs--;
+                break;
+            }
+        }
+#endif
+        /* (Now) we're allowed to use a normal free() on this pointer. */
+        save_free(name,file,line,ptr);
+    }
+}
+
index c49fbc55413bc8e6b82d7a425e06aa6aeae7b2d6..68f21978817f813522a0e4ed651c045c88cccae7 100644 (file)
@@ -165,88 +165,90 @@ static const t_ftupd ftupd[] = {
 /* Needed for backward compatibility */
 #define MAXNODES 256
 
-void _do_section(int fp,int key,bool bRead,const char *src,int line)
+static void _do_section(t_fileio *fio,int key,bool bRead,const char *src,
+                        int line)
 {
   char buf[STRLEN];
   bool bDbg;
 
-  if (gmx_fio_getftp(fp) == efTPA) {
+  if (gmx_fio_getftp(fio) == efTPA) {
     if (!bRead) {
-      do_string(itemstr[key]);
-      bDbg       = gmx_fio_getdebug(fp);
-      gmx_fio_setdebug(fp,FALSE);
-      do_string(comment_str[key]);
-      gmx_fio_setdebug(fp,bDbg);
+      gmx_fio_write_string(fio,itemstr[key]);
+      bDbg       = gmx_fio_getdebug(fio);
+      gmx_fio_setdebug(fio,FALSE);
+      gmx_fio_write_string(fio,comment_str[key]);
+      gmx_fio_setdebug(fio,bDbg);
     }
     else {
-      if (gmx_fio_getdebug(fp))
+      if (gmx_fio_getdebug(fio))
        fprintf(stderr,"Looking for section %s (%s, %d)",
                itemstr[key],src,line);
       
       do {
-       do_string(buf);
+       gmx_fio_do_string(fio,buf);
       } while ((strcasecmp(buf,itemstr[key]) != 0));
       
       if (strcasecmp(buf,itemstr[key]) != 0) 
        gmx_fatal(FARGS,"\nCould not find section heading %s",itemstr[key]);
-      else if (gmx_fio_getdebug(fp))
+      else if (gmx_fio_getdebug(fio))
        fprintf(stderr," and found it\n");
     }
   }
 }
 
-#define do_section(key,bRead) _do_section(fp,key,bRead,__FILE__,__LINE__)
+#define do_section(fio,key,bRead) _do_section(fio,key,bRead,__FILE__,__LINE__)
 
 /**************************************************************
  *
  * Now the higer level routines that do io of the structures and arrays
  *
  **************************************************************/
-static void do_pullgrp(t_pullgrp *pgrp,bool bRead, int file_version)
+static void do_pullgrp(t_fileio *fio, t_pullgrp *pgrp, bool bRead, 
+                       int file_version)
 {
   bool bDum=TRUE;
   int  i;
 
-  do_int(pgrp->nat);
+  gmx_fio_do_int(fio,pgrp->nat);
   if (bRead)
     snew(pgrp->ind,pgrp->nat);
-  ndo_int(pgrp->ind,pgrp->nat,bDum);
-  do_int(pgrp->nweight);
+  bDum=gmx_fio_ndo_int(fio,pgrp->ind,pgrp->nat);
+  gmx_fio_do_int(fio,pgrp->nweight);
   if (bRead)
     snew(pgrp->weight,pgrp->nweight);
-  ndo_real(pgrp->weight,pgrp->nweight,bDum);
-  do_int(pgrp->pbcatom);
-  do_rvec(pgrp->vec);
-  do_rvec(pgrp->init);
-  do_real(pgrp->rate);
-  do_real(pgrp->k);
+  bDum=gmx_fio_ndo_real(fio,pgrp->weight,pgrp->nweight);
+  gmx_fio_do_int(fio,pgrp->pbcatom);
+  gmx_fio_do_rvec(fio,pgrp->vec);
+  gmx_fio_do_rvec(fio,pgrp->init);
+  gmx_fio_do_real(fio,pgrp->rate);
+  gmx_fio_do_real(fio,pgrp->k);
   if (file_version >= 56) {
-    do_real(pgrp->kB);
+    gmx_fio_do_real(fio,pgrp->kB);
   } else {
     pgrp->kB = pgrp->k;
   }
 }
 
-static void do_pull(t_pull *pull,bool bRead, int file_version)
+static void do_pull(t_fileio *fio, t_pull *pull,bool bRead, int file_version)
 {
   int g;
 
-  do_int(pull->ngrp);
-  do_int(pull->eGeom);
-  do_ivec(pull->dim);
-  do_real(pull->cyl_r1);
-  do_real(pull->cyl_r0);
-  do_real(pull->constr_tol);
-  do_int(pull->nstxout);
-  do_int(pull->nstfout);
+  gmx_fio_do_int(fio,pull->ngrp);
+  gmx_fio_do_int(fio,pull->eGeom);
+  gmx_fio_do_ivec(fio,pull->dim);
+  gmx_fio_do_real(fio,pull->cyl_r1);
+  gmx_fio_do_real(fio,pull->cyl_r0);
+  gmx_fio_do_real(fio,pull->constr_tol);
+  gmx_fio_do_int(fio,pull->nstxout);
+  gmx_fio_do_int(fio,pull->nstfout);
   if (bRead)
     snew(pull->grp,pull->ngrp+1);
   for(g=0; g<pull->ngrp+1; g++)
-    do_pullgrp(&pull->grp[g],bRead,file_version);
+    do_pullgrp(fio,&pull->grp[g],bRead,file_version);
 }
 
-static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
-                       real *fudgeQQ)
+static void do_inputrec(t_fileio *fio, t_inputrec *ir,bool bRead, 
+                        int file_version, real *fudgeQQ)
 {
   int  i,j,k,*tmp,idum=0; 
   bool bDum=TRUE;
@@ -266,18 +268,18 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
 
   if (file_version >= 1) {  
     /* Basic inputrec stuff */  
-    do_int(ir->eI); 
+    gmx_fio_do_int(fio,ir->eI); 
     if (file_version >= 62) {
-      do_gmx_large_int(ir->nsteps);
+      gmx_fio_do_gmx_large_int(fio, ir->nsteps);
     } else {
-      do_int(idum);
+      gmx_fio_do_int(fio,idum);
       ir->nsteps = idum;
     }
     if(file_version > 25) {
       if (file_version >= 62) {
-       do_gmx_large_int(ir->init_step);
+       gmx_fio_do_gmx_large_int(fio, ir->init_step);
       } else {
-       do_int(idum);
+       gmx_fio_do_int(fio,idum);
        ir->init_step = idum;
       }
     }  else {
@@ -285,12 +287,12 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
     }
 
        if(file_version >= 58)
-         do_int(ir->simulation_part);
+         gmx_fio_do_int(fio,ir->simulation_part);
        else
          ir->simulation_part=1;
          
     if (file_version >= 67) {
-      do_int(ir->nstcalcenergy);
+      gmx_fio_do_int(fio,ir->nstcalcenergy);
     } else {
       ir->nstcalcenergy = 1;
     }
@@ -298,11 +300,11 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
       /* The pbc info has been moved out of do_inputrec,
        * since we always want it, also without reading the inputrec.
        */
-      do_int(ir->ePBC);
+      gmx_fio_do_int(fio,ir->ePBC);
       if ((file_version <= 15) && (ir->ePBC == 2))
        ir->ePBC = epbcNONE;
       if (file_version >= 45) {
-       do_int(ir->bPeriodicMols);
+       gmx_fio_do_int(fio,ir->bPeriodicMols);
       } else {
        if (ir->ePBC == 2) {
          ir->ePBC = epbcXYZ;
@@ -312,20 +314,20 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
        }
       }
     }
-    do_int(ir->ns_type);
-    do_int(ir->nstlist);
-    do_int(ir->ndelta);
+    gmx_fio_do_int(fio,ir->ns_type);
+    gmx_fio_do_int(fio,ir->nstlist);
+    gmx_fio_do_int(fio,ir->ndelta);
     if (file_version < 41) {
-      do_int(idum);
-      do_int(idum);
+      gmx_fio_do_int(fio,idum);
+      gmx_fio_do_int(fio,idum);
     }
     if (file_version >= 45)
-      do_real(ir->rtpi);
+      gmx_fio_do_real(fio,ir->rtpi);
     else
       ir->rtpi = 0.05;
-    do_int(ir->nstcomm); 
+    gmx_fio_do_int(fio,ir->nstcomm); 
     if (file_version > 34)
-      do_int(ir->comm_mode);
+      gmx_fio_do_int(fio,ir->comm_mode);
     else if (ir->nstcomm < 0) 
       ir->comm_mode = ecmANGULAR;
     else
@@ -333,58 +335,58 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
     ir->nstcomm = abs(ir->nstcomm);
     
     if(file_version > 25)
-      do_int(ir->nstcheckpoint);
+      gmx_fio_do_int(fio,ir->nstcheckpoint);
     else
       ir->nstcheckpoint=0;
     
-    do_int(ir->nstcgsteep); 
+    gmx_fio_do_int(fio,ir->nstcgsteep); 
 
     if(file_version>=30)
-      do_int(ir->nbfgscorr); 
+      gmx_fio_do_int(fio,ir->nbfgscorr); 
     else if (bRead)
       ir->nbfgscorr = 10;
 
-    do_int(ir->nstlog); 
-    do_int(ir->nstxout); 
-    do_int(ir->nstvout); 
-    do_int(ir->nstfout); 
-    do_int(ir->nstenergy); 
-    do_int(ir->nstxtcout); 
+    gmx_fio_do_int(fio,ir->nstlog); 
+    gmx_fio_do_int(fio,ir->nstxout); 
+    gmx_fio_do_int(fio,ir->nstvout); 
+    gmx_fio_do_int(fio,ir->nstfout); 
+    gmx_fio_do_int(fio,ir->nstenergy); 
+    gmx_fio_do_int(fio,ir->nstxtcout); 
     if (file_version >= 59) {
-      do_double(ir->init_t);
-      do_double(ir->delta_t);
+      gmx_fio_do_double(fio,ir->init_t);
+      gmx_fio_do_double(fio,ir->delta_t);
     } else {
-      do_real(rdum);
+      gmx_fio_do_real(fio,rdum);
       ir->init_t = rdum;
-      do_real(rdum);
+      gmx_fio_do_real(fio,rdum);
       ir->delta_t = rdum;
     }
-    do_real(ir->xtcprec); 
+    gmx_fio_do_real(fio,ir->xtcprec); 
     if (file_version < 19) {
-      do_int(idum); 
-      do_int(idum);
+      gmx_fio_do_int(fio,idum); 
+      gmx_fio_do_int(fio,idum);
     }
     if(file_version < 18)
-      do_int(idum); 
-    do_real(ir->rlist); 
+      gmx_fio_do_int(fio,idum); 
+    gmx_fio_do_real(fio,ir->rlist); 
     if (file_version >= 67) {
-      do_real(ir->rlistlong);
+      gmx_fio_do_real(fio,ir->rlistlong);
     }
-    do_int(ir->coulombtype); 
+    gmx_fio_do_int(fio,ir->coulombtype); 
     if (file_version < 32 && ir->coulombtype == eelRF)
       ir->coulombtype = eelRF_NEC;      
-    do_real(ir->rcoulomb_switch); 
-    do_real(ir->rcoulomb); 
-    do_int(ir->vdwtype);
-    do_real(ir->rvdw_switch); 
-    do_real(ir->rvdw); 
+    gmx_fio_do_real(fio,ir->rcoulomb_switch); 
+    gmx_fio_do_real(fio,ir->rcoulomb); 
+    gmx_fio_do_int(fio,ir->vdwtype);
+    gmx_fio_do_real(fio,ir->rvdw_switch); 
+    gmx_fio_do_real(fio,ir->rvdw); 
     if (file_version < 67) {
       ir->rlistlong = max_cutoff(ir->rlist,max_cutoff(ir->rvdw,ir->rcoulomb));
     }
-    do_int(ir->eDispCorr); 
-    do_real(ir->epsilon_r);
+    gmx_fio_do_int(fio,ir->eDispCorr); 
+    gmx_fio_do_real(fio,ir->epsilon_r);
     if (file_version >= 37) {
-      do_real(ir->epsilon_rf);
+      gmx_fio_do_real(fio,ir->epsilon_rf);
     } else {
       if (EEL_RF(ir->coulombtype)) {
        ir->epsilon_rf = ir->epsilon_r;
@@ -394,16 +396,16 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
       }
     }
     if (file_version >= 29)
-      do_real(ir->tabext);
+      gmx_fio_do_real(fio,ir->tabext);
     else
       ir->tabext=1.0;
  
     if(file_version > 25) {
-      do_int(ir->gb_algorithm);
-      do_int(ir->nstgbradii);
-      do_real(ir->rgbradii);
-      do_real(ir->gb_saltconc);
-      do_int(ir->implicit_solvent);
+      gmx_fio_do_int(fio,ir->gb_algorithm);
+      gmx_fio_do_int(fio,ir->nstgbradii);
+      gmx_fio_do_real(fio,ir->rgbradii);
+      gmx_fio_do_real(fio,ir->gb_saltconc);
+      gmx_fio_do_int(fio,ir->implicit_solvent);
     } else {
       ir->gb_algorithm=egbSTILL;
       ir->nstgbradii=1;
@@ -413,21 +415,21 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
     }
        if(file_version>=55)
        {
-               do_real(ir->gb_epsilon_solvent);
-               do_real(ir->gb_obc_alpha);
-               do_real(ir->gb_obc_beta);
-               do_real(ir->gb_obc_gamma);
+               gmx_fio_do_real(fio,ir->gb_epsilon_solvent);
+               gmx_fio_do_real(fio,ir->gb_obc_alpha);
+               gmx_fio_do_real(fio,ir->gb_obc_beta);
+               gmx_fio_do_real(fio,ir->gb_obc_gamma);
                if(file_version>=60)
                {
-                       do_real(ir->gb_dielectric_offset);
-                       do_int(ir->sa_algorithm);
+                       gmx_fio_do_real(fio,ir->gb_dielectric_offset);
+                       gmx_fio_do_int(fio,ir->sa_algorithm);
                }
                else
                {
                        ir->gb_dielectric_offset = 0.09;
                        ir->sa_algorithm = esaAPPROX;
                }
-               do_real(ir->sa_surface_tension);
+               gmx_fio_do_real(fio,ir->sa_surface_tension);
        }
        else
        {
@@ -440,41 +442,41 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
        }
 
          
-    do_int(ir->nkx); 
-    do_int(ir->nky); 
-    do_int(ir->nkz);
-    do_int(ir->pme_order);
-    do_real(ir->ewald_rtol);
+    gmx_fio_do_int(fio,ir->nkx); 
+    gmx_fio_do_int(fio,ir->nky); 
+    gmx_fio_do_int(fio,ir->nkz);
+    gmx_fio_do_int(fio,ir->pme_order);
+    gmx_fio_do_real(fio,ir->ewald_rtol);
 
     if (file_version >=24) 
-      do_int(ir->ewald_geometry);
+      gmx_fio_do_int(fio,ir->ewald_geometry);
     else
       ir->ewald_geometry=eewg3D;
 
     if (file_version <=17) {
       ir->epsilon_surface=0;
       if (file_version==17)
-       do_int(idum);
+       gmx_fio_do_int(fio,idum);
     } 
     else
-      do_real(ir->epsilon_surface);
+      gmx_fio_do_real(fio,ir->epsilon_surface);
     
-    do_int(ir->bOptFFT);
+    gmx_fio_do_int(fio,ir->bOptFFT);
 
-    do_int(ir->bContinuation); 
-    do_int(ir->etc);
+    gmx_fio_do_int(fio,ir->bContinuation); 
+    gmx_fio_do_int(fio,ir->etc);
     /* before version 18, ir->etc was a bool (ir->btc),
      * but the values 0 and 1 still mean no and
      * berendsen temperature coupling, respectively.
      */
     if (file_version <= 15)
-      do_int(idum);
+      gmx_fio_do_int(fio,idum);
     if (file_version <=17) {
-      do_int(ir->epct); 
+      gmx_fio_do_int(fio,ir->epct); 
       if (file_version <= 15) {
        if (ir->epct == 5)
          ir->epct = epctSURFACETENSION;
-       do_int(idum);
+       gmx_fio_do_int(fio,idum);
       }
       ir->epct -= 1;
       /* we have removed the NO alternative at the beginning */
@@ -486,203 +488,203 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
        ir->epc=epcBERENDSEN;
     } 
     else {
-      do_int(ir->epc);
-      do_int(ir->epct);
+      gmx_fio_do_int(fio,ir->epc);
+      gmx_fio_do_int(fio,ir->epct);
     }
-    do_real(ir->tau_p); 
+    gmx_fio_do_real(fio,ir->tau_p); 
     if (file_version <= 15) {
-      do_rvec(vdum);
+      gmx_fio_do_rvec(fio,vdum);
       clear_mat(ir->ref_p);
       for(i=0; i<DIM; i++)
        ir->ref_p[i][i] = vdum[i];
     } else {
-      do_rvec(ir->ref_p[XX]);
-      do_rvec(ir->ref_p[YY]);
-      do_rvec(ir->ref_p[ZZ]);
+      gmx_fio_do_rvec(fio,ir->ref_p[XX]);
+      gmx_fio_do_rvec(fio,ir->ref_p[YY]);
+      gmx_fio_do_rvec(fio,ir->ref_p[ZZ]);
     }
     if (file_version <= 15) {
-      do_rvec(vdum);
+      gmx_fio_do_rvec(fio,vdum);
       clear_mat(ir->compress);
       for(i=0; i<DIM; i++)
        ir->compress[i][i] = vdum[i];
     } 
     else {
-      do_rvec(ir->compress[XX]);
-      do_rvec(ir->compress[YY]);
-      do_rvec(ir->compress[ZZ]);
+      gmx_fio_do_rvec(fio,ir->compress[XX]);
+      gmx_fio_do_rvec(fio,ir->compress[YY]);
+      gmx_fio_do_rvec(fio,ir->compress[ZZ]);
     }
     if (file_version >= 47) {
-      do_int(ir->refcoord_scaling);
-      do_rvec(ir->posres_com);
-      do_rvec(ir->posres_comB);
+      gmx_fio_do_int(fio,ir->refcoord_scaling);
+      gmx_fio_do_rvec(fio,ir->posres_com);
+      gmx_fio_do_rvec(fio,ir->posres_comB);
     } else {
       ir->refcoord_scaling = erscNO;
       clear_rvec(ir->posres_com);
       clear_rvec(ir->posres_comB);
     }
     if(file_version > 25)
-      do_int(ir->andersen_seed);
+      gmx_fio_do_int(fio,ir->andersen_seed);
     else
       ir->andersen_seed=0;
     
     if(file_version < 26) {
-      do_int(bSimAnn); 
-      do_real(zerotemptime);
+      gmx_fio_do_int(fio,bSimAnn); 
+      gmx_fio_do_real(fio,zerotemptime);
     }
     
     if (file_version < 37)
-      do_real(rdum); 
+      gmx_fio_do_real(fio,rdum); 
 
-    do_real(ir->shake_tol);
+    gmx_fio_do_real(fio,ir->shake_tol);
     if (file_version < 54)
-      do_real(*fudgeQQ);
-    do_int(ir->efep);
+      gmx_fio_do_real(fio,*fudgeQQ);
+    gmx_fio_do_int(fio,ir->efep);
     if (file_version <= 14 && ir->efep > efepNO)
       ir->efep = efepYES;
     if (file_version >= 59) {
-      do_double(ir->init_lambda); 
-      do_double(ir->delta_lambda);
+      gmx_fio_do_double(fio, ir->init_lambda); 
+      gmx_fio_do_double(fio, ir->delta_lambda);
     } else {
-      do_real(rdum);
+      gmx_fio_do_real(fio,rdum);
       ir->init_lambda = rdum;
-      do_real(rdum);
+      gmx_fio_do_real(fio,rdum);
       ir->delta_lambda = rdum;
     }
     if (file_version >= 64) {
-      do_int(ir->n_flambda);
+      gmx_fio_do_int(fio,ir->n_flambda);
       if (bRead) {
        snew(ir->flambda,ir->n_flambda);
       }
-      ndo_double(ir->flambda,ir->n_flambda,bDum);
+      bDum=gmx_fio_ndo_double(fio,ir->flambda,ir->n_flambda);
     } else {
       ir->n_flambda = 0;
       ir->flambda   = NULL;
     }
     if (file_version >= 13)
-      do_real(ir->sc_alpha);
+      gmx_fio_do_real(fio,ir->sc_alpha);
     else
       ir->sc_alpha = 0;
     if (file_version >= 38)
-      do_int(ir->sc_power);
+      gmx_fio_do_int(fio,ir->sc_power);
     else
       ir->sc_power = 2;
     if (file_version >= 15)
-      do_real(ir->sc_sigma);
+      gmx_fio_do_real(fio,ir->sc_sigma);
     else
       ir->sc_sigma = 0.3;
     if (file_version >= 64) {
-      do_int(ir->nstdhdl);
+      gmx_fio_do_int(fio,ir->nstdhdl);
     } else {
       ir->nstdhdl = 1;
     }
     if (file_version >= 57) {
-      do_int(ir->eDisre); 
+      gmx_fio_do_int(fio,ir->eDisre); 
     }
-    do_int(ir->eDisreWeighting); 
+    gmx_fio_do_int(fio,ir->eDisreWeighting); 
     if (file_version < 22) {
       if (ir->eDisreWeighting == 0)
        ir->eDisreWeighting = edrwEqual;
       else
        ir->eDisreWeighting = edrwConservative;
     }
-    do_int(ir->bDisreMixed); 
-    do_real(ir->dr_fc); 
-    do_real(ir->dr_tau); 
-    do_int(ir->nstdisreout);
+    gmx_fio_do_int(fio,ir->bDisreMixed); 
+    gmx_fio_do_real(fio,ir->dr_fc); 
+    gmx_fio_do_real(fio,ir->dr_tau); 
+    gmx_fio_do_int(fio,ir->nstdisreout);
     if (file_version >= 22) {
-      do_real(ir->orires_fc);
-      do_real(ir->orires_tau);
-      do_int(ir->nstorireout);
+      gmx_fio_do_real(fio,ir->orires_fc);
+      gmx_fio_do_real(fio,ir->orires_tau);
+      gmx_fio_do_int(fio,ir->nstorireout);
     } else {
       ir->orires_fc = 0;
       ir->orires_tau = 0;
       ir->nstorireout = 0;
     }
     if(file_version >= 26) {
-      do_real(ir->dihre_fc);
+      gmx_fio_do_real(fio,ir->dihre_fc);
       if (file_version < 56) {
-       do_real(rdum);
-       do_int(idum);
+       gmx_fio_do_real(fio,rdum);
+       gmx_fio_do_int(fio,idum);
       }
     } else {
       ir->dihre_fc=0;
     }
 
-    do_real(ir->em_stepsize); 
-    do_real(ir->em_tol); 
+    gmx_fio_do_real(fio,ir->em_stepsize); 
+    gmx_fio_do_real(fio,ir->em_tol); 
     if (file_version >= 22) 
-      do_int(ir->bShakeSOR);
+      gmx_fio_do_int(fio,ir->bShakeSOR);
     else if (bRead)
       ir->bShakeSOR = TRUE;
     if (file_version >= 11)
-      do_int(ir->niter);
+      gmx_fio_do_int(fio,ir->niter);
     else if (bRead) {
       ir->niter = 25;
       fprintf(stderr,"Note: niter not in run input file, setting it to %d\n",
              ir->niter);
     }
     if (file_version >= 21)
-      do_real(ir->fc_stepsize);
+      gmx_fio_do_real(fio,ir->fc_stepsize);
     else
       ir->fc_stepsize = 0;
-    do_int(ir->eConstrAlg);
-    do_int(ir->nProjOrder);
-    do_real(ir->LincsWarnAngle);
+    gmx_fio_do_int(fio,ir->eConstrAlg);
+    gmx_fio_do_int(fio,ir->nProjOrder);
+    gmx_fio_do_real(fio,ir->LincsWarnAngle);
     if (file_version <= 14)
-      do_int(idum);
+      gmx_fio_do_int(fio,idum);
     if (file_version >=26)
-      do_int(ir->nLincsIter);
+      gmx_fio_do_int(fio,ir->nLincsIter);
     else if (bRead) {
       ir->nLincsIter = 1;
       fprintf(stderr,"Note: nLincsIter not in run input file, setting it to %d\n",
              ir->nLincsIter);
     }
     if (file_version < 33)
-      do_real(bd_temp);
-    do_real(ir->bd_fric);
-    do_int(ir->ld_seed);
+      gmx_fio_do_real(fio,bd_temp);
+    gmx_fio_do_real(fio,ir->bd_fric);
+    gmx_fio_do_int(fio,ir->ld_seed);
     if (file_version >= 33) {
       for(i=0; i<DIM; i++)
-       do_rvec(ir->deform[i]);
+       gmx_fio_do_rvec(fio,ir->deform[i]);
     } else {
       for(i=0; i<DIM; i++)
        clear_rvec(ir->deform[i]);
     }
     if (file_version >= 14)
-      do_real(ir->cos_accel);
+      gmx_fio_do_real(fio,ir->cos_accel);
     else if (bRead)
       ir->cos_accel = 0;
-    do_int(ir->userint1); 
-    do_int(ir->userint2); 
-    do_int(ir->userint3); 
-    do_int(ir->userint4); 
-    do_real(ir->userreal1); 
-    do_real(ir->userreal2); 
-    do_real(ir->userreal3); 
-    do_real(ir->userreal4); 
+    gmx_fio_do_int(fio,ir->userint1); 
+    gmx_fio_do_int(fio,ir->userint2); 
+    gmx_fio_do_int(fio,ir->userint3); 
+    gmx_fio_do_int(fio,ir->userint4); 
+    gmx_fio_do_real(fio,ir->userreal1); 
+    gmx_fio_do_real(fio,ir->userreal2); 
+    gmx_fio_do_real(fio,ir->userreal3); 
+    gmx_fio_do_real(fio,ir->userreal4); 
     
     /* pull stuff */
     if (file_version >= 48) {
-      do_int(ir->ePull);
+      gmx_fio_do_int(fio,ir->ePull);
       if (ir->ePull != epullNO) {
        if (bRead)
          snew(ir->pull,1);
-       do_pull(ir->pull,bRead,file_version);
+       do_pull(fio, ir->pull,bRead,file_version);
       }
     } else {
       ir->ePull = epullNO;
     }
     
     /* grpopts stuff */
-    do_int(ir->opts.ngtc); 
+    gmx_fio_do_int(fio,ir->opts.ngtc); 
     if (file_version >= 69) {
-      do_int(ir->opts.nhchainlength);
+      gmx_fio_do_int(fio,ir->opts.nhchainlength);
     } else {
       ir->opts.nhchainlength = 1;
     }
-    do_int(ir->opts.ngacc); 
-    do_int(ir->opts.ngfrz); 
-    do_int(ir->opts.ngener);
+    gmx_fio_do_int(fio,ir->opts.ngacc); 
+    gmx_fio_do_int(fio,ir->opts.ngfrz); 
+    gmx_fio_do_int(fio,ir->opts.ngener);
     
     if (bRead) {
       snew(ir->opts.nrdf,   ir->opts.ngtc); 
@@ -699,26 +701,27 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
     if (ir->opts.ngtc > 0) {
       if (bRead && file_version<13) {
        snew(tmp,ir->opts.ngtc);
-       ndo_int (tmp, ir->opts.ngtc,bDum);
+       bDum=gmx_fio_ndo_int(fio,tmp, ir->opts.ngtc);
        for(i=0; i<ir->opts.ngtc; i++)
          ir->opts.nrdf[i] = tmp[i];
        sfree(tmp);
       } else {
-       ndo_real(ir->opts.nrdf, ir->opts.ngtc,bDum);
+       bDum=gmx_fio_ndo_real(fio,ir->opts.nrdf, ir->opts.ngtc);
       }
-      ndo_real(ir->opts.ref_t,ir->opts.ngtc,bDum); 
-      ndo_real(ir->opts.tau_t,ir->opts.ngtc,bDum); 
+      bDum=gmx_fio_ndo_real(fio,ir->opts.ref_t,ir->opts.ngtc); 
+      bDum=gmx_fio_ndo_real(fio,ir->opts.tau_t,ir->opts.ngtc); 
       if (file_version<33 && ir->eI==eiBD) {
        for(i=0; i<ir->opts.ngtc; i++)
          ir->opts.tau_t[i] = bd_temp;
       }
     }
     if (ir->opts.ngfrz > 0) 
-      ndo_ivec(ir->opts.nFreeze,ir->opts.ngfrz,bDum);
+      bDum=gmx_fio_ndo_ivec(fio,ir->opts.nFreeze,ir->opts.ngfrz);
     if (ir->opts.ngacc > 0) 
-      ndo_rvec(ir->opts.acc,ir->opts.ngacc); 
+      gmx_fio_ndo_rvec(fio,ir->opts.acc,ir->opts.ngacc); 
     if (file_version >= 12)
-      ndo_int(ir->opts.egp_flags,ir->opts.ngener*ir->opts.ngener,bDum);
+      bDum=gmx_fio_ndo_int(fio,ir->opts.egp_flags,
+                           ir->opts.ngener*ir->opts.ngener);
 
     if(bRead && file_version < 26) {
       for(i=0;i<ir->opts.ngtc;i++) {
@@ -743,31 +746,31 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
     } else {
       /* file version 26 or later */
       /* First read the lists with annealing and npoints for each group */
-      ndo_int(ir->opts.annealing,ir->opts.ngtc,bDum);
-      ndo_int(ir->opts.anneal_npoints,ir->opts.ngtc,bDum);
+      bDum=gmx_fio_ndo_int(fio,ir->opts.annealing,ir->opts.ngtc);
+      bDum=gmx_fio_ndo_int(fio,ir->opts.anneal_npoints,ir->opts.ngtc);
       for(j=0;j<(ir->opts.ngtc);j++) {
        k=ir->opts.anneal_npoints[j];
        if(bRead) {
          snew(ir->opts.anneal_time[j],k);
          snew(ir->opts.anneal_temp[j],k);
        }
-       ndo_real(ir->opts.anneal_time[j],k,bDum);
-       ndo_real(ir->opts.anneal_temp[j],k,bDum);
+       bDum=gmx_fio_ndo_real(fio,ir->opts.anneal_time[j],k);
+       bDum=gmx_fio_ndo_real(fio,ir->opts.anneal_temp[j],k);
       }
     }
     /* Walls */
     if (file_version >= 45) {
-      do_int(ir->nwall);
-      do_int(ir->wall_type);
+      gmx_fio_do_int(fio,ir->nwall);
+      gmx_fio_do_int(fio,ir->wall_type);
       if (file_version >= 50)
-       do_real(ir->wall_r_linpot);
+       gmx_fio_do_real(fio,ir->wall_r_linpot);
       else
        ir->wall_r_linpot = -1;
-      do_int(ir->wall_atomtype[0]);
-      do_int(ir->wall_atomtype[1]);
-      do_real(ir->wall_density[0]);
-      do_real(ir->wall_density[1]);
-      do_real(ir->wall_ewald_zfac);
+      gmx_fio_do_int(fio,ir->wall_atomtype[0]);
+      gmx_fio_do_int(fio,ir->wall_atomtype[1]);
+      gmx_fio_do_real(fio,ir->wall_density[0]);
+      gmx_fio_do_real(fio,ir->wall_density[1]);
+      gmx_fio_do_real(fio,ir->wall_ewald_zfac);
     } else {
       ir->nwall = 0;
       ir->wall_type = 0;
@@ -779,26 +782,26 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
     }
     /* Cosine stuff for electric fields */
     for(j=0; (j<DIM); j++) {
-      do_int  (ir->ex[j].n);
-      do_int  (ir->et[j].n);
+      gmx_fio_do_int(fio,ir->ex[j].n);
+      gmx_fio_do_int(fio,ir->et[j].n);
       if (bRead) {
        snew(ir->ex[j].a,  ir->ex[j].n);
        snew(ir->ex[j].phi,ir->ex[j].n);
        snew(ir->et[j].a,  ir->et[j].n);
        snew(ir->et[j].phi,ir->et[j].n);
       }
-      ndo_real(ir->ex[j].a,  ir->ex[j].n,bDum);
-      ndo_real(ir->ex[j].phi,ir->ex[j].n,bDum);
-      ndo_real(ir->et[j].a,  ir->et[j].n,bDum);
-      ndo_real(ir->et[j].phi,ir->et[j].n,bDum);
+      bDum=gmx_fio_ndo_real(fio,ir->ex[j].a,  ir->ex[j].n);
+      bDum=gmx_fio_ndo_real(fio,ir->ex[j].phi,ir->ex[j].n);
+      bDum=gmx_fio_ndo_real(fio,ir->et[j].a,  ir->et[j].n);
+      bDum=gmx_fio_ndo_real(fio,ir->et[j].phi,ir->et[j].n);
     }
     
     /* QMMM stuff */
     if(file_version>=39){
-      do_int(ir->bQMMM);
-      do_int(ir->QMMMscheme);
-      do_real(ir->scalefactor);
-      do_int(ir->opts.ngQM);
+      gmx_fio_do_int(fio,ir->bQMMM);
+      gmx_fio_do_int(fio,ir->QMMMscheme);
+      gmx_fio_do_real(fio,ir->scalefactor);
+      gmx_fio_do_int(fio,ir->opts.ngQM);
       if (bRead) {
         snew(ir->opts.QMmethod,    ir->opts.ngQM);
         snew(ir->opts.QMbasis,     ir->opts.ngQM);
@@ -814,18 +817,18 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
         snew(ir->opts.bTS,         ir->opts.ngQM);
       }
       if (ir->opts.ngQM > 0) {
-        ndo_int(ir->opts.QMmethod,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.QMbasis,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.QMcharge,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.QMmult,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.bSH,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.CASorbitals,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.CASelectrons,ir->opts.ngQM,bDum);
-        ndo_real(ir->opts.SAon,ir->opts.ngQM,bDum);
-        ndo_real(ir->opts.SAoff,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.SAsteps,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.bOPT,ir->opts.ngQM,bDum);
-        ndo_int(ir->opts.bTS,ir->opts.ngQM,bDum);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.QMmethod,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.QMbasis,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.QMcharge,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.QMmult,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.bSH,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.CASorbitals,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.CASelectrons,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_real(fio,ir->opts.SAon,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_real(fio,ir->opts.SAoff,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.SAsteps,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.bOPT,ir->opts.ngQM);
+        bDum=gmx_fio_ndo_int(fio,ir->opts.bTS,ir->opts.ngQM);
       }
       /* end of QMMM stuff */
     }    
@@ -833,22 +836,23 @@ static void do_inputrec(t_inputrec *ir,bool bRead, int file_version,
 }
 
 
-static void do_harm(t_iparams *iparams,bool bRead)
+static void do_harm(t_fileio *fio, t_iparams *iparams,bool bRead)
 {
-  do_real(iparams->harmonic.rA);
-  do_real(iparams->harmonic.krA);
-  do_real(iparams->harmonic.rB);
-  do_real(iparams->harmonic.krB);
+  gmx_fio_do_real(fio,iparams->harmonic.rA);
+  gmx_fio_do_real(fio,iparams->harmonic.krA);
+  gmx_fio_do_real(fio,iparams->harmonic.rB);
+  gmx_fio_do_real(fio,iparams->harmonic.krB);
 }
 
-void do_iparams(t_functype ftype,t_iparams *iparams,bool bRead, int file_version)
+void do_iparams(t_fileio *fio, t_functype ftype,t_iparams *iparams,
+                bool bRead, int file_version)
 {
   int i;
   bool bDum;
   real rdum;
   
   if (!bRead)
-    set_comment(interaction_function[ftype].name);
+    gmx_fio_set_comment(fio, interaction_function[ftype].name);
   switch (ftype) {
   case F_ANGLES:
   case F_G96ANGLES:
@@ -856,7 +860,7 @@ void do_iparams(t_functype ftype,t_iparams *iparams,bool bRead, int file_version
   case F_G96BONDS:
   case F_HARMONIC:
   case F_IDIHS:
-    do_harm(iparams,bRead);
+    do_harm(fio, iparams,bRead);
     if ((ftype == F_ANGRES || ftype == F_ANGRESZ) && bRead) {
       /* Correct incorrect storage of parameters */
       iparams->pdihs.phiB = iparams->pdihs.phiA;
@@ -864,199 +868,199 @@ void do_iparams(t_functype ftype,t_iparams *iparams,bool bRead, int file_version
     }
     break;
   case F_FENEBONDS:
-    do_real(iparams->fene.bm);
-    do_real(iparams->fene.kb);
+    gmx_fio_do_real(fio,iparams->fene.bm);
+    gmx_fio_do_real(fio,iparams->fene.kb);
     break;
   case F_RESTRBONDS:
-    do_real(iparams->restraint.lowA);
-    do_real(iparams->restraint.up1A);
-    do_real(iparams->restraint.up2A);
-    do_real(iparams->restraint.kA);
-    do_real(iparams->restraint.lowB);
-    do_real(iparams->restraint.up1B);
-    do_real(iparams->restraint.up2B);
-    do_real(iparams->restraint.kB);
+    gmx_fio_do_real(fio,iparams->restraint.lowA);
+    gmx_fio_do_real(fio,iparams->restraint.up1A);
+    gmx_fio_do_real(fio,iparams->restraint.up2A);
+    gmx_fio_do_real(fio,iparams->restraint.kA);
+    gmx_fio_do_real(fio,iparams->restraint.lowB);
+    gmx_fio_do_real(fio,iparams->restraint.up1B);
+    gmx_fio_do_real(fio,iparams->restraint.up2B);
+    gmx_fio_do_real(fio,iparams->restraint.kB);
     break;
   case F_TABBONDS:
   case F_TABBONDSNC:
   case F_TABANGLES:
   case F_TABDIHS:
-    do_real(iparams->tab.kA);
-    do_int (iparams->tab.table);
-    do_real(iparams->tab.kB);
+    gmx_fio_do_real(fio,iparams->tab.kA);
+    gmx_fio_do_int(fio,iparams->tab.table);
+    gmx_fio_do_real(fio,iparams->tab.kB);
     break;
   case F_CROSS_BOND_BONDS:
-    do_real(iparams->cross_bb.r1e);
-    do_real(iparams->cross_bb.r2e);
-    do_real(iparams->cross_bb.krr);
+    gmx_fio_do_real(fio,iparams->cross_bb.r1e);
+    gmx_fio_do_real(fio,iparams->cross_bb.r2e);
+    gmx_fio_do_real(fio,iparams->cross_bb.krr);
     break;
   case F_CROSS_BOND_ANGLES:
-    do_real(iparams->cross_ba.r1e);
-    do_real(iparams->cross_ba.r2e);
-    do_real(iparams->cross_ba.r3e);
-    do_real(iparams->cross_ba.krt);
+    gmx_fio_do_real(fio,iparams->cross_ba.r1e);
+    gmx_fio_do_real(fio,iparams->cross_ba.r2e);
+    gmx_fio_do_real(fio,iparams->cross_ba.r3e);
+    gmx_fio_do_real(fio,iparams->cross_ba.krt);
     break;
   case F_UREY_BRADLEY:
-    do_real(iparams->u_b.theta);
-    do_real(iparams->u_b.ktheta);
-    do_real(iparams->u_b.r13);
-    do_real(iparams->u_b.kUB);
+    gmx_fio_do_real(fio,iparams->u_b.theta);
+    gmx_fio_do_real(fio,iparams->u_b.ktheta);
+    gmx_fio_do_real(fio,iparams->u_b.r13);
+    gmx_fio_do_real(fio,iparams->u_b.kUB);
     break;
   case F_QUARTIC_ANGLES:
-    do_real(iparams->qangle.theta);
-    ndo_real(iparams->qangle.c,5,bDum);
+    gmx_fio_do_real(fio,iparams->qangle.theta);
+    bDum=gmx_fio_ndo_real(fio,iparams->qangle.c,5);
     break;
   case F_BHAM:
-    do_real(iparams->bham.a);
-    do_real(iparams->bham.b);
-    do_real(iparams->bham.c);
+    gmx_fio_do_real(fio,iparams->bham.a);
+    gmx_fio_do_real(fio,iparams->bham.b);
+    gmx_fio_do_real(fio,iparams->bham.c);
     break;
   case F_MORSE:
-    do_real(iparams->morse.b0);
-    do_real(iparams->morse.cb);
-    do_real(iparams->morse.beta);
+    gmx_fio_do_real(fio,iparams->morse.b0);
+    gmx_fio_do_real(fio,iparams->morse.cb);
+    gmx_fio_do_real(fio,iparams->morse.beta);
     break;
   case F_CUBICBONDS:
-    do_real(iparams->cubic.b0);
-    do_real(iparams->cubic.kb);
-    do_real(iparams->cubic.kcub);
+    gmx_fio_do_real(fio,iparams->cubic.b0);
+    gmx_fio_do_real(fio,iparams->cubic.kb);
+    gmx_fio_do_real(fio,iparams->cubic.kcub);
     break;
   case F_CONNBONDS:
     break;
   case F_POLARIZATION:
-    do_real(iparams->polarize.alpha);
+    gmx_fio_do_real(fio,iparams->polarize.alpha);
     break;
   case F_WATER_POL:
     if (file_version < 31) 
       gmx_fatal(FARGS,"Old tpr files with water_polarization not supported. Make a new.");
-    do_real(iparams->wpol.al_x);
-    do_real(iparams->wpol.al_y);
-    do_real(iparams->wpol.al_z);
-    do_real(iparams->wpol.rOH);
-    do_real(iparams->wpol.rHH);
-    do_real(iparams->wpol.rOD);
+    gmx_fio_do_real(fio,iparams->wpol.al_x);
+    gmx_fio_do_real(fio,iparams->wpol.al_y);
+    gmx_fio_do_real(fio,iparams->wpol.al_z);
+    gmx_fio_do_real(fio,iparams->wpol.rOH);
+    gmx_fio_do_real(fio,iparams->wpol.rHH);
+    gmx_fio_do_real(fio,iparams->wpol.rOD);
     break;
   case F_THOLE_POL:
-    do_real(iparams->thole.a);
-    do_real(iparams->thole.alpha1);
-    do_real(iparams->thole.alpha2);
-    do_real(iparams->thole.rfac);
+    gmx_fio_do_real(fio,iparams->thole.a);
+    gmx_fio_do_real(fio,iparams->thole.alpha1);
+    gmx_fio_do_real(fio,iparams->thole.alpha2);
+    gmx_fio_do_real(fio,iparams->thole.rfac);
     break;
   case F_LJ:
-    do_real(iparams->lj.c6);
-    do_real(iparams->lj.c12);
+    gmx_fio_do_real(fio,iparams->lj.c6);
+    gmx_fio_do_real(fio,iparams->lj.c12);
     break;
   case F_LJ14:
-    do_real(iparams->lj14.c6A);
-    do_real(iparams->lj14.c12A);
-    do_real(iparams->lj14.c6B);
-    do_real(iparams->lj14.c12B);
+    gmx_fio_do_real(fio,iparams->lj14.c6A);
+    gmx_fio_do_real(fio,iparams->lj14.c12A);
+    gmx_fio_do_real(fio,iparams->lj14.c6B);
+    gmx_fio_do_real(fio,iparams->lj14.c12B);
     break;
   case F_LJC14_Q:
-    do_real(iparams->ljc14.fqq);
-    do_real(iparams->ljc14.qi);
-    do_real(iparams->ljc14.qj);
-    do_real(iparams->ljc14.c6);
-    do_real(iparams->ljc14.c12);
+    gmx_fio_do_real(fio,iparams->ljc14.fqq);
+    gmx_fio_do_real(fio,iparams->ljc14.qi);
+    gmx_fio_do_real(fio,iparams->ljc14.qj);
+    gmx_fio_do_real(fio,iparams->ljc14.c6);
+    gmx_fio_do_real(fio,iparams->ljc14.c12);
     break;
   case F_LJC_PAIRS_NB:
-    do_real(iparams->ljcnb.qi);
-    do_real(iparams->ljcnb.qj);
-    do_real(iparams->ljcnb.c6);
-    do_real(iparams->ljcnb.c12);
+    gmx_fio_do_real(fio,iparams->ljcnb.qi);
+    gmx_fio_do_real(fio,iparams->ljcnb.qj);
+    gmx_fio_do_real(fio,iparams->ljcnb.c6);
+    gmx_fio_do_real(fio,iparams->ljcnb.c12);
     break;
   case F_PDIHS:
   case F_PIDIHS:
   case F_ANGRES:
   case F_ANGRESZ:
-    do_real(iparams->pdihs.phiA);
-    do_real(iparams->pdihs.cpA);
+    gmx_fio_do_real(fio,iparams->pdihs.phiA);
+    gmx_fio_do_real(fio,iparams->pdihs.cpA);
     if ((ftype == F_ANGRES || ftype == F_ANGRESZ) && file_version < 42) {
       /* Read the incorrectly stored multiplicity */
-      do_real(iparams->harmonic.rB);
-      do_real(iparams->harmonic.krB);
+      gmx_fio_do_real(fio,iparams->harmonic.rB);
+      gmx_fio_do_real(fio,iparams->harmonic.krB);
       iparams->pdihs.phiB = iparams->pdihs.phiA;
       iparams->pdihs.cpB  = iparams->pdihs.cpA;
     } else {
-      do_real(iparams->pdihs.phiB);
-      do_real(iparams->pdihs.cpB);
-      do_int (iparams->pdihs.mult);
+      gmx_fio_do_real(fio,iparams->pdihs.phiB);
+      gmx_fio_do_real(fio,iparams->pdihs.cpB);
+      gmx_fio_do_int(fio,iparams->pdihs.mult);
     }
     break;
   case F_DISRES:
-    do_int (iparams->disres.label);
-    do_int (iparams->disres.type);
-    do_real(iparams->disres.low);
-    do_real(iparams->disres.up1);
-    do_real(iparams->disres.up2);
-    do_real(iparams->disres.kfac);
+    gmx_fio_do_int(fio,iparams->disres.label);
+    gmx_fio_do_int(fio,iparams->disres.type);
+    gmx_fio_do_real(fio,iparams->disres.low);
+    gmx_fio_do_real(fio,iparams->disres.up1);
+    gmx_fio_do_real(fio,iparams->disres.up2);
+    gmx_fio_do_real(fio,iparams->disres.kfac);
     break;
   case F_ORIRES:
-    do_int (iparams->orires.ex);
-    do_int (iparams->orires.label);
-    do_int (iparams->orires.power);
-    do_real(iparams->orires.c);
-    do_real(iparams->orires.obs);
-    do_real(iparams->orires.kfac);
+    gmx_fio_do_int(fio,iparams->orires.ex);
+    gmx_fio_do_int(fio,iparams->orires.label);
+    gmx_fio_do_int(fio,iparams->orires.power);
+    gmx_fio_do_real(fio,iparams->orires.c);
+    gmx_fio_do_real(fio,iparams->orires.obs);
+    gmx_fio_do_real(fio,iparams->orires.kfac);
     break;
   case F_DIHRES:
-    do_int (iparams->dihres.power);
-    do_int (iparams->dihres.label);
-    do_real(iparams->dihres.phi);
-    do_real(iparams->dihres.dphi);
-    do_real(iparams->dihres.kfac);
+    gmx_fio_do_int(fio,iparams->dihres.power);
+    gmx_fio_do_int(fio,iparams->dihres.label);
+    gmx_fio_do_real(fio,iparams->dihres.phi);
+    gmx_fio_do_real(fio,iparams->dihres.dphi);
+    gmx_fio_do_real(fio,iparams->dihres.kfac);
     break;
   case F_POSRES:
-    do_rvec(iparams->posres.pos0A);
-    do_rvec(iparams->posres.fcA);
+    gmx_fio_do_rvec(fio,iparams->posres.pos0A);
+    gmx_fio_do_rvec(fio,iparams->posres.fcA);
     if (bRead && file_version < 27) {
       copy_rvec(iparams->posres.pos0A,iparams->posres.pos0B);
       copy_rvec(iparams->posres.fcA,iparams->posres.fcB);
     } else {
-      do_rvec(iparams->posres.pos0B);
-      do_rvec(iparams->posres.fcB);
+      gmx_fio_do_rvec(fio,iparams->posres.pos0B);
+      gmx_fio_do_rvec(fio,iparams->posres.fcB);
     }
     break;
   case F_RBDIHS:
-    ndo_real(iparams->rbdihs.rbcA,NR_RBDIHS,bDum);
+    bDum=gmx_fio_ndo_real(fio,iparams->rbdihs.rbcA,NR_RBDIHS);
     if(file_version>=25) 
-      ndo_real(iparams->rbdihs.rbcB,NR_RBDIHS,bDum);
+      bDum=gmx_fio_ndo_real(fio,iparams->rbdihs.rbcB,NR_RBDIHS);
     break;
   case F_FOURDIHS:
     /* Fourier dihedrals are internally represented
      * as Ryckaert-Bellemans since those are faster to compute.
      */
-    ndo_real(iparams->rbdihs.rbcA, NR_RBDIHS, bDum);
-    ndo_real(iparams->rbdihs.rbcB, NR_RBDIHS, bDum);
+     bDum=gmx_fio_ndo_real(fio,iparams->rbdihs.rbcA, NR_RBDIHS);
+     bDum=gmx_fio_ndo_real(fio,iparams->rbdihs.rbcB, NR_RBDIHS);
     break;
   case F_CONSTR:
   case F_CONSTRNC:
-    do_real(iparams->constr.dA);
-    do_real(iparams->constr.dB);
+    gmx_fio_do_real(fio,iparams->constr.dA);
+    gmx_fio_do_real(fio,iparams->constr.dB);
     break;
   case F_SETTLE:
-    do_real(iparams->settle.doh);
-    do_real(iparams->settle.dhh);
+    gmx_fio_do_real(fio,iparams->settle.doh);
+    gmx_fio_do_real(fio,iparams->settle.dhh);
     break;
   case F_VSITE2:
-    do_real(iparams->vsite.a);
+    gmx_fio_do_real(fio,iparams->vsite.a);
     break;
   case F_VSITE3:
   case F_VSITE3FD:
   case F_VSITE3FAD:
-    do_real(iparams->vsite.a);
-    do_real(iparams->vsite.b);
+    gmx_fio_do_real(fio,iparams->vsite.a);
+    gmx_fio_do_real(fio,iparams->vsite.b);
     break;
   case F_VSITE3OUT:
   case F_VSITE4FD: 
   case F_VSITE4FDN: 
-    do_real(iparams->vsite.a);
-    do_real(iparams->vsite.b);
-    do_real(iparams->vsite.c);
+    gmx_fio_do_real(fio,iparams->vsite.a);
+    gmx_fio_do_real(fio,iparams->vsite.b);
+    gmx_fio_do_real(fio,iparams->vsite.c);
     break;
   case F_VSITEN:
-    do_int (iparams->vsiten.n);
-    do_real(iparams->vsiten.a);
+    gmx_fio_do_int(fio,iparams->vsiten.n);
+    gmx_fio_do_real(fio,iparams->vsiten.a);
     break;
   case F_GB12:
   case F_GB13:
@@ -1064,20 +1068,20 @@ void do_iparams(t_functype ftype,t_iparams *iparams,bool bRead, int file_version
     /* We got rid of some parameters in version 68 */
     if(bRead && file_version<68)
     {
-        do_real(rdum); 
-        do_real(rdum); 
-        do_real(rdum); 
-        do_real(rdum); 
-    }
-       do_real(iparams->gb.sar);       
-       do_real(iparams->gb.st);
-       do_real(iparams->gb.pi);
-       do_real(iparams->gb.gbr);
-       do_real(iparams->gb.bmlt);
+        gmx_fio_do_real(fio,rdum);     
+        gmx_fio_do_real(fio,rdum);     
+        gmx_fio_do_real(fio,rdum);     
+        gmx_fio_do_real(fio,rdum);     
+    }
+       gmx_fio_do_real(fio,iparams->gb.sar);   
+       gmx_fio_do_real(fio,iparams->gb.st);
+       gmx_fio_do_real(fio,iparams->gb.pi);
+       gmx_fio_do_real(fio,iparams->gb.gbr);
+       gmx_fio_do_real(fio,iparams->gb.bmlt);
        break;
   case F_CMAP:
-       do_int(iparams->cmap.cmapA);
-       do_int(iparams->cmap.cmapB);
+       gmx_fio_do_int(fio,iparams->cmap.cmapA);
+       gmx_fio_do_int(fio,iparams->cmap.cmapB);
     break;
   default:
     gmx_fatal(FARGS,"unknown function type %d (%s) in %s line %d",
@@ -1085,41 +1089,41 @@ void do_iparams(t_functype ftype,t_iparams *iparams,bool bRead, int file_version
                ftype,interaction_function[ftype].name,__FILE__,__LINE__);
   }
   if (!bRead)
-    unset_comment();
+    gmx_fio_unset_comment(fio);
 }
 
-static void do_ilist(t_ilist *ilist,bool bRead,int file_version,
+static void do_ilist(t_fileio *fio, t_ilist *ilist,bool bRead,int file_version,
                     int ftype)
 {
   int  i,k,idum;
   bool bDum=TRUE;
   
   if (!bRead) {
-    set_comment(interaction_function[ftype].name);
+    gmx_fio_set_comment(fio, interaction_function[ftype].name);
   }
   if (file_version < 44) {
     for(i=0; i<MAXNODES; i++)
-      do_int(idum);
+      gmx_fio_do_int(fio,idum);
   }
-  do_int (ilist->nr);
+  gmx_fio_do_int(fio,ilist->nr);
   if (bRead)
     snew(ilist->iatoms,ilist->nr);
-  ndo_int(ilist->iatoms,ilist->nr,bDum);
+  bDum=gmx_fio_ndo_int(fio,ilist->iatoms,ilist->nr);
   if (!bRead)
-    unset_comment();
+    gmx_fio_unset_comment(fio);
 }
 
-static void do_ffparams(gmx_ffparams_t *ffparams,
+static void do_ffparams(t_fileio *fio, gmx_ffparams_t *ffparams,
                        bool bRead, int file_version)
 {
   int  idum,i,j,k;
   bool bDum=TRUE;
 
-  do_int(ffparams->atnr);
+  gmx_fio_do_int(fio,ffparams->atnr);
   if (file_version < 57) {
-    do_int(idum);
+    gmx_fio_do_int(fio,idum);
   }
-  do_int(ffparams->ntypes);
+  gmx_fio_do_int(fio,ffparams->ntypes);
   if (bRead && debug)
     fprintf(debug,"ffparams->atnr = %d, ntypes = %d\n",
            ffparams->atnr,ffparams->ntypes);
@@ -1128,18 +1132,18 @@ static void do_ffparams(gmx_ffparams_t *ffparams,
     snew(ffparams->iparams,ffparams->ntypes);
   }
   /* Read/write all the function types */
-  ndo_int(ffparams->functype,ffparams->ntypes,bDum);
+  bDum=gmx_fio_ndo_int(fio,ffparams->functype,ffparams->ntypes);
   if (bRead && debug)
     pr_ivec(debug,0,"functype",ffparams->functype,ffparams->ntypes,TRUE);
 
   if (file_version >= 66) {
-    do_double(ffparams->reppow);
+    gmx_fio_do_double(fio,ffparams->reppow);
   } else {
     ffparams->reppow = 12.0;
   }
 
   if (file_version >= 57) {
-    do_real(ffparams->fudgeQQ);
+    gmx_fio_do_real(fio,ffparams->fudgeQQ);
   }
 
   /* Check whether all these function types are supported by the code.
@@ -1162,13 +1166,15 @@ static void do_ffparams(gmx_ffparams_t *ffparams,
          }
        }
     
-    do_iparams(ffparams->functype[i],&ffparams->iparams[i],bRead,file_version);
+    do_iparams(fio, ffparams->functype[i],&ffparams->iparams[i],bRead,
+               file_version);
     if (bRead && debug)
       pr_iparams(debug,ffparams->functype[i],&ffparams->iparams[i]);
   }
 }
 
-static void do_ilists(t_ilist *ilist,bool bRead, int file_version)
+static void do_ilists(t_fileio *fio, t_ilist *ilist,bool bRead, 
+                      int file_version)
 {
   int i,j,k,renum[F_NRE];
   bool bDum=TRUE,bClear;
@@ -1183,7 +1189,7 @@ static void do_ilists(t_ilist *ilist,bool bRead, int file_version)
       ilist[j].nr = 0;
       ilist[j].iatoms = NULL;
     } else {
-      do_ilist(&ilist[j],bRead,file_version,j);
+      do_ilist(fio, &ilist[j],bRead,file_version,j);
     }
     /*
     if (bRead && gmx_debug_at)
@@ -1193,77 +1199,78 @@ static void do_ilists(t_ilist *ilist,bool bRead, int file_version)
   }
 }
 
-static void do_idef(gmx_ffparams_t *ffparams,gmx_moltype_t *molt,
+static void do_idef(t_fileio *fio, gmx_ffparams_t *ffparams,gmx_moltype_t *molt,
                    bool bRead, int file_version)
 {
-  do_ffparams(ffparams,bRead,file_version);
+  do_ffparams(fio, ffparams,bRead,file_version);
     
   if (file_version >= 54) {
-    do_real(ffparams->fudgeQQ);
+    gmx_fio_do_real(fio,ffparams->fudgeQQ);
   }
 
-  do_ilists(molt->ilist,bRead,file_version);
+  do_ilists(fio, molt->ilist,bRead,file_version);
 }
 
-static void do_block(t_block *block,bool bRead,int file_version)
+static void do_block(t_fileio *fio, t_block *block,bool bRead,int file_version)
 {
   int  i,idum,dum_nra,*dum_a;
   bool bDum=TRUE;
 
   if (file_version < 44)
     for(i=0; i<MAXNODES; i++)
-      do_int(idum);
-  do_int (block->nr);
+      gmx_fio_do_int(fio,idum);
+  gmx_fio_do_int(fio,block->nr);
   if (file_version < 51)
-    do_int (dum_nra);
+    gmx_fio_do_int(fio,dum_nra);
   if (bRead) {
     block->nalloc_index = block->nr+1;
     snew(block->index,block->nalloc_index);
   }
-  ndo_int(block->index,block->nr+1,bDum);
+  bDum=gmx_fio_ndo_int(fio,block->index,block->nr+1);
 
   if (file_version < 51 && dum_nra > 0) {
     snew(dum_a,dum_nra);
-    ndo_int(dum_a,dum_nra,bDum);
+    bDum=gmx_fio_ndo_int(fio,dum_a,dum_nra);
     sfree(dum_a);
   }
 }
 
-static void do_blocka(t_blocka *block,bool bRead,int file_version)
+static void do_blocka(t_fileio *fio, t_blocka *block,bool bRead,
+                      int file_version)
 {
   int  i,idum;
   bool bDum=TRUE;
 
   if (file_version < 44)
     for(i=0; i<MAXNODES; i++)
-      do_int(idum);
-  do_int (block->nr);
-  do_int (block->nra);
+      gmx_fio_do_int(fio,idum);
+  gmx_fio_do_int(fio,block->nr);
+  gmx_fio_do_int(fio,block->nra);
   if (bRead) {
     block->nalloc_index = block->nr+1;
     snew(block->index,block->nalloc_index);
     block->nalloc_a = block->nra;
     snew(block->a,block->nalloc_a);
   }
-  ndo_int(block->index,block->nr+1,bDum);
-  ndo_int(block->a,block->nra,bDum);
+  bDum=gmx_fio_ndo_int(fio,block->index,block->nr+1);
+  bDum=gmx_fio_ndo_int(fio,block->a,block->nra);
 }
 
-static void do_atom(t_atom *atom,int ngrp,bool bRead, int file_version,
-                   gmx_groups_t *groups,int atnr)
+static void do_atom(t_fileio *fio, t_atom *atom,int ngrp,bool bRead, 
+                    int file_version, gmx_groups_t *groups,int atnr)
 { 
   int i,myngrp;
   
-  do_real (atom->m);
-  do_real (atom->q);
-  do_real (atom->mB);
-  do_real (atom->qB);
-  do_ushort(atom->type);
-  do_ushort(atom->typeB);
-  do_int (atom->ptype);
-  do_int (atom->resind);
+  gmx_fio_do_real(fio,atom->m);
+  gmx_fio_do_real(fio,atom->q);
+  gmx_fio_do_real(fio,atom->mB);
+  gmx_fio_do_real(fio,atom->qB);
+  gmx_fio_do_ushort(fio, atom->type);
+  gmx_fio_do_ushort(fio, atom->typeB);
+  gmx_fio_do_int(fio,atom->ptype);
+  gmx_fio_do_int(fio,atom->resind);
   if (file_version >= 52)
-    do_int(atom->atomnumber);
+    gmx_fio_do_int(fio,atom->atomnumber);
   else if (bRead)
     atom->atomnumber = NOTSET;
   if (file_version < 23) 
@@ -1275,7 +1282,7 @@ static void do_atom(t_atom *atom,int ngrp,bool bRead, int file_version,
 
   if (file_version < 57) {
     unsigned char uchar[egcNR];
-    do_nuchar(uchar,myngrp);
+    gmx_fio_ndo_uchar(fio,uchar,myngrp);
     for(i=myngrp; (i<ngrp); i++) {
       uchar[i] = 0;
     }
@@ -1286,7 +1293,8 @@ static void do_atom(t_atom *atom,int ngrp,bool bRead, int file_version,
   }
 }
 
-static void do_grps(int ngrp,t_grps grps[],bool bRead, int file_version)
+static void do_grps(t_fileio *fio, int ngrp,t_grps grps[],bool bRead, 
+                    int file_version)
 {
   int i,j,myngrp;
   bool bDum=TRUE;
@@ -1300,10 +1308,10 @@ static void do_grps(int ngrp,t_grps grps[],bool bRead, int file_version)
 
   for(j=0; (j<ngrp); j++) {
     if (j<myngrp) {
-      do_int (grps[j].nr);
+      gmx_fio_do_int(fio,grps[j].nr);
       if (bRead)
        snew(grps[j].nm_ind,grps[j].nr);
-      ndo_int(grps[j].nm_ind,grps[j].nr,bDum);
+      bDum=gmx_fio_ndo_int(fio,grps[j].nm_ind,grps[j].nr);
     }
     else {
       grps[j].nr = 1;
@@ -1312,38 +1320,39 @@ static void do_grps(int ngrp,t_grps grps[],bool bRead, int file_version)
   }
 }
 
-static void do_symstr(char ***nm,bool bRead,t_symtab *symtab)
+static void do_symstr(t_fileio *fio, char ***nm,bool bRead,t_symtab *symtab)
 {
   int ls;
   
   if (bRead) {
-    do_int(ls);
+    gmx_fio_do_int(fio,ls);
     *nm = get_symtab_handle(symtab,ls);
   }
   else {
     ls = lookup_symtab(symtab,*nm);
-    do_int(ls);
+    gmx_fio_do_int(fio,ls);
   }
 }
 
-static void do_strstr(int nstr,char ***nm,bool bRead,t_symtab *symtab)
+static void do_strstr(t_fileio *fio, int nstr,char ***nm,bool bRead,
+                      t_symtab *symtab)
 {
   int  j;
   
   for (j=0; (j<nstr); j++) 
-    do_symstr(&(nm[j]),bRead,symtab);
+    do_symstr(fio, &(nm[j]),bRead,symtab);
 }
 
-static void do_resinfo(int n,t_resinfo *ri,bool bRead,t_symtab *symtab,
-                      int file_version)
+static void do_resinfo(t_fileio *fio, int n,t_resinfo *ri,bool bRead,
+                       t_symtab *symtab, int file_version)
 {
   int  j;
   
   for (j=0; (j<n); j++) {
-    do_symstr(&(ri[j].name),bRead,symtab);
+    do_symstr(fio, &(ri[j].name),bRead,symtab);
     if (file_version >= 63) {
-      do_int  (ri[j].nr);
-      do_uchar(ri[j].ic);
+      gmx_fio_do_int(fio,ri[j].nr);
+      gmx_fio_do_uchar(fio, ri[j].ic);
     } else {
       ri[j].nr = j + 1;
       ri[j].ic = ' ';
@@ -1351,16 +1360,16 @@ static void do_resinfo(int n,t_resinfo *ri,bool bRead,t_symtab *symtab,
   }
 }
 
-static void do_atoms(t_atoms *atoms,bool bRead,t_symtab *symtab,
+static void do_atoms(t_fileio *fio, t_atoms *atoms,bool bRead,t_symtab *symtab,
                     int file_version,
                     gmx_groups_t *groups)
 {
   int i;
   
-  do_int(atoms->nr);
-  do_int(atoms->nres);
+  gmx_fio_do_int(fio,atoms->nr);
+  gmx_fio_do_int(fio,atoms->nres);
   if (file_version < 57) {
-    do_int(groups->ngrpname);
+    gmx_fio_do_int(fio,groups->ngrpname);
     for(i=0; i<egcNR; i++) {
       groups->ngrpnr[i] = atoms->nr;
       snew(groups->grpnr[i],groups->ngrpnr[i]);
@@ -1378,42 +1387,42 @@ static void do_atoms(t_atoms *atoms,bool bRead,t_symtab *symtab,
     atoms->pdbinfo = NULL;
   }
   for(i=0; (i<atoms->nr); i++) {
-    do_atom(&atoms->atom[i],egcNR,bRead, file_version,groups,i);
+    do_atom(fio, &atoms->atom[i],egcNR,bRead, file_version,groups,i);
   }
-  do_strstr(atoms->nr,atoms->atomname,bRead,symtab);
+  do_strstr(fio, atoms->nr,atoms->atomname,bRead,symtab);
   if (bRead && (file_version <= 20)) {
     for(i=0; i<atoms->nr; i++) {
       atoms->atomtype[i]  = put_symtab(symtab,"?");
       atoms->atomtypeB[i] = put_symtab(symtab,"?");
     }
   } else {
-    do_strstr(atoms->nr,atoms->atomtype,bRead,symtab);
-    do_strstr(atoms->nr,atoms->atomtypeB,bRead,symtab);
+    do_strstr(fio, atoms->nr,atoms->atomtype,bRead,symtab);
+    do_strstr(fio, atoms->nr,atoms->atomtypeB,bRead,symtab);
   }
-  do_resinfo(atoms->nres,atoms->resinfo,bRead,symtab,file_version);
+  do_resinfo(fio, atoms->nres,atoms->resinfo,bRead,symtab,file_version);
 
   if (file_version < 57) {
-    do_strstr(groups->ngrpname,groups->grpname,bRead,symtab);
+    do_strstr(fio, groups->ngrpname,groups->grpname,bRead,symtab);
   
-    do_grps(egcNR,groups->grps,bRead,file_version);
+    do_grps(fio, egcNR,groups->grps,bRead,file_version);
   }
 }
 
-static void do_groups(gmx_groups_t *groups,
+static void do_groups(t_fileio *fio, gmx_groups_t *groups,
                      bool bRead,t_symtab *symtab,
                      int file_version)
 {
   int  g,n,i;
   bool bDum=TRUE;
 
-  do_grps(egcNR,groups->grps,bRead,file_version);
-  do_int(groups->ngrpname);
+  do_grps(fio, egcNR,groups->grps,bRead,file_version);
+  gmx_fio_do_int(fio,groups->ngrpname);
   if (bRead) {
     snew(groups->grpname,groups->ngrpname);
   }
-  do_strstr(groups->ngrpname,groups->grpname,bRead,symtab);
+  do_strstr(fio, groups->ngrpname,groups->grpname,bRead,symtab);
   for(g=0; g<egcNR; g++) {
-    do_int(groups->ngrpnr[g]);
+    gmx_fio_do_int(fio,groups->ngrpnr[g]);
     if (groups->ngrpnr[g] == 0) {
       if (bRead) {
        groups->grpnr[g] = NULL;
@@ -1422,19 +1431,19 @@ static void do_groups(gmx_groups_t *groups,
       if (bRead) {
        snew(groups->grpnr[g],groups->ngrpnr[g]);
       }
-      ndo_nuchar(groups->grpnr[g],groups->ngrpnr[g],bDum);
+      bDum=gmx_fio_ndo_uchar(fio, groups->grpnr[g],groups->ngrpnr[g]);
     }
   }
 }
 
-static void do_atomtypes(t_atomtypes *atomtypes,bool bRead,
+static void do_atomtypes(t_fileio *fio, t_atomtypes *atomtypes,bool bRead,
                         t_symtab *symtab,int file_version)
 {
   int i,j;
   bool bDum = TRUE;
   
   if (file_version > 25) {
-    do_int(atomtypes->nr);
+    gmx_fio_do_int(fio,atomtypes->nr);
     j=atomtypes->nr;
     if (bRead) {
       snew(atomtypes->radius,j);
@@ -1444,17 +1453,17 @@ static void do_atomtypes(t_atomtypes *atomtypes,bool bRead,
       snew(atomtypes->gb_radius,j);
       snew(atomtypes->S_hct,j);
     }
-    ndo_real(atomtypes->radius,j,bDum);
-    ndo_real(atomtypes->vol,j,bDum);
-    ndo_real(atomtypes->surftens,j,bDum);
+    bDum=gmx_fio_ndo_real(fio,atomtypes->radius,j);
+    bDum=gmx_fio_ndo_real(fio,atomtypes->vol,j);
+    bDum=gmx_fio_ndo_real(fio,atomtypes->surftens,j);
     if(file_version >= 40)
     {
-        ndo_int(atomtypes->atomnumber,j,bDum);
+        bDum=gmx_fio_ndo_int(fio,atomtypes->atomnumber,j);
     }
        if(file_version >= 60)
        {
-               ndo_real(atomtypes->gb_radius,j,bDum);
-               ndo_real(atomtypes->S_hct,j,bDum);
+               bDum=gmx_fio_ndo_real(fio,atomtypes->gb_radius,j);
+               bDum=gmx_fio_ndo_real(fio,atomtypes->S_hct,j);
        }
   } else {
     /* File versions prior to 26 cannot do GBSA, 
@@ -1470,13 +1479,13 @@ static void do_atomtypes(t_atomtypes *atomtypes,bool bRead,
   }  
 }
 
-static void do_symtab(t_symtab *symtab,bool bRead)
+static void do_symtab(t_fileio *fio, t_symtab *symtab,bool bRead)
 {
   int i,nr;
   t_symbuf *symbuf;
   char buf[STRLEN];
   
-  do_int(symtab->nr);
+  gmx_fio_do_int(fio,symtab->nr);
   nr     = symtab->nr;
   if (bRead) {
     snew(symtab->symbuf,1);
@@ -1484,7 +1493,7 @@ static void do_symtab(t_symtab *symtab,bool bRead)
     symbuf->bufsize = nr;
     snew(symbuf->buf,nr);
     for (i=0; (i<nr); i++) {
-      do_string(buf);
+      gmx_fio_do_string(fio,buf);
       symbuf->buf[i]=strdup(buf);
     }
   }
@@ -1492,7 +1501,7 @@ static void do_symtab(t_symtab *symtab,bool bRead)
     symbuf = symtab->symbuf;
     while (symbuf!=NULL) {
       for (i=0; (i<symbuf->bufsize) && (i<nr); i++) 
-       do_string(symbuf->buf[i]);
+       gmx_fio_do_string(fio,symbuf->buf[i]);
       nr-=i;
       symbuf=symbuf->next;
     }
@@ -1501,13 +1510,12 @@ static void do_symtab(t_symtab *symtab,bool bRead)
   }
 }
 
-static void
-do_cmap(gmx_cmap_t *cmap_grid, bool bRead)
+static void do_cmap(t_fileio *fio, gmx_cmap_t *cmap_grid, bool bRead)
 {
        int i,j,ngrid,gs,nelem;
        
-       do_int(cmap_grid->ngrid);
-       do_int(cmap_grid->grid_spacing);
+       gmx_fio_do_int(fio,cmap_grid->ngrid);
+       gmx_fio_do_int(fio,cmap_grid->grid_spacing);
        
        ngrid = cmap_grid->ngrid;
        gs    = cmap_grid->grid_spacing;
@@ -1527,17 +1535,16 @@ do_cmap(gmx_cmap_t *cmap_grid, bool bRead)
        {
                for(j=0;j<nelem;j++)
                {
-                       do_real(cmap_grid->cmapdata[i].cmap[j*4]);
-                       do_real(cmap_grid->cmapdata[i].cmap[j*4+1]);
-                       do_real(cmap_grid->cmapdata[i].cmap[j*4+2]);
-                       do_real(cmap_grid->cmapdata[i].cmap[j*4+3]);
+                       gmx_fio_do_real(fio,cmap_grid->cmapdata[i].cmap[j*4]);
+                       gmx_fio_do_real(fio,cmap_grid->cmapdata[i].cmap[j*4+1]);
+                       gmx_fio_do_real(fio,cmap_grid->cmapdata[i].cmap[j*4+2]);
+                       gmx_fio_do_real(fio,cmap_grid->cmapdata[i].cmap[j*4+3]);
                }
        }       
 }
 
 
-void 
-tpx_make_chain_identifiers(t_atoms *atoms,t_block *mols)
+void tpx_make_chain_identifiers(t_atoms *atoms,t_block *mols)
 {
   int m,a,a0,a1,r;
   unsigned char c,chain;
@@ -1563,56 +1570,57 @@ tpx_make_chain_identifiers(t_atoms *atoms,t_block *mols)
   }
 }
   
-static void do_moltype(gmx_moltype_t *molt,bool bRead,t_symtab *symtab,
-                      int file_version,
+static void do_moltype(t_fileio *fio, gmx_moltype_t *molt,bool bRead,
+                       t_symtab *symtab, int file_version,
                       gmx_groups_t *groups)
 {
   int i;
 
   if (file_version >= 57) {
-    do_symstr(&(molt->name),bRead,symtab);
+    do_symstr(fio, &(molt->name),bRead,symtab);
   }
 
-  do_atoms(&molt->atoms, bRead, symtab, file_version, groups);
+  do_atoms(fio, &molt->atoms, bRead, symtab, file_version, groups);
 
   if (bRead && gmx_debug_at) {
     pr_atoms(debug,0,"atoms",&molt->atoms,TRUE);
   }
   
   if (file_version >= 57) {
-    do_ilists(molt->ilist,bRead,file_version);
+    do_ilists(fio, molt->ilist,bRead,file_version);
 
-    do_block(&molt->cgs,bRead,file_version);
+    do_block(fio, &molt->cgs,bRead,file_version);
     if (bRead && gmx_debug_at) {
       pr_block(debug,0,"cgs",&molt->cgs,TRUE);
     }
   }
 
   /* This used to be in the atoms struct */
-  do_blocka(&molt->excls, bRead, file_version);
+  do_blocka(fio, &molt->excls, bRead, file_version);
 }
 
-static void do_molblock(gmx_molblock_t *molb,bool bRead,int file_version)
+static void do_molblock(t_fileio *fio, gmx_molblock_t *molb,bool bRead,
+                        int file_version)
 {
   int i;
 
-  do_int(molb->type);
-  do_int(molb->nmol);
-  do_int(molb->natoms_mol);
+  gmx_fio_do_int(fio,molb->type);
+  gmx_fio_do_int(fio,molb->nmol);
+  gmx_fio_do_int(fio,molb->natoms_mol);
   /* Position restraint coordinates */
-  do_int(molb->nposres_xA);
+  gmx_fio_do_int(fio,molb->nposres_xA);
   if (molb->nposres_xA > 0) {
     if (bRead) {
       snew(molb->posres_xA,molb->nposres_xA);
     }
-    ndo_rvec(molb->posres_xA,molb->nposres_xA);
+    gmx_fio_ndo_rvec(fio,molb->posres_xA,molb->nposres_xA);
   }
-  do_int(molb->nposres_xB);
+  gmx_fio_do_int(fio,molb->nposres_xB);
   if (molb->nposres_xB > 0) {
     if (bRead) {
       snew(molb->posres_xB,molb->nposres_xB);
     }
-    ndo_rvec(molb->posres_xB,molb->nposres_xB);
+    gmx_fio_ndo_rvec(fio,molb->posres_xB,molb->nposres_xB);
   }
 
 }
@@ -1719,23 +1727,24 @@ static void set_disres_npair(gmx_mtop_t *mtop)
   }
 }
 
-static void do_mtop(gmx_mtop_t *mtop,bool bRead, int file_version)
+static void do_mtop(t_fileio *fio, gmx_mtop_t *mtop,bool bRead, 
+                    int file_version)
 {
   int  mt,mb,i;
   t_blocka dumb;
 
   if (bRead)
     init_mtop(mtop);
-  do_symtab(&(mtop->symtab),bRead);
+  do_symtab(fio, &(mtop->symtab),bRead);
   if (bRead && debug) 
     pr_symtab(debug,0,"symtab",&mtop->symtab);
   
-  do_symstr(&(mtop->name),bRead,&(mtop->symtab));
+  do_symstr(fio, &(mtop->name),bRead,&(mtop->symtab));
   
   if (file_version >= 57) {
-    do_ffparams(&mtop->ffparams,bRead,file_version);
+    do_ffparams(fio, &mtop->ffparams,bRead,file_version);
 
-    do_int(mtop->nmoltype);
+    gmx_fio_do_int(fio,mtop->nmoltype);
   } else {
     mtop->nmoltype = 1;
   }
@@ -1746,12 +1755,12 @@ static void do_mtop(gmx_mtop_t *mtop,bool bRead, int file_version)
     }
   }
   for(mt=0; mt<mtop->nmoltype; mt++) {
-    do_moltype(&mtop->moltype[mt],bRead,&mtop->symtab,file_version,
+    do_moltype(fio, &mtop->moltype[mt],bRead,&mtop->symtab,file_version,
               &mtop->groups);
   }
 
   if (file_version >= 57) {
-    do_int(mtop->nmolblock);
+    gmx_fio_do_int(fio,mtop->nmolblock);
   } else {
     mtop->nmolblock = 1;
   }
@@ -1760,9 +1769,9 @@ static void do_mtop(gmx_mtop_t *mtop,bool bRead, int file_version)
   }
   if (file_version >= 57) {
     for(mb=0; mb<mtop->nmolblock; mb++) {
-      do_molblock(&mtop->molblock[mb],bRead,file_version);
+      do_molblock(fio, &mtop->molblock[mb],bRead,file_version);
     }
-    do_int(mtop->natoms);
+    gmx_fio_do_int(fio,mtop->natoms);
   } else {
     mtop->molblock[0].type = 0;
     mtop->molblock[0].nmol = 1;
@@ -1771,19 +1780,19 @@ static void do_mtop(gmx_mtop_t *mtop,bool bRead, int file_version)
     mtop->molblock[0].nposres_xB = 0;
   }
 
-  do_atomtypes (&(mtop->atomtypes),bRead,&(mtop->symtab), file_version);
+  do_atomtypes (fio, &(mtop->atomtypes),bRead,&(mtop->symtab), file_version);
   if (bRead && debug) 
     pr_atomtypes(debug,0,"atomtypes",&mtop->atomtypes,TRUE);
 
   if (file_version < 57) {
     /* Debug statements are inside do_idef */    
-    do_idef (&mtop->ffparams,&mtop->moltype[0],bRead,file_version);
+    do_idef (fio, &mtop->ffparams,&mtop->moltype[0],bRead,file_version);
     mtop->natoms = mtop->moltype[0].atoms.nr;
   }
        
   if(file_version >= 65)
   {
-      do_cmap(&mtop->ffparams.cmap_grid,bRead);
+      do_cmap(fio, &mtop->ffparams.cmap_grid,bRead);
   }
   else
   {
@@ -1793,15 +1802,15 @@ static void do_mtop(gmx_mtop_t *mtop,bool bRead, int file_version)
   }
          
   if (file_version >= 57) {
-    do_groups(&mtop->groups,bRead,&(mtop->symtab),file_version);
+    do_groups(fio, &mtop->groups,bRead,&(mtop->symtab),file_version);
   }
 
   if (file_version < 57) {
-    do_block(&mtop->moltype[0].cgs,bRead,file_version);
+    do_block(fio, &mtop->moltype[0].cgs,bRead,file_version);
     if (bRead && gmx_debug_at) {
       pr_block(debug,0,"cgs",&mtop->moltype[0].cgs,TRUE);
     }
-    do_block(&mtop->mols,bRead,file_version);
+    do_block(fio, &mtop->mols,bRead,file_version);
     /* Add the posres coordinates to the molblock */
     add_posres_molblock(mtop);
   }
@@ -1816,7 +1825,7 @@ static void do_mtop(gmx_mtop_t *mtop,bool bRead, int file_version)
 
   if (file_version < 51) {
     /* Here used to be the shake blocks */
-    do_blocka(&dumb,bRead,file_version);
+    do_blocka(fio, &dumb,bRead,file_version);
     if (dumb.nr > 0)
       sfree(dumb.index);
     if (dumb.nra > 0)
@@ -1838,8 +1847,9 @@ static void do_mtop(gmx_mtop_t *mtop,bool bRead, int file_version)
  * 
  * If possible, we will read the inputrec even when TopOnlyOK is TRUE.
  */
-static void do_tpxheader(int fp,bool bRead,t_tpxheader *tpx, bool TopOnlyOK, 
-                         int *file_version, int *file_generation)
+static void do_tpxheader(t_fileio *fio,bool bRead,t_tpxheader *tpx, 
+                         bool TopOnlyOK, int *file_version, 
+                         int *file_generation)
 {
   char  buf[STRLEN];
   bool  bDouble;
@@ -1847,42 +1857,43 @@ static void do_tpxheader(int fp,bool bRead,t_tpxheader *tpx, bool TopOnlyOK,
   int   fver,fgen;
   int   idum=0;
   real  rdum=0;
-  gmx_fio_select(fp);
-  gmx_fio_setdebug(fp,bDebugMode());
+
+  gmx_fio_checktype(fio);
+  gmx_fio_setdebug(fio,bDebugMode());
   
   /* NEW! XDR tpb file */
   precision = sizeof(real);
   if (bRead) {
-    do_string(buf);
+    gmx_fio_do_string(fio,buf);
     if (strncmp(buf,"VERSION",7))
       gmx_fatal(FARGS,"Can not read file %s,\n"
                  "             this file is from a Gromacs version which is older than 2.0\n"
                  "             Make a new one with grompp or use a gro or pdb file, if possible",
-                 gmx_fio_getname(fp));
-    do_int(precision);
+                 gmx_fio_getname(fio));
+    gmx_fio_do_int(fio,precision);
     bDouble = (precision == sizeof(double));
     if ((precision != sizeof(float)) && !bDouble)
       gmx_fatal(FARGS,"Unknown precision in file %s: real is %d bytes "
                  "instead of %d or %d",
-                 gmx_fio_getname(fp),precision,sizeof(float),sizeof(double));
-    gmx_fio_setprecision(fp,bDouble);
+                 gmx_fio_getname(fio),precision,sizeof(float),sizeof(double));
+    gmx_fio_setprecision(fio,bDouble);
     fprintf(stderr,"Reading file %s, %s (%s precision)\n",
-           gmx_fio_getname(fp),buf,bDouble ? "double" : "single");
+           gmx_fio_getname(fio),buf,bDouble ? "double" : "single");
   }
   else {
-    do_string(GromacsVersion());
+    gmx_fio_write_string(fio,GromacsVersion());
     bDouble = (precision == sizeof(double));
-    gmx_fio_setprecision(fp,bDouble);
-    do_int(precision);
+    gmx_fio_setprecision(fio,bDouble);
+    gmx_fio_do_int(fio,precision);
     fver = tpx_version;
     fgen = tpx_generation;
   }
   
   /* Check versions! */
-  do_int(fver);
+  gmx_fio_do_int(fio,fver);
   
   if(fver>=26)
-    do_int(fgen);
+    gmx_fio_do_int(fio,fgen);
   else
     fgen=0;
  
@@ -1896,25 +1907,25 @@ static void do_tpxheader(int fp,bool bRead,t_tpxheader *tpx, bool TopOnlyOK,
       ((fver > tpx_version) && !TopOnlyOK) ||
       (fgen > tpx_generation))
     gmx_fatal(FARGS,"reading tpx file (%s) version %d with version %d program",
-               gmx_fio_getname(fp),fver,tpx_version);
+               gmx_fio_getname(fio),fver,tpx_version);
   
-  do_section(eitemHEADER,bRead);
-  do_int (tpx->natoms);
+  do_section(fio,eitemHEADER,bRead);
+  gmx_fio_do_int(fio,tpx->natoms);
   if (fver >= 28)
-    do_int(tpx->ngtc);
+    gmx_fio_do_int(fio,tpx->ngtc);
   else
     tpx->ngtc = 0;
   if (fver < 62) {
-    do_int (idum);
-    do_real(rdum);
+    gmx_fio_do_int(fio,idum);
+    gmx_fio_do_real(fio,rdum);
   }
-  do_real(tpx->lambda);
-  do_int (tpx->bIr);
-  do_int (tpx->bTop);
-  do_int (tpx->bX);
-  do_int (tpx->bV);
-  do_int (tpx->bF);
-  do_int (tpx->bBox);
+  gmx_fio_do_real(fio,tpx->lambda);
+  gmx_fio_do_int(fio,tpx->bIr);
+  gmx_fio_do_int(fio,tpx->bTop);
+  gmx_fio_do_int(fio,tpx->bX);
+  gmx_fio_do_int(fio,tpx->bV);
+  gmx_fio_do_int(fio,tpx->bF);
+  gmx_fio_do_int(fio,tpx->bBox);
 
   if((fgen > tpx_generation)) {
     /* This can only happen if TopOnlyOK=TRUE */
@@ -1922,7 +1933,7 @@ static void do_tpxheader(int fp,bool bRead,t_tpxheader *tpx, bool TopOnlyOK,
   }
 }
 
-static int do_tpx(int fp,bool bRead,
+static int do_tpx(t_fileio *fio, bool bRead,
                  t_inputrec *ir,t_state *state,rvec *f,gmx_mtop_t *mtop,
                  bool bXVallocated)
 {
@@ -1950,7 +1961,7 @@ static int do_tpx(int fp,bool bRead,
   
   TopOnlyOK = (ir==NULL);
   
-  do_tpxheader(fp,bRead,&tpx,TopOnlyOK,&file_version,&file_generation);
+  do_tpxheader(fio,bRead,&tpx,TopOnlyOK,&file_version,&file_generation);
 
   if (bRead) {
     state->flags  = 0;
@@ -1969,23 +1980,23 @@ static int do_tpx(int fp,bool bRead,
     }
   }
 
-#define do_test(b,p) if (bRead && (p!=NULL) && !b) gmx_fatal(FARGS,"No %s in %s",#p,gmx_fio_getname(fp)) 
+#define do_test(fio,b,p) if (bRead && (p!=NULL) && !b) gmx_fatal(FARGS,"No %s in %s",#p,gmx_fio_getname(fio)) 
 
-  do_test(tpx.bBox,state->box);
-  do_section(eitemBOX,bRead);
+  do_test(fio,tpx.bBox,state->box);
+  do_section(fio,eitemBOX,bRead);
   if (tpx.bBox) {
-    ndo_rvec(state->box,DIM);
+    gmx_fio_ndo_rvec(fio,state->box,DIM);
     if (file_version >= 51) {
-      ndo_rvec(state->box_rel,DIM);
+      gmx_fio_ndo_rvec(fio,state->box_rel,DIM);
     } else {
       /* We initialize box_rel after reading the inputrec */
       clear_mat(state->box_rel);
     }
     if (file_version >= 28) {
-      ndo_rvec(state->boxv,DIM);
+      gmx_fio_ndo_rvec(fio,state->boxv,DIM);
       if (file_version < 56) {
        matrix mdum;
-       ndo_rvec(mdum,DIM);
+       gmx_fio_ndo_rvec(fio,mdum,DIM);
       }
     }
   }
@@ -1997,10 +2008,10 @@ static int do_tpx(int fp,bool bRead,
     /*ndo_double(state->therm_integral,state->ngtc,bDum);*/
     snew(dumv,state->ngtc);
     if (file_version < 69) {
-      ndo_real(dumv,state->ngtc,bDum);
+      bDum=gmx_fio_ndo_real(fio,dumv,state->ngtc);
     }
     /* These used to be the Berendsen tcoupl_lambda's */
-    ndo_real(dumv,state->ngtc,bDum);
+    bDum=gmx_fio_ndo_real(fio,dumv,state->ngtc);
     sfree(dumv);
   }
 
@@ -2009,16 +2020,18 @@ static int do_tpx(int fp,bool bRead,
    * for analysis/viewer programs.
    */
   if(file_version<26) {
-    do_test(tpx.bIr,ir);
-    do_section(eitemIR,bRead);
+    do_test(fio,tpx.bIr,ir);
+    do_section(fio,eitemIR,bRead);
     if (tpx.bIr) {
       if (ir) {
-       do_inputrec(ir,bRead,file_version,mtop ? &mtop->ffparams.fudgeQQ : NULL);
+       do_inputrec(fio, ir,bRead,file_version,
+                    mtop ? &mtop->ffparams.fudgeQQ : NULL);
        if (bRead && debug) 
          pr_inputrec(debug,0,"inputrec",ir,FALSE);
       }
       else {
-       do_inputrec(&dum_ir,bRead,file_version,mtop ? &mtop->ffparams.fudgeQQ :NULL);
+       do_inputrec(fio, &dum_ir,bRead,file_version,
+                    mtop ? &mtop->ffparams.fudgeQQ :NULL);
        if (bRead && debug) 
          pr_inputrec(debug,0,"inputrec",&dum_ir,FALSE);
        done_inputrec(&dum_ir);
@@ -2027,37 +2040,37 @@ static int do_tpx(int fp,bool bRead,
     }
   }
   
-  do_test(tpx.bTop,mtop);
-  do_section(eitemTOP,bRead);
+  do_test(fio,tpx.bTop,mtop);
+  do_section(fio,eitemTOP,bRead);
   if (tpx.bTop) {
     if (mtop) {
-      do_mtop(mtop,bRead, file_version);
+      do_mtop(fio,mtop,bRead, file_version);
     } else {
-      do_mtop(&dum_top,bRead,file_version);
+      do_mtop(fio,&dum_top,bRead,file_version);
       done_mtop(&dum_top,TRUE);
     }
   }
-  do_test(tpx.bX,state->x);  
-  do_section(eitemX,bRead);
+  do_test(fio,tpx.bX,state->x);  
+  do_section(fio,eitemX,bRead);
   if (tpx.bX) {
     if (bRead) {
       state->flags |= (1<<estX);
     }
-    ndo_rvec(state->x,state->natoms);
+    gmx_fio_ndo_rvec(fio,state->x,state->natoms);
   }
   
-  do_test(tpx.bV,state->v);
-  do_section(eitemV,bRead);
+  do_test(fio,tpx.bV,state->v);
+  do_section(fio,eitemV,bRead);
   if (tpx.bV) {
     if (bRead) {
       state->flags |= (1<<estV);
     }
-    ndo_rvec(state->v,state->natoms);
+    gmx_fio_ndo_rvec(fio,state->v,state->natoms);
   }
 
-  do_test(tpx.bF,f);
-  do_section(eitemF,bRead);
-  if (tpx.bF) ndo_rvec(f,state->natoms);
+  do_test(fio,tpx.bF,f);
+  do_section(fio,eitemF,bRead);
+  if (tpx.bF) gmx_fio_ndo_rvec(fio,f,state->natoms);
 
   /* Starting with tpx version 26, we have the inputrec
    * at the end of the file, so we can ignore it 
@@ -2069,8 +2082,8 @@ static int do_tpx(int fp,bool bRead,
   ePBC = -1;
   bPeriodicMols = FALSE;
   if (file_version >= 26) {
-    do_test(tpx.bIr,ir);
-    do_section(eitemIR,bRead);
+    do_test(fio,tpx.bIr,ir);
+    do_section(fio,eitemIR,bRead);
     if (tpx.bIr) {
       if (file_version >= 53) {
        /* Removed the pbc info from do_inputrec, since we always want it */
@@ -2078,11 +2091,11 @@ static int do_tpx(int fp,bool bRead,
          ePBC          = ir->ePBC;
          bPeriodicMols = ir->bPeriodicMols;
        }
-       do_int(ePBC);
-       do_int(bPeriodicMols);
+       gmx_fio_do_int(fio,ePBC);
+       gmx_fio_do_int(fio,bPeriodicMols);
       }
       if (file_generation <= tpx_generation && ir) {
-       do_inputrec(ir,bRead,file_version,mtop ? &mtop->ffparams.fudgeQQ : NULL);
+       do_inputrec(fio, ir,bRead,file_version,mtop ? &mtop->ffparams.fudgeQQ : NULL);
        if (bRead && debug) 
          pr_inputrec(debug,0,"inputrec",ir,FALSE);
        if (file_version < 51)
@@ -2162,59 +2175,59 @@ static int do_tpx(int fp,bool bRead,
  *
  ************************************************************/
 
-int open_tpx(const char *fn,const char *mode)
+t_fileio *open_tpx(const char *fn,const char *mode)
 {
   return gmx_fio_open(fn,mode);
 }    
  
-void close_tpx(int fp)
+void close_tpx(t_fileio *fio)
 {
-  gmx_fio_close(fp);
+  gmx_fio_close(fio);
 }
 
 void read_tpxheader(const char *fn, t_tpxheader *tpx, bool TopOnlyOK,
                     int *file_version, int *file_generation)
 {
-  int fp;
+  t_fileio *fio;
 
-  fp = open_tpx(fn,"r");
-  do_tpxheader(fp,TRUE,tpx,TopOnlyOK,file_version,file_generation);
-  close_tpx(fp);
+  fio = open_tpx(fn,"r");
+  do_tpxheader(fio,TRUE,tpx,TopOnlyOK,file_version,file_generation);
+  close_tpx(fio);
 }
 
 void write_tpx_state(const char *fn,
                     t_inputrec *ir,t_state *state,gmx_mtop_t *mtop)
 {
-  int fp;
+  t_fileio *fio;
 
-  fp = open_tpx(fn,"w");
-  do_tpx(fp,FALSE,ir,state,NULL,mtop,FALSE);
-  close_tpx(fp);
+  fio = open_tpx(fn,"w");
+  do_tpx(fio,FALSE,ir,state,NULL,mtop,FALSE);
+  close_tpx(fio);
 }
 
 void read_tpx_state(const char *fn,
                    t_inputrec *ir,t_state *state,rvec *f,gmx_mtop_t *mtop)
 {
-  int fp;
+  t_fileio *fio;
        
-  fp = open_tpx(fn,"r");
-  do_tpx(fp,TRUE,ir,state,f,mtop,FALSE);
-  close_tpx(fp);
+  fio = open_tpx(fn,"r");
+  do_tpx(fio,TRUE,ir,state,f,mtop,FALSE);
+  close_tpx(fio);
 }
 
 int read_tpx(const char *fn,
             t_inputrec *ir, matrix box,int *natoms,
             rvec *x,rvec *v,rvec *f,gmx_mtop_t *mtop)
 {
-  int fp;
+  t_fileio *fio;
   t_state state;
   int ePBC;
 
   state.x = x;
   state.v = v;
-  fp = open_tpx(fn,"r");
-  ePBC = do_tpx(fp,TRUE,ir,&state,f,mtop,TRUE);
-  close_tpx(fp);
+  fio = open_tpx(fn,"r");
+  ePBC = do_tpx(fio,TRUE,ir,&state,f,mtop,TRUE);
+  close_tpx(fio);
   *natoms = state.natoms;
   if (box) 
     copy_mat(state.box,box);
index 950b4e16eee1386128b00f6e5ba70704e619824e..d7bfc6e9f7b8dc9a1d30d9152f566197b33add88 100644 (file)
@@ -202,7 +202,7 @@ struct gmx_ana_traj_t
     /** The current frame, or \p NULL if no frame loaded yet. */
     t_trxframe               *fr;
     /** Used to store the status variable from read_first_frame(). */
-    int                       status;
+    t_trxstatus              *status;
     /** The number of frames read. */
     int                       nframes;
 
@@ -306,7 +306,7 @@ gmx_ana_traj_create(gmx_ana_traj_t **data, unsigned long flags)
         *data = NULL;
         return rc;
     }
-    d->status          = -1;
+    d->status          = NULL;
     d->oenv            = NULL;
 
     *data              = d;
index 933cc436a76fa132e906839969e48dccdf97ea1c..762e8534ef0dc15e16f65f67438f22f8d2f4b577 100644 (file)
@@ -70,51 +70,52 @@ static int nFloatSize(t_trnheader *sh)
   return nflsize;
 }
 
-static bool do_trnheader(int fp,bool bRead,t_trnheader *sh, bool *bOK)
+static bool do_trnheader(t_fileio *fio,bool bRead,t_trnheader *sh, bool *bOK)
 {
-  const int magic=GROMACS_MAGIC;
-  const char *version = "GMX_trn_file";
+  int magic=GROMACS_MAGIC;
+  char *version = "GMX_trn_file";
   static bool bFirst=TRUE;
   char buf[256];
   
   *bOK=TRUE;
 
-  gmx_fio_select(fp);
-  if (!do_int(magic))
+  gmx_fio_checktype(fio);
+
+  if (!gmx_fio_do_int(fio,magic) || magic!=GROMACS_MAGIC)
     return FALSE;
   
   if (bRead) {
-    *bOK = *bOK && do_string(buf);
+    *bOK = *bOK && gmx_fio_do_string(fio,buf);
     if (bFirst)
       fprintf(stderr,"trn version: %s ",buf);
   }
   else
-    *bOK = *bOK && do_string(version);
-  *bOK = *bOK && do_int(sh->ir_size);
-  *bOK = *bOK && do_int(sh->e_size);
-  *bOK = *bOK && do_int(sh->box_size);
-  *bOK = *bOK && do_int(sh->vir_size);
-  *bOK = *bOK && do_int(sh->pres_size);
-  *bOK = *bOK && do_int(sh->top_size); 
-  *bOK = *bOK && do_int(sh->sym_size); 
-  *bOK = *bOK && do_int(sh->x_size); 
-  *bOK = *bOK && do_int(sh->v_size); 
-  *bOK = *bOK && do_int(sh->f_size); 
-  *bOK = *bOK && do_int(sh->natoms);
+    *bOK = *bOK && gmx_fio_do_string(fio,version);
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->ir_size);
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->e_size);
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->box_size);
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->vir_size);
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->pres_size);
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->top_size); 
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->sym_size); 
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->x_size); 
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->v_size); 
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->f_size); 
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->natoms);
 
   if (!*bOK) return *bOK; 
   sh->bDouble = (nFloatSize(sh) == sizeof(double));
-  gmx_fio_setprecision(fp,sh->bDouble);
+  gmx_fio_setprecision(fio,sh->bDouble);
 
   if (bRead && bFirst) {
     fprintf(stderr,"(%s precision)\n",sh->bDouble ? "double" : "single");
     bFirst = FALSE;
   }
   
-  *bOK = *bOK && do_int(sh->step); 
-  *bOK = *bOK && do_int(sh->nre); 
-  *bOK = *bOK && do_real(sh->t); 
-  *bOK = *bOK && do_real(sh->lambda); 
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->step); 
+  *bOK = *bOK && gmx_fio_do_int(fio,sh->nre); 
+  *bOK = *bOK && gmx_fio_do_real(fio,sh->t); 
+  *bOK = *bOK && gmx_fio_do_real(fio,sh->lambda); 
   
   return *bOK;
 }
@@ -143,24 +144,24 @@ void pr_trnheader(FILE *fp,int indent,char *title,t_trnheader *sh)
   }
 }
 
-static bool do_htrn(int fp,bool bRead,t_trnheader *sh,
+static bool do_htrn(t_fileio *fio,bool bRead,t_trnheader *sh,
                    rvec *box,rvec *x,rvec *v,rvec *f)
 {
   matrix pv;
   bool bOK;
 
   bOK = TRUE;
-  if (sh->box_size != 0) bOK = bOK && ndo_rvec(box,DIM);
-  if (sh->vir_size != 0) bOK = bOK && ndo_rvec(pv,DIM);
-  if (sh->pres_size!= 0) bOK = bOK && ndo_rvec(pv,DIM);
-  if (sh->x_size   != 0) bOK = bOK && ndo_rvec(x,sh->natoms);
-  if (sh->v_size   != 0) bOK = bOK && ndo_rvec(v,sh->natoms);
-  if (sh->f_size   != 0) bOK = bOK && ndo_rvec(f,sh->natoms);
+  if (sh->box_size != 0) bOK = bOK && gmx_fio_ndo_rvec(fio,box,DIM);
+  if (sh->vir_size != 0) bOK = bOK && gmx_fio_ndo_rvec(fio,pv,DIM);
+  if (sh->pres_size!= 0) bOK = bOK && gmx_fio_ndo_rvec(fio,pv,DIM);
+  if (sh->x_size   != 0) bOK = bOK && gmx_fio_ndo_rvec(fio,x,sh->natoms);
+  if (sh->v_size   != 0) bOK = bOK && gmx_fio_ndo_rvec(fio,v,sh->natoms);
+  if (sh->f_size   != 0) bOK = bOK && gmx_fio_ndo_rvec(fio,f,sh->natoms);
 
   return bOK;
 }
 
-static bool do_trn(int fp,bool bRead,int *step,real *t,real *lambda,
+static bool do_trn(t_fileio *fio,bool bRead,int *step,real *t,real *lambda,
                   rvec *box,int *natoms,rvec *x,rvec *v,rvec *f)
 {
   t_trnheader *sh;
@@ -178,7 +179,7 @@ static bool do_trn(int fp,bool bRead,int *step,real *t,real *lambda,
     sh->t      = *t;
     sh->lambda = *lambda;
   }
-  if (!do_trnheader(fp,bRead,sh,&bOK))
+  if (!do_trnheader(fio,bRead,sh,&bOK))
     return FALSE;
   if (bRead) {
     *natoms = sh->natoms;
@@ -194,7 +195,7 @@ static bool do_trn(int fp,bool bRead,int *step,real *t,real *lambda,
     if (sh->sym_size)
       gmx_file("symbol table in trn file");
   }
-  bOK = do_htrn(fp,bRead,sh,box,x,v,f);
+  bOK = do_htrn(fio,bRead,sh,box,x,v,f);
 
   sfree(sh);
   
@@ -209,67 +210,68 @@ static bool do_trn(int fp,bool bRead,int *step,real *t,real *lambda,
  
 void read_trnheader(const char *fn,t_trnheader *trn)
 {
-  int  fp;
+  t_fileio *fio;
   bool bOK;
   
-  fp = open_trn(fn,"r");
-  if (!do_trnheader(fp,TRUE,trn,&bOK))
+  fio = open_trn(fn,"r");
+  if (!do_trnheader(fio,TRUE,trn,&bOK))
     gmx_fatal(FARGS,"Empty file %s",fn);
-  close_trn(fp);
+  close_trn(fio);
 }
 
-bool fread_trnheader(int fp,t_trnheader *trn, bool *bOK)
+bool fread_trnheader(t_fileio *fio,t_trnheader *trn, bool *bOK)
 {
-  return do_trnheader(fp,TRUE,trn,bOK);
+  return do_trnheader(fio,TRUE,trn,bOK);
 }
 
 void write_trn(const char *fn,int step,real t,real lambda,
               rvec *box,int natoms,rvec *x,rvec *v,rvec *f)
 {
-  int fp;
+  t_fileio *fio;
   
-  fp = open_trn(fn,"w");
-  do_trn(fp,FALSE,&step,&t,&lambda,box,&natoms,x,v,f);
-  close_trn(fp);
+  fio = open_trn(fn,"w");
+  do_trn(fio,FALSE,&step,&t,&lambda,box,&natoms,x,v,f);
+  close_trn(fio);
 }
 
 void read_trn(const char *fn,int *step,real *t,real *lambda,
              rvec *box,int *natoms,rvec *x,rvec *v,rvec *f)
 {
-  int fp;
+  t_fileio *fio;
   
-  fp = open_trn(fn,"r");
-  (void) do_trn(fp,TRUE,step,t,lambda,box,natoms,x,v,f);
-  close_trn(fp);
+  fio = open_trn(fn,"r");
+  (void) do_trn(fio,TRUE,step,t,lambda,box,natoms,x,v,f);
+  close_trn(fio);
 }
 
-void fwrite_trn(int fp,int step,real t,real lambda,
+void fwrite_trn(t_fileio *fio,int step,real t,real lambda,
                rvec *box,int natoms,rvec *x,rvec *v,rvec *f)
 {
-  if( do_trn(fp,FALSE,&step,&t,&lambda,box,&natoms,x,v,f) == FALSE)
+  if( do_trn(fio,FALSE,&step,&t,&lambda,box,&natoms,x,v,f) == FALSE)
   {
-         gmx_file("Cannot write trajectory frame; maybe you are out of quota?");
+      gmx_file("Cannot write trajectory frame; maybe you are out of quota?");
   }
 }
 
 
-bool fread_trn(int fp,int *step,real *t,real *lambda,
+bool fread_trn(t_fileio *fio,int *step,real *t,real *lambda,
               rvec *box,int *natoms,rvec *x,rvec *v,rvec *f)
 {
-  return do_trn(fp,TRUE,step,t,lambda,box,natoms,x,v,f);
+  return do_trn(fio,TRUE,step,t,lambda,box,natoms,x,v,f);
 }
 
-bool fread_htrn(int fp,t_trnheader *trn,rvec *box,rvec *x,rvec *v,rvec *f)
+bool fread_htrn(t_fileio *fio,t_trnheader *trn,rvec *box,rvec *x,rvec *v,
+                rvec *f)
 {
-  return do_htrn(fp,TRUE,trn,box,x,v,f);
+  return do_htrn(fio,TRUE,trn,box,x,v,f);
 }
 
-int open_trn(const char *fn,const char *mode)
+t_fileio *open_trn(const char *fn,const char *mode)
 {
   return gmx_fio_open(fn,mode);
 }
 
-void close_trn(int fp)
+void close_trn(t_fileio *fio)
 {
-  gmx_fio_close(fp);
+  gmx_fio_close(fio);
 }
index d62f4354897938817ffa526b9b3e3b0cf5a5a060..903e49def484a8bb5df4952ae00ef74effd260ef 100644 (file)
 #include <math.h>
 
 /* defines for frame counter output */
+#if 0
 static int __frame=NOTSET;
+#endif
 #define SKIP1   10
 #define SKIP2  100
 #define SKIP3 1000
+#if 0
 #define INITCOUNT __frame=-1
+#endif
 
-
+#if 0
 /* frames for read_first/next_x */
 static t_trxframe *xframe=NULL;
 static int nxframe=0;
+#endif
+
+struct t_trxstatus
+{
+    int __frame;
+    t_trxframe *xframe;
+    int nxframe;
+    t_fileio *fio;
+};
+
+static void initcount(t_trxstatus *status)
+{
+    status->__frame=-1;
+}
+
+static void status_init(t_trxstatus *status)
+{
+    status->nxframe=0;
+    status->xframe=NULL;
+    status->fio=NULL;
+    status->__frame=-1;
+}
 
 
-int nframes_read(void)
+int nframes_read(t_trxstatus *status)
 {
-  return __frame;
+    return status->__frame;
 }
 
-static void printcount_(const output_env_t oenv,const char *l,real t)
+static void printcount_(t_trxstatus *status, const output_env_t oenv,
+                        const char *l,real t)
 {
-  if ((__frame < 2*SKIP1 || __frame % SKIP1 == 0) &&
-      (__frame < 2*SKIP2 || __frame % SKIP2 == 0) &&
-      (__frame < 2*SKIP3 || __frame % SKIP3 == 0))
-    fprintf(stderr,"\r%-14s %6d time %8.3f   ",l,__frame,output_env_conv_time(oenv,t));
+  if ((status->__frame < 2*SKIP1 || status->__frame % SKIP1 == 0) &&
+      (status->__frame < 2*SKIP2 || status->__frame % SKIP2 == 0) &&
+      (status->__frame < 2*SKIP3 || status->__frame % SKIP3 == 0))
+    fprintf(stderr,"\r%-14s %6d time %8.3f   ",l,status->__frame,
+            output_env_conv_time(oenv,t));
 }
 
-static void printcount(const output_env_t oenv,real t,bool bSkip)
+static void printcount(t_trxstatus *status, const output_env_t oenv,real t,
+                       bool bSkip)
 {
-  __frame++;
-  printcount_(oenv,bSkip ? "Skipping frame" : "Reading frame",t);
+  status->__frame++;
+  printcount_(status, oenv,bSkip ? "Skipping frame" : "Reading frame",t);
 }
 
-static void printlast(const output_env_t oenv,real t)
+static void printlast(t_trxstatus *status, const output_env_t oenv,real t)
 {
-  printcount_(oenv,"Last frame",t);
+  printcount_(status, oenv,"Last frame",t);
   fprintf(stderr,"\n");
 }
 
-static void printincomp(t_trxframe *fr)
+static void printincomp(t_trxstatus *status, t_trxframe *fr)
 {
   if (fr->not_ok & HEADER_NOT_OK)
     fprintf(stderr,"WARNING: Incomplete header: nr %d time %g\n",
-           __frame+1,fr->time);
+           status->__frame+1,fr->time);
   else if (fr->not_ok)
     fprintf(stderr,"WARNING: Incomplete frame: nr %d time %g\n",
-           __frame+1,fr->time);
+           status->__frame+1,fr->time);
 }
 
 int prec2ndec(real prec)
@@ -112,6 +141,13 @@ int prec2ndec(real prec)
   return (int)(log(prec)/log(10.0)+0.5);
 }
 
+
+t_fileio *trx_get_fileio(t_trxstatus *status)
+{
+    return status->fio;
+}
+
+
 /* Globals for gromos-87 input */
 typedef enum { effXYZ, effXYZBox, effG87, effG87Box, effNR } eFileFormat;
 static eFileFormat eFF;
@@ -160,8 +196,8 @@ void set_trxframe_ePBC(t_trxframe *fr,int ePBC)
   fr->ePBC = ePBC;
 }
 
-int write_trxframe_indexed(int fnum,t_trxframe *fr,int nind,atom_id *ind,
-                          gmx_conect gc)
+int write_trxframe_indexed(t_trxstatus *status,t_trxframe *fr,int nind,
+                           atom_id *ind, gmx_conect gc)
 {
   char title[STRLEN];
   rvec *xout=NULL,*vout=NULL,*fout=NULL;
@@ -173,18 +209,18 @@ int write_trxframe_indexed(int fnum,t_trxframe *fr,int nind,atom_id *ind,
   else
     prec = 1000.0;
   
-  switch (gmx_fio_getftp(fnum)) {
+  switch (gmx_fio_getftp(status->fio)) {
   case efTRJ:
   case efTRR:
     break;
   default:
     if (!fr->bX)
       gmx_fatal(FARGS,"Need coordinates to write a %s trajectory",
-                 ftp2ext(gmx_fio_getftp(fnum)));
+                 ftp2ext(gmx_fio_getftp(status->fio)));
     break;
   }
 
-  switch (gmx_fio_getftp(fnum)) {
+  switch (gmx_fio_getftp(status->fio)) {
   case efTRJ:
   case efTRR:
     if (fr->bV) {
@@ -209,13 +245,13 @@ int write_trxframe_indexed(int fnum,t_trxframe *fr,int nind,atom_id *ind,
     break;
   }
 
-  switch (gmx_fio_getftp(fnum)) {
+  switch (gmx_fio_getftp(status->fio)) {
   case efXTC: 
-    write_xtc(fnum,nind,fr->step,fr->time,fr->box,xout,prec);
+    write_xtc(status->fio,nind,fr->step,fr->time,fr->box,xout,prec);
     break;
   case efTRJ:
   case efTRR:  
-    fwrite_trn(fnum,nframes_read(),
+    fwrite_trn(status->fio,nframes_read(status),
               fr->time,fr->step,fr->box,nind,xout,vout,fout);
     break;
   case efGRO:
@@ -224,29 +260,29 @@ int write_trxframe_indexed(int fnum,t_trxframe *fr,int nind,atom_id *ind,
   case efENT:
     if (!fr->bAtoms)
       gmx_fatal(FARGS,"Can not write a %s file without atom names",
-                 ftp2ext(gmx_fio_getftp(fnum)));
+                 ftp2ext(gmx_fio_getftp(status->fio)));
     sprintf(title,"frame t= %.3f",fr->time);
-    if (gmx_fio_getftp(fnum) == efGRO)
-      write_hconf_indexed_p(gmx_fio_getfp(fnum),title,fr->atoms,nind,ind,
+    if (gmx_fio_getftp(status->fio) == efGRO)
+      write_hconf_indexed_p(gmx_fio_getfp(status->fio),title,fr->atoms,nind,ind,
                            prec2ndec(prec),
                            fr->x,fr->bV ? fr->v : NULL,fr->box);
     else
-      write_pdbfile_indexed(gmx_fio_getfp(fnum),title,fr->atoms,
+      write_pdbfile_indexed(gmx_fio_getfp(status->fio),title,fr->atoms,
                            fr->x,-1,fr->box,0,fr->step,nind,ind,gc);
     break;
   case efG87:
-    write_gms(gmx_fio_getfp(fnum),nind,xout,fr->box);
+    write_gms(gmx_fio_getfp(status->fio),nind,xout,fr->box);
     break;
   case efG96:
-    write_g96_conf(gmx_fio_getfp(fnum),fr,nind,ind); 
+    write_g96_conf(gmx_fio_getfp(status->fio),fr,nind,ind); 
     break;
   default:
     gmx_fatal(FARGS,"Sorry, write_trxframe_indexed can not write %s",
-               ftp2ext(gmx_fio_getftp(fnum)));
+               ftp2ext(gmx_fio_getftp(status->fio)));
     break;
   }
 
-  switch (gmx_fio_getftp(fnum)) {
+  switch (gmx_fio_getftp(status->fio)) {
   case efTRN:
   case efTRJ:
   case efTRR:
@@ -263,7 +299,7 @@ int write_trxframe_indexed(int fnum,t_trxframe *fr,int nind,atom_id *ind,
   return 0;
 }
 
-int write_trxframe(int fnum,t_trxframe *fr,gmx_conect gc)
+int write_trxframe(t_trxstatus *status,t_trxframe *fr,gmx_conect gc)
 {
   char title[STRLEN];
   real prec;
@@ -273,24 +309,24 @@ int write_trxframe(int fnum,t_trxframe *fr,gmx_conect gc)
   else
     prec = 1000.0;
 
-  switch (gmx_fio_getftp(fnum)) {
+  switch (gmx_fio_getftp(status->fio)) {
   case efTRJ:
   case efTRR:
     break;
   default:
     if (!fr->bX)
       gmx_fatal(FARGS,"Need coordinates to write a %s trajectory",
-                 ftp2ext(gmx_fio_getftp(fnum)));
+                 ftp2ext(gmx_fio_getftp(status->fio)));
     break;
   }
 
-  switch (gmx_fio_getftp(fnum)) {
+  switch (gmx_fio_getftp(status->fio)) {
   case efXTC:
-    write_xtc(fnum,fr->natoms,fr->step,fr->time,fr->box,fr->x,prec);
+    write_xtc(status->fio,fr->natoms,fr->step,fr->time,fr->box,fr->x,prec);
     break;
   case efTRJ:
   case efTRR:  
-    fwrite_trn(fnum,fr->step,fr->time,fr->lambda,fr->box,fr->natoms,
+    fwrite_trn(status->fio,fr->step,fr->time,fr->lambda,fr->box,fr->natoms,
               fr->bX ? fr->x:NULL,fr->bV ? fr->v:NULL ,fr->bF ? fr->f:NULL);
     break;
   case efGRO:
@@ -299,32 +335,32 @@ int write_trxframe(int fnum,t_trxframe *fr,gmx_conect gc)
   case efENT:
     if (!fr->bAtoms)
       gmx_fatal(FARGS,"Can not write a %s file without atom names",
-                 ftp2ext(gmx_fio_getftp(fnum)));
+                 ftp2ext(gmx_fio_getftp(status->fio)));
     sprintf(title,"frame t= %.3f",fr->time);
-    if (gmx_fio_getftp(fnum) == efGRO)
-      write_hconf_p(gmx_fio_getfp(fnum),title,fr->atoms,
+    if (gmx_fio_getftp(status->fio) == efGRO)
+      write_hconf_p(gmx_fio_getfp(status->fio),title,fr->atoms,
                    prec2ndec(prec),fr->x,fr->bV ? fr->v : NULL,fr->box);
     else
-      write_pdbfile(gmx_fio_getfp(fnum),title,
+      write_pdbfile(gmx_fio_getfp(status->fio),title,
                    fr->atoms,fr->x,fr->bPBC ? fr->ePBC : -1,fr->box,
                    0,fr->step,gc);
     break;
   case efG87:
-    write_gms(gmx_fio_getfp(fnum),fr->natoms,fr->x,fr->box);
+    write_gms(gmx_fio_getfp(status->fio),fr->natoms,fr->x,fr->box);
     break;
   case efG96:
-    write_g96_conf(gmx_fio_getfp(fnum),fr,-1,NULL); 
+    write_g96_conf(gmx_fio_getfp(status->fio),fr,-1,NULL); 
     break;
   default:
     gmx_fatal(FARGS,"Sorry, write_trxframe can not write %s",
-               ftp2ext(gmx_fio_getftp(fnum)));
+               ftp2ext(gmx_fio_getftp(status->fio)));
     break;
   }
 
   return 0;
 }
 
-int write_trx(int fnum,int nind,atom_id *ind,t_atoms *atoms,
+int write_trx(t_trxstatus *status,int nind,atom_id *ind,t_atoms *atoms,
              int step,real time,matrix box,rvec x[],rvec *v,
              gmx_conect gc)
 {
@@ -344,30 +380,35 @@ int write_trx(int fnum,int nind,atom_id *ind,t_atoms *atoms,
   fr.bBox = TRUE;
   copy_mat(box,fr.box);
   
-  return write_trxframe_indexed(fnum,&fr,nind,ind,gc);
+  return write_trxframe_indexed(status,&fr,nind,ind,gc);
 }
 
-void close_trx(int status)
+void close_trx(t_trxstatus *status)
 {
-  gmx_fio_close(status);
+  gmx_fio_close(status->fio);
 }
 
-int open_trx(const char *outfile,const char *filemode)
+t_trxstatus *open_trx(const char *outfile,const char *filemode)
 {
-  if (filemode[0]!='w' && filemode[0]!='a' && filemode[1]!='+')
-    gmx_fatal(FARGS,"Sorry, write_trx can only write");
+    t_trxstatus *stat;
+    if (filemode[0]!='w' && filemode[0]!='a' && filemode[1]!='+')
+        gmx_fatal(FARGS,"Sorry, write_trx can only write");
+
+    snew(stat,1);
+    status_init(stat);
 
-  return gmx_fio_open(outfile,filemode);
+    stat->fio=gmx_fio_open(outfile,filemode);
+    return stat;
 }
 
-static bool gmx_next_frame(int status,t_trxframe *fr)
+static bool gmx_next_frame(t_trxstatus *status,t_trxframe *fr)
 {
   t_trnheader sh;
   bool bOK,bRet;
   
   bRet = FALSE;
 
-  if (fread_trnheader(status,&sh,&bOK)) {
+  if (fread_trnheader(status->fio,&sh,&bOK)) {
     fr->bDouble=sh.bDouble;
     fr->natoms=sh.natoms;
     fr->bStep=TRUE;
@@ -392,7 +433,7 @@ static bool gmx_next_frame(int status,t_trxframe *fr)
        snew(fr->f,sh.natoms);
       fr->bF = sh.f_size>0;
     }
-    if (fread_htrn(status,&sh,fr->box,fr->x,fr->v,fr->f))
+    if (fread_htrn(status->fio,&sh,fr->box,fr->x,fr->v,fr->f))
       bRet = TRUE;
     else
       fr->not_ok = DATA_NOT_OK;
@@ -403,7 +444,7 @@ static bool gmx_next_frame(int status,t_trxframe *fr)
   return bRet;    
 }
 
-static void choose_ff(FILE *status)
+static void choose_ff(FILE *fp)
 {
   int i,m,c;
   int rc;
@@ -437,7 +478,7 @@ static void choose_ff(FILE *status)
   switch (eFF) {
   case effXYZ:
   case effXYZBox:
-    if( 5 != fscanf(status,"%d%lf%lf%lf%lf",&NATOMS,&BOX[XX],&BOX[YY],&BOX[ZZ],&DT)) 
+    if( 5 != fscanf(fp,"%d%lf%lf%lf%lf",&NATOMS,&BOX[XX],&BOX[YY],&BOX[ZZ],&DT)) 
     {
       gmx_fatal(FARGS,"Error reading natoms/box in file");
     }
@@ -468,7 +509,7 @@ static void choose_ff(FILE *status)
       }
     }
     do {
-      c=fgetc(status);
+      c=fgetc(fp);
       printf("%c",c);
     } while (c != '\n');
     printf("\n");
@@ -479,14 +520,14 @@ static void choose_ff(FILE *status)
   }
 }
 
-static bool do_read_xyz(FILE *status,int natoms,rvec x[],matrix box)
+static bool do_read_xyz(FILE *fp,int natoms,rvec x[],matrix box)
 {
   int    i,m;
   double x0;
 
   for(i=0; (i<natoms); i++) {
     for(m=0; (m<DIM); m++) {
-      if (fscanf(status,"%lf",&x0) != 1) {
+      if (fscanf(fp,"%lf",&x0) != 1) {
        if (i || m)
          fprintf(stderr,"error reading statusfile: x[%d][%d]\n",i,m);
        /* else eof! */
@@ -497,7 +538,7 @@ static bool do_read_xyz(FILE *status,int natoms,rvec x[],matrix box)
   }
   if (bReadBox) {
     for(m=0; (m<DIM); m++) {
-      if (fscanf(status,"%lf",&x0) != 1) 
+      if (fscanf(fp,"%lf",&x0) != 1) 
        return FALSE;
       box[m][m]=x0;
     }
@@ -505,7 +546,7 @@ static bool do_read_xyz(FILE *status,int natoms,rvec x[],matrix box)
   return TRUE;
 }
 
-static bool xyz_next_x(FILE *status, const output_env_t oenv,
+static bool xyz_next_x(t_trxstatus *status, FILE *fp, const output_env_t oenv,
                        real *t, int natoms, rvec x[], matrix box)
      /* Reads until a new x can be found (return TRUE)
       * or eof (return FALSE)
@@ -515,52 +556,52 @@ static bool xyz_next_x(FILE *status, const output_env_t oenv,
   
   pt=*t;
   while (!bTimeSet(TBEGIN) || (*t < rTimeValue(TBEGIN))) {
-    if (!do_read_xyz(status,natoms,x,box))
+    if (!do_read_xyz(fp,natoms,x,box))
       return FALSE;
-    printcount(oenv,*t,FALSE);
+    printcount(status,oenv,*t,FALSE);
     *t+=DT;
     pt=*t;
   }
   if (!bTimeSet(TEND) || (*t <= rTimeValue(TEND))) {
-    if (!do_read_xyz(status,natoms,x,box)) {
-      printlast(oenv,*t);
+    if (!do_read_xyz(fp,natoms,x,box)) {
+      printlast(status, oenv,*t);
       return FALSE;
     }
-    printcount(oenv,*t,FALSE);
+    printcount(status,oenv,*t,FALSE);
     pt=*t;
     *t+=DT;
     return TRUE;
   }
-  printlast(oenv,pt);
+  printlast(status,oenv,pt);
   return FALSE;
 }
 
-static int xyz_first_x(FILE *status, const output_env_t oenv, 
+static int xyz_first_x(t_trxstatus *status, FILE *fp, const output_env_t oenv, 
                        real *t, rvec **x, matrix box)
-/* Reads status, mallocs x, and returns x and box
+/* Reads fp, mallocs x, and returns x and box
  * Returns natoms when successful, FALSE otherwise
  */
 {
   int    m;
   
-  INITCOUNT;
+  initcount(status);
 
   clear_mat(box);
-  choose_ff(status);
+  choose_ff(fp);
 
   for(m=0; (m<DIM); m++)
     box[m][m]=BOX[m];
 
   snew(*x,NATOMS);
   *t=DT;
-  if (!xyz_next_x(status,oenv,t,NATOMS,*x,box)) 
+  if (!xyz_next_x(status, fp,oenv,t,NATOMS,*x,box)) 
     return 0;
   *t=0.0;
   
   return NATOMS;
 }
 
-static bool pdb_next_x(FILE *status,t_trxframe *fr)
+static bool pdb_next_x(t_trxstatus *status, FILE *fp,t_trxframe *fr)
 {
   t_atoms   atoms;
   matrix    boxpdb;
@@ -573,9 +614,9 @@ static bool pdb_next_x(FILE *status,t_trxframe *fr)
   atoms.pdbinfo=NULL;
   /* the other pointers in atoms should not be accessed if these are NULL */
   model_nr=NOTSET;
-  na=read_pdbfile(status,title,&model_nr,&atoms,fr->x,&ePBC,boxpdb,TRUE,NULL);
+  na=read_pdbfile(fp,title,&model_nr,&atoms,fr->x,&ePBC,boxpdb,TRUE,NULL);
   set_trxframe_ePBC(fr,ePBC);
-  if (nframes_read()==0)
+  if (nframes_read(status)==0)
     fprintf(stderr," '%s', %d atoms\n",title, fr->natoms);
   fr->bPrec = TRUE;
   fr->prec = 10000;
@@ -601,39 +642,40 @@ static bool pdb_next_x(FILE *status,t_trxframe *fr)
     if (fr->bStep)
       fr->time=(real)fr->step;
     else
-      fr->time=(real)nframes_read();
+      fr->time=(real)nframes_read(status);
   }
   if (na == 0) {
     return FALSE;
   } else { 
     if (na != fr->natoms)
       gmx_fatal(FARGS,"Number of atoms in pdb frame %d is %d instead of %d",
-                 nframes_read(),na,fr->natoms);
+                 nframes_read(status),na,fr->natoms);
     return TRUE;
   }
 }
 
-static int pdb_first_x(FILE *status, t_trxframe *fr)
+static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
 {
-  INITCOUNT;
+  initcount(status);
   
   fprintf(stderr,"Reading frames from pdb file");
-  frewind(status);
-  get_pdb_coordnum(status, &fr->natoms);
+  frewind(fp);
+  get_pdb_coordnum(fp, &fr->natoms);
   if (fr->natoms==0)
     gmx_fatal(FARGS,"\nNo coordinates in pdb file\n");
-  frewind(status);
+  frewind(fp);
   snew(fr->x,fr->natoms);
-  pdb_next_x(status, fr);
+  pdb_next_x(status, fp, fr);
 
   return fr->natoms;
 }
 
-bool read_next_frame(const output_env_t oenv,int status,t_trxframe *fr)
+bool read_next_frame(const output_env_t oenv,t_trxstatus *status,t_trxframe *fr)
 {
   real pt;
   int  ct;
   bool bOK,bRet,bMissingData=FALSE,bSkip=FALSE;
+  int dummy=0;
 
   bRet = FALSE;
   pt=fr->time; 
@@ -643,7 +685,7 @@ bool read_next_frame(const output_env_t oenv,int status,t_trxframe *fr)
     fr->tppf = fr->tpf;
     fr->tpf  = fr->time;
     
-    switch (gmx_fio_getftp(status)) {
+    switch (gmx_fio_getftp(status->fio)) {
     case efTRJ:
     case efTRR:
         bRet = gmx_next_frame(status,fr);
@@ -652,12 +694,12 @@ bool read_next_frame(const output_env_t oenv,int status,t_trxframe *fr)
       /* Checkpoint files can not contain mulitple frames */
       break;
     case efG96:
-      read_g96_conf(gmx_fio_getfp(status),NULL,fr);
+      read_g96_conf(gmx_fio_getfp(status->fio),NULL,fr);
       bRet = (fr->natoms > 0);
       break;
     case efG87:
-      bRet = xyz_next_x(gmx_fio_getfp(status),oenv,&fr->time,fr->natoms,
-                        fr->x,fr->box);
+      bRet = xyz_next_x(status, gmx_fio_getfp(status->fio),oenv,&fr->time,
+                        fr->natoms, fr->x,fr->box);
       fr->bTime = bRet;
       fr->bX    = bRet;
       fr->bBox  = bRet;
@@ -671,12 +713,12 @@ bool read_next_frame(const output_env_t oenv,int status,t_trxframe *fr)
        * accuracy of the control over -b and -e options.
        */
         if (bTimeSet(TBEGIN) && (fr->time < rTimeValue(TBEGIN))) {
-            if (xtc_seek_time(rTimeValue(TBEGIN),status,fr->natoms)) {
+            if (xtc_seek_time(status->fio, rTimeValue(TBEGIN),fr->natoms)) {
                 gmx_fatal(FARGS,"Specified frame doesn't exist or file not seekable");
             }
-            INITCOUNT;
+            initcount(status);
         }
-      bRet = read_next_xtc(status,fr->natoms,&fr->step,&fr->time,fr->box,
+      bRet = read_next_xtc(status->fio,fr->natoms,&fr->step,&fr->time,fr->box,
                           fr->x,&fr->prec,&bOK);
       fr->bPrec = (bRet && fr->prec > 0);
       fr->bStep = bRet;
@@ -690,17 +732,18 @@ bool read_next_frame(const output_env_t oenv,int status,t_trxframe *fr)
       }
       break;
     case efPDB:
-      bRet = pdb_next_x(gmx_fio_getfp(status),fr);
+      bRet = pdb_next_x(status, gmx_fio_getfp(status->fio),fr);
       break;
     case efGRO:
-      bRet = gro_next_x_or_v(gmx_fio_getfp(status),fr);
+      bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio),fr);
       break;
     default:
 #ifdef GMX_DLOPEN
-      bRet = read_next_vmd_frame(status,fr);
+      bRet = read_next_vmd_frame(dummy,fr);
 #else
-      gmx_fatal(FARGS,"DEATH HORROR in read_next_frame ftp=%s,status=%d",
-                ftp2ext(gmx_fio_getftp(status)),status);
+      gmx_fatal(FARGS,"DEATH HORROR in read_next_frame ftp=%s,status=%s",
+                ftp2ext(gmx_fio_getftp(status->fio)),
+                gmx_fio_getname(status->fio));
 #endif
     }
     
@@ -712,11 +755,11 @@ bool read_next_frame(const output_env_t oenv,int status,t_trxframe *fr)
       if (!bMissingData) {
        ct=check_times2(fr->time,fr->t0,fr->tpf,fr->tppf,fr->bDouble);
        if (ct == 0 || (fr->flags & TRX_DONT_SKIP && ct<0)) {
-         printcount(oenv,fr->time,FALSE);
+         printcount(status, oenv,fr->time,FALSE);
        } else if (ct > 0)
          bRet = FALSE;
        else {
-         printcount(oenv,fr->time,TRUE);
+         printcount(status, oenv,fr->time,TRUE);
          bSkip = TRUE;
        }
       }
@@ -725,59 +768,66 @@ bool read_next_frame(const output_env_t oenv,int status,t_trxframe *fr)
   } while (bRet && (bMissingData || bSkip));
   
   if (!bRet) {
-    printlast(oenv,pt);
+    printlast(status, oenv,pt);
     if (fr->not_ok)
-      printincomp(fr);
+      printincomp(status, fr);
   }
   
   return bRet;
 }
 
-int read_first_frame(const output_env_t oenv,int *status,
+int read_first_frame(const output_env_t oenv,t_trxstatus **status,
                      const char *fn,t_trxframe *fr,int flags)
 {
-  int  fp;
+  t_fileio *fio;
   bool bFirst,bOK;
+  int dummy=0;
 
   clear_trxframe(fr,TRUE);
   fr->flags = flags;
 
   bFirst = TRUE;
-  INITCOUNT;
+
+  snew((*status), 1);
+
+  status_init( *status );
+  (*status)->nxframe=1;
+  initcount(*status);
   
-  fp = *status =gmx_fio_open(fn,"r");
-  switch (gmx_fio_getftp(fp)) 
+  fio = (*status)->fio =gmx_fio_open(fn,"r");
+  switch (gmx_fio_getftp(fio)) 
   {
   case efTRJ:
   case efTRR:
     break;
   case efCPT:
-    read_checkpoint_trxframe(fp,fr);
+    read_checkpoint_trxframe(fio,fr);
     bFirst = FALSE;
     break;
   case efG96:
     /* Can not rewind a compressed file, so open it twice */
-    read_g96_conf(gmx_fio_getfp(fp),fn,fr);
-    gmx_fio_close(fp);
+    read_g96_conf(gmx_fio_getfp(fio),fn,fr);
+    gmx_fio_close(fio);
     clear_trxframe(fr,FALSE);
     if (flags & (TRX_READ_X | TRX_NEED_X))
       snew(fr->x,fr->natoms);
     if (flags & (TRX_READ_V | TRX_NEED_V))
       snew(fr->v,fr->natoms);
-    fp = *status =gmx_fio_open(fn,"r");
+    fio = (*status)->fio =gmx_fio_open(fn,"r");
     break;
   case efG87:
-    fr->natoms=xyz_first_x(gmx_fio_getfp(fp),oenv,&fr->time,&fr->x,fr->box);
+    fr->natoms=xyz_first_x(*status, gmx_fio_getfp(fio),oenv,&fr->time,
+                           &fr->x,fr->box);
     if (fr->natoms) {
       fr->bTime = TRUE;
       fr->bX    = TRUE;
       fr->bBox  = TRUE;
-      printcount(oenv,fr->time,FALSE);
+      printcount(*status,oenv,fr->time,FALSE);
     }
     bFirst = FALSE;
     break;
   case efXTC:
-    if (read_first_xtc(fp,&fr->natoms,&fr->step,&fr->time,fr->box,&fr->x,
+    if (read_first_xtc(fio,&fr->natoms,&fr->step,&fr->time,fr->box,&fr->x,
                       &fr->prec,&bOK) == 0) {
       if (bOK) {
        gmx_fatal(FARGS,"No XTC!\n");
@@ -787,32 +837,32 @@ int read_first_frame(const output_env_t oenv,int *status,
     }
     if (fr->not_ok) {
       fr->natoms = 0;
-      printincomp(fr);
+      printincomp(*status,fr);
     } else {
       fr->bPrec = (fr->prec > 0);
       fr->bStep = TRUE;
       fr->bTime = TRUE;
       fr->bX    = TRUE;
       fr->bBox  = TRUE;
-      printcount(oenv,fr->time,FALSE);
+      printcount(*status,oenv,fr->time,FALSE);
     }
     bFirst = FALSE;
     break;
   case efPDB:
-    pdb_first_x(gmx_fio_getfp(fp),fr);
+    pdb_first_x(*status, gmx_fio_getfp(fio),fr);
     if (fr->natoms)
-      printcount(oenv,fr->time,FALSE);
+      printcount(*status,oenv,fr->time,FALSE);
     bFirst = FALSE;
     break;
   case efGRO:
-    if (gro_first_x_or_v(gmx_fio_getfp(fp),fr))
-      printcount(oenv,fr->time,FALSE);
+    if (gro_first_x_or_v(gmx_fio_getfp(fio),fr))
+      printcount(*status,oenv,fr->time,FALSE);
     bFirst = FALSE;
     break;
   default:
 #ifdef GMX_DLOPEN
-      gmx_fio_fp_close(fp); /*only close the file without removing FIO entry*/
-      if (!read_first_vmd_frame(status,fn,fr,flags))
+      gmx_fio_fp_close(fio); /*only close the file without removing FIO entry*/
+      if (!read_first_vmd_frame(&dummy,fn,fr,flags))
       {
          gmx_fatal(FARGS,"Not supported in read_first_frame: %s",fn);
       }
@@ -840,47 +890,47 @@ int read_first_frame(const output_env_t oenv,int *status,
 
 /***** C O O R D I N A T E   S T U F F *****/
 
-int read_first_x(const output_env_t oenv,int *status,const char *fn,
+int read_first_x(const output_env_t oenv,t_trxstatus **status,const char *fn,
                 real *t,rvec **x,matrix box)
 {
   t_trxframe fr;
 
   read_first_frame(oenv,status,fn,&fr,TRX_NEED_X);
-  if (*status >= nxframe) {
-    nxframe = *status+1;
-    srenew(xframe,nxframe);
-  }
-  xframe[*status] = fr;
-  *t = xframe[*status].time;
-  *x = xframe[*status].x;
-  copy_mat(xframe[*status].box,box);
+
+  snew((*status)->xframe, 1);
+  (*status)->nxframe=1;
+  (*(*status)->xframe) = fr;
+  *t = (*status)->xframe->time;
+  *x = (*status)->xframe->x;
+  copy_mat((*status)->xframe->box,box);
   
-  return xframe[*status].natoms;
+  return (*status)->xframe->natoms;
 }
 
-bool read_next_x(const output_env_t oenv, int status,real *t, int natoms
-                 rvec x[], matrix box)
+bool read_next_x(const output_env_t oenv, t_trxstatus *status,real *t
+                 int natoms, rvec x[], matrix box)
 {
   bool bRet;
-  
-  xframe[status].x = x;
-  bRet = read_next_frame(oenv,status,&xframe[status]);
-  *t = xframe[status].time;
-  copy_mat(xframe[status].box,box);
+  status->xframe->x= x;
+  /*xframe[status].x = x;*/
+  bRet = read_next_frame(oenv,status,status->xframe);
+  *t = status->xframe->time;
+  copy_mat(status->xframe->box,box);
   
   return bRet;
 }
 
-void close_trj(int status)
+void close_trj(t_trxstatus *status)
 {
-    gmx_fio_close(status);
+    gmx_fio_close(status->fio);
 }
 
-void rewind_trj(int status)
+void rewind_trj(t_trxstatus *status)
 {
-  INITCOUNT;
+  initcount(status);
   
-  gmx_fio_rewind(status);
+  gmx_fio_rewind(status->fio);
 }
 
 /***** V E L O C I T Y   S T U F F *****/
@@ -894,8 +944,8 @@ static void clear_v(t_trxframe *fr)
       clear_rvec(fr->v[i]);
 }
 
-int read_first_v(const output_env_t oenv, int *status,const char *fn,real *t,
-                 rvec **v,matrix box)
+int read_first_v(const output_env_t oenv, t_trxstatus **status,const char *fn,
+                 real *t, rvec **v,matrix box)
 {
   t_trxframe fr;
 
@@ -908,8 +958,8 @@ int read_first_v(const output_env_t oenv, int *status,const char *fn,real *t,
   return fr.natoms;
 }
 
-bool read_next_v(const output_env_t oenv,int status,real *t,int natoms,rvec v[],
-                 matrix box)
+bool read_next_v(const output_env_t oenv,t_trxstatus *status,real *t,
+                 int natoms,rvec v[], matrix box)
 {
   t_trxframe fr;
   bool bRet;
index cd7ba88880139bf61503f4e6ac0f2c4f279b45ed..cfab228f1ae35d43ff8a8e0e9ca4a33eaccf19d1 100644 (file)
@@ -57,7 +57,7 @@ int xdr_real(XDR *xdrs,real *r)
 #endif
 }
 
-int xdr3drcoord(XDR *xdrs, real *fp, int *size, real *precision)
+int xdr3drcoord(XDR *xdrs, real *fp, int *size, real *precision, bool bRead)
 {
 #ifdef GMX_DOUBLE
   float *ffp;
@@ -73,7 +73,7 @@ int xdr3drcoord(XDR *xdrs, real *fp, int *size, real *precision)
   for(i=0; (i<isize); i++)
     ffp[i]=fp[i];
   fprec=*precision;
-  ret=xdr3dfcoord(xdrs,ffp,size,&fprec);
+  ret=xdr3dfcoord(xdrs,ffp,size,&fprec,bRead);
   
   *precision=fprec;
   for(i=0; (i<isize); i++)
@@ -82,7 +82,7 @@ int xdr3drcoord(XDR *xdrs, real *fp, int *size, real *precision)
   sfree(ffp);
   return ret;
 #else
-  return xdr3dfcoord(xdrs,(float *)fp,size,(float *)precision);
+  return xdr3dfcoord(xdrs,(float *)fp,size,(float *)precision,bRead);
 #endif
 }
 
index af7832f1e07bf9218f8a11adab55f939478c1054..cd1f270fcad60f76ba23208c16f8c6cf49d01b1a 100644 (file)
@@ -68,14 +68,14 @@ static int xdr_r2f(XDR *xdrs,real *r,bool bRead)
 }
 
 
-int open_xtc(const char *fn,const char *mode)
+t_fileio *open_xtc(const char *fn,const char *mode)
 {
-  return gmx_fio_open(fn,mode);
+    return gmx_fio_open(fn,mode);
 }
 
-void close_xtc(int fp)
+void close_xtc(t_fileio *fio)
 {
-  gmx_fio_close(fp);
+    gmx_fio_close(fio);
 }
 
 static void check_xtc_magic(int magic)
@@ -153,7 +153,7 @@ static int xtc_coord(XDR *xd,int *natoms,matrix box,rvec *x,real *prec, bool bRe
       }
       fprec = *prec;
   }
-  result=XTC_CHECK("x",xdr3dfcoord(xd,ftmp,natoms,&fprec));
+  result=XTC_CHECK("x",xdr3dfcoord(xd,ftmp,natoms,&fprec,bRead));
   
   /* Copy from temp. array if reading */
   if(bRead)
@@ -168,7 +168,7 @@ static int xtc_coord(XDR *xd,int *natoms,matrix box,rvec *x,real *prec, bool bRe
   }  
   sfree(ftmp);
 #else
-    result=XTC_CHECK("x",xdr3dfcoord(xd,x[0],natoms,prec)); 
+    result=XTC_CHECK("x",xdr3dfcoord(xd,x[0],natoms,prec,bRead)); 
 #endif 
     
   return result;
@@ -176,7 +176,7 @@ static int xtc_coord(XDR *xd,int *natoms,matrix box,rvec *x,real *prec, bool bRe
 
 
 
-int write_xtc(int fp,
+int write_xtc(t_fileio *fio,
              int natoms,int step,real time,
              matrix box,rvec *x,real prec)
 {
@@ -185,7 +185,7 @@ int write_xtc(int fp,
   bool bDum;
   int bOK;
        
-  xd = gmx_fio_getxdr(fp);
+  xd = gmx_fio_getxdr(fio);
   /* write magic number and xtc identidier */
   if (xtc_header(xd,&magic_number,&natoms,&step,&time,FALSE,&bDum) == 0)
   {
@@ -197,7 +197,7 @@ int write_xtc(int fp,
 
   if(bOK)
   {
-         if(gmx_fio_flush(fp) !=0)
+         if(gmx_fio_flush(fio) !=0)
          {
                  bOK = 0;
          }
@@ -205,14 +205,14 @@ int write_xtc(int fp,
   return bOK;  /* 0 if bad, 1 if writing went well */
 }
 
-int read_first_xtc(int fp,int *natoms,int *step,real *time,
+int read_first_xtc(t_fileio *fio,int *natoms,int *step,real *time,
                   matrix box,rvec **x,real *prec,bool *bOK)
 {
   int magic;
   XDR *xd;
   
   *bOK=TRUE;
-  xd = gmx_fio_getxdr(fp);
+  xd = gmx_fio_getxdr(fio);
   
   /* read header and malloc x */
   if ( !xtc_header(xd,&magic,natoms,step,time,TRUE,bOK))
@@ -228,7 +228,7 @@ int read_first_xtc(int fp,int *natoms,int *step,real *time,
   return *bOK;
 }
 
-int read_next_xtc(int fp,
+int read_next_xtc(t_fileio* fio,
                  int natoms,int *step,real *time,
                  matrix box,rvec *x,real *prec,bool *bOK)
 {
@@ -237,7 +237,7 @@ int read_next_xtc(int fp,
   XDR *xd;
 
   *bOK=TRUE;
-  xd = gmx_fio_getxdr(fp);
+  xd = gmx_fio_getxdr(fio);
   
   /* read header */
   if (!xtc_header(xd,&magic,&n,step,time,TRUE,bOK))
index 1c19009ebcd2ce124c7c98f508e64b3f3f7d0a0b..5ac1b28a44c7bef3ccdbba181a79b27815aaeef2 100644 (file)
@@ -74,7 +74,8 @@ int main (int argc,char *argv[])
   t_atoms     *atoms,*iatoms;
   t_protonate protdata;
   atom_id     *index;
-  int         status,out;
+  t_trxstatus *status;
+  t_trxstatus *out;
   t_trxframe  fr,frout;
   rvec        *x,*ix;
   int         nidx,natoms,natoms_out;
index f419ad8f93312ddd185bbe4379f4a6fe48b29ecb..79d1ffb84734c08c5b623bf1db96384dde25ddfe 100644 (file)
@@ -247,7 +247,7 @@ void chk_trj(const output_env_t oenv,const char *fn,const char *tpr,real tol)
   off_t        fpos;
   real         rdum,tt,old_t1,old_t2,prec;
   bool         bShowTimestep=TRUE,bOK,newline=FALSE;
-  int          status;
+  t_trxstatus *status;
   gmx_mtop_t   mtop;
   gmx_localtop_t *top;
   t_state      state;
@@ -339,7 +339,7 @@ void chk_trj(const output_env_t oenv,const char *fn,const char *tpr,real tol)
     INC(fr,count,first,last,bF);
     INC(fr,count,first,last,bBox);
 #undef INC
-    fpos = gmx_fio_ftell(status);
+    fpos = gmx_fio_ftell(trx_get_fileio(status));
   } while (read_next_frame(oenv,status,&fr));
   
   fprintf(stderr,"\n");
index c6f023b2154eb515230a0ab659546ae6a652cd75..2beb70aee23daca42e7cb672f3222694ae3548c7 100644 (file)
@@ -207,7 +207,8 @@ static void list_top(const char *fn)
 
 static void list_trn(const char *fn)
 {
-  int         fpread,fpwrite,nframe,indent;
+  t_fileio    *fpread, *fpwrite;
+  int         nframe,indent;
   char        buf[256];
   rvec        *x,*v,*f;
   matrix      box;
@@ -261,7 +262,8 @@ static void list_trn(const char *fn)
 
 void list_xtc(const char *fn, bool bXVG)
 {
-  int    xd,indent;
+  t_fileio *xd;
+  int    indent;
   char   buf[256];
   rvec   *x;
   matrix box;
index 49e852a30f95c4ca94d0b819f4814922d78889cc..be252dc955f2a6ae8342886a3e322a0426e37557 100644 (file)
@@ -436,7 +436,7 @@ static void cont_status(const char *slog,const char *ener,
      /* If fr_time == -1 read the last frame available which is complete */
 {
   t_trxframe  fr;
-  int         fp;
+  t_trxstatus *fp;
 
   fprintf(stderr,
          "Reading Coordinates%s and Box size from old trajectory\n",
index 38c258cf3a056a8c8e393568028d88c9d4b22895..5384dcb01a9a1552cf01a7a40672e02a2c79907d 100644 (file)
@@ -1024,7 +1024,8 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
     bool       bMasterState;
     int        force_flags,cglo_flags;
     tensor     force_vir,shake_vir,total_vir,tmp_vir,pres;
-    int        i,m,status;
+    int        i,m;
+    t_trxstatus *status;
     rvec       mu_tot;
     t_vcm      *vcm;
     t_state    *bufstate=NULL;   
index bb2662e429b26220a58b817aa451707aa56593e1..79da815d020071d6cd895d6174ac17f181d84135 100644 (file)
@@ -1040,9 +1040,11 @@ int main(int argc, char *argv[])
   sfree(rrn);
 
   clear_mat(box);
-  if (watermodel != NULL && strncmp(watermodel,"tip4p",5) == 0) {
+  if (watermodel != NULL && (strstr(watermodel,"4p") ||
+                            strstr(watermodel,"4P"))) {
     watres = "HO4";
-  } else if (watermodel != NULL && strncmp(watermodel,"tip5p",5) == 0) {
+  } else if (watermodel != NULL && (strstr(watermodel,"5p") ||
+                                   strstr(watermodel,"5P"))) {
     watres = "HO5";
   } else {
     watres = "HOH";
index e4ecd12834d73dd489456505f4baedb2d9c9ea3a..f61e00b3b924f64c54e7169ec832858a4fb80902 100644 (file)
@@ -438,6 +438,11 @@ void check_ir(const char *mdparin,t_inputrec *ir, t_gromppopts *opts,
 
   /* ELECTROSTATICS */
   /* More checks are in triple check (grompp.c) */
+    if (ir->coulombtype == eelPPPM)
+    {
+        warning_error(wi,"PPPM is not functional in the current version, we plan to implement PPPM through a small modification of the PME code");
+    }
+
   if (ir->coulombtype == eelSWITCH) {
     sprintf(warn_buf,"coulombtype = %s is only for testing purposes and can lead to serious artifacts, advice: use coulombtype = %s",
            eel_names[ir->coulombtype],
index bbeda38b2988f0113a5b8a479304836ede01a30d..f7aa0563274b1bffe0696d321dfcf34483e7cc08 100644 (file)
@@ -732,7 +732,7 @@ void comp_trx(const output_env_t oenv,const char *fn1, const char *fn2,
   int i;
   const char *fn[2];
   t_trxframe fr[2];
-  int status[2];
+  t_trxstatus *status[2];
   bool b[2];
   
   fn[0]=fn1;
index 62cce01e2977f154dd3733109f19e209296755dc..b6c3ae0160b4b831eb8007514324763ee76af72f 100644 (file)
@@ -294,7 +294,8 @@ int main (int argc, char *argv[])
   const char *desc[] = {
     "tpbconv can edit run input files in four ways.[PAR]",
     "[BB]1st.[bb] by modifying the number of steps in a run input file",
-    "with option [TT]-nsteps[tt] or option [TT]-runtime[tt].[PAR]",
+    "with options [TT]-extend[tt], [TT]-until[tt] or [TT]-nsteps[tt]",
+    "(nsteps=-1 means unlimited number of steps)[PAR]",
     "[BB]2nd.[bb] (OBSOLETE) by creating a run input file",
     "for a continuation run when your simulation has crashed due to e.g.",
     "a full disk, or by making a continuation run input file.",
@@ -314,7 +315,7 @@ int main (int argc, char *argv[])
   };
 
   const char   *top_fn,*frame_fn;
-  int          fp;
+  t_fileio     *fp;
   ener_file_t  fp_ener=NULL;
   t_trnheader head;
   int          i;
@@ -347,21 +348,18 @@ int main (int argc, char *argv[])
 #define NFILE asize(fnm)
 
   /* Command line options */
-  static int  nsteps_req_int = -1;
-  static real runtime_req = -1;
+  static int  nsteps_req_int = 0;
   static real start_t = -1.0, extend_t = 0.0, until_t = 0.0;
   static bool bContinuation = TRUE,bZeroQ = FALSE,bVel=TRUE;
   static t_pargs pa[] = {
-    { "-nsteps",        FALSE, etINT,  {&nsteps_req_int},
-      "Change the number of steps" },
-    { "-runtime",       FALSE, etREAL, {&runtime_req},
-      "Set the run time (ps)" },
-    { "-time",          FALSE, etREAL, {&start_t}, 
-      "Continue from frame at this time (ps) instead of the last frame" },
     { "-extend",        FALSE, etREAL, {&extend_t}, 
       "Extend runtime by this amount (ps)" },
     { "-until",         FALSE, etREAL, {&until_t}, 
       "Extend runtime until this ending time (ps)" },
+    { "-nsteps",        FALSE, etINT,  {&nsteps_req_int},
+      "Change the number of steps" },
+    { "-time",          FALSE, etREAL, {&start_t}, 
+      "Continue from frame at this time (ps) instead of the last frame" },
     { "-zeroq",         FALSE, etBOOL, {&bZeroQ},
       "Set the charges of a group (from the index) to zero" },
     { "-vel",           FALSE, etBOOL, {&bVel},
@@ -379,7 +377,7 @@ int main (int argc, char *argv[])
 
   /* Convert int to gmx_large_int_t */
   nsteps_req = nsteps_req_int;
-  bNsteps = (nsteps_req >= 0 || runtime_req >= 0);
+  bNsteps = opt2parg_bSet("-nsteps",asize(pa),pa);
   bExtend = opt2parg_bSet("-extend",asize(pa),pa);
   bUntil  = opt2parg_bSet("-until",asize(pa),pa);
   bTime   = opt2parg_bSet("-time",asize(pa),pa);
@@ -523,13 +521,6 @@ int main (int argc, char *argv[])
   }
 
   if (bNsteps) {
-    if (nsteps_req < 0) {
-      if (!EI_DYNAMICS(ir->eI)) {
-       gmx_fatal(FARGS,"Can not set the run time with integrator '%s'",
-                 EI(ir->eI));
-      }
-      nsteps_req = (int)(runtime_req/ir->delta_t + 0.5);
-    }
     fprintf(stderr,"Setting nsteps to %s\n",gmx_step_str(nsteps_req,buf));
     ir->nsteps = nsteps_req;
   } else {
index fe68367746e4f1abf49e2b8074338b4bb7041f0d..1cd3a4dae64744033eef6545f77e005db6b39e4e 100644 (file)
@@ -46,10 +46,10 @@ libmd@LIBSUFFIX@_la_SOURCES = \
        csettle.c       clincs.c        \
        qmmm.c          gmx_fft.c       gmx_parallel_3dfft.c    \
        fft5d.c         fft5d.h         \
-       gmx_wallcycle.c fftgrid.c       \
+       gmx_wallcycle.c \
        qm_gaussian.c   qm_mopac.c      qm_gamess.c             \
        gmx_fft_fftw2.c gmx_fft_fftw3.c gmx_fft_fftpack.c       \
-       gmx_fft_mkl.c   
+       gmx_fft_mkl.c   qm_orca.c
 
 LDADD = ../mdlib/libmd@LIBSUFFIX@.la ../gmxlib/libgmx@LIBSUFFIX@.la 
 
index 32c3fe4b345b4007b7ee7ba357c408e7d5e12d4e..192a9d93573114982c352f8f01cc891c266f7858 100644 (file)
@@ -43,7 +43,6 @@
 #include "gmxcomplex.h"
 #include "smalloc.h"
 #include "futil.h"
-#include "fftgrid.h"
 #include "gmx_fatal.h"
 #include "physics.h"
 #include "coulomb.h"
diff --git a/src/mdlib/fftgrid.c b/src/mdlib/fftgrid.c
deleted file mode 100644 (file)
index 89b5874..0000000
+++ /dev/null
@@ -1,493 +0,0 @@
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
- *
- * 
- *                This source code is part of
- * 
- *                 G   R   O   M   A   C   S
- * 
- *          GROningen MAchine for Chemical Simulations
- * 
- *                        VERSION 3.2.0
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
- * 
- * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- * 
- * For more info, check our website at http://www.gromacs.org
- * 
- * And Hey:
- * GROwing Monsters And Cloning Shrimps
- */
-/* This file is completely threadsafe - keep it that way! */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "typedefs.h"
-#include "futil.h"
-#include "smalloc.h"
-#include "futil.h"
-#include "macros.h"
-#include "network.h"
-#include "fftgrid.h"
-#include "gmx_fft.h"
-#include "gmx_parallel_3dfft.h"
-#include "gmxfio.h"
-
-
-#ifdef GMX_MPI
-static void print_parfft(FILE *fp,char *title,t_parfft *pfft)
-{
-  fprintf(fp,"PARALLEL FFT DATA:\n"
-         "   local_nx:                 %3d  local_x_start:                 %3d\n"
-         "   local_ny_after_transpose: %3d  local_y_start_after_transpose  %3d\n",
-         pfft->local_nx,pfft->local_x_start,pfft->local_ny_after_transpose,
-         pfft->local_y_start_after_transpose);
-}
-#endif
-
-
-void *
-gmx_alloc_aligned(size_t size)
-{
-    void *p0,*p;
-    
-    p0 = malloc(size+32);
-    
-    if(p0 == NULL)
-    {
-        gmx_fatal(FARGS,"Failed to allocated %u bytes of aligned memory.",size+32);
-    }
-    
-    p = (void *) (((size_t) p0 + 32) & (~((size_t) 31)));
-    
-    /* Yeah, yeah, we cannot free this pointer, but who cares... */
-    return p;
-}
-
-/*
-t_fftgrid *mk_fftgrid(int          nx,
-                      int          ny,
-                      int          nz,
-                      int          *node2slab,
-                      int          *slab2grid_x,
-                      t_commrec *  cr,
-                      bool         bReproducible)
-{
-// parallel runs with non-parallel ffts haven't been tested yet 
-    int           nnodes;
-    int           x1,y1,maxlocalsize;
-    t_fftgrid *   grid;
-    int           flags;
-    
-    nnodes = 1;
-#ifdef GMX_MPI
-    if (cr && cr->nnodes > 1) {
-        MPI_Comm_size(cr->mpi_comm_mygroup,&nnodes);
-    }
-#endif
-    
-    snew(grid,1);
-    grid->nx   = nx;
-    grid->ny   = ny;
-    grid->nz   = nz;
-    grid->nxyz = nx*ny*nz;
-    grid->bParallel = (nnodes > 1);
-    
-    if (grid->bParallel)
-    {
-        grid->la2r = (nz/2+1)*2;
-    }
-    else
-    {
-        grid->la2r = nz;  
-    }
-    
-    grid->la2c = (nz/2+1);    
-    
-    grid->la12r = ny*grid->la2r;
-    
-    if (grid->bParallel)
-    {
-        grid->la12c = nx*grid->la2c;
-    }
-    else
-    {
-        grid->la12c = ny*grid->la2c;
-    }
-    
-    // This code assumes that the when the grid is not divisble by nnodes,
-    // the maximum difference in local grid sizes is 1.
-    
-    x1 = (nx % nnodes == 0 ? 0 : 1);
-    y1 = (ny % nnodes == 0 ? 0 : 1);
-    
-    grid->nptr = (nx + x1)*(ny + y1)*grid->la2c*2;
-    
-    if (grid->bParallel) 
-    {
-#ifdef GMX_MPI
-        gmx_parallel_3dfft_init(&grid->mpi_fft_setup,nx,ny,nz,
-                                node2slab,slab2grid_x,cr->mpi_comm_mygroup,
-                                bReproducible);
-        
-        gmx_parallel_3dfft_limits(grid->mpi_fft_setup,
-                                  &(grid->pfft.local_x_start),
-                                  &(grid->pfft.local_nx),
-                                  &(grid->pfft.local_y_start_after_transpose),
-                                  &(grid->pfft.local_ny_after_transpose));
-#else
-        gmx_fatal(FARGS,"Parallel FFT supported with MPI only!");
-#endif
-    }
-    else 
-    {
-        gmx_fft_init_3d_real(&grid->fft_setup,nx,ny,nz,bReproducible ? GMX_FFT_FLAG_CONSERVATIVE : GMX_FFT_FLAG_NONE);
-    }
-    grid->ptr = (real *)gmx_alloc_aligned(grid->nptr*sizeof(*(grid->ptr)));
-    
-#ifdef GMX_MPI
-    if (grid->bParallel && debug) 
-    {
-        print_parfft(debug,"Plan", &grid->pfft);
-    }
-    if (grid->bParallel)
-    {
-        maxlocalsize = max((nx/nnodes + x1)*ny*grid->la2c*2,
-                           (ny/nnodes + y1)*nx*grid->la2c*2);
-        grid->workspace = (real *)
-            gmx_alloc_aligned(maxlocalsize*sizeof(*(grid->workspace)));
-    }
-    else
-    {
-        grid->workspace =
-            (real*)gmx_alloc_aligned(grid->nptr*sizeof(*(grid->workspace)));
-    }
-#else // no MPI 
-    grid->workspace = (real *)gmx_alloc_aligned(grid->nptr*sizeof(*(grid->workspace)));
-#endif
-
-    return grid;
-}
-*/
-
-void 
-pr_fftgrid(FILE *fp,char *title,t_fftgrid *grid)
-{
-  int     i,j,k,index_x,index_xy,ntot=0;
-  int     nx,ny,nz,nx2,ny2,nz2,la12,la2;
-  real *  ptr;
-
-  /* Unpack structure */
-  unpack_fftgrid(grid,&nx,&ny,&nz,&nx2,&ny2,&nz2,&la2,&la12,TRUE,&ptr);
-  for(i=0; (i<nx); i++) {
-    index_x = la12*i;
-    for(j=0; (j<ny); j++) {
-      index_xy = index_x + la2*j;
-      for(k=0; (k<nz); k++) {
-       if (ptr[index_xy+k] != 0) {
-         fprintf(fp,"%-12s  %5d  %5d  %5d  %12.5e\n",
-                 title,i,j,k,ptr[index_xy+k]);
-         ntot++;
-       }
-      }
-    }
-  }
-  fprintf(fp,"%d non zero elements in %s\n",ntot,title);
-}
-
-void done_fftgrid(t_fftgrid *grid)
-{
-  /* memory can't be freed because it is allocated by gmx_alloc_aligned */
-  if (grid->ptr) {
-    /* sfree(grid->ptr); */
-    grid->ptr = NULL;
-  }
-  if (grid->workspace) {
-    /* sfree(grid->workspace); */
-    grid->workspace=NULL;
-  }
-}
-
-/*
-void gmxfft3D(t_fftgrid *grid,enum gmx_fft_direction dir,t_commrec *cr)
-{
-  real *tmp;
-
-  if (grid->bParallel) 
-  {
-#ifdef GMX_MPI
-    if( dir == GMX_FFT_REAL_TO_COMPLEX || dir == GMX_FFT_COMPLEX_TO_REAL )
-    {
-      gmx_parallel_3dfft(grid->mpi_fft_setup,dir,grid->ptr,grid->ptr);
-    }
-    else
-    {
-        gmx_fatal(FARGS,"Invalid direction for FFT: %d",dir);
-    }
-#else
-    gmx_fatal(FARGS,"Parallel FFT supported with MPI only!");   
-#endif
-  }
-  else
-  {
-    if( dir == GMX_FFT_REAL_TO_COMPLEX || dir == GMX_FFT_COMPLEX_TO_REAL)
-    {
-        gmx_fft_3d_real(grid->fft_setup,dir,grid->ptr,grid->workspace);
-        tmp = grid->ptr;
-        grid->ptr = grid->workspace;
-        grid->workspace = tmp;        
-    }
-    else
-    {
-      gmx_fatal(FARGS,"Invalid direction for FFT: %d",dir);
-    }
-  }
-}
-*/
-void clear_fftgrid(t_fftgrid *grid)
-{
-    /* clears the whole grid */
-  int      i,ngrid;
-  real *   ptr;
-  
-  ngrid = grid->nptr;
-  ptr   = grid->ptr;
-  
-  for (i=0; (i<ngrid); i++) {
-    ptr[i] = 0;
-  }
-}
-
-void unpack_fftgrid(t_fftgrid *grid,int *nx,int *ny,int *nz,
-                    int *nx2,int *ny2,int *nz2,
-                    int *la2,int *la12,bool bReal,real **ptr)
-{
-  *nx  = grid->nx;
-  *ny  = grid->ny;
-  *nz  = grid->nz;
-  *nx2 = 2*grid->nx;
-  *ny2 = 2*grid->ny;
-  *nz2 = 2*grid->nz;
-  if(bReal) {
-    *la2 = grid->la2r;
-    *la12= grid->la12r;
-  } 
-  else {
-    *la2 = grid->la2c;
-    *la12= grid->la12c;
-  }
-  *ptr = grid->ptr;
-}
-
-
-
-/*****************************************************************
- * 
- * For backward compatibility (for testing the ewald code vs. PPPM etc)
- * some old grid routines are retained here.
- *
- ************************************************************************/
-
-real ***mk_rgrid(int nx,int ny,int nz)
-{
-  real *ptr1;
-  real **ptr2;
-  real ***ptr3;
-  int  i,j,n2,n3;
-  
-  snew(ptr1,nx*ny*nz);
-  snew(ptr2,nx*ny);
-  snew(ptr3,nx);
-  
-  n2=n3=0;
-  for(i=0; (i<nx); i++) {
-    ptr3[i]=&(ptr2[n2]);
-    for(j=0; (j<ny); j++,n2++) { 
-      ptr2[n2] = &(ptr1[n3]);
-      n3 += nz;
-    }
-  }
-  return ptr3;
-}
-
-void free_rgrid(real ***grid,int nx,int ny)
-{
-  int i;
-
-  sfree(grid[0][0]);  
-  for(i=0; (i<nx); i++) {
-    sfree(grid[i]);
-  }
-  sfree(grid);
-}
-
-real print_rgrid(FILE *fp,char *title,int nx,int ny,int nz,real ***grid)
-{
-  int  ix,iy,iz;
-  real g,gtot;
-  
-  gtot=0;
-  if (fp)
-    fprintf(fp,"Printing all non-zero real elements of %s\n",title);
-  for(ix=0; (ix<nx); ix++)
-    for(iy=0; (iy<ny); iy++)
-      for(iz=0; (iz<nz); iz++) {
-       g=grid[ix][iy][iz];
-       if (fp && (g != 0))
-         fprintf(fp,"%s[%2d][%2d][%2d] = %12.5e\n",title,ix,iy,iz,g);
-       gtot+=g;
-      }
-  return gtot;
-}
-
-void print_rgrid_pdb(char *fn,int nx,int ny,int nz,real ***grid)
-{
-  FILE *fp;
-  int  ix,iy,iz,n,ig;
-  real x,y,z,g;
-
-  n=1;
-  fp=gmx_fio_fopen(fn,"w");  
-  for(ix=0; (ix<nx); ix++) {
-    for(iy=0; (iy<ny); iy++) {
-      for(iz=0; (iz<nz); iz++) {
-       g=grid[ix][iy][iz];
-       ig=g;
-       if ((ig != 0) || (1)) {
-         x = 4*ix;
-         y = 4*iy;
-         z = 4*iz;
-         fprintf(fp,"ATOM  %5d  Na   Na     1    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
-                 n++,x,y,z,0.0,g);
-       }
-      }
-    }
-  }
-  gmx_fio_fclose(fp);
-}
-
-void clear_rgrid(int nx,int ny,int nz,real ***grid)
-{
-  int i,j,k;
-  
-  for(i=0; (i<nx); i++)
-    for(j=0; (j<ny); j++)
-      for(k=0; (k<nz); k++)
-       grid[i][j][k] = 0;
-}
-
-void clear_cgrid(int nx,int ny,int nz,t_complex ***grid)
-{
-  int i,j,k;
-  
-  for(i=0; (i<nx); i++)
-    for(j=0; (j<ny); j++)
-      for(k=0; (k<nz); k++)
-       grid[i][j][k] = cnul;
-}
-
-t_complex ***mk_cgrid(int nx,int ny,int nz)
-{
-  t_complex *ptr1;
-  t_complex **ptr2;
-  t_complex ***ptr3;
-  int  i,j,n2,n3;
-  
-  snew(ptr1,nx*ny*nz);
-  snew(ptr2,nx*ny);
-  snew(ptr3,nx);
-  
-  n2=n3=0;
-  for(i=0; (i<nx); i++) {
-    ptr3[i]=&(ptr2[n2]);
-    for(j=0; (j<ny); j++,n2++) { 
-      ptr2[n2] = &(ptr1[n3]);
-      n3 += nz;
-    }
-  }
-  return ptr3;
-}
-
-void free_cgrid(t_complex ***grid,int nx,int ny)
-{
-  int i;
-
-  sfree(grid[0][0]);
-  for(i=0; (i<nx); i++) 
-    sfree(grid[i]);
-  sfree(grid);
-}
-
-t_complex print_cgrid(FILE *fp,char *title,int nx,int ny,int nz,
-                      t_complex ***grid)
-{
-  int     ix,iy,iz;
-  t_complex g,gtot;
-  
-  gtot=cnul;
-  if (fp)
-    fprintf(fp,"Printing all non-zero complex elements of %s\n",title);
-  for(ix=0; (ix<nx); ix++)
-    for(iy=0; (iy<ny); iy++)
-      for(iz=0; (iz<nz); iz++) {
-       g=grid[ix][iy][iz];
-       if (fp  && ((g.re != 0) || (g.im != 0)))
-         fprintf(fp,"%s[%2d][%2d][%2d] = %12.5e + i %12.5e\n",
-                 title,ix,iy,iz,g.re,g.im);
-       gtot = cadd(gtot,g);
-      }
-  return gtot;
-}
-
-void print_cgrid_pdb(char *fn,int nx,int ny,int nz,t_complex ***grid)
-{
-  FILE *fp;
-  int  ix,iy,iz,n;
-  real x,y,z,g;
-
-  n=1;
-  fp=gmx_fio_fopen(fn,"w");  
-  for(ix=0; (ix<nx); ix++) {
-    for(iy=0; (iy<ny); iy++) {
-      for(iz=0; (iz<nz); iz++) {
-       g=grid[ix][iy][iz].re;
-       if (g != 0) {
-         x = 4*ix;
-         y = 4*iy;
-         z = 4*iz;
-         fprintf(fp,"ATOM  %5d  Na   Na     1    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
-                 n++,x,y,z,0.0,g);
-       }
-      }
-    }
-  }
-  gmx_fio_fclose(fp);
-}
-
-
-
-
-
-
-
-
index ccd36d1441c05b4addc4f86b6eb9e700e48575ce..6ebca5eae460092cf82caca6d80bb06cd4756b5b 100644 (file)
@@ -45,9 +45,9 @@
 #include "coulomb.h"
 #include "pppm.h"
 #include "xvgr.h"
-#include "fftgrid.h"
 #include "gmxfio.h"
 #include "pppm.h"
+#include "smalloc.h"
 
 static void calc_k(rvec lll,int ix,int iy,int iz,int nx,int ny,int nz,rvec k)
 {
@@ -218,6 +218,28 @@ void pr_scalar_gk(const char *fn,const output_env_t oenv,int nx,int ny,int nz,
   gmx_fio_fclose(fp);
 }
 
+static real ***mk_rgrid(int nx,int ny,int nz)
+{
+  real *ptr1;
+  real **ptr2;
+  real ***ptr3;
+  int  i,j,n2,n3;
+
+  snew(ptr1,nx*ny*nz);
+  snew(ptr2,nx*ny);
+  snew(ptr3,nx);
+
+  n2=n3=0;
+  for(i=0; (i<nx); i++) {
+    ptr3[i]=&(ptr2[n2]);
+    for(j=0; (j<ny); j++,n2++) {
+      ptr2[n2] = &(ptr1[n3]);
+      n3 += nz;
+    }
+  }
+  return ptr3;
+}
+
 real ***rd_ghat(FILE *log,const output_env_t oenv,char *fn,ivec igrid,
                 rvec gridspace, rvec beta,int *porder,real *r1,real *rc)
 {
index 09fbfe2f0d858f66833aa0e8ef4e90a8220a43c0..7320895b10f9660011e7cff0f1f283b1db49e83f 100644 (file)
@@ -508,7 +508,7 @@ int gmx_pppm_init(FILE *log,      t_commrec *cr,
   rvec  box_diag,spacing;
 
 #ifdef DISABLE_PPPM
-    gmx_fatal(FARGS,"PPPM temporarily disabled while working on 2DPME\n");
+    gmx_fatal(FARGS,"PPPM is not functional in the current version, we plan to implement PPPM through a small modification of the PME code.");
     return -1;
 #else
     
@@ -684,4 +684,4 @@ static int gmx_pppm_opt_do(FILE *log,       gmx_pme_t pme,
   return 0;
 }
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/mdlib/qm_orca.c b/src/mdlib/qm_orca.c
new file mode 100644 (file)
index 0000000..6d9ce70
--- /dev/null
@@ -0,0 +1,394 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+#include "sysstuff.h"
+#include "typedefs.h"
+#include "macros.h"
+#include "smalloc.h"
+#include "assert.h"
+#include "physics.h"
+#include "macros.h"
+#include "vec.h"
+#include "force.h"
+#include "invblock.h"
+#include "confio.h"
+#include "names.h"
+#include "network.h"
+#include "pbc.h"
+#include "ns.h"
+#include "nrnb.h"
+#include "bondf.h"
+#include "mshift.h"
+#include "txtdump.h"
+#include "copyrite.h"
+#include "qmmm.h"
+#include <stdio.h>
+#include <string.h>
+#include "gmx_fatal.h"
+#include "typedefs.h"
+#include <stdlib.h>
+
+/* ORCA interface routines */
+
+void init_orca(t_commrec *cr, t_QMrec *qm, t_MMrec *mm)
+{
+ char
+   *buf;
+ snew(buf,200);    
+ buf = getenv("BASENAME");
+ if (buf){
+     snew(qm->orca_basename,200);
+     sscanf(buf,"%s",qm->orca_basename);
+ }
+ else
+     gmx_fatal(FARGS,"no $BASENAME\n");
+ fprintf(stderr,"orca initialised...\n");
+ /* since we append the output to the BASENAME.out file,
+ we should delete an existent old out-file here. */
+ sprintf(buf,"%s.out",qm->orca_basename);
+ remove(buf);
+}  
+
+
+void write_orca_input(int step ,t_forcerec *fr, t_QMrec *qm, t_MMrec *mm)
+{
+ int
+   i;
+ t_QMMMrec
+   *QMMMrec;
+ FILE
+   *out, *pcFile, *addInputFile, *LJCoeff;
+ char
+   *buf,*orcaInput,*addInputFilename,*LJCoeffFilename,
+   *pcFilename,*exclInName,*exclOutName;
+ QMMMrec = fr->qr;
+ /* write the first part of the input-file */
+ snew(orcaInput,200);
+ sprintf(orcaInput,"%s.inp",qm->orca_basename);
+ out = fopen(orcaInput,"w");
+ snew(addInputFilename,200);
+ sprintf(addInputFilename,"%s.ORCAINFO",qm->orca_basename);
+ addInputFile = fopen(addInputFilename,"r");
+ fprintf(out, "#input-file generated by gromacs\n");
+ if(qm->bTS){
+     fprintf(out,"!QMMMOpt TightSCF\n");
+     fprintf(out,"%s\n","%geom TS_Search EF end");
+ }
+ else if (qm->bOPT){
+     fprintf(out,"!QMMMOpt TightSCF\n");
+ }
+ else{
+     fprintf(out,"!EnGrad TightSCF\n");
+ }
+ /* here we include the insertion of the additional orca-input */
+ snew(buf,200);
+ if (addInputFile!=NULL) {
+     while (!feof(addInputFile)) {
+         if (fgets(buf , 200 , addInputFile) != '\0' ) 
+             fputs(buf, out);
+     }
+ }
+ else {
+     fprintf(stderr,"No information on the calculation given in <%s>\n",addInputFilename);
+     gmx_call("qm_orca.c");
+ }
+ fclose(addInputFile);
+ if(qm->bTS||qm->bOPT){
+     /* freeze the frontier QM atoms and Link atoms. This is
+      * important only if a full QM subsystem optimization is done
+      * with a frozen MM environmeent. For dynamics, or gromacs's own
+      * optimization routines this is not important.
+      */
+     /* ORCA reads the exclusions from LJCoeffFilename.Excl, 
+      *so we have to rename the file
+      */
+     int didStart = 0;
+     for(i=0;i<qm->nrQMatoms;i++){
+          if(qm->frontatoms[i]){
+             if (!didStart){
+                 fprintf(out,"%s\n","%geom");
+                 fprintf(out,"   Constraints \n");
+                 didStart = 1;
+             }
+              fprintf(out,"        {C %d C}\n",i); /* counting from 0 */
+          }
+     }
+     if (didStart) fprintf(out,"     end\n   end\n");
+     // make a file with information on the C6 and C12 coefficients
+     if(QMMMrec->QMMMscheme!=eQMMMschemeoniom && mm->nrMMatoms){
+         snew(exclInName,200);
+         snew(exclOutName,200);
+         sprintf(exclInName,"QMMMexcl.dat");
+         sprintf(exclOutName,"%s.LJ.Excl",qm->orca_basename);
+         rename(exclInName,exclOutName);
+         snew(LJCoeffFilename,200);
+         sprintf(LJCoeffFilename,"%s.LJ",qm->orca_basename);
+         fprintf(out,"%s%s%s\n","%LJCOEFFICIENTS \"",LJCoeffFilename,"\"");
+         // make a file with information on the C6 and C12 coefficients
+         LJCoeff = fopen(LJCoeffFilename,"w");
+         fprintf(LJCoeff,"%d\n",qm->nrQMatoms);
+         for (i=0;i<qm->nrQMatoms;i++){
+#ifdef GMX_DOUBLE
+             fprintf(LJCoeff,"%10.7lf  %10.7lf\n",qm->c6[i],qm->c12[i]);
+#else
+             fprintf(LJCoeff,"%10.7f  %10.7f\n",qm->c6[i],qm->c12[i]);
+#endif
+         }
+         fprintf(LJCoeff,"%d\n",mm->nrMMatoms);
+         for (i=0;i<mm->nrMMatoms;i++){
+#ifdef GMX_DOUBLE
+             fprintf(LJCoeff,"%10.7lf  %10.7lf\n",mm->c6[i],mm->c12[i]);
+#else
+             fprintf(LJCoeff,"%10.7f  %10.7f\n",mm->c6[i],mm->c12[i]);
+#endif
+         }
+         fclose(LJCoeff);
+     }
+ }
+ /* write charge and multiplicity
+  */
+ fprintf(out,"*xyz %2d%2d\n",qm->QMcharge,qm->multiplicity);
+ /* write the QM coordinates
+  */
+ for (i=0;i<qm->nrQMatoms;i++){
+     int atomNr;
+     if (qm->atomicnumberQM[i]==0) 
+         atomNr = 1;
+     else 
+         atomNr = qm->atomicnumberQM[i];
+#ifdef GMX_DOUBLE
+     fprintf(out,"%3d %10.7lf  %10.7lf  %10.7lf\n",
+     atomNr,
+     qm->xQM[i][XX]/0.1,
+     qm->xQM[i][YY]/0.1,
+     qm->xQM[i][ZZ]/0.1);
+#else
+     fprintf(out,"%3d %10.7f  %10.7f  %10.7f\n",
+     atomNr,
+     qm->xQM[i][XX]/0.1,
+     qm->xQM[i][YY]/0.1,
+     qm->xQM[i][ZZ]/0.1);
+#endif
+ }
+ fprintf(out,"*\n");
+ /* write the MM point charge data 
+  */
+ if(QMMMrec->QMMMscheme!=eQMMMschemeoniom && mm->nrMMatoms){
+     /* name of the point charge file */
+     snew(pcFilename,200);
+     sprintf(pcFilename,"%s.pc",qm->orca_basename);
+     fprintf(out,"%s%s%s\n","%pointcharges \"",pcFilename,"\"");
+     pcFile = fopen(pcFilename,"w");
+     fprintf(pcFile,"%d\n",mm->nrMMatoms);
+     for(i=0;i<mm->nrMMatoms;i++){
+#ifdef GMX_DOUBLE
+         fprintf(pcFile,"%8.4lf %10.7lf  %10.7lf  %10.7lf\n",
+                        mm->MMcharges[i],
+                        mm->xMM[i][XX]/0.1,
+                        mm->xMM[i][YY]/0.1,
+                        mm->xMM[i][ZZ]/0.1);
+#else
+         fprintf(pcFile,"%8.4f %10.7f  %10.7f  %10.7f\n",
+                        mm->MMcharges[i],
+                        mm->xMM[i][XX]/0.1,
+                        mm->xMM[i][YY]/0.1,
+                        mm->xMM[i][ZZ]/0.1);
+#endif
+     }
+     fprintf(pcFile,"\n");
+     fclose(pcFile);
+ }
+ fprintf(out,"\n");
+
+ fclose(out);
+}  /* write_orca_input */
+
+real read_orca_output(rvec QMgrad[],rvec MMgrad[],int step,t_forcerec *fr,
+                         t_QMrec *qm, t_MMrec *mm)
+{
+ int
+   i,j,atnum;
+ char
+   buf[300], tmp[300], orca_xyzFilename[300], orca_pcgradFilename[300], orca_engradFilename[300];
+ real
+   QMener;
+ FILE
+   *xyz, *pcgrad, *engrad;
+ t_QMMMrec
+   *QMMMrec;
+ QMMMrec = fr->qr;
+ sprintf(orca_xyzFilename,"%s.xyz",qm->orca_basename);
+ xyz=fopen(orca_xyzFilename,"r");
+ /* in case of an optimization, the coordinates are printed in the
+  * xyz file, the energy and gradients for the QM part are stored in the engrad file
+  * and the gradients for the point charges are stored in the pc file.
+  */
+
+ /* we need the new xyz coordinates of the QM atoms only for separate QM-optimization
+  */
+
+ if(qm->bTS||qm->bOPT){
+     fgets(buf,300,xyz);
+     fgets(buf,300,xyz);
+     for(i=0;i<qm->nrQMatoms;i++){
+         fgets(buf,300,xyz);
+#ifdef GMX_DOUBLE
+         sscanf(buf,"%s%lf%lf%lf\n",
+                    &tmp,
+                    &qm->xQM[i][XX],
+                    &qm->xQM[i][YY],
+                    &qm->xQM[i][ZZ]);
+#else
+         sscanf(buf,"%s%f%f%f\n",
+                    &atnum,
+                    &qm->xQM[i][XX],
+                    &qm->xQM[i][YY],
+                    &qm->xQM[i][ZZ]);
+#endif
+         for(j=0;j<DIM;j++){
+             qm->xQM[i][j]*=0.1;
+         }
+     }
+ fclose(xyz);
+ }
+ sprintf(orca_engradFilename,"%s.engrad",qm->orca_basename);
+ engrad=fopen(orca_engradFilename,"r");
+ /* we read the energy and the gradient for the qm-atoms from the engrad file
+  */
+ /* we can skip the first seven lines
+  */
+ for (j=0;j<7;j++){
+     fgets(buf,300,engrad);
+ }
+ /* now comes the energy
+  */
+ fgets(buf,300,engrad);
+#ifdef GMX_DOUBLE
+ sscanf(buf,"%lf\n",&QMener);
+#else
+ sscanf(buf,"%f\n", &QMener);
+#endif
+ /* we can skip the next three lines
+  */
+ for (j=0;j<3;j++){
+     fgets(buf,300,engrad);
+ }
+ /* next lines contain the gradients of the QM atoms
+  * now comes the gradient, one value per line:
+  * (atom1 x \n atom1 y \n atom1 z \n atom2 x ...
+  */
+ int k;
+ for(i=0;i<3*qm->nrQMatoms;i++){
+     k = i/3;
+     fgets(buf,300,engrad);
+#ifdef GMX_DOUBLE
+     if (i%3==0) 
+         sscanf(buf,"%lf\n", &QMgrad[k][XX]);
+     else if (i%3==1) 
+         sscanf(buf,"%lf\n", &QMgrad[k][YY]);
+     else if (i%3==2)
+         sscanf(buf,"%lf\n", &QMgrad[k][ZZ]);
+#else
+     if (i%3==0) 
+         sscanf(buf,"%f\n", &QMgrad[k][XX]);
+     else if (i%3==1) 
+         sscanf(buf,"%f\n", &QMgrad[k][YY]);
+     else if (i%3==2) 
+         sscanf(buf,"%f\n", &QMgrad[k][ZZ]);
+#endif
+ }
+ fclose(engrad);
+ /* write the MM point charge data 
+  */
+ if(QMMMrec->QMMMscheme!=eQMMMschemeoniom && mm->nrMMatoms){
+     sprintf(orca_pcgradFilename,"%s.pcgrad",qm->orca_basename);
+     pcgrad=fopen(orca_pcgradFilename,"r");
+    
+     /* we read the gradient for the mm-atoms from the pcgrad file
+      */
+     /* we can skip the first line
+      */
+     fgets(buf,300,pcgrad);
+     for(i=0;i<mm->nrMMatoms;i++){
+         fgets(buf,300,pcgrad);
+    #ifdef GMX_DOUBLE
+         sscanf(buf,"%lf%lf%lf\n",
+                    &MMgrad[i][XX],
+                    &MMgrad[i][YY],
+                    &MMgrad[i][ZZ]);
+    #else
+         sscanf(buf,"%f%f%f\n",
+                    &MMgrad[i][XX],
+                    &MMgrad[i][YY],
+                    &MMgrad[i][ZZ]);
+    #endif     
+     }
+     fclose(pcgrad);
+ }
+ return(QMener);  
+}
+
+void do_orca(int step,char *exe, char *basename)
+{
+
+ /* make the call to the orca binary through system()
+  * The location of the binary is set through the
+  * environment.
+  */
+ char
+   buf[100];
+ sprintf(buf,"%s %s.inp >> %s.out",
+             "orca",
+             basename,
+             basename);
+ fprintf(stderr,"Calling '%s'\n",buf);
+ if ( system(buf) != 0 )
+     gmx_fatal(FARGS,"Call to '%s' failed\n",buf);
+}
+
+real call_orca(t_commrec *cr,  t_forcerec *fr, 
+                  t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[])
+{
+ /* normal orca jobs */
+ static int
+   step=0;
+ int
+   i,j;
+ real
+   QMener=0.0;
+ rvec
+   *QMgrad,*MMgrad;
+ char
+   *exe;
+
+ snew(exe,30);
+ sprintf(exe,"%s","orca");
+ snew(QMgrad,qm->nrQMatoms);
+ snew(MMgrad,mm->nrMMatoms);
+
+ write_orca_input(step,fr,qm,mm);
+ do_orca(step,exe,qm->orca_basename);
+ QMener = read_orca_output(QMgrad,MMgrad,step,fr,qm,mm);
+ /* put the QMMM forces in the force array and to the fshift
+  */
+ for(i=0;i<qm->nrQMatoms;i++){
+     for(j=0;j<DIM;j++){
+         f[i][j]      = HARTREE_BOHR2MD*QMgrad[i][j];
+         fshift[i][j] = HARTREE_BOHR2MD*QMgrad[i][j];
+     }
+ }
+ for(i=0;i<mm->nrMMatoms;i++){
+     for(j=0;j<DIM;j++){
+         f[i+qm->nrQMatoms][j]      = HARTREE_BOHR2MD*MMgrad[i][j];      
+         fshift[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j];
+     }
+ }
+ QMener = QMener*HARTREE2KJ*AVOGADRO;
+ step++;
+ free(exe);
+ return(QMener);
+} /* call_orca */
+
+/* end of orca sub routines */
index 07b6e24d1829a060c0021ab818cbb30bd779fb07..a7a085bc1b9bd696120292916751c40d1d2408e7 100644 (file)
@@ -107,6 +107,16 @@ real
 call_gaussian(t_commrec *cr,t_forcerec *fr, t_QMrec *qm,
               t_MMrec *mm,rvec f[], rvec fshift[]);
 
+#elif defined GMX_QMMM_ORCA
+/* ORCA interface */
+
+void 
+init_orca(t_commrec *cr ,t_QMrec *qm, t_MMrec *mm);
+
+real 
+call_orca(t_commrec *cr,t_forcerec *fr, t_QMrec *qm,
+              t_MMrec *mm,rvec f[], rvec fshift[]);
+
 #endif
 
 
@@ -186,8 +196,10 @@ real call_QMroutine(t_commrec *cr, t_forcerec *fr, t_QMrec *qm,
             QMener = call_gamess(cr,fr,qm,mm,f,fshift);
 #elif defined GMX_QMMM_GAUSSIAN
             QMener = call_gaussian(cr,fr,qm,mm,f,fshift);
+#elif defined GMX_QMMM_ORCA
+            QMener = call_orca(cr,fr,qm,mm,f,fshift);
 #else
-            gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess or Gaussian.");
+            gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
 #endif
         }
     }
@@ -213,8 +225,10 @@ void init_QMroutine(t_commrec *cr, t_QMrec *qm, t_MMrec *mm)
         init_gamess(cr,qm,mm);
 #elif defined GMX_QMMM_GAUSSIAN
         init_gaussian(cr,qm,mm);
+#elif defined GMX_QMMM_ORCA
+        init_orca(cr,qm,mm);
 #else
-        gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess or Gaussian.");   
+        gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");   
 #endif
     }
 } /* init_QMroutine */
@@ -685,13 +699,15 @@ void init_QMMMrec(t_commrec *cr,
     }
     else 
     { 
-        /* ab initio calculation requested (gamess/gaussian) */
+        /* ab initio calculation requested (gamess/gaussian/ORCA) */
 #ifdef GMX_QMMM_GAMESS
         init_gamess(cr,qr->qm[0],qr->mm);
 #elif defined GMX_QMMM_GAUSSIAN
         init_gaussian(cr,qr->qm[0],qr->mm);
+#elif defined GMX_QMMM_ORCA
+        init_orca(cr,qr->qm[0],qr->mm);
 #else
-        gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess or Gaussian.");
+        gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
 #endif
     }
   }
@@ -979,7 +995,7 @@ real calculate_QMMM(t_commrec *cr,
   real
     QMener=0.0;
   /* a selection for the QM package depending on which is requested
-   * (Gaussian, GAMESS-UK or MOPAC) needs to be implemented here. Now
+   * (Gaussian, GAMESS-UK, MOPAC or ORCA) needs to be implemented here. Now
    * it works through defines.... Not so nice yet 
    */
   t_QMMMrec
index 12425d89b8c2ab9a074fd6e605dfb5de4677ddf6..4c2a134245e14a8fab3071f236c00853d5c74de4 100644 (file)
@@ -440,9 +440,9 @@ gmx_mdoutf_t *init_mdoutf(int nfile,const t_filenm fnm[],bool bAppendFiles,
 
     snew(of,1);
 
-    of->fp_trn   = -1;
+    of->fp_trn   = NULL;
     of->fp_ene   = NULL;
-    of->fp_xtc   = -1;
+    of->fp_xtc   = NULL;
     of->fp_dhdl  = NULL;
     of->fp_field = NULL;
     
@@ -454,11 +454,13 @@ gmx_mdoutf_t *init_mdoutf(int nfile,const t_filenm fnm[],bool bAppendFiles,
         sprintf(filemode, bAppendFiles ? "a+" : "w+");  
         
         if (ir->eI != eiNM 
-            #ifndef GMX_FAHCORE
-            && (ir->nstxout > 0 ||
-             ir->nstvout > 0 ||
-             ir->nstfout > 0)
-            #endif
+#ifndef GMX_FAHCORE
+            &&
+            !(EI_DYNAMICS(ir->eI) &&
+              ir->nstxout == 0 &&
+              ir->nstvout == 0 &&
+              ir->nstfout == 0)
+#endif
            )
         {
             of->fp_trn = open_trn(ftp2fn(efTRN,nfile,fnm), filemode);
@@ -511,11 +513,11 @@ void done_mdoutf(gmx_mdoutf_t *of)
     {
         close_enx(of->fp_ene);
     }
-    if (of->fp_xtc >= 0)
+    if (of->fp_xtc)
     {
         close_xtc(of->fp_xtc);
     }
-    if (of->fp_trn >= 0)
+    if (of->fp_trn)
     {
         close_trn(of->fp_trn);
     }
index 2f32c1a57dc429c3fa1aa739e1f57c67b99ab02a..bd3e5d4698a61eecb5e1855c69869542c1e2d46f 100644 (file)
@@ -846,7 +846,6 @@ t_forcetable make_tables(FILE *out,const output_env_t oenv,
   bool        b14only,bReadTab,bGenTab;
   real        x0,y0,yp;
   int         i,j,k,nx,nx0,tabsel[etiNR];
-  void *      p_tmp;
   
   t_forcetable table;
 
@@ -909,21 +908,11 @@ t_forcetable make_tables(FILE *out,const output_env_t oenv,
   }
 
   /* Each table type (e.g. coul,lj6,lj12) requires four 
-   * numbers per datapoint. For performance reasons we want
-   * the table data to be aligned to 16-byte. This is accomplished
-   * by allocating 16 bytes extra to a temporary pointer, and then
-   * calculating an aligned pointer. This new pointer must not be
-   * used in a free() call, but thankfully we're sloppy enough not
-   * to do this :-)
+   * numbers per nx+1 data points. For performance reasons we want
+   * the table data to be aligned to 16-byte.
    */
+  snew_aligned(table.tab, 12*(nx+1)*sizeof(real),16);
 
-  /* 12 fp entries per table point, nx+1 points, and 16 bytes extra to align it. */
-  p_tmp = malloc(12*(nx+1)*sizeof(real)+16);
-  
-  /* align it - size_t has the same same as a pointer */
-  table.tab = (real *) (((size_t) p_tmp + 16) & (~((size_t) 15)));  
-  
-  
   for(k=0; (k<etiNR); k++) {
     if (tabsel[k] != etabUSER) {
       init_table(out,nx,nx0,
index 78bb75043a04e4521bcbb0291759c9f479373836..25d33099a485ccc563b6618105d3eeff89b9115e 100644 (file)
@@ -131,7 +131,7 @@ double do_tpi(FILE *fplog,t_commrec *cr,
   rvec   *f;
   real   lambda,t,temp,beta,drmax,epot;
   double embU,sum_embU,*sum_UgembU,V,V_all,VembU_all;
-  int    status;
+  t_trxstatus   *status;
   t_trxframe rerun_fr;
   bool   bDispCorr,bCharge,bRFExcl,bNotLastFrame,bStateChanged,bNS,bOurStep;
   tensor force_vir,shake_vir,vir,pres;
index ae648b868ca5f11197fbf99b77f874edbb7fc73d..92839b8d25dc59a26a4452ba75a86e069a5af4d2 100644 (file)
@@ -391,7 +391,7 @@ static void HandleClient(t_x11 *x11,t_manager *man,long data[])
     draw_mol(x11,man);
     break;
   case IDREWIND:
-    if (man->status != -1) {
+    if (man->status) {
       rewind_trj(man->status);
       read_next_x(man->oenv,man->status,&(man->time),man->natom,man->x,
                   man->box);
@@ -547,7 +547,7 @@ void map_man(t_x11 *x11,t_manager *man)
 
 bool toggle_animate (t_x11 *x11,t_manager *man)
 { 
-  if (man->status != -1) {
+  if (man->status) {
     man->bAnimate=!man->bAnimate;
     man->bStop=TRUE;
     man->bEof=FALSE;
@@ -576,7 +576,7 @@ t_manager *init_man(t_x11 *x11,Window Parent,
   t_manager *man;
 
   snew(man,1);
-  man->status=-1;
+  man->status=NULL;
   man->bPlus=TRUE;
   man->bSort=TRUE;
   man->oenv=oenv;
index 0c13baa3da2f30a0412f860aed93d98220414105..4f961e192a38b7c49bc09dd89027a746f4ec1939 100644 (file)
@@ -43,6 +43,7 @@
 #include "3dview.h"
 #include "nleg.h"
 #include "buttons.h"
+#include "statutil.h"
 
 /* Some window sizes */
 #define EWIDTH         200
@@ -91,7 +92,7 @@ typedef struct {
  *
  */
 typedef struct {
-  int       status;
+  t_trxstatus *status;
   const char  *trajfile;
   int       natom;             /* The number of atoms                  */
   t_topology top;               /* topology                             */
index 870f5b5e5cd06f040a201783b992b6e93d7cb9fe..afcf0ee0cf1ad9792a88bac61ac14c92953fe776 100644 (file)
@@ -209,7 +209,7 @@ void ps_draw_mol(t_psdata ps,t_manager *man)
   real      sx,sy;
   vec4      x4;
 
-  if (man->status == -1)
+  if (!man->status)
     return;
 
   view=man->view;
index 9175d00c23151b61647eb7cccbe42af6b29592d0..a2234f82d31753715f91a9cbc39fcaef07c11eaa 100644 (file)
@@ -358,7 +358,7 @@ void init_gmx(t_x11 *x11,char *program,int nfile,t_filenm fnm[],
   int                  ePBC;
   matrix               box;
   t_trxframe           fr;
-  int                  status;
+  t_trxstatus          *status;
   char                 quote[256];
   
   snew(gmx,1);
index a4399a9d4592a0c241ddb3a3a37ec9f094940816..d13d20fb26c60e4e49eab5cfd84ef5dd669df50e 100644 (file)
@@ -495,7 +495,7 @@ void draw_mol(t_x11 *x11,t_manager *man)
   real      sx,sy;
   vec4      x4;
 
-  if (man->status == -1)
+  if (!man->status)
     return;
 
   view=man->view;
index fbe24534bad5f64054da4d8be66ac19544e3f0e4..998997b8d0b08eba2f65ead924f0c81265c2727f 100644 (file)
@@ -28,7 +28,8 @@ add_library(gmxana
             gmx_trjconv.c   gmx_trjcat.c    gmx_trjorder.c  gmx_xpm2ps.c    
             gmx_editconf.c  gmx_genbox.c    gmx_genion.c    gmx_genconf.c   
             gmx_genpr.c     gmx_eneconv.c   gmx_vanhove.c   gmx_wheel.c     
-            addconf.c       calcpot.c       edittop.c       gmx_bar.c)
+            addconf.c       calcpot.c       edittop.c       gmx_bar.c
+            gmx_membed.c    )
 
 target_link_libraries(gmxana md ${GMX_EXTRA_LIBRARIES})
 set_target_properties(gmxana PROPERTIES OUTPUT_NAME "gmxana${GMX_BINARY_SUFFIX}")
@@ -49,6 +50,7 @@ set(GMX_TOOLS_PROGRAMS
     g_rmsf g_rotacf g_saltbr g_sas g_select g_sgangle g_sham g_sorient
     g_spol g_sdf g_spatial g_tcaf g_traj g_tune_pme g_vanhove
     g_velacc g_clustsize g_mdmat g_wham g_kinetics g_sigeps g_bar
+    g_membed
     )
 
 
index 9ac6f174377b77ee6af54a2c284954c57926dcd7..069673b5a6d7e9f7bc1b9fac3a453e7cbe4fa7d2 100644 (file)
@@ -662,7 +662,8 @@ void read_ang_dih(const char *trj_fn,
                   const output_env_t oenv)
 {
   t_pbc      *pbc;
-  int        i,angind,status,natoms,total,teller;
+  t_trxstatus *status;
+  int        i,angind,natoms,total,teller;
   int        nangles,n_alloc;
   real       t,fraction,pifac,aa,angle;
   real       *angles[2];
index 5eea87d62e5b1872e55215a584adf8fad3c0ffe8..a20fdee4b517623d303c3a19f917e31ef4828b4e 100644 (file)
@@ -375,7 +375,7 @@ int main(int argc,char *argv[])
       "Secondary structures for structure count"}
   };
   
-  int        status;
+  t_trxstatus *status;
   FILE       *tapein;
   FILE       *ss,*acc,*fTArea,*tmpf;
   const char *fnSCount,*fnArea,*fnTArea,*fnAArea;
index 74753ad59f80326708d9a6ef41bf3267e0cae461..3faba70c9fb49145e204fd3df356d126265f54af 100644 (file)
@@ -41,6 +41,7 @@
 #include "eigio.h"
 #include "trnio.h"
 #include "tpxio.h"
+#include "statutil.h"
 #include "futil.h"
 
 void read_eigenvectors(const char *file,int *natoms,bool *bFit,
@@ -50,7 +51,8 @@ void read_eigenvectors(const char *file,int *natoms,bool *bFit,
                        rvec ***eigvec,real **eigval)
 {
   t_trnheader head;
-  int    status,i,snew_size;
+  int    i,snew_size;
+  t_fileio *status;
   rvec   *x;
   matrix box;
   bool   bOK;
@@ -141,7 +143,7 @@ void write_eigenvectors(const char *trnname,int natoms,real mat[],
                         int WriteXref,rvec *xref,bool bDMR,
                         rvec xav[], bool bDMA,real eigval[])
 {
-    int    trnout;
+    t_fileio *trnout;
     int    ndim,i,j,d,vec;
     matrix zerobox;
     rvec   *x;
index ac26a9f9d03775f26f0a413cca86c481ea639f94..33022bd14fcbf0e2cd629992fec3fb206dd34f4c 100644 (file)
@@ -405,7 +405,9 @@ static void project(const char *trajfile,t_topology *top,int ePBC,matrix topbox,
                     const output_env_t oenv)
 {
   FILE    *xvgrout=NULL;
-  int     status,out=0,nat,i,j,d,v,vec,nfr,nframes=0,snew_size,frame;
+  int     nat,i,j,d,v,vec,nfr,nframes=0,snew_size,frame;
+  t_trxstatus *out=NULL;
+  t_trxstatus *status;
   int     noutvec_extr,*imin,*imax;
   atom_id *all_at;
   matrix  box;
@@ -486,7 +488,7 @@ static void project(const char *trajfile,t_topology *top,int ePBC,matrix topbox,
       }
       nfr++;
     } while (read_next_x(oenv,status,&t,nat,xread,box));
-    close_trj(status);
+    close_trj(out);
      sfree(x);
      if (filterfile)
        close_trx(out);
index 96ad80e2c976128c0171fc542d34c0baaf00c213..c44cff85441c4a6e5d38f08892660ac33741dc34 100644 (file)
@@ -58,7 +58,8 @@
 static void dump_dih_trn(int nframes,int nangles,real **dih,const char *fn,
                          real dt)
 {
-  int    i,j,k,l,m,na,trn;
+  int    i,j,k,l,m,na;
+  t_fileio *trn;
   rvec   *x;
   matrix box = {{2,0,0},{0,2,0},{0,0,2}};  
   
index 9bd1197c8173d250ab3591d92b0d667f4e9a8691..6d067518acbfe52f335fc4394daa6bad956f6b7e 100644 (file)
@@ -93,7 +93,8 @@ static void do_bonds(FILE *log,const char *fn,const char *fbond,
     int    counter;*/
   rvec   *x;
   rvec   dx;
-  int    status,natoms;
+  t_trxstatus *status;
+  int    natoms;
   matrix box;
   real   t,fac;
   int    bind,i,nframes,i0,i1;
index e7a47aec181511be5bb23c9616db5c8b24223096..5ea38694f71bc97ae73da925aa1bcbf4c6d284f3 100644 (file)
@@ -135,7 +135,8 @@ static void calc_axes(rvec x[],t_atom atom[],int gnx[],atom_id *index[],
   }
 }
 
-static void dump_axes(int fp,t_trxframe *fr,t_atoms *outat,t_bundle *bun)
+static void dump_axes(t_trxstatus *status,t_trxframe *fr,t_atoms *outat,
+                      t_bundle *bun)
 {
   t_trxframe  frout;
   static rvec *xout=NULL;
@@ -160,7 +161,7 @@ static void dump_axes(int fp,t_trxframe *fr,t_atoms *outat,t_bundle *bun)
   frout.natoms = outat->nr;
   frout.atoms  = outat;
   frout.x      = xout;
-  write_trxframe(fp,&frout,NULL);
+  write_trxframe(status,&frout,NULL);
 }
 
 int gmx_bundle(int argc,char *argv[])
@@ -198,7 +199,8 @@ int gmx_bundle(int argc,char *argv[])
   };
   FILE       *out,*flen,*fdist,*fz,*ftilt,*ftiltr,*ftiltl;
   FILE       *fkink=NULL,*fkinkr=NULL,*fkinkl=NULL;
-  int        status,fpdb;
+  t_trxstatus *status;
+  t_trxstatus *fpdb;
   t_topology top;
   int        ePBC;
   rvec       *xtop;
@@ -302,7 +304,7 @@ int gmx_bundle(int argc,char *argv[])
     }
     fpdb = open_trx(opt2fn("-oa",NFILE,fnm),"w");
   } else
-    fpdb = -1;
+    fpdb = NULL;
   
   read_first_frame(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&fr,TRX_NEED_X); 
   
@@ -361,13 +363,13 @@ int gmx_bundle(int argc,char *argv[])
       fprintf(fkinkr,"\n");
       fprintf(fkinkl,"\n");
     }
-    if (fpdb >= 0)
+    if (fpdb )
       dump_axes(fpdb,&fr,&outatoms,&bun);
   } while(read_next_frame(oenv,status,&fr));
 
   close_trx(status);
   
-  if (fpdb >= 0)
+  if (fpdb )
     close_trx(fpdb);
   ffclose(flen);
   ffclose(fdist);
index 6b64474469b529cc66b85b27b9f5200d43200770..8a62ce7d87f0e1820441437d9cb8a1d6ce14c0f0 100644 (file)
@@ -555,7 +555,9 @@ rvec **read_whole_trj(const char *fn,int isize,atom_id index[],int skip,
   matrix box;
   real   t;
   int    i,i0,j,max_nf;
-  int    status,natom;
+  int    natom;
+  t_trxstatus *status;
+
   
   max_nf = 0;
   xx     = NULL;
@@ -735,7 +737,8 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd,
 {
   FILE *fp=NULL;
   char buf[STRLEN],buf1[40],buf2[40],buf3[40],*trxsfn;
-  int  trxout=0,trxsout=0;
+  t_trxstatus *trxout=NULL;
+  t_trxstatus *trxsout=NULL;
   int  i,i1,cl,nstr,*structure,first=0,midstr;
   bool *bWrite=NULL;
   real r,clrmsd,midrmsd;
@@ -776,7 +779,7 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd,
   
     /* Prepare a reference structure for the orientation of the clusters  */
     if (bFit)
-    reset_x(ifsize,fitidx,natom,NULL,xtps,mass);
+        reset_x(ifsize,fitidx,natom,NULL,xtps,mass);
     trxout = open_trx(trxfn,"w");
     /* Calculate the average structure in each cluster,               *
      * all structures are fitted to the first struture of the cluster */
index ecb50f518daebfd157f4ecc15ce3a64ac5f58a0c..df41652dfd978d6f1e11abd0bda9df7320488c99 100644 (file)
@@ -75,7 +75,8 @@ static void clust_size(const char *ndx,const char *trx,const char *xpm,
 {
   FILE    *fp,*gp,*hp,*tp;
   atom_id *index=NULL;
-  int     nindex,natoms,status;
+  int     nindex,natoms;
+  t_trxstatus *status;
   rvec    *x=NULL,*v=NULL,dx;
   t_pbc   pbc;
   char    *gname;
index 57ee9ca47132522b6b19ed185f1c9dfb2ff7f835..f0cbccd53372d35c69986858ae7f3388652ccfa9 100644 (file)
@@ -112,7 +112,8 @@ int gmx_covar(int argc,char *argv[])
       "Apply corrections for periodic boundary conditions" }
   };
   FILE       *out;
-  int        status,trjout;
+  t_trxstatus *status;
+  t_trxstatus *trjout;
   t_topology top;
   int        ePBC;
   t_atoms    *atoms;  
index 93f275a91321842cac52e4083a336e4f2993e4cb..a76dfbad2961c18ff4c15d99ea789941d212376b 100644 (file)
@@ -288,7 +288,7 @@ static void dielectric(FILE *fmj,FILE *fmd,FILE *outf,FILE *fcur,FILE *mcor,
                        FILE *fmjdsp, bool bNoJump,bool bACF,bool bINT,
                        int ePBC,t_topology top, t_trxframe fr,real temp,
                        real trust,real bfit,real efit,real bvit,real evit,
-                      int status,int isize,int nmols, int nshift,
+                      t_trxstatus *status,int isize,int nmols, int nshift,
                        atom_id *index0,int indexm[],real mass2[],
                        real qmol[], real eps_rf, const output_env_t oenv)
 {
@@ -705,7 +705,7 @@ int gmx_current(int argc,char *argv[])
   atom_id    *index0=NULL;
   int                                  *indexm=NULL;
   int        isize;
-  int        status;
+  t_trxstatus *status;
   int        flags = 0;
   bool      bTop;
   bool          bNEU;
index 2b2662831aef407e77dfa3a4d6081e78d89b60e2..c771e8a06e05878687157d292783e5e294c651a7 100644 (file)
@@ -149,9 +149,9 @@ void calc_electron_density(const char *fn, atom_id **index, int gnx[],
 {
   rvec *x0;              /* coordinates without pbc */
   matrix box;            /* box (3x3) */
-  int natoms,            /* nr. atoms in trj */
-      status,  
-      i,n,               /* loop indices */
+  int natoms;            /* nr. atoms in trj */
+  t_trxstatus *status;  
+  int i,n,               /* loop indices */
       ax1=0, ax2=0,
       nr_frames = 0,     /* number of frames */
       slice;             /* current slice */
@@ -251,9 +251,9 @@ void calc_density(const char *fn, atom_id **index, int gnx[],
 {
   rvec *x0;              /* coordinates without pbc */
   matrix box;            /* box (3x3) */
-  int natoms,            /* nr. atoms in trj */
-      status,  
-      **slCount,         /* nr. of atoms in one slice for a group */
+  int natoms;            /* nr. atoms in trj */
+  t_trxstatus *status;  
+  int  **slCount,         /* nr. of atoms in one slice for a group */
       i,j,n,               /* loop indices */
       teller = 0,      
       ax1=0, ax2=0,
index 4394116bf835022f0117d3e070a61d931fde6d4d..1a4c5406433ace25ca83bd1e2d9083e35ccb17c3 100644 (file)
@@ -134,7 +134,7 @@ int gmx_densmap(int argc,char *argv[])
   };
   bool       bXmin,bXmax,bRadial;
   FILE       *fp;
-  int        status;
+  t_trxstatus *status;
   t_topology top;
   int        ePBC=-1;
   rvec       *x,xcom[2],direction,center,dx;
index 002248a9baee812ba7633897d5e5cdc3f0c19e46..6e73fdf775c448e5f4cfcd74724964f0fa11e403 100644 (file)
@@ -673,7 +673,8 @@ static void do_dip(t_topology *top,int ePBC,real volume,
   t_enxframe *fr;
   int        nframes=1000,nre,timecheck=0,ncolour=0;
   ener_file_t fmu=NULL;
-  int        i,j,k,n,m,natom=0,nmol,status,gnx_tot,teller,tel3;
+  int        i,j,k,n,m,natom=0,nmol,gnx_tot,teller,tel3;
+  t_trxstatus *status;
   int        *dipole_bin,ndipbin,ibin,iVol,step,idim=-1;
   unsigned long mode;
   char       buf[STRLEN];
index 47d9335cf69fa4eb79d4bf928739621cd20d0655..62c013a753d6f65cd593d95a126470d5259186be 100644 (file)
@@ -588,7 +588,8 @@ int gmx_disre(int argc,char *argv[])
   t_nrnb      nrnb;
   t_commrec   *cr;
   t_graph     *g;
-  int         status,ntopatoms,natoms,i,j,kkk;
+  int         ntopatoms,natoms,i,j,kkk;
+  t_trxstatus *status;
   real        t;
   rvec        *x,*f,*xav=NULL;
   matrix      box;
index 744c7bcffb43b54a91341914cb6ee76c437e4629..12726592ae01aef9275d6e7510fb3a910eb3f3a1 100644 (file)
@@ -87,7 +87,7 @@ int gmx_dist(int argc,char *argv[])
   real t,t0,cut2,dist2;
   rvec *x=NULL,*v=NULL,dx;
   matrix box;
-  int status;
+  t_trxstatus *status;
   int natoms;
 
   int g,d,i,j,res,teller=0;
index 0390c5c0177cfd4e11028439d150b47d71941950..356776c29d090945caa74e36c614291fefcac3fd 100644 (file)
@@ -167,7 +167,8 @@ int gmx_dyndom(int argc,char *argv[])
     { "-tail",     FALSE, etRVEC, {tail},
       "Last atom of the arrow vector" }
   };
-  int     i,j,natoms,isize,status;
+  int     i,j,natoms,isize;
+  t_trxstatus *status;
   atom_id *index=NULL,*index_all;
   char    title[256],*grpname;
   t_atoms atoms;
index 769bcef984c6de9561674322463f2937988f4d1e..f94a3dbf1c75a7d8c713436d63571a0b5081a1ed 100644 (file)
@@ -425,7 +425,7 @@ static void update_ee_sum(int nre,
     }
     nsteps = fr->nsteps;
     nsum   = fr_nsum;
-  } else if (out_step - *ee_sum_step == nsteps + fr->nsteps) {
+  } else if (out_step + *ee_sum_nsum - *ee_sum_step == nsteps + fr->nsteps) {
     if (fr_nsum == 1) {
       for(i=0;i<nre;i++) {
        ee_sum[i].eav  +=
@@ -661,7 +661,8 @@ int gmx_eneconv(int argc,char *argv[])
        if (ee_sum_nsum <= 1) {
          fro->nsum = 0;
        } else {
-         fro->nsum = ee_sum_nsum;
+         fro->nsum = gmx_large_int_to_int(ee_sum_nsum,
+                                          "energy average summation");
          /* Copy the energy sums */
          for(i=0; i<nre; i++) {
            fro->ener[i].esum = ee_sum[i].esum;
index c07deeed82fc93c556dde985c942379c34fe5b74..75aff3881fe178c24c8e4fb55ef21cacbe2f5f5f 100644 (file)
@@ -102,7 +102,8 @@ int gmx_filter(int argc,char *argv[])
   int        isize;
   atom_id    *index;
   real       *w_rls=NULL;
-  int        in,outl,outh;
+  t_trxstatus *in;
+  t_trxstatus *outl,*outh;
   int        nffr,i,fr,nat,j,d,m;
   atom_id    *ind;
   real       flen,*filt,sum,*t;
index fce46cb77723a4d36f7261404eecb4ae41b4edae..08932cc60761af5652708f53ad694dea4c83e6dd 100644 (file)
@@ -137,7 +137,8 @@ int gmx_genconf(int argc, char *argv[])
   rvec    shift;         
   int     natoms;       /* number of atoms in one molecule  */
   int     nres;         /* number of molecules? */
-  int     i,j,k,l,m,ndx,nrdx,nx,ny,nz,status=-1;
+  int     i,j,k,l,m,ndx,nrdx,nx,ny,nz;
+  t_trxstatus *status;
   bool    bTRX;
   output_env_t oenv;
   
index 7798c63f64683a8e14aa6e9c2b32d089a90b9e44..c2afb3f0578c00b57a1e8bf545833946349d06a0 100644 (file)
@@ -175,7 +175,7 @@ int gmx_gyrate(int argc,char *argv[])
       "Calculate the 2D radii of gyration of # slices along the z-axis" },
   };
   FILE       *out;
-  int        status;
+  t_trxstatus *status;
   t_topology top;
   int        ePBC;
   rvec       *x,*x_s;
index 1244baea2ef4b86ae2996c271671a0d02a84fb6c..a93c98e0c3584f87ea83cb1c2dac54dfe51260d2 100644 (file)
@@ -76,7 +76,7 @@ void calc_h2order(const char *fn, atom_id index[], int ngx, rvec **slDipole,
        com;              /* center of mass of micel, with bMicel */
   rvec *dip;             /* sum of dipoles, unnormalized */
   matrix box;            /* box (3x3) */
-  int   status;
+  t_trxstatus *status;
   real  t,               /* time from trajectory */
        *sum,             /* sum of all cosines of dipoles, per slice */
        *frame;           /* order over one frame */
index 34301c938625b09488f1ca9569c9412c92efa1b7..e5b6f1d1706f491bf7bc48f45b37701996541343 100644 (file)
@@ -3262,7 +3262,8 @@ int gmx_hbond(int argc,char *argv[])
     char *hbdesc[HB_NR]={ "None", "Present", "Inserted", "Present & Inserted" };
     t_rgb hbrgb [HB_NR]={ {1,1,1},{1,0,0},   {0,0,1},    {1,0,1} };
 
-    int     status, trrStatus=1;
+    t_trxstatus *status;
+    int trrStatus=1;
     t_topology top;
     t_inputrec ir;
     t_pargs *ppa;
index 7a19935ec24a6d2aec00d334f7fb298564d47aba..1683c57dbdce79130e9d6389c521ed2a7e62f659 100644 (file)
@@ -211,7 +211,7 @@ int gmx_helix(int argc,char *argv[])
   output_env_t oenv;
   FILE       *otrj;
   char       buf[54],prop[256];
-  int        status;
+  t_trxstatus *status;
   int        natoms,nre,nres;
   t_bb       *bb;
   int        i,j,ai,m,nall,nbb,nca,teller,nSel=0;
index 935bded7762a31a4e1778986bc465eee1f797fb1..4768f8a780b0db1ffa21777a155f6dd74416ef85 100644 (file)
@@ -80,7 +80,7 @@ int gmx_helixorient(int argc,char *argv[])
     real t;
     rvec *x=NULL,dx;
     matrix box;
-    int status;
+    t_trxstatus *status;
     int natoms;
     real theta1,theta2,theta3;
 
index ab3af2fe3a89b434a684d7d9353500016734e6fa..54e56444432bbc4b7ce0b9c8800725394c84ccd0 100644 (file)
@@ -190,7 +190,8 @@ int gmx_mdmat(int argc,char *argv[])
   char       *grpname;
   int        *rndx,*natm,prevres,newres;
   
-  int        i,j,status,nres,natoms,nframes,it,trxnat;
+  int        i,j,nres,natoms,nframes,it,trxnat;
+  t_trxstatus *status;
   int        nr0;
   bool       bCalcN,bFrames;
   real       t,ratio;
index 4df830423288a8ed19c9d5a509a773e691c75354..3042bcd7736b68a30f0ed85a45b0f5f3e108d4b9 100644 (file)
@@ -133,8 +133,8 @@ typedef struct {
        int             id;
        char    *name;
        int     nr;
-       int     natoms;                 //nr of atoms per lipid
-       int             mol1;                   //id of the first lipid molecule
+       int     natoms;     /*nr of atoms per lipid*/
+       int     mol1;       /*id of the first lipid molecule*/
        real    area;
 } lip_t;
 
@@ -208,37 +208,38 @@ int get_type(int mol_id,int nmblock,gmx_molblock_t *mblock)
        return -1;
 }
 
-int get_tpr_version(char *infile)
+int get_tpr_version(const char *infile)
 {
        char    buf[STRLEN];
        bool    bDouble;
-       int     precision,fver,fp;
+       int     precision,fver;
+        t_fileio *fio;
        bool    bRead=TRUE;
 
-       fp = open_tpx(infile,"r");
-       gmx_fio_select(fp);
+       fio = open_tpx(infile,"r");
+       gmx_fio_checktype(fio);
 
        precision = sizeof(real);
 
-       do_string(buf);
+       gmx_fio_do_string(fio,buf);
        if (strncmp(buf,"VERSION",7))
                gmx_fatal(FARGS,"Can not read file %s,\n"
                                "             this file is from a Gromacs version which is older than 2.0\n"
                                "             Make a new one with grompp or use a gro or pdb file, if possible",
-                               gmx_fio_getname(fp));
-       do_int(precision);
+                               gmx_fio_getname(fio));
+       gmx_fio_do_int(fio,precision);
        bDouble = (precision == sizeof(double));
        if ((precision != sizeof(float)) && !bDouble)
                gmx_fatal(FARGS,"Unknown precision in file %s: real is %d bytes "
                                "instead of %d or %d",
-                               gmx_fio_getname(fp),precision,sizeof(float),sizeof(double));
-       gmx_fio_setprecision(fp,bDouble);
+                               gmx_fio_getname(fio),precision,sizeof(float),sizeof(double));
+       gmx_fio_setprecision(fio,bDouble);
        fprintf(stderr,"Reading file %s, %s (%s precision)\n",
-                       gmx_fio_getname(fp),buf,bDouble ? "double" : "single");
+                       gmx_fio_getname(fio),buf,bDouble ? "double" : "single");
 
-       do_int(fver);
+       gmx_fio_do_int(fio,fver);
 
-       close_tpx(fp);
+       close_tpx(fio);
 
        return fver;
 }
@@ -262,7 +263,8 @@ void set_inbox(int natom, rvec *x)
 
 int get_mtype_list(t_block *at, gmx_mtop_t *mtop, t_block *tlist)
 {
-       int i,j,nr,mol_id,type;
+       int i,j,nr,mol_id;
+        int type=0;
        bool bNEW;
 
        nr=0;
@@ -366,7 +368,7 @@ int init_ins_at(t_block *ins_at,t_block *rest_at,t_state *state, pos_ins_t *pos_
                pos_ins->xmax[YY]=ymax;
        }
 
-       // 6.0 is estimated thickness of bilayer
+       /* 6.0 is estimated thickness of bilayer */
        if( (zmax-zmin) < 6.0 )
        {
                pos_ins->xmin[ZZ]=zmin+(zmax-zmin)/2.0-3.0;
@@ -438,12 +440,12 @@ int init_mem_at(mem_t *mem_p, gmx_mtop_t *mtop, rvec *r, matrix box, pos_ins_t *
        real z,zmin,zmax,mem_area;
        bool bNew;
        atom_id *mol_id;
-       int type;
+       int type=0;
 
        nmol=count=0;
        mem_a=&(mem_p->mem_at);
        snew(mol_id,mem_a->nr);
-//     snew(index,mem_a->nr);
+/*     snew(index,mem_a->nr); */
        zmin=pos_ins->xmax[ZZ];
        zmax=pos_ins->xmin[ZZ];
        for(i=0;i<mem_a->nr;i++)
@@ -470,7 +472,7 @@ int init_mem_at(mem_t *mem_p, gmx_mtop_t *mtop, rvec *r, matrix box, pos_ins_t *
                        if(z<zmin)                                      zmin=z;
                        if(z>zmax)                                      zmax=z;
 
-//                     index[count]=at;
+/*                     index[count]=at;*/
                        count++;
                }
        }
@@ -478,10 +480,10 @@ int init_mem_at(mem_t *mem_p, gmx_mtop_t *mtop, rvec *r, matrix box, pos_ins_t *
        mem_p->nmol=nmol;
        srenew(mol_id,nmol);
        mem_p->mol_id=mol_id;
-//     srenew(index,count);
-//     mem_p->mem_at.nr=count;
-//     sfree(mem_p->mem_at.index);
-//     mem_p->mem_at.index=index;
+/*     srenew(index,count);*/
+/*     mem_p->mem_at.nr=count;*/
+/*     sfree(mem_p->mem_at.index);*/
+/*     mem_p->mem_at.index=index;*/
 
        if((zmax-zmin)>(box[ZZ][ZZ]-0.5))
                gmx_fatal(FARGS,"Something is wrong with your membrane. Max and min z values are %f and %f.\n"
@@ -492,7 +494,7 @@ int init_mem_at(mem_t *mem_p, gmx_mtop_t *mtop, rvec *r, matrix box, pos_ins_t *
        mem_p->zmax=zmax;
        mem_p->zmed=(zmax-zmin)/2+zmin;
 
-       //number of membrane molecules in protein box
+       /*number of membrane molecules in protein box*/
        nmolbox = count/mtop->molblock[type].natoms_mol;
        /*mem_area = box[XX][XX]*box[YY][YY]-box[XX][YY]*box[YY][XX];
        mem_p->lip_area = 2.0*mem_area/(double)mem_p->nmol;*/
@@ -561,11 +563,14 @@ void resize(t_block *ins_at, rvec *r_ins, rvec *r, pos_ins_t *pos_ins,rvec fac)
 int gen_rm_list(rm_t *rm_p,t_block *ins_at,t_block *rest_at,t_pbc *pbc, gmx_mtop_t *mtop,
                rvec *r, rvec *r_ins, mem_t *mem_p, pos_ins_t *pos_ins, real probe_rad, int low_up_rm, bool bALLOW_ASYMMETRY)
 {
-       int i,j,k,l,at,at2,mol_id,type;
+       int i,j,k,l,at,at2,mol_id;
+        int type=0;
        int nrm,nupper,nlower;
        real r_min_rad,z_lip,min_norm;
        bool bRM;
        rvec dr,dr_tmp;
+       real *dist;
+       int *order;
 
        r_min_rad=probe_rad*probe_rad;
        snew(rm_p->mol,mtop->mols.nr);
@@ -589,7 +594,7 @@ int gen_rm_list(rm_t *rm_p,t_block *ins_at,t_block *rest_at,t_pbc *pbc, gmx_mtop
                                                bRM=FALSE;
                                if(bRM)
                                {
-                                       //fprintf(stderr,"%d wordt toegevoegd\n",mol_id);
+                                       /*fprintf(stderr,"%d wordt toegevoegd\n",mol_id);*/
                                        rm_p->mol[nrm]=mol_id;
                                        rm_p->type[nrm]=type;
                                        nrm++;
@@ -612,9 +617,7 @@ int gen_rm_list(rm_t *rm_p,t_block *ins_at,t_block *rest_at,t_pbc *pbc, gmx_mtop
                }
        }
 
-       real *dist;
-       int *order;
-       //make sure equal number of lipids from upper and lower layer are removed
+       /*make sure equal number of lipids from upper and lower layer are removed */
        if( (nupper!=nlower) && (!bALLOW_ASYMMETRY) )
        {
                snew(dist,mem_p->nmol);
@@ -851,7 +854,7 @@ int rm_bonded(t_block *ins_at, gmx_mtop_t *mtop)
        return rm_at;
 }
 
-void top_update(char *topfile, char *ins, rm_t *rm_p, gmx_mtop_t *mtop)
+void top_update(const char *topfile, char *ins, rm_t *rm_p, gmx_mtop_t *mtop)
 {
 #define TEMP_FILENM "temp.top"
        bool    bMolecules=FALSE;
@@ -1810,14 +1813,15 @@ double do_md_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
     bool       bMasterState;
     int        force_flags,cglo_flags;
     tensor     force_vir,shake_vir,total_vir,tmp_vir,pres;
-    int        i,m,status;
+    int        i,m;
+    t_trxstatus *status;
     rvec       mu_tot;
     t_vcm      *vcm;
     t_state    *bufstate=NULL;
     matrix     *scale_tot,pcoupl_mu,M,ebox;
     gmx_nlheur_t nlh;
     t_trxframe rerun_fr;
-//    gmx_repl_ex_t repl_ex=NULL;
+/*    gmx_repl_ex_t repl_ex=NULL;*/
     int        nchkpt=1;
 
     gmx_localtop_t *top;
@@ -1849,7 +1853,7 @@ double do_md_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
     int         a0,a1,gnx=0,ii;
     atom_id     *grpindex=NULL;
     char        *grpname;
-//    t_coupl_rec *tcr=NULL;
+/*    t_coupl_rec *tcr=NULL; */
     rvec        *xcopy=NULL,*vcopy=NULL,*cbuf=NULL;
     matrix      boxcopy={{0}},lastbox;
        tensor      tmpvir;
@@ -2833,7 +2837,7 @@ double do_md_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
         if (do_per_step(step,ir->nstvout)) { mdof_flags |= MDOF_V; }
         if (do_per_step(step,ir->nstfout)) { mdof_flags |= MDOF_F; }
         if (do_per_step(step,ir->nstxtcout)) { mdof_flags |= MDOF_XTC; }
-//        if (bCPT) { mdof_flags |= MDOF_CPT; };
+/*        if (bCPT) { mdof_flags |= MDOF_CPT; };*/
 
 #ifdef GMX_FAHCORE
         if (MASTER(cr))
@@ -3577,20 +3581,20 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
 
 
        char                    *ins;
-       int                             rm_bonded_at,fr_id,fr_i,tmp_id,warn=0;
+       int                     rm_bonded_at,fr_id,fr_i=0,tmp_id,warn=0;
        int                     ng,j,max_lip_rm,ins_grp_id,ins_nat,mem_nat,ntype,lip_rm,tpr_version;
-       real                    xy_step,z_step;
+       real                    xy_step=0,z_step=0;
        real                    prot_area;
-       rvec                    *r_ins,fac;
+       rvec                    *r_ins=NULL,fac;
        t_block                 *ins_at,*rest_at;
        pos_ins_t               *pos_ins;
        mem_t                   *mem_p;
        rm_t                    *rm_p;
-       gmx_groups_t    *groups;
+       gmx_groups_t            *groups;
        bool                    bExcl=FALSE;
        t_atoms                 atoms;
        t_pbc                   *pbc;
-       char            **piecename;
+       char                    **piecename=NULL;
 
     /* CAUTION: threads may be started later on in this function, so
        cr doesn't reflect the final parallel state right now */
@@ -3665,14 +3669,14 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                pos_ins->pieces=pieces;
                snew(pos_ins->nidx,pieces);
                snew(pos_ins->subindex,pieces);
-               snew(piecename,pieces);
+               snew(piecename,pieces); 
                if (pieces>1)
                {
                        fprintf(stderr,"\nSelect pieces to embed:\n");
                        get_index(&atoms,ftp2fn_null(efNDX,nfile,fnm),pieces,pos_ins->nidx,pos_ins->subindex,piecename);
                }
                else
-               {
+               {       
                        /*use whole embedded group*/
                        snew(pos_ins->nidx,1);
                        snew(pos_ins->subindex,1);
@@ -3748,13 +3752,13 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                if (!bExcl)
                        gmx_input("No energy exclusion groups defined. This is necessary for energy exclusion in the freeze group");
 
-               // Set all atoms in box
-               //set_inbox(state->natoms,state->x);
+               /* Set all atoms in box*/
+               /*set_inbox(state->natoms,state->x);*/
 
-               // Guess the area the protein will occupy in the membrane plane // Calculate area per lipid
+               /* Guess the area the protein will occupy in the membrane plane  Calculate area per lipid*/
                snew(rest_at,1);
                ins_nat = init_ins_at(ins_at,rest_at,state,pos_ins,groups,ins_grp_id,xy_max);
-               // Check moleculetypes in insertion group
+               /* Check moleculetypes in insertion group */
                check_types(ins_at,rest_at,mtop);
 
                mem_nat = init_mem_at(mem_p,mtop,state->x,state->box,pos_ins);
@@ -3774,7 +3778,7 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                printf("The estimated area of the protein in the membrane is %.3f nm^2\n",prot_area);
                printf("\nThere are %d lipids in the membrane part that overlaps the protein.\nThe area per lipid is %.4f nm^2.\n",mem_p->nmol,mem_p->lip_area);
 
-               // Maximum number of lipids to be removed
+               /* Maximum number of lipids to be removed*/
                max_lip_rm=(int)(2*prot_area/mem_p->lip_area);
                printf("Maximum number of lipids that will be removed is %d.\n",max_lip_rm);
 
@@ -3782,7 +3786,7 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                                "This resizing will be done with respect to the geometrical center of all protein atoms\n"
                                "that span the membrane region, i.e. z between %.3f and %.3f\n\n",xy_fac,z_fac,mem_p->zmin,mem_p->zmax);
 
-               // resize the protein by xy and by z if necessary
+               /* resize the protein by xy and by z if necessary*/
                snew(r_ins,ins_at->nr);
                init_resize(ins_at,r_ins,pos_ins,mem_p,state->x,bALLOW_ASYMMETRY);
                fac[0]=fac[1]=xy_fac;
@@ -3793,8 +3797,8 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
 
                resize(ins_at,r_ins,state->x,pos_ins,fac);
 
-               // remove overlapping lipids and water from the membrane box
-               //mark molecules to be removed
+               /* remove overlapping lipids and water from the membrane box*/
+               /*mark molecules to be removed*/
                snew(pbc,1);
                set_pbc(pbc,inputrec->ePBC,state->box);
 
@@ -3822,7 +3826,7 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                                        "Try making the -xyinit resize factor smaller. If you are sure about this increase maxwarn.\n\n",warn);
                }
 
-               //freeze all lipids and waters that should be removed and exclude interactions
+               /*freeze all lipids and waters that should be removed and exclude interactions*/
                freeze_rm_group(inputrec,groups,mtop,rm_p,state);
 
                rm_bonded_at = rm_bonded(ins_at,mtop);
@@ -3893,8 +3897,8 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
          * This should be thread safe, since they are only written once
          * and with identical values.
          */
-//        deform_init_init_step_tpx = inputrec->init_step;
-//        copy_mat(box,deform_init_box_tpx);
+/*        deform_init_init_step_tpx = inputrec->init_step;*/
+/*        copy_mat(box,deform_init_box_tpx);*/
     }
 
     if (opt2bSet("-cpi",nfile,fnm))
@@ -4145,7 +4149,7 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
          * is communicated to the PP nodes.
          */
         signal_handler_install();
-//    }
+/*    }*/
 
     if (cr->duty & DUTY_PP)
     {
@@ -4259,7 +4263,7 @@ int gmx_membed(int argc,char *argv[])
                        "The output is a structure file containing the protein embedded in the membrane. If a topology",
                        "file is provided, the number of lipid and ",
                        "solvent molecules will be updated to match the new structure file.\n",
-                       "For a more extensive manual see Wolf et al, J Comp Chem, doi 10.1002/jcc.21507:Appendix.\n",
+                       "For a more extensive manual see Wolf et al, J Comp Chem 31 (2010) 2169-2174, Appendix.\n",
                        "\n",
                        "SHORT METHOD DESCRIPTION\n",
                        "------------------------\n",
@@ -4276,12 +4280,12 @@ int gmx_membed(int argc,char *argv[])
                        "is incremented first. The resize factor for the z-direction is not changed until the -xy factor",
                        "is 1 (thus after -nxy iteration).\n",
                        "5. Repeat step 3 and 4 until the protein reaches its original size (-nxy + -nz iterations).\n",
-                       "For a more extensive method descrition see Wolf et al, J Comp Chem, doi 10.1002/jcc.21507.\n",
+                       "For a more extensive method descrition see Wolf et al, J Comp Chem, 31 (2010) 2169-2174.\n",
                        "\n",
                        "NOTE\n----\n",
                        " - Protein can be any molecule you want to insert in the membrane.\n",
                        " - It is recommended to perform a short equilibration run after the embedding",
-                       "(see Wolf et al, J Comp Chem, doi 10.1002/jcc.21507) to re-equilibrate the membrane. Clearly",
+                       "(see Wolf et al, J Comp Chem 31 (2010) 2169-2174, to re-equilibrate the membrane. Clearly",
                        "protein equilibration might require longer.\n",
                        "\n"
        };
@@ -4373,7 +4377,7 @@ int gmx_membed(int argc,char *argv[])
     bool bALLOW_ASYMMETRY=FALSE;
 
 
-// arguments relevant to OPENMM only
+/* arguments relevant to OPENMM only*/
 #ifdef GMX_OPENMM
     gmx_input("g_membed not functional in openmm");
 #endif
@@ -4616,7 +4620,7 @@ int gmx_membed(int argc,char *argv[])
 
        /* Log file has to be closed in mdrunner if we are appending to it
    (fplog not set here) */
-       fprintf(stderr,"Please cite:\nWolf et al, J Comp Chem, doi 10.1002/jcc.21507.\n");
+       fprintf(stderr,"Please cite:\nWolf et al, J Comp Chem 31 (2010) 2169-2174.\n");
 
        if (MASTER(cr) && !bAppendFiles)
        {
index 98d4966598b6d6bbe5007fd068a34efd1ab16cd0..9a0944aaca28eaf606c7de94e540a13e37351651 100644 (file)
@@ -108,7 +108,7 @@ static void periodic_mindist_plot(const char *trxfn,const char *outfn,
 {
   FILE   *out;
   char *leg[5] = { "min per.","max int.","box1","box2","box3" };
-  int    status;
+  t_trxstatus *status;
   real   t;
   rvec   *x;
   matrix box;
@@ -252,11 +252,12 @@ void dist_plot(const char *fn,const char *afile,const char *dfile,
                const output_env_t oenv)
 {
   FILE         *atm,*dist,*num;
-  int          trxout;
+  t_trxstatus  *trxout;
   char         buf[256];
   char         **leg;
   real         t,dmin,dmax,**mindres=NULL,**maxdres=NULL;
-  int          nmin,nmax,status;
+  int          nmin,nmax;
+  t_trxstatus  *status;
   int          i=-1,j,k,natoms;
   int         min1,min2,max1,max2;
   atom_id      oindex[2];
@@ -274,7 +275,7 @@ void dist_plot(const char *fn,const char *afile,const char *dfile,
   sprintf(buf,"Number of Contacts %s %g nm",bMin ? "<" : ">",rcut);
   num = nfile ? xvgropen(nfile,buf,output_env_get_time_label(oenv),"Number",oenv) : NULL;
   atm = afile ? ffopen(afile,"w") : NULL;
-  trxout = xfile ? open_trx(xfile,"w") : NOTSET;
+  trxout = xfile ? open_trx(xfile,"w") : NULL;
   
   if (bMat) {
     if (ng == 1) {
@@ -385,7 +386,7 @@ void dist_plot(const char *fn,const char *afile,const char *dfile,
                output_env_conv_time(oenv,t),1+(bMin ? min1 : max1),
                                   1+(bMin ? min2 : max2));
     
-    if (trxout>=0) {
+    if (trxout) {
       oindex[0]=bMin?min1:max1;
       oindex[1]=bMin?min2:max2;
       write_trx(trxout,2,oindex,atoms,i,t,box,x0,NULL,NULL);
@@ -411,7 +412,7 @@ void dist_plot(const char *fn,const char *afile,const char *dfile,
   ffclose(dist);
   if (num) ffclose(num);
   if (atm) ffclose(atm);
-  if (trxout>=0) close_xtc(trxout);
+  if (trxout) close_trx(trxout);
   
   if(nres && !bEachResEachTime) {
     FILE *res;
index 91845f433a3f3fbc625daf16d2cd553a60bb0923..ee0925ba0659aff37f0ab264fcc7fce5058661df 100644 (file)
@@ -106,7 +106,8 @@ int gmx_morph(int argc,char *argv[])
   };
   char *leg[] = { "Ref = 1\\Sst\\N conf", "Ref = 2\\Snd\\N conf" };
   FILE     *fp=NULL;
-  int      i,isize,is_lsq,status,nat1,nat2;
+  int      i,isize,is_lsq,nat1,nat2;
+  t_trxstatus *status;
   atom_id  *index,*index_lsq,*index_all,*dummy;
   t_atoms  atoms;
   rvec     *x1,*x2,*xx,*v;
index 0f20862176ce912bd115b64e07fc62e500070fcb..666ebfcead23831a2a06d543a31b7200b0b8bc03 100644 (file)
@@ -564,7 +564,8 @@ int corr_loop(t_corr *curr,const char *fn,t_topology *top,int ePBC,
   rvec         *xa[2]; /* the coordinates to calculate displacements for */
   rvec         com={0};
   real         t,t_prev=0;
-  int          natoms,i,j,status,cur=0,maxframes=0;
+  int          natoms,i,j,cur=0,maxframes=0;
+  t_trxstatus *status;
 #define        prev (1-cur)
   matrix       box;
   bool         bFirst;
index 160847727c98af651861c8bc8313bc1747e088c5..855dd02fecc3541a988a46f8dc89e6538250263f 100644 (file)
@@ -86,7 +86,7 @@ int gmx_nmens(int argc,char *argv[])
   };
 #define NPA asize(pa)
   
-  int        out;
+  t_trxstatus *out;
   int        status,trjout;
   t_topology top;
   int        ePBC;
index 3d05d3709b263667c9bda6c7fbd4cf5974366d4f..a3860e3de447ba17227ded9fec903f2b796e13e2 100644 (file)
@@ -96,7 +96,7 @@ int gmx_nmtraj(int argc,char *argv[])
     
 #define NPA asize(pa)
   
-  int        out;
+  t_trxstatus *out;
   t_topology top;
   int        ePBC;
   t_atoms    *atoms;
index 27262b04c3851ce710785cdeb9f233d66e0dcd4a..8979f7cc0ed7cd1c15a739cf81a1b17a4e64e6a4 100644 (file)
@@ -238,7 +238,7 @@ static void calc_tetra_order_parm(const char *fnNDX,const char *fnTPS,
   t_topology top;
   int        ePBC;
   char       title[STRLEN],fn[STRLEN],subtitle[STRLEN];
-  int        status;
+  t_trxstatus *status;
   int        natoms;
   real       t;
   rvec       *xtop,*x;
@@ -348,7 +348,7 @@ void calc_order(const char *fn, atom_id *index, atom_id *a, rvec **order,
     *x1,             /* coordinates without pbc                        */
     dist;            /* vector between two atoms                       */
   matrix box;        /* box (3x3)                                      */
-  int   status;  
+  t_trxstatus *status;  
   rvec  cossum,      /* sum of vector angles for three axes            */
     Sx, Sy, Sz,      /* the three molecular axes                       */
     tmp1, tmp2,      /* temp. rvecs for calculating dot products       */
@@ -708,7 +708,7 @@ void write_bfactors(t_filenm  *fnm, int nfile, atom_id *index, atom_id *a, int n
 {
        /*function to write order parameters as B factors in PDB file using 
           first frame of trajectory*/
-       int status;
+       t_trxstatus *status;
        int natoms;
        t_trxframe fr, frout;
        t_atoms useatoms;
index 429424250547ee9aa5b940246065953d314ccfac..5403c532a59dba1c54e695202d7c6a64cf8b8188 100644 (file)
@@ -144,7 +144,7 @@ int gmx_polystat(int argc,char *argv[])
   int    ePBC;
   int    isize,*index,nmol,*molind,mol,nat_min=0,nat_max=0;
   char   *grpname;
-  int    status;
+  t_trxstatus *status;
   real   t;
   rvec   *x,*bond=NULL;
   matrix box;
index 89d54af82f57a7ced60ab80f1810a13f786f9738..114a37550a8861c6f7561bf7f319965d7edd803f 100644 (file)
@@ -104,9 +104,9 @@ void calc_potential(const char *fn, atom_id **index, int gnx[],
 {
   rvec *x0;              /* coordinates without pbc */
   matrix box;            /* box (3x3) */
-  int natoms,            /* nr. atoms in trj */
-      status,
-      **slCount,         /* nr. of atoms in one slice for a group */
+  int natoms;            /* nr. atoms in trj */
+  t_trxstatus *status;
+  int **slCount,         /* nr. of atoms in one slice for a group */
       i,j,n,             /* loop indices */
       teller = 0,      
       ax1=0, ax2=0,
index 5cd9d72d7043e3745aaf86827044c1c57791429b..4746daf1104e02d33fdaff1bb756909501fd9656 100644 (file)
@@ -85,7 +85,7 @@ int gmx_principal(int argc,char *argv[])
   t_pargs pa[] = {
          { "-foo",      FALSE, etBOOL, {&foo}, "Dummy option to avoid empty array" }
   };
-  int        status;
+  t_trxstatus *status;
   t_topology top;
   int        ePBC;
   real       t;
index 2a51198f12d0935fb75193fffa3074e7b3a760e5..95360c4d1b6ef040b6e72ba532299a116c851154 100644 (file)
@@ -53,7 +53,6 @@
 #include "physics.h"
 #include "index.h"
 #include "smalloc.h"
-#include "fftgrid.h"
 #include "calcgrid.h"
 #include "nrnb.h"
 #include "coulomb.h"
@@ -165,7 +164,7 @@ static void do_rdf(const char *fnNDX,const char *fnTPS,const char *fnTRX,
                    const output_env_t oenv)
 {
   FILE       *fp;
-  int        status;
+  t_trxstatus *status;
   char       outf1[STRLEN],outf2[STRLEN];
   char       title[STRLEN],gtitle[STRLEN],refgt[30];
   int        g,natoms,i,ii,j,k,nbin,j0,j1,n,nframes;
index f6524fd7260a2870f7dd92ed1082e168e68fa88b..a34472baa63e0186512366a736836aece6998234 100644 (file)
@@ -226,7 +226,7 @@ int gmx_rms(int argc, char *argv[])
     matrix box;
     rvec *x, *xp, *xm = NULL, **mat_x = NULL, **mat_x2, *mat_x2_j = NULL, vec1,
         vec2;
-    int status;
+    t_trxstatus *status;
     char buf[256], buf2[256];
     int ncons = 0;
     FILE *fp;
index e142dcf36101e9b2a4753cb24793e426befaf3df..65f732fe718e4c586f04e4799e78a9fda701548f 100644 (file)
@@ -542,7 +542,8 @@ int gmx_rmsdist (int argc,char *argv[])
   rvec         *x;
   FILE         *fp;
 
-  int      status,isize,gnr=0;
+  t_trxstatus *status;
+  int      isize,gnr=0;
   atom_id  *index, *noe_index;
   char     *grpname;
   real     **d_r,**d,**dtot,**dtot2,**mean,**rms,**rmsc,*resnr;
@@ -669,7 +670,7 @@ int gmx_rmsdist (int argc,char *argv[])
   ffclose(fp);
   close_trj(status);
 
-  teller = nframes_read();
+  teller = nframes_read(status);
   calc_rms(isize,teller,dtot,dtot2,mean,&meanmax,rms,&rmsmax,rmsc,&rmscmax);
   fprintf(stderr,"rmsmax = %g, rmscmax = %g\n",rmsmax,rmscmax);
   
index d241e4225b8b132f828a5b8eb7f95162531466a6..09d36632d9e64053201a25e131232f0fc766a8b4 100644 (file)
@@ -211,7 +211,8 @@ int gmx_rmsf(int argc,char *argv[])
 
   matrix       box,pdbbox;
   rvec         *x,*pdbx,*xref;
-  int          status,npdbatoms,res0;
+  t_trxstatus   *status;
+  int          npdbatoms,res0;
   char         buf[256];
   const char   *label;
   char         title[STRLEN];
index beedaabfc2b6a56e89214a132842d2251c24c5c0..3285ae41c845a5163633c9aa5dc90a5adb0cf834 100644 (file)
@@ -87,7 +87,8 @@ int gmx_rotacf(int argc,char *argv[])
       "Average over molecules" }
   };
 
-  int        status,isize;
+  t_trxstatus *status;
+  int        isize;
   atom_id    *index;
   char       *grpname;
   rvec       *x,*x_s;
index a0f6d9df20523620a1bd3e71a27388785f90d691..67161ffc9164b69b3bee2201d947e93344e1ae05 100644 (file)
@@ -64,7 +64,7 @@ static void get_refx(output_env_t oenv,const char *trxfn,int nfitdim,int skip,
                      bool bMW,t_topology *top,int ePBC,rvec *x_ref)
 {
     int    natoms,nfr_all,nfr,i,j,a,r,c,min_fr;
-    int    status;
+    t_trxstatus *status;
     real   *ti,min_t;
     double tot_mass,msd,*srmsd,min_srmsd,srmsd_tot;
     rvec   *x,**xi;
@@ -216,7 +216,7 @@ int gmx_rotmat(int argc,char *argv[])
           "Use mass weighted fitting" }
     };
     FILE       *out;
-    int        status;
+    t_trxstatus *status;
     t_topology top;
     int        ePBC;
     rvec       *x_ref,*x;
index 057b58241d27ff467c8acb40eb438944c88b678c..fe9aae9b9d927b31323b41b5772beb467a635e46 100644 (file)
@@ -159,7 +159,8 @@ int gmx_saltbr(int argc,char *argv[])
   t_topology *top;
   int        ePBC;
   char       *buf;
-  int        status,i,j,k,m,nnn,teller,ncg,n1,n2,n3,natoms;
+  t_trxstatus *status;
+  int        i,j,k,m,nnn,teller,ncg,n1,n2,n3,natoms;
   real       t,*time,qi,qj;
   t_charge   *cg;
   real       ***cgdist;
index 79a9847b81bdbc1ce356bc4b0d04be7c8c090a80..8f1d4dd33577f704d237c14cc91712aba08c463f 100644 (file)
@@ -229,7 +229,8 @@ void sas_plot(int nfile,t_filenm fnm[],real solsize,int ndots,
   const char   *vfile;
   real         t;
   gmx_atomprop_t aps=NULL;
-  int          status,ndefault;
+  t_trxstatus  *status;
+  int          ndefault;
   int          i,j,ii,nfr,natoms,flag,nsurfacedots,res;
   rvec         *xtop,*x;
   matrix       topbox,box;
index 21d0228bf407d1c11f62c7c38049637a9d5a009d..902f1fd16384db7c89d38364f7ce9e78fa5be4be 100644 (file)
@@ -71,7 +71,7 @@ static void do_sdf(const char *fnNDX,const char *fnTPS,const char *fnTRX,
                    rvec dtri, const output_env_t oenv)
 {
   FILE       *fp;
-  int        status;
+  t_trxstatus *status;
   int        ng,natoms,i,j,k,l,X,Y,Z,lc,dest;
   ivec       nbin;
   int        ***count;
index 990a89e0d3eaa2fcb5459c9ae5d21147ed6f10ba..a738fd2c51722d53b1d5a99dffc6a2bbf0b2ddc6 100644 (file)
@@ -196,7 +196,8 @@ void sgangle_plot(const char *fn,const char *afile,const char *dfile,
     distance,            /* distance between two groups. */
     distance1,           /* distance between plane and one of two atoms */
     distance2;           /* same for second of two atoms */
-  int        status,natoms,teller=0;
+  t_trxstatus *status;
+  int        natoms,teller=0;
   rvec       *x0;   /* coordinates, and coordinates corrected for pb */
   matrix     box;        
   char       buf[256];   /* for xvgr title */
@@ -355,7 +356,8 @@ void sgangle_plot_single(const char *fn,const char *afile,const char *dfile,
     distance,            /* distance between two groups. */
     distance1,           /* distance between plane and one of two atoms */
     distance2;           /* same for second of two atoms */
-  int        status,natoms,teller=0;
+  t_trxstatus *status;
+  int        natoms,teller=0;
   int        i;
   rvec       *x0;   /* coordinates, and coordinates corrected for pb */
   rvec       *xzero;
index 9b97c56a13402c12e6aeb9ffeaaf21631391adc2..a64885b8b9da809b9f7ee8b1e59f85521c731ad6 100644 (file)
@@ -99,7 +99,7 @@ int gmx_sorient(int argc,char *argv[])
   t_topology top;
   int      ePBC;
   char     title[STRLEN];
-  int      status;
+  t_trxstatus *status;
   int      natoms;
   real     t;
   rvec     *xtop,*x;
index 1ec61418939ab3c7998ee2b1b94653669e1f3e97..be371498f3de0c2845c1a38e4cfd7614a6ae4129 100644 (file)
@@ -129,7 +129,7 @@ int gmx_spatial(int argc,char *argv[])
   t_trxframe fr;
   rvec       *xtop,*shx[26];
   matrix     box,box_pbc;
-  int        status;
+  t_trxstatus *status;
   int        flags = TRX_READ_X;
   t_pbc      pbc;
   t_atoms    *atoms;
index ed2d9aa864ad991d6ca0e7a6acc92ce42407f84d..bb73a0c35ae3df83b33674b6b574315bdcac0470 100644 (file)
@@ -126,7 +126,7 @@ int gmx_spol(int argc,char *argv[])
   t_inputrec *ir;
   t_atom     *atom;
   char     title[STRLEN];
-  int      status;
+  t_trxstatus *status;
   int      nrefat,natoms,nf,ntot;
   real     t;
   rvec     *xtop,*x,xref,trial,dx={0},dip,dir;
index 6c3e19b2caaba8287c6a94dfdf87f4dcd28244c3..cbe10ee6ae968d53df0fd1772a0dec004eddd63b 100644 (file)
@@ -271,7 +271,8 @@ int gmx_tcaf(int argc,char *argv[])
   char       *grpname;
   char       title[256];
   real       t0,t1,dt,m,mtot,sysmass,rho,sx,cx;
-  int        status,nframes,n_alloc,i,j,k,d;
+  t_trxstatus *status;
+  int        nframes,n_alloc,i,j,k,d;
   rvec       mv_mol,cm_mol,kfac[NK];
   int        nkc,nk,ntc;
   real       **c1,**tc;
index 1e2e321eee373a9a2db33d0605c2399adf29c109..f9d98aa678bf1da9f429316ce97a15d65fa8de50 100644 (file)
@@ -133,7 +133,7 @@ static void print_data(FILE *fp,real time,rvec x[],real *mass,bool bCom,
     low_print_data(fp,time,x,isize[0],index[0],bDim);
 }
 
-static void write_trx_x(int status,t_trxframe *fr,real *mass,bool bCom,
+static void write_trx_x(t_trxstatus *status,t_trxframe *fr,real *mass,bool bCom,
                        int ngrps,int isize[],atom_id **index)
 {
   static rvec *xav=NULL;
@@ -528,7 +528,8 @@ int gmx_traj(int argc,char *argv[])
   rvec       *xtop,*xp=NULL;
   rvec       *sumxv=NULL,*sumv=NULL,*sumxf=NULL,*sumf=NULL;
   matrix     topbox;
-  int        status,status_out=-1;
+  t_trxstatus *status;
+  t_trxstatus *status_out=NULL;
   int        i,j,n;
   int        nr_xfr,nr_vfr,nr_ffr;
   char       **grpname;
index 164e7b156361c58a04e1fca5b8e35f681d29efa6..4bafafd738afaa2e515c42ebb5330bcd77123a2c 100644 (file)
@@ -76,7 +76,8 @@ static void scan_trj_files(char **fnms, int nfiles, real *readtime,
                            const output_env_t oenv)
 {
     /* Check start time of all files */
-    int i, status, natoms = 0;
+    int i, natoms = 0;
+    t_trxstatus *status;
     real t;
     t_trxframe fr;
     bool ok;
@@ -291,7 +292,7 @@ static void do_demux(int nset, char *fnms[], char *fnms_out[], int nval,
                      atom_id index[], real dt, const output_env_t oenv)
 {
     int i, j, k, natoms, nnn;
-    int *fp_in, *fp_out;
+    t_trxstatus **fp_in, **fp_out;
     bool bCont, *bSet;
     real t, first_time = 0;
     t_trxframe *trx;
@@ -451,13 +452,14 @@ int gmx_trjcat(int argc, char *argv[])
             { "-cat", FALSE, etBOOL,
                 { &bCat }, "do not discard double time frames" } };
 #define npargs asize(pa)
-    int status, ftpin, i, frame, frame_out, step = 0, trjout = 0;
+    int ftpin, i, frame, frame_out, step = 0, trjout = 0;
+    t_trxstatus *status;
     rvec *x, *v;
     real xtcpr, t_corr;
     t_trxframe fr, frout;
     char **fnms, **fnms_out, *in_file, *out_file;
     int n_append;
-    int trxout = -1;
+    t_trxstatus *trxout = NULL;
     bool bNewFile, bIndex, bWrite;
     int earliersteps, nfile_in, nfile_out, *cont_type, last_ok_step;
     real *readtime, *timest, *settime;
@@ -619,8 +621,12 @@ int gmx_trjcat(int argc, char *argv[])
         }
         else 
         {
+            t_fileio *stfio;
+
             if (!read_first_frame(oenv,&status,out_file,&fr,FLAGS))
                 gmx_fatal(FARGS,"Reading first frame from %s",out_file);
+
+            stfio=trx_get_fileio(status);
             if (!bKeepLast && !bOverwrite)
             {
                 fprintf(stderr, "\n\nWARNING: Appending without -overwrite implies -keeplast "
@@ -631,9 +637,12 @@ int gmx_trjcat(int argc, char *argv[])
                 /* Fails if last frame is incomplete
                  * We can't do anything about it without overwriting
                  * */
-                if (gmx_fio_getftp(status) == efXTC) 
+                if (gmx_fio_getftp(stfio) == efXTC) 
                 {
-                    lasttime = xdr_xtc_get_last_frame_time(gmx_fio_getfp(status),gmx_fio_getxdr(status),fr.natoms,&bOK);
+                    lasttime = 
+                         xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio),
+                                                     gmx_fio_getxdr(stfio),
+                                                     fr.natoms,&bOK);
                     fr.time = lasttime;
                     if (!bOK)
                     {
@@ -652,10 +661,13 @@ int gmx_trjcat(int argc, char *argv[])
             }
             else if (bOverwrite)
             {
-                if (gmx_fio_getftp(status) != efXTC) {
+                if (gmx_fio_getftp(stfio) != efXTC) {
                     gmx_fatal(FARGS,"Overwrite only supported for XTC." );
                 }
-                last_frame_time = xdr_xtc_get_last_frame_time(gmx_fio_getfp(status),gmx_fio_getxdr(status),fr.natoms,&bOK);
+                last_frame_time = 
+                          xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio),
+                                                      gmx_fio_getxdr(stfio),
+                                                      fr.natoms,&bOK);
                 if (!bOK)
                 {
                    gmx_fatal(FARGS,"Error reading last frame. Maybe seek not supported." );
@@ -672,7 +684,7 @@ int gmx_trjcat(int argc, char *argv[])
                 {
                     searchtime = last_frame_time;
                 }
-                if (xtc_seek_time(searchtime,status,fr.natoms))
+                if (xtc_seek_time(stfio,searchtime,fr.natoms))
                 {
                     gmx_fatal(FARGS,"Error seeking to append position.");
                 }
@@ -683,10 +695,10 @@ int gmx_trjcat(int argc, char *argv[])
                               searchtime,fr.time);
                 }
                 lasttime = fr.time;             
-                fpos = gmx_fio_ftell(status);
+                fpos = gmx_fio_ftell(stfio);
                 close_trj(status);
                 trxout = open_trx(out_file,"r+");
-                if (gmx_fio_seek(trxout,fpos)) {
+                if (gmx_fio_seek(trx_get_fileio(trxout),fpos)) {
                     gmx_fatal(FARGS,"Error seeking to append position.");
                 }
             }
@@ -822,7 +834,8 @@ int gmx_trjcat(int argc, char *argv[])
 
                         if (bIndex)
                         {
-                            write_trxframe_indexed(trxout,&frout,isize,index,NULL);
+                            write_trxframe_indexed(trxout,&frout,isize,index,
+                                                   NULL);
                         }
                         else
                         {
@@ -841,7 +854,7 @@ int gmx_trjcat(int argc, char *argv[])
 
             earliersteps+=step;          
         }  
-        if (trxout >= 0)
+        if (trxout)
         {
             close_trx(trxout);
         }
index fe481f31cd190940dea6d0e04da8cbff79fe287c..dcdb1f127e1a6bd8d4b4e0b827e99e87a59f691c 100644 (file)
@@ -413,7 +413,7 @@ void check_trn(const char *fn)
 #if (!defined WIN32 && !defined _WIN32 && !defined WIN64 && !defined _WIN64)
 void do_trunc(const char *fn, real t0)
 {
-    int          in;
+    t_fileio     *in;
     FILE         *fp;
     bool         bStop,bOK;
     t_trnheader  sh;
@@ -731,8 +731,9 @@ int gmx_trjconv(int argc,char *argv[])
 #define NPA asize(pa)
 
     FILE         *out=NULL;
-    int          trxout=NOTSET;
-    int          status,ftp,ftpin=0,file_nr;
+    t_trxstatus *trxout=NULL;
+    t_trxstatus *status;
+    int          ftp,ftpin=0,file_nr;
     t_trxframe   fr,frout;
     int          flags;
     rvec         *xmem=NULL,*vmem=NULL,*fmem=NULL;
@@ -753,7 +754,8 @@ int gmx_trjconv(int argc,char *argv[])
     atom_id      *ind_fit,*ind_rms;
     char         *gn_fit,*gn_rms;
     t_cluster_ndx *clust=NULL;
-    int          *clust_status=NULL;
+    t_trxstatus  **clust_status=NULL;
+    int          *clust_status_id=NULL;
     int          ntrxopen=0;
     int          *nfwritten=NULL;
     int          ndrop=0,ncol,drop0=0,drop1=0,dropuse=0;
@@ -909,9 +911,13 @@ int gmx_trjconv(int argc,char *argv[])
                           clust->clust->nr,1+clust->clust->nr/FOPEN_MAX,FOPEN_MAX);
 
             snew(clust_status,clust->clust->nr);
+            snew(clust_status_id,clust->clust->nr);
             snew(nfwritten,clust->clust->nr);
             for(i=0; (i<clust->clust->nr); i++)
-                clust_status[i] = -1;
+            {
+                clust_status[i] = NULL;
+                clust_status_id[i] = -1;
+            }
             bSeparate = bSplit = FALSE;
         }
         /* skipping */  
@@ -1110,7 +1116,8 @@ int gmx_trjconv(int argc,char *argv[])
             }
 
             if (ftp == efG87)
-                fprintf(gmx_fio_getfp(trxout),"Generated by %s. #atoms=%d, a BOX is"
+                fprintf(gmx_fio_getfp(trx_get_fileio(trxout)),
+                        "Generated by %s. #atoms=%d, a BOX is"
                         " stored in this file.\n",Program(),nout);
 
             /* Start the big loop over frames */
@@ -1364,19 +1371,20 @@ int gmx_trjconv(int argc,char *argv[])
                         case efG87:
                         case efXTC:
                             if ( bSplitHere ) {
-                                if ( trxout >= 0 )
+                                if ( trxout )
                                     close_trx(trxout);
                                 trxout = open_trx(out_file2,filemode);
                             }
                             if (bSubTraj) {
                                 if (my_clust != -1) {
                                     char buf[STRLEN];
-                                    if (clust_status[my_clust] == -1) {
+                                    if (clust_status_id[my_clust] == -1) {
                                         sprintf(buf,"%s.%s",clust->grpname[my_clust],ftp2ext(ftp));
                                         clust_status[my_clust] = open_trx(buf,"w");
+                                        clust_status_id[my_clust] = 1;
                                         ntrxopen++;
                                     }
-                                    else if (clust_status[my_clust] == -2)
+                                    else if (clust_status_id[my_clust] == -2)
                                         gmx_fatal(FARGS,"File %s.xtc should still be open (%d open xtc files)\n""in order to write frame %d. my_clust = %d",
                                                   clust->grpname[my_clust],ntrxopen,frame,
                                                   my_clust);
@@ -1386,7 +1394,7 @@ int gmx_trjconv(int argc,char *argv[])
                                         (clust->clust->index[my_clust+1]-
                                             clust->clust->index[my_clust])) {
                                         close_trx(clust_status[my_clust]);
-                                        clust_status[my_clust] = -2;
+                                        clust_status_id[my_clust] = -2;
                                         ntrxopen--;
                                         if (ntrxopen < 0)
                                             gmx_fatal(FARGS,"Less than zero open xtc files!");
@@ -1479,13 +1487,13 @@ int gmx_trjconv(int argc,char *argv[])
 
         close_trj(status);
 
-        if (trxout >= 0)
+        if (trxout)
             close_trx(trxout);
         else if (out != NULL)
             ffclose(out);
         if (bSubTraj) {
             for(i=0; (i<clust->clust->nr); i++)
-                if (clust_status[i] >= 0)
+                if (clust_status[i] )
                     close_trx(clust_status[i]);
         }
     }
index 69e03e652bc89abb454a98f9d1d56adfc6f49eb9..4e87837ff5d225f458768ab402c8209990c9ed41 100644 (file)
@@ -120,7 +120,8 @@ int gmx_trjorder(int argc,char *argv[])
       "Order molecules on z-coordinate" }
   };
   FILE       *fp;
-  int        status,out;
+  t_trxstatus *out;
+  t_trxstatus *status;
   bool       bNShell,bPDBout;
   t_topology top;
   int        ePBC;
@@ -190,7 +191,7 @@ int gmx_trjorder(int argc,char *argv[])
   for(i=0; (i<natoms); i++)
     swi[i] = i;
 
-  out     = -1;
+  out     = NULL;
   fp      = NULL;
   bNShell = ((opt2bSet("-nshell",NFILE,fnm)) ||
             (opt2parg_bSet("-r",asize(pa),pa)));
@@ -285,7 +286,7 @@ int gmx_trjorder(int argc,char *argv[])
          ncut++;
       fprintf(fp,"%10.3f  %8d\n",t,ncut);
     }
-    if (out != -1) {
+    if (out) {
       qsort(order,nwat,sizeof(*order),ocomp);
       for(i=0; (i<nwat); i++)
        for(j=0; (j<na); j++) 
@@ -303,7 +304,7 @@ int gmx_trjorder(int argc,char *argv[])
     }
   } while(read_next_x(oenv,status,&t,natoms,x,box));
   close_trj(status);
-  if (out != -1)
+  if (out)
     close_trx(out);
   if (fp)
     ffclose(fp);
index 18ad40ef9aa4dfb28e006b65f7fccc3aa90bef3c..4633802aa13a127266b1e8f087f5eaefe4a85fcd 100644 (file)
@@ -43,6 +43,7 @@
 #include "calcgrid.h"
 #include "checkpoint.h"
 #include "gmx_ana.h"
+#include "names.h"
 
 
 
@@ -86,9 +87,18 @@ typedef struct
     int  nr_inputfiles;         /* The number of tpr and mdp input files */
     gmx_large_int_t orig_sim_steps;  /* Number of steps to be done in the real simulation */
     real *r_coulomb;            /* The coulomb radii [0...nr_inputfiles] */
-    real *r_vdW;                /* The vdW radii */
+    real *r_vdw;                /* The vdW radii */
+    real *rlist;                /* Neighbourlist cutoff radius */
+    real *rlistlong;
     int  *fourier_nx, *fourier_ny, *fourier_nz;
     real *fourier_sp;           /* Fourierspacing */
+
+    /* Original values as in inputfile: */
+    real orig_rcoulomb;
+    real orig_rvdw;
+    real orig_rlist, orig_rlistlong;
+    int  orig_nk[DIM];
+    real orig_fs[DIM];
 } t_inputinfo;
 
 
@@ -126,6 +136,41 @@ static void cleandata(t_perf *perfdata, int test_nr)
 }
 
 
+static bool is_equal(real a, real b)
+{
+    real diff, eps=1.0e-6;
+
+
+    diff = a - b;
+
+    if (diff < 0.0) diff = -diff;
+
+    if (diff < eps)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+
+static void finalize(const char *fn_out)
+{
+    char buf[STRLEN];
+    FILE *fp;
+
+
+    fp = fopen(fn_out,"r");
+    fprintf(stdout,"\n\n");
+
+    while( fgets(buf,STRLEN-1,fp) != NULL )
+    {
+        fprintf(stdout,"%s",buf);
+    }
+    fclose(fp);
+    fprintf(stdout,"\n\n");
+    thanx(stderr);
+}
+
+
 enum {eFoundNothing, eFoundDDStr, eFoundAccountingStr, eFoundCycleStr};
 
 static int parse_logfile(const char *logfile, t_perf *perfdata, int test_nr, 
@@ -265,7 +310,7 @@ static int parse_logfile(const char *logfile, t_perf *perfdata, int test_nr,
 }
 
 
-static int analyze_data(
+static bool analyze_data(
         FILE        *fp,
         const char  *fn,
         t_perf      **perfdata,
@@ -284,6 +329,7 @@ static int analyze_data(
     t_perf *pd;
     char strbuf[STRLEN];
     char str_PME_f_load[13];
+    bool bCanUseOrigTPR;
 
 
     if (nrepeats > 1)
@@ -387,19 +433,38 @@ static int analyze_data(
         sprintf(strbuf, "%d", winPME);
     fprintf(fp, "Best performance was achieved with %s PME nodes", strbuf);
     if (nrepeats > 1)
-        fprintf(fp, " (see line %d) ", line_win);
-    if (ntprs > 1)
-        fprintf(fp, "\nand %s PME settings. ", (k_win ? "optimized" : "original"));
+        fprintf(fp, " (see line %d)", line_win);
     fprintf(fp, "\n");
 
-    /* Only mention settings if rcoulomb, rvdv, nkx, nky, or nkz was modified: */
-    if (k_win)
+    /* Only mention settings if they were modified: */
+    bCanUseOrigTPR = TRUE;
+    if ( !is_equal(info->r_coulomb[k_win], info->orig_rcoulomb) )
     {
-        fprintf(fp, "Optimized PME settings:\n");
-        fprintf(fp, "r_coulomb = %f, r_vdW = %f, nx,ny,nz = %d %d %d\n",
-                info->r_coulomb[k_win], info->r_vdW[k_win],
-                info->fourier_nx[k_win], info->fourier_ny[k_win], info->fourier_nz[k_win]);
+        fprintf(fp, "Optimized PME settings:\n"
+                    "   New Coulomb radius: %f nm (was %f nm)\n",
+                    info->r_coulomb[k_win], info->orig_rcoulomb);
+        bCanUseOrigTPR = FALSE;
     }
+
+    if ( !is_equal(info->r_vdw[k_win], info->orig_rvdw) )
+    {
+        fprintf(fp, "   New Van der Waals radius: %f nm (was %f nm)\n",
+                info->r_vdw[k_win], info->orig_rvdw);
+        bCanUseOrigTPR = FALSE;
+    }
+
+    if ( ! (info->fourier_nx[k_win]==info->orig_nk[XX] &&
+            info->fourier_ny[k_win]==info->orig_nk[YY] &&
+            info->fourier_nz[k_win]==info->orig_nk[ZZ] ) )
+    {
+        fprintf(fp, "   New Fourier grid xyz: %d %d %d (was %d %d %d)\n",
+                info->fourier_nx[k_win], info->fourier_ny[k_win], info->fourier_nz[k_win],
+                info->orig_nk[XX], info->orig_nk[YY], info->orig_nk[ZZ]);
+        bCanUseOrigTPR = FALSE;
+    }
+    if (bCanUseOrigTPR && ntprs > 1)
+        fprintf(fp, "and original PME settings.\n");
+    
     fflush(fp);
     
     /* Return the index of the mdp file that showed the highest performance
@@ -407,7 +472,7 @@ static int analyze_data(
     *index_tpr    = k_win; 
     *npme_optimal = winPME;
     
-    return 0;
+    return bCanUseOrigTPR;
 }
 
 
@@ -572,7 +637,7 @@ static void launch_simulation(
 
 
 static void modify_PMEsettings(
-        gmx_large_int_t simsteps, /* Set this value as number of time steps */
+        gmx_large_int_t simsteps,  /* Set this value as number of time steps */
         const char *fn_best_tpr,   /* tpr file with the best performance */
         const char *fn_sim_tpr)    /* name of tpr file to be launched */
 {
@@ -597,6 +662,8 @@ static void modify_PMEsettings(
 }
 
 
+#define EPME_SWITCHED(e) ((e) == eelPMESWITCH || (e) == eelPMEUSERSWITCH)
+
 /* Make additional TPR files with more computational load for the
  * direct space processors: */
 static void make_benchmark_tprs(
@@ -616,11 +683,10 @@ static void make_benchmark_tprs(
     t_state      state;
     gmx_mtop_t   mtop;
     real         fac;
-    real         orig_rcoulomb, orig_rvdw, orig_rlist;
-    rvec         orig_fs;      /* original fourierspacing per dimension */
-    ivec         orig_nk;      /* original number of grid points per dimension */
+    real         nlist_buffer; /* Thickness of the buffer regions for PME-switch potentials: */
     char         buf[200];
     rvec         box_size;
+    bool         bNote = FALSE;
     
 
     sprintf(buf, "Making benchmark tpr file%s with %s time steps", ntprs>1? "s":"", gmx_large_int_pfmt);
@@ -637,19 +703,29 @@ static void make_benchmark_tprs(
     snew(ir,1);
     read_tpx_state(fn_sim_tpr,ir,&state,NULL,&mtop);
 
-    /* Check if PME was chosen */
+    /* Check if some kind of PME was chosen */
     if (EEL_PME(ir->coulombtype) == FALSE)
-        gmx_fatal(FARGS, "Can only do optimizations for simulations with PME");
+        gmx_fatal(FARGS, "Can only do optimizations for simulations with %s electrostatics.",
+                EELTYPE(eelPME));
     
-    /* Check if rcoulomb == rlist, which is necessary for PME */
-    if (!(ir->rcoulomb == ir->rlist))
-        gmx_fatal(FARGS, "PME requires rcoulomb (%f) to be equal to rlist (%f).", ir->rcoulomb, ir->rlist);
+    /* Check if rcoulomb == rlist, which is necessary for plain PME. */
+    if (  (eelPME == ir->coulombtype) && !(ir->rcoulomb == ir->rlist) )
+    {
+        gmx_fatal(FARGS, "%s requires rcoulomb (%f) to be equal to rlist (%f).",
+                EELTYPE(eelPME), ir->rcoulomb, ir->rlist);
+    }
+    /* For other PME types, rcoulomb is allowed to be smaller than rlist */
+    else if (ir->rcoulomb > ir->rlist)
+    {
+        gmx_fatal(FARGS, "%s requires rcoulomb (%f) to be equal to or smaller than rlist (%f)",
+                EELTYPE(ir->coulombtype), ir->rcoulomb, ir->rlist);
+    }
 
     /* Reduce the number of steps for the benchmarks */
     info->orig_sim_steps = ir->nsteps;
     ir->nsteps           = benchsteps;
     
-    /* Determine lenght of triclinic box vectors */
+    /* Determine length of triclinic box vectors */
     for(d=0; d<DIM; d++)
     {
         box_size[d] = 0;
@@ -659,21 +735,47 @@ static void make_benchmark_tprs(
     }
     
     /* Remember the original values: */
-    orig_rvdw     = ir->rvdw;
-    orig_rcoulomb = ir->rcoulomb;
-    orig_rlist    = ir->rlist;
-    orig_nk[XX]   = ir->nkx;
-    orig_nk[YY]   = ir->nky;
-    orig_nk[ZZ]   = ir->nkz;
-    orig_fs[XX]   = box_size[XX]/ir->nkx;  /* fourierspacing in x direction */
-    orig_fs[YY]   = box_size[YY]/ir->nky;
-    orig_fs[ZZ]   = box_size[ZZ]/ir->nkz;
-     
-    fprintf(fp, "Input file Fourier grid : %dx%dx%d\n", orig_nk[XX], orig_nk[YY], orig_nk[ZZ]);
-    fprintf(fp, "           Coulomb rad. : %f nm\n", orig_rcoulomb);
-    fprintf(fp, "           Van d. Waals : %f nm\n", orig_rvdw);
+    info->orig_rvdw            = ir->rvdw;
+    info->orig_rcoulomb        = ir->rcoulomb;
+    info->orig_rlist           = ir->rlist;
+    info->orig_rlistlong       = ir->rlistlong;
+    info->orig_nk[XX]          = ir->nkx;
+    info->orig_nk[YY]          = ir->nky;
+    info->orig_nk[ZZ]          = ir->nkz;
+    info->orig_fs[XX]          = box_size[XX]/ir->nkx;  /* fourierspacing in x direction */
+    info->orig_fs[YY]          = box_size[YY]/ir->nky;
+    info->orig_fs[ZZ]          = box_size[ZZ]/ir->nkz;
+
+    /* For PME-switch potentials, keep the radial distance of the buffer region */
+    nlist_buffer   = info->orig_rlist    - info->orig_rcoulomb;
+
+    /* Print information about settings of which some are potentially modified: */
+    fprintf(fp, "   Coulomb type         : %s\n", EELTYPE(ir->coulombtype));
+    fprintf(fp, "   Fourier nkx nky nkz  : %d %d %d\n",
+            info->orig_nk[XX], info->orig_nk[YY], info->orig_nk[ZZ]);
+    fprintf(fp, "   rcoulomb             : %f nm\n", info->orig_rcoulomb);
+    fprintf(fp, "   Van der Waals type   : %s\n", EVDWTYPE(ir->vdwtype));
+    fprintf(fp, "   rvdw                 : %f nm\n", info->orig_rvdw);
+    if (EVDW_SWITCHED(ir->vdwtype))
+        fprintf(fp, "   rvdw_switch          : %f nm\n", ir->rvdw_switch);
+    if (EPME_SWITCHED(ir->coulombtype))
+        fprintf(fp, "   rlist                : %f nm\n", info->orig_rlist);
+    if (info->orig_rlistlong != max_cutoff(ir->rvdw,ir->rcoulomb))
+        fprintf(fp, "   rlistlong            : %f nm\n", info->orig_rlistlong);
+
+    /* Print a descriptive line about the tpr settings tested */
     fprintf(fp, "\nWill try these real/reciprocal workload settings:\n");
-    fprintf(fp, " No. scaling   r_coul   (r_vdW)     nkx  nky  nkz   (spacing)   tpr file\n");
+    fprintf(fp, " No.   scaling  rcoulomb");
+    fprintf(fp, "  nkx  nky  nkz");
+    if (fourierspacing > 0)
+        fprintf(fp, "   spacing");
+    if (evdwCUT == ir->vdwtype)
+        fprintf(fp, "      rvdw");
+    if (EPME_SWITCHED(ir->coulombtype))
+        fprintf(fp, "     rlist");
+    if ( info->orig_rlistlong != max_cutoff(info->orig_rlist,max_cutoff(info->orig_rvdw,info->orig_rcoulomb)) )
+        fprintf(fp, " rlistlong");
+    fprintf(fp, "  tpr file\n");
     
     if (ntprs > 1)
     {
@@ -689,15 +791,34 @@ static void make_benchmark_tprs(
     {
         /* Rcoulomb scaling factor for this file: */
         if (ntprs == 1)
-            fac = 1.0;
+            fac = downfac;
          else
             fac = (upfac-downfac)/(ntprs-1) * j + downfac;
         fprintf(stdout, "--- Scaling factor %f ---\n", fac);
         
-        ir->rcoulomb = orig_rcoulomb*fac;
-        ir->rlist    = orig_rlist   *fac;
-        ir->rvdw     = orig_rvdw    *fac;
-        
+        /* Scale the Coulomb radius */
+        ir->rcoulomb = info->orig_rcoulomb*fac;
+
+        /* Adjust other radii since various conditions neet to be fulfilled */
+        if (eelPME == ir->coulombtype)
+        {
+            /* plain PME, rcoulomb must be equal to rlist */
+            ir->rlist = ir->rcoulomb;
+        }
+        else
+        {
+            /* rlist must be >= rcoulomb, we keep the size of the buffer region */
+            ir->rlist = ir->rcoulomb + nlist_buffer;
+        }
+
+        if (evdwCUT == ir->vdwtype)
+        {
+            /* For vdw cutoff, rvdw >= rlist */
+            ir->rvdw = max(info->orig_rvdw, ir->rlist);
+        }
+
+        ir->rlistlong = max_cutoff(ir->rlist,max_cutoff(ir->rvdw,ir->rcoulomb));
+
         /* Try to reduce the number of reciprocal grid points in a smart way */
         /* Did the user supply a value for fourierspacing on the command line? */
         if (fourierspacing > 0)
@@ -710,11 +831,12 @@ static void make_benchmark_tprs(
             calc_grid(stdout,state.box,info->fourier_sp[j],&(ir->nkx),&(ir->nky),&(ir->nkz),1);
             /* Check consistency */
             if (0 == j)
-                if ((ir->nkx != orig_nk[XX]) || (ir->nky != orig_nk[YY]) || (ir->nkz != orig_nk[ZZ]))
+                if ((ir->nkx != info->orig_nk[XX]) || (ir->nky != info->orig_nk[YY]) || (ir->nkz != info->orig_nk[ZZ]))
                 {
                     fprintf(stderr, "WARNING: Original grid was %dx%dx%d. The fourierspacing of %f nm does not reproduce the grid\n"
                                     "         found in the tpr input file! Will use the new settings.\n", 
-                                    orig_nk[XX],orig_nk[YY],orig_nk[ZZ],fourierspacing);
+                                    info->orig_nk[XX],info->orig_nk[YY],info->orig_nk[ZZ],fourierspacing);
+                    bNote = TRUE;
                 }
         }
         else
@@ -722,26 +844,26 @@ static void make_benchmark_tprs(
             if (0 == j)
             {
                 /* Print out fourierspacing from input tpr */
-                fprintf(stdout, "Input file fourier grid is %dx%dx%d\n", orig_nk[XX], orig_nk[YY], orig_nk[ZZ]);
+                fprintf(stdout, "Input file fourier grid is %dx%dx%d\n",
+                        info->orig_nk[XX], info->orig_nk[YY], info->orig_nk[ZZ]);
             }
             /* Reconstruct fourierspacing for each dimension from the input file */
             ir->nkx=0;
-            calc_grid(stdout,state.box,orig_fs[XX]*fac,&(ir->nkx),&(ir->nky),&(ir->nkz),1);
+            calc_grid(stdout,state.box,info->orig_fs[XX]*fac,&(ir->nkx),&(ir->nky),&(ir->nkz),1);
             ir->nky=0;
-            calc_grid(stdout,state.box,orig_fs[YY]*fac,&(ir->nkx),&(ir->nky),&(ir->nkz),1);
+            calc_grid(stdout,state.box,info->orig_fs[YY]*fac,&(ir->nkx),&(ir->nky),&(ir->nkz),1);
             ir->nkz=0;
-            calc_grid(stdout,state.box,orig_fs[ZZ]*fac,&(ir->nkx),&(ir->nky),&(ir->nkz),1);
+            calc_grid(stdout,state.box,info->orig_fs[ZZ]*fac,&(ir->nkx),&(ir->nky),&(ir->nkz),1);
         }
-        /* r_vdw should only grow if necessary! */
-        ir->rvdw = min(ir->rvdw, orig_rcoulomb*fac);
-        ir->rvdw = max(ir->rvdw, orig_rvdw);
 
         /* Save modified radii and fourier grid components for later output: */
-        info->r_coulomb[j] = ir->rcoulomb;
-        info->r_vdW[j]     = ir->rvdw;        
-        info->fourier_nx[j]= ir->nkx;
-        info->fourier_ny[j]= ir->nky;
-        info->fourier_nz[j]= ir->nkz;
+        info->r_coulomb[j]        = ir->rcoulomb;
+        info->r_vdw[j]            = ir->rvdw;
+        info->fourier_nx[j]       = ir->nkx;
+        info->fourier_ny[j]       = ir->nky;
+        info->fourier_nz[j]       = ir->nkz;
+        info->rlist[j]            = ir->rlist;
+        info->rlistlong[j]        = ir->rlistlong;
 
         /* Write the benchmark tpr file */
         strncpy(fn_bench_tprs[j],fn_sim_tpr,strlen(fn_sim_tpr)-strlen(".tpr"));
@@ -752,13 +874,32 @@ static void make_benchmark_tprs(
         fprintf(stdout,", scaling factor %f\n", fac);
         write_tpx_state(fn_bench_tprs[j],ir,&state,&mtop);
         
-        /* Write some info to log file */
-        fprintf(fp, "%3d %9f %9f (%7f) %4d %4d %4d   %9f   %-14s\n",
-                j, fac, ir->rcoulomb, ir->rvdw, ir->nkx, ir->nky, ir->nkz, info->fourier_sp[j],fn_bench_tprs[j]);
+        /* Write information about modified tpr settings to log file */
+        fprintf(fp, "%4d%10f%10f", j, fac, ir->rcoulomb);
+        fprintf(fp, "%5d%5d%5d", ir->nkx, ir->nky, ir->nkz);
+        if (fourierspacing > 0)
+            fprintf(fp, "%9f ", info->fourier_sp[j]);
+        if (evdwCUT == ir->vdwtype)
+            fprintf(fp, "%10f", ir->rvdw);
+        if (EPME_SWITCHED(ir->coulombtype))
+            fprintf(fp, "%10f", ir->rlist);
+        if ( info->orig_rlistlong != max_cutoff(info->orig_rlist,max_cutoff(info->orig_rvdw,info->orig_rcoulomb)) )
+            fprintf(fp, "%10f", ir->rlistlong);
+        fprintf(fp, "  %-14s\n",fn_bench_tprs[j]);
+
+        /* Make it clear to the user that some additional settings were modified */
+        if (   !is_equal(ir->rvdw           , info->orig_rvdw)
+            || !is_equal(ir->rlistlong      , info->orig_rlistlong) )
+        {
+            bNote = TRUE;
+        }
     }
+    if (bNote)
+        fprintf(fp, "\nNote that in addition to rcoulomb and the fourier grid\n"
+                    "also other input settings were changed (see table above).\n"
+                    "Please check if the modified settings are appropriate.\n");
     fflush(stdout);
     fflush(fp);
-    
     sfree(ir);
 }
 
@@ -826,31 +967,179 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes,
 }
 
 
-static void do_the_tests(FILE *fp, char **tpr_names, int maxPMEnodes, 
-        int minPMEnodes,
-        int datasets, t_perf **perfdata, int repeats, int nnodes, int nr_tprs,
-        bool bThreads, char *cmd_mpirun, char *cmd_np, char *cmd_mdrun,
-        char *cmd_args_bench,
-        const t_filenm *fnm, int nfile, int sim_part, int presteps, 
-        gmx_large_int_t cpt_steps)
+/* Returns the largest common factor of n1 and n2 */
+static int largest_common_factor(int n1, int n2)
+{
+    int factor, nmax;
+
+    nmax = min(n1, n2);
+    for (factor=nmax; factor > 0; factor--)
+    {
+        if ( 0==(n1 % factor) && 0==(n2 % factor) )
+        {
+            return(factor);
+        }
+    }
+    return 0; /* one for the compiler */
+}
+
+enum {eNpmeAuto, eNpmeAll, eNpmeReduced, eNpmeSubset, eNpmeNr};
+
+/* Create a list of numbers of PME nodes to test */
+static void make_npme_list(
+        const char *npmevalues_opt,  /* Make a complete list with all
+                           * possibilities or a short list that keeps only
+                           * reasonable numbers of PME nodes                  */
+        int *nentries,    /* Number of entries we put in the nPMEnodes list   */
+        int *nPMEnodes[], /* Each entry contains the value for -npme          */
+        int nnodes,       /* Total number of nodes to do the tests on         */
+        int minPMEnodes,  /* Minimum number of PME nodes                      */
+        int maxPMEnodes)  /* Maximum number of PME nodes                      */
 {
-    int     i,nr,k,ret;
-    int     nPMEnodes;
+    int i,npme,npp;
+    int min_factor=1;     /* We request that npp and npme have this minimal
+                           * largest common factor (depends on npp)           */
+    int nlistmax;         /* Max. list size                                   */
+    int nlist;            /* Actual number of entries in list                 */
+    int eNPME;
+
+
+    /* Do we need to check all possible values for -npme or is a reduced list enough? */
+    if ( 0 == strcmp(npmevalues_opt, "all") )
+    {
+        eNPME = eNpmeAll;
+    }
+    else if ( 0 == strcmp(npmevalues_opt, "subset") )
+    {
+        eNPME = eNpmeSubset;
+    }
+    else if ( 0 == strcmp(npmevalues_opt, "auto") )
+    {
+        if (nnodes <= 64)
+            eNPME = eNpmeAll;
+        else if (nnodes < 128)
+            eNPME = eNpmeReduced;
+        else
+            eNPME = eNpmeSubset;
+    }
+    else
+    {
+        gmx_fatal(FARGS, "Unknown option for -npme in make_npme_list");
+    }
+
+    /* Calculate how many entries we could possibly have (in case of -npme all) */
+    if (nnodes > 2)
+    {
+        nlistmax = maxPMEnodes - minPMEnodes + 3;
+        if (0 == minPMEnodes)
+            nlistmax--;
+    }
+    else
+        nlistmax = 1;
+
+    /* Now make the actual list which is at most of size nlist */
+    snew(*nPMEnodes, nlistmax);
+    nlist = 0; /* start counting again, now the real entries in the list */
+    for (i = 0; i < nlistmax - 2; i++)
+    {
+        npme = maxPMEnodes - i;
+        npp  = nnodes-npme;
+        switch (eNPME)
+        {
+            case eNpmeAll:
+                min_factor = 1;
+                break;
+            case eNpmeReduced:
+                min_factor = 2;
+                break;
+            case eNpmeSubset:
+                /* For 2d PME we want a common largest factor of at least the cube
+                 * root of the number of PP nodes */
+                min_factor = (int) pow(npp, 1.0/3.0);
+                break;
+            default:
+                gmx_fatal(FARGS, "Unknown option for eNPME in make_npme_list");
+                break;
+        }
+        if (largest_common_factor(npp, npme) >= min_factor)
+        {
+            (*nPMEnodes)[nlist] = npme;
+            nlist++;
+        }
+    }
+    /* We always test 0 PME nodes and the automatic number */
+    *nentries = nlist + 2;
+    (*nPMEnodes)[nlist  ] =  0;
+    (*nPMEnodes)[nlist+1] = -1;
+
+    fprintf(stderr, "Will try the following %d different values for -npme:\n", *nentries);
+    for (i=0; i<*nentries-1; i++)
+        fprintf(stderr, "%d, ", (*nPMEnodes)[i]);
+    fprintf(stderr, "and %d (auto).\n", (*nPMEnodes)[*nentries-1]);
+}
+
+
+/* Allocate memory to store the performance data */
+static void init_perfdata(t_perf *perfdata[], int ntprs, int datasets, int repeats)
+{
+    int i, j, k;
+
+
+    for (k=0; k<ntprs; k++)
+    {
+        snew(perfdata[k], datasets);
+        for (i=0; i<datasets; i++)
+        {
+            for (j=0; j<repeats; j++)
+            {
+                snew(perfdata[k][i].Gcycles   , repeats);
+                snew(perfdata[k][i].ns_per_day, repeats);
+                snew(perfdata[k][i].PME_f_load, repeats);
+            }
+        }
+    }
+}
+
+
+static void do_the_tests(
+        FILE *fp,                   /* General g_tune_pme output file         */
+        char **tpr_names,           /* Filenames of the input files to test   */
+        int maxPMEnodes,            /* Max fraction of nodes to use for PME   */
+        int minPMEnodes,            /* Min fraction of nodes to use for PME   */
+        const char *npmevalues_opt, /* Which -npme values should be tested    */
+        t_perf **perfdata,          /* Here the performace data is stored     */
+        int *pmeentries,            /* Entries in the nPMEnodes list          */
+        int repeats,                /* Repeat each test this often            */
+        int nnodes,                 /* Total number of nodes = nPP + nPME     */
+        int nr_tprs,                /* Total number of tpr files to test      */
+        bool bThreads,              /* Threads or MPI?                        */
+        char *cmd_mpirun,           /* mpirun command string                  */
+        char *cmd_np,               /* "-np", "-n", whatever mpirun needs     */
+        char *cmd_mdrun,            /* mdrun command string                   */
+        char *cmd_args_bench,       /* arguments for mdrun in a string        */
+        const t_filenm *fnm,        /* List of filenames from command line    */
+        int nfile,                  /* Number of files specified on the cmdl. */
+        int sim_part,               /* For checkpointing                      */
+        int presteps,               /* DLB equilibration steps, is checked    */
+        gmx_large_int_t cpt_steps)  /* Time step counter in the checkpoint    */
+{
+    int     i,nr,k,ret,count=0,totaltests;
+    int     *nPMEnodes=NULL;
     t_perf  *pd=NULL;
     int     cmdline_length;
-    char    *command;
+    char    *command, *cmd_stub;
     char    buf[STRLEN];
     bool    bResetProblem=FALSE;
-    
+
 
     /* This string array corresponds to the eParselog enum type at the start
      * of this file */
-    const char* ParseLog[] = {"OK",
+    const char* ParseLog[] = {"OK.",
                               "Logfile not found!",
                               "No timings, logfile truncated?",
-                              "Run was terminated",
-                              "Counters were not reset properly",
-                              "No DD grid found for these settings",
+                              "Run was terminated.",
+                              "Counters were not reset properly.",
+                              "No DD grid found for these settings.",
                               "TPX version conflict!",
                               "mdrun was not started in parallel!"};
     char    str_PME_f_load[13];
@@ -863,49 +1152,65 @@ static void do_the_tests(FILE *fp, char **tpr_names, int maxPMEnodes,
                     + strlen(cmd_mdrun) 
                     + strlen(cmd_args_bench) 
                     + strlen(tpr_names[0]) + 100;
-    snew(command, cmdline_length);
+    snew(command , cmdline_length);
+    snew(cmd_stub, cmdline_length);
+
+    /* Construct the part of the command line that stays the same for all tests: */
+    if (bThreads)
+    {
+        sprintf(cmd_stub, "%s%s%s", cmd_mdrun, cmd_np, cmd_args_bench);
+    }
+    else
+    {
+        sprintf(cmd_stub, "%s%s%s %s", cmd_mpirun, cmd_np, cmd_mdrun, cmd_args_bench);
+    }
+
+    /* Create a list of numbers of PME nodes to test */
+    make_npme_list(npmevalues_opt, pmeentries, &nPMEnodes,
+                   nnodes, minPMEnodes, maxPMEnodes);
 
-    /* Loop over all tpr files to test: */
+    if (0 == repeats)
+    {
+        fprintf(fp, "\nNo benchmarks done since number of repeats (-r) is 0.\n");
+        fclose(fp);
+        finalize(opt2fn("-p", nfile, fnm));
+        exit(0);
+    }
+
+    /* Allocate one dataset for each tpr input file: */
+    init_perfdata(perfdata, nr_tprs, *pmeentries, repeats);
+
+    /*****************************************/
+    /* Main loop over all tpr files to test: */
+    /*****************************************/
+    totaltests = nr_tprs*(*pmeentries)*repeats;
     for (k=0; k<nr_tprs;k++)
     {
         fprintf(fp, "\nIndividual timings for input file %d (%s):\n", k, tpr_names[k]);
         fprintf(fp, "PME nodes      Gcycles       ns/day        PME/f    Remark\n");
-        i=0;
-        /* Start with the maximum number of PME only nodes: */
-        nPMEnodes = maxPMEnodes;
-
         /* Loop over various numbers of PME nodes: */
-        for (i = 0; i<datasets; i++)
+        for (i = 0; i < *pmeentries; i++)
         {
             pd = &perfdata[k][i];
 
             /* Loop over the repeats for each scenario: */
             for (nr = 0; nr < repeats; nr++)
             {
-                pd->nPMEnodes = nPMEnodes;
+                pd->nPMEnodes = nPMEnodes[i];
                 
-                /* Construct the command line to call mdrun (and save it): */
+                /* Add -npme and -s to the command line and save it: */
                 snew(pd->mdrun_cmd_line, cmdline_length);
-                if (bThreads)
-                {
-                    sprintf(pd->mdrun_cmd_line, "%s%s%s-npme %d -s %s",
-                            cmd_mdrun, cmd_np,
-                            cmd_args_bench,nPMEnodes, tpr_names[k]);
-                }
-                else
-                {
-                    sprintf(pd->mdrun_cmd_line, 
-                            "%s%s%s %s-npme %d -s %s",
-                            cmd_mpirun, cmd_np, cmd_mdrun,
-                            cmd_args_bench,nPMEnodes, tpr_names[k]);
-                }
+                sprintf(pd->mdrun_cmd_line, "%s-npme %d -s %s",
+                        cmd_stub, pd->nPMEnodes, tpr_names[k]);
 
                 /* Do a benchmark simulation: */
                 if (repeats > 1)
                     sprintf(buf, ", pass %d/%d", nr+1, repeats);
                 else
                     buf[0]='\0';
-                fprintf(stdout, "\n=== tpr %d/%d, run %d/%d%s:\n", k+1, nr_tprs, i+1, datasets, buf);
+                fprintf(stdout, "\n=== Progress %2.0f%%, tpr %d/%d, run %d/%d%s:\n",
+                        (100.0*count)/totaltests,
+                        k+1, nr_tprs, i+1, *pmeentries, buf);
                 sprintf(command, "%s 1> /dev/null 2>&1", pd->mdrun_cmd_line);
                 fprintf(stdout, "%s\n", pd->mdrun_cmd_line);
                 gmx_system_call(command);
@@ -915,7 +1220,7 @@ static void do_the_tests(FILE *fp, char **tpr_names, int maxPMEnodes,
                 if ((presteps > 0) && (ret == eParselogResetProblem))
                     bResetProblem = TRUE;
 
-                if (nPMEnodes == -1)
+                if (-1 == pd->nPMEnodes)
                     sprintf(buf, "(%3d)", pd->guessPME);
                 else
                     sprintf(buf, "     ");
@@ -927,33 +1232,27 @@ static void do_the_tests(FILE *fp, char **tpr_names, int maxPMEnodes,
                     sprintf(str_PME_f_load, "%s", "         -  ");
                 
                 /* Write the data we got to disk */
-                fprintf(fp, "%4d%s %12.3f %12.3f %s    %s", pd->nPMEnodes, buf, pd->Gcycles[nr], pd->ns_per_day[nr], str_PME_f_load, ParseLog[ret]);
-                if (ret != eParselogOK)
+                fprintf(fp, "%4d%s %12.3f %12.3f %s    %s", pd->nPMEnodes,
+                        buf, pd->Gcycles[nr], pd->ns_per_day[nr], str_PME_f_load, ParseLog[ret]);
+                if (! (ret==eParselogOK || ret==eParselogNoDDGrid || ret==eParselogNotFound) )
                     fprintf(fp, " Check log file for problems.");
                 fprintf(fp, "\n");
                 fflush(fp);
+                count++;
 
                 /* Do some cleaning up and delete the files we do not need any more */
-                cleanup(fnm, nfile, k, nnodes, nPMEnodes, nr);
+                cleanup(fnm, nfile, k, nnodes, pd->nPMEnodes, nr);
 
                 /* If the first run with this number of processors already failed, do not try again: */
                 if (pd->Gcycles[0] <= 0.0 && repeats > 1)
                 {
                     fprintf(stdout, "Skipping remaining passes of unsuccessful setting, see log file for details.\n");
+                    count += repeats-(nr+1);
                     break;
                 }
-            }
-            /* Prepare for the next number of PME only nodes */
-            /* The last but one check is always without MPMD PME ... */
-            if ((nPMEnodes == minPMEnodes) && (0 != minPMEnodes)) 
-                nPMEnodes = 0;
-            /* ... and the last check with the guessed settings */
-            else if (nPMEnodes == 0)
-                nPMEnodes = -1;
-            else
-                nPMEnodes--;
-        }
-    }
+            } /* end of repeats loop */
+        } /* end of -npme loop */
+    } /* end of tpr file loop */
     if (bResetProblem)
     {
         sep_line(fp);
@@ -968,28 +1267,12 @@ static void do_the_tests(FILE *fp, char **tpr_names, int maxPMEnodes,
 }
 
 
-static bool is_equal(real a, real b)
-{
-    real diff, eps=1.0e-6;
-    
-    
-    diff = a - b;
-    
-    if (diff < 0.0) diff = -diff;
-    
-    if (diff < eps)
-        return TRUE;
-    else
-        return FALSE;
-}
-
-
 static void check_input(
         int nnodes, 
         int repeats, 
         int *ntprs, 
-        real upfac,
-        real downfac,
+        real *upfac,
+        real *downfac,
         real maxPMEfraction,
         real minPMEfraction,
         real fourierspacing,
@@ -997,7 +1280,9 @@ static void check_input(
         const t_filenm *fnm,
         int nfile,
         int sim_part,
-        int presteps)
+        int presteps,
+        int npargs,
+        t_pargs *pa)
 {
     /* Make sure the input file exists */
     if (!gmx_fexist(opt2fn("-s",nfile,fnm)))
@@ -1026,11 +1311,11 @@ static void check_input(
     }
     else
     {
-        if ( (1 == *ntprs) && (!is_equal(upfac,1.0) || !is_equal(downfac,1.0)) )
+        if (1 == *ntprs)
             fprintf(stderr, "Note: Choose ntpr>1 to shift PME load between real and reciprocal space.\n");
     }
     
-    if ( is_equal(downfac,upfac) && (*ntprs > 1) )
+    if ( is_equal(*downfac,*upfac) && (*ntprs > 1) )
     {
         fprintf(stderr, "WARNING: Resetting -ntpr to 1 since both scaling factors are the same.\n"
                         "Please choose upfac unequal to downfac to test various PME grid settings\n");
@@ -1061,15 +1346,35 @@ static void check_input(
         gmx_fatal(FARGS, "Cannot have a negative number of presteps.\n");
     }
     
-    if (upfac <= 0.0 || downfac <= 0.0 || downfac > upfac)
-        gmx_fatal(FARGS, "Both scaling factors must be larger than zero and "
-                         "upper scaling limit must be larger than lower limit");
+    if (*upfac <= 0.0 || *downfac <= 0.0 || *downfac > *upfac)
+        gmx_fatal(FARGS, "Both scaling factors must be larger than zero and upper\n"
+                         "scaling limit (%f) must be larger than lower limit (%f).",
+                         *upfac, *downfac);
 
-    if (downfac < 0.75 || upfac > 1.5)
+    if (*downfac < 0.75 || *upfac > 1.5)
         fprintf(stderr, "WARNING: Applying extreme scaling factor. I hope you know what you are doing.\n");
     
     if (fourierspacing < 0)
         gmx_fatal(FARGS, "Please choose a positive value for fourierspacing.");
+
+    /* Make shure that the scaling factor options are compatible with the number of tprs */
+    if ( (1 == *ntprs) && ( opt2parg_bSet("-upfac",npargs,pa) || opt2parg_bSet("-downfac",npargs,pa) ) )
+    {
+        if (opt2parg_bSet("-upfac",npargs,pa) && opt2parg_bSet("-downfac",npargs,pa) && !is_equal(*upfac,*downfac))
+        {
+            gmx_fatal(FARGS, "Please specify -ntpr > 1 for both scaling factors to take effect.\n"
+                             "(upfac=%f, downfac=%f)\n", *upfac, *downfac);
+        }
+        if (opt2parg_bSet("-upfac",npargs,pa))
+            *downfac = *upfac;
+        if (opt2parg_bSet("-downfac",npargs,pa))
+            *upfac = *downfac;
+        if (!is_equal(*upfac, 1.0))
+        {
+            fprintf(stderr, "WARNING: Using a scaling factor of %f with -ntpr 1, thus not testing the original tpr settings.\n",
+                    *upfac);
+        }
+    }
 }
 
 
@@ -1090,7 +1395,8 @@ static bool is_main_switch(char *opt)
       || (0 == strcmp(opt,"-simsteps" ))
       || (0 == strcmp(opt,"-resetstep"))
       || (0 == strcmp(opt,"-so"       ))
-      || (0 == strcmp(opt,"-npstring" )) )
+      || (0 == strcmp(opt,"-npstring" ))
+      || (0 == strcmp(opt,"-npme"     )) )
     return TRUE;
     
     return FALSE;
@@ -1358,25 +1664,6 @@ static double gettime()
 }
 
 
-static void finalize(const char *fn_out)
-{
-    char buf[STRLEN];
-    FILE *fp;
-
-
-    fp = fopen(fn_out,"r");
-    fprintf(stdout,"\n\n");
-
-    while( fgets(buf,STRLEN-1,fp) != NULL )
-    {
-        fprintf(stdout,"%s",buf);
-    }
-    fclose(fp);
-    fprintf(stdout,"\n\n");
-    thanx(stderr);
-}
-
-
 #define BENCHSTEPS (1000)
 
 int gmx_tune_pme(int argc,char *argv[])
@@ -1402,7 +1689,7 @@ int gmx_tune_pme(int argc,char *argv[])
             "g_tune_pme can test various real space / reciprocal space workloads",
             "for you. With [TT]-ntpr[tt] you control how many extra [TT].tpr[tt] files will be",
             "written with enlarged cutoffs and smaller fourier grids respectively.",
-            "The first test (no. 0) will be with the settings from the input",
+            "Typically, the first test (no. 0) will be with the settings from the input",
             "[TT].tpr[tt] file; the last test (no. [TT]ntpr[tt]) will have cutoffs multiplied",
             "by (and at the same time fourier grid dimensions divided by) the scaling",
             "factor [TT]-fac[tt] (default 1.2). The remaining [TT].tpr[tt] files will have equally",
@@ -1427,6 +1714,7 @@ int gmx_tune_pme(int argc,char *argv[])
 
     int        nnodes =1;
     int        repeats=2;
+    int        pmeentries=0; /* How many values for -npme do we actually test for each tpr file */
     real       maxPMEfraction=0.50;
     real       minPMEfraction=0.25;
     int        maxPMEnodes, minPMEnodes;
@@ -1437,7 +1725,7 @@ int gmx_tune_pme(int argc,char *argv[])
     gmx_large_int_t new_sim_nsteps=-1;   /* -1 indicates: not set by the user */
     gmx_large_int_t cpt_steps=0;         /* Step counter in .cpt input file   */
     int        presteps=100;    /* Do a full cycle reset after presteps steps */
-    bool       bOverwrite=FALSE;
+    bool       bOverwrite=FALSE, bKeepTPR;
     bool       bLaunch=FALSE;
     char       **tpr_names=NULL;
     const char *simulation_tpr=NULL;
@@ -1446,12 +1734,12 @@ int gmx_tune_pme(int argc,char *argv[])
     
     /* Default program names if nothing else is found */
     char        *cmd_mpirun=NULL, *cmd_mdrun=NULL;
-    char        *cmd_args_bench, *cmd_args_launch, *cmd_np;
+    char        *cmd_args_bench, *cmd_args_launch;
+    char        *cmd_np=NULL;
 
-    t_perf      **perfdata;
+    t_perf      **perfdata=NULL;
     t_inputinfo *info;
-    int         datasets;
-    int         i,j,k;
+    int         i;
     FILE        *fp;
     t_commrec   *cr;
 
@@ -1537,6 +1825,8 @@ int gmx_tune_pme(int argc,char *argv[])
       { NULL, "auto", "no", "yes", NULL };
     const char *procstring[] =
       { NULL, "-np", "-n", "none", NULL };
+    const char *npmevalues_opt[] =
+      { NULL, "auto", "all", "subset", NULL };
     real rdd=0.0,rconstr=0.0,dlb_scale=0.8,pforce=-1;
     char *ddcsx=NULL,*ddcsy=NULL,*ddcsz=NULL;
     char *deffnm=NULL;
@@ -1562,6 +1852,8 @@ int gmx_tune_pme(int argc,char *argv[])
         "Max fraction of PME nodes to test with" },
       { "-min",      FALSE, etREAL, {&minPMEfraction},
         "Min fraction of PME nodes to test with" },
+      { "-npme",     FALSE, etENUM, {npmevalues_opt},
+        "Benchmark all possible values for -npme or just the subset that is expected to perform well"},
       { "-upfac",    FALSE, etREAL, {&upfac},
         "Upper limit for rcoulomb scaling factor (Note that rcoulomb upscaling results in fourier grid downscaling)" },
       { "-downfac",  FALSE, etREAL, {&downfac},
@@ -1569,7 +1861,7 @@ int gmx_tune_pme(int argc,char *argv[])
       { "-ntpr",     FALSE, etINT,  {&ntprs},
         "Number of tpr files to benchmark. Create these many files with scaling factors ranging from 1.0 to fac. If < 1, automatically choose the number of tpr files to test" },
       { "-four",     FALSE, etREAL, {&fs},
-        "Use this fourierspacing value instead of the grid found in the tpr input file" },        
+        "Use this fourierspacing value instead of the grid found in the tpr input file. (Spacing applies to a scaling factor of 1.0 if multiple tpr files are written)" },
       { "-steps",    FALSE, etGMX_LARGE_INT, {&bench_nsteps},
         "Take timings for these many steps in the benchmark runs" }, 
       { "-resetstep",FALSE, etINT,  {&presteps},
@@ -1692,8 +1984,9 @@ int gmx_tune_pme(int argc,char *argv[])
     fp = ffopen(opt2fn("-p",NFILE,fnm),"w");
     
     /* Make a quick consistency check of command line parameters */
-    check_input(nnodes, repeats, &ntprs, upfac, downfac, maxPMEfraction,
-                minPMEfraction, fs, bench_nsteps, fnm, NFILE, sim_part, presteps);
+    check_input(nnodes, repeats, &ntprs, &upfac, &downfac, maxPMEfraction,
+                minPMEfraction, fs, bench_nsteps, fnm, NFILE, sim_part, presteps,
+                asize(pa),pa);
     
     /* Determine max and min number of PME nodes to test: */
     if (nnodes > 2)
@@ -1732,7 +2025,6 @@ int gmx_tune_pme(int argc,char *argv[])
         fprintf(fp, "Number of threads       : %d\n", nnodes);
 
     fprintf(fp, "The mdrun  command is   : %s\n", cmd_mdrun);
-    fprintf(fp, "Input file is           : %s\n", opt2fn("-s",NFILE,fnm));
     fprintf(fp, "mdrun args benchmarks   : %s\n", cmd_args_bench);
     fprintf(fp, "Benchmark steps         : ");
     fprintf(fp, gmx_large_int_pfmt, bench_nsteps);
@@ -1760,15 +2052,22 @@ int gmx_tune_pme(int argc,char *argv[])
         fprintf(fp, "Repeats for each test   : %d\n", repeats);
     
     if (fs > 0.0)
+    {
         fprintf(fp, "Requested grid spacing  : %f (tpr file will be changed accordingly)\n", fs);
+        fprintf(fp, "                          This will be the grid spacing at a scaling factor of 1.0\n");
+    }
     
+    fprintf(fp, "Input file              : %s\n", opt2fn("-s",NFILE,fnm));
+
     /* Allocate memory for the inputinfo struct: */
     snew(info, 1);
     info->nr_inputfiles = ntprs;
     for (i=0; i<ntprs; i++)
     {
         snew(info->r_coulomb , ntprs);
-        snew(info->r_vdW     , ntprs);
+        snew(info->r_vdw     , ntprs);
+        snew(info->rlist     , ntprs);
+        snew(info->rlistlong , ntprs);
         snew(info->fourier_nx, ntprs);
         snew(info->fourier_ny, ntprs);
         snew(info->fourier_nz, ntprs);
@@ -1782,65 +2081,33 @@ int gmx_tune_pme(int argc,char *argv[])
     make_benchmark_tprs(opt2fn("-s",NFILE,fnm), tpr_names, bench_nsteps+presteps,
             cpt_steps, upfac, downfac, ntprs, fs, info, fp);
 
-    if (repeats == 0)
-    {
-        fprintf(fp, "\nNo benchmarks done since number of repeats (-r) is 0.\n");
-        fclose(fp);
-        finalize(opt2fn("-p", NFILE, fnm));
-        return 0;
-    }
-    
-    /* Memory allocation for performance data */
-    if (nnodes > 2)
-    {
-        datasets = maxPMEnodes - minPMEnodes + 3;
-        if (0 == minPMEnodes)
-            datasets--;
-    }
-    else
-        datasets = 1;
-
-    /* Allocate one dataset for each tpr input file: */
-    snew(perfdata, ntprs);
-
-    /* Allocate a subset for each test with a given number of PME nodes */
-    for (k=0; k<ntprs; k++)
-    {
-        snew(perfdata[k], datasets);
-        for (i=0; i<datasets; i++)
-        {
-            for (j=0; j<repeats; j++)
-            {
-                snew(perfdata[k][i].Gcycles   , repeats);
-                snew(perfdata[k][i].ns_per_day, repeats);
-                snew(perfdata[k][i].PME_f_load, repeats);
-            }
-        }
-    }
 
     /********************************************************************************/
     /* Main loop over all scenarios we need to test: tpr files, PME nodes, repeats  */
     /********************************************************************************/
-    do_the_tests(fp, tpr_names, maxPMEnodes, minPMEnodes, datasets, perfdata,
+    snew(perfdata, ntprs);
+    do_the_tests(fp, tpr_names, maxPMEnodes, minPMEnodes, npmevalues_opt[0], perfdata, &pmeentries,
                  repeats, nnodes, ntprs, bThreads, cmd_mpirun, cmd_np, cmd_mdrun,
                  cmd_args_bench, fnm, NFILE, sim_part, presteps, cpt_steps);
     
     fprintf(fp, "\nTuning took%8.1f minutes.\n", (gettime()-seconds)/60.0);
 
     /* Analyse the results and give a suggestion for optimal settings: */
-    analyze_data(fp, opt2fn("-p", NFILE, fnm), perfdata, nnodes, ntprs, datasets,
-                 repeats, info, &best_tpr, &best_npme);
+    bKeepTPR = analyze_data(fp, opt2fn("-p", NFILE, fnm), perfdata, nnodes, ntprs, pmeentries,
+                            repeats, info, &best_tpr, &best_npme);
     
     /* Take the best-performing tpr file and enlarge nsteps to original value */
-    if ((best_tpr > 0) || bOverwrite || (fs > 0.0))
+    if ( bKeepTPR && !bOverwrite && !(fs > 0.0) )
+    {
+        simulation_tpr = opt2fn("-s",NFILE,fnm);
+    }
+    else
     {
         simulation_tpr = opt2fn("-so",NFILE,fnm);
         modify_PMEsettings(bOverwrite? (new_sim_nsteps+cpt_steps) : 
                            info->orig_sim_steps, tpr_names[best_tpr], 
                            simulation_tpr);            
     }
-    else
-        simulation_tpr = opt2fn("-s",NFILE,fnm);
 
     /* Now start the real simulation if the user requested it ... */
     launch_simulation(bLaunch, fp, bThreads, cmd_mpirun, cmd_np, cmd_mdrun,
index 8e4c123edddd05cb4ed2b175afaddc574bab8464..bd81d928d03fb8ceeb110dfe7b99d1204da0ae00 100644 (file)
@@ -133,7 +133,8 @@ int gmx_vanhove(int argc,char *argv[])
   int      ePBC;
   matrix   boxtop,box,*sbox,avbox,corr;
   rvec     *xtop,*x,**sx;
-  int      status,isize,nalloc,nallocn,natom;
+  int      isize,nalloc,nallocn,natom;
+  t_trxstatus *status;
   atom_id  *index;
   char     *grpname;
   int      nfr,f,ff,i,m,mat_nx=0,nbin=0,bin,mbin,fbin;
index 9bab05fa761f50df670480eefa19b8c35b930cd7..5b041bc618d6d46dedf27adc850731dfeed313be 100644 (file)
@@ -137,7 +137,8 @@ int gmx_velacc(int argc,char *argv[])
   char       *grpname;
   char       title[256];
   real       t0,t1,m;
-  int        status,teller,n_alloc,i,j,tel3,k,l;
+  t_trxstatus *status;
+  int        teller,n_alloc,i,j,tel3,k,l;
   rvec       mv_mol;
   real       **c1;
   real      *normm=NULL;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e7a39ae
--- /dev/null
@@ -0,0 +1,2 @@
+enable_testing()
+add_test(TestExec_mdrun-h ../src/kernel/mdrun -h)