ROL
ROL_ConstraintAssembler_Def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef ROL_CONSTRAINT_ASSEMBLER_DEF_H
11 #define ROL_CONSTRAINT_ASSEMBLER_DEF_H
12 
13 namespace ROL {
14 
15 template<typename Real>
17  const Ptr<BoundConstraint<Real>> &cbnd,
18  const Ptr<Vector<Real>> &s,
19  const Ptr<Vector<Real>> &x) const {
20  // Set slack variable to s = proj(c(x))
21  Real tol = std::sqrt(ROL_EPSILON<Real>());
22  con->value(*s,*x,tol);
23  cbnd->project(*s);
24 }
25 
26 template<typename Real>
27 void ConstraintAssembler<Real>::initialize( const std::unordered_map<std::string,ConstraintData<Real>> &input_con,
28  const Ptr<Vector<Real>> &xprim,
29  const Ptr<Vector<Real>> &xdual,
30  const Ptr<BoundConstraint<Real>> &bnd) {
31  // If bnd is null, then make a null BoundConstraint
32  Ptr<BoundConstraint<Real>> bnd0;
33  if ( bnd == nullPtr ) {
34  bnd0 = makePtr<BoundConstraint<Real>>(*xprim);
35  bnd0->deactivate();
36  }
37  else {
38  bnd0 = bnd;
39  }
40  // Build slack variables
41  psvec_.clear(); psvec_.push_back(xprim);
42  dsvec_.clear(); dsvec_.push_back(xdual);
43  sbnd_.clear(); sbnd_.push_back(bnd0);
44  cvec_.clear(); lvec_.clear(); rvec_.clear();
45  isInequality_.clear();
46  int cnt = 1, cnt_con = 0;
47  isNull_ = true;
48  hasInequality_ = false;
49  for (auto it = input_con.begin(); it != input_con.end(); ++it) {
50  Ptr<Constraint<Real>> con = it->second.constraint;
51  Ptr<Vector<Real>> l = it->second.multiplier;
52  Ptr<Vector<Real>> r = it->second.residual;
53  Ptr<BoundConstraint<Real>> cbnd = it->second.bounds;
54  if (con != nullPtr) {
55  if ( con->isActivated() ) {
56  // Set default type to equality
57  isInequality_.push_back(false);
58  // Fill constraint and multiplier vectors
59  cvec_.push_back(con);
60  lvec_.push_back(l);
61  rvec_.push_back(r);
62  if (cbnd != nullPtr) {
63  if ( cbnd->isActivated() ) {
64  // Set type to inequality
65  isInequality_.back() = true;
66  // Create slack variables
67  psvec_.push_back(r->clone());
68  dsvec_.push_back(l->clone());
69  initializeSlackVariable(con,cbnd,psvec_[cnt],xprim);
70  // Create slack bound
71  sbnd_.push_back(cbnd);
72  // Update inequality constraint counter
73  cnt++;
74  hasInequality_ = true;
75  }
76  }
77  cnt_con++;
78  isNull_ = false;
79  }
80  }
81  }
82  // Create partitioned constraint and multiplier vector
83  if ( !isNull_ ) {
84  if ( cnt_con > 1 || hasInequality_ ) {
85  con_ = makePtr<Constraint_Partitioned<Real>>(cvec_,isInequality_);
86  mul_ = makePtr<PartitionedVector<Real>>(lvec_);
87  res_ = makePtr<PartitionedVector<Real>>(rvec_);
88  }
89  else {
90  con_ = cvec_[0];
91  mul_ = lvec_[0];
92  res_ = rvec_[0];
93  }
94  }
95  else {
96  con_ = nullPtr;
97  mul_ = nullPtr;
98  res_ = nullPtr;
99  }
100  // Create partitioned optimization vector and bound constraint
101  if ( hasInequality_ ) {
102  xprim_ = makePtr<PartitionedVector<Real>>(psvec_);
103  xdual_ = makePtr<PartitionedVector<Real>>(dsvec_);
104  bnd_ = makePtr<BoundConstraint_Partitioned<Real>>(sbnd_,psvec_);
105  }
106  else {
107  xprim_ = xprim;
108  xdual_ = xdual;
109  bnd_ = bnd0;
110  }
111 }
112 
113 template<typename Real>
114 void ConstraintAssembler<Real>::initialize( const std::unordered_map<std::string,ConstraintData<Real>> &input_con,
115  const std::unordered_map<std::string,ConstraintData<Real>> &input_lcon,
116  const Ptr<Vector<Real>> &xprim,
117  const Ptr<Vector<Real>> &xdual,
118  const Ptr<BoundConstraint<Real>> &bnd) {
119  // If bnd is null, then make a null BoundConstraint
120  Ptr<BoundConstraint<Real>> bnd0;
121  if ( bnd == nullPtr ) {
122  bnd0 = makePtr<BoundConstraint<Real>>(*xprim);
123  bnd0->deactivate();
124  }
125  else {
126  bnd0 = bnd;
127  }
128  // Build slack variables
129  psvec_.clear(); psvec_.push_back(xprim);
130  dsvec_.clear(); dsvec_.push_back(xdual);
131  sbnd_.clear(); sbnd_.push_back(bnd0);
132  cvec_.clear(); lvec_.clear(); rvec_.clear();
133  lcvec_.clear(); llvec_.clear(); lrvec_.clear();
134  isInequality_.clear(); isLinearInequality_.clear();
135  int cnt = 1, cnt_con = 0, cnt_lcon = 0;
136  isNull_ = true;
137  hasInequality_ = false;
138  for (auto it = input_con.begin(); it != input_con.end(); ++it) {
139  Ptr<Constraint<Real>> con = it->second.constraint;
140  Ptr<Vector<Real>> l = it->second.multiplier;
141  Ptr<Vector<Real>> r = it->second.residual;
142  Ptr<BoundConstraint<Real>> cbnd = it->second.bounds;
143  if (con != nullPtr) {
144  if ( con->isActivated() ) {
145  // Set default type to equality
146  isInequality_.push_back(false);
147  // Fill constraint and multiplier vectors
148  cvec_.push_back(con);
149  lvec_.push_back(l);
150  rvec_.push_back(r);
151  if (cbnd != nullPtr) {
152  if ( cbnd->isActivated() ) {
153  // Set type to inequality
154  isInequality_.back() = true;
155  // Create slack variables
156  psvec_.push_back(r->clone());
157  dsvec_.push_back(l->clone());
158  initializeSlackVariable(con,cbnd,psvec_[cnt],xprim);
159  // Create slack bound
160  sbnd_.push_back(cbnd);
161  // Update inequality constraint counter
162  cnt++;
163  hasInequality_ = true;
164  }
165  }
166  cnt_con++;
167  isNull_ = false;
168  }
169  }
170  }
171  for (auto it = input_lcon.begin(); it != input_lcon.end(); ++it) {
172  Ptr<Constraint<Real>> con = it->second.constraint;
173  Ptr<Vector<Real>> l = it->second.multiplier;
174  Ptr<Vector<Real>> r = it->second.residual;
175  Ptr<BoundConstraint<Real>> cbnd = it->second.bounds;
176  if (con != nullPtr) {
177  if ( con->isActivated() ) {
178  // Set default type to equality
179  isLinearInequality_.push_back(false);
180  // Fill constraint and multiplier vectors
181  lcvec_.push_back(con);
182  llvec_.push_back(l);
183  lrvec_.push_back(r);
184  if (cbnd != nullPtr) {
185  if ( cbnd->isActivated() ) {
186  // Set type to inequality
187  isLinearInequality_.back() = true;
188  // Create slack variables
189  psvec_.push_back(r->clone());
190  dsvec_.push_back(l->clone());
191  initializeSlackVariable(con,cbnd,psvec_[cnt],xprim);
192  // Create slack bound
193  sbnd_.push_back(cbnd);
194  // Update inequality constraint counter
195  cnt++;
196  hasInequality_ = true;
197  }
198  }
199  cnt_lcon++;
200  isNull_ = false;
201  }
202  }
203  }
204  // Create partitioned constraint and multiplier vector
205  if ( !isNull_ ) {
206  if ( cnt_con > 1 || hasInequality_ ) {
207  con_ = makePtr<Constraint_Partitioned<Real>>(cvec_,isInequality_);
208  mul_ = makePtr<PartitionedVector<Real>>(lvec_);
209  res_ = makePtr<PartitionedVector<Real>>(rvec_);
210  }
211  else {
212  con_ = cvec_[0];
213  mul_ = lvec_[0];
214  res_ = rvec_[0];
215  }
216  if ( cnt_lcon > 1 || hasInequality_ ) {
217  linear_con_ = makePtr<Constraint_Partitioned<Real>>(lcvec_,isLinearInequality_,cnt_con);
218  linear_mul_ = makePtr<PartitionedVector<Real>>(llvec_);
219  linear_res_ = makePtr<PartitionedVector<Real>>(lrvec_);
220  }
221  else {
222  linear_con_ = lcvec_[0];
223  linear_mul_ = llvec_[0];
224  linear_res_ = lrvec_[0];
225  }
226  }
227  else {
228  con_ = nullPtr;
229  mul_ = nullPtr;
230  res_ = nullPtr;
231  linear_con_ = nullPtr;
232  linear_mul_ = nullPtr;
233  linear_res_ = nullPtr;
234  }
235  // Create partitioned optimization vector and bound constraint
236  if ( hasInequality_ ) {
237  xprim_ = makePtr<PartitionedVector<Real>>(psvec_);
238  xdual_ = makePtr<PartitionedVector<Real>>(dsvec_);
239  bnd_ = makePtr<BoundConstraint_Partitioned<Real>>(sbnd_,psvec_);
240  }
241  else {
242  xprim_ = xprim;
243  xdual_ = xdual;
244  bnd_ = bnd0;
245  }
246 }
247 
248 template<typename Real>
249 ConstraintAssembler<Real>::ConstraintAssembler( const std::unordered_map<std::string,ConstraintData<Real>> &con,
250  const Ptr<Vector<Real>> &xprim,
251  const Ptr<Vector<Real>> &xdual,
252  const Ptr<BoundConstraint<Real>> &bnd)
253  : isNull_(true), hasInequality_(false) {
254  initialize(con,xprim,xdual,bnd);
255 }
256 
257 template<typename Real>
258 ConstraintAssembler<Real>::ConstraintAssembler( const std::unordered_map<std::string,ConstraintData<Real>> &con,
259  const std::unordered_map<std::string,ConstraintData<Real>> &linear_con,
260  const Ptr<Vector<Real>> &xprim,
261  const Ptr<Vector<Real>> &xdual,
262  const Ptr<BoundConstraint<Real>> &bnd)
263  : isNull_(true), hasInequality_(false) {
264  initialize(con,linear_con,xprim,xdual,bnd);
265 }
266 
267 template<typename Real>
268 const Ptr<Constraint<Real>>& ConstraintAssembler<Real>::getConstraint() const {
269  return con_;
270 }
271 
272 template<typename Real>
273 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getMultiplier() const {
274  return mul_;
275 }
276 
277 template<typename Real>
278 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getResidual() const {
279  return res_;
280 }
281 
282 template<typename Real>
283 const Ptr<Constraint<Real>>& ConstraintAssembler<Real>::getLinearConstraint() const {
284  return linear_con_;
285 }
286 
287 template<typename Real>
288 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getLinearMultiplier() const {
289  return linear_mul_;
290 }
291 
292 template<typename Real>
293 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getLinearResidual() const {
294  return linear_res_;
295 }
296 
297 template<typename Real>
298 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getOptVector() const {
299  return xprim_;
300 }
301 
302 template<typename Real>
303 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getDualOptVector() const {
304  return xdual_;
305 }
306 
307 template<typename Real>
308 const Ptr<BoundConstraint<Real>>& ConstraintAssembler<Real>::getBoundConstraint() const {
309  return bnd_;
310 }
311 
312 template<typename Real>
314  return isNull_;
315 }
316 
317 template<typename Real>
319  return hasInequality_;
320 }
321 
322 template<typename Real>
324  if (hasInequality_) {
325  int size = static_cast<int>(cvec_.size());
326  int cnt = 1;
327  for (int i = 0; i < size; ++i) {
328  if (isInequality_[i]) {
329  // Reset slack variables
330  initializeSlackVariable(cvec_[i],sbnd_[cnt],psvec_[cnt],psvec_[0]);
331  cnt++;
332  }
333  }
334  size = static_cast<int>(lcvec_.size());
335  for (int i = 0; i < size; ++i) {
336  if (isLinearInequality_[i]) {
337  // Reset slack variables
338  initializeSlackVariable(lcvec_[i],sbnd_[cnt],psvec_[cnt],psvec_[0]);
339  cnt++;
340  }
341  }
342  }
343 }
344 
345 } // namespace ROL
346 
347 #endif
const Ptr< BoundConstraint< Real > > & getBoundConstraint() const
const Ptr< Constraint< Real > > & getConstraint() const
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
const Ptr< Vector< Real > > & getLinearResidual() const
void initializeSlackVariable(const Ptr< Constraint< Real >> &con, const Ptr< BoundConstraint< Real >> &cbnd, const Ptr< Vector< Real >> &s, const Ptr< Vector< Real >> &x) const
ConstraintAssembler(const std::unordered_map< std::string, ConstraintData< Real >> &con, const Ptr< Vector< Real >> &xprim, const Ptr< Vector< Real >> &xdual, const Ptr< BoundConstraint< Real >> &bnd=nullPtr)
const Ptr< Vector< Real > > & getMultiplier() const
Provides the interface to apply upper and lower bound constraints.
const Ptr< Vector< Real > > & getDualOptVector() const
void initialize(const std::unordered_map< std::string, ConstraintData< Real >> &input_con, const Ptr< Vector< Real >> &xprim, const Ptr< Vector< Real >> &xdual, const Ptr< BoundConstraint< Real >> &bnd)
const Ptr< Vector< Real > > & getOptVector() const
const Ptr< Constraint< Real > > & getLinearConstraint() const
const Ptr< Vector< Real > > & getLinearMultiplier() const
const Ptr< Vector< Real > > & getResidual() const
Defines the general constraint operator interface.