1#ifndef RPG_EINSTEIN_CRYSTAL_PERTURBATION_TPP
2#define RPG_EINSTEIN_CRYSTAL_PERTURBATION_TPP
4#include "EinsteinCrystalPerturbation.h"
5#include <rpg/fts/simulator/Simulator.h>
6#include <rpg/fts/VecOpFts.h>
7#include <rpg/system/System.h>
8#include <rpg/solvers/Mixture.h>
9#include <rpg/field/Domain.h>
10#include <prdc/cuda/resources.h>
17 using namespace Prdc::Cuda;
27 unperturbedHamiltonian_(0.0),
28 stateEcHamiltonian_(0.0),
29 stateUnperturbedHamiltonian_(0.0),
49 const int nMonomer =
system().mixture().nMonomer();
50 epsilon_.allocate(nMonomer - 1);
51 for (
int i = 0; i < nMonomer - 1 ; ++i) {
59 read(in,
"referenceFieldFileName", referenceFieldFileName_);
68 const int nMonomer =
system().mixture().nMonomer();
70 meshDimensions =
system().domain().mesh().dimensions();
73 w0_.allocate(nMonomer);
74 wc0_.allocate(nMonomer);
75 for (
int i = 0; i < nMonomer; ++i) {
76 w0_[i].allocate(meshDimensions);
77 wc0_[i].allocate(meshDimensions);
85 for (
int i = 0; i < nMonomer - 1 ; ++i) {
86 epsilon_[i] = -1.0 *
simulator().chiEval(i);
91 for (
int i = 0; i < nMonomer - 1 ; ++i) {
102 computeWcReference();
113 const int nMonomer =
system().mixture().nMonomer();
114 const int meshSize =
system().domain().mesh().size();
115 const IntVec<D> meshDimensions =
system().domain().mesh().dimensions();
116 const double vSystem =
system().domain().unitCell().volume();
117 const double vMonomer =
system().mixture().vMonomer();
118 const double nMonomerSystem = vSystem / vMonomer;
122 ecHamiltonian_ = 0.0;
124 for (
int j = 0; j < nMonomer - 1; ++j) {
126 prefactor = double(nMonomer)/(2.0 * epsilon_[j]);
130 ecHamiltonian_ += prefactor * wSqure;
134 ecHamiltonian_ /= double(meshSize);
137 ecHamiltonian_ *= nMonomerSystem;
140 unperturbedHamiltonian_ = unperturbedHamiltonian;
142 return (1.0 -
lambda_)*(ecHamiltonian_ - unperturbedHamiltonian_);
152 const IntVec<D> meshDimensions =
system().domain().mesh().dimensions();
153 const int nMonomer =
system().mixture().nMonomer();
154 const double vMonomer =
system().mixture().vMonomer();
160 for (
int i = 0; i < nMonomer - 1; ++i) {
163 prefactor = double(nMonomer) / (epsilon_[i] * vMonomer);
181 return unperturbedHamiltonian_ - ecHamiltonian_;
189 stateEcHamiltonian_ = ecHamiltonian_;
190 stateUnperturbedHamiltonian_ = unperturbedHamiltonian_;
198 ecHamiltonian_ = stateEcHamiltonian_;
199 unperturbedHamiltonian_ = stateUnperturbedHamiltonian_;
207 void EinsteinCrystalPerturbation<D>::computeWcReference()
209 const int nMonomer = system().mixture().nMonomer();
213 for (i = 0; i < nMonomer; ++i) {
221 for (j = 0; j < nMonomer; ++j) {
223 vec = (cudaReal) simulator().chiEvecs(i, j)/nMonomer;
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.
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.
virtual double df()
Compute and return derivative of free energy.
DArrayParam< Type > & readOptionalDArray(std::istream &in, const char *label, DArray< Type > &array, int n)
Add and read an optional DArray < Type > parameter.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
void setClassName(const char *className)
Set class name string.
EinsteinCrystalPerturbation(Simulator< D > &simulator)
Constructor.
virtual double hamiltonian(double unperturbedHamiltonian)
Compute and return the perturbation to the Hamiltonian.
virtual void setup()
Complete any required initialization.
virtual void incrementDc(DArray< RField< D > > &dc)
Modify the generalized forces to include perturbation.
virtual ~EinsteinCrystalPerturbation()
Destructor.
virtual void restoreState()
Restore any required internal state variables.
virtual void saveState()
Save any required internal state variables.
virtual void readParameters(std::istream &in)
Read parameters from archive.
File input/output operations and format conversions for fields.
bool readFieldsRGrid(std::istream &in, DArray< RField< D > > &fields, UnitCell< D > &unitCell) const override
Read array of RField objects (r-grid fields) from a stream.
System< D > const & system() const
Get parent System<D> by const reference.
double lambda_
Strength of the perturbation.
Simulator< D > const & simulator() const
Get parent Simulator<D> by const reference.
Perturbation(Simulator< D > &simulator)
Constructor.
Field theoretic simulator (base class).
Dynamically allocatable contiguous array template.
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
double innerProduct(Array< double > const &a, Array< double > const &b)
Compute inner product of two real arrays .
void subVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector subtraction, a[i] = b[i] - c[i].
void mulEqS(Array< double > &a, double b)
Vector multiplication in-place, a[i] *= b.
void eqS(Array< double > &a, double b)
Vector assignment, a[i] = b.
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.
void addEqVc(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, cudaReal const c)
Vector addition in-place w/ coefficient, a[i] += b[i] * c, kernel wrapper.
SCFT and PS-FTS with real periodic fields (GPU)
PSCF package top-level namespace.