13#include <pspc/sweep/Sweep.h>
14#include <pspc/sweep/SweepFactory.h>
15#include <pspc/iterator/Iterator.h>
16#include <pspc/iterator/IteratorFactory.h>
17#include <pspc/solvers/Polymer.h>
18#include <pspc/solvers/Solvent.h>
19#include <pspc/field/BFieldComparison.h>
20#include <pspc/field/RFieldComparison.h>
22#include <pscf/inter/Interaction.h>
23#include <pscf/math/IntVec.h>
24#include <pscf/homogeneous/Clump.h>
26#include <util/param/BracketPolicy.h>
27#include <util/format/Str.h>
28#include <util/format/Int.h>
29#include <util/format/Dbl.h>
30#include <util/misc/ioUtil.h>
52 iteratorFactoryPtr_(0),
65 isAllocatedRGrid_(false),
66 isAllocatedBasis_(false),
71 domain_.setFileMaster(fileMaster_);
72 w_.setFieldIo(domain_.fieldIo());
73 h_.setFieldIo(domain_.fieldIo());
74 mask_.setFieldIo(domain_.fieldIo());
87 if (interactionPtr_) {
88 delete interactionPtr_;
93 if (iteratorFactoryPtr_) {
94 delete iteratorFactoryPtr_;
99 if (sweepFactoryPtr_) {
100 delete sweepFactoryPtr_;
123 while ((c = getopt(argc, argv,
"er:p:c:i:o:f")) != -1) {
145 Log::file() <<
"Unknown option -" << optopt << std::endl;
157 fileMaster_.setParamFileName(std::string(pArg));
162 fileMaster_.setCommandFileName(std::string(cArg));
167 fileMaster_.setInputPrefix(std::string(iArg));
172 fileMaster_.setOutputPrefix(std::string(oArg));
184 readParamComposite(in, mixture_);
187 int nm = mixture_.nMonomer();
188 int np = mixture_.nPolymer();
189 int ns = mixture_.nSolvent();
196 interaction().setNMonomer(nm);
197 readParamComposite(in, interaction());
200 readParamComposite(in, domain_);
202 mixture_.setMesh(domain_.mesh());
203 mixture_.setupUnitCell(unitCell());
206 allocateFieldsGrid();
207 if (domain_.basis().isInitialized()) {
208 allocateFieldsBasis();
212 std::string className;
215 iteratorFactoryPtr_->readObjectOptional(in, *
this, className,
218 Log::file() <<
"Notification: No iterator was constructed\n";
224 sweepFactoryPtr_->readObjectOptional(in, *
this, className,
230 homogeneous_.setNMolecule(np+ns);
231 homogeneous_.setNMonomer(nm);
242 readBegin(in, className().c_str());
252 { readParam(fileMaster_.paramFile()); }
261 std::string command, filename, inFileName, outFileName;
263 bool readNext =
true;
274 if (command ==
"FINISH") {
278 if (command ==
"READ_W_BASIS") {
279 readEcho(in, filename);
280 readWBasis(filename);
282 if (command ==
"READ_W_RGRID") {
283 readEcho(in, filename);
284 readWRGrid(filename);
286 if (command ==
"ESTIMATE_W_FROM_C") {
287 readEcho(in, inFileName);
288 estimateWfromC(inFileName);
290 if (command ==
"SET_UNIT_CELL") {
293 Log::file() <<
" " << unitCell << std::endl;
294 setUnitCell(unitCell);
296 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(in, filename);
316 fileMaster().openOutputFile(filename, file);
317 writeParamNoSweep(file);
320 if (command ==
"WRITE_THERMO") {
321 readEcho(in, filename);
323 fileMaster().openOutputFile(filename, file,
328 if (command ==
"WRITE_W_BASIS") {
329 readEcho(in, filename);
330 writeWBasis(filename);
332 if (command ==
"WRITE_W_RGRID") {
333 readEcho(in, filename);
334 writeWRGrid(filename);
336 if (command ==
"WRITE_C_BASIS") {
337 readEcho(in, filename);
338 writeCBasis(filename);
340 if (command ==
"WRITE_C_RGRID") {
341 readEcho(in, filename);
342 writeCRGrid(filename);
344 if (command ==
"WRITE_BLOCK_C_RGRID") {
345 readEcho(in, filename);
346 writeBlockCRGrid(filename);
348 if (command ==
"WRITE_Q_SLICE") {
349 int polymerId, blockId, directionId, segmentId;
350 readEcho(in, filename);
355 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
356 <<
Str(
"block ID ", 21) << blockId <<
"\n"
357 <<
Str(
"direction ID ", 21) << directionId <<
"\n"
358 <<
Str(
"segment ID ", 21) << segmentId << std::endl;
359 writeQSlice(filename, polymerId, blockId, directionId,
362 if (command ==
"WRITE_Q_TAIL") {
363 readEcho(in, filename);
364 int polymerId, blockId, directionId;
368 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
369 <<
Str(
"block ID ", 21) << blockId <<
"\n"
370 <<
Str(
"direction ID ", 21) << directionId <<
"\n";
371 writeQTail(filename, polymerId, blockId, directionId);
373 if (command ==
"WRITE_Q") {
374 readEcho(in, filename);
375 int polymerId, blockId, directionId;
379 Log::file() <<
Str(
"polymer ID ", 21) << polymerId <<
"\n"
380 <<
Str(
"block ID ", 21) << blockId <<
"\n"
381 <<
Str(
"direction ID ", 21) << directionId <<
"\n";
382 writeQ(filename, polymerId, blockId, directionId);
384 if (command ==
"WRITE_Q_ALL") {
385 readEcho(in, filename);
388 if (command ==
"WRITE_STARS") {
389 readEcho(in, filename);
390 writeStars(filename);
392 if (command ==
"WRITE_WAVES") {
393 readEcho(in, filename);
394 writeWaves(filename);
396 if (command ==
"WRITE_GROUP") {
397 readEcho(in, filename);
398 writeGroup(filename);
400 if (command ==
"BASIS_TO_RGRID") {
401 readEcho(in, inFileName);
402 readEcho(in, outFileName);
403 basisToRGrid(inFileName, outFileName);
405 if (command ==
"RGRID_TO_BASIS") {
406 readEcho(in, inFileName);
407 readEcho(in, outFileName);
408 rGridToBasis(inFileName, outFileName);
410 if (command ==
"KGRID_TO_RGRID") {
411 readEcho(in, inFileName);
412 readEcho(in, outFileName);
413 kGridToRGrid(inFileName, outFileName);
415 if (command ==
"RGRID_TO_KGRID") {
416 readEcho(in, inFileName);
417 readEcho(in, outFileName);
418 rGridToKGrid(inFileName, outFileName);
420 if (command ==
"BASIS_TO_KGRID") {
421 readEcho(in, inFileName);
422 readEcho(in, outFileName);
423 basisToKGrid(inFileName, outFileName);
425 if (command ==
"KGRID_TO_BASIS") {
426 readEcho(in, inFileName);
427 readEcho(in, outFileName);
428 kGridToBasis(inFileName, outFileName);
430 if (command ==
"CHECK_RGRID_SYMMETRY") {
432 readEcho(in, inFileName);
433 readEcho(in, epsilon);
435 hasSymmetry = checkRGridFieldSymmetry(inFileName, epsilon);
438 <<
"Symmetry of r-grid file matches this space group."
439 << std::endl << std::endl;
442 <<
"Symmetry of r-grid file does not match this space group"
444 <<
"to within error threshold of "
445 <<
Dbl(epsilon) <<
"."
446 << std::endl << std::endl;
449 if (command ==
"COMPARE_BASIS") {
452 std::string filecompare1, filecompare2;
453 readEcho(in, filecompare1);
454 readEcho(in, filecompare2);
457 domain_.fieldIo().readFieldsBasis(filecompare1, Bfield1,
459 domain_.fieldIo().readFieldsBasis(filecompare2, Bfield2,
464 compare(Bfield1, Bfield2);
467 if (command ==
"COMPARE_RGRID") {
469 std::string filecompare1, filecompare2;
470 readEcho(in, filecompare1);
471 readEcho(in, filecompare2);
474 domain_.fieldIo().readFieldsRGrid(filecompare1, Rfield1,
476 domain_.fieldIo().readFieldsRGrid(filecompare2, Rfield2,
481 compare(Rfield1, Rfield2);
484 if (command ==
"READ_H_BASIS") {
485 readEcho(in, filename);
486 if (!h_.isAllocatedBasis()) {
487 h_.allocateBasis(basis().nBasis());
489 if (!h_.isAllocatedRGrid()) {
490 h_.allocateRGrid(mesh().dimensions());
492 h_.readBasis(filename, domain_.unitCell());
494 if (command ==
"READ_H_RGRID") {
495 readEcho(in, filename);
496 if (!h_.isAllocatedRGrid()) {
497 h_.allocateRGrid(mesh().dimensions());
499 h_.readRGrid(filename, domain_.unitCell());
501 if (command ==
"WRITE_H_BASIS") {
502 readEcho(in, filename);
505 fieldIo().writeFieldsBasis(filename, h_.basis(), unitCell());
507 if (command ==
"WRITE_H_RGRID") {
508 readEcho(in, filename);
510 fieldIo().writeFieldsRGrid(filename, h_.rgrid(), unitCell());
512 if (command ==
"READ_MASK_BASIS") {
514 readEcho(in, filename);
515 if (!mask_.isAllocated()) {
516 mask_.allocate(basis().nBasis(), mesh().dimensions());
518 mask_.readBasis(filename, domain_.unitCell());
520 if (command ==
"READ_MASK_RGRID") {
521 readEcho(in, filename);
522 if (!mask_.isAllocated()) {
523 mask_.allocate(basis().nBasis(), mesh().dimensions());
525 mask_.readBasis(filename, domain_.unitCell());
527 if (command ==
"WRITE_MASK_BASIS") {
528 readEcho(in, filename);
531 fieldIo().writeFieldBasis(filename, mask_.basis(), unitCell());
533 if (command ==
"WRITE_MASK_RGRID") {
534 readEcho(in, filename);
536 fieldIo().writeFieldRGrid(filename, mask_.rgrid(), unitCell());
539 << command << std::endl;
551 if (fileMaster_.commandFileName().empty()) {
554 readCommands(fileMaster_.commandFile());
567 if (!isAllocatedBasis_) {
568 readFieldHeader(filename);
569 allocateFieldsBasis();
573 w_.readBasis(filename, domain_.unitCell());
574 mixture_.setupUnitCell(domain_.unitCell());
576 hasFreeEnergy_ =
false;
588 if (!isAllocatedBasis_) {
589 readFieldHeader(filename);
590 allocateFieldsBasis();
594 w_.readRGrid(filename, domain_.unitCell());
595 mixture_.setupUnitCell(domain_.unitCell());
597 hasFreeEnergy_ =
false;
610 hasFreeEnergy_ =
false;
622 hasFreeEnergy_ =
false;
634 const int nm = mixture_.nMonomer();
639 if (!isAllocatedBasis_) {
640 readFieldHeader(filename);
641 allocateFieldsBasis();
643 const int nb = domain_.basis().nBasis();
647 domain_.fieldIo().readFieldsBasis(filename, tmpFieldsBasis_,
655 for (i = 0; i < nb; ++i) {
656 for (j = 0; j < nm; ++j) {
658 for (k = 0; k < nm; ++k) {
659 wtmp[j] += interaction().chi(j,k)*tmpFieldsBasis_[k][i];
662 for (j = 0; j < nm; ++j) {
663 tmpFieldsBasis_[j][i] = wtmp[j];
668 w_.setBasis(tmpFieldsBasis_);
671 hasFreeEnergy_ =
false;
682 domain_.setUnitCell(unitCell);
683 mixture_.setupUnitCell(domain_.unitCell());
684 if (!isAllocatedBasis_) {
685 allocateFieldsBasis();
697 domain_.setUnitCell(lattice, parameters);
698 mixture_.setupUnitCell(domain_.unitCell());
699 if (!isAllocatedBasis_) {
700 allocateFieldsBasis();
710 domain_.setUnitCell(parameters);
711 mixture_.setupUnitCell(domain_.unitCell());
712 if (!isAllocatedBasis_) {
713 allocateFieldsBasis();
730 mixture_.compute(w_.rgrid(), c_.rgrid(), mask_.phiTot());
732 hasFreeEnergy_ =
false;
736 mixture_.computeStress();
740 if (w_.isSymmetric()) {
742 domain_.fieldIo().convertRGridToBasis(c_.rgrid(), c_.basis(),
false);
757 hasFreeEnergy_ =
false;
763 int error = iterator().solve(isContinuation);
768 if (!iterator().isFlexible()) {
769 mixture().computeStress();
812 int np = mixture_.nPolymer();
813 int ns = mixture_.nSolvent();
819 for (
int i = 0; i < np; ++i) {
820 polymerPtr = &mixture_.polymer(i);
821 phi = polymerPtr->
phi();
822 mu = polymerPtr->
mu();
823 length = polymerPtr->
length();
826 fIdeal_ += phi*( mu - 1.0 )/length;
835 for (
int i = 0; i < ns; ++i) {
836 solventPtr = &mixture_.solvent(i);
837 phi = solventPtr->
phi();
838 mu = solventPtr->
mu();
839 size = solventPtr->
size();
841 fIdeal_ += phi*( mu - 1.0 )/size;
846 int nm = mixture_.nMonomer();
847 int nBasis = domain_.basis().nBasis();
852 for (
int i = 0; i < nm; ++i) {
853 for (
int k = 0; k < nBasis; ++k) {
854 temp -= w_.basis(i)[k] * c_.basis(i)[k];
867 temp /= mask().phiTot();
869 fHelmholtz_ += fIdeal_;
872 if (hasExternalFields()) {
874 for (
int i = 0; i < nm; ++i) {
875 for (
int k = 0; k < nBasis; ++k) {
876 fExt_ += h_.basis(i)[k] * c_.basis(i)[k];
879 fExt_ /= mask().phiTot();
880 fHelmholtz_ += fExt_;
885 for (
int i = 0; i < nm; ++i) {
886 for (
int j = i + 1; j < nm; ++j) {
887 chi = interaction().chi(i,j);
888 for (
int k = 0; k < nBasis; ++k) {
889 fInter_ += chi * c_.basis(i)[k] * c_.basis(j)[k];
893 fInter_ /= mask().phiTot();
894 fHelmholtz_ += fInter_;
897 pressure_ = -fHelmholtz_;
903 for (
int i = 0; i < np; ++i) {
904 polymerPtr = &mixture_.polymer(i);
905 phi = polymerPtr->
phi();
906 mu = polymerPtr->
mu();
907 length = polymerPtr->
length();
909 pressure_ += mu * phi /length;
918 for (
int i = 0; i < ns; ++i) {
919 solventPtr = &mixture_.solvent(i);
920 phi = solventPtr->
phi();
921 mu = solventPtr->
mu();
922 size = solventPtr->
size();
924 pressure_ += mu * phi /size;
929 hasFreeEnergy_ =
true;
940 out <<
"System{" << std::endl;
941 mixture().writeParam(out);
942 interaction().writeParam(out);
943 domain_.writeParam(out);
945 iterator().writeParam(out);
947 out <<
"}" << std::endl;
956 if (!hasFreeEnergy_) {
961 out <<
"fHelmholtz " <<
Dbl(fHelmholtz(), 18, 11) << std::endl;
962 out <<
"pressure " <<
Dbl(pressure(), 18, 11) << std::endl;
964 out <<
"fIdeal " <<
Dbl(fIdeal_, 18, 11) << std::endl;
965 out <<
"fInter " <<
Dbl(fInter_, 18, 11) << std::endl;
966 if (hasExternalFields()) {
967 out <<
"fExt " <<
Dbl(fExt_, 18, 11) << std::endl;
971 int np = mixture_.nPolymer();
972 int ns = mixture_.nSolvent();
975 out <<
"polymers:" << std::endl;
980 for (
int i = 0; i < np; ++i) {
982 <<
" " <<
Dbl(mixture_.polymer(i).phi(),18, 11)
983 <<
" " <<
Dbl(mixture_.polymer(i).mu(), 18, 11)
990 out <<
"solvents:" << std::endl;
995 for (
int i = 0; i < ns; ++i) {
997 <<
" " <<
Dbl(mixture_.solvent(i).phi(),18, 11)
998 <<
" " <<
Dbl(mixture_.solvent(i).mu(), 18, 11)
1004 out <<
"cellParams:" << std::endl;
1005 for (
int i = 0; i < unitCell().nParameter(); ++i) {
1008 <<
Dbl(unitCell().parameter(i), 18, 11)
1024 domain_.fieldIo().writeFieldsBasis(filename, w_.basis(),
1025 domain_.unitCell());
1036 domain_.fieldIo().writeFieldsRGrid(filename, w_.rgrid(),
1037 domain_.unitCell());
1050 domain_.fieldIo().writeFieldsBasis(filename, c_.basis(),
1051 domain_.unitCell());
1062 domain_.fieldIo().writeFieldsRGrid(filename, c_.rgrid(),
1063 domain_.unitCell());
1078 blockCFields.
allocate(mixture_.nSolvent() + mixture_.nBlock());
1080 for (
int i = 0; i < n; i++) {
1081 blockCFields[i].
allocate(domain_.mesh().dimensions());
1085 mixture_.createBlockCRGrid(blockCFields);
1086 domain_.fieldIo().writeFieldsRGrid(filename, blockCFields,
1087 domain_.unitCell());
1095 int polymerId,
int blockId,
1096 int directionId,
int segmentId)
1101 Polymer<D> const& polymer = mixture_.polymer(polymerId);
1107 propagator = polymer.
propagator(blockId, directionId);
1108 RField<D> const& field = propagator.
q(segmentId);
1109 domain_.fieldIo().writeFieldRGrid(filename, field,
1110 domain_.unitCell());
1118 int polymerId,
int blockId,
int directionId)
1123 Polymer<D> const& polymer = mixture_.polymer(polymerId);
1130 domain_.fieldIo().writeFieldRGrid(filename, field,
1131 domain_.unitCell());
1139 int polymerId,
int blockId,
int directionId)
1144 Polymer<D> const& polymer = mixture_.polymer(polymerId);
1151 int ns = propagator.
ns();
1155 fileMaster_.openOutputFile(filename, file);
1158 fieldIo().writeFieldHeader(file, 1, domain_.unitCell());
1159 file <<
"mesh " << std::endl
1160 <<
" " << domain_.mesh().dimensions() << std::endl
1161 <<
"nslice" << std::endl
1162 <<
" " << ns << std::endl;
1165 bool hasHeader =
false;
1166 for (
int i = 0; i < ns; ++i) {
1167 file <<
"slice " << i << std::endl;
1168 fieldIo().writeFieldRGrid(file, propagator.
q(i),
1169 domain_.unitCell(), hasHeader);
1180 std::string filename;
1181 int np, nb, ip, ib, id;
1182 np = mixture_.nPolymer();
1183 for (ip = 0; ip < np; ++ip) {
1184 nb = mixture_.polymer(ip).nBlock();
1185 for (ib = 0; ib < nb; ++ib) {
1186 for (
id = 0;
id < 2; ++id) {
1187 filename = basename;
1195 writeQ(filename, ip, ib,
id);
1209 fileMaster_.openOutputFile(filename, file);
1210 fieldIo().writeFieldHeader(file, mixture_.nMonomer(),
1211 domain_.unitCell());
1212 domain_.basis().outputStars(file);
1224 fileMaster_.openOutputFile(filename, file);
1225 fieldIo().writeFieldHeader(file, mixture_.nMonomer(),
1226 domain_.unitCell());
1227 domain_.basis().outputWaves(file);
1237 Pscf::writeGroup(filename, domain_.group());
1247 const std::string & outFileName)
1251 if (!isAllocatedBasis_) {
1252 readFieldHeader(inFileName);
1253 allocateFieldsBasis();
1258 fieldIo().readFieldsBasis(inFileName, tmpFieldsBasis_, tmpUnitCell);
1259 fieldIo().convertBasisToRGrid(tmpFieldsBasis_, tmpFieldsRGrid_);
1260 fieldIo().writeFieldsRGrid(outFileName, tmpFieldsRGrid_,
1269 const std::string & outFileName)
1273 if (!isAllocatedBasis_) {
1274 readFieldHeader(inFileName);
1275 allocateFieldsBasis();
1280 fieldIo().readFieldsRGrid(inFileName, tmpFieldsRGrid_, tmpUnitCell);
1281 fieldIo().convertRGridToBasis(tmpFieldsRGrid_, tmpFieldsBasis_);
1282 fieldIo().writeFieldsBasis(outFileName, tmpFieldsBasis_,
1291 const std::string& outFileName)
1295 if (!isAllocatedBasis_) {
1296 readFieldHeader(inFileName);
1297 allocateFieldsBasis();
1302 fieldIo().readFieldsKGrid(inFileName, tmpFieldsKGrid_, tmpUnitCell);
1303 for (
int i = 0; i < mixture_.nMonomer(); ++i) {
1304 domain_.fft().inverseTransform(tmpFieldsKGrid_[i],
1305 tmpFieldsRGrid_[i]);
1307 fieldIo().writeFieldsRGrid(outFileName, tmpFieldsRGrid_,
1316 const std::string & outFileName)
1320 if (!isAllocatedBasis_) {
1321 readFieldHeader(inFileName);
1322 allocateFieldsBasis();
1327 fieldIo().readFieldsRGrid(inFileName, tmpFieldsRGrid_,
1329 for (
int i = 0; i < mixture_.nMonomer(); ++i) {
1330 domain_.fft().forwardTransform(tmpFieldsRGrid_[i],
1331 tmpFieldsKGrid_[i]);
1333 domain_.fieldIo().writeFieldsKGrid(outFileName, tmpFieldsKGrid_,
1342 const std::string& outFileName)
1346 if (!isAllocatedBasis_) {
1347 readFieldHeader(inFileName);
1348 allocateFieldsBasis();
1353 domain_.fieldIo().readFieldsKGrid(inFileName, tmpFieldsKGrid_,
1355 domain_.fieldIo().convertKGridToBasis(tmpFieldsKGrid_,
1357 domain_.fieldIo().writeFieldsBasis(outFileName,
1358 tmpFieldsBasis_, tmpUnitCell);
1366 const std::string & outFileName)
1370 if (!isAllocatedBasis_) {
1371 readFieldHeader(inFileName);
1372 allocateFieldsBasis();
1377 domain_.fieldIo().readFieldsBasis(inFileName,
1378 tmpFieldsBasis_, tmpUnitCell);
1379 domain_.fieldIo().convertBasisToKGrid(tmpFieldsBasis_,
1381 domain_.fieldIo().writeFieldsKGrid(outFileName,
1382 tmpFieldsKGrid_, tmpUnitCell);
1394 if (!isAllocatedBasis_) {
1395 readFieldHeader(inFileName);
1396 allocateFieldsBasis();
1401 domain_.fieldIo().readFieldsRGrid(inFileName,
1402 tmpFieldsRGrid_, tmpUnitCell);
1405 for (
int i = 0; i < mixture_.nMonomer(); ++i) {
1407 symmetric = domain_.fieldIo().hasSymmetry(tmpFieldsRGrid_[i],
1425 comparison.
compare(field1,field2);
1427 Log::file() <<
"\n Basis expansion field comparison results"
1429 Log::file() <<
" Maximum Absolute Difference: "
1430 << comparison.
maxDiff() << std::endl;
1431 Log::file() <<
" Root-Mean-Square Difference: "
1432 << comparison.
rmsDiff() <<
"\n" << std::endl;
1443 comparison.
compare(field1, field2);
1445 Log::file() <<
"\n Real-space field comparison results"
1447 Log::file() <<
" Maximum Absolute Difference: "
1448 << comparison.
maxDiff() << std::endl;
1449 Log::file() <<
" Root-Mean-Square Difference: "
1450 << comparison.
rmsDiff() <<
"\n" << std::endl;
1463 int nMonomer = mixture_.nMonomer();
1469 IntVec<D> const & dimensions = domain_.mesh().dimensions();
1472 w_.setNMonomer(nMonomer);
1473 w_.allocateRGrid(dimensions);
1476 c_.setNMonomer(nMonomer);
1477 c_.allocateRGrid(dimensions);
1479 h_.setNMonomer(nMonomer);
1482 tmpFieldsRGrid_.allocate(nMonomer);
1483 tmpFieldsKGrid_.allocate(nMonomer);
1484 for (
int i = 0; i < nMonomer; ++i) {
1485 tmpFieldsRGrid_[i].allocate(dimensions);
1486 tmpFieldsKGrid_[i].allocate(dimensions);
1488 isAllocatedRGrid_ =
true;
1495 void System<D>::allocateFieldsBasis()
1499 const int nMonomer = mixture_.nMonomer();
1504 const int nBasis = domain_.basis().nBasis();
1507 w_.allocateBasis(nBasis);
1508 c_.allocateBasis(nBasis);
1511 tmpFieldsBasis_.allocate(nMonomer);
1512 for (
int i = 0; i < nMonomer; ++i) {
1513 tmpFieldsBasis_[i].allocate(nBasis);
1515 isAllocatedBasis_ =
true;
1522 void System<D>::readFieldHeader(std::string filename)
1529 fileMaster_.openInputFile(filename, file);
1533 domain_.fieldIo().readFieldHeader(file, nMonomer,
1534 domain_.unitCell());
1540 UTIL_CHECK(domain_.unitCell().nParameter() > 0);
1541 UTIL_CHECK(domain_.unitCell().lattice() != UnitCell<D>::Null);
1542 UTIL_CHECK(domain_.unitCell().isInitialized());
1551 void System<D>::readEcho(std::istream& in, std::string&
string)
const
1555 UTIL_THROW(
"Unable to read string parameter.");
1564 void System<D>::readEcho(std::istream& in,
double& value)
const
1568 UTIL_THROW(
"Unable to read floating point parameter.");
1578 void System<D>::initHomogeneous()
1583 int nm = mixture_.nMonomer();
1584 int np = mixture_.nPolymer();
1585 int ns = mixture_.nSolvent();
1586 UTIL_CHECK(homogeneous_.nMolecule() == np + ns);
1604 for (i = 0; i < np; ++i) {
1607 for (j = 0; j < nm; ++j) {
1612 nb = mixture_.polymer(i).nBlock();
1613 for (k = 0; k < nb; ++k) {
1614 Block<D>& block = mixture_.polymer(i).block(k);
1615 j = block.monomerId();
1616 s[j] += block.length();
1621 for (j = 0; j < nm; ++j) {
1622 if (s[j] > 1.0E-8) {
1626 homogeneous_.molecule(i).setNClump(nc);
1630 for (j = 0; j < nm; ++j) {
1631 if (s[j] > 1.0E-8) {
1632 homogeneous_.molecule(i).clump(k).setMonomerId(j);
1633 homogeneous_.molecule(i).clump(k).setSize(s[j]);
1637 homogeneous_.molecule(i).computeSize();
1646 for (
int is = 0; is < ns; ++is) {
1648 monomerId = mixture_.solvent(is).monomerId();
1649 size = mixture_.solvent(is).size();
1650 homogeneous_.molecule(i).setNClump(1);
1651 homogeneous_.molecule(i).clump(0).setMonomerId(monomerId);
1652 homogeneous_.molecule(i).clump(0).setSize(size);
1653 homogeneous_.molecule(i).computeSize();
Comparator for fields in symmetry-adapted basis format.
double rmsDiff() const
Return the precomputed root-mean-squared difference.
double compare(FT const &a, FT const &b)
Compare individual fields.
double maxDiff() const
Return the precomputed maximum element-by-element difference.
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.
Factory for subclasses of Iterator.
Descriptor and solver for one polymer species.
MDE solver for one direction of one block.
int ns() const
Number of values of s (or slices), including head and tail.
const QField & q(int i) const
Return q-field at specified step.
const QField & tail() const
Return q-field at the end of the block.
Comparator for fields in real-space (r-grid) format.
Field of real double precision values on an FFT mesh.
Solver and descriptor for a solvent species.
Default Factory for subclasses of Sweep.
Main class for SCFT simulation of one system.
void setWBasis(DArray< DArray< double > > const &fields)
Set chemical potential fields, in symmetry-adapted basis format.
int iterate(bool isContinuation=false)
Iteratively solve a SCFT problem.
void setOptions(int argc, char **argv)
Process command line options.
void writeCRGrid(const std::string &filename) const
Write concentration fields in real space grid (r-grid) format.
void writeGroup(std::string const &filename) const
Output all elements of the space group.
void readParam()
Read input parameters from default param file.
void kGridToBasis(const std::string &inFileName, const std::string &outFileName)
Convert fields from Fourier (k-grid) to symmetrized basis format.
void writeWRGrid(const std::string &filename) const
Write chemical potential fields in real space grid (r-grid) format.
void setUnitCell(UnitCell< D > const &unitCell)
Set parameters of the associated unit cell.
void compare(const DArray< DArray< double > > field1, const DArray< DArray< double > > field2)
Compare two field files in symmetrized basis format.
void writeBlockCRGrid(const std::string &filename) const
Write c-fields for all blocks and solvents in r-grid format.
void compute(bool needStress=false)
Solve the modified diffusion equation once, without iteration.
void writeParamNoSweep(std::ostream &out) const
Write parameter file to an ostream, omitting any sweep block.
void basisToRGrid(const std::string &inFileName, const std::string &outFileName)
Convert a field from symmetrized basis format to r-grid format.
virtual void readParameters(std::istream &in)
Read body of parameter block (without opening and closing lines).
void sweep()
Sweep in parameter space, solving an SCF problem at each point.
void readWRGrid(const std::string &filename)
Read chemical potential fields in real space grid (r-grid) format.
void writeThermo(std::ostream &out)
Write thermodynamic properties to a file.
void writeCBasis(const std::string &filename) const
Write concentration fields in symmetrized basis 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.
void writeQAll(std::string const &basename)
Write all propagators of all blocks, each to a separate file.
void estimateWfromC(const std::string &filename)
Construct trial w-fields from c-fields.
void writeStars(std::string const &filename) const
Output information about stars and symmetrized basis functions.
void kGridToRGrid(const std::string &inFileName, const std::string &outFileName)
Convert fields from Fourier (k-grid) to real-space (r-grid) format.
void writeWBasis(const std::string &filename) const
Write chemical potential fields in symmetrized basis format.
void readCommands()
Read commands from default command file.
void rGridToBasis(const std::string &inFileName, const std::string &outFileName)
Convert a field from real-space grid to symmetrized basis format.
void readWBasis(const std::string &filename)
Read chemical potential fields in symmetry adapted basis format.
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.
bool checkRGridFieldSymmetry(const std::string &inFileName, double epsilon=1.0E-8)
Check if r-grid fields have the declared space group symmetry.
void rGridToKGrid(const std::string &inFileName, const std::string &outFileName)
Convert fields from real-space (r-grid) to Fourier (k-grid) format.
void writeWaves(std::string const &filename) const
Output information about waves.
void computeFreeEnergy()
Compute free energy density and pressure for current 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 basisToKGrid(const std::string &inFileName, const std::string &outFileName)
Convert fields from symmetrized basis to Fourier (k-grid) format.
void setWRGrid(DArray< RField< D > > const &fields)
Set new w fields, in real-space (r-grid) format.
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.
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.