Skip to content
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
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ModelingToolkitStandardLibrary"
uuid = "16a59e39-deab-5bd0-87e4-056b12336739"
version = "2.29.5"
version = "2.29.6"
authors = ["Chris Rackauckas and Julia Computing"]

[deps]
Expand Down Expand Up @@ -34,7 +34,7 @@ SafeTestsets = "0.1"
SciCompDSL = "1"
SciMLBase = "2, 3"
SciMLStructures = "1.7.0"
SciMLTesting = "2.1"
SciMLTesting = "2.4"
SymbolicIndexingInterface = "0.3.39"
SymbolicUtils = "4.38.1"
Symbolics = "7.4.1"
Expand Down
8 changes: 4 additions & 4 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ makedocs(
sitename = "ModelingToolkitStandardLibrary.jl",
authors = "Julia Computing",
modules = [
ModelingToolkit,
ModelingToolkitStandardLibrary,
ModelingToolkitStandardLibrary.Blocks,
ModelingToolkitStandardLibrary.Mechanical,
Expand All @@ -33,9 +32,10 @@ makedocs(
ModelingToolkitStandardLibrary.Hydraulic,
ModelingToolkitStandardLibrary.Hydraulic.IsothermalCompressible,
],
clean = true, doctest = false, linkcheck = true,
linkcheck_ignore = ["https://www.mathworks.com/help/simscape/ug/basic-principles-of-modeling-physical-networks.html#bq89sba-6"],
warnonly = [:docs_block, :missing_docs, :cross_references],
clean = true,
checkdocs = :exports,
doctest = true,
linkcheck = true,
format = Documenter.HTML(
assets = ["assets/favicon.ico"],
canonical = "https://docs.sciml.ai/ModelingToolkitStandardLibrary/stable/"
Expand Down
2 changes: 2 additions & 0 deletions docs/pages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ pages = [
"Thermal Components" => "API/thermal.md",
"Hydraulic Components" => "API/hydraulic.md",
"Linear Analysis" => "API/linear_analysis.md",
"API Reference" => "API/reference.md",
"Domain API Reference" => "API/domain_reference.md",
],
]
15 changes: 15 additions & 0 deletions docs/src/API/domain_reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Domain API Reference

```@autodocs
Modules = [
ModelingToolkitStandardLibrary.Mechanical.Rotational,
ModelingToolkitStandardLibrary.Mechanical.Translational,
ModelingToolkitStandardLibrary.Mechanical.TranslationalModelica,
ModelingToolkitStandardLibrary.Mechanical.TranslationalPosition,
ModelingToolkitStandardLibrary.Mechanical.MultiBody2D,
ModelingToolkitStandardLibrary.Thermal,
ModelingToolkitStandardLibrary.Electrical,
ModelingToolkitStandardLibrary.Hydraulic.IsothermalCompressible,
]
Private = false
```
33 changes: 0 additions & 33 deletions docs/src/API/electrical.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ Capacitor
Inductor
IdealOpAmp
Diode
HeatingDiode
VariableResistor
NMOS
PMOS
Expand All @@ -56,35 +55,3 @@ MultiSensor
Voltage
Current
```

## Digital Gates

```@docs
Not
And
Nand
Or
Nor
Xor
Xnor
```

## Digital Components

```@docs
HalfAdder
FullAdder
MUX
DEMUX
Encoder
Decoder
```

## Digital Sources

```@docs
PulseDiff
Set
Reset
Pulse
```
4 changes: 4 additions & 0 deletions docs/src/API/hydraulic.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# [ModelingToolkit Standard Library: Hydraulic Components](@id hydraulic)

```@docs
ModelingToolkitStandardLibrary.Hydraulic
```

```@contents
Pages = ["hydraulic.md"]
Depth = 3
Expand Down
20 changes: 8 additions & 12 deletions docs/src/API/linear_analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

The interface described here is currently experimental and at any time subject to breaking changes not respecting semantic versioning.

Linear analysis refers to the process of linearizing a nonlinear model and analysing the resulting linear dynamical system. To facilitate linear analysis, ModelingToolkitStandardLibrary provides the concept of an [`AnalysisPoint`](@ref), which can be inserted in-between two causal blocks (such as those from the `Blocks` sub module). Once a model containing analysis points is built, several operations are available:
Linear analysis refers to the process of linearizing a nonlinear model and analysing the resulting linear dynamical system. To facilitate linear analysis, ModelingToolkitStandardLibrary provides the concept of an `AnalysisPoint`, which can be inserted in-between two causal blocks (such as those from the `Blocks` sub module). Once a model containing analysis points is built, several operations are available:

- [`get_sensitivity`](@ref) get the [sensitivity function (wiki)](https://en.wikipedia.org/wiki/Sensitivity_(control_systems)), $S(s)$, as defined in the field of control theory.
- [`get_comp_sensitivity`](@ref) get the complementary sensitivity function $T(s) : S(s)+T(s)=1$.
- [`get_looptransfer`](@ref) get the (open) loop-transfer function where the loop starts and ends in the analysis point. For a typical simple feedback connection with a plant $P(s)$ and a controller $C(s)$, the loop-transfer function at the plant output is $P(s)C(s)$.
- [`linearize`](@ref) can be called with two analysis points denoting the input and output of the linearized system.
- [`open_loop`](@ref) return a new (nonlinear) system where the loop has been broken in the analysis point, i.e., the connection the analysis point usually implies has been removed.
- `get_sensitivity` gets the [sensitivity function (wiki)](https://en.wikipedia.org/wiki/Sensitivity_(control_systems)), $S(s)$, as defined in the field of control theory.
- `get_comp_sensitivity` gets the complementary sensitivity function $T(s) : S(s)+T(s)=1$.
- `get_looptransfer` gets the (open) loop-transfer function where the loop starts and ends in the analysis point. For a typical simple feedback connection with a plant $P$ and a controller $C$, the loop-transfer function at the plant output is $P(s)C(s)$.
- `linearize` can be called with two analysis points denoting the input and output of the linearized system.
- `open_loop` returns a new nonlinear system where the loop has been broken at the analysis point.

An analysis point can be created explicitly using the constructor [`AnalysisPoint`](@ref), or automatically when connecting two causal components using `connect`:
An analysis point can be created explicitly using the `AnalysisPoint` constructor, or automatically when connecting two causal components using `connect`:

```julia
connect(comp1.output, :analysis_point_name, comp2.input)
Expand All @@ -34,7 +34,7 @@ The directionality of an analysis point can be thought of as an arrow in a block

This is signified by the name being the middle argument to `connect`.

Of the above mentioned functions, all except for [`open_loop`](@ref) return the output of [`ModelingToolkit.linearize`](@ref), which is
Of the above mentioned functions, all except for `open_loop` return the output of `ModelingToolkit.linearize`, which is

```julia
matrices, simplified_sys = linearize(...)
Expand Down Expand Up @@ -148,7 +148,3 @@ Pages = ["Blocks/analysis_points.jl"]
Order = [:function, :type]
Private = false
```

```@docs
ModelingToolkit.linearize
```
4 changes: 4 additions & 0 deletions docs/src/API/mechanical.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# ModelingToolkit Standard Library: Mechanical Components

```@docs
ModelingToolkitStandardLibrary.Mechanical
```

```@contents
Pages = ["mechanical.md"]
Depth = 3
Expand Down
8 changes: 8 additions & 0 deletions docs/src/API/reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# API Reference

```@autodocs
Modules = [
ModelingToolkitStandardLibrary.Blocks,
]
Private = false
```
2 changes: 1 addition & 1 deletion docs/src/connectors/connections.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
In Physical Network Acausal modeling, each physical domain must define a **connector** to combine model components. Each physical domain **connector** defines a minimum of 2 variables, one which is called a *Through* variable, and one which is called an *Across* variable. Both Modelica and SimScape define these variables in the same way:

- [Modelica Connectors](https://mbe.modelica.university/components/connectors/#acausal-connection)
- [SimScape Connectors](https://www.mathworks.com/help/simscape/ug/basic-principles-of-modeling-physical-networks.html#bq89sba-6)
- Simscape connector documentation

However, the standard libraries differ on the selection of the Across variable for the Mechanical Translation and Rotation libraries, Modelica choosing position and angle and SimScape choosing velocity and angular velocity, respectively for Translation and Rotation. Modelica describes their decision [here](https://mbe.modelica.university/components/connectors/simple_domains/). In summary, they would like to provide less integration in the model to avoid lossy numerical behavior, but this decision assumes the lowest order derivative is needed by the model. Numerically it is possible to define the connector either way, but there are some consequences of this decision, and therefore we will study them in detail here as they relate to ModelingToolkit.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The following are the constituent libraries of the ModelingToolkit Standard Libr
## Contributing

- Please refer to the
[SciML ColPrac: Contributor's Guide on Collaborative Practices for Community Packages](https://github.com/SciML/ColPrac/blob/master/README.md)
SciML ColPrac: Contributor's Guide on Collaborative Practices for Community Packages
for guidance on PRs, issues, and other matters relating to contributing to SciML.

- See the [SciML Style Guide](https://github.com/SciML/SciMLStyle) for common coding practices and other style decisions.
Expand Down
2 changes: 1 addition & 1 deletion src/Blocks/Blocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Blocks
using ModelingToolkitBase: ModelingToolkitBase, @component, @connector, @named,
@parameters, @unpack, System, compose, connect, extend,
getdefault, t_nounits as t, D_nounits as D
using SymbolicUtils: @syms, symtype
using SymbolicUtils: @syms, symtype, BasicSymbolic, SymReal
using Symbolics: Symbolics, @register_symbolic, @variables, Differential, Equation
import Base: ifelse
import ..@symcheck
Expand Down
2 changes: 1 addition & 1 deletion src/Blocks/continuous.jl
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ To set the initial state, it's recommended to set the initial condition for `x`,
- `input`
- `output`

See also [`StateSpace`](@ref) which handles MIMO systems, as well as [ControlSystemsMTK.jl](https://juliacontrol.github.io/ControlSystemsMTK.jl/stable/) for an interface between [ControlSystems.jl](https://juliacontrol.github.io/ControlSystems.jl/stable/) and ModelingToolkitBase.jl for advanced manipulation of transfer functions and linear statespace systems. For linearization, see [`linearize`](@ref) and [Linear Analysis](https://docs.sciml.ai/ModelingToolkitStandardLibrary/stable/API/linear_analysis/).
See also [`StateSpace`](@ref) which handles MIMO systems, as well as [ControlSystemsMTK.jl](https://juliacontrol.github.io/ControlSystemsMTK.jl/stable/) for an interface between [ControlSystems.jl](https://juliacontrol.github.io/ControlSystems.jl/stable/) and ModelingToolkitBase.jl for advanced manipulation of transfer functions and linear statespace systems. For linearization, see `ModelingToolkit.linearize` and [Linear Analysis](https://docs.sciml.ai/ModelingToolkitStandardLibrary/stable/API/linear_analysis/).
"""
@component function TransferFunction(; b = [1], a = [1, 1], name)
nb = length(b)
Expand Down
2 changes: 1 addition & 1 deletion src/Blocks/nonlinear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ If the input is within `u_min` ... `u_max`, the output is zero. Outside of this
_u_min = isnothing(u_min) ? (isnothing(u_max) ? nothing : -u_max) : u_min

# Validation (only if u_max is a concrete value)
if !isnothing(u_max) && !ModelingToolkitBase.isvariable(u_max)
if !isnothing(u_max) && !(u_max isa Symbolics.Num)
u_max ≥ _u_min || throw(ArgumentError("`u_min` must be smaller than `u_max`"))
end

Expand Down
36 changes: 32 additions & 4 deletions src/Blocks/sources.jl
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,9 @@ struct Parameter{T <: Real}
circular_buffer::Bool
end

Parameter(data::Symbolics.Arr, ref, circular_buffer) =
Symbolics.term(Parameter, data, ref, circular_buffer)

Parameter(data::Vector{T}, ref::T) where {T <: Real} = Parameter(data, ref, true)
Parameter(x::Parameter) = x
function Parameter(x::T; tofloat = true) where {T <: Real}
Expand Down Expand Up @@ -565,7 +568,6 @@ end
get_sample_time(memory::Parameter) = memory.ref
Symbolics.@register_symbolic get_sample_time(memory::Parameter)

Base.convert(::Type{T}, x::Parameter{T}) where {T <: Real} = x.ref
function Base.convert(::Type{<:Parameter{T}}, x::Number) where {T <: Real}
return Parameter{T}(T[], x, true)
end
Expand Down Expand Up @@ -647,18 +649,44 @@ end
function get_sampled_data(t, buffer)
return get_sampled_data(t, buffer.data, buffer.ref, buffer.circular_buffer)
end
Symbolics.@register_symbolic Parameter(data::Vector, ref, circular_buffer::Bool)
Symbolics.@register_symbolic get_sampled_data(t, buffer::Parameter)
Symbolics.@register_symbolic get_sampled_data(t, buffer::Vector, dt, circular_buffer) false

for (t_type, circular_buffer_type) in (
(Real, Real),
(Real, Symbolics.Num),
(Real, BasicSymbolic{SymReal}),
(Symbolics.Num, Real),
(Symbolics.Num, Symbolics.Num),
(Symbolics.Num, BasicSymbolic{SymReal}),
(BasicSymbolic{SymReal}, Real),
(BasicSymbolic{SymReal}, Symbolics.Num),
(BasicSymbolic{SymReal}, BasicSymbolic{SymReal}),
)
@eval function get_sampled_data(
t::$(t_type), buffer::Vector{T}, dt::Symbolics.Num,
circular_buffer::$(circular_buffer_type)
) where {T <: Real}
return invoke(
get_sampled_data,
Tuple{typeof(t), Vector, Symbolics.Num, typeof(circular_buffer)},
t,
buffer,
dt,
circular_buffer,
)
end
end

Symbolics.@register_derivative get_sampled_data(t, buffer) 1 first_order_backwards_difference(t, buffer)
function ChainRulesCore.frule((_, ẋ, _), ::typeof(get_sampled_data), t, buffer)
function ChainRulesCore.frule((_, ẋ, _)::Tuple, ::typeof(get_sampled_data), t, buffer)
return first_order_backwards_difference(t, buffer) * ẋ
end
Symbolics.@register_derivative get_sampled_data(t, buffer, dt, circular_buffer) 1 begin
first_order_backwards_difference(t, buffer, dt, circular_buffer)
end
function ChainRulesCore.frule(
(_, ẋ, _),
(_, ẋ, _)::Tuple,
::typeof(get_sampled_data),
t,
buffer,
Expand Down
Loading
Loading