Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds doctests #72

Merged
merged 3 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](http://mtkstdlib.sciml.ai/stable/)
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](http://mtkstdlib.sciml.ai/dev/)

The ModelingToolkit Standard Library is standard library of components to model the world and beyond.
The ModelingToolkit Standard Library is a standard library of components to model the world and beyond.

![](https://user-images.githubusercontent.com/1814174/172000112-3579f5cf-c370-48c2-8047-558fbc46aeb6.png)

Expand Down Expand Up @@ -41,27 +41,30 @@ The following is the [RC Circuit Demonstration](http://mtkstdlib.sciml.ai/dev/tu
```julia
using ModelingToolkit, OrdinaryDiffEq, Plots
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Blocks: Constant

R = 1.0
C = 1.0
V = 1.0
@variables t
@named resistor = Resistor(R=R)
@named capacitor = Capacitor(C=C)
@named source = ConstantVoltage(V=V)
@named source = Voltage()
@named constant = Constant(k=V)
@named ground = Ground()

rc_eqs = [
connect(constant.output, source.V)
connect(source.p, resistor.p)
connect(resistor.n, capacitor.p)
connect(capacitor.n, source.n, ground.g)
]

@named rc_model = ODESystem(rc_eqs, t, systems=[resistor, capacitor, source, ground])
@named rc_model = ODESystem(rc_eqs, t, systems=[resistor, capacitor, constant, source, ground])
sys = structural_simplify(rc_model)
prob = ODAEProblem(sys, Pair[], (0, 10.0))
sol = solve(prob, Tsit5())
plot(sol, vars = [capacitor.v,resistor.i],
plot(sol, vars = [capacitor.v, resistor.i],
title = "RC Circuit Demonstration",
labels = ["Capacitor Voltage" "Resistor Current"])
savefig("plot.png")
Expand Down
5 changes: 5 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
IfElse = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
ModelingToolkitStandardLibrary = "16a59e39-deab-5bd0-87e4-056b12336739"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

[compat]
Documenter = "0.26, 0.27"
4 changes: 4 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ makedocs(
authors="Julia Computing",
clean=true,
doctest=false,
strict=[
:doctest,
:example_block,
],
modules=[ModelingToolkitStandardLibrary,
ModelingToolkitStandardLibrary.Blocks,
ModelingToolkitStandardLibrary.Mechanical,
Expand Down
36 changes: 20 additions & 16 deletions docs/src/tutorials/custom_component.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Custom Component
In this tutorial the creation of a custom component is demonstrated via the [Chua's circuit](https://en.wikipedia.org/wiki/Chua%27s_circuit).
In this tutorial, the creation of a custom component is demonstrated via the [Chua's circuit](https://en.wikipedia.org/wiki/Chua%27s_circuit).
The circuit is a simple circuit that shows chaotic behaviour.
Except for a non-linear resistor every other component already is part of `ModelingToolkitStandardLibrary.Electrical`.

First we need to make some imports.
```julia
First, we need to make some imports.
```@example components
using ModelingToolkit
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Electrical: OnePort
Expand All @@ -26,8 +26,8 @@ equation
i = if (v < -Ve) then Gb*(v + Ve) - Ga*Ve else if (v > Ve) then Gb*(v - Ve) + Ga*Ve else Ga*v;
end NonlinearResistor;
```
this can almost be directly translate it to the syntax of `ModelingToolkit`.
```julia
this can almost be directly translated to the syntax of `ModelingToolkit`.
```@example components
@parameters t

function NonlinearResistor(;name, Ga, Gb, Ve)
Expand All @@ -45,36 +45,37 @@ function NonlinearResistor(;name, Ga, Gb, Ve)
]
extend(ODESystem(eqs, t, [], pars; name=name), oneport)
end
nothing # hide
```

### Explanation
All components in `ModelingToolkit` are created via a function that serves as the constructor and returns some form of system, in this case a `ODESystem`.
All components in `ModelingToolkit` are created via a function that serves as the constructor and returns some form of system, in this case, an `ODESystem`.
Since the non-linear resistor is essentially a standard electrical component with two ports, we can extend from the `OnePort` component of the library.
```julia
@named oneport = OnePort()
```
This creates a `OnePort` with the `name = :oneport`.
For easier notation we can unpack the states of the component
For easier notation, we can unpack the states of the component
```julia
@unpack v, i = oneport
```
It might be a good idea to create parameters for the constants of the `NonlinearResistor`.
```julia
pars = @parameters Ga=Ga Gb=Gb Ve=Ve
```
The syntax looks funny but it simply creates symbolic parameters with the name `Ga` where it's default value is set from the function's argument `Ga`.
While this is not strictly necessary it allows the user to `remake` the problem easily with different parameters or allow for auto-tuning or parameter optimization without having to do all costly steps that may be involved with building and simplifying a model.
The syntax looks funny but it simply creates symbolic parameters with the name `Ga` where its default value is set from the function's argument `Ga`.
While this is not strictly necessary it allows the user to `remake` the problem easily with different parameters or allow for auto-tuning or parameter optimization without having to do all the costly steps that may be involved with building and simplifying a model.
The non-linear (in this case piece-wise constant) equation for the current can be implemented using `IfElse.ifelse`.
Finally, the created `oneport` component is extended with the created equations and parameters.
In this case no extra state variables are added, hence an empty vector is supplied.
The independent variable `t` needs to be supplied as second argument.
In this case, no extra state variables are added, hence an empty vector is supplied.
The independent variable `t` needs to be supplied as the second argument.
```julia
extend(ODESystem(eqs, t, [], pars; name=name), oneport)
```

## Building the Model
The final model can now be created with the components from the library and the new custom component.
```julia
```@example components
@named L = Inductor(L=18)
@named Ro = Resistor(R=12.5e-3)
@named G = Conductor(G=0.565)
Expand All @@ -99,24 +100,27 @@ connections = [
]

@named model = ODESystem(connections, t, systems=[L, Ro, G, C1, C2, Nr])
nothing # hide
```

## Simulating the Model
Now the model can be simulated.
First `structural_simplify` is called on the model and a `ODEProblem` is build from the result.
First, `structural_simplify` is called on the model and an `ODEProblem` is built from the result.
Since the initial voltage of the first capacitor was already specified via `v_start`, no initial condition is given and an empty pair is supplied.
```julia
```@example components
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[], (0, 5e4), saveat=0.01)
sol = solve(prob, Rodas4())

Plots.plot(sol[C1.v], sol[C2.v], title="Chaotic Attractor", label="", ylabel="C1 Voltage in V", xlabel="C2 Voltage in V")
Plots.savefig("chua_phase_plane.png")
nothing # hide

Plots.plot(sol; vars=[C1.v, C2.v, L.i], labels=["C1 Voltage in V" "C1 Voltage in V" "Inductor Current in A"])
Plots.savefig("chua.png")
nothing # hide
```

![Time series plot of C1.v, C2.v and L.i](https://user-images.githubusercontent.com/50108075/169712569-9ae5a074-ca1a-4801-b666-75a2f6e21bf5.png)
![Time series plot of C1.v, C2.v and L.i](chua_phase_plane.png)

![Phase plane plot of C1.v and C2.v](https://user-images.githubusercontent.com/50108075/169712578-b3f314f6-3310-4471-a31e-af7fac3c0fbc.png)
![Phase plane plot of C1.v and C2.v](chua.png)
17 changes: 10 additions & 7 deletions docs/src/tutorials/rc_circuit.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
# RC Circuit Model

This tutorial is a simplified version of the [RC circuit tutorial in the
ModelingToolkit.jl documentation](https://mtk.sciml.ai/dev/tutorials/acausal_components/).
`ModelingToolkit.jl` documentation](https://mtk.sciml.ai/dev/tutorials/acausal_components/).
In that tutorial, the full RC circuit is built from scratch. Here, we will use the
components of the `Electrical` model in the ModelingToolkit Standard Library to simply
connect pre-made components and simulate the model.

```julia
```@example
using ModelingToolkit, OrdinaryDiffEq, Plots
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Blocks: Constant

R = 1.0
C = 1.0
V = 1.0
@variables t
@named resistor = Resistor(R=R)
@named capacitor = Capacitor(C=C)
@named source = ConstantVoltage(V=V)
@named source = Voltage()
@named constant = Constant(k=V)
@named ground = Ground()

rc_eqs = [
connect(constant.output, source.V)
connect(source.p, resistor.p)
connect(resistor.n, capacitor.p)
connect(capacitor.n, source.n, ground.g)
]

@named rc_model = ODESystem(rc_eqs, t, systems=[resistor, capacitor, source, ground])
@named rc_model = ODESystem(rc_eqs, t, systems=[resistor, capacitor, constant, source, ground])
sys = structural_simplify(rc_model)
prob = ODAEProblem(sys, Pair[], (0, 10.0))
sol = solve(prob, Tsit5())
plot(sol, vars = [capacitor.v,resistor.i],
plot(sol, vars = [capacitor.v, resistor.i],
title = "RC Circuit Demonstration",
labels = ["Capacitor Voltage" "Resistor Current"])
savefig("plot.png")
savefig("plot.png"); nothing # hide
```

![](https://user-images.githubusercontent.com/1814174/164912983-c3f73628-0e19-4e42-b085-4f62ba6f23d1.png)
![](plot.png)