1#ifndef PRDC_MIXTURE_REAL_TPP
2#define PRDC_MIXTURE_REAL_TPP
11#include "MixtureReal.h"
12#include <prdc/crystal/UnitCell.h>
13#include <pscf/mesh/Mesh.h>
14#include <pscf/chem/Monomer.h>
15#include <pscf/chem/PolymerModel.h>
16#include <util/containers/DArray.h>
17#include <util/misc/ioUtil.h>
18#include <util/misc/FileMaster.h>
26 template <
int D,
class PT,
class ST>
31 unitCellPtr_(nullptr),
41 template <
int D,
class PT,
class ST>
48 template <
int D,
class PT,
class ST>
69 template <
int D,
class PT,
class ST>
92 for (j = 0; j <
polymer(i).nBlock(); ++j) {
93 polymer(i).block(j).associate(
mesh, fft, cell, waveList);
100 for (
int i = 0; i <
nSolvent(); ++i) {
110 template <
int D,
class PT,
class ST>
117 template <
int D,
class PT,
class ST>
132 for (j = 0; j <
polymer(i).nBlock(); ++j) {
133 polymer(i).block(j).allocate(ds_);
140 if (nSolvent() > 0) {
141 for (
int i = 0; i < nSolvent(); ++i) {
142 solvent(i).allocate();
152 template <
int D,
class PT,
class ST>
156 for (
int i = 0; i <
nPolymer(); ++i) {
157 polymer(i).clearUnitCellData();
167 template <
int D,
class PT,
class ST>
171 monomer(monomerId).setKuhn(kuhn);
174 for (
int i = 0; i <
nPolymer(); ++i) {
175 for (
int j = 0; j <
polymer(i).nBlock(); ++j) {
177 if (monomerId == block.monomerId()) {
190 template <
int D,
class PT,
class ST>
207 for (i = 0; i < nm; ++i) {
208 eqS(cFields[i], 0.0);
212 if (nPolymer() > 0) {
215 for (i = 0; i < nPolymer(); ++i) {
220 for (i = 0; i < nPolymer(); ++i) {
221 for (j = 0; j < polymer(i).nBlock(); ++j) {
222 monomerId = polymer(i).block(j).monomerId();
225 FieldT& monomerField = cFields[monomerId];
226 FieldT
const & blockField = polymer(i).block(j).cField();
227 addEqV(monomerField, blockField);
234 if (nSolvent() > 0) {
237 for (i = 0; i < nSolvent(); ++i) {
238 monomerId = solvent(i).monomerId();
239 solvent(i).compute(wFields[monomerId], phiTot);
243 for (i = 0; i < nSolvent(); ++i) {
244 monomerId = solvent(i).monomerId();
247 FieldT& monomerField = cFields[monomerId];
249 addEqV(monomerField, solventField);
254 isSymmetric_ =
false;
261 template <
int D,
class PT,
class ST>
263 { isSymmetric_ = isSymmetric; }
268 template <
int D,
class PT,
class ST>
277 for (i = 0; i < nParam_; ++i) {
289 for (i = 0; i < nParam_; ++i) {
290 for (j = 0; j < nPolymer(); ++j) {
291 stress_[i] += polymer(j).stress(i);
299 for (i = 0; i < nParam_; ++i) {
300 stress_[i] /= phiTot;
314 template <
int D,
class PT,
class ST>
321 int nx =
mesh().size();
331 for (i = 0; i < np; ++i) {
332 if (!blockCFields[i].isAllocated()) {
333 blockCFields[i].
allocate(mesh().dimensions());
335 eqS(blockCFields[i], 0.0);
342 if (nPolymer() > 0) {
343 for (i = 0; i < nPolymer(); ++i) {
344 for (j = 0; j < polymer(i).nBlock(); ++j) {
348 blockCFields[sectionId] = polymer(i).block(j).cField();
356 if (nSolvent() > 0) {
361 blockCFields[sectionId] =
solvent(i).cField();
373 template <
int D,
class PT,
class ST>
384 for (
int i = 0; i < np; i++) {
392 fieldIo().writeFieldsRGrid(filename, blockCFields,
401 template <
int D,
class PT,
class ST>
403 std::string
const & filename,
419 propagator = polymerRef.propagator(blockId, directionId);
420 FieldT const & field = propagator.q(sliceId);
427 template <
int D,
class PT,
class ST>
429 std::string
const & filename,
432 int directionId)
const
444 field = polymerRef.propagator(blockId, directionId).tail();
451 template <
int D,
class PT,
class ST>
453 std::string
const & filename,
456 int directionId)
const
468 propagator = polymerRef.propagator(blockId, directionId);
469 int ns = propagator.ns();
473 fieldIo().fileMaster().openOutputFile(filename, file);
477 file <<
"mesh" << std::endl
478 <<
" " <<
mesh().dimensions() << std::endl
479 <<
"nslice" << std::endl
480 <<
" " << ns << std::endl;
483 bool hasHeader =
false;
484 for (
int i = 0; i < ns; ++i) {
485 file <<
"slice " << i << std::endl;
495 template <
int D,
class PT,
class ST>
499 std::string filename;
500 int np, nb, ip, ib, id;
502 for (ip = 0; ip < np; ++ip) {
504 for (ib = 0; ib < nb; ++ib) {
505 for (
id = 0;
id < 2; ++id) {
514 writeQ(filename, ip, ib,
id);
523 template <
int D,
class PT,
class ST>
528 out <<
"stress:" << std::endl;
530 for (
int i = 0; i < nParam_; i++) {
533 <<
Dbl(stress_[i], 18, 11)
Description of a regular grid of points in a periodic domain.
virtual void readParameters(std::istream &in)
Read parameters from file and initialize.
typename BlockT::FieldIoT FieldIoT
FieldIo type.
SolventT & solvent(int id)
void associate(Mesh< D > const &mesh, FFTT const &fft, UnitCell< D > const &cell, WaveListT &waveList)
Create associations with Mesh, FFT, UnitCell, and WaveList objects.
void writeStress(std::ostream &out) const
Write stress values to output stream.
void clearUnitCellData()
Clear all data that depends on the unit cell parameters.
void writeQAll(std::string const &basename)
Write all propagators of all blocks, each to a separate file.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
void setFieldIo(FieldIoT const &fieldIo)
Create an association with a FieldIoT object.
void setClassName(const char *className)
Set class name string.
typename PT::BlockT BlockT
Block polymer block type.
FieldIoT const & fieldIo() const
Return associated FieldIoT by const reference.
virtual void readParameters(std::istream &in)
Read all parameters and initialize.
~MixtureReal()
Destructor.
int nPolymer() const
Get number of polymer species.
void writeBlockCRGrid(std::string const &filename) const
Write c fields for all blocks and solvents in r-grid format.
Monomer const & monomer(int id) const
Get a Monomer type descriptor by const reference.
PT PolymerT
Polymer species solver type.
void writeQTail(std::string const &filename, int polymerId, int blockId, int directionId) const
Write the final slice of a propagator in r-grid format.
void compute(DArray< FieldT > const &wFields, DArray< FieldT > &cFields, double phiTot=1.0)
Compute partition functions and concentrations.
int nMonomer() const
Get number of monomer types.
int nBlock() const
Get total number blocks among all polymer species.
void setIsSymmetric(bool isSymmetric)
Set the isSymmetric flag true or false.
PolymerT & polymer(int id)
Get a polymer solver object by non-const reference.
int nSolvent() const
Get number of solvent (point particle) species.
void createBlockCRGrid(DArray< FieldT > &blockCFields) const
Get c-fields for all blocks and solvents as array of r-grid fields.
void writeQSlice(std::string const &filename, int polymerId, int blockId, int directionId, int segmentId) const
Write one slice of a propagator at fixed s in r-grid format.
void computeStress(double phiTot=1.0)
Compute derivatives of free energy w/ respect to cell parameters.
MixtureReal()
Constructor.
typename BlockT::FFTT FFTT
WaveList type.
UnitCell< D > const & unitCell() const
Return associated UnitCell<D> by const reference.
typename BlockT::WaveListT WaveListT
WaveList type.
Mesh< D > const & mesh() const
Return associated Mesh<D> by const reference.
typename BlockT::PropagatorT PropagatorT
Polymer block propagator type.
void setKuhn(int monomerId, double kuhn)
Reset statistical segment length for one monomer type.
void writeQ(std::string const &filename, int polymerId, int blockId, int directionId) const
Write the complete propagator for one block, in r-grid format.
typename PropagatorT::FieldT FieldT
void allocate()
Allocate required internal memory for all solvers.
int nParameter() const
Get the number of parameters in the unit cell.
Base template for UnitCell<D> classes, D=1, 2 or 3.
int capacity() const
Return allocated size.
Dynamically allocatable contiguous array template.
void allocate(int capacity)
Allocate the underlying C array.
bool isAllocated() const
Return true if this DArray has been allocated, false otherwise.
Wrapper for a double precision number, for formatted ostream output.
Wrapper for an int, for formatted ostream output.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
std::string toString(int n)
Return string representation of an integer.
bool isThread()
Is the thread model in use ?
Periodic fields and crystallography.
PSCF package top-level namespace.