1#ifndef RPG_INTRACORRELATION_TPP
2#define RPG_INTRACORRELATION_TPP
11#include "IntraCorrelation.h"
12#include <rpg/System.h>
14#include <pscf/mesh/MeshIterator.h>
15#include <pscf/chem/Debye.h>
16#include <pscf/chem/EdgeIterator.h>
17#include <pscf/iterator/NanException.h>
18#include <pscf/chem/PolymerType.h>
19#include <pscf/cuda/HostDArray.h>
20#include <prdc/crystal/shiftToMinimum.h>
30 : systemPtr_(&system),
32 { setClassName(
"IntraCorrelation"); }
36 IntraCorrelation<D>::~IntraCorrelation()
42 IntraCorrelation<D>::computeIntraCorrelations(RField<D>& correlations)
45 Mixture<D>
const & mixture = system().mixture();
46 UnitCell<D>
const & unitCell = system().domain().unitCell();
47 IntVec<D>
const & dimensions = system().domain().mesh().dimensions();
48 const int nPolymer = mixture.nPolymer();
49 const double vMonomer = mixture.vMonomer();
52 for (
int i = 0; i < D; ++i) {
54 kMeshDimensions_[i] = dimensions[i];
55 kSize_ *= dimensions[i];
57 kMeshDimensions_[i] = dimensions[i]/2 + 1;
58 kSize_ *= (dimensions[i]/2 + 1);
70 iter.setDimensions(kMeshDimensions_);
71 for (iter.begin(); !iter.atEnd(); ++iter) {
73 Gmin = shiftToMinimum(G, dimensions, unitCell);
74 Gsq[iter.rank()] = unitCell.ksq(Gmin);
77 double phi, cPolymer, polymerLength;
78 double length, lengthA, lengthB, ksq;
79 double kuhn, kuhnA, kuhnB, eA, eB;
80 int monomerId, monomerIdA, monomerIdB, rank;
83 HostDArray<cudaReal> correlations_h;
84 correlations_h.allocate(kSize_);
87 for (
int i = 0; i < correlations_h.capacity(); ++i){
88 correlations_h[i] = 0.0;
92 for (
int i = 0; i < nPolymer; i++){
95 Polymer<D>
const & polymer = mixture.polymer(i);
96 const int nBlock = polymer.nBlock();
101 for (
int j = 0; j < nBlock; j++) {
102 length = polymer.block(j).length();
103 polymerLength += length;
107 cPolymer = phi/(polymerLength*vMonomer);
110 for (
int j = 0; j < nBlock; j++) {
112 monomerId = polymer.block(j).monomerId();
113 kuhn = mixture.monomer(monomerId).kuhn();
114 length = polymer.block(j).length();
117 for (iter.begin(); !iter.atEnd(); ++iter) {
120 correlations_h[rank] += cPolymer * Debye::d(ksq, length, kuhn);
127 EdgeIterator EdgeItr(polymer);
130 for (
int ia = 1; ia < nBlock; ++ia) {
133 Block<D>
const & blockA = polymer.block(ia);
134 lengthA = blockA.length();
135 monomerIdA = blockA.monomerId();
136 kuhnA = mixture.monomer(monomerIdA).kuhn();
139 for (
int ib = 0; ib < ia; ++ib) {
142 Block<D>
const & blockB = polymer.block(ib);
143 lengthB = blockB.length();
144 monomerIdB = blockB.monomerId();
145 kuhnB = mixture.monomer(monomerIdB).kuhn();
150 EdgeItr.begin(ia, ib);
151 while (EdgeItr.notEnd()) {
152 edgeId = EdgeItr.currentEdgeId();
153 if (edgeId != ia && edgeId != ib){
154 Block<D>
const & blockK = polymer.block(edgeId);
155 double lengthK = blockK.length();
156 double monomerIdK = blockK.monomerId();
157 double kuhnK = mixture.monomer(monomerIdK).kuhn();
158 d += lengthK * kuhnK * kuhnK;
165 double prefactor = 2.0*cPolymer;
166 for (iter.begin(); !iter.atEnd(); ++iter) {
169 x = std::exp( -d * ksq / 6.0);
170 eA = Debye::e(ksq, lengthA, kuhnA);
171 eB = Debye::e(ksq, lengthB, kuhnB);
172 correlations_h[rank] += prefactor * x * eA * eB;
182 correlations = correlations_h;
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.