1#ifndef PRDC_FIELD_IO_UTIL_TPP
2#define PRDC_FIELD_IO_UTIL_TPP
11#include <prdc/crystal/Basis.h>
12#include <prdc/crystal/UnitCell.h>
13#include <prdc/crystal/replicateUnitCell.h>
14#include <prdc/crystal/shiftToMinimum.h>
15#include <prdc/crystal/fieldHeader.h>
17#include <pscf/mesh/Mesh.h>
18#include <pscf/mesh/MeshIterator.h>
19#include <pscf/mesh/MeshIteratorFortran.h>
20#include <pscf/math/IntVec.h>
21#include <pscf/math/complex.h>
23#include <util/containers/DArray.h>
24#include <util/misc/FileMaster.h>
25#include <util/misc/Log.h>
26#include <util/format/Int.h>
27#include <util/format/Dbl.h>
37 template <
int D,
class FT>
41 if (field.isAllocated()) {
42 UTIL_CHECK(field.meshDimensions() == dimensions);
44 field.allocate(dimensions);
51 template <
int D,
class FT>
57 int nMonomerFields = fields.
capacity();
60 for (
int i = 0; i < nMonomer; ++i) {
61 UTIL_CHECK(fields[i].meshDimensions() == dimensions);
65 for (
int i = 0; i < nMonomer; ++i) {
74 template <
int D,
class FT>
83 dimensions = fields[0].meshDimensions();
84 for (
int i = 0; i < nMonomer; ++i) {
85 UTIL_CHECK(fields[i].meshDimensions() == dimensions);
98 int nMonomerArrays = arrays.
capacity();
101 for (
int i = 0; i < nMonomer; ++i) {
106 for (
int i = 0; i < nMonomer; ++i) {
126 for (
int i = 0; i < nMonomer; ++i) {
140 if (label !=
"mesh" && label !=
"ngrid") {
141 std::string msg =
"\n";
142 msg +=
"Error reading field file:\n";
143 msg +=
"Expected mesh or ngrid, but found [";
149 in >> meshDimensionsIn;
150 if (meshDimensionsIn != meshDimensions) {
152 <<
"Inconsistent mesh dimensions:\n"
153 <<
"meshDimensions (expected) = " << meshDimensions <<
"\n"
154 <<
"meshDimensions (from file) = " << meshDimensionsIn <<
"\n";
155 UTIL_THROW(
"Unexpected mesh dimensions in field file header");
163 out <<
"mesh " << std::endl
164 <<
" " << meshDimensions << std::endl;
167 template <
int D,
class ART>
178 for (iter.begin(); !iter.atEnd(); ++iter) {
180 for (
int k = 0; k < nMonomer; ++k) {
181 in >> fields[k][rank];
186 template <
int D,
class ART>
189 IntVec<D>
const& dimensions)
191 MeshIteratorFortran<D> iter(dimensions);
193 for (iter.begin(); !iter.atEnd(); ++iter) {
199 template <
int D,
class ART>
203 IntVec<D>
const& dimensions)
208 MeshIteratorFortran<D> iter(dimensions);
210 for (iter.begin(); !iter.atEnd(); ++iter) {
212 for (j = 0; j < nMonomer; ++j) {
213 out <<
" " <<
Dbl(fields[j][rank], 21, 13);
220 template <
int D,
class ART>
223 IntVec<D>
const& dimensions)
225 MeshIteratorFortran<D> iter(dimensions);
227 for (iter.begin(); !iter.atEnd(); ++iter) {
229 out <<
" " <<
Dbl(field[rank], 21, 13);
236 template <
int D,
class ACT>
240 IntVec<D>
const& dftDimensions)
242 typedef typename ACT::Complex CT;
243 typedef typename ACT::Real RT;
246 MeshIterator<D> iter(dftDimensions);
247 int rank, i, j, idum;
249 for (iter.begin(); !iter.atEnd(); ++iter) {
254 for (j = 0; j < nMonomer; ++j) {
263 template <
int D,
class ACT>
266 IntVec<D>
const& dftDimensions)
268 typedef typename ACT::Complex CT;
269 typedef typename ACT::Real RT;
272 MeshIterator<D> iter(dftDimensions);
275 for (iter.begin(); !iter.atEnd(); ++iter) {
289 template <
int D,
class ACT>
293 IntVec<D>
const& dftDimensions)
298 typedef typename ACT::Complex CT;
299 typedef typename ACT::Real RT;
302 MeshIterator<D> iter(dftDimensions);
305 for (iter.begin(); !iter.atEnd(); ++iter) {
309 for (
int j = 0; j < nMonomer; ++j) {
322 template <
int D,
class ACT>
325 IntVec<D>
const& dftDimensions)
327 typedef typename ACT::Complex CT;
328 typedef typename ACT::Real RT;
331 MeshIterator<D> iter(dftDimensions);
334 for (iter.begin(); !iter.atEnd(); ++iter) {
359 if (label !=
"N_star" && label !=
"N_basis") {
360 std::string msg =
"\n";
361 msg +=
"Error reading field file:\n";
362 msg +=
"Expected N_basis or N_star, but found [";
381 out <<
"N_basis " << std::endl
382 <<
" " << nBasis << std::endl;
403 int fieldCapacity = fields[0].
capacity();
405 for (
int i = 0; i < nMonomer; ++i) {
406 UTIL_CHECK(fields[i].capacity() == fieldCapacity);
407 for (
int j = 0; j < fieldCapacity; ++j) {
413 int nBasis = nBasisIn;
414 if (fieldCapacity < nBasisIn) {
415 nBasis = fieldCapacity;
428 int basisId, basisId2;
431 std::complex<double> coeff, phasor;
433 int nReversedPair = 0;
434 bool waveExists, sizeMatches;
441 for (
int j = 0; j < nMonomer; ++j) {
452 waveBz = shiftToMinimum(waveIn, mesh.
dimensions(), unitCell);
453 waveExists = (waveIn == waveBz);
460 waveId = basis.
waveId(waveDft);
462 starPtr = &basis.
star(starId);
466 if (starPtr->
size == sizeIn) {
470 <<
"Warning: Inconsistent star size (line ignored)\n"
471 <<
"wave from file = " << waveIn <<
"\n"
472 <<
"size from file = " << sizeIn <<
"\n"
473 <<
"size of star = " << starPtr->
size
480 if (waveExists && sizeMatches) {
484 if (starPtr->
waveBz == waveIn) {
487 for (
int j = 0; j < nMonomer; ++j) {
488 fields[j][basisId] = temp[j];
494 <<
"Inconsistent wave of closed star on input\n"
495 <<
"wave from file = " << waveIn <<
"\n"
496 <<
"starId of wave = " << starId <<
"\n"
497 <<
"waveBz of star = " << starPtr->
waveBz
505 for (
int j = 0; j < nMonomer; ++j) {
514 shiftToMinimum(waveIn2, mesh.
dimensions(), unitCell);
520 waveId2 = basis.
waveId(waveDft);
522 starPtr2 = &basis.
star(starId2);
539 for (
int j = 0; j < nMonomer; ++j) {
540 fields[j][basisId] = temp[j];
541 fields[j][basisId2] = temp2[j];
558 shiftToMinimum(nVec, mesh.
dimensions(), unitCell);
607 phasor = phasor/std::abs(phasor);
608 for (
int j = 0; j < nMonomer; ++j) {
609 coeff = std::complex<double>(temp[j],-temp2[j]);
611 fields[j][basisId2] =
real(coeff);
612 fields[j][basisId ] =
imag(coeff);
628 if (nReversedPair > 0) {
630 Log::file() << nReversedPair <<
" reversed pairs of open stars"
631 <<
" detected in readFieldsBasis\n";
647 int fieldCapacity = fields[0].
capacity();
648 for (
int j = 0; j < nMonomer; ++j) {
649 UTIL_CHECK(fieldCapacity == fields[j].capacity());
655 int nStar = basis.
nStar();
656 for (
int i = 0; i < nStar; ++i) {
657 if (ib >= fieldCapacity)
break;
659 for (
int j = 0; j < nMonomer; ++j) {
660 out <<
Dbl(fields[j][ib], 20, 10);
663 for (
int j = 0; j < D; ++j) {
673 template <
int D,
class ACT>
676 Basis<D>
const& basis,
681 typedef typename ACT::Complex CT;
682 typedef typename ACT::Real RT;
685 Mesh<D> dftMesh(dftDimensions);
687 typename Basis<D>::Star
const* starPtr;
688 typename Basis<D>::Wave
const* wavePtr;
689 std::complex<double> component;
690 std::complex<double> coeff;
698 for (rank = 0; rank < dftMesh.size(); ++rank) {
706 while (is < basis.nStar()) {
707 starPtr = &(basis.star(is));
709 if (starPtr->cancel) {
715 ib = starPtr->basisId;
717 if (starPtr->invertFlag == 0) {
720 component = std::complex<double>(in[ib], 0.0);
723 for (iw = starPtr->beginId; iw < starPtr->endId; ++iw) {
724 wavePtr = &basis.wave(iw);
725 if (!wavePtr->implicit) {
726 coeff = component*(wavePtr->coeff);
727 indices = wavePtr->indicesDft;
728 rank = dftMesh.rank(indices);
737 if (starPtr->invertFlag == 1) {
740 component = std::complex<double>(in[ib], -in[ib+1]);
741 component /= sqrt(2.0);
742 starPtr = &(basis.star(is));
743 for (iw = starPtr->beginId; iw < starPtr->endId; ++iw) {
744 wavePtr = &basis.wave(iw);
745 if (!(wavePtr->implicit)) {
746 coeff = component*(wavePtr->coeff);
747 indices = wavePtr->indicesDft;
748 rank = dftMesh.rank(indices);
756 starPtr = &(basis.star(is+1));
758 component = std::complex<double>(in[ib], +in[ib+1]);
759 component /= sqrt(2.0);
760 for (iw = starPtr->beginId; iw < starPtr->endId; ++iw) {
761 wavePtr = &basis.wave(iw);
762 if (!(wavePtr->implicit)) {
763 coeff = component*(wavePtr->coeff);
764 indices = wavePtr->indicesDft;
765 rank = dftMesh.rank(indices);
785 template <
int D,
class ACT>
788 Basis<D>
const& basis,
789 IntVec<D>
const& dftDimensions,
795 typedef typename ACT::Complex CT;
796 typedef typename ACT::Real RT;
801 symmetric =
hasSymmetry(in, basis, dftDimensions, epsilon,
true);
804 <<
"WARNING: Conversion of asymmetric field to"
805 <<
"symmetry-adapted basis in Prdc::convertKgridToBasis."
806 << std::endl << std::endl;
811 Mesh<D> dftMesh(dftDimensions);
813 typename Basis<D>::Star
const* starPtr;
814 typename Basis<D>::Wave
const* wavePtr;
815 std::complex<double> component;
822 for (is = 0; is < basis.nBasis(); ++is) {
828 while (is < basis.nStar()) {
829 starPtr = &(basis.star(is));
831 if (starPtr->cancel) {
837 ib = starPtr->basisId;
839 if (starPtr->invertFlag == 0) {
842 int beginId = starPtr->beginId;
843 int endId = starPtr->endId;
845 bool isImplicit =
true;
847 wavePtr = &basis.wave(beginId + iw);
848 if (!wavePtr->implicit) {
852 wavePtr = &basis.wave(endId - 1 - iw);
853 if (!wavePtr->implicit) {
862 rank = dftMesh.rank(wavePtr->indicesDft);
865 component /= wavePtr->coeff;
866 out[ib] = component.real();
870 if (starPtr->invertFlag == 1) {
875 wavePtr = &basis.wave(starPtr->beginId);
877 if (wavePtr->implicit) {
878 iw = wavePtr->inverseId;
879 starPtr = &(basis.star(is+1));
881 wavePtr = &basis.wave(iw);
885 rank = dftMesh.rank(wavePtr->indicesDft);
888 UTIL_CHECK(std::abs(wavePtr->coeff) > 1.0E-8);
889 component /= wavePtr->coeff;
890 component *= sqrt(2.0);
893 if (starPtr->invertFlag == 1) {
894 out[ib] = component.real();
895 out[ib+1] = -component.imag();
897 out[ib] = component.real();
898 out[ib+1] = component.imag();
914 template <
int D,
class ACT>
916 Basis<D>
const& basis,
917 IntVec<D>
const& dftDimensions,
923 typedef typename ACT::Complex CT;
924 typedef typename ACT::Real RT;
926 typename Basis<D>::Star
const* starPtr;
927 typename Basis<D>::Wave
const* wavePtr;
928 std::complex<double> waveCoeff;
929 std::complex<double> rootCoeff;
930 std::complex<double> diff;
936 double cancelledError(0.0);
937 double uncancelledError(0.0);
940 Mesh<D> dftMesh(dftDimensions);
943 for (is = 0; is < basis.nStar(); ++is) {
944 starPtr = &(basis.star(is));
946 if (starPtr->cancel) {
949 beginId = starPtr->beginId;
950 endId = starPtr->endId;
951 for (iw = beginId; iw < endId; ++iw) {
952 wavePtr = &basis.wave(iw);
953 if (!wavePtr->implicit) {
954 rank = dftMesh.rank(wavePtr->indicesDft);
958 if (std::abs(waveCoeff) > cancelledError) {
959 cancelledError = std::abs(waveCoeff);
960 if ((!verbose) && (cancelledError > epsilon)) {
970 bool hasRoot =
false;
971 beginId = starPtr->beginId;
972 endId = starPtr->endId;
973 for (iw = beginId; iw < endId; ++iw) {
974 wavePtr = &basis.wave(iw);
975 if (!(wavePtr->implicit)) {
976 rank = dftMesh.rank(wavePtr->indicesDft);
980 waveCoeff /= wavePtr->coeff;
982 diff = waveCoeff - rootCoeff;
983 if (std::abs(diff) > uncancelledError) {
984 uncancelledError = std::abs(diff);
985 if ((!verbose) && (uncancelledError > epsilon)) {
990 rootCoeff = waveCoeff;
1000 if ((cancelledError < epsilon) && (uncancelledError < epsilon)) {
1002 }
else if (verbose) {
1005 <<
"Maximum coefficient of a cancelled star: "
1006 << cancelledError << std::endl
1007 <<
"Maximum error of coefficient for an uncancelled star: "
1008 << uncancelledError << std::endl;
1015 template <
int D,
class ART>
1018 IntVec<D>
const & meshDimensions,
1019 UnitCell<D>
const & unitCell,
1020 IntVec<D>
const & replicas)
1027 IntVec<D> repDimensions;
1029 for (
int i = 0; i < D; ++i) {
1032 repDimensions[i] = replicas[i] * meshDimensions[i];
1033 repSize *= repDimensions[i];
1039 for (
int i = 0; i < nMonomer; ++i) {
1044 Mesh<D> mesh(meshDimensions);
1045 Mesh<D> cellMesh(replicas);
1046 Mesh<D> repMesh(repDimensions);
1047 MeshIterator<D> iter(meshDimensions);
1048 MeshIterator<D> cellIter(replicas);
1050 IntVec<D> cellPosition;
1051 IntVec<D> repPosition;
1054 for (
int i = 0; i < nMonomer; ++i) {
1055 for (iter.begin(); !iter.atEnd(); ++iter) {
1056 position = iter.position();
1057 value = fields[i][iter.rank()];
1058 for (cellIter.begin(); !cellIter.atEnd(); ++cellIter) {
1059 cellPosition = cellIter.position();
1060 for (
int j=0; j < D; ++j) {
1061 repPosition[j] = position[j]
1062 + meshDimensions[j]*cellPosition[j];
1064 repRank = repMesh.rank(repPosition);
1065 repFields[i][repRank] = value;
1078 std::string gName =
"";
1086 template <
int D,
class ART>
1090 IntVec<D>
const & meshDimensions,
1091 UnitCell<D>
const & unitCell,
1098 template <
class ART>
1102 IntVec<1>
const & meshDimensions,
1103 UnitCell<1>
const & unitCell,
1120 cellParameters.
append(unitCell.parameter(0));
1123 std::string gName =
"";
1130 IntVec<2> dimensions;
1131 dimensions[0] = meshDimensions[0];
1132 dimensions[1] = newGridDimensions[0];
1136 if (dimensions[0] == dimensions[1]) {
1137 cell.set(UnitCell<2>::Square, cellParameters);
1139 cellParameters.
append((
double)dimensions[1]/dimensions[0]
1140 * cellParameters[0]);
1141 cell.set(UnitCell<2>::Rectangular, cellParameters);
1146 out <<
"mesh " << std::endl
1147 <<
" " << dimensions << std::endl;
1149 }
else if (d == 3) {
1154 IntVec<3> dimensions;
1155 dimensions[0] = meshDimensions[0];
1156 dimensions[1] = newGridDimensions[0];
1157 dimensions[2] = newGridDimensions[1];
1161 if (dimensions[2] == dimensions[1]) {
1162 if (dimensions[1] == dimensions[0]) {
1163 cell.set(UnitCell<3>::Cubic, cellParameters);
1165 cellParameters.
append((
double)dimensions[1]/dimensions[0]
1166 * cellParameters[0]);
1167 cellParameters.append((
double)dimensions[2]/dimensions[0]
1168 * cellParameters[0]);
1169 cell.set(UnitCell<3>::Orthorhombic, cellParameters);
1172 if (dimensions[1] == dimensions[0]) {
1173 cellParameters.append((
double)dimensions[2]/dimensions[0]
1174 * cellParameters[0]);
1175 cell.set(UnitCell<3>::Tetragonal, cellParameters);
1177 cellParameters.append((
double)dimensions[1]/dimensions[0]
1178 * cellParameters[0]);
1179 cellParameters.append((
double)dimensions[2]/dimensions[0]
1180 * cellParameters[0]);
1181 cell.set(UnitCell<3>::Orthorhombic, cellParameters);
1187 out <<
"mesh " << std::endl
1188 <<
" " << dimensions << std::endl;
1197 int nReplica = newGridDimensions[0];
1199 nReplica *= newGridDimensions[1];
1201 MeshIteratorFortran<1> iter(meshDimensions);
1203 for (
int i = 0; i < nReplica; ++i) {
1204 for (iter.begin(); !iter.atEnd(); ++iter) {
1206 for (
int j = 0; j < nMonomer; ++j) {
1207 out <<
" " <<
Dbl(fields[j][rank], 21, 13);
1215 template <
class ART>
1218 IntVec<2>
const & meshDimensions,
1219 UnitCell<2>
const & unitCell,
1234 IntVec<3> dimensions;
1235 dimensions[0] = meshDimensions[0];
1236 dimensions[1] = meshDimensions[1];
1237 dimensions[2] = newGridDimensions[0];
1242 cellParameters.
append(unitCell.parameter(0));
1243 if (unitCell.lattice() == UnitCell<2>::Square) {
1244 if (newGridDimensions[0] == meshDimensions[0]){
1245 cell.set(UnitCell<3>::Cubic, cellParameters);
1247 cellParameters.
append((
double)dimensions[2]/dimensions[0]
1248 * cellParameters[0]);
1249 cell.set(UnitCell<3>::Tetragonal, cellParameters);
1251 }
else if (unitCell.lattice() == UnitCell<2>::Rectangular) {
1252 cellParameters.
append(unitCell.parameter(1));
1253 cellParameters.
append((
double)dimensions[2]/dimensions[0]
1254 * cellParameters[0]);
1255 cell.set(UnitCell<3>::Orthorhombic, cellParameters);
1256 }
else if (unitCell.lattice() == UnitCell<2>::Hexagonal){
1257 cellParameters.append((
double)dimensions[2]/dimensions[0]
1258 * cellParameters[0]);
1259 cell.set(UnitCell<3>::Hexagonal, cellParameters);
1260 }
else if (unitCell.lattice() == UnitCell<2>::Rhombic) {
1261 cellParameters.append(unitCell.parameter(0));
1262 cellParameters.append((
double)dimensions[2]/dimensions[0]
1263 * cellParameters[0]);
1265 cellParameters.append(0.0);
1266 cellParameters.append(unitCell.parameter(1));
1267 cell.set(UnitCell<3>::Triclinic, cellParameters);
1268 }
else if (unitCell.lattice() == UnitCell<2>::Oblique) {
1269 cellParameters.append(unitCell.parameter(1));
1270 cellParameters.append((
double)dimensions[2]/dimensions[0]
1271 * cellParameters[0]);
1273 cellParameters.append(0.0);
1274 cellParameters.append(unitCell.parameter(2));
1275 cell.set(UnitCell<3>::Triclinic, cellParameters);
1277 UTIL_THROW(
"Unrecognized 2D lattice system.");
1283 std::string gName =
"";
1285 out <<
"mesh " << std::endl
1286 <<
" " << dimensions << std::endl;
1289 int nReplica = newGridDimensions[0];
1290 MeshIteratorFortran<2> iter(meshDimensions);
1292 for (
int i = 0; i < nReplica; ++i) {
1293 for (iter.begin(); !iter.atEnd(); ++iter) {
1295 for (
int j = 0; j < nMonomer; ++j) {
1296 out <<
" " <<
Dbl(fields[j][rank], 21, 13);
1304 template <
class ART>
1307 IntVec<3>
const & meshDimensions,
1308 UnitCell<3>
const & unitCell,
1312 {
UTIL_THROW(
"expandRGridDimension is invalid when D = 3."); }
An IntVec<D, T> is a D-component vector of elements of integer type T.
Iterator over points in a mesh in "Fortran" order.
Description of a regular grid of points in a periodic domain.
IntVec< D > dimensions() const
Get an IntVec<D> of the grid dimensions.
int shift(int &coordinate, int i) const
Shift a periodic coordinate into range.
A list of wavevectors that are related by space-group symmetries.
int basisId
Index of basis function associated with this star.
IntVec< D > waveBz
Integer indices indicesBz of a characteristic wave of this star.
int invertFlag
Index for inversion symmetry of star.
int size
Number of wavevectors in this star.
int beginId
Wave index of first wavevector in star.
bool cancel
Is this star cancelled, i.e., associated with a zero function?
std::complex< double > coeff
Coefficient of wave within the associated star basis function.
int starId
Index of the star that contains this wavevector.
Symmetry-adapted Fourier basis for pseudo-spectral scft.
Wave const & wave(int id) const
Get a specific Wave, access by integer index.
int waveId(IntVec< D > vector) const
Get the integer index of a wave, as required by wave(int id).
int nStar() const
Total number of stars.
bool isInitialized() const
Returns true iff this basis is fully initialized.
Star const & star(int id) const
Get a Star, accessed by integer star index.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Vec< D, T > & negate(const Vec< D, T > &v)
Return negative of vector v.
int capacity() const
Return allocated size.
static const double Pi
Trigonometric constant Pi.
Dynamically allocatable contiguous array template.
void allocate(int capacity)
Allocate the underlying C array.
bool isAllocated() const
Return true if this DArray has been allocated, false otherwise.
Wrapper for a double precision number, for formatted ostream output.
A fixed capacity (static) contiguous array with a variable logical size.
void append(Data const &data)
Append data to the end of the array.
Wrapper for an int, for formatted ostream output.
static std::ostream & file()
Get log ostream by reference.
#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.
void replicateUnitCell(IntVec< 1 > const &replicas, UnitCell< 1 > const &cellIn, UnitCell< 1 > &cellOut)
Create a replicated UnitCell<1>.
void writeFieldHeader(std::ostream &out, int ver1, int ver2, UnitCell< D > const &cell, std::string const &groupName, int nMonomer)
Write common part of field header (fortran PSCF format).
void writeKGridData(std::ostream &out, DArray< AT > const &fields, int nMonomer, IntVec< D > const &dftDimensions)
Write data for array of k-grid fields, with no header section.
void writeNBasis(std::ostream &out, int nBasis)
Write the number of basis functions to a basis field file header.
bool hasSymmetry(AT const &in, Basis< D > const &basis, IntVec< D > const &dftDimensions, double epsilon=1.0e-8, bool verbose=true)
Check if a k-grid field has the declared space group symmetry.
void inspectArrays(DArray< AT > const &arrays, int &nMonomer, int &capacity)
Inspect dimensions of a DArray of 1D arrays, each of type AT.
void inspectFields(DArray< FT > const &fields, int &nMonomer, IntVec< D > &dimensions)
Inspect dimensions of a DArray of fields, each of type FT.
void checkAllocateArrays(DArray< AT > &arrays, int nMonomer, int capacity)
Check allocation of a DArray of 1D arrays, allocate if necessary.
void readKGridData(std::istream &in, DArray< AT > &fields, int nMonomer, IntVec< D > const &dftDimensions)
Read data for array of k-grid fields, with no header section.
void convertBasisToKGrid(DArray< double > const &components, AT &dft, Basis< D > const &basis, IntVec< D > const &dftDimensions)
Convert a real field from symmetrized basis to Fourier grid.
void writeMeshDimensions(std::ostream &out, IntVec< D > const &meshDimensions)
Write mesh dimensions to a field file header.
void expandRGridDimension(std::ostream &out, DArray< AT > const &fields, IntVec< D > const &meshDimensions, UnitCell< D > const &unitCell, int d, DArray< int > newGridDimensions)
Expand the dimensionality of space from D to d.
void writeRGridData(std::ostream &out, DArray< AT > const &fields, int nMonomer, IntVec< D > const &dimensions)
Write data for array of r-grid fields, with no header section.
void convertKGridToBasis(AT const &in, DArray< double > &out, Basis< D > const &basis, IntVec< D > const &dftDimensions, bool checkSymmetry=true, double epsilon=1.0e-8)
Convert a real field from Fourier grid to symmetrized basis.
int readNBasis(std::istream &in)
Read the number of basis functions from a basis field file header.
void readRGridData(std::istream &in, DArray< AT > &fields, int nMonomer, IntVec< D > const &dimensions)
Read data for array of r-grid fields, with no header section.
void readMeshDimensions(std::istream &in, IntVec< D > const &meshDimensions)
Read mesh dimensions from a field file header.
void writeBasisData(std::ostream &out, DArray< DArray< double > > const &fields, Basis< D > const &basis)
Write array of fields in basis format, without a header.
void readBasisData(std::istream &in, DArray< DArray< double > > &fields, UnitCell< D > const &unitCell, Mesh< D > const &mesh, Basis< D > const &basis, int nStarIn)
Read a set of fields in basis format.
void checkAllocateFields(DArray< FT > &fields, int nMonomer, IntVec< D > const &dimensions)
Check allocation of an array of fields, allocate if necessary.
void checkAllocateField(FT &field, IntVec< D > const &dimensions)
Check allocation of a single field, allocate if necessary.
RT imag(CT const &a)
Return the imaginary part of a complex number.
void assign(CT &z, RT const &a, RT const &b)
Create a complex number from real and imaginary parts, z = a + ib.
RT real(CT const &a)
Return the real part of a complex number.
PSCF package top-level namespace.