12#include <prdc/crystal/UnitCell.h>
13#include <prdc/crystal/shiftToMinimum.h>
14#include <pscf/mesh/Mesh.h>
15#include <pscf/mesh/MeshIterator.h>
16#include <pscf/math/IntVec.h>
17#include <util/containers/DMatrix.h>
18#include <util/containers/DArray.h>
19#include <util/containers/FArray.h>
20#include <util/containers/FSArray.h>
85 UTIL_CHECK(mesh().dimensions() == fft().meshDimensions());
92 tempNs = floor( length()/(2.0 *ds) + 0.5 );
97 ds_ = length()/double(ns_-1);
101 for (
int i = 0; i < D; ++i) {
103 kMeshDimensions_[i] = mesh().dimensions()[i];
105 kMeshDimensions_[i] = mesh().dimensions()[i]/2 + 1;
107 kSize_ *= kMeshDimensions_[i];
111 expKsq_.allocate(kMeshDimensions_);
112 expKsq2_.allocate(kMeshDimensions_);
113 expW_.allocate(mesh().dimensions());
114 expW2_.allocate(mesh().dimensions());
115 qr_.allocate(mesh().dimensions());
116 qk_.allocate(mesh().dimensions());
117 qr2_.allocate(mesh().dimensions());
118 qk2_.allocate(mesh().dimensions());
121 dGsq_.allocate(kSize_, 6);
124 cField().allocate(mesh().dimensions());
127 propagator(0).allocate(ns_, mesh());
128 propagator(1).allocate(ns_, mesh());
147 tempNs = floor( length()/(2.0 *dsTarget_) + 0.5 );
152 ds_ = length()/double(ns_-1);
157 propagator(0).reallocate(ns_);
158 propagator(1).reallocate(ns_);
180 { hasExpKsq_ =
false; }
196 double factor = -1.0*kuhn()*kuhn()*ds_/6.0;
201 Gmin = shiftToMinimum(G, mesh().dimensions(), unitCell());
202 Gsq = unitCell().ksq(Gmin);
203 expKsq_[i] = exp(Gsq*factor);
204 expKsq2_[i] = exp(Gsq*factor*0.5);
218 int nx = mesh().size();
223 for (
int i = 0; i < nx; ++i) {
231 expW_[i] = exp(-0.5*w[i]*ds_);
232 expW2_[i] = exp(-0.5*0.5*w[i]*ds_);
250 int nx = mesh().size();
260 for (i = 0; i < nx; ++i) {
264 Propagator<D>
const & p0 = propagator(0);
265 Propagator<D>
const & p1 = propagator(1);
270 for (i = 0; i < nx; ++i) {
271 cField()[i] += p0.q(0)[i]*p1.q(ns_ - 1)[i];
272 cField()[i] += p0.q(ns_ -1)[i]*p1.q(0)[i];
277 for (j = 1; j < (ns_ -1); j += 2) {
278 for (i = 0; i < nx; ++i) {
279 cField()[i] += p0.q(j)[i] * p1.q(ns_ - 1 - j)[i] * 4.0;
284 for (j = 2; j < (ns_ -2); j += 2) {
285 for (i = 0; i < nx; ++i) {
286 cField()[i] += p0.q(j)[i] * p1.q(ns_ - 1 - j)[i] * 2.0;
291 prefactor *= ds_ / 3.0;
292 for (i = 0; i < nx; ++i) {
293 cField()[i] *= prefactor;
305 int nx = mesh().size();
308 UTIL_CHECK(mesh().dimensions() == fft().meshDimensions());
316 double dels, normal, increment;
321 nParam = unitCell().nParameter();
328 for (i = 0; i < nParam; ++i) {
335 Propagator<D>
const & p0 = propagator(0);
336 Propagator<D>
const & p1 = propagator(1);
339 for (
int j = 0; j < ns_ ; ++j) {
342 fft().forwardTransform(qr_, qk_);
344 qr2_ = p1.q(ns_ - 1 - j);
345 fft().forwardTransform(qr2_, qk2_);
349 if (j != 0 && j != ns_ - 1) {
357 for (
int n = 0; n < nParam ; ++n) {
360 for (m = 0; m < c ; ++m) {
362 prod = (qk2_[m][0] * qk_[m][0]) + (qk2_[m][1] * qk_[m][1]);
366 increment = (increment * kuhn() * kuhn() * dels)/normal;
367 dQ[n] = dQ[n] - increment;
372 for (i = 0; i < nParam; ++i) {
373 stress_[i] = stress_[i] - (dQ[i] * prefactor);
390 for (
int n = 0; n < unitCell().nParameter() ; ++n) {
393 vec = shiftToMinimum(temp, mesh().dimensions(), unitCell());
394 dGsq_(iter.
rank(), n) = unitCell().dksq(vec, n);
395 for (
int p = 0; p < D; ++p) {
397 Partner[p] = mesh().dimensions()[p] - temp[p];
402 if (Partner[D-1] > kMeshDimensions_[D-1]) {
403 dGsq_(iter.
rank(), n) *= 2;
416 int nx = mesh().size();
419 UTIL_CHECK(mesh().dimensions() == fft().meshDimensions());
423 int nk = qk_.capacity();
440 for (i = 0; i < nx; ++i) {
441 qr_[i] = q[i]*expW_[i];
442 qr2_[i] = q[i]*expW2_[i];
444 fft().forwardTransform(qr_, qk_);
445 fft().forwardTransform(qr2_, qk2_);
446 for (i = 0; i < nk; ++i) {
447 qk_[i][0] *= expKsq_[i];
448 qk_[i][1] *= expKsq_[i];
449 qk2_[i][0] *= expKsq2_[i];
450 qk2_[i][1] *= expKsq2_[i];
452 fft().inverseTransformUnsafe(qk_, qr_);
453 fft().inverseTransformUnsafe(qk2_, qr2_);
454 for (i = 0; i < nx; ++i) {
455 qr_[i] = qr_[i]*expW_[i];
456 qr2_[i] = qr2_[i]*expW_[i];
460 fft().forwardTransform(qr2_, qk2_);
461 for (i = 0; i < nk; ++i) {
462 qk2_[i][0] *= expKsq2_[i];
463 qk2_[i][1] *= expKsq2_[i];
465 fft().inverseTransformUnsafe(qk2_, qr2_);
466 for (i = 0; i < nx; ++i) {
467 qr2_[i] = qr2_[i]*expW2_[i];
471 for (i = 0; i < nx; ++i) {
472 qNew[i] = (4.0*qr2_[i] - qr_[i])/3.0;
virtual void setLength(double length)
Set the length of this block.
Class template for a block in a block copolymer.
Propagator< D > & propagator(int directionId)
An IntVec<D, T> is a D-component vector of elements of integer type T.
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.
Description of a regular grid of points in a periodic domain.
Fourier transform wrapper.
bool isAllocated() const
Return true if the FftwDArray has been allocated, false otherwise.
Field of real double precision values on an FFT mesh.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Block within a branched polymer.
void computeStress(double prefactor)
Compute stress contribution for this block.
void setLength(double newLength)
Set or reset block length.
void setKuhn(double kuhn)
Set or reset monomer statistical segment length.
void clearUnitCellData()
Clear all internal data that depends on the unit cell parameters.
void setupSolver(RField< D > const &w)
Set solver for this block.
void allocate(double ds)
Allocate memory and set contour step size.
void associate(Mesh< D > const &mesh, FFT< D > const &fft, UnitCell< D > const &cell)
Initialize discretization and allocate required memory.
void step(RField< D > const &q, RField< D > &qNew)
Compute one step of solution of MDE, from step i to i+1.
void computeConcentration(double prefactor)
Compute concentration (volume fraction) for block by integration.
int capacity() const
Return allocated size.
A fixed capacity (static) contiguous array with a variable logical size.
void append(Data const &data)
Append data to the end of the array.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Fields and FFTs for periodic boundary conditions (CPU)
Periodic fields and crystallography.
PSCF package top-level namespace.
Utility classes for scientific computation.