PSCF v1.3
rpg/fts/analyzer/FourthOrderParameter.tpp
1#ifndef RPG_FOURTH_ORDER_PARAMETER_TPP
2#define RPG_FOURTH_ORDER_PARAMETER_TPP
3
4#include "FourthOrderParameter.h"
5
6#include <rpg/fts/simulator/Simulator.h>
7#include <rpg/system/System.h>
8
9#include <prdc/cuda/FFT.h>
10#include <prdc/cuda/RField.h>
11#include <prdc/cuda/resources.h>
12#include <prdc/crystal/shiftToMinimum.h>
13
14#include <pscf/inter/Interaction.h>
15#include <pscf/mesh/MeshIterator.h>
16#include <pscf/math/IntVec.h>
17
18#include <util/misc/ioUtil.h>
19#include <util/format/Int.h>
20#include <util/format/Dbl.h>
21#include <util/global.h>
22
23namespace Pscf {
24namespace Rpg {
25
26 using namespace Util;
27 using namespace Pscf::Prdc;
28
29 /*
30 * Constructor.
31 */
32 template <int D>
36 kSize_(1),
37 isInitialized_(false)
38 { setClassName("FourthOrderParameter"); }
39
40 /*
41 * Destructor.
42 */
43 template <int D>
46
47 /*
48 * FourthOrderParameter setup
49 */
50 template <int D>
52 {
53 // Local copies of data
54 const int nMonomer = system().mixture().nMonomer();
55 IntVec<D> const & dimensions = system().domain().mesh().dimensions();
56
57 // Precondition: Require that the system has two monomer types
58 UTIL_CHECK(nMonomer == 2);
59
61
62 // Compute DFT k-space mesh kMeshDimensions_ and kSize_
63 FFT<D>::computeKMesh(dimensions, kMeshDimensions_, kSize_);
64
65 // Allocate variables
66 if (!isInitialized_){
67 wc0_.allocate(dimensions);
68 wK_.allocate(dimensions);
69 prefactor_.allocate(kMeshDimensions_);
70 VecOp::eqS(prefactor_, 0);
71 }
72
73 isInitialized_ = true;
74
76 }
77
78 template <int D>
80 {
81 UTIL_CHECK(system().w().hasData());
82
83 if (!simulator().hasWc()){
84 simulator().computeWc();
85 }
86
87 RField<D> psi;
88 psi.allocate(kMeshDimensions_);
89
90 // Convert W_(r) to fourier mode W_(k)
91 VecOp::eqV(wc0_, simulator().wc(0));
92 system().domain().fft().forwardTransform(wc0_, wK_);
93
94 // psi = |wK_|^4
95 VecOp::sqSqNormV(psi, wK_);
96
97 // W_(k)^4 * weight factor
98 VecOp::mulEqV(psi, prefactor_);
99
100 // Get sum over all wavevectors
101 HostDArray<cudaReal> psiHost(kSize_);
102 psiHost = psi;
103 FourthOrderParameter_ = 0.0;
104
105 for (int i = 1; i < kSize_; ++i){
106 FourthOrderParameter_ += psiHost[i];
107 }
108
109 FourthOrderParameter_ = std::pow(FourthOrderParameter_, 0.25);
110
111 return FourthOrderParameter_;
112 }
113
114 template <int D>
115 void FourthOrderParameter<D>::outputValue(int step, double value)
116 {
117 if (simulator().hasRamp() && nSamplePerOutput() == 1) {
118 double chi = system().interaction().chi(0,1);
119
120 UTIL_CHECK(outputFile_.is_open());
121 outputFile_ << Int(step);
122 outputFile_ << Dbl(chi);
123 outputFile_ << Dbl(value);
124 outputFile_ << "\n";
125 } else {
127 }
128 }
129
130 template <int D>
132 {
133 IntVec<D> meshDimensions = system().domain().mesh().dimensions();
134 UnitCell<D> const & unitCell = system().domain().unitCell();
135 HostDArray<cudaReal> prefactor_h(kSize_);
136 for (int i = 0; i < kSize_; ++i){
137 prefactor_h[i] = 0;
138 }
139 IntVec<D> G;
140 IntVec<D> Gmin;
141 IntVec<D> nGmin;
142 DArray<IntVec<D>> GminList;
143 GminList.allocate(kSize_);
144 MeshIterator<D> itr(kMeshDimensions_);
145 MeshIterator<D> searchItr(kMeshDimensions_);
146
147 // Calculate GminList
148 for (itr.begin(); !itr.atEnd(); ++itr){
149 G = itr.position();
150 Gmin = shiftToMinimum(G, meshDimensions, unitCell);
151 GminList[itr.rank()] = Gmin;
152 }
153
154 // Compute weight factor for each G wavevector
155 for (itr.begin(); !itr.atEnd(); ++itr){
156 bool inverseFound = false;
157
158 // If the weight factor of the current wavevector has not been assigned
159 if (prefactor_h[itr.rank()] == 0){
160 Gmin = GminList[itr.rank()];
161
162 // Compute inverse of wavevector
163 nGmin.negate(Gmin);
164
165 // Search for inverse of wavevector
166 searchItr = itr;
167 for (; !searchItr.atEnd(); ++searchItr){
168 if (nGmin == GminList[searchItr.rank()]){
169 prefactor_h[itr.rank()] = 1.0/2.0;
170 prefactor_h[searchItr.rank()] = 1.0/2.0;
171 inverseFound = true;
172 }
173 }
174
175 if (inverseFound == false){
176 prefactor_h[itr.rank()] = 1.0;
177 }
178
179 }
180
181 }
182
183 // Copy the weight factor from cpu(host) to gpu(device)
184 prefactor_ = prefactor_h;
185 }
186
187}
188}
189#endif
Template for dynamic array stored in host CPU memory.
Definition HostDArray.h:43
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
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)?
IntVec< D > position() const
Get current position in the grid, as integer vector.
static void computeKMesh(IntVec< D > const &rMeshDimensions, IntVec< D > &kMeshDimensions, int &kSize)
Compute dimensions and size of k-space mesh for DFT of real data.
Definition cpu/FFT.tpp:262
Field of real double precision values on an FFT mesh.
Definition cpu/RField.h:29
void allocate(IntVec< D > const &meshDimensions)
Allocate the underlying C array for an FFT grid.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Definition UnitCell.h:56
AverageAnalyzer(Simulator< D > &simulator, System< D > &system)
Constructor.
virtual void setup()
Setup before loop.
virtual void outputValue(int step, double value)
Output a sampled or block average value.
int nSamplePerOutput() const
Get value of nSamplePerOutput.
Simulator< D > & simulator()
Return reference to parent simulator.
System< D > & system()
Return reference to parent system.
virtual double compute()
Compute and return the fourth order parameter.
void setClassName(const char *className)
Set class name string.
FourthOrderParameter(Simulator< D > &simulator, System< D > &system)
Constructor.
virtual void outputValue(int step, double value)
Output a sampled or block average value.
virtual void setup()
Setup before simulation loop.
void computePrefactor()
Compute prefactor for each Fourier wavevector.
Field theoretic simulator (base class).
Main class, representing one complete system.
Vec< D, T > & negate(const Vec< D, T > &v)
Return negative of vector v.
Definition Vec.h:520
Dynamically allocatable contiguous array template.
Definition DArray.h:32
void allocate(int capacity)
Allocate the underlying C array.
Definition DArray.h:199
Wrapper for a double precision number, for formatted ostream output.
Definition Dbl.h:40
Wrapper for an int, for formatted ostream output.
Definition Int.h:37
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
void eqV(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, const int beginIdA, const int beginIdB, const int n)
Vector assignment, a[i] = b[i], kernel wrapper (cudaReal).
Definition VecOp.cu:1039
void eqS(DeviceArray< cudaReal > &a, const cudaReal b, const int beginIdA, const int n)
Vector assignment, a[i] = b, kernel wrapper (cudaReal).
Definition VecOp.cu:1073
void sqSqNormV(DeviceArray< cudaReal > &a, DeviceArray< cudaComplex > const &b)
Norm of complex number to the 4th power, a[i] = norm(b[i])^4, kernel wrapper.
Definition VecOpMisc.cu:600
void mulEqV(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, const int beginIdA, const int beginIdB, const int n)
Vector multiplication in-place, a[i] *= b[i], kernel wrapper (cudaReal).
Definition VecOp.cu:1867
Periodic fields and crystallography.
Definition CField.cpp:11
SCFT and PS-FTS with real periodic fields (GPU)
PSCF package top-level namespace.
Definition param_pc.dox:1