diff --git a/.gitignore b/.gitignore index 3c01935b6..b0c1d9676 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,6 @@ org.sonarlint.eclipse.core.prefs # Log files powsybl.log + +# Generated readthedocs pages +build-docs/ diff --git a/README.md b/README.md index ad67b3cec..3f0ba697c 100644 --- a/README.md +++ b/README.md @@ -172,3 +172,57 @@ For the above example, the corresponding parameter file could be: Other examples can be found in the [resources](https://github.com/powsybl/powsybl-dynawo/tree/main/dynawaltz-dsl/src/test/resources) of this project. + + +## Contribute to documentation + +The documentation sources for PowSybl Dynawo features are in the `docs` folder. + +Please keep them up to date with your developments. +They are published on https://powsybl.readthedocs.io and pull requests are built and previewed automatically via github CI. + +### Preview results +When modifying the website content, you can easily preview the result by building the docs locally. +To do so, run the following commands: +~~~bash +pip install -r docs/requirements.txt +sphinx-build -a docs ./build-docs +~~~ +Then open `build-docs/index.html` in your browser. + +### Cross-documentation links +If you want to add links to another documentation, add the corresponding repository to the `conf.py` file. +In order to automatically get the version specified in the `pom.xml`, please use the same naming as the version: if you define the +Groovy version with ``, then use `groovy` as key. The specified URL should start with `https://` and end with `latest/` (the final `/` is mandatory). +For example, to add a link to the documentation of Sphinx, you need to add the following lines: +~~~python +# This parameter might already be present, just add the new value +intersphinx_mapping = { + "sphinx": ("https://www.sphinx-doc.org/en/master/", None), +} +~~~ + +Then in your documentation file, you can add links to Sphinx documentation. If you want to link to a whole page, +use one of the following example: +~~~Markdown +- {doc}`sphinx:usage/extensions/intersphinx` +- {doc}`Intersphinx ` +- [Intersphinx](inv:sphinx:std:doc#usage/extensions/intersphinx). +~~~ + +If you want to link a specific part of a page, use one of those examples: +~~~Markdown +- [Intersphinx roles](inv:#ref-role). +- [Intersphinx roles](inv:sphinx#ref-role). +- [Intersphinx roles](inv:sphinx:std:label:#ref-role). +- [Intersphinx roles](inv:sphinx:*:*:#ref-role). +~~~ +*Note 1: for the last examples to work, there need to be a corresponding reference in the external documentation. +For those examples, `(ref-role)=` has been added right before the corresponding title +in the [Cross-referencing syntax page](inv:sphinx:std:doc#usage/referencing). Another way to make it work is to use the `autosectionlabel` module in Sphinx to +automatically generate anchors for each title.* + +*Note 2: if the build fails, try with the `-E` option to clear the cache:* +~~~bash +sphinx-build -a -E docs ./build-docs +~~~ \ No newline at end of file diff --git a/commons/src/test/java/com/powsybl/dynawo/commons/AbstractDynawoCommonsTest.java b/commons/src/test/java/com/powsybl/dynawo/commons/AbstractDynawoCommonsTest.java index d284f684d..832792558 100644 --- a/commons/src/test/java/com/powsybl/dynawo/commons/AbstractDynawoCommonsTest.java +++ b/commons/src/test/java/com/powsybl/dynawo/commons/AbstractDynawoCommonsTest.java @@ -17,7 +17,7 @@ import java.nio.file.Path; import java.util.Objects; -import static com.powsybl.commons.test.ComparisonUtils.compareXml; +import static com.powsybl.commons.test.ComparisonUtils.assertXmlEquals; /** * @author Florian Dupuy {@literal } @@ -26,11 +26,11 @@ abstract class AbstractDynawoCommonsTest extends AbstractSerDeTest { protected void compare(String expectedIidmResource, Network actual) throws IOException { InputStream expected = Objects.requireNonNull(getClass().getResourceAsStream(expectedIidmResource)); - compareXml(expected, getInputStream(actual, tmpDir.resolve("actual.xiidm"))); + assertXmlEquals(expected, getInputStream(actual, tmpDir.resolve("actual.xiidm"))); } protected void compare(Network expected, Network actual) throws IOException { - compareXml(getInputStream(expected, tmpDir.resolve("expected.xiidm")), + assertXmlEquals(getInputStream(expected, tmpDir.resolve("expected.xiidm")), getInputStream(actual, tmpDir.resolve("actual.xiidm"))); } diff --git a/commons/src/test/resources/mergedLoadsMultiBusesVl.xiidm b/commons/src/test/resources/mergedLoadsMultiBusesVl.xiidm index afd02ea3c..a0fab37b9 100644 --- a/commons/src/test/resources/mergedLoadsMultiBusesVl.xiidm +++ b/commons/src/test/resources/mergedLoadsMultiBusesVl.xiidm @@ -1,5 +1,5 @@ - + diff --git a/commons/src/test/resources/mergedLoadsPnQn.xiidm b/commons/src/test/resources/mergedLoadsPnQn.xiidm index 743431fd2..8ea0e7220 100644 --- a/commons/src/test/resources/mergedLoadsPnQn.xiidm +++ b/commons/src/test/resources/mergedLoadsPnQn.xiidm @@ -1,5 +1,5 @@ - + diff --git a/commons/src/test/resources/mergedLoadsPnQp.xiidm b/commons/src/test/resources/mergedLoadsPnQp.xiidm index 91678abdd..955239c23 100644 --- a/commons/src/test/resources/mergedLoadsPnQp.xiidm +++ b/commons/src/test/resources/mergedLoadsPnQp.xiidm @@ -1,5 +1,5 @@ - + diff --git a/commons/src/test/resources/mergedLoadsPpQn.xiidm b/commons/src/test/resources/mergedLoadsPpQn.xiidm index 82613c9dd..9457d1b08 100644 --- a/commons/src/test/resources/mergedLoadsPpQn.xiidm +++ b/commons/src/test/resources/mergedLoadsPpQn.xiidm @@ -1,5 +1,5 @@ - + diff --git a/commons/src/test/resources/mergedLoadsPpQp.xiidm b/commons/src/test/resources/mergedLoadsPpQp.xiidm index 6353002c2..f72c58cba 100644 --- a/commons/src/test/resources/mergedLoadsPpQp.xiidm +++ b/commons/src/test/resources/mergedLoadsPpQp.xiidm @@ -1,5 +1,5 @@ - + diff --git a/commons/src/test/resources/mergedThreeLoadsGroups.xiidm b/commons/src/test/resources/mergedThreeLoadsGroups.xiidm index e81bcd16c..62728cc89 100644 --- a/commons/src/test/resources/mergedThreeLoadsGroups.xiidm +++ b/commons/src/test/resources/mergedThreeLoadsGroups.xiidm @@ -1,5 +1,5 @@ - + diff --git a/commons/src/test/resources/nonMergeableLoads.xiidm b/commons/src/test/resources/nonMergeableLoads.xiidm index 9de5e3985..5a0611c83 100644 --- a/commons/src/test/resources/nonMergeableLoads.xiidm +++ b/commons/src/test/resources/nonMergeableLoads.xiidm @@ -1,5 +1,5 @@ - + diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml new file mode 100644 index 000000000..934aaacee --- /dev/null +++ b/docs/.readthedocs.yaml @@ -0,0 +1,13 @@ +version: 2 + +build: + os: ubuntu-20.04 + tools: + python: "3.9" + +sphinx: + configuration: docs/conf.py + +python: + install: + - requirements: docs/requirements.txt \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 000000000..4d15385e8 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,27 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + + +clean: + @echo "Removing $(SOURCEDIR)/reference/api" + @rm -rf "$(SOURCEDIR)/reference/api" + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/_static/favicon.ico b/docs/_static/favicon.ico new file mode 100644 index 000000000..2ea6b5c3f Binary files /dev/null and b/docs/_static/favicon.ico differ diff --git a/docs/_static/logos/logo_lfe_powsybl.svg b/docs/_static/logos/logo_lfe_powsybl.svg new file mode 100644 index 000000000..37450078f --- /dev/null +++ b/docs/_static/logos/logo_lfe_powsybl.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_static/styles/styles.css b/docs/_static/styles/styles.css new file mode 100644 index 000000000..f3340e112 --- /dev/null +++ b/docs/_static/styles/styles.css @@ -0,0 +1,6 @@ +/* The following code ensures font is not too big (Furo theme can make font too big on large screens) */ +@media(min-width:97em) { + html { + font-size: 100% + } +} \ No newline at end of file diff --git a/docs/_templates/page.html b/docs/_templates/page.html new file mode 100644 index 000000000..4652e049e --- /dev/null +++ b/docs/_templates/page.html @@ -0,0 +1,101 @@ + + +{% extends "furo/page.html" %} + +{% block footer %} + +
+
+ {%- if show_copyright %} + + {%- endif %} + {% trans %}Made with {% endtrans -%} + {%- if show_sphinx -%} + {% trans %}Sphinx and {% endtrans -%} + @pradyunsg's + {% endif -%} + {% trans %} + Furo + {% endtrans %} + {%- if last_updated -%} +
+ {% trans last_updated=last_updated|e -%} + Last updated on {{ last_updated }} + {%- endtrans -%} +
+ {%- endif %} +
+
+ {% if theme_footer_icons or READTHEDOCS -%} +
+ {% if theme_footer_icons -%} + {% for icon_dict in theme_footer_icons -%} + + {{- icon_dict.html -}} + + {% endfor %} + {%- endif %} +
+ {%- endif %} +
+
+{% endblock footer %} diff --git a/docs/_templates/sidebar/brand.html b/docs/_templates/sidebar/brand.html new file mode 100644 index 000000000..8aef92a7b --- /dev/null +++ b/docs/_templates/sidebar/brand.html @@ -0,0 +1,25 @@ +{#- +Overrides furo's brand.html to customize links: +- The logo links to a custom page (set sidebar_logo_href option in html_context) +- The title links to the subproject's main page +-#} + +{% if not theme_sidebar_hide_name %} + +{%- endif %} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 000000000..927f08de8 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,168 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import datetime +import os +import re +import sys + +# Path to python sources, for doc generation on readthedocs +source_path = os.path.abspath('..') +sys.path.insert(0, source_path) +print(f'appended {source_path}') + + +# -- Project information ----------------------------------------------------- + +# Only those 3 parameters have to be modified for each specific repository +project = 'powsybl-dynawo' +module_name = "powsybl-dynawo" +github_repository = "https://github.com/powsybl/powsybl-dynawo/" + +# Build year for the copyright +copyright_year = f'2018-{ datetime.datetime.now().year }' + +# Find the version and release information. +# We have a single source of truth for our version number: the project's pom.xml file. +# This next bit of code reads from it. +file_with_version = os.path.join(source_path, "pom.xml") +with open(file_with_version) as f: + next_line_contains_version = False + for line in f: + if next_line_contains_version == False: + m = re.match(r'^ {4}\' + module_name + r'\<\/artifactId\>', line) + if m: + next_line_contains_version = True + else: + m = re.match(r'^ {4}\(.*)\<\/version\>', line) + if m: + __version__ = m.group(1) + # The short X.Y version. + version = ".".join(__version__.split(".")[:2]) + # The full version, including alpha/beta/rc tags. + release = __version__ + break + else: # AKA no-break + version = release = "dev" + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', + 'sphinx.ext.autosectionlabel', + 'sphinx.ext.autosummary', + 'sphinx.ext.viewcode', + 'sphinx.ext.doctest', + 'sphinx.ext.napoleon', + 'sphinx.ext.todo', + 'sphinx.ext.intersphinx', + 'sphinx_tabs.tabs', + 'myst_parser', + # Extension used to add a "copy" button on code blocks + 'sphinx_copybutton'] +myst_enable_extensions = [ + "amsmath", + "colon_fence", + "dollarmath", + "attrs_inline" +] +myst_heading_anchors = 6 + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# Reference sections generation +autosectionlabel_prefix_document = True +autosectionlabel_maxdepth = 2 + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "furo" + +html_title = f"{project} v{release}" + +html_logo = '_static/logos/logo_lfe_powsybl.svg' +html_favicon = "_static/favicon.ico" + +html_context = { + "copyright_year": copyright_year, + "sidebar_logo_href": "https://powsybl.readthedocs.io/", + "github_repository": github_repository +} + +html_theme_options = { + # the following 3 lines enable edit button + "source_repository": github_repository, + "source_branch": "main", + "source_directory": "docs/", +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] +html_css_files = ['styles/styles.css'] + +todo_include_todos = True + +# Links to external documentations : python 3 and pandas +intersphinx_mapping = { + "powsyblcore": ("https://powsybl.readthedocs.io/projects/powsybl-core/en/latest/", None) +} +intersphinx_disabled_reftypes = ["*"] + +# Generate one file per method +autosummary_generate = True + + +# -- Dependencies versions --------------------------------------------------- +# This part will automatically look in the pom.xml to find versions corresponding to the dependencies whose +# documentation is used in the present one, except if it's a SNAPSHOT version or if a specific version has been chosen +# in intersphinx_mapping + +# Get the URL without the default version +def extract_base_url(url): + default_version = "latest" + + m = re.match(r'(^https\:\/\/.*)' + default_version + r'\/$', url) + if m: + return m.group(1) + +# Replace the default version in the URL with the version from the pom.xml +def replace_versions(intersphinx_mapping, file): + with open(file) as f: + for line in f: + m = re.match(r'^ {8}\<(.*)\.version\>(.*)\<\/(.*)\.version\>', line) + if m and m.group(1) == m.group(3): + dependency = m.group(1) + version = m.group(2) + if "SNAPSHOT" not in version and dependency in intersphinx_mapping: + url_start = extract_base_url(intersphinx_mapping[dependency][0]) + if url_start: + intersphinx_mapping[dependency] = (url_start + version + "/", None) + if "" in line: + break + return intersphinx_mapping + +intersphinx_mapping = replace_versions(intersphinx_mapping, file_with_version) \ No newline at end of file diff --git a/docs/dynamic_simulation/curves-dsl.md b/docs/dynamic_simulation/curves-dsl.md new file mode 100644 index 000000000..96c4e0c54 --- /dev/null +++ b/docs/dynamic_simulation/curves-dsl.md @@ -0,0 +1,37 @@ +# Curves DSL +The curves domain specific language allow a user to configure the curves Dynawo will export at the end of the simulation. This DSL defines the `curve` and the `curves` keywords. + +The `curve` keyword create a single curve for a dynamic model. One identifies a dynamic model by its ID, the same as the one used in the [Dynamic Models DSL](dynamic-models-dsl). The variable to plot is identified by its name. +```groovy +curve { + dynamicModelId load.id + variable "load_PPu" +} +``` + +If you want to plot a static variable, the `dynamicModelId` parameter has to be replaced by the `staticId` keyword and refers to an ID present in the static network. +```groovy +curve { + staticId bus.id + variable "Upu_value" +} +``` + +If you want to plot several variables of the same dynamic model, you can use the `curves` keyword that permit limiting boilerplate code in the script. +``` +// This: +curve { + dynamicModelId load.id + variable "load_PPu" +} +curve { + dynamicModelId load.id + variable "load_QPu" +} + +// is equivalent to: +curves { + dynamicModelId load.id + variables "load_PPu", "load_QPu" +} +``` diff --git a/docs/dynamic_simulation/dynamic-models-dsl.md b/docs/dynamic_simulation/dynamic-models-dsl.md new file mode 100644 index 000000000..505219171 --- /dev/null +++ b/docs/dynamic_simulation/dynamic-models-dsl.md @@ -0,0 +1,94 @@ +# Dynamic Models DSL + +The Dynamic Models DSL is a domain specific language written in groovy for the creation dynamic models used by Dynawo, most of them associated with a static equipment present in the network. +If some equipments are not configured, Dynawo would use a default model and set of parameters. + +## BlackBoxModel +All the models supported are `BlackBoxModel`. This kind of dynamic model have three attributes: +- `lib` refers to the dynamic model library used in Dynawo. +- `dynamicModelId` identifies the model. +- `parameterSetId` refers a set of parameters for this model in one of the network parameters file. + +## Equipment models +These models are `BlackBoxModel` matching an IIDM equipment (generator, load, ...). +To instantiate them with DSL, you have to use their model name as a keyword and define at least a `staticId` and a `parameterSetId`. +The `dynamicModelId` is optional and would be equal to the `staticId` if not set. + +**Example** +```groovy +GeneratorSynchronousThreeWindings { + staticId '' + dynamicModelId '' + parameterSetId '' +} +LoadAlphaBeta { + staticId '' + parameterSetId '' +} +``` + +## Automation system models +These models are `BlackBoxModel` of automation system without IIDM equipment. + +### OverloadManagementSystem +This model connect to IIDM line or two windings transformer. Besides `dynamicModelId` and `parameterSetId` it needs: +- one control branch +- one measurement branch (can be the controlled one) +- which side is monitored. + +**Example** +```groovy +OverloadManagementSystem { + dynamicModelId '' + parameterSetId '' + controlledBranch '' + iMeasurement '' + iMeasurementSide TwoSides.TWO +} +``` + +#### TODO add all automation systems + +## Supported models +Models are listed in [models.json](../../dynawaltz/src/main/resources/models.json). +The list is divided in categories each linked to a dedicated builder. +### Categories properties +* `defaultLib` : name of the default library +* `libs` : list of dynawo libraries supported for this category + +The list is statically loaded via [ModelConfigLoader](https://javadoc.io/doc/com.powsybl/powsybl-dynawo/latest/com/powsybl/dynawaltz/builders/ModelConfigLoader.html) services and thus can be extended. + +### Library properties +* `lib`: library name used in dynawo +* `alias`: name used in powsybl-dynawo instead of lib +* `properties`: dynamic model properties (synchronized, dangling, etc.) +* `internalModelPrefix`: used for dyd file creation + +## Dynamic model Builder List +Ultimately, all groovy scripts call dedicated builders that can be used directly by developers. +### Equipments +* BaseStaticVarCompensatorBuilder +* HvdcPBuilder +* HvdcVscBuilder +* GeneratorFictitiousBuilder +* SynchronizedGeneratorBuilder +* SynchronousGeneratorBuilder +* WeccBuilder +* GridFormingConverterBuilder +* LineBuilder +* StandardBusBuilder +* InfiniteBusBuilder +* TransformerFixedRatioBuilder +* BaseLoadBuilder +* LoadOneTransformerBuilder +* LoadTwoTransformersBuilder +* LoadOneTransformerTapChangerBuilder +* LoadTwoTransformersTapChangersBuilder +### Automation Systems +* TapChangerAutomationSystemBuilder +* TapChangerBlockingAutomationSystemBuilder +* UnderVoltageAutomationSystemBuilder +* DynamicOverloadManagementSystemBuilder +* DynamicTwoLevelsOverloadManagementSystemBuilder +* PhaseShifterPAutomationSystemBuilder +* PhaseShifterIAutomationSystemBuilder diff --git a/docs/dynamic_simulation/dynawo-configuration.md b/docs/dynamic_simulation/dynawo-configuration.md new file mode 100644 index 000000000..f54886c9e --- /dev/null +++ b/docs/dynamic_simulation/dynawo-configuration.md @@ -0,0 +1,140 @@ +# Configuration + +## Dynawo properties +The `dynawo` module defines the required parameters to run with Dynawo. + +**homeDir** +Use the `homeDir` property to defines the installation directory of the dynawo simulator. + +**debug** +Use the `debug` property to specify if the temporary folder where the inputs are generated should be kept after the simulation. + +### Examples + +**YAML configuration:** +```yaml +dynawo: + homeDir: /home/user/dynawo + debug: false +``` + +**XML configuration:** +```xml + + /home/user/dynawo + false + +``` + +## Default parameters +The `dynawo-default-parameters` module defines the default values for all specific parameters of a dynamic simulation run with Dynawo. + +### Required parameters + +**parametersFile** +`parametersFile` defines the path of the main parameters file. +The default value is `models.par`. + +**network.parametersFile** +`network.parametersFile` defines the path of the network parameters file. +The default value is `network.par`. + +**solver.parametersFile** +`solver.parametersFile` defines the path of the solver parameters file. +The default value is `solvers.par`. + +### Optional parameters + +**network.parametersId** +`network.parametersId` defines the network parameters set id stored in `network.parametersFile`. +The default value is `1`. + +**solver.parametersId** +`solver.parametersId` defines the solver parameters set id stored in `solver.parametersFile`. +The default value is `1`. + +**solver.type** +`solver.type` defines the solver used in the simulation. +The available `com.powsybl.dynawaltz.DynaWaltzParameters.SolverType` values are: +- `SIM`: the simplified solver (fixed time step solver) +- `IDA`: the IDA solver (variable time step solver) + +The default value is `SIM`. + +**dump.export** +`dump.export` defines if the dynamic simulation result should be exported as a dump. +The default value is `FALSE`. + +**dump.useAsInput** +`dump.useAsInput` defines if a previous simulation result dump should be used as input for the current simulation. +The default value is `FALSE`. + +**dump.exportFolder** +`dump.exportFolder` defines the folder name where the dump is exported. +The default value is `null`. + +**dump.fileName** +`dump.fileName` defines the dump file name. +The default value is `null`. + +**useModelSimplifiers** +`useModelSimplifiers` defines if simplifiers are used before macro connection computation **(TODO: link)**. +The default value is `FALSE`. + +**mergeLoads** +`mergeLoads` defines if loads connected to the same bus are merged or not. +The default value is `FALSE`. + +**timeline.exportMode** +`timeline.exportMode` defines the file extension of the timeline export. +The available `com.powsybl.dynawaltz.DynaWaltzParameters.ExportMode` values are: +- `CSV` +- `TXT`: same format as `CSV` but with `|` separator +- `XML` + +The default value is `TXT`. + +**precision** +`precision` defines the simulation step precision. +The default value is `1e-6`. + +### Examples + +**YAML configuration:** +```yaml +dynawo-default-parameters: + parametersFile: /home/user/parametersFile + network.parametersFile: /home/user/networkParametersFile + network.parametersId: 1 + solver.type: SIM + solver.parametersFile: /home/user/solverParametersFile + solver.parametersId: 1 + dump.export: false + dump.useAsInput: false + dump.exportFolder: /home/user/dumps + dump.fileName: dump.dmp + useModelSimplifiers: false + mergeLoads: false + timeline.exportMode: XML + precision: 10e-6 +``` + +**XML configuration:** +```xml + + /home/user/parametersFile + /home/user/networkParametersFile + NETWORK + SIM + /home/user/solverParametersFile + SIM + false + false + /home/user/dumps + dump.dmp + false + false + XML + 10e-6 + +``` diff --git a/docs/dynamic_simulation/event-models-dsl.md b/docs/dynamic_simulation/event-models-dsl.md new file mode 100644 index 000000000..d0b8b2a95 --- /dev/null +++ b/docs/dynamic_simulation/event-models-dsl.md @@ -0,0 +1,22 @@ +# Event Models DSL + +The Event Models DSL is a domain specific language written in groovy for the simulation of events that occurs during the simulation. + +## Event Model +- All the models supported are `BlackBoxModel`. This kind of event model have three attributes: +- `lib` refers to the event model library used in Dynawo. +- `staticId` identifies the equipment affected by the event +- `startTime` defines when the event starts. + +## Disconnect +Use this event to disconnect a branch, injection or an HVDC line. + +**Example** +```groovy +Disconnect { + staticId "GEN" + startTime 1 +} +``` + +### TODO add remaining events diff --git a/docs/dynamic_simulation/index.md b/docs/dynamic_simulation/index.md new file mode 100644 index 000000000..67bc6ac78 --- /dev/null +++ b/docs/dynamic_simulation/index.md @@ -0,0 +1,21 @@ +# Dynamic simulation + +```{toctree} +:hidden: +dynawo-configuration.md +dynamic-models-dsl.md +event-models-dsl.md +curves-dsl.md +``` + +PowSyBl provides an implementation of the [DynamicSimulation API from powsybl-core](inv:powsyblcore:*:*#simulation/dynamic/index) with [DynaWaltz](https://dynawo.github.io/about/dynawaltz), a tool for long-term stability simulation from the [Dynaωo](https://dynawo.github.io) suite. + +## Installation + +Read this [documentation page](https://dynawo.github.io/install/) to learn how to install and configure Dynawo. + +## Going further + +You may find an extensive documentation of the Dynawo project [here](https://github.com/dynawo/dynawo/releases/latest/download/DynawoDocumentation.pdf). + + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..bdf6e07cb --- /dev/null +++ b/docs/index.md @@ -0,0 +1,11 @@ +# Powsybl-dynawo documentation +Powsybl-dynawo is an interface between PowSyBl and [Dynaωo](https://dynawo.github.io) open source suites, providing: +- an implementation of [LoadFlow API from powsybl-core](inv:powsyblcore:*:*#simulation/loadflow/index), +- an implementation of [SecurityAnalysis API from powsybl-core](inv:powsyblcore:*:*#simulation/security/index), +- an implementation of [DynamicSimulation API from powsybl-core](inv:powsyblcore:*:*#simulation/dynamic/index). + +```{toctree} +:hidden: +load_flow/index.md +dynamic_simulation/index.md +``` diff --git a/docs/load_flow/dynaflow-configuration.md b/docs/load_flow/dynaflow-configuration.md new file mode 100644 index 000000000..87d9907c3 --- /dev/null +++ b/docs/load_flow/dynaflow-configuration.md @@ -0,0 +1,154 @@ +# Configuration + +## DynaFlow configuration + +You need to tell powsybl where to find DynaFlow, by adding this into you configuration file: +```yaml +dynaflow: + homeDir: /path/to/dynaflow # Directory obtained by unzipping the package, should contain "bin" + debug: false +``` + +To use DynaFlow as a default for all power flow computations, you may configure the `load-flow` +module in your configuration file: +```yaml +load-flow: + default-impl-name: DynaFlow +``` + +## Default parameters +The `dynaflow-default-parameters` module defines the default values for all specific parameters of a load flow run with DynaFlow. + +## Optional parameters + +**svcRegulationOn** +`svcRegulationOn` defines if SVCs (Static Var Compensator) take part in the voltage regulation. +The default value is `TRUE`. + +**shuntRegulationOn** +`shuntRegulationOn` defines if Shunts take part in the voltage regulation. +The default value is `TRUE`. + +**automaticSlackBusOn** +`automaticSlackbusOn` defines if DynaFlow computes the slack bus (phase reference bus) by itself or if the slack bus is provided. +The default value is `TRUE`. + +**dsoVoltageLevel** +`dsoVoltageLevel` defines the minimum voltage of level of loads. +The default value is `45.0`. + +**activePowerCompensation** +`activePowerCompensation` defines which type of power compensation applies. +Available values **(TODO: describe them)**: +- `P` +- `TARGET_P` +- `PMAX` + +The default value is `PMAX`. + +**settingPath** +`settingPath` is used to indicates the file which defines the model settings values. +The default value is `null`. + +**assemblingPath** +`assemblingPath` is used to indicates the file which defines the models' association. +The default value is `null`. + +**startTime** +`startTime` defines the simulation start time (in s). +The default value is `0`. + +**stopTime** +`stopTime` defines the simulation stop time (in s). +The default value is `100`. + +**precision** +**(TODO: description)** +The default value is `Nan`. + +**timeOfEvent** +**(TODO: description)** +The default value is `10`. + +**chosenOutputs** +**(TODO: description)** +Available values **(TODO: describe them)**: +- `STEADYSTATE` +- `LOSTEQ` +- `TIMELINE` +- `CONSTRAINTS` + +The default value is a list of all of them. + +**timeStep** +**(TODO: description)** +The default value is `10`. + +**mergeLoads** +`mergeLoads` is used to indicates if loads connected to the same bus are merged. +The default value is `TRUE`. + +**startingPointMode** +**(TODO: description)** +Available values **(TODO: describe them)**: +- `WARM` +- `FLAT` + +The default value is `WARM`. + +## Generic parameters +Furthermore, DynaFlow only supports `useReactiveLimits` generic parameter, the other parameters are ignored. +You may have a description of these parameters [here](inv:powsyblcore:*:*:#loadflow-generic-parameters). + +## Example + +You may define those parameters in your configuration file: +```yaml +dynaflow-default-parameters: + svcRegulationOn: true + shuntRegulationOn: false + automaticSlackBusOn: true + dsoVoltageLevel: 987.6 + activePowerCompensation: "P" + settingPath: "path/to/settingFile" + assemblingPath: "path/to/assemblingFile" + startTime: 0.0 + stopTime: 100.0 + precision: 1.0 + timeOfEvent: 10.0 + chosenOutputs: [ "STEADYSTATE", "LOSTEQ", "TIMELINE", "CONSTRAINTS" ] + timeStep: 2.6 + mergeLoads: true + startingPointMode: "WARM" +``` + + +Alternatively, you can provide parameters as a JSON file where supported +(for example when using `itools loadflow` command): +```json +{ + "version" : "1.9", + "useReactiveLimits" : true, + "extensions" : { + "DynaflowParameters" : { + "svcRegulationOn" : true, + "shuntRegulationOn" : false, + "automaticSlackBusOn" : true, + "dsoVoltageLevel" : 987.6, + "activePowerCompensation" : "P", + "settingPath" : "path/to/settingFile", + "assemblingPath" : "path/to/assemblingFile", + "startTime" : 0.0, + "stopTime" : 100.0, + "precision" : 1.0, + "sa" : { + "timeOfEvent" : 10.0 + }, + "chosenOutputs" : [ "STEADYSTATE", "LOSTEQ", "TIMELINE", "CONSTRAINTS" ], + "timeStep" : 2.6, + "mergeLoads" : true, + "startingPointMode" : "WARM" + } + } +} +``` \ No newline at end of file diff --git a/docs/load_flow/index.md b/docs/load_flow/index.md new file mode 100644 index 000000000..21df76d21 --- /dev/null +++ b/docs/load_flow/index.md @@ -0,0 +1,14 @@ +# Load flow + +```{toctree} +:hidden: +dynaflow-configuration.md +``` + +PowSyBl provides an implementation of the [LoadFlow API from powsybl-core](inv:powsyblcore:*:*#simulation/loadflow/index) with [DynaFlow](https://dynawo.github.io/about/dynaflow). +DynaFlow is an advanced steady-state simulation tool that aims at calculating the steady-state point by using a simplified time-domain simulation, guaranteeing the correctness of the solution found. +You can find more information about it [here](https://dynawo.github.io/about/dynaflow). + +## Installation + +You may download DynaFlow release packages from [here](https://github.com/dynawo/dynaflow-launcher/releases). diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 000000000..96ed7097e --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..c410d7c58 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,5 @@ +sphinx==7.1.2 +sphinx-tabs +furo==2024.1.29 +myst-parser +sphinx-copybutton \ No newline at end of file diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisProvider.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisProvider.java index bbcacc572..2a2cea440 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisProvider.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisProvider.java @@ -7,26 +7,21 @@ package com.powsybl.dynaflow; import com.google.auto.service.AutoService; -import com.powsybl.action.Action; import com.powsybl.commons.report.ReportNode; -import com.powsybl.computation.ComputationManager; import com.powsybl.contingency.ContingenciesProvider; import com.powsybl.dynawo.commons.PowsyblDynawoVersion; import com.powsybl.iidm.network.Network; -import com.powsybl.security.*; -import com.powsybl.security.interceptors.SecurityAnalysisInterceptor; -import com.powsybl.security.limitreduction.LimitReduction; -import com.powsybl.security.monitor.StateMonitor; -import com.powsybl.security.strategy.OperatorStrategy; +import com.powsybl.security.SecurityAnalysisProvider; +import com.powsybl.security.SecurityAnalysisReport; +import com.powsybl.security.SecurityAnalysisRunParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; -import static com.powsybl.dynaflow.DynaFlowConstants.*; +import static com.powsybl.dynaflow.DynaFlowConstants.DYNAFLOW_NAME; /** * @author Marcos de Miguel {@literal } @@ -49,37 +44,25 @@ public DynaFlowSecurityAnalysisProvider(Supplier configSupplier) @Override public CompletableFuture run(Network network, String workingVariantId, - LimitViolationDetector detector, - LimitViolationFilter filter, - ComputationManager computationManager, - SecurityAnalysisParameters parameters, ContingenciesProvider contingenciesProvider, - List interceptors, - List operatorStrategies, - List actions, - List monitors, - List limitReductions, - ReportNode reportNode) { - if (detector != null) { - LOG.error("LimitViolationDetector is not used in Dynaflow implementation."); - } - if (monitors != null && !monitors.isEmpty()) { + SecurityAnalysisRunParameters runParameters) { + if (!runParameters.getMonitors().isEmpty()) { LOG.error("Monitoring is not possible with Dynaflow implementation. There will not be supplementary information about monitored equipment."); } - if (operatorStrategies != null && !operatorStrategies.isEmpty()) { + if (!runParameters.getOperatorStrategies().isEmpty()) { LOG.error("Strategies are not implemented in Dynaflow"); } - if (actions != null && !actions.isEmpty()) { + if (!runParameters.getActions().isEmpty()) { LOG.error("Actions are not implemented in Dynaflow"); } - if (limitReductions != null && !limitReductions.isEmpty()) { + if (!runParameters.getLimitReductions().isEmpty()) { LOG.error("Limit reductions are not implemented in Dynaflow"); } - DynaFlowSecurityAnalysis securityAnalysis = new DynaFlowSecurityAnalysis(network, filter, computationManager, configSupplier); - interceptors.forEach(securityAnalysis::addInterceptor); + DynaFlowSecurityAnalysis securityAnalysis = new DynaFlowSecurityAnalysis(network, runParameters.getFilter(), runParameters.getComputationManager(), configSupplier); + runParameters.getInterceptors().forEach(securityAnalysis::addInterceptor); - ReportNode dfsaReportNode = DynaflowReports.createDynaFlowSecurityAnalysisReportNode(reportNode, network.getId()); - return securityAnalysis.run(workingVariantId, parameters, contingenciesProvider, dfsaReportNode); + ReportNode dfsaReportNode = DynaflowReports.createDynaFlowSecurityAnalysisReportNode(runParameters.getReportNode(), network.getId()); + return securityAnalysis.run(workingVariantId, runParameters.getSecurityAnalysisParameters(), contingenciesProvider, dfsaReportNode); } @Override diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/ConstraintsReaderTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/ConstraintsReaderTest.java index 2b2db1202..b58af03c1 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/ConstraintsReaderTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/ConstraintsReaderTest.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Objects; -import static com.powsybl.commons.test.ComparisonUtils.compareTxt; +import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -40,6 +40,6 @@ void test() throws IOException { ObjectMapper mapper = JsonUtil.createObjectMapper().registerModule(new SecurityAnalysisJsonModule()); mapper.writerWithDefaultPrettyPrinter().writeValue(stringWriter, violations); - compareTxt(Objects.requireNonNull(getClass().getResourceAsStream("/limitViolations.json")), stringWriter.toString()); + assertTxtEquals(Objects.requireNonNull(getClass().getResourceAsStream("/limitViolations.json")), stringWriter.toString()); } } diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java index ad6dd9447..9d646b02e 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java @@ -26,7 +26,7 @@ import java.nio.file.Path; import java.util.*; -import static com.powsybl.commons.test.ComparisonUtils.compareTxt; +import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; import static com.powsybl.dynaflow.DynaFlowProvider.MODULE_SPECIFIC_PARAMETERS; import static org.junit.jupiter.api.Assertions.*; @@ -205,7 +205,7 @@ void defaultParametersSerialization() throws IOException { try (InputStream actual = Files.newInputStream(parameterFile); InputStream expected = getClass().getResourceAsStream("/params_default.json")) { - compareTxt(expected, actual); + assertTxtEquals(expected, actual); } } @@ -239,7 +239,7 @@ void parametersSerialization() throws IOException { try (InputStream actual = Files.newInputStream(parameterFile); InputStream expected = getClass().getResourceAsStream("/params.json")) { - compareTxt(expected, actual); + assertTxtEquals(expected, actual); } } diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowProviderTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowProviderTest.java index ff68bbb7a..9bac95638 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowProviderTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowProviderTest.java @@ -33,7 +33,7 @@ import java.util.Objects; import java.util.concurrent.ForkJoinPool; -import static com.powsybl.commons.test.ComparisonUtils.compareXml; +import static com.powsybl.commons.test.ComparisonUtils.assertXmlEquals; import static com.powsybl.dynaflow.DynaFlowConstants.*; import static com.powsybl.loadflow.LoadFlowResult.Status.FAILED; import static com.powsybl.loadflow.LoadFlowResult.Status.FULLY_CONVERGED; @@ -222,7 +222,7 @@ private void compare(Network expected, Network actual) throws IOException { NetworkSerDe.write(expected, pexpected); actual.setCaseDate(expected.getCaseDate()); NetworkSerDe.write(actual, pactual); - compareXml(Files.newInputStream(pexpected), Files.newInputStream(pactual)); + assertXmlEquals(Files.newInputStream(pexpected), Files.newInputStream(pactual)); } private static Network createTestNetwork() { diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisTest.java index 60d6c4910..75c9b4ced 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisTest.java @@ -8,19 +8,14 @@ import com.powsybl.commons.PowsyblException; import com.powsybl.commons.test.AbstractSerDeTest; -import com.powsybl.computation.ComputationManager; import com.powsybl.computation.local.LocalCommandExecutor; import com.powsybl.computation.local.LocalComputationConfig; import com.powsybl.computation.local.LocalComputationManager; -import com.powsybl.contingency.ContingenciesProvider; import com.powsybl.contingency.Contingency; import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; import com.powsybl.loadflow.LoadFlowResult; -import com.powsybl.security.SecurityAnalysis; -import com.powsybl.security.SecurityAnalysisParameters; -import com.powsybl.security.SecurityAnalysisReport; -import com.powsybl.security.SecurityAnalysisResult; +import com.powsybl.security.*; import com.powsybl.security.json.SecurityAnalysisResultSerializer; import org.junit.jupiter.api.Test; @@ -36,8 +31,8 @@ import java.util.Objects; import java.util.concurrent.ForkJoinPool; -import static com.powsybl.commons.test.ComparisonUtils.compareTxt; -import static com.powsybl.commons.test.ComparisonUtils.compareXml; +import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; +import static com.powsybl.commons.test.ComparisonUtils.assertXmlEquals; import static com.powsybl.dynaflow.DynaFlowConstants.DYNAFLOW_NAME; import static com.powsybl.dynaflow.DynaFlowConstants.IIDM_FILENAME; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -86,11 +81,11 @@ public int execute(String program, List args, Path outFile, Path errFile private void validateInputs(Path workingDir) throws IOException { if (inputFile != null) { - compareXml(getClass().getResourceAsStream(inputFile), Files.newInputStream(workingDir.resolve(IIDM_FILENAME))); + assertXmlEquals(getClass().getResourceAsStream(inputFile), Files.newInputStream(workingDir.resolve(IIDM_FILENAME))); } if (contingencyFile != null) { InputStream contingencyIs = Objects.requireNonNull(getClass().getResourceAsStream(contingencyFile)); - compareTxt(contingencyIs, Files.newInputStream(workingDir.resolve("contingencies.json"))); + assertTxtEquals(contingencyIs, Files.newInputStream(workingDir.resolve("contingencies.json"))); } } @@ -120,25 +115,25 @@ void test() throws IOException { LocalCommandExecutor commandExecutor = new LocalCommandExecutorMock("/dynawo_version.out", "/SecurityAnalysis/input.xiidm", "/SecurityAnalysis/contingencies.json", contingencyIds, List.of("/SecurityAnalysis/constraints1.xml", "/SecurityAnalysis/constraints2.xml")); - ComputationManager computationManager = new LocalComputationManager(new LocalComputationConfig(fileSystem.getPath("/working-dir"), 1), commandExecutor, ForkJoinPool.commonPool()); - - SecurityAnalysisReport report = SecurityAnalysis.run(network, n -> contingencies, SecurityAnalysisParameters.load(), computationManager); + SecurityAnalysisRunParameters runParameters = new SecurityAnalysisRunParameters() + .setComputationManager(new LocalComputationManager(new LocalComputationConfig(fileSystem.getPath("/working-dir"), 1), commandExecutor, ForkJoinPool.commonPool())); + SecurityAnalysisReport report = SecurityAnalysis.run(network, contingencies, runParameters); SecurityAnalysisResult result = report.getResult(); assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getPreContingencyResult().getStatus()); StringWriter writer = new StringWriter(); SecurityAnalysisResultSerializer.write(result, writer); - compareTxt(Objects.requireNonNull(getClass().getResourceAsStream("/SecurityAnalysis/result.json")), writer.toString()); + assertTxtEquals(Objects.requireNonNull(getClass().getResourceAsStream("/SecurityAnalysis/result.json")), writer.toString()); } @Test void testCallingBadVersionDynawo() throws IOException { Network network = Network.create("test", "test"); - ContingenciesProvider contingenciesProvider = n -> List.of(); LocalCommandExecutor commandExecutor = new LocalCommandExecutorMock("/dynawo_bad_version.out", null); - ComputationManager computationManager = new LocalComputationManager(new LocalComputationConfig(fileSystem.getPath("/working-dir"), 1), commandExecutor, ForkJoinPool.commonPool()); - SecurityAnalysisParameters sap = SecurityAnalysisParameters.load(); - assertThrows(PowsyblException.class, () -> SecurityAnalysis.run(network, contingenciesProvider, sap, computationManager)); + SecurityAnalysisRunParameters runParameters = new SecurityAnalysisRunParameters() + .setComputationManager(new LocalComputationManager(new LocalComputationConfig(fileSystem.getPath("/working-dir"), 1), commandExecutor, ForkJoinPool.commonPool())); + List contingencies = List.of(); + assertThrows(PowsyblException.class, () -> SecurityAnalysis.run(network, contingencies, runParameters)); } private static Network buildNetwork() { diff --git a/dynaflow/src/test/resources/output.xiidm b/dynaflow/src/test/resources/output.xiidm index e5fc1fabe..8a22372d9 100644 --- a/dynaflow/src/test/resources/output.xiidm +++ b/dynaflow/src/test/resources/output.xiidm @@ -1,5 +1,5 @@ - + diff --git a/dynaflow/src/test/resources/outputMergedLoads.xiidm b/dynaflow/src/test/resources/outputMergedLoads.xiidm index 57e61ecff..ac485a0ec 100644 --- a/dynaflow/src/test/resources/outputMergedLoads.xiidm +++ b/dynaflow/src/test/resources/outputMergedLoads.xiidm @@ -1,5 +1,5 @@ - + diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigsJsonDeserializer.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigsJsonDeserializer.java index c008aeb85..c34cdcd46 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigsJsonDeserializer.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigsJsonDeserializer.java @@ -29,7 +29,7 @@ public ModelConfigsJsonDeserializer() { public Map deserialize(JsonParser parser, DeserializationContext context) throws IOException { Map configMap = new HashMap<>(); while (parser.nextToken() != JsonToken.END_OBJECT) { - String category = parser.getCurrentName(); + String category = parser.currentName(); parser.nextToken(); configMap.put(category, parseModelConfigs(parser)); } @@ -66,7 +66,7 @@ private static ModelConfig parseModelConfig(JsonParser parser) { List properties = Collections.emptyList(); }; JsonUtil.parseObject(parser, name -> - switch (parser.getCurrentName()) { + switch (parser.currentName()) { case "lib" -> { parsingContext.lib = parser.nextTextValue(); yield true; diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/JobsXml.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/JobsXml.java index d0ec6e1fb..67c56091f 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/JobsXml.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/JobsXml.java @@ -81,8 +81,8 @@ private static void writeModeler(XMLStreamWriter writer, DynaWaltzContext contex private static void writeSimulation(XMLStreamWriter writer, DynaWaltzContext context) throws XMLStreamException { writer.writeEmptyElement(DYN_URI, "simulation"); - writer.writeAttribute("startTime", Integer.toString(context.getParameters().getStartTime())); - writer.writeAttribute("stopTime", Integer.toString(context.getParameters().getStopTime())); + writer.writeAttribute("startTime", Double.toString(context.getParameters().getStartTime())); + writer.writeAttribute("stopTime", Double.toString(context.getParameters().getStopTime())); writer.writeAttribute("precision", Double.toString(context.getDynaWaltzParameters().getPrecision())); } diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/AbstractDynamicModelXmlTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/AbstractDynamicModelXmlTest.java index c92778183..390cd2d87 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/AbstractDynamicModelXmlTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/AbstractDynamicModelXmlTest.java @@ -35,7 +35,7 @@ import java.util.List; import java.util.Objects; -import static com.powsybl.commons.test.ComparisonUtils.compareTxt; +import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -73,7 +73,7 @@ public void validate(String schemaDefinition, String expectedResourceName, Path Schema schema = factory.newSchema(xsd); Validator validator = schema.newValidator(); validator.validate(xml); - compareTxt(expected, actual); + assertTxtEquals(expected, actual); } void setupDynawaltzContext() { diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/AbstractParametrizedDynamicModelXmlTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/AbstractParametrizedDynamicModelXmlTest.java index c0a138037..4c4016698 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/AbstractParametrizedDynamicModelXmlTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/AbstractParametrizedDynamicModelXmlTest.java @@ -30,7 +30,7 @@ import java.util.List; import java.util.Objects; -import static com.powsybl.commons.test.ComparisonUtils.compareTxt; +import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; /** * @author Laurent Issertial {@literal } @@ -52,7 +52,7 @@ public void validate(String schemaDefinition, String expectedResourceName, Path Schema schema = factory.newSchema(xsd); Validator validator = schema.newValidator(); validator.validate(xml); - compareTxt(expected, actual); + assertTxtEquals(expected, actual); } void setupDynawaltzContext() { diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java index 52f7048c4..b57d27a61 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java @@ -37,7 +37,7 @@ import java.util.List; import java.util.Objects; -import static com.powsybl.commons.test.ComparisonUtils.compareTxt; +import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; /** * @author Marcos de Miguel {@literal } @@ -161,7 +161,7 @@ public void validate(String schemaDefinition, String expectedResourceName, Path Schema schema = factory.newSchema(xsd); Validator validator = schema.newValidator(); validator.validate(xml); - compareTxt(Objects.requireNonNull(getClass().getResourceAsStream("/" + expectedResourceName)), Files.newInputStream(xmlFile)); + assertTxtEquals(Objects.requireNonNull(getClass().getResourceAsStream("/" + expectedResourceName)), Files.newInputStream(xmlFile)); } private static Network createEurostagTutorialExample1WithMoreLoads() { diff --git a/dynawaltz/src/test/resources/DynaWaltzParameters.json b/dynawaltz/src/test/resources/DynaWaltzParameters.json index fdcdb051c..bb2be0ef0 100644 --- a/dynawaltz/src/test/resources/DynaWaltzParameters.json +++ b/dynawaltz/src/test/resources/DynaWaltzParameters.json @@ -1,7 +1,7 @@ { "version" : "1.0", - "startTime" : 0, - "stopTime" : 3600, + "startTime" : 0.0, + "stopTime" : 3600.0, "extensions" : { "DynaWaltzParameters" : { "networkParameters" : { diff --git a/dynawaltz/src/test/resources/jobs.xml b/dynawaltz/src/test/resources/jobs.xml index 363d4f347..932f6e78f 100644 --- a/dynawaltz/src/test/resources/jobs.xml +++ b/dynawaltz/src/test/resources/jobs.xml @@ -8,7 +8,7 @@ - + diff --git a/dynawaltz/src/test/resources/jobsWithDump.xml b/dynawaltz/src/test/resources/jobsWithDump.xml index 3456cb08c..9cb41ea07 100644 --- a/dynawaltz/src/test/resources/jobsWithDump.xml +++ b/dynawaltz/src/test/resources/jobsWithDump.xml @@ -9,7 +9,7 @@ - + diff --git a/dynawaltz/src/test/resources/mergedLoads.xiidm b/dynawaltz/src/test/resources/mergedLoads.xiidm index ee99c90c6..668158686 100644 --- a/dynawaltz/src/test/resources/mergedLoads.xiidm +++ b/dynawaltz/src/test/resources/mergedLoads.xiidm @@ -1,5 +1,5 @@ - + diff --git a/dynawaltz/src/test/resources/noMergedLoads.xiidm b/dynawaltz/src/test/resources/noMergedLoads.xiidm index 048ca7153..87a77c7aa 100644 --- a/dynawaltz/src/test/resources/noMergedLoads.xiidm +++ b/dynawaltz/src/test/resources/noMergedLoads.xiidm @@ -1,5 +1,5 @@ - + diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java index 06755bfb1..70f8cc6eb 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java @@ -10,7 +10,6 @@ import com.powsybl.commons.datasource.ResourceDataSource; import com.powsybl.commons.datasource.ResourceSet; import com.powsybl.commons.report.ReportNode; -import com.powsybl.commons.test.ComparisonUtils; import com.powsybl.commons.test.TestUtil; import com.powsybl.contingency.Contingency; import com.powsybl.dynaflow.DynaFlowConfig; @@ -23,10 +22,9 @@ import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.loadflow.LoadFlowResult; -import com.powsybl.security.LimitViolationFilter; import com.powsybl.security.SecurityAnalysisParameters; import com.powsybl.security.SecurityAnalysisResult; -import com.powsybl.security.detectors.DefaultLimitViolationDetector; +import com.powsybl.security.SecurityAnalysisRunParameters; import com.powsybl.security.json.SecurityAnalysisResultSerializer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -36,10 +34,10 @@ import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Path; -import java.util.Collections; import java.util.List; import java.util.Objects; +import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; import static com.powsybl.loadflow.LoadFlowResult.ComponentResult.Status.CONVERGED; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -125,9 +123,11 @@ void testSaBb() throws IOException { .toList(); ReportNode reportNode = ReportNode.newRootReportNode().withMessageTemplate("root", "Root message").build(); - SecurityAnalysisResult result = securityAnalysisProvider.run(network, VariantManagerConstants.INITIAL_VARIANT_ID, new DefaultLimitViolationDetector(), - new LimitViolationFilter(), computationManager, securityAnalysisParameters, n -> contingencies, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), reportNode) + SecurityAnalysisRunParameters runParameters = new SecurityAnalysisRunParameters() + .setComputationManager(computationManager) + .setSecurityAnalysisParameters(securityAnalysisParameters) + .setReportNode(reportNode); + SecurityAnalysisResult result = securityAnalysisProvider.run(network, VariantManagerConstants.INITIAL_VARIANT_ID, n -> contingencies, runParameters) .join() .getResult(); @@ -141,7 +141,7 @@ void testSaBb() throws IOException { StringWriter serializedResult = new StringWriter(); SecurityAnalysisResultSerializer.write(result, serializedResult); InputStream expected = Objects.requireNonNull(getClass().getResourceAsStream("/ieee14/security-analysis/sa_bb_results.json")); - ComparisonUtils.compareTxt(expected, serializedResult.toString()); + assertTxtEquals(expected, serializedResult.toString()); } @Test @@ -151,15 +151,16 @@ void testSaNb() throws IOException { List contingencies = network.getGeneratorStream() .map(g -> Contingency.generator(g.getId())) .toList(); - SecurityAnalysisResult result = securityAnalysisProvider.run(network, VariantManagerConstants.INITIAL_VARIANT_ID, new DefaultLimitViolationDetector(), - new LimitViolationFilter(), computationManager, securityAnalysisParameters, n -> contingencies, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), ReportNode.NO_OP) + SecurityAnalysisRunParameters runParameters = new SecurityAnalysisRunParameters() + .setComputationManager(computationManager) + .setSecurityAnalysisParameters(securityAnalysisParameters); + SecurityAnalysisResult result = securityAnalysisProvider.run(network, VariantManagerConstants.INITIAL_VARIANT_ID, n -> contingencies, runParameters) .join() .getResult(); StringWriter serializedResult = new StringWriter(); SecurityAnalysisResultSerializer.write(result, serializedResult); InputStream expected = Objects.requireNonNull(getClass().getResourceAsStream("/ieee14/security-analysis/sa_nb_results.json")); - ComparisonUtils.compareTxt(expected, serializedResult.toString()); + assertTxtEquals(expected, serializedResult.toString()); } } diff --git a/pom.xml b/pom.xml index 1ea98d84e..99c49ebeb 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 17 - 6.3.0 + 6.4.0-RC2 4.0.14 ../distribution/target/site/jacoco-aggregate/jacoco.xml, @@ -107,7 +107,7 @@ com.powsybl powsybl-core - ${powsyblcore.version} + ${powsybl-core.version} pom import