1#ifndef PRDC_CL_SYSTEM_TPP
2#define PRDC_CL_SYSTEM_TPP
13#include <prdc/crystal/Basis.h>
14#include <prdc/crystal/UnitCell.h>
16#include <pscf/math/IntVec.h>
18#include <util/containers/DArray.h>
19#include <util/containers/FSArray.h>
20#include <util/param/BracketPolicy.h>
21#include <util/param/ParamComponent.h>
22#include <util/signal/Signal.h>
23#include <util/format/Str.h>
24#include <util/format/Dbl.h>
25#include <util/misc/ioUtil.h>
26#include <util/misc/FileMaster.h>
40 template <
int D,
class T>
48 interactionPtr_(nullptr),
51 fileMasterPtr_(nullptr),
60 mixturePtr_ =
new typename T::Mixture();
62 interactionPtr_ =
new typename T::Interaction();
63 domainPtr_ =
new typename T::Domain();
69 domain_().setFileMaster(*fileMasterPtr_);
70 w_.setFieldIo(domain_().fieldIo());
71 w_.setReadUnitCell(domain_().unitCell());
72 w_.setWriteUnitCell(domain_().unitCell());
73 c_.setFieldIo(domain_().fieldIo());
74 c_.setWriteUnitCell(domain_().unitCell());
92 Signal<void>& cellSignal = domain_().unitCell().signal();
103 template <
int D,
class T>
108 delete interactionPtr_;
114 delete fileMasterPtr_;
122 template <
int D,
class T>
142 while ((
c = getopt(argc, argv,
"ed:p:c:i:o:t:")) != -1) {
172 Log::file() <<
"Unknown option -" << optopt << std::endl;
188 fileMaster().setParamFileName(std::string(pArg));
190 UTIL_THROW(
"Missing required -p option - no parameter file");
195 fileMaster().setCommandFileName(std::string(cArg));
197 UTIL_THROW(
"Missing required -c option - no command file");
207 fileMaster().setInputPrefix(std::string(iArg));
212 fileMaster().setOutputPrefix(std::string(oArg));
218 UTIL_THROW(
"Error: Non-positive thread count -t option");
220 setThreadCount(tArg);
227 template <
int D,
class T>
232 polymerModel_ = PolymerModel::Thread;
249 int nm = mixture_().nMonomer();
250 int np = mixture_().nPolymer();
251 int ns = mixture_().nSolvent();
266 domain_().fieldIo().setNMonomer(nm);
269 mixture_().associate(domain_().mesh(), domain_().fft(),
270 domain_().unitCell(), domain_().waveList());
271 mixture_().setFieldIo(domain_().fieldIo());
272 mixture_().allocate();
281 simulatorFactoryPtr_->readObjectOptional(in, *
this,
302 template <
int D,
class T>
313 template <
int D,
class T>
320 template <
int D,
class T>
324 std::string command, filename, inFileName, outFileName;
327 bool readNext =
true;
338 if (command ==
"FINISH") {
342 if (command ==
"READ_W") {
343 readEcho(in, filename);
344 w().readFields(filename);
345 UTIL_CHECK(domain_().unitCell().isInitialized());
349 if (command ==
"SET_UNIT_CELL") {
352 Log::file() <<
" " << unitCell << std::endl;
355 if (command ==
"COMPUTE") {
361 if (command ==
"SIMULATE") {
368 if (command ==
"ANALYZE" || command ==
"ANALYZE_TRAJECTORY") {
375 std::string classname;
376 readEcho(in, classname);
377 readEcho(in, filename);
378 simulator().analyze(min, max, classname, filename);
382 if (command ==
"WRITE_PARAM") {
383 readEcho(in, filename);
389 if (command ==
"WRITE_W") {
390 readEcho(in, filename);
391 w().writeFields(filename);
393 if (command ==
"WRITE_C") {
394 readEcho(in, filename);
395 c().writeFields(filename);
399 if (command ==
"WRITE_BLOCK_C_RGRID") {
400 readEcho(in, filename);
401 mixture_().writeBlockCRGrid(filename);
403 if (command ==
"WRITE_Q_SLICE") {
404 int polymerId, blockId, directionId, segmentId;
405 readEcho(in, filename);
410 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
411 <<
Str(
"block ID ", 21) << blockId <<
"\n"
412 <<
Str(
"direction ID ", 21) << directionId
414 <<
Str(
"segment ID ", 21) << segmentId
416 mixture_().writeQSlice(filename, polymerId, blockId,
417 directionId, segmentId);
419 if (command ==
"WRITE_Q_TAIL") {
420 readEcho(in, filename);
421 int polymerId, blockId, directionId;
425 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
426 <<
Str(
"block ID ", 21) << blockId <<
"\n"
427 <<
Str(
"direction ID ", 21) << directionId
429 mixture_().writeQTail(filename, polymerId, blockId, directionId);
431 if (command ==
"WRITE_Q") {
432 readEcho(in, filename);
433 int polymerId, blockId, directionId;
437 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
438 <<
Str(
"block ID ", 21) << blockId <<
"\n"
439 <<
Str(
"direction ID ", 21) << directionId
441 mixture_().writeQ(filename, polymerId, blockId, directionId);
443 if (command ==
"WRITE_Q_ALL") {
444 readEcho(in, filename);
445 mixture_().writeQAll(filename);
450 if (command ==
"WRITE_TIMERS") {
451 readEcho(in, filename);
457 if (command ==
"CLEAR_TIMERS") {
464 << command << std::endl;
473 template <
int D,
class T>
487 template <
int D,
class T>
498 mixture_().compute(w_.fields(), c_.fields());
507 template <
int D,
class T>
514 simulator().simulate(nStep);
521 template <
int D,
class T>
523 { c_.setHasData(
false); }
530 template <
int D,
class T>
535 UTIL_CHECK(domain_().lattice() == unitCell.lattice());
538 domain_().unitCell() = unitCell;
541 UTIL_CHECK(domain_().unitCell().isInitialized());
542 UTIL_CHECK(domain_().unitCell().lattice() == domain_().lattice());
549 template <
int D,
class T>
557 domain_().unitCell().set(domain_().lattice(), parameters);
559 domain_().unitCell().setParameters(parameters);
563 UTIL_CHECK(domain_().unitCell().isInitialized());
564 UTIL_CHECK(domain_().unitCell().lattice() == domain_().lattice());
571 template <
int D,
class T>
575 mixture_().clearUnitCellData();
576 domain_().waveList().clearUnitCellData();
585 template <
int D,
class T>
590 simulator().outputTimers(out);
597 template <
int D,
class T>
598 void System<D,T>::clearTimers()
601 simulator().clearTimers();
611 template <
int D,
class T>
612 void System<D,T>::allocateFields()
616 int nMonomer = mixture_().nMonomer();
622 IntVec<D> const & dimensions = domain_().mesh().dimensions();
626 w_.allocate(nMonomer, dimensions);
630 c_.allocate(nMonomer, dimensions);
638 template <
int D,
class T>
639 void System<D,T>::readEcho(std::istream& in, std::string&
string)
const
643 UTIL_THROW(
"Unable to read a string parameter.");
651 template <
int D,
class T>
652 void System<D,T>::readEcho(std::istream& in,
double& value)
const
656 UTIL_THROW(
"Unable to read floating point parameter.");
Base class template for a complex CL-FTS system.
void readCommands()
Read and process commands from the default command file.
T::WFields & w()
Get the chemical potential (w) fields (non-const).
void readParam()
Read input parameters from default param file.
FileMaster & fileMaster()
Get the FileMaster (non-const).
virtual void readParameters(std::istream &in)
Read body of parameter block (without opening and closing lines).
void clearUnitCellData()
Notify System members that unit cell parameters have been modified.
void readCommands(std::istream &in)
Read and process commands from an input stream.
void clearCFields()
Mark c-fields and free energy as outdated or invalid.
Types< D >::CFields const & c() const
void compute(bool needStress=false)
Solve the modified diffusion equation once, without iteration.
virtual void readParam(std::istream &in)
Read input parameters (with opening and closing lines).
void setUnitCell(UnitCell< D > const &unitCell)
Set parameters of the associated unit cell.
void setOptions(int argc, char **argv)
Process command line options.
Types< D >::Interaction & interaction()
System(typename T::System &system)
Constructor.
void simulate(int nStep)
Perform a field theoretic simulation (PS-FTS).
An IntVec<D, T> is a D-component vector of elements of integer type T.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Wrapper for a double precision number, for formatted ostream output.
A fixed capacity (static) contiguous array with a variable logical size.
A FileMaster manages input and output files for a simulation.
static std::ostream & file()
Get log ostream by reference.
std::string indent() const
Return indent string for this object (string of spaces).
static bool echo()
Get echo parameter.
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.
ScalarParam< Type > & readOptional(std::istream &in, const char *label, Type &value)
Add and read a new optional ScalarParam < Type > object.
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.
Notifier (or subject) in the Observer design pattern.
void addObserver(Observer &observer, void(Observer::*methodPtr)(const T &))
Register an observer.
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.
Complex-valued periodic fields (class templates).
Enumeration and functions to specify a model for polymer chains.
int nSet()
How many times has setModel been called?
void setModel(Type model)
Set the global polymer model enumeration value.
bool isLocked()
Has the model type been locked (i.e., made immutable) ?
Periodic fields and crystallography.
void allocateFields(DArray< FT > &fields, int n, IntVec< D > const &dimension)
Allocate a DArray of fields.
PSCF package top-level namespace.
void set(BracketPolicy::Type policy)
Set policy regarding use of bracket delimiters on arrays.