1 // @HEADER
2 // ************************************************************************
3 //
4 //               Rapid Optimization Library (ROL) Package
5 //                 Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 //              Drew Kouri   (dpkouri@sandia.gov) and
39 //              Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 /*! \file  obj.hpp
45     \brief Provides the interface for local (cell-based) objective function computations.
46 */
47 
48 #ifndef PDEOPT_QOI_VOLUME_HPP
49 #define PDEOPT_QOI_VOLUME_HPP
50 
51 #include "ROL_StdConstraint.hpp"
52 #include "ROL_ParameterList.hpp"
53 
54 template<class Real>
55 class Volume_TopoOpt : public ROL::StdConstraint<Real> {
56 private:
57   Real w0_, vol_;
58   std::vector<Real> w_;
59   int N_, M_, T_;
60 
61 public:
Volume_TopoOpt(ROL::ParameterList & list)62   Volume_TopoOpt(ROL::ParameterList &list) {
63     w_  = ROL::getArrayFromStringParameter<Real>(list.sublist("Problem"), "Density");
64     M_  = list.sublist("Problem").get("Number of Horizontal Cells",10);
65     N_  = list.sublist("Problem").get("Number of Vertical Cells",20);
66     T_  = w_.size();
67 
68     Real width  = list.sublist("Geometry").get("Width",2.0);
69     Real height = list.sublist("Geometry").get("Height",1.0);
70     vol_ = width*height/static_cast<Real>(M_*N_);
71 
72     Real mw(0);
73     for (int i = 0; i < T_; ++i) {
74       mw = std::max(mw,w_[i]);
75     }
76     w0_ = list.sublist("Problem").get("Maximum Weight Fraction", 0.5) * mw * width * height;
77   }
78 
value(std::vector<Real> & c,const std::vector<Real> & x,Real & tol)79   void value( std::vector<Real> &c, const std::vector<Real> &x, Real &tol ) {
80     c[0] = -w0_;
81     for (int i=0; i<M_; ++i) {
82       for (int j=0; j<N_; ++j) {
83         for (int k=0; k<T_; ++k) {
84           c[0] += vol_ * w_[k] * x[i + M_*(j + N_*k)];
85         }
86       }
87     }
88   }
89 
applyJacobian(std::vector<Real> & jv,const std::vector<Real> & v,const std::vector<Real> & x,Real & tol)90   void applyJacobian( std::vector<Real> &jv, const std::vector<Real> &v,
91                 const std::vector<Real> &x, Real &tol ) {
92     jv[0] = static_cast<Real>(0);
93     for (int i=0; i<M_; ++i) {
94       for (int j=0; j<N_; ++j) {
95         for (int k=0; k<T_; ++k) {
96           jv[0] += vol_ * w_[k] * v[i + M_*(j + N_*k)];
97         }
98       }
99     }
100   }
101 
applyAdjointJacobian(std::vector<Real> & ajv,const std::vector<Real> & v,const std::vector<Real> & x,Real & tol)102    void applyAdjointJacobian( std::vector<Real> &ajv, const std::vector<Real> &v,
103                         const std::vector<Real> &x, Real &tol ) {
104     for (int i=0; i<M_; ++i) {
105       for (int j=0; j<N_; ++j) {
106         for (int k=0; k<T_; ++k) {
107           ajv[i + M_*(j + N_*k)] = vol_ * w_[k] * v[0];
108         }
109       }
110     }
111   }
112 
applyAdjointHessian(std::vector<Real> & ahuv,const std::vector<Real> & u,const std::vector<Real> & v,const std::vector<Real> & x,Real & tol)113   void applyAdjointHessian( std::vector<Real> &ahuv, const std::vector<Real> &u,
114                       const std::vector<Real> &v, const std::vector<Real> &x,
115                             Real &tol ) {
116     int size = ahuv.size();
117     ahuv.assign(size,static_cast<Real>(0));
118   }
119 };
120 
121 template<class Real>
122 class Selection_TopoOpt : public ROL::StdConstraint<Real> {
123 private:
124   int N_, M_, T_;
125 
126 public:
Selection_TopoOpt(ROL::ParameterList & list)127   Selection_TopoOpt(ROL::ParameterList &list) {
128     std::vector<Real> w = ROL::getArrayFromStringParameter<Real>(list.sublist("Problem"), "Density");
129     M_  = list.sublist("Problem").get("Number of Horizontal Cells",10);
130     N_  = list.sublist("Problem").get("Number of Vertical Cells",20);
131     T_  = w.size();
132   }
133 
value(std::vector<Real> & c,const std::vector<Real> & x,Real & tol)134   void value( std::vector<Real> &c, const std::vector<Real> &x, Real &tol ) {
135     for (int i=0; i<M_; ++i) {
136       for (int j=0; j<N_; ++j) {
137         c[i + M_*j] = static_cast<Real>(-1);
138         for (int k=0; k<T_; ++k) {
139           c[i + M_*j] += x[i + M_*(j + N_*k)];
140         }
141       }
142     }
143   }
144 
applyJacobian(std::vector<Real> & jv,const std::vector<Real> & v,const std::vector<Real> & x,Real & tol)145   void applyJacobian( std::vector<Real> &jv, const std::vector<Real> &v,
146                 const std::vector<Real> &x, Real &tol ) {
147     for (int i=0; i<M_; ++i) {
148       for (int j=0; j<N_; ++j) {
149         jv[i + M_*j] = static_cast<Real>(0);
150         for (int k=0; k<T_; ++k) {
151           jv[i + M_*j] += v[i + M_*(j + N_*k)];
152         }
153       }
154     }
155   }
156 
applyAdjointJacobian(std::vector<Real> & ajv,const std::vector<Real> & v,const std::vector<Real> & x,Real & tol)157    void applyAdjointJacobian( std::vector<Real> &ajv, const std::vector<Real> &v,
158                         const std::vector<Real> &x, Real &tol ) {
159     for (int i=0; i<M_; ++i) {
160       for (int j=0; j<N_; ++j) {
161         for (int k=0; k<T_; ++k) {
162           ajv[i + M_*(j + N_*k)] = v[i + M_*j];
163         }
164       }
165     }
166   }
167 
applyAdjointHessian(std::vector<Real> & ahuv,const std::vector<Real> & u,const std::vector<Real> & v,const std::vector<Real> & x,Real & tol)168   void applyAdjointHessian( std::vector<Real> &ahuv, const std::vector<Real> &u,
169                       const std::vector<Real> &v, const std::vector<Real> &x,
170                             Real &tol ) {
171     int size = ahuv.size();
172     ahuv.assign(size,static_cast<Real>(0));
173   }
174 };
175 
176 #endif
177