1#ifndef PSCF_POLYMER_TMPL_H
2#define PSCF_POLYMER_TMPL_H
11#include <pscf/chem/Species.h>
12#include <util/param/ParamComposite.h>
14#include <pscf/chem/Monomer.h>
15#include <pscf/chem/Vertex.h>
16#include <pscf/chem/PolymerType.h>
17#include <util/containers/Pair.h>
18#include <util/containers/DArray.h>
19#include <util/containers/DMatrix.h>
40 template <
class Block>
47 typedef typename Block::Propagator Propagator;
50 typedef typename Propagator::CField CField;
53 typedef typename Propagator::WField WField;
98 virtual void solve(
double phiTot = 1.0);
140 Propagator
const &
propagator(
int blockId,
int directionId)
const;
226 PolymerType::Enum type_;
233 template <
class Block>
240 template <
class Block>
247 template <
class Block>
249 {
return nPropagator_; }
254 template <
class Block>
258 for (
int blockId = 0; blockId < nBlock_; ++blockId) {
259 value += blocks_[blockId].length();
267 template <
class Block>
270 {
return vertices_[id]; }
275 template <
class Block>
277 {
return blocks_[id]; }
282 template <
class Block>
284 {
return blocks_[id]; }
289 template <
class Block>
295 return propagatorIds_[id];
301 template <
class Block>
303 typename Block::Propagator&
305 {
return block(blockId).propagator(directionId); }
310 template <
class Block>
312 typename Block::Propagator
const &
314 {
return block(blockId).propagator(directionId); }
319 template <
class Block>
324 return propagator(propId[0], propId[1]);
332 template <
class Block>
346 template <
class Block>
350 template <
class Block>
354 type_ = PolymerType::Linear;
355 readOptional<PolymerType::Enum>(in,
"type", type_);
357 read<int>(in,
"nBlock", nBlock_);
360 nVertex_ = nBlock_ + 1;
363 blocks_.allocate(nBlock_);
364 vertices_.allocate(nVertex_);
365 propagatorIds_.allocate(2*nBlock_);
368 for (
int blockId = 0; blockId < nBlock_; ++blockId) {
369 blocks_[blockId].setId(blockId);
370 blocks_[blockId].setPolymerType(type_);
374 for (
int vertexId = 0; vertexId < nVertex_; ++vertexId) {
375 vertices_[vertexId].setId(vertexId);
380 if (type_ == PolymerType::Linear) {
381 for (
int blockId = 0; blockId < nBlock_; ++blockId) {
382 blocks_[blockId].setVertexIds(blockId, blockId + 1);
387 readDArray<Block>(in,
"blocks", blocks_, nBlock_);
413 int vertexId0, vertexId1;
415 for (
int blockId = 0; blockId < nBlock_; ++blockId) {
416 blockPtr = &(blocks_[blockId]);
417 vertexId0 = blockPtr->vertexId(0);
418 vertexId1 = blockPtr->vertexId(1);
419 vertices_[vertexId0].addBlock(*blockPtr);
420 vertices_[vertexId1].addBlock(*blockPtr);
430 bool hasPhi = readOptional(in,
"phi", phi_).isActive();
432 ensemble_ = Species::Closed;
434 ensemble_ = Species::Open;
439 Vertex const * vertexPtr = 0;
440 Propagator
const * sourcePtr = 0;
441 Propagator * propagatorPtr = 0;
443 int blockId, directionId, vertexId, i;
444 for (blockId = 0; blockId < nBlock(); ++blockId) {
446 for (directionId = 0; directionId < 2; ++directionId) {
447 vertexId = block(blockId).vertexId(directionId);
448 vertexPtr = &vertex(vertexId);
449 propagatorPtr = &block(blockId).propagator(directionId);
450 for (i = 0; i < vertexPtr->
size(); ++i) {
452 if (propagatorId[0] == blockId) {
456 &block(propagatorId[0]).propagator(propagatorId[1]);
457 propagatorPtr->addSource(*sourcePtr);
469 template <
class Block>
472 if (nPropagator_ != 0) {
479 for (
int iBlock = 0; iBlock < nBlock_; ++iBlock) {
480 for (
int iDirection = 0; iDirection < 2; ++iDirection) {
481 isFinished(iBlock, iDirection) =
false;
489 while (nPropagator_ < nBlock_*2) {
490 for (
int iBlock = 0; iBlock < nBlock_; ++iBlock) {
491 for (
int iDirection = 0; iDirection < 2; ++iDirection) {
492 if (isFinished(iBlock, iDirection) ==
false) {
493 inVertexId = blocks_[iBlock].vertexId(iDirection);
494 inVertexPtr = &vertices_[inVertexId];
496 for (
int j = 0; j < inVertexPtr->
size(); ++j) {
498 if (propagatorId[0] != iBlock) {
499 if (!isFinished(propagatorId[0], propagatorId[1])) {
506 propagatorIds_[nPropagator_][0] = iBlock;
507 propagatorIds_[nPropagator_][1] = iDirection;
508 isFinished(iBlock, iDirection) =
true;
521 template <
class Block>
526 for (
int j = 0; j < nPropagator(); ++j) {
527 propagator(j).setIsSolved(
false);
532 for (
int j = 0; j < nPropagator(); ++j) {
534 propagator(j).solve();
538 q_ = block(0).propagator(0).computeQ();
545 if (ensemble() == Species::Closed) {
548 if (ensemble() == Species::Open) {
553 double prefactor = phi_ / ( q_ * length() );
554 for (
int i = 0; i < nBlock(); ++i) {
555 block(i).computeConcentration(prefactor);
Descriptor and MDE solver for an acyclic block polymer.
Block const & block(int id) const
Get a specified Block by const reference.
virtual void readParameters(std::istream &in)
Read and initialize.
virtual void makePlan()
Make a plan for order in which propagators should be computed.
Block & block(int id)
Get a specified Block.
PolymerTmpl()
Constructor.
const Pair< int > & propagatorId(int id) const
Get propagator identifier, indexed by order of computation.
int nBlock() const
Number of blocks.
Propagator & propagator(int blockId, int directionId)
Get propagator for a specific block and direction.
int nPropagator() const
Number of propagators (nBlock*2).
Propagator const & propagator(int blockId, int directionId) const
Get a const propagator for a specific block and direction.
~PolymerTmpl()
Destructor.
Propagator & propagator(int id)
Get propagator indexed in order of computation.
int nVertex() const
Number of vertices (junctions and chain ends).
virtual void solve(double phiTot=1.0)
Solve modified diffusion equation.
double length() const
Sum of the lengths of all blocks in the polymer.
const Vertex & vertex(int id) const
Get a specified Vertex by const reference.
Base class for a molecular species (polymer or solvent).
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.
Dynamically allocated Matrix.
void allocate(int capacity1, int capacity2)
Allocate memory for a matrix.
An array of exactly 2 objects.
An object that can read multiple parameters from file.
void setClassName(const char *className)
Set class name string.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.