PSCF v1.1
pspc/field/WFieldContainer.tpp
1#ifndef PSPC_W_FIELD_CONTAINER_TPP
2#define PSPC_W_FIELD_CONTAINER_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 "WFieldContainer.h"
12#include <pspc/field/FieldIo.h>
13
14namespace Pscf {
15namespace Pspc
16{
17
18 using namespace Util;
19
20 /*
21 * Constructor.
22 */
23 template <int D>
25 : basis_(),
26 rgrid_(),
27 fieldIoPtr_(0),
28 meshDimensions_(),
29 meshSize_(0),
30 nBasis_(0),
31 nMonomer_(0),
32 isAllocatedRGrid_(false),
33 isAllocatedBasis_(false),
34 hasData_(false),
35 isSymmetric_(false)
36 {}
37
38 /*
39 * Destructor.
40 */
41 template <int D>
43 {}
44
45 /*
46 * Create an association with a FieldIo object.
47 */
48 template <int D>
50 { fieldIoPtr_ = &fieldIo; }
51
52 /*
53 * Set the stored value of nMonomer (this may only be called once).
54 */
55 template <int D>
57 {
58 UTIL_CHECK(nMonomer_ == 0);
59 UTIL_CHECK(nMonomer > 0);
60 nMonomer_ = nMonomer;
61 }
62
63 /*
64 * Allocate memory for fields in r-grid format.
65 */
66 template <int D>
67 void
69 {
70 UTIL_CHECK(nMonomer_ > 0);
71
72 // If already allocated, deallocate.
73 if (isAllocatedRGrid_) {
74 deallocateRGrid();
75 }
76
77 // Store mesh dimensions
78 meshDimensions_ = meshDimensions;
79 meshSize_ = 1;
80 for (int i = 0; i < D; ++i) {
81 UTIL_CHECK(meshDimensions[i] > 0);
82 meshSize_ *= meshDimensions[i];
83 }
84
85 // Allocate arrays
86 rgrid_.allocate(nMonomer_);
87 for (int i = 0; i < nMonomer_; ++i) {
88 rgrid_[i].allocate(meshDimensions);
89 }
90 isAllocatedRGrid_ = true;
91
92 }
93
94 /*
95 * De-allocate memory for fields in r-grid format
96 */
97 template <int D>
99 {
100 UTIL_CHECK(isAllocatedRGrid_);
101 UTIL_CHECK(nMonomer_ > 0);
102 for (int i = 0; i < nMonomer_; ++i) {
103 rgrid_[i].deallocate();
104 }
105 rgrid_.deallocate();
106 meshDimensions_ = 0;
107 meshSize_ = 0;
108 isAllocatedRGrid_ = false;
109 }
110
111 /*
112 * Allocate memory for fields in basis format.
113 */
114 template <int D>
116 {
117 UTIL_CHECK(nMonomer_ > 0);
118 UTIL_CHECK(nBasis > 0);
119
120 // If already allocated, deallocate.
121 if (isAllocatedBasis_) {
122 deallocateBasis();
123 }
124
125 // Allocate
126 nBasis_ = nBasis;
127 basis_.allocate(nMonomer_);
128 for (int i = 0; i < nMonomer_; ++i) {
129 basis_[i].allocate(nBasis);
130 }
131 isAllocatedBasis_ = true;
132
133 }
134
135 /*
136 * De-allocate memory for fields in basis format.
137 */
138 template <int D>
140 {
141 UTIL_CHECK(isAllocatedBasis_);
142 UTIL_CHECK(nMonomer_ > 0);
143 for (int i = 0; i < nMonomer_; ++i) {
144 basis_[i].deallocate();
145 }
146 basis_.deallocate();
147 nBasis_ = 0;
148 isAllocatedBasis_ = false;
149 }
150
151 /*
152 * Allocate memory for all fields.
153 */
154 template <int D>
155 void WFieldContainer<D>::allocate(int nMonomer, int nBasis,
156 IntVec<D> const & meshDimensions)
157 {
158 setNMonomer(nMonomer);
159 allocateRGrid(meshDimensions);
160 allocateBasis(nBasis);
161 }
162
163 /*
164 * Set new w-field values.
165 */
166 template <int D>
167 void
169 {
170 UTIL_CHECK(fields.capacity() == nMonomer_);
171
172 // Update system wFields
173 for (int i = 0; i < nMonomer_; ++i) {
174 DArray<double> const & f = fields[i];
175 DArray<double> & w = basis_[i];
176 UTIL_CHECK(f.capacity() == nBasis_);
177 UTIL_CHECK(w.capacity() == nBasis_);
178 for (int j = 0; j < nBasis_; ++j) {
179 w[j] = f[j];
180 }
181 }
182
183 // Update system wFieldsRGrid
184 fieldIoPtr_->convertBasisToRGrid(basis_, rgrid_);
185
186 hasData_ = true;
187 isSymmetric_ = true;
188 }
189
190 /*
191 * Set new field values, using r-grid fields as inputs.
192 */
193 template <int D>
195 bool isSymmetric)
196 {
197 UTIL_CHECK(fields.capacity() == nMonomer_);
198
199 // Update system wFieldsRGrid
200 for (int i = 0; i < nMonomer_; ++i) {
201 RField<D> const & f = fields[i];
202 RField<D>& w = rgrid_[i];
203 UTIL_CHECK(f.capacity() == meshSize_);
204 UTIL_CHECK(w.capacity() == meshSize_);
205 for (int j = 0; j < meshSize_; ++j) {
206 w[j] = f[j];
207 }
208 }
209
210 if (isSymmetric) {
211 fieldIoPtr_->convertRGridToBasis(rgrid_, basis_);
212 }
213
214 hasData_ = true;
215 isSymmetric_ = isSymmetric;
216 }
217
218 /*
219 * Read field component values from input stream, in symmetrized
220 * Fourier format.
221 *
222 * This function also computes and stores the corresponding
223 * r-grid representation. On return, hasData and isSymmetric
224 * are both true.
225 */
226 template <int D>
227 void WFieldContainer<D>::readBasis(std::istream& in,
228 UnitCell<D>& unitCell)
229 {
230 UTIL_CHECK(isAllocatedBasis());
231 fieldIoPtr_->readFieldsBasis(in, basis_, unitCell);
232
233 // Update system wFieldsRGrid
234 fieldIoPtr_->convertBasisToRGrid(basis_, rgrid_);
235
236 hasData_ = true;
237 isSymmetric_ = true;
238 }
239
240 /*
241 * Read field component values from file, in symmetrized
242 * Fourier format.
243 *
244 * This function also computes and stores the corresponding
245 * r-grid representation. On return, hasData and isSymmetric
246 * are both true.
247 */
248 template <int D>
249 void WFieldContainer<D>::readBasis(std::string filename,
250 UnitCell<D>& unitCell)
251 {
252 UTIL_CHECK(isAllocatedBasis());
253 fieldIoPtr_->readFieldsBasis(filename, basis_, unitCell);
254
255 // Update system wFieldsRGrid
256 fieldIoPtr_->convertBasisToRGrid(basis_, rgrid_);
257
258 hasData_ = true;
259 isSymmetric_ = true;
260 }
261
262 /*
263 * Reads fields from an input stream in real-space (r-grid) format.
264 *
265 * If the isSymmetric parameter is true, this function assumes that
266 * the fields are known to be symmetric and so computes and stores
267 * the corresponding basis components. If isSymmetric is false, it
268 * only sets the values in the r-grid format.
269 *
270 * On return, hasData is true and the persistent isSymmetric flag
271 * defined by the class is set to the value of the isSymmetric
272 * input parameter.
273 */
274 template <int D>
275 void WFieldContainer<D>::readRGrid(std::istream& in,
276 UnitCell<D>& unitCell,
277 bool isSymmetric)
278 {
279 UTIL_CHECK(isAllocatedRGrid());
280 fieldIoPtr_->readFieldsRGrid(in, rgrid_, unitCell);
281
282 if (isSymmetric) {
283 fieldIoPtr_->convertRGridToBasis(rgrid_, basis_);
284 }
285
286 hasData_ = true;
287 isSymmetric_ = isSymmetric;
288 }
289
290 /*
291 * Reads fields from a file in real-space (r-grid) format.
292 *
293 * If the isSymmetric parameter is true, this function assumes that
294 * the fields are known to be symmetric and so computes and stores
295 * the corresponding basis components. If isSymmetric is false, it
296 * only sets the values in the r-grid format.
297 *
298 * On return, hasData is true and the persistent isSymmetric flag
299 * defined by the class is set to the value of the isSymmetric
300 * input parameter.
301 */
302 template <int D>
303 void WFieldContainer<D>::readRGrid(std::string filename,
304 UnitCell<D>& unitCell,
305 bool isSymmetric)
306 {
307 UTIL_CHECK(isAllocatedRGrid());
308 fieldIoPtr_->readFieldsRGrid(filename, rgrid_, unitCell);
309
310 if (isSymmetric) {
311 fieldIoPtr_->convertRGridToBasis(rgrid_, basis_);
312 }
313
314 hasData_ = true;
315 isSymmetric_ = isSymmetric;
316 }
317
318} // namespace Pspc
319} // namespace Pscf
320#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition: IntVec.h:27
File input/output operations and format conversions for fields.
Field of real double precision values on an FFT mesh.
Definition: RField.h:29
void deallocateRGrid()
De-allocate fields in rgrid format.
void readRGrid(std::istream &in, UnitCell< D > &unitCell, bool isSymmetric=false)
Reads fields from an input stream in real-space (r-grid) format.
void deallocateBasis()
De-allocate fields in basis format.
void setFieldIo(FieldIo< D > const &fieldIo)
Create association with FieldIo (store pointer).
void setBasis(DArray< DArray< double > > const &fields)
Set field component values, in symmetrized Fourier format.
void allocate(int nMonomer, int nBasis, IntVec< D > const &dimensions)
Allocate memory for all fields.
void allocateBasis(int nBasis)
Allocate or re-allocate memory for fields in basis format.
void setNMonomer(int nMonomer)
Set stored value of nMonomer.
void setRGrid(DArray< RField< D > > const &fields, bool isSymmetric=false)
Set fields values in real-space (r-grid) format.
void allocateRGrid(IntVec< D > const &dimensions)
Allocate or re-allocate memory for fields in rgrid format.
void readBasis(std::istream &in, UnitCell< D > &unitCell)
Read field component values from input stream, in symmetrized Fourier format.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Definition: UnitCell.h:44
int capacity() const
Return allocated size.
Definition: Array.h:159
Dynamically allocatable contiguous array template.
Definition: DArray.h:32
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
Definition: accumulators.mod:1