00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <string.h>
00021 #include <stdlib.h>
00022 #include <ctype.h>
00023
00024 #include "InfoStream.h"
00025 #include "Molecule.h"
00026 #include "strlib.h"
00027 #include "MStream.h"
00028 #include "Communicate.h"
00029
00030 #include "ObjectArena.h"
00031 #include "Parameters.h"
00032 #include "PDB.h"
00033 #include "SimParameters.h"
00034 #include "Hydrogen.h"
00035 #include "UniqueSetIter.h"
00036 #include "charm++.h"
00037
00038 #include "ComputeGridForce.h"
00039 #include "GridForceGrid.h"
00040
00041 #include "MGridforceParams.h"
00042
00043
00044 #define MIN_DEBUG_LEVEL 3
00045
00046 #include "Debug.h"
00047
00048 #include "CompressPsf.h"
00049 #include <deque>
00050 #include <algorithm>
00051
00052 #ifndef M_PI
00053 #define M_PI 3.14159265358979323846
00054 #endif
00055
00056 using namespace std;
00057
00058 class ResidueLookupElem
00059 {
00060 public:
00061 char mySegid[11];
00062 ResidueLookupElem *next;
00063 int firstResid;
00064 int lastResid;
00065 ResizeArray<int> atomIndex;
00066
00067 ResidueLookupElem(void) { next = 0; firstResid = -1; lastResid = -1; }
00068 ~ResidueLookupElem(void) { delete next; }
00069 int lookup(const char *segid, int resid, int *begin, int *end) const;
00070 ResidueLookupElem* append(const char *segid, int resid, int aid);
00071 };
00072
00073 #ifndef MOLECULE2_C // first object file
00074
00075 #ifdef MEM_OPT_VERSION
00076 template int lookupCstPool<AtomSignature>(const vector<AtomSignature>&, const AtomSignature&);
00077 template int lookupCstPool<ExclusionSignature>(const vector<ExclusionSignature>&, const ExclusionSignature&);
00078 #endif
00079
00080 int ResidueLookupElem::lookup(
00081 const char *segid, int resid, int *begin, int *end) const {
00082 const ResidueLookupElem *elem = this;
00083 int rval = -1;
00084 while ( elem && strcasecmp(elem->mySegid,segid) ) elem = elem->next;
00085 if ( elem && (resid >= elem->firstResid) && (resid <= elem->lastResid) ) {
00086 *begin = elem->atomIndex[resid - elem->firstResid];
00087 *end = elem->atomIndex[resid - elem->firstResid + 1];
00088 rval = 0;
00089 }
00090 return rval;
00091 }
00092
00093 ResidueLookupElem* ResidueLookupElem::append(
00094 const char *segid, int resid, int aid) {
00095 ResidueLookupElem *rval = this;
00096 if ( firstResid == -1 ) {
00097 strcpy(mySegid,segid);
00098 firstResid = resid;
00099 lastResid = resid;
00100 atomIndex.add(aid);
00101 atomIndex.add(aid+1);
00102 } else if ( ! strcasecmp(mySegid,segid) ) {
00103 if ( resid == lastResid ) {
00104 atomIndex[lastResid - firstResid + 1] = aid + 1;
00105 } else if ( resid < lastResid ) {
00106
00107 iout << iWARN << "Residue " << resid <<
00108 " out of order in segment " << segid <<
00109 ", lookup for additional residues in this segment disabled.\n" << endi;
00110 rval = next = new ResidueLookupElem;
00111 next->append(segid,resid,aid);
00112 } else {
00113 for ( ; lastResid < resid; ++lastResid ) atomIndex.add(aid);
00114 atomIndex[lastResid - firstResid + 1] = aid + 1;
00115 }
00116 } else {
00117 rval = next = new ResidueLookupElem;
00118 next->append(segid,resid,aid);
00119 }
00120 return rval;
00121 }
00122
00123
00124
00125 int Molecule::get_atom_from_name(
00126 const char *segid, int resid, const char *aname) const {
00127
00128 if (atomNames == NULL || resLookup == NULL)
00129 {
00130 NAMD_die("Tried to find atom from name on node other than node 0");
00131 }
00132
00133 int i = 0;
00134 int end = 0;
00135 if ( resLookup->lookup(segid,resid,&i,&end) ) return -1;
00136 for ( ; i < end; ++i ) {
00137 #ifdef MEM_OPT_VERSION
00138 Index idx = atomNames[i].atomnameIdx;
00139 if(!strcasecmp(aname, atomNamePool[idx])) return i;
00140 #else
00141 if ( ! strcasecmp(aname,atomNames[i].atomname) ) return i;
00142 #endif
00143 }
00144 return -1;
00145 }
00146
00147
00148 int Molecule::get_residue_size(
00149 const char *segid, int resid) const {
00150
00151 if (atomNames == NULL || resLookup == NULL)
00152 {
00153 NAMD_die("Tried to find atom from name on node other than node 0");
00154 }
00155 int i = 0;
00156 int end = 0;
00157 if ( resLookup->lookup(segid,resid,&i,&end) ) return 0;
00158 return ( end - i );
00159 }
00160
00161
00162 int Molecule::get_atom_from_index_in_residue(
00163 const char *segid, int resid, int index) const {
00164
00165 if (atomNames == NULL || resLookup == NULL)
00166 {
00167 NAMD_die("Tried to find atom from name on node other than node 0");
00168 }
00169 int i = 0;
00170 int end = 0;
00171 if ( resLookup->lookup(segid,resid,&i,&end) ) return -1;
00172 if ( index >= 0 && index < ( end - i ) ) return ( index + i );
00173 return -1;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 void Molecule::initialize(SimParameters *simParams, Parameters *param)
00188 {
00189 if ( sizeof(int32) != 4 ) { NAMD_bug("sizeof(int32) != 4"); }
00190 this->simParams = simParams;
00191 this->params = param;
00192
00193
00194 atoms=NULL;
00195 atomNames=NULL;
00196 resLookup=NULL;
00197
00198
00199 is_drude_psf = 0;
00200 drudeConsts=NULL;
00201 lphosts=NULL;
00202 anisos=NULL;
00203 lphostIndexes=NULL;
00204
00205
00206
00207 atomSegResids=NULL;
00208
00209 if ( simParams->globalForcesOn ) {
00210 resLookup = new ResidueLookupElem;
00211 }
00212
00213 #ifdef MEM_OPT_VERSION
00214 eachAtomSig = NULL;
00215 atomSigPoolSize = 0;
00216 atomSigPool = NULL;
00217 massPoolSize = 0;
00218 atomMassPool = NULL;
00219 eachAtomMass = NULL;
00220 chargePoolSize = 0;
00221 atomChargePool = NULL;
00222 eachAtomCharge = NULL;
00223 #else
00224 bonds=NULL;
00225 angles=NULL;
00226 dihedrals=NULL;
00227 impropers=NULL;
00228 crossterms=NULL;
00229 #endif
00230
00231 donors=NULL;
00232 acceptors=NULL;
00233
00234
00235 #ifndef MEM_OPT_VERSION
00236 tmpArena=NULL;
00237 exclusions=NULL;
00238 bondsWithAtom=NULL;
00239 bondsByAtom=NULL;
00240 anglesByAtom=NULL;
00241 dihedralsByAtom=NULL;
00242 impropersByAtom=NULL;
00243 crosstermsByAtom=NULL;
00244 #endif
00245
00246 #ifdef MEM_OPT_VERSION
00247 exclSigPool = NULL;
00248 exclChkSigPool = NULL;
00249 exclSigPoolSize = 0;
00250 eachAtomExclSig = NULL;
00251 #else
00252 exclusionsByAtom=NULL;
00253 fullExclusionsByAtom=NULL;
00254 modExclusionsByAtom=NULL;
00255 all_exclusions=NULL;
00256 #endif
00257
00258 langevinParams=NULL;
00259 fixedAtomFlags=NULL;
00260
00261 #ifdef MEM_OPT_VERSION
00262 clusterSigs=NULL;
00263 #else
00264 cluster=NULL;
00265 #endif
00266 clusterSize=NULL;
00267
00268 exPressureAtomFlags=NULL;
00269 rigidBondLengths=NULL;
00270 consIndexes=NULL;
00271 consParams=NULL;
00272
00273 gridfrcIndexes=NULL;
00274 gridfrcParams=NULL;
00275 gridfrcGrid=NULL;
00276 numGridforces=NULL;
00277
00278 stirIndexes=NULL;
00279 stirParams=NULL;
00280 movDragIndexes=NULL;
00281 movDragParams=NULL;
00282 rotDragIndexes=NULL;
00283 rotDragParams=NULL;
00284 consTorqueIndexes=NULL;
00285 consTorqueParams=NULL;
00286 consForceIndexes=NULL;
00287 consForce=NULL;
00288
00289 fepAtomFlags=NULL;
00290
00291
00292 nameArena = new ObjectArena<char>;
00293
00294
00295 #ifndef MEM_OPT_VERSION
00296 arena = new ObjectArena<int32>;
00297 exclArena = new ObjectArena<char>;
00298 #endif
00299
00300
00301
00302 numAtoms=0;
00303 numRealBonds=0;
00304 numBonds=0;
00305 numAngles=0;
00306 numDihedrals=0;
00307 numImpropers=0;
00308 numCrossterms=0;
00309 numDonors=0;
00310 numAcceptors=0;
00311 numExclusions=0;
00312
00313
00314 numLonepairs=0;
00315 numDrudeAtoms=0;
00316 numLphosts=0;
00317 numAnisos=0;
00318
00319
00320 numConstraints=0;
00321 numStirredAtoms=0;
00322 numMovDrag=0;
00323 numRotDrag=0;
00324 numConsTorque=0;
00325 numConsForce=0;
00326 numFixedAtoms=0;
00327 numFixedGroups=0;
00328 numExPressureAtoms=0;
00329 numRigidBonds=0;
00330 numFixedRigidBonds=0;
00331 numMultipleDihedrals=0;
00332 numMultipleImpropers=0;
00333 numCalcBonds=0;
00334 numCalcAngles=0;
00335 numCalcDihedrals=0;
00336 numCalcImpropers=0;
00337 numCalcCrossterms=0;
00338 numCalcExclusions=0;
00339
00340
00341 numFepInitial = 0;
00342 numFepFinal = 0;
00343
00344
00345
00346 occupancy = NULL;
00347 bfactor = NULL;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 Molecule::Molecule(SimParameters *simParams, Parameters *param)
00361 {
00362 initialize(simParams,param);
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 Molecule::Molecule(SimParameters *simParams, Parameters *param, char *filename, ConfigList *cfgList)
00374 {
00375 initialize(simParams,param);
00376
00377 if(simParams->useCompressedPsf)
00378 read_compressed_psf_file(filename, param, cfgList);
00379
00380
00381
00382 else
00383 read_psf_file(filename, param);
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393 Molecule::Molecule(SimParameters *simParams, Parameters *param, molfile_plugin_t *pIOHdl, void *pIOFileHdl, int natoms)
00394 {
00395 #ifdef MEM_OPT_VERSION
00396 NAMD_die("Sorry, plugin IO is not supported in the memory optimized version.");
00397 #endif
00398 initialize(simParams, param);
00399 numAtoms = natoms;
00400 int optflags = MOLFILE_BADOPTIONS;
00401 molfile_atom_t *atomarray = (molfile_atom_t *) malloc(natoms*sizeof(molfile_atom_t));
00402 memset(atomarray, 0, natoms*sizeof(molfile_atom_t));
00403
00404
00405 int rc = pIOHdl->read_structure(pIOFileHdl, &optflags, atomarray);
00406 if (rc != MOLFILE_SUCCESS && rc != MOLFILE_NOSTRUCTUREDATA) {
00407 free(atomarray);
00408 NAMD_die("ERROR: plugin failed reading structure data");
00409 }
00410 if(optflags == MOLFILE_BADOPTIONS) {
00411 free(atomarray);
00412 NAMD_die("ERROR: plugin didn't initialize optional data flags");
00413 }
00414 if(optflags & MOLFILE_OCCUPANCY) {
00415 setOccupancyData(atomarray);
00416 }
00417 if(optflags & MOLFILE_BFACTOR) {
00418 setBFactorData(atomarray);
00419 }
00420
00421 plgLoadAtomBasics(atomarray);
00422 free(atomarray);
00423
00424
00425
00426 int *from, *to;
00427 float *bondorder;
00428 if(pIOHdl->read_bonds!=NULL) {
00429 if(pIOHdl->read_bonds(pIOFileHdl, &numBonds, &from, &to, &bondorder)){
00430 NAMD_die("ERROR: failed reading bond information.");
00431 }
00432 }
00433
00434 if(numBonds!=0) {
00435 plgLoadBonds(from,to);
00436 }
00437
00438
00439 int *plgAngles, *plgDihedrals, *plgImpropers, *plgCterms;
00440 int ctermcols, ctermrows;
00441 double *angleforces, *dihedralforces, *improperforces, *ctermforces;
00442
00443 plgAngles=plgDihedrals=plgImpropers=plgCterms=NULL;
00444 if(pIOHdl->read_angles!=NULL) {
00445 if(pIOHdl->read_angles(pIOFileHdl,
00446 &numAngles, &plgAngles, &angleforces,
00447 &numDihedrals, &plgDihedrals, &dihedralforces,
00448 &numImpropers, &plgImpropers, &improperforces,
00449 &numCrossterms, &plgCterms, &ctermcols, &ctermrows,
00450 &ctermforces)) {
00451 NAMD_die("ERROR: failed reading angle information.");
00452 }
00453 }
00454
00455 if(numAngles!=0) plgLoadAngles(plgAngles);
00456 if(numDihedrals!=0) plgLoadDihedrals(plgDihedrals);
00457 if(numImpropers!=0) plgLoadImpropers(plgImpropers);
00458 if(numCrossterms!=0) plgLoadCrossterms(plgCterms);
00459
00460 numRealBonds = numBonds;
00461 build_atom_status();
00462
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 Molecule::~Molecule()
00478 {
00479
00480
00481 if (atoms != NULL)
00482 delete [] atoms;
00483
00484 if (atomNames != NULL)
00485 {
00486
00487 delete [] atomNames;
00488 }
00489 delete nameArena;
00490
00491 if (resLookup != NULL)
00492 delete resLookup;
00493
00494
00495 if (drudeConsts != NULL) delete [] drudeConsts;
00496 if (lphosts != NULL) delete [] lphosts;
00497 if (anisos != NULL) delete [] anisos;
00498 if (lphostIndexes != NULL) delete [] lphostIndexes;
00499
00500
00501 #ifdef MEM_OPT_VERSION
00502 if(eachAtomSig) delete [] eachAtomSig;
00503 if(atomSigPool) delete [] atomSigPool;
00504 #else
00505 if (bonds != NULL)
00506 delete [] bonds;
00507
00508 if (angles != NULL)
00509 delete [] angles;
00510
00511 if (dihedrals != NULL)
00512 delete [] dihedrals;
00513
00514 if (impropers != NULL)
00515 delete [] impropers;
00516
00517 if (crossterms != NULL)
00518 delete [] crossterms;
00519
00520 if (exclusions != NULL)
00521 delete [] exclusions;
00522 #endif
00523
00524 if (donors != NULL)
00525 delete [] donors;
00526
00527 if (acceptors != NULL)
00528 delete [] acceptors;
00529
00530 #ifdef MEM_OPT_VERSION
00531 if(exclSigPool) delete [] exclSigPool;
00532 if(exclChkSigPool) delete [] exclChkSigPool;
00533 if(eachAtomExclSig) delete [] eachAtomExclSig;
00534 #else
00535 if (bondsByAtom != NULL)
00536 delete [] bondsByAtom;
00537
00538 if (anglesByAtom != NULL)
00539 delete [] anglesByAtom;
00540
00541 if (dihedralsByAtom != NULL)
00542 delete [] dihedralsByAtom;
00543
00544 if (impropersByAtom != NULL)
00545 delete [] impropersByAtom;
00546
00547 if (crosstermsByAtom != NULL)
00548 delete [] crosstermsByAtom;
00549
00550 if (exclusionsByAtom != NULL)
00551 delete [] exclusionsByAtom;
00552
00553 if (fullExclusionsByAtom != NULL)
00554 delete [] fullExclusionsByAtom;
00555
00556 if (modExclusionsByAtom != NULL)
00557 delete [] modExclusionsByAtom;
00558
00559 if (all_exclusions != NULL)
00560 delete [] all_exclusions;
00561 #endif
00562
00563
00564 if (fixedAtomFlags != NULL)
00565 delete [] fixedAtomFlags;
00566
00567 if (stirIndexes != NULL)
00568 delete [] stirIndexes;
00569
00570
00571 #ifdef MEM_OPT_VERSION
00572 if(clusterSigs != NULL){
00573 delete [] clusterSigs;
00574 }
00575 #else
00576 if (cluster != NULL)
00577 delete [] cluster;
00578 #endif
00579 if (clusterSize != NULL)
00580 delete [] clusterSize;
00581
00582 if (exPressureAtomFlags != NULL)
00583 delete [] exPressureAtomFlags;
00584
00585 if (rigidBondLengths != NULL)
00586 delete [] rigidBondLengths;
00587
00588
00589 if (fepAtomFlags != NULL)
00590 delete [] fepAtomFlags;
00591
00592
00593
00594 #ifndef MEM_OPT_VERSION
00595 delete arena;
00596 delete exclArena;
00597 #endif
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 void Molecule::read_psf_file(char *fname, Parameters *params)
00619
00620 {
00621 #ifdef MEM_OPT_VERSION
00622 return;
00623 #else
00624 char err_msg[512];
00625 char buffer[512];
00626 int i;
00627 int NumTitle;
00628 FILE *psf_file;
00629 int ret_code;
00630
00631
00632 if ( (psf_file = Fopen(fname, "r")) == NULL)
00633 {
00634 sprintf(err_msg, "UNABLE TO OPEN .psf FILE %s", fname);
00635 NAMD_die(err_msg);
00636 }
00637
00638
00639 ret_code = NAMD_read_line(psf_file, buffer);
00640
00641 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00642 {
00643 ret_code = NAMD_read_line(psf_file, buffer);
00644 }
00645
00646
00647
00648 if (ret_code!=0)
00649 {
00650 sprintf(err_msg, "EMPTY .psf FILE %s", fname);
00651 NAMD_die(err_msg);
00652 }
00653
00654
00655
00656 if (!NAMD_find_word(buffer, "psf"))
00657 {
00658 sprintf(err_msg, "UNABLE TO FIND \"PSF\" STRING IN PSF FILE %s",
00659 fname);
00660 NAMD_die(err_msg);
00661 }
00662
00663
00664 if (NAMD_find_word(buffer, "drude"))
00665 {
00666 is_drude_psf = 1;
00667 }
00668
00669
00670
00671 ret_code = NAMD_read_line(psf_file, buffer);
00672
00673 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00674 {
00675 ret_code = NAMD_read_line(psf_file, buffer);
00676 }
00677
00678
00679
00680
00681 if (ret_code!=0)
00682 {
00683 sprintf(err_msg, "MISSING EVERYTHING BUT PSF FROM %s", fname);
00684 NAMD_die(err_msg);
00685 }
00686
00687
00688
00689 if (!NAMD_find_word(buffer, "NTITLE"))
00690 {
00691 sprintf(err_msg,"CAN NOT FIND \"NTITLE\" STRING IN PSF FILE %s",
00692 fname);
00693 NAMD_die(err_msg);
00694 }
00695
00696 sscanf(buffer, "%d", &NumTitle);
00697
00698
00699
00700 i=0;
00701
00702 while ( ((ret_code=NAMD_read_line(psf_file, buffer)) == 0) &&
00703 (i<NumTitle) )
00704 {
00705 if (!NAMD_blank_string(buffer))
00706 i++;
00707 }
00708
00709
00710 if (ret_code!=0)
00711 {
00712 sprintf(err_msg, "FOUND EOF INSTEAD OF NATOM IN PSF FILE %s",
00713 fname);
00714 NAMD_die(err_msg);
00715 }
00716
00717 while (NAMD_blank_string(buffer))
00718 {
00719 NAMD_read_line(psf_file, buffer);
00720 }
00721
00722
00723 if (!NAMD_find_word(buffer, "NATOM"))
00724 {
00725 sprintf(err_msg, "DIDN'T FIND \"NATOM\" IN PSF FILE %s",
00726 fname);
00727 NAMD_die(err_msg);
00728 }
00729
00730
00731 sscanf(buffer, "%d", &numAtoms);
00732
00733 read_atoms(psf_file, params);
00734
00735
00736 ret_code = NAMD_read_line(psf_file, buffer);
00737
00738 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00739 {
00740 ret_code = NAMD_read_line(psf_file, buffer);
00741 }
00742
00743
00744 if (ret_code != 0)
00745 {
00746 NAMD_die("EOF ENCOUNTERED LOOKING FOR NBONDS IN PSF");
00747 }
00748
00749
00750 if (!NAMD_find_word(buffer, "NBOND"))
00751 {
00752 NAMD_die("DID NOT FIND NBOND AFTER ATOM LIST IN PSF");
00753 }
00754
00755
00756 sscanf(buffer, "%d", &numBonds);
00757
00758 if (numBonds)
00759 read_bonds(psf_file, params);
00760
00761
00762 ret_code = NAMD_read_line(psf_file, buffer);
00763
00764 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00765 {
00766 ret_code = NAMD_read_line(psf_file, buffer);
00767 }
00768
00769
00770 if (ret_code != 0)
00771 {
00772 NAMD_die("EOF ENCOUNTERED LOOKING FOR NTHETA IN PSF");
00773 }
00774
00775
00776 if (!NAMD_find_word(buffer, "NTHETA"))
00777 {
00778 NAMD_die("DID NOT FIND NTHETA AFTER BOND LIST IN PSF");
00779 }
00780
00781
00782 sscanf(buffer, "%d", &numAngles);
00783
00784 if (numAngles)
00785 read_angles(psf_file, params);
00786
00787
00788 ret_code = NAMD_read_line(psf_file, buffer);
00789
00790 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00791 {
00792 ret_code = NAMD_read_line(psf_file, buffer);
00793 }
00794
00795
00796 if (ret_code != 0)
00797 {
00798 NAMD_die("EOF ENCOUNTERED LOOKING FOR NPHI IN PSF");
00799 }
00800
00801
00802 if (!NAMD_find_word(buffer, "NPHI"))
00803 {
00804 NAMD_die("DID NOT FIND NPHI AFTER ANGLE LIST IN PSF");
00805 }
00806
00807
00808 sscanf(buffer, "%d", &numDihedrals);
00809
00810 if (numDihedrals)
00811 read_dihedrals(psf_file, params);
00812
00813
00814 ret_code = NAMD_read_line(psf_file, buffer);
00815
00816 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00817 {
00818 ret_code = NAMD_read_line(psf_file, buffer);
00819 }
00820
00821
00822 if (ret_code != 0)
00823 {
00824 NAMD_die("EOF ENCOUNTERED LOOKING FOR NIMPHI IN PSF");
00825 }
00826
00827
00828 if (!NAMD_find_word(buffer, "NIMPHI"))
00829 {
00830 NAMD_die("DID NOT FIND NIMPHI AFTER ATOM LIST IN PSF");
00831 }
00832
00833
00834 sscanf(buffer, "%d", &numImpropers);
00835
00836 if (numImpropers)
00837 read_impropers(psf_file, params);
00838
00839
00840 ret_code = NAMD_read_line(psf_file, buffer);
00841
00842 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00843 {
00844 ret_code = NAMD_read_line(psf_file, buffer);
00845 }
00846
00847
00848 if (ret_code != 0)
00849 {
00850 NAMD_die("EOF ENCOUNTERED LOOKING FOR NDON IN PSF");
00851 }
00852
00853
00854 if (!NAMD_find_word(buffer, "NDON"))
00855 {
00856 NAMD_die("DID NOT FIND NDON AFTER ATOM LIST IN PSF");
00857 }
00858
00859
00860 sscanf(buffer, "%d", &numDonors);
00861
00862 if (numDonors)
00863 read_donors(psf_file);
00864
00865
00866 ret_code = NAMD_read_line(psf_file, buffer);
00867
00868 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00869 {
00870 ret_code = NAMD_read_line(psf_file, buffer);
00871 }
00872
00873
00874 if (ret_code != 0)
00875 {
00876 NAMD_die("EOF ENCOUNTERED LOOKING FOR NACC IN PSF");
00877 }
00878
00879
00880 if (!NAMD_find_word(buffer, "NACC"))
00881 {
00882 NAMD_die("DID NOT FIND NACC AFTER ATOM LIST IN PSF");
00883 }
00884
00885
00886 sscanf(buffer, "%d", &numAcceptors);
00887
00888 if (numAcceptors)
00889 read_acceptors(psf_file);
00890
00891
00892 while (!NAMD_find_word(buffer, "NNB"))
00893 {
00894 ret_code = NAMD_read_line(psf_file, buffer);
00895
00896 if (ret_code != 0)
00897 {
00898 NAMD_die("EOF ENCOUNTERED LOOKING FOR NNB IN PSF FILE");
00899 }
00900 }
00901
00902
00903 sscanf(buffer, "%d", &numExclusions);
00904
00905 if (numExclusions)
00906 read_exclusions(psf_file);
00907
00908
00909 if (is_drude_psf)
00910 {
00911 while (!NAMD_find_word(buffer, "NUMLP"))
00912 {
00913 ret_code = NAMD_read_line(psf_file, buffer);
00914 if (ret_code != 0)
00915 {
00916 NAMD_die("EOF ENCOUNTERED LOOKING FOR NUMLP IN DRUDE PSF FILE");
00917 }
00918 }
00919 sscanf(buffer, "%d", &numLphosts);
00920 if (numLphosts) read_lphosts(psf_file);
00921
00922 while (!NAMD_find_word(buffer, "NUMANISO"))
00923 {
00924 ret_code = NAMD_read_line(psf_file, buffer);
00925 if (ret_code != 0)
00926 {
00927 NAMD_die("EOF ENCOUNTERED LOOKING FOR NUMANISO IN DRUDE PSF FILE");
00928 }
00929 }
00930 sscanf(buffer, "%d", &numAnisos);
00931 if (numAnisos) read_anisos(psf_file);
00932
00933 }
00934
00935
00936
00937 int crossterms_present = 1;
00938 while (!NAMD_find_word(buffer, "NCRTERM"))
00939 {
00940 ret_code = NAMD_read_line(psf_file, buffer);
00941
00942 if (ret_code != 0)
00943 {
00944
00945 crossterms_present = 0;
00946 break;
00947 }
00948 }
00949
00950 if ( crossterms_present) {
00951
00952
00953 sscanf(buffer, "%d", &numCrossterms);
00954
00955 if (numCrossterms)
00956 read_crossterms(psf_file, params);
00957
00958 }
00959
00960
00961 Fclose(psf_file);
00962
00963
00964 numRealBonds = numBonds;
00965 build_atom_status();
00966
00967 return;
00968 #endif
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 void Molecule::read_compressed_psf_file(char *fname, Parameters *params, ConfigList *cfgList){
00989 #ifndef MEM_OPT_VERSION
00990 return;
00991 #else
00992 FILE *psf_file;
00993 int ret_code;
00994 char buffer[512];
00995
00996
00997 if ( (psf_file = Fopen(fname, "r")) == NULL)
00998 {
00999 char err_msg[512];
01000 sprintf(err_msg, "UNABLE TO OPEN THE COMPRESSED .psf FILE %s", fname);
01001 NAMD_die(err_msg);
01002 }
01003
01004 char strBuf[12];
01005
01006
01007 NAMD_read_line(psf_file, buffer);
01008 if(!NAMD_find_word(buffer, "FORMAT VERSION")) {
01009 NAMD_die("The compressed psf file format is incorrect, please re-generate!\n");
01010 }
01011 float psfVer = 0.0f;
01012 sscanf(buffer, "FORMAT VERSION: %f\n", &psfVer);
01013 if(fabs(psfVer - COMPRESSED_PSF_VER)>1e-6) {
01014 NAMD_die("The compressed psf file format is incorrect, please re-generate!\n");
01015 }
01016
01017
01018
01019 NAMD_read_line(psf_file, buffer);
01020 if(!NAMD_find_word(buffer, "NSEGMENTNAMES"))
01021 NAMD_die("UNABLE TO FIND NSEGMENTNAMES");
01022 sscanf(buffer, "%d", &segNamePoolSize);
01023 if(segNamePoolSize!=0)
01024 segNamePool = new char *[segNamePoolSize];
01025 for(int i=0; i<segNamePoolSize; i++){
01026 NAMD_read_line(psf_file, buffer);
01027 sscanf(buffer, "%s", strBuf);
01028 segNamePool[i] = nameArena->getNewArray(strlen(strBuf)+1);
01029 strcpy(segNamePool[i], strBuf);
01030 }
01031
01032
01033 NAMD_read_line(psf_file, buffer);
01034 if(!NAMD_find_word(buffer, "NRESIDUENAMES"))
01035 NAMD_die("UNABLE TO FIND NRESIDUENAMES");
01036 sscanf(buffer, "%d", &resNamePoolSize);
01037 if(resNamePoolSize!=0)
01038 resNamePool = new char *[resNamePoolSize];
01039 for(int i=0; i<resNamePoolSize; i++){
01040 NAMD_read_line(psf_file, buffer);
01041 sscanf(buffer, "%s", strBuf);
01042 resNamePool[i] = nameArena->getNewArray(strlen(strBuf)+1);
01043 strcpy(resNamePool[i], strBuf);
01044 }
01045
01046
01047 NAMD_read_line(psf_file, buffer);
01048 if(!NAMD_find_word(buffer, "NATOMNAMES"))
01049 NAMD_die("UNABLE TO FIND NATOMNAMES");
01050 sscanf(buffer, "%d", &atomNamePoolSize);
01051 if(atomNamePoolSize!=0)
01052 atomNamePool = new char *[atomNamePoolSize];
01053 for(int i=0; i<atomNamePoolSize; i++){
01054 NAMD_read_line(psf_file, buffer);
01055 sscanf(buffer, "%s", strBuf);
01056 atomNamePool[i] = nameArena->getNewArray(strlen(strBuf)+1);
01057 strcpy(atomNamePool[i], strBuf);
01058 }
01059
01060
01061 NAMD_read_line(psf_file, buffer);
01062 if(!NAMD_find_word(buffer, "NATOMTYPES"))
01063 NAMD_die("UNABLE TO FIND NATOMTYPES");
01064 sscanf(buffer, "%d", &atomTypePoolSize);
01065 if(atomTypePoolSize!=0)
01066 atomTypePool = new char *[atomTypePoolSize];
01067 for(int i=0; i<atomTypePoolSize; i++){
01068 NAMD_read_line(psf_file, buffer);
01069 sscanf(buffer, "%s", strBuf);
01070 atomTypePool[i] = nameArena->getNewArray(strlen(strBuf)+1);
01071 strcpy(atomTypePool[i], strBuf);
01072 }
01073
01074
01075 NAMD_read_line(psf_file, buffer);
01076 if(!NAMD_find_word(buffer, "NCHARGES"))
01077 NAMD_die("UNABLE TO FIND NCHARGES");
01078 sscanf(buffer, "%d", &chargePoolSize);
01079 if(chargePoolSize!=0)
01080 atomChargePool = new Real[chargePoolSize];
01081 for(int i=0; i<chargePoolSize; i++){
01082 NAMD_read_line(psf_file, buffer);
01083 sscanf(buffer, "%f", atomChargePool+i);
01084 }
01085
01086
01087 NAMD_read_line(psf_file, buffer);
01088 if(!NAMD_find_word(buffer, "NMASSES"))
01089 NAMD_die("UNABLE TO FIND NMASSES");
01090 sscanf(buffer, "%d", &massPoolSize);
01091 if(massPoolSize!=0)
01092 atomMassPool = new Real[massPoolSize];
01093 for(int i=0; i<massPoolSize; i++){
01094 NAMD_read_line(psf_file, buffer);
01095 sscanf(buffer, "%f", atomMassPool+i);
01096 }
01097
01098
01099 NAMD_read_line(psf_file, buffer);
01100 if(!NAMD_find_word(buffer, "ATOMSIGS"))
01101 NAMD_die("UNABLE TO FIND ATOMSIGS");
01102 sscanf(buffer, "%d", &atomSigPoolSize);
01103 atomSigPool = new AtomSignature[atomSigPoolSize];
01104 int typeCnt;
01105 int tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
01106 int tisReal;
01107 int ttype;
01108 for(int i=0; i<atomSigPoolSize; i++){
01109
01110 NAMD_read_line(psf_file, buffer);
01111 if(!NAMD_find_word(buffer, "NBONDSIGS"))
01112 NAMD_die("UNABLE TO FIND NBONDSIGS");
01113 sscanf(buffer, "%d", &typeCnt);
01114 if(typeCnt!=0){
01115 atomSigPool[i].bondCnt = typeCnt;
01116 atomSigPool[i].bondSigs = new TupleSignature[typeCnt];
01117 }
01118 for(int j=0; j<typeCnt; j++){
01119 NAMD_read_line(psf_file, buffer);
01120 sscanf(buffer, "%d | %d | %d", &tmp1, &ttype, &tisReal);
01121 TupleSignature oneSig(1, BOND, (Index)ttype, (char)tisReal);
01122 oneSig.offset[0] = tmp1;
01123 atomSigPool[i].bondSigs[j]=oneSig;
01124 if(tisReal) numRealBonds++;
01125 }
01126
01127
01128 NAMD_read_line(psf_file, buffer);
01129 if(!NAMD_find_word(buffer, "NTHETASIGS"))
01130 NAMD_die("UNABLE TO FIND NTHETASIGS");
01131 sscanf(buffer, "%d", &typeCnt);
01132 if(typeCnt!=0){
01133 atomSigPool[i].angleCnt = typeCnt;
01134 atomSigPool[i].angleSigs = new TupleSignature[typeCnt];
01135 }
01136 for(int j=0; j<typeCnt; j++){
01137 NAMD_read_line(psf_file, buffer);
01138 sscanf(buffer, "%d %d | %d | %d", &tmp1, &tmp2, &ttype, &tisReal);
01139 TupleSignature oneSig(2,ANGLE,(Index)ttype, (char)tisReal);
01140 oneSig.offset[0] = tmp1;
01141 oneSig.offset[1] = tmp2;
01142 atomSigPool[i].angleSigs[j] = oneSig;
01143 }
01144
01145 NAMD_read_line(psf_file, buffer);
01146 if(!NAMD_find_word(buffer, "NPHISIGS"))
01147 NAMD_die("UNABLE TO FIND NPHISIGS");
01148 sscanf(buffer, "%d", &typeCnt);
01149 if(typeCnt!=0){
01150 atomSigPool[i].dihedralCnt = typeCnt;
01151 atomSigPool[i].dihedralSigs = new TupleSignature[typeCnt];
01152 }
01153 for(int j=0; j<typeCnt; j++){
01154 NAMD_read_line(psf_file, buffer);
01155 sscanf(buffer, "%d %d %d | %d | %d", &tmp1, &tmp2, &tmp3, &ttype, &tisReal);
01156 TupleSignature oneSig(3,DIHEDRAL,(Index)ttype, (char)tisReal);
01157 oneSig.offset[0] = tmp1;
01158 oneSig.offset[1] = tmp2;
01159 oneSig.offset[2] = tmp3;
01160 atomSigPool[i].dihedralSigs[j] = oneSig;
01161 }
01162
01163 NAMD_read_line(psf_file, buffer);
01164 if(!NAMD_find_word(buffer, "NIMPHISIGS"))
01165 NAMD_die("UNABLE TO FIND NIMPHISIGS");
01166 sscanf(buffer, "%d", &typeCnt);
01167 if(typeCnt!=0){
01168 atomSigPool[i].improperCnt = typeCnt;
01169 atomSigPool[i].improperSigs = new TupleSignature[typeCnt];
01170 }
01171 for(int j=0; j<typeCnt; j++){
01172 NAMD_read_line(psf_file, buffer);
01173 sscanf(buffer, "%d %d %d | %d | %d", &tmp1, &tmp2, &tmp3, &ttype, &tisReal);
01174 TupleSignature oneSig(3,IMPROPER,(Index)ttype, (char)tisReal);
01175 oneSig.offset[0] = tmp1;
01176 oneSig.offset[1] = tmp2;
01177 oneSig.offset[2] = tmp3;
01178 atomSigPool[i].improperSigs[j] = oneSig;
01179 }
01180
01181 NAMD_read_line(psf_file, buffer);
01182 if(!NAMD_find_word(buffer, "NCRTERMSIGS"))
01183 NAMD_die("UNABLE TO FIND NCRTERMSIGS");
01184 sscanf(buffer, "%d", &typeCnt);
01185 if(typeCnt!=0){
01186 atomSigPool[i].crosstermCnt = typeCnt;
01187 atomSigPool[i].crosstermSigs = new TupleSignature[typeCnt];
01188 }
01189 for(int j=0; j<typeCnt; j++){
01190 NAMD_read_line(psf_file, buffer);
01191 sscanf(buffer, "%d %d %d %d %d %d %d | %d | %d", &tmp1, &tmp2, &tmp3, &tmp4, &tmp5, &tmp6, &tmp7, &ttype, &tisReal);
01192 TupleSignature oneSig(7,CROSSTERM,(Index)ttype, (char)tisReal);
01193 oneSig.offset[0] = tmp1;
01194 oneSig.offset[1] = tmp2;
01195 oneSig.offset[2] = tmp3;
01196 oneSig.offset[3] = tmp4;
01197 oneSig.offset[4] = tmp5;
01198 oneSig.offset[5] = tmp6;
01199 oneSig.offset[6] = tmp7;
01200 atomSigPool[i].crosstermSigs[j] = oneSig;
01201 }
01202 }
01203
01204
01205 NAMD_read_line(psf_file, buffer);
01206 if(!NAMD_find_word(buffer, "NEXCLSIGS")){
01207 NAMD_die("UNABLE TO FIND NEXCLSIGS");
01208 }
01209 sscanf(buffer, "%d", &exclSigPoolSize);
01210 if(exclSigPoolSize>0) exclSigPool = new ExclusionSignature[exclSigPoolSize];
01211 vector<int> fullExcls;
01212 vector<int> modExcls;
01213 for(int i=0; i<exclSigPoolSize; i++){
01214 int fullExclCnt = NAMD_read_int(psf_file, buffer);
01215 for(int j=0; j<fullExclCnt; j++)
01216 fullExcls.push_back(NAMD_read_int(psf_file, buffer));
01217 int modExclCnt = NAMD_read_int(psf_file, buffer);
01218 for(int j=0; j<modExclCnt; j++)
01219 modExcls.push_back(NAMD_read_int(psf_file, buffer));
01220
01221
01222
01223 exclSigPool[i].setOffsets(fullExcls, modExcls);
01224
01225 fullExcls.clear();
01226 modExcls.clear();
01227 }
01228
01229
01230 NAMD_read_line(psf_file, buffer);
01231 if(!NAMD_find_word(buffer, "NCLUSTERS")) {
01232 NAMD_die("UNABLE TO FIND NCLUSTERS");
01233 }
01234 sscanf(buffer, "%d", &numClusters);
01235
01236 NAMD_read_line(psf_file, buffer);
01237 if(!NAMD_find_word(buffer, "CLUSTERCONTIGUITY")) {
01238 NAMD_die("UNABLE TO FIND CLUSTERCONTIGUITY");
01239 }
01240 sscanf(buffer, "%d", &isClusterContiguous);
01241 if(!isClusterContiguous) {
01242 clusterSize = new int32[numClusters];
01243 memset(clusterSize, 0, sizeof(int32)*numClusters);
01244 }
01245
01246
01247
01248
01249 NAMD_read_line(psf_file, buffer);
01250 if(!NAMD_find_word(buffer, "NATOM"))
01251 NAMD_die("UNABLE TO FIND NATOM");
01252 sscanf(buffer, "%d", &numAtoms);
01253
01254 NAMD_read_line(psf_file, buffer);
01255 if(!NAMD_find_word(buffer, "NHYDROGENGROUP"))
01256 NAMD_die("UNABLE TO FIND NHYDROGENGROUP");
01257 sscanf(buffer, "%d", &numHydrogenGroups);
01258
01259 int isOccupancyValid, isBFactorValid;
01260 NAMD_read_line(psf_file, buffer);
01261 if(!NAMD_find_word(buffer, "OCCUPANCYVALID"))
01262 NAMD_die("UNABLE TO FIND OCCUPANCYVALID");
01263 sscanf(buffer, "%d", &isOccupancyValid);
01264 NAMD_read_line(psf_file, buffer);
01265 if(!NAMD_find_word(buffer, "TEMPFACTORVALID"))
01266 NAMD_die("UNABLE TO FIND TEMPFACTORVALID");
01267 sscanf(buffer, "%d", &isBFactorValid);
01268
01269 if(numAtoms>0){
01270 atoms = new AtomCstInfo[numAtoms];
01271 atomNames = new AtomNameIdx[numAtoms];
01272 eachAtomMass = new Index[numAtoms];
01273 eachAtomCharge = new Index[numAtoms];
01274 eachAtomSig = new Index[numAtoms];
01275 eachAtomExclSig = new Index[numAtoms];
01276
01277 clusterSigs = new int[numAtoms];
01278
01279 int *tmpHgSize = new int[numAtoms];
01280 int *tmpHgGP = new int[numAtoms];
01281 int *tmpHgSV = new int[numAtoms];
01282 hydrogenGroup.resize(numAtoms);
01283 HydrogenGroupID *hg = hydrogenGroup.begin();
01284
01285 ResidueLookupElem *tmpResLookup = resLookup;
01286
01287 if(isOccupancyValid) {
01288 occupancy = new float[numAtoms];
01289 }
01290 if(isBFactorValid) {
01291 bfactor = new float[numAtoms];
01292 }
01293
01294 int residue_number;
01295 char *segment_name;
01296 int read_count;
01297 float tmpf[2];
01298
01299 #if BINARY_PERATOM_OUTPUT
01300
01301 char *binFName = new char[strlen(fname)+10];
01302 sprintf(binFName, "%s.bin", fname);
01303 FILE *perAtomFile = Fopen(binFName, "rb");
01304 if(perAtomFile==NULL) {
01305 char err_msg[512];
01306 sprintf(err_msg, "UNABLE TO OPEN THE ASSOCIATED PER-ATOM FILE FOR THE COMPRESSED .psf FILE %s", binFName);
01307 NAMD_die(err_msg);
01308 }
01309
01310 int needFlip = 0;
01311 int magicNum = COMPRESSED_PSF_MAGICNUM;
01312 int rMagicNum = COMPRESSED_PSF_MAGICNUM;
01313 flipNum((char *)&rMagicNum, sizeof(int), 1);
01314 int fMagicNum;
01315 fread(&fMagicNum, sizeof(int), 1, perAtomFile);
01316 if(fMagicNum==magicNum) {
01317 needFlip = 0;
01318 }else if(fMagicNum==rMagicNum){
01319 needFlip = 1;
01320 }else{
01321 char err_msg[512];
01322 sprintf(err_msg, "THE ASSOCIATED PER-ATOM FILE FOR THE COMPRESSED .psf FILE %s IS CORRUPTED", binFName);
01323 NAMD_die(err_msg);
01324 }
01325
01326 float verNum = 0.0f;
01327 fread(&verNum, sizeof(float), 1, perAtomFile);
01328 if(needFlip) flipNum((char *)&verNum, sizeof(float), 1);
01329 if(fabs(verNum - COMPRESSED_PSF_VER)>1e-6) {
01330 char err_msg[512];
01331 sprintf(err_msg, "THE ASSOCIATED PER-ATOM FILE FOR THE COMPRESSED .psf FILE %s IS INCORRECT, PLEASE RE-GENERATE!\n", binFName);
01332 NAMD_die(err_msg);
01333 }
01334 delete[] binFName;
01335
01336 Index sIdx[8];
01337 int iIdx[8];
01338 for(int i=0; i<numAtoms; i++){
01339 fread(sIdx, sizeof(Index), 8, perAtomFile);
01340 fread(iIdx, sizeof(int), 7, perAtomFile);
01341 fread(tmpf, sizeof(float), 2, perAtomFile);
01342 if(needFlip) {
01343 flipNum((char *)sIdx, sizeof(Index), 8);
01344 flipNum((char *)iIdx, sizeof(int), 7);
01345 flipNum((char *)tmpf, sizeof(float), 2);
01346 }
01347 segment_name = segNamePool[sIdx[0]];
01348 atomNames[i].resnameIdx = sIdx[1];
01349 atomNames[i].atomnameIdx = sIdx[2];
01350 atomNames[i].atomtypeIdx = sIdx[3];
01351 eachAtomCharge[i] = sIdx[4];
01352 eachAtomMass[i] = sIdx[5];
01353 eachAtomSig[i] = sIdx[6];
01354 eachAtomExclSig[i] = sIdx[7];
01355 residue_number = iIdx[0];
01356 clusterSigs[i] = iIdx[1];
01357 if(!isClusterContiguous)
01358 clusterSize[iIdx[1]]++;
01359
01360 atoms[i].partner = iIdx[2];
01361 atoms[i].hydrogenList= iIdx[3];
01362
01363 tmpHgSize[i] = iIdx[4];
01364 tmpHgGP[i] = iIdx[5];
01365 tmpHgSV[i] = iIdx[6];
01366
01367
01368 #else
01369 int idx[15];
01370 for(int i=0; i<numAtoms; i++){
01371 NAMD_read_line(psf_file, buffer);
01372 read_count = sscanf(buffer, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %f %f",
01373 idx, idx+1, idx+2, idx+3, idx+4,
01374 idx+5, idx+6, idx+7, idx+8, idx+9, idx+10, idx+11, idx+12,
01375 idx+13, idx+14, tmpf, tmpf+1);
01376 if(read_count!=17){
01377 char err_msg[128];
01378 sprintf(err_msg, "BAD ATOM LINE FORMAT IN COMPRESSED PSF FILE IN ATOM LINE %d\nLINE=%s",i+1, buffer);
01379 NAMD_die(err_msg);
01380 }
01381 segment_name = segNamePool[idx[0]];
01382 atomNames[i].resnameIdx = (Index)idx[1];
01383 atomNames[i].atomnameIdx = (Index)idx[2];
01384 atomNames[i].atomtypeIdx = (Index)idx[3];
01385 eachAtomCharge[i] = (Index)idx[4];
01386 eachAtomMass[i] = (Index)idx[5];
01387 eachAtomSig[i] = (Index)idx[6];
01388 eachAtomExclSig[i] = (Index)idx[7];
01389 residue_number = idx[8];
01390 clusterSigs[i] = idx[9];
01391 if(!isClusterContiguous)
01392 clusterSize[idx[9]]++;
01393
01394 atoms[i].partner = idx[10];
01395 atoms[i].hydrogenList= idx[11];
01396
01397 tmpHgSize[i] = idx[12];
01398 tmpHgGP[i] = idx[13];
01399 tmpHgSV[i] = idx[14];
01400
01401 #endif
01402
01403 if(isOccupancyValid)
01404 occupancy[i] = tmpf[0];
01405 if(isBFactorValid)
01406 bfactor[i] = tmpf[1];
01407
01408
01409 if(tmpResLookup) tmpResLookup =
01410 tmpResLookup->append(segment_name, residue_number, i);
01411
01412 Real thisAtomMass = atomMassPool[eachAtomMass[i]];
01413 if (thisAtomMass <= 0.05) {
01414 atoms[i].status |= LonepairAtom;
01415 } else if (thisAtomMass < 1.0) {
01416 atoms[i].status |= DrudeAtom;
01417 } else if(thisAtomMass <= 3.5){
01418 atoms[i].status = HydrogenAtom;
01419 }else if(atomNamePool[atomNames[i].atomnameIdx][0]=='O' &&
01420 (thisAtomMass >= 14.0) && (thisAtomMass <= 18.0)){
01421 atoms[i].status = OxygenAtom;
01422 }
01423
01424
01425 params->assign_vdw_index(atomTypePool[atomNames[i].atomtypeIdx],
01426 &(atoms[i]));
01427 }
01428
01429
01430
01431 for(int i=0; i<numAtoms; i++){
01432 int hgIdx = atoms[i].hydrogenList;
01433 hg[hgIdx].atomID = i;
01434 hg[hgIdx].atomsInGroup = tmpHgSize[i];
01435 hg[hgIdx].GPID = tmpHgGP[i];
01436 hg[hgIdx].sortVal = tmpHgSV[i];
01437 hg[hgIdx].isGP = 1;
01438 if(tmpHgSize[i]==0) hg[hgIdx].isGP = 0;
01439 }
01440
01441 delete [] tmpHgSize;
01442 delete [] tmpHgGP;
01443 delete [] tmpHgSV;
01444
01445
01446 }
01447
01448 numBonds=0;
01449 numAngles=0;
01450 numDihedrals=0;
01451 numImpropers=0;
01452 numCrossterms=0;
01453 numTotalExclusions=0;
01454 for(int i=0; i<numAtoms; i++){
01455 AtomSignature *thisSig = &atomSigPool[eachAtomSig[i]];
01456 numBonds += thisSig->bondCnt;
01457 numAngles += thisSig->angleCnt;
01458 numDihedrals += thisSig->dihedralCnt;
01459 numImpropers += thisSig->improperCnt;
01460 numCrossterms += thisSig->crosstermCnt;
01461
01462 ExclusionSignature *exclSig = &exclSigPool[eachAtomExclSig[i]];
01463 numTotalExclusions += (exclSig->fullExclCnt + exclSig->modExclCnt);
01464 }
01465
01466 numTotalExclusions /= 2;
01467
01468
01469
01470
01471
01472 if(simParams->extraBondsOn)
01473 build_extra_bonds(params, cfgList->find("extraBondsFile"));
01474 #if 0
01475
01476
01477 int extraDihedralParamNum = 0;
01478 int extraImproperParamNum = 0;
01479 if(simParams->extraBondsOn){
01480 int numExtraParams=0;
01481
01482
01483 NAMD_read_line(psf_file, buffer);
01484 if(!NAMD_find_word(buffer, "NEXTRABONDPARAMS")){
01485 NAMD_die("UNABLE TO FIND NEXTRABONDPARAMS");
01486 }
01487 sscanf(buffer, "%d", &numExtraParams);
01488 if(numExtraParams>0){
01489 BondValue *newParams = new BondValue[params->NumBondParams+numExtraParams];
01490 memcpy(newParams, params->bond_array, params->NumBondParams*sizeof(BondValue));
01491 delete [] params->bond_array;
01492
01493 int curNumPs = params->NumBondParams;
01494 for(int i=0; i<numExtraParams; i++){
01495 Real k, x0;
01496 NAMD_read_line(psf_file, buffer);
01497 sscanf(buffer, "%f %f", &k, &x0);
01498 newParams[curNumPs+i].k = k;
01499 newParams[curNumPs+i].x0 = x0;
01500 }
01501 params->bond_array = newParams;
01502 params->NumBondParams += numExtraParams;
01503 }
01504
01505
01506 NAMD_read_line(psf_file, buffer);
01507 if(!NAMD_find_word(buffer, "NEXTRAANGLEPARAMS")){
01508 NAMD_die("UNABLE TO FIND NEXTRAANGLEPARAMS");
01509 }
01510 sscanf(buffer, "%d", &numExtraParams);
01511 if(numExtraParams>0){
01512 AngleValue *newParams = new AngleValue[params->NumAngleParams+numExtraParams];
01513 memcpy(newParams, params->angle_array, params->NumAngleParams*sizeof(AngleValue));
01514 delete [] params->angle_array;
01515
01516 int curNumPs = params->NumAngleParams;
01517 for(int i=0; i<numExtraParams; i++) {
01518 Real k, theta0, k_ub, r_ub;
01519 NAMD_read_line(psf_file, buffer);
01520 sscanf(buffer, "%f %f %f %f", &k, &theta0, &k_ub, &r_ub);
01521 newParams[curNumPs+i].k = k;
01522 newParams[curNumPs+i].theta0 = theta0;
01523 newParams[curNumPs+i].k_ub = k_ub;
01524 newParams[curNumPs+i].r_ub = r_ub;
01525 }
01526 params->angle_array = newParams;
01527 params->NumAngleParams += numExtraParams;
01528 }
01529
01530
01531 NAMD_read_line(psf_file, buffer);
01532 if(!NAMD_find_word(buffer, "NEXTRADIHEDRALPARAMS")){
01533 NAMD_die("UNABLE TO FIND NEXTRADIHEDRALPARAMS");
01534 }
01535 sscanf(buffer, "%d", &numExtraParams);
01536 extraDihedralParamNum = numExtraParams;
01537 if(numExtraParams>0){
01538 DihedralValue *newParams = new DihedralValue[params->NumDihedralParams+numExtraParams];
01539 memcpy(newParams, params->dihedral_array, params->NumDihedralParams*sizeof(DihedralValue));
01540 delete [] params->dihedral_array;
01541
01542 int curNumPs = params->NumDihedralParams;
01543 for(int i=0; i<numExtraParams; i++) {
01544 int multiplicity;
01545 Real k, delta;
01546 int n;
01547 NAMD_read_line(psf_file, buffer);
01548 sscanf(buffer, "%d", &multiplicity);
01549 newParams[curNumPs+i].multiplicity = multiplicity;
01550 for(int j=0; j<multiplicity; j++) {
01551 NAMD_read_line(psf_file, buffer);
01552 sscanf(buffer, "%f %d %f", &k, &n, &delta);
01553 newParams[curNumPs+i].values[j].k = k;
01554 newParams[curNumPs+i].values[j].n = n;
01555 newParams[curNumPs+i].values[j].delta = delta;
01556 }
01557 }
01558 params->dihedral_array = newParams;
01559 }
01560
01561
01562 NAMD_read_line(psf_file, buffer);
01563 if(!NAMD_find_word(buffer, "NEXTRAIMPROPERPARAMS")){
01564 NAMD_die("UNABLE TO FIND NEXTRAIMPROPERPARAMS");
01565 }
01566 sscanf(buffer, "%d", &numExtraParams);
01567 extraImproperParamNum = numExtraParams;
01568 if(numExtraParams>0){
01569 ImproperValue *newParams = new ImproperValue[params->NumImproperParams+numExtraParams];
01570 memcpy(newParams, params->improper_array, params->NumImproperParams*sizeof(ImproperValue));
01571 delete [] params->improper_array;
01572
01573 int curNumPs = params->NumImproperParams;
01574 for(int i=0; i<numExtraParams; i++) {
01575 int multiplicity;
01576 Real k, delta;
01577 int n;
01578 NAMD_read_line(psf_file, buffer);
01579 sscanf(buffer, "%d", &multiplicity);
01580 newParams[curNumPs+i].multiplicity = multiplicity;
01581 for(int j=0; j<multiplicity; j++) {
01582 NAMD_read_line(psf_file, buffer);
01583 sscanf(buffer, "%f %d %f", &k, &n, &delta);
01584 newParams[curNumPs+i].values[j].k = k;
01585 newParams[curNumPs+i].values[j].n = n;
01586 newParams[curNumPs+i].values[j].delta = delta;
01587 }
01588 }
01589 params->improper_array = newParams;
01590 }
01591 }
01592 #endif
01593
01594
01595 NAMD_read_line(psf_file, buffer);
01596 if(!NAMD_find_word(buffer, "DIHEDRALPARAMARRAY"))
01597 NAMD_die("UNABLE TO FIND DIHEDRALPARAMARRAY");
01598 for(int i=0; i<params->NumDihedralParams; i++){
01599 params->dihedral_array[i].multiplicity = NAMD_read_int(psf_file, buffer);
01600 }
01601
01602
01603 NAMD_read_line(psf_file, buffer);
01604 NAMD_read_line(psf_file, buffer);
01605 if(!NAMD_find_word(buffer, "IMPROPERPARAMARRAY"))
01606 NAMD_die("UNABLE TO FIND IMPROPERPARAMARRAY");
01607 for(int i=0; i<params->NumImproperParams; i++){
01608 params->improper_array[i].multiplicity = NAMD_read_int(psf_file, buffer);
01609 }
01610
01611 Fclose(psf_file);
01612
01613
01614
01615 build_atom_status();
01616 #endif
01617 }
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637 void Molecule::read_atoms(FILE *fd, Parameters *params)
01638
01639 {
01640 #ifdef MEM_OPT_VERSION
01641 return;
01642 #else
01643 char buffer[512];
01644 int atom_number=0;
01645 int last_atom_number=0;
01646
01647 char segment_name[11];
01648 char residue_number[11];
01649 char residue_name[11];
01650 char atom_name[11];
01651 char atom_type[11];
01652 Real charge;
01653 Real mass;
01654 int read_count;
01655
01656
01657 atoms = new Atom[numAtoms];
01658 atomNames = new AtomNameInfo[numAtoms];
01659 if(simParams->genCompressedPsf) {
01660 atomSegResids = new AtomSegResInfo[numAtoms];
01661 }
01662
01663
01664 if (is_drude_psf) {
01665 drudeConsts = new DrudeConst[numAtoms];
01666 }
01667
01668
01669 hydrogenGroup.resize(0);
01670
01671 if (atoms == NULL || atomNames == NULL )
01672 {
01673 NAMD_die("memory allocation failed in Molecule::read_atoms");
01674 }
01675
01676 ResidueLookupElem *tmpResLookup = resLookup;
01677
01678
01679 while (atom_number < numAtoms)
01680 {
01681
01682 NAMD_read_line(fd, buffer);
01683
01684
01685 if ( (NAMD_blank_string(buffer)) || (buffer[0] == '!') )
01686 continue;
01687
01688
01689 read_count=sscanf(buffer, "%d %s %s %s %s %s %f %f",
01690 &atom_number, segment_name, residue_number,
01691 residue_name, atom_name, atom_type, &charge, &mass);
01692
01693
01694 if (read_count != 8)
01695 {
01696 char err_msg[128];
01697
01698 sprintf(err_msg, "BAD ATOM LINE FORMAT IN PSF FILE IN ATOM LINE %d\nLINE=%s",
01699 last_atom_number+1, buffer);
01700 NAMD_die(err_msg);
01701 }
01702
01703
01704 if (is_drude_psf)
01705 {
01706 Real alpha, thole;
01707 read_count=sscanf(buffer,
01708
01709
01710 "%*d %*s %*s %*s %*s %*s %*f %*f %*d %f %f", &alpha, &thole);
01711 if (read_count != 2)
01712 {
01713 char err_msg[128];
01714
01715 sprintf(err_msg, "BAD ATOM LINE FORMAT IN PSF FILE "
01716 "IN ATOM LINE %d\nLINE=%s", last_atom_number+1, buffer);
01717 NAMD_die(err_msg);
01718 }
01719 drudeConsts[atom_number-1].alpha = alpha;
01720 drudeConsts[atom_number-1].thole = thole;
01721 }
01722
01723
01724
01725 int atom_type_num;
01726 if ( sscanf(atom_type, "%d", &atom_type_num) > 0 )
01727 {
01728 NAMD_die("Structure (psf) file is either in CHARMM format (with numbers for atoms types, the X-PLOR format using names is required) or the segment name field is empty.");
01729 }
01730
01731
01732 if (atom_number != last_atom_number+1)
01733 {
01734 char err_msg[128];
01735
01736 sprintf(err_msg, "ATOM NUMBERS OUT OF ORDER AT ATOM #%d OF PSF FILE",
01737 last_atom_number+1);
01738 NAMD_die(err_msg);
01739 }
01740
01741 last_atom_number++;
01742
01743
01744
01745
01746 int reslength = strlen(residue_name)+1;
01747 int namelength = strlen(atom_name)+1;
01748 int typelength = strlen(atom_type)+1;
01749
01750 atomNames[atom_number-1].resname = nameArena->getNewArray(reslength);
01751 atomNames[atom_number-1].atomname = nameArena->getNewArray(namelength);
01752 atomNames[atom_number-1].atomtype = nameArena->getNewArray(typelength);
01753
01754 if (atomNames[atom_number-1].resname == NULL)
01755 {
01756 NAMD_die("memory allocation failed in Molecule::read_atoms");
01757 }
01758
01759
01760 strcpy(atomNames[atom_number-1].resname, residue_name);
01761 strcpy(atomNames[atom_number-1].atomname, atom_name);
01762 strcpy(atomNames[atom_number-1].atomtype, atom_type);
01763 atoms[atom_number-1].mass = mass;
01764 atoms[atom_number-1].charge = charge;
01765 atoms[atom_number-1].status = UnknownAtom;
01766
01767
01768 if ( tmpResLookup ) tmpResLookup =
01769 tmpResLookup->append(segment_name, atoi(residue_number), atom_number-1);
01770
01771 if(atomSegResids) {
01772 AtomSegResInfo *one = atomSegResids + (atom_number - 1);
01773 memcpy(one->segname, segment_name, strlen(segment_name)+1);
01774 one->resid = atoi(residue_number);
01775 }
01776
01777
01778 if (atoms[atom_number-1].mass <= 0.05) {
01779 atoms[atom_number-1].status |= LonepairAtom;
01780 } else if (atoms[atom_number-1].mass < 1.0) {
01781 atoms[atom_number-1].status |= DrudeAtom;
01782 } else if (atoms[atom_number-1].mass <=3.5) {
01783 atoms[atom_number-1].status |= HydrogenAtom;
01784 } else if ((atomNames[atom_number-1].atomname[0] == 'O') &&
01785 (atoms[atom_number-1].mass >= 14.0) &&
01786 (atoms[atom_number-1].mass <= 18.0)) {
01787 atoms[atom_number-1].status |= OxygenAtom;
01788 }
01789
01790
01791 params->assign_vdw_index(atomNames[atom_number-1].atomtype,
01792 &(atoms[atom_number-1]));
01793 }
01794
01795 return;
01796 #endif
01797 }
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812 void Molecule::read_bonds(FILE *fd, Parameters *params)
01813
01814 {
01815 #ifdef MEM_OPT_VERSION
01816 return;
01817 #else
01818 int atom_nums[2];
01819 char atom1name[11];
01820 char atom2name[11];
01821 register int j;
01822 int num_read=0;
01823 int origNumBonds = numBonds;
01824
01825
01826 bonds=new Bond[numBonds];
01827
01828 if (bonds == NULL)
01829 {
01830 NAMD_die("memory allocations failed in Molecule::read_bonds");
01831 }
01832
01833
01834 while (num_read < numBonds)
01835 {
01836
01837 for (j=0; j<2; j++)
01838 {
01839
01840
01841
01842
01843 atom_nums[j]=NAMD_read_int(fd, "BONDS")-1;
01844
01845
01846 if (atom_nums[j] >= numAtoms)
01847 {
01848 char err_msg[128];
01849
01850 sprintf(err_msg, "BOND INDEX %d GREATER THAN NATOM %d IN BOND # %d IN PSF FILE", atom_nums[j]+1, numAtoms, num_read+1);
01851 NAMD_die(err_msg);
01852 }
01853 }
01854
01855
01856
01857
01858 if (strcasecmp(atomNames[atom_nums[0]].atomtype,
01859 atomNames[atom_nums[1]].atomtype) < 0)
01860 {
01861 strcpy(atom1name, atomNames[atom_nums[0]].atomtype);
01862 strcpy(atom2name, atomNames[atom_nums[1]].atomtype);
01863 }
01864 else
01865 {
01866 strcpy(atom2name, atomNames[atom_nums[0]].atomtype);
01867 strcpy(atom1name, atomNames[atom_nums[1]].atomtype);
01868 }
01869
01870
01871
01872 Bond *b = &(bonds[num_read]);
01873 params->assign_bond_index(atom1name, atom2name, b);
01874
01875
01876 b->atom1=atom_nums[0];
01877 b->atom2=atom_nums[1];
01878
01879
01880 Real k, x0;
01881 params->get_bond_params(&k,&x0,b->bond_type);
01882 if (simParams->watmodel == WAT_SWM4) {
01883
01884 if ( k == 0. && !is_lp(b->atom1) && !is_lp(b->atom2)) --numBonds;
01885 else ++num_read;
01886 }
01887 else {
01888 if ( k == 0. ) --numBonds;
01889 else ++num_read;
01890 }
01891 }
01892
01893
01894 if ( numBonds != origNumBonds ) {
01895 iout << iWARN << "Ignored " << origNumBonds - numBonds <<
01896 " bonds with zero force constants.\n" << endi;
01897 iout << iWARN <<
01898 "Will get H-H distance in rigid H2O from H-O-H angle.\n" << endi;
01899 }
01900
01901 return;
01902 #endif
01903 }
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922 void Molecule::read_angles(FILE *fd, Parameters *params)
01923
01924 {
01925 #ifdef MEM_OPT_VERSION
01926 return;
01927 #else
01928 int atom_nums[3];
01929 char atom1name[11];
01930 char atom2name[11];
01931 char atom3name[11];
01932 register int j;
01933 int num_read=0;
01934 int origNumAngles = numAngles;
01935
01936 angles=new Angle[numAngles];
01937
01938 if (angles == NULL)
01939 {
01940 NAMD_die("memory allocation failed in Molecule::read_angles");
01941 }
01942
01943
01944 while (num_read < numAngles)
01945 {
01946
01947 for (j=0; j<3; j++)
01948 {
01949
01950
01951
01952
01953 atom_nums[j]=NAMD_read_int(fd, "ANGLES")-1;
01954
01955
01956
01957 if (atom_nums[j] >= numAtoms)
01958 {
01959 char err_msg[128];
01960
01961 sprintf(err_msg, "ANGLES INDEX %d GREATER THAN NATOM %d IN ANGLES # %d IN PSF FILE", atom_nums[j]+1, numAtoms, num_read+1);
01962 NAMD_die(err_msg);
01963 }
01964 }
01965
01966
01967
01968
01969
01970
01971 if (strcasecmp(atomNames[atom_nums[0]].atomtype,
01972 atomNames[atom_nums[2]].atomtype) < 0)
01973 {
01974 strcpy(atom1name, atomNames[atom_nums[0]].atomtype);
01975 strcpy(atom2name, atomNames[atom_nums[1]].atomtype);
01976 strcpy(atom3name, atomNames[atom_nums[2]].atomtype);
01977 }
01978 else
01979 {
01980 strcpy(atom1name, atomNames[atom_nums[2]].atomtype);
01981 strcpy(atom2name, atomNames[atom_nums[1]].atomtype);
01982 strcpy(atom3name, atomNames[atom_nums[0]].atomtype);
01983 }
01984
01985
01986
01987 params->assign_angle_index(atom1name, atom2name,
01988 atom3name, &(angles[num_read]));
01989
01990
01991 angles[num_read].atom1=atom_nums[0];
01992 angles[num_read].atom2=atom_nums[1];
01993 angles[num_read].atom3=atom_nums[2];
01994
01995
01996 Real k, t0, k_ub, r_ub;
01997 params->get_angle_params(&k,&t0,&k_ub,&r_ub,angles[num_read].angle_type);
01998 if ( k == 0. && k_ub == 0. ) --numAngles;
01999 else ++num_read;
02000 }
02001
02002
02003 if ( numAngles != origNumAngles ) {
02004 iout << iWARN << "Ignored " << origNumAngles - numAngles <<
02005 " angles with zero force constants.\n" << endi;
02006 }
02007
02008 return;
02009 #endif
02010 }
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028 void Molecule::read_dihedrals(FILE *fd, Parameters *params)
02029 {
02030 #ifdef MEM_OPT_VERSION
02031 return;
02032 #else
02033 int atom_nums[4];
02034 int last_atom_nums[4];
02035 char atom1name[11];
02036 char atom2name[11];
02037 char atom3name[11];
02038 char atom4name[11];
02039 register int j;
02040 int num_read=0;
02041 int multiplicity=1;
02042 Bool duplicate_bond;
02043 int num_unique=0;
02044
02045
02046 for (j=0; j<4; j++)
02047 last_atom_nums[j] = -1;
02048
02049
02050 dihedrals = new Dihedral[numDihedrals];
02051
02052 if (dihedrals == NULL)
02053 {
02054 NAMD_die("memory allocation failed in Molecule::read_dihedrals");
02055 }
02056
02057
02058 while (num_read < numDihedrals)
02059 {
02060 duplicate_bond = TRUE;
02061
02062
02063 for (j=0; j<4; j++)
02064 {
02065
02066
02067
02068
02069 atom_nums[j]=NAMD_read_int(fd, "DIHEDRALS")-1;
02070
02071
02072 if (atom_nums[j] >= numAtoms)
02073 {
02074 char err_msg[128];
02075
02076 sprintf(err_msg, "DIHEDRALS INDEX %d GREATER THAN NATOM %d IN DIHEDRALS # %d IN PSF FILE", atom_nums[j]+1, numAtoms, num_read+1);
02077 NAMD_die(err_msg);
02078 }
02079
02080
02081 if (atom_nums[j] != last_atom_nums[j])
02082 {
02083 duplicate_bond = FALSE;
02084 }
02085
02086 last_atom_nums[j] = atom_nums[j];
02087 }
02088
02089
02090
02091 strcpy(atom1name, atomNames[atom_nums[0]].atomtype);
02092 strcpy(atom2name, atomNames[atom_nums[1]].atomtype);
02093 strcpy(atom3name, atomNames[atom_nums[2]].atomtype);
02094 strcpy(atom4name, atomNames[atom_nums[3]].atomtype);
02095
02096
02097
02098 if (duplicate_bond)
02099 {
02100
02101 multiplicity++;
02102
02103 if (multiplicity == 2)
02104 {
02105 numMultipleDihedrals++;
02106 }
02107 }
02108 else
02109 {
02110 multiplicity=1;
02111 num_unique++;
02112 }
02113
02114
02115 params->assign_dihedral_index(atom1name, atom2name,
02116 atom3name, atom4name, &(dihedrals[num_unique-1]),
02117 multiplicity);
02118
02119
02120 dihedrals[num_unique-1].atom1=atom_nums[0];
02121 dihedrals[num_unique-1].atom2=atom_nums[1];
02122 dihedrals[num_unique-1].atom3=atom_nums[2];
02123 dihedrals[num_unique-1].atom4=atom_nums[3];
02124
02125 num_read++;
02126 }
02127
02128 numDihedrals = num_unique;
02129
02130 return;
02131 #endif
02132 }
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 void Molecule::read_impropers(FILE *fd, Parameters *params)
02151 {
02152 #ifdef MEM_OPT_VERSION
02153 return;
02154 #else
02155 int atom_nums[4];
02156 int last_atom_nums[4];
02157 char atom1name[11];
02158 char atom2name[11];
02159 char atom3name[11];
02160 char atom4name[11];
02161 register int j;
02162 int num_read=0;
02163 int multiplicity=1;
02164 Bool duplicate_bond;
02165 int num_unique=0;
02166
02167
02168
02169 for (j=0; j<4; j++)
02170 last_atom_nums[j] = -1;
02171
02172
02173 impropers=new Improper[numImpropers];
02174
02175 if (impropers == NULL)
02176 {
02177 NAMD_die("memory allocation failed in Molecule::read_impropers");
02178 }
02179
02180
02181 while (num_read < numImpropers)
02182 {
02183 duplicate_bond = TRUE;
02184
02185
02186 for (j=0; j<4; j++)
02187 {
02188
02189
02190
02191
02192 atom_nums[j]=NAMD_read_int(fd, "IMPROPERS")-1;
02193
02194
02195 if (atom_nums[j] >= numAtoms)
02196 {
02197 char err_msg[128];
02198
02199 sprintf(err_msg, "IMPROPERS INDEX %d GREATER THAN NATOM %d IN IMPROPERS # %d IN PSF FILE", atom_nums[j]+1, numAtoms, num_read+1);
02200 NAMD_die(err_msg);
02201 }
02202
02203 if (atom_nums[j] != last_atom_nums[j])
02204 {
02205 duplicate_bond = FALSE;
02206 }
02207
02208 last_atom_nums[j] = atom_nums[j];
02209 }
02210
02211
02212 strcpy(atom1name, atomNames[atom_nums[0]].atomtype);
02213 strcpy(atom2name, atomNames[atom_nums[1]].atomtype);
02214 strcpy(atom3name, atomNames[atom_nums[2]].atomtype);
02215 strcpy(atom4name, atomNames[atom_nums[3]].atomtype);
02216
02217
02218 if (duplicate_bond)
02219 {
02220
02221
02222
02223 multiplicity++;
02224
02225 if (multiplicity == 2)
02226 {
02227
02228 numMultipleImpropers++;
02229 }
02230 }
02231 else
02232 {
02233
02234 multiplicity = 1;
02235 num_unique++;
02236 }
02237
02238
02239 params->assign_improper_index(atom1name, atom2name,
02240 atom3name, atom4name, &(impropers[num_unique-1]),
02241 multiplicity);
02242
02243
02244 impropers[num_unique-1].atom1=atom_nums[0];
02245 impropers[num_unique-1].atom2=atom_nums[1];
02246 impropers[num_unique-1].atom3=atom_nums[2];
02247 impropers[num_unique-1].atom4=atom_nums[3];
02248
02249 num_read++;
02250 }
02251
02252
02253
02254
02255 numImpropers = num_unique;
02256
02257 return;
02258 #endif
02259 }
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276 void Molecule::read_crossterms(FILE *fd, Parameters *params)
02277
02278 {
02279 #ifdef MEM_OPT_VERSION
02280 return;
02281 #else
02282 int atom_nums[8];
02283 int last_atom_nums[8];
02284 char atom1name[11];
02285 char atom2name[11];
02286 char atom3name[11];
02287 char atom4name[11];
02288 char atom5name[11];
02289 char atom6name[11];
02290 char atom7name[11];
02291 char atom8name[11];
02292 register int j;
02293 int num_read=0;
02294 Bool duplicate_bond;
02295
02296
02297
02298 for (j=0; j<8; j++)
02299 last_atom_nums[j] = -1;
02300
02301
02302 crossterms=new Crossterm[numCrossterms];
02303
02304 if (crossterms == NULL)
02305 {
02306 NAMD_die("memory allocation failed in Molecule::read_crossterms");
02307 }
02308
02309
02310 while (num_read < numCrossterms)
02311 {
02312 duplicate_bond = TRUE;
02313
02314
02315 for (j=0; j<8; j++)
02316 {
02317
02318
02319
02320
02321 atom_nums[j]=NAMD_read_int(fd, "CROSS-TERMS")-1;
02322
02323
02324 if (atom_nums[j] >= numAtoms)
02325 {
02326 char err_msg[128];
02327
02328 sprintf(err_msg, "CROSS-TERM INDEX %d GREATER THAN NATOM %d IN CROSS-TERMS # %d IN PSF FILE", atom_nums[j]+1, numAtoms, num_read+1);
02329 NAMD_die(err_msg);
02330 }
02331
02332 if (atom_nums[j] != last_atom_nums[j])
02333 {
02334 duplicate_bond = FALSE;
02335 }
02336
02337 last_atom_nums[j] = atom_nums[j];
02338 }
02339
02340
02341 strcpy(atom1name, atomNames[atom_nums[0]].atomtype);
02342 strcpy(atom2name, atomNames[atom_nums[1]].atomtype);
02343 strcpy(atom3name, atomNames[atom_nums[2]].atomtype);
02344 strcpy(atom4name, atomNames[atom_nums[3]].atomtype);
02345 strcpy(atom5name, atomNames[atom_nums[4]].atomtype);
02346 strcpy(atom6name, atomNames[atom_nums[5]].atomtype);
02347 strcpy(atom7name, atomNames[atom_nums[6]].atomtype);
02348 strcpy(atom8name, atomNames[atom_nums[7]].atomtype);
02349
02350
02351 if (duplicate_bond)
02352 {
02353 iout << iWARN << "Duplicate cross-term detected.\n" << endi;
02354 }
02355
02356
02357 params->assign_crossterm_index(atom1name, atom2name,
02358 atom3name, atom4name, atom5name, atom6name,
02359 atom7name, atom8name, &(crossterms[num_read]));
02360
02361
02362 crossterms[num_read].atom1=atom_nums[0];
02363 crossterms[num_read].atom2=atom_nums[1];
02364 crossterms[num_read].atom3=atom_nums[2];
02365 crossterms[num_read].atom4=atom_nums[3];
02366 crossterms[num_read].atom5=atom_nums[4];
02367 crossterms[num_read].atom6=atom_nums[5];
02368 crossterms[num_read].atom7=atom_nums[6];
02369 crossterms[num_read].atom8=atom_nums[7];
02370
02371 if(!duplicate_bond) num_read++;
02372 }
02373
02374 numCrossterms = num_read;
02375
02376 return;
02377 #endif
02378 }
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398 void Molecule::read_donors(FILE *fd)
02399 {
02400 #ifdef MEM_OPT_VERSION
02401 return;
02402 #else
02403 int d[2];
02404 register int j;
02405 int num_read=0;
02406 int num_no_hydr=0;
02407
02408
02409 donors=new Bond[numDonors];
02410
02411 if (donors == NULL)
02412 {
02413 NAMD_die("memory allocations failed in Molecule::read_donors");
02414 }
02415
02416
02417 while (num_read < numDonors)
02418 {
02419
02420 for (j=0; j<2; j++)
02421 {
02422
02423
02424
02425
02426 d[j]=NAMD_read_int(fd, "DONORS")-1;
02427
02428
02429 if (d[j] >= numAtoms)
02430 {
02431 char err_msg[128];
02432
02433 sprintf(err_msg,
02434 "DONOR INDEX %d GREATER THAN NATOM %d IN DONOR # %d IN PSF FILE",
02435 d[j]+1, numAtoms, num_read+1);
02436 NAMD_die(err_msg);
02437 }
02438
02439
02440 if (d[j] < 0)
02441 num_no_hydr++;
02442 }
02443
02444
02445 Bond *b = &(donors[num_read]);
02446 b->atom1=d[0];
02447 b->atom2=d[1];
02448
02449 num_read++;
02450 }
02451
02452 return;
02453 #endif
02454 }
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476 void Molecule::read_acceptors(FILE *fd)
02477 {
02478 #ifdef MEM_OPT_VERSION
02479 return;
02480 #else
02481 int d[2];
02482 register int j;
02483 int num_read=0;
02484 int num_no_ante=0;
02485
02486
02487 acceptors=new Bond[numAcceptors];
02488
02489 if (acceptors == NULL)
02490 {
02491 NAMD_die("memory allocations failed in Molecule::read_acceptors");
02492 }
02493
02494
02495 while (num_read < numAcceptors)
02496 {
02497
02498 for (j=0; j<2; j++)
02499 {
02500
02501
02502
02503
02504 d[j]=NAMD_read_int(fd, "ACCEPTORS")-1;
02505
02506
02507 if (d[j] >= numAtoms)
02508 {
02509 char err_msg[128];
02510
02511 sprintf(err_msg, "ACCEPTOR INDEX %d GREATER THAN NATOM %d IN DONOR # %d IN PSF FILE", d[j]+1, numAtoms, num_read+1);
02512 NAMD_die(err_msg);
02513 }
02514
02515
02516 if (d[j] < 0)
02517 num_no_ante++;
02518 }
02519
02520
02521 Bond *b = &(acceptors[num_read]);
02522 b->atom1=d[0];
02523 b->atom2=d[1];
02524
02525 num_read++;
02526 }
02527
02528 return;
02529 #endif
02530 }
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561 void Molecule::read_exclusions(FILE *fd)
02562
02563 {
02564 #ifdef MEM_OPT_VERSION
02565 return;
02566 #else
02567 int *exclusion_atoms;
02568 register int num_read=0;
02569 int current_index;
02570 int last_index;
02571 register int insert_index=0;
02572
02573
02574
02575 exclusions = new Exclusion[numExclusions];
02576 exclusion_atoms = new int[numExclusions];
02577
02578 if ( (exclusions == NULL) || (exclusion_atoms == NULL) )
02579 {
02580 NAMD_die("memory allocation failed in Molecule::read_exclusions");
02581 }
02582
02583
02584 for (num_read=0; num_read<numExclusions; num_read++)
02585 {
02586
02587
02588
02589 exclusion_atoms[num_read]=NAMD_read_int(fd, "IMPROPERS")-1;
02590
02591
02592 if (exclusion_atoms[num_read] >= numAtoms)
02593 {
02594 char err_msg[128];
02595
02596 sprintf(err_msg, "EXCLUSION INDEX %d GREATER THAN NATOM %d IN EXCLUSION # %d IN PSF FILE", exclusion_atoms[num_read]+1, numAtoms, num_read+1);
02597 NAMD_die(err_msg);
02598 }
02599 }
02600
02601
02602
02603 last_index=0;
02604
02605 for (num_read=0; num_read<numAtoms; num_read++)
02606 {
02607
02608 current_index=NAMD_read_int(fd, "EXCLUSIONS");
02609
02610
02611 if (current_index>numExclusions)
02612 {
02613 char err_msg[128];
02614
02615 sprintf(err_msg, "EXCLUSION INDEX %d LARGER THAN NUMBER OF EXLCUSIONS %d IN PSF FILE, EXCLUSION #%d\n",
02616 current_index+1, numExclusions, num_read);
02617 NAMD_die(err_msg);
02618 }
02619
02620
02621
02622
02623 if (current_index != last_index)
02624 {
02625
02626
02627
02628
02629 for (insert_index=last_index;
02630 insert_index<current_index; insert_index++)
02631 {
02632
02633
02634
02635
02636 int a1 = num_read;
02637 int a2 = exclusion_atoms[insert_index];
02638 if ( a1 < a2 ) {
02639 exclusions[insert_index].atom1 = a1;
02640 exclusions[insert_index].atom2 = a2;
02641 } else if ( a2 < a1 ) {
02642 exclusions[insert_index].atom1 = a2;
02643 exclusions[insert_index].atom2 = a1;
02644 } else {
02645 char err_msg[128];
02646 sprintf(err_msg, "ATOM %d EXCLUDED FROM ITSELF IN PSF FILE\n", a1+1);
02647 NAMD_die(err_msg);
02648 }
02649 }
02650
02651 last_index=current_index;
02652 }
02653 }
02654
02655
02656 delete [] exclusion_atoms;
02657
02658 return;
02659 #endif
02660 }
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672 void Molecule::read_lphosts(FILE *fd)
02673 {
02674 char buffer[512];
02675 char lptype[8];
02676 int numhosts, index, i, read_count;
02677 Real distance, angle, dihedral;
02678
02679 lphosts = new Lphost[numLphosts];
02680 if (lphosts == NULL)
02681 {
02682 NAMD_die("memory allocation failed in Molecule::read_lphosts");
02683 }
02684 for (i = 0; i < numLphosts; i++)
02685 {
02686 NAMD_read_line(fd, buffer);
02687 if ( (NAMD_blank_string(buffer)) || (buffer[0] == '!') ) continue;
02688 read_count=sscanf(buffer, "%d %d %6s %f %f %f",
02689 &numhosts, &index, lptype, &distance, &angle, &dihedral);
02690 if (read_count != 6 || numhosts != 3 || index != 4*i + 1
02691 || strcmp(lptype,"F") != 0)
02692 {
02693 char err_msg[128];
02694 sprintf(err_msg, "BAD FORMAT FOR LPHOST LINE %d IN PSF FILE LINE\n"
02695 "LINE=%s\n", i+1, buffer);
02696 NAMD_die(err_msg);
02697 }
02698 lphosts[i].distance = distance;
02699 lphosts[i].angle = angle * (M_PI/180);
02700 lphosts[i].dihedral = dihedral;
02701 }
02702 for (i = 0; i < numLphosts; i++) {
02703 lphosts[i].atom1 = NAMD_read_int(fd, "LPHOSTS")-1;
02704 lphosts[i].atom2 = NAMD_read_int(fd, "LPHOSTS")-1;
02705 lphosts[i].atom3 = NAMD_read_int(fd, "LPHOSTS")-1;
02706 lphosts[i].atom4 = NAMD_read_int(fd, "LPHOSTS")-1;
02707 }
02708 }
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720 void Molecule::read_anisos(FILE *fd)
02721 {
02722 char buffer[512];
02723 int numhosts, index, i, read_count;
02724 Real k11, k22, k33;
02725
02726 anisos = new Aniso[numAnisos];
02727 if (anisos == NULL)
02728 {
02729 NAMD_die("memory allocation failed in Molecule::read_anisos");
02730 }
02731 for (i = 0; i < numAnisos; i++)
02732 {
02733 NAMD_read_line(fd, buffer);
02734 if ( (NAMD_blank_string(buffer)) || (buffer[0] == '!') ) continue;
02735 read_count=sscanf(buffer, "%f %f %f", &k11, &k22, &k33);
02736 if (read_count != 3)
02737 {
02738 char err_msg[128];
02739 sprintf(err_msg, "BAD FORMAT FOR ANISO LINE %d IN PSF FILE LINE\n"
02740 "LINE=%s\n", i+1, buffer);
02741 NAMD_die(err_msg);
02742 }
02743 anisos[i].k11 = k11;
02744 anisos[i].k22 = k22;
02745 anisos[i].k33 = k33;
02746 }
02747 for (i = 0; i < numAnisos; i++) {
02748 anisos[i].atom1 = NAMD_read_int(fd, "ANISOS")-1;
02749 anisos[i].atom2 = NAMD_read_int(fd, "ANISOS")-1;
02750 anisos[i].atom3 = NAMD_read_int(fd, "ANISOS")-1;
02751 anisos[i].atom4 = NAMD_read_int(fd, "ANISOS")-1;
02752 }
02753 }
02754
02755
02756 void Molecule::setOccupancyData(molfile_atom_t *atomarray){
02757 occupancy = new float[numAtoms];
02758 for(int i=0; i<numAtoms; i++) {
02759 occupancy[i] = atomarray[i].occupancy;
02760 }
02761 }
02762
02763 void Molecule::setBFactorData(molfile_atom_t *atomarray){
02764 bfactor = new float[numAtoms];
02765 for(int i=0; i<numAtoms; i++) {
02766 bfactor[i] = atomarray[i].bfactor;
02767 }
02768 }
02769
02770 void Molecule::plgLoadAtomBasics(molfile_atom_t *atomarray){
02771 #ifndef MEM_OPT_VERSION
02772 atoms = new Atom[numAtoms];
02773 atomNames = new AtomNameInfo[numAtoms];
02774 if(simParams->genCompressedPsf) {
02775 atomSegResids = new AtomSegResInfo[numAtoms];
02776 }
02777 hydrogenGroup.resize(0);
02778
02779 ResidueLookupElem *tmpResLookup = resLookup;
02780
02781 for(int i=0; i<numAtoms; i++) {
02782 int reslength = strlen(atomarray[i].resname)+1;
02783 int namelength = strlen(atomarray[i].name)+1;
02784 int typelength = strlen(atomarray[i].type)+1;
02785 atomNames[i].resname = nameArena->getNewArray(reslength);
02786 atomNames[i].atomname = nameArena->getNewArray(namelength);
02787 atomNames[i].atomtype = nameArena->getNewArray(typelength);
02788 strcpy(atomNames[i].resname, atomarray[i].resname);
02789 strcpy(atomNames[i].atomname, atomarray[i].name);
02790 strcpy(atomNames[i].atomtype, atomarray[i].type);
02791
02792 atoms[i].mass = atomarray[i].mass;
02793 atoms[i].charge = atomarray[i].charge;
02794 atoms[i].status = UnknownAtom;
02795
02796
02797 if(tmpResLookup) {
02798 tmpResLookup = tmpResLookup->append(atomarray[i].segid, atomarray[i].resid, i);
02799 }
02800
02801 if(atomSegResids) {
02802 AtomSegResInfo *one = atomSegResids + i;
02803 memcpy(one->segname, atomarray[i].segid, strlen(atomarray[i].segid)+1);
02804 one->resid = atomarray[i].resid;
02805 }
02806
02807 if(atoms[i].mass <= 0.05) {
02808 atoms[i].status |= LonepairAtom;
02809 }else if(atoms[i].mass < 1.0) {
02810 atoms[i].status |= DrudeAtom;
02811 }else if(atoms[i].mass <= 3.5) {
02812 atoms[i].status |= HydrogenAtom;
02813 }else if((atomNames[i].atomname[0] == 'O') &&
02814 (atoms[i].mass>=14.0) && (atoms[i].mass<=18.0)){
02815 atoms[i].status |= OxygenAtom;
02816 }
02817
02818 params->assign_vdw_index(atomNames[i].atomtype, &atoms[i]);
02819 }
02820 #endif
02821 }
02822
02823 void Molecule::plgLoadBonds(int *from, int *to){
02824 #ifndef MEM_OPT_VERSION
02825 bonds = new Bond[numBonds];
02826 char atom1name[11];
02827 char atom2name[11];
02828 int realNumBonds = 0;
02829 for(int i=0; i<numBonds; i++) {
02830 Bond *thisBond = bonds+realNumBonds;
02831 thisBond->atom1 = from[i]-1;
02832 thisBond->atom2 = to[i]-1;
02833
02834
02835
02836
02837
02838 if(strcasecmp(atomNames[thisBond->atom1].atomtype,
02839 atomNames[thisBond->atom2].atomtype)<0) {
02840 strcpy(atom1name, atomNames[thisBond->atom1].atomtype);
02841 strcpy(atom2name, atomNames[thisBond->atom2].atomtype);
02842 }else{
02843 strcpy(atom2name, atomNames[thisBond->atom1].atomtype);
02844 strcpy(atom1name, atomNames[thisBond->atom2].atomtype);
02845 }
02846 params->assign_bond_index(atom1name, atom2name, thisBond);
02847
02848
02849 Real k, x0;
02850 params->get_bond_params(&k, &x0, thisBond->bond_type);
02851 if(simParams->watmodel == WAT_SWM4) {
02852
02853 if(k!=0. || is_lp(thisBond->atom1) ||
02854 is_lp(thisBond->atom2)) {
02855 realNumBonds++;
02856 }
02857 }else{
02858 if(k != 0.) realNumBonds++;
02859 }
02860 }
02861
02862 if(numBonds != realNumBonds) {
02863 iout << iWARN << "Ignored" << numBonds-realNumBonds <<
02864 "bonds with zero force constants.\n" <<endi;
02865 iout << iWARN << "Will get H-H distance in rigid H20 from H-O-H angle.\n" <<endi;
02866 }
02867 numBonds = realNumBonds;
02868 #endif
02869 }
02870
02871 void Molecule::plgLoadAngles(int *plgAngles)
02872 {
02873 #ifndef MEM_OPT_VERSION
02874 char atom1name[11];
02875 char atom2name[11];
02876 char atom3name[11];
02877
02878 angles=new Angle[numAngles];
02879 int *atomid = plgAngles;
02880 int numRealAngles = 0;
02881 for(int i=0; i<numAngles; i++) {
02882 Angle *thisAngle = angles+numRealAngles;
02883 thisAngle->atom1 = atomid[0]-1;
02884 thisAngle->atom2 = atomid[1]-1;
02885 thisAngle->atom3 = atomid[2]-1;
02886 atomid += 3;
02887
02888 if(strcasecmp(atomNames[thisAngle->atom1].atomtype,
02889 atomNames[thisAngle->atom2].atomtype)<0) {
02890 strcpy(atom1name, atomNames[thisAngle->atom1].atomtype);
02891 strcpy(atom2name, atomNames[thisAngle->atom2].atomtype);
02892 strcpy(atom3name, atomNames[thisAngle->atom3].atomtype);
02893 }else{
02894 strcpy(atom1name, atomNames[thisAngle->atom3].atomtype);
02895 strcpy(atom2name, atomNames[thisAngle->atom2].atomtype);
02896 strcpy(atom3name, atomNames[thisAngle->atom1].atomtype);
02897 }
02898
02899 params->assign_angle_index(atom1name, atom2name, atom3name, thisAngle);
02900
02901 Real k, t0, k_ub, r_ub;
02902 params->get_angle_params(&k, &t0, &k_ub, &r_ub, thisAngle->angle_type);
02903 if(k!=0. || k_ub!=0.) numRealAngles++;
02904 }
02905
02906 if(numAngles != numRealAngles) {
02907 iout << iWARN << "Ignored" << numAngles-numRealAngles <<
02908 " angles with zero force constants.\n" << endi;
02909 }
02910 numAngles = numRealAngles;
02911 #endif
02912 }
02913
02914 void Molecule::plgLoadDihedrals(int *plgDihedrals)
02915 {
02916 #ifndef MEM_OPT_VERSION
02917 char atom1name[11];
02918 char atom2name[11];
02919 char atom3name[11];
02920 char atom4name[11];
02921 int lastAtomIds[4];
02922 int multiplicity = 1;
02923
02924 lastAtomIds[0]=lastAtomIds[1]=lastAtomIds[2]=lastAtomIds[3]=-1;
02925 dihedrals = new Dihedral[numDihedrals];
02926 int numRealDihedrals = 0;
02927 int *atomid = plgDihedrals;
02928 for(int i=0; i<numDihedrals; i++, atomid+=4) {
02929 Dihedral *thisDihedral = dihedrals + numRealDihedrals;
02930 Bool duplicate_bond = TRUE;
02931 for(int j=0; j<4; j++) {
02932 if(atomid[j] != lastAtomIds[j]) {
02933 duplicate_bond = FALSE;
02934 }
02935 lastAtomIds[j] = atomid[j];
02936 }
02937
02938 strcpy(atom1name, atomNames[atomid[0]-1].atomtype);
02939 strcpy(atom2name, atomNames[atomid[1]-1].atomtype);
02940 strcpy(atom3name, atomNames[atomid[2]-1].atomtype);
02941 strcpy(atom4name, atomNames[atomid[3]-1].atomtype);
02942
02943 if(duplicate_bond) {
02944 multiplicity++;
02945 if(multiplicity==2) {
02946 numMultipleDihedrals++;
02947 }
02948 }else{
02949 multiplicity=1;
02950 numRealDihedrals++;
02951 }
02952
02953 params->assign_dihedral_index(atom1name, atom2name,
02954 atom3name, atom4name, thisDihedral,
02955 multiplicity);
02956 thisDihedral->atom1 = atomid[0]-1;
02957 thisDihedral->atom2 = atomid[1]-1;
02958 thisDihedral->atom3 = atomid[2]-1;
02959 thisDihedral->atom4 = atomid[3]-1;
02960 }
02961
02962 numDihedrals = numRealDihedrals;
02963 #endif
02964 }
02965
02966 void Molecule::plgLoadImpropers(int *plgImpropers)
02967 {
02968 #ifndef MEM_OPT_VERSION
02969 char atom1name[11];
02970 char atom2name[11];
02971 char atom3name[11];
02972 char atom4name[11];
02973 int lastAtomIds[4];
02974 int multiplicity = 1;
02975
02976 lastAtomIds[0]=lastAtomIds[1]=lastAtomIds[2]=lastAtomIds[3]=-1;
02977 impropers = new Improper[numImpropers];
02978 int numRealImpropers = 0;
02979 int *atomid = plgImpropers;
02980 for(int i=0; i<numImpropers; i++, atomid+=4) {
02981 Improper *thisImproper = impropers + numRealImpropers;
02982 Bool duplicate_bond = TRUE;
02983 for(int j=0; j<4; j++) {
02984 if(atomid[j] != lastAtomIds[j]) {
02985 duplicate_bond = FALSE;
02986 }
02987 lastAtomIds[j] = atomid[j];
02988 }
02989
02990 strcpy(atom1name, atomNames[atomid[0]-1].atomtype);
02991 strcpy(atom2name, atomNames[atomid[1]-1].atomtype);
02992 strcpy(atom3name, atomNames[atomid[2]-1].atomtype);
02993 strcpy(atom4name, atomNames[atomid[3]-1].atomtype);
02994
02995 if(duplicate_bond) {
02996 multiplicity++;
02997 if(multiplicity==2) {
02998 numMultipleImpropers++;
02999 }
03000 }else{
03001 multiplicity=1;
03002 numRealImpropers++;
03003 }
03004
03005 params->assign_improper_index(atom1name, atom2name,
03006 atom3name, atom4name, thisImproper,
03007 multiplicity);
03008 thisImproper->atom1 = atomid[0]-1;
03009 thisImproper->atom2 = atomid[1]-1;
03010 thisImproper->atom3 = atomid[2]-1;
03011 thisImproper->atom4 = atomid[3]-1;
03012 }
03013
03014 numImpropers = numRealImpropers;
03015 #endif
03016 }
03017
03018 void Molecule::plgLoadCrossterms(int *plgCterms)
03019 {
03020 #ifndef MEM_OPT_VERSION
03021 char atom1name[11];
03022 char atom2name[11];
03023 char atom3name[11];
03024 char atom4name[11];
03025 char atom5name[11];
03026 char atom6name[11];
03027 char atom7name[11];
03028 char atom8name[11];
03029 int lastAtomIds[8];
03030
03031 for(int i=0; i<8; i++)
03032 lastAtomIds[i]=-1;
03033
03034 crossterms = new Crossterm[numCrossterms];
03035 int numRealCrossterms = 0;
03036 int *atomid = plgCterms;
03037 for(int i=0; i<numCrossterms; i++, atomid+=8) {
03038 Crossterm *thisCrossterm = crossterms + numRealCrossterms;
03039 Bool duplicate_bond = TRUE;
03040 for(int j=0; j<8; j++) {
03041 if(atomid[j] != lastAtomIds[j]) {
03042 duplicate_bond = FALSE;
03043 }
03044 lastAtomIds[j] = atomid[j];
03045 }
03046
03047 strcpy(atom1name, atomNames[atomid[0]-1].atomtype);
03048 strcpy(atom2name, atomNames[atomid[1]-1].atomtype);
03049 strcpy(atom3name, atomNames[atomid[2]-1].atomtype);
03050 strcpy(atom4name, atomNames[atomid[3]-1].atomtype);
03051 strcpy(atom5name, atomNames[atomid[4]-1].atomtype);
03052 strcpy(atom6name, atomNames[atomid[5]-1].atomtype);
03053 strcpy(atom7name, atomNames[atomid[6]-1].atomtype);
03054 strcpy(atom8name, atomNames[atomid[7]-1].atomtype);
03055
03056 if(duplicate_bond) {
03057 iout << iWARN <<"Duplicate cross-term detected.\n" << endi;
03058 }else
03059 numRealCrossterms++;
03060
03061 params->assign_crossterm_index(atom1name, atom2name,
03062 atom3name, atom4name, atom5name,
03063 atom6name, atom7name, atom8name,
03064 thisCrossterm);
03065
03066 thisCrossterm->atom1 = atomid[0]-1;
03067 thisCrossterm->atom2 = atomid[1]-1;
03068 thisCrossterm->atom3 = atomid[2]-1;
03069 thisCrossterm->atom4 = atomid[3]-1;
03070 thisCrossterm->atom5 = atomid[4]-1;
03071 thisCrossterm->atom6 = atomid[5]-1;
03072 thisCrossterm->atom7 = atomid[6]-1;
03073 thisCrossterm->atom8 = atomid[7]-1;
03074 }
03075
03076 numCrossterms = numRealCrossterms;
03077 #endif
03078 }
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090 void Molecule::print_atoms(Parameters *params)
03091
03092 {
03093 register int i;
03094 Real sigma;
03095 Real epsilon;
03096 Real sigma14;
03097 Real epsilon14;
03098
03099 DebugM(2,"ATOM LIST\n" \
03100 << "******************************************\n" \
03101 << "NUM NAME TYPE RES MASS CHARGE CHARGE FEP-CHARGE" \
03102 << "SIGMA EPSILON SIGMA14 EPSILON14\n" \
03103 << endi);
03104
03105 for (i=0; i<numAtoms; i++)
03106 {
03107 params->get_vdw_params(&sigma, &epsilon, &sigma14, &epsilon14,
03108 atoms[i].vdw_type);
03109
03110 #ifdef MEM_OPT_VERSION
03111 DebugM(2,i+1 << " " << atomNamePool[atomNames[i].atomnameIdx] \
03112 << " " << atomTypePool[atomNames[i].atomtypeIdx] << " " \
03113 << resNamePool[atomNames[i].resnameIdx] << " " \
03114 << atommass(i) \
03115 << " " << atomcharge(i) << " " << sigma \
03116 << " " << epsilon << " " << sigma14 \
03117 << " " << epsilon14 << "\n" \
03118 << endi);
03119 #else
03120 DebugM(2,i+1 << " " << atomNames[i].atomname \
03121 << " " << atomNames[i].atomtype << " " \
03122 << atomNames[i].resname << " " << atoms[i].mass \
03123 << " " << atoms[i].charge << " " << sigma \
03124 << " " << epsilon << " " << sigma14 \
03125 << " " << epsilon14 << "\n" \
03126 << endi);
03127 #endif
03128 }
03129 }
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141 void Molecule::print_bonds(Parameters *params)
03142
03143 {
03144 register int i;
03145 Real k;
03146 Real x0;
03147
03148 DebugM(2,"BOND LIST\n" << "********************************\n" \
03149 << "ATOM1 ATOM2 TYPE1 TYPE2 k x0" \
03150 << endi);
03151
03152 #ifdef MEM_OPT_VERSION
03153 for(i=0; i<numAtoms; i++){
03154 AtomSignature *sig = &atomSigPool[eachAtomSig[i]];
03155 int bCnt = sig->bondCnt;
03156 TupleSignature *bSigs = sig->bondSigs;
03157 for(int j=0; j<bCnt; j++){
03158 Bond aBond;
03159 aBond.atom1 = i;
03160 aBond.atom2 = i+bSigs[j].offset[0];
03161 aBond.bond_type = bSigs[j].tupleParamType;
03162 params->get_bond_params(&k, &x0, aBond.bond_type);
03163
03164 DebugM(2,aBond.atom1+1 << " " \
03165 << aBond.atom2+1 << " " \
03166 << get_atomtype(aBond.atom1) << " " \
03167 << get_atomtype(aBond.atom2) << " " << k \
03168 << " " << x0 << endi);
03169 }
03170 }
03171 #else
03172 for (i=0; i<numBonds; i++)
03173 {
03174 params->get_bond_params(&k, &x0, bonds[i].bond_type);
03175
03176 DebugM(2,bonds[i].atom1+1 << " " \
03177 << bonds[i].atom2+1 << " " \
03178 << atomNames[bonds[i].atom1].atomtype << " " \
03179 << atomNames[bonds[i].atom2].atomtype << " " << k \
03180 << " " << x0 << endi);
03181 }
03182 #endif
03183 }
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195 void Molecule::print_exclusions()
03196 {
03197 #ifdef MEM_OPT_VERSION
03198 DebugM(2, "WARNING: this function is not availabe in memory optimized version!\n" << endi);
03199 #else
03200 register int i;
03201
03202 DebugM(2,"EXPLICIT EXCLUSION LIST\n" \
03203 << "********************************\n" \
03204 << "ATOM1 ATOM2 " \
03205 << endi);
03206
03207 for (i=0; i<numExclusions; i++)
03208 {
03209 DebugM(2,exclusions[i].atom1+1 << " " \
03210 << exclusions[i].atom2+1 << endi);
03211 }
03212 #endif
03213 }
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227 void Molecule::send_Molecule(MOStream *msg)
03228
03229 {
03230 #ifdef MEM_OPT_VERSION
03231
03232
03233 build_lists_by_atom();
03234 #endif
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246 #ifdef MEM_OPT_VERSION
03247 msg->put(numAtoms);
03248
03249
03250 msg->put(massPoolSize);
03251 msg->put(massPoolSize, atomMassPool);
03252 msg->put(numAtoms*sizeof(Index), (char *)eachAtomMass);
03253
03254 msg->put(chargePoolSize);
03255 msg->put(chargePoolSize, atomChargePool);
03256 msg->put(numAtoms*sizeof(Index), (char *)eachAtomCharge);
03257
03258
03259 msg->put(numAtoms*sizeof(AtomCstInfo), (char *)atoms);
03260
03261
03262 msg->put(atomSigPoolSize);
03263 for(int i=0; i<atomSigPoolSize; i++)
03264 atomSigPool[i].pack(msg);
03265
03266
03267 msg->put(exclSigPoolSize);
03268 for(int i=0; i<exclSigPoolSize; i++)
03269 exclSigPool[i].pack(msg);
03270
03271
03272 msg->put(numAtoms*sizeof(Index), (char *)eachAtomSig);
03273 msg->put(numAtoms*sizeof(Index), (char *)eachAtomExclSig);
03274
03275 msg->put(numAtoms*sizeof(int32), (char *)clusterSigs);
03276 #else
03277 msg->put(numAtoms);
03278 msg->put(numAtoms*sizeof(Atom), (char*)atoms);
03279 #endif
03280
03281 msg->put(numRealBonds);
03282 msg->put(numBonds);
03283
03284 #ifndef MEM_OPT_VERSION
03285 if (numBonds)
03286 {
03287 msg->put(numBonds*sizeof(Bond), (char*)bonds);
03288 }
03289 #endif
03290
03291
03292 msg->put(numAngles);
03293
03294 #ifndef MEM_OPT_VERSION
03295 if (numAngles)
03296 {
03297 msg->put(numAngles*sizeof(Angle), (char*)angles);
03298 }
03299 #endif
03300
03301
03302 msg->put(numDihedrals);
03303
03304 #ifndef MEM_OPT_VERSION
03305 if (numDihedrals)
03306 {
03307 msg->put(numDihedrals*sizeof(Dihedral), (char*)dihedrals);
03308 }
03309 #endif
03310
03311
03312 msg->put(numImpropers);
03313
03314 #ifndef MEM_OPT_VERSION
03315 if (numImpropers)
03316 {
03317 msg->put(numImpropers*sizeof(Improper), (char*)impropers);
03318 }
03319 #endif
03320
03321
03322 msg->put(numCrossterms);
03323
03324 #ifndef MEM_OPT_VERSION
03325 if (numCrossterms)
03326 {
03327 msg->put(numCrossterms*sizeof(Crossterm), (char*)crossterms);
03328 }
03329 #endif
03330
03331
03332 msg->put(numDonors);
03333
03334 if(numDonors)
03335 {
03336 msg->put(numDonors*sizeof(Bond), (char*)donors);
03337 }
03338
03339
03340 msg->put(numAcceptors);
03341
03342 if(numAcceptors)
03343 {
03344 msg->put(numAcceptors*sizeof(Bond), (char*)acceptors);
03345 }
03346
03347
03348 #ifndef MEM_OPT_VERSION
03349 msg->put(numExclusions);
03350
03351 if (numExclusions)
03352 {
03353 msg->put(numExclusions*sizeof(Exclusion), (char*)exclusions);
03354 }
03355 #endif
03356
03357
03358
03359
03360 #ifdef MEM_OPT_VERSION
03361 msg->put(numHydrogenGroups);
03362 msg->put(numAtoms*sizeof(HydrogenGroupID), (char *)hydrogenGroup.begin());
03363 #endif
03364
03365
03366 if (simParams->constraintsOn)
03367 {
03368 msg->put(numConstraints);
03369
03370 msg->put(numAtoms, consIndexes);
03371
03372 if (numConstraints)
03373 {
03374 msg->put(numConstraints*sizeof(ConstraintParams), (char*)consParams);
03375 }
03376 }
03377
03378
03379
03380 if (simParams->mgridforceOn)
03381 {
03382 DebugM(3, "Sending gridforce info\n");
03383 msg->put(numGridforceGrids);
03384
03385 for (int grid = 0; grid < numGridforceGrids; grid++) {
03386 msg->put(numGridforces[grid]);
03387 msg->put(numAtoms, gridfrcIndexes[grid]);
03388 if (numGridforces[grid])
03389 {
03390 msg->put(numGridforces[grid]*sizeof(GridforceParams), (char*)gridfrcParams[grid]);
03391 }
03392 gridfrcGrid[grid]->pack(msg);
03393 }
03394 }
03395
03396
03397
03398 if (simParams->stirOn)
03399 {
03400
03401 msg->put(numStirredAtoms);
03402
03403 msg->put(numAtoms, stirIndexes);
03404
03405 if (numStirredAtoms)
03406 {
03407
03408 msg->put(numStirredAtoms*sizeof(StirParams), (char*)stirParams);
03409 }
03410 }
03411
03412
03413
03414 if (simParams->movDragOn) {
03415 msg->put(numMovDrag);
03416 msg->put(numAtoms, movDragIndexes);
03417 if (numMovDrag)
03418 {
03419 msg->put(numMovDrag*sizeof(MovDragParams), (char*)movDragParams);
03420 }
03421 }
03422
03423
03424 if (simParams->rotDragOn) {
03425 msg->put(numRotDrag);
03426 msg->put(numAtoms, rotDragIndexes);
03427 if (numRotDrag)
03428 {
03429 msg->put(numRotDrag*sizeof(RotDragParams), (char*)rotDragParams);
03430 }
03431 }
03432
03433
03434 if (simParams->consTorqueOn) {
03435 msg->put(numConsTorque);
03436 msg->put(numAtoms, consTorqueIndexes);
03437 if (numConsTorque)
03438 {
03439 msg->put(numConsTorque*sizeof(ConsTorqueParams), (char*)consTorqueParams);
03440 }
03441 }
03442
03443
03444 if (simParams->consForceOn)
03445 { msg->put(numConsForce);
03446 msg->put(numAtoms, consForceIndexes);
03447 if (numConsForce)
03448 msg->put(numConsForce*sizeof(Vector), (char*)consForce);
03449 }
03450
03451
03452 if (simParams->langevinOn || simParams->tCoupleOn)
03453 {
03454 msg->put(numAtoms, langevinParams);
03455 }
03456
03457
03458 if (simParams->fixedAtomsOn)
03459 {
03460 msg->put(numFixedAtoms);
03461 msg->put(numAtoms, fixedAtomFlags);
03462 msg->put(numFixedRigidBonds);
03463 }
03464
03465 if (simParams->excludeFromPressure) {
03466 msg->put(numExPressureAtoms);
03467 msg->put(numAtoms, exPressureAtomFlags);
03468 }
03469
03470
03471
03472 if (simParams->alchFepOn || simParams->alchThermIntOn || simParams->lesOn || simParams->pairInteractionOn) {
03473 msg->put(numFepInitial);
03474 msg->put(numFepFinal);
03475 msg->put(numAtoms*sizeof(char), (char*)fepAtomFlags);
03476 }
03477
03478
03479
03480 msg->end();
03481 delete msg;
03482
03483 #ifdef MEM_OPT_VERSION
03484 build_excl_check_signatures();
03485 #else
03486
03487 build_lists_by_atom();
03488 #endif
03489
03490 }
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503 void Molecule::receive_Molecule(MIStream *msg)
03504 {
03505
03506 msg->get(numAtoms);
03507
03508 #ifdef MEM_OPT_VERSION
03509
03510 msg->get(massPoolSize);
03511 if(atomMassPool) delete [] atomMassPool;
03512 atomMassPool = new Real[massPoolSize];
03513 msg->get(massPoolSize, atomMassPool);
03514 if(eachAtomMass) delete [] eachAtomMass;
03515 eachAtomMass = new Index[numAtoms];
03516 msg->get(numAtoms*sizeof(Index), (char *)eachAtomMass);
03517
03518 msg->get(chargePoolSize);
03519 if(atomChargePool) delete [] atomChargePool;
03520 atomChargePool = new Real[chargePoolSize];
03521 msg->get(chargePoolSize, atomChargePool);
03522 if(eachAtomCharge) delete [] eachAtomCharge;
03523 eachAtomCharge = new Index[numAtoms];
03524 msg->get(numAtoms*sizeof(Index), (char *)eachAtomCharge);
03525
03526
03527 if(atoms) delete [] atoms;
03528 atoms = new AtomCstInfo[numAtoms];
03529 msg->get(numAtoms*sizeof(AtomCstInfo), (char *)atoms);
03530
03531
03532 msg->get(atomSigPoolSize);
03533 if(atomSigPool) delete [] atomSigPool;
03534 atomSigPool = new AtomSignature[atomSigPoolSize];
03535 for(int i=0; i<atomSigPoolSize; i++)
03536 atomSigPool[i].unpack(msg);
03537
03538
03539 msg->get(exclSigPoolSize);
03540 if(exclSigPool) delete [] exclSigPool;
03541 exclSigPool = new ExclusionSignature[exclSigPoolSize];
03542 for(int i=0; i<exclSigPoolSize; i++)
03543 exclSigPool[i].unpack(msg);
03544
03545
03546 if(eachAtomSig) delete [] eachAtomSig;
03547 eachAtomSig = new Index[numAtoms];
03548 msg->get(numAtoms*sizeof(Index), (char *)eachAtomSig);
03549 if(eachAtomExclSig) delete [] eachAtomExclSig;
03550 eachAtomExclSig = new Index[numAtoms];
03551 msg->get(numAtoms*sizeof(Index), (char *)eachAtomExclSig);
03552
03553 if(clusterSigs) delete [] clusterSigs;
03554 clusterSigs = new int32[numAtoms];
03555 msg->get(numAtoms*sizeof(int32), (char *)clusterSigs);
03556 #else
03557 delete [] atoms;
03558 atoms= new Atom[numAtoms];
03559
03560 msg->get(numAtoms*sizeof(Atom), (char*)atoms);
03561 #endif
03562
03563
03564 msg->get(numRealBonds);
03565 msg->get(numBonds);
03566
03567 #ifndef MEM_OPT_VERSION
03568 if (numBonds)
03569 {
03570 delete [] bonds;
03571 bonds=new Bond[numBonds];
03572
03573 msg->get(numBonds*sizeof(Bond), (char*)bonds);
03574 }
03575 #endif
03576
03577
03578 msg->get(numAngles);
03579
03580 #ifndef MEM_OPT_VERSION
03581 if (numAngles)
03582 {
03583 delete [] angles;
03584 angles=new Angle[numAngles];
03585
03586 msg->get(numAngles*sizeof(Angle), (char*)angles);
03587 }
03588 #endif
03589
03590
03591 msg->get(numDihedrals);
03592
03593 #ifndef MEM_OPT_VERSION
03594 if (numDihedrals)
03595 {
03596 delete [] dihedrals;
03597 dihedrals=new Dihedral[numDihedrals];
03598
03599 msg->get(numDihedrals*sizeof(Dihedral), (char*)dihedrals);
03600 }
03601 #endif
03602
03603
03604 msg->get(numImpropers);
03605
03606 #ifndef MEM_OPT_VERSION
03607 if (numImpropers)
03608 {
03609 delete [] impropers;
03610 impropers=new Improper[numImpropers];
03611
03612 msg->get(numImpropers*sizeof(Improper), (char*)impropers);
03613 }
03614 #endif
03615
03616
03617 msg->get(numCrossterms);
03618
03619 #ifndef MEM_OPT_VERSION
03620 if (numCrossterms)
03621 {
03622 delete [] crossterms;
03623 crossterms=new Crossterm[numCrossterms];
03624
03625 msg->get(numCrossterms*sizeof(Crossterm), (char*)crossterms);
03626 }
03627 #endif
03628
03629
03630 msg->get(numDonors);
03631
03632 if (numDonors)
03633 {
03634 delete [] donors;
03635 donors=new Bond[numDonors];
03636
03637 msg->get(numDonors*sizeof(Bond), (char*)donors);
03638 }
03639
03640
03641 msg->get(numAcceptors);
03642
03643 if (numAcceptors)
03644 {
03645 delete [] acceptors;
03646 acceptors=new Bond[numAcceptors];
03647
03648 msg->get(numAcceptors*sizeof(Bond), (char*)acceptors);
03649 }
03650
03651
03652 #ifndef MEM_OPT_VERSION
03653 msg->get(numExclusions);
03654
03655 if (numExclusions)
03656 {
03657 delete [] exclusions;
03658 exclusions=new Exclusion[numExclusions];
03659
03660 msg->get(numExclusions*sizeof(Exclusion), (char*)exclusions);
03661 }
03662 #endif
03663
03664 #ifdef MEM_OPT_VERSION
03665 msg->get(numHydrogenGroups);
03666 hydrogenGroup.resize(numAtoms);
03667 msg->get(numAtoms*sizeof(HydrogenGroupID), (char *)hydrogenGroup.begin());
03668 #endif
03669
03670
03671 if (simParams->constraintsOn)
03672 {
03673 msg->get(numConstraints);
03674
03675 delete [] consIndexes;
03676 consIndexes = new int32[numAtoms];
03677
03678 msg->get(numAtoms, consIndexes);
03679
03680 if (numConstraints)
03681 {
03682 delete [] consParams;
03683 consParams = new ConstraintParams[numConstraints];
03684
03685 msg->get(numConstraints*sizeof(ConstraintParams), (char*)consParams);
03686 }
03687 }
03688
03689
03690 if (simParams->mgridforceOn)
03691 {
03692 DebugM(3, "Receiving gridforce info\n");
03693
03694 msg->get(numGridforceGrids);
03695
03696 delete [] numGridforces;
03697 numGridforces = new int[numGridforceGrids];
03698
03699 delete [] gridfrcIndexes;
03700 delete [] gridfrcParams;
03701 delete [] gridfrcGrid;
03702 gridfrcIndexes = new int32*[numGridforceGrids];
03703 gridfrcParams = new GridforceParams*[numGridforceGrids];
03704 gridfrcGrid = new GridforceGrid*[numGridforceGrids];
03705
03706 for (int grid = 0; grid < numGridforceGrids; grid++) {
03707 msg->get(numGridforces[grid]);
03708
03709 gridfrcIndexes[grid] = new int32[numAtoms];
03710 msg->get(numAtoms, gridfrcIndexes[grid]);
03711
03712 if (numGridforces[grid])
03713 {
03714 gridfrcParams[grid] = new GridforceParams[numGridforces[grid]];
03715 msg->get(numGridforces[grid]*sizeof(GridforceParams), (char*)gridfrcParams[grid]);
03716 }
03717
03718 gridfrcGrid[grid] = new GridforceGrid(grid);
03719 gridfrcGrid[grid]->unpack(msg);
03720 CProxy_ComputeGridForceNodeMgr
03721 mgr(CkpvAccess(BOCclass_group).computeGridForceNodeMgr);
03722 GridDepositMsg *outmsg = new GridDepositMsg;
03723 outmsg->gridnum = grid;
03724 outmsg->grid = gridfrcGrid[grid];
03725 outmsg->num_grids = numGridforceGrids;
03726 mgr[CkMyNode()].depositInitialGrid(outmsg);
03727 }
03728 }
03729
03730
03731
03732 if (simParams->stirOn)
03733 {
03734 msg->get(numStirredAtoms);
03735
03736 delete [] stirIndexes;
03737 stirIndexes = new int32[numAtoms];
03738
03739 msg->get(numAtoms, stirIndexes);
03740
03741 if (numStirredAtoms)
03742 {
03743 delete [] stirParams;
03744 stirParams = new StirParams[numStirredAtoms];
03745
03746 msg->get(numStirredAtoms*sizeof(StirParams), (char*)stirParams);
03747 }
03748 }
03749
03750
03751 if (simParams->movDragOn) {
03752 msg->get(numMovDrag);
03753 delete [] movDragIndexes;
03754 movDragIndexes = new int32[numAtoms];
03755 msg->get(numAtoms, movDragIndexes);
03756 if (numMovDrag)
03757 {
03758 delete [] movDragParams;
03759 movDragParams = new MovDragParams[numMovDrag];
03760 msg->get(numMovDrag*sizeof(MovDragParams), (char*)movDragParams);
03761 }
03762 }
03763
03764
03765 if (simParams->rotDragOn) {
03766 msg->get(numRotDrag);
03767 delete [] rotDragIndexes;
03768 rotDragIndexes = new int32[numAtoms];
03769 msg->get(numAtoms, rotDragIndexes);
03770 if (numRotDrag)
03771 {
03772 delete [] rotDragParams;
03773 rotDragParams = new RotDragParams[numRotDrag];
03774 msg->get(numRotDrag*sizeof(RotDragParams), (char*)rotDragParams);
03775 }
03776 }
03777
03778
03779 if (simParams->consTorqueOn) {
03780 msg->get(numConsTorque);
03781 delete [] consTorqueIndexes;
03782 consTorqueIndexes = new int32[numAtoms];
03783 msg->get(numAtoms, consTorqueIndexes);
03784 if (numConsTorque)
03785 {
03786 delete [] consTorqueParams;
03787 consTorqueParams = new ConsTorqueParams[numConsTorque];
03788 msg->get(numConsTorque*sizeof(ConsTorqueParams), (char*)consTorqueParams);
03789 }
03790 }
03791
03792
03793 if (simParams->consForceOn)
03794 { msg->get(numConsForce);
03795 delete [] consForceIndexes;
03796 consForceIndexes = new int32[numAtoms];
03797 msg->get(numAtoms, consForceIndexes);
03798 if (numConsForce)
03799 { delete [] consForce;
03800 consForce = new Vector[numConsForce];
03801 msg->get(numConsForce*sizeof(Vector), (char*)consForce);
03802 }
03803 }
03804
03805
03806 if (simParams->langevinOn || simParams->tCoupleOn)
03807 {
03808 delete [] langevinParams;
03809 langevinParams = new Real[numAtoms];
03810
03811 msg->get(numAtoms, langevinParams);
03812 }
03813
03814
03815 if (simParams->fixedAtomsOn)
03816 {
03817 delete [] fixedAtomFlags;
03818 fixedAtomFlags = new int32[numAtoms];
03819
03820 msg->get(numFixedAtoms);
03821 msg->get(numAtoms, fixedAtomFlags);
03822 msg->get(numFixedRigidBonds);
03823 }
03824
03825 if (simParams->excludeFromPressure) {
03826 exPressureAtomFlags = new int32[numAtoms];
03827 msg->get(numExPressureAtoms);
03828 msg->get(numAtoms, exPressureAtomFlags);
03829 }
03830
03831
03832
03833 if (simParams->alchFepOn || simParams->lesOn || simParams->alchThermIntOn || simParams->pairInteractionOn) {
03834 delete [] fepAtomFlags;
03835 fepAtomFlags = new unsigned char[numAtoms];
03836
03837 msg->get(numFepInitial);
03838 msg->get(numFepFinal);
03839 msg->get(numAtoms*sizeof(unsigned char), (char*)fepAtomFlags);
03840 }
03841
03842
03843
03844 delete msg;
03845
03846
03847 build_atom_status();
03848
03849
03850 #ifdef MEM_OPT_VERSION
03851 build_excl_check_signatures();
03852 #else
03853 build_lists_by_atom();
03854 #endif
03855
03856 #ifdef MEM_OPT_VERSION
03857 delEachAtomSigs();
03858 delChargeSpace();
03859 delMassSpace();
03860 delOtherEachAtomStructs();
03861 #endif
03862 }
03863
03864
03865
03866 #ifdef MEM_OPT_VERSION
03867
03868
03869
03870 void Molecule::build_excl_check_signatures(){
03871 exclChkSigPool = new ExclusionCheck[exclSigPoolSize];
03872 for(int i=0; i<exclSigPoolSize; i++){
03873 ExclusionSignature *sig = &exclSigPool[i];
03874 ExclusionCheck *sigChk = &exclChkSigPool[i];
03875 if(sig->fullExclCnt){
03876 if(!sig->modExclCnt){
03877 sigChk->min = sig->fullOffset[0];
03878 sigChk->max = sig->fullOffset[sig->fullExclCnt-1];
03879 }else{
03880 int fullMin, fullMax, modMin, modMax;
03881
03882 fullMin = sig->fullOffset[0];
03883 fullMax = sig->fullOffset[sig->fullExclCnt-1];
03884
03885 modMin = sig->modOffset[0];
03886 modMax = sig->modOffset[sig->modExclCnt-1];
03887
03888 if(fullMin < modMin)
03889 sigChk->min = fullMin;
03890 else
03891 sigChk->min = modMin;
03892 if(fullMax < modMax)
03893 sigChk->max = modMax;
03894 else
03895 sigChk->max = fullMax;
03896 }
03897 }else{
03898 if(sig->modExclCnt){
03899 sigChk->min = sig->modOffset[0];
03900 sigChk->max = sig->modOffset[sig->modExclCnt-1];
03901 }else{
03902 if(CkMyPe()==0)
03903 printf("Warning: an empty exclusion signature with index %d!\n", i);
03904 continue;
03905 }
03906 }
03907
03908 if((sigChk->max-sigChk->min) > simParams->maxExclusionFlags){
03909 printf("The distance of a exclusion check %d exceeds the value %d simulation parameter maxExclusionFlags specifies! Please increase the value\n", sigChk->max-sigChk->min, simParams->maxExclusionFlags);
03910 NAMD_die("Currently not supporting building exclusion check on the fly for memory optimized version!\n");
03911 }
03912
03913 sigChk->flags = new char[sigChk->max-sigChk->min+1];
03914 memset(sigChk->flags, 0, sizeof(char)*(sigChk->max-sigChk->min+1));
03915 for(int j=0; j<sig->fullExclCnt; j++){
03916 int dist = sig->fullOffset[j] - sigChk->min;
03917 sigChk->flags[dist] = EXCHCK_FULL;
03918 }
03919 for(int j=0; j<sig->modExclCnt; j++){
03920 int dist = sig->modOffset[j] - sigChk->min;
03921 sigChk->flags[dist] = EXCHCK_MOD;
03922 }
03923 }
03924 }
03925 #endif
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938 #ifdef MEM_OPT_VERSION
03939
03940
03941
03942
03943
03944
03945 void Molecule::build_lists_by_atom()
03946
03947 {
03948 register int i;
03949
03950 register int numFixedAtoms = this->numFixedAtoms;
03951
03952
03953 if ( simParams->fixedAtomsForces ) numFixedAtoms = 0;
03954
03955 const int pair_self =
03956 simParams->pairInteractionOn ? simParams->pairInteractionSelf : 0;
03957
03958
03959
03960
03961
03962 DebugM(3, "Building the atom list for each signature.\n");
03963
03964
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985 numCalcBonds = numBonds;
03986 numCalcAngles = numAngles;
03987 numCalcDihedrals = numDihedrals;
03988 numCalcImpropers = numImpropers;
03989 numCalcCrossterms = numCrossterms;
03990 if(numFixedAtoms || pair_self){
03991 vector<AtomSignature> newAtomSigPool;
03992
03993
03994
03995 AtomSignature emptyAtomSig;
03996 newAtomSigPool.push_back(emptyAtomSig);
03997
03998
03999
04000
04001 AtomSignature newAtomSig;
04002 for(i=0; i<numAtoms; i++){
04003 AtomSignature *curAtomSig = &atomSigPool[eachAtomSig[i]];
04004
04005
04006 if(pair_self && fepAtomFlags[i]!=1){
04007
04008
04009 numCalcBonds -= curAtomSig->bondCnt;
04010 numCalcAngles -= curAtomSig->angleCnt;
04011 numCalcDihedrals -= curAtomSig->dihedralCnt;
04012 numCalcImpropers -= curAtomSig->improperCnt;
04013 numCalcCrossterms -= curAtomSig->crosstermCnt;
04014
04015
04016 eachAtomSig[i] = (Index)atomSigPoolSize;
04017
04018 continue;
04019 }
04020
04021
04022 int sigChanged = 0;
04023 if(numFixedAtoms && fixedAtomFlags[i]){
04024
04025 newAtomSig = *curAtomSig;
04026
04027
04028 int tupleCnt = curAtomSig->bondCnt;
04029 TupleSignature *tupleSigs = curAtomSig->bondSigs;
04030 for(int j=0; j<tupleCnt; j++){
04031 int atom2 = i+tupleSigs[j].offset[0];
04032 if(fixedAtomFlags[atom2]){
04033 newAtomSig.bondSigs[j].setEmpty();
04034 numCalcBonds--;
04035 sigChanged = 1;
04036 }
04037 }
04038
04039
04040 tupleCnt = curAtomSig->angleCnt;
04041 tupleSigs = curAtomSig->angleSigs;
04042 for(int j=0; j<tupleCnt; j++){
04043 int atom2 = i+tupleSigs[j].offset[0];
04044 int atom3 = i+tupleSigs[j].offset[1];
04045 if(fixedAtomFlags[atom2] && fixedAtomFlags[atom3]){
04046 newAtomSig.angleSigs[j].setEmpty();
04047 numCalcAngles--;
04048 sigChanged = 1;
04049 }
04050 }
04051
04052
04053 tupleCnt = curAtomSig->dihedralCnt;
04054 tupleSigs = curAtomSig->dihedralSigs;
04055 for(int j=0; j<tupleCnt; j++){
04056 int atom2 = i+tupleSigs[j].offset[0];
04057 int atom3 = i+tupleSigs[j].offset[1];
04058 int atom4 = i+tupleSigs[j].offset[2];
04059 if(fixedAtomFlags[atom2] && fixedAtomFlags[atom3]
04060 && fixedAtomFlags[atom4]){
04061 newAtomSig.dihedralSigs[j].setEmpty();
04062 numCalcDihedrals--;
04063 sigChanged = 1;
04064 }
04065 }
04066
04067
04068 tupleCnt = curAtomSig->improperCnt;
04069 tupleSigs = curAtomSig->improperSigs;
04070 for(int j=0; j<tupleCnt; j++){
04071 int atom2 = i+tupleSigs[j].offset[0];
04072 int atom3 = i+tupleSigs[j].offset[1];
04073 int atom4 = i+tupleSigs[j].offset[2];
04074 if(fixedAtomFlags[atom2] && fixedAtomFlags[atom3]
04075 && fixedAtomFlags[atom4]){
04076 newAtomSig.improperSigs[j].setEmpty();
04077 numCalcImpropers--;
04078 sigChanged = 1;
04079 }
04080 }
04081
04082
04083 tupleCnt = curAtomSig->crosstermCnt;
04084 tupleSigs = curAtomSig->crosstermSigs;
04085 for(int j=0; j<tupleCnt; j++){
04086 int atom2 = i+tupleSigs[j].offset[0];
04087 int atom3 = i+tupleSigs[j].offset[1];
04088 int atom4 = i+tupleSigs[j].offset[2];
04089 int atom5 = i+tupleSigs[j].offset[3];
04090 int atom6 = i+tupleSigs[j].offset[4];
04091 int atom7 = i+tupleSigs[j].offset[5];
04092 int atom8 = i+tupleSigs[j].offset[6];
04093
04094 if(fixedAtomFlags[atom2] && fixedAtomFlags[atom3]
04095 && fixedAtomFlags[atom4] && fixedAtomFlags[atom5]
04096 && fixedAtomFlags[atom6] && fixedAtomFlags[atom7]
04097 && fixedAtomFlags[atom8]){
04098 newAtomSig.crosstermSigs[j].setEmpty();
04099 numCalcCrossterms--;
04100 sigChanged = 1;
04101 }
04102 }
04103
04104
04105 if(sigChanged){
04106 newAtomSig.removeEmptyTupleSigs();
04107
04108
04109 int poolIndex = lookupCstPool(newAtomSigPool, newAtomSig);
04110 if(poolIndex==-1){
04111 poolIndex = newAtomSigPool.size();
04112 newAtomSigPool.push_back(newAtomSig);
04113 }
04114 eachAtomSig[i] = (Index)(poolIndex+atomSigPoolSize);
04115 }
04116 }
04117 }
04118
04119 AtomSignature *tmpAtomSigPool = new AtomSignature[atomSigPoolSize+newAtomSigPool.size()];
04120 for(i=0; i<atomSigPoolSize; i++)
04121 tmpAtomSigPool[i] = atomSigPool[i];
04122 for(i=0; i<newAtomSigPool.size(); i++)
04123 tmpAtomSigPool[atomSigPoolSize+i] = newAtomSigPool[i];
04124
04125 delete [] atomSigPool;
04126 atomSigPoolSize += newAtomSigPool.size();
04127 atomSigPool = tmpAtomSigPool;
04128 newAtomSigPool.clear();
04129
04130 if(CkMyPe()==0){
04131 printf("Current number of atom signatures: %d\n", atomSigPoolSize);
04132 }
04133 }
04134
04135 DebugM(3,"Building exclusion data.\n");
04136
04137
04138
04139
04140
04141 if(CkMyPe()==0){
04142 CkPrintf("Current exclusion signatures: %d\n", exclSigPoolSize);
04143 }
04144 build_exclusions();
04145
04146 if(CkMyPe()==0){
04147 CkPrintf("After stripping, exclusion signatures: %d\n", exclSigPoolSize);
04148 }
04149
04150
04151
04152
04153 }
04154 #else
04155 void Molecule::build_lists_by_atom()
04156
04157 {
04158 register int i;
04159
04160 register int numFixedAtoms = this->numFixedAtoms;
04161
04162
04163 if ( simParams->fixedAtomsForces ) numFixedAtoms = 0;
04164
04165
04166
04167
04168
04169 tmpArena = new ObjectArena<int32>;
04170 bondsWithAtom = new int32 *[numAtoms];
04171 cluster = new int32 [numAtoms];
04172 clusterSize = new int32 [numAtoms];
04173
04174 bondsByAtom = new int32 *[numAtoms];
04175 anglesByAtom = new int32 *[numAtoms];
04176 dihedralsByAtom = new int32 *[numAtoms];
04177 impropersByAtom = new int32 *[numAtoms];
04178 crosstermsByAtom = new int32 *[numAtoms];
04179
04180 exclusionsByAtom = new int32 *[numAtoms];
04181 fullExclusionsByAtom = new int32 *[numAtoms];
04182 modExclusionsByAtom = new int32 *[numAtoms];
04183
04184 int32 *byAtomSize = new int32[numAtoms];
04185
04186 const int pair_self =
04187 simParams->pairInteractionOn ? simParams->pairInteractionSelf : 0;
04188
04189 DebugM(3,"Building bond lists.\n");
04190
04191
04192 for (i=0; i<numAtoms; i++)
04193 {
04194 byAtomSize[i] = 0;
04195 }
04196 for (i=0; i<numRealBonds; i++)
04197 {
04198 byAtomSize[bonds[i].atom1]++;
04199 byAtomSize[bonds[i].atom2]++;
04200 }
04201 for (i=0; i<numAtoms; i++)
04202 {
04203 bondsWithAtom[i] = tmpArena->getNewArray(byAtomSize[i]+1);
04204 bondsWithAtom[i][byAtomSize[i]] = -1;
04205 byAtomSize[i] = 0;
04206 }
04207 for (i=0; i<numRealBonds; i++)
04208 {
04209 int a1 = bonds[i].atom1;
04210 int a2 = bonds[i].atom2;
04211 bondsWithAtom[a1][byAtomSize[a1]++] = i;
04212 bondsWithAtom[a2][byAtomSize[a2]++] = i;
04213 }
04214
04215
04216 for (i=0; i<numAtoms; i++) {
04217 cluster[i] = i;
04218 }
04219 for (i=0; i<numAtoms; i++) {
04220 int ci = i;
04221 while ( cluster[ci] != ci ) ci = cluster[ci];
04222 for ( int32 *b = bondsWithAtom[i]; *b != -1; ++b ) {
04223 int a = bonds[*b].atom1;
04224 if ( a == i ) a = bonds[*b].atom2;
04225 if ( a > i ) {
04226 int ca = a;
04227 while ( cluster[ca] != ca ) ca = cluster[ca];
04228 if ( ca > ci ) cluster[ca] = cluster[ci];
04229 else cluster[ci] = cluster[ca];
04230 }
04231 }
04232 }
04233 while ( 1 ) {
04234 int allok = 1;
04235 for (i=0; i<numAtoms; i++) {
04236 int ci = cluster[i];
04237 if ( cluster[ci] != ci ) {
04238 allok = 0;
04239 cluster[i] = cluster[ci];
04240 }
04241 }
04242 if ( allok ) break;
04243 }
04244
04245 for (i=0; i<numAtoms; i++) {
04246 clusterSize[i] = 0;
04247 }
04248 for (i=0; i<numAtoms; i++) {
04249 clusterSize[cluster[i]] += 1;
04250 }
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262 for (i=0; i<numAtoms; i++)
04263 {
04264 byAtomSize[i] = 0;
04265 }
04266 numCalcBonds = 0;
04267 for (i=0; i<numBonds; i++)
04268 {
04269 if ( numFixedAtoms && fixedAtomFlags[bonds[i].atom1]
04270 && fixedAtomFlags[bonds[i].atom2] ) continue;
04271
04272 if ( pair_self && fepAtomFlags[bonds[i].atom1] != 1) continue;
04273 byAtomSize[bonds[i].atom1]++;
04274 numCalcBonds++;
04275 }
04276 for (i=0; i<numAtoms; i++)
04277 {
04278 bondsByAtom[i] = arena->getNewArray(byAtomSize[i]+1);
04279 bondsByAtom[i][byAtomSize[i]] = -1;
04280 byAtomSize[i] = 0;
04281 }
04282 for (i=0; i<numBonds; i++)
04283 {
04284 if ( numFixedAtoms && fixedAtomFlags[bonds[i].atom1]
04285 && fixedAtomFlags[bonds[i].atom2] ) continue;
04286 if ( pair_self && fepAtomFlags[bonds[i].atom1] != 1) continue;
04287 int a1 = bonds[i].atom1;
04288 bondsByAtom[a1][byAtomSize[a1]++] = i;
04289 }
04290 for (i=0; i<numBonds; ++i) {
04291 int a1 = bonds[i].atom1;
04292 int a2 = bonds[i].atom2;
04293 int j;
04294 if ( a1 == a2 ) {
04295 char buff[512];
04296 sprintf(buff,"Atom %d is bonded to itself", a1+1);
04297 NAMD_die(buff);
04298 }
04299 for ( j = 0; j < byAtomSize[a1]; ++j ) {
04300 int b = bondsByAtom[a1][j];
04301 int ba1 = bonds[b].atom1;
04302 int ba2 = bonds[b].atom2;
04303 if ( b != i && ( (ba1==a1 && ba2==a2) || (ba1==a2 && ba2==a1) ) ) {
04304 char buff[512];
04305 sprintf(buff,"Duplicate bond from atom %d to atom %d", a1+1, a2+1);
04306 NAMD_die(buff);
04307 }
04308 }
04309 for ( j = 0; j < byAtomSize[a2]; ++j ) {
04310 int b = bondsByAtom[a2][j];
04311 int ba1 = bonds[b].atom1;
04312 int ba2 = bonds[b].atom2;
04313 if ( b != i && ( (ba1==a1 && ba2==a2) || (ba1==a2 && ba2==a1) ) ) {
04314 char buff[512];
04315 sprintf(buff,"Duplicate bond from atom %d to atom %d", a1+1, a2+1);
04316 NAMD_die(buff);
04317 }
04318 }
04319 }
04320
04321 DebugM(3,"Building angle lists.\n");
04322
04323
04324 for (i=0; i<numAtoms; i++)
04325 {
04326 byAtomSize[i] = 0;
04327 }
04328 numCalcAngles = 0;
04329 for (i=0; i<numAngles; i++)
04330 {
04331 if ( numFixedAtoms && fixedAtomFlags[angles[i].atom1]
04332 && fixedAtomFlags[angles[i].atom2]
04333 && fixedAtomFlags[angles[i].atom3] ) continue;
04334 if ( pair_self && fepAtomFlags[angles[i].atom1] != 1) continue;
04335 byAtomSize[angles[i].atom1]++;
04336 numCalcAngles++;
04337 }
04338 for (i=0; i<numAtoms; i++)
04339 {
04340 anglesByAtom[i] = arena->getNewArray(byAtomSize[i]+1);
04341 anglesByAtom[i][byAtomSize[i]] = -1;
04342 byAtomSize[i] = 0;
04343 }
04344 for (i=0; i<numAngles; i++)
04345 {
04346 if ( pair_self && fepAtomFlags[angles[i].atom1] != 1) continue;
04347 if ( numFixedAtoms && fixedAtomFlags[angles[i].atom1]
04348 && fixedAtomFlags[angles[i].atom2]
04349 && fixedAtomFlags[angles[i].atom3] ) continue;
04350 int a1 = angles[i].atom1;
04351 anglesByAtom[a1][byAtomSize[a1]++] = i;
04352 }
04353
04354 DebugM(3,"Building improper lists.\n");
04355
04356
04357 for (i=0; i<numAtoms; i++)
04358 {
04359 byAtomSize[i] = 0;
04360 }
04361 numCalcImpropers = 0;
04362 for (i=0; i<numImpropers; i++)
04363 {
04364 if ( numFixedAtoms && fixedAtomFlags[impropers[i].atom1]
04365 && fixedAtomFlags[impropers[i].atom2]
04366 && fixedAtomFlags[impropers[i].atom3]
04367 && fixedAtomFlags[impropers[i].atom4] ) continue;
04368 if ( pair_self && fepAtomFlags[impropers[i].atom1] != 1) continue;
04369 byAtomSize[impropers[i].atom1]++;
04370 numCalcImpropers++;
04371 }
04372 for (i=0; i<numAtoms; i++)
04373 {
04374 impropersByAtom[i] = arena->getNewArray(byAtomSize[i]+1);
04375 impropersByAtom[i][byAtomSize[i]] = -1;
04376 byAtomSize[i] = 0;
04377 }
04378 for (i=0; i<numImpropers; i++)
04379 {
04380 if ( numFixedAtoms && fixedAtomFlags[impropers[i].atom1]
04381 && fixedAtomFlags[impropers[i].atom2]
04382 && fixedAtomFlags[impropers[i].atom3]
04383 && fixedAtomFlags[impropers[i].atom4] ) continue;
04384 if ( pair_self && fepAtomFlags[impropers[i].atom1] != 1) continue;
04385 int a1 = impropers[i].atom1;
04386 impropersByAtom[a1][byAtomSize[a1]++] = i;
04387 }
04388
04389 DebugM(3,"Building dihedral lists.\n");
04390
04391
04392 for (i=0; i<numAtoms; i++)
04393 {
04394 byAtomSize[i] = 0;
04395 }
04396 numCalcDihedrals = 0;
04397 for (i=0; i<numDihedrals; i++)
04398 {
04399 if ( numFixedAtoms && fixedAtomFlags[dihedrals[i].atom1]
04400 && fixedAtomFlags[dihedrals[i].atom2]
04401 && fixedAtomFlags[dihedrals[i].atom3]
04402 && fixedAtomFlags[dihedrals[i].atom4] ) continue;
04403 if ( pair_self && fepAtomFlags[dihedrals[i].atom1] != 1) continue;
04404 byAtomSize[dihedrals[i].atom1]++;
04405 numCalcDihedrals++;
04406 }
04407 for (i=0; i<numAtoms; i++)
04408 {
04409 dihedralsByAtom[i] = arena->getNewArray(byAtomSize[i]+1);
04410 dihedralsByAtom[i][byAtomSize[i]] = -1;
04411 byAtomSize[i] = 0;
04412 }
04413 for (i=0; i<numDihedrals; i++)
04414 {
04415 if ( numFixedAtoms && fixedAtomFlags[dihedrals[i].atom1]
04416 && fixedAtomFlags[dihedrals[i].atom2]
04417 && fixedAtomFlags[dihedrals[i].atom3]
04418 && fixedAtomFlags[dihedrals[i].atom4] ) continue;
04419 if ( pair_self && fepAtomFlags[dihedrals[i].atom1] != 1) continue;
04420 int a1 = dihedrals[i].atom1;
04421 dihedralsByAtom[a1][byAtomSize[a1]++] = i;
04422 }
04423
04424 DebugM(3,"Building crossterm lists.\n");
04425
04426
04427 for (i=0; i<numAtoms; i++)
04428 {
04429 byAtomSize[i] = 0;
04430 }
04431 numCalcCrossterms = 0;
04432 for (i=0; i<numCrossterms; i++)
04433 {
04434 if ( numFixedAtoms && fixedAtomFlags[crossterms[i].atom1]
04435 && fixedAtomFlags[crossterms[i].atom2]
04436 && fixedAtomFlags[crossterms[i].atom3]
04437 && fixedAtomFlags[crossterms[i].atom4]
04438 && fixedAtomFlags[crossterms[i].atom5]
04439 && fixedAtomFlags[crossterms[i].atom6]
04440 && fixedAtomFlags[crossterms[i].atom7]
04441 && fixedAtomFlags[crossterms[i].atom8] ) continue;
04442 if ( pair_self && fepAtomFlags[crossterms[i].atom1] != 1) continue;
04443 byAtomSize[crossterms[i].atom1]++;
04444 numCalcCrossterms++;
04445 }
04446 for (i=0; i<numAtoms; i++)
04447 {
04448 crosstermsByAtom[i] = arena->getNewArray(byAtomSize[i]+1);
04449 crosstermsByAtom[i][byAtomSize[i]] = -1;
04450 byAtomSize[i] = 0;
04451 }
04452 for (i=0; i<numCrossterms; i++)
04453 {
04454 if ( numFixedAtoms && fixedAtomFlags[crossterms[i].atom1]
04455 && fixedAtomFlags[crossterms[i].atom2]
04456 && fixedAtomFlags[crossterms[i].atom3]
04457 && fixedAtomFlags[crossterms[i].atom4]
04458 && fixedAtomFlags[crossterms[i].atom5]
04459 && fixedAtomFlags[crossterms[i].atom6]
04460 && fixedAtomFlags[crossterms[i].atom7]
04461 && fixedAtomFlags[crossterms[i].atom8] ) continue;
04462 if ( pair_self && fepAtomFlags[crossterms[i].atom1] != 1) continue;
04463 int a1 = crossterms[i].atom1;
04464 crosstermsByAtom[a1][byAtomSize[a1]++] = i;
04465 }
04466
04467
04468 DebugM(3,"Initializing lone pair host index array.\n");
04469 lphostIndexes = new int32[numAtoms];
04470 for (i = 0; i < numAtoms; i++) {
04471 lphostIndexes[i] = -1;
04472 }
04473 for (i = 0; i < numLphosts; i++) {
04474 int32 index = lphosts[i].atom1;
04475 lphostIndexes[index] = i;
04476 }
04477
04478
04479 DebugM(3,"Building exclusion data.\n");
04480
04481
04482 build_exclusions();
04483
04484
04485 delete [] bondsWithAtom; bondsWithAtom = 0;
04486 delete tmpArena; tmpArena = 0;
04487
04488 if (exclusions != NULL)
04489 delete [] exclusions;
04490
04491
04492 numTotalExclusions = exclusionSet.size();
04493 exclusions = new Exclusion[numTotalExclusions];
04494 UniqueSetIter<Exclusion> exclIter(exclusionSet);
04495 for ( exclIter=exclIter.begin(),i=0; exclIter != exclIter.end(); exclIter++,i++ )
04496 {
04497 exclusions[i] = *exclIter;
04498 }
04499
04500
04501 exclusionSet.clear();
04502
04503 DebugM(3,"Building exclusion lists.\n");
04504
04505 for (i=0; i<numAtoms; i++)
04506 {
04507 byAtomSize[i] = 0;
04508 }
04509 numCalcExclusions = 0;
04510 for (i=0; i<numTotalExclusions; i++)
04511 {
04512 if ( numFixedAtoms && fixedAtomFlags[exclusions[i].atom1]
04513 && fixedAtomFlags[exclusions[i].atom2] ) continue;
04514 byAtomSize[exclusions[i].atom1]++;
04515 numCalcExclusions++;
04516 }
04517 for (i=0; i<numAtoms; i++)
04518 {
04519 exclusionsByAtom[i] = arena->getNewArray(byAtomSize[i]+1);
04520 exclusionsByAtom[i][byAtomSize[i]] = -1;
04521 byAtomSize[i] = 0;
04522 }
04523 for (i=0; i<numTotalExclusions; i++)
04524 {
04525 if ( numFixedAtoms && fixedAtomFlags[exclusions[i].atom1]
04526 && fixedAtomFlags[exclusions[i].atom2] ) continue;
04527 int a1 = exclusions[i].atom1;
04528 exclusionsByAtom[a1][byAtomSize[a1]++] = i;
04529 }
04530
04531 int32 *byAtomSize2 = new int32[numAtoms];
04532
04533 for (i=0; i<numAtoms; i++)
04534 {
04535 byAtomSize[i] = 0;
04536 byAtomSize2[i] = 0;
04537 }
04538
04539 for (i=0; i<numTotalExclusions; i++)
04540 {
04541 if ( numFixedAtoms && fixedAtomFlags[exclusions[i].atom1]
04542 && fixedAtomFlags[exclusions[i].atom2] ) continue;
04543 if ( exclusions[i].modified ) {
04544 byAtomSize2[exclusions[i].atom1]++;
04545 byAtomSize2[exclusions[i].atom2]++;
04546 } else {
04547 byAtomSize[exclusions[i].atom1]++;
04548 byAtomSize[exclusions[i].atom2]++;
04549 }
04550 }
04551
04552 for (i=0; i<numAtoms; i++)
04553 {
04554 fullExclusionsByAtom[i] = arena->getNewArray(byAtomSize[i]+1);
04555 fullExclusionsByAtom[i][0] = 0;
04556 modExclusionsByAtom[i] = arena->getNewArray(byAtomSize2[i]+1);
04557 modExclusionsByAtom[i][0] = 0;
04558 }
04559
04560 for (i=0; i<numTotalExclusions; i++)
04561 {
04562 int a1 = exclusions[i].atom1;
04563 int a2 = exclusions[i].atom2;
04564 if ( numFixedAtoms && fixedAtomFlags[a1]
04565 && fixedAtomFlags[a2] ) continue;
04566 int32 *l1, *l2;
04567 if ( exclusions[i].modified ) {
04568 l1 = modExclusionsByAtom[a1];
04569 l2 = modExclusionsByAtom[a2];
04570 } else {
04571 l1 = fullExclusionsByAtom[a1];
04572 l2 = fullExclusionsByAtom[a2];
04573 }
04574 l1[++(*l1)] = a2;
04575 l2[++(*l2)] = a1;
04576 }
04577
04578 delete [] byAtomSize; byAtomSize = 0;
04579 delete [] byAtomSize2; byAtomSize2 = 0;
04580
04581
04582
04583 all_exclusions = new ExclusionCheck[numAtoms];
04584
04585 for (i=0; i<numAtoms; i++)
04586 {
04587 all_exclusions[i].min = numAtoms;
04588 all_exclusions[i].max = -1;
04589 }
04590 for (i=0; i<numTotalExclusions; i++)
04591 {
04592
04593 int a1 = exclusions[i].atom1;
04594 int a2 = exclusions[i].atom2;
04595 if ( numFixedAtoms && fixedAtomFlags[a1]
04596 && fixedAtomFlags[a2] ) continue;
04597 if ( all_exclusions[a1].min > a2 ) all_exclusions[a1].min = a2;
04598 if ( all_exclusions[a2].min > a1 ) all_exclusions[a2].min = a1;
04599 if ( a2 > all_exclusions[a1].max ) all_exclusions[a1].max = a2;
04600 if ( a1 > all_exclusions[a2].max ) all_exclusions[a2].max = a1;
04601 }
04602 int exclmem = 0;
04603 int maxExclusionFlags = simParams->maxExclusionFlags;
04604 for (i=0; i<numAtoms; i++)
04605 {
04606 int s = all_exclusions[i].max - all_exclusions[i].min + 1;
04607 if ( all_exclusions[i].max != -1 ) {
04608 if ( s < maxExclusionFlags ) {
04609 char *f = all_exclusions[i].flags = exclArena->getNewArray(s);
04610 for ( int k=0; k<s; ++k ) f[k] = 0;
04611 exclmem += s;
04612 } else {
04613 all_exclusions[i].flags = 0;
04614 }
04615 } else {
04616 all_exclusions[i].flags = (char*)-1;
04617 }
04618 }
04619 if ( 0 ) {
04620 iout << iINFO << numTotalExclusions << " exclusions consume "
04621 << exclmem << " bytes.\n" << endi;
04622 }
04623 for (i=0; i<numTotalExclusions; i++)
04624 {
04625 int a1 = exclusions[i].atom1;
04626 int a2 = exclusions[i].atom2;
04627 if ( numFixedAtoms && fixedAtomFlags[a1]
04628 && fixedAtomFlags[a2] ) continue;
04629 if ( exclusions[i].modified ) {
04630 if ( all_exclusions[a1].flags )
04631 all_exclusions[a1].flags[a2-all_exclusions[a1].min] = EXCHCK_MOD;
04632 if ( all_exclusions[a2].flags )
04633 all_exclusions[a2].flags[a1-all_exclusions[a2].min] = EXCHCK_MOD;
04634 } else {
04635 if ( all_exclusions[a1].flags )
04636 all_exclusions[a1].flags[a2-all_exclusions[a1].min] = EXCHCK_FULL;
04637 if ( all_exclusions[a2].flags )
04638 all_exclusions[a2].flags[a1-all_exclusions[a2].min] = EXCHCK_FULL;
04639 }
04640 }
04641
04642 }
04643 #endif
04644
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665
04666
04667
04668
04669 void Molecule::build_exclusions()
04670 {
04671 #ifdef MEM_OPT_VERSION
04672 numCalcExclusions = numTotalExclusions*2;
04673
04674
04675
04676
04677
04678
04679 ExclusionSettings exclude_flag;
04680 exclude_flag = simParams->exclude;
04681 int stripHGroupExclFlag = (simParams->splitPatch == SPLIT_PATCH_HYDROGEN);
04682 if (!simParams->amberOn || !simParams->readExclusions){
04683 switch (exclude_flag)
04684 {
04685 case NONE:
04686 case ONETWO:
04687 break;
04688 case ONETHREE:
04689 case ONEFOUR:
04690 case SCALED14:
04691 if ( stripHGroupExclFlag ) stripHGroupExcl();
04692 break;
04693 }
04694 }
04695 else if (stripHGroupExclFlag && exclude_flag!=NONE && exclude_flag!=ONETWO)
04696 stripHGroupExcl();
04697
04698 stripFepFixedExcl();
04699 return;
04700 #else
04701 register int i;
04702 ExclusionSettings exclude_flag;
04703
04704 exclude_flag = simParams->exclude;
04705 int stripHGroupExclFlag = (simParams->splitPatch == SPLIT_PATCH_HYDROGEN);
04706
04707
04708 for (i=0; i<numExclusions; i++)
04709 {
04710 exclusionSet.add(exclusions[i]);
04711 }
04712
04713
04714
04715
04716 if (!simParams->amberOn || !simParams->readExclusions)
04717 {
04718 switch (exclude_flag)
04719 {
04720 case NONE:
04721 break;
04722 case ONETWO:
04723 build12excl();
04724 break;
04725 case ONETHREE:
04726 build12excl();
04727 build13excl();
04728 if ( stripHGroupExclFlag ) stripHGroupExcl();
04729 break;
04730 case ONEFOUR:
04731 build12excl();
04732 build13excl();
04733 build14excl(0);
04734 if ( stripHGroupExclFlag ) stripHGroupExcl();
04735 break;
04736 case SCALED14:
04737 build12excl();
04738 build13excl();
04739 build14excl(1);
04740 if ( stripHGroupExclFlag ) stripHGroupExcl();
04741 break;
04742 }
04743 }
04744 else if (stripHGroupExclFlag && exclude_flag!=NONE && exclude_flag!=ONETWO)
04745 stripHGroupExcl();
04746
04747 stripFepExcl();
04748
04749
04750 if (is_drude_psf) build_inherited_excl();
04751 #endif
04752 }
04753
04754
04755
04756
04757
04758 void Molecule::build_inherited_excl(void) {
04759 #ifdef MEM_OPT_VERSION
04760 NAMD_die("Drude and LP particles not supported in memopt version.");
04761 #else
04762 ExclusionSettings exclude_flag = simParams->exclude;
04763 int32 *bond1, *bond2, *bond3;
04764 int32 i, mid1, mid2;
04765
04766 if (exclude_flag == ONEFOUR || exclude_flag == SCALED14) {
04767 NAMD_die("DRUDE MODEL SUPPORTS ONLY UP TO 1-3 EXCLUSION POLICY");
04768 }
04769
04770 if (exclude_flag == NONE) return;
04771
04772
04773
04774 for (i = 0; i < numAtoms; i++) {
04775
04776 if (is_drude(i) || is_lp(i)) {
04777
04778 bond1 = bondsWithAtom[i];
04779
04780 if (-1 == *bond1) {
04781 char err_msg[512];
04782 const char *idescrip = (is_drude(i) ? "DRUDE" : "LONE PAIR");
04783 sprintf(err_msg, "FOUND ISOLATED %s PARTICLE %d", idescrip, i+1);
04784 NAMD_die(err_msg);
04785 }
04786 if (-1 != *(bond1+1)) {
04787 char err_msg[512];
04788 const char *idescrip = (is_drude(i) ? "DRUDE" : "LONE PAIR");
04789 sprintf(err_msg, "FOUND MULTIPLY LINKED %s PARTICLE %d",
04790 idescrip, i+1);
04791 NAMD_die(err_msg);
04792 }
04793
04794
04795 mid1 = bonds[*bond1].atom1;
04796 if (mid1 == i) mid1 = bonds[*bond1].atom2;
04797
04798
04799 if (is_drude(mid1) || is_lp(mid1) || is_hydrogen(mid1)) {
04800 char err_msg[512];
04801 const char *idescrip = (is_drude(i) ? "DRUDE" : "LONE PAIR");
04802 sprintf(err_msg, "PARENT ATOM %d of %s PARTICLE %d "
04803 "IS NOT HEAVY ATOM", mid1+1, idescrip, i+1);
04804 NAMD_die(err_msg);
04805 }
04806
04807
04808 bond2 = bondsWithAtom[mid1];
04809
04810
04811 while (*bond2 != -1) {
04812 if (bonds[*bond2].atom1 == mid1) {
04813 mid2 = bonds[*bond2].atom2;
04814 }
04815 else {
04816 mid2 = bonds[*bond2].atom1;
04817 }
04818
04819
04820
04821 if (mid2 == i) {
04822 bond2++;
04823 continue;
04824 }
04825
04826 if (exclude_flag == ONETWO) {
04827
04828 if (i < mid2) {
04829 exclusionSet.add(Exclusion(i, mid2));
04830 }
04831 else {
04832 exclusionSet.add(Exclusion(mid2, i));
04833 }
04834 }
04835 else {
04836
04837 bond3 = bondsWithAtom[mid2];
04838
04839
04840 while (*bond3 != -1) {
04841
04842 if (bonds[*bond3].atom1 == mid2) {
04843
04844
04845 if (bonds[*bond3].atom2 != mid1) {
04846 if (i < bonds[*bond3].atom2) {
04847 exclusionSet.add(Exclusion(i, bonds[*bond3].atom2));
04848 }
04849 else if (bonds[*bond3].atom2 < i) {
04850 exclusionSet.add(Exclusion(bonds[*bond3].atom2, i));
04851 }
04852 }
04853 }
04854 else {
04855
04856
04857 if (bonds[*bond3].atom1 != mid1) {
04858 if (i < bonds[*bond3].atom1) {
04859 exclusionSet.add(Exclusion(i, bonds[*bond3].atom1));
04860 }
04861 else if (bonds[*bond3].atom1 < i) {
04862 exclusionSet.add(Exclusion(bonds[*bond3].atom1, i));
04863 }
04864 }
04865 }
04866
04867 ++bond3;
04868 }
04869 }
04870
04871 ++bond2;
04872 }
04873
04874 }
04875
04876 }
04877
04878 #endif
04879 }
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889 void Molecule::build12excl(void)
04890
04891 {
04892 #ifndef MEM_OPT_VERSION
04893 int32 *current_val;
04894 register int i;
04895
04896
04897 for (i=0; i<numAtoms; i++)
04898 {
04899 current_val = bondsWithAtom[i];
04900
04901
04902 while (*current_val != -1)
04903 {
04904 if (bonds[*current_val].atom1 == i)
04905 {
04906 if (i<bonds[*current_val].atom2)
04907 {
04908 exclusionSet.add(Exclusion(i,bonds[*current_val].atom2));
04909 }
04910 }
04911 else
04912 {
04913 if (i<bonds[*current_val].atom1)
04914 {
04915 exclusionSet.add(Exclusion(i,bonds[*current_val].atom1));
04916 }
04917 }
04918
04919 ++current_val;
04920 }
04921 }
04922 #endif
04923 }
04924
04925
04926
04927
04928
04929
04930
04931
04932 void Molecule::build13excl(void)
04933
04934 {
04935 #ifndef MEM_OPT_VERSION
04936 int32 *bond1, *bond2;
04937 int middle_atom;
04938 register int i;
04939
04940
04941
04942 for (i=0; i<numAtoms; i++)
04943 {
04944 bond1 = bondsWithAtom[i];
04945
04946
04947 while (*bond1 != -1)
04948 {
04949 if (bonds[*bond1].atom1 == i)
04950 {
04951 middle_atom=bonds[*bond1].atom2;
04952 }
04953 else
04954 {
04955 middle_atom=bonds[*bond1].atom1;
04956 }
04957
04958 bond2 = bondsWithAtom[middle_atom];
04959
04960
04961
04962 while (*bond2 != -1)
04963 {
04964 if (bonds[*bond2].atom1 == middle_atom)
04965 {
04966 if (i < bonds[*bond2].atom2)
04967 {
04968 exclusionSet.add(Exclusion(i,bonds[*bond2].atom2));
04969 }
04970 }
04971 else
04972 {
04973 if (i < bonds[*bond2].atom1)
04974 {
04975 exclusionSet.add(Exclusion(i,bonds[*bond2].atom1));
04976 }
04977 }
04978
04979 ++bond2;
04980 }
04981
04982 ++bond1;
04983 }
04984 }
04985 #endif
04986 }
04987
04988
04989
04990
04991
04992
04993
04994
04995
04996 void Molecule::build14excl(int modified)
04997
04998 {
04999 #ifndef MEM_OPT_VERSION
05000 int32 *bond1, *bond2, *bond3;
05001 int mid1, mid2;
05002 register int i;
05003
05004
05005 for (i=0; i<numAtoms; i++)
05006 {
05007
05008 bond1 = bondsWithAtom[i];
05009
05010 while (*bond1 != -1)
05011 {
05012 if (bonds[*bond1].atom1 == i)
05013 {
05014 mid1=bonds[*bond1].atom2;
05015 }
05016 else
05017 {
05018 mid1=bonds[*bond1].atom1;
05019 }
05020
05021 bond2 = bondsWithAtom[mid1];
05022
05023
05024 while (*bond2 != -1)
05025 {
05026 if (bonds[*bond2].atom1 == mid1)
05027 {
05028 mid2 = bonds[*bond2].atom2;
05029 }
05030 else
05031 {
05032 mid2 = bonds[*bond2].atom1;
05033 }
05034
05035
05036
05037
05038 if (mid2 == i)
05039 {
05040 ++bond2;
05041 continue;
05042 }
05043
05044 bond3=bondsWithAtom[mid2];
05045
05046
05047 while (*bond3 != -1)
05048 {
05049 if (bonds[*bond3].atom1 == mid2)
05050 {
05051
05052
05053
05054
05055 if (bonds[*bond3].atom2 != mid1)
05056 if (i<bonds[*bond3].atom2)
05057 {
05058 exclusionSet.add(Exclusion(i,bonds[*bond3].atom2,modified));
05059 }
05060 }
05061 else
05062 {
05063
05064
05065
05066
05067 if (bonds[*bond3].atom1 != mid1)
05068 if (i<bonds[*bond3].atom1)
05069 {
05070 exclusionSet.add(Exclusion(i,bonds[*bond3].atom1,modified));
05071 }
05072 }
05073
05074 ++bond3;
05075 }
05076
05077 ++bond2;
05078 }
05079
05080 ++bond1;
05081 }
05082 }
05083 #endif
05084 }
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095
05096
05097
05098 void Molecule::stripHGroupExcl(void)
05099 {
05100 #ifdef NAMD_CUDA
05101 return;
05102 #endif
05103
05104 #ifdef MEM_OPT_VERSION
05105
05106
05107
05108 int delExclCnt=0;
05109 UniqueSet<Exclusion> strippedExcls;
05110 HydrogenGroup::iterator h_i, h_e, h_j;
05111 h_i = hydrogenGroup.begin(); h_e = hydrogenGroup.end();
05112 for( ; h_i != h_e; ++h_i ) {
05113 for ( h_j = h_i + 1; h_j != h_e && ! h_j->isGP; ++h_j ) {
05114 if ( h_i->atomID < h_j->atomID )
05115 strippedExcls.add(Exclusion(h_i->atomID,h_j->atomID));
05116 else
05117 strippedExcls.add(Exclusion(h_j->atomID,h_i->atomID));
05118 }
05119 }
05120
05121 UniqueSetIter<Exclusion> iter(strippedExcls);
05122 for(iter=iter.begin(); iter!=iter.end(); iter++){
05123 int atom1 = iter->atom1;
05124 int atom2 = iter->atom2;
05125 ExclusionSignature *a1Sig = &exclSigPool[eachAtomExclSig[atom1]];
05126 int fullOrMod, idx;
05127 idx = a1Sig->findOffset(atom2-atom1, &fullOrMod);
05128 if(idx==-1) continue;
05129 delExclCnt++;
05130 if(!exclStrippedByFepOrFixedAtoms(atom1, atom2))
05131 numCalcExclusions -= 2;
05132 }
05133
05134 numTotalExclusions -= delExclCnt;
05135
05136 return;
05137
05138 #if 0
05139 UniqueSet<Exclusion> strippedExcls;
05140 HydrogenGroup::iterator h_i, h_e, h_j;
05141 h_i = hydrogenGroup.begin(); h_e = hydrogenGroup.end();
05142 for( ; h_i != h_e; ++h_i ) {
05143 for ( h_j = h_i + 1; h_j != h_e && ! h_j->isGP; ++h_j ) {
05144 if ( h_i->atomID < h_j->atomID )
05145 strippedExcls.add(Exclusion(h_i->atomID,h_j->atomID));
05146 else
05147 strippedExcls.add(Exclusion(h_j->atomID,h_i->atomID));
05148 }
05149 }
05150
05151 vector<int> *strippedList = new vector<int>[numAtoms];
05152 UniqueSetIter<Exclusion> iter(strippedExcls);
05153 for(iter=iter.begin(); iter!=iter.end(); iter++){
05154 int atom1 = iter->atom1;
05155 int atom2 = iter->atom2;
05156 strippedList[atom1].push_back(atom2);
05157 strippedList[atom2].push_back(atom1);
05158 }
05159
05160 vector<ExclusionSignature> newExclSigPool;
05161 for(int i=0; i<numAtoms; i++){
05162 ExclusionSignature a1Sig = exclSigPool[eachAtomExclSig[i]];
05163 sort(strippedList[i].begin(), strippedList[i].end());
05164
05165 int fullOrMod = 0;
05166 vector<int> whichOffs;
05167 vector<int> changedOffs;
05168 for(int j=0; j<strippedList[i].size(); j++){
05169 int atom2 = strippedList[i][j];
05170 int offset = atom2-i;
05171
05172
05173
05174 int idx = a1Sig.findOffset(offset, &fullOrMod);
05175 if(idx==-1) continue;
05176
05177 whichOffs.push_back(fullOrMod);
05178 changedOffs.push_back(idx);
05179 }
05180
05181 for(int j=0; j<whichOffs.size(); j++){
05182 if(whichOffs[j]==0){
05183 a1Sig.fullOffset[changedOffs[j]] = 0;
05184 }else{
05185 a1Sig.modOffset[changedOffs[j]] = 0;
05186 }
05187 }
05188 whichOffs.clear();
05189 changedOffs.clear();
05190
05191 if(strippedList[i].size()){
05192
05193 a1Sig.removeEmptyOffset();
05194 int poolIndex = lookupCstPool(newExclSigPool, a1Sig);
05195 if(poolIndex==-1){
05196 poolIndex = newExclSigPool.size();
05197 newExclSigPool.push_back(a1Sig);
05198 }
05199 eachAtomExclSig[i] = poolIndex + exclSigPoolSize;
05200 }
05201 strippedList[i].clear();
05202 }
05203
05204 addNewExclSigPool(newExclSigPool);
05205
05206 newExclSigPool.clear();
05207
05208 delete [] strippedList;
05209 #endif
05210 #else
05211 HydrogenGroup::iterator h_i, h_e, h_j;
05212 h_i = hydrogenGroup.begin(); h_e = hydrogenGroup.end();
05213 for( ; h_i != h_e; ++h_i ) {
05214 for ( h_j = h_i + 1; h_j != h_e && ! h_j->isGP; ++h_j ) {
05215 if ( h_i->atomID < h_j->atomID )
05216 exclusionSet.del(Exclusion(h_i->atomID,h_j->atomID));
05217 else
05218 exclusionSet.del(Exclusion(h_j->atomID,h_i->atomID));
05219 }
05220 }
05221 #endif
05222 }
05223
05224
05225
05226
05227
05228
05229
05230
05231 #ifdef MEM_OPT_VERSION
05232 void Molecule::stripFepFixedExcl(void)
05233 {
05234 int delExclCnt=0;
05235
05236 vector<ExclusionSignature> newExclSigPool;
05237 if(simParams->alchFepOn || simParams->alchThermIntOn || simParams->lesOn){
05238 for(int i=0; i<numAtoms; i++){
05239 int atom1 = i;
05240 int t1 = get_fep_type(atom1);
05241 if(t1==0) continue;
05242 ExclusionSignature a1Sig = exclSigPool[eachAtomExclSig[atom1]];
05243 int sigChanged = 0;
05244 for(int j=0; j<a1Sig.fullExclCnt; j++){
05245 int atom2 = atom1 + a1Sig.fullOffset[j];
05246 int t2 = get_fep_type(atom2);
05247 if(t2 && t1!=t2){
05248 a1Sig.fullOffset[j] = 0;
05249 sigChanged = 1;
05250 delExclCnt++;
05251 }
05252 }
05253 for(int j=0; j<a1Sig.modExclCnt; j++){
05254 int atom2 = atom1 + a1Sig.modOffset[j];
05255 int t2 = get_fep_type(atom2);
05256 if(t2 && t1!=t2){
05257 a1Sig.modOffset[j] = 0;
05258 sigChanged = 1;
05259 delExclCnt++;
05260 }
05261 }
05262
05263
05264 if(sigChanged){
05265 a1Sig.removeEmptyOffset();
05266 int poolIndex = lookupCstPool(newExclSigPool, a1Sig);
05267 if(poolIndex==-1){
05268 poolIndex = newExclSigPool.size();
05269 newExclSigPool.push_back(a1Sig);
05270 }
05271 eachAtomExclSig[atom1] = poolIndex + exclSigPoolSize;
05272 }
05273 }
05274
05275 addNewExclSigPool(newExclSigPool);
05276 newExclSigPool.clear();
05277 }else if(simParams->pairInteractionOn){
05278 for(int i=0; i<numAtoms; i++){
05279 int atom1 = i;
05280 int t1 = get_fep_type(atom1);
05281 ExclusionSignature a1Sig = exclSigPool[eachAtomExclSig[atom1]];
05282 int sigChanged = 0;
05283 for(int j=0; j<a1Sig.fullExclCnt; j++){
05284 int atom2 = atom1 + a1Sig.fullOffset[j];
05285 int t2 = get_fep_type(atom2);
05286
05287 int cond1 = simParams->pairInteractionSelf && (t1!=1 || t2!=1);
05288 int cond2 = (t1!=1 || t2!=2) && (t1!=2 || t2!=1);
05289 if(cond1 || cond2){
05290 a1Sig.fullOffset[j] = 0;
05291 sigChanged = 1;
05292 delExclCnt++;
05293 }
05294 }
05295 for(int j=0; j<a1Sig.modExclCnt; j++){
05296 int atom2 = atom1 + a1Sig.modOffset[j];
05297 int t2 = get_fep_type(atom2);
05298 int cond1 = simParams->pairInteractionSelf && (t1!=1 || t2!=1);
05299 int cond2 = (t1!=1 || t2!=2) && (t1!=2 || t2!=1);
05300 if(cond1 || cond2){
05301 a1Sig.modOffset[j] = 0;
05302 sigChanged = 1;
05303 delExclCnt++;
05304 }
05305 }
05306
05307
05308 if(sigChanged){
05309 a1Sig.removeEmptyOffset();
05310 int poolIndex = lookupCstPool(newExclSigPool, a1Sig);
05311 if(poolIndex==-1){
05312 poolIndex = newExclSigPool.size();
05313 newExclSigPool.push_back(a1Sig);
05314 }
05315 eachAtomExclSig[atom1] = poolIndex + exclSigPoolSize;
05316 }
05317 }
05318
05319 addNewExclSigPool(newExclSigPool);
05320 newExclSigPool.clear();
05321 }
05322
05323 numTotalExclusions -= (delExclCnt/2);
05324
05325
05326
05327
05328 if(!numFixedAtoms){
05329 for(int i=0; i<numAtoms; i++){
05330 ExclusionSignature *a1Sig = &exclSigPool[eachAtomExclSig[i]];
05331
05332 }
05333 }else{
05334 for(int i=0; i<numAtoms; i++){
05335 int atom1 = i;
05336 int t1 = fixedAtomFlags[atom1];
05337 ExclusionSignature a1Sig = exclSigPool[eachAtomExclSig[atom1]];
05338 if(t1==0){
05339
05340 continue;
05341 }
05342 int sigChanged = 0;
05343 for(int j=0; j<a1Sig.fullExclCnt; j++){
05344 int atom2 = atom1 + a1Sig.fullOffset[j];
05345 int t2 = fixedAtomFlags[atom2];
05346 if(t2){
05347 a1Sig.fullOffset[j] = 0;
05348 sigChanged = 1;
05349 delExclCnt++;
05350 }
05351 }
05352 for(int j=0; j<a1Sig.modExclCnt; j++){
05353 int atom2 = atom1 + a1Sig.modOffset[j];
05354 int t2 = fixedAtomFlags[atom2];
05355 if(t2){
05356 a1Sig.modOffset[j] = 0;
05357 sigChanged = 1;
05358 delExclCnt++;
05359 }
05360 }
05361
05362
05363 if(sigChanged){
05364 a1Sig.removeEmptyOffset();
05365 int poolIndex = lookupCstPool(newExclSigPool, a1Sig);
05366 if(poolIndex==-1){
05367 poolIndex = newExclSigPool.size();
05368 newExclSigPool.push_back(a1Sig);
05369 }
05370 eachAtomExclSig[atom1] = poolIndex + exclSigPoolSize;
05371 }
05372
05373 }
05374
05375 addNewExclSigPool(newExclSigPool);
05376 newExclSigPool.clear();
05377 }
05378
05379 numCalcExclusions = (numCalcExclusions - delExclCnt)/2;
05380 }
05381 #else
05382 void Molecule::stripFepExcl(void)
05383 {
05384 UniqueSet<Exclusion> fepExclusionSet;
05385 UniqueSetIter<Exclusion> exclIter(exclusionSet);
05386
05387 if ( simParams->alchFepOn || simParams->alchThermIntOn || simParams->lesOn ) {
05388 for ( exclIter=exclIter.begin(); exclIter != exclIter.end(); exclIter++ )
05389 {
05390 int t1 = get_fep_type(exclIter->atom1);
05391 int t2 = get_fep_type(exclIter->atom2);
05392 if ( t1 && t2 && t1 != t2 ) {
05393 fepExclusionSet.add(*exclIter);
05394 }
05395 }
05396 } else if ( simParams->pairInteractionOn ) {
05397 for ( exclIter=exclIter.begin(); exclIter != exclIter.end(); exclIter++ )
05398 {
05399 int ifep_type = get_fep_type(exclIter->atom1);
05400 int jfep_type = get_fep_type(exclIter->atom2);
05401 if ( simParams->pairInteractionSelf ) {
05402
05403 if (ifep_type != 1 || jfep_type != 1) {
05404 fepExclusionSet.add(*exclIter);
05405 }
05406 } else {
05407
05408
05409 if (!(ifep_type == 1 && jfep_type == 2) &&
05410 !(ifep_type == 2 && jfep_type == 1)) {
05411 fepExclusionSet.add(*exclIter);
05412 }
05413 }
05414 }
05415 }
05416
05417 UniqueSetIter<Exclusion> fepIter(fepExclusionSet);
05418 for ( fepIter=fepIter.begin(); fepIter != fepIter.end(); fepIter++ )
05419 {
05420 exclusionSet.del(*fepIter);
05421 }
05422 }
05423 #endif
05424
05425
05426
05427 #endif // MOLECULE2_C undefined = first object file
05428 #ifdef MOLECULE2_C // second object file
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450 void Molecule::build_gridforce_params(StringList *gridfrcfile,
05451 StringList *gridfrccol,
05452 StringList *gridfrcchrgcol,
05453 StringList *potfile,
05454 PDB *initial_pdb,
05455 char *cwd)
05456 {
05457 PDB *kPDB;
05458 register int i;
05459 register int j;
05460 register int k;
05461
05462 DebugM(3, "Entered build_gridforce_params multi...\n");
05463
05464
05465
05466 MGridforceParams* mgridParams = simParams->mgridforcelist.get_first();
05467 numGridforceGrids = 0;
05468 while (mgridParams != NULL) {
05469 numGridforceGrids++;
05470 mgridParams = mgridParams->next;
05471 }
05472
05473 gridfrcIndexes = new int32*[numGridforceGrids];
05474 gridfrcParams = new GridforceParams*[numGridforceGrids];
05475 gridfrcGrid = new GridforceGrid*[numGridforceGrids];
05476 numGridforces = new int[numGridforceGrids];
05477
05478 mgridParams = simParams->mgridforcelist.get_first();
05479 for (int gridnum = 0; gridnum < numGridforceGrids; gridnum++) {
05480 int current_index=0;
05481 int kcol = 5;
05482 int qcol = 0;
05483 Real kval = 0;
05484 char filename[129];
05485 char potfilename[129];
05486
05487 if (mgridParams == NULL) {
05488 NAMD_die("Problem with mgridParams!");
05489 }
05490
05491
05492 if (mgridParams->gridforceFile == NULL)
05493 {
05494 kPDB = initial_pdb;
05495 }
05496 else
05497 {
05498 DebugM(4, "mgridParams->gridforceFile = " << mgridParams->gridforceFile << "\n" << endi);
05499
05500 if ( (cwd == NULL) || (mgridParams->gridforceFile[0] == '/') )
05501 {
05502 strcpy(filename, mgridParams->gridforceFile);
05503 }
05504 else
05505 {
05506 strcpy(filename, cwd);
05507 strcat(filename, mgridParams->gridforceFile);
05508 }
05509
05510 kPDB = new PDB(filename);
05511 if ( kPDB == NULL )
05512 {
05513 NAMD_die("Memory allocation failed in Molecule::build_gridforce_params");
05514 }
05515
05516 if (kPDB->num_atoms() != numAtoms)
05517 {
05518 NAMD_die("Number of atoms in grid force PDB doesn't match coordinate PDB");
05519 }
05520 }
05521
05522
05523
05524
05525
05526
05527 if (mgridParams->gridforceCol == NULL)
05528 {
05529 kcol = 5;
05530 }
05531 else
05532 {
05533 if (strcasecmp(mgridParams->gridforceCol, "X") == 0)
05534 {
05535 kcol=1;
05536 }
05537 else if (strcasecmp(mgridParams->gridforceCol, "Y") == 0)
05538 {
05539 kcol=2;
05540 }
05541 else if (strcasecmp(mgridParams->gridforceCol, "Z") == 0)
05542 {
05543 kcol=3;
05544 }
05545 else if (strcasecmp(mgridParams->gridforceCol, "O") == 0)
05546 {
05547 kcol=4;
05548 }
05549 else if (strcasecmp(mgridParams->gridforceCol, "B") == 0)
05550 {
05551 kcol=5;
05552 }
05553 else
05554 {
05555 NAMD_die("gridforcecol must have value of X, Y, Z, O, or B");
05556 }
05557 }
05558
05559
05560 if (mgridParams->gridforceQcol == NULL)
05561 {
05562 qcol = 0;
05563 }
05564 else
05565 {
05566 if (strcasecmp(mgridParams->gridforceQcol, "X") == 0)
05567 {
05568 qcol=1;
05569 }
05570 else if (strcasecmp(mgridParams->gridforceQcol, "Y") == 0)
05571 {
05572 qcol=2;
05573 }
05574 else if (strcasecmp(mgridParams->gridforceQcol, "Z") == 0)
05575 {
05576 qcol=3;
05577 }
05578 else if (strcasecmp(mgridParams->gridforceQcol, "O") == 0)
05579 {
05580 qcol=4;
05581 }
05582 else if (strcasecmp(mgridParams->gridforceQcol, "B") == 0)
05583 {
05584 qcol=5;
05585 }
05586 else
05587 {
05588 NAMD_die("gridforcechargecol must have value of X, Y, Z, O, or B");
05589 }
05590 }
05591
05592 if (kcol == qcol) {
05593 NAMD_die("gridforcecol and gridforcechargecol cannot have same value");
05594 }
05595
05596
05597
05598
05599
05600 DebugM(4, "Here!\n" << endi);
05601 gridfrcIndexes[gridnum] = new int32[numAtoms];
05602 DebugM(4, "There!\n" << endi);
05603
05604 if (gridfrcIndexes[gridnum] == NULL)
05605 {
05606 NAMD_die("memory allocation failed in Molecule::build_gridforce_params()");
05607 }
05608
05609
05610 for (i=0; i<numAtoms; i++)
05611 {
05612
05613 switch (kcol)
05614 {
05615 case 1:
05616 kval = (kPDB->atom(i))->xcoor();
05617 break;
05618 case 2:
05619 kval = (kPDB->atom(i))->ycoor();
05620 break;
05621 case 3:
05622 kval = (kPDB->atom(i))->zcoor();
05623 break;
05624 case 4:
05625 kval = (kPDB->atom(i))->occupancy();
05626 break;
05627 case 5:
05628 kval = (kPDB->atom(i))->temperaturefactor();
05629 break;
05630 }
05631
05632 if (kval > 0.0)
05633 {
05634
05635 gridfrcIndexes[gridnum][i] = current_index;
05636 current_index++;
05637 }
05638 else
05639 {
05640
05641 gridfrcIndexes[gridnum][i] = -1;
05642 }
05643 }
05644
05645 if (current_index == 0)
05646 {
05647
05648 iout << iWARN << "NO GRIDFORCE ATOMS WERE FOUND, BUT GRIDFORCE IS ON . . .\n" << endi;
05649 }
05650 else
05651 {
05652
05653 gridfrcParams[gridnum] = new GridforceParams[current_index];
05654 if (gridfrcParams[gridnum] == NULL)
05655 {
05656 NAMD_die("memory allocation failed in Molecule::build_gridforce_params");
05657 }
05658 }
05659
05660 numGridforces[gridnum] = current_index;
05661
05662
05663
05664 for (i=0; i<numAtoms; i++)
05665 {
05666 if (gridfrcIndexes[gridnum][i] != -1)
05667 {
05668
05669 switch (kcol)
05670 {
05671 case 1:
05672 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].k = (kPDB->atom(i))->xcoor();
05673 break;
05674 case 2:
05675 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].k = (kPDB->atom(i))->ycoor();
05676 break;
05677 case 3:
05678 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].k = (kPDB->atom(i))->zcoor();
05679 break;
05680 case 4:
05681 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].k = (kPDB->atom(i))->occupancy();
05682 break;
05683 case 5:
05684 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].k = (kPDB->atom(i))->temperaturefactor();
05685 break;
05686 }
05687
05688
05689 switch (qcol)
05690 {
05691 case 0:
05692 #ifdef MEM_OPT_VERSION
05693 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].q = atomChargePool[eachAtomCharge[i]];
05694 #else
05695 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].q = atoms[i].charge;
05696 #endif
05697 break;
05698 case 1:
05699 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].q = (kPDB->atom(i))->xcoor();
05700 break;
05701 case 2:
05702 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].q = (kPDB->atom(i))->ycoor();
05703 break;
05704 case 3:
05705 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].q = (kPDB->atom(i))->zcoor();
05706 break;
05707 case 4:
05708 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].q = (kPDB->atom(i))->occupancy();
05709 break;
05710 case 5:
05711 gridfrcParams[gridnum][gridfrcIndexes[gridnum][i]].q = (kPDB->atom(i))->temperaturefactor();
05712 break;
05713 }
05714 }
05715 }
05716
05717
05718 if (mgridParams->gridforceFile != NULL)
05719 {
05720 delete kPDB;
05721 }
05722
05723
05724
05725
05726 if ( (cwd == NULL) || (mgridParams->gridforceVfile[0] == '/') )
05727 {
05728 strcpy(potfilename, mgridParams->gridforceVfile);
05729 }
05730 else
05731 {
05732 strcpy(potfilename, cwd);
05733 strcat(potfilename, mgridParams->gridforceVfile);
05734 }
05735
05736
05737
05738
05739 gridfrcGrid[gridnum] = new GridforceGrid(gridnum);
05740
05741 gridfrcGrid[gridnum]->init1(potfilename, simParams, mgridParams);
05742
05743
05744
05745
05746
05747 CProxy_ComputeGridForceNodeMgr
05748 mgr(CkpvAccess(BOCclass_group).computeGridForceNodeMgr);
05749
05750 GridDepositMsg *outmsg = new GridDepositMsg;
05751 outmsg->gridnum = gridnum;
05752 outmsg->grid = gridfrcGrid[gridnum];
05753 outmsg->num_grids = numGridforceGrids;
05754 mgr[CkMyNode()].depositInitialGrid(outmsg);
05755
05756
05757 mgridParams = mgridParams->next;
05758 }
05759 }
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769
05770
05771
05772
05773
05774
05775
05776
05777
05778
05779
05780
05781
05782
05783
05784 void Molecule::build_constraint_params(StringList *consref,
05785 StringList *conskfile,
05786 StringList *conskcol,
05787 PDB *initial_pdb,
05788 char *cwd)
05789
05790 {
05791 PDB *refPDB, *kPDB;
05792 register int i;
05793 int current_index=0;
05794 int kcol = 4;
05795 Real kval = 0;
05796 char filename[129];
05797
05798
05799
05800
05801
05802
05803 if (consref == NULL)
05804 {
05805 refPDB = initial_pdb;
05806 }
05807 else
05808 {
05809 if (consref->next != NULL)
05810 {
05811 NAMD_die("Multiple definitions of constraint reference file in configruation file");
05812 }
05813
05814 if ( (cwd == NULL) || (consref->data[0] == '/') )
05815 {
05816 strcpy(filename, consref->data);
05817 }
05818 else
05819 {
05820 strcpy(filename, cwd);
05821 strcat(filename, consref->data);
05822 }
05823
05824 refPDB = new PDB(filename);
05825 if ( refPDB == NULL )
05826 {
05827 NAMD_die("Memory allocation failed in Molecule::build_constraint_params");
05828 }
05829
05830 if (refPDB->num_atoms() != numAtoms)
05831 {
05832 NAMD_die("Number of atoms in constraint reference PDB doesn't match coordinate PDB");
05833 }
05834 }
05835
05836
05837
05838
05839 if (conskfile == NULL)
05840 {
05841 kPDB = initial_pdb;
05842 }
05843 else
05844 {
05845 if (conskfile->next != NULL)
05846 {
05847 NAMD_die("Multiple definitions of constraint constant file in configuration file");
05848 }
05849
05850 if ( (consref != NULL) && (strcasecmp(consref->data, conskfile->data) == 0) )
05851 {
05852
05853 kPDB = refPDB;
05854 }
05855 else
05856 {
05857 if ( (cwd == NULL) || (conskfile->data[0] == '/') )
05858 {
05859 strcpy(filename, conskfile->data);
05860 }
05861 else
05862 {
05863 strcpy(filename, cwd);
05864 strcat(filename, conskfile->data);
05865 }
05866
05867 kPDB = new PDB(filename);
05868 if ( kPDB == NULL )
05869 {
05870 NAMD_die("Memory allocation failed in Molecule::build_constraint_params");
05871 }
05872
05873 if (kPDB->num_atoms() != numAtoms)
05874 {
05875 NAMD_die("Number of atoms in constraint constant PDB doesn't match coordinate PDB");
05876 }
05877 }
05878 }
05879
05880
05881
05882
05883
05884
05885 if (conskcol == NULL)
05886 {
05887 kcol = 4;
05888 }
05889 else
05890 {
05891 if (conskcol->next != NULL)
05892 {
05893 NAMD_die("Multiple definitions of harmonic constraint column in config file");
05894 }
05895
05896 if (strcasecmp(conskcol->data, "X") == 0)
05897 {
05898 kcol=1;
05899 }
05900 else if (strcasecmp(conskcol->data, "Y") == 0)
05901 {
05902 kcol=2;
05903 }
05904 else if (strcasecmp(conskcol->data, "Z") == 0)
05905 {
05906 kcol=3;
05907 }
05908 else if (strcasecmp(conskcol->data, "O") == 0)
05909 {
05910 kcol=4;
05911 }
05912 else if (strcasecmp(conskcol->data, "B") == 0)
05913 {
05914 kcol=5;
05915 }
05916 else
05917 {
05918 NAMD_die("conskcol must have value of X, Y, Z, O, or B");
05919 }
05920 }
05921
05922
05923
05924
05925 consIndexes = new int32[numAtoms];
05926
05927 if (consIndexes == NULL)
05928 {
05929 NAMD_die("memory allocation failed in Molecule::build_constraint_params()");
05930 }
05931
05932
05933 for (i=0; i<numAtoms; i++)
05934 {
05935
05936 switch (kcol)
05937 {
05938 case 1:
05939 kval = (kPDB->atom(i))->xcoor();
05940 break;
05941 case 2:
05942 kval = (kPDB->atom(i))->ycoor();
05943 break;
05944 case 3:
05945 kval = (kPDB->atom(i))->zcoor();
05946 break;
05947 case 4:
05948 kval = (kPDB->atom(i))->occupancy();
05949 break;
05950 case 5:
05951 kval = (kPDB->atom(i))->temperaturefactor();
05952 break;
05953 }
05954
05955 if (kval > 0.0)
05956 {
05957
05958 consIndexes[i] = current_index;
05959 current_index++;
05960 }
05961 else
05962 {
05963
05964 consIndexes[i] = -1;
05965 }
05966 }
05967
05968 if (current_index == 0)
05969 {
05970
05971 iout << iWARN << "NO CONSTRAINED ATOMS WERE FOUND, BUT CONSTRAINTS ARE ON . . .\n" << endi;
05972 }
05973 else
05974 {
05975
05976 consParams = new ConstraintParams[current_index];
05977
05978 if (consParams == NULL)
05979 {
05980 NAMD_die("memory allocation failed in Molecule::build_constraint_params");
05981 }
05982 }
05983
05984 numConstraints = current_index;
05985
05986
05987
05988 for (i=0; i<numAtoms; i++)
05989 {
05990 if (consIndexes[i] != -1)
05991 {
05992
05993 switch (kcol)
05994 {
05995 case 1:
05996 consParams[consIndexes[i]].k = (kPDB->atom(i))->xcoor();
05997 break;
05998 case 2:
05999 consParams[consIndexes[i]].k = (kPDB->atom(i))->ycoor();
06000 break;
06001 case 3:
06002 consParams[consIndexes[i]].k = (kPDB->atom(i))->zcoor();
06003 break;
06004 case 4:
06005 consParams[consIndexes[i]].k = (kPDB->atom(i))->occupancy();
06006 break;
06007 case 5:
06008 consParams[consIndexes[i]].k = (kPDB->atom(i))->temperaturefactor();
06009 break;
06010 }
06011
06012
06013 consParams[consIndexes[i]].refPos.x = (refPDB->atom(i))->xcoor();
06014 consParams[consIndexes[i]].refPos.y = (refPDB->atom(i))->ycoor();
06015 consParams[consIndexes[i]].refPos.z = (refPDB->atom(i))->zcoor();
06016 }
06017 }
06018
06019
06020 if (consref != NULL)
06021 {
06022 delete refPDB;
06023 }
06024
06025 if ((conskfile != NULL) &&
06026 !((consref != NULL) &&
06027 (strcasecmp(consref->data, conskfile->data) == 0)
06028 )
06029 )
06030 {
06031 delete kPDB;
06032 }
06033
06034 }
06035
06036
06037
06038
06039
06040
06041
06042
06043
06044
06045
06046
06047
06048
06049
06050
06051
06052
06053
06054
06055
06056
06057 void Molecule::build_movdrag_params(StringList *movDragFile,
06058 StringList *movDragCol,
06059 StringList *movDragVelFile,
06060 PDB *initial_pdb,
06061 char *cwd)
06062
06063 {
06064 PDB *tPDB, *vPDB;
06065 register int i;
06066 int current_index=0;
06067 int dtcol = 4;
06068 Real dtval = 0;
06069 char mainfilename[129];
06070 char velfilename[129];
06071
06072
06073
06074
06075 if (movDragFile == NULL) {
06076 tPDB = initial_pdb;
06077
06078 } else {
06079
06080 if (movDragFile->next != NULL) {
06081 NAMD_die("Multiple definitions of moving drag tag file in configuration file");
06082 }
06083
06084 if ( (cwd == NULL) || (movDragFile->data[0] == '/') ) {
06085 strcpy(mainfilename, movDragFile->data);
06086 } else {
06087 strcpy(mainfilename, cwd);
06088 strcat(mainfilename, movDragFile->data);
06089 }
06090
06091 tPDB = new PDB(mainfilename);
06092 if ( tPDB == NULL ) {
06093 NAMD_die("Memory allocation failed in Molecule::build_movdrag_params");
06094 }
06095
06096 if (tPDB->num_atoms() != numAtoms) {
06097 NAMD_die("Number of atoms in moving drag tag PDB doesn't match coordinate PDB");
06098 }
06099 }
06100
06101
06102
06103
06104
06105 if (movDragVelFile == NULL) {
06106 if (movDragFile == NULL) {
06107 NAMD_die("Moving drag velocity file can not be same as coordinate PDB file");
06108 } else {
06109 if (movDragVelFile->next != NULL) {
06110 NAMD_die("Multiple definitions of moving drag velocity file in configuration file");
06111 };
06112 vPDB = tPDB;
06113 };
06114
06115 } else {
06116
06117 if ( (cwd == NULL) || (movDragVelFile->data[0] == '/') ) {
06118 strcpy(velfilename, movDragVelFile->data);
06119 } else {
06120 strcpy(velfilename, cwd);
06121 strcat(velfilename, movDragVelFile->data);
06122 }
06123
06124 vPDB = new PDB(velfilename);
06125 if ( vPDB == NULL ) {
06126 NAMD_die("Memory allocation failed in Molecule::build_movdrag_params");
06127 }
06128
06129 if (vPDB->num_atoms() != numAtoms) {
06130 NAMD_die("Number of atoms in moving drag velocity PDB doesn't match coordinate PDB");
06131 }
06132 };
06133
06134
06135
06136
06137
06138
06139
06140
06141
06142 if (movDragCol == NULL) {
06143 dtcol = 4;
06144 } else {
06145 if (movDragCol->next != NULL) {
06146 NAMD_die("Multiple definitions of drag column in config file");
06147 };
06148
06149 if (movDragFile == NULL
06150 && strcasecmp(movDragCol->data, "B")
06151 && strcasecmp(movDragCol->data, "O")) {
06152 NAMD_die("Can not read moving drag tags from X, Y, or Z column of the coordinate or velocity file");
06153 };
06154 if (!strcasecmp(movDragCol->data, "X")) {
06155 dtcol=1;
06156 } else if (!strcasecmp(movDragCol->data, "Y")) {
06157 dtcol=2;
06158 } else if (!strcasecmp(movDragCol->data, "Z")) {
06159 dtcol=3;
06160 } else if (!strcasecmp(movDragCol->data, "O")) {
06161 dtcol=4;
06162 } else if (!strcasecmp(movDragCol->data, "B")) {
06163 dtcol=5;
06164 }
06165 else {
06166 NAMD_die("movDragCol must have value of X, Y, Z, O, or B");
06167 };
06168 };
06169
06170
06171
06172
06173 movDragIndexes = new int32[numAtoms];
06174 if (movDragIndexes == NULL) {
06175 NAMD_die("memory allocation failed in Molecule::build_movdrag_params()");
06176 };
06177
06178
06179 for (i=0; i<numAtoms; i++) {
06180 switch (dtcol) {
06181 case 1:
06182 dtval = (tPDB->atom(i))->xcoor();
06183 break;
06184 case 2:
06185 dtval = (tPDB->atom(i))->ycoor();
06186 break;
06187 case 3:
06188 dtval = (tPDB->atom(i))->zcoor();
06189 break;
06190 case 4:
06191 dtval = (tPDB->atom(i))->occupancy();
06192 break;
06193 case 5:
06194 dtval = (tPDB->atom(i))->temperaturefactor();
06195 break;
06196 }
06197
06198 if (dtval != 0.0) {
06199
06200 movDragIndexes[i] = current_index;
06201 current_index++;
06202 } else {
06203
06204 movDragIndexes[i] = -1;
06205 }
06206 }
06207
06208 if (current_index == 0) {
06209
06210 iout << iWARN << "NO DRAGGED ATOMS WERE FOUND, BUT MOVING DRAG IS ON . . . " << endi;
06211 } else {
06212
06213 movDragParams = new MovDragParams[current_index];
06214 if (movDragParams == NULL) {
06215 NAMD_die("memory allocation failed in Molecule::build_movdrag_params");
06216 }
06217 };
06218
06219 numMovDrag = current_index;
06220
06221
06222
06223 for (i=0; i<numAtoms; i++) {
06224 if (movDragIndexes[i] != -1) {
06225 movDragParams[movDragIndexes[i]].v[0] = (vPDB->atom(i))->xcoor();
06226 movDragParams[movDragIndexes[i]].v[1] = (vPDB->atom(i))->ycoor();
06227 movDragParams[movDragIndexes[i]].v[2] = (vPDB->atom(i))->zcoor();
06228 };
06229 };
06230
06231 if (movDragFile != NULL) delete tPDB;
06232 if (movDragVelFile != NULL) delete vPDB;
06233 }
06234
06235
06236
06237
06238
06239
06240
06241
06242
06243
06244
06245
06246
06247
06248
06249
06250
06251
06252
06253
06254
06255
06256
06257
06258
06259 void Molecule::build_rotdrag_params(StringList *rotDragFile,
06260 StringList *rotDragCol,
06261 StringList *rotDragAxisFile,
06262 StringList *rotDragPivotFile,
06263 StringList *rotDragVelFile,
06264 StringList *rotDragVelCol,
06265 PDB *initial_pdb,
06266 char *cwd)
06267
06268 {
06269 PDB *tPDB, *aPDB, *pPDB, *vPDB;
06270 register int i;
06271 int current_index=0;
06272 int dtcol = 4;
06273 Real dtval = 0;
06274 int dvcol = 4;
06275 Real dvval = 0;
06276 char mainfilename[129];
06277 char axisfilename[129];
06278 char pivotfilename[129];
06279 char velfilename[129];
06280
06281
06282
06283
06284 if (rotDragFile == NULL) {
06285 tPDB = initial_pdb;
06286
06287 } else {
06288
06289 if (rotDragFile->next != NULL) {
06290 NAMD_die("Multiple definitions of rotating drag tag file in configuration file");
06291 }
06292
06293 if ( (cwd == NULL) || (rotDragFile->data[0] == '/') ) {
06294 strcpy(mainfilename, rotDragFile->data);
06295 } else {
06296 strcpy(mainfilename, cwd);
06297 strcat(mainfilename, rotDragFile->data);
06298 }
06299
06300 tPDB = new PDB(mainfilename);
06301 if ( tPDB == NULL ) {
06302 NAMD_die("Memory allocation failed in Molecule::build_rotdrag_params");
06303 }
06304
06305 if (tPDB->num_atoms() != numAtoms) {
06306 NAMD_die("Number of atoms in rotating drag tag PDB doesn't match coordinate PDB");
06307 }
06308 }
06309
06310
06311
06312
06313
06314 if (rotDragAxisFile == NULL) {
06315 if (rotDragFile == NULL) {
06316 NAMD_die("Rotating drag axis file can not be same as coordinate PDB file");
06317 } else {
06318 if (rotDragAxisFile->next != NULL) {
06319 NAMD_die("Multiple definitions of rotating drag axis file in configuration file");
06320 };
06321 if (rotDragPivotFile == NULL) {
06322 NAMD_die("Need to specify at least one of rotDragAxisFile and rotDragPivotFile; they can not be same");
06323 };
06324 aPDB = tPDB;
06325 };
06326
06327 } else {
06328
06329 if ( (cwd == NULL) || (rotDragAxisFile->data[0] == '/') ) {
06330 strcpy(axisfilename, rotDragAxisFile->data);
06331 } else {
06332 strcpy(axisfilename, cwd);
06333 strcat(axisfilename, rotDragAxisFile->data);
06334 }
06335
06336 aPDB = new PDB(axisfilename);
06337 if ( aPDB == NULL ) {
06338 NAMD_die("Memory allocation failed in Molecule::build_rotdrag_params");
06339 }
06340
06341 if (aPDB->num_atoms() != numAtoms) {
06342 NAMD_die("Number of atoms in rotating drag axis PDB doesn't match coordinate PDB");
06343 }
06344 };
06345
06346
06347
06348
06349
06350 if (rotDragPivotFile == NULL) {
06351 if (rotDragFile == NULL) {
06352 NAMD_die("Rotating drag pivot point file can not be same as coordinate PDB file");
06353 } else {
06354 if (rotDragPivotFile->next != NULL) {
06355 NAMD_die("Multiple definitions of rotating drag pivot point file in configuration file");
06356 };
06357 if (rotDragAxisFile == NULL) {
06358 NAMD_die("Need to specify at least one of rotDragAxisFile and rotDragPivotFile; they can not be same");
06359 };
06360 pPDB = tPDB;
06361 };
06362
06363 } else {
06364
06365 if ( (cwd == NULL) || (rotDragPivotFile->data[0] == '/') ) {
06366 strcpy(pivotfilename, rotDragPivotFile->data);
06367 } else {
06368 strcpy(pivotfilename, cwd);
06369 strcat(pivotfilename, rotDragPivotFile->data);
06370 }
06371
06372 pPDB = new PDB(pivotfilename);
06373 if ( pPDB == NULL ) {
06374 NAMD_die("Memory allocation failed in Molecule::build_rotdrag_params");
06375 }
06376
06377 if (pPDB->num_atoms() != numAtoms) {
06378 NAMD_die("Number of atoms in rotating drag pivot point PDB doesn't match coordinate PDB");
06379 }
06380 };
06381
06382
06383
06384
06385
06386
06387 if (rotDragVelFile == NULL) {
06388 vPDB = tPDB;
06389 } else {
06390 if (rotDragVelFile->next != NULL) {
06391 NAMD_die("Multiple definitions of rotating drag velocity file in configuration file");
06392 };
06393
06394 if ( (cwd == NULL) || (rotDragVelFile->data[0] == '/') ) {
06395 strcpy(velfilename, rotDragVelFile->data);
06396 } else {
06397 strcpy(velfilename, cwd);
06398 strcat(velfilename, rotDragVelFile->data);
06399 }
06400
06401 vPDB = new PDB(velfilename);
06402 if ( vPDB == NULL ) {
06403 NAMD_die("Memory allocation failed in Molecule::build_rotdrag_params");
06404 }
06405
06406 if (vPDB->num_atoms() != numAtoms) {
06407 NAMD_die("Number of atoms in rotating drag velocity PDB doesn't match coordinate PDB");
06408 }
06409 };
06410
06411
06412
06413
06414
06415
06416
06417
06418 if (rotDragCol == NULL) {
06419 dtcol = 4;
06420 } else {
06421 if (rotDragCol->next != NULL) {
06422 NAMD_die("Multiple definitions of drag tag column in config file");
06423 };
06424
06425 if ( rotDragFile == NULL
06426 && (!strcasecmp(rotDragCol->data, "X")
06427 || !strcasecmp(rotDragCol->data, "Y")
06428 || !strcasecmp(rotDragCol->data, "Z"))) {
06429 NAMD_die("Can not read rotating drag tags from X, Y, or Z column of the PDB coordinate file");
06430 };
06431 if (!strcasecmp(rotDragCol->data, "X")) {
06432 dtcol=1;
06433 } else if (!strcasecmp(rotDragCol->data, "Y")) {
06434 dtcol=2;
06435 } else if (!strcasecmp(rotDragCol->data, "Z")) {
06436 dtcol=3;
06437 } else if (!strcasecmp(rotDragCol->data, "O")) {
06438 dtcol=4;
06439 } else if (!strcasecmp(rotDragCol->data, "B")) {
06440 dtcol=5;
06441 }
06442 else {
06443 NAMD_die("rotDragCol must have value of X, Y, Z, O, or B");
06444 };
06445 };
06446
06447
06448
06449
06450
06451
06452
06453
06454
06455 if (rotDragVelCol == NULL) {
06456 dvcol = 4;
06457 } else {
06458 if (rotDragVelCol->next != NULL) {
06459 NAMD_die("Multiple definitions of drag angular velocity column in config file");
06460 };
06461
06462 if (rotDragVelFile == NULL
06463 && rotDragFile == NULL
06464 && strcasecmp(rotDragCol->data, "B")
06465 && strcasecmp(rotDragCol->data, "O")) {
06466 NAMD_die("Can not read rotating drag angular velocities from X, Y, or Z column of the PDB coordinate file");
06467 };
06468 if (!strcasecmp(rotDragVelCol->data, "X")) {
06469 dvcol=1;
06470 } else if (!strcasecmp(rotDragVelCol->data, "Y")) {
06471 dvcol=2;
06472 } else if (!strcasecmp(rotDragVelCol->data, "Z")) {
06473 dvcol=3;
06474 } else if (!strcasecmp(rotDragVelCol->data, "O")) {
06475 dvcol=4;
06476 } else if (!strcasecmp(rotDragVelCol->data, "B")) {
06477 dvcol=5;
06478 }
06479 else {
06480 NAMD_die("rotDragVelCol must have value of X, Y, Z, O, or B");
06481 };
06482 };
06483
06484
06485
06486
06487 rotDragIndexes = new int32[numAtoms];
06488 if (rotDragIndexes == NULL) {
06489 NAMD_die("memory allocation failed in Molecule::build_rotdrag_params()");
06490 };
06491
06492
06493 for (i=0; i<numAtoms; i++) {
06494 switch (dtcol) {
06495 case 1:
06496 dtval = (tPDB->atom(i))->xcoor();
06497 break;
06498 case 2:
06499 dtval = (tPDB->atom(i))->ycoor();
06500 break;
06501 case 3:
06502 dtval = (tPDB->atom(i))->zcoor();
06503 break;
06504 case 4:
06505 dtval = (tPDB->atom(i))->occupancy();
06506 break;
06507 case 5:
06508 dtval = (tPDB->atom(i))->temperaturefactor();
06509 break;
06510 }
06511
06512 if (dtval != 0.0) {
06513
06514 rotDragIndexes[i] = current_index;
06515 current_index++;
06516 } else {
06517
06518 rotDragIndexes[i] = -1;
06519 }
06520 }
06521
06522 if (current_index == 0) {
06523 iout << iWARN << "NO DRAGGED ATOMS WERE FOUND, BUT ROTATING DRAG IS ON . . . " << endi;
06524 } else {
06525 rotDragParams = new RotDragParams[current_index];
06526 if (rotDragParams == NULL) {
06527 NAMD_die("memory allocation failed in Molecule::build_rotdrag_params");
06528 }
06529 };
06530
06531 numRotDrag = current_index;
06532
06533
06534
06535 for (i=0; i<numAtoms; i++) {
06536 if (rotDragIndexes[i] != -1) {
06537 rotDragParams[rotDragIndexes[i]].a[0] = (aPDB->atom(i))->xcoor();
06538 rotDragParams[rotDragIndexes[i]].a[1] = (aPDB->atom(i))->ycoor();
06539 rotDragParams[rotDragIndexes[i]].a[2] = (aPDB->atom(i))->zcoor();
06540 rotDragParams[rotDragIndexes[i]].p[0] = (pPDB->atom(i))->xcoor();
06541 rotDragParams[rotDragIndexes[i]].p[1] = (pPDB->atom(i))->ycoor();
06542 rotDragParams[rotDragIndexes[i]].p[2] = (pPDB->atom(i))->zcoor();
06543 switch (dvcol) {
06544 case 1:
06545 rotDragParams[rotDragIndexes[i]].v = (vPDB->atom(i))->xcoor();
06546 break;
06547 case 2:
06548 rotDragParams[rotDragIndexes[i]].v = (vPDB->atom(i))->ycoor();
06549 break;
06550 case 3:
06551 rotDragParams[rotDragIndexes[i]].v = (vPDB->atom(i))->zcoor();
06552 break;
06553 case 4:
06554 rotDragParams[rotDragIndexes[i]].v = (vPDB->atom(i))->occupancy();
06555 break;
06556 case 5:
06557 rotDragParams[rotDragIndexes[i]].v = (vPDB->atom(i))->temperaturefactor();
06558 break;
06559 };
06560 };
06561 };
06562
06563 if (rotDragFile != NULL) delete tPDB;
06564 if (rotDragAxisFile != NULL) delete aPDB;
06565 if (rotDragPivotFile != NULL) delete pPDB;
06566 if (rotDragVelFile != NULL) delete vPDB;
06567 }
06568
06569
06570
06571
06572
06573
06574
06575
06576
06577
06578
06579
06580
06581
06582
06583
06584
06585
06586
06587
06588
06589
06590
06591
06592
06593 void Molecule::build_constorque_params(StringList *consTorqueFile,
06594 StringList *consTorqueCol,
06595 StringList *consTorqueAxisFile,
06596 StringList *consTorquePivotFile,
06597 StringList *consTorqueValFile,
06598 StringList *consTorqueValCol,
06599 PDB *initial_pdb,
06600 char *cwd)
06601
06602 {
06603 PDB *tPDB, *aPDB, *pPDB, *vPDB;
06604 register int i;
06605 int current_index=0;
06606 int dtcol = 4;
06607 Real dtval = 0;
06608 int dvcol = 4;
06609 Real dvval = 0;
06610 char mainfilename[129];
06611 char axisfilename[129];
06612 char pivotfilename[129];
06613 char velfilename[129];
06614
06615
06616
06617
06618 if (consTorqueFile == NULL) {
06619 tPDB = initial_pdb;
06620
06621 } else {
06622
06623 if (consTorqueFile->next != NULL) {
06624 NAMD_die("Multiple definitions of \"constant\" torque tag file in configuration file");
06625 }
06626
06627 if ( (cwd == NULL) || (consTorqueFile->data[0] == '/') ) {
06628 strcpy(mainfilename, consTorqueFile->data);
06629 } else {
06630 strcpy(mainfilename, cwd);
06631 strcat(mainfilename, consTorqueFile->data);
06632 }
06633
06634 tPDB = new PDB(mainfilename);
06635 if ( tPDB == NULL ) {
06636 NAMD_die("Memory allocation failed in Molecule::build_constorque_params");
06637 }
06638
06639 if (tPDB->num_atoms() != numAtoms) {
06640 NAMD_die("Number of atoms in \"constant\" torque tag PDB doesn't match coordinate PDB");
06641 }
06642 }
06643
06644
06645
06646
06647
06648 if (consTorqueAxisFile == NULL) {
06649 if (consTorqueFile == NULL) {
06650 NAMD_die("\"Constant\" torque axis file can not be same as coordinate PDB file");
06651 } else {
06652 if (consTorqueAxisFile->next != NULL) {
06653 NAMD_die("Multiple definitions of \"constant\" torque axis file in configuration file");
06654 };
06655 if (consTorquePivotFile == NULL) {
06656 NAMD_die("Need to specify at least one of consTorqueAxisFile and consTorquePivotFile; they can not be same");
06657 };
06658 aPDB = tPDB;
06659 };
06660
06661 } else {
06662
06663 if ( (cwd == NULL) || (consTorqueAxisFile->data[0] == '/') ) {
06664 strcpy(axisfilename, consTorqueAxisFile->data);
06665 } else {
06666 strcpy(axisfilename, cwd);
06667 strcat(axisfilename, consTorqueAxisFile->data);
06668 }
06669
06670 aPDB = new PDB(axisfilename);
06671 if ( aPDB == NULL ) {
06672 NAMD_die("Memory allocation failed in Molecule::build_constorque_params");
06673 }
06674
06675 if (aPDB->num_atoms() != numAtoms) {
06676 NAMD_die("Number of atoms in \"constant\" torque axis PDB doesn't match coordinate PDB");
06677 }
06678 };
06679
06680
06681
06682
06683
06684 if (consTorquePivotFile == NULL) {
06685 if (consTorqueFile == NULL) {
06686 NAMD_die("\"Constant\" torque pivot point file can not be same as coordinate PDB file");
06687 } else {
06688