9#include <r1d/solvers/Polymer.h>
10#include <r1d/solvers/Solvent.h>
12#include <r1d/iterator/Iterator.h>
13#include <r1d/iterator/IteratorFactory.h>
14#include <r1d/sweep/Sweep.h>
15#include <r1d/sweep/SweepFactory.h>
16#include <r1d/iterator/NrIterator.h>
17#include <r1d/system/HomogeneousComparison.h>
18#include <r1d/field/FieldIo.h>
20#include <pscf/interaction/Interaction.h>
22#include <util/format/Str.h>
23#include <util/format/Int.h>
24#include <util/format/Dbl.h>
25#include <util/param/BracketPolicy.h>
26#include <util/misc/ioUtil.h>
47 iteratorFactoryPtr_(0),
65 fieldIo_.associate(domain_, fileMaster_);
78 if (interactionPtr_) {
79 delete interactionPtr_;
84 if (iteratorFactoryPtr_) {
85 delete iteratorFactoryPtr_;
90 if (sweepFactoryPtr_) {
91 delete sweepFactoryPtr_;
113 while ((c = getopt(argc, argv,
"er:p:c:i:o:f")) != -1) {
135 Log::file() <<
"Unknown option -" << optopt << std::endl;
185 iteratorPtr_ = iteratorFactoryPtr_->readObject(in, *
this,
188 std::string msg =
"Unrecognized Iterator subclass name ";
195 sweepFactoryPtr_->readObjectOptional(in, *
this,
className, isEnd);
198 sweepPtr_->setSystem(*
this);
225 out <<
"System{" << std::endl;
226 mixture_.writeParam(out);
227 interactionPtr_->writeParam(out);
228 domain_.writeParam(out);
229 iteratorPtr_->writeParam(out);
230 out <<
"}" << std::endl;
236 void System::allocateFields()
247 wFields_.allocate(nMonomer);
248 cFields_.allocate(nMonomer);
250 for (
int i = 0; i < nMonomer; ++i) {
266 std::string filename;
268 std::istream& inBuffer = in;
270 bool readNext =
true;
275 if (inBuffer.eof()) {
281 if (command ==
"FINISH") {
285 if (command ==
"READ_W") {
286 readEcho(inBuffer, filename);
287 fieldIo_.readFields(
wFields(), filename);
289 if (command ==
"COMPUTE") {
294 if (command ==
"ITERATE") {
296 bool isContinuation =
false;
297 int fail =
iterate(isContinuation);
302 if (command ==
"SWEEP") {
307 if (command ==
"WRITE_PARAM") {
308 readEcho(inBuffer, filename);
314 if (command ==
"WRITE_THERMO") {
315 readEcho(inBuffer, filename);
321 if (command ==
"COMPARE_HOMOGENEOUS") {
325 readEcho(inBuffer, filename);
327 Log::file() <<
"mode = " << mode << std::endl;
334 comparison.
output(mode, file);
337 if (command ==
"WRITE_W") {
338 readEcho(inBuffer, filename);
339 fieldIo_.writeFields(
wFields(), filename);
341 if (command ==
"WRITE_C") {
342 readEcho(inBuffer, filename);
343 fieldIo_.writeFields(
cFields(), filename);
345 if (command ==
"WRITE_BLOCK_C") {
346 readEcho(inBuffer, filename);
347 fieldIo_.writeBlockCFields(mixture_, filename);
349 if (command ==
"WRITE_Q_SLICE") {
350 int polymerId, blockId, directionId, segmentId;
351 readEcho(inBuffer, filename);
352 inBuffer >> polymerId;
354 inBuffer >> directionId;
355 inBuffer >> segmentId;
356 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
357 <<
Str(
"block ID ", 21) << blockId <<
"\n"
358 <<
Str(
"direction ID ", 21) << directionId <<
"\n"
359 <<
Str(
"segment ID ", 21) << segmentId << std::endl;
360 writeQSlice(filename, polymerId, blockId, directionId,
363 if (command ==
"WRITE_Q_TAIL") {
364 readEcho(inBuffer, filename);
365 int polymerId, blockId, directionId;
366 inBuffer >> polymerId;
368 inBuffer >> directionId;
369 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
370 <<
Str(
"block ID ", 21) << blockId <<
"\n"
371 <<
Str(
"direction ID ", 21) << directionId <<
"\n";
372 writeQTail(filename, polymerId, blockId, directionId);
374 if (command ==
"WRITE_Q_VERTEX") {
375 int polymerId, vertexId;
376 inBuffer >> polymerId;
379 <<
Int(polymerId, 5) << std::endl;
380 inBuffer >> vertexId;
382 <<
Int(vertexId, 5) << std::endl;
383 inBuffer >> filename;
385 <<
Str(filename, 20) << std::endl;
386 fieldIo_.writeVertexQ(mixture_, polymerId, vertexId, filename);
388 if (command ==
"WRITE_Q") {
389 readEcho(inBuffer, filename);
390 int polymerId, blockId, directionId;
391 inBuffer >> polymerId;
393 inBuffer >> directionId;
394 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
395 <<
Str(
"block ID ", 21) << blockId <<
"\n"
396 <<
Str(
"direction ID ", 21) << directionId <<
"\n";
397 writeQ(filename, polymerId, blockId, directionId);
399 if (command ==
"WRITE_Q_ALL") {
400 readEcho(inBuffer, filename);
403 if (command ==
"REMESH_W") {
408 inBuffer >> filename;
409 Log::file() <<
"outfile = " <<
Str(filename, 20) << std::endl;
410 fieldIo_.remesh(
wFields(), nx, filename);
412 if (command ==
"EXTEND_W") {
417 inBuffer >> filename;
418 Log::file() <<
"outfile = " <<
Str(filename, 20) << std::endl;
419 fieldIo_.extend(
wFields(), m, filename);
421 Log::file() <<
" Error: Unknown command "
422 << command << std::endl;
443 void System::readEcho(std::istream& in, std::string&
string)
const
459 mixture_.compute(
wFields(), cFields_);
517 for (
int i = 0; i < np; ++i) {
519 phi = polymerPtr->
phi();
520 mu = polymerPtr->
mu();
522 length = polymerPtr->
length();
524 fHelmholtz_ += phi*( mu - 1.0 )/length;
533 for (
int i = 0; i < ns; ++i) {
535 phi = solventPtr->
phi();
536 mu = solventPtr->
mu();
538 size = solventPtr->
size();
540 fHelmholtz_ += phi*( mu - 1.0 )/size;
546 for (
int i = 0; i < nm; ++i) {
550 fIdeal_ = fHelmholtz_;
554 if (!f_.isAllocated()) f_.allocate(nx);
555 if (!c_.isAllocated()) c_.allocate(nm);
559 for (
int i = 0; i < nx; ++i) {
561 for (j = 0; j < nm; ++j) {
562 c_[j] = cFields_[j][i];
567 for (j = 0; j < nm; ++j) {
568 for (k = 0; k < nm; ++k) {
569 f_[i] += c_[j]*chi(j, k)*c_[k];
575 fInter_ = fHelmholtz_ - fIdeal_;
578 pressure_ = -fHelmholtz_;
582 for (
int i = 0; i < np; ++i) {
584 phi = polymerPtr->
phi();
585 mu = polymerPtr->
mu();
586 length = polymerPtr->
length();
588 pressure_ += phi*mu/length;
595 for (
int i = 0; i < ns; ++i) {
597 phi = solventPtr->
phi();
598 mu = solventPtr->
mu();
599 size = solventPtr->
size();
601 pressure_ += phi*mu/size;
611 out <<
"fHelmholtz " <<
Dbl(
fHelmholtz(), 18, 11) << std::endl;
612 out <<
"pressure " <<
Dbl(
pressure(), 18, 11) << std::endl;
614 out <<
"fIdeal " <<
Dbl(fIdeal_, 18, 11) << std::endl;
615 out <<
"fInter " <<
Dbl(fInter_, 18, 11) << std::endl;
621 out <<
"polymers:" << std::endl;
626 for (
int i = 0; i < np; ++i) {
628 <<
" " <<
Dbl(
mixture().polymer(i).phi(),18, 11)
629 <<
" " <<
Dbl(
mixture().polymer(i).mu(), 18, 11)
638 out <<
"solvents:" << std::endl;
643 for (
int i = 0; i < ns; ++i) {
645 <<
" " <<
Dbl(
mixture().solvent(i).phi(),18, 11)
646 <<
" " <<
Dbl(
mixture().solvent(i).mu(), 18, 11)
662 fieldIo_.writeFields(
wFields(), filename);
671 fieldIo_.writeFields(
cFields(), filename);
681 fieldIo_.writeBlockCFields(mixture_, filename);
688 int polymerId,
int blockId,
689 int directionId,
int segmentId)
694 Polymer const& polymer = mixture_.polymer(polymerId);
700 propagator = polymer.
propagator(blockId, directionId);
701 Field const& field = propagator.
q(segmentId);
702 fieldIo_.writeField(field, filename);
709 int polymerId,
int blockId,
int directionId)
714 Polymer const& polymer = mixture_.polymer(polymerId);
720 field = polymer.
propagator(blockId, directionId).tail();
721 fieldIo_.writeField(field, filename);
728 int polymerId,
int blockId,
int directionId)
733 Polymer const& polymer = mixture_.polymer(polymerId);
740 int nslice = propagator.
ns();
744 fileMaster_.openOutputFile(filename, file);
747 file <<
"ngrid" << std::endl
748 <<
" " << domain_.nx() << std::endl
749 <<
"nslice" << std::endl
750 <<
" " << nslice << std::endl;
753 bool hasHeader =
false;
754 for (
int i = 0; i < nslice; ++i) {
755 file <<
"slice " << i << std::endl;
756 Field const& field = propagator.
q(i);
757 fieldIo_.writeField(field, file, hasHeader);
767 std::string filename;
768 int np, nb, ip, ib, id;
769 np = mixture_.nPolymer();
770 for (ip = 0; ip < np; ++ip) {
771 nb = mixture_.polymer(ip).nBlock();
772 for (ib = 0; ib < nb; ++ib) {
773 for (
id = 0;
id < 2; ++id) {
782 writeQ(filename, ip, ib,
id);
Interaction model for complex Langevin FTS.
DMatrix< double > const & chi() const
Return the chi matrix by const reference.
void setNMonomer(int nMonomer)
Set the number of monomer types.
int nSolvent() const
Get number of solvent (point particle) species.
int nPolymer() const
Get number of polymer species.
int nMonomer() const
Get number of monomer types.
PolymerT & polymer(int id)
Get a polymer solver object by non-const reference.
SolventT & solvent(int id)
Get a solvent solver object.
double length() const
Sum of the lengths of all blocks in the polymer (thread model).
int nBlock() const
Number of blocks.
PT & propagator(int blockId, int directionId)
Get the propagator for a specific block and direction (non-const).
int nx() const
Get number of spatial grid points, including both endpoints.
double spatialAverage(Field const &f) const
Compute spatial average of a field.
double innerProduct(Field const &f, Field const &g) const
Compute inner product of two real fields.
Command to compute properties of homogeneous reference system.
void output(int mode, std::ostream &out) const
Output comparison to a homogeneous reference system.
void compute(int mode)
Compute properties of a homogeneous reference system.
Factory for subclasses of Iterator.
virtual int solve(bool isContinuation=false)=0
Iterate to solution.
void setDomain(Domain const &domain)
Create an association with the domain and allocate memory.
Descriptor and solver for a block polymer species.
MDE solver for one-direction of one block.
FieldT const & q(int i) const
Return q-field at specified step.
int ns() const
Number of values of s (or slices), including head and tail.
Solver and descriptor for a solvent species in a mixture.
Default Factory for subclasses of Sweep.
DArray< double > Field
Generic Field type.
DArray< Field > & cFields()
Get array of all chemical potential fields.
void compute()
Solve the modified diffusion equation once, without iteration.
void readParam()
Read input parameters from default param file.
double fHelmholtz() const
Get precomputed Helmholtz free energy per monomer / kT.
double pressure() const
Get precomputed pressure x monomer volume kT.
void writeC(std::string const &filename) const
Write concentration fields in symmetrized basis format.
int iterate(bool isContinuation=false)
Iteratively solve a SCFT problem.
void writeQSlice(std::string const &filename, int polymerId, int blockId, int directionId, int segmentId) const
Write slice of a propagator at fixed s in r-grid format.
Interaction & interaction()
Get interaction (i.e., excess free energy) by reference.
void computeFreeEnergy()
Compute free energy density and pressure for current fields.
void writeW(std::string const &filename) const
Write chemical potential fields in symmetrized basis format.
void readCommands()
Read commands from default command file.
Iterator & iterator()
Get the Iterator by reference.
Domain & domain()
Get spatial domain (including grid info) by reference.
void writeQAll(std::string const &basename) const
Write all propagators of all blocks, each to a separate file.
FileMaster & fileMaster()
Get FileMaster by reference.
Field & cField(int monomerId)
Get chemical potential field for a specific monomer type.
void setOptions(int argc, char **argv)
Process command line options.
WField & wField(int monomerId)
Get chemical potential field for a specific monomer type.
DArray< WField > & wFields()
Get array of all chemical potential fields.
void writeQ(std::string const &filename, int polymerId, int blockId, int directionId) const
Write one propagator for one block, in r-grid format.
void writeQTail(std::string const &filename, int polymerId, int blockId, int directionId) const
Write the final slice of a propagator in r-grid format.
virtual void readParameters(std::istream &in)
Read input parameters (without opening and closing lines).
void writeBlockC(std::string const &filename) const
Write c-fields for all blocks and solvents in r-grid format.
void sweep()
Sweep in parameter space, solving an SCF problem at each point.
void writeThermo(std::ostream &out) const
Write thermodynamic properties to a file.
void writeParamNoSweep(std::ostream &out) const
Write parameter file to an ostream, omitting any Sweep block.
Mixture & mixture()
Get Mixture by reference.
double size() const
Get the size (number of monomers) in this solvent.
WT mu() const
Get the chemical potential for this species (units kT=1).
WT phi() const
Get the overall volume fraction for this species.
void allocate(int capacity)
Allocate the underlying C array.
Wrapper for a double precision number, for formatted ostream output.
void openOutputFile(const std::string &filename, std::ofstream &out, std::ios_base::openmode mode=std::ios_base::out) const
Open an output file.
void setParamFileName(const std::string ¶mFileName)
Set the parameter file name.
void setOutputPrefix(const std::string &outputPrefix)
Set the output file prefix string.
void setCommandFileName(const std::string &commandFileName)
Set the command file name.
void setInputPrefix(const std::string &inputPrefix)
Set the input file prefix string.
Wrapper for an int, for formatted ostream output.
static std::ostream & file()
Get log ostream by reference.
Two-dimensional array container template (abstract).
static void setEcho(bool echo=true)
Enable or disable echoing for all subclasses of ParamComponent.
Begin & readBegin(std::istream &in, const char *label, bool isRequired=true)
Add and read a class label and opening bracket.
void setClassName(const char *className)
Set class name string.
virtual void writeParam(std::ostream &out) const
Write all parameters to an output stream.
std::string className() const
Get class name string.
void readParamComposite(std::istream &in, ParamComposite &child, bool next=true)
Add and read a required child ParamComposite.
End & readEnd(std::istream &in)
Add and read the closing bracket.
Wrapper for a std::string, for formatted ostream output.
#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.
std::string toString(int n)
Return string representation of an integer.
SCFT with real 1D fields.
PSCF package top-level namespace.
void set(BracketPolicy::Type policy)
Set policy regarding use of bracket delimiters on arrays.