PSCF v1.3
FilmFieldGenExtBase.tpp
1#ifndef PRDC_FILM_FIELD_GEN_EXT_BASE_TPP
2#define PRDC_FILM_FIELD_GEN_EXT_BASE_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 "FilmFieldGenExtBase.h"
12#include <prdc/crystal/SpaceGroup.h>
13#include <pscf/sweep/ParameterType.h>
14#include <util/param/ParamComponent.h>
15#include <util/containers/GArray.h>
16
17namespace Pscf {
18namespace Prdc {
19
20 using namespace Util;
21
22 /*
23 * Constructor
24 */
25 template <int D>
28 normalVecId_(-1),
29 interfaceThickness_(-1.0),
30 excludedThickness_(-1.0)
31 {
32 type_ = External;
33 isDependent_ = true;
34 }
35
36 /*
37 * Destructor
38 */
39 template <int D>
42
43 /*
44 * Read and initialize.
45 */
46 template <int D>
48 {
49 // First, read data defining the mask (quietly, with echo = false)
52 read(in, "normalVecId", normalVecId_);
53 read(in, "interfaceThickness", interfaceThickness_);
54 read(in, "excludedThickness", excludedThickness_);
55 double tmp;
56 readOptional(in, "fBulk", tmp); // will not be used
58
59 // Remove all of these parameters from this ParamComposite, since
60 // they are already managed by the FilmFieldGenMask ParamComposite
62
63 // Make sure inputs are valid
64 if (normalVecId_ > D || normalVecId_ < 0) {
65 UTIL_THROW("bad value for normalVecId, must be in [0,D)");
66 }
67 if (interfaceThickness_ > excludedThickness_) {
68 UTIL_THROW("excludedThickness must be larger than interfaceThickness");
69 }
70 if ((excludedThickness_ <= 0) || (interfaceThickness_ <= 0)) {
71 UTIL_THROW("excludedThickness and interfaceThickness must be >0");
72 }
73
74 // Allocate chiBottom_ and chiTop_
75 int nm = systemNMonomer();
76 chiBottom_.allocate(nm);
77 chiTop_.allocate(nm);
78
79 // Read chiBottom_ and chiTop_ arrays
80 readDArray(in, "chiBottom", chiBottom_, nm);
81 readDArray(in, "chiTop", chiTop_, nm);
82 }
83
84 /*
85 * Check whether system has changed such that the fields need updating
86 */
87 template <int D>
89 {
90 UTIL_CHECK(normalVecId_ >= 0); // Check that readParameters was called
91
92 // If chiBottomCurrent_ and chiTopCurrent_ are unset, generate() has
93 // not been called. Therefore, needsUpdate is true
94 if (!chiBottomCurrent_.isAllocated()) {
95 UTIL_CHECK(!chiTopCurrent_.isAllocated());
96 return true;
97 }
98
99 // Check if chiBottom or chiTop have been changed
100 for (int i = 0; i < chiBottom_.capacity(); i++) {
101 if ((chiBottom_[i] != chiBottomCurrent_[i]) ||
102 (chiTop_[i] != chiTopCurrent_[i])) {
103 return true;
104 }
105 }
106
107 // If chiTop and chiBottom are unchanged and all zeros, no update needed
108 if (isAthermal()) return false;
109
110 // Check if system normalVec differ from normalVecCurrent_
111 if (normalVecCurrent_ == systemLatticeVector(normalVecId_)) {
112 return false;
113 } else {
114 return true;
115 }
116 }
117
118 /*
119 * Check that the system is compatible with this field
120 */
121 template <int D>
123 {
124 // Ensure that space group symmetry is compatible with the fields
125
126 // If chiBottom == chiTop, do nothing. All necessary checks have
127 // already been performed by the mask generator.
128 if (hasSymmetricWalls()) return;
129
130 // Otherwise, walls are asymmetric, so the space group must not
131 // have any operations that swap the two walls
132 std::string groupName = systemSpaceGroup();
133 SpaceGroup<D> group;
134 std::ifstream in;
135
136 // Open and read file containing space group's symmetry operations
137 readGroup(groupName, group);
138
139 // Make sure all symmetry operations are allowed
140 std::string msg = "Space group contains forbidden symmetry operations";
141 for (int i = 0; i < group.size(); i++) {
142 for (int j = 0; j < D; j++) {
143 int r = group[i].R(normalVecId_,j);
144 if (j == normalVecId_) {
145 if (r != 1) {
146 UTIL_THROW(msg.c_str());
147 }
148 } else { // j != normalVecId_
149 if (r != 0) {
150 UTIL_THROW(msg.c_str());
151 }
152 }
153 }
154 if (group[i].t(normalVecId_) != 0) {
155 UTIL_THROW(msg.c_str());
156 }
157 }
158 }
159
160 /*
161 * Check whether or not the two walls are chemically identical using
162 * the chi array.
163 */
164 template <int D>
166 {
167 int nm = systemNMonomer();
168
169 UTIL_CHECK(nm > 0);
170 UTIL_CHECK(chiBottom_.capacity() == nm);
171 UTIL_CHECK(chiTop_.capacity() == nm);
172
173 for (int i = 0; i < nm; i++) {
174 if (fabs(chiBottom_[i]-chiTop_[i]) > 1e-7) {
175 return false;
176 }
177 }
178 return true;
179 }
180
181 /*
182 * Check whether or not the walls are athermal (only true if all values
183 * in chi array are zero)
184 */
185 template <int D>
187 {
188 int nm = systemNMonomer();
189
190 UTIL_CHECK(nm > 0);
191 UTIL_CHECK(chiBottom_.capacity() == nm);
192 UTIL_CHECK(chiTop_.capacity() == nm);
193
194 for (int i = 0; i < nm; i++) {
195 if ((fabs(chiBottom_[i]) >= 1e-7) || (fabs(chiTop_[i]) >= 1e-7)) {
196 return false;
197 }
198 }
199 return true;
200 }
201
202 /*
203 * Return specialized sweep parameter types to add to the Sweep object.
204 */
205 template <int D>
208 {
210 pTypes.append(ParameterType("chi_top", 1, *this));
211 pTypes.append(ParameterType("chi_bottom", 1, *this));
212 return pTypes;
213 }
214
215 /*
216 * Set the value of a specialized sweep parameter (chi_top or chi_bottom).
217 */
218 template <int D>
220 DArray<int> ids,
221 double value,
222 bool& success)
223 {
224 success = true;
225 if (name == "chi_top") {
226 chiTop_[ids[0]] = value;
227 } else if (name == "chi_bottom") {
228 chiBottom_[ids[0]] = value;
229 } else {
230 success = false;
231 }
232 }
233
234 /*
235 * Get the value of a specialized sweep parameter (chi_top or chi_bottom).
236 */
237 template <int D>
238 double FilmFieldGenExtBase<D>::getParameter(std::string name,
239 DArray<int> ids,
240 bool& success)
241 const
242 {
243 success = true;
244 if (name == "chi_top") {
245 return chiTop_[ids[0]];
246 } else if (name == "chi_bottom") {
247 return chiBottom_[ids[0]];
248 } else {
249 success = false;
250 return 0.0;
251 }
252 }
253
254}
255}
256#endif
Type type_
Type of field (Mask, External, or None).
bool isDependent_
Is this object dependent on parameters of another FieldGeneratorBase?
DArray< double > chiTopCurrent_
The chiTop array used to generate the current external fields.
DArray< double > chiBottomCurrent_
The chiBottom array used to generate the current external fields.
double getParameter(std::string name, DArray< int > ids, bool &success) const
Get the value of a specialized sweep parameter.
virtual int systemNMonomer() const =0
Get the number of monomer species for this system.
bool isAthermal() const
Are the walls athermal?
void setParameter(std::string name, DArray< int > ids, double value, bool &success)
Set the value of a specialized sweep parameter.
void checkCompatibility()
Check that the system is compatible with these fields.
RealVec< D > normalVecCurrent_
The lattice vector normal to the film used to generate these fields.
bool needsUpdate() const
Check whether system has changed such that the fields need updating.
virtual std::string systemSpaceGroup() const =0
Get the space group name for this system.
virtual RealVec< D > systemLatticeVector(int id) const =0
Get one of the lattice vectors for this system.
GArray< ParameterType > getParameterTypes()
Return specialized sweep parameter types to add to the Sweep object.
void readParameters(std::istream &in)
Read parameters and initialize.
bool hasSymmetricWalls() const
Are the walls chemically identical?
Crystallographic space group.
Definition SpaceGroup.h:32
int size() const
Return number of elements in group (i.e., the order of the group).
Dynamically allocatable contiguous array template.
Definition DArray.h:32
An automatically growable array, analogous to a std::vector.
Definition GArray.h:34
void append(Data const &data)
Append an element to the end of the sequence.
Definition GArray.h:306
static bool echo()
Get echo parameter.
static void setEcho(bool echo=true)
Enable or disable echoing for all subclasses of ParamComponent.
DArrayParam< Type > & readDArray(std::istream &in, const char *label, DArray< Type > &array, int n)
Add and read a required DArray < Type > parameter.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
void resetParam()
Resets ParamComposite to its empty state.
ScalarParam< Type > & readOptional(std::istream &in, const char *label, Type &value)
Add and read a new optional ScalarParam < Type > object.
#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
Periodic fields and crystallography.
Definition CField.cpp:11
PSCF package top-level namespace.
Definition param_pc.dox:1
Declaration of a specialized sweep parameter type.