Merge release-4-5-patches into release-4-6
[alexxy/gromacs.git] / src / gmxlib / tpxio.c
index 59fed9f4207f64b7ccd6ff8501ffa388eca059ac..c640bb5dac989eefa2a9ec9c00a2396ce6aaae40 100644 (file)
@@ -38,7 +38,7 @@
 #endif
 
 /* This file is completely threadsafe - keep it that way! */
-#ifdef GMX_THREADS
+#ifdef GMX_THREAD_MPI
 #include <thread_mpi.h>
 #endif
 
 #include "vec.h"
 #include "mtop_util.h"
 
+#define TPX_TAG_RELEASE  "release"
+
+/* This is the tag string which is stored in the tpx file.
+ * Change this if you want to change the tpx format in a feature branch.
+ * This ensures that there will not be different tpx formats around which
+ * can not be distinguished.
+ */
+static const char *tpx_tag = TPX_TAG_RELEASE;
+
 /* This number should be increased whenever the file format changes! */
-static const int tpx_version = 73;
+static const int tpx_version = 77;
 
 /* This number should only be increased when you edit the TOPOLOGY section
  * of the tpx format. This way we can maintain forward compatibility too
@@ -126,6 +135,7 @@ static const t_ftupd ftupd[] = {
   { 43, F_TABBONDS          },
   { 43, F_TABBONDSNC        },
   { 70, F_RESTRBONDS        },
+  { 76, F_LINEAR_ANGLES     },
   { 30, F_CROSS_BOND_BONDS  },
   { 30, F_CROSS_BOND_ANGLES },
   { 30, F_UREY_BRADLEY      },
@@ -161,6 +171,7 @@ static const t_ftupd ftupd[] = {
   { 69, F_VTEMP             },
   { 66, F_PDISPCORR         },
   { 54, F_DHDL_CON          },
+  { 76, F_ANHARM_POL        }
 };
 #define NFTUPD asize(ftupd)
 
@@ -249,6 +260,47 @@ static void do_pull(t_fileio *fio, t_pull *pull,gmx_bool bRead, int file_version
     do_pullgrp(fio,&pull->grp[g],bRead,file_version);
 }
 
+
+static void do_rotgrp(t_fileio *fio, t_rotgrp *rotg,gmx_bool bRead, int file_version)
+{
+  gmx_bool bDum=TRUE;
+  int  i;
+
+  gmx_fio_do_int(fio,rotg->eType);
+  gmx_fio_do_int(fio,rotg->bMassW);
+  gmx_fio_do_int(fio,rotg->nat);
+  if (bRead)
+    snew(rotg->ind,rotg->nat);
+  gmx_fio_ndo_int(fio,rotg->ind,rotg->nat);
+  if (bRead)
+      snew(rotg->x_ref,rotg->nat);
+  gmx_fio_ndo_rvec(fio,rotg->x_ref,rotg->nat);
+  gmx_fio_do_rvec(fio,rotg->vec);
+  gmx_fio_do_rvec(fio,rotg->pivot);
+  gmx_fio_do_real(fio,rotg->rate);
+  gmx_fio_do_real(fio,rotg->k);
+  gmx_fio_do_real(fio,rotg->slab_dist);
+  gmx_fio_do_real(fio,rotg->min_gaussian);
+  gmx_fio_do_real(fio,rotg->eps);
+  gmx_fio_do_int(fio,rotg->eFittype);
+  gmx_fio_do_int(fio,rotg->PotAngle_nstep);
+  gmx_fio_do_real(fio,rotg->PotAngle_step);
+}
+
+static void do_rot(t_fileio *fio, t_rot *rot,gmx_bool bRead, int file_version)
+{
+  int g;
+
+  gmx_fio_do_int(fio,rot->ngrp);
+  gmx_fio_do_int(fio,rot->nstrout);
+  gmx_fio_do_int(fio,rot->nstsout);
+  if (bRead)
+    snew(rot->grp,rot->ngrp);
+  for(g=0; g<rot->ngrp; g++)
+    do_rotgrp(fio, &rot->grp[g],bRead,file_version);
+}
+
+
 static void do_inputrec(t_fileio *fio, t_inputrec *ir,gmx_bool bRead, 
                         int file_version, real *fudgeQQ)
 {
@@ -262,7 +314,7 @@ static void do_inputrec(t_fileio *fio, t_inputrec *ir,gmx_bool bRead,
     if (file_version != tpx_version)
     {
         /* Give a warning about features that are not accessible */
