Skip to content

Commit dde9850

Browse files
Merge Pull Request trilinos#12770 from dridzal/Trilinos/rol-trilinos-sync
Automatically Merged using Trilinos Pull Request AutoTester PR Title: b'ROL Trilinos Sync 23-Feb-2024' PR Author: dridzal
2 parents 150b934 + 915e66c commit dde9850

File tree

116 files changed

+5028
-243
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+5028
-243
lines changed

packages/rol/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ TRIBITS_ADD_OPTION_AND_DEFINE(${PACKAGE_NAME}_ENABLE_TIMERS
2424
OFF
2525
)
2626

27+
TRIBITS_ADD_OPTION_AND_DEFINE(${PACKAGE_NAME}_ENABLE_PYROL
28+
ENABLE_PYBIND11_PYROL
29+
"Build ROL with PyROL interface."
30+
OFF
31+
)
32+
2733
# Build Options
2834
SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
2935
INCLUDE(BuildOptions)
@@ -49,6 +55,10 @@ IF (ROL_ENABLE_ArrayFireCPU)
4955
ADD_SUBDIRECTORY(adapters/arrayfire)
5056
ENDIF()
5157

58+
IF( ROL_ENABLE_PYROL )
59+
ADD_SUBDIRECTORY(pyrol)
60+
ENDIF()
61+
5262
# Adapters which require use of Teuchos
5363

5464
#GET_PROPERTY( PTR_STRING GLOBAL PROPERTY PTR_IMPL )
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MACRO(PYTHON_ADD_TEST TEST_NAME)
2+
3+
TRIBITS_ADD_TEST(
4+
${PYTHON_EXECUTABLE}
5+
NOEXEPREFIX
6+
NOEXESUFFIX
7+
NAME PYTHON_${TEST_NAME}
8+
ARGS "-m unittest ${TEST_NAME}.py"
9+
NUM_MPI_PROCS 1
10+
PASS_REGULAR_EXPRESSION "OK"
11+
${ARGN}
12+
)
13+
14+
IF(TPL_ENABLE_MPI)
15+
tribits_set_tests_properties(ROL_PYTHON_${TEST_NAME}_MPI_1
16+
PROPERTIES ENVIRONMENT "${PyROL_PYTHONPATH}")
17+
ELSE()
18+
tribits_set_tests_properties(ROL_PYTHON_${TEST_NAME}
19+
PROPERTIES ENVIRONMENT "${PyROL_PYTHONPATH}")
20+
ENDIF()
21+
22+
ENDMACRO(PYTHON_ADD_TEST TEST_NAME)

packages/rol/cmake/ROL_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,6 @@
5151

5252
/* Define for performance timer support. */
5353
#cmakedefine ROL_TIMERS
54+
55+
/* Define for python interface support. */
56+
#cmakedefine ENABLE_PYBIND11_PYROL

