예제 #1
0
void ComputeDPMEMaster::recvData(ComputeDPMEDataMsg *msg)
{ 
  DebugM(4,"ComputeDPMEMaster::recvData() " << msg->numParticles
	<< " particles from node " << msg->node << "\n");

  {
    homeNode.add(msg->node);
    Pme2Particle *data_ptr = localData + numLocalAtoms;
    for ( int j = 0; j < msg->numParticles; ++j, ++data_ptr ) {
      *data_ptr = msg->particles[j];
    }
    numLocalAtoms += msg->numParticles;
    endForNode.add(numLocalAtoms);
    delete msg;
  }

  if ( homeNode.size() < numWorkingPes ) return;  // messages outstanding

  DebugM(4,"ComputeDPMEMaster::recvData() running serial code.\n");

  // single processor version

  Lattice lattice = host->getFlags()->lattice;
  SimParameters * simParams = Node::Object()->simParameters;
  int i;

  AtomInfo atom_info;
  atom_info.numatoms = numLocalAtoms;
  atom_info.atompnt = 0;  // not used
  atom_info.freepnt = 0;  // not used
  atom_info.nlocal = numLocalAtoms;
  atom_info.nother = 0;

  if ( ! lattice.orthogonal() ) {
    NAMD_die("DPME only supports orthogonal PBC's.");
  }

  BoxInfo box_info;
  box_info.box.x = lattice.a().x;
  box_info.box.y = lattice.b().y;
  box_info.box.z = lattice.c().z;
  box_info.box.origin = 0.;  // why only one number?
  box_info.prd.x = box_info.box.x;
  box_info.prd.y = box_info.box.y;
  box_info.prd.z = box_info.box.z;
  box_info.prd2.x = 0.5 * box_info.box.x;
  box_info.prd2.y = 0.5 * box_info.box.y;
  box_info.prd2.z = 0.5 * box_info.box.z;
  box_info.cutoff = simParams->cutoff;
  box_info.rs = simParams->cutoff;
  box_info.mc2.x = 2. * ( box_info.prd.x - box_info.cutoff );
  box_info.mc2.y = 2. * ( box_info.prd.y - box_info.cutoff );
  box_info.mc2.z = 2. * ( box_info.prd.z - box_info.cutoff );
  box_info.ewaldcof = ComputeNonbondedUtil::ewaldcof;
  box_info.dtol = simParams->PMETolerance;
  for (i = 0; i <= 8; i++) {
    box_info.recip[i] = 0.; /* assume orthogonal box */
  }
  box_info.recip[0] = 1.0/box_info.box.x;
  box_info.recip[4] = 1.0/box_info.box.y;
  box_info.recip[8] = 1.0/box_info.box.z;

  GridInfo grid_info;
  grid_info.order = simParams->PMEInterpOrder;
  grid_info.nfftgrd.x = simParams->PMEGridSizeX;
  grid_info.nfftgrd.y = simParams->PMEGridSizeY;
  grid_info.nfftgrd.z = simParams->PMEGridSizeZ;
  grid_info.nfft = 0;
  grid_info.volume = lattice.volume();

  PeInfo pe_info;  // hopefully this isn't used for anything
  pe_info.myproc.node = 0;
  pe_info.myproc.nprocs = 1;
  pe_info.myproc.ncube = 0;
  pe_info.inst_node[0] = 0;
  pe_info.igrid = 0;

  PmeVector *localResults;
  double recip_vir[6];
  int time_count = 0;
  int tsteps = 1;
  double mytime = 0.;

  // perform calculations
  BigReal electEnergy = 0;

  // calculate self energy
  Pme2Particle *data_ptr = localData;
  for(i=0; i<numLocalAtoms; ++i)
  {
    electEnergy += data_ptr->cg * data_ptr->cg;
    ++data_ptr;
  }
  electEnergy *= -1. * box_info.ewaldcof / SQRT_PI;

  DebugM(4,"Ewald self energy: " << electEnergy << "\n");

  DebugM(4,"Calling dpme_eval_recip().\n");

  double pme_start_time = 0;
  if ( runcount == 1 ) pme_start_time = CmiTimer();

  electEnergy += dpme_eval_recip( atom_info, localData - 1, &localResults,
			recip_vir, grid_info, box_info, pe_info,
			time_count, tsteps, &mytime );

  if ( runcount == 1 ) {
    iout << iINFO << "PME reciprocal sum CPU time per evaluation: "
         << (CmiTimer() - pme_start_time) << "\n" << endi;
  }

  DebugM(4,"Returned from dpme_eval_recip().\n");

  // REVERSE SIGN OF VIRIAL RETURNED BY DPME
  for(i=0; i<6; ++i) recip_vir[i] *= -1.;

  // send out reductions
  DebugM(4,"Timestep : " << host->getFlags()->step << "\n");
  DebugM(4,"Reciprocal sum energy: " << electEnergy << "\n");
  DebugM(4,"Reciprocal sum virial: " << recip_vir[0] << " " <<
	recip_vir[1] << " " << recip_vir[2] << " " << recip_vir[3] << " " <<
	recip_vir[4] << " " << recip_vir[5] << "\n");
  reduction->item(REDUCTION_ELECT_ENERGY_SLOW) += electEnergy;
  reduction->item(REDUCTION_VIRIAL_SLOW_XX) += (BigReal)(recip_vir[0]);
  reduction->item(REDUCTION_VIRIAL_SLOW_XY) += (BigReal)(recip_vir[1]);
  reduction->item(REDUCTION_VIRIAL_SLOW_XZ) += (BigReal)(recip_vir[2]);
  reduction->item(REDUCTION_VIRIAL_SLOW_YX) += (BigReal)(recip_vir[1]);
  reduction->item(REDUCTION_VIRIAL_SLOW_YY) += (BigReal)(recip_vir[3]);
  reduction->item(REDUCTION_VIRIAL_SLOW_YZ) += (BigReal)(recip_vir[4]);
  reduction->item(REDUCTION_VIRIAL_SLOW_ZX) += (BigReal)(recip_vir[2]);
  reduction->item(REDUCTION_VIRIAL_SLOW_ZY) += (BigReal)(recip_vir[4]);
  reduction->item(REDUCTION_VIRIAL_SLOW_ZZ) += (BigReal)(recip_vir[5]);
  reduction->submit();

  PmeVector *results_ptr = localResults + 1;

  numLocalAtoms = 0;
  for ( i = 0; i < homeNode.size(); ++i ) {
    ComputeDPMEResultsMsg *msg = new ComputeDPMEResultsMsg;
    msg->node = homeNode[i];
    msg->numParticles = endForNode[i] - numLocalAtoms;
    msg->forces = new PmeVector[msg->numParticles];
    for ( int j = 0; j < msg->numParticles; ++j, ++results_ptr ) {
      msg->forces[j] = *results_ptr;
    }
    numLocalAtoms = endForNode[i];
    host->comm->sendComputeDPMEResults(msg,homeNode[i]);
  }

  // reset
  runcount += 1;
  numLocalAtoms = 0;
  homeNode.resize(0);
  endForNode.resize(0);

}
예제 #2
0
GromacsTopFile::GromacsTopFile(char *filename) {
  fudgeLJ = fudgeQQ = 1.0;
  /* open the file */
  FILE *f = fopen(filename,"r");
  char buf[LINESIZE];
  char modename[20];
  int mode;
  if(f==NULL) {
    sprintf(buf,"Error opening file '%s'",filename);
    NAMD_die(buf);
  }

  /* really bad parser XXX probably just works on the files we
     happen to have REWRITE THIS SOON.  It should allow for \- line
     continuations, check for errors in the file, etc. */
  while(fgets(buf,LINESIZE-1,f)) {
    char testchar;
    int i,j;

    /* defaults */
    int nbfunc, combrule;
    char genpairs[20];
    
    /* atom buffers */
    int num, resnum, chargegp, typenum;
    char type[NAMESIZE+1], restype[NAMESIZE+1], atomname[NAMESIZE+1];
    char particletype[NAMESIZE+1];
    float charge, mass, c6, c12, junkf;

    /* moltype buffers */
    int nrexcl;
    char molname[LONGNAMESIZE+1];

    /* molInst buffers */
    int copies;
    MolInst *moleculeinstance;

    /* general atomset buffers */
    int atomi, atomj, atomk, atoml;
    char typea[NAMESIZE+1],typeb[NAMESIZE+1],
      typec[NAMESIZE+1],typed[NAMESIZE+1];
    const char *tmptypea,*tmptypeb,*tmptypec,*tmptyped;
    int funct, index;
    float c0,c1;
    
    /* bonds */
    float b0,kB,th0,kth;

    /* dihedrals */
    float c[6];
    int mult=0;

    /* check for comments */
    if(sscanf(buf," %c",&testchar)==1) {
      if(testchar == ';') continue;
    }
    else { /* this is a blank line */
      continue;
    }

    /* check for a new mode */
    if(sscanf(buf," [ %19[^] ] ]",modename)==1) {
      /* switch the mode */
      if(0==strcmp(modename,"atoms"))              mode = ATOMS;
      else if(0==strcmp(modename,"atomtypes"))	   mode = ATOMTYPES;
      else if(0==strcmp(modename,"moleculetype"))  mode = MOLECULETYPE;
      else if(0==strcmp(modename,"molecules"))	   mode = MOLECULES;
      else if(0==strcmp(modename,"system"))	   mode = SYSTEM;
      else if(0==strcmp(modename,"bonds"))	   mode = BONDS;
      else if(0==strcmp(modename,"bondtypes"))	   mode = BONDTYPES;
      else if(0==strcmp(modename,"angles"))	   mode = ANGLES;
      else if(0==strcmp(modename,"angletypes"))	   mode = ANGLETYPES;
      else if(0==strcmp(modename,"dihedrals"))	   mode = DIHEDRALS;
      else if(0==strcmp(modename,"dihedraltypes")) mode = DIHEDRALTYPES;
      else if(0==strcmp(modename,"defaults"))      mode = DEFAULTS;
      else if(0==strcmp(modename,"nonbond_params")) mode = NONBOND;
      // JLai
      else if(0==strcmp(modename,"pairs")) mode = PAIRS;
      else if(0==strcmp(modename,"exclusions")) mode = EXCLUSIONS;
      else {	
	fprintf(stderr,"Warning: unknown mode %s\n",modename);
	mode = UNKNOWN;
      }

      continue;
    }

    /* now do the appropriate thing based on the current mode */
    switch(mode) {
    case SYSTEM:
      systemName = strdup(buf);
      break;

    case DEFAULTS:
      i = sscanf(buf," %d %d %20s %f %f",
		 &nbfunc,&combrule,genpairs,&fudgeLJ,&fudgeQQ);
      if(i < 3) { // didn't get enough parameters 
	fprintf(stderr,"syntax error in DEFAULTS\n");
	exit(1);
      }
      if(nbfunc != 1) { // I don't know how it works with nbfunc=2
	fprintf(stderr,"Non-bonded function != 1 unsupported in DEFAULTS\n");
	exit(1);
      }
      if(combrule != 1) { // same here
	fprintf(stderr,"Combination rule != 1 unsupported in DEFAULTS\n");
	exit(1);
      }
      if(0==strcmp(genpairs,"yes")) {
	genPairs=1;
	if(i!=5) {
	  fprintf(stderr,"syntax error in DEFAULTS\n");
	  exit(1);
	}
	// else fudgeLJ and fudgeQQ got written automatically
      }
      else genPairs=0;

      break;

    case NONBOND:
      if(5 != sscanf(buf," %5s %5s %d %f %f",
		     typea, typeb, &funct, &c6, &c12)) {
	fprintf(stderr,"Syntax error in NONBOND\n");
	exit(1);
      }
      // convert kJ/mol*nm6 to kcal/mol*A6 and ..12 ..12
      c6 =  c6/JOULES_PER_CALORIE*1E6;
      c12= c12/JOULES_PER_CALORIE*1E12;
      vdwTable.addType(typea,typeb,c6,c12);
      break;

    case BONDS:
      i = sscanf(buf," %d %d %d %f %f",
		 &atomi,&atomj,&funct,&c0,&c1);
      atomi--; // shift right away to a zero-indexing
      atomj--;
      if(i==3) {
       tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
       tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
	/* find the index and parameters */
	index = bondTable.getParams(tmptypea, tmptypeb, funct, &b0, &kB);
	if(index==-1) {
	  fprintf(stderr,"Required bondtype %s--%s (function %d) not found.\n",
		  tmptypea,tmptypeb,funct);
	  exit(1);
	}
      }
      else if(i==5) {
	/* first set the values of b0 and kB correctly */
	b0 = c0*ANGSTROMS_PER_NM; /* convert nm to A */
	if(funct==1) { /* harmonic potential */
	  /* convert kJ/nm2 to kcal/A2 and use E=kx2 instead of half that. */
	  kB = c1/JOULES_PER_CALORIE/100/2;
	}
	else if(funct==2) { /* special fourth-order potential */
	  /* convert to the normal harmonic constant and kJ/nm2 to kcal/A2 */
	  kB = 2*c1*c0*c0/JOULES_PER_CALORIE/100;
	  kB /= 2; /* use the NAMD system where E=kx2 */
	}
	else {
	  fprintf(stderr,"I don't know what funct=%d means in BONDS\n",funct);
	  exit(1);
	}
	/* look up the index */
	index = bondTable.getIndex(b0,kB,funct);
      }
      else {
	fprintf(stderr,"Syntax error in BONDS\n");
	exit(1);
      }

      genericMols[genericMols.size()-1]->addBond(atomi,atomj,index);
      break;
      
    case BONDTYPES:
      if(5 != sscanf(buf," %5s %5s %d %f %f",
		     typea,typeb,&funct,&c0,&c1)) {
	fprintf(stderr,"Syntax error in BONDTYPES\n");
	exit(1);
      }

      /* first set the values of b0 and kB correctly */
      b0 = c0*10; /* convert nm to A */
      if(funct==1) { /* harmonic potential */
	/* convert kJ/nm2 to kcal/A2 and use E=kx2 instead of half that. */
	kB = c1/JOULES_PER_CALORIE/100/2;
      }
      else if(funct==2) { /* special fourth-order potential */
	/* convert to the normal harmonic constant and kJ/nm2 to kcal/A2 */
	kB = 2*c1*c0*c0/JOULES_PER_CALORIE/100;
	kB /= 2; /* use the NAMD system where E=kx2 */
      }
      else {
 fprintf(stderr,"I don't know what funct=%d means in BONDTYPES\n",funct);
	exit(1);
      }

      bondTable.addType(typea,typeb,b0,kB,funct);
      break;

    case ANGLES:
      i = sscanf(buf," %d %d %d %d %f %f",
		     &atomi,&atomj,&atomk,&funct,&c0,&c1);
      atomi--; // shift right away to a zero-indexing
      atomj--;
      atomk--;
      if(i == 4) { /* we have to look up the last two parameters */
       tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
       tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
       tmptypec = genericMols[genericMols.size()-1]->getAtom(atomk)->getType();
	/* find the index and parameters */
	index = angleTable.getParams(tmptypea, tmptypeb, tmptypec,
					funct, &th0, &kth);
	if(index==-1) {
	  fprintf(stderr,
		  "Required angletype %s--%s--%s (function %d) not found.\n",
		  tmptypea,tmptypeb,tmptypec,funct);
	  exit(1);
	}
      }
      else if(i == 6) {
	/* first set the values of th0 and kth correctly */
	if(funct == 1) {
	  th0 = c0; /* both are in degrees */
	  kth = c1/JOULES_PER_CALORIE/2; /* convert kJ/rad2 to kcal/rad2 and use E=kx2 */
	}
	else if(funct == 2) {
	  th0 = c0; /* both are in degrees */
	  /* convert G96 kJ to kcal/rad2 and use E=kx2 */
	  kth = sin(th0*PI/180)*sin(th0*PI/180)*c1/JOULES_PER_CALORIE/2;
	}
	else {
	  fprintf(stderr,"I don't know what funct=%d means in ANGLES\n",funct);
	  exit(1);
	}
	/* add the angle type to our table */
	index = angleTable.getIndex(th0,kth,funct);
      }
      else {
	fprintf(stderr,"Syntax error (%d args) in ANGLES: %s\n",i,buf);
	exit(1);
      }

      /* add the angle to our table */
      genericMols[genericMols.size()-1]->addAngle(atomi,atomj,atomk,index);
      break;

    case ANGLETYPES:
      if(6 != sscanf(buf," %5s %5s %5s %d %f %f",
		     typea,typeb,typec,&funct,&c0,&c1)) {
	fprintf(stderr,"Syntax error in ANGLETYPES\n");
	exit(1);
      }
      /* first set the values of th0 and kth correctly */
      if(funct == 1) {
	th0 = c0; /* both are in degrees */
	kth = c1/JOULES_PER_CALORIE/2; /* convert kJ/rad2 to kcal/rad2 and use E=kx2 */
      }
      else if(funct == 2) {
	th0 = c0; /* both are in degrees */
	/* convert G96 kJ to kcal/rad2 and use E=kx2 */
	kth = sin(th0*PI/180)*sin(th0*PI/180)*c1/JOULES_PER_CALORIE/2;
      }
      else {
	fprintf(stderr,"I don't know what funct=%d means in ANGLETYPES\n",
		funct);
	exit(1);
      }
      angleTable.addType(typea,typeb,typec,th0,kth,funct);
      break;

    case DIHEDRALS:
      i = sscanf(buf," %d %d %d %d %d %f %f %f %f %f %f",
		 &atomi,&atomj,&atomk,&atoml,&funct,
		 &c[0],&c[1],&c[2],&c[3],&c[4],&c[5]);
      atomi--; // shift right away to a zero-indexing
      atomj--;
      atomk--;
      atoml--;
      if(i==5) { /* we have to look up the parameters */
       tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
       tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
       tmptypec = genericMols[genericMols.size()-1]->getAtom(atomk)->getType();
       tmptyped = genericMols[genericMols.size()-1]->getAtom(atoml)->getType();
	/* find the index and parameters */
	index = dihedralTable.getParams(tmptypea, tmptypeb, tmptypec,
					tmptyped, funct, c, &mult);
	if(index==-1) {
	  fprintf(stderr,
	     "Required dihedraltype %s--%s--%s--%s (function %d) not found.\n",
		  tmptypea,tmptypeb,tmptypec,tmptyped,funct);
	  exit(1);
	}
      }
      else if(i==7 || i==8 || i==11) { /* the parameters are given */
	if(funct==1 || funct==2) { /* we should have two parameters */
	  if(i!=7+(funct==1)) {    /* plus a multiplicity for funct==1 */
	    fprintf(stderr,"Must have 7 args for funct=1,2\n");
	    exit(1);
	  }
	  c[0] = c[0]; /* both in deg */
	  if(i==7) {
	      c[1] = c[1]/(2*JOULES_PER_CALORIE); /* convert kJ to kcal and still use E=kx2*/
	  } else if (i==8 || i==11) {
	      c[1] = c[1]/(1*JOULES_PER_CALORIE); /* convert kJ to kcal and still use E=kx2*/
	  } 
	  //c[1] = c[1]/(2*JOULES_PER_CALORIE); /* convert kJ to kcal and still use E=kx2*/
	  /* for funct==1 these are both divided by rad^2 */
	  if(funct==1) {
	    mult=(int)(c[2]+0.5); /* round to nearest integer :p */
	  }
	}
	else if(funct==3) {
	  if(i!=11){
	    fprintf(stderr,"Must have 11 args for funct=3\n");
	    exit(1);
	  }

	  for(j=0;j<6;j++) {
	    c[j] = c[j]/JOULES_PER_CALORIE; /* convert kJ to kcal and E=Cn cos^n */
	  }
	}
	else {
	  fprintf(stderr,
		  "I don't know what funct=%d means in DIHEDRALS\n",funct);
	  exit(1);
	}
	index = dihedralTable.getIndex(c,mult,funct);
      }
      else {
	fprintf(stderr,"Syntax error (%d args) in DIHEDRALS: %s\n",i,buf);
	exit(1);
      }

      /* add the dihedrals to our table */
      genericMols[genericMols.size()-1]->addDihedral(atomi,atomj,atomk,atoml,
						     index);
      break;
    case DIHEDRALTYPES:
      i = sscanf(buf," %5s %5s %d %f %f %f %f %f %f",
		 typea,typeb,&funct,&c[0],&c[1],&c[2],&c[3],&c[4],&c[5]);
      if(funct == 1 || funct == 2) {
	if(i!=5+(funct==1)) { /* 6 for f=2, 5 for f=1 */
	  fprintf(stderr,"Syntax error in DIHEDRALTYPES: %s\n",buf);
	  exit(1);
	}
	c[0] = c[0]; /* both in deg */
	c[1] = c[1]/JOULES_PER_CALORIE; /* convert kJ to kcal and still use E=kx2*/
	/* for funct==1 these are both divided by rad^2 */
	if(funct==1) {
	  mult=(int)(c[2]+0.5); /* round to nearest integer :p */
	}
      }
      else if(funct == 3) {
	if(i!=9) {
	  fprintf(stderr,"Syntax error in DIHEDRALTYPES\n");
	  exit(1);
	}
	for(j=0;j<6;j++) {
	  c[j] = c[j]/JOULES_PER_CALORIE; /* convert kJ to kcal and E=Cn cos^n */
	}
      }
      else {
	fprintf(stderr,"I don't know what funct=%d means in DIHEDRALTYPES\n",
		funct);
	exit(1);
      }
      dihedralTable.addType(typea,typeb,c,mult,funct);
      break;
      
    case ATOMS:
      i = sscanf(buf," %d %5s %d %5s %5s %d %f %f",
		   &num, type, &resnum, restype,
		 atomname, &chargegp, &charge, &mass);
      if(i==7) { /* XXX temporary - I should be able to get more
		    params */
        typenum = atomTable.getParams(type,&mass,&junkf,&junkf,&junkf);
	i=8;
      }
      else {
	if(i!=8) {
	  fprintf(stderr,"Syntax error in ATOMS\n");
	  exit(1);
	}
	// just get the type number
	typenum = atomTable.getParams(type,&junkf,&junkf,&junkf,&junkf);
      }
      genericMols[genericMols.size()-1]->addAtom(type,typenum,resnum,
						 restype,atomname,charge,mass);
      break;

    case ATOMTYPES:
      if(6 != sscanf(buf," %5s %f %f %5s %f %f",type,&mass,&charge,
		     particletype,&c6,&c12)) {
	fprintf(stderr,"Syntax error in ATOMTYPES: %s\n",buf);
	exit(1);
      }
      /* conversions:
	 c6  - kJ/mol nm6  -> kcal/mol A6
	 c12 - kJ/mol nm12 -> kcal/mol A12 */
      atomTable.addType(type,mass,charge,
			c6/(JOULES_PER_CALORIE)*1E6,
			c12/(JOULES_PER_CALORIE)*1E12);
      break;

    case MOLECULETYPE:
      if(2!=sscanf(buf," %20s %d",molname,&nrexcl)) {
	fprintf(stderr,"Syntax error in MOLECULETYPE: %s\n",buf);
	exit(1);
      }

      /* add another generic molecule holder */
      genericMols.add(new GenericMol(molname));
      break;

    case MOLECULES:
      if(2!=sscanf(buf," %20s %d",molname,&copies)) {
	fprintf(stderr,"Syntax error in MOLECULES: %s\n",buf);
	exit(1);
      }
      
      /* search for the specified molecule and make a molInst of it*/
      moleculeinstance = NULL;
      for(i=0;i<genericMols.size();i++) {
	if(0==strcmp(molname,genericMols[i]->getName())) {
	  moleculeinstance = new MolInst(genericMols[i],copies);
	  break;
	}
      }

      if(moleculeinstance==NULL) {
	fprintf(stderr,"Molecule %s undefined.\n",molname);
	exit(1);
      }
      
      /* put it at the end of the list */
      molInsts.add(moleculeinstance);

      break;
    case PAIRS:
      int indexA;
      int indexB;
      int pairFunction;
      Real fA;
      Real fB;
      Real fC;
      Real fD;
      Real fE;
      Real fF;
      
      int countVariables;
      countVariables = sscanf(buf," %d %d %d %f %f %f %f %f %f",&indexA,&indexB,&pairFunction,&fA,&fB,&fC,&fD,&fE,&fF);

      if ((countVariables >= 4 && countVariables >= 10)) {
	fprintf(stderr,"Syntax error in PAIRS: %s\n",buf);
	exit(1);
      }
      
      // Shift the atom indices to be zero-based
      indexA--;
      indexB--;

      // Make sure that the indexA is less than indexB
      /*if ( indexA > indexB ) {
	  int tmpIndex = indexA;
	  indexB = indexA;
	  indexA = tmpIndex;
	  }*/

      if (pairFunction == 1) {
	
	// LJ code
	fA = (fA/JOULES_PER_CALORIE)*1E6;
	fB= (fB/JOULES_PER_CALORIE)*1E12;
	pairTable.addPairLJType2(indexA,indexB,fA,fB);
      } else if (pairFunction == 5){
	
	// Bare Gaussian potential
	fA = (fA/JOULES_PER_CALORIE); //-->gaussA
	fB = (fB*ANGSTROMS_PER_NM); //-->gaussMu1
	if(fC == 0) {
	  char buff[100];
	  sprintf(buff,"GromacsTopFile.C::Attempting to load zero into gaussSigma.  Please check the pair: %s\n",buf);
	  NAMD_die(buff);
	}
	if(fC < 0 && !bool_negative_number_warning_flag) {
	  iout << iWARN << "Attempting to load a negative standard deviation into the gaussSigma.  Taking the absolute value of the standard deviation.";
	  bool_negative_number_warning_flag = true;
	}
	fC = (fC*ANGSTROMS_PER_NM); //-->gaussSigma1
	fC = 1.0/(2 * fC * fC); // Normalizes sigma
	pairTable.addPairGaussType2(indexA,indexB,fA,fB,fC);
      } else if (pairFunction == 6) {
	
	// Combined Gaussian + repulsive r^-12 potential
	fA = (fA/JOULES_PER_CALORIE); //-->gaussA
	fB = (fB*ANGSTROMS_PER_NM); //-->gaussMu1
	if(fC == 0) {
	  char buff[100];
	  sprintf(buff,"GromacsTopFile.C::Attempting to load zero into gaussSigma.  Please check the pair: %s\n",buf);
	  NAMD_die(buff);
	}
	if(fC < 0 && !bool_negative_number_warning_flag) {
	  iout << iWARN << "Attempting to load a negative standard deviation into the gaussSigma.  Taking the absolute value of the standard deviation.";
	  bool_negative_number_warning_flag = true;
	}
	fC = (fC*ANGSTROMS_PER_NM); //-->gaussSigma1
	fC = 1.0/(2 * fC * fC); // Normalizes sigma
	fD = (fD*ANGSTROMS_PER_NM); //-->gaussRepulsive
	pairTable.addPairGaussType2(indexA,indexB,fA,fB,fC,fD);
      } else if (pairFunction == 7) {
	
	// Double well Guassian function
	fA = (fA/JOULES_PER_CALORIE); //-->gaussA
	fB = (fB*ANGSTROMS_PER_NM); //-->gaussMu1
        if(fC == 0 || fE == 0) {
	  char buff[100];
	  sprintf(buff,"GromacsTopFile.C::Attempting to load zero into gaussSigma.  Please check the pair: %s\n",buf);
	  NAMD_die(buff);
	}
	if((fC < 0 || fE < 0)&& !bool_negative_number_warning_flag) {
	  iout << iWARN << "Attempting to load a negative standard deviation into the gaussSigma.  Taking the absolute value of the standard deviation.";
	  bool_negative_number_warning_flag = true;
	}
	fC = (fC*ANGSTROMS_PER_NM); //-->gaussSigma1
	fC = 1.0/(2 * fC * fC); // Normalizes sigma
        fD = (fD*ANGSTROMS_PER_NM); //-->gaussMu2
	fE = (fE*ANGSTROMS_PER_NM); //-->gaussSigma2
	fE = 1.0/(2 * fE * fE); // Normalizes sigma
	fF = (fE*ANGSTROMS_PER_NM); //-->gaussRepulsive
	pairTable.addPairGaussType2(indexA,indexB,fA,fB,fC,fD,fE,fF);
      } else {
	
	// Generic error statement
	fprintf(stderr,"Unknown pairFunction in GromacsTopFile.C under the PAIRS section: %d\n",pairFunction);
      }
      break;
    case EXCLUSIONS:
      /* Start of JLai modifications August 16th, 2012 */
      if(2 != sscanf(buf," %d %d ",&atomi,&atomj)) {
	fprintf(stderr,"Syntax error in EXCLUSIONS: %s\n",buf);
	exit(1);
      }
      
      // Shift the atom indices to be zero-based
      atomi--;
      atomj--;

      /*Load exclusion information into file*/
      exclusions_atom_i.add(atomi);
      exclusions_atom_j.add(atomj);
      numExclusion++;

      /* Reading in exclusions information from file and loading */
      break;
      // End of JLai modifications August 16th, 2012
    }
  }

  fclose(f);
}