void Action_Closest::Action_ImageOrtho(Frame& frmIn, double maxD) { double Dist; int solventMol; AtomMask::const_iterator solute_atom; Iarray::const_iterator solvent_atom; // Loop over all solvent molecules in original frame if (useMaskCenter_) { Vec3 maskCenter = frmIn.VGeometricCenter( distanceMask_ ); for (solventMol=0; solventMol < NsolventMolecules_; solventMol++) { SolventMols_[solventMol].D = maxD; for (solvent_atom = SolventMols_[solventMol].solventAtoms.begin(); solvent_atom != SolventMols_[solventMol].solventAtoms.end(); ++solvent_atom) { Dist = DIST2_ImageOrtho( maskCenter.Dptr(), frmIn.XYZ(*solvent_atom),frmIn.BoxCrd()); if (Dist < SolventMols_[solventMol].D) SolventMols_[solventMol].D = Dist; } } } else { for (solventMol=0; solventMol < NsolventMolecules_; solventMol++) { if (debug_ > 1) mprintf("DEBUG: Calculating distance for molecule %i\n", solventMol); // Set the initial minimum distance for this solvent mol to be the // max possible distance. SolventMols_[solventMol].D = maxD; // Calculate distance between each atom in distanceMask and atoms in solvent Mask for (solvent_atom = SolventMols_[solventMol].solventAtoms.begin(); solvent_atom != SolventMols_[solventMol].solventAtoms.end(); ++solvent_atom) { for (solute_atom = distanceMask_.begin(); solute_atom != distanceMask_.end(); ++solute_atom) { Dist = DIST2_ImageOrtho(frmIn.XYZ(*solute_atom), frmIn.XYZ(*solvent_atom), frmIn.BoxCrd()); if (Dist < SolventMols_[solventMol].D) SolventMols_[solventMol].D = Dist; if (debug_ > 2) mprintf("DEBUG: SolvMol %i, soluteAtom %i, solventAtom %i, D= %f, minD= %f\n", solventMol, *solute_atom, *solvent_atom, Dist, sqrt(SolventMols_[solventMol].D)); } } if (debug_ > 1) mprintf("DEBUG:\tMol %8i minD= %lf\n",solventMol, SolventMols_[solventMol].D); } // END for loop over solventMol } }
// Action_NMRrst::DoAction() Action::RetType Action_NMRrst::DoAction(int frameNum, ActionFrame& frm) { double Dist; Vec3 a1, a2; if (Image_.ImageType() == NONORTHO) frm.Frm().BoxCrd().ToRecip(ucell_, recip_); // NOEs from file. for (noeDataArray::iterator noe = NOEs_.begin(); noe != NOEs_.end(); ++noe) { if ( noe->active_ ) { if (useMass_) { a1 = frm.Frm().VCenterOfMass( noe->dMask1_ ); a2 = frm.Frm().VCenterOfMass( noe->dMask2_ ); } else { a1 = frm.Frm().VGeometricCenter( noe->dMask1_ ); a2 = frm.Frm().VGeometricCenter( noe->dMask2_ ); } switch ( Image_.ImageType() ) { case NONORTHO: Dist = DIST2_ImageNonOrtho(a1, a2, ucell_, recip_); break; case ORTHO: Dist = DIST2_ImageOrtho(a1, a2, frm.Frm().BoxCrd()); break; case NOIMAGE: Dist = DIST2_NoImage(a1, a2); break; } Dist = sqrt(Dist); noe->dist_->Add(frameNum, &Dist); } } // Find NOEs ProcessNoeArray( noeArray_, frm.Frm(), frameNum ); // Specified NOEs ProcessNoeArray( specifiedNOEs_, frm.Frm(), frameNum ); ++nframes_; return Action::OK; }
// Action_Distance::DoAction() Action::RetType Action_Distance::DoAction(int frameNum, ActionFrame& frm) { double Dist; Matrix_3x3 ucell, recip; Vec3 a1, a2; if (useMass_) { a1 = frm.Frm().VCenterOfMass( Mask1_ ); a2 = frm.Frm().VCenterOfMass( Mask2_ ); } else { a1 = frm.Frm().VGeometricCenter( Mask1_ ); a2 = frm.Frm().VGeometricCenter( Mask2_ ); } switch ( image_.ImageType() ) { case NONORTHO: frm.Frm().BoxCrd().ToRecip(ucell, recip); Dist = DIST2_ImageNonOrtho(a1, a2, ucell, recip); break; case ORTHO: Dist = DIST2_ImageOrtho(a1, a2, frm.Frm().BoxCrd()); break; case NOIMAGE: Dist = DIST2_NoImage(a1, a2); break; } Dist = sqrt(Dist); dist_->Add(frameNum, &Dist); return Action::OK; }
// Action_Distance::action() Action::RetType Action_Distance::DoAction(int frameNum, Frame* currentFrame, Frame** frameAddress) { double Dist; Matrix_3x3 ucell, recip; Vec3 a1, a2; if (useMass_) { a1 = currentFrame->VCenterOfMass( Mask1_ ); a2 = currentFrame->VCenterOfMass( Mask2_ ); } else { a1 = currentFrame->VGeometricCenter( Mask1_ ); a2 = currentFrame->VGeometricCenter( Mask2_ ); } switch ( ImageType() ) { case NONORTHO: currentFrame->BoxCrd().ToRecip(ucell, recip); Dist = DIST2_ImageNonOrtho(a1, a2, ucell, recip); break; case ORTHO: Dist = DIST2_ImageOrtho(a1, a2, currentFrame->BoxCrd()); break; case NOIMAGE: Dist = DIST2_NoImage(a1, a2); break; } Dist = sqrt(Dist); dist_->Add(frameNum, &Dist); //fprintf(outfile,"%10i %10.4lf\n",frameNum,D); return Action::OK; }
double DIST2(const double* a1, const double* a2, ImagingType itype, Box const& box, Matrix_3x3 const& ucell, Matrix_3x3 const& recip) { if (itype==NOIMAGE) return DIST2_NoImage( a1, a2 ); else if (itype==ORTHO) return DIST2_ImageOrtho( a1, a2, box ); else // NONORTHO return DIST2_ImageNonOrtho( a1, a2, ucell, recip ); }
double Action_LIE::Calculate_LJ(Frame const& frameIn, Topology const& parmIn) const { double result = 0; // Loop over ligand atoms AtomMask::const_iterator mask1_end = Mask1_.end(); AtomMask::const_iterator mask2_end = Mask2_.end(); for (AtomMask::const_iterator maskatom1 = Mask1_.begin(); maskatom1 != mask1_end; maskatom1++) { int crdidx1 = (*maskatom1) * 3; // index into coordinate array Vec3 atm1 = Vec3(frameIn.CRD(crdidx1)); for (AtomMask::const_iterator maskatom2 = Mask2_.begin(); maskatom2 != mask2_end; maskatom2++) { int crdidx2 = (*maskatom2) * 3; // index into coordinate array Vec3 atm2 = Vec3(frameIn.CRD(crdidx2)); double dist2; // Get imaged distance Matrix_3x3 ucell, recip; switch( ImageType() ) { case NONORTHO: frameIn.BoxCrd().ToRecip(ucell, recip); dist2 = DIST2_ImageNonOrtho(atm1, atm2, ucell, recip); break; case ORTHO: dist2 = DIST2_ImageOrtho(atm1, atm2, frameIn.BoxCrd()); break; default: dist2 = DIST2_NoImage(atm1, atm2); } if (dist2 > cut2vdw_) continue; // Here we add to our nonbonded (VDW) energy NonbondType const& LJ = parmIn.GetLJparam(*maskatom1, *maskatom2); double r2 = 1 / dist2; double r6 = r2 * r2 * r2; result += LJ.A() * r6 * r6 - LJ.B() * r6; } } return result; }
double Action_LIE::Calculate_Elec(Frame const& frameIn) const { double result = 0; // Loop over ligand atoms AtomMask::const_iterator mask1_end = Mask1_.end(); AtomMask::const_iterator mask2_end = Mask2_.end(); for (AtomMask::const_iterator maskatom1 = Mask1_.begin(); maskatom1 != mask1_end; maskatom1++) { int crdidx1 = (*maskatom1) * 3; // index into coordinate array Vec3 atm1 = Vec3(frameIn.CRD(crdidx1)); for (AtomMask::const_iterator maskatom2 = Mask2_.begin(); maskatom2 != mask2_end; maskatom2++) { int crdidx2 = (*maskatom2) * 3; // index into coordinate array Vec3 atm2 = Vec3(frameIn.CRD(crdidx2)); double dist2; // Get imaged distance Matrix_3x3 ucell, recip; switch( ImageType() ) { case NONORTHO: frameIn.BoxCrd().ToRecip(ucell, recip); dist2 = DIST2_ImageNonOrtho(atm1, atm2, ucell, recip); break; case ORTHO: dist2 = DIST2_ImageOrtho(atm1, atm2, frameIn.BoxCrd()); break; default: dist2 = DIST2_NoImage(atm1, atm2); } if (dist2 > cut2elec_) continue; // Here we add to our electrostatic energy double qiqj = atom_charge_[*maskatom1] * atom_charge_[*maskatom2]; double shift = (1 - dist2 * onecut2_); result += qiqj / sqrt(dist2) * shift * shift; } } return result; }
double Action_Spam::Calculate_Energy(Frame *frameIn, Residue const& res) { // The first atom of the solvent residue we want the energy from double result = 0; /* Now loop through all atoms in the residue and loop through the pairlist to * get the energies */ for (int i = res.FirstAtom(); i < res.LastAtom(); i++) { Vec3 atm1 = Vec3(frameIn->XYZ(i)); for (int j = 0; j < CurrentParm_.Natom(); j++) { if (j >= res.FirstAtom() && j < res.LastAtom()) continue; Vec3 atm2 = Vec3(frameIn->XYZ(j)); double dist2; // Get imaged distance Matrix_3x3 ucell, recip; switch( ImageType() ) { case NONORTHO: frameIn->BoxCrd().ToRecip(ucell, recip); dist2 = DIST2_ImageNonOrtho(atm1, atm2, ucell, recip); break; case ORTHO: dist2 = DIST2_ImageOrtho(atm1, atm2, frameIn->BoxCrd()); break; default: dist2 = DIST2_NoImage(atm1, atm2); } if (dist2 < cut2_) { double qiqj = atom_charge_[i] * atom_charge_[j]; NonbondType const& LJ = CurrentParm_.GetLJparam(i, j); double r2 = 1 / dist2; double r6 = r2 * r2 * r2; // Shifted electrostatics: qiqj/r * (1-r/rcut)^2 + VDW double shift = (1 - dist2 * onecut2_); result += qiqj / sqrt(dist2) * shift * shift + LJ.A() * r6 * r6 - LJ.B() * r6; } } } return result; }
// Action_Watershell::DoAction() Action::RetType Action_Watershell::DoAction(int frameNum, ActionFrame& frm) { int nlower = 0; int nupper = 0; # ifdef CUDA // Copy solvent atom coords to array unsigned int idx = 0; // Index into V_atom_coords_ for (AtomMask::const_iterator atm = solventMask_.begin(); atm != solventMask_.end(); ++atm, idx += 3) { const double* xyz = frm.Frm().XYZ( *atm ); V_atom_coords_[idx ] = xyz[0]; V_atom_coords_[idx+1] = xyz[1]; V_atom_coords_[idx+2] = xyz[2]; } Matrix_3x3 ucell, recip; if (image_.ImageType() == NONORTHO) frm.Frm().BoxCrd().ToRecip(ucell, recip); // Copy solute atom coords to array idx = 0; for (AtomMask::const_iterator atm = soluteMask_.begin(); atm != soluteMask_.end(); ++atm, idx += 3) { const double* XYZ = frm.Frm().XYZ( *atm ); soluteCoords_[idx ] = XYZ[0]; soluteCoords_[idx+1] = XYZ[1]; soluteCoords_[idx+2] = XYZ[2]; } Action_Closest_NoCenter( &V_atom_coords_[0], &V_distances_[0], &soluteCoords_[0], 9999999999999.0, NsolventMolecules_, NAtoms_, soluteMask_.Nselected(), image_.ImageType(), frm.Frm().BoxCrd().boxPtr(), ucell.Dptr(), recip.Dptr() ); // V_distances_ now has the closest distance of each solvent molecule to // solute. Determine shell status of each. for (Darray::const_iterator dist2 = V_distances_.begin(); dist2 != V_distances_.end(); ++dist2) if (*dist2 < upperCutoff_) { ++nupper; // Less than lower, 1st shell if (*dist2 < lowerCutoff_) ++nlower; } # else // --------------------------------------------------------------------------- int NV = solventMask_.Nselected(); int Vidx; # ifdef _OPENMP int mythread; # endif int* status = 0; if (image_.ImageType() == NONORTHO) { // ----- NON-ORTHORHOMBIC IMAGING ------------ Matrix_3x3 ucell, recip; frm.Frm().BoxCrd().ToRecip(ucell, recip); // Wrap all solute atoms back into primary cell, save coords. Image::WrapToCell0( soluteCoords_, frm.Frm(), soluteMask_, ucell, recip ); // Calculate every imaged distance of all solvent atoms to solute # ifdef _OPENMP # pragma omp parallel private(Vidx, mythread, status) { mythread = omp_get_thread_num(); status = &(shellStatus_thread_[mythread][0]); # pragma omp for # else status = &shellStatus_[0]; # endif for (Vidx = 0; Vidx < NV; Vidx++) { int Vat = solventMask_[Vidx]; int currentRes = (*CurrentParm_)[ Vat ].ResNum(); // Convert to frac coords Vec3 vFrac = recip * Vec3( frm.Frm().XYZ( Vat ) ); // Wrap to primary unit cell vFrac[0] = vFrac[0] - floor(vFrac[0]); vFrac[1] = vFrac[1] - floor(vFrac[1]); vFrac[2] = vFrac[2] - floor(vFrac[2]); // Loop over all images of this solvent atom for (int ix = -1; ix != 2; ix++) for (int iy = -1; iy != 2; iy++) for (int iz = -1; iz != 2; iz++) { // Convert image back to Cartesian Vec3 vCart = ucell.TransposeMult( vFrac + Vec3(ix, iy, iz) ); // Loop over all solute atoms for (unsigned int idx = 0; idx < soluteCoords_.size(); idx += 3) { if (status[currentRes] < 2) { // Residue is not yet marked as 1st shell, calc distance double x = vCart[0] - soluteCoords_[idx ]; double y = vCart[1] - soluteCoords_[idx+1]; double z = vCart[2] - soluteCoords_[idx+2]; double dist2 = x*x + y*y + z*z; // Less than upper, 2nd shell if (dist2 < upperCutoff_) { status[currentRes] = 1; // Less than lower, 1st shell if (dist2 < lowerCutoff_) status[currentRes] = 2; } } else { // Residue already in first shell. No need for more distance calcs ix = iy = iz = 1; break; } } // END loop over solute atoms } // END loop over images (Z) } // END loop over solvent atoms # ifdef _OPENMP } // END pragma omp parallel # endif } else { // ----- ORTHORHOMBIC/NO IMAGING ------------- // Store selected solute coordinates. int idx = 0; for (AtomMask::const_iterator atm = soluteMask_.begin(); atm != soluteMask_.end(); ++atm, idx += 3) { const double* XYZ = frm.Frm().XYZ( *atm ); soluteCoords_[idx ] = XYZ[0]; soluteCoords_[idx+1] = XYZ[1]; soluteCoords_[idx+2] = XYZ[2]; } // Calculate distance of all solvent atoms to solute # ifdef _OPENMP # pragma omp parallel private(Vidx, mythread, status) { mythread = omp_get_thread_num(); status = &(shellStatus_thread_[mythread][0]); # pragma omp for # else status = &shellStatus_[0]; # endif for (Vidx = 0; Vidx < NV; Vidx++) { int Vat = solventMask_[Vidx]; int currentRes = (*CurrentParm_)[ Vat ].ResNum(); Vec3 Vcoord( frm.Frm().XYZ( Vat ) ); // Loop over all solute atoms for (unsigned int idx = 0; idx < soluteCoords_.size(); idx += 3) { if (status[currentRes] < 2) { // Residue is not yet marked as 1st shell, calc distance Vec3 Ucoord( soluteCoords_[idx], soluteCoords_[idx+1], soluteCoords_[idx+2] ); double dist2; if (image_.ImageType() == ORTHO) dist2 = DIST2_ImageOrtho( Vcoord, Ucoord, frm.Frm().BoxCrd() ); else dist2 = DIST2_NoImage( Vcoord, Ucoord ); // Less than upper, 2nd shell if (dist2 < upperCutoff_) { status[currentRes] = 1; // Less than lower, 1st shell if (dist2 < lowerCutoff_) status[currentRes] = 2; } } else { // Residue already in first shell. No need for more distance calcs. break; } } // END loop over solute atoms } // END loop over solvent atoms # ifdef _OPENMP } // END pragma omp parallel # endif } # ifdef _OPENMP // Combine results from each thread. for (unsigned int res = 0; res < shellStatus_thread_[0].size(); res++) { int shell = 0; for (unsigned int thread = 0; thread < shellStatus_thread_.size(); thread++) { shell = std::max( shellStatus_thread_[thread][res], shell ); // Dont break here so we can reset counts. Could also do with a fill shellStatus_thread_[thread][res] = 0; } if (shell > 0) { ++nupper; if (shell > 1) ++nlower; } } # else // Now each residue is marked 0 (no shell), 1 (second shell), 2 (first shell) for (Iarray::iterator shell = shellStatus_.begin(); shell != shellStatus_.end(); ++shell) { if ( *shell > 0 ) { ++nupper; if ( *shell > 1 ) ++nlower; } // Reset for next pass *shell = 0; } # endif # endif /* CUDA */ lower_->Add(frameNum, &nlower); upper_->Add(frameNum, &nupper); return Action::OK; }