PSCF v1.3
rpc/fts/analyzer/MaxOrderParameter.tpp
1#ifndef RPC_MAX_ORDER_PARAMETER_TPP
2#define RPC_MAX_ORDER_PARAMETER_TPP
3
4#include "MaxOrderParameter.h"
5
6#include <rpc/system/System.h>
7#include <rpc/fts/simulator/Simulator.h>
8#include <rpc/solvers/Mixture.h>
9#include <rpc/field/Domain.h>
10
11#include <prdc/cpu/FFT.h>
12#include <prdc/cpu/RField.h>
13#include <prdc/crystal/shiftToMinimum.h>
14
15#include <pscf/inter/Interaction.h>
16#include <pscf/mesh/MeshIterator.h>
17#include <pscf/math/IntVec.h>
18
19#include <util/param/ParamComposite.h>
20#include <util/misc/FileMaster.h>
21#include <util/misc/ioUtil.h>
22#include <util/format/Int.h>
23#include <util/format/Dbl.h>
24#include <util/global.h>
25
26#include <iostream>
27#include <complex>
28#include <vector>
29#include <algorithm>
30
31namespace Pscf {
32namespace Rpc {
33
34 using namespace Util;
35 using namespace Pscf::Prdc;
36
37 /*
38 * Constructor.
39 */
40 template <int D>
44 kSize_(1),
45 isInitialized_(false)
46 { setClassName("MaxOrderParameter"); }
47
48 /*
49 * Destructor.
50 */
51 template <int D>
54
55 /*
56 * MaxOrderParameter setup
57 */
58 template <int D>
60 {
61
62 // Precondition: Require that the system has two monomer types
63 const int nMonomer = system().mixture().nMonomer();
64 UTIL_CHECK(nMonomer == 2);
65
67
68 // Set mesh dimensions
69 IntVec<D> const & dimensions = system().domain().mesh().dimensions();
70 FFT<D>::computeKMesh(dimensions, kMeshDimensions_, kSize_);
71
72 // Allocate variables
73 if (!isInitialized_){
74 wK_.allocate(dimensions);
75 }
76
77 isInitialized_ = true;
78
79 if (!isInitialized_) {
80 UTIL_THROW("Error: object is not initialized");
81 }
82 }
83
84 /*
85 * Search for and return maximum Fourier amplitude.
86 */
87 template <int D>
89 {
90 UTIL_CHECK(system().w().hasData());
91
92 if (!simulator().hasWc()){
93 simulator().computeWc();
94 }
95
97 itr.setDimensions(kMeshDimensions_);
98 std::vector<double> psi(kSize_);
99 DArray<IntVec<D>> GminList;
100 GminList.allocate(kSize_);
101 IntVec<D> G;
102 IntVec<D> Gmin;
103 UnitCell<D> const & unitCell = system().domain().unitCell();
104 IntVec<D> const & dimensions = system().domain().mesh().dimensions();
105
106 // Conver W_(r) to fourier mode W_(k)
107 system().domain().fft().forwardTransform(simulator().wc(0), wK_);
108
109 for (itr.begin(); !itr.atEnd(); ++itr) {
110 G = itr.position();
111 Gmin = shiftToMinimum(G, dimensions, unitCell);
112 GminList[itr.rank()] = Gmin;
113
114 std::complex<double> wK(wK_[itr.rank()][0], wK_[itr.rank()][1]);
115 psi[itr.rank()] = std::norm(wK);
116 }
117
118 maxOrderParameter_ = psi[1];
119 int maxIndex = 1;
120 for (int i = 2; i < kSize_; ++i){
121 if (psi[i] > maxOrderParameter_){
122 maxOrderParameter_ = psi[i];
123 maxIndex = i;
124 }
125 }
126
127 GminStar_ = GminList[maxIndex];
128
129 return maxOrderParameter_;
130 }
131
132 /*
133 * Output instantaneous value during simulation.
134 */
135 template <int D>
136 void MaxOrderParameter<D>::outputValue(int step, double value)
137 {
138 if (simulator().hasRamp() && nSamplePerOutput() == 1) {
139 double chi= system().interaction().chi(0,1);
140
141 UTIL_CHECK(outputFile_.is_open());
142 outputFile_ << Int(step);
143 outputFile_ << Dbl(chi);
144 outputFile_ << " ( ";
145 for (int i = 0; i < D; i++){
146 outputFile_ << Int(GminStar_[i],3) << " ";
147 }
148 outputFile_ << " ) ";
149 outputFile_ << Dbl(value);
150 outputFile_ << "\n";
151 } else {
152 //AverageAnalyzer<D>::outputValue(step, value);
153 outputFile_ << Int(step);
154 outputFile_ << " ( ";
155 for (int i = 0; i < D; i++){
156 outputFile_ << Int(GminStar_[i],3) << " ";
157 }
158 outputFile_ << " ) ";
159 outputFile_ << Dbl(value);
160 outputFile_ << "\n";
161 }
162 }
163
164}
165}
166#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)?
void setDimensions(const IntVec< D > &dimensions)
Set the grid dimensions in all directions.
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
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.
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 max order parameter.
MaxOrderParameter(Simulator< D > &simulator, System< D > &system)
Constructor.
void setClassName(const char *className)
Set class name string.
virtual void setup()
Setup before simulation loop.
virtual void outputValue(int step, double value)
Output a sampled or block average value.
Field theoretic simulator (base class).
Main class, representing one complete system.
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
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition global.h:49
Periodic fields and crystallography.
Definition CField.cpp:11
Real periodic fields, SCFT and PS-FTS (CPU).
Definition param_pc.dox:2
PSCF package top-level namespace.
Definition param_pc.dox:1