optimize_petsc.cpp
Go to the documentation of this file.
1 // Copyright 2019, University of Maryland and the MANGO development team.
2 //
3 // This file is part of MANGO.
4 //
5 // MANGO is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License as
7 // published by the Free Software Foundation, either version 3 of the
8 // License, or (at your option) any later version.
9 //
10 // MANGO is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with MANGO. If not, see
17 // <https://www.gnu.org/licenses/>.
18 
19 #include <iostream>
20 #include <stdexcept>
21 #include "mango.hpp"
22 #include "Solver.hpp"
23 #include "Package_petsc.hpp"
24 #ifdef MANGO_PETSC_AVAILABLE
25 #include <petsctao.h>
26 #endif
27 
28 static char help[]="";
29 
31 #ifdef MANGO_PETSC_AVAILABLE
32 
33  // The need for this line is described on https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Sys/PetscInitialize.html
34  PETSC_COMM_WORLD = MPI_COMM_SELF;
35 
36  int ierr;
37  ierr = PetscInitialize(&(solver->argc),&(solver->argv),(char *)0,help);
38  if (ierr) throw std::runtime_error("Error in PetscInitialize in mango::Package_petsc::optimize().");
39  ierr = PetscInitializeFortran();
40 
41  Tao my_tao;
42  TaoCreate(PETSC_COMM_SELF, &my_tao);
43 
44  Vec tao_state_vec;
45  VecCreateSeq(PETSC_COMM_SELF, solver->N_parameters, &tao_state_vec);
46 
47  // Set initial condition
48  double* temp_array;
49  VecGetArray(tao_state_vec, &temp_array);
50  memcpy(temp_array, solver->state_vector, solver->N_parameters * sizeof(double));
51  VecRestoreArray(tao_state_vec, &temp_array);
52  if (solver->verbose > 0) {
53  std::cout << "Here comes petsc vec for initial condition:" << std::endl;
54  VecView(tao_state_vec, PETSC_VIEWER_STDOUT_SELF);
55  }
56  TaoSetInitialVector(my_tao, tao_state_vec);
57 
58  if (solver->verbose > 0) std::cout << "PETSc has been initialized." << std::endl;
59 
60  switch (solver->algorithm) {
61  case PETSC_NM:
62  TaoSetType(my_tao, TAONM);
63  TaoSetObjectiveRoutine(my_tao, &mango_petsc_objective_function, (void*)solver);
64  break;
65  case PETSC_POUNDERS:
66  throw std::runtime_error("Should not get here! For the petsc_pounders algorithm, mango_optimize_least_squares_petsc should be called instead of mango_optimize_petsc.");
67  break;
68  default:
69  throw std::runtime_error("Should not get here!");
70  }
71 
72  TaoSetMaximumFunctionEvaluations(my_tao, (PetscInt) solver->max_function_and_gradient_evaluations);
73 
74  Vec lower_bounds_vec, upper_bounds_vec;
75  if (solver->bound_constraints_set) {
76  VecCreateSeq(PETSC_COMM_SELF, solver->N_parameters, &lower_bounds_vec);
77  VecCreateSeq(PETSC_COMM_SELF, solver->N_parameters, &upper_bounds_vec);
78 
79  for (int j=0; j<solver->N_parameters; j++) {
80  VecSetValue(lower_bounds_vec, j, solver->lower_bounds[j], INSERT_VALUES);
81  VecSetValue(upper_bounds_vec, j, solver->upper_bounds[j], INSERT_VALUES);
82  }
83  VecAssemblyBegin(lower_bounds_vec);
84  VecAssemblyBegin(upper_bounds_vec);
85  VecAssemblyEnd(lower_bounds_vec);
86  VecAssemblyEnd(upper_bounds_vec);
87 
88  TaoSetVariableBounds(my_tao, lower_bounds_vec, upper_bounds_vec);
89  }
90 
91  // TaoSetTolerances(my_tao, 1e-30, 1e-30, 1e-30);
92  TaoSetFromOptions(my_tao);
93  TaoSolve(my_tao);
94  if (solver->verbose > 0) TaoView(my_tao, PETSC_VIEWER_STDOUT_SELF);
95 
96  // Copy PETSc solution to the mango state vector.
97  VecGetArray(tao_state_vec, &temp_array);
98  memcpy(solver->state_vector, temp_array, solver->N_parameters * sizeof(double));
99  VecRestoreArray(tao_state_vec, &temp_array);
100 
101  if (solver->bound_constraints_set) {
102  VecDestroy(&lower_bounds_vec);
103  VecDestroy(&upper_bounds_vec);
104  }
105 
106  TaoDestroy(&my_tao);
107  VecDestroy(&tao_state_vec);
108 
109  PetscFinalize();
110 
111 #else
112  throw std::runtime_error("Error! A PETSc algorithm was requested, but Mango was compiled without PETSc support.");
113 #endif
114 
115 }
116 
117 //////////////////////////////////////////////////////////////////////////////////
118 //////////////////////////////////////////////////////////////////////////////////
119 
120 #ifdef MANGO_PETSC_AVAILABLE
121 PetscErrorCode mango::Package_petsc::mango_petsc_objective_function(Tao my_tao, Vec x, PetscReal* f_petsc, void* user_context) {
122 
123  const double* x_array;
124  VecGetArrayRead(x, &x_array);
125 
126  mango::Solver* solver = (mango::Solver*) user_context;
127 
128  bool failed;
129  double f;
130  solver->objective_function_wrapper(x_array, &f, &failed);
131 
132  if (failed) f = (PetscReal)mango::NUMBER_FOR_FAILED;
133 
134  VecRestoreArrayRead(x, &x_array);
135 
136  *f_petsc = f;
137 
138  return(0);
139 }
140 #endif
mango::Solver::lower_bounds
double * lower_bounds
Definition: Solver.hpp:54
mango::Solver::upper_bounds
double * upper_bounds
Definition: Solver.hpp:55
mango::Solver::verbose
int verbose
Definition: Solver.hpp:63
mango::PETSC_POUNDERS
@ PETSC_POUNDERS
Definition: mango.hpp:81
help
static char help[]
Definition: optimize_petsc.cpp:28
mango::Solver::argc
int argc
Definition: Solver.hpp:46
mango::Solver::objective_function_wrapper
virtual void objective_function_wrapper(const double *, double *, bool *)
Definition: objective_function_wrapper.cpp:27
Package_petsc.hpp
Solver.hpp
mango::Solver::state_vector
double * state_vector
Definition: Solver.hpp:58
mango::Solver::bound_constraints_set
bool bound_constraints_set
Definition: Solver.hpp:53
mango::Solver::argv
char ** argv
Definition: Solver.hpp:47
mango.hpp
mango::Package_petsc::optimize
void optimize(Solver *)
Definition: optimize_petsc.cpp:30
mango::Solver::N_parameters
int N_parameters
Definition: Solver.hpp:43
mango::NUMBER_FOR_FAILED
const double NUMBER_FOR_FAILED
A large finite number.
Definition: mango.hpp:52
mango::Solver::algorithm
algorithm_type algorithm
Definition: Solver.hpp:42
mango::Solver
Definition: Solver.hpp:31
mango::Solver::max_function_and_gradient_evaluations
int max_function_and_gradient_evaluations
Definition: Solver.hpp:48
mango::PETSC_NM
@ PETSC_NM
Definition: mango.hpp:80