1#ifndef PSCF_POLYMER_TMPL_H
2#define PSCF_POLYMER_TMPL_H
11#include <pscf/chem/PolymerSpecies.h>
12#include <util/containers/DArray.h>
15#include <pscf/chem/Vertex.h>
16#include <pscf/chem/PolymerType.h>
17#include <util/containers/Pair.h>
45 template <
class Block>
52 typedef typename Block::Propagator Propagator;
55 typedef typename Propagator::CField CField;
58 typedef typename Propagator::WField WField;
103 virtual void solve(
double phiTot = 1.0);
159 Propagator
const &
propagator(
int blockId,
int directionId)
const;
212 template <
class Block>
214 {
return blocks_[id]; }
219 template <
class Block>
222 {
return blocks_[id]; }
227 template <
class Block>
230 {
return blocks_[id]; }
235 template <
class Block>
238 {
return blocks_[id]; }
243 template <
class Block>
245 typename Block::Propagator&
247 {
return block(blockId).propagator(directionId); }
252 template <
class Block>
254 typename Block::Propagator
const &
256 {
return block(blockId).propagator(directionId); }
261 template <
class Block>
266 return propagator(propId[0], propId[1]);
274 template <
class Block>
283 template <
class Block>
287 template <
class Block>
289 { blocks_.allocate(nBlock()); }
291 template <
class Block>
293 { readDArray<Block>(in,
"blocks", blocks_, nBlock()); }
295 template <
class Block>
302 Vertex const * vertexPtr = 0;
303 Propagator
const * sourcePtr = 0;
304 Propagator * propagatorPtr = 0;
306 int blockId, directionId, vertexId, i;
307 for (blockId = 0; blockId < nBlock(); ++blockId) {
309 for (directionId = 0; directionId < 2; ++directionId) {
310 vertexId = block(blockId).vertexId(directionId);
311 vertexPtr = &vertex(vertexId);
312 propagatorPtr = &block(blockId).propagator(directionId);
313 for (i = 0; i < vertexPtr->
size(); ++i) {
315 if (propagatorId[0] == blockId) {
319 &block(propagatorId[0]).propagator(propagatorId[1]);
320 propagatorPtr->addSource(*sourcePtr);
332 template <
class Block>
337 for (
int j = 0; j < nPropagator(); ++j) {
338 propagator(j).setIsSolved(
false);
343 for (
int j = 0; j < nPropagator(); ++j) {
345 propagator(j).solve();
349 q_ = block(0).propagator(0).computeQ();
356 if (ensemble() == Species::Closed) {
359 if (ensemble() == Species::Open) {
364 double prefactor = phi_ / ( q_ * length() );
365 for (
int i = 0; i < nBlock(); ++i) {
366 block(i).computeConcentration(prefactor);
Descriptor for a block within an acyclic block polymer.
Descriptor for a linear or acyclic branched block polymer.
const Vertex & vertex(int id) const
Get a specified Vertex by const reference.
Pair< int > const & path(int is, int it) const
Get an id for a propagator from one vertex towards a target.
int nVertex() const
Number of vertices (junctions and chain ends).
virtual Edge & edge(int id)=0
Get a specified Edge (block descriptor) by non-const reference.
virtual void readParameters(std::istream &in)
Read parameters and initialize.
int nPropagator() const
Number of propagators (2*nBlock).
int nBlock() const
Number of blocks.
double length() const
Sum of the lengths of all blocks in the polymer.
Pair< int > const & propagatorId(int id) const
Get a propagator identifier, indexed by order of computation.
PolymerType::Enum type() const
Get Polymer type (Branched or Linear)
Descriptor and MDE solver for an acyclic branched block polymer.
Block const & block(int id) const
Get a specified Block (solver and descriptor) by const reference.
virtual void readParameters(std::istream &in)
Read and initialize.
virtual Edge & edge(int id)
Get a specified Edge (block descriptor) by non-const reference.
Block & block(int id)
Get a specified Block (block solver and descriptor)
PolymerTmpl()
Constructor.
Propagator & propagator(int blockId, int directionId)
Get the Propagator for a specific block and direction (non-const).
Propagator const & propagator(int blockId, int directionId) const
Get the Propagator for a specific block and direction (const).
virtual Edge const & edge(int id) const
Get a specified Edge (block descriptor) by const reference.
virtual void allocateBlocks()
Allocate array of Block objects.
virtual void readBlocks(std::istream &in)
Read array of data for blocks from parameter file.
~PolymerTmpl()
Destructor.
Propagator & propagator(int id)
Get propagator indexed in order of computation (non-const).
virtual void solve(double phiTot=1.0)
Solve modified diffusion equation.
double phi() const
Get the overall volume fraction for this species.
Ensemble ensemble()
Get the statistical ensemble for this species (open or closed).
double mu() const
Get the chemical potential for this species (units kT=1).
double q() const
Get the molecular partition function for this species.
A junction or chain end in a block polymer.
int size() const
Get the number of attached blocks.
Pair< int > const & inPropagatorId(int i) const
Get the block and direction of an incoming propagator.
Dynamically allocatable contiguous array template.
An array of exactly 2 objects.
void setClassName(const char *className)
Set class name string.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
PSCF package top-level namespace.
Utility classes for scientific computation.