PSCF v1.4.0
SweepParameter.tpp
1#ifndef RP_SWEEP_PARAMETER_TPP
2#define RP_SWEEP_PARAMETER_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 <rp/scft/sweep/SweepParameter.h>
12
13#include <prdc/crystal/UnitCell.h>
14#include <pscf/interaction/Interaction.h>
15#include <pscf/sweep/ParameterModifier.h>
16#include <util/containers/FSArray.h>
17#include <util/global.h>
18
19#include <algorithm>
20#include <iomanip>
21
22namespace Pscf {
23namespace Rp {
24
25 using namespace Util;
26 using namespace Prdc;
27
28 /*
29 * Default constructor.
30 */
31 template <int D, class T>
33 : type_(SweepParameter<D,T>::Null),
34 nId_(0),
35 id_(),
36 initial_(0.0),
37 change_(0.0),
38 systemPtr_(nullptr),
39 parameterTypesPtr_(nullptr),
40 parameterTypeId_(-1)
41 {}
42
43 /*
44 * Constructor, creates association with system.
45 */
46 template <int D, class T>
47 SweepParameter<D,T>::SweepParameter(typename T::System& system)
48 : type_(SweepParameter<D,T>::Null),
49 nId_(0),
50 id_(),
51 initial_(0.0),
52 change_(0.0),
53 systemPtr_(&system),
54 parameterTypesPtr_(nullptr),
55 parameterTypeId_(-1)
56 {}
57
58 /*
59 * Read type, set nId and allocate id_ array.
60 */
61 template <int D, class T>
62 void SweepParameter<D,T>::readParamType(std::istream& in)
63 {
64 std::string buffer;
65 in >> buffer;
66 std::transform(buffer.begin(), buffer.end(),
67 buffer.begin(), ::tolower);
68
69 if (buffer == "block" || buffer == "block_length") {
70 type_ = Block;
71 nId_ = 2; // polymer and block identifiers
72 } else if (buffer == "chi") {
73 type_ = Chi;
74 nId_ = 2; // two monomer type identifiers
75 } else if (buffer == "kuhn") {
76 type_ = Kuhn;
77 nId_ = 1; // monomer type identifier
78 } else if (buffer == "phi_polymer") {
79 type_ = Phi_Polymer;
80 nId_ = 1; // species identifier
81 } else if (buffer == "phi_solvent") {
82 type_ = Phi_Solvent;
83 nId_ = 1; // species identifier
84 } else if (buffer == "mu_polymer") {
85 type_ = Mu_Polymer;
86 nId_ = 1; // species identifier
87 } else if (buffer == "mu_solvent") {
88 type_ = Mu_Solvent;
89 nId_ = 1; // species identifier
90 } else if (buffer == "solvent" || buffer == "solvent_size") {
91 type_ = Solvent;
92 nId_ = 1; // species identifier
93 } else if (buffer == "cell_param") {
94 type_ = Cell_Param;
95 nId_ = 1; // lattice parameter identifier
96 } else {
97 // Search in parameterTypes array for this sweep parameter
98 bool found = false;
99 if (parameterTypesPtr_) {
100 for (int i = 0; i < parameterTypesPtr_->size(); i++) {
101 ParameterType& pType = (*parameterTypesPtr_)[i];
102 if (buffer == pType.name) {
103 type_ = Special;
104 nId_ = pType.nId;
105 parameterTypeId_ = i;
106 found = true;
107 break;
108 }
109 }
110 }
111 if (!found) {
112 std::string msg;
113 msg = "Invalid SweepParameter::ParamType value: " + buffer;
114 UTIL_THROW(msg.c_str());
115 }
116 }
117
118 if (id_.isAllocated()) id_.deallocate();
119 id_.allocate(nId_);
120
121 }
122
123 /*
124 * Write type enum value.
125 */
126 template <int D, class T>
127 void SweepParameter<D,T>::writeParamType(std::ostream& out) const
128 { out << type(); }
129
130 /*
131 * Get the ParameterType object for a specialized sweep parameter.
132 */
133 template <int D, class T>
135 {
136 UTIL_CHECK(parameterTypesPtr_);
138 return (*parameterTypesPtr_)[parameterTypeId_];
139 }
140
141 /*
142 * Get and store initial (current) value from the parent system.
143 */
144 template <int D, class T>
146 { initial_ = get_(); }
147
148 /*
149 * Set a new parameter value in the parent system.
150 */
151 template <int D, class T>
152 void SweepParameter<D,T>::update(double newVal)
153 { set_(newVal); }
154
155 /*
156 * Get string representation of type enum value.
157 */
158 template <int D, class T>
159 std::string SweepParameter<D,T>::type() const
160 {
161 if (type_ == Block) {
162 return "block";
163 } else if (type_ == Chi) {
164 return "chi";
165 } else if (type_ == Kuhn) {
166 return "kuhn";
167 } else if (type_ == Phi_Polymer) {
168 return "phi_polymer";
169 } else if (type_ == Phi_Solvent) {
170 return "phi_solvent";
171 } else if (type_ == Mu_Polymer) {
172 return "mu_polymer";
173 } else if (type_ == Mu_Solvent) {
174 return "mu_solvent";
175 } else if (type_ == Solvent) {
176 return "solvent_size";
177 } else if (type_ == Cell_Param) {
178 return "cell_param";
179 } else if (type_ == Special) {
180 return parameterType().name;
181 } else {
182 UTIL_THROW("This should never happen.");
183 }
185
186 template <int D, class T>
187 double SweepParameter<D,T>::get_()
188 {
189 UTIL_CHECK(systemPtr_);
190 if (type_ == Chi) {
191 return systemPtr_->interaction().chi(id(0), id(1));
192 } else if (type_ == Kuhn) {
193 return systemPtr_->mixture().monomer(id(0)).kuhn();
194 } else if (type_ == Phi_Polymer) {
195 return systemPtr_->mixture().polymer(id(0)).phi();
196 } else if (type_ == Mu_Polymer) {
197 return systemPtr_->mixture().polymer(id(0)).mu();
198 } else if (type_ == Block) {
199 return systemPtr_->mixture().polymer(id(0)).block(id(1)).length();
200 } else if (type_ == Phi_Solvent) {
201 return systemPtr_->mixture().solvent(id(0)).phi();
202 } else if (type_ == Mu_Solvent) {
203 return systemPtr_->mixture().solvent(id(0)).mu();
204 } else if (type_ == Solvent) {
205 return systemPtr_->mixture().solvent(id(0)).size();
206 } else if (type_ == Cell_Param) {
207 return systemPtr_->domain().unitCell().parameter(id(0));
208 } else if (type_ == Special) {
209 ParameterModifier* modifier = parameterType().modifierPtr;
210 std::string name = parameterType().name;
211 return modifier->getParameter(name,id_);
212 } else {
213 UTIL_THROW("This should never happen.");
214 }
215 }
216
217 template <int D, class T>
218 void SweepParameter<D,T>::set_(double newVal)
219 {
220 UTIL_CHECK(systemPtr_);
221 if (type_ == Chi) {
222 systemPtr_->interaction().setChi(id(0), id(1), newVal);
223 } else if (type_ == Kuhn) {
224 systemPtr_->mixtureModifier().setKuhn(id(0), newVal);
225 } else if (type_ == Phi_Polymer) {
226 systemPtr_->mixtureModifier().setPhiPolymer(id(0), newVal);
227 } else if (type_ == Mu_Polymer) {
228 systemPtr_->mixtureModifier().setMuPolymer(id(0), newVal);
229 } else if (type_ == Block) {
230 systemPtr_->mixtureModifier().setBlockLength(id(0), id(1), newVal);
231 } else if (type_ == Phi_Solvent) {
232 systemPtr_->mixtureModifier().setPhiSolvent(id(0), newVal);
233 } else if (type_ == Mu_Solvent) {
234 systemPtr_->mixtureModifier().setMuSolvent(id(0), newVal);
235 } else if (type_ == Solvent) {
236 systemPtr_->mixtureModifier().setSolventSize(id(0), newVal);
237 } else if (type_ == Cell_Param) {
238 FSArray<double,6> params
239 = systemPtr_->domain().unitCell().parameters();
240 params[id(0)] = newVal;
241 systemPtr_->setUnitCell(params);
242 } else if (type_ == Special) {
243 ParameterModifier* modifier = parameterType().modifierPtr;
244 std::string name = parameterType().name;
245 return modifier->setParameter(name,id_,newVal);
246 } else {
247 UTIL_THROW("This should never happen.");
248 }
249 }
250
251 #if 0
252 template <int D, class T>
253 template <class Archive>
254 void SweepParameter<D,T>::serialize(Archive ar, const unsigned int version)
255 {
256 serializeEnum(ar, type_, version);
257 ar & nId_;
258 for (int i = 0; i < nId_; ++i) {
259 ar & id_[i];
260 }
261 ar & initial_;
262 ar & change_;
263 }
264
265 // Definitions of IO operator templates
266
267 /*
268 * Inserter for reading a SweepParameter from an istream.
269 */
270 template <int D, class T>
271 std::istream& operator >> (std::istream& in,
272 SweepParameter<D,T>& param)
273 {
274 // Read the parameter type identifier string
275 param.readParamType(in);
276
277 // Read the identifiers associated with this parameter type.
278 for (int i = 0; i < param.nId_; ++i) {
279 in >> param.id_[i];
280 }
281 // Read in the range in the parameter to sweep over
282 in >> param.change_;
283
284 return in;
285 }
286
287 /*
288 * Extractor for writing a SweepParameter to ostream.
289 */
290 template <int D, class T>
291 std::ostream& operator << (std::ostream& out,
292 SweepParameter<D,T> const & param)
293 {
294 param.writeParamType(out);
295 out << " ";
296 for (int i = 0; i < param.nId_; ++i) {
297 out << param.id(i);
298 out << " ";
299 }
300 out << param.change_;
301
302 return out;
303 }
304 #endif
305
306}
307}
308#endif
Base class allowing subclasses to define sweepable parameters.
virtual double getParameter(std::string name, DArray< int > ids, bool &success) const
Get the value of a specialized sweep parameter.
Solver and descriptor for a solvent species.
Class template for storing data about an individual sweep parameter.
void getInitial()
Get initial value of this parameter.
SweepParameter()
Default constructor.
std::string type() const
Return a string representation of the parameter type.
void writeParamType(std::ostream &out) const
Write the parameter type to an output stream.
void serialize(Archive ar, const unsigned int version)
Serialize to or from an archive.
ParameterType & parameterType() const
Get the ParameterType object for a specialized sweep parameter.
void update(double newVal)
Update the corresponding parameter value in the system.
bool isSpecialized() const
Is this SweepParameter a specialized parameter type?
A fixed capacity (static) contiguous array with a variable logical size.
Definition FSArray.h:38
File containing preprocessor macros for error handling.
#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
void serializeEnum(Archive &ar, T &data, const unsigned int version=0)
Serialize an enumeration value.
Definition serialize.h:59
Periodic fields and crystallography.
Definition complex.cpp:11
Class templates for real-valued periodic fields.
PSCF package top-level namespace.
std::istream & operator>>(std::istream &in, Pair< Data > &pair)
Input a Pair from an istream.
Definition Pair.h:44
std::ostream & operator<<(std::ostream &out, const Pair< Data > &pair)
Output a Pair to an ostream, without line breaks.
Definition Pair.h:57
Declaration of a specialized sweep parameter type.