1#ifndef RPC_INTRACORRELATION_TPP
2#define RPC_INTRACORRELATION_TPP
11#include "IntraCorrelation.h"
12#include <rpc/System.h>
14#include <pscf/mesh/MeshIterator.h>
15#include <pscf/chem/Debye.h>
16#include <pscf/chem/EdgeIterator.h>
17#include <prdc/crystal/shiftToMinimum.h>
27 : systemPtr_(&system),
29 { setClassName(
"IntraCorrelation"); }
33 IntraCorrelation<D>::~IntraCorrelation()
38 IntraCorrelation<D>::computeIntraCorrelations(RField<D>& correlations)
41 Mixture<D>
const & mixture = system().mixture();
42 UnitCell<D>
const & unitCell = system().domain().unitCell();
43 IntVec<D>
const & dimensions = system().domain().mesh().dimensions();
44 const int nPolymer = mixture.nPolymer();
45 const double vMonomer = mixture.vMonomer();
48 for (
int i = 0; i < D; ++i) {
50 kMeshDimensions_[i] = dimensions[i];
51 kSize_ *= dimensions[i];
53 kMeshDimensions_[i] = dimensions[i]/2 + 1;
54 kSize_ *= (dimensions[i]/2 + 1);
66 iter.setDimensions(kMeshDimensions_);
67 for (iter.begin(); !iter.atEnd(); ++iter) {
69 Gmin = shiftToMinimum(G, dimensions, unitCell);
70 Gsq[iter.rank()] = unitCell.ksq(Gmin);
73 double phi, cPolymer, polymerLength;
74 double length, lengthA, lengthB, ksq;
75 double kuhn, kuhnA, kuhnB, eA, eB;
76 int monomerId, monomerIdA, monomerIdB, rank;
79 for (
int i = 0; i < correlations.capacity(); ++i){
80 correlations[i] = 0.0;
84 for (
int i = 0; i < nPolymer; i++){
87 Polymer<D>
const & polymer = mixture.polymer(i);
88 const int nBlock = polymer.nBlock();
93 for (
int j = 0; j < nBlock; j++) {
94 length = polymer.block(j).length();
95 polymerLength += length;
99 cPolymer = phi/(polymerLength*vMonomer);
102 for (
int j = 0; j < nBlock; j++) {
104 monomerId = polymer.block(j).monomerId();
105 kuhn = mixture.monomer(monomerId).kuhn();
106 length = polymer.block(j).length();
109 for (iter.begin(); !iter.atEnd(); ++iter) {
112 correlations[rank] += cPolymer * Debye::d(ksq, length, kuhn);
119 EdgeIterator EdgeItr(polymer);
122 for (
int ia = 1; ia < nBlock; ++ia) {
125 Block<D>
const & blockA = polymer.block(ia);
126 lengthA = blockA.length();
127 monomerIdA = blockA.monomerId();
128 kuhnA = mixture.monomer(monomerIdA).kuhn();
131 for (
int ib = 0; ib < ia; ++ib) {
134 Block<D>
const & blockB = polymer.block(ib);
135 lengthB = blockB.length();
136 monomerIdB = blockB.monomerId();
137 kuhnB = mixture.monomer(monomerIdB).kuhn();
142 EdgeItr.begin(ia, ib);
143 while (EdgeItr.notEnd()) {
144 edgeId = EdgeItr.currentEdgeId();
145 if (edgeId != ia && edgeId != ib){
146 Block<D>
const & blockK = polymer.block(edgeId);
147 double lengthK = blockK.length();
148 double monomerIdK = blockK.monomerId();
149 double kuhnK = mixture.monomer(monomerIdK).kuhn();
150 d += lengthK * kuhnK * kuhnK;
157 double prefactor = 2.0*cPolymer;
158 for (iter.begin(); !iter.atEnd(); ++iter) {
161 x = std::exp( -d * ksq / 6.0);
162 eA = Debye::e(ksq, lengthA, kuhnA);
163 eB = Debye::e(ksq, lengthB, kuhnB);
164 correlations[rank] += prefactor * x * eA * eB;
IntraCorrelation(System< D > &system)
Constructor.
Dynamically allocatable contiguous array template.
void allocate(int capacity)
Allocate the underlying C array.
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
double d(double ksq, double length, double kuhn)
Compute and return a homopolymer correlation function.
PSCF package top-level namespace.
Utility classes for scientific computation.