1#ifndef RPG_BINARY_STRUCTURE_FACTOR_GRID_TPP
2#define RPG_BINARY_STRUCTURE_FACTOR_GRID_TPP
4#include "BinaryStructureFactorGrid.h"
6#include <rpg/fts/simulator/Simulator.h>
8#include <prdc/crystal/shiftToMinimum.h>
9#include <prdc/cuda/resources.h>
10#include <prdc/cuda/complex.h>
11#include <pscf/mesh/MeshIterator.h>
12#include <util/misc/FileMaster.h>
13#include <util/misc/ioUtil.h>
14#include <util/format/Dbl.h>
15#include <util/format/Int.h>
20#include <unordered_map>
36 simulatorPtr_(&simulator),
37 systemPtr_(&(simulator.system())),
38 isInitialized_(false),
49 UTIL_CHECK(system().mixture().nMonomer() == 2);
52 readOutputFileName(in);
53 readOptional(in,
"nSamplePerBlock", nSamplePerBlock_);
63 const int nMonomer = system().mixture().nMonomer();
64 IntVec<D> const & dimensions = system().mesh().dimensions();
66 wm_.allocate(dimensions);
67 wk_.allocate(dimensions);
71 for (
int i = 0; i < D; ++i) {
73 kMeshDimensions_[i] = dimensions[i];
75 kMeshDimensions_[i] = dimensions[i]/2 + 1;
79 for(
int i = 0; i < D; ++i) {
80 kSize_ *= kMeshDimensions_[i];
84 structureFactors_.allocate(nWave_);
85 accumulators_.allocate(nWave_);
88 qList_.resize(kSize_);
89 RField<D> const & kSq = system().domain().waveList().kSq();
95 qList_[itr.
rank()] = sqrt(
double(kSqHost[itr.
rank()]));
98 isInitialized_ =
true;
101 for (
int i = 0; i < nWave_; ++i) {
102 structureFactors_[i] = 0.0;
103 accumulators_[i].setNSamplePerBlock(nSamplePerBlock_);
104 accumulators_[i].clear();
107 if (!isInitialized_) {
108 UTIL_THROW(
"Error: object is not initialized");
120 if (isAtInterval(iStep)) {
121 IntVec<D> const & dimensions = system().mesh().dimensions();
125 system().w().rgrid(1), -0.5);
128 system().fft().forwardTransform(wm_, wk_);
132 for (
int k = 0; k < wk_.capacity(); k++) {
142 const double vSystem = system().domain().unitCell().volume();
143 const double vMonomer = system().mixture().vMonomer();
144 double n = vSystem / vMonomer;
145 double chi= system().interaction().chi(0,1);
150 structureFactors_[itr.
rank()] = n / (chi * chi) * accumulators_[itr.
rank()].average() - 1.0/(2.0*chi);
153 structureFactors_[itr.
rank()] /= vMonomer;
161 UTIL_CHECK(qList_.capacity() == structureFactors_.capacity());
163 std::map<double, double> SMap;
164 for (
int i = 0; i < qList_.capacity(); ++i) {
165 double q = qList_[i];
166 double s = structureFactors_[i];
171 for (
auto& i : SMap) {
173 double sum = i.second;
174 int count = std::count(qList_.begin(), qList_.end(), q);
175 i.second = sum / count;
179 double tolerance = 1e-5;
180 auto it = SMap.begin();
181 double currentq = it->first;
182 double sumS = it->second;
184 for (++it; it != SMap.end(); ++it) {
185 double key = it->first;
186 double s = it->second;
187 if (std::abs(key - currentq) <= tolerance) {
191 averageSMap_[currentq] = sumS / count;
199 averageSMap_[currentq] = sumS / count;
211 computeStructureFactor();
212 averageStructureFactor();
215 system().fileMaster().openOutputFile(outputFileName(), outputFile_);
216 outputFile_ <<
"\t" <<
"q";
217 outputFile_ <<
"\t" <<
"\t" <<
"S(q)/(\u03C1 N)";
218 outputFile_<< std::endl;
219 for (
const auto& i : averageSMap_) {
221 double averageS = i.second;
222 outputFile_ <<
Dbl(q, 18, 8);
223 outputFile_ <<
Dbl(averageS, 18, 8);
224 outputFile_ << std::endl;
Template for dynamic array stored in host CPU memory.
An IntVec<D, T> is a D-component vector of elements of integer type T.
Iterator over points in a Mesh<D>.
int rank() const
Get the rank of current element.
void begin()
Set iterator to the first point in the mesh.
bool atEnd() const
Is this the end (i.e., one past the last point)?
void setDimensions(const IntVec< D > &dimensions)
Set the grid dimensions in all directions.
Field of real double precision values on an FFT mesh.
Abstract base for periodic output and/or analysis actions.
void setup()
Clear accumulators.
void sample(long iStep)
Add particles to BinaryStructureFactor accumulators.
void setClassName(const char *className)
Set class name string.
void averageStructureFactor()
Compute average S(k) over k of equal magnitude.
void computeStructureFactor()
Compute structure factor.
void output()
Output results to predefined output file.
void readParameters(std::istream &in)
Read parameters from file.
BinaryStructureFactorGrid(Simulator< D > &simulator, System< D > &system)
Constructor.
Field theoretic simulator (base class).
Main class for calculations that represent one system.
Wrapper for a double precision number, for formatted ostream output.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
RT absSq(CT const &a)
Return square of absolute magnitude of a complex number.
void addVcVc(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, cudaReal const c, DeviceArray< cudaReal > const &d, cudaReal const e)
Vector addition w/ coefficient, a[i] = (b[i]*c) + (d[i]*e), kernel wrapper.
Fields, FFTs, and utilities for periodic boundary conditions (CUDA)
Periodic fields and crystallography.
PSCF package top-level namespace.
Utility classes for scientific computation.