ModiaMath provides a simulation engine and other mathematical utilities for packages Modia and Modia3D that are used to model physical systems such as electrical circuits, robots, or vehicles. The recommended way is to use ModiaMath via Modia or Modia3D. However, ModiaMath is self-contained and can be also used without Modia/Modia3D.

The central part of ModiaMath is a simulation engine to solve
*implicit index one Differential Algebraic Equations (DAEs)*
with and without *time and state events*. The theory is partially described in
(Otter/Elmqvist, 2017).
In particular it is shown, that a large class of DAEs can be transformed *automatically* to this
form (including multibody systems with kinematic loops). As integrator currently
IDA of the Sundials integrator suite
is used (via the Julia Sundials interface package).
It is planned to adapt ModiaMath to Julia package
DifferentialEquations
and use IDA and other appropriate integrators via this package in the future.

Additionally, ModiaMath provides functions to perform plotting in a convenient way, to generate and use rotation matrices and quaternions for kinematic transformations in 3D, and to provide an infrastructure for DAE variables as needed by Modia3D.

The package is registered in METADATA.jl and can be installed in the following way (Julia >= 1.0 is required):

```
julia> ]add ModiaMath
```

ModiaMath uses PyPlot for plotting.
If `PyPlot`

is not available in your current Julia environment
an information message is printed and all `ModiaMath.plot(..)`

calls are ignored.
In order that plot windows are displayed, you need to add `PyPlot`

to your current environment
via `]add PyPlot`

. Often this automatic installation fails and it is recommended to follow
instead the instructions
Installing PyPlot in a robust way.

**STABLE**—*documentation of the last released version.***LATEST**—*in-development version of the documentation.*

(note, it is simpler and less error prone to define a model with Modia or Modia3D):

```
using ModiaMath
using StaticArrays
@component Pendulum(;L=1.0, m=1.0, d=0.1, g=9.81) begin
phi = RealScalar(start=pi/2, unit="rad" , fixed=true, numericType=ModiaMath.XD_EXP)
w = RealScalar(start=0.0 , unit="rad/s" , fixed=true, integral=phi, numericType=ModiaMath.XD_EXP)
a = RealScalar( unit="rad/s^2", integral=w , numericType=ModiaMath.DER_XD_EXP)
r = RealSVector{2}( unit="m" , numericType=ModiaMath.WC)
end;
function ModiaMath.computeVariables!(p::Pendulum, sim::ModiaMath.SimulationState)
L = p.L; m = p.m; d = p.d; g = p.g; phi = p.phi.value; w = p.w.value
p.a.value = (-m*g*L*sin(phi) - d*w) / (m*L^2)
if ModiaMath.isStoreResult(sim)
p.r.value = @SVector [L*sin(phi), -L*cos(phi)]
end
end;
simulationModel = ModiaMath.SimulationModel(Pendulum(L=0.8, m=0.5, d=0.2), stopTime=5.0);
```

```
result = ModiaMath.simulate!(simulationModel; log=true);
ModiaMath.plot(result, [(:phi, :w) :a])
```

```
# run examples
import ModiaMath
include("$(ModiaMath.path)/examples/Simulate_Pendulum.jl") # ODE as index-0 DAE
include("$(ModiaMath.path)/examples/Simulate_FreeBodyRotation.jl") # index-1 DAE
include("$(ModiaMath.path)/examples/withoutMacros_withoutVariables/Simulate_PendulumDAE.jl") # index-3 DAE
include("$(ModiaMath.path)/examples/withoutMacros_withoutVariables/Simulate_SimpleStateEvents.jl")
include("$(ModiaMath.path)/examples/withoutMacros_withoutVariables/Simulate_BouncingBall.jl")
include("$(ModiaMath.path)/examples/withoutMacros_withoutVariables/Simulate_IdealClutch.jl") # Dirac impulses
# run all tests
include("$(ModiaMath.path)/test/runtests.jl")
```

The ModiaMath version number is 0.5.2, for details see the release notes, and functionality and robustness is planned to be improved for the 1.0 version, see Plans for ModiaMath version 1.0.

Contributions are welcome, as are feature requests and suggestions. Please open an issue in this case and also if you encounter problems.

Martin Otter, DLR - Institute of System Dynamics and Control

License: MIT (expat)

08/02/2018

3 months ago

178 commits