-        fprintf(stderr,"Note: tpx file_version %d, software version %d\n",
+        fprintf(stderr,"Note: file tpx version %d, software tpx version %d\n",
                 file_version,tpx_version);
     }
 
@@ -745,6 +797,36 @@ static void do_inputrec(t_fileio *fio, t_inputrec *ir,gmx_bool bRead,
     gmx_fio_do_real(fio,ir->userreal3); 
     gmx_fio_do_real(fio,ir->userreal4); 
     
+    /* AdResS stuff */
+    if (file_version >= 75) {
+      gmx_fio_do_gmx_bool(fio,ir->bAdress);
+      if(ir->bAdress){
+          if (bRead) snew(ir->adress, 1);
+          gmx_fio_do_int(fio,ir->adress->type);
+          gmx_fio_do_real(fio,ir->adress->const_wf);
+          gmx_fio_do_real(fio,ir->adress->ex_width);
+          gmx_fio_do_real(fio,ir->adress->hy_width);
+          gmx_fio_do_int(fio,ir->adress->icor);
+          gmx_fio_do_int(fio,ir->adress->site);
+          gmx_fio_do_rvec(fio,ir->adress->refs);
+          gmx_fio_do_int(fio,ir->adress->n_tf_grps);
+          gmx_fio_do_real(fio, ir->adress->ex_forcecap);
+          gmx_fio_do_int(fio, ir->adress->n_energy_grps);
+          gmx_fio_do_int(fio,ir->adress->do_hybridpairs);
+
+          if (bRead)snew(ir->adress->tf_table_index,ir->adress->n_tf_grps);
+          if (ir->adress->n_tf_grps > 0) {
+            bDum=gmx_fio_ndo_int(fio,ir->adress->tf_table_index,ir->adress->n_tf_grps);
+          }
+          if (bRead)snew(ir->adress->group_explicit,ir->adress->n_energy_grps);
+          if (ir->adress->n_energy_grps > 0) {
+            bDum=gmx_fio_ndo_int(fio, ir->adress->group_explicit,ir->adress->n_energy_grps);
+          }
+      }
+    } else {
+      ir->bAdress = FALSE;
+    }
+
     /* pull stuff */
     if (file_version >= 48) {
       gmx_fio_do_int(fio,ir->ePull);
@@ -757,6 +839,18 @@ static void do_inputrec(t_fileio *fio, t_inputrec *ir,gmx_bool bRead,
       ir->ePull = epullNO;
     }
     
+    /* Enforced rotation */
+    if (file_version >= 74) {
+        gmx_fio_do_int(fio,ir->bRot);
+        if (ir->bRot == TRUE) {
+            if (bRead)
+                snew(ir->rot,1);
+            do_rot(fio, ir->rot,bRead,file_version);
+        }
+    } else {
+        ir->bRot = FALSE;
+    }
+    
     /* grpopts stuff */
     gmx_fio_do_int(fio,ir->opts.ngtc); 
     if (file_version >= 69) {
@@ -948,6 +1042,12 @@ void do_iparams(t_fileio *fio, t_functype ftype,t_iparams *iparams,
       iparams->pdihs.cpB  = iparams->pdihs.cpA;
     }
     break;
+  case F_LINEAR_ANGLES:
+    gmx_fio_do_real(fio,iparams->linangle.klinA);
+    gmx_fio_do_real(fio,iparams->linangle.aA);
+    gmx_fio_do_real(fio,iparams->linangle.klinB);
+    gmx_fio_do_real(fio,iparams->linangle.aB);
+    break;
   case F_FENEBONDS:
     gmx_fio_do_real(fio,iparams->fene.bm);
     gmx_fio_do_real(fio,iparams->fene.kb);
@@ -1011,6 +1111,11 @@ void do_iparams(t_fileio *fio, t_functype ftype,t_iparams *iparams,
   case F_POLARIZATION:
     gmx_fio_do_real(fio,iparams->polarize.alpha);
     break;
+  case F_ANHARM_POL:
+    gmx_fio_do_real(fio,iparams->anharm_polarize.alpha);
+    gmx_fio_do_real(fio,iparams->anharm_polarize.drcut);
+    gmx_fio_do_real(fio,iparams->anharm_polarize.khyp);
+    break;
   case F_WATER_POL:
     if (file_version < 31) 
       gmx_fatal(FARGS,"Old tpr files with water_polarization not supported. Make a new.");
@@ -1952,7 +2057,8 @@ static void do_tpxheader(t_fileio *fio,gmx_bool bRead,t_tpxheader *tpx,
                          gmx_bool TopOnlyOK, int *file_version, 
                          int *file_generation)
 {
-  char  buf[STRLEN];
+    char  buf[STRLEN];
+    char  file_tag[STRLEN];
   gmx_bool  bDouble;
   int   precision;
   int   fver,fgen;
@@ -1987,21 +2093,59 @@ static void do_tpxheader(t_fileio *fio,gmx_bool bRead,t_tpxheader *tpx,
     gmx_fio_setprecision(fio,bDouble);
     gmx_fio_do_int(fio,precision);
     fver = tpx_version;
+    sprintf(file_tag,"%s",tpx_tag);
     fgen = tpx_generation;
   }
   
-  /* Check versions! */
-  gmx_fio_do_int(fio,fver);
+    /* Check versions! */
+    gmx_fio_do_int(fio,fver);
   
-  if(fver>=26)
-    gmx_fio_do_int(fio,fgen);
-  else
-    fgen=0;
+    if (fver >= 77)
+    {
+        gmx_fio_do_string(fio,file_tag);
+    }
+    if (bRead)
+    {
+        if (fver < 77)
+        {
+            /* Versions before 77 don't have the tag, set it to release */
+            sprintf(file_tag,"%s",TPX_TAG_RELEASE);
+        }
+
+        if (strcmp(file_tag,tpx_tag) != 0)
+        {
+            fprintf(stderr,"Note: file tpx tag '%s', software tpx tag '%s'\n",
+                    file_tag,tpx_tag);
+
+            /* We only support reading tpx files with the same tag as the code
+             * or tpx files with the release tag and with lower version number.
+             */
+            if (!(strcmp(file_tag,TPX_TAG_RELEASE) == 0 && fver < tpx_version))
+            {
+                gmx_fatal(FARGS,"tpx tag/version mismatch: reading tpx file (%s) version %d, tag '%s' with program for tpx version %d, tag '%s'",
+                          gmx_fio_getname(fio),fver,file_tag,
+                          tpx_version,tpx_tag);
+            }
+        }
+    }
+
+    if (fver >= 26)
+    {
+        gmx_fio_do_int(fio,fgen);
+    }
+    else
+    {
+        fgen=0;
+    }
  
-  if(file_version!=NULL)
-    *file_version = fver;
-  if(file_generation!=NULL)
-    *file_generation = fgen;
+    if (file_version != NULL)
+    {
+        *file_version = fver;
+    }
+    if (file_generation != NULL)
+    {
+        *file_generation = fgen;
+    }
    
   
   if ((fver <= tpx_incompatible_version) ||
@@ -2371,7 +2515,7 @@ gmx_bool read_tps_conf(const char *infile,char *title,t_topology *top,int *ePBC,
 {
   t_tpxheader  header;
   int          natoms,i,version,generation;
-  gmx_bool         bTop,bXNULL;
+  gmx_bool         bTop,bXNULL=FALSE;
   gmx_mtop_t   *mtop;
   t_topology   *topconv;
   gmx_atomprop_t aps;
@@ -2395,14 +2539,19 @@ gmx_bool read_tps_conf(const char *infile,char *title,t_topology *top,int *ePBC,
   else {
     get_stx_coordnum(infile,&natoms);
     init_t_atoms(&top->atoms,natoms,(fn2ftp(infile) == efPDB));
-    bXNULL = (x == NULL);
+    if (x == NULL)
+    {
+        snew(x,1);
+        bXNULL = TRUE;
+    }
     snew(*x,natoms);
     if (v)
       snew(*v,natoms);
     read_stx_conf(infile,title,&top->atoms,*x,(v==NULL) ? NULL : *v,ePBC,box);
-    if (bXNULL) {
+    if (bXNULL)
+    {
       sfree(*x);
-      x = NULL;
+      sfree(x);
     }
     if (bMass) {
       aps = gmx_atomprop_init();