00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <math.h>
00005 #include "common.h"
00006 #include "ResizeArray.h"
00007 #include "GromacsTopFile.h"
00008
00009 #define JOULES_PER_CALORIE 4.184
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define LINESIZE 200
00025
00026
00027 #define UNKNOWN 0
00028 #define ATOMS 1
00029 #define MOLECULETYPE 2
00030 #define MOLECULES 3
00031 #define SYSTEM 4
00032 #define BONDS 5
00033 #define BONDTYPES 6
00034 #define ANGLES 7
00035 #define ATOMTYPES 8
00036 #define ANGLETYPES 9
00037 #define DIHEDRALS 10
00038 #define DIHEDRALTYPES 11
00039 #define DEFAULTS 12
00040 #define NONBOND 13
00041 #define PAIR
00042
00043 GromacsTopFile::GromacsTopFile(char *filename) {
00044
00045 FILE *f = fopen(filename,"r");
00046 char buf[LINESIZE];
00047 char modename[20];
00048 int mode;
00049 if(f==NULL) {
00050 sprintf(buf,"Error opening file '%s'",filename);
00051 NAMD_die(buf);
00052 }
00053
00054
00055
00056
00057 while(fgets(buf,LINESIZE-1,f)) {
00058 char testchar;
00059 int i,j;
00060
00061
00062 int nbfunc, combrule;
00063 char genpairs[20];
00064
00065
00066 int num, resnum, chargegp, typenum;
00067 char type[NAMESIZE+1], restype[NAMESIZE+1], atomname[NAMESIZE+1];
00068 char particletype[NAMESIZE+1];
00069 float charge, mass, c6, c12, junkf;
00070
00071
00072 int nrexcl;
00073 char molname[LONGNAMESIZE+1];
00074
00075
00076 int copies;
00077 MolInst *moleculeinstance;
00078
00079
00080 int atomi, atomj, atomk, atoml;
00081 char typea[NAMESIZE+1],typeb[NAMESIZE+1],
00082 typec[NAMESIZE+1],typed[NAMESIZE+1];
00083 const char *tmptypea,*tmptypeb,*tmptypec,*tmptyped;
00084 int funct, index;
00085 float c0,c1;
00086
00087
00088 float b0,kB,th0,kth;
00089
00090
00091 float c[6];
00092 int mult=0;
00093
00094
00095 if(sscanf(buf," %c",&testchar)==1) {
00096 if(testchar == ';') continue;
00097 }
00098 else {
00099 continue;
00100 }
00101
00102
00103 if(sscanf(buf," [ %19[^] ] ]",modename)==1) {
00104
00105 if(0==strcmp(modename,"atoms")) mode = ATOMS;
00106 else if(0==strcmp(modename,"atomtypes")) mode = ATOMTYPES;
00107 else if(0==strcmp(modename,"moleculetype")) mode = MOLECULETYPE;
00108 else if(0==strcmp(modename,"molecules")) mode = MOLECULES;
00109 else if(0==strcmp(modename,"system")) mode = SYSTEM;
00110 else if(0==strcmp(modename,"bonds")) mode = BONDS;
00111 else if(0==strcmp(modename,"bondtypes")) mode = BONDTYPES;
00112 else if(0==strcmp(modename,"angles")) mode = ANGLES;
00113 else if(0==strcmp(modename,"angletypes")) mode = ANGLETYPES;
00114 else if(0==strcmp(modename,"dihedrals")) mode = DIHEDRALS;
00115 else if(0==strcmp(modename,"dihedraltypes")) mode = DIHEDRALTYPES;
00116 else if(0==strcmp(modename,"defaults")) mode = DEFAULTS;
00117 else if(0==strcmp(modename,"nonbond_params")) mode = NONBOND;
00118 else {
00119 fprintf(stderr,"Warning: unknown mode %s\n",modename);
00120 mode = UNKNOWN;
00121 }
00122
00123 continue;
00124 }
00125
00126
00127 switch(mode) {
00128 case SYSTEM:
00129 systemName = strdup(buf);
00130 break;
00131
00132 case DEFAULTS:
00133 i = sscanf(buf," %d %d %20s %f %f",
00134 &nbfunc,&combrule,genpairs,&fudgeLJ,&fudgeQQ);
00135 if(i < 3) {
00136 fprintf(stderr,"syntax error in DEFAULTS\n");
00137 exit(1);
00138 }
00139 if(nbfunc != 1) {
00140 fprintf(stderr,"Non-bonded function != 1 unsupported in DEFAULTS\n");
00141 exit(1);
00142 }
00143 if(combrule != 1) {
00144 fprintf(stderr,"Combination rule != 1 unsupported in DEFAULTS\n");
00145 exit(1);
00146 }
00147 if(0==strcmp(genpairs,"yes")) {
00148 genPairs=1;
00149 if(i!=5) {
00150 fprintf(stderr,"syntax error in DEFAULTS\n");
00151 exit(1);
00152 }
00153
00154 }
00155 else genPairs=0;
00156
00157 break;
00158
00159 case NONBOND:
00160 if(5 != sscanf(buf," %5s %5s %d %f %f",
00161 typea, typeb, &funct, &c6, &c12)) {
00162 fprintf(stderr,"Syntax error in NONBOND\n");
00163 exit(1);
00164 }
00165
00166 c6 = c6/JOULES_PER_CALORIE*1E6;
00167 c12= c12/JOULES_PER_CALORIE*1E12;
00168 vdwTable.addType(typea,typeb,c6,c12);
00169 break;
00170
00171 case BONDS:
00172 i = sscanf(buf," %d %d %d %f %f",
00173 &atomi,&atomj,&funct,&c0,&c1);
00174 atomi--;
00175 atomj--;
00176 if(i==3) {
00177 tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
00178 tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
00179
00180 index = bondTable.getParams(tmptypea, tmptypeb, funct, &b0, &kB);
00181 if(index==-1) {
00182 fprintf(stderr,"Required bondtype %s--%s (function %d) not found.\n",
00183 tmptypea,tmptypeb,funct);
00184 exit(1);
00185 }
00186 }
00187 else if(i==5) {
00188
00189 b0 = c0*10;
00190 if(funct==1) {
00191
00192 kB = c1/JOULES_PER_CALORIE/100/2;
00193 }
00194 else if(funct==2) {
00195
00196 kB = 2*c1*c0*c0/JOULES_PER_CALORIE/100;
00197 kB /= 2;
00198 }
00199 else {
00200 fprintf(stderr,"I don't know what funct=%d means in BONDS\n",funct);
00201 exit(1);
00202 }
00203
00204 index = bondTable.getIndex(b0,kB,funct);
00205 }
00206 else {
00207 fprintf(stderr,"Syntax error in BONDS\n");
00208 exit(1);
00209 }
00210
00211 genericMols[genericMols.size()-1]->addBond(atomi,atomj,index);
00212 break;
00213
00214 case BONDTYPES:
00215 if(5 != sscanf(buf," %5s %5s %d %f %f",
00216 typea,typeb,&funct,&c0,&c1)) {
00217 fprintf(stderr,"Syntax error in BONDTYPES\n");
00218 exit(1);
00219 }
00220
00221
00222 b0 = c0*10;
00223 if(funct==1) {
00224
00225 kB = c1/JOULES_PER_CALORIE/100/2;
00226 }
00227 else if(funct==2) {
00228
00229 kB = 2*c1*c0*c0/JOULES_PER_CALORIE/100;
00230 kB /= 2;
00231 }
00232 else {
00233 fprintf(stderr,"I don't know what funct=%d means in BONDTYPES\n",funct);
00234 exit(1);
00235 }
00236
00237 bondTable.addType(typea,typeb,b0,kB,funct);
00238 break;
00239
00240 case ANGLES:
00241 i = sscanf(buf," %d %d %d %d %f %f",
00242 &atomi,&atomj,&atomk,&funct,&c0,&c1);
00243 atomi--;
00244 atomj--;
00245 atomk--;
00246 if(i == 4) {
00247 tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
00248 tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
00249 tmptypec = genericMols[genericMols.size()-1]->getAtom(atomk)->getType();
00250
00251 index = angleTable.getParams(tmptypea, tmptypeb, tmptypec,
00252 funct, &th0, &kth);
00253 if(index==-1) {
00254 fprintf(stderr,
00255 "Required angletype %s--%s--%s (function %d) not found.\n",
00256 tmptypea,tmptypeb,tmptypec,funct);
00257 exit(1);
00258 }
00259 }
00260 else if(i == 6) {
00261
00262 if(funct == 1) {
00263 th0 = c0;
00264 kth = c1/JOULES_PER_CALORIE/2;
00265 }
00266 else if(funct == 2) {
00267 th0 = c0;
00268
00269 kth = sin(th0*PI/180)*sin(th0*PI/180)*c1/JOULES_PER_CALORIE/2;
00270 }
00271 else {
00272 fprintf(stderr,"I don't know what funct=%d means in ANGLES\n",funct);
00273 exit(1);
00274 }
00275
00276 index = angleTable.getIndex(th0,kth,funct);
00277 }
00278 else {
00279 fprintf(stderr,"Syntax error (%d args) in ANGLES: %s\n",i,buf);
00280 exit(1);
00281 }
00282
00283
00284 genericMols[genericMols.size()-1]->addAngle(atomi,atomj,atomk,index);
00285 break;
00286
00287 case ANGLETYPES:
00288 if(6 != sscanf(buf," %5s %5s %5s %d %f %f",
00289 typea,typeb,typec,&funct,&c0,&c1)) {
00290 fprintf(stderr,"Syntax error in ANGLETYPES\n");
00291 exit(1);
00292 }
00293
00294 if(funct == 1) {
00295 th0 = c0;
00296 kth = c1/JOULES_PER_CALORIE/2;
00297 }
00298 else if(funct == 2) {
00299 th0 = c0;
00300
00301 kth = sin(th0*PI/180)*sin(th0*PI/180)*c1/JOULES_PER_CALORIE/2;
00302 }
00303 else {
00304 fprintf(stderr,"I don't know what funct=%d means in ANGLETYPES\n",
00305 funct);
00306 exit(1);
00307 }
00308 angleTable.addType(typea,typeb,typec,th0,kth,funct);
00309 break;
00310
00311 case DIHEDRALS:
00312 i = sscanf(buf," %d %d %d %d %d %f %f %f %f %f %f",
00313 &atomi,&atomj,&atomk,&atoml,&funct,
00314 &c[0],&c[1],&c[2],&c[3],&c[4],&c[5]);
00315 atomi--;
00316 atomj--;
00317 atomk--;
00318 atoml--;
00319 if(i==5) {
00320 tmptypea = genericMols[genericMols.size()-1]->getAtom(atomi)->getType();
00321 tmptypeb = genericMols[genericMols.size()-1]->getAtom(atomj)->getType();
00322 tmptypec = genericMols[genericMols.size()-1]->getAtom(atomk)->getType();
00323 tmptyped = genericMols[genericMols.size()-1]->getAtom(atoml)->getType();
00324
00325 index = dihedralTable.getParams(tmptypea, tmptypeb, tmptypec,
00326 tmptyped, funct, c, &mult);
00327 if(index==-1) {
00328 fprintf(stderr,
00329 "Required dihedraltype %s--%s--%s--%s (function %d) not found.\n",
00330 tmptypea,tmptypeb,tmptypec,tmptyped,funct);
00331 exit(1);
00332 }
00333 }
00334 else if(i==7 || i==8 || i==11) {
00335 if(funct==1 || funct==2) {
00336 if(i!=7+(funct==1)) {
00337 fprintf(stderr,"Must have 7 args for funct=1,2\n");
00338 exit(1);
00339 }
00340 c[0] = c[0];
00341 c[1] = c[1]/JOULES_PER_CALORIE;
00342
00343 if(funct==1) {
00344 mult=(int)(c[2]+0.5);
00345 }
00346 }
00347 else if(funct==3) {
00348 if(i!=11){
00349 fprintf(stderr,"Must have 11 args for funct=3\n");
00350 exit(1);
00351 }
00352
00353 for(j=0;j<6;j++) {
00354 c[j] = c[j]/JOULES_PER_CALORIE;
00355 }
00356 }
00357 else {
00358 fprintf(stderr,
00359 "I don't know what funct=%d means in DIHEDRALS\n",funct);
00360 exit(1);
00361 }
00362 index = dihedralTable.getIndex(c,mult,funct);
00363 }
00364 else {
00365 fprintf(stderr,"Syntax error (%d args) in DIHEDRALS: %s\n",i,buf);
00366 exit(1);
00367 }
00368
00369
00370 genericMols[genericMols.size()-1]->addDihedral(atomi,atomj,atomk,atoml,
00371 index);
00372 break;
00373 case DIHEDRALTYPES:
00374 i = sscanf(buf," %5s %5s %d %f %f %f %f %f %f",
00375 typea,typeb,&funct,&c[0],&c[1],&c[2],&c[3],&c[4],&c[5]);
00376 if(funct == 1 || funct == 2) {
00377 if(i!=5+(funct==1)) {
00378 fprintf(stderr,"Syntax error in DIHEDRALTYPES: %s\n",buf);
00379 exit(1);
00380 }
00381 c[0] = c[0];
00382 c[1] = c[1]/JOULES_PER_CALORIE;
00383
00384 if(funct==1) {
00385 mult=(int)(c[2]+0.5);
00386 }
00387 }
00388 else if(funct == 3) {
00389 if(i!=9) {
00390 fprintf(stderr,"Syntax error in DIHEDRALTYPES\n");
00391 exit(1);
00392 }
00393 for(j=0;j<6;j++) {
00394 c[j] = c[j]/JOULES_PER_CALORIE;
00395 }
00396 }
00397 else {
00398 fprintf(stderr,"I don't know what funct=%d means in DIHEDRALTYPES\n",
00399 funct);
00400 exit(1);
00401 }
00402 dihedralTable.addType(typea,typeb,c,mult,funct);
00403 break;
00404
00405 case ATOMS:
00406 i = sscanf(buf," %d %5s %d %5s %5s %d %f %f",
00407 &num, type, &resnum, restype,
00408 atomname, &chargegp, &charge, &mass);
00409 if(i==7) {
00410
00411 typenum = atomTable.getParams(type,&mass,&junkf,&junkf,&junkf);
00412 i=8;
00413 }
00414 else {
00415 if(i!=8) {
00416 fprintf(stderr,"Syntax error in ATOMS\n");
00417 exit(1);
00418 }
00419
00420 typenum = atomTable.getParams(type,&junkf,&junkf,&junkf,&junkf);
00421 }
00422 genericMols[genericMols.size()-1]->addAtom(type,typenum,resnum,
00423 restype,atomname,charge,mass);
00424 break;
00425
00426 case ATOMTYPES:
00427 if(6 != sscanf(buf," %5s %f %f %5s %f %f",type,&mass,&charge,
00428 particletype,&c6,&c12)) {
00429 fprintf(stderr,"Syntax error in ATOMTYPES: %s\n",buf);
00430 exit(1);
00431 }
00432
00433
00434
00435 atomTable.addType(type,mass,charge,
00436 c6/JOULES_PER_CALORIE*1E6,
00437 c12/JOULES_PER_CALORIE*1E12);
00438 break;
00439
00440 case MOLECULETYPE:
00441 if(2!=sscanf(buf," %20s %d",molname,&nrexcl)) {
00442 fprintf(stderr,"Syntax error in MOLECULETYPE: %s\n",buf);
00443 exit(1);
00444 }
00445
00446
00447 genericMols.add(new GenericMol(molname));
00448 break;
00449
00450 case MOLECULES:
00451 if(2!=sscanf(buf," %20s %d",molname,&copies)) {
00452 fprintf(stderr,"Syntax error in MOLECULES: %s\n",buf);
00453 exit(1);
00454 }
00455
00456
00457 moleculeinstance = NULL;
00458 for(i=0;i<genericMols.size();i++) {
00459 if(0==strcmp(molname,genericMols[i]->getName())) {
00460 moleculeinstance = new MolInst(genericMols[i],copies);
00461 break;
00462 }
00463 }
00464
00465 if(moleculeinstance==NULL) {
00466 fprintf(stderr,"Molecule %s undefined.\n",molname);
00467 exit(1);
00468 }
00469
00470
00471 molInsts.add(moleculeinstance);
00472
00473 break;
00474 }
00475 }
00476
00477 fclose(f);
00478 }
00479
00480
00481 int GromacsTopFile::getNumBonds() const {
00482 int n=0,i;
00483 for(i=0;i<molInsts.size();i++) {
00484 n += molInsts[i]->getNum() *
00485 molInsts[i]->getMol()->getNumBonds();
00486 }
00487 return n;
00488 }
00489
00490
00491 int GromacsTopFile::getNumAngles() const {
00492 int n=0,i;
00493 for(i=0;i<molInsts.size();i++) {
00494 n += molInsts[i]->getNum() *
00495 molInsts[i]->getMol()->getNumAngles();
00496 }
00497 return n;
00498 }
00499
00500
00501 int GromacsTopFile::getNumDihedrals() const {
00502 int n=0,i;
00503 for(i=0;i<molInsts.size();i++) {
00504 n += molInsts[i]->getNum() *
00505 molInsts[i]->getMol()->getNumDihedrals();
00506 }
00507 return n;
00508 }
00509
00510
00511
00512
00513
00514 void GromacsTopFile::getBond(int n, int *atomi, int *atomj, int *bondtype) const {
00515
00516 int nbonds=0;
00517 int natoms=0;
00518 int i;
00519 for(i=0;i<molInsts.size();i++) {
00520 int molbonds = molInsts[i]->getMol()->getNumBonds();
00521 int molatoms = molInsts[i]->getMol()->getNumAtoms();
00522 int newbonds = molInsts[i]->getNumBonds();
00523 int newatoms = molInsts[i]->getNumAtoms();
00524
00525 if(nbonds+newbonds-1 >= n) {
00526
00527 int localnum = (n-nbonds) % molbonds;
00528 int instnum = (n-nbonds) / molbonds;
00529 int addatoms = natoms+instnum*molatoms;
00530
00531 const GenericBond *b = molInsts[i]->getMol()->getBond(localnum);
00532
00533 *atomi = b->getAtomi() + addatoms;
00534 *atomj = b->getAtomj() + addatoms;
00535 *bondtype = b->getType();
00536 break;
00537 }
00538
00539 nbonds += newbonds;
00540 natoms += newatoms;
00541 }
00542 }
00543
00544
00545
00546
00547
00548 void GromacsTopFile::getAngle(int n, int *atomi, int *atomj, int *atomk,
00549 int *angletype) const {
00550
00551 int nangles=0;
00552 int natoms=0;
00553 int i;
00554 for(i=0;i<molInsts.size();i++) {
00555 int molangles = molInsts[i]->getMol()->getNumAngles();
00556 int molatoms = molInsts[i]->getMol()->getNumAtoms();
00557 int newangles = molInsts[i]->getNumAngles();
00558 int newatoms = molInsts[i]->getNumAtoms();
00559
00560 if(nangles+newangles-1 >= n) {
00561
00562 int localnum = (n-nangles) % molangles;
00563 int instnum = (n-nangles) / molangles;
00564 int addatoms = natoms+instnum*molatoms;
00565
00566 const GenericAngle *a = molInsts[i]->getMol()->getAngle(localnum);
00567
00568 *atomi = a->getAtomi() + addatoms;
00569 *atomj = a->getAtomj() + addatoms;
00570 *atomk = a->getAtomk() + addatoms;
00571 *angletype = a->getType();
00572 break;
00573 }
00574
00575 nangles += newangles;
00576 natoms += newatoms;
00577 }
00578 }
00579
00580
00581
00582
00583 void GromacsTopFile::getDihedral(int n, int *atomi, int *atomj, int *atomk,
00584 int *atoml, int *type) const {
00585
00586 int ndihedrals=0;
00587 int natoms=0;
00588 int i;
00589 for(i=0;i<molInsts.size();i++) {
00590 int moldihedrals = molInsts[i]->getMol()->getNumDihedrals();
00591 int molatoms = molInsts[i]->getMol()->getNumAtoms();
00592 int newdihedrals = molInsts[i]->getNumDihedrals();
00593 int newatoms = molInsts[i]->getNumAtoms();
00594
00595 if(ndihedrals+newdihedrals-1 >= n) {
00596
00597 int localnum = (n-ndihedrals) % moldihedrals;
00598 int instnum = (n-ndihedrals) / moldihedrals;
00599 int addatoms = natoms+instnum*molatoms;
00600
00601 const GenericDihedral *a = molInsts[i]->getMol()->getDihedral(localnum);
00602
00603 *atomi = a->getAtomi() + addatoms;
00604 *atomj = a->getAtomj() + addatoms;
00605 *atomk = a->getAtomk() + addatoms;
00606 *atoml = a->getAtoml() + addatoms;
00607 *type = a->getType();
00608 break;
00609 }
00610
00611 ndihedrals += newdihedrals;
00612 natoms += newatoms;
00613 }
00614 }
00615
00616
00617 int GromacsTopFile::getNumAtoms() const {
00618 int n=0;
00619 int i;
00620 for(i=0;i<molInsts.size();i++) {
00621 n += molInsts[i]->getNum() *
00622 molInsts[i]->getMol()->getNumAtoms();
00623 }
00624 return n;
00625 }
00626
00627
00628
00629
00630 void GromacsTopFile::getAtom(int num,
00631 int *residue_number, char *residue_name,
00632 char *atom_name, char *atom_type, int *atom_typenum,
00633 Real *charge, Real *mass)
00634 const {
00635 int natoms=0,n=num;
00636 int resnum=0;
00637
00638
00639 int i;
00640
00641 for(i=0;i<molInsts.size();i++) {
00642 int numnew = molInsts[i]->getNumAtoms();
00643 int resmol = molInsts[i]->getMol()->getNumRes();
00644 int newres = molInsts[i]->getNumRes();
00645
00646 if(natoms+numnew-1 >= n) {
00647
00648 int localnum = (n-natoms) % molInsts[i]->getMol()->getNumAtoms();
00649 int instnum = (n-natoms) / molInsts[i]->getMol()->getNumAtoms();
00650
00651
00652 const GenericAtom *a = molInsts[i]->getMol()->getAtom(localnum);
00653 int residue = resnum + resmol*instnum + a->getResNum();
00654
00655 *residue_number = residue;
00656 strncpy(residue_name,a->getResType(),11);
00657 strncpy(atom_name,a->getAtomName(),11);
00658 strncpy(atom_type,a->getType(),11);
00659 *charge=a->getCharge();
00660 *mass=a->getMass();
00661 *atom_typenum=a->getTypeNum();
00662 break;
00663 }
00664
00665
00666 natoms += numnew;
00667 resnum += newres;
00668 }
00669 }
00670
00671 GenericAtom::GenericAtom(const char *theType, int theTypeNum, int theResNum,
00672 const char *theResType,const char *theAtomName,
00673 Real theCharge, Real theMass) {
00674 strncpy(type,theType,NAMESIZE+1);
00675 typeNum = theTypeNum;
00676 resNum = theResNum;
00677 strncpy(resType,theResType,NAMESIZE+1);
00678 strncpy(atomName,theAtomName,NAMESIZE+1);
00679 charge = theCharge;
00680 mass = theMass;
00681 }
00682
00683
00684
00685 GenericBond::GenericBond(int i, int j, int theType) {
00686 atomi=i;
00687 atomj=j;
00688 type=theType;
00689 }
00690
00691
00692
00693 GenericAngle::GenericAngle(int i, int j, int k, int theType) {
00694 atomi=i;
00695 atomj=j;
00696 atomk=k;
00697 type=theType;
00698 }
00699
00700
00701
00702 GenericDihedral::GenericDihedral(int i, int j, int k, int l, int theType) {
00703 atomi=i;
00704 atomj=j;
00705 atomk=k;
00706 atoml=l;
00707 type=theType;
00708 }
00709
00710
00711 void GenericMol::addBond(int atomi, int atomj, int type) {
00712 bondList.add(new GenericBond(atomi, atomj, type));
00713 }
00714
00715
00716 void GenericMol::addAngle(int atomi, int atomj, int atomk, int type) {
00717 angleList.add(new GenericAngle(atomi, atomj, atomk, type));
00718 }
00719
00720
00721 void GenericMol::addDihedral(int atomi, int atomj, int atomk,
00722 int atoml, int type) {
00723 dihedralList.add(new GenericDihedral(atomi, atomj, atomk,
00724 atoml, type));
00725 }
00726
00727
00728 void GenericMol::addAtom(const char *theType, int theTypeNum, int theResNum,
00729 const char *theResType,const char *theAtomName,
00730 Real theCharge, Real theMass) {
00731
00732 atomList.add(new GenericAtom(theType,theTypeNum,theResNum,theResType,
00733 theAtomName,theCharge,theMass));
00734 }
00735
00736
00737 GenericMol::GenericMol(const char *theName) {
00738 name = strdup(theName);
00739 }
00740
00741
00742 const GenericBond *GenericMol::getBond(int n) const {
00743
00744 if(n >= bondList.size() || n<0) {
00745 fprintf(stderr,"Bond index %d out of bounds.\n",n);
00746 exit(1);
00747 }
00748 return bondList[n];
00749 }
00750
00751
00752 const GenericAngle *GenericMol::getAngle(int n) const {
00753
00754 if(n >= angleList.size() || n<0) {
00755 fprintf(stderr,"Angle index %d out of bounds.\n",n);
00756 exit(1);
00757 }
00758 return angleList[n];
00759 }
00760
00761
00762 const GenericDihedral *GenericMol::getDihedral(int n) const {
00763
00764 if(n >= dihedralList.size() || n<0) {
00765 fprintf(stderr,"Dihedral index %d out of bounds.\n",n);
00766 exit(1);
00767 }
00768 return dihedralList[n];
00769 }
00770
00771
00772 const GenericAtom *GenericMol::getAtom(int n) const {
00773
00774 if(n >= atomList.size() || n<0) {
00775 fprintf(stderr,"Atom index %d out of bounds for %s.\n",n,name);
00776 exit(1);
00777 }
00778 return atomList[n];
00779 }
00780
00781
00782 MolInst::MolInst(const GenericMol *theMol, int theNum) {
00783 mol = theMol;
00784 num = theNum;
00785 }
00786
00787
00788 int MolInst::getNumAtoms() const {
00789 return getMol()->getNumAtoms() * getNum();
00790 }
00791 int MolInst::getNumBonds() const {
00792 return getMol()->getNumBonds() * getNum();
00793 }
00794 int MolInst::getNumAngles() const {
00795 return getMol()->getNumAngles() * getNum();
00796 }
00797 int MolInst::getNumDihedrals() const {
00798 return getMol()->getNumDihedrals() * getNum();
00799 }
00800 int MolInst::getNumRes() const {
00801 return getMol()->getNumRes()
00802 * getNum();
00803 }
00804
00805
00806
00807
00808
00809
00810
00811 int BondTable::getIndex(float b0, float kB, int funct) {
00812
00813 int i;
00814 for(i=0;i<b0Array.size();i++) {
00815 if(fabs(b0-b0Array[i])<0.00001 &&
00816 fabs(kB-kBArray[i])<0.00001 &&
00817 funct == functArray[i]) {
00818 return i;
00819 }
00820 }
00821
00822
00823 b0Array.add(b0);
00824 kBArray.add(kB);
00825 functArray.add(funct);
00826 typeaArray.add(NULL);
00827 typebArray.add(NULL);
00828 return b0Array.size()-1;
00829 }
00830
00831
00832
00833
00834
00835
00836
00837 int AngleTable::getIndex(float th0, float kth, int funct) {
00838
00839 int i;
00840 for(i=0;i<th0Array.size();i++) {
00841 if(fabs(th0-th0Array[i])<0.00001 &&
00842 fabs(kth-kthArray[i])<0.00001 &&
00843 funct == functArray[i]) {
00844 return i;
00845 }
00846 }
00847
00848
00849 th0Array.add(th0);
00850 kthArray.add(kth);
00851 functArray.add(funct);
00852 typeaArray.add(NULL);
00853 typebArray.add(NULL);
00854 typecArray.add(NULL);
00855 return th0Array.size()-1;
00856 }
00857
00858
00859
00860
00861
00862 int DihedralTable::getIndex(const float *c, int mult, int funct) {
00863
00864 int i,j,jmax;
00865 if(funct==1 || funct==2) {
00866 jmax=2;
00867 } else {
00868 jmax=6;
00869 }
00870
00871 for(i=0;i<cArray.size();i++) {
00872 int mismatch=0;
00873 if(mult != multArray[i]) continue;
00874 if(funct != functArray[i]) continue;
00875
00876 for(j=0;j<jmax;j++) {
00877 if(fabs(c[j]-cArray[i][j])>=0.00001) {
00878 mismatch=1;
00879 break;
00880 }
00881 }
00882 if(!mismatch) {
00883
00884 return i;
00885 }
00886 }
00887
00888
00889 addType(NULL,NULL,c,mult,funct);
00890 return cArray.size()-1;
00891 }
00892
00893
00894
00895
00896
00897
00898 void GromacsTopFile::getBondParams(int num, float *b0, float *kB, int *funct)
00899 const {
00900 bondTable.getParams(num,b0,kB,funct);
00901 }
00902
00903
00904
00905 void GromacsTopFile::getAngleParams(int num, float *th0, float *kth, int *funct)
00906 const {
00907 angleTable.getParams(num,th0,kth,funct);
00908 }
00909
00910 void GromacsTopFile::getDihedralParams(int num, float *c, int *mult, int *funct)
00911 const {
00912 dihedralTable.getParams(num,c,mult,funct);
00913 }
00914
00915
00916
00917
00918
00919
00920 void BondTable::getParams(int num, float *b0, float *kB, int *funct)
00921 const {
00922 *b0=b0Array[num];
00923 *kB=kBArray[num];
00924 *funct=functArray[num];
00925 }
00926
00927
00928
00929 void AngleTable::getParams(int num, float *th0, float *kth, int *funct)
00930 const {
00931 *th0=th0Array[num];
00932 *kth=kthArray[num];
00933 *funct=functArray[num];
00934 }
00935
00936
00937
00938
00939
00940 void DihedralTable::getParams(int num, float *c, int *mult, int *funct) const {
00941 int i;
00942
00943 *funct=functArray[num];
00944
00945 if(*funct==1 || *funct==2) {
00946 c[0]=cArray[num][0];
00947 c[1]=cArray[num][1];
00948 } else if(*funct==3) {
00949 for(i=0;i<6;i++) {
00950 c[i]=cArray[num][i];
00951 }
00952 } else {
00953 fprintf(stderr,"Bad function number %d - don't know what to do!\n",
00954 funct);
00955 exit(1);
00956 }
00957
00958 if(*funct==1) {
00959 *mult=multArray[num];
00960 }
00961 }
00962
00963
00964
00965 void AngleTable::addType(const char *typea, const char *typeb,
00966 const char *typec, float th0, float kth, int funct) {
00967 typeaArray.add(strdup(typea));
00968 typebArray.add(strdup(typeb));
00969 typecArray.add(strdup(typec));
00970 th0Array.add(th0);
00971 kthArray.add(kth);
00972 functArray.add(funct);
00973 }
00974
00975
00976
00977
00978
00979
00980 void DihedralTable::addType(const char *typea, const char *typeb,
00981 const float *c, int mult, int funct) {
00982 float *cNew;
00983 int i;
00984
00985 if(typea != NULL) typeaArray.add(strdup(typea));
00986 if(typeb != NULL) typebArray.add(strdup(typeb));
00987 functArray.add(funct);
00988
00989 if(funct==1) multArray.add(mult);
00990 else multArray.add(0);
00991
00992 if(funct==1 || funct==2) {
00993 cNew = new float[2];
00994 cNew[0]=c[0];
00995 cNew[1]=c[1];
00996 } else if(funct==3) {
00997 cNew = new float[6];
00998 for(i=0;i<6;i++) {
00999 cNew[i]=c[i];
01000 }
01001 } else {
01002 fprintf(stderr,"Bad function number %d - don't know what to do!\n",
01003 funct);
01004 exit(1);
01005 }
01006
01007
01008 cArray.add(cNew);
01009 }
01010
01011
01012
01013
01014
01015 int AngleTable::getParams(const char *typea, const char *typeb,
01016 const char *typec, int funct,
01017 float *th0, float *kth) const {
01018 int i;
01019 for(i=0;i<th0Array.size();i++) {
01020 if(typeaArray[i] == NULL || typebArray[i] == NULL
01021 || typecArray[i] == NULL) continue;
01022 if( (0==strcmp(typea,typeaArray[i]) &&
01023 0==strcmp(typeb,typebArray[i]) &&
01024 0==strcmp(typec,typecArray[i]))
01025 || (0==strcmp(typec,typeaArray[i]) &&
01026 0==strcmp(typeb,typebArray[i]) &&
01027 0==strcmp(typea,typecArray[i]))
01028 && funct==functArray[i]) {
01029 *th0 = th0Array[i];
01030 *kth = kthArray[i];
01031 return i;
01032 }
01033 }
01034 return -1;
01035 }
01036
01037
01038 int DihedralTable::getParams(const char *typea, const char *typeb,
01039 const char *typec, const char *typed,
01040 int funct, float *c, int *mult) const {
01041 int i,j;
01042 const char *comparea, *compareb;
01043
01044 if(funct == 1 || funct == 3) {
01045 comparea = typeb;
01046 compareb = typec;
01047 } else {
01048 comparea = typea;
01049 compareb = typed;
01050 }
01051
01052 for(i=0;i<cArray.size();i++) {
01053 if(typeaArray[i] == NULL || typebArray[i] == NULL)
01054 continue;
01055 if(functArray[i] != funct)
01056 continue;
01057
01058 if( (0==strcmp(comparea,typeaArray[i]) &&
01059 0==strcmp(compareb,typebArray[i]))
01060 || (0==strcmp(compareb,typeaArray[i]) &&
01061 0==strcmp(comparea,typebArray[i]))
01062 ) {
01063 if(funct==1 || funct==2) {
01064 c[0]=cArray[i][0];
01065 c[1]=cArray[i][1];
01066 if(funct==1) {
01067 *mult = multArray[i];
01068 }
01069 } else if(funct==3) {
01070 for(j=0;j<6;j++) {
01071 c[j]=cArray[i][j];
01072 }
01073 }
01074 return i;
01075 }
01076 }
01077 return -1;
01078 }
01079
01080
01081
01082 void BondTable::addType(const char *typea, const char *typeb,
01083 float b0, float kB, int funct) {
01084 b0Array.add(b0);
01085 kBArray.add(kB);
01086 functArray.add(funct);
01087 typeaArray.add(strdup(typea));
01088 typebArray.add(strdup(typeb));
01089 }
01090
01091
01092
01093 int BondTable::getParams(const char *typea, const char *typeb,
01094 int funct, float *b0, float *kB) const {
01095 int i;
01096 for(i=0;i<b0Array.size();i++) {
01097 if(typeaArray[i] == NULL || typebArray[i] == NULL) continue;
01098 if( (0==strcmp(typea,typeaArray[i]) &&
01099 0==strcmp(typeb,typebArray[i]))
01100 || (0==strcmp(typeb,typeaArray[i]) &&
01101 0==strcmp(typea,typebArray[i]))
01102 && funct==functArray[i]) {
01103 *b0 = b0Array[i];
01104 *kB = kBArray[i];
01105 return i;
01106 }
01107 }
01108 return -1;
01109 }
01110
01111
01112 void AtomTable::addType(const char *type, float m, float q,
01113 float c6, float c12) {
01114 typeArray.add(strdup(type));
01115 mArray.add(m);
01116 qArray.add(q);
01117 c6Array.add(c6);
01118 c12Array.add(c12);
01119 }
01120
01121
01122
01123 void AtomTable::getType(int num, char *type) const {
01124 if(num>=mArray.size() || num<0) {
01125 fprintf(stderr,"atomParam index %d out of bounds!\n",num);
01126 exit(1);
01127 }
01128 strncpy(type,typeArray[num],NAMESIZE+1);
01129 }
01130
01131
01132
01133
01134 int AtomTable::getParams(const char *type, float *m, float *q,
01135 float *c6, float *c12) const {
01136 int i;
01137 for(i=0;i<mArray.size();i++) {
01138 if(typeArray[i]==NULL) {
01139 fprintf(stderr,"Found NULL atom type in list.\n");
01140 exit(1);
01141 }
01142 if(0==strcmp(typeArray[i],type)) {
01143 *m = mArray[i];
01144 *q = qArray[i];
01145 *c6 = c6Array[i];
01146 *c12 = c12Array[i];
01147 return i;
01148 }
01149 }
01150 return -1;
01151 }
01152
01153
01154 int VDWTable::getIndex(const char *typea, const char *typeb) const {
01155 int i;
01156 for(i=0;i<c6Array.size();i++) {
01157 if((0==strcmp(typea,typeAArray[i]) &&
01158 0==strcmp(typeb,typeBArray[i])) ||
01159 (0==strcmp(typeb,typeAArray[i]) &&
01160 0==strcmp(typea,typeBArray[i]))) {
01161 return i;
01162 }
01163 }
01164 return -1;
01165 }
01166
01167
01168 void VDWTable::addType(const char *typea, const char *typeb, Real c6,
01169 Real c12) {
01170 int i;
01171
01172
01173 i = getIndex(typea,typeb);
01174 if(i != -1) {
01175 c6Array[i] = c6;
01176 c12Array[i] = c12;
01177 }
01178 else {
01179 typeAArray.add(strdup(typea));
01180 typeBArray.add(strdup(typeb));
01181 c6Array.add(c6);
01182 c12Array.add(c12);
01183 c6PairArray.add(0);
01184 c12PairArray.add(0);
01185 }
01186 }
01187
01188 void VDWTable::add14Type(const char *typea, const char *typeb,
01189 Real c6pair, Real c12pair) {
01190 int i;
01191
01192
01193 i = getIndex(typea,typeb);
01194 if(i != -1) {
01195 c6PairArray[i] = c6pair;
01196 c12PairArray[i] = c12pair;
01197 }
01198 else {
01199 typeAArray.add(strdup(typea));
01200 typeBArray.add(strdup(typeb));
01201 c6PairArray.add(c6pair);
01202 c12PairArray.add(c12pair);
01203 c6Array.add(0);
01204 c12Array.add(0);
01205 }
01206 }
01207
01208
01209
01210
01211 int VDWTable::getParams(const char *typea, const char *typeb,
01212 Real *c6, Real *c12, Real *c6pair, Real *c12pair) const {
01213 int i;
01214
01215 i = getIndex(typea,typeb);
01216 if(i != -1) {
01217 *c6 = c6Array[i];
01218 *c12 = c12Array[i];
01219 *c6pair = c6PairArray[i];
01220 *c12pair = c12PairArray[i];
01221 }
01222 return i;
01223 }
01224
01225
01226
01227
01228 void GromacsTopFile::getVDWParams(int numa, int numb,
01229 Real *c6, Real *c12, Real *c6pair, Real *c12pair) const {
01230 int i,ret;
01231 Real c6a,c6b,c12a,c12b, mjunk, qjunk;
01232 char typea[11]="",typeb[11]="";
01233
01234
01235 getAtomParams(numa,typea);
01236 getAtomParams(numb,typeb);
01237 if(typea[0]==0) {
01238 fprintf(stderr,"Failed to get name of atom %d\n",numa);
01239 exit(1);
01240 }
01241 if(typeb[0]==0) {
01242 fprintf(stderr,"Failed to get name of atom %d\n",numb);
01243 exit(1);
01244 }
01245
01246
01247 i = vdwTable.getParams(typea,typeb,c6,c12,c6pair,c12pair);
01248
01249 if(i==-1) {
01250
01251 ret = atomTable.getParams(typea, &mjunk, &qjunk, &c6a, &c12a);
01252 if(ret==-1) {
01253 fprintf(stderr,"Couldn't find atom type %s\n",typea);
01254 exit(1);
01255 }
01256 ret = atomTable.getParams(typeb, &mjunk, &qjunk, &c6b, &c12b);
01257 if(ret==-1) {
01258 fprintf(stderr,"Couldn't find atom type %s\n",typeb);
01259 exit(1);
01260 }
01261
01262 *c6 = (float)(sqrt(c6a * c6b));
01263 *c12 = (float)(sqrt(c12a*c12b));
01264 }
01265
01266
01267
01268
01269
01270
01271
01272 if(!genPairs) {
01273 return;
01274 }
01275
01276 *c6pair = *c6 * fudgeLJ;
01277 *c12pair = *c12 * fudgeLJ;
01278
01279 }
01280