PSCF v1.4.0
FourthOrderParameter.tpp
1#ifndef RP_FOURTH_ORDER_PARAMETER_TPP
2#define RP_FOURTH_ORDER_PARAMETER_TPP
3
4#include "FourthOrderParameter.h"
5
6#include <prdc/crystal/shiftToMinimum.h>
7
8#include <pscf/interaction/Interaction.h>
9#include <pscf/mesh/MeshIterator.h>
10
11#include <util/containers/Array.h>
12#include <util/containers/DArray.h>
13#include <util/misc/ioUtil.h>
14#include <util/format/Int.h>
15#include <util/format/Dbl.h>
16#include <util/global.h>
17
18#include <iostream>
19
20namespace Pscf {
21namespace Rp {
22
23 using namespace Util;
24 using namespace Prdc;
25
26 /*
27 * Constructor.
28 */
29 template <int D, class T>
31 typename T::Simulator& simulator,
32 typename T::System& system)
33 : AverageAnalyzerT(simulator, system),
34 kSize_(1),
35 isInitialized_(false)
36 { ParamComposite::setClassName("FourthOrderParameter"); }
37
38 /*
39 * Setup before the main loop.
40 */
41 template <int D, class T>
43 {
44 // Precondition: The system must have exactly two monomer types
45 UTIL_CHECK(system().mixture().nMonomer() == 2);
46
47 AverageAnalyzerT::setup();
48
49 // Compute k-space mesh kMeshDimensions_ and kSize_
50 IntVec<D> const & dimensions = system().domain().mesh().dimensions();
51 FFTT::computeKMesh(dimensions, kMeshDimensions_, kSize_);
52
53 // Allocate variables
54 if (!isInitialized_){
55 wK_.allocate(dimensions);
56 prefactor_.allocate(kMeshDimensions_);
57 psi_.allocate(kMeshDimensions_);
59 }
60
62 isInitialized_ = true;
63 }
64
65 /*
66 * Compute and return the order parameter.
67 */
68 template <int D, class T>
70 {
71 UTIL_CHECK(isInitialized_);
72 UTIL_CHECK(wK_.capacity() == kSize_);
73 UTIL_CHECK(prefactor_.capacity() == kSize_);
74 UTIL_CHECK(psi_.capacity() == kSize_);
75 UTIL_CHECK(system().w().hasData());
76
77 if (!simulator().hasWc()){
78 simulator().computeWc();
79 }
80
81 // Fourier transform W_(r) to obtain wK_ = W_(k)
82 system().domain().fft().forwardTransform(simulator().wc(0), wK_);
83
84 // Evaluate fourth powers, scaled by prefactors
85 VecOp::sqSqAbsV(psi_, wK_);
87
88 // Summation
89 double orderParameter = Reduce::sum(psi_, 1, kSize_);
90 orderParameter = std::pow(orderParameter, 0.25);
91
92 return orderParameter;
93 }
94
95 /*
96 * Compute prefactors for all wavevectors.
97 */
98 template <int D, class T>
99 void
101 {
102 IntVec<D> G;
103 IntVec<D> Gmin;
104 IntVec<D> nGmin;
105 DArray< IntVec<D> > GminList;
106 GminList.allocate(kSize_);
107 MeshIterator<D> itr(kMeshDimensions_);
108 MeshIterator<D> searchItr(kMeshDimensions_);
109
110 // Calculate GminList
111 IntVec<D> meshDimensions = system().domain().mesh().dimensions();
112 UnitCell<D> const & unitCell = system().domain().unitCell();
113 for (itr.begin(); !itr.atEnd(); ++itr){
114 G = itr.position();
115 Gmin = shiftToMinimum(G, meshDimensions, unitCell);
116 GminList[itr.rank()] = Gmin;
117 }
118
119 // Compute prefactor for each wavevector
120 for (itr.begin(); !itr.atEnd(); ++itr){
121 bool inverseFound = false;
122
123 // If prefactor of current wavevector has not been assigned
124 if (prefactor[itr.rank()] == 0){
125 Gmin = GminList[itr.rank()];
126
127 // Compute inverse of wavevector
128 nGmin.negate(Gmin);
129
130 // Search for inverse of wavevector
131 searchItr = itr;
132 for (; !searchItr.atEnd(); ++searchItr){
133 if (nGmin == GminList[searchItr.rank()]){
134 prefactor[itr.rank()] = 1.0/2.0;
135 prefactor[searchItr.rank()] = 1.0/2.0;
136 inverseFound = true;
137 }
138 }
139
140 if (inverseFound == false){
141 prefactor[itr.rank()] = 1.0;
142 }
143
144 }
145
146 }
147 }
148
149}
150}
151#endif
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.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Definition UnitCell.h:56
double compute() override
Compute and return the order parameter.
void setup() override
Setup before the main loop.
FourthOrderParameter(typename T::Simulator &simulator, typename T::System &system)
Constructor.
T::RField prefactor_
Prefactor for each Fourier component.
int kSize_
Number of wavevectors in Fourier space (k-grid) mesh.
void computePrefactor(Array< double > &prefactor)
Compute prefactor for each Fourier wavevector.
Vec< D, T > & negate(const Vec< D, T > &v)
Return negative of vector v.
Definition Vec.h:520
Array container class template.
Definition Array.h:40
Dynamically allocatable contiguous array template.
Definition DArray.h:32
void allocate(int capacity)
Allocate the underlying C array.
Definition DArray.h:269
void setClassName(const char *className)
Set class name string.
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
double sum(Array< double > const &in)
Compute sum of array elements (real).
Definition Reduce.cpp:20
void mulEqV(Array< double > &a, Array< double > const &b)
Vector-vector in-place multiplication, a[i] *= b[i] (real).
Definition VecOp.cpp:252
void sqSqAbsV(Array< double > &a, Array< fftw_complex > const &b)
Fourth power of absolute magnitude, a[i] = |b[i]|^4 (complex).
Definition VecOpCx.cpp:714
void eqS(Array< double > &a, double b)
Vector assignment, a[i] = b (real).
Definition VecOp.cpp:50
Periodic fields and crystallography.
Definition complex.cpp:11
Class templates for real-valued periodic fields.
PSCF package top-level namespace.