PSCF v1.1
pspc/field/Domain.tpp
1#ifndef PSPC_DOMAIN_TPP
2#define PSPC_DOMAIN_TPP
3
4/*
5* PSCF - Polymer Self-Consistent Field Theory
6*
7* Copyright 2016 - 2022, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "Domain.h"
12
13namespace Pscf {
14namespace Pspc
15{
16
17 using namespace Util;
18
19 /*
20 * Constructor.
21 */
22 template <int D>
24 : unitCell_(),
25 mesh_(),
26 group_(),
27 basis_(),
28 fft_(),
29 fieldIo_(),
30 lattice_(UnitCell<D>::Null),
31 groupName_(),
32 hasFileMaster_(false),
33 isInitialized_(false)
34 { setClassName("Domain"); }
35
36 /*
37 * Destructor.
38 */
39 template <int D>
41 {}
42
43 template <int D>
45 {
46 fieldIo_.associate(mesh_, fft_,
47 lattice_, groupName_, group_, basis_,
48 fileMaster);
49 hasFileMaster_ = true;
50 }
51
52 /*
53 * Read parameters and initialize.
54 */
55 template <int D>
56 void Domain<D>::readParameters(std::istream& in)
57 {
58 // Preconditins
59 UTIL_CHECK(!isInitialized_);
60 UTIL_CHECK(hasFileMaster_);
61
62 bool hasUnitCell = false;
63 // Uncomment for backwards compatibility with old format (< v1.0)
64 #if 0
65 readOptional(in, "unitCell", unitCell_);
66 if (unitCell_.lattice() != UnitCell<D>::Null) {
67 lattice_ = unitCell_.lattice();
68 hasUnitCell = true;
69 }
70 #endif
71
72 read(in, "mesh", mesh_);
73 fft_.setup(mesh_.dimensions());
74
75 // If no unit cell was read, read lattice system
76 if (lattice_ == UnitCell<D>::Null) {
77 read(in, "lattice", lattice_);
78 unitCell_.set(lattice_);
79 }
80
81 // Read group name and initialized space group
82 read(in, "groupName", groupName_);
83 readGroup(groupName_, group_);
84
85 // Initialize unit cell if unit cell parameters are known
86 if (hasUnitCell) {
87 basis().makeBasis(mesh(), unitCell(), group_);
88 }
89 isInitialized_ = true;
90 }
91
92 /*
93 * Read header of r-grid field in order to initialize the Domain.
94 *
95 * Useful for unit testing.
96 */
97 template <int D>
98 void Domain<D>::readRGridFieldHeader(std::istream& in, int& nMonomer)
99 {
100 // Read common section of standard field header
101 int ver1, ver2;
102 Pscf::readFieldHeader(in, ver1, ver2,
103 unitCell_, groupName_, nMonomer);
104
105 lattice_ = unitCell_.lattice();
106
107 // Read grid dimensions
108 std::string label;
109 in >> label;
110 if (label != "mesh" && label != "ngrid") {
111 std::string msg = "\n";
112 msg += "Error reading field file:\n";
113 msg += "Expected mesh or ngrid, but found [";
114 msg += label;
115 msg += "]";
116 UTIL_THROW(msg.c_str());
117 }
118 IntVec<D> nGrid;
119 in >> nGrid;
120
121 // Initialize mesh, fft
122 mesh_.setDimensions(nGrid);
123 fft_.setup(mesh_.dimensions());
124
125 // Initialize group and basis
126 readGroup(groupName_, group_);
127 basis_.makeBasis(mesh_, unitCell_, group_);
128
129 isInitialized_ = true;
130 }
131
132 template <int D>
133 void Domain<D>::setUnitCell(UnitCell<D> const & unitCell)
134 {
135 if (lattice_ == UnitCell<D>::Null) {
136 lattice_ = unitCell.lattice();
137 } else {
138 UTIL_CHECK(lattice_ == unitCell.lattice());
139 }
140 unitCell_ = unitCell;
141 if (!basis_.isInitialized()) {
142 makeBasis();
143 }
144 }
145
146 /*
147 * Set parameters of the associated unit cell.
148 */
149 template <int D>
151 FSArray<double, 6> const & parameters)
152 {
153 if (lattice_ == UnitCell<D>::Null) {
154 lattice_ = lattice;
155 } else {
156 UTIL_CHECK(lattice_ == lattice);
157 }
158 unitCell_.set(lattice, parameters);
159 if (!basis_.isInitialized()) {
160 makeBasis();
161 }
162 }
163
164 /*
165 * Set parameters of the associated unit cell.
166 */
167 template <int D>
169 {
170 UTIL_CHECK(unitCell_.lattice() != UnitCell<D>::Null);
171 UTIL_CHECK(unitCell_.nParameter() == parameters.size());
172 unitCell_.setParameters(parameters);
173 if (!basis_.isInitialized()) {
174 makeBasis();
175 }
176 }
177
178 template <int D>
180 {
181 UTIL_CHECK(mesh_.size() > 0);
182 UTIL_CHECK(unitCell_.lattice() != UnitCell<D>::Null);
183
184 // Check group, read from file if necessary
185 if (group_.size() == 1) {
186 if (groupName_ != "I") {
187 UTIL_CHECK(groupName_ != "");
188 readGroup(groupName_, group_);
189 }
190 }
191
192 // Check basis, construct if not initialized
193 if (!basis().isInitialized()) {
194 basis_.makeBasis(mesh_, unitCell_, group_);
195 }
196 UTIL_CHECK(basis().isInitialized());
197 }
198
199} // namespace Pspc
200} // namespace Pscf
201#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition: IntVec.h:27
virtual void readParameters(std::istream &in)
Read body of parameter block (without opening and closing lines).
void setFileMaster(FileMaster &fileMaster)
Create association with a FileMaster, needed by FieldIo.
void setUnitCell(UnitCell< D > const &unitCell)
Set unit cell.
void readRGridFieldHeader(std::istream &in, int &nMonomer)
Read header of an r-grid field file to initialize this Domain.
void makeBasis()
Construct basis if not done already.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Definition: UnitCell.h:44
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:38
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
A FileMaster manages input and output files for a simulation.
Definition: FileMaster.h:143
void setClassName(const char *className)
Set class name string.
#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:51
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
Definition: accumulators.mod:1