PSCF v1.1
pspg/field/WFieldContainer.tpp
1#ifndef PSPG_W_FIELD_CONTAINER_TPP
2#define PSPG_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 <pspg/field/FieldIo.h>
13
14namespace Pscf {
15namespace Pspg
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(isAllocatedBasis_);
171 UTIL_CHECK(fields.capacity() == nMonomer_);
172
173 // Update system wFields
174 for (int i = 0; i < nMonomer_; ++i) {
175 DArray<double> const & f = fields[i];
176 DArray<double> & w = basis_[i];
177 UTIL_CHECK(f.capacity() == nBasis_);
178 UTIL_CHECK(w.capacity() == nBasis_);
179 for (int j = 0; j < nBasis_; ++j) {
180 w[j] = f[j];
181 }
182 }
183
184 // Update system wFieldsRGrid
185 fieldIoPtr_->convertBasisToRGrid(basis_, rgrid_);
186
187 hasData_ = true;
188 isSymmetric_ = true;
189 }
190
191 /*
192 * Set new field values, using r-grid fields as inputs.
193 */
194 template <int D>
196 bool isSymmetric)
197 {
198 UTIL_CHECK(isAllocatedRGrid_);
199 UTIL_CHECK(fields.capacity() == nMonomer_);
200
201 // Update system wFieldsRGrid
202 for (int i = 0; i < nMonomer_; ++i) {
203 UTIL_CHECK(fields[i].capacity() == nBasis_)
204 rgrid_[i] = fields[i];
205 }
206
207 if (isSymmetric) {
208 fieldIoPtr_->convertRGridToBasis(rgrid_, basis_);
209 }
210
211 hasData_ = true;
212 isSymmetric_ = isSymmetric;
213 }
214
215 /*
216 * Set new w-field values, using unfoldeded array of r-grid fields.
217 */
218 template <int D>
220 {
221 UTIL_CHECK(isAllocatedRGrid_);
222
223 // GPU resources
224 int nBlocks, nThreads;
225 ThreadGrid::setThreadsLogical(meshSize_, nBlocks, nThreads);
226
227 for (int i = 0; i < nMonomer_; i++) {
228 assignReal<<<nBlocks, nThreads>>>(rgrid_[i].cDField(),
229 fields.cDField() + i*meshSize_,
230 meshSize_);
231 }
232
233 hasData_ = true;
234 isSymmetric_ = false;
235 }
236
237 /*
238 * Read field component values from input stream, in symmetrized
239 * Fourier format.
240 *
241 * This function also computes and stores the corresponding
242 * r-grid representation. On return, hasData and isSymmetric
243 * are both true.
244 */
245 template <int D>
246 void WFieldContainer<D>::readBasis(std::istream& in,
247 UnitCell<D>& unitCell)
248 {
249 UTIL_CHECK(isAllocatedBasis());
250 fieldIoPtr_->readFieldsBasis(in, basis_, unitCell);
251
252 // Update system wFieldsRGrid
253 fieldIoPtr_->convertBasisToRGrid(basis_, rgrid_);
254
255 hasData_ = true;
256 isSymmetric_ = true;
257 }
258
259 /*
260 * Read field component values from file, in symmetrized
261 * Fourier format.
262 *
263 * This function also computes and stores the corresponding
264 * r-grid representation. On return, hasData and isSymmetric
265 * are both true.
266 */
267 template <int D>
268 void WFieldContainer<D>::readBasis(std::string filename,
269 UnitCell<D>& unitCell)
270 {
271 UTIL_CHECK(isAllocatedBasis());
272 fieldIoPtr_->readFieldsBasis(filename, basis_, unitCell);
273
274 // Update system wFieldsRGrid
275 fieldIoPtr_->convertBasisToRGrid(basis_, rgrid_);
276
277 hasData_ = true;
278 isSymmetric_ = true;
279 }
280
281 /*
282 * Reads fields from an input stream in real-space (r-grid) format.
283 *
284 * If the isSymmetric parameter is true, this function assumes that
285 * the fields are known to be symmetric and so computes and stores
286 * the corresponding basis components. If isSymmetric is false, it
287 * only sets the values in the r-grid format.
288 *
289 * On return, hasData is true and the persistent isSymmetric flag
290 * defined by the class is set to the value of the isSymmetric
291 * input parameter.
292 */
293 template <int D>
294 void WFieldContainer<D>::readRGrid(std::istream& in,
295 UnitCell<D>& unitCell,
296 bool isSymmetric)
297 {
298 UTIL_CHECK(isAllocatedRGrid());
299 fieldIoPtr_->readFieldsRGrid(in, rgrid_, unitCell);
300
301 if (isSymmetric) {
302 fieldIoPtr_->convertRGridToBasis(rgrid_, basis_);
303 }
304
305 hasData_ = true;
306 isSymmetric_ = isSymmetric;
307 }
308
309 /*
310 * Reads fields from a file in real-space (r-grid) format.
311 *
312 * If the isSymmetric parameter is true, this function assumes that
313 * the fields are known to be symmetric and so computes and stores
314 * the corresponding basis components. If isSymmetric is false, it
315 * only sets the values in the r-grid format.
316 *
317 * On return, hasData is true and the persistent isSymmetric flag
318 * defined by the class is set to the value of the isSymmetric
319 * input parameter.
320 */
321 template <int D>
322 void WFieldContainer<D>::readRGrid(std::string filename,
323 UnitCell<D>& unitCell,
324 bool isSymmetric)
325 {
326 UTIL_CHECK(isAllocatedRGrid());
327 fieldIoPtr_->readFieldsRGrid(filename, rgrid_, unitCell);
328
329 if (isSymmetric) {
330 fieldIoPtr_->convertRGridToBasis(rgrid_, basis_);
331 }
332
333 hasData_ = true;
334 isSymmetric_ = isSymmetric;
335 }
336
337 /*
338 * Set new w-field values, using array of r-grid fields as input.
339 */
340 template <int D>
342 {
343 UTIL_CHECK(hasData_);
344 fieldIoPtr_->convertRGridToBasis(rgrid_, basis_);
345 fieldIoPtr_->convertBasisToRGrid(basis_, rgrid_);
346 isSymmetric_ = true;
347 }
348
349} // namespace Pspg
350} // namespace Pscf
351#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition: IntVec.h:27
Dynamic array on the GPU with alligned data.
Definition: DField.h:30
Data * cDField()
Return pointer to underlying C array.
Definition: DField.h:119
File input/output operations for fields in several file formats.
Field of real single precision values on an FFT mesh on a device.
Definition: RDField.h:34
void setRGrid(DArray< RDField< D > > const &fields, bool isSymmetric=false)
Set fields values in real-space (r-grid) format.
void symmetrize()
Symmetrize r-grid fields, compute corresponding basis components.
void deallocateBasis()
De-allocate fields in basis format.
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 setNMonomer(int nMonomer)
Set stored value of nMonomer.
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 setFieldIo(FieldIo< D > const &fieldIo)
Create association with FieldIo (store pointer).
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.
void allocateBasis(int nBasis)
Allocate or re-allocate memory for fields in basis 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
void setThreadsLogical(int nThreadsLogical)
Set the total number of threads required for execution.
Definition: ThreadGrid.cu:80
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
Definition: accumulators.mod:1