Skip to content

Commit

Permalink
clean
Browse files Browse the repository at this point in the history
Signed-off-by: Damien Jeandemange <[email protected]>
  • Loading branch information
jeandemanged committed Dec 16, 2024
1 parent 5e81640 commit b802754
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 166 deletions.
206 changes: 101 additions & 105 deletions src/main/java/com/powsybl/openloadflow/knitro/solver/KnitroSolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public List<Double> getUpperBounds() {
/**
* Handles initialization of the state vector.
*/
public class StateInitializer {
public static class StateInitializer {
private final List<Double> initialState;

public StateInitializer(LfNetwork lfNetwork, EquationSystem<AcVariableType, AcEquationType> equationSystem,
Expand All @@ -178,102 +178,6 @@ public List<Double> getInitialState() {
}
}

/**
* Adds constraints to the Knitro problem, classifying them as linear or non-linear.
*
* @param knitroProblem The Knitro problem to which constraints are added.
* @param sortedEquationsToSolve A list of equations to solve.
* @param solverUtils Utils for solving external non-linear equations.
* @param listNonLinearConsts A list to store ids of non-linear constraints.
*/
public void addLinearConstraints(KnitroProblem knitroProblem,
List<Equation<AcVariableType, AcEquationType>> sortedEquationsToSolve,
NonLinearExternalSolverUtils solverUtils, List<Integer> listNonLinearConsts) {

int numConst = sortedEquationsToSolve.size();

for (int equationId = 0; equationId < numConst; equationId++) {
addConstraint(equationId, knitroProblem, sortedEquationsToSolve, solverUtils, listNonLinearConsts);
}
}

/**
* Adds a specific constraint to the Knitro problem, classifying it as linear or non-linear.
*
* @param equationId The id of the equation.
* @param knitroProblem The Knitro problem to which the constraint is added.
* @param sortedEquationsToSolve A list of equations to solve.
* @param solverUtils Utils for solving external non-linear equations.
* @param listNonLinearConsts A list to store ids of non-linear constraints.
*/
public void addConstraint(int equationId, KnitroProblem knitroProblem, List<Equation<AcVariableType, AcEquationType>> sortedEquationsToSolve, NonLinearExternalSolverUtils solverUtils, List<Integer> listNonLinearConsts) {
Equation<AcVariableType, AcEquationType> equation = sortedEquationsToSolve.get(equationId);
AcEquationType typeEq = equation.getType();
List<EquationTerm<AcVariableType, AcEquationType>> terms = equation.getTerms();

if (NonLinearExternalSolverUtils.isLinear(typeEq, terms)) {
try {
List<Integer> listVar = solverUtils.getLinearConstraint(typeEq, terms).getListIdVar();

List<Double> listCoef = solverUtils.getLinearConstraint(typeEq, terms).getListCoef();

for (int i = 0; i < listVar.size(); i++) {
knitroProblem.addConstraintLinearPart(equationId, listVar.get(i), listCoef.get(i));
}
LOGGER.trace("Adding linear constraint n° {} of type {}", equationId, typeEq);
} catch (UnsupportedOperationException e) {
throw new PowsyblException(e);
}
} else {
// ----- Non-linear constraints -----
listNonLinearConsts.add(equationId); // Add constraint number to list of non-linear constraints
}
}

/**
* Configures the Jacobian matrix for the Knitro problem, using either a dense or sparse representation.
*
* @param knitroProblem The Knitro problem instance.
* @param lfNetwork The PowSyBl network.
* @param jacobianMatrix The PowSyBl Jacobian matrix.
* @param sortedEquationsToSolve The list of equations to solve.
* @param listNonLinearConsts The list of non-linear constraint ids.
* @param listNonZerosCtsDense Dense non-zero constraints.
* @param listNonZerosVarsDense Dense non-zero variables.
* @param listNonZerosCtsSparse Sparse non-zero constraints.
* @param listNonZerosVarsSparse Sparse non-zero variables.
* @throws KNException If an error occurs in Knitro operations.
*/
public void setJacobianMatrix(KnitroProblem knitroProblem, LfNetwork lfNetwork, JacobianMatrix<AcVariableType, AcEquationType> jacobianMatrix,
List<Equation<AcVariableType, AcEquationType>> sortedEquationsToSolve, List<Integer> listNonLinearConsts,
List<Integer> listNonZerosCtsDense, List<Integer> listNonZerosVarsDense,
List<Integer> listNonZerosCtsSparse, List<Integer> listNonZerosVarsSparse) throws KNException {

int numVar = equationSystem.getIndex().getSortedVariablesToFind().size();
if (knitroParameters.getGradientComputationMode() == 1) { // User routine to compute the Jacobian
if (knitroParameters.getGradientUserRoutine() == 1) {
// Dense method: all non-linear constraints are considered as a function of all variables.
buildDenseJacobianMatrix(numVar, listNonLinearConsts, listNonZerosCtsDense, listNonZerosVarsDense);
knitroProblem.setJacNnzPattern(listNonZerosCtsDense, listNonZerosVarsDense);
} else if (knitroParameters.getGradientUserRoutine() == 2) {
// Sparse method: compute Jacobian only for variables the constraints depend on.
buildSparseJacobianMatrix(sortedEquationsToSolve, listNonLinearConsts, listNonZerosCtsSparse, listNonZerosVarsSparse);
knitroProblem.setJacNnzPattern(listNonZerosCtsSparse, listNonZerosVarsSparse);
}
// Set the callback for gradient evaluations if the user directly passes the Jacobian to the solver.
knitroProblem.setGradEvalCallback(new KnitroProblem.CallbackEvalG(
jacobianMatrix,
listNonZerosCtsDense,
listNonZerosVarsDense,
listNonZerosCtsSparse,
listNonZerosVarsSparse,
lfNetwork,
equationSystem,
knitroParameters
));
}
}

public void buildDenseJacobianMatrix(int numVar, List<Integer> listNonLinearConsts, List<Integer> listNonZerosCtsDense, List<Integer> listNonZerosVarsDense) {
for (Integer idCt : listNonLinearConsts) {
for (int i = 0; i < numVar; i++) {
Expand All @@ -298,7 +202,7 @@ public void buildSparseJacobianMatrix(List<Equation<AcVariableType, AcEquationTy
List<Integer> listNonZerosVarsCurrentCt = new ArrayList<>(); //list of variables involved in current constraint

for (EquationTerm<AcVariableType, AcEquationType> term : terms) {
for (Variable variable : term.getVariables()) {
for (Variable<AcVariableType> variable : term.getVariables()) {
listNonZerosVarsCurrentCt.add(variable.getRow());
}
}
Expand All @@ -315,7 +219,7 @@ private final class KnitroProblem extends KNProblem {
* Callback function to evaluate non-linear parts of the objective and of constraints
*/

private final class CallbackEvalFC extends KNEvalFCCallback {
private static final class CallbackEvalFC extends KNEvalFCCallback {

private final List<Equation<AcVariableType, AcEquationType>> sortedEquationsToSolve;
private final List<Integer> listNonLinearConsts;
Expand Down Expand Up @@ -347,7 +251,7 @@ public void evaluateFC(final List<Double> x, final List<Double> obj, final List<
throw new IllegalArgumentException("Equation of type " + typeEq + " is linear, and should be considered in the main function of Knitro, not in the callback function");
} else {
// we evaluate the equation with respect to the current state
for (EquationTerm term : equation.getTerms()) {
for (EquationTerm<AcVariableType, AcEquationType> term : equation.getTerms()) {
term.setStateVector(currentState);
if (term.isActive()) {
valueConst += term.eval();
Expand Down Expand Up @@ -468,7 +372,7 @@ public void evaluateH(final List<Double> x, final double sigma, final List<Doubl
* - definition of non-linear constraints, evaluated in the callback function
* - definition of the Jacobian matrix passed to Knitro to solve the problem
*/
private KnitroProblem(LfNetwork lfNetwork, EquationSystem<AcVariableType, AcEquationType> equationSystem, TargetVector targetVector, VoltageInitializer voltageInitializer, JacobianMatrix<AcVariableType, AcEquationType> jacobianMatrix) throws KNException {
private KnitroProblem(LfNetwork lfNetwork, EquationSystem<AcVariableType, AcEquationType> equationSystem, TargetVector<AcVariableType, AcEquationType> targetVector, VoltageInitializer voltageInitializer, JacobianMatrix<AcVariableType, AcEquationType> jacobianMatrix) throws KNException {

// =============== Variables ===============
// Defining variables
Expand Down Expand Up @@ -502,7 +406,7 @@ private KnitroProblem(LfNetwork lfNetwork, EquationSystem<AcVariableType, AcEqua

// ----- Linear constraints -----
NonLinearExternalSolverUtils solverUtils = new NonLinearExternalSolverUtils();
addLinearConstraints(this, sortedEquationsToSolve, solverUtils, listNonLinearConsts); // add linear constraints and fill the list of non-linear constraints
addLinearConstraints(sortedEquationsToSolve, solverUtils, listNonLinearConsts); // add linear constraints and fill the list of non-linear constraints

// ----- Non-linear constraints -----
// Callback
Expand All @@ -526,10 +430,102 @@ private KnitroProblem(LfNetwork lfNetwork, EquationSystem<AcVariableType, AcEqua
List<Integer> listNonZerosCtsSparse = new ArrayList<>();
List<Integer> listNonZerosVarsSparse = new ArrayList<>();

setJacobianMatrix(this, lfNetwork, jacobianMatrix, sortedEquationsToSolve, listNonLinearConsts,
setJacobianMatrix(lfNetwork, jacobianMatrix, sortedEquationsToSolve, listNonLinearConsts,
listNonZerosCtsDense, listNonZerosVarsDense,
listNonZerosCtsSparse, listNonZerosVarsSparse);
}

/**
* Adds constraints to the Knitro problem, classifying them as linear or non-linear.
*
* @param sortedEquationsToSolve A list of equations to solve.
* @param solverUtils Utils for solving external non-linear equations.
* @param listNonLinearConsts A list to store ids of non-linear constraints.
*/
private void addLinearConstraints(List<Equation<AcVariableType, AcEquationType>> sortedEquationsToSolve,
NonLinearExternalSolverUtils solverUtils, List<Integer> listNonLinearConsts) {

int numConst = sortedEquationsToSolve.size();

for (int equationId = 0; equationId < numConst; equationId++) {
addConstraint(equationId, sortedEquationsToSolve, solverUtils, listNonLinearConsts);
}
}

/**
* Adds a specific constraint to the Knitro problem, classifying it as linear or non-linear.
*
* @param equationId The id of the equation.
* @param sortedEquationsToSolve A list of equations to solve.
* @param solverUtils Utils for solving external non-linear equations.
* @param listNonLinearConsts A list to store ids of non-linear constraints.
*/
private void addConstraint(int equationId, List<Equation<AcVariableType, AcEquationType>> sortedEquationsToSolve, NonLinearExternalSolverUtils solverUtils, List<Integer> listNonLinearConsts) {
Equation<AcVariableType, AcEquationType> equation = sortedEquationsToSolve.get(equationId);
AcEquationType typeEq = equation.getType();
List<EquationTerm<AcVariableType, AcEquationType>> terms = equation.getTerms();

if (NonLinearExternalSolverUtils.isLinear(typeEq, terms)) {
try {
List<Integer> listVar = solverUtils.getLinearConstraint(typeEq, terms).listIdVar();

List<Double> listCoef = solverUtils.getLinearConstraint(typeEq, terms).listCoef();

for (int i = 0; i < listVar.size(); i++) {
this.addConstraintLinearPart(equationId, listVar.get(i), listCoef.get(i));
}
LOGGER.trace("Adding linear constraint n° {} of type {}", equationId, typeEq);
} catch (UnsupportedOperationException e) {
throw new PowsyblException(e);
}
} else {
// ----- Non-linear constraints -----
listNonLinearConsts.add(equationId); // Add constraint number to list of non-linear constraints
}
}

/**
* Configures the Jacobian matrix for the Knitro problem, using either a dense or sparse representation.
*
* @param lfNetwork The PowSyBl network.
* @param jacobianMatrix The PowSyBl Jacobian matrix.
* @param sortedEquationsToSolve The list of equations to solve.
* @param listNonLinearConsts The list of non-linear constraint ids.
* @param listNonZerosCtsDense Dense non-zero constraints.
* @param listNonZerosVarsDense Dense non-zero variables.
* @param listNonZerosCtsSparse Sparse non-zero constraints.
* @param listNonZerosVarsSparse Sparse non-zero variables.
* @throws KNException If an error occurs in Knitro operations.
*/
private void setJacobianMatrix(LfNetwork lfNetwork, JacobianMatrix<AcVariableType, AcEquationType> jacobianMatrix,
List<Equation<AcVariableType, AcEquationType>> sortedEquationsToSolve, List<Integer> listNonLinearConsts,
List<Integer> listNonZerosCtsDense, List<Integer> listNonZerosVarsDense,
List<Integer> listNonZerosCtsSparse, List<Integer> listNonZerosVarsSparse) throws KNException {

int numVar = equationSystem.getIndex().getSortedVariablesToFind().size();
if (knitroParameters.getGradientComputationMode() == 1) { // User routine to compute the Jacobian
if (knitroParameters.getGradientUserRoutine() == 1) {
// Dense method: all non-linear constraints are considered as a function of all variables.
buildDenseJacobianMatrix(numVar, listNonLinearConsts, listNonZerosCtsDense, listNonZerosVarsDense);
this.setJacNnzPattern(listNonZerosCtsDense, listNonZerosVarsDense);
} else if (knitroParameters.getGradientUserRoutine() == 2) {
// Sparse method: compute Jacobian only for variables the constraints depend on.
buildSparseJacobianMatrix(sortedEquationsToSolve, listNonLinearConsts, listNonZerosCtsSparse, listNonZerosVarsSparse);
this.setJacNnzPattern(listNonZerosCtsSparse, listNonZerosVarsSparse);
}
// Set the callback for gradient evaluations if the user directly passes the Jacobian to the solver.
this.setGradEvalCallback(new KnitroProblem.CallbackEvalG(
jacobianMatrix,
listNonZerosCtsDense,
listNonZerosVarsDense,
listNonZerosCtsSparse,
listNonZerosVarsSparse,
lfNetwork,
equationSystem,
knitroParameters
));
}
}
}

private void setSolverParameters(KNSolver solver) throws KNException {
Expand Down Expand Up @@ -562,7 +558,7 @@ public void close() {

@Override
public AcSolverResult run(VoltageInitializer voltageInitializer, ReportNode reportNode) {
int nbIter = -1;
int nbIter;
AcSolverStatus acStatus;
KnitroProblem instance;

Expand Down Expand Up @@ -610,7 +606,7 @@ public AcSolverResult run(VoltageInitializer voltageInitializer, ReportNode repo
if (acStatus == AcSolverStatus.CONVERGED || knitroParameters.isAlwaysUpdateNetwork()) {
equationSystem.getStateVector().set(toArray(solution.getX())); // update equation system
for (Equation<AcVariableType, AcEquationType> equation : equationSystem.getEquations()) { // update terms
for (EquationTerm term : equation.getTerms()) {
for (EquationTerm<AcVariableType, AcEquationType> term : equation.getTerms()) {
term.setStateVector(equationSystem.getStateVector());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public double getLowerVoltageBound() {

public KnitroSolverParameters setLowerVoltageBound(double lowerVoltageBound) {
if (lowerVoltageBound < 0) {
throw new IllegalArgumentException("Realistic voltage bounds must strictly greater then 0");
throw new IllegalArgumentException("Realistic voltage bounds must strictly greater than 0");
}
this.lowerVoltageBound = lowerVoltageBound;
return this;
Expand All @@ -93,10 +93,10 @@ public double getUpperVoltageBound() {

public KnitroSolverParameters setUpperVoltageBound(double upperVoltageBound) {
if (upperVoltageBound < 0) {
throw new IllegalArgumentException("Realistic voltage bounds must strictly greater then 0");
throw new IllegalArgumentException("Realistic voltage bounds must strictly greater than 0");
}
if (upperVoltageBound <= lowerVoltageBound) {
throw new IllegalArgumentException("Realistic voltage upper bounds must greater then lower bounds");
throw new IllegalArgumentException("Realistic voltage upper bounds must greater than lower bounds");
}
this.upperVoltageBound = upperVoltageBound;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,7 @@ public VarAndCoefList getLinearConstraint(AcEquationType typeEq, List<EquationTe
return varAndCoefList;
}

public class VarAndCoefList {
private List<Integer> listIdVar;
private List<Double> listCoef;

public VarAndCoefList(List<Integer> listIdVar, List<Double> listCoef) {
this.listIdVar = listIdVar;
this.listCoef = listCoef;
}

public List<Integer> getListIdVar() {
return listIdVar;
}

public List<Double> getListCoef() {
return listCoef;
}
public record VarAndCoefList(List<Integer> listIdVar, List<Double> listCoef) {
}

public VarAndCoefList addConstraintConstantTarget(List<EquationTerm<AcVariableType, AcEquationType>> terms) {
Expand Down
Loading

0 comments on commit b802754

Please sign in to comment.