Network.java
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* 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.iidm.network;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.datasource.*;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.computation.ComputationManager;
import com.powsybl.computation.local.LocalComputationManager;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* A power network model.
*
* <p>
* Characteristics
* </p>
*
* <table style="border: 1px solid black; border-collapse: collapse">
* <thead>
* <tr>
* <th style="border: 1px solid black">Attribute</th>
* <th style="border: 1px solid black">Type</th>
* <th style="border: 1px solid black">Unit</th>
* <th style="border: 1px solid black">Required</th>
* <th style="border: 1px solid black">Default value</th>
* <th style="border: 1px solid black">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td style="border: 1px solid black">Id</td>
* <td style="border: 1px solid black">String</td>
* <td style="border: 1px solid black"> - </td>
* <td style="border: 1px solid black">yes</td>
* <td style="border: 1px solid black"> - </td>
* <td style="border: 1px solid black">Unique identifier of the network</td>
* </tr>
* <tr>
* <td style="border: 1px solid black">Name</td>
* <td style="border: 1px solid black">String</td>
* <td style="border: 1px solid black">-</td>
* <td style="border: 1px solid black">yes</td>
* <td style="border: 1px solid black"> - </td>
* <td style="border: 1px solid black">Human-readable name of the network</td>
* </tr>
* <tr>
* <td style="border: 1px solid black">CaseDate</td>
* <td style="border: 1px solid black">DateTime</td>
* <td style="border: 1px solid black">-</td>
* <td style="border: 1px solid black">no</td>
* <td style="border: 1px solid black"> Now </td>
* <td style="border: 1px solid black">The date of the case</td>
* </tr>
* <tr>
* <td style="border: 1px solid black">ForecastDistance</td>
* <td style="border: 1px solid black">integer</td>
* <td style="border: 1px solid black">-</td>
* <td style="border: 1px solid black">no</td>
* <td style="border: 1px solid black"> 0 </td>
* <td style="border: 1px solid black">The number of minutes between the date of the case generation and the date of the case</td>
* </tr>
* </tbody>
* </table>
*
* To create a new empty network with default implementation:
*<pre>
* Network n = Network.create("test", "test");
*</pre>
*
* <p>The network is initially created with one variant identified by
* <code>VariantManagerConstants.INITIAL_VARIANT_ID</code>. {@link VariantManager} is
* responsible for variant management and is accessible from the network thanks
* to {@link #getVariantManager()}.
*
* <p>Instances of <code>Network</code> are not thread safe except for attributes
* depending of the variant (always specified in the javadoc) if
* {@link VariantManager#allowVariantMultiThreadAccess(boolean)} is set to true.
*
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
* @see NetworkFactory
* @see VariantManager
*/
public interface Network extends Container<Network> {
default Collection<Network> getSubnetworks() {
return Collections.emptyList();
}
default Network getSubnetwork(String id) {
return null;
}
/**
* Read a network from the specified file, trying to guess its format.
*
* @param file The file to be loaded.
* @param computationManager A computation manager which may be used by import post-processors
* @param config The import config, in particular definition of post processors
* @param parameters Import-specific parameters
* @param networkFactory Network factory
* @param loader Provides the list of available importers and post-processors
* @param reportNode The reportNode used for functional logs
* @return The loaded network
*/
static Network read(Path file, ComputationManager computationManager, ImportConfig config, Properties parameters, NetworkFactory networkFactory,
ImportersLoader loader, ReportNode reportNode) {
ReadOnlyDataSource dataSource = DataSource.fromPath(file);
Importer importer = Importer.find(dataSource, loader, computationManager, config);
if (importer != null) {
return importer.importData(dataSource, networkFactory, parameters, reportNode);
}
throw new PowsyblException(Importers.UNSUPPORTED_FILE_FORMAT_OR_INVALID_FILE);
}
static Network read(Path file, ComputationManager computationManager, ImportConfig config, Properties parameters,
ImportersLoader loader, ReportNode reportNode) {
return read(file, computationManager, config, parameters, NetworkFactory.findDefault(), loader, reportNode);
}
/**
* Read a network from the specified file, trying to guess its format.
*
* @param file The file to be loaded.
* @param computationManager A computation manager which may be used by import post-processors
* @param config The import config, in particular definition of post processors
* @param parameters Import-specific parameters
* @param loader Provides the list of available importers and post-processors
* @return The loaded network
*/
static Network read(Path file, ComputationManager computationManager, ImportConfig config, Properties parameters, ImportersLoader loader) {
return read(file, computationManager, config, parameters, loader, ReportNode.NO_OP);
}
/**
* Read a network from the specified file, trying to guess its format,
* and using importers and post processors defined as services.
*
* @param file The file to be loaded.
* @param computationManager A computation manager which may be used by import post-processors
* @param config The import config, in particular definition of post processors
* @param parameters Import-specific parameters
* @return The loaded network
*/
static Network read(Path file, ComputationManager computationManager, ImportConfig config, Properties parameters) {
return read(file, computationManager, config, parameters, new ImportersServiceLoader());
}
/**
* Read a network from the specified file, trying to guess its format,
* and using importers and post processors defined as services.
* Import will be performed using import configuration defined in default platform config,
* and with no importer-specific parameters.
* Post processors will use the default {@link LocalComputationManager}, as defined in
* default platform config.
*
* @param file The file to be loaded.
* @return The loaded network
*/
static Network read(Path file) {
return read(file, LocalComputationManager.getDefault(), ImportConfig.CACHE.get(), null);
}
/**
* Loads a network from the specified file path, see {@link #read(Path)}.
*
* @param file The file to be loaded.
* @return The loaded network
*/
static Network read(String file) {
return read(Paths.get(file));
}
/**
* Read a network from a raw input stream, trying to guess the format from the specified filename.
* Please note that the input stream must be from a simple file, not a zipped one.
*
* @param filename The name of the file to be imported.
* @param data The raw data from which the network should be loaded
* @param computationManager A computation manager which may be used by import post-processors
* @param config The import config, in particular definition of post processors
* @param parameters Import-specific parameters
* @param networkFactory Network factory
* @param loader Provides the list of available importers and post-processors
* @param reportNode The reportNode used for functional logs
* @return The loaded network
*/
static Network read(String filename, InputStream data, ComputationManager computationManager, ImportConfig config, Properties parameters, NetworkFactory networkFactory, ImportersLoader loader, ReportNode reportNode) {
ReadOnlyMemDataSource dataSource = new ReadOnlyMemDataSource(DataSourceUtil.getBaseName(filename));
dataSource.putData(filename, data);
Importer importer = Importer.find(dataSource, loader, computationManager, config);
if (importer != null) {
return importer.importData(dataSource, networkFactory, parameters, reportNode);
}
throw new PowsyblException(Importers.UNSUPPORTED_FILE_FORMAT_OR_INVALID_FILE);
}
/**
* Read a network from a raw input stream, trying to guess the format from the specified filename.
* Please note that the input stream must be from a simple file, not a zipped one.
*
* @param filename The name of the file to be imported.
* @param data The raw data from which the network should be loaded
* @param computationManager A computation manager which may be used by import post-processors
* @param config The import config, in particular definition of post processors
* @param parameters Import-specific parameters
* @param loader Provides the list of available importers and post-processors
* @param reportNode The reportNode used for functional logs
* @return The loaded network
*/
static Network read(String filename, InputStream data, ComputationManager computationManager, ImportConfig config, Properties parameters, ImportersLoader loader, ReportNode reportNode) {
return read(filename, data, computationManager, config, parameters, NetworkFactory.findDefault(), loader, reportNode);
}
/**
* Read a network from a raw input stream, trying to guess the format from the specified filename.
* Please note that the input stream must be from a simple file, not a zipped one.
*
* @param filename The name of the file to be imported.
* @param data The raw data from which the network should be loaded
* @param computationManager A computation manager which may be used by import post-processors
* @param config The import config, in particular definition of post processors
* @param parameters Import-specific parameters
* @param loader Provides the list of available importers and post-processors
* @return The loaded network
*/
static Network read(String filename, InputStream data, ComputationManager computationManager, ImportConfig config, Properties parameters, ImportersLoader loader) {
return read(filename, data, computationManager, config, parameters, loader, ReportNode.NO_OP);
}
/**
* Read a network from a raw input stream, trying to guess the format from the specified filename,
* and using importers and post processors defined as services.
* Please note that the input stream must be from a simple file, not a zipped one.
*
* @param filename The name of the file to be imported.
* @param data The raw data from which the network should be loaded
* @param computationManager A computation manager which may be used by import post-processors
* @param config The import config, in particular definition of post processors
* @param parameters Import-specific parameters
* @return The loaded network
*/
static Network read(String filename, InputStream data, ComputationManager computationManager, ImportConfig config, Properties parameters) {
return read(filename, data, computationManager, config, parameters, new ImportersServiceLoader());
}
/**
* Read a network from a raw input stream, trying to guess the format from the specified filename,
* and using importers and post processors defined as services.
* Import will be performed using import configuration defined in default platform config,
* and with no importer-specific parameters.
* Please note that the input stream must be from a simple file, not a zipped one.
*
* @param filename The name of the file to be imported.
* @param data The raw data from which the network should be loaded
* @param computationManager A computation manager which may be used by import post-processors
* @return The loaded network
*/
static Network read(String filename, InputStream data, ComputationManager computationManager) {
return read(filename, data, computationManager, ImportConfig.CACHE.get(), null);
}
/**
* Read a network from a raw input stream, trying to guess the format from the specified filename,
* and using importers and post processors defined as services.
* Import will be performed using import configuration defined in default platform config,
* and with no importer-specific parameters.
* Post processors will use the default {@link LocalComputationManager}, as defined in
* default platform config.
* Please note that the input stream must be from a simple file, not a zipped one.
*
* @param filename The name of the file to be imported.
* @param data The raw data from which the network should be loaded
* @return The loaded network
*/
static Network read(String filename, InputStream data) {
return read(filename, data, LocalComputationManager.getDefault());
}
/**
* Read a network from a raw input stream, trying to guess the format from the specified filename,
* and using importers and post processors defined as services.
* Import will be performed using import configuration defined in default platform config,
* and with no importer-specific parameters.
* Post processors will use the default {@link LocalComputationManager}, as defined in
* default platform config.
* Please note that the input stream must be from a simple file, not a zipped one.
*
* @param filename The name of the file to be imported.
* @param data The raw data from which the network should be loaded
* @param reportNode The reportNode used for functional logs
* @return The loaded network
*/
static Network read(String filename, InputStream data, ReportNode reportNode) {
return read(filename, data, LocalComputationManager.getDefault(), ImportConfig.CACHE.get(), null, new ImportersServiceLoader(), reportNode);
}
static Network read(ReadOnlyDataSource dataSource) {
return read(dataSource, null);
}
static Network read(ReadOnlyDataSource dataSource, Properties properties) {
return read(dataSource, properties, ReportNode.NO_OP);
}
static Network read(ReadOnlyDataSource dataSource, Properties parameters, ReportNode reportNode) {
return read(dataSource, LocalComputationManager.getDefault(), ImportConfig.load(), parameters, NetworkFactory.findDefault(),
new ImportersServiceLoader(), reportNode);
}
static Network read(ReadOnlyDataSource dataSource, ComputationManager computationManager, ImportConfig config, Properties parameters,
NetworkFactory networkFactory, ImportersLoader loader, ReportNode reportNode) {
Importer importer = Importer.find(dataSource, loader, computationManager, config);
if (importer != null) {
return importer.importData(dataSource, networkFactory, parameters, reportNode);
}
throw new PowsyblException(Importers.UNSUPPORTED_FILE_FORMAT_OR_INVALID_FILE);
}
static Network read(ReadOnlyDataSource... dataSources) {
return read(List.of(dataSources));
}
static Network read(Path... files) {
List<ReadOnlyDataSource> dataSources = Arrays.stream(Objects.requireNonNull(files)).map(DataSource::fromPath).collect(Collectors.toList());
return read(dataSources);
}
static Network read(List<ReadOnlyDataSource> dataSources) {
return read(dataSources, null);
}
static Network read(List<ReadOnlyDataSource> dataSources, Properties properties) {
return read(dataSources, properties, ReportNode.NO_OP);
}
static Network read(List<ReadOnlyDataSource> dataSources, Properties properties, ReportNode reportNode) {
Objects.requireNonNull(dataSources);
return read(new MultipleReadOnlyDataSource(dataSources), properties, reportNode);
}
static void readAll(Path dir, boolean parallel, ImportersLoader loader, ComputationManager computationManager, ImportConfig config, Properties parameters, Consumer<Network> consumer, Consumer<ReadOnlyDataSource> listener, NetworkFactory networkFactory, ReportNode reportNode) throws IOException, InterruptedException, ExecutionException {
if (!Files.isDirectory(dir)) {
throw new PowsyblException("Directory " + dir + " does not exist or is not a regular directory");
}
for (Importer importer : Importer.list(loader, computationManager, config)) {
Importers.importAll(dir, importer, parallel, parameters, consumer, listener, networkFactory, reportNode);
}
}
static void readAll(Path dir, boolean parallel, ImportersLoader loader, ComputationManager computationManager, ImportConfig config, Properties parameters, Consumer<Network> consumer, Consumer<ReadOnlyDataSource> listener, ReportNode reportNode) throws IOException, InterruptedException, ExecutionException {
readAll(dir, parallel, loader, computationManager, config, parameters, consumer, listener, NetworkFactory.findDefault(), reportNode);
}
static void readAll(Path dir, boolean parallel, ImportersLoader loader, ComputationManager computationManager, ImportConfig config, Properties parameters, Consumer<Network> consumer, Consumer<ReadOnlyDataSource> listener) throws IOException, InterruptedException, ExecutionException {
readAll(dir, parallel, loader, computationManager, config, parameters, consumer, listener, ReportNode.NO_OP);
}
static void readAll(Path dir, boolean parallel, ImportersLoader loader, ComputationManager computationManager, ImportConfig config, Consumer<Network> consumer, Consumer<ReadOnlyDataSource> listener) throws IOException, InterruptedException, ExecutionException {
readAll(dir, parallel, loader, computationManager, config, null, consumer, listener);
}
static void readAll(Path dir, boolean parallel, ComputationManager computationManager, ImportConfig config, Properties parameters, Consumer<Network> consumer, Consumer<ReadOnlyDataSource> listener) throws IOException, InterruptedException, ExecutionException {
readAll(dir, parallel, new ImportersServiceLoader(), computationManager, config, parameters, consumer, listener);
}
static void readAll(Path dir, boolean parallel, ComputationManager computationManager, ImportConfig config, Consumer<Network> consumer, Consumer<ReadOnlyDataSource> listener) throws IOException, InterruptedException, ExecutionException {
readAll(dir, parallel, new ImportersServiceLoader(), computationManager, config, consumer, listener);
}
static void readAll(Path dir, boolean parallel, ComputationManager computationManager, ImportConfig config, Consumer<Network> consumer) throws IOException, InterruptedException, ExecutionException {
readAll(dir, parallel, computationManager, config, consumer, null);
}
static void readAll(Path dir, boolean parallel, Consumer<Network> consumer) throws IOException, InterruptedException, ExecutionException {
readAll(dir, parallel, LocalComputationManager.getDefault(), ImportConfig.CACHE.get(), consumer);
}
static void readAll(Path dir, boolean parallel, Consumer<Network> consumer, Consumer<ReadOnlyDataSource> listener) throws IOException, InterruptedException, ExecutionException {
readAll(dir, parallel, LocalComputationManager.getDefault(), ImportConfig.CACHE.get(), consumer, listener);
}
static void readAll(Path dir, Consumer<Network> consumer) throws IOException, InterruptedException, ExecutionException {
readAll(dir, false, LocalComputationManager.getDefault(), ImportConfig.CACHE.get(), consumer);
}
default void update(ReadOnlyDataSource dataSource) {
update(dataSource, null);
}
default void update(ReadOnlyDataSource dataSource, Properties properties) {
update(dataSource, properties, ReportNode.NO_OP);
}
default void update(ReadOnlyDataSource dataSource, Properties parameters, ReportNode reportNode) {
update(dataSource, LocalComputationManager.getDefault(), ImportConfig.load(), parameters,
new ImportersServiceLoader(), reportNode);
}
default void update(ReadOnlyDataSource dataSource, ComputationManager computationManager, ImportConfig config, Properties parameters,
ImportersLoader loader, ReportNode reportNode) {
Importer importer = Importer.find(dataSource, loader, computationManager, config);
if (importer != null) {
importer.update(this, dataSource, parameters, reportNode);
} else {
throw new PowsyblException(Importers.UNSUPPORTED_FILE_FORMAT_OR_INVALID_FILE);
}
}
/**
* A global bus/breaker view of the network.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
interface BusBreakerView {
/**
* Get all buses.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
Iterable<Bus> getBuses();
/**
* Get all buses.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
Stream<Bus> getBusStream();
/**
* Get the bus count.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
int getBusCount();
/**
* Get all switches
*/
Iterable<Switch> getSwitches();
/**
* Get all switches.
*/
Stream<Switch> getSwitchStream();
/**
* Get the switch count.
*/
int getSwitchCount();
/**
* Get a Bus.
*/
default Bus getBus(String id) {
throw new PowsyblException("Method should be overridden in the current implementation");
}
}
/**
* A global bus view of the network.
*/
interface BusView {
/**
* Get all buses.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
Iterable<Bus> getBuses();
/**
* Get all buses.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
Stream<Bus> getBusStream();
/**
* Get a Bus.
*/
default Bus getBus(String id) {
throw new PowsyblException("Method should be overridden in the current implementation");
}
/**
* Get all connected components.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
Collection<Component> getConnectedComponents();
/**
* Get all synchronous components.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
Collection<Component> getSynchronousComponents();
}
/**
* Create an empty network using default implementation.
*
* @param id id of the network
* @param sourceFormat source format
* @return an empty network
*/
static Network create(String id, String sourceFormat) {
return NetworkFactory.findDefault().createNetwork(id, sourceFormat);
}
/**
* Create a network (using default implementation) as the result of the merge of the given networks. Each given
* network is represented as a subnetwork in the resulting network. As a result of that merge, the given networks
* are empty at the end of the call.
* Note that, as no id is given, the id of the network created is generated.
*
* @return the merged network with subnetworks inside.
*/
static Network merge(Network... networks) {
return NetworkFactory.findDefault().merge(networks);
}
/**
* Create a network (using default implementation) as the result of the merge of the given networks. Each given
* network is represented as a subnetwork in the resulting network. As a result of that merge, the given networks
* are empty at the end of the call.
*
* @param id id of the network to create
* @return the merged network with subnetworks inside.
*/
static Network merge(String id, Network... networks) {
return NetworkFactory.findDefault().merge(id, networks);
}
/**
* Just being able to name method create et not createNetwork. Create is not available in {@link NetworkFactory} for backward
* compatibility reason. To cleanup when {@link NetworkFactory#create(String, String)} will be removed.
*/
interface PrettyNetworkFactory {
Network create(String id, String sourceFormat);
}
/**
* Get network factory named {@code name}.
*
* @param name name of the {@link NetworkFactory}
* @return network factory with the given name
*/
static PrettyNetworkFactory with(String name) {
return (id, sourceFormat) -> NetworkFactory.find(name).createNetwork(id, sourceFormat);
}
/**
* Get the date that the network represents.
*/
ZonedDateTime getCaseDate();
/**
* Set the date that the network represents.
* @throws IllegalArgumentException if date is null.
*/
Network setCaseDate(ZonedDateTime date);
/**
* Get the forecast distance in minutes.
* <p>Example: 0 for a snapshot, 6*60 to 30*60 for a DACF.
*/
int getForecastDistance();
Network setForecastDistance(int forecastDistance);
/**
* Get the source format.
* @return the source format
*/
String getSourceFormat();
/**
* Get the variant manager of the network.
*/
VariantManager getVariantManager();
/**
* <p>Allows {@link ReportNodeContext} to be accessed simultaneously by different threads.</p>
* <p>When this option is activated, the reportNode context can have a different content
* for each thread.</p>
* <p>Note that to avoid memory leaks when in multi-thread configuration: </p>
* <ul>
* <li>each reportNode pushed in the ReportNodeContext should be popped in a "finally" section:
* <pre>
* {@code
* network.getReportNodeContext().pushReportNode(reportNode);
* try {
* // code that can throw an exception
* } finally {
* network.getReportNodeContext().popReportNode();
* }
* }
* </pre>
* </li>
* <li>the context should be set in mono-thread access when multi-threading policy is no more useful.</li>
* </ul>
* @param allow allow multi-thread access to the ReportNodeContext
*/
void allowReportNodeContextMultiThreadAccess(boolean allow);
/**
* Get the {@link ReportNodeContext} of the network.
*/
ReportNodeContext getReportNodeContext();
/**
* Get all countries.
*/
Set<Country> getCountries();
/**
* Get the country count.
*/
int getCountryCount();
/**
* Get all areaTypes.
*/
Iterable<String> getAreaTypes();
/**
* Get all areaTypes.
*/
Stream<String> getAreaTypeStream();
/**
* Get the areaType count.
*/
int getAreaTypeCount();
/**
* Get a builder to create a new area.
* @return a builder to create a new area
*/
AreaAdder newArea();
/**
* @return all existing areas, which may include several areas for each area type
*/
Iterable<Area> getAreas();
/**
* @return all existing areas, which may include several areas for each area type
*/
Stream<Area> getAreaStream();
/**
* Get an area.
* @param id the id or an alias of the area
*/
Area getArea(String id);
/**
* Get the area count.
*/
int getAreaCount();
/**
* Get a builder to create a new substation.
* @return a builder to create a new substation
*/
SubstationAdder newSubstation();
/**
* Get all substations.
*/
Iterable<Substation> getSubstations();
/**
* Get all substations.
*/
Stream<Substation> getSubstationStream();
/**
* Get the substation count.
*/
int getSubstationCount();
/**
* Get substation located in a specific county, TSO and marked with a list
* of geographical tag.
*
* @param country the country, if <code>null</code> there is no
* filtering on countries
* @param tsoId the id of the TSO, if <code>null</code> there is no
* filtering on TSOs
* @param geographicalTags a list a geographical tags
*/
Iterable<Substation> getSubstations(Country country, String tsoId, String... geographicalTags);
/**
* Get substation located in a specific county, TSO and marked with a list
* of geographical tag.
*
* @param country the country name, if empty string, the filtering will be on
* substations without country, if <code>null</code> there is no
* filtering on countries
* @param tsoId the id of the TSO, if <code>null</code> there is no
* filtering on TSOs
* @param geographicalTags a list a geographical tags
*/
Iterable<Substation> getSubstations(String country, String tsoId, String... geographicalTags);
/**
* Get a substation.
*
* @param id the id or an alias of the substation
*/
Substation getSubstation(String id);
/**
* Get a builder to create a new voltage level (without substation).
* Note: if this method is not implemented, it will create an intermediary fictitious {@link Substation}.
* @return a builder to create a new voltage level
*/
default VoltageLevelAdder newVoltageLevel() {
return newSubstation()
.setId("FICTITIOUS_SUBSTATION")
.setEnsureIdUnicity(true)
.setFictitious(true)
.add()
.newVoltageLevel();
}
/**
* Get all substation voltage levels.
*/
Iterable<VoltageLevel> getVoltageLevels();
/**
* Get all substation voltage levels.
*/
Stream<VoltageLevel> getVoltageLevelStream();
/**
* Get the voltage level count.
*/
int getVoltageLevelCount();
/**
* Get a substation voltage level.
*
* @param id the id or an alias of the substation voltage level
*/
VoltageLevel getVoltageLevel(String id);
/**
* Get a builder to create a new AC line.
* @return a builder to create a new line
*/
LineAdder newLine();
/**
* Get a builder to create a new AC line by copying an existing one.
* @return a builder to create a new line
*/
LineAdder newLine(Line line);
/**
* Get all AC lines.
*/
Iterable<Line> getLines();
/**
* Get all tie lines.
*/
Iterable<TieLine> getTieLines();
/**
* Get a branch
* @param branchId the id of the branch
*/
Branch getBranch(String branchId);
/**
* Get all branches
*/
Iterable<Branch> getBranches();
/**
* Get all branches
*/
Stream<Branch> getBranchStream();
/**
* Get the branch count.
*/
int getBranchCount();
/**
* Get all AC lines.
*/
Stream<Line> getLineStream();
/**
* Get all tie lines.
*/
Stream<TieLine> getTieLineStream();
/**
* Get the AC line count.
*/
int getLineCount();
/**
* Get the tie line count.
*/
int getTieLineCount();
/**
* Get a AC line.
*
* @param id the id or an alias of the AC line
*/
Line getLine(String id);
/**
* Get a tie line.
*
* @param id the id or an alias of the AC line
*/
TieLine getTieLine(String id);
/**
* Get a builder to create a new AC tie line.
* @return a builder to create a new AC tie line
*/
TieLineAdder newTieLine();
/**
* Get all two windings transformers.
*/
Iterable<TwoWindingsTransformer> getTwoWindingsTransformers();
/**
* Get all two windings transformers.
*/
Stream<TwoWindingsTransformer> getTwoWindingsTransformerStream();
/**
* Get the two windings transformer count.
*/
int getTwoWindingsTransformerCount();
/**
* Get a two windings transformer.
*
* @param id the id or an alias of the two windings transformer
*/
TwoWindingsTransformer getTwoWindingsTransformer(String id);
/**
* Get all 3 windings transformers.
*/
Iterable<ThreeWindingsTransformer> getThreeWindingsTransformers();
/**
* Get all 3 windings transformers.
*/
Stream<ThreeWindingsTransformer> getThreeWindingsTransformerStream();
/**
* Get the 3 windings transformer count.
*/
int getThreeWindingsTransformerCount();
/**
* Get a 3 windings transformer.
*
* @param id the id or an alias of the 3 windings transformer
*/
ThreeWindingsTransformer getThreeWindingsTransformer(String id);
/**
* Get all overload management systems.
*/
Iterable<OverloadManagementSystem> getOverloadManagementSystems();
/**
* Get all overload management systems.
*/
Stream<OverloadManagementSystem> getOverloadManagementSystemStream();
/**
* Get the overload management system count.
*/
int getOverloadManagementSystemCount();
/**
* Get an overload management system.
*
* @param id the id or an alias of the overload management system
*/
OverloadManagementSystem getOverloadManagementSystem(String id);
/**
* Get all generators.
*/
Iterable<Generator> getGenerators();
/**
* Get all generators.
*/
Stream<Generator> getGeneratorStream();
/**
* Get the generator count.
*/
int getGeneratorCount();
/**
* Get a generator.
*
* @param id the id or an alias of the generator
*/
Generator getGenerator(String id);
/**
* Get all batteries.
*/
Iterable<Battery> getBatteries();
/**
* Get all batteries.
*/
Stream<Battery> getBatteryStream();
/**
* Get the battery count.
*/
int getBatteryCount();
/**
* Get a battery.
*
* @param id the id or an alias of the battery
*/
Battery getBattery(String id);
/**
* Get all loads.
*/
Iterable<Load> getLoads();
/**
* Get all loads.
*/
Stream<Load> getLoadStream();
/**
* Get the load count.
*/
int getLoadCount();
/**
* Get a load.
*
* @param id the id or an alias of the load
*/
Load getLoad(String id);
/**
* Get all compensator shunts.
*/
Iterable<ShuntCompensator> getShuntCompensators();
/**
* Get all compensator shunts.
*/
Stream<ShuntCompensator> getShuntCompensatorStream();
/**
* Get the shunt count.
*/
int getShuntCompensatorCount();
/**
* Get a compensator shunt.
*
* @param id the id or an alias of the compensator shunt
*/
ShuntCompensator getShuntCompensator(String id);
/**
* Get all dangling lines corresponding to given filter.
*/
Iterable<DanglingLine> getDanglingLines(DanglingLineFilter danglingLineFilter);
/**
* Get all dangling lines.
*/
default Iterable<DanglingLine> getDanglingLines() {
return getDanglingLines(DanglingLineFilter.ALL);
}
/**
* Get the dangling lines corresponding to given filter.
*/
Stream<DanglingLine> getDanglingLineStream(DanglingLineFilter danglingLineFilter);
/**
* Get all the dangling lines.
*/
default Stream<DanglingLine> getDanglingLineStream() {
return getDanglingLineStream(DanglingLineFilter.ALL);
}
/**
* Get the dangling line count.
*/
int getDanglingLineCount();
/**
* Get a dangling line.
*
* @param id the id or an alias of the dangling line
*/
DanglingLine getDanglingLine(String id);
/**
* Get all static var compensators.
*/
Iterable<StaticVarCompensator> getStaticVarCompensators();
/**
* Get all static var compensators.
*/
Stream<StaticVarCompensator> getStaticVarCompensatorStream();
/**
* Get the static var compensator count.
*/
int getStaticVarCompensatorCount();
/**
* Get a static var compensator.
*
* @param id the id or an alias of the static var compensator
*/
StaticVarCompensator getStaticVarCompensator(String id);
/**
* Get a switch from its id or an alias.
* @param id id or an alias of the switch
* @return the switch
*/
Switch getSwitch(String id);
/**
* Get all switches.
* @return all switches
*/
Iterable<Switch> getSwitches();
/**
* Get all switches.
* @return all switches
*/
Stream<Switch> getSwitchStream();
/**
* Get the switch count.
*
* @return the switch count
*/
int getSwitchCount();
/**
* Get a busbar section from its id or an alias.
* @param id the id or an alias of the busbar section
* @return the busbar section
*/
BusbarSection getBusbarSection(String id);
/**
* Get all busbar sections.
* @return all busbar sections
*/
Iterable<BusbarSection> getBusbarSections();
/**
* Get all busbar sections.
* @return all busbar sections
*/
Stream<BusbarSection> getBusbarSectionStream();
/**
* Get the busbar section count.
* @return the busbar section count.
*/
int getBusbarSectionCount();
/**
* Get all HVDC converter stations.
* @return all HVDC converter stations
*/
Iterable<HvdcConverterStation<?>> getHvdcConverterStations();
/**
* Get all HVDC converter stations.
* @return all HVDC converter stations
*/
Stream<HvdcConverterStation<?>> getHvdcConverterStationStream();
/**
* Get HVDC converter stations count.
* @return HVDC converter station count
*/
int getHvdcConverterStationCount();
/**
* Get an HVDC converter station.
* @param id the id or an alias of the HVDC converter station
* @return the HVDC converter station or null if not found
*/
HvdcConverterStation<?> getHvdcConverterStation(String id);
/**
* Get all LCC converter stations.
* @return all LCC converter stations
*/
Iterable<LccConverterStation> getLccConverterStations();
/**
* Get all LCC converter stations.
* @return all LCC converter stations
*/
Stream<LccConverterStation> getLccConverterStationStream();
/**
* Get LCC converter stations count.
* @return LCC converter station count
*/
int getLccConverterStationCount();
/**
* Get an LCC converter station.
* @param id the id or an alias of the LCC converter station
* @return the LCC converter station or null if not found
*/
LccConverterStation getLccConverterStation(String id);
/**
* Get all VSC converter stations.
* @return all VSC converter stations
*/
Iterable<VscConverterStation> getVscConverterStations();
/**
* Get all VSC converter stations.
* @return all VSC converter stations
*/
Stream<VscConverterStation> getVscConverterStationStream();
/**
* Get VSC converter stations count.
* @return VSC converter station count
*/
int getVscConverterStationCount();
/**
* Get an VSC converter station.
* @param id the id or an alias of the VSC converter station
* @return the VSC converter station or null if not found
*/
VscConverterStation getVscConverterStation(String id);
/**
* Get all HVDC lines.
* @return all HVDC lines
*/
Iterable<HvdcLine> getHvdcLines();
/**
* Get all HVDC lines.
* @return all HVDC lines
*/
Stream<HvdcLine> getHvdcLineStream();
/**
* Get HVDC lines count.
* @return HVDC lines count
*/
int getHvdcLineCount();
/**
* Get an HVDC line.
* @param id the id or an alias of the HVDC line
* @return the HVDC line or null if not found
*/
HvdcLine getHvdcLine(String id);
/**
* Get an HVDC line from a converter station
* @param converterStation a HVDC converter station
* @return the HVDC line or null if not found
*/
default HvdcLine getHvdcLine(HvdcConverterStation converterStation) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* Get a builder to create a new HVDC line.
* @return a builder to create a new HVDC line
*/
HvdcLineAdder newHvdcLine();
/**
* Get all grounds.
*/
Iterable<Ground> getGrounds();
/**
* Get all grounds.
*/
Stream<Ground> getGroundStream();
/**
* Get the ground count.
*/
int getGroundCount();
/**
* Get a ground.
*
* @param id the id or an alias of the ground
*/
Ground getGround(String id);
/**
* * Get an identifiable by its ID or alias
*
* @param id the id or an alias of the identifiable
*/
Identifiable<?> getIdentifiable(String id);
/**
* Get all identifiables of the network.
*
* @return all identifiables of the network
*/
Collection<Identifiable<?>> getIdentifiables();
/**
* Get all connectables of the network for a given type
*
* @param clazz connectable type class
* @return all the connectables of the given type
*/
default <C extends Connectable> Iterable<C> getConnectables(Class<C> clazz) {
throw new UnsupportedOperationException();
}
/**
* Get a stream of all connectables of the network for a given type
*
* @param clazz connectable type class
* @return a stream of all the connectables of the given type
*/
default <C extends Connectable> Stream<C> getConnectableStream(Class<C> clazz) {
throw new UnsupportedOperationException();
}
/**
* Count the connectables of the network for a given type
*
* @param clazz connectable type class
* @return the count of all the connectables of the given type
*/
default <C extends Connectable> int getConnectableCount(Class<C> clazz) {
throw new UnsupportedOperationException();
}
/**
* Get all connectables of the network
*
* @return all the connectables
*/
default Iterable<Connectable> getConnectables() {
throw new UnsupportedOperationException();
}
/**
* Get a stream of all connectables of the network
*
* @return a stream of all the connectables
*/
default Stream<Connectable> getConnectableStream() {
throw new UnsupportedOperationException();
}
/**
* Get a connectable by its ID or alias
*
* @param id the id or an alias of the equipment
*/
default Connectable<?> getConnectable(String id) {
Identifiable<?> identifiable = getIdentifiable(id);
if (identifiable instanceof Connectable<?>) {
return (Connectable<?>) identifiable;
}
return null;
}
/**
* Count the connectables of the network
*
* @return the count of all the connectables
*/
default int getConnectableCount() {
throw new UnsupportedOperationException();
}
/**
* Get a bus/breaker view of the network.
*/
BusBreakerView getBusBreakerView();
/**
* Get a bus view of the network.
*/
BusView getBusView();
/**
* Get a builder to create a new VoltageAngleLimit.
*/
VoltageAngleLimitAdder newVoltageAngleLimit();
/**
* Get all voltageAngleLimits.
*/
Iterable<VoltageAngleLimit> getVoltageAngleLimits();
/**
* Get all voltageAngleLimits.
*/
Stream<VoltageAngleLimit> getVoltageAngleLimitsStream();
/**
* Get voltage angle limit with id
*/
VoltageAngleLimit getVoltageAngleLimit(String id);
/**
* Create an empty subnetwork in the current network.
*
* @param subnetworkId id of the subnetwork
* @param name subnetwork's name
* @param sourceFormat source format
* @return the created subnetwork
*/
Network createSubnetwork(String subnetworkId, String name, String sourceFormat);
/**
* <p>Detach the current network (including its subnetworks) from its parent network.</p>
* <p>Note that this operation is destructive: after it the current network's content
* couldn't be accessed from the parent network anymore.</p>
* <p>The boundary elements, i.e. linking this network to an external voltage level are split if possible.</br>
* A {@link PowsyblException} is thrown if some un-splittable boundary elements are detected. This detection is processed
* before any network modification. So if an un-splittable boundary element is detected, no destructive operation will be done.</p>
*
* @return a fully-independent network corresponding to the current network and its subnetworks.
*/
Network detach();
/**
* <p>Check if the current network can be detached from its parent network (with {@link #detach()}).</p>
*
* @return True if the network can be detached from its parent network.
*/
boolean isDetachable();
/**
* Return all the boundary elements of the current network, i.e. the elements which link or might link this network
* to an external voltage level.
*
* @return a set containing the boundary elements of the network.
*/
Set<Identifiable<?>> getBoundaryElements();
/**
* Check if an identifiable is a boundary element for the current network.
*
* @param identifiable the identifiable to check
* @return True if the identifiable is a boundary element for the current network
*/
boolean isBoundaryElement(Identifiable<?> identifiable);
/**
* <p>Remove the subnetworks structure from the current network.</p>
* <ul>
* <li>If the current network is a subnetwork of another network, this method throws a {@link UnsupportedOperationException}.</li>
* <li>If the current network doesn't contains any subnetworks, the network is unchanged by this method.</li>
* <li>If the current network contains one or several subnetworks, all the subnetworks' elements will be "moved"
* into the current network and the subnetworks (thus emptied) will be removed.</li>
* </ul>
* <p>Subnetworks' extensions and properties are transferred to the flatten network.</p>
* <p>Note that subnetworks are integrated in the whole network following the same order they were merged.
* For each one, only the properties and the extensions which are not already present in the currently flattened network
* (i.e same name for properties or same type for extensions) are transferred. If a duplicate is detected,
* this latter is not transferred and will remain in its original subnetwork at the end of the flattening operation.
* It is thus possible to retrieve potential duplicates and to handle them manually.</p>
*<p>For instance, if:
* <ul>
* <li>{@code n0} has 2 subnetworks {@code s1} and {@code s2} (merged in this order).</li>
* <li>{@code s1} has the property {@code (key = val1)}.</li>
* <li>{@code s2} has the property {@code (key = val2)}.</li>
* </ul>
* After {@code n0.flatten()}:
* <ul>
* <li>{@code n0} will have the property {@code (key = val1)}
* (when "integrating" {@code s1}, no property of key {@code key} was found in {@code n0}).</li>
* <li>{@code s1} will have no property
* (it was transferred to {@code n0}).</li>
* <li>{@code s2} will have the property {@code (key = val2)}
* (the property was NOT transferred because the property {@code (key = val1)} was already in {@code n0}).</li>
* </ul>
*</p>
* <p>Also note that only well-formed (implementing an interface) network extensions will be transferred.</p>
*/
void flatten();
/**
* <p>Add a listener on the network.</p>
* @param listener the listener to add
*/
void addListener(NetworkListener listener);
/**
* <p>Remove a listener from the network.</p>
* @param listener the listener to remove
*/
void removeListener(NetworkListener listener);
@Override
default IdentifiableType getType() {
return IdentifiableType.NETWORK;
}
/**
* If network is valid, do nothing.<br>
* If network not valid, check if each network component is valid. A {@link ValidationException} is thrown with an explicit message if one network component is not valid.<br>
* If all network components are valid, network validation status is updated to true.
* Return the network validation status.
*/
default ValidationLevel runValidationChecks() {
return runValidationChecks(true);
}
/**
* If network is valid, do nothing.<br>
* If network not valid and <code>throwsException</code> is <code>true</code>, check if each network component is valid. A {@link ValidationException} is thrown with an explicit message if one network component is not valid.<br>
* If all network components are valid, network validation status is updated to true.
* Return the network validation status.
*/
default ValidationLevel runValidationChecks(boolean throwsException) {
return runValidationChecks(throwsException, ReportNode.NO_OP);
}
/**
* If network is valid, do nothing.<br>
* If network not valid and <code>throwsException</code> is <code>true</code>, check if each network component is valid. A {@link ValidationException} is thrown with an explicit message if one network component is not valid.<br>
* If all network components are valid, network validation status is updated to true.
* Return the network validation status.
*/
default ValidationLevel runValidationChecks(boolean throwsException, ReportNode reportNode) {
return ValidationLevel.STEADY_STATE_HYPOTHESIS;
}
/**
* Return the network validation status. Do <b>not</b> run any validation check.
*/
default ValidationLevel getValidationLevel() {
return ValidationLevel.STEADY_STATE_HYPOTHESIS;
}
default Network setMinimumAcceptableValidationLevel(ValidationLevel validationLevel) {
if (validationLevel != ValidationLevel.STEADY_STATE_HYPOTHESIS) {
throw new UnsupportedOperationException("Validation level below STEADY_STATE_HYPOTHESIS not supported");
}
return this;
}
default Stream<Identifiable<?>> getIdentifiableStream(IdentifiableType identifiableType) {
return switch (identifiableType) {
case SWITCH -> getSwitchStream().map(Function.identity());
case TWO_WINDINGS_TRANSFORMER -> getTwoWindingsTransformerStream().map(Function.identity());
case THREE_WINDINGS_TRANSFORMER -> getThreeWindingsTransformerStream().map(Function.identity());
case DANGLING_LINE -> getDanglingLineStream(DanglingLineFilter.ALL).map(Function.identity());
case LINE -> getLineStream().map(Function.identity());
case TIE_LINE -> getTieLineStream().map(Function.identity());
case LOAD -> getLoadStream().map(Function.identity());
case BATTERY -> getBatteryStream().map(Function.identity());
case GENERATOR -> getGeneratorStream().map(Function.identity());
case HVDC_LINE -> getHvdcLineStream().map(Function.identity());
case SUBSTATION -> getSubstationStream().map(Function.identity());
case VOLTAGE_LEVEL -> getVoltageLevelStream().map(Function.identity());
case BUSBAR_SECTION -> getBusbarSectionStream().map(Function.identity());
case SHUNT_COMPENSATOR -> getShuntCompensatorStream().map(Function.identity());
case HVDC_CONVERTER_STATION -> getHvdcConverterStationStream().map(Function.identity());
case STATIC_VAR_COMPENSATOR -> getStaticVarCompensatorStream().map(Function.identity());
case GROUND -> getGroundStream().map(Function.identity());
case AREA -> getAreaStream().map(Function.identity());
case OVERLOAD_MANAGEMENT_SYSTEM -> getOverloadManagementSystemStream().map(Function.identity());
default -> throw new PowsyblException("can get a stream of " + identifiableType + " from a network.");
};
}
/**
* Write the network to a given format.
*
* @param format the export format
* @param parameters some properties to configure the export
* @param dataSource data source
* @param reportNode the reportNode used for functional logs
*/
default void write(ExportersLoader loader, String format, Properties parameters, DataSource dataSource, ReportNode reportNode) {
Exporter exporter = Exporter.find(loader, format);
if (exporter == null) {
throw new PowsyblException("Export format " + format + " not supported");
}
exporter.export(this, parameters, dataSource, reportNode);
}
default void write(ExportersLoader loader, String format, Properties parameters, DataSource dataSource) {
write(loader, format, parameters, dataSource, ReportNode.NO_OP);
}
default void write(String format, Properties parameters, DataSource dataSource) {
write(new ExportersServiceLoader(), format, parameters, dataSource);
}
/**
* Write the network to a given format.
*
* @param format the export format
* @param parameters some properties to configure the export
* @param file the network file
* @param reportNode the reportNode used for functional logs
*/
default void write(ExportersLoader loader, String format, Properties parameters, Path file, ReportNode reportNode) {
DataSource dataSource = Exporters.createDataSource(file);
write(loader, format, parameters, dataSource, reportNode);
}
default void write(ExportersLoader loader, String format, Properties parameters, Path file) {
write(loader, format, parameters, file, ReportNode.NO_OP);
}
default void write(String format, Properties parameters, Path file) {
write(new ExportersServiceLoader(), format, parameters, file);
}
/**
* Write the network to a given format.
*
* @param format the export format
* @param parameters some properties to configure the export
* @param directory the output directory where files are generated
* @param baseName a base name for all generated files
* @param reportNode the reportNode used for functional logs
*/
default void write(ExportersLoader loader, String format, Properties parameters, String directory, String baseName, ReportNode reportNode) {
write(loader, format, parameters, new DirectoryDataSource(Paths.get(directory), baseName), reportNode);
}
default void write(ExportersLoader loader, String format, Properties parameters, String directory, String basename) {
write(loader, format, parameters, directory, basename, ReportNode.NO_OP);
}
default void write(String format, Properties parameters, String directory, String baseName) {
write(new ExportersServiceLoader(), format, parameters, directory, baseName);
}
}