PSCF v1.3.3
DomainTmpl.tpp
1#ifndef PRDC_DOMAIN_TMPL_TPP
2#define PRDC_DOMAIN_TMPL_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 "DomainTmpl.h"
12#include <prdc/crystal/SpaceGroup.h>
13#include <prdc/crystal/Basis.h>
14#include <prdc/field/fieldIoUtil.h>
15#include <util/signal/Signal.h>
16#include <util/misc/FileMaster.h>
17
18namespace Pscf {
19namespace Prdc {
20
21 using namespace Util;
22
23 /*
24 * Constructor.
25 */
26 template <int D, class FFT, class WLT, class FIT>
28 : mesh_(),
29 unitCell_(),
30 lattice_(UnitCell<D>::Null),
31 groupName_(""),
32 groupPtr_(nullptr),
33 basisPtr_(nullptr),
34 fftPtr_(nullptr),
35 waveListPtr_(nullptr),
36 fieldIoPtr_(nullptr),
37 signalPtr_(nullptr),
38 fileMasterPtr_(nullptr),
39 hasGroup_(false),
40 isInitialized_(false)
41 {
42 setClassName("DomainTmpl");
43
44 // Construct associated objects
45 groupPtr_ = new SpaceGroup<D>();
46 basisPtr_ = new Basis<D>();
47 fftPtr_ = new FFT();
48 waveListPtr_ = new WLT();
49 fieldIoPtr_ = new FIT();
50 signalPtr_ = new Signal<void>();
51
52 // Create associations between objects
53 fieldIo().associate(mesh_, fft(), lattice_,
54 hasGroup_, groupName_, group(), basis());
55 unitCell_.setSignal(*signalPtr_);
56 }
57
58 /*
59 * Destructor.
60 */
61 template <int D, class FFT, class WLT, class FIT>
63 {
64 delete basisPtr_;
65 delete fftPtr_;
66 delete waveListPtr_;
67 delete fieldIoPtr_;
68 delete signalPtr_;
69 }
70
71 /*
72 * Create association with a FileMaster.
73 */
74 template <int D, class FFT, class WLT, class FIT>
76 {
77 fileMasterPtr_ = &fileMaster;
78 fieldIo().setFileMaster(fileMaster);
79 }
80
81 /*
82 * Read parameters and initialize.
83 */
84 template <int D, class FFT, class WLT, class FIT>
86 {
87 // Preconditions
88 UTIL_CHECK(!isInitialized_);
89 UTIL_CHECK(fileMasterPtr_);
90
91 // Read computational mesh dimensions (required)
92 read(in, "mesh", mesh_);
93 UTIL_CHECK(mesh_.size() > 0);
94 fft().setup(mesh_.dimensions());
95
96 // Read lattice system enumeration value (required)
97 read(in, "lattice", lattice_);
98 unitCell_.set(lattice_);
99 UTIL_CHECK(unitCell_.lattice() != UnitCell<D>::Null);
100 UTIL_CHECK(unitCell_.nParameter() > 0);
101
102 // Allocate memory for WaveList
103 waveList().allocate(mesh_, unitCell_);
104
105 // Optionally read groupName_ (string identifier for space group)
106 hasGroup_ = false;
107 bool hasGroupName = false;
108 hasGroupName = readOptional(in, "groupName", groupName_).isActive();
109
110 // If groupName_ exists, read and construct group (space group)
111 if (hasGroupName) {
112 // Read group symmetry operations from file
113 // An Exception is thrown if groupName_ string is not recognized
114 readGroup(groupName_, *groupPtr_);
115 hasGroup_ = true;
116 }
117
118 isInitialized_ = true;
119 }
120
121 /*
122 * Read header of r-grid field to initialize the DomainTmpl.
123 *
124 * Alternative to parameter file, used only for unit testing.
125 */
126 template <int D, class FFT, class WLT, class FIT>
127 void
129 int& nMonomer)
130 {
131 // Preconditions - confirm that nothing is initialized
132 UTIL_CHECK(!isInitialized_);
133 UTIL_CHECK(lattice_ == UnitCell<D>::Null);
134 UTIL_CHECK(!unitCell_.isInitialized());
135 UTIL_CHECK(!hasGroup_);
136 UTIL_CHECK(groupName_ == "");
137
138 // Read common section of standard field header
139 int ver1, ver2;
140 Pscf::Prdc::readFieldHeader(in, ver1, ver2,
141 unitCell_, groupName_, nMonomer);
142
143 // Set lattice_ (lattice system identifier)
144 lattice_ = unitCell_.lattice();
145 UTIL_CHECK(lattice_ != UnitCell<D>::Null);
146 UTIL_CHECK(unitCell_.isInitialized());
147
148 // Read grid dimensions
149 std::string label;
150 in >> label;
151 if (label != "mesh" && label != "ngrid") {
152 std::string msg = "\n";
153 msg += "Error reading field file:\n";
154 msg += "Expected mesh or ngrid, but found [";
155 msg += label;
156 msg += "]";
157 UTIL_THROW(msg.c_str());
158 }
159 IntVec<D> nGrid;
160 in >> nGrid;
161
162 // Initialize mesh and fft
163 if (mesh_.size() == 0) {
164 mesh_.setDimensions(nGrid);
165 fft().setup(mesh_.dimensions());
166 }
167
168 // Allocate waveList
169 if (!waveList().isAllocated()) {
170 waveList().allocate(mesh_, unitCell_);
171 }
172
173 // If groupName is present, construct group and basis
174 if (groupName_ != "") {
175 readGroup(groupName_, *groupPtr_);
176 hasGroup_ = true;
177 basis().makeBasis(mesh_, unitCell_, group());
178 }
179
180 isInitialized_ = true;
181 }
182
183 /*
184 * Make basis if needed.
185 */
186 template <int D, class FFT, class WLT, class FIT>
188 {
189 UTIL_CHECK(mesh_.size() > 0);
190 UTIL_CHECK(unitCell_.lattice() != UnitCell<D>::Null);
191 UTIL_CHECK(unitCell_.isInitialized());
192 UTIL_CHECK(hasGroup_);
193
194 // Check basis, construct if not initialized
195 if (!basis().isInitialized()) {
196 basis().makeBasis(mesh_, unitCell_, group());
197 }
198 UTIL_CHECK(basis().isInitialized());
199 }
200
201 // Crystallographic Data Output
202
203 /*
204 * Write description of symmetry-adapted stars and basis to file.
205 */
206 template <int D, class FFT, class WLT, class FIT>
207 void
208 DomainTmpl<D,FFT,WLT,FIT>::writeStars(std::string const & filename)
209 const
210 {
212 UTIL_CHECK(basis().isInitialized());
213 std::ofstream file;
214 fileMaster().openOutputFile(filename, file);
215 bool isSymmetric = true;
216 int nMonomer = 0;
217 fieldIo().writeFieldHeader(file, nMonomer, unitCell_, isSymmetric);
218 basis().outputStars(file);
219 file.close();
220 }
221
222 /*
223 * Write a list of waves and associated stars to file.
224 */
225 template <int D, class FFT, class WLT, class FIT>
226 void
227 DomainTmpl<D,FFT,WLT,FIT>::writeWaves(std::string const & filename)
228 const
229 {
231 UTIL_CHECK(basis().isInitialized());
232 std::ofstream file;
233 fileMaster().openOutputFile(filename, file);
234 bool isSymmetric = true;
235 int nMonomer = 0;
236 fieldIo().writeFieldHeader(file, nMonomer, unitCell_, isSymmetric);
237 basis().outputWaves(file);
238 file.close();
239 }
240
241 /*
242 * Write all elements of the space group to a file.
243 */
244 template <int D, class FFT, class WLT, class FIT>
245 void
246 DomainTmpl<D,FFT,WLT,FIT>::writeGroup(std::string const & filename)
247 const
248 {
250 std::ofstream file;
251 fileMaster().openOutputFile(filename, file);
252 file << group();
253 file.close();
254 }
255
256 /*
257 * Has a symmetry-adapted Fourier basis been initialized ?
258 */
259 template <int D, class FFT, class WLT, class FIT>
261 { return basis().isInitialized(); }
262
263} // namespace Prdc
264} // namespace Pscf
265#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
Symmetry-adapted Fourier basis for pseudo-spectral SCFT.
Definition Basis.h:383
Fourier transform wrapper.
Definition cpu/FFT.h:38
void writeWaves(std::string const &filename) const
Output information about waves.
WLT & waveList()
Get the WaveList by non-const reference.
Definition DomainTmpl.h:383
DomainTmpl()
Constructor.
void readRGridFieldHeader(std::istream &in, int &nMonomer)
Read initialization data from header of an r-grid field file.
bool hasBasis() const
Has a symmetry-adapted Fourier basis been initialized?
virtual void readParameters(std::istream &in)
Read body of parameter block (without opening and closing lines).
Basis< D > & basis()
Get the Basis object by non-const reference.
Definition DomainTmpl.h:363
FIT & fieldIo()
Get the FieldIo by non-const reference.
Definition DomainTmpl.h:393
void setFileMaster(FileMaster &fileMaster)
Create association with a FileMaster, needed by FieldIo.
FFT & fft()
Get the FFT by non-const reference.
Definition DomainTmpl.h:373
SpaceGroup< D > const & group() const
Get the SpaceGroup by const reference.
Definition DomainTmpl.h:358
void writeStars(std::string const &filename) const
Output information about stars and symmetrized basis functions.
bool hasGroup() const
Has a space group been declared?
Definition DomainTmpl.h:415
void writeGroup(std::string const &filename) const
Output all elements of the space group.
~DomainTmpl()
Destructor.
void makeBasis()
Construct basis if not done already.
Crystallographic space group.
Definition SpaceGroup.h:32
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.