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