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/misc/HomogeneousComparison.h>
18#include <r1d/misc/FieldIo.h>
20#include <pscf/inter/Interaction.h>
21#include <pscf/inter/Interaction.h>
22#include <pscf/floryHuggins/Clump.h>
24#include <util/format/Str.h>
25#include <util/format/Int.h>
26#include <util/format/Dbl.h>
27#include <util/param/BracketPolicy.h>
28#include <util/misc/ioUtil.h>
50 iteratorFactoryPtr_(0),
68 fieldIo_.associate(domain_, fileMaster_);
81 if (interactionPtr_) {
82 delete interactionPtr_;
87 if (iteratorFactoryPtr_) {
88 delete iteratorFactoryPtr_;
93 if (sweepFactoryPtr_) {
94 delete sweepFactoryPtr_;
116 while ((c = getopt(argc, argv,
"er:p:c:i:o:f")) != -1) {
138 Log::file() <<
"Unknown option -" << optopt << std::endl;
179 homogeneous_.initialize(
mixture());
191 iteratorPtr_ = iteratorFactoryPtr_->readObject(in, *
this,
194 std::string msg =
"Unrecognized Iterator subclass name ";
201 sweepFactoryPtr_->readObjectOptional(in, *
this,
className, isEnd);
204 sweepPtr_->setSystem(*
this);
231 out <<
"System{" << std::endl;
232 mixture_.writeParam(out);
233 interactionPtr_->writeParam(out);
234 domain_.writeParam(out);
235 iteratorPtr_->writeParam(out);
236 out <<
"}" << std::endl;
242 void System::allocateFields()
253 wFields_.allocate(nMonomer);
254 cFields_.allocate(nMonomer);
256 for (
int i = 0; i < nMonomer; ++i) {
272 std::string filename;
274 std::istream& inBuffer = in;
276 bool readNext =
true;
281 if (inBuffer.eof()) {
287 if (command ==
"FINISH") {
291 if (command ==
"READ_W") {
292 readEcho(inBuffer, filename);
293 fieldIo_.readFields(
wFields(), filename);
295 if (command ==
"COMPUTE") {
300 if (command ==
"ITERATE") {
302 bool isContinuation =
false;
303 int fail =
iterate(isContinuation);
308 if (command ==
"SWEEP") {
313 if (command ==
"WRITE_PARAM") {
314 readEcho(inBuffer, filename);
320 if (command ==
"WRITE_THERMO") {
321 readEcho(inBuffer, filename);
327 if (command ==
"COMPARE_HOMOGENEOUS") {
331 readEcho(inBuffer, filename);
333 Log::file() <<
"mode = " << mode << std::endl;
340 comparison.
output(mode, file);
343 if (command ==
"WRITE_W") {
344 readEcho(inBuffer, filename);
345 fieldIo_.writeFields(
wFields(), filename);
347 if (command ==
"WRITE_C") {
348 readEcho(inBuffer, filename);
349 fieldIo_.writeFields(
cFields(), filename);
351 if (command ==
"WRITE_BLOCK_C") {
352 readEcho(inBuffer, filename);
353 fieldIo_.writeBlockCFields(mixture_, filename);
355 if (command ==
"WRITE_Q_SLICE") {
356 int polymerId, blockId, directionId, segmentId;
357 readEcho(inBuffer, filename);
358 inBuffer >> polymerId;
360 inBuffer >> directionId;
361 inBuffer >> segmentId;
362 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
363 <<
Str(
"block ID ", 21) << blockId <<
"\n"
364 <<
Str(
"direction ID ", 21) << directionId <<
"\n"
365 <<
Str(
"segment ID ", 21) << segmentId << std::endl;
366 writeQSlice(filename, polymerId, blockId, directionId,
369 if (command ==
"WRITE_Q_TAIL") {
370 readEcho(inBuffer, filename);
371 int polymerId, blockId, directionId;
372 inBuffer >> polymerId;
374 inBuffer >> directionId;
375 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
376 <<
Str(
"block ID ", 21) << blockId <<
"\n"
377 <<
Str(
"direction ID ", 21) << directionId <<
"\n";
378 writeQTail(filename, polymerId, blockId, directionId);
380 if (command ==
"WRITE_Q_VERTEX") {
381 int polymerId, vertexId;
382 inBuffer >> polymerId;
385 <<
Int(polymerId, 5) << std::endl;
386 inBuffer >> vertexId;
388 <<
Int(vertexId, 5) << std::endl;
389 inBuffer >> filename;
391 <<
Str(filename, 20) << std::endl;
392 fieldIo_.writeVertexQ(mixture_, polymerId, vertexId, filename);
394 if (command ==
"WRITE_Q") {
395 readEcho(inBuffer, filename);
396 int polymerId, blockId, directionId;
397 inBuffer >> polymerId;
399 inBuffer >> directionId;
400 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
401 <<
Str(
"block ID ", 21) << blockId <<
"\n"
402 <<
Str(
"direction ID ", 21) << directionId <<
"\n";
403 writeQ(filename, polymerId, blockId, directionId);
405 if (command ==
"WRITE_Q_ALL") {
406 readEcho(inBuffer, filename);
409 if (command ==
"REMESH_W") {
414 inBuffer >> filename;
415 Log::file() <<
"outfile = " <<
Str(filename, 20) << std::endl;
416 fieldIo_.remesh(
wFields(), nx, filename);
418 if (command ==
"EXTEND_W") {
423 inBuffer >> filename;
424 Log::file() <<
"outfile = " <<
Str(filename, 20) << std::endl;
425 fieldIo_.extend(
wFields(), m, filename);
427 Log::file() <<
" Error: Unknown command "
428 << command << std::endl;
449 void System::readEcho(std::istream& in, std::string&
string)
const
465 mixture_.compute(
wFields(), cFields_);
523 for (
int i = 0; i < np; ++i) {
525 phi = polymerPtr->
phi();
526 mu = polymerPtr->
mu();
528 length = polymerPtr->
length();
530 fHelmholtz_ += phi*( mu - 1.0 )/length;
539 for (
int i = 0; i < ns; ++i) {
541 phi = solventPtr->
phi();
542 mu = solventPtr->
mu();
544 size = solventPtr->
size();
546 fHelmholtz_ += phi*( mu - 1.0 )/size;
552 for (
int i = 0; i < nm; ++i) {
556 fIdeal_ = fHelmholtz_;
560 if (!f_.isAllocated()) f_.allocate(nx);
561 if (!c_.isAllocated()) c_.allocate(nm);
563 for (
int i = 0; i < nx; ++i) {
565 for (j = 0; j < nm; ++j) {
566 c_[j] = cFields_[j][i];
572 fInter_ = fHelmholtz_ - fIdeal_;
575 pressure_ = -fHelmholtz_;
579 for (
int i = 0; i < np; ++i) {
581 phi = polymerPtr->
phi();
582 mu = polymerPtr->
mu();
583 length = polymerPtr->
length();
585 pressure_ += phi*mu/length;
592 for (
int i = 0; i < ns; ++i) {
594 phi = solventPtr->
phi();
595 mu = solventPtr->
mu();
596 size = solventPtr->
size();
598 pressure_ += phi*mu/size;
608 out <<
"fHelmholtz " <<
Dbl(
fHelmholtz(), 18, 11) << std::endl;
609 out <<
"pressure " <<
Dbl(
pressure(), 18, 11) << std::endl;
611 out <<
"fIdeal " <<
Dbl(fIdeal_, 18, 11) << std::endl;
612 out <<
"fInter " <<
Dbl(fInter_, 18, 11) << std::endl;
618 out <<
"polymers:" << std::endl;
623 for (
int i = 0; i < np; ++i) {
625 <<
" " <<
Dbl(
mixture().polymer(i).phi(),18, 11)
626 <<
" " <<
Dbl(
mixture().polymer(i).mu(), 18, 11)
635 out <<
"solvents:" << std::endl;
640 for (
int i = 0; i < ns; ++i) {
642 <<
" " <<
Dbl(
mixture().solvent(i).phi(),18, 11)
643 <<
" " <<
Dbl(
mixture().solvent(i).mu(), 18, 11)
659 fieldIo_.writeFields(
wFields(), filename);
668 fieldIo_.writeFields(
cFields(), filename);
678 fieldIo_.writeBlockCFields(mixture_, filename);
685 int polymerId,
int blockId,
686 int directionId,
int segmentId)
691 Polymer const& polymer = mixture_.polymer(polymerId);
697 propagator = polymer.
propagator(blockId, directionId);
698 Field const& field = propagator.
q(segmentId);
699 fieldIo_.writeField(field, filename);
706 int polymerId,
int blockId,
int directionId)
711 Polymer const& polymer = mixture_.polymer(polymerId);
717 field = polymer.
propagator(blockId, directionId).tail();
718 fieldIo_.writeField(field, filename);
725 int polymerId,
int blockId,
int directionId)
730 Polymer const& polymer = mixture_.polymer(polymerId);
737 int nslice = propagator.
ns();
741 fileMaster_.openOutputFile(filename, file);
744 file <<
"ngrid" << std::endl
745 <<
" " << domain_.nx() << std::endl
746 <<
"nslice" << std::endl
747 <<
" " << nslice << std::endl;
750 bool hasHeader =
false;
751 for (
int i = 0; i < nslice; ++i) {
752 file <<
"slice " << i << std::endl;
753 Field const& field = propagator.
q(i);
754 fieldIo_.writeField(field, file, hasHeader);
764 std::string filename;
765 int np, nb, ip, ib, id;
766 np = mixture_.nPolymer();
767 for (ip = 0; ip < np; ++ip) {
768 nb = mixture_.polymer(ip).nBlock();
769 for (ib = 0; ib < nb; ++ib) {
770 for (
id = 0;
id < 2; ++id) {
779 writeQ(filename, ip, ib,
id);
Flory-Huggins excess free energy model.
virtual double fHelmholtz(Array< double > const &c) const
Compute excess Helmholtz free energy per monomer.
void setNMonomer(int nMonomer)
Set the number of monomer types.
int nPolymer() const
Get number of polymer species.
int nMonomer() const
Get number of monomer types.
int nSolvent() const
Get number of solvent (point particle) species.
SolventT & solvent(int id)
Get a solvent solver object.
PolymerT & polymer(int id)
Get a polymer solver object by non-const reference.
double phi() const
Get the overall volume fraction for this species.
PT & propagator(int blockId, int directionId)
Get the propagator for a specific block and direction (non-const).
int nBlock() const
Number of blocks.
double mu() const
Get the chemical potential for this species (units kT=1).
double length() const
Sum of the lengths of all blocks in the polymer (thread model).
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)
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.
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.
CField & cField(int monomerId)
Get chemical potential field for a specific monomer type.
DArray< CField > & cFields()
Get array of all chemical potential fields.
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.
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.
double phi() const
Get the overall volume fraction for this species.
double mu() const
Get the chemical potential for this species (units kT=1).
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.
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.