gem5/splash2/codes/apps/water-nsquared/intraf.C

136 lines
5.3 KiB
C
Raw Normal View History

/*************************************************************************/
/* */
/* Copyright (c) 1994 Stanford University */
/* */
/* All rights reserved. */
/* */
/* Permission is given to use, copy, and modify this software for any */
/* non-commercial purpose as long as this copyright notice is not */
/* removed. All other uses, including redistribution in whole or in */
/* part, are forbidden without prior written permission. */
/* */
/* This software is provided with absolutely no warranty and no */
/* support. */
/* */
/*************************************************************************/
EXTERN_ENV
#include "math.h"
#include "frcnst.h"
#include "mdvar.h"
#include "water.h"
#include "wwpot.h"
#include "parameters.h"
#include "mddata.h"
#include "split.h"
#include "global.h"
void INTRAF(double *VIR, long ProcID)
{
/*
.....this routine calculates the intra-molecular force/mass acting on
each atom.
FC11, FC12, FC13, AND FC33 are the quardratic force constants
FC111, FC112, ....... ETC. are the cubic force constants
FC1111, FC1112 ...... ETC. are the quartic force constants
*/
double SUM, R1, R2, VR1[4], VR2[4], COS, SIN;
double DT, DTS, DR1, DR1S, DR2, DR2S, R1S, R2S, DR11[4], DR23[4];
double DT1[4], DT3[4], F1, F2, F3, T1, T2;
long mol, dir, atom;
double LVIR; /* process keeps a local copy of the sum,
to reduce synchronized updates*/
double *temp_p;
/* loop through the molecules */
for (mol = StartMol[ProcID]; mol < StartMol[ProcID+1]; mol++) {
SUM=0.0;
R1=0.0;
R2=0.0;
/* loop through the three directions */
for (dir = XDIR; dir <= ZDIR; dir++) {
temp_p = VAR[mol].F[DISP][dir];
VAR[mol].VM[dir] = C1 * temp_p[O]
+ C2 * (temp_p[H1] +
temp_p[H2] );
VR1[dir] = temp_p[O] - temp_p[H1];
R1 += VR1[dir] * VR1[dir] ;
VR2[dir] = temp_p[O] - temp_p[H2];
R2 += VR2[dir] * VR2[dir];
SUM += VR1[dir] * VR2[dir];
} /* for dir */
R1=sqrt(R1);
R2=sqrt(R2);
/* calculate cos(THETA), sin(THETA), delta(R1),
delta(R2), and delta(THETA) */
COS=SUM/(R1*R2);
SIN=sqrt(ONE-COS*COS);
DT=(acos(COS)-ANGLE)*ROH;
DTS=DT*DT;
DR1=R1-ROH;
DR1S=DR1*DR1;
DR2=R2-ROH;
DR2S=DR2*DR2;
/* calculate derivatives of R1/X1, R2/X3, THETA/X1, and THETA/X3 */
R1S=ROH/(R1*SIN);
R2S=ROH/(R2*SIN);
for (dir = XDIR; dir <= ZDIR; dir++) {
DR11[dir]=VR1[dir]/R1;
DR23[dir]=VR2[dir]/R2;
DT1[dir]=(-DR23[dir]+DR11[dir]*COS)*R1S;
DT3[dir]=(-DR11[dir]+DR23[dir]*COS)*R2S;
} /* for dir */
/* calculate forces */
F1=FC11*DR1+FC12*DR2+FC13*DT;
F2=FC33*DT +FC13*(DR1+DR2);
F3=FC11*DR2+FC12*DR1+FC13*DT;
F1=F1+(3.0*FC111*DR1S+FC112*(2.0*DR1+DR2)*DR2
+2.0*FC113*DR1*DT+FC123*DR2*DT+FC133*DTS)*ROHI;
F2=F2+(3.0*FC333*DTS+FC113*(DR1S+DR2S)
+FC123*DR1*DR2+2.0*FC133*(DR1+DR2)*DT)*ROHI;
F3=F3+(3.0*FC111*DR2S+FC112*(2.0*DR2+DR1)*DR1
+2.0*FC113*DR2*DT+FC123*DR1*DT+FC133*DTS)*ROHI;
F1=F1+(4.0*FC1111*DR1S*DR1+FC1112*(3.0*DR1S+DR2S)
*DR2+2.0*FC1122*DR1*DR2S+3.0*FC1113*DR1S*DT
+FC1123*(2.0*DR1+DR2)*DR2*DT+(2.0*FC1133*DR1
+FC1233*DR2+FC1333*DT)*DTS)*ROHI2;
F2=F2+(4.0*FC3333*DTS*DT+FC1113*(DR1S*DR1+DR2S*DR2)
+FC1123*(DR1+DR2)*DR1*DR2+2.0*FC1133*(DR1S+DR2S)
*DT+2.0*FC1233*DR1*DR2*DT+3.0*FC1333*(DR1+DR2)*DTS)
*ROHI2;
F3=F3+(4.0*FC1111*DR2S*DR2+FC1112*(3.0*DR2S+DR1S)
*DR1+2.0*FC1122*DR1S*DR2+3.0*FC1113*DR2S*DT
+FC1123*(2.0*DR2+DR1)*DR1*DT+(2.0*FC1133*DR2
+FC1233*DR1+FC1333*DT)*DTS)*ROHI2;
for (dir = XDIR; dir <= ZDIR; dir++) {
temp_p = VAR[mol].F[FORCES][dir];
T1=F1*DR11[dir]+F2*DT1[dir];
temp_p[H1] = T1;
T2=F3*DR23[dir]+F2*DT3[dir];
temp_p[H2] = T2;
temp_p[O] = -(T1+T2);
} /* for dir */
} /* for mol */
/* calculate summation of the product of the displacement and computed
force for every molecule, direction, and atom */
LVIR=0.0;
for (mol = StartMol[ProcID]; mol < StartMol[ProcID+1]; mol++)
for ( dir = XDIR; dir <= ZDIR; dir++)
for (atom = 0; atom < NATOM; atom++)
LVIR += VAR[mol].F[DISP][dir][atom] *
VAR[mol].F[FORCES][dir][atom];
LOCK(gl->IntrafVirLock);
*VIR = *VIR + LVIR;
UNLOCK(gl->IntrafVirLock);
} /* end of subroutine INTRAF */