68 iout <<
"FreeEnergy: " << std::endl <<
endi;
69 iout <<
"FreeEnergy: " << Str;
72 NAMD_die(
"FreeEnergy: Fatal Error with Fixed or Forcing Restraints");
132 double a = B.
Dist(C);
133 double b = A.
Dist(C);
134 double c = A.
Dist(B);
136 u = (a*a + c*c - b*b) / (2.0*a*c);
138 if (u < -1.0) {u = -1.0;}
139 if (u > 1.0) {u = 1.0;}
153 double top, bot, cos_u, sin_u,
Angle;
156 CDxCB = CD.
cross(CB);
157 BCxBA = BC.
cross(BA);
159 top = CDxCB.
dot(BCxBA);
164 if (cos_u < -1.0) {cos_u = -1.0;}
165 if (cos_u > 1.0) {cos_u = 1.0;}
167 topVec = CDxCB.
cross(BCxBA);
168 sin_u = (topVec/bot).dot(CB/CB.
Dist());
171 if (sin_u < -1.0) {sin_u = -1.0;}
172 if (sin_u > 1.0) {sin_u = 1.0;}
174 Angle = atan2(sin_u, cos_u);
189 int i,
AtomID, NumAtoms, RetVal;
190 double Mass, TotalMass=0;
198 for (i=0; i<NumAtoms; i++) {
206 for (i=0; i<NumAtoms; i++) {
231 double Mass, TotalMass;
274 sprintf(Str,
"%7.3f", Distance);
276 #if defined(_VERBOSE_PMF) 277 iout <<
"Position = ";
279 iout <<
" Target = ";
281 iout <<
" Distance = ";
306 return( ((
m_Kf*LambdaKf)/2.0) *
m_pCOMs[0].DistSqr(RefPos) );
311 AVector RefPos,
double LambdaKf) {
329 return(Vec*
m_Kf*LambdaKf);
348 char Str1[20], Str2[20];
351 sprintf(Str1,
"%7.3f", Distance);
353 sprintf(Str2,
"%7.3f", Distance);
355 #if defined(_VERBOSE_PMF) 356 iout <<
"Distance = ";
358 iout <<
" Target = ";
384 Diff = Dist - RefDist;
385 return( ((
m_Kf*LambdaKf)/2.0) * (Diff*Diff) );
390 double RefDist,
double LambdaKf) {
404 ASSERT( (WhichGroup==0) || (WhichGroup==1) );
405 if (WhichGroup == 0) {
415 Vec.
Set(A[0]-B[0], A[1]-B[1], A[2]-B[2]);
416 Vec *=
m_Kf * LambdaKf * (Dist - RefDist) / Dist;
436 char Str1[20], Str2[20];
439 sprintf(Str1,
"%8.3f",
Angle);
441 sprintf(Str2,
"%8.3f",
Angle);
443 #if defined(_VERBOSE_PMF) 447 iout <<
" Target = ";
475 Diff =
Angle - RefAngle;
476 return( ((
m_Kf*LambdaKf)/2.0) * (Diff*Diff) );
481 double RefAngle,
double LambdaKf) {
495 double Const1, Const2, Const3, Const4, Const5;
498 ASSERT( (WhichGroup==0) || (WhichGroup==1) || (WhichGroup==2) );
507 u = (a*a + c*c - b*b) / (2.0*a*c);
510 if (u < -1.0) {u = -1.0;}
514 Const1 = -1.0 / sqrt(1.0 - u*u);
515 Const2 =
m_Kf * LambdaKf * (
Angle-RefAngle) * Const1;
517 Const3 = -a/(2.0*c*c) + 1.0/(a+a) + (b*b)/(2.0*a*c*c);
518 Const4 = -c/(2.0*a*a) + 1.0/(c+c) + (b*b)/(2.0*c*a*a);
521 if (WhichGroup == 0) {
522 Vec1 = (A-C) * (Const5/b);
523 Vec2 = (A-B) * (Const3/c);
525 else if (WhichGroup == 1) {
526 Vec1 = (B-A) * (Const3/c);
527 Vec2 = (B-C) * (Const4/a);
530 Vec1 = (C-A) * (Const5/b);
531 Vec2 = (C-B) * (Const4/a);
533 return( (Vec1+Vec2)*Const2);
552 char Str1[20], Str2[20], Str3[20];
561 #if defined(_VERBOSE_PMF) 562 iout <<
"Dihedral = ";
565 iout <<
" Target = ";
602 return( (Const/2.0) * (1.0 - cos(
Angle-RefAngle)) );
607 double RefAngle,
double Const) {
619 ASSERT((WhichGroup==0)||(WhichGroup==1)||(WhichGroup==2)||(WhichGroup==3));
621 if ((WhichGroup==0) || (WhichGroup==1)) {
633 if (WhichGroup==3) {WhichGroup=0;}
634 if (WhichGroup==2) {WhichGroup=1;}
647 CDxCB = CD.
cross(CB);
648 BCxBA = BC.
cross(BA);
650 top = CDxCB.
dot(BCxBA);
663 ASSERT((WhichGroup==0) || (WhichGroup==1));
668 dP4.
Set( 0, -BC[2], BC[1]);
669 dP5.
Set( BC[2], 0, -BC[0]);
670 dP6.
Set(-BC[1], BC[0], 0 );
673 dP1.
Set( 0, -CD[2], CD[1]);
674 dP2.
Set( CD[2], 0, -CD[0]);
675 dP3.
Set(-CD[1], CD[0], 0 );
676 dP4.
Set( 0, AC[2], -AC[1]);
677 dP5.
Set(-AC[2], 0, AC[0]);
678 dP6.
Set( AC[1], -AC[0], 0 );
681 Vec =
gradU(CDxCB, BCxBA, dP1, dP2, dP3, dP4, dP5, dP6);
682 Vec *= (Const/2.0) * sin(phi-RefAngle) * (-1.0/sqrt(1.0 - u*u));
707 double Mag123, Mag456, Dot;
708 double Const1, Const2, Const3;
709 double P1, P2, P3, P4, P5, P6;
712 P1 = P1P2P3[0]; P2 = P1P2P3[1]; P3 = P1P2P3[2];
713 P4 = P4P5P6[0]; P5 = P4P5P6[1]; P6 = P4P5P6[2];
715 Mag123 = P1P2P3.
Dist();
716 Mag456 = P4P5P6.
Dist();
717 Dot = P1P2P3.
dot(P4P5P6);
719 Const1 = 1.0 / (Mag123*Mag456);
720 Const2 = -Dot * (1.0 / (Mag123*Mag456*Mag456*Mag456));
721 Const3 = -Dot * (1.0 / (Mag456*Mag123*Mag123*Mag123));
723 RetVec = (dP4*P1 + dP1*P4 + dP5*P2 + dP2*P5 + dP6*P3 + dP3*P6) * Const1 +
724 (dP4*P4 + dP5*P5 + dP6*P6) * Const2 +
725 (dP1*P1 + dP2*P2 + dP3*P3) * Const3;
735 return(
GetE(m_RefPos));
743 return(
GetGrad(WhichGroup, m_RefPos));
754 double E, Dist, Diff;
758 if (((m_Bound==
kUpper) && (Dist>m_RefDist)) ||
759 ((m_Bound==
kLower) && (Dist<m_RefDist))) {
760 Diff = Dist - m_RefDist;
761 E = (
m_Kf/2.0) * (Diff*Diff);
779 if (((m_Bound==
kUpper) && (Dist>m_RefDist)) ||
780 ((m_Bound==
kLower) && (Dist<m_RefDist))) {
784 Vec *=
m_Kf * (Dist - m_RefDist) / Dist;
826 T1 = (
m_pCOMs[0][0] - RefPos[0]) * (m_StartPos[0] - m_StopPos[0]);
827 T2 = (
m_pCOMs[0][1] - RefPos[1]) * (m_StartPos[1] - m_StopPos[1]);
828 T3 = (
m_pCOMs[0][2] - RefPos[2]) * (m_StartPos[2] - m_StopPos[2]);
837 return(
GetE(m_RefDist));
845 return(
GetGrad(WhichGroup, m_RefDist));
857 if (((m_Bound==
kUpper) && (Dist>m_RefDist)) ||
858 ((m_Bound==
kLower) && (Dist<m_RefDist))) {
873 if (((m_Bound==
kUpper) && (Dist>m_RefDist)) ||
874 ((m_Bound==
kLower) && (Dist<m_RefDist))) {
875 Vec =
GetGrad(WhichGroup, m_RefDist);
912 return(
m_Kf *
m_LambdaKf * (Dist-RefDist)*(m_StartDist-m_StopDist) );
920 return(
GetE(m_RefAngle));
928 return(
GetGrad(WhichGroup, m_RefAngle));
942 E =
GetE(m_RefAngle);
958 Vec =
GetGrad(WhichGroup, m_RefAngle);
1019 double E, Dihe, Const;
1021 Const =
m_Kf / (1.0 - cos(m_IntervalAngle));
1024 if ( (Dihe>m_LowerAngle) && (Dihe<m_UpperAngle) ) {
1028 else if ( (Dihe<m_LowerAngle) && (Dihe>(m_LowerAngle-m_IntervalAngle)) ) {
1029 E =
GetE(m_LowerAngle, Const);
1032 else if ( (Dihe>m_UpperAngle) && (Dihe<(m_UpperAngle+m_IntervalAngle)) ) {
1033 E =
GetE(m_UpperAngle, Const);
1050 Const =
m_Kf / (1.0 - cos(m_IntervalAngle));
1053 if ( (Dihe<m_LowerAngle) && (Dihe>(m_LowerAngle-m_IntervalAngle)) ) {
1054 Vec =
GetGrad(WhichGroup, m_LowerAngle, Const);
1057 else if ( (Dihe>m_UpperAngle) && (Dihe<(m_UpperAngle+m_IntervalAngle)) ) {
1058 Vec =
GetGrad(WhichGroup, m_UpperAngle, Const);
1095 return((
m_Kf/2)*
m_LambdaKf * sin(Dihe-RefDihe) * (m_StartAngle-m_StopAngle));
Bool_t Set(double x, double y, double z)
int getPosition(int atomid, Position &position)
const double kAlmostMinusOne
void SetGroup(AGroup &Group, int GroupIndex)
AVector cross(const AVector &Vector)
AVector GetGrad(int WhichGroup, double RefDihe, double Const)
AVector gradU(AVector &P1P2P3, AVector &P4P5P6, AVector &dP1, AVector &dP2, AVector &dP3, AVector &dP4, AVector &dP5, AVector &dP6)
double GetE(double RefAngle, double LambdaKf=1.0)
AVector GetGradient(int WhichGroup)
std::ostream & endi(std::ostream &s)
double GetDihe(AVector &A, AVector &B, AVector &C, AVector &D)
int addForce(int atomid, Force force)
double GetE(double RefDist, double LambdaKf=1.0)
double GetE(AVector RefPos, double LambdaKf=1.0)
virtual double GetDiheTarget1()=0
virtual double GetDistTarget()=0
double dot(const AVector &Vector)
AVector GetGradient(int WhichGroup)
double GetAngle(AVector &A, AVector &B, AVector &C)
AVector GetGrad(int WhichGroup, double RefAngle, double LambdaKf=1.0)
AVector GetGradient(int WhichGroup)
virtual double GetDiheTarget2()=0
void DistributeForce(int WhichGroup, AVector Force, GlobalMasterFreeEnergy &CFE)
AVector GetGradient(int WhichGroup)
virtual Bool_t TwoTargets()=0
AVector GetGradient(int WhichGroup)
virtual AVector GetPosTarget()=0
AVector GetGradient(int WhichGroup)
void NAMD_die(const char *err_msg)
static double m_LambdaRef
AVector GetGrad(int WhichGroup, AVector RefPos, double LambdaKf=1.0)
AVector GetGradient(int WhichGroup)
AVector GetGrad(int WhichGroup, double RefDist, double LambdaKf=1.0)
void UpdateCOMs(GlobalMasterFreeEnergy &CFE)
void SetGroups(AGroup &Group1)
AVector GetGradient(int WhichGroup)
AVector GetGradient(int WhichGroup)
void EarlyExit(const char *Str, int AtomID)
AVector GetGradient(int WhichGroup)
void SetEqual(AVector &Vec1, const Vector &Vec2)
double GetE(double RefDihe, double Const)
AVector GetGradient(int WhichGroup)
AVector GetGradient(int WhichGroup)
virtual double GetDistance()=0
virtual double GetAngleTarget()=0
double getMass(int atomid)