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  example_02.cpp
45     \brief Shows how to solve a steady Burgers' optimal control problem using
46 	   the SimOpt interface.  We solve the control problem using Composite
47            Step and trust regions.
48 */
49 
50 #include "example_02.hpp"
51 
52 typedef double RealT;
53 
main(int argc,char * argv[])54 int main(int argc, char *argv[]) {
55 
56   Teuchos::GlobalMPISession mpiSession(&argc, &argv);
57 
58   // This little trick lets us print to std::cout only if a (dummy) command-line argument is provided.
59   int iprint = argc - 1;
60   ROL::Ptr<std::ostream> outStream;
61   ROL::nullstream bhs; // outputs nothing
62   if (iprint > 0)
63     outStream = ROL::makePtrFromRef(std::cout);
64   else
65     outStream = ROL::makePtrFromRef(bhs);
66 
67   int errorFlag = 0;
68 
69   // *** Example body.
70 
71   try {
72     // Initialize full objective function.
73     int nx      = 256;   // Set spatial discretization.
74     RealT alpha = 1.e-3; // Set penalty parameter.
75     RealT nu    = 1e-2;  // Viscosity parameter.
76     Objective_BurgersControl<RealT> obj(alpha,nx);
77     // Initialize equality constraints
78     Constraint_BurgersControl<RealT> con(nx,nu);
79     ROL::ParameterList list;
80     list.sublist("SimOpt").sublist("Solve").set("Absolute Residual Tolerance",1.e2*ROL::ROL_EPSILON<RealT>());
81     con.setSolveParameters(list);
82     // Initialize iteration vectors.
83     ROL::Ptr<std::vector<RealT> > z_ptr  = ROL::makePtr<std::vector<RealT>>(nx+2, 1.0);
84     ROL::Ptr<std::vector<RealT> > gz_ptr = ROL::makePtr<std::vector<RealT>>(nx+2, 1.0);
85     ROL::Ptr<std::vector<RealT> > yz_ptr = ROL::makePtr<std::vector<RealT>>(nx+2, 1.0);
86     for (int i=0; i<nx+2; i++) {
87       (*z_ptr)[i]  = (RealT)rand()/(RealT)RAND_MAX;
88       (*yz_ptr)[i] = (RealT)rand()/(RealT)RAND_MAX;
89     }
90     ROL::StdVector<RealT> z(z_ptr);
91     ROL::StdVector<RealT> gz(gz_ptr);
92     ROL::StdVector<RealT> yz(yz_ptr);
93     ROL::Ptr<ROL::Vector<RealT> > zp  = ROL::makePtrFromRef(z);
94     ROL::Ptr<ROL::Vector<RealT> > gzp = ROL::makePtrFromRef(z);
95     ROL::Ptr<ROL::Vector<RealT> > yzp = ROL::makePtrFromRef(yz);
96 
97     ROL::Ptr<std::vector<RealT> > u_ptr  = ROL::makePtr<std::vector<RealT>>(nx, 1.0);
98     ROL::Ptr<std::vector<RealT> > gu_ptr = ROL::makePtr<std::vector<RealT>>(nx, 1.0);
99     ROL::Ptr<std::vector<RealT> > yu_ptr = ROL::makePtr<std::vector<RealT>>(nx, 1.0);
100     for (int i=0; i<nx; i++) {
101       (*u_ptr)[i]  = (RealT)rand()/(RealT)RAND_MAX;
102       (*yu_ptr)[i] = (RealT)rand()/(RealT)RAND_MAX;
103     }
104     ROL::StdVector<RealT> u(u_ptr);
105     ROL::StdVector<RealT> gu(gu_ptr);
106     ROL::StdVector<RealT> yu(yu_ptr);
107     ROL::Ptr<ROL::Vector<RealT> > up  = ROL::makePtrFromRef(u);
108     ROL::Ptr<ROL::Vector<RealT> > gup = ROL::makePtrFromRef(gu);
109     ROL::Ptr<ROL::Vector<RealT> > yup = ROL::makePtrFromRef(yu);
110 
111     ROL::Ptr<std::vector<RealT> > c_ptr = ROL::makePtr<std::vector<RealT>>(nx, 1.0);
112     ROL::Ptr<std::vector<RealT> > l_ptr = ROL::makePtr<std::vector<RealT>>(nx, 1.0);
113     ROL::StdVector<RealT> c(c_ptr);
114     ROL::StdVector<RealT> l(l_ptr);
115 
116     ROL::Vector_SimOpt<RealT> x(up,zp);
117     ROL::Vector_SimOpt<RealT> g(gup,gzp);
118     ROL::Vector_SimOpt<RealT> y(yup,yzp);
119 
120     // Check derivatives.
121     obj.checkGradient(x,x,y,true,*outStream);
122     obj.checkHessVec(x,x,y,true,*outStream);
123     con.checkApplyJacobian(x,y,c,true,*outStream);
124     con.checkApplyAdjointJacobian(x,yu,c,x,true,*outStream);
125     con.checkApplyAdjointHessian(x,yu,y,x,true,*outStream);
126 
127     // Initialize reduced objective function.
128     ROL::Ptr<std::vector<RealT> > p_ptr  = ROL::makePtr<std::vector<RealT>>(nx, 1.0);
129     ROL::StdVector<RealT> p(p_ptr);
130     ROL::Ptr<ROL::Vector<RealT> > pp              = ROL::makePtrFromRef(p);
131     ROL::Ptr<ROL::Objective_SimOpt<RealT> > pobj  = ROL::makePtrFromRef(obj);
132     ROL::Ptr<ROL::Constraint_SimOpt<RealT> > pcon = ROL::makePtrFromRef(con);
133     ROL::Reduced_Objective_SimOpt<RealT> robj(pobj,pcon,up,zp,pp);
134     // Check derivatives.
135     robj.checkGradient(z,z,yz,true,*outStream);
136     robj.checkHessVec(z,z,yz,true,*outStream);
137 
138     // Get parameter list.
139     std::string filename = "input.xml";
140     auto parlist = ROL::getParametersFromXmlFile( filename );
141     parlist->sublist("Status Test").set("Gradient Tolerance",1.e-14);
142     parlist->sublist("Status Test").set("Constraint Tolerance",1.e-14);
143     parlist->sublist("Status Test").set("Step Tolerance",1.e-16);
144     parlist->sublist("Status Test").set("Iteration Limit",1000);
145     // Declare ROL algorithm pointer.
146     ROL::Ptr<ROL::Algorithm<RealT>>  algo;
147     ROL::Ptr<ROL::Step<RealT>>       step;
148     ROL::Ptr<ROL::StatusTest<RealT>> status;
149 
150     // Run optimization with Composite Step.
151     step   = ROL::makePtr<ROL::CompositeStep<RealT>>(*parlist);
152     status = ROL::makePtr<ROL::ConstraintStatusTest<RealT>>(*parlist);
153     algo   = ROL::makePtr<ROL::Algorithm<RealT>>(step,status,false);
154     RealT zerotol = std::sqrt(ROL::ROL_EPSILON<RealT>());
155     z.zero();
156     con.solve(c,u,z,zerotol);
157     c.zero(); l.zero();
158     algo->run(x, g, l, c, obj, con, true, *outStream);
159     ROL::Ptr<ROL::Vector<RealT> > zCS = z.clone();
160     zCS->set(z);
161 
162     // Run Optimization with Trust-Region algorithm.
163     step   = ROL::makePtr<ROL::TrustRegionStep<RealT>>(*parlist);
164     status = ROL::makePtr<ROL::StatusTest<RealT>>(*parlist);
165     algo   = ROL::makePtr<ROL::Algorithm<RealT>>(step,status,false);
166     z.zero();
167     algo->run(z,robj,true,*outStream);
168 
169     // Check solutions.
170     ROL::Ptr<ROL::Vector<RealT> > err = z.clone();
171     err->set(*zCS); err->axpy(-1.,z);
172     errorFlag += ((err->norm()) > 1.e-8) ? 1 : 0;
173   }
174   catch (std::logic_error& err) {
175     *outStream << err.what() << "\n";
176     errorFlag = -1000;
177   }; // end try
178 
179   if (errorFlag != 0)
180     std::cout << "End Result: TEST FAILED\n";
181   else
182     std::cout << "End Result: TEST PASSED\n";
183 
184   return 0;
185 
186 }
187 
188