1#ifndef RPC_EINSTEIN_CRYSTAL_PERTURBATION_TPP
2#define RPC_EINSTEIN_CRYSTAL_PERTURBATION_TPP
4#include "EinsteinCrystalPerturbation.h"
5#include <rpc/fts/simulator/Simulator.h>
7#include <prdc/cpu/RField.h>
8#include <util/containers/DArray.h>
24 unperturbedHamiltonian_(0.0),
25 stateEcHamiltonian_(0.0),
26 stateUnperturbedHamiltonian_(0.0),
43 read(in,
"lambda", lambda_);
46 const int nMonomer = system().mixture().nMonomer();
47 epsilon_.allocate(nMonomer - 1);
48 for (
int i = 0; i < nMonomer - 1 ; ++i) {
54 readOptionalDArray(in,
"epsilon", epsilon_, nMonomer-1).isActive();
56 read(in,
"referenceFieldFileName", referenceFieldFileName_);
65 const int nMonomer = system().mixture().nMonomer();
67 meshDimensions = system().domain().mesh().dimensions();
70 w0_.allocate(nMonomer);
71 wc0_.allocate(nMonomer);
72 for (
int i = 0; i < nMonomer; ++i) {
73 w0_[i].allocate(meshDimensions);
74 wc0_[i].allocate(meshDimensions);
83 for (
int i = 0; i < nMonomer - 1 ; ++i) {
84 epsilon_[i] = -1.0 * simulator().chiEval(i);
89 for (
int i = 0; i < nMonomer - 1 ; ++i) {
95 FieldIo<D> const & fieldIo = system().domain().fieldIo();
100 computeWcReference();
111 const int nMonomer = system().mixture().nMonomer();
112 const int meshSize = system().domain().mesh().size();
113 const double vSystem = system().domain().unitCell().volume();
114 const double vMonomer = system().mixture().vMonomer();
115 const double nMonomerSystem = vSystem / vMonomer;
117 ecHamiltonian_ = 0.0;
119 for (
int j = 0; j < nMonomer - 1; ++j) {
120 RField<D> const & Wc = simulator().wc(j);
121 prefactor = double(nMonomer)/(2.0 * epsilon_[j]);
122 for (
int i = 0; i < meshSize; ++i) {
123 w = Wc[i] - wc0_[j][i];
124 ecHamiltonian_ += prefactor*w*w;
129 ecHamiltonian_ /= double(meshSize);
132 ecHamiltonian_ *= nMonomerSystem;
135 unperturbedHamiltonian_ = unperturbedHamiltonian;
137 return (1.0 - lambda_)*(ecHamiltonian_ - unperturbedHamiltonian_);
147 const int meshSize = system().domain().mesh().size();
148 const int nMonomer = system().mixture().nMonomer();
149 const double vMonomer = system().mixture().vMonomer();
150 double DcEC, prefactor;
153 for (
int i = 0; i < nMonomer - 1; ++i) {
155 RField<D> const & Wc = simulator().wc(i);
156 prefactor = double(nMonomer) / (epsilon_[i] * vMonomer);
159 for (
int k = 0; k < meshSize; ++k) {
160 DcEC = prefactor * (Wc[k] - wc0_[i][k]);
161 Dc[k] += (1.0 - lambda_) * (DcEC - Dc[k]);
172 return unperturbedHamiltonian_ - ecHamiltonian_;
180 stateEcHamiltonian_ = ecHamiltonian_;
181 stateUnperturbedHamiltonian_ = unperturbedHamiltonian_;
189 ecHamiltonian_ = stateEcHamiltonian_;
190 unperturbedHamiltonian_ = stateUnperturbedHamiltonian_;
200 const int nMonomer = system().mixture().nMonomer();
201 const int meshSize = system().domain().mesh().size();
205 for (j = 0; j < nMonomer; ++j) {
209 for (i = 0; i < meshSize; ++i) {
214 for (k = 0; k < nMonomer; ++k) {
215 double vec = simulator().chiEvecs(j, k)/double(nMonomer);
218 RField<D>
const & Wr = w0_[k];
219 for (i = 0; i < meshSize; ++i) {
226 Log::file() <<
"wc " << wc0_.capacity() <<
"\n";
227 for (i = 0; i < 10; ++i) {
228 Log::file() <<
"wc_1 " << wc0_[0][i] <<
"\n";
229 Log::file() <<
"wc_2 " << wc0_[1][i] <<
"\n";
An IntVec<D, T> is a D-component vector of elements of integer type T.
Field of real double precision values on an FFT mesh.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Perturbation for Einstein crystal thermodynamic integration method.
virtual void restoreState()
Restore any required internal state variables.
virtual void readParameters(std::istream &in)
Read parameters from archive.
virtual void saveState()
Save any required internal state variables.
void setClassName(const char *className)
Set class name string.
EinsteinCrystalPerturbation(Simulator< D > &simulator)
Constructor.
virtual double df()
Compute and return derivative of free energy.
virtual void incrementDc(DArray< RField< D > > &dc)
Modify the generalized forces to include perturbation.
virtual void setup()
Complete any required initialization.
virtual double hamiltonian(double unperturbedHamiltonian)
Compute and return the perturbation to the Hamiltonian.
virtual ~EinsteinCrystalPerturbation()
Destructor.
File input/output operations and format conversions for fields.
void readFieldsRGrid(std::istream &in, DArray< RField< D > > &fields, UnitCell< D > &unitCell) const override
Read array of RField objects (r-grid fields) from a stream.
Base class for additive perturbations of standard FTS Hamiltonian.
Field theoretic simulator (base class).
Dynamically allocatable contiguous array template.
static std::ostream & file()
Get log ostream by reference.
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
PSCF package top-level namespace.
Utility classes for scientific computation.