12#include <pspg/sweep/Sweep.h>
13#include <pspg/sweep/SweepFactory.h>
14#include <pspg/iterator/Iterator.h>
15#include <pspg/iterator/IteratorFactory.h>
16#include <pspg/field/RDField.h>
17#include <pspg/math/GpuResources.h>
19#include <pscf/inter/Interaction.h>
20#include <pscf/math/IntVec.h>
21#include <pscf/homogeneous/Clump.h>
23#include <util/param/BracketPolicy.h>
24#include <util/format/Str.h>
25#include <util/format/Int.h>
26#include <util/format/Dbl.h>
27#include <util/misc/ioUtil.h>
50 iteratorFactoryPtr_(0),
60 isAllocatedGrid_(false),
61 isAllocatedBasis_(false),
65 domain_.setFileMaster(fileMaster_);
66 w_.setFieldIo(domain_.fieldIo());
82 if (interactionPtr_) {
83 delete interactionPtr_;
88 if (iteratorFactoryPtr_) {
89 delete iteratorFactoryPtr_;
94 if (sweepFactoryPtr_) {
95 delete sweepFactoryPtr_;
120 while ((c = getopt(argc, argv,
"er:p:c:i:o:t:")) != -1) {
146 Log::file() <<
"Unknown option -" << optopt << std::endl;
158 fileMaster().setParamFileName(std::string(pArg));
163 fileMaster().setCommandFileName(std::string(cArg));
168 fileMaster().setInputPrefix(std::string(iArg));
173 fileMaster().setOutputPrefix(std::string(oArg));
189 readBegin(in, className().c_str());
199 { readParam(fileMaster().paramFile()); }
208 readParamComposite(in, mixture());
211 int nm = mixture().nMonomer();
212 int np = mixture().nPolymer();
213 int ns = mixture().nSolvent();
220 interaction().setNMonomer(mixture().nMonomer());
221 readParamComposite(in, interaction());
224 readParamComposite(in, domain_);
226 mixture().setMesh(mesh());
228 UTIL_CHECK(domain_.unitCell().nParameter() > 0);
232 allocateFieldsGrid();
233 if (domain_.basis().isInitialized()) {
234 allocateFieldsBasis();
238 std::string className;
241 iteratorFactoryPtr_->readObjectOptional(in, *
this, className,
244 Log::file() <<
"Notification: No iterator was constructed\n";
250 sweepFactoryPtr_->readObjectOptional(in, *
this, className,
256 std::string className;
259 = iteratorFactoryPtr_->readObject(in, *
this, className, isEnd);
261 std::string msg =
"Unrecognized Iterator subclass name ";
268 sweepFactoryPtr_->readObjectOptional(in, *
this, className, isEnd);
270 sweepPtr_->setSystem(*
this);
275 homogeneous_.setNMolecule(np+ns);
276 homogeneous_.setNMonomer(nm);
288 std::string command, filename, inFileName, outFileName;
290 bool readNext =
true;
301 if (command ==
"FINISH") {
305 if (command ==
"READ_W_BASIS") {
306 readEcho(in, filename);
307 readWBasis(filename);
309 if (command ==
"READ_W_RGRID") {
310 readEcho(in, filename);
311 readWRGrid(filename);
313 if (command ==
"ESTIMATE_W_FROM_C") {
315 readEcho(in, inFileName);
316 estimateWfromC(inFileName);
318 if (command ==
"SET_UNIT_CELL") {
321 Log::file() <<
" " << unitCell << std::endl;
322 setUnitCell(unitCell);
324 if (command ==
"COMPUTE") {
328 if (command ==
"ITERATE") {
330 int error = iterate();
335 if (command ==
"SWEEP") {
340 if (command ==
"WRITE_PARAM") {
341 readEcho(in, filename);
343 fileMaster().openOutputFile(filename, file);
344 writeParamNoSweep(file);
347 if (command ==
"WRITE_THERMO") {
348 readEcho(in, filename);
350 fileMaster().openOutputFile(filename, file,
355 if (command ==
"WRITE_W_BASIS") {
358 readEcho(in, filename);
359 fieldIo().writeFieldsBasis(filename, w_.basis(),
362 if (command ==
"WRITE_W_RGRID") {
364 readEcho(in, filename);
365 fieldIo().writeFieldsRGrid(filename, w_.rgrid(),
368 if (command ==
"WRITE_C_BASIS") {
369 readEcho(in, filename);
372 fieldIo().writeFieldsBasis(filename, c_.basis(),
375 if (command ==
"WRITE_C_RGRID") {
377 readEcho(in, filename);
378 fieldIo().writeFieldsRGrid(filename, c_.rgrid(),
381 if (command ==
"WRITE_BLOCK_C_RGRID") {
382 readEcho(in, filename);
383 writeBlockCRGrid(filename);
385 if (command ==
"WRITE_Q_SLICE") {
386 int polymerId, blockId, directionId, segmentId;
387 readEcho(in, filename);
392 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
393 <<
Str(
"block ID ", 21) << blockId <<
"\n"
394 <<
Str(
"direction ID ", 21) << directionId <<
"\n"
395 <<
Str(
"segment ID ", 21) << segmentId << std::endl;
396 writeQSlice(filename, polymerId, blockId, directionId,
399 if (command ==
"WRITE_Q_TAIL") {
400 int polymerId, blockId, directionId;
401 readEcho(in, filename);
405 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
406 <<
Str(
"block ID ", 21) << blockId <<
"\n"
407 <<
Str(
"direction ID ", 21) << directionId <<
"\n";
408 writeQTail(filename, polymerId, blockId, directionId);
410 if (command ==
"WRITE_Q") {
411 int polymerId, blockId, directionId;
412 readEcho(in, filename);
416 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
417 <<
Str(
"block ID ", 21) << blockId <<
"\n"
418 <<
Str(
"direction ID ", 21) << directionId <<
"\n";
419 writeQ(filename, polymerId, blockId, directionId);
421 if (command ==
"WRITE_Q_ALL") {
422 readEcho(in, filename);
425 if (command ==
"WRITE_STARS") {
426 readEcho(in, filename);
427 writeStars(filename);
429 if (command ==
"WRITE_WAVES") {
430 readEcho(in, filename);
431 writeWaves(filename);
433 if (command ==
"WRITE_GROUP") {
434 readEcho(in, filename);
435 writeGroup(filename);
438 if (command ==
"BASIS_TO_RGRID") {
439 readEcho(in, inFileName);
440 readEcho(in, outFileName);
441 basisToRGrid(inFileName, outFileName);
443 if (command ==
"RGRID_TO_BASIS") {
444 readEcho(in, inFileName);
445 readEcho(in, outFileName);
446 rGridToBasis(inFileName, outFileName);
448 if (command ==
"KGRID_TO_RGRID") {
449 readEcho(in, inFileName);
450 readEcho(in, outFileName);
451 kGridToRGrid(inFileName, outFileName);
453 if (command ==
"RGRID_TO_KGRID") {
454 readEcho(in, inFileName);
455 readEcho(in, outFileName);
456 rGridToKGrid(inFileName, outFileName);
458 if (command ==
"KGRID_TO_BASIS") {
459 readEcho(in, inFileName);
460 readEcho(in, outFileName);
461 kGridToBasis(inFileName, outFileName);
463 if (command ==
"BASIS_TO_KGRID") {
464 readEcho(in, inFileName);
465 readEcho(in, outFileName);
466 basisToKGrid(inFileName, outFileName);
468 Log::file() <<
" Error: Unknown command "
469 << command << std::endl;
481 if (fileMaster().commandFileName().empty()) {
484 readCommands(fileMaster().commandFile());
497 if (!isAllocatedBasis_) {
498 readFieldHeader(filename);
499 allocateFieldsBasis();
503 w_.readBasis(filename, domain_.unitCell());
504 domain_.waveList().computeKSq(domain_.unitCell());
505 domain_.waveList().computedKSq(domain_.unitCell());
506 mixture_.setupUnitCell(domain_.unitCell(), domain_.waveList());
515 if (!isAllocatedBasis_) {
516 readFieldHeader(filename);
517 allocateFieldsBasis();
520 w_.readRGrid(filename, domain_.unitCell());
521 domain_.waveList().computeKSq(domain_.unitCell());
522 domain_.waveList().computedKSq(domain_.unitCell());
523 mixture_.setupUnitCell(domain_.unitCell(), domain_.waveList());
566 const int nMonomer = mixture_.nMonomer();
571 if (!isAllocatedBasis_) {
572 readFieldHeader(filename);
573 allocateFieldsBasis();
576 const int nBasis = domain_.basis().nBasis();
582 for (
int i = 0; i < nMonomer; ++i) {
583 tmpCFieldsBasis[i].
allocate(nBasis);
587 fieldIo().readFieldsBasis(filename, tmpCFieldsBasis,
591 for (
int i = 0; i < nBasis; ++i) {
592 for (
int j = 0; j < nMonomer; ++j) {
593 tmpFieldsBasis_[j][i] = 0.0;
594 for (
int k = 0; k < nMonomer; ++k) {
595 tmpFieldsBasis_[j][i] += interaction().chi(j,k)
596 * tmpCFieldsBasis[k][i];
602 w_.setBasis(tmpFieldsBasis_);
622 domain_.setUnitCell(unitCell);
623 mixture_.setupUnitCell(unitCell, domain_.waveList());
624 if (!isAllocatedBasis_) {
625 allocateFieldsBasis();
637 domain_.setUnitCell(lattice, parameters);
638 mixture_.setupUnitCell(domain_.unitCell(), domain_.waveList());
639 if (!isAllocatedBasis_) {
640 allocateFieldsBasis();
650 domain_.setUnitCell(parameters);
651 mixture_.setupUnitCell(domain_.unitCell(), domain_.waveList());
652 if (!isAllocatedBasis_) {
653 allocateFieldsBasis();
668 mixture().compute(w_.rgrid(), c_.rgrid());
672 if (w_.isSymmetric()) {
673 fieldIo().convertRGridToBasis(c_.rgrid(), c_.basis());
677 mixture().computeStress(domain_.waveList());
694 int error = iterator().solve(isContinuation);
698 if (w_.isSymmetric()) {
699 fieldIo().convertRGridToBasis(c_.rgrid(), c_.basis());
703 if (!iterator().isFlexible()) {
704 mixture().computeStress(domain_.waveList());
744 int np = mixture_.nPolymer();
745 int ns = mixture_.nSolvent();
750 double phi, mu, length;
751 int np = mixture().nPolymer();
752 for (
int i = 0; i < np; ++i) {
753 polymerPtr = &mixture().polymer(i);
754 phi = polymerPtr->
phi();
755 mu = polymerPtr->
mu();
757 length = polymerPtr->
length();
759 fHelmholtz_ += phi*( mu - 1.0 )/length;
768 for (
int i = 0; i < ns; ++i) {
769 solventPtr = &mixture_.solvent(i);
770 phi = solventPtr->
phi();
771 mu = solventPtr->
mu();
772 size = solventPtr->
size();
774 fHelmholtz_ += phi*( mu - 1.0 )/size;
779 int nm = mixture().nMonomer();
780 int nx = mesh().size();
783 int nBlocks, nThreads;
788 for (
int i = 0; i < nm; i++) {
789 pointWiseBinaryMultiply<<<nBlocks,nThreads>>>
790 (w_.rgrid(i).cDField(), c_.rgrid()[i].cDField(),
791 workArray_.cDField(), nx);
792 temp += gpuSum(workArray_.cDField(),nx) / double(nx);
795 fIdeal_ = fHelmholtz_;
798 for (
int i = 0; i < nm; ++i) {
799 for (
int j = i + 1; j < nm; ++j) {
800 assignUniformReal<<<nBlocks, nThreads>>>
801 (workArray_.cDField(), interaction().chi(i, j), nx);
802 inPlacePointwiseMul<<<nBlocks, nThreads>>>
803 (workArray_.cDField(), c_.rgrid()[i].cDField(), nx);
804 inPlacePointwiseMul<<<nBlocks, nThreads>>>
805 (workArray_.cDField(), c_.rgrid()[j].cDField(), nx);
806 fHelmholtz_ += gpuSum(workArray_.cDField(), nx) / double(nx);
809 fInter_ = fHelmholtz_ - fIdeal_;
812 pressure_ = -fHelmholtz_;
818 for (
int i = 0; i < np; ++i) {
819 polymerPtr = &mixture_.polymer(i);
820 phi = polymerPtr->
phi();
821 mu = polymerPtr->
mu();
822 length = polymerPtr->
length();
824 pressure_ += mu * phi /length;
833 for (
int i = 0; i < ns; ++i) {
834 solventPtr = &mixture_.solvent(i);
835 phi = solventPtr->
phi();
836 mu = solventPtr->
mu();
837 size = solventPtr->
size();
839 pressure_ += mu * phi /size;
854 out <<
"System{" << std::endl;
855 mixture_.writeParam(out);
856 interaction().writeParam(out);
857 domain_.writeParam(out);
859 iteratorPtr_->writeParam(out);
861 out <<
"}" << std::endl;
868 out <<
"fHelmholtz " <<
Dbl(fHelmholtz(), 18, 11) << std::endl;
869 out <<
"pressure " <<
Dbl(pressure(), 18, 11) << std::endl;
871 out <<
"fIdeal " <<
Dbl(fIdeal_, 18, 11) << std::endl;
872 out <<
"fInter " <<
Dbl(fInter_, 18, 11) << std::endl;
875 int np = mixture_.nPolymer();
876 int ns = mixture_.nSolvent();
879 out <<
"polymers:" << std::endl;
884 for (
int i = 0; i < np; ++i) {
886 <<
" " <<
Dbl(mixture_.polymer(i).phi(),18, 11)
887 <<
" " <<
Dbl(mixture_.polymer(i).mu(), 18, 11)
894 out <<
"solvents:" << std::endl;
899 for (
int i = 0; i < ns; ++i) {
901 <<
" " <<
Dbl(mixture_.solvent(i).phi(),18, 11)
902 <<
" " <<
Dbl(mixture_.solvent(i).mu(), 18, 11)
908 out <<
"cellParams:" << std::endl;
909 for (
int i = 0; i < unitCell().nParameter(); ++i) {
912 <<
Dbl(unitCell().parameter(i), 18, 11)
926 fieldIo().writeFieldsBasis(filename, w_.basis(), unitCell());
936 fieldIo().writeFieldsRGrid(filename, w_.rgrid(), unitCell());
947 fieldIo().writeFieldsBasis(filename, c_.basis(), unitCell());
957 fieldIo().writeFieldsRGrid(filename, c_.rgrid(), unitCell());
971 blockCFields.
allocate(mixture_.nSolvent() + mixture_.nBlock());
973 for (
int i = 0; i < n; i++) {
974 blockCFields[i].
allocate(mesh().dimensions());
978 mixture_.createBlockCRGrid(blockCFields);
979 fieldIo().writeFieldsRGrid(filename, blockCFields, unitCell());
987 int polymerId,
int blockId,
988 int directionId,
int segmentId)
993 Polymer<D> const& polymer = mixture_.polymer(polymerId);
999 propagator = polymer.
propagator(blockId, directionId);
1002 cudaMemcpy(field.
cDField(), propagator.
q(segmentId),
1003 mesh().size() *
sizeof(cudaReal), cudaMemcpyDeviceToDevice);
1004 fieldIo().writeFieldRGrid(filename, field, unitCell());
1012 int polymerId,
int blockId,
int directionId)
1017 Polymer<D> const& polymer = mixture_.polymer(polymerId);
1023 propagator = polymer.
propagator(blockId, directionId);
1027 mesh().size()*
sizeof(cudaReal),
1028 cudaMemcpyDeviceToDevice);
1029 fieldIo().writeFieldRGrid(filename, field, unitCell());
1037 int polymerId,
int blockId,
int directionId)
1042 Polymer<D> const& polymer = mixture_.polymer(polymerId);
1048 propagator = polymer.
propagator(blockId, directionId);
1049 int ns = propagator.
ns();
1053 fileMaster_.openOutputFile(filename, file);
1056 fieldIo().writeFieldHeader(file, 1, unitCell());
1057 file <<
"ngrid" << std::endl
1058 <<
" " << mesh().dimensions() << std::endl
1059 <<
"nslice" << std::endl
1060 <<
" " << ns << std::endl;
1065 bool hasHeader =
false;
1066 for (
int i = 0; i < ns; ++i) {
1067 file <<
"slice " << i << std::endl;
1068 cudaMemcpy(field.
cDField(), propagator.
q(i),
1069 mesh().size() *
sizeof(cudaReal),
1070 cudaMemcpyDeviceToDevice);
1071 fieldIo().writeFieldRGrid(file, field, unitCell(), hasHeader);
1081 std::string filename;
1082 int np, nb, ip, ib, id;
1083 np = mixture_.nPolymer();
1084 for (ip = 0; ip < np; ++ip) {
1087 nb = mixture_.polymer(ip).nBlock();
1088 for (ib = 0; ib < nb; ++ib) {
1089 for (
id = 0;
id < 2; ++id) {
1090 filename = basename;
1098 writeQ(filename, ip, ib,
id);
1111 std::ofstream outFile;
1112 fileMaster_.openOutputFile(filename, outFile);
1113 fieldIo().writeFieldHeader(outFile, mixture_.nMonomer(),
1115 basis().outputStars(outFile);
1125 std::ofstream outFile;
1126 fileMaster_.openOutputFile(filename, outFile);
1127 fieldIo().writeFieldHeader(outFile, mixture_.nMonomer(),
1129 basis().outputWaves(outFile);
1138 Pscf::writeGroup(filename, domain_.group());
1148 const std::string & outFileName)
1152 if (!isAllocatedBasis_) {
1153 readFieldHeader(inFileName);
1154 allocateFieldsBasis();
1159 fieldIo().readFieldsBasis(inFileName, tmpFieldsBasis_, tmpUnitCell);
1160 fieldIo().convertBasisToRGrid(tmpFieldsBasis_, tmpFieldsRGrid_);
1161 fieldIo().writeFieldsRGrid(outFileName, tmpFieldsRGrid_,
1170 const std::string & outFileName)
1174 if (!isAllocatedBasis_) {
1175 readFieldHeader(inFileName);
1176 allocateFieldsBasis();
1181 fieldIo().readFieldsRGrid(inFileName, tmpFieldsRGrid_, tmpUnitCell);
1182 fieldIo().convertRGridToBasis(tmpFieldsRGrid_, tmpFieldsBasis_);
1183 fieldIo().writeFieldsBasis(outFileName, tmpFieldsBasis_,
1192 const std::string& outFileName)
1196 if (!isAllocatedBasis_) {
1197 readFieldHeader(inFileName);
1198 allocateFieldsBasis();
1203 fieldIo().readFieldsKGrid(inFileName, tmpFieldsKGrid_, tmpUnitCell);
1204 for (
int i = 0; i < mixture_.nMonomer(); ++i) {
1205 fft().inverseTransform(tmpFieldsKGrid_[i], tmpFieldsRGrid_[i]);
1207 fieldIo().writeFieldsRGrid(outFileName, tmpFieldsRGrid_,
1216 const std::string & outFileName)
1220 if (!isAllocatedBasis_) {
1221 readFieldHeader(inFileName);
1222 allocateFieldsBasis();
1227 fieldIo().readFieldsRGrid(inFileName, tmpFieldsRGrid_,
1229 for (
int i = 0; i < mixture_.nMonomer(); ++i) {
1230 fft().forwardTransform(tmpFieldsRGrid_[i], tmpFieldsKGrid_[i]);
1232 fieldIo().writeFieldsKGrid(outFileName, tmpFieldsKGrid_,
1241 const std::string& outFileName)
1245 if (!isAllocatedBasis_) {
1246 readFieldHeader(inFileName);
1247 allocateFieldsBasis();
1252 fieldIo().readFieldsKGrid(inFileName, tmpFieldsKGrid_, tmpUnitCell);
1253 fieldIo().convertKGridToBasis(tmpFieldsKGrid_, tmpFieldsBasis_);
1254 fieldIo().writeFieldsBasis(outFileName, tmpFieldsBasis_,
1263 const std::string & outFileName)
1267 if (!isAllocatedBasis_) {
1268 readFieldHeader(inFileName);
1269 allocateFieldsBasis();
1274 fieldIo().readFieldsBasis(inFileName, tmpFieldsBasis_, tmpUnitCell);
1275 fieldIo().convertBasisToKGrid(tmpFieldsBasis_, tmpFieldsKGrid_);
1276 fieldIo().writeFieldsKGrid(outFileName, tmpFieldsKGrid_,
1290 int nMonomer = mixture().nMonomer();
1296 IntVec<D> const & dimensions = domain_.mesh().dimensions();
1299 w_.setNMonomer(nMonomer);
1300 w_.allocateRGrid(dimensions);
1303 c_.setNMonomer(nMonomer);
1304 c_.allocateRGrid(dimensions);
1307 tmpFieldsRGrid_.allocate(nMonomer);
1308 tmpFieldsKGrid_.allocate(nMonomer);
1309 for (
int i = 0; i < nMonomer; ++i) {
1310 tmpFieldsRGrid_[i].allocate(dimensions);
1311 tmpFieldsKGrid_[i].allocate(dimensions);
1314 workArray_.allocate(mesh().size());
1317 isAllocatedGrid_ =
true;
1324 void System<D>::allocateFieldsBasis()
1328 const int nMonomer = mixture().nMonomer();
1332 UTIL_CHECK(domain_.unitCell().nParameter() > 0);
1335 const int nBasis = basis().nBasis();
1338 w_.allocateBasis(nBasis);
1339 c_.allocateBasis(nBasis);
1342 tmpFieldsBasis_.allocate(nMonomer);
1343 for (
int i = 0; i < nMonomer; ++i) {
1344 tmpFieldsBasis_[i].allocate(nBasis);
1348 if (!domain_.waveList().hasMinimumImages()) {
1349 domain_.waveList().computeMinimumImages(domain_.mesh(),
1350 domain_.unitCell());
1353 isAllocatedBasis_ =
true;
1360 void System<D>::readFieldHeader(std::string filename)
1367 fileMaster_.openInputFile(filename, file);
1371 domain_.fieldIo().readFieldHeader(file, nMonomer,
1372 domain_.unitCell());
1378 UTIL_CHECK(domain_.unitCell().nParameter() > 0);
1379 UTIL_CHECK(domain_.unitCell().lattice() != UnitCell<D>::Null);
1380 UTIL_CHECK(domain_.unitCell().isInitialized());
1389 void System<D>::readEcho(std::istream& in, std::string&
string)
const
1399 void System<D>::readEcho(std::istream& in,
double& value)
const
1403 UTIL_THROW(
"Unable to read floating point parameter.");
1412 void System<D>::initHomogeneous()
1416 int nm = mixture().nMonomer();
1417 int np = mixture().nPolymer();
1418 int ns = mixture().nSolvent();
1420 UTIL_CHECK(homogeneous_.nMolecule() == np + ns);
1435 for (i = 0; i < np; ++i) {
1438 for (j = 0; j < nm; ++j) {
1443 nb = mixture_.polymer(i).nBlock();
1444 for (k = 0; k < nb; ++k) {
1445 Block<D>& block = mixture_.polymer(i).block(k);
1446 j = block.monomerId();
1447 cTmp[j] += block.length();
1452 for (j = 0; j < nm; ++j) {
1453 if (cTmp[j] > 1.0E-8) {
1457 homogeneous_.molecule(i).setNClump(nc);
1461 for (j = 0; j < nm; ++j) {
1462 if (cTmp[j] > 1.0E-8) {
1463 homogeneous_.molecule(i).clump(k).setMonomerId(j);
1464 homogeneous_.molecule(i).clump(k).setSize(cTmp[j]);
1468 homogeneous_.molecule(i).computeSize();
1477 for (
int is = 0; is < ns; ++is) {
1479 monomerId = mixture_.solvent(is).monomerId();
1480 size = mixture_.solvent(is).size();
1481 homogeneous_.molecule(i).setNClump(1);
1482 homogeneous_.molecule(i).clump(0).setMonomerId(monomerId);
1483 homogeneous_.molecule(i).clump(0).setSize(size);
1484 homogeneous_.molecule(i).computeSize();
1495 bool System<D>::checkRGridFieldSymmetry(
const std::string & inFileName)
1500 if (!isAllocatedBasis_) {
1501 readFieldHeader(inFileName);
1502 allocateFieldsBasis();
1505 const int nBasis = domain_.basis().nBasis();
1508 UnitCell<D> tmpUnitCell;
1509 fieldIo().readFieldsRGrid(inFileName, tmpFieldsRGrid_, tmpUnitCell);
1510 for (
int i = 0; i < mixture_.nMonomer(); ++i) {
1511 bool symmetric = fieldIo().hasSymmetry(tmpFieldsRGrid_[i]);
An IntVec<D, T> is a D-component vector of elements of integer type T.
Flory-Huggins excess free energy model.
int nBlock() const
Number of blocks.
Propagator & propagator(int blockId, int directionId)
Get propagator for a specific block and direction.
double length() const
Sum of the lengths of all blocks in the polymer.
Dynamic array on the GPU with alligned data.
Data * cDField()
Return pointer to underlying C array.
Factory for subclasses of Iterator.
Descriptor and solver for a branched polymer species.
MDE solver for one-direction of one block.
int ns() const
Get the number of contour grid points.
const cudaReal * tail() const
Return q-field at end of block.
const cudaReal * q(int i) const
Return q-field at specified step.
Field of real single precision values on an FFT mesh on a device.
void allocate(const IntVec< D > &meshDimensions)
Allocate the underlying C array for an FFT grid.
Solver and descriptor for a solvent species.
Default Factory for subclasses of Sweep.
Main class in SCFT simulation of one system.
void writeThermo(std::ostream &out)
Write thermodynamic properties to a file.
void readWRGrid(const std::string &filename)
Read chemical potential fields in real space grid (r-grid) format.
void setWRGrid(DArray< RDField< D > > const &fields)
Set new w fields, in real-space (r-grid) format.
void writeQSlice(std::string const &filename, int polymerId, int blockId, int directionId, int segmentId) const
Write specified slice of a propagator at fixed s in r-grid format.
void compute(bool needStress=false)
Solve the modified diffusion equation once, without iteration.
void writeGroup(std::string const &filename) const
Output all elements of the space group.
void symmetrizeWFields()
Symmetrize r-grid w-fields, compute basis components.
void writeCRGrid(const std::string &filename) const
Write concentration fields in real space grid (r-grid) format.
void estimateWfromC(const std::string &filename)
Construct trial w-fields from c-fields.
void writeStars(const std::string &filename) const
Output information about stars and symmetrized basis functions.
void rGridToBasis(const std::string &inFileName, const std::string &outFileName)
Convert a field from real-space grid to symmetrized basis format.
void rGridToKGrid(const std::string &inFileName, const std::string &outFileName)
Convert fields from real-space (r-grid) to Fourier (k-grid) format.
void basisToRGrid(const std::string &inFileName, const std::string &outFileName)
Convert a field from symmetry-adapted basis to r-grid format.
void writeParamNoSweep(std::ostream &out) const
Write parameter file to an ostream, omitting the sweep block.
int iterate(bool isContinuation=false)
Iteratively solve a SCFT problem.
void writeWBasis(const std::string &filename)
Write chemical potential fields in symmetry adapted basis format.
void setUnitCell(UnitCell< D > const &unitCell)
Set parameters of the associated unit cell.
void writeBlockCRGrid(const std::string &filename) const
Write c fields for all blocks and solvents in r-grid format.
void readParam()
Read input parameters from default param file.
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 writeQ(std::string const &filename, int polymerId, int blockId, int directionId) const
Write one propagator for one block, in r-grid format.
void writeWRGrid(const std::string &filename) const
Write chemical potential fields in real space grid (r-grid) format.
void kGridToRGrid(const std::string &inFileName, const std::string &outFileName)
Convert fields from Fourier (k-grid) to real-space (r-grid) format.
void writeQAll(std::string const &basename)
Write all propagators of all blocks, each to a separate file.
void readCommands()
Read commands from default command file.
void basisToKGrid(const std::string &inFileName, const std::string &outFileName)
Convert fields from symmetrized basis to Fourier (k-grid) format.
void sweep()
Sweep in parameter space, solving an SCF problem at each point.
void writeCBasis(const std::string &filename)
Write concentrations in symmetry-adapted basis format.
void setWBasis(DArray< DArray< double > > const &fields)
Set chemical potential fields, in symmetry-adapted basis format.
void writeWaves(const std::string &filename) const
Output information about waves.
void kGridToBasis(const std::string &inFileName, const std::string &outFileName)
Convert fields from Fourier (k-grid) to symmetrized basis format.
void readWBasis(const std::string &filename)
Read chemical potential fields in symmetry adapted basis format.
virtual void readParameters(std::istream &in)
Read body of parameter file (without opening, closing lines).
void setOptions(int argc, char **argv)
Process command line options.
void computeFreeEnergy()
Compute free energy density and pressure for current fields.
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).
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.
Wrapper for a double precision number, for formatted ostream output.
A fixed capacity (static) contiguous array with a variable logical size.
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.
void setClassName(const char *className)
Set class name string.
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.
void setThreadsPerBlock()
Set the number of threads per block to a default value.
void setThreadsLogical(int nThreadsLogical)
Set the total number of threads required for execution.
void init()
Initialize static variables in Pspg::ThreadGrid namespace.
C++ namespace for polymer self-consistent field theory (PSCF).
void set(BracketPolicy::Type policy)
Set policy regarding use of bracket delimiters on arrays.
Utility classes for scientific computation.