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
25 changes: 24 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jobs:
strategy:
fail-fast: false
matrix:
omc-version:
- 'nightly'
version:
- '1.10'
- '1.12'
Expand All @@ -31,10 +33,31 @@ jobs:
- x64
steps:
- uses: actions/checkout@v6
- uses: julia-actions/setup-julia@v2

- name: "Set up OpenModelica Compiler"
uses: OpenModelica/setup-openmodelica@v1.0
with:
version: ${{ matrix.omc-version }}
packages: |
omc
libraries: |
'Modelica 4.1.0'

- name: "Setup Julia ${{ matrix.version }}-${{ matrix.arch }}"
uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v2
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1

- name: Sanity check
run: |
julia --project='.' -e 'using BaseModelicaLibraryTesting; main(library = "Modelica", version = "4.1.0", filter = "Modelica.Electrical.Analog.Examples.ChuaCircuit", results_root = "main/Modelica/4.1.0/")'

- name: Upload test results
uses: actions/upload-artifact@v6
with:
name: test-results-${{ matrix.version }}-${{ matrix.os }}-${{ matrix.arch }}
path: main/
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,15 @@

# Julia files
/Manifest*.toml

# Python
.CondaPkg/

# Generated files and example results
*.log
*.html
!asserts/*.html
*.csv
*.bmo
MAP-LIB_ReferenceResults/
main/
13 changes: 12 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
name = "BaseModelicaLibraryTesting"
uuid = "e216686d-a052-4e92-9543-563498248f9c"
authors = ["Andreas Heuermann"]
version = "0.1.0-DEV"
authors = ["AnHeuermann"]

[deps]
BaseModelica = "a17d5099-185d-4ff5-b5d3-51aa4569e56d"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
OMJulia = "0f4fe800-344e-11e9-2949-fb537ad918e1"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
ZMQ = "c2297ded-f4af-51ae-bb23-16f91089e4e1"

[compat]
OMJulia = "0.3.3"
julia = "1.10.10, 1.12.5"

[extras]
Expand Down
58 changes: 53 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# BaseModelicaLibraryTesting
# BaseModelicaLibraryTesting.jl

[![Build Status](https://github.com/OpenModelica/BaseModelicaLibraryTesting.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/OpenModelica/BaseModelicaLibraryTesting.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![Build Status][build-badge-svg]][build-action-url]

Experimental Base Modelica library testing based on Julia.

Expand All @@ -15,16 +15,64 @@ For a given Modelica library test
[DifferentialEquations.jl][diffeqjl-url])
4. Validating simulation results

## Usage

```julia
main(
library = "<Modelica library name>",
version = "<Modelica library version>",
filter = "<Modelica class filter>",
omc_exe = "path/to/omc",
results_root = "results",
ref_root = "path/to/ReferenceResults"
)
```

If reference results are available provide the path via `ref_root`.

### Example - Testing the Modelica Standard Library v4.1.0

For example, for the Modelica Standard Library v4.1.0 reference results can be obtained by cloning the [MAP-LIB_ReferenceResults][map-lib-ref-results-url] repository:`

```bash
git clone --depth 1 -b v4.1.0 https://github.com/modelica/MAP-LIB_ReferenceResults
```

Run the library testing for the ChuaCircuit example of the Modelica Standard
Library v4.1.0 with:

```julia
using BaseModelicaLibraryTesting

main(
library = "Modelica",
version = "4.1.0",
filter = "Modelica.Electrical.Analog.Examples.ChuaCircuit",
omc_exe = "omc",
results_root = "main/Modelica/4.1.0/",
ref_root = "MAP-LIB_ReferenceResults"
)
```

Preview the generated HTML report at `main/Modelica/4.1.0/report.html`.

```bash
python -m http.server -d main/Modelica/4.1.0/
```

## License

This package is available under the [OSMC-PL License][osmc-license-file] and the
[AGPL-3.0 License][agpl-file]. See the [OSMC-License.txt][osmc-license-file]
file for details.

[build-badge-svg]: https://github.com/OpenModelica/BaseModelicaLibraryTesting.jl/actions/workflows/CI.yml/badge.svg?branch=main
[build-action-url]: https://github.com/OpenModelica/BaseModelicaLibraryTesting.jl/actions/workflows/CI.yml?query=branch%3Amain
[openmodelica-url]: https://openmodelica.org/
[omjuliajl-url]: https://github.com/OpenModelica/OMJulia.jl
[osmc-license-file]: OSMC-License.txt
[agpl-file]: LICENSE
[basemodelicajl-url]: https://github.com/SciML/BaseModelica.jl
[modelingtoolkitjl-url]: https://github.com/SciML/ModelingToolkit.jl
[diffeqjl-url]: https://github.com/SciML/DifferentialEquations.jl
[omjuliajl-url]: https://github.com/OpenModelica/OMJulia.jl
[map-lib-ref-results-url]: https://github.com/modelica/MAP-LIB_ReferenceResults/tree/v4.1.0
[osmc-license-file]: OSMC-License.txt
[agpl-file]: LICENSE
95 changes: 95 additions & 0 deletions assets/diff_template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Diff &#x2014; {{TITLE}}</title>
<link rel="stylesheet" href="../../assets/dygraph.min.css"/>
<script src="../../assets/dygraph.min.js"></script>
<style>
body { font-family: sans-serif; margin: 2em; font-size: 14px; }
h1 { font-size: 1.3em; }
h3 { font-size: 1.1em; margin-top: 2.5em; border-bottom: 1px solid #ddd;
padding-bottom: 4px; }
.graph { width: 100%; height: 320px; margin-bottom: 0.5em; }
.meta { color: #555; font-size: 12px; margin: 0.4em 0 2em; }
a { color: #0366d6; text-decoration: none; }
a:hover { text-decoration: underline; }
.dygraph-legend { font-size: 12px !important; }
</style>
</head>
<body>
<h1>Diff &#x2014; {{MODEL}}</h1>
<p class="meta">
{{N_FAIL}} signal(s) outside tolerance
(rel &#x2264; {{REL_TOL_PCT}}%,&nbsp; abs &#x2264; {{ABS_TOL}})
&nbsp;&middot;&nbsp;
<a href="{{CSV_NAME}}">Download CSV</a>
</p>
<div id="charts"></div>
<script>
var csvRaw = `{{CSV_DATA}}`;

(function () {
var lines = csvRaw.trim().split('\n');
var headers = lines[0].split(',').map(function (s) { return s.trim(); });
var rows = lines.slice(1).filter(function (l) { return l.trim() !== ''; })
.map(function (l) { return l.split(',').map(Number); });

// Collect unique signal names from columns ending with "_ref"
var sigs = [], seen = {};
headers.forEach(function (h) {
if (h.slice(-4) === '_ref') {
var sig = h.slice(0, h.length - 4);
if (!seen[sig]) { sigs.push(sig); seen[sig] = true; }
}
});

var container = document.getElementById('charts');

sigs.forEach(function (sig, si) {
var refIdx = headers.indexOf(sig + '_ref');
var simIdx = headers.indexOf(sig + '_sim');
var errIdx = headers.indexOf(sig + '_relerr');

var data = rows.map(function (r) {
return [r[0], r[refIdx], r[simIdx], r[errIdx]];
});

var h3 = document.createElement('h3');
h3.textContent = sig;
var div = document.createElement('div');
div.id = 'g' + si;
div.className = 'graph';
container.appendChild(h3);
container.appendChild(div);

new Dygraph(div, data, {
labels: ['time', sig + ' (ref)', sig + ' (sim)', 'rel. err'],
colors: ['#1a73e8', '#e8700a', '#b0b0b0'],
series: {
'rel. err': { axis: 'y2', strokeWidth: 1 }
},
axes: {
y: { axisLabelWidth: 70 },
y2: {
independentTicks: true,
axisLabelFormatter: function (v) {
return (v * 100).toPrecision(3) + '%';
},
valueFormatter: function (v) {
return (v * 100).toPrecision(4) + '%';
}
}
},
y2label: 'Relative Error',
xlabel: 'time',
legend: 'always',
showRangeSelector: true,
highlightCircleSize: 3,
strokeWidth: 2
});
});
}());
</script>
</body>
</html>
87 changes: 87 additions & 0 deletions assets/dygraph.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions assets/dygraph.min.js

Large diffs are not rendered by default.

41 changes: 39 additions & 2 deletions src/BaseModelicaLibraryTesting.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
module BaseModelicaLibraryTesting

# Write your package code here.
import OMJulia
import OMJulia: sendExpression
import BaseModelica
import DifferentialEquations: solve, Rodas5P, ReturnCode
import ModelingToolkit
import Dates: now
import Printf: @sprintf

end
include("types.jl")
include("compare.jl") # defines _clean_var_name used by simulate.jl
include("export.jl")
include("parse_bm.jl")
include("simulate.jl")
include("report.jl")
include("pipeline.jl")

# ── Public API ─────────────────────────────────────────────────────────────────

# Shared types and constants
export ModelResult, CompareSettings
export LIBRARY, LIBRARY_VERSION, CMP_REL_TOL, CMP_ABS_TOL

# Comparison configuration
export configure_comparison!, compare_settings

# Pipeline phases
export run_export # Phase 1: Base Modelica export via OMC
export run_parse # Phase 2: BaseModelica.jl → ODEProblem
export run_simulate # Phase 3: DifferentialEquations solve + CSV

# Reference comparison
export compare_with_reference, write_diff_html

# HTML report
export generate_report

# Top-level orchestration
export test_model, main

end # module BaseModelicaLibraryTesting
Loading
Loading