PSCF v1.3
DomainReal.tpp
1#ifndef PRDC_DOMAIN_REAL_TPP
2#define PRDC_DOMAIN_REAL_TPP
3
4/*
5* PSCF - Polymer Self-Consistent Field
6*
7* Copyright 2015 - 2025, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "DomainReal.h"
12#include <prdc/field/fieldIoUtil.h>
13#include <util/signal/Signal.h>
14#include <util/misc/FileMaster.h>
15
16namespace Pscf {
17namespace Prdc {
18
19 using namespace Util;
20
21 /*
22 * Constructor.
23 */
24 template <int D, class FFT, class WLT, class FIT>
26 : mesh_(),
27 unitCell_(),
28 group_(),
29 basis_(),
30 fft_(),
31 waveList_(),
32 fieldIo_(),
33 lattice_(UnitCell<D>::Null),
34 groupName_(""),
35 signalPtr_(nullptr),
36 fileMasterPtr_(nullptr),
37 hasGroup_(false),
38 isInitialized_(false)
39 {
40 setClassName("DomainReal");
41 fieldIo_.associate(mesh_, fft_, lattice_,
42 hasGroup_, groupName_, group_, basis_);
43
44 // Create Signal used by UnitCell, triggered by modification
45 signalPtr_ = new Signal<void>();
46 unitCell_.setSignal(*signalPtr_);
47 }
48
49 /*
50 * Destructor.
51 */
52 template <int D, class FFT, class WLT, class FIT>
54 {
55 delete signalPtr_;
56 }
57
58 /*
59 * Create association with a FileMaster.
60 */
61 template <int D, class FFT, class WLT, class FIT>
63 {
64 fileMasterPtr_ = &fileMaster;
65 fieldIo_.setFileMaster(fileMaster);
66 }
67
68 /*
69 * Read parameters and initialize.
70 */
71 template <int D, class FFT, class WLT, class FIT>
73 {
74 // Preconditions
75 UTIL_CHECK(!isInitialized_);
76 UTIL_CHECK(fileMasterPtr_);
77
78 // Read computational mesh dimensions (required)
79 read(in, "mesh", mesh_);
80 UTIL_CHECK(mesh_.size() > 0);
81 fft_.setup(mesh_.dimensions());
82
83 // Read lattice system enumeration value (required)
84 read(in, "lattice", lattice_);
85 unitCell_.set(lattice_);
86 UTIL_CHECK(unitCell_.lattice() != UnitCell<D>::Null);
87 UTIL_CHECK(unitCell_.nParameter() > 0);
88
89 // Allocate memory for WaveList
90 waveList_.allocate(mesh_, unitCell_);
91
92 // Optionally read groupName_ (string identifier for space group)
93 hasGroup_ = false;
94 bool hasGroupName = false;
95 hasGroupName = readOptional(in, "groupName", groupName_).isActive();
96
97 // If groupName_ exists, read and construct group_ (space group)
98 if (hasGroupName) {
99 // Read group symmetry operations from file
100 // An Exception is thrown if groupName_ string is not recognized
101 readGroup(groupName_, group_);
102 hasGroup_ = true;
103 }
104
105 isInitialized_ = true;
106 }
107
108 /*
109 * Read header of r-grid field to initialize the DomainReal.
110 *
111 * Alternative to parameter file, used only for unit testing.
112 */
113 template <int D, class FFT, class WLT, class FIT>
114 void
116 int& nMonomer)
117 {
118 // Preconditions - confirm that nothing is initialized
119 UTIL_CHECK(!isInitialized_);
120 UTIL_CHECK(lattice_ == UnitCell<D>::Null);
121 UTIL_CHECK(!unitCell_.isInitialized());
122 UTIL_CHECK(!hasGroup_);
123 UTIL_CHECK(groupName_ == "");
124
125 // Read common section of standard field header
126 int ver1, ver2;
127 Pscf::Prdc::readFieldHeader(in, ver1, ver2,
128 unitCell_, groupName_, nMonomer);
129
130 // Set lattice_ (lattice system identifier)
131 lattice_ = unitCell_.lattice();
132 UTIL_CHECK(lattice_ != UnitCell<D>::Null);
133 UTIL_CHECK(unitCell_.isInitialized());
134
135 // Read grid dimensions
136 std::string label;
137 in >> label;
138 if (label != "mesh" && label != "ngrid") {
139 std::string msg = "\n";
140 msg += "Error reading field file:\n";
141 msg += "Expected mesh or ngrid, but found [";
142 msg += label;
143 msg += "]";
144 UTIL_THROW(msg.c_str());
145 }
146 IntVec<D> nGrid;
147 in >> nGrid;
148
149 // Initialize mesh and fft
150 if (mesh_.size() == 0) {
151 mesh_.setDimensions(nGrid);
152 fft_.setup(mesh_.dimensions());
153 }
154
155 // Allocate waveList
156 if (!waveList_.isAllocated()) {
157 waveList_.allocate(mesh_, unitCell_);
158 }
159
160 // If groupName is present, construct group and basis
161 if (groupName_ != "") {
162 readGroup(groupName_, group_);
163 hasGroup_ = true;
164 basis_.makeBasis(mesh_, unitCell_, group_);
165 }
166
167 isInitialized_ = true;
168 }
169
170 /*
171 * Make basis if needed.
172 */
173 template <int D, class FFT, class WLT, class FIT>
175 {
176 UTIL_CHECK(mesh_.size() > 0);
177 UTIL_CHECK(unitCell_.lattice() != UnitCell<D>::Null);
178 UTIL_CHECK(unitCell_.isInitialized());
179 UTIL_CHECK(hasGroup_);
180
181 // Check basis, construct if not initialized
182 if (!basis_.isInitialized()) {
183 basis_.makeBasis(mesh_, unitCell_, group_);
184 }
185 UTIL_CHECK(basis_.isInitialized());
186 }
187
188 // Crystallographic Data Output
189
190 /*
191 * Write description of symmetry-adapted stars and basis to file.
192 */
193 template <int D, class FFT, class WLT, class FIT>
194 void
195 DomainReal<D,FFT,WLT,FIT>::writeStars(std::string const & filename)
196 const
197 {
199 UTIL_CHECK(basis_.isInitialized());
200 std::ofstream file;
201 fileMaster().openOutputFile(filename, file);
202 bool isSymmetric = true;
203 int nMonomer = 0;
204 fieldIo_.writeFieldHeader(file, nMonomer, unitCell_, isSymmetric);
205 basis_.outputStars(file);
206 file.close();
207 }
208
209 /*
210 * Write a list of waves and associated stars to file.
211 */
212 template <int D, class FFT, class WLT, class FIT>
213 void
214 DomainReal<D,FFT,WLT,FIT>::writeWaves(std::string const & filename)
215 const
216 {
218 UTIL_CHECK(basis_.isInitialized());
219 std::ofstream file;
220 fileMaster().openOutputFile(filename, file);
221 bool isSymmetric = true;
222 int nMonomer = 0;
223 fieldIo_.writeFieldHeader(file, nMonomer, unitCell_, isSymmetric);
224 basis_.outputWaves(file);
225 file.close();
226 }
227
228 /*
229 * Write all elements of the space group to a file.
230 */
231 template <int D, class FFT, class WLT, class FIT>
232 void
233 DomainReal<D,FFT,WLT,FIT>::writeGroup(std::string const & filename)
234 const
235 {
237 std::ofstream file;
238 fileMaster().openOutputFile(filename, file);
239 file << group_;
240 file.close();
241 }
242
243} // namespace Prdc
244} // namespace Pscf
245#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
void writeGroup(std::string const &filename) const
Output all elements of the space group.
virtual void readParameters(std::istream &in)
Read body of parameter block (without opening and closing lines).
void readRGridFieldHeader(std::istream &in, int &nMonomer)
Read initialization data from header of an r-grid field file.
~DomainReal()
Destructor.
void setFileMaster(FileMaster &fileMaster)
Create association with a FileMaster, needed by FieldIo.
DomainReal()
Constructor.
void writeStars(std::string const &filename) const
Output information about stars and symmetrized basis functions.
void makeBasis()
Construct basis if not done already.
bool hasGroup() const
Has a space group been declared?
Definition DomainReal.h:405
void writeWaves(std::string const &filename) const
Output information about waves.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Definition UnitCell.h:56
A FileMaster manages input and output files for a simulation.
Definition FileMaster.h:143
void setClassName(const char *className)
Set class name string.
Notifier (or subject) in the Observer design pattern.
Definition Signal.h:39
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition global.h:49
void readFieldHeader(std::istream &in, int &ver1, int &ver2, UnitCell< D > &cell, std::string &groupName, int &nMonomer)
Read common part of field header (fortran PSCF format).
Periodic fields and crystallography.
Definition CField.cpp:11
PSCF package top-level namespace.
Definition param_pc.dox:1