packages/rol/example/PDE-OPT/dynamic/adv_diff/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ IF(${PROJECT_NAME}_ENABLE_Intrepid AND
1919
SOURCES example_02.cpp
2020
ADD_DIR_TO_NAME
2121
)
22+
TRIBITS_ADD_EXECUTABLE(
23+
example_03
24+
SOURCES example_03.cpp
25+
ADD_DIR_TO_NAME
26+
)
2227
TRIBITS_COPY_FILES_TO_BINARY_DIR(
2328
ParabolicDataCopy
2429
SOURCE_FILES
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
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_01.cpp
45+
\brief Solves a source inversion problem governed by the
46+
advection-diffusion equation.
47+
*/
48+
49+
#include "Teuchos_Comm.hpp"
50+
#include "Teuchos_GlobalMPISession.hpp"
51+
#include "Tpetra_Core.hpp"
52+
#include "Tpetra_Version.hpp"
53+
54+
#include "ROL_Stream.hpp"
55+
#include "ROL_ParameterList.hpp"
56+
#include "ROL_Solver.hpp"
57+
#include "ROL_ReducedDynamicObjective.hpp"
58+
#include "ROL_Bounds.hpp"
59+
#include "ROL_DynamicConstraintCheck.hpp"
60+
#include "ROL_DynamicObjectiveCheck.hpp"
61+
#include "ROL_TypeBIndicatorObjective.hpp"
62+
#include <iostream>
63+
//#include <fenv.h>
64+
65+
#include "../../TOOLS/meshmanager.hpp"
66+
#include "../../TOOLS/lindynconstraint.hpp"
67+
#include "../../TOOLS/ltiobjective.hpp"
68+
#include "../../TOOLS/pdevector.hpp"
69+
#include "../../TOOLS/pdeobjective.hpp"
70+
#include "dynpde_adv_diff.hpp"
71+
#include "obj_adv_diff.hpp"
72+
#include "mesh_adv_diff.hpp"
73+
#include "l1penaltydynamic.hpp"
74+
75+
#include "ROL_TypeP_TrustRegionAlgorithm.hpp"
76+
77+
78+
int main(int argc, char *argv[]) {
79+
// feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
80+
81+
using RealT = double;
82+
83+
/*** Initialize communicator. ***/
84+
Teuchos::GlobalMPISession mpiSession(&argc, &argv);
85+
ROL::Ptr<const Teuchos::Comm<int>> comm
86+
= Tpetra::getDefaultComm();
87+
88+
// This little trick lets us print to std::cout only if a (dummy) command-line argument is provided.
89+
const int myRank = comm->getRank();
90+
ROL::Ptr<std::ostream> outStream = ROL::makeStreamPtr( std::cout, (argc > 1) && (myRank==0) );
91+
92+
int errorFlag = 0;
93+
94+
// *** Example body.
95+
try {
96+
97+
/*** Read in XML input ***/
98+
ROL::Ptr<ROL::ParameterList> parlist = ROL::getParametersFromXmlFile("input.xml");
99+
int nt = parlist->sublist("Time Discretization").get("Number of Time Steps", 100);
100+
RealT T = parlist->sublist("Time Discretization").get("End Time", 1.0);
101+
RealT dt = T/static_cast<RealT>(nt);
102+
int controlDim = 9;
103+
104+
/*************************************************************************/
105+
/***************** BUILD GOVERNING PDE ***********************************/
106+
/*************************************************************************/
107+
/*** Initialize main data structure. ***/
108+
ROL::Ptr<MeshManager<RealT>> meshMgr
109+
= ROL::makePtr<MeshManager_adv_diff<RealT>>(*parlist);
110+
// Initialize PDE describing advection-diffusion equation
111+
ROL::Ptr<DynamicPDE_adv_diff<RealT>> pde
112+
= ROL::makePtr<DynamicPDE_adv_diff<RealT>>(*parlist);
113+
114+
/*************************************************************************/
115+
/***************** BUILD CONSTRAINT **************************************/
116+
/*************************************************************************/
117+
bool isLTI = !parlist->sublist("Problem").get("Time Varying Coefficients",false);
118+
ROL::Ptr<LinDynConstraint<RealT>> dyn_con
119+
= ROL::makePtr<LinDynConstraint<RealT>>(pde,meshMgr,comm,*parlist,isLTI,*outStream);
120+
dyn_con->getAssembler()->printMeshData(*outStream);
121+
122+
/*************************************************************************/
123+
/***************** BUILD STATE VECTORS ***********************************/
124+
/*************************************************************************/
125+
ROL::Ptr<Tpetra::MultiVector<>> u0_ptr, uo_ptr, un_ptr, ck_ptr;
126+
u0_ptr = dyn_con->getAssembler()->createStateVector();
127+
uo_ptr = dyn_con->getAssembler()->createStateVector();
128+
un_ptr = dyn_con->getAssembler()->createStateVector();
129+
ck_ptr = dyn_con->getAssembler()->createResidualVector();
130+
ROL::Ptr<ROL::Vector<RealT>> u0, uo, un, ck, zk;
131+
u0 = ROL::makePtr<PDE_PrimalSimVector<RealT>>(u0_ptr,pde,*dyn_con->getAssembler());
132+
uo = ROL::makePtr<PDE_PrimalSimVector<RealT>>(uo_ptr,pde,*dyn_con->getAssembler());
133+
un = ROL::makePtr<PDE_PrimalSimVector<RealT>>(un_ptr,pde,*dyn_con->getAssembler());
134+
ck = ROL::makePtr<PDE_DualSimVector<RealT>>(ck_ptr,pde,*dyn_con->getAssembler());
135+
zk = ROL::makePtr<PDE_OptVector<RealT>>(ROL::makePtr<ROL::StdVector<RealT>>(controlDim));
136+
ROL::Ptr<ROL::PartitionedVector<RealT>> z
137+
= ROL::PartitionedVector<RealT>::create(*zk, nt);
138+
139+
/*************************************************************************/
140+
/***************** BUILD COST FUNCTIONAL *********************************/
141+
/*************************************************************************/
142+
std::vector<ROL::Ptr<QoI<RealT>>> qoi_vec(2,ROL::nullPtr);
143+
qoi_vec[0] = ROL::makePtr<QoI_State_Cost_adv_diff<RealT>>(pde->getFE());
144+
qoi_vec[1] = ROL::makePtr<QoI_State_MY_adv_diff<RealT>>(pde->getFE());
145+
RealT stateCost = parlist->sublist("Problem").get("State Cost",1e5);
146+
RealT myCost = 1e0;
147+
std::vector<RealT> wts = {stateCost, myCost};
148+
ROL::Ptr<ROL::Objective_SimOpt<RealT>> obj_k
149+
= ROL::makePtr<PDE_Objective<RealT>>(qoi_vec,wts,dyn_con->getAssembler());
150+
ROL::Ptr<LTI_Objective<RealT>> dyn_obj
151+
= ROL::makePtr<LTI_Objective<RealT>>(*parlist,obj_k,false);
152+
153+
/*************************************************************************/
154+
/***************** BUILD REDUCED COST FUNCTIONAL *************************/
155+
/*************************************************************************/
156+
std::vector<ROL::TimeStamp<RealT>> timeStamp(nt);
157+
for( int k=0; k<nt; ++k ) {
158+
timeStamp.at(k).t.resize(2);
159+
timeStamp.at(k).t.at(0) = k*dt;
160+
timeStamp.at(k).t.at(1) = (k+1)*dt;
161+
}
162+
ROL::ParameterList &rpl = parlist->sublist("Reduced Dynamic Objective");
163+
ROL::Ptr<ROL::ReducedDynamicObjective<RealT>> obj
164+
= ROL::makePtr<ROL::ReducedDynamicObjective<RealT>>(dyn_obj, dyn_con, u0, zk, ck, timeStamp, rpl, outStream);
165+
166+
/*************************************************************************/
167+
/***************** BUILD BOUND CONSTRAINT AND L1 PENALTY *****************/
168+
/*************************************************************************/
169+
ROL::Ptr<ROL::PartitionedVector<RealT>> zlo = ROL::PartitionedVector<RealT>::create(*zk, nt);
170+
ROL::Ptr<ROL::PartitionedVector<RealT>> zhi = ROL::PartitionedVector<RealT>::create(*zk, nt);
171+
zlo->setScalar(-static_cast<RealT>(1)); zhi->setScalar(static_cast<RealT>(1));
172+
ROL::Ptr<L1_Dyn_Objective<RealT>> nobj
173+
= ROL::makePtr<L1_Dyn_Objective<RealT>>(*parlist, timeStamp, zlo, zhi);
174+
175+
/*************************************************************************/
176+
/***************** RUN VECTOR AND DERIVATIVE CHECKS **********************/
177+
/*************************************************************************/
178+
bool checkDeriv = parlist->sublist("Problem").get("Check Derivatives",false);
179+
if ( checkDeriv ) {
180+
ROL::Ptr<ROL::PartitionedVector<RealT>> dz = ROL::PartitionedVector<RealT>::create(*zk, nt);
181+
ROL::Ptr<ROL::PartitionedVector<RealT>> hz = ROL::PartitionedVector<RealT>::create(*zk, nt);
182+
z->randomize(); dz->randomize(); hz->randomize();
183+
zk->randomize(); uo->randomize(); un->randomize();
184+
ROL::ValidateFunction<RealT> validate(1,13,20,11,true,*outStream);
185+
ROL::DynamicObjectiveCheck<RealT>::check(*dyn_obj,validate,*uo,*un,*zk,timeStamp[0]);
186+
ROL::DynamicConstraintCheck<RealT>::check(*dyn_con,validate,*uo,*un,*zk,timeStamp[0]);
187+
obj->checkGradient(*z,*dz,true,*outStream);
188+
obj->checkHessVec(*z,*dz,true,*outStream);
189+
obj->checkHessSym(*z,*dz,*hz,true,*outStream);
190+
}
191+
192+
/*************************************************************************/
193+
/***************** SOLVE OPTIMIZATION PROBLEM ****************************/
194+
/*************************************************************************/
195+
RealT gtol(1e-2), zerr(0), ztol0(1e-6), ztol(1);
196+
z->zero();
197+
ROL::Ptr<ROL::Vector<RealT>> zprev = z->clone(), zdiff = z->clone();
198+
ROL::Ptr<ROL::TypeP::TrustRegionAlgorithm<RealT>> algo;
199+
parlist->sublist("Status Test").set("Use Relative Tolerances",false);
200+
for (unsigned i = 0; i < 20; ++i) {
201+
*outStream << std::endl << "Moreau-Yosida Parameter: "
202+
<< myCost << std::endl
203+
<< "Gradient Tolerance: "
204+
<< gtol << std::endl << std::endl;
205+
206+
ztol = ztol0 / std::max(static_cast<RealT>(1),z->norm());
207+
zprev->set(*z);
208+
parlist->sublist("Status Test").set("Gradient Tolerance",gtol);
209+
parlist->sublist("Status Test").set("Step Tolerance",static_cast<RealT>(1e-4)*gtol);
210+
algo = ROL::makePtr<ROL::TypeP::TrustRegionAlgorithm<RealT>>(*parlist);
211+
std::clock_t timer = std::clock();
212+
algo->run(*z, *obj, *nobj, *outStream);
213+
*outStream << "Optimization time: "
214+
<< static_cast<RealT>(std::clock()-timer)/static_cast<RealT>(CLOCKS_PER_SEC)
215+
<< " seconds." << std::endl << std::endl;
216+
parlist->sublist("Reduced Dynamic Objective").set("State Rank", static_cast<int>(obj->getStateRank()));
217+
parlist->sublist("Reduced Dynamic Objective").set("Adjoint Rank", static_cast<int>(obj->getAdjointRank()));
218+
parlist->sublist("Reduced Dynamic Objective").set("State Sensitivity Rank", static_cast<int>(obj->getStateSensitivityRank()));
219+
220+
zdiff->set(*z); zdiff->axpy(static_cast<RealT>(-1),*zprev);
221+
zerr = zdiff->norm();
222+
*outStream << std::endl << "Control Difference: "
223+
<< zerr << std::endl << std::endl;
224+
if (zerr < ztol && algo->getState()->gnorm < static_cast<RealT>(1e-8)) break;
225+
226+
myCost *= static_cast<RealT>(2e0);
227+
gtol *= static_cast<RealT>(1e-1); gtol = std::max(gtol,static_cast<RealT>(1e-10));
228+
wts = {stateCost, myCost};
229+
obj_k = ROL::makePtr<PDE_Objective<RealT>>(qoi_vec,wts,dyn_con->getAssembler());
230+
dyn_obj = ROL::makePtr<LTI_Objective<RealT>>(*parlist,obj_k,false);
231+
obj = ROL::makePtr<ROL::ReducedDynamicObjective<RealT>>(dyn_obj, dyn_con, u0, zk, ck, timeStamp, rpl, outStream);
232+
}
233+
234+
/*************************************************************************/
235+
/***************** OUTPUT RESULTS ****************************************/
236+
/*************************************************************************/
237+
std::clock_t timer_print = std::clock();
238+
// Output control to file
239+
if ( myRank == 0 ) {
240+
ROL::Ptr<std::vector<RealT>> zn;
241+
std::ofstream zfile;
242+
zfile.open("control.txt");
243+
zfile << std::scientific << std::setprecision(15);
244+
for (int n = 0; n < nt; ++n) {
245+
zn = ROL::dynamicPtrCast<PDE_OptVector<RealT>>(z->get(n))->getParameter()->getVector();
246+
for (int i = 0; i < controlDim; ++i) {
247+
zfile << std::right << std::setw(25) << (*zn)[i];
248+
}
249+
zfile << std::endl;
250+
}
251+
zfile.close();
252+
}
253+
// Output state to file
254+
uo->set(*u0); un->zero();
255+
for (int k = 1; k < nt; ++k) {
256+
// Print previous state to file
257+
std::stringstream ufile;
258+
ufile << "state." << k-1 << ".txt";
259+
dyn_con->outputTpetraVector(uo_ptr, ufile.str());
260+
// Advance time stepper
261+
dyn_con->solve(*ck, *uo, *un, *z->get(k), timeStamp[k]);
262+
uo->set(*un);
263+
}
264+
// Print previous state to file
265+
std::stringstream ufile;
266+
ufile << "state." << nt-1 << ".txt";
267+
dyn_con->outputTpetraVector(uo_ptr, ufile.str());
268+
*outStream << "Output time: "
269+
<< static_cast<RealT>(std::clock()-timer_print)/static_cast<RealT>(CLOCKS_PER_SEC)
270+
<< " seconds." << std::endl << std::endl;
271+
}
272+
catch (std::logic_error& err) {
273+
*outStream << err.what() << "\n";
274+
errorFlag = -1000;
275+
}; // end try
276+
277+
if (errorFlag != 0)
278+
std::cout << "End Result: TEST FAILED\n";
279+
else
280+
std::cout << "End Result: TEST PASSED\n";
281+
282+
return 0;
283+
}

0 commit comments

Comments
 (0)