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