Skip to content

Commit

Permalink
Merge branch 'master' into checkstyle_parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
mathbagu committed Nov 4, 2017
2 parents 16812a0 + 849b8f7 commit 41a2698
Show file tree
Hide file tree
Showing 10 changed files with 436 additions and 286 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -16,7 +16,7 @@ install:

script:
- cd ${TRAVIS_BUILD_DIR}
- mvn clean test jacoco:report coveralls:report
- mvn clean verify jacoco:report coveralls:report

addons:
ssh_known_hosts: sftp.dc0.gpaas.net
Expand Down

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions eurostag-step-up-transformer/pom.xml
Expand Up @@ -62,6 +62,11 @@
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-iidm-impl</artifactId>
Expand Down
Expand Up @@ -7,43 +7,66 @@
package eu.itesla_project.iidm.ddb.eurostag;

import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
class EurostagDDB {

private static final Logger LOGGER = LoggerFactory.getLogger(EurostagDDB.class);

private final Map<String, Path> generators = new HashMap<>();

EurostagDDB(List<Path> ddbDirs) throws IOException {
for (Path ddbDir : ddbDirs) {
ddbDir = readSymbolicLink(ddbDir);
if (!Files.exists(ddbDir) && !Files.isDirectory(ddbDir)) {
throw new IllegalArgumentException(ddbDir + " must exist and be a dir");
}
Files.walkFileTree(ddbDir, new SimpleFileVisitor<Path>() {
Files.walkFileTree(ddbDir, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (Files.isRegularFile(file) && file.toString().endsWith(".tg")) {
String fileName = file.getFileName().toString();
generators.put(fileName.substring(0, fileName.length() - 3), file);
String fileName = file.getFileName().toString();
Path tmpfile = readSymbolicLink(file);
if (Files.isDirectory(tmpfile)) {
Files.walkFileTree(tmpfile, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, this);
} else if (Files.isRegularFile(tmpfile) && fileName.endsWith(".tg")) {
String key = fileName.substring(0, fileName.length() - 3);
if (generators.containsKey(key)) {
LOGGER.warn("the processing has detected that the file {} is present in {} and {}", fileName, tmpfile, generators.get(key));
}
generators.put(key, tmpfile);
}
return super.visitFile(file, attrs);
}
});
}
}

Path findGenerator(String idDdb) throws IOException {
Path findGenerator(String idDdb) {
return generators.get(idDdb);
}

private static Path readSymbolicLink(Path link) throws IOException {
Path path = link;
while (Files.isSymbolicLink(path)) {
path = Files.readSymbolicLink(path);
}
return path;
}

}
@@ -1,15 +1,13 @@
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* Copyright (c) 2017, 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/.
*/
package eu.itesla_project.iidm.ddb.eurostag;

import com.powsybl.computation.ComputationManager;
import eu.itesla_project.iidm.ddb.eurostag.model.PowerFlow;
import eu.itesla_project.iidm.ddb.eurostag.model.StateVariable;
import eu.itesla_project.iidm.ddb.eurostag.model.TransformerModel;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.ReactiveCapabilityCurve.Point;
import com.powsybl.iidm.network.util.Identifiables;
Expand All @@ -18,6 +16,9 @@
import com.powsybl.loadflow.LoadFlowFactory;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.loadflow.LoadFlowResult;
import eu.itesla_project.iidm.ddb.eurostag.model.PowerFlow;
import eu.itesla_project.iidm.ddb.eurostag.model.StateVariable;
import eu.itesla_project.iidm.ddb.eurostag.model.TransformerModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -39,7 +40,7 @@ public class EurostagStepUpTransformerInserter {

private final static float SB = 100;
private final static float ACCEPTABLE_VOLTAGE_DIFF = 0.1f;
private final static float INFINITE_REACTIVE_LIMIT = 9999f;
private final static float INFINITE_REACTIVE_LIMIT = 99999f;

public enum InsertionStatus {
OK("ok"),
Expand Down Expand Up @@ -301,7 +302,7 @@ private static void fillGeneratorState(Generator g, StateVariable sv) {
}

private static Generator moveGenerator(Generator srcGen, StateVariable srcSv, VoltageLevel destVl, Bus destBus, boolean connected,
Function<StateVariable, StateVariable> fct, EurostagStepUpTransformerConfig config) {
Function<StateVariable, StateVariable> fct, EurostagStepUpTransformerConfig config, TwoWindingsTransformer twt) {

fillGeneratorState(srcGen, srcSv);

Expand Down Expand Up @@ -367,6 +368,17 @@ private static Generator moveGenerator(Generator srcGen, StateVariable srcSv, Vo
float newP = (float) -fct.apply(new StateVariable(-point.getP(), 0, srcSv.u, srcSv.theta)).p;
float newMinQ = config.isNoReactiveLimits() ? -INFINITE_REACTIVE_LIMIT : (float) -fct.apply(new StateVariable(srcSv.p, -point.getMinQ(), srcSv.u, srcSv.theta)).q;
float newMaxQ = config.isNoReactiveLimits() ? INFINITE_REACTIVE_LIMIT : (float) -fct.apply(new StateVariable(srcSv.p, -point.getMaxQ(), srcSv.u, srcSv.theta)).q;

//test if the step-up transformer impedance is compatible with the reactive limit bounds: the maximun nominal power with a very high
//short-circuit power should be higher than the reactive bounds. If not, remove the bounds
float sMax = computeMaxRate(twt);
if ((sMax < Math.abs(newMinQ)) || (sMax < Math.abs(newMaxQ))) {
LOGGER.warn("Infinite limit mode activated for '{}': either abs({}) or abs({}) higher than {} (maximum nominal power with a short-circuit power of 40%)",
lvGen.getId(), newMinQ, newMaxQ, sMax);
newMinQ = -INFINITE_REACTIVE_LIMIT;
newMaxQ = INFINITE_REACTIVE_LIMIT;
}

LOGGER.trace("Resizing reactive limits of '{}': [{}, {}] -> [{}, {}]",
lvGen.getId(), point.getMinQ(), point.getMaxQ(), newMinQ, newMaxQ);
rcca.beginPoint()
Expand Down Expand Up @@ -455,13 +467,27 @@ public static InsertionStatus insert(Generator hvGen, TG tg, IdDictionary auxDic
Function<StateVariable, StateVariable> fct = sv -> toLvGenPf(transformerModel, sv, hvAuxPf, lvAuxPf);

StateVariable hvGenSv = new StateVariable();
moveGenerator(hvGen, hvGenSv, lvVl, lvBus, hvGenBus != null, fct, config);
moveGenerator(hvGen, hvGenSv, lvVl, lvBus, hvGenBus != null, fct, config, twt);

stateBefore.injections.put(twt.getId(), new PowerFlow((float) (hvGenSv.p + hvAuxPf.p), (float) (hvGenSv.q + hvAuxPf.q)));

return InsertionStatus.OK;
}

/**
* Compute a reasonable maximum nominal power ('rate') for a TwoWindingsTransformer
* with a very high short-circuit power of 40%
*
* @param twt two winding transformer
* @return maximum nominal power
*/
private static float computeMaxRate(TwoWindingsTransformer twt) {
Objects.requireNonNull(twt);
VoltageLevel u2 = twt.getTerminal2().getVoltageLevel();
float z = SV.getX(twt);
return 0.4f * (float) Math.pow(u2.getNominalV(), 2) / z;
}

public static InsertionStatus insert(Generator g, Path ddbFile, IdDictionary auxDict, EurostagStepUpTransformerConfig config, StateBefore stateBefore) throws IOException {
if (!Files.exists(ddbFile) && !Files.isRegularFile(ddbFile)) {
throw new IllegalArgumentException(ddbFile + " must exist and be a file");
Expand Down Expand Up @@ -612,7 +638,7 @@ public void visitThreeWindingsTransformer(ThreeWindingsTransformer transformer,
boolean connected = twt.getTerminal1().isConnected() && twt.getTerminal2().isConnected() && lvGen.getTerminal().isConnected();

StateVariable lvGenSv = new StateVariable();
moveGenerator(lvGen, lvGenSv, hvVl, hvBus, connected, fct, config);
moveGenerator(lvGen, lvGenSv, hvVl, hvBus, connected, fct, config, twt);
}

for (Load aux : auxLs) {
Expand Down
@@ -0,0 +1,76 @@
package eu.itesla_project.iidm.ddb.eurostag;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;

import org.junit.Test;

import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;

public class EurostagDDBTest {

@Test
public void testEurostagDDB() throws IOException {
try (FileSystem fs = Jimfs.newFileSystem(Configuration.unix())) {
Path folder1 = Files.createDirectory(fs.getPath("/folder1"));
Path folder2 = Files.createDirectory(fs.getPath("/folder2"));
Path folder3 = Files.createDirectory(fs.getPath("/folder3"));

Path generator1 = Files.createFile(folder1.resolve("generator1.tg"));
Path generator2 = Files.createFile(folder1.resolve("generator2.tg"));

Files.createFile(folder2.resolve("generator3.tg.bck"));
Path link = Files.createSymbolicLink(folder2.resolve("folder3"), folder3);

Path generator4 = Files.createFile(link.resolve("generator4.tg"));
Path dataFile = Files.createFile(folder3.resolve("generator.data"));
Files.createSymbolicLink(folder3.resolve("generator5.tg"), dataFile);

EurostagDDB eurostagDDB = new EurostagDDB(Arrays.asList(folder1, folder2));
assertEquals(generator1, eurostagDDB.findGenerator("generator1"));
assertEquals(generator2, eurostagDDB.findGenerator("generator2"));
assertNull(eurostagDDB.findGenerator("generator3"));
assertEquals(generator4, eurostagDDB.findGenerator("generator4"));
assertEquals(dataFile, eurostagDDB.findGenerator("generator5"));
}
}

@Test
public void testLinkFiles() throws IOException {
try (FileSystem fs = Jimfs.newFileSystem(Configuration.unix())) {
Path folder = Files.createDirectory(fs.getPath("/tmp"));
Path dataFile = Files.createFile(folder.resolve("generator.data"));
Files.createSymbolicLink(folder.resolve("generator1.tg"), dataFile);
Files.createSymbolicLink(folder.resolve("generator2.tg"), dataFile);
Files.createSymbolicLink(folder.resolve("generator3.tg"), dataFile);
Path generator4 = Files.createFile(folder.resolve("generator4.tg"));

EurostagDDB eurostagDDB = new EurostagDDB(Collections.singletonList(folder));
assertEquals(dataFile, eurostagDDB.findGenerator("generator1"));
assertEquals(dataFile, eurostagDDB.findGenerator("generator2"));
assertEquals(dataFile, eurostagDDB.findGenerator("generator3"));
assertEquals(generator4, eurostagDDB.findGenerator("generator4"));
}
}

@Test
public void testLinkDirectory() throws IOException {
try (FileSystem fs = Jimfs.newFileSystem(Configuration.unix())) {
Path folder = Files.createDirectory(fs.getPath("/folder"));
Path file = Files.createFile(folder.resolve("generator.tg"));
Path linkFolder = Files.createSymbolicLink(fs.getPath("/work/folder.link"), folder);

EurostagDDB eurostagDDB = new EurostagDDB(Collections.singletonList(linkFolder));
assertEquals(file, eurostagDDB.findGenerator("generator"));
}
}

}
Expand Up @@ -20,6 +20,7 @@

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.*;

Expand Down Expand Up @@ -79,16 +80,17 @@ public void load(Network network, HistoDbClient histoDbClient) throws IOExceptio

public void write(DataSource dataSource, StringToIntMapper<AmplSubset> mapper) throws IOException {

try (TableFormatter formatter = new AmplDatTableFormatter(
new OutputStreamWriter(dataSource.newOutputStream(HISTO_LOADS_FILE_SUFFIX, TXT_EXT, false), StandardCharsets.UTF_8),
"loads historical data " + histoInterval,
INVALID_FLOAT_VALUE,
true,
LOCALE,
new Column("num"),
new Column("min p (MW)"),
new Column("max p (MW)"),
new Column("id"))) {
try (Writer writer = new OutputStreamWriter(dataSource.newOutputStream(HISTO_LOADS_FILE_SUFFIX, TXT_EXT, false), StandardCharsets.UTF_8);
TableFormatter formatter = new AmplDatTableFormatter(
writer,
"loads historical data " + histoInterval,
INVALID_FLOAT_VALUE,
true,
LOCALE,
new Column("num"),
new Column("min p (MW)"),
new Column("max p (MW)"),
new Column("id"))) {

for (Map.Entry<String, Range<Float>> e : loadLimits.entrySet()) {
String id = e.getKey();
Expand All @@ -110,16 +112,17 @@ public void write(DataSource dataSource, StringToIntMapper<AmplSubset> mapper) t
}
}

try (TableFormatter formatter = new AmplDatTableFormatter(
new OutputStreamWriter(dataSource.newOutputStream(HISTO_GENERATORS_FILE_SUFFIX, TXT_EXT, false), StandardCharsets.UTF_8),
"generators historical data " + histoInterval,
INVALID_FLOAT_VALUE,
true,
LOCALE,
new Column("num"),
new Column("min p (MW)"),
new Column("max p (MW)"),
new Column("id"))) {
try (Writer writer = new OutputStreamWriter(dataSource.newOutputStream(HISTO_GENERATORS_FILE_SUFFIX, TXT_EXT, false), StandardCharsets.UTF_8);
TableFormatter formatter = new AmplDatTableFormatter(
writer,
"generators historical data " + histoInterval,
INVALID_FLOAT_VALUE,
true,
LOCALE,
new Column("num"),
new Column("min p (MW)"),
new Column("max p (MW)"),
new Column("id"))) {

for (Map.Entry<String, Range<Float>> e : generatorLimits.entrySet()) {
String id = e.getKey();
Expand Down
Expand Up @@ -28,6 +28,7 @@

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -136,23 +137,24 @@ private static WCAEntity toEntity(HistoDbNetworkAttributeId attrId, Network netw
}

public void write() {
try (TableFormatter formatter = new AmplDatTableFormatter(
new OutputStreamWriter(dataSource.newOutputStream(SECURITY_RULES_FILE_SUFFIX, TXT_EXT, false), StandardCharsets.UTF_8),
"Security rules",
INVALID_FLOAT_VALUE,
true,
LOCALE,
new Column("inequality num"),
new Column("convex num"),
new Column("var type (1: P, 2: Q, 3: V)"),
new Column("entity type (1: branch, 2: load, 3: generator, 4: compensator shunt, 5: substation)"),
new Column("entity num"),
new Column("branch side (1 or 2, 0 if NA)"),
new Column("inequality coeff."),
new Column("constant value"),
new Column("contingency num"),
new Column("security index type"),
new Column("attribute set (0: active only, 1: active/reactive)"))) {
try (Writer writer = new OutputStreamWriter(dataSource.newOutputStream(SECURITY_RULES_FILE_SUFFIX, TXT_EXT, false), StandardCharsets.UTF_8);
TableFormatter formatter = new AmplDatTableFormatter(
writer,
"Security rules",
INVALID_FLOAT_VALUE,
true,
LOCALE,
new Column("inequality num"),
new Column("convex num"),
new Column("var type (1: P, 2: Q, 3: V)"),
new Column("entity type (1: branch, 2: load, 3: generator, 4: compensator shunt, 5: substation)"),
new Column("entity num"),
new Column("branch side (1 or 2, 0 if NA)"),
new Column("inequality coeff."),
new Column("constant value"),
new Column("contingency num"),
new Column("security index type"),
new Column("attribute set (0: active only, 1: active/reactive)"))) {

class Context {

Expand Down

0 comments on commit 41a2698

Please sign in to comment.