PSCF v1.3.3
SweepParameter.cpp
1/*
2* PSCF - Polymer Self-Consistent Field
3*
4* Copyright 2015 - 2025, The Regents of the University of Minnesota
5* Distributed under the terms of the GNU General Public License.
6*/
7
8#include <r1d/sweep/SweepParameter.h>
9#include <r1d/System.h>
10#include <r1d/solvers/Block.h>
11#include <r1d/solvers/Mixture.h>
12#include <r1d/solvers/Polymer.h>
13#include <r1d/solvers/Solvent.h>
14#include <pscf/inter/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 R1d {
24
25 using namespace Util;
26
27 /*
28 * Default constructor.
29 */
31 : type_(SweepParameter::Null),
32 nId_(0),
33 id_(),
34 initial_(0.0),
35 change_(0.0),
36 systemPtr_(0),
37 parameterTypesPtr_(0),
38 parameterTypeId_(-1)
39 {}
40
41 /*
42 * Constructor, creates association with system.
43 */
45 : type_(SweepParameter::Null),
46 nId_(0),
47 id_(),
48 initial_(0.0),
49 change_(0.0),
50 systemPtr_(&system),
51 parameterTypesPtr_(0),
52 parameterTypeId_(-1)
53 {}
54
55 /*
56 * Read type, set nId and allocate id_ array.
57 */
58 void SweepParameter::readParamType(std::istream& in)
59 {
60 std::string buffer;
61 in >> buffer;
62 std::transform(buffer.begin(), buffer.end(),
63 buffer.begin(), ::tolower);
64
65 if (buffer == "block" || buffer == "block_length") {
66 type_ = Block;
67 nId_ = 2; // polymer and block identifiers
68 } else if (buffer == "chi") {
69 type_ = Chi;
70 nId_ = 2; // two monomer type identifiers
71 } else if (buffer == "kuhn") {
72 type_ = Kuhn;
73 nId_ = 1; // monomer type identifier
74 } else if (buffer == "phi_polymer") {
75 type_ = Phi_Polymer;
76 nId_ = 1; //species identifier.
77 } else if (buffer == "phi_solvent") {
78 type_ = Phi_Solvent;
79 nId_ = 1; //species identifier.
80 } else if (buffer == "mu_polymer") {
81 type_ = Mu_Polymer;
82 nId_ = 1; //species identifier.
83 } else if (buffer == "mu_solvent") {
84 type_ = Mu_Solvent;
85 nId_ = 1; //species identifier.
86 } else if (buffer == "solvent" || buffer == "solvent_size") {
87 type_ = Solvent;
88 nId_ = 1; //species identifier.
89 } else if (buffer == "cell_param") {
90 type_ = Cell_Param;
91 nId_ = 1; //lattice parameter identifier.
92 } else {
93 // Search in parameterTypes array for this sweep parameter
94 bool found = false;
95 for (int i = 0; i < parameterTypesPtr_->size(); i++) {
96 ParameterType& pType = (*parameterTypesPtr_)[i];
97 if (buffer == pType.name) {
98 type_ = Special;
99 nId_ = pType.nId;
100 parameterTypeId_ = i;
101 found = true;
102 break;
103 }
104 }
105 if (!found) {
106 std::string msg;
107 msg = "Invalid SweepParameter::ParamType value: " + buffer;
108 UTIL_THROW(msg.c_str());
109 }
110 }
111
112 if (id_.isAllocated()) id_.deallocate();
113 id_.allocate(nId_);
114 }
115
116 /*
117 * Write type enum value
118 */
119 void SweepParameter::writeParamType(std::ostream& out) const
120 {
121 out << type();
122 }
123
124 /*
125 * Get the ParameterType object for a specialized sweep parameter
126 */
128 {
130 return (*parameterTypesPtr_)[parameterTypeId_];
131 }
132
133 /*
134 * Get the current value from the parent system.
135 */
137 {
138 initial_ = get_();
139 }
140
141 /*
142 * Set a new value in the parent system.
143 */
144 void SweepParameter::update(double newVal)
145 {
146 set_(newVal);
147 }
148
149 /*
150 * Get string representation of type enum value.
151 */
152 std::string SweepParameter::type() const
153 {
154 if (type_ == Block) {
155 return "block";
156 } else if (type_ == Chi) {
157 return "chi";
158 } else if (type_ == Kuhn) {
159 return "kuhn";
160 } else if (type_ == Phi_Polymer) {
161 return "phi_polymer";
162 } else if (type_ == Phi_Solvent) {
163 return "phi_solvent";
164 } else if (type_ == Mu_Polymer) {
165 return "mu_polymer";
166 } else if (type_ == Mu_Solvent) {
167 return "mu_solvent";
168 } else if (type_ == Solvent) {
169 return "solvent_size";
170 } else if (type_ == Special) {
171 return parameterType().name;
172 } else {
173 UTIL_THROW("Invalid type_ in accessor SweepParameter::type().");
174 }
175 }
176
177 double SweepParameter::get_()
178 {
179 if (type_ == Block) {
180 return systemPtr_->mixture().polymer(id(0)).block(id(1)).length();
181 } else if (type_ == Chi) {
182 return systemPtr_->interaction().chi(id(0), id(1));
183 } else if (type_ == Kuhn) {
184 return systemPtr_->mixture().monomer(id(0)).kuhn();
185 } else if (type_ == Phi_Polymer) {
186 return systemPtr_->mixture().polymer(id(0)).phi();
187 } else if (type_ == Phi_Solvent) {
188 return systemPtr_->mixture().solvent(id(0)).phi();
189 } else if (type_ == Mu_Polymer) {
190 return systemPtr_->mixture().polymer(id(0)).mu();
191 } else if (type_ == Mu_Solvent) {
192 return systemPtr_->mixture().solvent(id(0)).mu();
193 } else if (type_ == Solvent) {
194 return systemPtr_->mixture().solvent(id(0)).size();
195 } else if (type_ == Special) {
196 ParameterModifier* modifier = parameterType().modifierPtr;
197 std::string name = parameterType().name;
198 return modifier->getParameter(name,id_);
199 } else {
200 UTIL_THROW("Invalid type_ in SweepParameter::get_.");
201 }
202 }
203
204 void SweepParameter::set_(double newVal)
205 {
206 if (type_ == Block) {
207 systemPtr_->mixture().polymer(id(0)).block(id(1)).setLength(newVal);
208 } else if (type_ == Chi) {
209 systemPtr_->interaction().setChi(id(0), id(1), newVal);
210 } else if (type_ == Kuhn) {
211 systemPtr_->mixture().setKuhn(id(0), newVal);
212 } else if (type_ == Phi_Polymer) {
213 systemPtr_->mixture().polymer(id(0)).setPhi(newVal);
214 } else if (type_ == Phi_Solvent) {
215 systemPtr_->mixture().solvent(id(0)).setPhi(newVal);
216 } else if (type_ == Mu_Polymer) {
217 systemPtr_->mixture().polymer(id(0)).setMu(newVal);
218 } else if (type_ == Mu_Solvent) {
219 systemPtr_->mixture().solvent(id(0)).setMu(newVal);
220 } else if (type_ == Solvent) {
221 systemPtr_->mixture().solvent(id(0)).setSize(newVal);
222 } else if (type_ == Special) {
223 ParameterModifier* modifier = parameterType().modifierPtr;
224 std::string name = parameterType().name;
225 return modifier->setParameter(name,id_,newVal);
226 } else {
227 UTIL_THROW("Invalid type_ in SweepParameter::set_.");
228 }
229 }
230
231 // Definitions of operators, with no explicit instantiations.
232
239 std::istream& operator >> (std::istream& in,
240 SweepParameter& param)
241 {
242 // Read the parameter type.
243 param.readParamType(in);
244 // Read the identifiers associated with this parameter type.
245 for (int i = 0; i < param.nId_; ++i) {
246 in >> param.id_[i];
247 }
248 // Read in the range in the parameter to sweep over
249 in >> param.change_;
250
251 return in;
252 }
253
260 std::ostream& operator << (std::ostream& out,
261 SweepParameter const & param)
262 {
263 param.writeParamType(out);
264 out << " ";
265 for (int i = 0; i < param.nId_; ++i) {
266 out << param.id(i);
267 out << " ";
268 }
269 out << param.change_;
270
271 return out;
272 }
273
274}
275}
DMatrix< double > const & chi() const
Return the chi matrix by const reference.
Monomer const & monomer(int id) const
Get a Monomer type descriptor by const reference.
PolymerT & polymer(int id)
Get a polymer solver object by non-const reference.
double kuhn() const
Statistical segment length (random walk step size).
Definition Monomer.h:131
Block within a block polymer.
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.
SweepParameter()
Default constructor.
bool isSpecialized() const
Is this SweepParameter a specialized parameter type?
void getInitial()
Store the pre-sweep value of the corresponding parameter.
int id(int i) const
Get a id for a sub-object or element to which this is applied.
ParameterType & parameterType() const
Get the ParameterType object for a specialized sweep parameter.
void update(double newVal)
Update the corresponding parameter value in the system.
Main class in SCFT simulation of one system.
Definition r1d/System.h:65
Interaction & interaction()
Get interaction (i.e., excess free energy) by reference.
Definition r1d/System.h:574
Mixture & mixture()
Get Mixture by reference.
Definition r1d/System.h:562
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
SCFT with real 1D 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.