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