Newer
Older
#include "Angle.h"
#include "Dihedral.h"
#include "Restraint.h"
cmaffeo2
committed
#include <cmath>
cmaffeo2
committed
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_math.h>
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
cmaffeo2
committed
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) {
if (code != cudaSuccess) {
fprintf(stderr,"CUDA Error: %s %s %d\n", cudaGetErrorString(code), __FILE__, line);
if (abort) exit(code);
}
}
Configuration::Configuration(const char* config_file, int simNum, bool debug) :
simNum(simNum) {
// Read the parameters.
eguzman6
committed
//type_d = NULL;
eguzman6
committed
//bonds_d = NULL;
//bondMap_d = NULL;
//excludes_d = NULL;
//excludeMap_d = NULL;
//angles_d = NULL;
//dihedrals_d = NULL;
Maxim Belkin
committed
// Get the number of particles
// printf("\nCounting particles specified in the ");
if (restartCoordinates.length() > 0) {
Maxim Belkin
committed
// Read them from the restart file.
num = countRestart(restartCoordinates.val());
Maxim Belkin
committed
} else {
if (readPartsFromFile) readAtoms();
if (numPartsFromFile > 0) {
// Determine number of particles from input file (PDB-style)
Maxim Belkin
committed
num = numPartsFromFile;
} else {
// Sum up all particles in config file
Maxim Belkin
committed
//int num0 = 0;
num = 0;
for (int i = 0; i < numParts; i++) num += part[i].num;
//num = num0;
}
} // end result: variable "num" is set
Maxim Belkin
committed
// Set the number capacity
if (numCap <= 0) numCap = numCapFactor*num; // max number of particles
if (numCap <= 0) numCap = 20;
Maxim Belkin
committed
// Allocate particle variables.
pos = new Vector3[num * simNum];
cmaffeo2
committed
//Han-Yi Chou
if (ParticleDynamicType == String("Langevin") || ParticleDynamicType == String("NoseHooverLangevin"))
momentum = new Vector3[num * simNum];
type = new int[num * simNum];
Maxim Belkin
committed
serial = new int[num * simNum];
posLast = new Vector3[num * simNum];
cmaffeo2
committed
//Han-Yi Chou
if(ParticleDynamicType == String("Langevin") || ParticleDynamicType == String("NoseHooverLangevin"))
momLast = new Vector3[num * simNum];
Maxim Belkin
committed
name = new String[num * simNum];
currSerial = 0;
// Now, load the coordinates
loadedCoordinates = false;
cmaffeo2
committed
loadedMomentum = false; //Han-Yi Chou
Maxim Belkin
committed
cmaffeo2
committed
//I need kT here Han-Yi Chou
kT = temperature * 0.0019872065f; // `units "k K" "kcal_mol"`
//kT = temperature * 0.593f;
Maxim Belkin
committed
// If we have a restart file - use it
if (restartCoordinates.length() > 0) {
cmaffeo2
committed
loadRestart(restartCoordinates.val());
Maxim Belkin
committed
printf("Loaded %d restart coordinates from `%s'.\n", num, restartCoordinates.val());
printf("Particle numbers specified in the configuration file will be ignored.\n");
loadedCoordinates = true;
cmaffeo2
committed
//Han-Yi Chou Langevin dynamic
if (ParticleDynamicType == String("Langevin") || ParticleDynamicType == String("NoseHooverLangevin"))
{
if (restartMomentum.length() > 0)
{
loadRestartMomentum(restartMomentum.val());
printf("Loaded %d restart momentum from `%s'.\n", num, restartMomentum.val());
printf("Particle numbers specified in the configuration file will be ignored.\n");
loadedMomentum = true;
}
else
{
printf("Warning: There is no restart momentum file when using restart coordinates in Langevin Dynamics\n");
printf("Initialize with Boltzmann distribution\n");
loadedMomentum = Boltzmann(COM_Velocity, num * simNum);
}
}
}
else
{
Maxim Belkin
committed
// Load coordinates from a file?
if (numPartsFromFile > 0) {
loadedCoordinates = true;
for (int i = 0; i < num; i++) {
int numTokens = partsFromFile[i].tokenCount();
// Break the line down into pieces (tokens) so we can process them individually
String* tokenList = new String[numTokens];
partsFromFile[i].tokenize(tokenList);
int currType = 0;
for (int j = 0; j < numParts; j++)
if (tokenList[2] == part[j].name)
currType = j;
for (int s = 0; s < simNum; ++s)
cmaffeo2
committed
type[i + s*num] = currType;
Maxim Belkin
committed
serial[i] = currSerial++;
cmaffeo2
committed
pos[i] = Vector3(atof(tokenList[3].val()), atof(tokenList[4].val()), atof(tokenList[5].val()));
//Han-Yi Chou
if (ParticleDynamicType == String("Langevin") || ParticleDynamicType == String("NoseHooverLangevin"))
{
loadedMomentum = true;
if(numTokens == 9)
momentum[i] = Vector3(atof(tokenList[6].val()), atof(tokenList[7].val()), atof(tokenList[8].val()));
else
{
printf("Error occurs in %s at line %d. Please specify momentum\n", __FILE__, __LINE__);
assert(1==2);
}
}
Maxim Belkin
committed
}
delete[] partsFromFile;
partsFromFile = NULL;
cmaffeo2
committed
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//Han-Yi Chou
for(int i = 1; i < simNum; ++i)
for(int j = 0; j < num; ++j)
serial[j + num * i] = currSerial++;
}
else
{
// Not loading coordinates from a file
populate();
if (inputCoordinates.length() > 0)
{
printf("Loading coordinates from %s ... ", inputCoordinates.val());
loadedCoordinates = loadCoordinates(inputCoordinates.val());
if (loadedCoordinates)
printf("done!\n");
}
if(ParticleDynamicType == String("Langevin") || ParticleDynamicType == String("NoseHooverLangevin"))
{
if (inputMomentum.length() > 0)
{
printf("Loading momentum from %s ... ", inputMomentum.val());
loadedMomentum = loadMomentum(inputMomentum.val());
if (loadedMomentum)
printf("done!\n");
}
else
loadedMomentum = Boltzmann(COM_Velocity, num * simNum);
}
}
}
//Check initialize momentum
//if(ParticleDynamicType == String("Langevin"))
//PrintMomentum();
cmaffeo2
committed
/* Initialize exclusions */
excludeCapacity = 256;
numExcludes = 0;
excludes = new Exclude[excludeCapacity];
cmaffeo2
committed
if (readBondsFromFile) readBonds();
if (readAnglesFromFile) readAngles();
if (readDihedralsFromFile) readDihedrals();
if (readRestraintsFromFile) readRestraints();
if (temperatureGridFile.length() != 0) {
printf("\nFound temperature grid file: %s\n", temperatureGridFile.val());
tGrid = new BaseGrid(temperatureGridFile.val());
printf("Loaded `%s'.\n", temperatureGridFile.val());
printf("Grid size %s.\n", tGrid->getExtent().toString().val());
// TODO: ask Max Belkin what this is about and how to remove hard-coded temps
Maxim Belkin
committed
float ToSo = 1.0f / (295.0f * 4.634248239f); // 1 / (To * sigma(To))
sigmaT = new BaseGrid(*tGrid);
sigmaT->shift(-122.8305f);
sigmaT->scale(0.0269167f);
sigmaT->mult(*tGrid);
sigmaT->scale(ToSo);
kTGrid = new BaseGrid(*tGrid);
float factor = 0.0019872065f; // `units "k K" "kcal_mol"`
kTGrid->scale(factor);
// char outFile[256];
// char comment[256]; sprintf(comment,"KTGrid");
// sprintf(outFile,"kTGrid.dx");
// kTGrid->write(outFile, comment);
}
printf("\nFound %d particle types.\n", numParts);
// Load the potential grids.
printf("Loading the potential grids...\n");
for (int i = 0; i < numParts; i++) {
// Decide which type of grid is given.
String map = partGridFile[i];
int len = map.length();
if (len >= 3 && map[len-3]=='.' && map[len-2]=='d' && map[len-1]=='x') {
// A dx file. Load the old-fashioned way.
part[i].pmf = new BaseGrid(map.val());
if (partGridFileScale[i] != 1.0f) part[i].pmf->scale(partGridFileScale[i]);
printf("Loaded dx potential grid `%s'.\n", map.val());
printf("Grid size %s.\n", part[i].pmf->getExtent().toString().val());
} else if (len >= 4 && map[len-4]=='.' && map[len-3]=='d' && map[len-2]=='e' && map[len-1]=='f') {
// A system definition file.
String rootGrid = OverlordGrid::readDefFirst(map);
OverlordGrid* over = new OverlordGrid(rootGrid.val());
int count = over->readDef(map);
printf("Loaded system def file `%s'.\n", map.val());
printf("Found %d unique grids.\n", over->getUniqueGridNum());
printf("Linked %d subgrids.\n", count);
part[i].pmf = static_cast<BaseGrid*>(over);
part[i].meanPmf = part[i].pmf->mean();
} else {
printf("WARNING: Unrecognized gridFile extension. Must be *.def or *.dx.\n");
exit(-1);
}
if (partForceXGridFile[i].length() != 0) {
part[i].forceXGrid = new BaseGrid(partForceXGridFile[i].val());
printf("Loaded `%s'.\n", partForceXGridFile[i].val());
printf("Grid size %s.\n", part[i].forceXGrid->getExtent().toString().val());
}
if (partForceYGridFile[i].length() != 0) {
part[i].forceYGrid = new BaseGrid(partForceYGridFile[i].val());
printf("Loaded `%s'.\n", partForceYGridFile[i].val());
printf("Grid size %s.\n", part[i].forceYGrid->getExtent().toString().val());
Maxim Belkin
committed
}
if (partForceZGridFile[i].length() != 0) {
part[i].forceZGrid = new BaseGrid(partForceZGridFile[i].val());
printf("Loaded `%s'.\n", partForceZGridFile[i].val());
printf("Grid size %s.\n", part[i].forceZGrid->getExtent().toString().val());
}
if (partDiffusionGridFile[i].length() != 0) {
part[i].diffusionGrid = new BaseGrid(partDiffusionGridFile[i].val());
printf("Loaded `%s'.\n", partDiffusionGridFile[i].val());
printf("Grid size %s.\n", part[i].diffusionGrid->getExtent().toString().val());
if (temperatureGridFile.length() != 0) {
if (partDiffusionGridFile[i].length() != 0) {
part[i].diffusionGrid->mult(*sigmaT);
} else {
part[i].diffusionGrid = new BaseGrid(*sigmaT);
part[i].diffusionGrid->scale(part[i].diffusion);
// char outFile[256];
// char comment[256]; sprintf(comment,"Diffusion for particle type %d", i);
// sprintf(outFile,"diffusion%d.dx",i);
// part[i].diffusionGrid->write(outFile, comment);
}
}
}
// Load reservoir files if any
for (int i = 0; i < numParts; i++) {
if (partReservoirFile[i].length() != 0) {
printf("\nLoading the reservoirs for %s... \n", part[i].name.val());
part[i].reservoir = new Reservoir(partReservoirFile[i].val());
int nRes = part[i].reservoir->length();
printf("\t -> %d reservoir(s) found in `%s'.\n", nRes, partReservoirFile[i].val());
}
}
// Get the system dimensions
// from the dimensions of supplied 3D potential maps
if (size.length2() > 0) { // use size if it's defined
if (basis1.length2() > 0 || basis2.length2() > 0 || basis3.length2() > 0)
printf("WARNING: both 'size' and 'basis' were specified... using 'size'\n");
basis1 = Vector3(size.x,0,0);
basis2 = Vector3(0,size.y,0);
basis3 = Vector3(0,0,size.z);
}
if (basis1.length2() > 0 && basis2.length2() > 0 && basis3.length2() > 0) {
sys = new BaseGrid( Matrix3(basis1,basis2,basis3), origin, 1, 1, 1 );
} else {
// TODO: use largest system in x,y,z
}
sysDim = sys->getExtent();
// RBTODO: clean this mess up
/* // RigidBodies... */
/* if (numRigidTypes > 0) { */
/* printf("\nCounting rigid bodies specified in the configuration file.\n"); */
/* numRB = 0; */
/* // grow list of rbs */
/* for (int i = 0; i < numRigidTypes; i++) { */
/* numRB += rigidBody[i].num; */
/* std::vector<RigidBody> tmp; */
/* for (int j = 0; j < rigidBody[i].num; j++) { */
/* tmp.push_back( new RigidBody( this, rigidBody[i] ) ); */
/* } */
/* rbs.push_back(tmp); */
/* } */
// // state data
// rbPos = new Vector3[numRB * simNum];
// type = new int[numRB * simNum];
Maxim Belkin
committed
/* } */
/* printf("Initial RigidBodies: %d\n", numRB); */
Maxim Belkin
committed
// Create exclusions from the exclude rule, if it was specified in the config file
if (excludeRule != String("")) {
int oldNumExcludes = numExcludes;
Exclude* newExcludes = makeExcludes(bonds, bondMap, num, numBonds, excludeRule, numExcludes);
if (excludes == NULL) {
Maxim Belkin
committed
excludes = new Exclude[numExcludes];
} else if (numExcludes >= excludeCapacity) {
Exclude* tempExcludes = excludes;
excludes = new Exclude[numExcludes];
for (int i = 0; i < oldNumExcludes; i++)
excludes[i] = tempExcludes[i];
delete tempExcludes;
Maxim Belkin
committed
}
for (int i = oldNumExcludes; i < numExcludes; i++)
excludes[i] = newExcludes[i - oldNumExcludes];
printf("Built %d exclusions.\n",numExcludes);
}
cmaffeo2
committed
buildExcludeMap();
// Count number of particles of each type
numPartsOfType = new int[numParts];
for (int i = 0; i < numParts; ++i) {
numPartsOfType[i] = 0;
}
for (int i = 0; i < num; ++i) {
++numPartsOfType[type[i]];
}
// Some geometric stuff that should be gotten rid of.
Vector3 buffer = (sys->getCenter() + 2.0f*sys->getOrigin())/3.0f;
initialZ = buffer.z;
// Set the initial conditions.
// Do the initial conditions come from restart coordinates?
// inputCoordinates are ignored if restartCoordinates exist.
/*
if (restartCoordinates.length() > 0) {
Maxim Belkin
committed
loadRestart(restartCoordinates.val());
printf("Loaded %d restart coordinates from `%s'.\n", num, restartCoordinates.val());
printf("Particle numbers specified in the configuration file will be ignored.\n");
} else {
// Set the particle types.
// Load coordinates from a file?
if (numPartsFromFile > 0) {
Maxim Belkin
committed
for (int i = 0; i < num; i++) {
Maxim Belkin
committed
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
// Break the line down into pieces (tokens) so we can process them individually
String* tokenList = new String[numTokens];
partsFromFile[i].tokenize(tokenList);
int currType = 0;
for (int j = 0; j < numParts; j++)
if (tokenList[2] == part[j].name)
currType = j;
type[i] = currType;
serial[i] = currSerial;
currSerial++;
pos[i] = Vector3(atof(tokenList[3].val()), atof(tokenList[4].val()), atof(tokenList[5].val()));
}
if (partsFromFile != NULL) {
delete[] partsFromFile;
partsFromFile = NULL;
}
} else if (inputCoordinates.length() > 0) {
populate();
printf("Loading coordinates from %s.\n", inputCoordinates.val());
bool loaded = loadCoordinates(inputCoordinates.val());
if (loaded)
printf("Loaded initial coordinates from %s.\n", inputCoordinates.val());
}
}
*/
// Get the maximum particle radius.
minimumSep = 0.0f;
for (int i = 0; i < numParts; ++i)
minimumSep = std::max(minimumSep, part[i].radius);
minimumSep *= 2.5f; // Make it a little bigger.
// Default outputEnergyPeriod
if (outputEnergyPeriod < 0)
outputEnergyPeriod = 10 * outputPeriod;
// If we are running with debug ON, ask the user which force computation to use
if (debug)
getDebugForce();
printf("\n");
switchStart = cutoff - switchLen;
if (fullLongRange == 0)
printf("Cutting off the potential from %.10g to %.10g.\n", switchStart, switchStart+switchLen);
if (fullLongRange != 0)
printf("No cell decomposition created.\n");
cmaffeo2
committed
}
Configuration::~Configuration() {
// System state
delete[] pos;
cmaffeo2
committed
//Han-Yi Chou
if (ParticleDynamicType == String("Langevin") || ParticleDynamicType == String("NoseHooverLangevin"))
delete[] momentum;
cmaffeo2
committed
//Han-Yi Chou
if (ParticleDynamicType == String("Langevin") || ParticleDynamicType == String("NoseHooverLangevin"))
delete[] momLast;
delete[] type;
delete[] name;
// Particle parameters
delete[] part;
delete[] partGridFile;
delete[] partGridFileScale;
delete[] partForceXGridFile;
delete[] partForceYGridFile;
delete[] partForceZGridFile;
delete[] partDiffusionGridFile;
delete[] partReservoirFile;
partRigidBodyGrid.clear();
// TODO: plug memory leaks
if (partsFromFile != NULL) delete[] partsFromFile;
if (bonds != NULL) delete[] bonds;
if (bondMap != NULL) delete[] bondMap;
if (excludes != NULL) delete[] excludes;
if (excludeMap != NULL) delete[] excludeMap;
if (angles != NULL) delete[] angles;
if (dihedrals != NULL) delete[] dihedrals;
delete[] numPartsOfType;
// Table parameters
delete[] partTableFile;
delete[] partTableIndex0;
delete[] partTableIndex1;
delete[] bondTableFile;
delete[] angleTableFile;
delete[] dihedralTableFile;
eguzman6
committed
//if (type_d != NULL) {
//gpuErrchk(cudaFree(type_d));
gpuErrchk(cudaFree(sys_d));
gpuErrchk(cudaFree(kTGrid_d));
gpuErrchk(cudaFree(part_d));
eguzman6
committed
//gpuErrchk(cudaFree(bonds_d));
//gpuErrchk(cudaFree(bondMap_d));
//gpuErrchk(cudaFree(excludes_d));
//gpuErrchk(cudaFree(excludeMap_d));
//gpuErrchk(cudaFree(angles_d));
//gpuErrchk(cudaFree(dihedrals_d));
//}
printf("Copying particle data to GPU %d\n", GPUManager::current());
BrownianParticleType **part_addr = new BrownianParticleType*[numParts];
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
// Copy the BaseGrid objects and their member variables/objects
gpuErrchk(cudaMalloc(&part_d, sizeof(BrownianParticleType*) * numParts));
// TODO: The above line fails when there is not enough memory. If it fails, stop.
for (int i = 0; i < numParts; i++) {
BaseGrid *pmf = NULL, *diffusionGrid = NULL;
BrownianParticleType *b = new BrownianParticleType(part[i]);
// Copy PMF
if (part[i].pmf != NULL) {
float *val = NULL;
size_t sz = sizeof(float) * part[i].pmf->getSize();
gpuErrchk(cudaMalloc(&pmf, sizeof(BaseGrid)));
gpuErrchk(cudaMalloc(&val, sz));
gpuErrchk(cudaMemcpyAsync(val, part[i].pmf->val, sz, cudaMemcpyHostToDevice));
BaseGrid *pmf_h = new BaseGrid(*part[i].pmf);
pmf_h->val = val;
gpuErrchk(cudaMemcpy(pmf, pmf_h, sizeof(BaseGrid), cudaMemcpyHostToDevice));
pmf_h->val = NULL;
}
// Copy the diffusion grid
if (part[i].diffusionGrid != NULL) {
float *val = NULL;
size_t sz = sizeof(float) * part[i].diffusionGrid->getSize();
BaseGrid *diffusionGrid_h = new BaseGrid(*part[i].diffusionGrid);
gpuErrchk(cudaMalloc(&diffusionGrid, sizeof(BaseGrid)));
gpuErrchk(cudaMalloc(&val, sz));
diffusionGrid_h->val = val;
gpuErrchk(cudaMemcpyAsync(diffusionGrid, diffusionGrid_h, sizeof(BaseGrid),
cudaMemcpyHostToDevice));
gpuErrchk(cudaMemcpy(val, part[i].diffusionGrid->val, sz, cudaMemcpyHostToDevice));
diffusionGrid_h->val = NULL;
}
b->pmf = pmf;
b->diffusionGrid = diffusionGrid;
gpuErrchk(cudaMalloc(&part_addr[i], sizeof(BrownianParticleType)));
gpuErrchk(cudaMemcpyAsync(part_addr[i], b, sizeof(BrownianParticleType),
cudaMemcpyHostToDevice));
}
// RBTODO: moved this out of preceding loop; was that correct?
gpuErrchk(cudaMemcpyAsync(part_d, part_addr, sizeof(BrownianParticleType*) * numParts,
cudaMemcpyHostToDevice));
if (temperatureGridFile.length() > 0) {
gpuErrchk(cudaMalloc(&kTGrid_d, sizeof(BaseGrid)));
gpuErrchk(cudaMemcpyAsync(kTGrid_d, kTGrid, sizeof(BaseGrid), cudaMemcpyHostToDevice));
}
// type_d and sys_d
gpuErrchk(cudaMalloc(&sys_d, sizeof(BaseGrid)));
gpuErrchk(cudaMemcpyAsync(sys_d, sys, sizeof(BaseGrid), cudaMemcpyHostToDevice));
eguzman6
committed
/*gpuErrchk(cudaMalloc(&type_d, sizeof(int) * num * simNum));
gpuErrchk(cudaMemcpyAsync(type_d, type, sizeof(int) * num * simNum, cudaMemcpyHostToDevice));
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
if (numBonds > 0) {
// bonds_d
gpuErrchk(cudaMalloc(&bonds_d, sizeof(Bond) * numBonds));
gpuErrchk(cudaMemcpyAsync(bonds_d, bonds, sizeof(Bond) * numBonds, cudaMemcpyHostToDevice));
// bondMap_d
gpuErrchk(cudaMalloc(&bondMap_d, sizeof(int2) * num));
gpuErrchk(cudaMemcpyAsync(bondMap_d, bondMap, sizeof(int2) * num, cudaMemcpyHostToDevice));
}
if (numExcludes > 0) {
// excludes_d
gpuErrchk(cudaMalloc(&excludes_d, sizeof(Exclude) * numExcludes));
gpuErrchk(cudaMemcpyAsync(excludes_d, excludes, sizeof(Exclude) * numExcludes,
cudaMemcpyHostToDevice));
// excludeMap_d
gpuErrchk(cudaMalloc(&excludeMap_d, sizeof(int2) * num));
gpuErrchk(cudaMemcpyAsync(excludeMap_d, excludeMap, sizeof(int2) * num,
cudaMemcpyHostToDevice));
}
if (numAngles > 0) {
// angles_d
gpuErrchk(cudaMalloc(&angles_d, sizeof(Angle) * numAngles));
gpuErrchk(cudaMemcpyAsync(angles_d, angles, sizeof(Angle) * numAngles,
cudaMemcpyHostToDevice));
}
if (numDihedrals > 0) {
// dihedrals_d
gpuErrchk(cudaMalloc(&dihedrals_d, sizeof(Dihedral) * numDihedrals));
gpuErrchk(cudaMemcpyAsync(dihedrals_d, dihedrals,
sizeof(Dihedral) * numDihedrals,
cudaMemcpyHostToDevice));
eguzman6
committed
}*/
gpuErrchk(cudaDeviceSynchronize());
}
void Configuration::setDefaults() {
// System parameters
cmaffeo2
committed
rigidBodyGridGridPeriod = 1;
origin = Vector3(0,0,0);
size = Vector3(0,0,0);
basis1 = Vector3(0,0,0);
basis2 = Vector3(0,0,0);
basis3 = Vector3(0,0,0);
inputCoordinates = "";
restartCoordinates = "";
cmaffeo2
committed
//Han-Yi Chou
inputMomentum = "";
restartMomentum = "";
copyReplicaCoordinates = 1;
numberFluct = 0;
numberFluctPeriod = 200;
interparticleForce = 1;
tabulatedPotential = 0;
fullLongRange = 1;
// kTGridFile = ""; // Commented out for an unknown reason
temperature = 295.0f;
temperatureGridFile = "";
coulombConst = 566.440698f/92.0f;
electricField = 0.0f;
cutoff = 10.0f;
switchLen = 2.0f;
pairlistDistance = 2.0f;
imdForceScale = 1.0f;
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
outputPeriod = 200;
outputEnergyPeriod = -1;
outputFormat = TrajectoryWriter::formatDcd;
currentSegmentZ = -1.0f;
numCap = 0;
decompPeriod = 10;
readPartsFromFile = 0;
numPartsFromFile = 0;
partsFromFile = NULL;
readBondsFromFile = false;
numBonds = 0;
bonds = NULL;
bondMap = NULL;
numTabBondFiles = 0;
readExcludesFromFile = false;
numExcludes = 0;
excludeCapacity = 256;
excludes = NULL;
excludeMap = NULL;
excludeRule = "";
readAnglesFromFile = false;
numAngles = 0;
angles = NULL;
numTabAngleFiles = 0;
readDihedralsFromFile = false;
numDihedrals = 0;
dihedrals = NULL;
numTabDihedralFiles = 0;
readRestraintsFromFile = false;
numRestraints = 0;
restraints = NULL;
cmaffeo2
committed
//Han-Yi Chou default values
ParticleDynamicType = String("Brown");
RigidBodyDynamicType = String("Brown");
COM_Velocity = Vector3(0.f,0.f,0.f);
ParticleLangevinIntegrator = String("BAOAB"); //The default is BAOAB
// Hidden parameters
// Might be parameters later
numCapFactor = 5;
}
int Configuration::readParameters(const char * config_file) {
Reader config(config_file);
printf("Read config file %s\n", config_file);
// Get the number of particles.
const int numParams = config.length();
numParts = config.countParameter("particle");
numRigidTypes = config.countParameter("rigidBody");
// Allocate the particle variables.
part = new BrownianParticleType[numParts];
partGridFile = new String[numParts];
partGridFileScale = new float[numParts];
partForceXGridFile = new String[numParts];
partForceYGridFile = new String[numParts];
partForceZGridFile = new String[numParts];
partDiffusionGridFile = new String[numParts];
partReservoirFile = new String[numParts];
partRigidBodyGrid.resize(numParts);
// Allocate the table variables.
partTableFile = new String[numParts*numParts];
partTableIndex0 = new int[numParts*numParts];
partTableIndex1 = new int[numParts*numParts];
// Allocate rigid body types
rigidBody = new RigidBodyType[numRigidTypes];
// Set a default
for (int i = 0; i < numParts; ++i) {
partGridFileScale[i] = 1.0f;
}
int btfcap = 10;
bondTableFile = new String[btfcap];
int atfcap = 10;
angleTableFile = new String[atfcap];
int dtfcap = 10;
dihedralTableFile = new String[dtfcap];
int currPart = -1;
int currTab = -1;
int currBond = -1;
int currAngle = -1;
int currDihedral = -1;
int currRB = -1;
int partClassPart = 0;
int partClassRB = 1;
int currPartClass = -1; // 0 => particle, 1 => rigidBody
for (int i = 0; i < numParams; i++) {
String param = config.getParameter(i);
String value = config.getValue(i);
if (param == String("outputName"))
outputName = value;
else if (param == String("timestep"))
timestep = (float) strtod(value.val(), NULL);
cmaffeo2
committed
else if (param == String("rigidBodyGridGridPeriod"))
rigidBodyGridGridPeriod = atoi(value.val());
else if (param == String("steps"))
steps = atol(value.val());
else if (param == String("seed"))
seed = atoi(value.val());
else if (param == String("origin"))
origin = stringToVector3( value );
else if (param == String("systemSize"))
size = stringToVector3( value );
else if (param == String("basis1"))
basis1 = stringToVector3( value );
else if (param == String("basis2"))
basis2 = stringToVector3( value );
else if (param == String("basis3"))
basis3 = stringToVector3( value );
else if (param == String("inputCoordinates"))
inputCoordinates = value;
else if (param == String("restartCoordinates"))
restartCoordinates = value;
cmaffeo2
committed
//Han-Yi Chou
else if (param == String("inputMomentum"))
inputMomentum = value;
else if (param == String("restartMomentum"))
restartMomentum = value;
else if (param == String("copyReplicaCoordinates"))
copyReplicaCoordinates = atoi(value.val());
else if (param == String("temperature"))
temperature = (float) strtod(value.val(),NULL);
temperatureGridFile = value;
else if (param == String("numberFluct"))
numberFluct = atoi(value.val());
else if (param == String("numberFluctPeriod"))
numberFluctPeriod = atoi(value.val());
else if (param == String("interparticleForce"))
interparticleForce = atoi(value.val());
else if (param == String("fullLongRange") || param == String("fullElect") )
fullLongRange = atoi(value.val());
else if (param == String("coulombConst"))
coulombConst = (float) strtod(value.val(), NULL);
else if (param == String("electricField"))
electricField = (float) strtod(value.val(), NULL);
else if (param == String("cutoff"))
cutoff = (float) strtod(value.val(), NULL);
else if (param == String("switchLen"))
switchLen = (float) strtod(value.val(), NULL);
else if (param == String("pairlistDistance"))
pairlistDistance = (float) strtod(value.val(), NULL);
else if (param == String("scaleIMDForce"))
imdForceScale = (float) strtod(value.val(), NULL);
else if (param == String("outputPeriod"))
outputPeriod = atoi(value.val());
else if (param == String("outputEnergyPeriod"))
outputEnergyPeriod = atoi(value.val());
else if (param == String("outputFormat"))
outputFormat = TrajectoryWriter::getFormatCode(value);
else if (param == String("currentSegmentZ"))
currentSegmentZ = (float) strtod(value.val(), NULL);
else if (param == String("numCap"))
numCap = atoi(value.val());
else if (param == String("decompPeriod"))
decompPeriod = atoi(value.val());
cmaffeo2
committed
//Han-Yi Chou
else if (param == String("ParticleDynamicType"))
ParticleDynamicType = value;
else if (param == String("RigidBodyDynamicType"))
RigidBodyDynamicType = value;
else if (param == String("ParticleLangevinIntegrator"))
ParticleLangevinIntegrator = value;
// PARTICLES
else if (param == String("particle")) {
cmaffeo2
committed
else if (param == String("mu")) // for Nose-Hoover Langevin
part[currPart].mu = (float) strtod(value.val(), NULL);
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
else if (param == String("forceXGridFile"))
partForceXGridFile[currPart] = value;
else if (param == String("forceYGridFile"))
partForceYGridFile[currPart] = value;
else if (param == String("forceZGridFile"))
partForceZGridFile[currPart] = value;
else if (param == String("diffusionGridFile"))
partDiffusionGridFile[currPart] = value;
else if (param == String("diffusion"))
part[currPart].diffusion = (float) strtod(value.val(), NULL);
else if (param == String("charge"))
part[currPart].charge = (float) strtod(value.val(), NULL);
else if (param == String("radius"))
part[currPart].radius = (float) strtod(value.val(), NULL);
else if (param == String("eps"))
part[currPart].eps = (float) strtod(value.val(), NULL);
else if (param == String("reservoirFile"))
partReservoirFile[currPart] = value;
else if (param == String("tabulatedPotential"))
tabulatedPotential = atoi(value.val());
else if (param == String("tabulatedFile"))
readTableFile(value, ++currTab);
else if (param == String("tabulatedBondFile")) {
if (numTabBondFiles >= btfcap) {
String* temp = bondTableFile;
btfcap *= 2;
bondTableFile = new String[btfcap];
for (int j = 0; j < numTabBondFiles; j++)
bondTableFile[j] = temp[j];
delete[] temp;
}
if (readBondFile(value, ++currBond))
numTabBondFiles++;
} else if (param == String("inputParticles")) {
if (readPartsFromFile) {
printf("WARNING: More than one particle file specified. Ignoring new file.\n");
} else {
partFile = value;
readPartsFromFile = true;
loadedCoordinates = true;
}
} else if (param == String("inputBonds")) {
if (readBondsFromFile) {
printf("WARNING: More than one bond file specified. Ignoring new bond file.\n");
} else {
bondFile = value;
readBondsFromFile = true;
}
} else if (param == String("inputExcludes")) {
if (readExcludesFromFile) {
printf("WARNING: More than one exclude file specified. Ignoring new exclude file.\n");
} else {
excludeFile = value;
readExcludesFromFile = true;
}
} else if (param == String("exclude") or param == String("exclusion")) {
excludeRule = value;
} else if (param == String("inputAngles")) {
if (readAnglesFromFile) {
printf("WARNING: More than one angle file specified. Ignoring new angle file.\n");
} else {
angleFile = value;
readAnglesFromFile = true;
}
} else if (param == String("tabulatedAngleFile")) {
if (numTabAngleFiles >= atfcap) {
String* temp = angleTableFile;
atfcap *= 2;
angleTableFile = new String[atfcap];
for (int j = 0; j < numTabAngleFiles; j++)
angleTableFile[j] = temp[j];
delete[] temp;
}
if (readAngleFile(value, ++currAngle))
numTabAngleFiles++;
} else if (param == String("inputDihedrals")) {
if (readDihedralsFromFile) {
printf("WARNING: More than one dihedral file specified. Ignoring new dihedral file.\n");
} else {
dihedralFile = value;
readDihedralsFromFile = true;
}
} else if (param == String("tabulatedDihedralFile")) {
if (numTabDihedralFiles >= dtfcap) {
String * temp = dihedralTableFile;
dtfcap *= 2;
dihedralTableFile = new String[dtfcap];
for (int j = 0; j < numTabDihedralFiles; j++)
dihedralTableFile[j] = temp[j];
delete[] temp;
}
if (readDihedralFile(value, ++currDihedral))
numTabDihedralFiles++;
} else if (param == String("inputRestraints")) {
if (readRestraintsFromFile) {
printf("WARNING: More than one restraint file specified. Ignoring new restraint file.\n");
} else {
restraintFile = value;
readRestraintsFromFile = true;
}
} else if (param == String("gridFileScale")) {
partGridFileScale[currPart] = (float) strtod(value.val(), NULL);
} else if (param == String("rigidBodyPotential")) {
partRigidBodyGrid[currPart].push_back(value);
}
cmaffeo2
committed
//Han-Yi Chou initial COM velocity for total particles
else if (param == String("COM_Velocity"))
COM_Velocity = stringToVector3(value);
// RIGID BODY
else if (param == String("rigidBody")) {
// part[++currPart] = BrownianParticleType(value);
rigidBody[++currRB] = RigidBodyType(value, this);
currPartClass = partClassRB;
}
else if (param == String("inertia"))
rigidBody[currRB].inertia = stringToVector3( value );
else if (param == String("rotDamping"))
rigidBody[currRB].rotDamping = stringToVector3( value );
else if (param == String("densityGrid"))
rigidBody[currRB].addDensityGrid(value);
else if (param == String("potentialGrid"))
rigidBody[currRB].addPotentialGrid(value);
else if (param == String("densityGridScale"))
rigidBody[currRB].scaleDensityGrid(value);
else if (param == String("potentialGridScale"))
rigidBody[currRB].scalePotentialGrid(value);
else if (param == String("pmfScale"))
rigidBody[currRB].scalePMF(value);
else if (param == String("position"))
rigidBody[currRB].initPos = stringToVector3( value );
else if (param == String("orientation"))
rigidBody[currRB].initRot = stringToMatrix3( value );
cmaffeo2
committed
else if (param == String("momentum"))
rigidBody[currRB].initMomentum = stringToVector3(value);
else if (param == String("angularMomentum"))//for angular momentum, serve as restart purpose
rigidBody[currRB].initAngularMomentum = stringToVector3(value);
else if (param == String("inputRBCoordinates"))
inputRBCoordinates = value;
// COMMON
else if (param == String("num")) {
if (currPartClass == partClassPart)
part[currPart].num = atoi(value.val());
rigidBody[currRB].num = atoi(value.val());
}
cmaffeo2
committed
//set mass here Han-Yi Chou
else if (param == String("mass"))
{
if(currPartClass == partClassPart)
part[currPart].mass = (float) strtod(value.val(),NULL);
else if (currPartClass == partClassRB)
rigidBody[currRB].mass = (float) strtod(value.val(),NULL);
}
//set damping here, using anisotropic damping, i.e. data type Vector3 Han-Yi Chou
else if (param == String("transDamping"))
{
if(currPartClass == partClassPart)
part[currPart].transDamping = stringToVector3(value);
else if (currPartClass == partClassRB)
rigidBody[currRB].transDamping = stringToVector3(value);
}
else if (param == String("gridFile")) {
if (currPartClass == partClassPart)
partGridFile[currPart] = value;
else if (currPartClass == partClassRB)
rigidBody[currRB].addPMF(value);
}
cmaffeo2
committed
printf("ERROR: Unrecognized keyword `%s'.\n", param.val());
exit(1);
cmaffeo2
committed
// extra configuration for RB types
for (int i = 0; i < numRigidTypes; i++)
rigidBody[i].setDampingCoeffs(timestep);
cmaffeo2
committed
//For debugging purpose Han-Yi Chou
//Print();
cmaffeo2
committed
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
//Han-Yi Chou
void Configuration::Print()
{
printf("The dynamic type for particle is %s \n", ParticleDynamicType.val());
for(int i = 0; i < numParts; ++i)
{
printf("The type %d has mass %f \n", i,part[i].mass);
printf("The diffusion coefficient is %f \n", part[i].diffusion);
printf("The translational damping is %f %f %f \n", part[i].transDamping.x, part[i].transDamping.y, part[i].transDamping.z);
}
printf("Done with check for Langevin");
//assert(1==2);
}
void Configuration::PrintMomentum()
{
for(int i = 0; i < num; ++i)
{
printf("%f %f %f\n", momentum[i].x, momentum[i].y, momentum[i].z);
}
//assert(1==2);
}
Vector3 Configuration::stringToVector3(String s) {
// tokenize and return
int numTokens = s.tokenCount();
if (numTokens != 3) {
printf("ERROR: could not convert input to Vector3.\n"); // TODO improve this message
exit(1);
}
String* token = new String[numTokens];
s.tokenize(token);
Vector3 v( (float) strtod(token[0], NULL),
(float) strtod(token[1], NULL),
(float) strtod(token[2], NULL) );
return v;
}
Matrix3 Configuration::stringToMatrix3(String s) {
// tokenize and return
int numTokens = s.tokenCount();
if (numTokens != 9) {
printf("ERROR: could not convert input to Matrix3.\n"); // TODO improve this message
exit(1);
}
String* token = new String[numTokens];
s.tokenize(token);
Matrix3 m( (float) strtod(token[0], NULL),
(float) strtod(token[1], NULL),
(float) strtod(token[2], NULL),
(float) strtod(token[3], NULL),
(float) strtod(token[4], NULL),
(float) strtod(token[5], NULL),
(float) strtod(token[6], NULL),
(float) strtod(token[7], NULL),
(float) strtod(token[8], NULL) );
return m;
}
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
void Configuration::readAtoms() {
// Open the file
FILE* inp = fopen(partFile.val(), "r");
char line[256];
// If the particle file cannot be found, exit the program
if (inp == NULL) {
printf("ERROR: Could not open `%s'.\n", partFile.val());
bool found = true;
for (int i = 0; i < numParts; i++)
if (part[i].num == 0)
found = false;
if (!found) {
printf("ERROR: Number of particles not specified in config file.\n");
exit(1);
}
printf("Using default coordinates file\n");
return;
}
// Our particle array has a starting capacity of 256
// We will expand this later if we need to.
int capacity = 256;
numPartsFromFile = 0;
partsFromFile = new String[capacity];
indices = new int[capacity];
indices[0] = 0;
// Get and process all lines of input
while (fgets(line, 256, inp) != NULL) {
// Lines in the particle file that begin with # are comments
if (line[0] == '#') continue;
String s(line);
int numTokens = s.tokenCount();
// Break the line down into pieces (tokens) so we can process them individually
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
// Legitimate ATOM input lines have 6 tokens:
// ATOM | Index | Name | X-coord | Y-coord | Z-coord
// A line without exactly six tokens should be discarded.
if (numTokens != 6) {
printf("Warning: Invalid particle file line: %s\n", line);
return;
}
// Ensure that this particle's type was defined in the config file.
// If not, discard this line.
bool found;
for (int j = 0; j < numParts; j++) {
// If this particle type exists, add a new one to the list
if (part[j].name == tokenList[2]) {
found = true;
part[j].num++;
}
}
// If the particle's type does not exist according to the config file, discard it.
if (!found) {
printf("WARNING Unknown particle type %s found and discarded.\n", tokenList[2].val());
continue;
}
// If we don't have enough room in our particle array, we need to expand it.
if (numPartsFromFile >= capacity) {
// Temporary pointers to the old arrays
String* temp = partsFromFile;
int* temp2 = indices;
// Double the capacity
capacity *= 2;
// Create pointers to new arrays which are twice the size of the old ones
partsFromFile = new String[capacity];
indices = new int[capacity];
// Copy the old values into the new arrays
for (int j = 0; j < numPartsFromFile; j++) {
partsFromFile[j] = temp[j];
indices[j] = temp2[j];
}
// delete the old arrays
delete[] temp;
delete[] temp2;
}
// Make sure the index of this particle is unique.
// NOTE: The particle list is sorted by index.
bool uniqueID = true;
int key = atoi(tokenList[1].val());
int mid = 0;
// If the index is greater than the last index in the list,
// this particle belongs at the end of the list. Since the
// list is kept sorted, we know this is okay.
if (numPartsFromFile == 0 || key > indices[numPartsFromFile - 1]) {
indices[numPartsFromFile] = key;
partsFromFile[numPartsFromFile++] = line;
}
// We need to do a binary search to figure out if
// the index already exists in the list.
// The assumption is that input files SHOULD have their indices sorted in
// ascending order, so we shouldn't actually use the binary search
// or the sort (which is pretty time consuming) very often.
else {
int low = 0, high = numPartsFromFile - 1;
while (low <= high) {
mid = (int)((high - low) / 2 + low);
int curr = indices[mid];
if (curr < key) {
low = mid + 1;
} else if (curr > key) {
high = mid - 1;
} else {
// For now, particles with non-unique IDs are simply not added to the array
// Other possible approaches which are not yet implemented:
// 1: Keep track of these particles and assign them new IDs after you have
// already added all of the other particles.
// 2: Get rid of ALL particles with that ID, even the ones that have already
// been added.
printf("WARNING: Non-unique ID found: %s\n", line);
uniqueID = false;
break;
}
}
if (uniqueID) {
// Add the particle to the end of the array, then sort it.
indices[numPartsFromFile] = key;
partsFromFile[numPartsFromFile++] = line;
std::sort(indices, indices + numPartsFromFile);
std::sort(partsFromFile, partsFromFile + numPartsFromFile, compare());
}
}
}
}
void Configuration::readBonds() {
// Open the file
FILE* inp = fopen(bondFile.val(), "r");
char line[256];
// If the particle file cannot be found, exit the program
if (inp == NULL) {
printf("WARNING: Could not open `%s'.\n", bondFile.val());
printf(" This simulation will not use particle bonds.\n");
return;
}
// Our particle array has a starting capacity of 256
// We will expand this later if we need to.
int capacity = 256;
numBonds = 0;
bonds = new Bond[capacity];
// Get and process all lines of input
while (fgets(line, 256, inp) != NULL) {
// Lines in the particle file that begin with # are comments
if (line[0] == '#') continue;
String s(line);
int numTokens = s.tokenCount();
// Break the line down into pieces (tokens) so we can process them individually
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
// Legitimate BOND input lines have 4 tokens:
// BOND | OPERATION_FLAG | INDEX1 | INDEX2 | FILENAME
// A line without exactly five tokens should be discarded.
if (numTokens != 5) {
printf("WARNING: Invalid bond file line: %s\n", line);
continue;
}
String op = tokenList[1];
int ind1 = atoi(tokenList[2].val());
int ind2 = atoi(tokenList[3].val());
String file_name = tokenList[4];
if (ind1 == ind2) {
printf("WARNING: Invalid bond file line: %s\n", line);
continue;
}
cmaffeo2
committed
if (ind1 < 0 || ind1 >= num || ind2 < 0 || ind2 >=num) {
printf("ERROR: Bond file line '%s' includes invalid index\n", line);
exit(1);
}
// If we don't have enough room in our bond array, we need to expand it.
if (numBonds+1 >= capacity) { // "numBonds+1" because we are adding two bonds to array
// Temporary pointer to the old array
Bond* temp = bonds;
// Double the capacity
capacity *= 2;
// Create pointer to new array which is twice the size of the old one
bonds = new Bond[capacity];
// Copy the old values into the new array
for (int j = 0; j < numBonds; j++)
bonds[j] = temp[j];
// delete the old array
delete[] temp;
}
// Add the bond to the bond array
// We must add it twice: Once for (ind1, ind2) and once for (ind2, ind1)
// RBTODO: add ind1/2 to exclusion list here iff op == REPLACE
cmaffeo2
committed
if (op == "REPLACE")
addExclusion(ind1, ind2);
Bond* b = new Bond(op, ind1, ind2, file_name);
bonds[numBonds++] = *b;
b = new Bond(op, ind2, ind1, file_name);
bonds[numBonds++] = *b;
delete[] tokenList;
}
// Call compareBondIndex with qsort to sort the bonds by BOTH ind1 AND ind2
std::sort(bonds, bonds + numBonds, compare());
/* Each particle may have a varying number of bonds
* bondMap is an array with one element for each particle
* which keeps track of where a particle's bonds are stored
* in the bonds array.
* bondMap[i].x is the index in the bonds array where the ith particle's bonds begin
* bondMap[i].y is the index in the bonds array where the ith particle's bonds end
*/
bondMap = new int2[num];
for (int i = 0; i < num; i++) {
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
bondMap[i].x = -1;
bondMap[i].y = -1;
}
int currPart = -1;
int lastPart = -1;
for (int i = 0; i < numBonds; i++) {
if (bonds[i].ind1 != currPart) {
currPart = bonds[i].ind1;
bondMap[currPart].x = i;
if (lastPart >= 0) bondMap[lastPart].y = i;
lastPart = currPart;
}
}
if (bondMap[lastPart].x > 0)
bondMap[lastPart].y = numBonds;
}
void Configuration::readExcludes()
{
// Open the file
FILE* inp = fopen(excludeFile.val(), "r");
char line[256];
// If the exclusion file cannot be found, exit the program
if (inp == NULL) {
printf("WARNING: Could not open `%s'.\n", excludeFile.val());
printf("This simulation will not use exclusions.\n");
return;
}
// Get and process all lines of input
while (fgets(line, 256, inp) != NULL) {
// Lines in the particle file that begin with # are comments
if (line[0] == '#') continue;
String s(line);
int numTokens = s.tokenCount();
// Break the line down into pieces (tokens) so we can process them individually
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
// Legitimate EXCLUDE input lines have 3 tokens:
// BOND | INDEX1 | INDEX2
// A line without exactly three tokens should be discarded.
if (numTokens != 3) {
printf("WARNING: Invalid exclude file line: %s\n", line);
continue;
}
int ind1 = atoi(tokenList[1].val());
int ind2 = atoi(tokenList[2].val());
cmaffeo2
committed
addExclusion(ind1, ind2);
delete[] tokenList;
}
}
void Configuration::addExclusion(int ind1, int ind2) {
if (ind1 >= num || ind2 >= num) {
printf("WARNING: Attempted to add an exclusion for an out-of-range particle index (%d or %d >= %d).\n", ind1, ind2, num);
return;
}
cmaffeo2
committed
// If we don't have enough room in our bond array, we need to expand it.
if (numExcludes >= excludeCapacity) {
// Temporary pointer to the old array
Exclude* temp = excludes;
cmaffeo2
committed
// Double the capacity
excludeCapacity *= 2;
cmaffeo2
committed
// Create pointer to new array which is twice the size of the old one
excludes = new Exclude[excludeCapacity];
cmaffeo2
committed
// Copy the old values into the new array
for (int j = 0; j < numExcludes; j++)
excludes[j] = temp[j];
cmaffeo2
committed
// delete the old array
delete[] temp;
}
cmaffeo2
committed
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
// Add the bond to the exclude array
// We must add it twice: Once for (ind1, ind2) and once for (ind2, ind1)
Exclude ex1(ind1, ind2);
excludes[numExcludes++] = ex1;
Exclude ex2(ind2, ind1);
excludes[numExcludes++] = ex2;
}
void Configuration::buildExcludeMap() {
// Call compareExcludeIndex with qsort to sort the excludes by BOTH ind1 AND ind2
std::sort(excludes, excludes + numExcludes, compare());
/* Each particle may have a varying number of excludes
* excludeMap is an array with one element for each particle
* which keeps track of where a particle's excludes are stored
* in the excludes array.
* excludeMap[i].x is the index in the excludes array where the ith particle's excludes begin
* excludeMap[i].y is the index in the excludes array where the ith particle's excludes end
*/
excludeMap = new int2[num];
for (int i = 0; i < num; i++) {
excludeMap[i].x = -1;
excludeMap[i].y = -1;
}
int currPart = -1;
int lastPart = -1;
for (int i = 0; i < numExcludes; i++) {
if (excludes[i].ind1 != currPart) {
currPart = excludes[i].ind1;
assert(currPart < num);
excludeMap[currPart].x = i;
if (lastPart >= 0)
excludeMap[lastPart].y = i;
lastPart = currPart;
}
}
if (excludeMap[lastPart].x > 0)
excludeMap[lastPart].y = numExcludes;
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
}
void Configuration::readAngles() {
FILE* inp = fopen(angleFile.val(), "r");
char line[256];
int capacity = 256;
numAngles = 0;
angles = new Angle[capacity];
// If the angle file cannot be found, exit the program
if (inp == NULL) {
printf("WARNING: Could not open `%s'.\n", angleFile.val());
printf("This simulation will not use angles.\n");
return;
}
while(fgets(line, 256, inp)) {
if (line[0] == '#') continue;
String s(line);
int numTokens = s.tokenCount();
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
// Legitimate ANGLE inputs have 5 tokens
// ANGLE | INDEX1 | INDEX2 | INDEX3 | FILENAME
// Any angle input line without exactly 5 tokens should be discarded
if (numTokens != 5) {
printf("WARNING: Invalid angle input line: %s\n", line);
continue;
}
// Discard any empty line
if (tokenList == NULL)
continue;
int ind1 = atoi(tokenList[1].val());
int ind2 = atoi(tokenList[2].val());
int ind3 = atoi(tokenList[3].val());
String file_name = tokenList[4];
//printf("file_name %s\n", file_name.val());
if (ind1 >= num or ind2 >= num or ind3 >= num)
continue;
if (numAngles >= capacity) {
Angle* temp = angles;
capacity *= 2;
angles = new Angle[capacity];
for (int i = 0; i < numAngles; i++)
angles[i] = temp[i];
delete[] temp;
}
Angle a(ind1, ind2, ind3, file_name);
angles[numAngles++] = a;
delete[] tokenList;
}
std::sort(angles, angles + numAngles, compare());
// for(int i = 0; i < numAngles; i++)
// angles[i].print();
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
}
void Configuration::readDihedrals() {
FILE* inp = fopen(dihedralFile.val(), "r");
char line[256];
int capacity = 256;
numDihedrals = 0;
dihedrals = new Dihedral[capacity];
// If the dihedral file cannot be found, exit the program
if (inp == NULL) {
printf("WARNING: Could not open `%s'.\n", dihedralFile.val());
printf("This simulation will not use dihedrals.\n");
return;
}
while(fgets(line, 256, inp)) {
if (line[0] == '#') continue;
String s(line);
int numTokens = s.tokenCount();
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
// Legitimate DIHEDRAL inputs have 6 tokens
// DIHEDRAL | INDEX1 | INDEX2 | INDEX3 | INDEX4 | FILENAME
// Any angle input line without exactly 6 tokens should be discarded
if (numTokens != 6) {
printf("WARNING: Invalid dihedral input line: %s\n", line);
continue;
}
// Discard any empty line
if (tokenList == NULL)
continue;
int ind1 = atoi(tokenList[1].val());
int ind2 = atoi(tokenList[2].val());
int ind3 = atoi(tokenList[3].val());
int ind4 = atoi(tokenList[4].val());
String file_name = tokenList[5];
//printf("file_name %s\n", file_name.val());
if (ind1 >= num or ind2 >= num
or ind3 >= num or ind4 >= num)
continue;
if (numDihedrals >= capacity) {
Dihedral* temp = dihedrals;
capacity *= 2;
dihedrals = new Dihedral[capacity];
for (int i = 0; i < numDihedrals; ++i)
dihedrals[i] = temp[i];
delete[] temp;
}
Dihedral d(ind1, ind2, ind3, ind4, file_name);
dihedrals[numDihedrals++] = d;
delete[] tokenList;
}
std::sort(dihedrals, dihedrals + numDihedrals, compare());
// for(int i = 0; i < numDihedrals; i++)
// dihedrals[i].print();
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
void Configuration::readRestraints() {
FILE* inp = fopen(restraintFile.val(), "r");
char line[256];
int capacity = 16;
numRestraints = 0;
restraints = new Restraint[capacity];
// If the restraint file cannot be found, exit the program
if (inp == NULL) {
printf("WARNING: Could not open `%s'.\n", restraintFile.val());
printf(" This simulation will not use restraints.\n");
return;
}
while(fgets(line, 256, inp)) {
if (line[0] == '#') continue;
String s(line);
int numTokens = s.tokenCount();
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
// inputs have 6 tokens
// RESTRAINT | INDEX1 | k | x0 | y0 | z0
if (numTokens != 6) {
printf("WARNING: Invalid restraint input line: %s\n", line);
continue;
}
// Discard any empty line
if (tokenList == NULL) continue;
int id = atoi(tokenList[1].val());
float k = (float) strtod(tokenList[2].val(), NULL);
float x0 = (float) strtod(tokenList[3].val(), NULL);
float y0 = (float) strtod(tokenList[4].val(), NULL);
float z0 = (float) strtod(tokenList[5].val(), NULL);
if (id >= num) continue;
if (numRestraints >= capacity) {
Restraint* temp = restraints;
capacity *= 2;
restraints = new Restraint[capacity];
for (int i = 0; i < numRestraints; ++i)
restraints[i] = temp[i];
delete[] temp;
}
Restraint tmp(id, Vector3(x0,y0,z0), k);
restraints[numRestraints++] = tmp;
delete[] tokenList;
}
// std::sort(restraints, restraints + numRestraints, compare());
}
cmaffeo2
committed
//populate the type list and serial list
cmaffeo2
committed
for (int repID = 0; repID < simNum; ++repID) {
const int offset = repID * num;
int pn = 0;
int p = 0;
for (int i = 0; i < num; ++i) {
type[i + offset] = p;
serial[i + offset] = currSerial++;
if (++pn >= part[p].num) {
p++;
pn = 0;
}
}
}
}
bool Configuration::readBondFile(const String& value, int currBond) {
int numTokens = value.tokenCount();
if (numTokens != 1) {
printf("ERROR: Invalid tabulatedBondFile: %s, numTokens = %d\n", value.val(), numTokens);
return false;
}
String* tokenList = new String[numTokens];
value.tokenize(tokenList);
if (tokenList == NULL) {
printf("ERROR: Invalid tabulatedBondFile: %s; tokenList is NULL\n", value.val());
return false;
}
bondTableFile[currBond] = tokenList[0];
// printf("Tabulated Bond Potential: %s\n", bondTableFile[currBond].val() );
return true;
}
bool Configuration::readAngleFile(const String& value, int currAngle) {
int numTokens = value.tokenCount();
if (numTokens != 1) {
printf("ERROR: Invalid tabulatedAngleFile: %s, numTokens = %d\n", value.val(), numTokens);
return false;
}
String* tokenList = new String[numTokens];
value.tokenize(tokenList);
if (tokenList == NULL) {
printf("ERROR: Invalid tabulatedAngleFile: %s; tokenList is NULL\n", value.val());
return false;
}
angleTableFile[currAngle] = tokenList[0];
// printf("Tabulated Angle Potential: %s\n", angleTableFile[currAngle].val() );
return true;
}
bool Configuration::readDihedralFile(const String& value, int currDihedral) {
int numTokens = value.tokenCount();
if (numTokens != 1) {
printf("ERROR: Invalid tabulatedDihedralFile: %s, numTokens = %d\n", value.val(), numTokens);
return false;
}
String* tokenList = new String[numTokens];
value.tokenize(tokenList);
if (tokenList == NULL) {
printf("ERROR: Invalid tabulatedDihedralFile: %s; tokenList is NULL\n", value.val());
return false;
}
dihedralTableFile[currDihedral] = tokenList[0];
// printf("Tabulated Dihedral Potential: %s\n", dihedralTableFile[currDihedral].val() );
cmaffeo2
committed
//Load the restart coordiantes only
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
void Configuration::loadRestart(const char* file_name) {
char line[STRLEN];
FILE* inp = fopen(file_name, "r");
if (inp == NULL) {
printf("GrandBrownTown:loadRestart File `%s' does not exist\n", file_name);
exit(-1);
}
int count = 0;
while (fgets(line, STRLEN, inp) != NULL) {
// Ignore comments.
int len = strlen(line);
if (line[0] == '#') continue;
if (len < 2) continue;
String s(line);
int numTokens = s.tokenCount();
if (numTokens != 4) {
printf("GrandBrownTown:loadRestart Invalid coordinate file line: %s\n", line);
fclose(inp);
exit(-1);
}
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
if (tokenList == NULL) {
printf("GrandBrownTown:loadRestart Invalid coordinate file line: %s\n", line);
fclose(inp);
exit(-1);
}
int typ = atoi(tokenList[0]);
float x = (float) strtod(tokenList[1],NULL);
float y = (float) strtod(tokenList[2],NULL);
float z = (float) strtod(tokenList[3],NULL);
pos[count] = Vector3(x,y,z);
type[count] = typ;
serial[count] = currSerial;
currSerial++;
if (typ < 0 || typ >= numParts) {
printf("GrandBrownTown:countRestart Invalid particle type: %d\n", typ);
fclose(inp);
exit(-1);
}
count++;
delete[] tokenList;
}
fclose(inp);
}
cmaffeo2
committed
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
//Han-Yi Chou
//First the resart coordinates should be loaded
void Configuration::loadRestartMomentum(const char* file_name)
{
char line[STRLEN];
FILE* inp = fopen(file_name, "r");
if (inp == NULL)
{
printf("GrandBrownTown:loadRestart File `%s' does not exist\n", file_name);
exit(-1);
}
if(!loadedCoordinates)
{
printf("First load the restart coordinates\n");
assert(1==2);
}
int count = 0;
while (fgets(line, STRLEN, inp) != NULL)
{
// Ignore comments.
int len = strlen(line);
if (line[0] == '#') continue;
if (len < 2) continue;
String s(line);
int numTokens = s.tokenCount();
if (numTokens != 4)
{
printf("GrandBrownTown:loadRestart Invalid momentum file line: %s\n", line);
fclose(inp);
exit(-1);
}
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
if (tokenList == NULL)
{
printf("GrandBrownTown:loadRestart Invalid momentum file line: %s\n", line);
fclose(inp);
exit(-1);
}
int typ = atoi(tokenList[0]);
float x = (float) strtod(tokenList[1],NULL);
float y = (float) strtod(tokenList[2],NULL);
float z = (float) strtod(tokenList[3],NULL);
if (typ < 0 || typ >= numParts)
{
printf("GrandBrownTown:countRestart Invalid particle type : %d\n", typ);
fclose(inp);
exit(-1);
}
if(typ != type[count])
{
printf("Inconsistent in momentum file with the position file\n");
fclose(inp);
exit(-1);
}
momentum[count] = Vector3(x,y,z);
++count;
delete[] tokenList;
}
fclose(inp);
}
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
bool Configuration::loadCoordinates(const char* file_name) {
char line[STRLEN];
FILE* inp = fopen(file_name, "r");
if (inp == NULL) return false;
int count = 0;
while (fgets(line, STRLEN, inp) != NULL) {
// Ignore comments.
int len = strlen(line);
if (line[0] == '#') continue;
if (len < 2) continue;
String s(line);
int numTokens = s.tokenCount();
if (numTokens != 3) {
printf("ERROR: Invalid coordinate file line: %s\n", line);
fclose(inp);
return false;
}
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
if (tokenList == NULL) {
printf("ERROR: Invalid coordinate file line: %s\n", line);
fclose(inp);
return false;
}
if (count >= num*simNum) {
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
printf("WARNING: Too many coordinates in coordinate file %s.\n", file_name);
fclose(inp);
return true;
}
float x = (float) strtod(tokenList[0],NULL);
float y = (float) strtod(tokenList[1],NULL);
float z = (float) strtod(tokenList[2],NULL);
pos[count] = Vector3(x,y,z);
count++;
delete[] tokenList;
}
fclose(inp);
if (count < num) {
printf("ERROR: Too few coordinates in coordinate file.\n");
return false;
}
return true;
}
cmaffeo2
committed
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
//Han-Yi Chou The function populate should be called before entering this function
bool Configuration::loadMomentum(const char* file_name)
{
char line[STRLEN];
FILE* inp = fopen(file_name, "r");
if (inp == NULL)
return false;
int count = 0;
while (fgets(line, STRLEN, inp) != NULL)
{
// Ignore comments.
int len = strlen(line);
if (line[0] == '#')
continue;
if (len < 2)
continue;
String s(line);
int numTokens = s.tokenCount();
if (numTokens != 3)
{
printf("ERROR: Invalid momentum file line: %s\n", line);
fclose(inp);
return false;
}
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
if (tokenList == NULL)
{
printf("ERROR: Invalid momentum file line: %s\n", line);
fclose(inp);
return false;
}
if (count >= num)
{
printf("WARNING: Too many momentum in momentum file %s.\n", file_name);
fclose(inp);
return false;
}
float x = (float) strtod(tokenList[0],NULL);
float y = (float) strtod(tokenList[1],NULL);
float z = (float) strtod(tokenList[2],NULL);
momentum[count] = Vector3(x,y,z);
++count;
delete[] tokenList;
}
fclose(inp);
if (count < num)
{
printf("ERROR: Too few momentum in momentum file.\n");
return false;
}
return true;
}
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
// Count the number of atoms in the restart file.
int Configuration::countRestart(const char* file_name) {
char line[STRLEN];
FILE* inp = fopen(file_name, "r");
if (inp == NULL) {
printf("ERROR: countRestart File `%s' does not exist\n", file_name);
exit(-1);
}
int count = 0;
while (fgets(line, STRLEN, inp) != NULL) {
int len = strlen(line);
// Ignore comments.
if (line[0] == '#') continue;
if (len < 2) continue;
String s(line);
int numTokens = s.tokenCount();
if (numTokens != 4) {
printf("ERROR: countRestart Invalid coordinate file line: %s\n", line);
fclose(inp);
exit(-1);
}
String* tokenList = new String[numTokens];
s.tokenize(tokenList);
if (tokenList == NULL) {
printf("ERROR: countRestart Invalid coordinate file line: %s\n", line);
fclose(inp);
exit(-1);
}
int typ = atoi(tokenList[0]);
// float x = strtod(tokenList[1],NULL);
// float y = strtod(tokenList[2],NULL);
// float z = strtod(tokenList[3],NULL);
if (typ < 0 || typ >= numParts) {
printf("ERROR: countRestart Invalid particle type: %d\n", typ);
fclose(inp);
exit(-1);
}
count++;
delete[] tokenList;
}
fclose(inp);
return count;
}
bool Configuration::readTableFile(const String& value, int currTab) {
int numTokens = value.tokenCount('@');
if (numTokens != 3) {
printf("ERROR: Invalid tabulatedFile: %s\n", value.val());
return false;
}
String* tokenList = new String[numTokens];
value.tokenize(tokenList, '@');
if (tokenList == NULL) {
printf("ERROR: Invalid tabulatedFile: %s\n", value.val());
return false;
}
if (currTab >= numParts*numParts) {
printf("ERROR: Number of tabulatedFile entries exceeded %d*%d particle types.\n", numParts,numParts);
exit(1);
}
partTableIndex0[currTab] = atoi(tokenList[0]);
partTableIndex1[currTab] = atoi(tokenList[1]);
partTableFile[currTab] = tokenList[2];
// printf("Tabulated Potential: %d %d %s\n", partTableIndex0[currTab],
// partTableIndex1[currTab], partTableFile[currTab].val() );
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
delete[] tokenList;
return true;
}
void Configuration::getDebugForce() {
// Allow the user to choose which force computation to use
printf("\n");
printf("(1) ComputeFull [Default] (2) ComputeSoftcoreFull\n");
printf("(3) ComputeElecFull (4) Compute (Decomposed)\n");
printf("(5) ComputeTabulated (Decomposed) (6) ComputeTabulatedFull\n");
printf("WARNING: ");
if (tabulatedPotential) {
if (fullLongRange) printf("(6) was specified by config file\n");
else printf("(5) was specified by config file\n");
} else {
if (fullLongRange != 0) printf("(%d) was specified by config file\n", fullLongRange);
else printf("(4) was specified by config file\n");
}
char buffer[256];
int choice;
while (true) {
printf("Choose a force computation (1 - 6): ");
fgets(buffer, 256, stdin);
bool good = sscanf(buffer, "%d", &choice) && (choice >= 1 && choice <= 6);
if (good)
break;
}
switch(choice) {
case 1:
tabulatedPotential = 0;
fullLongRange = 1;
break;
case 2:
tabulatedPotential = 0;
fullLongRange = 2;
break;
case 3:
tabulatedPotential = 0;
fullLongRange = 3;
break;
case 4:
tabulatedPotential = 0;
fullLongRange = 0;
break;
case 5:
tabulatedPotential = 1;
fullLongRange = 0;
break;
case 6:
tabulatedPotential = 1;
fullLongRange = 1;
break;
default:
tabulatedPotential = 0;
fullLongRange = 1;
break;
}
printf("\n");
}
cmaffeo2
committed
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
//Han-Yi Chou setting boltzman distribution of momentum with a given center of mass velocity
//Before using this code, make sure the array type list and serial list are both already initialized
bool Configuration::Boltzmann(const Vector3& v_com, int N)
{
int count = 0;
Vector3 total_momentum = Vector3(0.);
gsl_rng *gslcpp_rng = gsl_rng_alloc(gsl_rng_default);
srand(time(NULL));
gsl_rng_set (gslcpp_rng, rand() % 100000);
for(int i = 0; i < N; ++i)
{
int typ = type[i];
double M = part[typ].mass;
double sigma = sqrt(kT * M) * 2.046167337e4;
Vector3 tmp(gsl_ran_gaussian(gslcpp_rng,sigma),gsl_ran_gaussian(gslcpp_rng,sigma),gsl_ran_gaussian(gslcpp_rng,sigma));
tmp = tmp * 1e-4;
total_momentum += tmp;
momentum[(size_t)count] = tmp;
++count;
}
if(N > 1)
{
total_momentum = total_momentum / (double)N;
for(int i = 0; i < N; ++i)
{
int typ = type[i];
double M = part[typ].mass;
momentum[i] = momentum[i] - total_momentum + M * v_com;
}
}
gsl_rng_free(gslcpp_rng);
return true;
}
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
//////////////////////////
// Comparison operators //
//////////////////////////
bool Configuration::compare::operator()(const String& lhs, const String& rhs) {
String* list_lhs = new String[lhs.tokenCount()];
String* list_rhs = new String[rhs.tokenCount()];
lhs.tokenize(list_lhs);
rhs.tokenize(list_rhs);
int key_lhs = atoi(list_lhs[1].val());
int key_rhs = atoi(list_rhs[1].val());
delete[] list_lhs;
delete[] list_rhs;
return key_lhs < key_rhs;
}
bool Configuration::compare::operator()(const Bond& lhs, const Bond& rhs) {
int diff = lhs.ind1 - rhs.ind1;
if (diff != 0)
return lhs.ind1 < rhs.ind1;
return lhs.ind2 < rhs.ind2;
}
bool Configuration::compare::operator()(const Exclude& lhs, const Exclude& rhs) {
int diff = lhs.ind1 - rhs.ind1;
if (diff != 0)
return lhs.ind1 < rhs.ind1;
return lhs.ind2 < rhs.ind2;
}
bool Configuration::compare::operator()(const Angle& lhs, const Angle& rhs) {
int diff = lhs.ind1 - rhs.ind1;
if (diff != 0)
return lhs.ind1 < rhs.ind1;
diff = lhs.ind2 - rhs.ind2;
if (diff != 0)
return lhs.ind2 < rhs.ind2;
return lhs.ind3 < rhs.ind3;
}
bool Configuration::compare::operator()(const Dihedral& lhs, const Dihedral& rhs) {
int diff = lhs.ind1 - rhs.ind1;
if (diff != 0)
return lhs.ind1 < rhs.ind1;
diff = lhs.ind2 - rhs.ind2;
if (diff != 0)
return lhs.ind2 < rhs.ind2;
diff = lhs.ind3 - rhs.ind3;
if (diff != 0)
return lhs.ind3 < rhs.ind3;
return lhs.ind4 < rhs.ind4;
}