2017-04-26 17:20:15 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* 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"
|
2017-04-26 18:03:02 +02:00
|
|
|
#include "stdio.h"
|
2017-04-26 17:20:15 +02:00
|
|
|
#include "mdvar.h"
|
2017-04-26 18:03:02 +02:00
|
|
|
#include "water.h"
|
|
|
|
#include "cnst.h"
|
|
|
|
#include "fileio.h"
|
2017-04-26 17:20:15 +02:00
|
|
|
#include "parameters.h"
|
2017-04-26 18:03:02 +02:00
|
|
|
#include "mddata.h"
|
2017-04-26 17:20:15 +02:00
|
|
|
#include "split.h"
|
2017-04-26 18:03:02 +02:00
|
|
|
#include "global.h"
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
void INITIA()
|
|
|
|
{
|
|
|
|
/* this routine initializes the positions of the molecules along
|
|
|
|
a regular cubical lattice, and randomizes the initial velocities of
|
|
|
|
the atoms. The random numbers used in the initialization of velocities
|
|
|
|
are read from the file random.in, which must be in the current working
|
|
|
|
directory in which the program is run */
|
|
|
|
|
|
|
|
FILE *random_numbers; /* points to input file containing
|
|
|
|
pseudo-random numbers for initializing
|
|
|
|
velocities */
|
|
|
|
double XMAS[4], XT[4], YT[4], Z;
|
|
|
|
double SUX, SUY, SUZ, SUMX, SUMY, SUMZ, FAC;
|
|
|
|
long mol=0;
|
|
|
|
long atom=0;
|
|
|
|
long deriv;
|
|
|
|
|
|
|
|
random_numbers = fopen("random.in","r");
|
|
|
|
if (random_numbers == NULL) {
|
|
|
|
fprintf(stderr,"Error in opening file random.in\n");
|
|
|
|
fflush(stderr);
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
XMAS[1]=sqrt(OMAS*HMAS);
|
|
|
|
XMAS[0]=HMAS;
|
|
|
|
XMAS[2]=HMAS;
|
|
|
|
|
|
|
|
/* .....assign positions */
|
|
|
|
{
|
|
|
|
double NS = pow((double) NMOL, 1.0/3.0) - 0.00001;
|
|
|
|
double XS = BOXL/NS;
|
|
|
|
double ZERO = XS * 0.50;
|
|
|
|
double WCOS = ROH * cos(ANGLE * 0.5);
|
|
|
|
double WSIN = ROH * sin(ANGLE * 0.5);
|
|
|
|
long i,j,k;
|
|
|
|
|
|
|
|
printf("\nNS = %.16f\n",NS);
|
|
|
|
printf("BOXL = %10f\n",BOXL);
|
|
|
|
printf("CUTOFF = %10f\n",CUTOFF);
|
|
|
|
printf("XS = %10f\n",XS);
|
|
|
|
printf("ZERO = %g\n",ZERO);
|
|
|
|
printf("WCOS = %f\n",WCOS);
|
|
|
|
printf("WSIN = %f\n",WSIN);
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
#ifdef RANDOM
|
|
|
|
/* if we want to initialize to a random distribution of displacements
|
|
|
|
for the molecules, rather than a distribution along a regular lattice
|
|
|
|
spaced according to intermolecular distances in water */
|
|
|
|
srand(1023);
|
|
|
|
for (i = 0; i < NMOL; i++) {
|
|
|
|
VAR[mol].F[DISP][XDIR][O] = xrand(0, BOXL);
|
|
|
|
VAR[mol].F[DISP][XDIR][H1] = VAR[mol].F[DISP][XDIR][O] + WCOS;
|
|
|
|
VAR[mol].F[DISP][XDIR][H2] = VAR[mol].F[DISP][XDIR][H1];
|
|
|
|
VAR[mol].F[DISP][YDIR][O] = xrand(0, BOXL);
|
|
|
|
VAR[mol].F[DISP][YDIR][H1] = VAR[mol].F[DISP][YDIR][O] + WSIN;
|
|
|
|
VAR[mol].F[DISP][YDIR][H2] = VAR[mol].F[DISP][YDIR][O] - WSIN;
|
|
|
|
VAR[mol].F[DISP][ZDIR][O] = xrand(0, BOXL);
|
|
|
|
VAR[mol].F[DISP][ZDIR][H1] = VAR[mol].F[DISP][ZDIR][O];
|
|
|
|
VAR[mol].F[DISP][ZDIR][H2] = VAR[mol].F[DISP][ZDIR][O];
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
/* not random initial placement, but rather along a regular
|
|
|
|
lattice. This is the default and the prefered initialization
|
|
|
|
since random does not necessarily make sense from the viewpoint
|
|
|
|
of preserving bond distances */
|
|
|
|
|
|
|
|
fprintf(six, "***** NEW RUN STARTING FROM REGULAR LATTICE *****\n");
|
|
|
|
fflush(six);
|
|
|
|
XT[2] = ZERO;
|
|
|
|
mol = 0;
|
|
|
|
for (i=0; i < NS; i+=1) {
|
|
|
|
XT[1]=XT[2]+WCOS;
|
|
|
|
XT[3]=XT[1];
|
|
|
|
YT[2]=ZERO;
|
|
|
|
for (j=0; j < NS; j+=1) {
|
|
|
|
YT[1]=YT[2]+WSIN;
|
|
|
|
YT[3]=YT[2]-WSIN;
|
|
|
|
Z=ZERO;
|
|
|
|
for (k = 0; k < NS; k++) {
|
|
|
|
for (atom = 0; atom < NATOMS; atom +=1) {
|
|
|
|
VAR[mol].F[DISP][XDIR][atom] = XT[atom+1];
|
|
|
|
VAR[mol].F[DISP][YDIR][atom] = YT[atom+1];
|
|
|
|
VAR[mol].F[DISP][ZDIR][atom] = Z;
|
|
|
|
}
|
|
|
|
mol += 1;
|
|
|
|
Z=Z+XS;
|
|
|
|
}
|
|
|
|
YT[2]=YT[2]+XS;
|
|
|
|
}
|
|
|
|
XT[2]=XT[2]+XS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NMOL != mol) {
|
|
|
|
printf("Lattice init error: total mol %ld != NMOL %ld\n", mol, NMOL);
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ASSIGN RANDOM MOMENTA */
|
|
|
|
fscanf(random_numbers,"%lf",&SUX);
|
|
|
|
|
|
|
|
SUMX=0.0;
|
|
|
|
SUMY=0.0;
|
|
|
|
SUMZ=0.0;
|
|
|
|
/* read pseudo-random numbers from input file random.in */
|
|
|
|
for (mol = 0; mol < NMOL; mol++) {
|
|
|
|
for (atom = 0; atom < NATOMS; atom++) {
|
|
|
|
fscanf(random_numbers,"%lf",&VAR[mol].F[VEL][XDIR][atom]);
|
|
|
|
fscanf(random_numbers,"%lf",&VAR[mol].F[VEL][YDIR][atom]);
|
|
|
|
fscanf(random_numbers,"%lf",&VAR[mol].F[VEL][ZDIR][atom]);
|
|
|
|
SUMX = SUMX + VAR[mol].F[VEL][XDIR][atom];
|
|
|
|
SUMY = SUMY + VAR[mol].F[VEL][YDIR][atom];
|
|
|
|
SUMZ = SUMZ + VAR[mol].F[VEL][ZDIR][atom];
|
|
|
|
for (deriv = ACC; deriv < MAXODR; deriv++) {
|
|
|
|
VAR[mol].F[deriv][XDIR][atom] = 0.0;
|
|
|
|
VAR[mol].F[deriv][YDIR][atom] = 0.0;
|
|
|
|
VAR[mol].F[deriv][ZDIR][atom] = 0.0;
|
|
|
|
}
|
|
|
|
} /* atoms */
|
|
|
|
} /* molecules */
|
|
|
|
|
|
|
|
/* find average momenta per atom */
|
|
|
|
SUMX=SUMX/(NATOMS*NMOL);
|
|
|
|
SUMY=SUMY/(NATOMS*NMOL);
|
|
|
|
SUMZ=SUMZ/(NATOMS*NMOL);
|
|
|
|
|
|
|
|
/* find normalization factor so that <k.e.>=KT/2 */
|
|
|
|
SUX=0.0;
|
|
|
|
SUY=0.0;
|
|
|
|
SUZ=0.0;
|
|
|
|
for (mol = 0; mol < NMOL; mol++) {
|
|
|
|
SUX = SUX + (pow( (VAR[mol].F[VEL][XDIR][H1] - SUMX),2.0)
|
|
|
|
+pow( (VAR[mol].F[VEL][XDIR][H2] - SUMX),2.0))/HMAS
|
|
|
|
+pow( (VAR[mol].F[VEL][XDIR][O] - SUMX),2.0)/OMAS;
|
|
|
|
|
|
|
|
SUY = SUY + (pow( (VAR[mol].F[VEL][YDIR][H1] - SUMY),2.0)
|
|
|
|
+pow( (VAR[mol].F[VEL][YDIR][H2] - SUMY),2.0))/HMAS
|
|
|
|
+pow( (VAR[mol].F[VEL][YDIR][O] - SUMY),2.0)/OMAS;
|
|
|
|
|
|
|
|
SUZ = SUZ + (pow( (VAR[mol].F[VEL][ZDIR][H1] - SUMZ),2.0)
|
|
|
|
+pow( (VAR[mol].F[VEL][ZDIR][H2] - SUMZ),2.0))/HMAS
|
|
|
|
+pow( (VAR[mol].F[VEL][ZDIR][O] - SUMZ),2.0)/OMAS;
|
|
|
|
}
|
|
|
|
FAC=BOLTZ*TEMP*NATMO/UNITM * pow((UNITT*TSTEP/UNITL),2.0);
|
|
|
|
SUX=sqrt(FAC/SUX);
|
|
|
|
SUY=sqrt(FAC/SUY);
|
|
|
|
SUZ=sqrt(FAC/SUZ);
|
|
|
|
|
|
|
|
/* normalize individual velocities so that there are no bulk
|
|
|
|
momenta */
|
|
|
|
XMAS[1]=OMAS;
|
|
|
|
for (mol = 0; mol < NMOL; mol++) {
|
|
|
|
for (atom = 0; atom < NATOMS; atom++) {
|
|
|
|
VAR[mol].F[VEL][XDIR][atom] = ( VAR[mol].F[VEL][XDIR][atom] -
|
|
|
|
SUMX) * SUX/XMAS[atom];
|
|
|
|
VAR[mol].F[VEL][YDIR][atom] = ( VAR[mol].F[VEL][YDIR][atom] -
|
|
|
|
SUMY) * SUY/XMAS[atom];
|
|
|
|
VAR[mol].F[VEL][ZDIR][atom] = ( VAR[mol].F[VEL][ZDIR][atom] -
|
|
|
|
SUMZ) * SUZ/XMAS[atom];
|
|
|
|
} /* for atom */
|
|
|
|
} /* for mol */
|
|
|
|
|
|
|
|
fclose(random_numbers);
|
|
|
|
|
|
|
|
} /* end of subroutine INITIA */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XRAND: generate floating-point random number.
|
|
|
|
*/
|
|
|
|
|
|
|
|
double xrand(double xl, double xh)
|
|
|
|
{
|
|
|
|
double x;
|
|
|
|
|
|
|
|
x=(xl + (xh - xl) * ((double) rand()) / 2147483647.0);
|
|
|
|
return (x);
|
|
|
|
}
|