LineSearchStateVectorScaling.java
/**
* Copyright (c) 2022, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openloadflow.ac.solver;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.openloadflow.ac.equations.AcEquationType;
import com.powsybl.openloadflow.ac.equations.AcVariableType;
import com.powsybl.openloadflow.equations.*;
import com.powsybl.openloadflow.util.Reports;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Objects;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public class LineSearchStateVectorScaling implements StateVectorScaling {
private static final Logger LOGGER = LoggerFactory.getLogger(LineSearchStateVectorScaling.class);
public static final int DEFAULT_MAX_ITERATION = 10;
public static final double DEFAULT_STEP_FOLD = 4d / 3;
private double[] lastDx;
private NewtonRaphsonStoppingCriteria.TestResult lastTestResult;
private final int maxIteration;
private final double stepFold;
public LineSearchStateVectorScaling(NewtonRaphsonStoppingCriteria.TestResult initialTestResult, int maxIteration, double stepFold) {
this.lastTestResult = Objects.requireNonNull(initialTestResult);
this.maxIteration = maxIteration;
this.stepFold = stepFold;
}
@Override
public StateVectorScalingMode getMode() {
return StateVectorScalingMode.LINE_SEARCH;
}
@Override
public void apply(double[] dx, EquationSystem<AcVariableType, AcEquationType> equationSystem, ReportNode reportNode) {
// just save dx vector
if (lastDx == null || lastDx.length != dx.length) {
lastDx = dx.clone();
} else {
System.arraycopy(dx, 0, lastDx, 0, dx.length);
}
}
@Override
public NewtonRaphsonStoppingCriteria.TestResult applyAfter(EquationSystem<AcVariableType, AcEquationType> equationSystem,
EquationVector<AcVariableType, AcEquationType> equationVector,
TargetVector<AcVariableType, AcEquationType> targetVector,
NewtonRaphsonStoppingCriteria stoppingCriteria,
NewtonRaphsonStoppingCriteria.TestResult testResult,
ReportNode reportNode) {
StateVector stateVector = equationSystem.getStateVector();
if (lastTestResult != null) {
double stepSize = 1;
NewtonRaphsonStoppingCriteria.TestResult currentTestResult = testResult;
double[] x = null;
int iteration = 1;
while (currentTestResult.getNorm() >= lastTestResult.getNorm() && iteration <= maxIteration) {
if (x == null) {
x = stateVector.get();
}
// x(i+1) = x(i) - dx
// x(i) = x(i+1) + dx
// x(i+1)' = x(i) - dx * mu
// x(i+1)' = x(i+1) + dx (1 - mu)
double[] newX = x.clone();
stepSize = 1 / Math.pow(stepFold, iteration);
Vectors.plus(newX, lastDx, 1 - stepSize);
stateVector.set(newX);
// equation vector has been updated
// recompute mismatch with new x
equationVector.minus(targetVector);
// and recompute new norm
currentTestResult = stoppingCriteria.test(equationVector.getArray(), equationSystem);
iteration++;
}
lastTestResult = currentTestResult;
LOGGER.debug("Step size: {}", stepSize);
if (reportNode != null) {
Reports.reportLineSearchStateVectorScaling(reportNode, stepSize);
}
}
return lastTestResult;
}
}