00001
00007 #ifndef STRUCTURES_H
00008 #define STRUCTURES_H
00009
00010 #include "common.h"
00011 #include <vector>
00012
00013
00014
00015 #define UnknownAtom 0x00
00016 #define HydrogenAtom 0x01
00017 #define OxygenAtom 0x02
00018 #define HBDonorAtom 0x04
00019 #define HBAcceptorAtom 0x08
00020 #define HBAntecedentAtom 0x10
00021 #define HBHydrogenAtom 0x20
00022 #define LonepairAtom 0x40
00023 #define DrudeAtom 0x80
00024
00025
00026 typedef int Index;
00027
00028
00029 typedef struct atom_name_info
00030 {
00031 char *resname;
00032 char *atomname;
00033 char *atomtype;
00034 } AtomNameInfo;
00035
00036 typedef struct atom_constants
00037 {
00038 Real mass;
00039 Real charge;
00040 Index vdw_type;
00041 int32 status;
00042 int32 partner;
00043 int32 hydrogenList;
00044 } Atom;
00045
00046 typedef struct bond
00047 {
00048 int32 atom1;
00049 int32 atom2;
00050 Index bond_type;
00051 } Bond;
00052
00053 typedef struct angle
00054 {
00055 int32 atom1;
00056 int32 atom2;
00057 int32 atom3;
00058 Index angle_type;
00059 } Angle;
00060
00061 typedef struct dihedral
00062 {
00063 int32 atom1;
00064 int32 atom2;
00065 int32 atom3;
00066 int32 atom4;
00067 Index dihedral_type;
00068 } Dihedral;
00069
00070 typedef struct improper
00071 {
00072 int32 atom1;
00073 int32 atom2;
00074 int32 atom3;
00075 int32 atom4;
00076 Index improper_type;
00077 } Improper;
00078
00079 typedef struct crossterm
00080 {
00081 int32 atom1;
00082 int32 atom2;
00083 int32 atom3;
00084 int32 atom4;
00085 int32 atom5;
00086 int32 atom6;
00087 int32 atom7;
00088 int32 atom8;
00089 Index crossterm_type;
00090 } Crossterm;
00091
00092
00093
00094 typedef struct drude_constants
00095 {
00096 Real alpha;
00097 Real thole;
00098 } DrudeConst;
00099
00100 typedef struct lphost
00101 {
00102 int32 atom1;
00103 int32 atom2;
00104 int32 atom3;
00105 int32 atom4;
00106 Real distance;
00107 Real angle;
00108 Real dihedral;
00109 } Lphost;
00110
00111 typedef struct aniso
00112 {
00113 int32 atom1;
00114 int32 atom2;
00115 int32 atom3;
00116 int32 atom4;
00117 Real k11;
00118 Real k22;
00119 Real k33;
00120 } Aniso;
00121
00122 typedef struct thole
00123 {
00124 int32 atom1;
00125 int32 atom2;
00126 int32 atom3;
00127 int32 atom4;
00128 Real aa;
00129 Real qq;
00130 } Thole;
00131
00132
00133
00134 class Exclusion
00135 {
00136 public:
00137 Exclusion(void) : modified(0) {;}
00138 Exclusion(int a1, int a2, int mod = 0) :
00139 atom1(a1), atom2(a2), modified(mod) {;}
00140 int32 atom1;
00141 int32 atom2;
00142 Index modified;
00143 int hash(void) const
00144 {
00145 return atom1 + atom2;
00146 }
00147 int operator==(const Exclusion &o) const
00148 {
00149 return atom1 == o.atom1 && atom2 == o.atom2;
00150 }
00151 int operator<(const Exclusion &o) const
00152 {
00153 return
00154 (
00155 ( atom1 < o.atom1 ) ||
00156 ( atom1 == o.atom1 && atom2 < o.atom2 )
00157 );
00158 }
00159 };
00160
00161
00162 class MOStream;
00163 class MIStream;
00164
00165 enum TupleSigType {BOND=0, ANGLE, DIHEDRAL, IMPROPER, DONOR, ACCEPTOR, CROSSTERM, EXCLUSION};
00166
00167 inline unsigned int circShift(unsigned int h, unsigned int by) {
00168 const unsigned int intBits=8*sizeof(unsigned int);
00169 by%=intBits;
00170 return (h<<by)|(h>>(intBits-by));
00171 }
00172
00173 class TupleSignature{
00174 public:
00175
00176 TupleSigType tupleType;
00177 int numOffset;
00178
00179 int *offset;
00180
00181
00182
00183 Index tupleParamType;
00184
00185
00186
00187
00188 char isReal;
00189
00190 public:
00191 TupleSignature(){
00192 offset = NULL;
00193 isReal = 1;
00194 }
00195
00196 TupleSignature(int n, TupleSigType t, Index paramType, char ir=1){
00197 tupleType = t;
00198 numOffset = n;
00199 offset = new int[n];
00200 tupleParamType = paramType;
00201 isReal = ir;
00202 }
00203 TupleSignature(const TupleSignature& oneSig){
00204 tupleType = oneSig.tupleType;
00205 numOffset = oneSig.numOffset;
00206 offset = new int[numOffset];
00207 setOffsets(oneSig.offset);
00208 tupleParamType = oneSig.tupleParamType;
00209 isReal = oneSig.isReal;
00210 }
00211 TupleSignature &operator=(const TupleSignature& oneSig){
00212 tupleType = oneSig.tupleType;
00213 numOffset = oneSig.numOffset;
00214 if(offset) delete [] offset;
00215 offset = new int[numOffset];
00216 setOffsets(oneSig.offset);
00217 tupleParamType = oneSig.tupleParamType;
00218 isReal = oneSig.isReal;
00219 return *this;
00220 }
00221 int operator==(const TupleSignature& sig) const{
00222 if(tupleType!=sig.tupleType)
00223 return 0;
00224
00225 if(tupleParamType != sig.tupleParamType)
00226 return 0;
00227
00228 if(isReal != sig.isReal)
00229 return 0;
00230
00231 if(numOffset != sig.numOffset) return 0;
00232
00233 int equalCnt=0;
00234
00235 for(int i=0; i<numOffset; i++){
00236 equalCnt += (offset[i]==sig.offset[i]);
00237 }
00238 return equalCnt==numOffset;
00239 }
00240 ~TupleSignature(){
00241 if(offset) delete[] offset;
00242 }
00243 void setOffsets(int *offs){
00244 for(int i=0; i<numOffset; i++)
00245 offset[i] = offs[i];
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 }
00273 void setEmpty(){
00274 delete [] offset;
00275 offset = NULL;
00276 }
00277 int isEmpty(){
00278 return offset==NULL;
00279 }
00280 void output(FILE *ofp){
00281 for(int i=0; i<numOffset; i++)
00282 fprintf(ofp, "%d ", offset[i]);
00283 fprintf(ofp, "| %d | %d\n", tupleParamType, isReal);
00284 }
00285
00286 int hash() const {
00287 unsigned int code = tupleType;
00288 unsigned int codesz = 8 * sizeof(int);
00289 unsigned int shift = codesz / numOffset;
00290
00291 if (shift == 0) shift=1;
00292 unsigned int i;
00293 for(i=0; i < numOffset; i++) {
00294 code = circShift(code,shift);
00295 code ^= offset[i];
00296 }
00297 return code;
00298 }
00299
00300 void pack(MOStream *msg);
00301 void unpack(MIStream *msg);
00302 };
00303
00304
00305 class AtomSignature{
00306 public:
00307 int bondCnt;
00308 int angleCnt;
00309 int dihedralCnt;
00310 int improperCnt;
00311 int crosstermCnt;
00312
00313 TupleSignature *bondSigs;
00314 TupleSignature *angleSigs;
00315 TupleSignature *dihedralSigs;
00316 TupleSignature *improperSigs;
00317 TupleSignature *crosstermSigs;
00318
00319 AtomSignature(){
00320 bondCnt=angleCnt=dihedralCnt=improperCnt=crosstermCnt=0;
00321 bondSigs = NULL;
00322 angleSigs = NULL;
00323 dihedralSigs = NULL;
00324 improperSigs = NULL;
00325 crosstermSigs = NULL;
00326 }
00327 AtomSignature(const AtomSignature &sig){
00328 bondSigs = NULL;
00329 angleSigs = NULL;
00330 dihedralSigs = NULL;
00331 improperSigs = NULL;
00332 crosstermSigs = NULL;
00333
00334 bondCnt = sig.bondCnt;
00335 if(bondCnt>0){
00336 bondSigs = new TupleSignature[bondCnt];
00337 for(int i=0; i<bondCnt; i++)
00338 bondSigs[i] = sig.bondSigs[i];
00339 }
00340
00341 angleCnt = sig.angleCnt;
00342 if(angleCnt>0){
00343 angleSigs = new TupleSignature[angleCnt];
00344 for(int i=0; i<angleCnt; i++)
00345 angleSigs[i] = sig.angleSigs[i];
00346 }
00347
00348 dihedralCnt = sig.dihedralCnt;
00349 if(dihedralCnt>0){
00350 dihedralSigs = new TupleSignature[dihedralCnt];
00351 for(int i=0; i<dihedralCnt; i++)
00352 dihedralSigs[i] = sig.dihedralSigs[i];
00353 }
00354
00355 improperCnt = sig.improperCnt;
00356 if(improperCnt>0){
00357 improperSigs = new TupleSignature[improperCnt];
00358 for(int i=0; i<improperCnt; i++)
00359 improperSigs[i] = sig.improperSigs[i];
00360 }
00361
00362 crosstermCnt = sig.crosstermCnt;
00363 if(crosstermCnt>0){
00364 crosstermSigs = new TupleSignature[crosstermCnt];
00365 for(int i=0; i<crosstermCnt; i++)
00366 crosstermSigs[i] = sig.crosstermSigs[i];
00367 }
00368 }
00369 AtomSignature& operator=(const AtomSignature& sig){
00370 bondCnt = sig.bondCnt;
00371 if(bondSigs) delete [] bondSigs;
00372 if(bondCnt>0){
00373 bondSigs = new TupleSignature[bondCnt];
00374 for(int i=0; i<bondCnt; i++)
00375 bondSigs[i] = sig.bondSigs[i];
00376 }else
00377 bondSigs = NULL;
00378
00379 angleCnt = sig.angleCnt;
00380 if(angleSigs) delete [] angleSigs;
00381 if(angleCnt>0){
00382 angleSigs = new TupleSignature[angleCnt];
00383 for(int i=0; i<angleCnt; i++)
00384 angleSigs[i] = sig.angleSigs[i];
00385 }else
00386 angleSigs = NULL;
00387
00388 dihedralCnt = sig.dihedralCnt;
00389 if(dihedralSigs) delete [] dihedralSigs;
00390 if(dihedralCnt>0){
00391 dihedralSigs = new TupleSignature[dihedralCnt];
00392 for(int i=0; i<dihedralCnt; i++)
00393 dihedralSigs[i] = sig.dihedralSigs[i];
00394 }else
00395 dihedralSigs = NULL;
00396
00397 improperCnt = sig.improperCnt;
00398 if(improperSigs) delete [] improperSigs;
00399 if(improperCnt>0){
00400 improperSigs = new TupleSignature[improperCnt];
00401 for(int i=0; i<improperCnt; i++)
00402 improperSigs[i] = sig.improperSigs[i];
00403 }else
00404 improperSigs = NULL;
00405
00406 crosstermCnt = sig.crosstermCnt;
00407 if(crosstermSigs) delete [] crosstermSigs;
00408 if(crosstermCnt>0){
00409 crosstermSigs = new TupleSignature[crosstermCnt];
00410 for(int i=0; i<crosstermCnt; i++)
00411 crosstermSigs[i] = sig.crosstermSigs[i];
00412 }else
00413 crosstermSigs = NULL;
00414
00415 return *this;
00416 }
00417 int operator==(const AtomSignature& sig) const{
00418 if(bondCnt!=sig.bondCnt) return 0;
00419 if(angleCnt!=sig.angleCnt) return 0;
00420 if(dihedralCnt!=sig.dihedralCnt) return 0;
00421 if(improperCnt!=sig.improperCnt) return 0;
00422 if(crosstermCnt!=sig.crosstermCnt) return 0;
00423
00424 #define CMPSIGS(TUPLE) \
00425 for(int i=0; i<sig.TUPLE##Cnt; i++){ \
00426 if(!(TUPLE##Sigs[i]==sig.TUPLE##Sigs[i])) return 0; \
00427 } \
00428
00429 CMPSIGS(bond)
00430 CMPSIGS(angle)
00431 CMPSIGS(dihedral)
00432 CMPSIGS(improper)
00433 CMPSIGS(crossterm)
00434
00435 return 1;
00436 }
00437 ~AtomSignature(){
00438 if(bondSigs) delete[] bondSigs;
00439 if(angleSigs) delete[] angleSigs;
00440 if(dihedralSigs) delete[] dihedralSigs;
00441 if(improperSigs) delete[] improperSigs;
00442 if(crosstermSigs) delete[] crosstermSigs;
00443 }
00444
00445 void removeEmptyTupleSigs();
00446 void pack(MOStream *msg);
00447 void unpack(MIStream *msg);
00448 };
00449
00450 struct AtomNameIdx{
00451 Index resnameIdx;
00452 Index atomnameIdx;
00453 Index atomtypeIdx;
00454 };
00455 struct AtomCstInfo{
00456 Index vdw_type;
00457 int32 status;
00458 int32 partner;
00459 int32 hydrogenList;
00460 };
00461
00462 struct ExclusionSignature{
00463 int fullExclCnt;
00464 int *fullOffset;
00465 int modExclCnt;
00466 int *modOffset;
00467 #ifdef NAMD_CUDA
00468 int allExclCnt;
00469 TupleSignature *allTuples;
00470 #endif
00471
00472 ExclusionSignature(){
00473 fullExclCnt = modExclCnt = 0;
00474 fullOffset = modOffset = NULL;
00475 #ifdef NAMD_CUDA
00476 allExclCnt = 0;
00477 allTuples = NULL;
00478 #endif
00479 }
00480 ExclusionSignature(const ExclusionSignature& sig){
00481 fullOffset = modOffset = NULL;
00482 fullExclCnt = sig.fullExclCnt;
00483 if(fullExclCnt>0){
00484 fullOffset = new int[fullExclCnt];
00485 for(int i=0; i<fullExclCnt; i++)
00486 fullOffset[i] = sig.fullOffset[i];
00487 }
00488
00489 modExclCnt = sig.modExclCnt;
00490 if(modExclCnt>0){
00491 modOffset = new int[modExclCnt];
00492 for(int i=0; i<modExclCnt; i++)
00493 modOffset[i] = sig.modOffset[i];
00494 }
00495 #ifdef NAMD_CUDA
00496 allTuples = NULL;
00497 allExclCnt = sig.allExclCnt;
00498 if(allExclCnt>0){
00499 allTuples = new TupleSignature[allExclCnt];
00500 for(int i=0; i<allExclCnt; i++)
00501 allTuples[i] = sig.allTuples[i];
00502 }
00503 #endif
00504 }
00505 ~ExclusionSignature(){
00506 if(fullOffset) delete [] fullOffset;
00507 if(modOffset) delete [] modOffset;
00508 #ifdef NAMD_CUDA
00509 if(allTuples) delete [] allTuples;
00510 #endif
00511 }
00512
00513 ExclusionSignature& operator=(const ExclusionSignature& sig){
00514 fullExclCnt = sig.fullExclCnt;
00515 if(fullOffset) delete [] fullOffset;
00516 if(fullExclCnt>0){
00517 fullOffset = new int[fullExclCnt];
00518 for(int i=0; i<fullExclCnt; i++)
00519 fullOffset[i] = sig.fullOffset[i];
00520 }else
00521 fullOffset = NULL;
00522
00523 modExclCnt = sig.modExclCnt;
00524 if(modOffset) delete [] modOffset;
00525 if(modExclCnt>0){
00526 modOffset = new int[modExclCnt];
00527 for(int i=0; i<modExclCnt; i++)
00528 modOffset[i] = sig.modOffset[i];
00529 }else
00530 modOffset = NULL;
00531 #ifdef NAMD_CUDA
00532 allExclCnt = sig.allExclCnt;
00533 if(allTuples) delete [] allTuples;
00534 if(allExclCnt>0){
00535 allTuples = new TupleSignature[allExclCnt];
00536 for(int i=0; i<allExclCnt; i++)
00537 allTuples[i] = sig.allTuples[i];
00538 }else
00539 allTuples = NULL;
00540 #endif
00541
00542 return *this;
00543 }
00544 int operator==(const ExclusionSignature& sig) const{
00545 if(fullExclCnt!=sig.fullExclCnt) return 0;
00546 if(modExclCnt!=sig.modExclCnt) return 0;
00547
00548 for(int i=0; i<fullExclCnt; i++){
00549 if(fullOffset[i]!=sig.fullOffset[i]) return 0;
00550 }
00551 for(int i=0; i<modExclCnt; i++){
00552 if(modOffset[i]!=sig.modOffset[i]) return 0;
00553 }
00554 return 1;
00555 }
00556
00557 void setOffsets(std::vector<int>& fullVec, std::vector<int>& modVec){
00558 fullExclCnt = fullVec.size();
00559 modExclCnt = modVec.size();
00560 if(fullExclCnt>0) {
00561 fullOffset = new int[fullExclCnt];
00562 for(int i=0; i<fullExclCnt; i++)
00563 fullOffset[i] = fullVec[i];
00564 }
00565
00566 if(modExclCnt>0) {
00567 modOffset = new int[modExclCnt];
00568 for(int i=0; i<modExclCnt; i++)
00569 modOffset[i] = modVec[i];
00570 }
00571 #ifdef NAMD_CUDA
00572 buildTuples();
00573 }
00574 void buildTuples() {
00575 delete [] allTuples;
00576 allTuples = NULL;
00577 allExclCnt = 0;
00578 for(int i=0; i<fullExclCnt; i++)
00579 if ( fullOffset[i] > 0 ) ++allExclCnt;
00580 for(int i=0; i<modExclCnt; i++)
00581 if ( modOffset[i] > 0 ) ++allExclCnt;
00582 if(allExclCnt>0){
00583 allTuples = new TupleSignature[allExclCnt];
00584 int j = 0;
00585 for(int i=0; i<fullExclCnt; i++){
00586 if ( fullOffset[i] <= 0 ) continue;
00587 TupleSignature oneSig(1,EXCLUSION,0);
00588 oneSig.offset[0] = fullOffset[i];
00589 allTuples[j++] = oneSig;
00590 }
00591 for(int i=0; i<modExclCnt; i++){
00592 if ( modOffset[i] <= 0 ) continue;
00593 TupleSignature oneSig(1,EXCLUSION,1);
00594 oneSig.offset[0] = modOffset[i];
00595 allTuples[j++] = oneSig;
00596 }
00597 }
00598 #endif
00599 }
00600
00601 int hash() const {
00602 unsigned int numOffset = fullExclCnt + modExclCnt;
00603 unsigned int code = 0x12345678;
00604 unsigned int codesz = 8 * sizeof(int);
00605 unsigned int shift = codesz / numOffset;
00606
00607 if (shift == 0) shift=1;
00608 unsigned int i;
00609 for(i=0; i < fullExclCnt; i++) {
00610 code = circShift(code,shift);
00611 code ^= fullOffset[i];
00612 }
00613 for(i=0; i < modExclCnt; i++) {
00614 code = circShift(code,shift);
00615 code ^= modOffset[i];
00616 }
00617 return code;
00618 }
00619
00620 void removeEmptyOffset();
00621
00622 int findOffset(int offset, int *fullOrMod);
00623 void pack(MOStream *msg);
00624 void unpack(MIStream *msg);
00625 };
00626
00627 #endif
00628