PSCF v1.4.0
cp/field/WFields.tpp
1#ifndef PRDC_CL_W_FIELDS_TPP
2#define PRDC_CL_W_FIELDS_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 "WFields.h"
12#include <prdc/field/cFieldIo.h>
13#include <prdc/crystal/UnitCell.h>
14#include <pscf/mesh/Mesh.h>
15#include <util/signal/Signal.h>
16#include <util/misc/FileMaster.h>
17
18namespace Pscf {
19namespace Cp {
20
21 using namespace Util;
22 using namespace Prdc;
23
24 // Public member functions
25
26 /*
27 * Constructor.
28 */
29 template <int D, class CFT, class FIT>
31 : fields_(),
32 meshDimensions_(),
33 meshSize_(0),
34 nMonomer_(0),
35 readUnitCellPtr_(nullptr),
36 writeUnitCellPtr_(nullptr),
37 fieldIoPtr_(nullptr),
38 signalPtr_(nullptr),
39 isAllocated_(false),
40 hasData_(false)
41 { signalPtr_ = new Signal<void>(); }
42
43 /*
44 * Destructor.
45 */
46 template <int D, class CFT, class FIT>
48 { delete signalPtr_; }
49
50 /*
51 * Create an association with a field Io (FIT) object.
52 */
53 template <int D, class CFT, class FIT>
55 { fieldIoPtr_ = &fieldIo; }
56
57 /*
58 * Set the unit cell that is modified by reading a field file.
59 */
60 template <int D, class CFT, class FIT>
62 {
63 UTIL_CHECK(!readUnitCellPtr_);
64 readUnitCellPtr_ = &cell;
65 }
66
67 /*
68 * Set the unit cell that is written to a field file header.
69 */
70 template <int D, class CFT, class FIT>
72 {
73 UTIL_CHECK(!writeUnitCellPtr_);
74 writeUnitCellPtr_ = &cell;
75 }
76
77 /*
78 * Allocate memory for fields.
79 */
80 template <int D, class CFT, class FIT>
83 {
84 UTIL_CHECK(nMonomer_ == 0);
85 UTIL_CHECK(!hasData_);
86 UTIL_CHECK(!isAllocated_);
88
89 // Store nMonomer and mesh dimensions
90 nMonomer_ = nMonomer;
91 meshDimensions_ = meshDimensions;
92 meshSize_ = 1;
93 for (int i = 0; i < D; ++i) {
95 meshSize_ *= meshDimensions[i];
96 }
97
98 // Allocate arrays
99 fields_.allocate(nMonomer_);
100 for (int i = 0; i < nMonomer_; ++i) {
101 fields_[i].allocate(meshDimensions);
102 }
103
104 isAllocated_ = true;
105 }
106
107 // Field Modification Functions
108
109 /*
110 * Set all field values.
111 */
112 template <int D, class CFT, class FIT>
114 {
115 UTIL_CHECK(isAllocated_);
116
117 // Update fields
118 UTIL_CHECK(fields.capacity() == nMonomer_);
119 for (int i = 0; i < nMonomer_; ++i) {
120 UTIL_CHECK(fields[i].capacity() == meshSize_);
121 assignField(fields_[i], fields[i]);
122 }
123
124 // Mark data as modified
125 hasData_ = true;
126 signal().notify();
127 }
128
129 // Read fields from a file
130
131 /*
132 * Write fields to an output stream.
133 */
134 template <int D, class CFT, class FIT>
135 void WFields<D,CFT,FIT>::readFields(std::istream& in)
136 {
137 // Preconditions
138 UTIL_CHECK(isAllocated_);
139 UTIL_CHECK(readUnitCellPtr_);
140 UTIL_CHECK(fieldIoPtr_);
141
142 fieldIo().readFields(in, fields_, *readUnitCellPtr_);
143
144 // Mark data as modified
145 hasData_ = true;
146 signal().notify();
147 }
148
149 /*
150 * Read fields from a file, by filename.
151 */
152 template <int D, class CFT, class FIT>
153 void WFields<D,CFT,FIT>::readFields(std::string const & filename)
154 {
155 std::ifstream file;
156 fieldIo().fileMaster().openInputFile(filename, file);
157 readFields(file);
158 file.close();
159 }
160
161 // Write fields to file
162
163 /*
164 * Write fields to an output stream.
165 */
166 template <int D, class CFT, class FIT>
167 void WFields<D,CFT,FIT>::writeFields(std::ostream& out) const
168 {
169 // Preconditions
170 UTIL_CHECK(nMonomer_ > 0);
171 UTIL_CHECK(writeUnitCellPtr_);
172 UTIL_CHECK(fieldIoPtr_);
173 UTIL_CHECK(isAllocated_);
174 UTIL_CHECK(hasData_);
175
176 bool writeHeader = true;
177
178 fieldIo().writeFields(out, fields_, *writeUnitCellPtr_,
179 writeHeader);
180 }
181
182 /*
183 * Write fields to a named file.
184 */
185 template <int D, class CFT, class FIT>
186 void WFields<D,CFT,FIT>::writeFields(std::string const & filename) const
187 {
188 std::ofstream file;
189 fieldIo().fileMaster().openOutputFile(filename, file);
190 writeFields(file);
191 file.close();
192 }
193
194 // Signal accessor
195
196 /*
197 * Get the Signal<void> that is triggered by field modification.
198 */
199 template <int D, class CFT, class FIT>
201 {
202 UTIL_CHECK(signalPtr_);
203 return *signalPtr_;
204 }
205
206 // Private virtual function
207
208 /*
209 * Assignment operation for r-grid fields (CFT objects).
210 *
211 * Unimplemented virtual function - must be overridden by subclasses.
212 */
213 template <int D, class CFT, class FIT>
214 void WFields<D,CFT,FIT>::assignField(CFT & lhs, CFT const & rhs) const
215 { UTIL_THROW("Unimplemented function WFields::assignRField"); }
216
217} // namespace Cp
218} // namespace Pscf
219#endif
void writeFields(std::ostream &out) const
Write fields to an output stream.
void setFields(DArray< CFT > const &fields)
Set values for all fields.
int nMonomer() const
Get number of monomer types.
void setWriteUnitCell(UnitCell< D > const &cell)
Set unit cell used when writing field files.
void readFields(std::istream &in)
Read all fields from an input file.
void setFieldIo(FIT const &fieldIo)
Create association with FIT (store pointer).
IntVec< D > const & meshDimensions() const
Get mesh dimensions in each direction, set on r-grid allocation.
FIT const & fieldIo() const
Get associated FIT field IO object (const reference).
Signal< void > & signal()
Get the signal that notifies observers of w-field modification.
void allocate(int nMonomer, IntVec< D > const &dimensions)
Allocate memory for fields.
DArray< CFT > const & fields() const
Get the array of all fields.
void setReadUnitCell(UnitCell< D > &cell)
Set unit cell used when reading field files.
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
Base template for UnitCell<D> classes, D=1, 2 or 3.
Definition UnitCell.h:56
Dynamically allocatable contiguous array template.
Definition DArray.h:32
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
Complex-valued periodic fields (class templates).
Definition cp.mod:6
Periodic fields and crystallography.
Definition complex.cpp:11
PSCF package top-level namespace.