示例#1
0
文件: box.cpp 项目: trisyoungs/duq
// Calculate the RDF normalisation for the Box
bool Box::calculateRDFNormalisation(ProcessPool& procPool, Data2D& boxNorm, double rdfRange, double rdfBinWidth, int nPoints) const
{
	// Setup array - we will use a nominal bin width of 0.1 Angstroms and then interpolate to the rdfBinWidth afterwards
	const double binWidth = 0.1;
	const double rBinWidth = 1.0/binWidth;
	int bin, nBins = rdfRange / binWidth;
	Data2D normData;
	normData.initialise(nBins);
	Array<double>& y = normData.arrayY();
	for (int n=0; n<nBins; ++n) normData.arrayX()[n] = (n+0.5)*binWidth;
	
	Vec3<double> centre = axes_*Vec3<double>(0.5,0.5,0.5);

	// Divide points over processes
	const int nPointsPerProcess = nPoints / procPool.nProcesses();
	Messenger::print("--> Number of insertion points (per process) is %i\n", nPointsPerProcess);
	y = 0.0;
	for (int n=0; n<nPointsPerProcess; ++n)
	{
		bin = (randomCoordinate() - centre).magnitude() * rBinWidth;
		if (bin < nBins) y[bin] += 1.0;
	}
	if (!procPool.allSum(y.array(), nBins)) return false;

	// Normalise histogram data, and scale by volume and binWidth ratio
	y /= double(nPointsPerProcess*procPool.nProcesses());
	y *= volume_ * (rdfBinWidth / binWidth);
	normData.interpolate();

	// Write histogram data for random distribution
	if (procPool.isMaster()) normData.save("duq.box.random");
	
	// Now we have the interpolated data, create the proper interpolated data
	nBins = rdfRange/rdfBinWidth;
	boxNorm.clear();

	// Rescale against expected volume for spherical shells
	double shellVolume, r = 0.0, maxHalf = inscribedSphereRadius(), x = 0.5*rdfBinWidth;
	for (int n=0; n<nBins; ++n)
	{
		// We know that up to the maximum (orthogonal) half-cell width the normalisation should be exactly 1.0...
		if (x < maxHalf) boxNorm.addPoint(x, 1.0);
		else
		{
			shellVolume = (4.0/3.0)*PI*(pow(r+rdfBinWidth,3.0) - pow(r,3.0));
			boxNorm.addPoint(x,  shellVolume / normData.interpolated(x));
// 			boxNorm[n] = normData.interpolated(r);
		}
		r += rdfBinWidth;
		x += rdfBinWidth;
	}
	
	// Interpolate normalisation array
	boxNorm.interpolate();

	// Write final box normalisation file
	if (procPool.isMaster()) boxNorm.save("duq.box.norm");

	return true;
}
示例#2
0
文件: forces.cpp 项目: trisyoungs/duq
// Calculate total forces within the system
void DUQ::totalForces(ProcessPool& procPool, Configuration* cfg, double* fx, double* fy, double* fz, double cutoffSq)
{
	/*
	 * Calculates the total forces within the system, arising from inter-Grain PairPotential interactions
	 * and intramolecular contributions.
	 * 
	 * This is a serial routine (subroutines called from within are parallel).
	 */

	// Create a Timer
	Timer timer;
	
	// Calculate Grain forces
	timer.start();
	grainForces(procPool, cfg, fx, fy, fz, cutoffSq);
	timer.stop();
	Messenger::printVerbose("Time to do Grain forces was %s.\n", timer.timeString());
	
	// Calculate intramolecular forces
	timer.start();
	intramolecularForces(procPool, cfg, fx, fy, fz);
	timer.stop();
	Messenger::printVerbose("Time to do intramolecular forces was %s.\n", timer.timeString());
	
	// Gather forces together
	if (!procPool.allSum(fx, cfg->nAtoms())) return;
	if (!procPool.allSum(fy, cfg->nAtoms())) return;
	if (!procPool.allSum(fz, cfg->nAtoms())) return;
}
示例#3
0
int main(int argc, const char * argv[]) {
    if(argc != 2){
        printf("Usage: ./xxx port(port stands for the port wanna listen on.)\n");
        exit(1);
    }
    
    signal(SIGCHLD, SIG_IGN);
    
    if(!is_free()){
//        exit(0);
    }
    
    int port = atoi(argv[1]);
    
    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(port);
    
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);
    bind(server_socket, (struct sockaddr *) &addr, sizeof(addr));
    listen(server_socket, 0);
    
    ProcessPool* pool = new ProcessPool(server_socket, 1, 10);
    pool->init();
    pool->addTask(print, NULL);
    pool->start();

    if(pool)
        delete(pool);
    exit(0);
}
示例#4
0
windows_process::~windows_process()
{
	ProcessPool *pp = ProcPool();
	GeneratorWindows* winGen = static_cast<GeneratorWindows*>(GeneratorWindows::getDefaultGenerator());
	pp->condvar()->lock();
	winGen->removeProcess(this);
	pp->condvar()->unlock();
	// Do NOT close the process handle; that's handled by ContinueDebugEvent. Closing the file is okay.
	::CloseHandle(hfile);
	
}
示例#5
0
// Broadcast data from Master to all Slaves
bool Parameters::broadcast(ProcessPool& procPool)
{
#ifdef PARALLEL
	if (!procPool.broadcast(name_)) return false;
	if (!procPool.broadcast(description_)) return false;
	if (!procPool.broadcast(&sigma_, 1)) return false;
	if (!procPool.broadcast(&epsilon_, 1)) return false;
	if (!procPool.broadcast(&charge_, 1)) return false;
#endif
	return true;
}
示例#6
0
文件: export.cpp 项目: trisyoungs/duq
// Execute Method
bool Export::process(DUQ& duq, ProcessPool& procPool)
{
	/*
	* Export data from the target Configuration(s)
	 */

	// Loop over target Configurations
	for (RefListItem<Configuration,bool>* ri = targetConfigurations_.first(); ri != NULL; ri = ri->next)
	{
		// Grab Configuration pointer
		Configuration* cfg = ri->item;

		// Retrieve control parameters from Configuration
		const char* saveTrajectory = variableAsChar(cfg, "SaveTrajectory");

		/*
		 * Save XYZ Trajectory
		 */
		if (!DUQSys::isEmpty(saveTrajectory))
		{
			Messenger::print("Export: Appending to trajectory output file '%s'...\n", cfg->outputCoordinatesFile());

			// Only the pool master saves the data
			if (procPool.isMaster())
			{
				// Open the file
				LineParser parser;
				if (!parser.appendOutput(saveTrajectory))
				{
					parser.closeFiles();
					procPool.stop();
					return false;
				}
				else if (!writeConfigurationXYZ(parser, cfg, cfg->name()))
				{
					Messenger::print("Export: Failed to append to trajectory file.\n");
					parser.closeFiles();
					procPool.stop();
					return false;
				}

				procPool.proceed();
			}
			else if (!procPool.decision()) return false;

			Messenger::print("Export: Finished appending trajectory file.\n");
		}
	}

	return true;
}
示例#7
0
// Broadcast data
bool VariableValue::broadcast(ProcessPool& procPool)
{
#ifdef PARALLEL
	// Broadcast type first, then value
	int tempType = type_;
	if (!procPool.broadcast(&tempType, 1)) return false;
	type_ = (VariableValue::ValueType) tempType;
	switch (type_)
	{
		case (VariableValue::BooleanType):
			if (!procPool.broadcast(valueB_)) return false;
			break;
		case (VariableValue::IntegerType):
			if (!procPool.broadcast(&valueI_, 1)) return false;
			break;
		case (VariableValue::DoubleType):
			if (!procPool.broadcast(&valueD_, 1)) return false;
			break;
		case (VariableValue::CharType):
			if (!procPool.broadcast(valueC_)) return false;
			break;
		case (VariableValue::IntegerArrayType):
			if (!procPool.broadcast(arrayI_)) return false;
			break;
		case (VariableValue::DoubleArrayType):
			if (!procPool.broadcast(arrayD_)) return false;
			break;
		default:
			Messenger::error("Broadcast of VariableValue failed - type_ %s not accounted for.\n", VariableValue::valueType(type_));
			return false;
	}
#endif
	return true;
}
示例#8
0
// Broadcast data from Master to all Slaves
bool AtomType::broadcast(ProcessPool& procPool)
{
#ifdef PARALLEL
	int index;

	// Send name
	procPool.broadcast(name_);
	
	// Send element
	procPool.broadcast(&element_, 1);
	
	// Get index of Parameters, 
	if (procPool.isMaster()) index = PeriodicTable::element(element_).indexOfParameters(parameters_);
	procPool.broadcast(&index, 1);
	parameters_ = PeriodicTable::element(element_).parameters(index);
#endif
	return true;
}
示例#9
0
bool GeneratorMT::processWait(bool block)
{
   ProcessPool *pp = ProcPool();
   pp->condvar()->lock();
   pthrd_printf("Checking for live processes\n");
   while (!hasLiveProc() && !isExitingState()) {
      pthrd_printf("Checked and found no live processes\n");
      if (!block) {
         pthrd_printf("Returning from non-blocking processWait\n");
         pp->condvar()->broadcast();
         pp->condvar()->unlock();
         return false;
      }
      pp->condvar()->wait();
   }
   pp->condvar()->broadcast();
   pp->condvar()->unlock();
   pthrd_printf("processWait returning true\n");
   return true;
}
示例#10
0
文件: forces.cpp 项目: trisyoungs/duq
// Calculate total intramolecular forces
void DUQ::intramolecularForces(ProcessPool& procPool, Configuration* cfg, double* fx, double* fy, double* fz)
{
	/*
	 * Calculate the total intramolecular forces within the system, arising from Bond, Angle, and Torsion
	 * terms in all molecules.
	 * 
	 * This is a parallel routine.
	 */

	double distance, angle, force, dp, magji, magjk;
	int index, start, stride;
	Atom* i, *j, *k;
	Vec3<double> vecji, vecjk, forcei, forcek;

	// Set start/skip for parallel loop
	start = procPool.interleavedLoopStart(ProcessPool::OverPoolProcesses);
	stride = procPool.interleavedLoopStride(ProcessPool::OverPoolProcesses);

	// Main loop over molecules
	for (Molecule* mol = cfg->molecules(); mol != NULL; mol = mol->next)
	{
		// Bonds
		for (SpeciesBond* b = mol->species()->bonds(); b != NULL; b = b->next)
		{
			// Grab pointers to atoms involved in bond
			i = mol->atom(b->indexI());
			j = mol->atom(b->indexJ());

			// Determine whether we need to apply minimum image to the vector calculation
			if (cfg->useMim(i->grain()->cell(), j->grain()->cell())) vecji = cfg->box()->minimumVector(i, j);
			else vecji = j->r() - i->r();
			
			// Get distance and normalise vector ready for force calculation
			distance = vecji.magAndNormalise();

			// Determine final forces
			vecji *= b->force(distance);

			// Calculate forces
			index = b->i()->index();
			fx[index] -= vecji.x;
			fy[index] -= vecji.y;
			fz[index] -= vecji.z;
			index = b->j()->index();
			fx[index] += vecji.x;
			fy[index] += vecji.y;
			fz[index] += vecji.z;
		}

		// Angles
		for (SpeciesAngle* a = mol->species()->angles(); a != NULL; a = a->next)
		{
			// Grab pointers to atoms involved in angle
			i = mol->atom(a->indexI());
			j = mol->atom(a->indexJ());
			k = mol->atom(a->indexK());

			// Determine whether we need to apply minimum image between 'j-i' and 'j-k'
			if (cfg->useMim(j->grain()->cell(), i->grain()->cell())) vecji = cfg->box()->minimumVector(j, i);
			else vecji = i->r() - j->r();
			if (cfg->useMim(j->grain()->cell(), k->grain()->cell())) vecjk = cfg->box()->minimumVector(j, k);
			else vecjk = k->r() - j->r();
			
			// Calculate angle
			magji = vecji.magAndNormalise();
			magjk = vecjk.magAndNormalise();
			angle = Box::angle(vecji, vecjk, dp);

			// Determine Angle force vectors for atoms
			force = a->force(angle);
			forcei = vecjk - vecji * dp;
			forcei *= force / magji;
			forcek = vecji - vecjk * dp;
			forcek *= force / magjk;
			
			// Store forces
			index = a->i()->index();
			fx[index] += forcei.x;
			fy[index] += forcei.y;
			fz[index] += forcei.z;
			index = a->j()->index();
			fx[index] -= forcei.x + forcek.x;
			fy[index] -= forcei.y + forcek.y;
			fz[index] -= forcei.z + forcek.z;
			index = a->k()->index();
			fx[index] += forcek.x;
			fy[index] += forcek.y;
			fz[index] += forcek.z;
		}

	}
}
示例#11
0
文件: forces.cpp 项目: trisyoungs/duq
// Calculate Grain forces within the system
void DUQ::grainForces(ProcessPool& procPool, Configuration* cfg, double* fx, double* fy, double* fz, double cutoffSq)
{
	/*
	 * Calculates the total Grain forces within the system, i.e. the energy contributions from PairPotential
	 * interactions between Grains. Any connections between Grains (which in reality correspond to proper chemical bonds
	 * between Atoms) are automatically excluded.
	 * 
	 * This is a parallel routine.
	 */

	// Initialise the Cell distributor
	const bool willBeModified = false, allowRepeats = false;
	cfg->initialiseCellDistribution();

	// Create a ForcesKernel
	ForceKernel kernel(procPool, cfg->box(), potentialMap_);

	int cellId, n, m, start, stride;
	Cell* cell;
	Grain* grainI, *grainJ;

	// Set start/skip for parallel loop
	start = procPool.interleavedLoopStart(ProcessPool::OverGroups);
	stride = procPool.interleavedLoopStride(ProcessPool::OverGroups);

	while (cellId = cfg->nextAvailableCell(procPool, willBeModified, allowRepeats), cellId != Cell::AllCellsComplete)
	{
		// Check for valid cell
		if (cellId == Cell::NoCellsAvailable)
		{
			Messenger::printVerbose("Nothing for this process to do.\n");
			cfg->finishedWithCell(procPool, willBeModified, cellId);
			continue;
		}
		cell = cfg->cell(cellId);
		Messenger::printVerbose("Cell %i now the target, containing %i Grains interacting with %i neighbours.\n", cellId, cell->nGrains(), cell->nTotalCellNeighbours());

		/*
		 * Calculation Begins
		 */

		for (n=start; n<cell->nGrains(); n += stride)
		{
			grainI = cell->grain(n);

			// Inter-Grain interactions in this Cell...
			for (m=n+1; m<cell->nGrains(); ++m)
			{
				grainJ = cell->grain(m);
				kernel.forces(grainI, grainJ, false, false, fx, fy, fz);
			}
			
			// Inter-Grain interactions between this Grain and those in Cell neighbours
			kernel.forces(grainI, cell->nCellNeighbours(), cell->cellNeighbours(), false, true, fx, fy, fz, ProcessPool::Individual);
			kernel.forces(grainI, cell->nMimCellNeighbours(), cell->mimCellNeighbours(), true, true, fx, fy, fz, ProcessPool::Individual);
		}

		/*
		 * Calculation End
		 */
		
		// Must unlock the Cell when we are done with it!
		cfg->finishedWithCell(procPool, willBeModified, cellId);
	}
}