Ejemplo n.º 1
0
// 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;
}
Ejemplo n.º 2
0
// 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;
}
Ejemplo n.º 3
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;
}