diff --git a/.github/workflows/doc-preview-cleanup.yml b/.github/workflows/doc-preview-cleanup.yml
new file mode 100644
index 000000000..7fb591415
--- /dev/null
+++ b/.github/workflows/doc-preview-cleanup.yml
@@ -0,0 +1,35 @@
+name: Doc Preview Cleanup
+
+on:
+ pull_request:
+ types: [closed]
+
+# Ensure that only one "Doc Preview Cleanup" workflow is force pushing at a time
+concurrency:
+ group: doc-preview-cleanup
+ cancel-in-progress: false
+
+jobs:
+ doc-preview-cleanup:
+ runs-on: ubuntu-latest
+ if: github.event.pull_request.head.repo.fork == false
+ # This workflow pushes to gh-pages; permissions are per-job and independent of docs.yml
+ permissions:
+ contents: write
+ steps:
+ - name: Checkout gh-pages branch
+ uses: actions/checkout@v4
+ with:
+ ref: gh-pages
+ - name: Delete preview and history + push changes
+ run: |
+ if [ -d "${preview_dir}" ]; then
+ git config user.name "Documenter.jl"
+ git config user.email "documenter@juliadocs.github.io"
+ git rm -rf "${preview_dir}"
+ git commit -m "delete preview"
+ git branch gh-pages-new "$(echo "delete history" | git commit-tree "HEAD^{tree}")"
+ git push --force origin gh-pages-new:gh-pages
+ fi
+ env:
+ preview_dir: previews/PR${{ github.event.number }}
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index f68a56b7d..cf1475cf3 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -18,6 +18,16 @@ jobs:
version: 1
- name: Install dependencies
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
+
+ - name: Set DOCUMENTER_CURRENT_VERSION for tutorial download links
+ run: |
+ if [[ "${{ github.event_name }}" == "pull_request" ]]; then
+ echo "DOCUMENTER_CURRENT_VERSION=previews/PR${{ github.event.pull_request.number }}" >> "$GITHUB_ENV"
+ elif [[ "${{ github.ref }}" == refs/tags/* ]]; then
+ echo "DOCUMENTER_CURRENT_VERSION=${GITHUB_REF_NAME}" >> "$GITHUB_ENV"
+ elif [[ "${{ github.ref }}" == "refs/heads/main" ]] || [[ "${{ github.ref }}" =~ ^refs/heads/release- ]]; then
+ echo "DOCUMENTER_CURRENT_VERSION=dev" >> "$GITHUB_ENV"
+ fi
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 000000000..2cdcf3837
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,9 @@
+repos:
+ - repo: local
+ hooks:
+ - id: julia-formatter
+ name: Run Julia formatter
+ entry: julia scripts/formatter/formatter_code.jl
+ language: system
+ types: [file]
+ pass_filenames: false
diff --git a/docs/Project.toml b/docs/Project.toml
index 85dae0c28..7d9b05862 100644
--- a/docs/Project.toml
+++ b/docs/Project.toml
@@ -2,6 +2,7 @@
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
+DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656"
DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
diff --git a/docs/make.jl b/docs/make.jl
index 291cda1f7..51d8dc457 100644
--- a/docs/make.jl
+++ b/docs/make.jl
@@ -1,14 +1,22 @@
using Documenter, PowerSystems, DocStringExtensions, PowerSimulationsDynamics
-
-const _DOCS_BASE_URL = "https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable"
+using DocumenterInterLinks
include(joinpath(@__DIR__, "make_tutorials.jl"))
make_tutorials()
+links = InterLinks(
+ "PowerSystems" => "https://sienna-platform.github.io/PowerSystems.jl/stable/",
+ "PowerSystemCaseBuilder" => "https://sienna-platform.github.io/PowerSystemCaseBuilder.jl/stable/",
+)
+
makedocs(;
modules = [PowerSimulationsDynamics],
- format = Documenter.HTML(; mathengine = Documenter.MathJax()),
+ format = Documenter.HTML(;
+ prettyurls = haskey(ENV, "GITHUB_ACTIONS"),
+ mathengine = Documenter.MathJax(),
+ ),
sitename = "PowerSimulationsDynamics.jl",
+ plugins = [links],
pages = Any[
"Welcome Page" => "index.md",
"Quick Start Guide" => "tutorials/generated_quick_start_guide.md",
diff --git a/docs/make_tutorials.jl b/docs/make_tutorials.jl
index 14b01e4d6..0c7c19951 100644
--- a/docs/make_tutorials.jl
+++ b/docs/make_tutorials.jl
@@ -3,40 +3,50 @@ using Literate
using DataFrames
using PrettyTables
-# Override show for DataFrames to limit output size during doc builds
-# This ensures large DataFrames are truncated when displayed as expression results in @example blocks
-# Explicit show() calls in tutorials with their own arguments are NOT affected (they use their own kwargs)
-# We override both text/plain and text/html since Documenter may use either
-#
-# Strategy: Call PrettyTables.pretty_table directly with explicit row/column limits.
-# This bypasses DataFrames' default display logic and gives us full control.
-
-function Base.show(io::IO, mime::MIME"text/plain", df::DataFrame)
- # Call PrettyTables directly with row/column limits
- # This ensures only 10 rows are shown regardless of DataFrame size
+# Limit DataFrame rendering during docs generation to avoid huge literal outputs.
+# Notes:
+# - Environment-variable approaches tested (`DATAFRAMES_ROWS`, `DATAFRAMES_COLUMNS`,
+# `LINES`, `COLUMNS`) did not constrain DataFrames output in this pipeline.
+# - We keep a docs-local Base.show override as a fallback and accept `kwargs...`
+# so explicit show(...; kwargs) calls do not error on unsupported keywords.
+function _env_int(name::String, default::Int)
+ parsed = tryparse(Int, get(ENV, name, string(default)))
+ return something(parsed, default)
+end
+
+const _DF_MAX_ROWS = _env_int("SIENNA_DOCS_DF_MAX_ROWS", 10)
+const _DF_MAX_COLS = _env_int("SIENNA_DOCS_DF_MAX_COLS", 80)
+
+function Base.show(io::IO, mime::MIME"text/plain", df::DataFrame; kwargs...)
+ # Keep docs output bounded while allowing explicit caller kwargs.
PrettyTables.pretty_table(io, df;
backend = :text,
- maximum_number_of_rows = 10,
- maximum_number_of_columns = 80,
- #display_size = (10, 80), # Show only 10 rows and 80 columns
+ maximum_number_of_rows = _DF_MAX_ROWS,
+ maximum_number_of_columns = _DF_MAX_COLS,
show_omitted_cell_summary = true,
compact_printing = false,
- limit_printing = true)
+ limit_printing = true,
+ kwargs...)
end
-function Base.show(io::IO, mime::MIME"text/html", df::DataFrame)
- # For HTML output (which Documenter prefers for large outputs)
- # Use PrettyTables HTML backend with explicit row/column limits
+function Base.show(io::IO, mime::MIME"text/html", df::DataFrame; kwargs...)
PrettyTables.pretty_table(io, df;
backend = :html,
- maximum_number_of_rows = 10,
- maximum_number_of_columns = 80,
+ maximum_number_of_rows = _DF_MAX_ROWS,
+ maximum_number_of_columns = _DF_MAX_COLS,
show_omitted_cell_summary = true,
compact_printing = false,
- limit_printing = true)
+ limit_printing = true,
+ kwargs...)
end
-# Function to clean up old generated files
+# Remove previously generated tutorial artifacts so a docs build only reflects
+# current source tutorials.
+#
+# Input:
+# - dir: tutorial output directory that can contain generated_*.md/ipynb.
+# Output:
+# - Deletes matching files in-place and logs each deletion.
function clean_old_generated_files(dir::String)
if !isdir(dir)
@warn "Directory does not exist: $dir"
@@ -58,12 +68,77 @@ end
# Literate post-processing functions for tutorial generation
#########################################################
-# postprocess function to insert md
+# Compute docs base URL from Documenter deploy context.
+#
+# Behavior:
+# - previews/PR123 -> .../previews/PR123
+# - dev (or custom DOCUMENTER_DEVURL) -> .../dev
+# - tagged versions like v0.9 -> .../v0.9
+# - fallback -> .../stable
+#
+# This keeps generated download/view-online links correct across preview, dev,
+# tagged, and stable deployments.
+function _compute_docs_base_url()
+ base = "https://sienna-platform.github.io/PowerSimulationsDynamics.jl"
+
+ current_version = get(ENV, "DOCUMENTER_CURRENT_VERSION", "")
+
+ # Preview builds (e.g. "previews/PR123")
+ if startswith(current_version, "previews/PR")
+ return "$base/$current_version"
+ end
+
+ # Dev builds
+ if current_version == "dev"
+ dev_suffix = get(ENV, "DOCUMENTER_DEVURL", "dev")
+ return "$base/$dev_suffix"
+ end
+
+ # Tagged/versioned builds (e.g. "v0.9", "v1.2.3")
+ if !isempty(current_version) && current_version != "stable"
+ return "$base/$current_version"
+ end
+
+ # Default to stable
+ return "$base/stable"
+end
+
+const _DOCS_BASE_URL = _compute_docs_base_url()
+
+"""
+Choose how tutorial download links are written in generated markdown.
+
+- **Absolute** (under `_DOCS_BASE_URL/tutorials/`): CI / Documenter context (`GITHUB_ACTIONS` or
+ non-empty `DOCUMENTER_CURRENT_VERSION`) so previews, `dev`, and versioned URLs match
+ `_compute_docs_base_url()`.
+- **Relative** (bare filenames): local/offline builds; files sit next to `generated_*.md`
+ under `docs/src/tutorials/`.
+
+Override: `SIENNA_DOCS_DOWNLOAD_LINKS`=`absolute` or `relative`.
+"""
+function _downloads_use_absolute_urls()
+ o = get(ENV, "SIENNA_DOCS_DOWNLOAD_LINKS", "")
+ o == "absolute" && return true
+ o == "relative" && return false
+ haskey(ENV, "GITHUB_ACTIONS") && return true
+ !isempty(get(ENV, "DOCUMENTER_CURRENT_VERSION", "")) && return true
+ return false
+end
+
+# Replace APPEND_MARKDOWN("path/to/file.md") placeholders with file contents.
+#
+# Sample input:
+# "Before\nAPPEND_MARKDOWN(\"docs/src/tutorials/_snippet.md\")\nAfter"
+# Sample output:
+# "Before\n
wrapper) - text = replace( - text, - r"(?:
]*>[\s\S]*?|```@raw html[\s\S]*?```|!\[[^\]]*\]\([^\)]*\)|
]*?/?>)" =>
- append_after,
+ # If the cell has any of the image shapes below, we append one "view online" note.
+ # We build one alternation pattern from sub-patterns (each line is one case).
+ #
+ # HTML paragraph wrapping an
(Literate often emits
……
]*> — opening
and attributes
+ # [\s\S]*? — any chars, non-greedy, up to the first — from
+ p_with_img_pattern = r"
]*>[\s\S]*?"
+ # Documenter @raw html chunk that Literate inlines in the notebook (backticks removed in output).
+ # ```@raw html — start marker
+ # [\s\S]*? — block body, non-greedy
+ # ``` — end fence
+ raw_html_block_pattern = r"```@raw html[\s\S]*?```"
+ # Standard markdown image: 
+ # !\[…\] — alt in brackets; \(…\) — path in parens
+ markdown_image_pattern = r"!\[[^\]]*\]\([^\)]*\)"
+ # A bare
not already covered by the
……
-``` ⠀
+```
An important thing to consider with the industrial models, is that the change of Flags can significantly vary the model and purpose of the controller.
@@ -32,8 +32,7 @@ Similar to the active controller, the following figure presents the reactive con
```@raw html
-``` ⠀
-
+```
### Inner Controller
@@ -41,7 +40,7 @@ Finally, the remaining part from [REECB](https://www.powerworld.com/WebHelp/Cont
```@raw html
-``` ⠀
+```
The [REGCA](https://www.powerworld.com/WebHelp/Content/TransientModels_HTML/Machine%20Model%20REGC_A.htm)model was directly included in a Converter Block, and the filter can be bypassed using an `RLFilter` block with `rf = lf = 0`.
@@ -56,10 +55,10 @@ For the active controller, both `Freq_Flag = 0` (ignoring frequency regulation)
The following table describes the current available combination of flags in PSID:
| `REF_Flag` | `PF_Flag` | `V_Flag` | `Q_Flag` |
-|:--------:|:-------:|:------:|:------:|
-| 0 | 0 | 0 | 0 |
-| 0 | 0 | 1 | 0 |
-| 1 | 0 | 1 | 1 |
-| 1 | 0 | 0 | 0 |
+|:----------:|:---------:|:--------:|:--------:|
+| 0 | 0 | 0 | 0 |
+| 0 | 0 | 1 | 0 |
+| 1 | 0 | 1 | 1 |
+| 1 | 0 | 0 | 0 |
-Any combination outside of these cases may not converge to a feasible operating point. Check the following [CAISO report](http://www.caiso.com/Documents/InverterBasedInterconnectionRequestsIBRDynamicModelReviewGuideline.pdf) for the description and compliance of each flag combination.
\ No newline at end of file
+Any combination outside of these cases may not converge to a feasible operating point. Check the following [CAISO report](http://www.caiso.com/Documents/InverterBasedInterconnectionRequestsIBRDynamicModelReviewGuideline.pdf) for the description and compliance of each flag combination.
diff --git a/docs/src/index.md b/docs/src/index.md
index 987c053e1..92f85fc70 100644
--- a/docs/src/index.md
+++ b/docs/src/index.md
@@ -27,20 +27,6 @@ year={2023}
}
```
-## Installation
-
-The latest stable release of PowerSimulationsDynamics.jl can be installed using the Julia package manager with
-
-```julia
-] add PowerSimulationsDynamics
-```
-
-For the current development version, "checkout" this package with
-
-```julia
-] add PowerSimulationsDynamics#master
-```
-
## Structure
The following figure shows the interactions between `PowerSimulationsDynamics.jl`, `PowerSystems.jl`, `ForwardDiff.jl`, `DiffEqBase.jl` and the integrators.
@@ -53,9 +39,29 @@ BDF and Rosenbrock methods.
```@raw html
-``` ⠀
+```
+
+## About Sienna
+
+`PowerSimulationsDynamics.jl` is part of the National Laboratory of the Rockies (formerly known as NREL)'s
+[Sienna ecosystem](https://sienna-platform.github.io/Sienna/), an open source framework for
+power system modeling, simulation, and optimization. The Sienna ecosystem can be
+[found on Github](https://github.com/Sienna-Platform/). It contains three applications:
+
+ - [Sienna\Data](https://sienna-platform.github.io/Sienna/pages/applications/sienna_data.html) enables
+ efficient data input, analysis, and transformation
+ - [Sienna\Ops](https://sienna-platform.github.io/Sienna/pages/applications/sienna_ops.html) enables
+ enables system scheduling simulations by formulating and solving optimization problems
+ - [Sienna\Dyn](https://sienna-platform.github.io/Sienna/pages/applications/sienna_dyn.html) enables
+ system transient analysis including small signal stability and full system dynamic
+ simulations
+
+Each application uses multiple packages in the [`Julia`](http://www.julialang.org)
+programming language.
+
+## Installation and Quick Links
-------------
-PowerSimulationsDynamics.jl has been developed as part of the Scalable Integrated Infrastructure Planning
-(SIIP) initiative at the U.S. Department of Energy's National Renewable Energy
-Laboratory ([NREL](https://www.nrel.gov/))
+ - [Sienna installation page](https://sienna-platform.github.io/Sienna/SiennaDocs/docs/build/how-to/install/):
+ Instructions to install `PowerSimulationsDynamics.jl` and other Sienna\Dyn packages
+ - [Sienna Documentation Hub](https://sienna-platform.github.io/Sienna/SiennaDocs/docs/build/index.html):
+ Links to other Sienna packages' documentation
diff --git a/docs/src/initialization.md b/docs/src/initialization.md
index d32f92d89..d41a6ad05 100644
--- a/docs/src/initialization.md
+++ b/docs/src/initialization.md
@@ -26,16 +26,17 @@ inner vars. `PowerSimulationsDynamics.jl` handles all this initializations by de
## Initialization interface
By default `PowerSimulationsDynamics.jl` initializes the system following the steps described below.
-it is possible to provide an initial guess for the initial conditions to speed up the initialization process.
+It is possible to provide an initial guess for the initial conditions to speed up the initialization process.
+The following uses [`Simulation`](@ref) with [`ResidualModel`](@ref) (other simulation models and kwargs are available in the API reference):
```julia
Simulation(
- ResidualModel,
- sys,
- pwd(),
- (0.0, 20.0);
- initial_conditions = x0_init,
- )
+ ResidualModel,
+ sys,
+ pwd(),
+ (0.0, 20.0);
+ initial_conditions = x0_init,
+)
```
It is also possible to initialize the simulation using a flat start (`V_mag = 1.0`, `V_angle = 0.0` and `x0 = zeros`)
@@ -44,12 +45,12 @@ result in a valid initial condition for the simulation.
```julia
Simulation(
- ResidualModel,
- sys,
- pwd(),
- (0.0, 20.0);
- initialize_simulation = false,
- )
+ ResidualModel,
+ sys,
+ pwd(),
+ (0.0, 20.0);
+ initialize_simulation = false,
+)
```
If you want to avoid `PowerSimulationsDynamics.jl` from finding an stable equilibrium automatically
@@ -57,13 +58,13 @@ and provide the initial condition manually you can use the following flag combin
```julia
Simulation(
- ResidualModel,
- sys,
- pwd(),
- (0.0, 20.0);
- initialize_simulation = false,
- initial_conditions = x0_init,
- )
+ ResidualModel,
+ sys,
+ pwd(),
+ (0.0, 20.0);
+ initialize_simulation = false,
+ initial_conditions = x0_init,
+)
```
*WARNING!*: when the `initialize_simulation` is set to `false`,
@@ -105,19 +106,19 @@ detailed documentation of the process.

-1. The first component to be initialized is the filter. Given that the filter is an RLC
- circuit connected to the grid, its currents and voltages need to match the results of the
- power flow. The initialization of the filter provides the values for the ``P`` and ``Q``
- used in the outer control and the ``V`` and ``I`` needed in the inner controls.
-2. Based on the bus voltage in the system's reference frame ``V_r`` and the bus angle ``\theta``
- the PLL's can be initialized to obtain the angle and frequency estimates needed by the
- outer control.
-3. The Outer Control calculates the internal angle ``\delta_{olc}`` required by the inner control
- to estimate the voltage and current phase difference.
-4. The DC Source uses the power set-point consistent with the power outputs of the filter
- to initialize the ``V_{dc}`` set-points. This value is used in the inner control.
-5. The inner control takes the phase angle ``\delta_{olc}`` and the ``V_{dc}`` to estimate the
- modulation values of the PWM converter.
+ 1. The first component to be initialized is the filter. Given that the filter is an RLC
+ circuit connected to the grid, its currents and voltages need to match the results of the
+ power flow. The initialization of the filter provides the values for the ``P`` and ``Q``
+ used in the outer control and the ``V`` and ``I`` needed in the inner controls.
+ 2. Based on the bus voltage in the system's reference frame ``V_r`` and the bus angle ``\theta``
+ the PLL's can be initialized to obtain the angle and frequency estimates needed by the
+ outer control.
+ 3. The Outer Control calculates the internal angle ``\delta_{olc}`` required by the inner control
+ to estimate the voltage and current phase difference.
+ 4. The DC Source uses the power set-point consistent with the power outputs of the filter
+ to initialize the ``V_{dc}`` set-points. This value is used in the inner control.
+ 5. The inner control takes the phase angle ``\delta_{olc}`` and the ``V_{dc}`` to estimate the
+ modulation values of the PWM converter.
**Note:** The initialization of an inverter through the proposed meta-model is actively under
development and subject to change. This page will maintain the latest version of the sequence.
diff --git a/docs/src/models.md b/docs/src/models.md
index e6d8c84fb..67fe2bc58 100644
--- a/docs/src/models.md
+++ b/docs/src/models.md
@@ -1,13 +1,12 @@
-
# Models
## Simulation Models
-PowerSimulations dynamics supports two formulations for the simulation model and define different methods for each simulation model. You can pass `ResidualModel` or `MassMatrixModel` to a call to Simulation to define the preferred formulation.
+PowerSimulations dynamics supports two formulations for the simulation model and define different methods for each simulation model. You can pass [`ResidualModel`](@ref) or [`MassMatrixModel`](@ref) to a call to [`Simulation`](@ref) to define the preferred formulation.
In this way, we provide a common set of development requirements for contributors of new models that maintains the same flexibility in choosing the solving algorithm.
-- *MassMatrixModel*: Defines models that can be solved using [Mass-Matrix Solvers](https://diffeq.sciml.ai/stable/solvers/dae_solve/#OrdinaryDiffEq.jl-(Mass-Matrix)). The model is formulated as follows:
+ - [`MassMatrixModel`](@ref): Defines models that can be solved using [Mass-Matrix Solvers](https://diffeq.sciml.ai/stable/solvers/dae_solve/#OrdinaryDiffEq.jl-(Mass-Matrix)). The model is formulated as follows:
```math
\begin{align}
@@ -17,8 +16,7 @@ M\frac{dx(t)}{dt} = f(x(t))
At this stage we have not conducted extensive tests with all the solvers in [DifferentialEquations](https://diffeq.sciml.ai/) most of our tests use `Rodas5()`.
-
-- *ResidualModel*: Define models that can be solved using [Implicit ODE solvers](https://diffeq.sciml.ai/stable/solvers/dae_solve/#OrdinaryDiffEq.jl-(Implicit-ODE)) and also the solver IDA from [Sundials](https://diffeq.sciml.ai/stable/solvers/dae_solve/#Sundials.jl). The model is formulated to solved the following problem:
+ - [`ResidualModel`](@ref): Define models that can be solved using [Implicit ODE solvers](https://diffeq.sciml.ai/stable/solvers/dae_solve/#OrdinaryDiffEq.jl-(Implicit-ODE)) and also the solver IDA from [Sundials](https://diffeq.sciml.ai/stable/solvers/dae_solve/#Sundials.jl). The model is formulated to solved the following problem:
```math
\begin{align}
@@ -30,7 +28,7 @@ At this stage we have not conducted extensive tests with all the solvers in [Dif
### The dynamic system model in PowerSimulationsDynamics
-In order to support both formulations, the default implementation of the ResidualModel solves the following problem:
+In order to support both formulations, the default implementation of [`ResidualModel`](@ref) solves the following problem:
```math
\begin{align}
@@ -50,16 +48,16 @@ For more details, check Brian Stott paper ["Power system dynamic response calcul
## Generator Models
-Here we discuss the structure and models used to model generators in `PowerSimulationsDynamics.jl`. See [`PowerSystems.jl` dynamic devices](https://sienna-platform.github.io/PowerSystems.jl/stable/modeler_guide/example_dynamic_data/)
-for details.
+Here we discuss the structure and models used to model generators in `PowerSimulationsDynamics.jl`. See the explanation on [Dynamic Devices](@extref)
+in [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) for details.
-Each generator is a data structure composed of the following components defined in `PowerSystems.jl`:
+Each generator is a data structure composed of the following components defined in [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/):
-- [`Machine`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_Machine/#Machine): That defines the stator electro-magnetic dynamics.
-- [`Shaft`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_Shaft/#Shaft): That describes the rotor electro-mechanical dynamics.
-- [`Automatic Voltage Regulator`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_AVR/#AVR): Electromotive dynamics to model an AVR controller.
-- [`Power System Stabilizer`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_PSS/#PSS): Control dynamics to define an stabilization signal for the AVR.
-- [`Prime Mover and Turbine Governor`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_TurbineGov/#TurbineGov): Thermo-mechanical dynamics and associated controllers.
+ - [`PowerSystems.Machine`](@extref): That defines the stator electro-magnetic dynamics.
+ - [`PowerSystems.Shaft`](@extref): That describes the rotor electro-mechanical dynamics.
+ - [`PowerSystems.AVR`](@extref): Electromotive dynamics to model an AVR controller.
+ - [`PowerSystems.PSS`](@extref): Control dynamics to define an stabilization signal for the AVR.
+ - [`PowerSystems.TurbineGov`](@extref): Thermo-mechanical dynamics and associated controllers.
The implementation of Synchronous generators as components uses the following structure to
share values across components.
@@ -70,16 +68,16 @@ share values across components.
## Inverter Models
-Here we discuss the structure and models used to model inverters in `PowerSimulationsDynamics.jl`. See [`PowerSystems.jl` dynamic devices](https://sienna-platform.github.io/PowerSystems.jl/stable/modeler_guide/example_dynamic_data/)
-for details. One of the key contributions in this software package is a separation of the
+Here we discuss the structure and models used to model inverters in `PowerSimulationsDynamics.jl`. See the explanation on [Dynamic Devices](@extref)
+in [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) for details. One of the key contributions in this software package is a separation of the
components in a way that resembles current practices for synchronoues machine modeling.
-- [`DC Source`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_DCSource/#DCSource): Defines the dynamics of the DC side of the converter.
-- [`Frequency Estimator`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_FrequencyEstimator/#FrequencyEstimator): That describes how the frequency of the grid can be estimated using the grid voltages. Typically a phase-locked loop (PLL).
-- [`Outer Loop Control`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/outer_control/#OuterControl): That describes the active and reactive power control dynamics.
-- [`Inner Loop Control`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_InnerControl/#InnerControl): That can describe virtual impedance, voltage control and current control dynamics.
-- [`Converter`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_Converter/#Converter): That describes the dynamics of the pulse width modulation (PWM) or space vector modulation (SVM).
-- [`Filter`](https://sienna-platform.github.io/PowerSystems.jl/stable/model_library/generated_Filter/): Used to connect the converter output to the grid.
+ - [`PowerSystems.DCSource`](@extref): Defines the dynamics of the DC side of the converter.
+ - [`PowerSystems.FrequencyEstimator`](@extref): That describes how the frequency of the grid can be estimated using the grid voltages. Typically a phase-locked loop (PLL).
+ - [`PowerSystems.OuterControl`](@extref): That describes the active and reactive power control dynamics.
+ - [`PowerSystems.InnerControl`](@extref): That can describe virtual impedance, voltage control and current control dynamics.
+ - [`PowerSystems.Converter`](@extref): That describes the dynamics of the pulse width modulation (PWM) or space vector modulation (SVM).
+ - [`PowerSystems.Filter`](@extref): Used to connect the converter output to the grid.
The following figure summarizes the components of a inverter and which variables they share:
@@ -94,4 +92,4 @@ these posibilities.
## Reference
-For models, check the library in [PowerSystems.jl](https://sienna-platform.github.io/PowerSystems.jl/stable/)
+For models, check the library in [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/).
diff --git a/docs/src/perturbations.md b/docs/src/perturbations.md
index 2c4345ab8..6caea8b20 100644
--- a/docs/src/perturbations.md
+++ b/docs/src/perturbations.md
@@ -4,32 +4,33 @@ Perturbations are used to alter the system from its steady state operation. If a
## List of perturbations
-- [`NetworkSwitch`](@ref): allows to modify directly the admittance matrix, `Ybus`, used in the Simulation.
-- [`BranchTrip`](@ref): completely disconnects a branch from the system.
-- [`BranchImpedanceChange`](@ref): change the impedance of a branch by a user defined multiplier.
-- [`GeneratorTrip`](@ref): allows to disconnect a Dynamic Generation unit from the system.
-- [`ControlReferenceChange`](@ref): allows to change the reference setpoint provided by a generator/inverter.
-- [`LoadChange`](@ref): allows to change the active or reactive power setpoint from a load.
-- [`LoadTrip`](@ref): allows the user to disconnect a load from the system.
-- [`SourceBusVoltageChange`](@ref): allows to change the reference setpoint provided by a voltage source.
+ - [`NetworkSwitch`](@ref): allows to modify directly the admittance matrix, `Ybus`, used in the Simulation.
+ - [`BranchTrip`](@ref): completely disconnects a branch from the system.
+ - [`BranchImpedanceChange`](@ref): change the impedance of a branch by a user defined multiplier.
+ - [`GeneratorTrip`](@ref): allows to disconnect a Dynamic Generation unit from the system.
+ - [`ControlReferenceChange`](@ref): allows to change the reference setpoint provided by a generator/inverter.
+ - [`LoadChange`](@ref): allows to change the active or reactive power setpoint from a load.
+ - [`LoadTrip`](@ref): allows the user to disconnect a load from the system.
+ - [`SourceBusVoltageChange`](@ref): allows to change the reference setpoint provided by a voltage source.
## Examples
-### Example 1: Circuit Disconnection using `NetworkSwitch`
+### Example 1: Circuit Disconnection using [`NetworkSwitch`](@ref)
Consider a two bus system connected via a double circuit line, on which each circuit has parameters, `r = 0.0, x = 0.1, b = 0.0` per unit, then the admittance matrix of the original system is given by:
```julia
-yb = [0.0 - 20.0im 0.0 + 20.0im
- 0.0 + 20.0im 0.0 - 20.0im]
+yb = [0.0-20.0im 0.0+20.0im
+ 0.0+20.0im 0.0-20.0im]
```
Triping one circuit can be modeled by doubling the impedance, i.e., dividing by 2 the admittance:
```julia
-new_yb = [0.0 - 10.0im 0.0 + 10.0im
- 0.0 + 10.0im 0.0 - 10.0im]
+new_yb = [0.0-10.0im 0.0+10.0im
+ 0.0+10.0im 0.0-10.0im]
```
+
To apply a Network Switch, we require to use a sparse matrix, so we can do this by simply:
```julia
@@ -38,18 +39,20 @@ new_yb = sparse(new_yb)
```
Then, this perturbation ocurring at ``t = 1.0`` seconds can be included as:
+
```julia
ns1 = NetworkSwitch(1.0, new_yb)
```
-### Example 2: Three Phase Fault using `NetworkSwitch`
+### Example 2: Three Phase Fault using [`NetworkSwitch`](@ref)
Another perturbation that can be modeled is a three phase fault at Bus 1 with impedance `r_f = 0.0001, x_f = 0.0` per unit, then the admittance of this new system is:
```julia
-new_yb2 = [10000.0 - 20.0im 0.0 + 20.0im
- 0.0 + 20.0im 0.0 - 20.0im]
+new_yb2 = [10000.0-20.0im 0.0+20.0im
+ 0.0+20.0im 0.0-20.0im]
```
+
Then, this perturbation ocurring at ``t = 1.0`` seconds can be included as:
```julia
@@ -60,8 +63,8 @@ ns2 = NetworkSwitch(1.0, new_yb2)
Now, consider that the fault is cleared at ``t = 1.05`` seconds by disconnecting the Circuit 2 of the line. This can be modeled with the single circuit admittance matrix:
```julia
-new_yb3 = [0.0 - 10.0im 0.0 + 10.0im
- 0.0 + 10.0im 0.0 - 10.0im]
+new_yb3 = [0.0-10.0im 0.0+10.0im
+ 0.0+10.0im 0.0-10.0im]
```
and the perturbation as:
@@ -79,8 +82,7 @@ three_fault = [ns2, ns3]
that can be passed as a perturbation argument in the Simulation construction.
-
-### Example 3: `BranchTrip`
+### Example 3: [`BranchTrip`](@ref)
Consider the following 2 bus system defined by:
@@ -91,29 +93,29 @@ buses = [
]
line1 = Line(
- "Circuit1",
- true,
- 0.0,
- 0.0,
- Arc(from = buses[1], to = buses[2]),
- 0.00,
- 0.1,
- (from = 0.0, to = 0.0),
- 2.0,
- (min = -0.7, max = 0.7),
- )
+ "Circuit1",
+ true,
+ 0.0,
+ 0.0,
+ Arc(; from = buses[1], to = buses[2]),
+ 0.00,
+ 0.1,
+ (from = 0.0, to = 0.0),
+ 2.0,
+ (min = -0.7, max = 0.7),
+)
line2 = Line(
- "Circuit2",
- true,
- 0.0,
- 0.0,
- Arc(from = buses[1], to = buses[2]),
- 0.0,
- 0.1,
- (from = 0.0, to = 0.0),
- 2.0,
- (min = -0.7, max = 0.7),
- )
+ "Circuit2",
+ true,
+ 0.0,
+ 0.0,
+ Arc(; from = buses[1], to = buses[2]),
+ 0.0,
+ 0.1,
+ (from = 0.0, to = 0.0),
+ 2.0,
+ (min = -0.7, max = 0.7),
+)
sys = System(100.0, buses, [], [], [line1, line2])
```
@@ -124,16 +126,17 @@ A Branch Trip of Circuit 2 at time ``t = 1.0`` seconds, can be implemented as:
b_trip = BranchTrip(1.0, Line, "Circuit2")
```
-**Note:** Islanding is currently not supported in `PowerSimulationsDynamics.jl`. If a `BranchTrip` isolates a generation unit, the system may diverge due to the isolated generator.
+**Note:** Islanding is currently not supported in `PowerSimulationsDynamics.jl`. If a [`BranchTrip`](@ref) isolates a generation unit, the system may diverge due to the isolated generator.
-### Example 4: `BranchImpedanceChange`
+### Example 4: [`BranchImpedanceChange`](@ref)
Following the same example as before, it is possible to amplify the impedance of a single circuit by 2.0 (that would represent that this Circuit is actually composed by 2 circuits) using the following perturbation:
+
```julia
b_change = BranchImpedanceChange(1.0, Line, "Circuit2", 2.0)
```
-### Example 5: `GeneratorTrip`
+### Example 5: [`GeneratorTrip`](@ref)
Consider that you have a generator at bus 102, named `"generator-102-1"` in your system called `sys`. The constructor to trip it from the system is:
@@ -141,7 +144,8 @@ Consider that you have a generator at bus 102, named `"generator-102-1"` in your
g = get_component(DynamicGenerator, sys, "generator-102-1")
g_trip = GeneratorTrip(1.0, g)
```
-### Example 6: `ControlReferenceChange`
+
+### Example 6: [`ControlReferenceChange`](@ref)
Consider that you have a generator at bus 102, named `"generator-102-1"` in your system called `sys`. The constructor to change is active power reference to `0.5` is:
@@ -150,7 +154,7 @@ g = get_component(DynamicGenerator, sys, "generator-102-1")
crc = ControlReferenceChange(1.0, g, :P_ref, 0.5)
```
-### Example 7: `LoadChange`
+### Example 7: [`LoadChange`](@ref)
Consider that you have a load at bus 103, named `"load-103-1"` in your system called `sys`. The constructor to change is active power reference to `0.8` per unit at ``t = 1.0`` seconds is:
@@ -159,7 +163,7 @@ l_device = get_component(ElectricLoad, sys, "load-103-1")
l_change = LoadChange(1.0, l_device, :P_ref, 0.8)
```
-### Example 8: `LoadTrip`
+### Example 8: [`LoadTrip`](@ref)
Consider that you have a load at bus 103, named `"load-103-1"` in your system called `sys`. The constructor to disconnect such load at ``t = 1.0`` seconds is:
@@ -168,11 +172,11 @@ l_device = get_component(ElectricLoad, sys, "load-103-1")
l_trip = LoadTrip(1.0, l_device)
```
-### Example 9: `SourceBusVoltageChange`
+### Example 9: [`SourceBusVoltageChange`](@ref)
Consider that you have a voltage source at bus 101, named `"source-101-1"` in your system called `sys`. The constructor to change is voltage magnitude reference to `1.02` per unit at ``t = 1.0`` seconds is:
```julia
s_device = get_component(Source, sys, "source-101-1")
s_change = SourceBusVoltageChange(1.0, s_device, 1, 1.02)
-```
\ No newline at end of file
+```
diff --git a/docs/src/reference_frames.md b/docs/src/reference_frames.md
index a76c7f75f..abb72db72 100644
--- a/docs/src/reference_frames.md
+++ b/docs/src/reference_frames.md
@@ -31,7 +31,7 @@ frame.
The previously convention is not the standard one used for modeling inverters. Most of
inverter and phase-lock loop (PLL) models follow the next convention:
- ```math
+```math
\begin{align}
v_d + jv_q &= (v_r + jv_i) e^{-j \delta} \tag{2a} \\
v_d &= v_h \cos(\delta - \theta) \tag{2b} \\
diff --git a/docs/src/small.md b/docs/src/small.md
index b47e0cf75..22ca99ecc 100644
--- a/docs/src/small.md
+++ b/docs/src/small.md
@@ -46,9 +46,9 @@ approximation:
\left[\begin{array}{c}
0 \\
\Delta\dot{x}
- \end{array}\right] = \underbrace{\left[\begin{array}
- ~g(y_{eq},x_{eq},p) \\
- f(y_{eq},x_{eq},p) \end{array}\right]}_{ =~ 0}
+ \end{array}\right] = \underbrace{\left[\begin{array}{c}
+ g(y_{eq},x_{eq},p) \\
+ f(y_{eq},x_{eq},p) \end{array}\right]}_{= 0}
+ J[y_{eq}, x_{eq}, p] \left[\begin{array}{c}
\Delta y \\
\Delta x
@@ -94,21 +94,21 @@ on which we can compute its eigenvalues to analyze local stability.
## Accessing the Jacobian function
-You can retrieve the Jacobian function for a simulation using the `get_jacobian` function as follows:
+You can retrieve the Jacobian function for a simulation using the [`get_jacobian`](@ref) function as follows:
```julia
-jacobian = function get_jacobian(ResidualModel, system)
+jacobian = get_jacobian(ResidualModel, system)
```
optionally you can pass the number of iterations to check for sparsity as follows:
```julia
-jacobian = function get_jacobian(ResidualModel, system, 0)
+jacobian = get_jacobian(ResidualModel, system, 0)
```
if you specify 0, the jacobian function will use a full matrix.
-The return of `get_jacobian` is known as a functor in Julia and can be used to make evaluations.
+The return of [`get_jacobian`](@ref) is known as a functor in Julia and can be used to make evaluations.
Currently, any function can be evaluated with the following inputs:
```julia
diff --git a/docs/src/time_delays.md b/docs/src/time_delays.md
index 799af868c..df95e1cd3 100644
--- a/docs/src/time_delays.md
+++ b/docs/src/time_delays.md
@@ -12,11 +12,11 @@ For more information on solving such models, refer to the documentation for [Del
The following models include time delays:
-* `DEGOV`
+ - `DEGOV`
There is currently limited support for including models with time delays. The following limitations apply:
-* Only constant delays are supported (state dependent delays are not).
-* System models with delays must use `MassMatrixModel` formulation (`ResidualModel` is not currently compatible).
-* System models with delays are not compatible with small signal analysis tools.
-* The system formulation with delays is not compatible with automatic differentiation for calculating the gradient with respect to time. The setting `autodiff=false` should be set when passing the solver (e.g. `MethodofSteps(Rodas5(autodiff=false))`).
+ - Only constant delays are supported (state dependent delays are not).
+ - System models with delays must use [`MassMatrixModel`](@ref) formulation ([`ResidualModel`](@ref) is not currently compatible).
+ - System models with delays are not compatible with small signal analysis tools.
+ - The system formulation with delays is not compatible with automatic differentiation for calculating the gradient with respect to time. The setting `autodiff=false` should be set when passing the solver (e.g. `MethodofSteps(Rodas5(autodiff=false))`).
diff --git a/docs/src/tutorials/quick_start_guide.jl b/docs/src/tutorials/quick_start_guide.jl
index 491360139..5a754ced7 100644
--- a/docs/src/tutorials/quick_start_guide.jl
+++ b/docs/src/tutorials/quick_start_guide.jl
@@ -1,12 +1,11 @@
# # Quick Start Guide
#
-# The data for these tutorials is provided in [PowerSystemCaseBuilder](https://github.com/nrel-sienna/PowerSystemCaseBuilder.jl).
+# The data for these tutorials is provided in [`PowerSystemCaseBuilder.jl`](https://sienna-platform.github.io/PowerSystemCaseBuilder.jl/stable/).
# If you want to build your own case, take a look at the tutorial
# [Creating and Handling Data for Dynamic Simulations](@ref)
#
# For more details about loading data and adding more dynamic components check the
-# [Creating a System with Dynamic devices](https://nrel-sienna.github.io/PowerSystems.jl/stable/modeler_guide/system_dynamic_data/)
-# section of the documentation in `PowerSystems.jl`.
+# tutorial on [Adding Data for Dynamic Simulations](@extref) in [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/).
#
# For a detailed tutorial about this case visit [One Machine against Infinite Bus (OMIB) Simulation](@ref)
#
@@ -22,7 +21,7 @@ using Plots
omib_sys = build_system(PSIDSystems, "OMIB System")
-# ## Define the Simulation
+# ## Define the [`Simulation`](@ref)
time_span = (0.0, 30.0)
perturbation_trip = BranchTrip(1.0, Line, "BUS 1-BUS 2-i_1")
diff --git a/docs/src/tutorials/tutorial_240bus.jl b/docs/src/tutorials/tutorial_240bus.jl
index e3c15a1dd..42d07e359 100644
--- a/docs/src/tutorials/tutorial_240bus.jl
+++ b/docs/src/tutorials/tutorial_240bus.jl
@@ -1,6 +1,4 @@
-# # [PSSE 240 Bus Case system with Renewables](https://www.nrel.gov/grid/test-case-repository.html)
-#
-# **Originally Contributed by**: José Daniel Lara
+# # [PSSE 240 Bus Case system with Renewables](https://www.nlr.gov/grid/test-case-repository)
#
# ## Introduction
#
@@ -19,8 +17,7 @@ using OrdinaryDiffEq
# !!! note
# `PowerSystemCaseBuilder.jl` is a helper library that makes it easier to reproduce
# examples in the documentation and tutorials. Normally you would pass your local files
-# to create the system data instead of calling the function `build_system`.
-# For more details visit [PowerSystemCaseBuilder Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/)
+# to create the system data instead of calling the function [`PowerSystemCaseBuilder.build_system`](@extref).
#
# ## Load the system and transform load data
#
@@ -39,9 +36,8 @@ end
# The next step is to create the simulation structure. This will create the indexing of our
# system that will be used to formulate the differential-algebraic system of equations. To
# do so, it is required to specify the perturbation that will occur in the system. In this
-# case, we will use a ResidualModel formulation, for more details about the formulation
-# checkout the [Models Section](https://nrel-sienna.github.io/PowerSimulationsDynamics.jl/stable/models/)
-# in `PowerSimulationsDynamics.jl` documentation.
+# case, we will use a [`ResidualModel`](@ref) formulation, for more details about the formulation
+# checkout the [Models](@ref) section.
using Logging
sim_ida = Simulation(
@@ -73,9 +69,8 @@ plot(v1101_ida)
# ## Run the simulation using Rodas4()
#
-# In this case, we will use a MassMatrixModel formulation, for more details about the
-# formulation checkout the [Models Section](https://nrel-sienna.github.io/PowerSimulationsDynamics.jl/stable/models/)
-# in `PowerSimulationsDynamics.jl` documentation
+# In this case, we will use a [`MassMatrixModel`](@ref) formulation, for more details about the
+# formulation checkout the [Models](@ref) section
sim_rodas = Simulation(
MassMatrixModel,
diff --git a/docs/src/tutorials/tutorial_activeload.jl b/docs/src/tutorials/tutorial_activeload.jl
index 9d5ab7847..947152da7 100644
--- a/docs/src/tutorials/tutorial_activeload.jl
+++ b/docs/src/tutorials/tutorial_activeload.jl
@@ -1,11 +1,9 @@
# # Tutorial Active Constant Power Load model
#
-# **Originally Contributed by**: Rodrigo Henriquez-Auba
-#
# ## Introduction
#
# This tutorial will introduce you to the functionality of `PowerSimulationsDynamics` and
-# `PowerSystems` to explore active load components and a small-signal analysis.
+# [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) to explore active load components and a small-signal analysis.
#
# This tutorial presents a simulation of a two-bus system with a GFM inverter at bus 1, and
# a load on bus 2. We will change the model from a constant power load model, to a constant
@@ -22,10 +20,9 @@ const PSY = PowerSystems;
# !!! note
# `PowerSystemCaseBuilder.jl` is a helper library that makes it easier to reproduce
# examples in the documentation and tutorials. Normally you would pass your local files
-# to create the system data instead of calling the function `build_system`.
-# For more details visit [PowerSystemCaseBuilder Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/)
+# to create the system data instead of calling the function [`PowerSystemCaseBuilder.build_system`](@extref).
#
-# `PowerSystems` (abbreviated with `PSY`) is used to properly define the data structure and
+# [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) (abbreviated with `PSY`) is used to properly define the data structure and
# establish an equilibrium point initial condition with a power flow routine using `PowerFlows`.
#
# ## Load the system
@@ -46,7 +43,7 @@ first(get_components(PSY.ExponentialLoad, sys))
# ## Run a small-signal analysis
#
-# We set up the Simulation. Since the droop model does not have a frequency state, we use a
+# We set up the [`Simulation`](@ref). Since the droop model does not have a frequency state, we use a
# constant frequency reference frame for the network.
sim = Simulation(ResidualModel,
diff --git a/docs/src/tutorials/tutorial_continuation_pf.jl b/docs/src/tutorials/tutorial_continuation_pf.jl
index 6f5a98c77..13eb1ea37 100644
--- a/docs/src/tutorials/tutorial_continuation_pf.jl
+++ b/docs/src/tutorials/tutorial_continuation_pf.jl
@@ -1,7 +1,5 @@
# # Tutorial Small Signal Analysis with Continuation Power Flow
#
-# **Originally Contributed by**: Rodrigo Henriquez-Auba
-#
# ## Introduction
#
# This tutorial will introduce you to the functionality of `PowerSimulationsDynamics` and
@@ -31,10 +29,9 @@ Logging.disable_logging(Logging.Warn);
# !!! note
# `PowerSystemCaseBuilder.jl` is a helper library that makes it easier to reproduce
# examples in the documentation and tutorials. Normally you would pass your local files
-# to create the system data instead of calling the function `build_system`.
-# For more details visit [PowerSystemCaseBuilder Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/)
+# to create the system data instead of calling the function [`PowerSystemCaseBuilder.build_system`](@extref).
#
-# `PowerSystems` (abbreviated with `PSY`) is used to properly define the data structure and
+# [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) (abbreviated with `PSY`) is used to properly define the data structure and
# establish an equilibrium point initial condition with a power flow routine using `PowerFlows`.
#
# ## Load the system
@@ -156,7 +153,7 @@ for p in P_range
set_active_power!(load, power)
q_power = power * tan(acos(load_pf))
set_reactive_power!(load, q_power)
- ## Construct Simulation
+ ## Construct [`Simulation`](@ref)
sim = Simulation(ResidualModel, sys, mktempdir(), (0.0, 1.0))
if sim.status == PSID.BUILT
## Check small-signal stability
diff --git a/docs/src/tutorials/tutorial_dynamic_data.jl b/docs/src/tutorials/tutorial_dynamic_data.jl
index 555858103..eb73b36da 100644
--- a/docs/src/tutorials/tutorial_dynamic_data.jl
+++ b/docs/src/tutorials/tutorial_dynamic_data.jl
@@ -1,13 +1,11 @@
# # Creating and Handling Data for Dynamic Simulations
#
-# **Originally Contributed by**: Rodrigo Henriquez and José Daniel Lara
-#
# ## Introduction
#
-# This tutorial briefly introduces how to create a system using `PowerSystems.jl` data
-# structures. For more details visit [`PowerSystems.jl` Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/)
+# This tutorial briefly introduces how to create a system using [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) data
+# structures.
#
-# Start by calling `PowerSystems.jl` and `PowerSystemCaseBuilder.jl`:
+# Start by calling [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) and `PowerSystemCaseBuilder.jl`:
using PowerSystems
using PowerSystemCaseBuilder
@@ -16,24 +14,23 @@ const PSY = PowerSystems;
# !!! note
# `PowerSystemCaseBuilder.jl` is a helper library that makes it easier to reproduce
# examples in the documentation and tutorials. Normally you would pass your local files
-# to create the system data instead of calling the function `build_system`.
-# For more details visit [PowerSystemCaseBuilder Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/)
+# to create the system data instead of calling the function [`PowerSystemCaseBuilder.build_system`](@extref).
#
# ## System description
#
# Next we need to define the different elements required to run a simulation. To run a
-# simulation in `PowerSimulationsDynamics`, it is required to define a `System` that
+# simulation in `PowerSimulationsDynamics`, it is required to define a [`PowerSystems.System`](@extref) that
# contains the following components:
#
# ### Static Components
#
# We called static components to those that are used to run a Power Flow problem.
#
-# - Vector of `Bus` elements, that define all the buses in the network.
-# - Vector of `Branch` elements, that define all the branches elements (that connect two buses) in the network.
-# - Vector of `StaticInjection` elements, that define all the devices connected to buses that can inject (or withdraw) power. These static devices, typically generators, in `PowerSimulationsDynamics` are used to solve the Power Flow problem that determines the active and reactive power provided for each device.
-# - Vector of `PowerLoad` elements, that define all the loads connected to buses that can withdraw current. These are also used to solve the Power Flow.
-# - Vector of `Source` elements, that define source components behind a reactance that can inject or withdraw current.
+# - Vector of [`PowerSystems.Bus`](@extref) elements, that define all the buses in the network.
+# - Vector of [`PowerSystems.ACBranch`](@extref) elements, that define all the branches elements (that connect two buses) in the network.
+# - Vector of [`PowerSystems.StaticInjection`](@extref) elements, that define all the devices connected to buses that can inject (or withdraw) power. These static devices, typically generators, in `PowerSimulationsDynamics` are used to solve the Power Flow problem that determines the active and reactive power provided for each device.
+# - Vector of [`PowerSystems.PowerLoad`](@extref) elements, that define all the loads connected to buses that can withdraw current. These are also used to solve the Power Flow.
+# - Vector of [`PowerSystems.Source`](@extref) elements, that define source components behind a reactance that can inject or withdraw current.
# - The base of power used to define per unit values, in MVA as a `Float64` value.
# - The base frequency used in the system, in Hz as a `Float64` value.
#
@@ -41,8 +38,8 @@ const PSY = PowerSystems;
#
# Dynamic components are those that define differential equations to run a transient simulation.
#
-# - Vector of `DynamicInjection` elements. These components must be attached to a `StaticInjection` that connects the power flow solution to the dynamic formulation of such device. `DynamicInjection` can be `DynamicGenerator` or `DynamicInverter`, and its specific formulation (i.e. differential equations) will depend on the specific components that define such device.
-# - (Optional) Selecting which of the `Lines` (of the `Branch` vector) elements must be modeled of `DynamicLines` elements, that can be used to model lines with differential equations.
+# - Vector of [`PowerSystems.DynamicInjection`](@extref) elements. These components must be attached to a [`PowerSystems.StaticInjection`](@extref) that connects the power flow solution to the dynamic formulation of such device. [`PowerSystems.DynamicInjection`](@extref) can be [`PowerSystems.DynamicGenerator`](@extref) or [`PowerSystems.DynamicInverter`](@extref), and its specific formulation (i.e. differential equations) will depend on the specific components that define such device.
+# - (Optional) Selecting which of the `Lines` (of the [`PowerSystems.ACBranch`](@extref) vector) elements must be modeled of `DynamicLines` elements, that can be used to model lines with differential equations.
#
# To start we will define the data structures for the network.
#
@@ -53,7 +50,7 @@ const PSY = PowerSystems;
# ## Static System creation
#
# To create the system you need to load data using `PowerSystemCaseBuilder.jl`. This system
-# was originally created from following [raw file](https://github.com/NREL-Sienna/PowerSystemsTestData/blob/master/psid_tests/data_tests/ThreeBusInverter.raw).
+# was originally created from following [raw file](https://github.com/sienna-platform/PowerSystemsTestData/blob/master/psid_tests/data_tests/ThreeBusInverter.raw).
sys = build_system(PSIDSystems, "3 Bus Inverter Base"; force_build = true)
@@ -117,7 +114,7 @@ tg_none() = TGFixed(1.0) #efficiency
## *PSS: No PSS*
pss_none() = PSSFixed(0.0)
-# The next lines receives a static generator name, and creates a `DynamicGenerator` based on
+# The next lines receives a static generator name, and creates a [`PowerSystems.DynamicGenerator`](@extref) based on
# that specific static generator, with the specific components defined previously. This is a
# classic machine model without AVR, Turbine Governor and PSS.
diff --git a/docs/src/tutorials/tutorial_dynamic_lines.jl b/docs/src/tutorials/tutorial_dynamic_lines.jl
index 869af1abf..9be7b37cf 100644
--- a/docs/src/tutorials/tutorial_dynamic_lines.jl
+++ b/docs/src/tutorials/tutorial_dynamic_lines.jl
@@ -1,7 +1,5 @@
# # Line Modeling Simulations
#
-# **Originally Contributed by**: Rodrigo Henriquez-Auba and José Daniel Lara
-#
# ## Introduction
#
# This tutorial will introduce an example of considering dynamic lines in
@@ -29,8 +27,7 @@ using Plots
# !!! note
# `PowerSystemCaseBuilder.jl` is a helper library that makes it easier to reproduce
# examples in the documentation and tutorials. Normally you would pass your local files
-# to create the system data instead of calling the function `build_system`.
-# For more details visit [PowerSystemCaseBuilder Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/)
+# to create the system data instead of calling the function [`PowerSystemCaseBuilder.build_system`](@extref).
#
# ### Step 2: Data creation
#
@@ -72,7 +69,7 @@ Ybus_change = NetworkSwitch(
#Time span of our simulation
tspan = (0.0, 30.0)
-#Define Simulation
+#Define [`Simulation`](@ref)
sim = Simulation(
ResidualModel, #Type of model used
threebus_sys, #system
@@ -144,7 +141,7 @@ Ybus_change_dyn = NetworkSwitch(
#
# Now, we construct the simulation:
-## Define Simulation
+## Define [`Simulation`](@ref)
sim_dyn = Simulation(
ResidualModel, #Type of model used
threebus_sys_dyn, #system
diff --git a/docs/src/tutorials/tutorial_inverter_modeling.jl b/docs/src/tutorials/tutorial_inverter_modeling.jl
index 4d566093a..e5efc6f86 100644
--- a/docs/src/tutorials/tutorial_inverter_modeling.jl
+++ b/docs/src/tutorials/tutorial_inverter_modeling.jl
@@ -1,7 +1,5 @@
# # Inverter Modeling simulation
#
-# **Originally Contributed by**: José Daniel Lara
-#
# ## Introduction
#
# This tutorial will introduce the modeling of an inverter with Virtual Inertia in a
@@ -28,8 +26,7 @@ using Plots
# !!! note
# `PowerSystemCaseBuilder.jl` is a helper library that makes it easier to reproduce
# examples in the documentation and tutorials. Normally you would pass your local files
-# to create the system data instead of calling the function `build_system`.
-# For more details visit [PowerSystemCaseBuilder Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/)
+# to create the system data instead of calling the function [`PowerSystemCaseBuilder.build_system`](@extref).
#
# Create the system using `PowerSystemCaseBuilder.jl`:
@@ -39,7 +36,7 @@ sys = build_system(PSIDSystems, "14 Bus Base Case")
# in the documentation and tutorials. Normally you would pass your local files to create the
# system data.
#
-# Define Simulation Problem with a 20 second simulation period and the branch trip at t = 1.0:
+# Define [`Simulation`](@ref) Problem with a 20 second simulation period and the branch trip at t = 1.0:
sim = Simulation(
ResidualModel, #Type of model used
@@ -131,7 +128,7 @@ storage = EnergyReservoirStorage(;
add_component!(sys, storage)
# A good sanity check it running a power flow on the system to make sure all the components
-# are properly scaled and that the system is properly balanced. We can use `PowerSystems` to
+# are properly scaled and that the system is properly balanced. We can use [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) to
# perform this check. We can get the results back and perform a sanity check.
res = solve_power_flow(ACPowerFlow(), sys)
@@ -174,7 +171,7 @@ add_component!(sys, inverter, storage)
sys
-# Define Simulation problem using the same parameters:
+# Define [`Simulation`](@ref) problem using the same parameters:
sim = Simulation(
ResidualModel, #Type of model used
diff --git a/docs/src/tutorials/tutorial_omib.jl b/docs/src/tutorials/tutorial_omib.jl
index b85459872..906af59f7 100644
--- a/docs/src/tutorials/tutorial_omib.jl
+++ b/docs/src/tutorials/tutorial_omib.jl
@@ -1,7 +1,5 @@
# # One Machine against Infinite Bus (OMIB) Simulation
#
-# **Originally Contributed by**: Rodrigo Henriquez-Auba and José Daniel Lara
-#
# ## Introduction
#
# This tutorial will introduce you to the functionality of `PowerSimulationsDynamics`
@@ -26,10 +24,9 @@ gr()
# !!! note
# `PowerSystemCaseBuilder.jl` is a helper library that makes it easier to reproduce
# examples in the documentation and tutorials. Normally you would pass your local files
-# to create the system data instead of calling the function `build_system`.
-# For more details visit [PowerSystemCaseBuilder Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/powersystembuilder/)
+# to create the system data instead of calling the function [`PowerSystemCaseBuilder.build_system`](@extref).
#
-# `PowerSystems` (abbreviated with `PSY`) is used to properly define the data structure and
+# [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) (abbreviated with `PSY`) is used to properly define the data structure and
# establish an equilibrium point initial condition with a power flow routine, while `Sundials`
# is used to solve the problem defined in `PowerSimulationsDynamics`.
#
@@ -67,7 +64,7 @@ sim = PSID.Simulation(
show_states_initial_value(sim)
-# ## Run the Simulation
+# ## Run the [`Simulation`](@ref)
#
# Finally, to run the simulation we simply use:
@@ -89,14 +86,14 @@ results = read_results(sim)
# `PowerSimulationsDynamics` has two functions to obtain different states of the solution:
#
-# - `get_state_series(results, ("generator-102-1", :δ))`: can be used to obtain the solution
+# - [`get_state_series`](@ref): can be used to obtain the solution
# as a tuple of time and the required state. In this case, we are obtaining the rotor angle
# `:δ` of the generator named `"generator-102-1"`.
angle = get_state_series(results, ("generator-102-1", :δ));
plot(angle; xlabel = "time", ylabel = "rotor angle [rad]", label = "rotor angle")
-# - `get_voltage_magnitude_series(results, 102)`: can be used to obtain the voltage magnitude
+# - [`get_voltage_magnitude_series`](@ref): can be used to obtain the voltage magnitude
# as a tuple of time and voltage. In this case, we are obtaining the voltage magnitude at
# bus 102 (where the generator is located).
diff --git a/docs/src/tutorials_page.md b/docs/src/tutorials_page.md
index 05943a396..4d2208005 100644
--- a/docs/src/tutorials_page.md
+++ b/docs/src/tutorials_page.md
@@ -7,7 +7,7 @@ All the tutorials for the SIIP project are part of a separate repository
Specific examples of common workflows and models:
-- [Loading Dynamic Data](https://nbviewer.org/github/Sienna-Platform/SIIPExamples.jl/blob/notebook/2_PowerSystems_examples/09_loading_dynamic_systems_data.ipynb)
-- [Solving a One Machine against Infinite Bus model](https://nbviewer.jupyter.org/github/Sienna-Platform/SIIPExamples.jl/blob/notebook/4_PowerSimulationsDynamics_examples/01_omib.ipynb)
-- [Changing line modeling assumptions](https://nbviewer.jupyter.org/github/Sienna-Platform/SIIPExamples.jl/blob/notebook/4_PowerSimulationsDynamics_examples/02_line_dynamics.ipynb)
-- [Using an Inverter in a Multi-Machine Model](https://nbviewer.jupyter.org/github/Sienna-Platform/SIIPExamples.jl/blob/notebook/4_PowerSimulationsDynamics_examples/03_inverter_model.ipynb)
+ - [Loading Dynamic Data](https://nbviewer.org/github/Sienna-Platform/SIIPExamples.jl/blob/notebook/2_PowerSystems_examples/09_loading_dynamic_systems_data.ipynb)
+ - [Solving a One Machine against Infinite Bus model](https://nbviewer.jupyter.org/github/Sienna-Platform/SIIPExamples.jl/blob/notebook/4_PowerSimulationsDynamics_examples/01_omib.ipynb)
+ - [Changing line modeling assumptions](https://nbviewer.jupyter.org/github/Sienna-Platform/SIIPExamples.jl/blob/notebook/4_PowerSimulationsDynamics_examples/02_line_dynamics.ipynb)
+ - [Using an Inverter in a Multi-Machine Model](https://nbviewer.jupyter.org/github/Sienna-Platform/SIIPExamples.jl/blob/notebook/4_PowerSimulationsDynamics_examples/03_inverter_model.ipynb)
diff --git a/scripts/formatter/formatter_code.jl b/scripts/formatter/formatter_code.jl
index 75bc991e6..d55dddd91 100644
--- a/scripts/formatter/formatter_code.jl
+++ b/scripts/formatter/formatter_code.jl
@@ -5,23 +5,25 @@ Pkg.update()
using JuliaFormatter
-main_paths = ["."]
+main_paths = ["./src", "./test", "./docs/src"]
for main_path in main_paths
for (root, dir, files) in walkdir(main_path)
for f in files
- @show file_path = abspath(root, f)
- !occursin(".jl", f) && continue
- format(file_path;
- whitespace_ops_in_indices = true,
- remove_extra_newlines = true,
- verbose = true,
- always_for_in = true,
- whitespace_typedefs = true,
- conditional_to_if = true,
- join_lines_based_on_source = true,
- separate_kwargs_with_semicolon = true,
+ @show file_path = abspath(root, f)
+ !((occursin(".jl", f) || occursin(".md", f))) && continue
+ format(file_path;
+ whitespace_ops_in_indices = true,
+ remove_extra_newlines = true,
+ verbose = true,
+ always_for_in = true,
+ whitespace_typedefs = true,
+ conditional_to_if = true,
+ join_lines_based_on_source = true,
+ separate_kwargs_with_semicolon = true,
+ format_markdown = true,
+ #ignore = [] # list of file that cause formatter to error
- # always_use_return = true. # Disabled since it throws a lot of false positives
+ # always_use_return = true. # Disabled since it throws a lot of false positives
)
end
end
diff --git a/src/base/device_wrapper.jl b/src/base/device_wrapper.jl
index 5e9ba4038..d248fb72e 100644
--- a/src/base/device_wrapper.jl
+++ b/src/base/device_wrapper.jl
@@ -27,7 +27,7 @@ get_delays(
Float64[PSY.get_Td(PSY.get_prime_mover(dynamic_injector))]
"""
-Wraps DynamicInjection devices from PowerSystems to handle changes in controls and connection
+Wraps [`PowerSystems.DynamicInjection`](@extref) devices from [`PowerSystems.jl`](https://sienna-platform.github.io/PowerSystems.jl/stable/) to handle changes in controls and connection
status, and allocate the required indexes of the state space.
"""
struct DynamicWrapper{T <: PSY.DynamicInjection}
diff --git a/src/base/frequency_reference.jl b/src/base/frequency_reference.jl
index 288b4ec9c..6a04806b5 100644
--- a/src/base/frequency_reference.jl
+++ b/src/base/frequency_reference.jl
@@ -1,4 +1,17 @@
+"""
+Frequency-reference mode that keeps system frequency fixed at 1.0 p.u.
+
+Use this mode when the network frequency should not track a dynamic device
+state during simulation.
+"""
struct ConstantFrequency end
+
+"""
+Frequency-reference mode that tracks the frequency state at the reference bus.
+
+If a dynamic injector at the slack bus provides a compatible frequency state,
+that state is used as the network frequency reference.
+"""
struct ReferenceBus end
function _get_frequency_state(d::DynamicWrapper{T}) where {T <: PSY.DynamicGenerator}
diff --git a/src/base/jacobian.jl b/src/base/jacobian.jl
index 0fe421ad0..756617c77 100644
--- a/src/base/jacobian.jl
+++ b/src/base/jacobian.jl
@@ -223,15 +223,15 @@ end
"""
function get_jacobian(
::Type{T},
- system::PSY.System,
+ system::[`PowerSystems.System`](@extref),
sparse_retrieve_loop::Int = 3,
) where {T <: SimulationModel}
Returns the jacobian function of the system model resulting from the system data.
# Arguments:
-- `::SimulationModel` : Type of Simulation Model. `ResidualModel` or `MassMatrixModel`. See [Models Section](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/models/) for more details
-- `system::PowerSystems.System` : System data
+- `::SimulationModel` : Type of Simulation Model. [`ResidualModel`](@ref) or [`MassMatrixModel`](@ref).
+- `system`: [`PowerSystems.System`](@extref) — power system data
- `sparse_retrieve_loop::Int` : Number of loops for sparsity detection. If 0, builds the Jacobian with a DenseMatrix
"""
function get_jacobian(
diff --git a/src/base/perturbations.jl b/src/base/perturbations.jl
index 8e18db678..06cc47ba9 100644
--- a/src/base/perturbations.jl
+++ b/src/base/perturbations.jl
@@ -3,18 +3,18 @@ abstract type Perturbation end
"""
mutable struct BranchTrip <: Perturbation
time::Float64
- branch_type::Type{<:PowerSystems.ACBranch}
+ branch_type::Type{<:[`PowerSystems.ACBranch`](@extref)}
branch_name::String
end
-A BranchTrip completely disconnects a branch from the system. Currently there is only support for static branches disconnection, `PowerSystems.Line` and `PowerSystems.Transformer2W`.
+A BranchTrip completely disconnects a branch from the system. Currently there is only support for static branches disconnection, [`PowerSystems.Line`](@extref) and [`PowerSystems.Transformer2W`](@extref).
Future releases will provide support for a Dynamic Line disconnection.
-**Note:** Islanding is currently not supported in `PowerSimulationsDynamics.jl`. If a `BranchTrip` isolates a generation unit, the system may diverge due to the isolated generator.
+**Note:** Islanding is currently not supported in `PowerSimulationsDynamics.jl`. If a [`BranchTrip`](@ref) isolates a generation unit, the system may diverge due to the isolated generator.
# Arguments:
- `time::Float64` : Defines when the Branch Trip will happen. This time should be inside the time span considered in the Simulation
-- `branch_tipe::Type{<:PowerSystems.ACBranch}` : Type of branch disconnected
+- `branch_tipe::Type{<:PowerSystems.ACBranch}` : Branch type (subtype of [`PowerSystems.ACBranch`](@extref))
- `branch_name::String` : User defined name for identifying the branch
"""
mutable struct BranchTrip <: Perturbation
@@ -31,13 +31,13 @@ end
multiplier::Float64
end
-A BranchImpedanceChange change the impedance of a branch by a user defined multiplier. Currently there is only support for static branches disconnection, `PowerSystems.Line` and `PowerSystems.Transformer2W`.
+A BranchImpedanceChange change the impedance of a branch by a user defined multiplier. Currently there is only support for static branches disconnection, [`PowerSystems.Line`](@extref) and [`PowerSystems.Transformer2W`](@extref).
Future releases will provide support for a Dynamic Line disconnection.
# Arguments:
- `time::Float64` : Defines when the Branch Impedance Change will happen. This time should be inside the time span considered in the Simulation
-- `branch_tipe::Type{<:PowerSystems.ACBranch}` : Type of branch modified
+- `branch_tipe::Type{<:PowerSystems.ACBranch}` : Branch type (subtype of [`PowerSystems.ACBranch`](@extref))
- `branch_name::String` : User defined name for identifying the branch
- `multiplier::Float64` : User defined value for impedance multiplier.
"""
@@ -376,7 +376,7 @@ end
"""
mutable struct ControlReferenceChange <: Perturbation
time::Float64
- device::PowerSystems.DynamicInjection
+ device::[`PowerSystems.DynamicInjection`](@extref)
signal::Symbol
ref_value::Float64
end
@@ -386,7 +386,7 @@ A ControlReferenceChange allows to change the reference setpoint provided by a g
# Arguments:
- `time::Float64` : Defines when the Control Reference Change will happen. This time should be inside the time span considered in the Simulation
-- `device::Type{<:PowerSystems.DynamicInjection}` : Dynamic device modified
+- `device::Type{<:PowerSystems.DynamicInjection}` : Dynamic device ([`PowerSystems.DynamicInjection`](@extref))
- `signal::Symbol` : determines which reference setpoint will be modified. The accepted signals are:
- `:P_ref`: Modifies the active power reference setpoint.
- `:V_ref`: Modifies the voltage magnitude reference setpoint (if used).
@@ -488,7 +488,7 @@ A `SourceBusVoltageChange` allows to change the reference setpoint provided by a
# Arguments:
- `time::Float64` : Defines when the Control Reference Change will happen. This time should be inside the time span considered in the Simulation
-- `device::Type{<:PowerSystems.Source}` : Device modified
+- `device::Type{<:PowerSystems.Source}` : Voltage source device ([`PowerSystems.Source`](@extref))
- `signal::Symbol` : determines which reference setpoint will be modified. The accepted signals are:
- :V_ref Modifies the internal voltage magnitude reference setpoint.
- :θ_ref Modifies the internal voltage angle reference setpoint.
@@ -519,7 +519,7 @@ end
"""
mutable struct GeneratorTrip <: Perturbation
time::Float64
- device::PowerSystems.DynamicInjection
+ device::[`PowerSystems.DynamicInjection`](@extref)
end
A `GeneratorTrip` allows to disconnect a Dynamic Generation unit from the system at a specified time.
@@ -527,7 +527,7 @@ A `GeneratorTrip` allows to disconnect a Dynamic Generation unit from the system
# Arguments:
- `time::Float64` : Defines when the Generator Trip will happen. This time should be inside the time span considered in the Simulation
-- `device::Type{<:PowerSystems.DynamicInjection}` : Device to be disconnected
+- `device::Type{<:PowerSystems.DynamicInjection}` : Device to disconnect ([`PowerSystems.DynamicInjection`](@extref))
"""
mutable struct GeneratorTrip <: Perturbation
time::Float64
@@ -552,7 +552,7 @@ end
"""
mutable struct LoadChange <: Perturbation
time::Float64
- device::PowerSystems.ElectricLoad
+ device::[`PowerSystems.ElectricLoad`](@extref)
signal::Symbol
ref_value::Float64
end
@@ -562,7 +562,7 @@ A LoadChange allows to change the active or reactive power setpoint from a load.
# Arguments:
- `time::Float64` : Defines when the Load Change will happen. This time should be inside the time span considered in the Simulation
-- `device::Type{<:PowerSystems.ElectricLoad}` : Dynamic device modified
+- `device::Type{<:PowerSystems.ElectricLoad}` : Load device ([`PowerSystems.ElectricLoad`](@extref))
- `signal::Symbol` : determines which reference setpoint will be modified. The accepted signals are:
- `:P_ref`: Modifies the active power reference setpoint.
- `:Q_ref`: Modifies the reactive power reference setpoint.
@@ -715,7 +715,7 @@ end
"""
mutable struct LoadTrip <: Perturbation
time::Float64
- device::PowerSystems.ElectricLoad
+ device::[`PowerSystems.ElectricLoad`](@extref)
end
A `LoadTrip` allows the user to disconnect a load from the system.
@@ -723,7 +723,7 @@ A `LoadTrip` allows the user to disconnect a load from the system.
# Arguments:
- `time::Float64` : Defines when the Generator Trip will happen. This time should be inside the time span considered in the Simulation
-- `device::Type{<:PowerSystems.ElectricLoad}` : Device to be disconnected
+- `device::Type{<:PowerSystems.ElectricLoad}` : Load to disconnect ([`PowerSystems.ElectricLoad`](@extref))
"""
mutable struct LoadTrip <: Perturbation
time::Float64
diff --git a/src/base/simulation.jl b/src/base/simulation.jl
index 469d91c8f..6e5d3f950 100644
--- a/src/base/simulation.jl
+++ b/src/base/simulation.jl
@@ -81,7 +81,7 @@ end
"""
function Simulation!
::SimulationModel
- system::PowerSystems.System
+ system::[`PowerSystems.System`](@extref)
simulation_folder::String
tspan::NTuple{2, Float64},
perturbations::Vector{<:Perturbation} = Vector{Perturbation}();
@@ -91,16 +91,16 @@ end
Builds the simulation object and conducts the indexing process. The initial conditions are stored in the system.
# Arguments:
-- `::SimulationModel` : Type of Simulation Model. `ResidualModel` or `MassMatrixModel`. See [Models Section](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/models/) for more details
-- `system::PowerSystems.System` : System data
+- `::SimulationModel` : Type of Simulation Model. [`ResidualModel`](@ref) or [`MassMatrixModel`](@ref).
+- `system`: [`PowerSystems.System`](@extref) — power system data
- `simulation_folder::String` : Folder directory
- `tspan::NTuple{2, Float64}` : Time span for simulation
- `perturbations::Vector{<:Perturbation}` : Vector of Perturbations for the Simulation. Default: No Perturbations
-- `initialize_simulation::Bool` : Runs the initialization routine. If false, simulation runs based on the operation point stored in System
+- `initialize_simulation::Bool` : Runs the initialization routine. If false, simulation runs based on the operating point stored in [`PowerSystems.System`](@extref)
- `initial_conditions::Vector{Float64}` : Allows the user to pass a vector with the initial condition values desired in the simulation. If initialize_simulation = true, these values are used as a first guess and overwritten.
-- `frequency_reference` : Default `ReferenceBus`. Determines which frequency model is used for the network. Currently there are two options available:
- - `ConstantFrequency` assumes that the network frequency is 1.0 per unit at all times.
- - `ReferenceBus` will use the frequency state of a Dynamic Generator (rotor speed) or Dynamic Inverter (virtual speed) connected to the Reference Bus (defined in the Power Flow data) as the network frequency. If multiple devices are connected to such bus, the device with larger base power will be used as a reference. If a Voltage Source is connected to the Reference Bus, then a `ConstantFrequency` model will be used.
+- `frequency_reference` : Default [`ReferenceBus`](@ref). Determines which frequency model is used for the network. Currently there are two options available:
+ - [`ConstantFrequency`](@ref) assumes that the network frequency is 1.0 per unit at all times.
+ - [`ReferenceBus`](@ref) will use the frequency state of a Dynamic Generator (rotor speed) or Dynamic Inverter (virtual speed) connected to the Reference Bus (defined in the Power Flow data) as the network frequency. If multiple devices are connected to such bus, the device with larger base power will be used as a reference. If a Voltage Source is connected to the Reference Bus, then a [`ConstantFrequency`](@ref) model will be used.
- `system_to_file::Bool` : Default `false`. Serializes the initialized system
- `console_level::Logging` : Default `Logging.Warn`. Sets the level of logging output to the console. Can be set to `Logging.Error`, `Logging.Warn`, `Logging.Info` or `Logging.Debug`
- `file_level::Logging` : Default `Logging.Info`. Sets the level of logging output to file. Can be set to `Logging.Error`, `Logging.Warn`, `Logging.Info` or `Logging.Debug`
@@ -138,7 +138,7 @@ end
"""
function Simulation
::SimulationModel
- system::PowerSystems.System
+ system::[`PowerSystems.System`](@extref)
simulation_folder::String
tspan::NTuple{2, Float64},
perturbations::Vector{<:Perturbation} = Vector{Perturbation}();
@@ -148,16 +148,16 @@ end
Builds the simulation object and conducts the indexing process. The original system is not modified and a copy its created and stored in the Simulation.
# Arguments:
-- `::SimulationModel` : Type of Simulation Model. `ResidualModel` or `MassMatrixModel`. See [Models Section](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/models/) for more details
-- `system::PowerSystems.System` : System data
+- `::SimulationModel` : Type of Simulation Model. [`ResidualModel`](@ref) or [`MassMatrixModel`](@ref).
+- `system`: [`PowerSystems.System`](@extref) — power system data
- `simulation_folder::String` : Folder directory
- `tspan::NTuple{2, Float64}` : Time span for simulation
- `perturbations::Vector{<:Perturbation}` : Vector of Perturbations for the Simulation. Default: No Perturbations
-- `initialize_simulation::Bool` : Runs the initialization routine. If false, simulation runs based on the operation point stored in System
+- `initialize_simulation::Bool` : Runs the initialization routine. If false, simulation runs based on the operating point stored in [`PowerSystems.System`](@extref)
- `initial_conditions::Vector{Float64}` : Allows the user to pass a vector with the initial condition values desired in the simulation. If initialize_simulation = true, these values are used as a first guess and overwritten.
-- `frequency_reference` : Default `ReferenceBus`. Determines which frequency model is used for the network. Currently there are two options available:
- - `ConstantFrequency` assumes that the network frequency is 1.0 per unit at all times.
- - `ReferenceBus` will use the frequency state of a Dynamic Generator (rotor speed) or Dynamic Inverter (virtual speed) connected to the Reference Bus (defined in the Power Flow data) as the network frequency. If multiple devices are connected to such bus, the device with larger base power will be used as a reference. If a Voltage Source is connected to the Reference Bus, then a `ConstantFrequency` model will be used.
+- `frequency_reference` : Default [`ReferenceBus`](@ref). Determines which frequency model is used for the network. Currently there are two options available:
+ - [`ConstantFrequency`](@ref) assumes that the network frequency is 1.0 per unit at all times.
+ - [`ReferenceBus`](@ref) will use the frequency state of a Dynamic Generator (rotor speed) or Dynamic Inverter (virtual speed) connected to the Reference Bus (defined in the Power Flow data) as the network frequency. If multiple devices are connected to such bus, the device with larger base power will be used as a reference. If a Voltage Source is connected to the Reference Bus, then a [`ConstantFrequency`](@ref) model will be used.
- `system_to_file::Bool` : Default `false`. Serializes the initialized system
- `console_level::Logging` : Default `Logging.Warn`. Sets the level of logging output to the console. Can be set to `Logging.Error`, `Logging.Warn`, `Logging.Info` or `Logging.Debug`
- `file_level::Logging` : Default `Logging.Info`. Sets the level of logging output to file. Can be set to `Logging.Error`, `Logging.Warn`, `Logging.Info` or `Logging.Debug`
@@ -567,8 +567,8 @@ end
Solves the time-domain dynamic simulation model.
# Arguments
-- `sim::Simulation` : Initialized simulation object
-- `solver` : Solver used for numerical integration. Must be passed correctly depending on the Type of Simulation Model
+- **`sim`**: [`Simulation`](@ref) — initialized simulation object
+- **`solver`**: solver used for numerical integration; must match the formulation (e.g. solvers for [`ResidualModel`](@ref) vs [`MassMatrixModel`](@ref))
- `enable_progress_bar::Bool` : Default: `true`. Enables progress bar for the integration routine.
- Additional solver keyword arguments can be included. See [Common Solver Options](https://diffeq.sciml.ai/stable/basics/common_solver_opts/) in the `DifferentialEquations.jl` documentation for more details.
"""
@@ -586,6 +586,15 @@ function execute!(sim::Simulation, solver; kwargs...)
return sim.status
end
+"""
+ read_results(sim::Simulation)
+
+Return the [`SimulationResults`](@ref) stored in `sim` after [`execute!`](@ref) completes (or the last available results object).
+
+# Arguments
+
+- **`sim`**: [`Simulation`](@ref) to read from
+"""
function read_results(sim::Simulation)
return sim.results
end
@@ -601,7 +610,7 @@ Function that returns the reference setpoints for all the dynamic devices.
# Arguments
-- `sim::Simulation` : Simulation object that contains the initial condition and setpoints.
+- **`sim`**: [`Simulation`](@ref) — object that contains the initial condition and setpoints
"""
function get_setpoints(sim::Simulation)
return get_setpoints(get_simulation_inputs(sim))
diff --git a/src/base/simulation_results.jl b/src/base/simulation_results.jl
index 89cb9bf7f..e1690ba30 100644
--- a/src/base/simulation_results.jl
+++ b/src/base/simulation_results.jl
@@ -1,3 +1,10 @@
+"""
+Container for the output of a dynamic simulation run.
+
+`SimulationResults` stores the solved trajectory together with lookup structures
+used by post-processing utilities (state maps, bus lookup, setpoints, and
+auxiliary pointers).
+"""
struct SimulationResults
global_index::MAPPING_DICT
bus_lookup::Dict{Int, Int}
diff --git a/src/base/small_signal.jl b/src/base/small_signal.jl
index 441c15e5b..702b79e8c 100644
--- a/src/base/small_signal.jl
+++ b/src/base/small_signal.jl
@@ -196,10 +196,10 @@ end
sim::Simulation,
)
-Returns the Small Signal Output object that contains the eigenvalues and participation factors.
+Returns the small-signal output object that contains the eigenvalues and participation factors.
# Arguments
-- `sim::Simulation` : Small Signal Output object that contains the eigenvalues and participation factors
+- **`sim`**: [`Simulation`](@ref) for a system **without** time delays
"""
function small_signal_analysis(sim::Simulation{T}; kwargs...) where {T <: SimulationModel}
inputs = get_simulation_inputs(sim)