12 #include "../config/config.hpp"
18 #include "hiopAlgFilterIPM.hpp"
25 bool HiopOptimizationProblem::get_prob_sizes(
long long &n,
long long &m)
28 m =
problem.GetNumConstraints();
33 bool HiopOptimizationProblem::get_starting_point(
const long long &n,
double *x0)
35 MFEM_ASSERT(x_start != NULL && ntdofs_loc == x_start->Size(),
36 "Starting point is not set properly.");
38 memcpy(x0, x_start->GetData(), ntdofs_loc *
sizeof(double));
43 bool HiopOptimizationProblem::get_vars_info(
const long long &n,
44 double *xlow,
double *xupp,
45 NonlinearityType *type)
47 MFEM_ASSERT(n == ntdofs_glob,
"Global input mismatch.");
48 MFEM_ASSERT(
problem.GetBoundsVec_Lo() &&
problem.GetBoundsVec_Hi(),
49 "Solution bounds are not set!");
51 const int s = ntdofs_loc *
sizeof(double);
52 std::memcpy(xlow,
problem.GetBoundsVec_Lo()->GetData(),
s);
53 std::memcpy(xupp,
problem.GetBoundsVec_Hi()->GetData(),
s);
58 bool HiopOptimizationProblem::get_cons_info(
const long long &m,
59 double *clow,
double *cupp,
60 NonlinearityType *type)
62 MFEM_ASSERT(m == m_total,
"Global constraint size mismatch.");
67 csize =
problem.GetEqualityVec()->Size();
68 const int s = csize *
sizeof(double);
69 std::memcpy(clow,
problem.GetEqualityVec()->GetData(),
s);
70 std::memcpy(cupp,
problem.GetEqualityVec()->GetData(),
s);
74 const int s =
problem.GetInequalityVec_Lo()->Size() *
sizeof(double);
75 std::memcpy(clow + csize,
problem.GetInequalityVec_Lo()->GetData(),
s);
76 std::memcpy(cupp + csize,
problem.GetInequalityVec_Hi()->GetData(),
s);
82 bool HiopOptimizationProblem::eval_f(
const long long &n,
const double *x,
83 bool new_x,
double &obj_value)
85 MFEM_ASSERT(n == ntdofs_glob,
"Global input mismatch.");
87 if (new_x) { constr_info_is_current =
false; }
91 obj_value =
problem.CalcObjective(x_vec);
96 bool HiopOptimizationProblem::eval_grad_f(
const long long &n,
const double *x,
97 bool new_x,
double *gradf)
99 MFEM_ASSERT(n == ntdofs_glob,
"Global input mismatch.");
101 if (new_x) { constr_info_is_current =
false; }
103 Vector x_vec(ntdofs_loc), gradf_vec(ntdofs_loc);
105 problem.CalcObjectiveGrad(x_vec, gradf_vec);
106 std::memcpy(gradf, gradf_vec.
GetData(), ntdofs_loc *
sizeof(double));
111 bool HiopOptimizationProblem::eval_cons(
const long long &n,
const long long &m,
112 const long long &num_cons,
113 const long long *idx_cons,
114 const double *x,
bool new_x,
117 MFEM_ASSERT(n == ntdofs_glob,
"Global input mismatch.");
118 MFEM_ASSERT(m == m_total,
"Constraint size mismatch.");
119 MFEM_ASSERT(num_cons <= m,
"num_cons should be at most m = " << m);
121 if (num_cons == 0) {
return true; }
123 if (new_x) { constr_info_is_current =
false; }
126 UpdateConstrValsGrads(x_vec);
128 for (
int c = 0; c < num_cons; c++)
130 MFEM_ASSERT(idx_cons[c] < m_total,
"Constraint index is out of bounds.");
131 cons[c] = constr_vals(idx_cons[c]);
137 bool HiopOptimizationProblem::eval_Jac_cons(
const long long &n,
139 const long long &num_cons,
140 const long long *idx_cons,
141 const double *x,
bool new_x,
144 MFEM_ASSERT(n == ntdofs_glob,
"Global input mismatch.");
145 MFEM_ASSERT(m == m_total,
"Constraint size mismatch.");
146 MFEM_ASSERT(num_cons <= m,
"num_cons should be at most m = " << m);
148 if (num_cons == 0) {
return true; }
150 if (new_x) { constr_info_is_current =
false; }
153 UpdateConstrValsGrads(x_vec);
155 for (
int c = 0; c < num_cons; c++)
157 MFEM_ASSERT(idx_cons[c] < m_total,
"Constraint index is out of bounds.");
158 for (
int j = 0; j < ntdofs_loc; j++)
161 Jac[c * ntdofs_loc + j] = constr_grads(idx_cons[c], j);
168 bool HiopOptimizationProblem::get_vecdistrib_info(
long long global_n,
173 MPI_Comm_size(comm, &nranks);
175 long long *sizes =
new long long[nranks];
176 MPI_Allgather(&ntdofs_loc, 1, MPI_LONG_LONG_INT, sizes, 1,
177 MPI_LONG_LONG_INT, comm);
179 for (
int r = 1; r <= nranks; r++)
181 cols[r] = sizes[r-1] + cols[r-1];
192 void HiopOptimizationProblem::UpdateConstrValsGrads(
const Vector x)
194 if (constr_info_is_current) {
return; }
202 cheight =
problem.GetC()->Height();
205 Vector vals_C(constr_vals.GetData(), cheight);
206 problem.GetC()->Mult(x, vals_C);
209 const Operator &oper_C =
problem.GetC()->GetGradient(x);
210 const DenseMatrix *grad_C =
dynamic_cast<const DenseMatrix *
>(&oper_C);
211 MFEM_VERIFY(grad_C,
"Hiop expects DenseMatrices as operator gradients.");
212 MFEM_ASSERT(grad_C->Height() == cheight && grad_C->Width() == ntdofs_loc,
213 "Incorrect dimensions of the C constraint gradient.");
214 for (
int i = 0; i < cheight; i++)
216 for (
int j = 0; j < ntdofs_loc; j++)
218 constr_grads(i, j) = (*grad_C)(i, j);
225 const int dheight =
problem.GetD()->Height();
228 Vector vals_D(constr_vals.GetData() + cheight, dheight);
229 problem.GetD()->Mult(x, vals_D);
232 const Operator &oper_D =
problem.GetD()->GetGradient(x);
233 const DenseMatrix *grad_D =
dynamic_cast<const DenseMatrix *
>(&oper_D);
234 MFEM_VERIFY(grad_D,
"Hiop expects DenseMatrices as operator gradients.");
235 MFEM_ASSERT(grad_D->Height() == dheight && grad_D->Width() == ntdofs_loc,
236 "Incorrect dimensions of the D constraint gradient.");
237 for (
int i = 0; i < dheight; i++)
239 for (
int j = 0; j < ntdofs_loc; j++)
241 constr_grads(i + cheight, j) = (*grad_D)(i, j);
246 constr_info_is_current =
true;
253 comm = MPI_COMM_WORLD;
254 int initialized, nret = MPI_Initialized(&initialized);
255 MFEM_ASSERT(MPI_SUCCESS == nret,
"Failure in calling MPI_Initialized!");
258 nret = MPI_Init(NULL, NULL);
259 MFEM_ASSERT(MPI_SUCCESS == nret,
"Failure in calling MPI_Init!");
291 "Unspecified OptimizationProblem that must be solved.");
295 hiop::hiopNlpDenseConstraints hiopInstance(*
hiop_problem);
297 hiopInstance.options->SetNumericValue(
"rel_tolerance",
rel_tol);
298 hiopInstance.options->SetNumericValue(
"tolerance",
abs_tol);
299 hiopInstance.options->SetIntegerValue(
"max_iter",
max_iter);
301 hiopInstance.options->SetStringValue(
"fixed_var",
"relax");
302 hiopInstance.options->SetNumericValue(
"fixed_var_tolerance", 1e-20);
303 hiopInstance.options->SetNumericValue(
"fixed_var_perturb", 1e-9);
306 hiopInstance.options->SetIntegerValue(
"verbosity_level",
print_level);
309 hiop::hiopAlgFilterIPM solver(&hiopInstance);
310 const hiop::hiopSolveStatus status = solver.run();
314 if (status != hiop::Solve_Success && status != hiop::Solve_Success_RelTol)
317 MFEM_WARNING(
"HIOP returned with a non-success status: " << status);
322 solver.getSolution(x.
GetData());
326 #endif // MFEM_USE_HIOP
virtual void SetOptimizationProblem(const OptimizationProblem &prob)
void setStartingPoint(const Vector &x0)
double * GetData() const
Return a pointer to the beginning of the Vector data.
virtual void Mult(const Vector &xt, Vector &x) const
Solves the optimization problem with xt as initial guess.
virtual ~HiopNlpOptimizer()
int height
Dimension of the output / number of rows in the matrix.
Abstract solver for OptimizationProblems.
const OptimizationProblem * problem
HiopOptimizationProblem * hiop_problem
int width
Dimension of the input / number of columns in the matrix.
Internal class - adapts the OptimizationProblem class to HiOp's interface.